Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Extension;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Core\Config\ConfigFactoryInterface;
|
Chris@17
|
6 use Drupal\Core\Extension\Exception\UninstalledExtensionException;
|
Chris@17
|
7 use Drupal\Core\Extension\Exception\UnknownExtensionException;
|
Chris@0
|
8 use Drupal\Core\State\StateInterface;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Default theme handler using the config system to store installation statuses.
|
Chris@0
|
12 */
|
Chris@0
|
13 class ThemeHandler implements ThemeHandlerInterface {
|
Chris@0
|
14
|
Chris@0
|
15 /**
|
Chris@0
|
16 * Contains the features enabled for themes by default.
|
Chris@0
|
17 *
|
Chris@0
|
18 * @var array
|
Chris@0
|
19 *
|
Chris@0
|
20 * @see _system_default_theme_features()
|
Chris@0
|
21 */
|
Chris@0
|
22 protected $defaultFeatures = [
|
Chris@0
|
23 'favicon',
|
Chris@0
|
24 'logo',
|
Chris@0
|
25 'node_user_picture',
|
Chris@0
|
26 'comment_user_picture',
|
Chris@0
|
27 'comment_user_verification',
|
Chris@0
|
28 ];
|
Chris@0
|
29
|
Chris@0
|
30 /**
|
Chris@0
|
31 * A list of all currently available themes.
|
Chris@0
|
32 *
|
Chris@0
|
33 * @var array
|
Chris@0
|
34 */
|
Chris@0
|
35 protected $list;
|
Chris@0
|
36
|
Chris@0
|
37 /**
|
Chris@0
|
38 * The config factory to get the installed themes.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @var \Drupal\Core\Config\ConfigFactoryInterface
|
Chris@0
|
41 */
|
Chris@0
|
42 protected $configFactory;
|
Chris@0
|
43
|
Chris@0
|
44 /**
|
Chris@0
|
45 * The module handler to fire themes_installed/themes_uninstalled hooks.
|
Chris@0
|
46 *
|
Chris@0
|
47 * @var \Drupal\Core\Extension\ModuleHandlerInterface
|
Chris@0
|
48 */
|
Chris@0
|
49 protected $moduleHandler;
|
Chris@0
|
50
|
Chris@0
|
51 /**
|
Chris@0
|
52 * The state backend.
|
Chris@0
|
53 *
|
Chris@0
|
54 * @var \Drupal\Core\State\StateInterface
|
Chris@0
|
55 */
|
Chris@0
|
56 protected $state;
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * The config installer to install configuration.
|
Chris@0
|
60 *
|
Chris@0
|
61 * @var \Drupal\Core\Config\ConfigInstallerInterface
|
Chris@0
|
62 */
|
Chris@0
|
63 protected $configInstaller;
|
Chris@0
|
64
|
Chris@0
|
65 /**
|
Chris@0
|
66 * The info parser to parse the theme.info.yml files.
|
Chris@0
|
67 *
|
Chris@0
|
68 * @var \Drupal\Core\Extension\InfoParserInterface
|
Chris@0
|
69 */
|
Chris@0
|
70 protected $infoParser;
|
Chris@0
|
71
|
Chris@0
|
72 /**
|
Chris@0
|
73 * A logger instance.
|
Chris@0
|
74 *
|
Chris@0
|
75 * @var \Psr\Log\LoggerInterface
|
Chris@0
|
76 */
|
Chris@0
|
77 protected $logger;
|
Chris@0
|
78
|
Chris@0
|
79 /**
|
Chris@0
|
80 * The route builder to rebuild the routes if a theme is installed.
|
Chris@0
|
81 *
|
Chris@0
|
82 * @var \Drupal\Core\Routing\RouteBuilderInterface
|
Chris@0
|
83 */
|
Chris@0
|
84 protected $routeBuilder;
|
Chris@0
|
85
|
Chris@0
|
86 /**
|
Chris@0
|
87 * An extension discovery instance.
|
Chris@0
|
88 *
|
Chris@0
|
89 * @var \Drupal\Core\Extension\ExtensionDiscovery
|
Chris@0
|
90 */
|
Chris@0
|
91 protected $extensionDiscovery;
|
Chris@0
|
92
|
Chris@0
|
93 /**
|
Chris@0
|
94 * The CSS asset collection optimizer service.
|
Chris@0
|
95 *
|
Chris@0
|
96 * @var \Drupal\Core\Asset\AssetCollectionOptimizerInterface
|
Chris@0
|
97 */
|
Chris@0
|
98 protected $cssCollectionOptimizer;
|
Chris@0
|
99
|
Chris@0
|
100 /**
|
Chris@0
|
101 * The config manager used to uninstall a theme.
|
Chris@0
|
102 *
|
Chris@0
|
103 * @var \Drupal\Core\Config\ConfigManagerInterface
|
Chris@0
|
104 */
|
Chris@0
|
105 protected $configManager;
|
Chris@0
|
106
|
Chris@0
|
107 /**
|
Chris@0
|
108 * The app root.
|
Chris@0
|
109 *
|
Chris@0
|
110 * @var string
|
Chris@0
|
111 */
|
Chris@0
|
112 protected $root;
|
Chris@0
|
113
|
Chris@0
|
114 /**
|
Chris@0
|
115 * Constructs a new ThemeHandler.
|
Chris@0
|
116 *
|
Chris@0
|
117 * @param string $root
|
Chris@0
|
118 * The app root.
|
Chris@0
|
119 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
Chris@0
|
120 * The config factory to get the installed themes.
|
Chris@0
|
121 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
Chris@0
|
122 * The module handler to fire themes_installed/themes_uninstalled hooks.
|
Chris@0
|
123 * @param \Drupal\Core\State\StateInterface $state
|
Chris@0
|
124 * The state store.
|
Chris@0
|
125 * @param \Drupal\Core\Extension\InfoParserInterface $info_parser
|
Chris@0
|
126 * The info parser to parse the theme.info.yml files.
|
Chris@0
|
127 * @param \Drupal\Core\Extension\ExtensionDiscovery $extension_discovery
|
Chris@0
|
128 * (optional) A extension discovery instance (for unit tests).
|
Chris@0
|
129 */
|
Chris@0
|
130 public function __construct($root, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, StateInterface $state, InfoParserInterface $info_parser, ExtensionDiscovery $extension_discovery = NULL) {
|
Chris@0
|
131 $this->root = $root;
|
Chris@0
|
132 $this->configFactory = $config_factory;
|
Chris@0
|
133 $this->moduleHandler = $module_handler;
|
Chris@0
|
134 $this->state = $state;
|
Chris@0
|
135 $this->infoParser = $info_parser;
|
Chris@0
|
136 $this->extensionDiscovery = $extension_discovery;
|
Chris@0
|
137 }
|
Chris@0
|
138
|
Chris@0
|
139 /**
|
Chris@0
|
140 * {@inheritdoc}
|
Chris@0
|
141 */
|
Chris@0
|
142 public function getDefault() {
|
Chris@0
|
143 return $this->configFactory->get('system.theme')->get('default');
|
Chris@0
|
144 }
|
Chris@0
|
145
|
Chris@0
|
146 /**
|
Chris@0
|
147 * {@inheritdoc}
|
Chris@0
|
148 */
|
Chris@0
|
149 public function setDefault($name) {
|
Chris@0
|
150 $list = $this->listInfo();
|
Chris@0
|
151 if (!isset($list[$name])) {
|
Chris@17
|
152 throw new UninstalledExtensionException("$name theme is not installed.");
|
Chris@0
|
153 }
|
Chris@0
|
154 $this->configFactory->getEditable('system.theme')
|
Chris@0
|
155 ->set('default', $name)
|
Chris@0
|
156 ->save();
|
Chris@0
|
157 return $this;
|
Chris@0
|
158 }
|
Chris@0
|
159
|
Chris@0
|
160 /**
|
Chris@0
|
161 * {@inheritdoc}
|
Chris@0
|
162 */
|
Chris@0
|
163 public function install(array $theme_list, $install_dependencies = TRUE) {
|
Chris@0
|
164 // We keep the old install() method as BC layer but redirect directly to the
|
Chris@0
|
165 // theme installer.
|
Chris@0
|
166 return \Drupal::service('theme_installer')->install($theme_list, $install_dependencies);
|
Chris@0
|
167 }
|
Chris@0
|
168
|
Chris@0
|
169 /**
|
Chris@0
|
170 * {@inheritdoc}
|
Chris@0
|
171 */
|
Chris@0
|
172 public function uninstall(array $theme_list) {
|
Chris@0
|
173 // We keep the old uninstall() method as BC layer but redirect directly to
|
Chris@0
|
174 // the theme installer.
|
Chris@0
|
175 \Drupal::service('theme_installer')->uninstall($theme_list);
|
Chris@0
|
176 }
|
Chris@0
|
177
|
Chris@0
|
178 /**
|
Chris@0
|
179 * {@inheritdoc}
|
Chris@0
|
180 */
|
Chris@0
|
181 public function listInfo() {
|
Chris@0
|
182 if (!isset($this->list)) {
|
Chris@0
|
183 $this->list = [];
|
Chris@0
|
184 $themes = $this->systemThemeList();
|
Chris@0
|
185 // @todo Ensure that systemThemeList() does not contain an empty list
|
Chris@0
|
186 // during the batch installer, see https://www.drupal.org/node/2322619.
|
Chris@0
|
187 if (empty($themes)) {
|
Chris@0
|
188 $this->refreshInfo();
|
Chris@0
|
189 $this->list = $this->list ?: [];
|
Chris@0
|
190 $themes = \Drupal::state()->get('system.theme.data', []);
|
Chris@0
|
191 }
|
Chris@0
|
192 foreach ($themes as $theme) {
|
Chris@0
|
193 $this->addTheme($theme);
|
Chris@0
|
194 }
|
Chris@0
|
195 }
|
Chris@0
|
196 return $this->list;
|
Chris@0
|
197 }
|
Chris@0
|
198
|
Chris@0
|
199 /**
|
Chris@0
|
200 * {@inheritdoc}
|
Chris@0
|
201 */
|
Chris@0
|
202 public function addTheme(Extension $theme) {
|
Chris@0
|
203 if (!empty($theme->info['libraries'])) {
|
Chris@0
|
204 foreach ($theme->info['libraries'] as $library => $name) {
|
Chris@0
|
205 $theme->libraries[$library] = $name;
|
Chris@0
|
206 }
|
Chris@0
|
207 }
|
Chris@0
|
208 if (isset($theme->info['engine'])) {
|
Chris@0
|
209 $theme->engine = $theme->info['engine'];
|
Chris@0
|
210 }
|
Chris@0
|
211 if (isset($theme->info['base theme'])) {
|
Chris@0
|
212 $theme->base_theme = $theme->info['base theme'];
|
Chris@0
|
213 }
|
Chris@0
|
214 $this->list[$theme->getName()] = $theme;
|
Chris@0
|
215 }
|
Chris@0
|
216
|
Chris@0
|
217 /**
|
Chris@0
|
218 * {@inheritdoc}
|
Chris@0
|
219 */
|
Chris@0
|
220 public function refreshInfo() {
|
Chris@0
|
221 $extension_config = $this->configFactory->get('core.extension');
|
Chris@0
|
222 $installed = $extension_config->get('theme');
|
Chris@0
|
223 // Only refresh the info if a theme has been installed. Modules are
|
Chris@0
|
224 // installed before themes by the installer and this method is called during
|
Chris@0
|
225 // module installation.
|
Chris@0
|
226 if (empty($installed) && empty($this->list)) {
|
Chris@0
|
227 return;
|
Chris@0
|
228 }
|
Chris@0
|
229
|
Chris@0
|
230 $this->reset();
|
Chris@0
|
231 // @todo Avoid re-scanning all themes by retaining the original (unaltered)
|
Chris@0
|
232 // theme info somewhere.
|
Chris@0
|
233 $list = $this->rebuildThemeData();
|
Chris@0
|
234 foreach ($list as $name => $theme) {
|
Chris@0
|
235 if (isset($installed[$name])) {
|
Chris@0
|
236 $this->addTheme($theme);
|
Chris@0
|
237 }
|
Chris@0
|
238 }
|
Chris@0
|
239 $this->state->set('system.theme.data', $this->list);
|
Chris@0
|
240 }
|
Chris@0
|
241
|
Chris@0
|
242 /**
|
Chris@0
|
243 * {@inheritdoc}
|
Chris@0
|
244 */
|
Chris@0
|
245 public function reset() {
|
Chris@0
|
246 $this->systemListReset();
|
Chris@0
|
247 $this->list = NULL;
|
Chris@0
|
248 }
|
Chris@0
|
249
|
Chris@0
|
250 /**
|
Chris@0
|
251 * {@inheritdoc}
|
Chris@0
|
252 */
|
Chris@0
|
253 public function rebuildThemeData() {
|
Chris@0
|
254 $listing = $this->getExtensionDiscovery();
|
Chris@0
|
255 $themes = $listing->scan('theme');
|
Chris@0
|
256 $engines = $listing->scan('theme_engine');
|
Chris@0
|
257 $extension_config = $this->configFactory->get('core.extension');
|
Chris@0
|
258 $installed = $extension_config->get('theme') ?: [];
|
Chris@0
|
259
|
Chris@0
|
260 // Set defaults for theme info.
|
Chris@0
|
261 $defaults = [
|
Chris@0
|
262 'engine' => 'twig',
|
Chris@0
|
263 'base theme' => 'stable',
|
Chris@0
|
264 'regions' => [
|
Chris@0
|
265 'sidebar_first' => 'Left sidebar',
|
Chris@0
|
266 'sidebar_second' => 'Right sidebar',
|
Chris@0
|
267 'content' => 'Content',
|
Chris@0
|
268 'header' => 'Header',
|
Chris@0
|
269 'primary_menu' => 'Primary menu',
|
Chris@0
|
270 'secondary_menu' => 'Secondary menu',
|
Chris@0
|
271 'footer' => 'Footer',
|
Chris@0
|
272 'highlighted' => 'Highlighted',
|
Chris@0
|
273 'help' => 'Help',
|
Chris@0
|
274 'page_top' => 'Page top',
|
Chris@0
|
275 'page_bottom' => 'Page bottom',
|
Chris@0
|
276 'breadcrumb' => 'Breadcrumb',
|
Chris@0
|
277 ],
|
Chris@0
|
278 'description' => '',
|
Chris@0
|
279 'features' => $this->defaultFeatures,
|
Chris@0
|
280 'screenshot' => 'screenshot.png',
|
Chris@0
|
281 'php' => DRUPAL_MINIMUM_PHP,
|
Chris@0
|
282 'libraries' => [],
|
Chris@0
|
283 ];
|
Chris@0
|
284
|
Chris@0
|
285 $sub_themes = [];
|
Chris@0
|
286 $files_theme = [];
|
Chris@0
|
287 $files_theme_engine = [];
|
Chris@0
|
288 // Read info files for each theme.
|
Chris@0
|
289 foreach ($themes as $key => $theme) {
|
Chris@0
|
290 // @todo Remove all code that relies on the $status property.
|
Chris@0
|
291 $theme->status = (int) isset($installed[$key]);
|
Chris@0
|
292
|
Chris@0
|
293 $theme->info = $this->infoParser->parse($theme->getPathname()) + $defaults;
|
Chris@0
|
294 // Remove the default Stable base theme when 'base theme: false' is set in
|
Chris@0
|
295 // a theme .info.yml file.
|
Chris@0
|
296 if ($theme->info['base theme'] === FALSE) {
|
Chris@0
|
297 unset($theme->info['base theme']);
|
Chris@0
|
298 }
|
Chris@0
|
299
|
Chris@0
|
300 // Add the info file modification time, so it becomes available for
|
Chris@0
|
301 // contributed modules to use for ordering theme lists.
|
Chris@0
|
302 $theme->info['mtime'] = $theme->getMTime();
|
Chris@0
|
303
|
Chris@0
|
304 // Invoke hook_system_info_alter() to give installed modules a chance to
|
Chris@0
|
305 // modify the data in the .info.yml files if necessary.
|
Chris@0
|
306 // @todo Remove $type argument, obsolete with $theme->getType().
|
Chris@0
|
307 $type = 'theme';
|
Chris@0
|
308 $this->moduleHandler->alter('system_info', $theme->info, $theme, $type);
|
Chris@0
|
309
|
Chris@0
|
310 if (!empty($theme->info['base theme'])) {
|
Chris@0
|
311 $sub_themes[] = $key;
|
Chris@0
|
312 // Add the base theme as a proper dependency.
|
Chris@0
|
313 $themes[$key]->info['dependencies'][] = $themes[$key]->info['base theme'];
|
Chris@0
|
314 }
|
Chris@0
|
315
|
Chris@0
|
316 // Defaults to 'twig' (see $defaults above).
|
Chris@0
|
317 $engine = $theme->info['engine'];
|
Chris@0
|
318 if (isset($engines[$engine])) {
|
Chris@0
|
319 $theme->owner = $engines[$engine]->getExtensionPathname();
|
Chris@0
|
320 $theme->prefix = $engines[$engine]->getName();
|
Chris@0
|
321 $files_theme_engine[$engine] = $engines[$engine]->getPathname();
|
Chris@0
|
322 }
|
Chris@0
|
323
|
Chris@0
|
324 // Prefix screenshot with theme path.
|
Chris@0
|
325 if (!empty($theme->info['screenshot'])) {
|
Chris@0
|
326 $theme->info['screenshot'] = $theme->getPath() . '/' . $theme->info['screenshot'];
|
Chris@0
|
327 }
|
Chris@0
|
328
|
Chris@0
|
329 $files_theme[$key] = $theme->getPathname();
|
Chris@0
|
330 }
|
Chris@0
|
331 // Build dependencies.
|
Chris@0
|
332 // @todo Move into a generic ExtensionHandler base class.
|
Chris@0
|
333 // @see https://www.drupal.org/node/2208429
|
Chris@0
|
334 $themes = $this->moduleHandler->buildModuleDependencies($themes);
|
Chris@0
|
335
|
Chris@0
|
336 // Store filenames to allow system_list() and drupal_get_filename() to
|
Chris@0
|
337 // retrieve them for themes and theme engines without having to scan the
|
Chris@0
|
338 // filesystem.
|
Chris@0
|
339 $this->state->set('system.theme.files', $files_theme);
|
Chris@0
|
340 $this->state->set('system.theme_engine.files', $files_theme_engine);
|
Chris@0
|
341
|
Chris@0
|
342 // After establishing the full list of available themes, fill in data for
|
Chris@0
|
343 // sub-themes.
|
Chris@0
|
344 foreach ($sub_themes as $key) {
|
Chris@0
|
345 $sub_theme = $themes[$key];
|
Chris@0
|
346 // The $base_themes property is optional; only set for sub themes.
|
Chris@0
|
347 // @see ThemeHandlerInterface::listInfo()
|
Chris@0
|
348 $sub_theme->base_themes = $this->getBaseThemes($themes, $key);
|
Chris@0
|
349 // empty() cannot be used here, since ThemeHandler::doGetBaseThemes() adds
|
Chris@0
|
350 // the key of a base theme with a value of NULL in case it is not found,
|
Chris@0
|
351 // in order to prevent needless iterations.
|
Chris@0
|
352 if (!current($sub_theme->base_themes)) {
|
Chris@0
|
353 continue;
|
Chris@0
|
354 }
|
Chris@0
|
355 // Determine the root base theme.
|
Chris@0
|
356 $root_key = key($sub_theme->base_themes);
|
Chris@0
|
357 // Build the list of sub-themes for each of the theme's base themes.
|
Chris@0
|
358 foreach (array_keys($sub_theme->base_themes) as $base_theme) {
|
Chris@0
|
359 $themes[$base_theme]->sub_themes[$key] = $sub_theme->info['name'];
|
Chris@0
|
360 }
|
Chris@0
|
361 // Add the theme engine info from the root base theme.
|
Chris@0
|
362 if (isset($themes[$root_key]->owner)) {
|
Chris@0
|
363 $sub_theme->info['engine'] = $themes[$root_key]->info['engine'];
|
Chris@0
|
364 $sub_theme->owner = $themes[$root_key]->owner;
|
Chris@0
|
365 $sub_theme->prefix = $themes[$root_key]->prefix;
|
Chris@0
|
366 }
|
Chris@0
|
367 }
|
Chris@0
|
368
|
Chris@0
|
369 return $themes;
|
Chris@0
|
370 }
|
Chris@0
|
371
|
Chris@0
|
372 /**
|
Chris@0
|
373 * {@inheritdoc}
|
Chris@0
|
374 */
|
Chris@0
|
375 public function getBaseThemes(array $themes, $theme) {
|
Chris@0
|
376 return $this->doGetBaseThemes($themes, $theme);
|
Chris@0
|
377 }
|
Chris@0
|
378
|
Chris@0
|
379 /**
|
Chris@0
|
380 * Finds the base themes for the specific theme.
|
Chris@0
|
381 *
|
Chris@0
|
382 * @param array $themes
|
Chris@0
|
383 * An array of available themes.
|
Chris@0
|
384 * @param string $theme
|
Chris@0
|
385 * The name of the theme whose base we are looking for.
|
Chris@0
|
386 * @param array $used_themes
|
Chris@0
|
387 * (optional) A recursion parameter preventing endless loops. Defaults to
|
Chris@0
|
388 * an empty array.
|
Chris@0
|
389 *
|
Chris@0
|
390 * @return array
|
Chris@0
|
391 * An array of base themes.
|
Chris@0
|
392 */
|
Chris@0
|
393 protected function doGetBaseThemes(array $themes, $theme, $used_themes = []) {
|
Chris@0
|
394 if (!isset($themes[$theme]->info['base theme'])) {
|
Chris@0
|
395 return [];
|
Chris@0
|
396 }
|
Chris@0
|
397
|
Chris@0
|
398 $base_key = $themes[$theme]->info['base theme'];
|
Chris@0
|
399 // Does the base theme exist?
|
Chris@0
|
400 if (!isset($themes[$base_key])) {
|
Chris@0
|
401 return [$base_key => NULL];
|
Chris@0
|
402 }
|
Chris@0
|
403
|
Chris@0
|
404 $current_base_theme = [$base_key => $themes[$base_key]->info['name']];
|
Chris@0
|
405
|
Chris@0
|
406 // Is the base theme itself a child of another theme?
|
Chris@0
|
407 if (isset($themes[$base_key]->info['base theme'])) {
|
Chris@0
|
408 // Do we already know the base themes of this theme?
|
Chris@0
|
409 if (isset($themes[$base_key]->base_themes)) {
|
Chris@0
|
410 return $themes[$base_key]->base_themes + $current_base_theme;
|
Chris@0
|
411 }
|
Chris@0
|
412 // Prevent loops.
|
Chris@0
|
413 if (!empty($used_themes[$base_key])) {
|
Chris@0
|
414 return [$base_key => NULL];
|
Chris@0
|
415 }
|
Chris@0
|
416 $used_themes[$base_key] = TRUE;
|
Chris@0
|
417 return $this->doGetBaseThemes($themes, $base_key, $used_themes) + $current_base_theme;
|
Chris@0
|
418 }
|
Chris@0
|
419 // If we get here, then this is our parent theme.
|
Chris@0
|
420 return $current_base_theme;
|
Chris@0
|
421 }
|
Chris@0
|
422
|
Chris@0
|
423 /**
|
Chris@0
|
424 * Returns an extension discovery object.
|
Chris@0
|
425 *
|
Chris@0
|
426 * @return \Drupal\Core\Extension\ExtensionDiscovery
|
Chris@0
|
427 * The extension discovery object.
|
Chris@0
|
428 */
|
Chris@0
|
429 protected function getExtensionDiscovery() {
|
Chris@0
|
430 if (!isset($this->extensionDiscovery)) {
|
Chris@0
|
431 $this->extensionDiscovery = new ExtensionDiscovery($this->root);
|
Chris@0
|
432 }
|
Chris@0
|
433 return $this->extensionDiscovery;
|
Chris@0
|
434 }
|
Chris@0
|
435
|
Chris@0
|
436 /**
|
Chris@0
|
437 * {@inheritdoc}
|
Chris@0
|
438 */
|
Chris@0
|
439 public function getName($theme) {
|
Chris@0
|
440 $themes = $this->listInfo();
|
Chris@0
|
441 if (!isset($themes[$theme])) {
|
Chris@17
|
442 throw new UnknownExtensionException("Requested the name of a non-existing theme $theme");
|
Chris@0
|
443 }
|
Chris@0
|
444 return $themes[$theme]->info['name'];
|
Chris@0
|
445 }
|
Chris@0
|
446
|
Chris@0
|
447 /**
|
Chris@0
|
448 * Wraps system_list_reset().
|
Chris@0
|
449 */
|
Chris@0
|
450 protected function systemListReset() {
|
Chris@0
|
451 system_list_reset();
|
Chris@0
|
452 }
|
Chris@0
|
453
|
Chris@0
|
454 /**
|
Chris@0
|
455 * Wraps system_list().
|
Chris@0
|
456 *
|
Chris@0
|
457 * @return array
|
Chris@0
|
458 * A list of themes keyed by name.
|
Chris@0
|
459 */
|
Chris@0
|
460 protected function systemThemeList() {
|
Chris@0
|
461 return system_list('theme');
|
Chris@0
|
462 }
|
Chris@0
|
463
|
Chris@0
|
464 /**
|
Chris@0
|
465 * {@inheritdoc}
|
Chris@0
|
466 */
|
Chris@0
|
467 public function getThemeDirectories() {
|
Chris@0
|
468 $dirs = [];
|
Chris@0
|
469 foreach ($this->listInfo() as $name => $theme) {
|
Chris@0
|
470 $dirs[$name] = $this->root . '/' . $theme->getPath();
|
Chris@0
|
471 }
|
Chris@0
|
472 return $dirs;
|
Chris@0
|
473 }
|
Chris@0
|
474
|
Chris@0
|
475 /**
|
Chris@0
|
476 * {@inheritdoc}
|
Chris@0
|
477 */
|
Chris@0
|
478 public function themeExists($theme) {
|
Chris@0
|
479 $themes = $this->listInfo();
|
Chris@0
|
480 return isset($themes[$theme]);
|
Chris@0
|
481 }
|
Chris@0
|
482
|
Chris@0
|
483 /**
|
Chris@0
|
484 * {@inheritdoc}
|
Chris@0
|
485 */
|
Chris@0
|
486 public function getTheme($name) {
|
Chris@0
|
487 $themes = $this->listInfo();
|
Chris@0
|
488 if (isset($themes[$name])) {
|
Chris@0
|
489 return $themes[$name];
|
Chris@0
|
490 }
|
Chris@17
|
491 throw new UnknownExtensionException(sprintf('The theme %s does not exist.', $name));
|
Chris@0
|
492 }
|
Chris@0
|
493
|
Chris@0
|
494 /**
|
Chris@0
|
495 * {@inheritdoc}
|
Chris@0
|
496 */
|
Chris@0
|
497 public function hasUi($name) {
|
Chris@0
|
498 $themes = $this->listInfo();
|
Chris@0
|
499 if (isset($themes[$name])) {
|
Chris@0
|
500 if (!empty($themes[$name]->info['hidden'])) {
|
Chris@0
|
501 $theme_config = $this->configFactory->get('system.theme');
|
Chris@0
|
502 return $name == $theme_config->get('default') || $name == $theme_config->get('admin');
|
Chris@0
|
503 }
|
Chris@0
|
504 return TRUE;
|
Chris@0
|
505 }
|
Chris@0
|
506 return FALSE;
|
Chris@0
|
507 }
|
Chris@0
|
508
|
Chris@0
|
509 }
|