4af1dcb856f4ac03d7f91f823f366f50684aa78f
[yaffs-website] / web / core / modules / system / src / Controller / SystemController.php
1 <?php
2
3 namespace Drupal\system\Controller;
4
5 use Drupal\Core\Cache\CacheableMetadata;
6 use Drupal\Core\Controller\ControllerBase;
7 use Drupal\Core\Extension\ThemeHandlerInterface;
8 use Drupal\Core\Form\FormBuilderInterface;
9 use Drupal\Core\Menu\MenuLinkTreeInterface;
10 use Drupal\Core\Menu\MenuTreeParameters;
11 use Drupal\Core\Theme\ThemeAccessCheck;
12 use Drupal\Core\Url;
13 use Drupal\system\SystemManager;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15
16 /**
17  * Returns responses for System routes.
18  */
19 class SystemController extends ControllerBase {
20
21   /**
22    * System Manager Service.
23    *
24    * @var \Drupal\system\SystemManager
25    */
26   protected $systemManager;
27
28   /**
29    * The theme access checker service.
30    *
31    * @var \Drupal\Core\Theme\ThemeAccessCheck
32    */
33   protected $themeAccess;
34
35   /**
36    * The form builder service.
37    *
38    * @var \Drupal\Core\Form\FormBuilderInterface
39    */
40   protected $formBuilder;
41
42   /**
43    * The theme handler service.
44    *
45    * @var \Drupal\Core\Extension\ThemeHandlerInterface
46    */
47   protected $themeHandler;
48
49   /**
50    * The menu link tree service.
51    *
52    * @var \Drupal\Core\Menu\MenuLinkTreeInterface
53    */
54   protected $menuLinkTree;
55
56   /**
57    * Constructs a new SystemController.
58    *
59    * @param \Drupal\system\SystemManager $systemManager
60    *   System manager service.
61    * @param \Drupal\Core\Theme\ThemeAccessCheck $theme_access
62    *   The theme access checker service.
63    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
64    *   The form builder.
65    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
66    *   The theme handler.
67    * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_link_tree
68    *   The menu link tree service.
69    */
70   public function __construct(SystemManager $systemManager, ThemeAccessCheck $theme_access, FormBuilderInterface $form_builder, ThemeHandlerInterface $theme_handler, MenuLinkTreeInterface $menu_link_tree) {
71     $this->systemManager = $systemManager;
72     $this->themeAccess = $theme_access;
73     $this->formBuilder = $form_builder;
74     $this->themeHandler = $theme_handler;
75     $this->menuLinkTree = $menu_link_tree;
76   }
77
78   /**
79    * {@inheritdoc}
80    */
81   public static function create(ContainerInterface $container) {
82     return new static(
83       $container->get('system.manager'),
84       $container->get('access_check.theme'),
85       $container->get('form_builder'),
86       $container->get('theme_handler'),
87       $container->get('menu.link_tree')
88     );
89   }
90
91   /**
92    * Provide the administration overview page.
93    *
94    * @param string $link_id
95    *   The ID of the administrative path link for which to display child links.
96    *
97    * @return array
98    *   A renderable array of the administration overview page.
99    */
100   public function overview($link_id) {
101     // Check for status report errors.
102     if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) {
103       drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the <a href=":status">status report</a> for more information.', [':status' => $this->url('system.status')]), 'error');
104     }
105     // Load all menu links below it.
106     $parameters = new MenuTreeParameters();
107     $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks();
108     $tree = $this->menuLinkTree->load(NULL, $parameters);
109     $manipulators = [
110       ['callable' => 'menu.default_tree_manipulators:checkAccess'],
111       ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
112     ];
113     $tree = $this->menuLinkTree->transform($tree, $manipulators);
114     $tree_access_cacheability = new CacheableMetadata();
115     $blocks = [];
116     foreach ($tree as $key => $element) {
117       $tree_access_cacheability = $tree_access_cacheability->merge(CacheableMetadata::createFromObject($element->access));
118
119       // Only render accessible links.
120       if (!$element->access->isAllowed()) {
121         continue;
122       }
123
124       $link = $element->link;
125       $block['title'] = $link->getTitle();
126       $block['description'] = $link->getDescription();
127       $block['content'] = [
128         '#theme' => 'admin_block_content',
129         '#content' => $this->systemManager->getAdminBlock($link),
130       ];
131
132       if (!empty($block['content']['#content'])) {
133         $blocks[$key] = $block;
134       }
135     }
136
137     if ($blocks) {
138       ksort($blocks);
139       $build = [
140         '#theme' => 'admin_page',
141         '#blocks' => $blocks,
142       ];
143       $tree_access_cacheability->applyTo($build);
144       return $build;
145     }
146     else {
147       $build = [
148         '#markup' => $this->t('You do not have any administrative items.'),
149       ];
150       $tree_access_cacheability->applyTo($build);
151       return $build;
152     }
153   }
154
155   /**
156    * Sets whether the admin menu is in compact mode or not.
157    *
158    * @param string $mode
159    *   Valid values are 'on' and 'off'.
160    *
161    * @return \Symfony\Component\HttpFoundation\RedirectResponse
162    */
163   public function compactPage($mode) {
164     user_cookie_save(['admin_compact_mode' => ($mode == 'on')]);
165     return $this->redirect('<front>');
166   }
167
168   /**
169    * Provides a single block from the administration menu as a page.
170    */
171   public function systemAdminMenuBlockPage() {
172     return $this->systemManager->getBlockContents();
173   }
174
175   /**
176    * Returns a theme listing.
177    *
178    * @return string
179    *   An HTML string of the theme listing page.
180    *
181    * @todo Move into ThemeController.
182    */
183   public function themesPage() {
184     $config = $this->config('system.theme');
185     // Get all available themes.
186     $themes = $this->themeHandler->rebuildThemeData();
187     uasort($themes, 'system_sort_modules_by_info_name');
188
189     $theme_default = $config->get('default');
190     $theme_groups  = ['installed' => [], 'uninstalled' => []];
191     $admin_theme = $config->get('admin');
192     $admin_theme_options = [];
193
194     foreach ($themes as &$theme) {
195       if (!empty($theme->info['hidden'])) {
196         continue;
197       }
198       $theme->is_default = ($theme->getName() == $theme_default);
199       $theme->is_admin = ($theme->getName() == $admin_theme || ($theme->is_default && $admin_theme == '0'));
200
201       // Identify theme screenshot.
202       $theme->screenshot = NULL;
203       // Create a list which includes the current theme and all its base themes.
204       if (isset($themes[$theme->getName()]->base_themes)) {
205         $theme_keys = array_keys($themes[$theme->getName()]->base_themes);
206         $theme_keys[] = $theme->getName();
207       }
208       else {
209         $theme_keys = [$theme->getName()];
210       }
211       // Look for a screenshot in the current theme or in its closest ancestor.
212       foreach (array_reverse($theme_keys) as $theme_key) {
213         if (isset($themes[$theme_key]) && file_exists($themes[$theme_key]->info['screenshot'])) {
214           $theme->screenshot = [
215             'uri' => $themes[$theme_key]->info['screenshot'],
216             'alt' => $this->t('Screenshot for @theme theme', ['@theme' => $theme->info['name']]),
217             'title' => $this->t('Screenshot for @theme theme', ['@theme' => $theme->info['name']]),
218             'attributes' => ['class' => ['screenshot']],
219           ];
220           break;
221         }
222       }
223
224       if (empty($theme->status)) {
225         // Ensure this theme is compatible with this version of core.
226         $theme->incompatible_core = !isset($theme->info['core']) || ($theme->info['core'] != \DRUPAL::CORE_COMPATIBILITY);
227         // Require the 'content' region to make sure the main page
228         // content has a common place in all themes.
229         $theme->incompatible_region = !isset($theme->info['regions']['content']);
230         $theme->incompatible_php = version_compare(phpversion(), $theme->info['php']) < 0;
231         // Confirm that all base themes are available.
232         $theme->incompatible_base = (isset($theme->info['base theme']) && !($theme->base_themes === array_filter($theme->base_themes)));
233         // Confirm that the theme engine is available.
234         $theme->incompatible_engine = isset($theme->info['engine']) && !isset($theme->owner);
235       }
236       $theme->operations = [];
237       if (!empty($theme->status) || !$theme->incompatible_core && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine) {
238         // Create the operations links.
239         $query['theme'] = $theme->getName();
240         if ($this->themeAccess->checkAccess($theme->getName())) {
241           $theme->operations[] = [
242             'title' => $this->t('Settings'),
243             'url' => Url::fromRoute('system.theme_settings_theme', ['theme' => $theme->getName()]),
244             'attributes' => ['title' => $this->t('Settings for @theme theme', ['@theme' => $theme->info['name']])],
245           ];
246         }
247         if (!empty($theme->status)) {
248           if (!$theme->is_default) {
249             $theme_uninstallable = TRUE;
250             if ($theme->getName() == $admin_theme) {
251               $theme_uninstallable = FALSE;
252             }
253             // Check it isn't the base of theme of an installed theme.
254             foreach ($theme->required_by as $themename => $dependency) {
255               if (!empty($themes[$themename]->status)) {
256                 $theme_uninstallable = FALSE;
257               }
258             }
259             if ($theme_uninstallable) {
260               $theme->operations[] = [
261                 'title' => $this->t('Uninstall'),
262                 'url' => Url::fromRoute('system.theme_uninstall'),
263                 'query' => $query,
264                 'attributes' => ['title' => $this->t('Uninstall @theme theme', ['@theme' => $theme->info['name']])],
265               ];
266             }
267             $theme->operations[] = [
268               'title' => $this->t('Set as default'),
269               'url' => Url::fromRoute('system.theme_set_default'),
270               'query' => $query,
271               'attributes' => ['title' => $this->t('Set @theme as default theme', ['@theme' => $theme->info['name']])],
272             ];
273           }
274           $admin_theme_options[$theme->getName()] = $theme->info['name'];
275         }
276         else {
277           $theme->operations[] = [
278             'title' => $this->t('Install'),
279             'url' => Url::fromRoute('system.theme_install'),
280             'query' => $query,
281             'attributes' => ['title' => $this->t('Install @theme theme', ['@theme' => $theme->info['name']])],
282           ];
283           $theme->operations[] = [
284             'title' => $this->t('Install and set as default'),
285             'url' => Url::fromRoute('system.theme_set_default'),
286             'query' => $query,
287             'attributes' => ['title' => $this->t('Install @theme as default theme', ['@theme' => $theme->info['name']])],
288           ];
289         }
290       }
291
292       // Add notes to default and administration theme.
293       $theme->notes = [];
294       if ($theme->is_default) {
295         $theme->notes[] = $this->t('default theme');
296       }
297       if ($theme->is_admin) {
298         $theme->notes[] = $this->t('administration theme');
299       }
300
301       // Sort installed and uninstalled themes into their own groups.
302       $theme_groups[$theme->status ? 'installed' : 'uninstalled'][] = $theme;
303     }
304
305     // There are two possible theme groups.
306     $theme_group_titles = [
307       'installed' => $this->formatPlural(count($theme_groups['installed']), 'Installed theme', 'Installed themes'),
308     ];
309     if (!empty($theme_groups['uninstalled'])) {
310       $theme_group_titles['uninstalled'] = $this->formatPlural(count($theme_groups['uninstalled']), 'Uninstalled theme', 'Uninstalled themes');
311     }
312
313     uasort($theme_groups['installed'], 'system_sort_themes');
314     $this->moduleHandler()->alter('system_themes_page', $theme_groups);
315
316     $build = [];
317     $build[] = [
318       '#theme' => 'system_themes_page',
319       '#theme_groups' => $theme_groups,
320       '#theme_group_titles' => $theme_group_titles,
321     ];
322     $build[] = $this->formBuilder->getForm('Drupal\system\Form\ThemeAdminForm', $admin_theme_options);
323
324     return $build;
325   }
326
327 }