Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / system / src / SystemManager.php
1 <?php
2
3 namespace Drupal\system;
4
5 use Drupal\Core\Entity\EntityManagerInterface;
6 use Drupal\Core\Menu\MenuActiveTrailInterface;
7 use Drupal\Core\Menu\MenuLinkTreeInterface;
8 use Drupal\Core\Menu\MenuLinkInterface;
9 use Drupal\Core\Menu\MenuTreeParameters;
10 use Drupal\Core\Extension\ModuleHandlerInterface;
11 use Symfony\Component\HttpFoundation\RequestStack;
12
13 /**
14  * System Manager Service.
15  */
16 class SystemManager {
17
18   /**
19    * Module handler service.
20    *
21    * @var \Drupal\Core\Extension\ModuleHandlerInterface
22    */
23   protected $moduleHandler;
24
25   /**
26    * The request stack.
27    *
28    * @var \Symfony\Component\HttpFoundation\RequestStack
29    */
30   protected $requestStack;
31
32   /**
33    * The menu link tree manager.
34    *
35    * @var \Drupal\Core\Menu\MenuLinkTreeInterface
36    */
37   protected $menuTree;
38
39   /**
40    * The active menu trail service.
41    *
42    * @var \Drupal\Core\Menu\MenuActiveTrailInterface
43    */
44   protected $menuActiveTrail;
45
46   /**
47    * A static cache of menu items.
48    *
49    * @var array
50    */
51   protected $menuItems;
52
53   /**
54    * Requirement severity -- Requirement successfully met.
55    */
56   const REQUIREMENT_OK = 0;
57
58   /**
59    * Requirement severity -- Warning condition; proceed but flag warning.
60    */
61   const REQUIREMENT_WARNING = 1;
62
63   /**
64    * Requirement severity -- Error condition; abort installation.
65    */
66   const REQUIREMENT_ERROR = 2;
67
68   /**
69    * Constructs a SystemManager object.
70    *
71    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
72    *   The module handler.
73    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
74    *   The entity manager.
75    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
76    *   The request stack.
77    * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
78    *   The menu tree manager.
79    * @param \Drupal\Core\Menu\MenuActiveTrailInterface $menu_active_trail
80    *   The active menu trail service.
81    */
82   public function __construct(ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager, RequestStack $request_stack, MenuLinkTreeInterface $menu_tree, MenuActiveTrailInterface $menu_active_trail) {
83     $this->moduleHandler = $module_handler;
84     $this->requestStack = $request_stack;
85     $this->menuTree = $menu_tree;
86     $this->menuActiveTrail = $menu_active_trail;
87   }
88
89   /**
90    * Checks for requirement severity.
91    *
92    * @return bool
93    *   Returns the status of the system.
94    */
95   public function checkRequirements() {
96     $requirements = $this->listRequirements();
97     return $this->getMaxSeverity($requirements) == static::REQUIREMENT_ERROR;
98   }
99
100   /**
101    * Displays the site status report. Can also be used as a pure check.
102    *
103    * @return array
104    *   An array of system requirements.
105    */
106   public function listRequirements() {
107     // Load .install files
108     include_once DRUPAL_ROOT . '/core/includes/install.inc';
109     drupal_load_updates();
110
111     // Check run-time requirements and status information.
112     $requirements = $this->moduleHandler->invokeAll('requirements', ['runtime']);
113     uasort($requirements, function($a, $b) {
114       if (!isset($a['weight'])) {
115         if (!isset($b['weight'])) {
116           return strcasecmp($a['title'], $b['title']);
117         }
118         return -$b['weight'];
119       }
120       return isset($b['weight']) ? $a['weight'] - $b['weight'] : $a['weight'];
121     });
122
123     return $requirements;
124   }
125
126   /**
127    * Extracts the highest severity from the requirements array.
128    *
129    * @param $requirements
130    *   An array of requirements, in the same format as is returned by
131    *   hook_requirements().
132    *
133    * @return
134    *   The highest severity in the array.
135    */
136   public function getMaxSeverity(&$requirements) {
137     $severity = static::REQUIREMENT_OK;
138     foreach ($requirements as $requirement) {
139       if (isset($requirement['severity'])) {
140         $severity = max($severity, $requirement['severity']);
141       }
142     }
143     return $severity;
144   }
145
146   /**
147    * Loads the contents of a menu block.
148    *
149    * This function is often a destination for these blocks.
150    * For example, 'admin/structure/types' needs to have a destination to be
151    * valid in the Drupal menu system, but too much information there might be
152    * hidden, so we supply the contents of the block.
153    *
154    * @return array
155    *   A render array suitable for drupal_render.
156    */
157   public function getBlockContents() {
158     // We hard-code the menu name here since otherwise a link in the tools menu
159     // or elsewhere could give us a blank block.
160     $link = $this->menuActiveTrail->getActiveLink('admin');
161     if ($link && $content = $this->getAdminBlock($link)) {
162       $output = [
163         '#theme' => 'admin_block_content',
164         '#content' => $content,
165       ];
166     }
167     else {
168       $output = [
169         '#markup' => t('You do not have any administrative items.'),
170       ];
171     }
172     return $output;
173   }
174
175   /**
176    * Provide a single block on the administration overview page.
177    *
178    * @param \Drupal\Core\Menu\MenuLinkInterface $instance
179    *   The menu item to be displayed.
180    *
181    * @return array
182    *   An array of menu items, as expected by admin-block-content.html.twig.
183    */
184   public function getAdminBlock(MenuLinkInterface $instance) {
185     $content = [];
186     // Only find the children of this link.
187     $link_id = $instance->getPluginId();
188     $parameters = new MenuTreeParameters();
189     $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks();
190     $tree = $this->menuTree->load(NULL, $parameters);
191     $manipulators = [
192       ['callable' => 'menu.default_tree_manipulators:checkAccess'],
193       ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
194     ];
195     $tree = $this->menuTree->transform($tree, $manipulators);
196     foreach ($tree as $key => $element) {
197       // Only render accessible links.
198       if (!$element->access->isAllowed()) {
199         // @todo Bubble cacheability metadata of both accessible and
200         //   inaccessible links. Currently made impossible by the way admin
201         //   blocks are rendered.
202         continue;
203       }
204
205       /** @var $link \Drupal\Core\Menu\MenuLinkInterface */
206       $link = $element->link;
207       $content[$key]['title'] = $link->getTitle();
208       $content[$key]['options'] = $link->getOptions();
209       $content[$key]['description'] = $link->getDescription();
210       $content[$key]['url'] = $link->getUrlObject();
211     }
212     ksort($content);
213     return $content;
214   }
215
216 }