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