Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 public function getVisibleBlocksPerRegion(array &$cacheable_metadata = [])
 {
     $active_theme = $this->themeManager->getActiveTheme();
     // Build an array of the region names in the right order.
     $empty = array_fill_keys($active_theme->getRegions(), array());
     $full = array();
     foreach ($this->blockStorage->loadByProperties(array('theme' => $active_theme->getName())) as $block_id => $block) {
         /** @var \Drupal\block\BlockInterface $block */
         $access = $block->access('view', NULL, TRUE);
         $region = $block->getRegion();
         if (!isset($cacheable_metadata[$region])) {
             $cacheable_metadata[$region] = CacheableMetadata::createFromObject($access);
         } else {
             $cacheable_metadata[$region] = $cacheable_metadata[$region]->merge(CacheableMetadata::createFromObject($access));
         }
         // Set the contexts on the block before checking access.
         if ($access->isAllowed()) {
             $full[$region][$block_id] = $block;
         }
     }
     // Merge it with the actual values to maintain the region ordering.
     $assignments = array_intersect_key(array_merge($empty, $full), $empty);
     foreach ($assignments as &$assignment) {
         // Suppress errors because PHPUnit will indirectly modify the contents,
         // triggering https://bugs.php.net/bug.php?id=50688.
         @uasort($assignment, 'Drupal\\block\\Entity\\Block::sort');
     }
     return $assignments;
 }
 /**
  * {@inheritdoc}
  */
 protected function getCid()
 {
     if (!isset($this->cid)) {
         $this->cid = 'library_info:' . $this->themeManager->getActiveTheme()->getName();
     }
     return $this->cid;
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 public function collect(Request $request, Response $response, \Exception $exception = NULL)
 {
     $activeTheme = $this->themeManager->getActiveTheme();
     $this->data['activeTheme'] = ['name' => $activeTheme->getName(), 'path' => $activeTheme->getPath(), 'engine' => $activeTheme->getEngine(), 'owner' => $activeTheme->getOwner(), 'baseThemes' => $activeTheme->getBaseThemes(), 'extension' => $activeTheme->getExtension(), 'styleSheetsRemove' => $activeTheme->getStyleSheetsRemove(), 'libraries' => $activeTheme->getLibraries(), 'regions' => $activeTheme->getRegions()];
     if ($this->themeNegotiator instanceof ThemeNegotiatorWrapper) {
         $this->data['negotiator'] = ['class' => $this->getMethodData($this->themeNegotiator->getNegotiator(), 'determineActiveTheme'), 'id' => $this->themeNegotiator->getNegotiator()->_serviceId];
     }
 }
Esempio n. 4
0
 /**
  * Tests opting out of Stable by setting the base theme to false.
  */
 public function testWildWest()
 {
     $this->themeHandler->install(['test_wild_west']);
     $this->config('system.theme')->set('default', 'test_wild_west')->save();
     $theme = $this->themeManager->getActiveTheme();
     /** @var \Drupal\Core\Theme\ActiveTheme $base_theme */
     $base_themes = $theme->getBaseThemes();
     $this->assertTrue(empty($base_themes), 'No base theme is set when a theme has opted out of using Stable.');
 }
Esempio n. 5
0
 /**
  * {@inheritdoc}
  */
 public function getInfo($type)
 {
     $theme_name = $this->themeManager->getActiveTheme()->getName();
     if (!isset($this->elementInfo[$theme_name])) {
         $this->elementInfo[$theme_name] = $this->buildInfo($theme_name);
     }
     $info = isset($this->elementInfo[$theme_name][$type]) ? $this->elementInfo[$theme_name][$type] : array();
     $info['#defaults_loaded'] = TRUE;
     return $info;
 }
 /**
  * Tests that changes to the info file are picked up.
  */
 public function testChanges()
 {
     $this->themeHandler->install(array('test_theme'));
     $this->themeHandler->setDefault('test_theme');
     $this->themeManager->resetActiveTheme();
     $active_theme = $this->themeManager->getActiveTheme();
     // Make sure we are not testing the wrong theme.
     $this->assertEqual('test_theme', $active_theme->getName());
     $this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling'], $active_theme->getLibraries());
     // @see theme_test_system_info_alter()
     $this->state->set('theme_test.modify_info_files', TRUE);
     drupal_flush_all_caches();
     $active_theme = $this->themeManager->getActiveTheme();
     $this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries());
 }
Esempio n. 7
0
 /**
  * {@inheritdoc}
  */
 public function evaluate()
 {
     if (!$this->configuration['theme']) {
         return TRUE;
     }
     return $this->themeManager->getActiveTheme()->getName() == $this->configuration['theme'];
 }
 /**
  * Gets the name of the theme used for this block listing.
  *
  * @return string
  *   The name of the theme.
  */
 protected function getThemeName()
 {
     // If no theme was specified, use the current theme.
     if (!$this->theme) {
         $this->theme = $this->themeManager->getActiveTheme()->getName();
     }
     return $this->theme;
 }
Esempio n. 9
0
 /**
  * Page callback: Tests the theme negotiation functionality.
  *
  * @param bool $inherited
  *   TRUE when the requested page is intended to inherit
  *   the theme of its parent.
  *
  * @return string
  *   A string describing the requested custom theme and actual
  *   theme being used
  *   for the current page request.
  */
 public function themePage($inherited)
 {
     $theme_key = $this->themeManager->getActiveTheme()->getName();
     // Now we check what the theme negotiator service returns.
     $active_theme = $this->themeNegotiator->determineActiveTheme($this->routeMatch);
     $output = "Active theme: {$active_theme}. Actual theme: {$theme_key}.";
     if ($inherited) {
         $output .= ' Theme negotiation inheritance is being tested.';
     }
     return ['#markup' => $output];
 }
Esempio n. 10
0
 /**
  * {@inheritdoc}
  */
 public function build()
 {
     $build = parent::build();
     $active_theme = $this->themeManager->getActiveTheme();
     $theme_name = $active_theme->getName();
     $destination = $this->redirectDestination->get();
     $visible_regions = $this->getVisibleRegionNames($theme_name);
     // Build an array of the region names in the right order.
     $build += array_fill_keys(array_keys($visible_regions), []);
     foreach ($visible_regions as $region => $region_name) {
         $query = ['region' => $region];
         if ($destination) {
             $query['destination'] = $destination;
         }
         $title = $this->t('<span class="visually-hidden">Place block in the %region region</span>', ['%region' => $region_name]);
         $operations['block_description'] = ['#type' => 'inline_template', '#template' => '<div class="block-place-region">{{ link }}</div>', '#context' => ['link' => Link::createFromRoute($title, 'block.admin_library', ['theme' => $theme_name], ['query' => $query, 'attributes' => ['title' => $title, 'class' => ['use-ajax', 'button', 'button--small'], 'data-dialog-type' => 'modal', 'data-dialog-options' => Json::encode(['width' => 700])]])]];
         $build[$region] = ['block_place_operations' => $operations] + $build[$region];
     }
     $build['#attached']['library'][] = 'block_place/drupal.block_place';
     return $build;
 }
Esempio n. 11
0
 /**
  * Apply libraries overrides specified for the current active theme.
  *
  * @param array $libraries
  *   The libraries definitions.
  * @param string $extension
  *   The extension in which these libraries are defined.
  *
  * @return array
  *   The modified libraries definitions.
  */
 protected function applyLibrariesOverride($libraries, $extension)
 {
     $active_theme = $this->themeManager->getActiveTheme();
     // ActiveTheme::getLibrariesOverride() returns libraries-overrides for the
     // current theme as well as all its base themes.
     $all_libraries_overrides = $active_theme->getLibrariesOverride();
     foreach ($all_libraries_overrides as $theme_path => $libraries_overrides) {
         foreach ($libraries as $library_name => $library) {
             // Process libraries overrides.
             if (isset($libraries_overrides["{$extension}/{$library_name}"])) {
                 // Active theme defines an override for this library.
                 $override_definition = $libraries_overrides["{$extension}/{$library_name}"];
                 if (is_string($override_definition) || $override_definition === FALSE) {
                     // A string or boolean definition implies an override (or removal)
                     // for the whole library. Use the override key to specify that this
                     // library will be overridden when it is called.
                     // @see \Drupal\Core\Asset\LibraryDiscovery::getLibraryByName()
                     if ($override_definition) {
                         $libraries[$library_name]['override'] = $override_definition;
                     } else {
                         $libraries[$library_name]['override'] = FALSE;
                     }
                 } elseif (is_array($override_definition)) {
                     // An array definition implies an override for an asset within this
                     // library.
                     foreach ($override_definition as $sub_key => $value) {
                         // Throw an exception if the asset is not properly specified.
                         if (!is_array($value)) {
                             throw new InvalidLibrariesOverrideSpecificationException(sprintf('Library asset %s is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".', "{$extension}/{$library_name}/{$sub_key}"));
                         }
                         if ($sub_key === 'drupalSettings') {
                             // drupalSettings may not be overridden.
                             throw new InvalidLibrariesOverrideSpecificationException(sprintf('drupalSettings may not be overridden in libraries-override. Trying to override %s. Use hook_library_info_alter() instead.', "{$extension}/{$library_name}/{$sub_key}"));
                         } elseif ($sub_key === 'css') {
                             // SMACSS category should be incorporated into the asset name.
                             foreach ($value as $category => $overrides) {
                                 $this->setOverrideValue($libraries[$library_name], [$sub_key, $category], $overrides, $theme_path);
                             }
                         } else {
                             $this->setOverrideValue($libraries[$library_name], [$sub_key], $value, $theme_path);
                         }
                     }
                 }
             }
         }
     }
     return $libraries;
 }
Esempio n. 12
0
 /**
  * {@inheritdoc}
  */
 public function getCssAssets(AttachedAssetsInterface $assets, $optimize)
 {
     $theme_info = $this->themeManager->getActiveTheme();
     $css = [];
     $default_options = ['type' => 'file', 'group' => CSS_AGGREGATE_DEFAULT, 'weight' => 0, 'every_page' => FALSE, 'media' => 'all', 'preprocess' => TRUE, 'browsers' => []];
     foreach ($this->getLibrariesToLoad($assets) as $library) {
         list($extension, $name) = explode('/', $library, 2);
         $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
         if (isset($definition['css'])) {
             foreach ($definition['css'] as $options) {
                 $options += $default_options;
                 $options['browsers'] += ['IE' => TRUE, '!IE' => TRUE];
                 // Files with a query string cannot be preprocessed.
                 if ($options['type'] === 'file' && $options['preprocess'] && strpos($options['data'], '?') !== FALSE) {
                     $options['preprocess'] = FALSE;
                 }
                 // Always add a tiny value to the weight, to conserve the insertion
                 // order.
                 $options['weight'] += count($css) / 1000;
                 // CSS files are being keyed by the full path.
                 $css[$options['data']] = $options;
             }
         }
     }
     // Allow modules and themes to alter the CSS assets.
     $this->moduleHandler->alter('css', $css, $assets);
     $this->themeManager->alter('css', $css, $assets);
     // Sort CSS items, so that they appear in the correct order.
     uasort($css, 'static::sort');
     // Allow themes to remove CSS files by CSS files full path and file name.
     if ($stylesheet_remove = $theme_info->getStyleSheetsRemove()) {
         foreach ($css as $key => $options) {
             if (isset($stylesheet_remove[$key])) {
                 unset($css[$key]);
             }
         }
     }
     if ($optimize) {
         $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css);
     }
     return $css;
 }
 /**
  * Applies the libraries-extend specified by the active theme.
  *
  * This extends the library definitions with the those specified by the
  * libraries-extend specifications for the active theme.
  *
  * @param string $extension
  *   The name of the extension for which library definitions will be extended.
  * @param string $library_name
  *   The name of the library whose definitions is to be extended.
  * @param $library_definition
  *   The library definition to be extended.
  *
  * @return array
  *   The library definition extended as specified by libraries-extend.
  *
  * @throws \Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException
  */
 protected function applyLibrariesExtend($extension, $library_name, $library_definition)
 {
     $libraries_extend = $this->themeManager->getActiveTheme()->getLibrariesExtend();
     if (!empty($libraries_extend["{$extension}/{$library_name}"])) {
         foreach ($libraries_extend["{$extension}/{$library_name}"] as $library_extend_name) {
             if (!is_string($library_extend_name)) {
                 // Only string library names are allowed.
                 throw new InvalidLibrariesExtendSpecificationException('The libraries-extend specification for each library must be a list of strings.');
             }
             list($new_extension, $new_library_name) = explode('/', $library_extend_name, 2);
             $new_libraries = $this->get($new_extension);
             if (isset($new_libraries[$new_library_name])) {
                 $library_definition = NestedArray::mergeDeep($library_definition, $new_libraries[$new_library_name]);
             } else {
                 throw new InvalidLibrariesExtendSpecificationException(sprintf('The specified library "%s" does not exist.', $library_extend_name));
             }
         }
     }
     return $library_definition;
 }
 /**
  * Retrieves the key of the theme used to render the emails.
  */
 public function getMailTheme()
 {
     $theme = $this->mailsystemConfig->get('theme');
     switch ($theme) {
         case 'default':
             $theme = $this->configFactory->get('system.theme')->get('default');
             break;
         case 'current':
             $theme = $this->themeManager->getActiveTheme()->getName();
             break;
         case 'domain':
             // Fetch the theme for the current domain.
             // @todo: Reimplement this as soon as module port or similar module is around.
             if (FALSE && \Drupal::moduleHandler()->moduleExists('domain_theme')) {
                 // Assign the selected theme, based on the active domain.
                 global $_domain;
                 $domain_theme = domain_theme_lookup($_domain['domain_id']);
                 // The above returns -1 on failure.
                 $theme = $domain_theme != -1 ? $domain_theme['theme'] : $this->themeManager->getActiveTheme()->getName();
             }
             break;
     }
     return $theme;
 }
Esempio n. 15
0
 /**
  * Gets the current theme for this page.
  *
  * @return string
  *   The current theme.
  */
 protected function getTheme()
 {
     return $this->themeManager->getActiveTheme()->getName();
 }
Esempio n. 16
0
 /**
  * {@inheritdoc}
  */
 public function getContext()
 {
     return $this->themeManager->getActiveTheme()->getName() ?: 'stark';
 }
 /**
  * {@inheritdoc}
  */
 public function getJsAssets(AttachedAssetsInterface $assets, $optimize)
 {
     $theme_info = $this->themeManager->getActiveTheme();
     // Add the theme name to the cache key since themes may implement
     // hook_library_info_alter(). Additionally add the current language to
     // support translation of JavaScript files via hook_js_alter().
     $libraries_to_load = $this->getLibrariesToLoad($assets);
     $cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
     if ($cached = $this->cache->get($cid)) {
         list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;
     } else {
         $javascript = [];
         $default_options = ['type' => 'file', 'group' => JS_DEFAULT, 'weight' => 0, 'cache' => TRUE, 'preprocess' => TRUE, 'attributes' => [], 'version' => NULL, 'browsers' => []];
         // Collect all libraries that contain JS assets and are in the header.
         $header_js_libraries = [];
         foreach ($libraries_to_load as $library) {
             list($extension, $name) = explode('/', $library, 2);
             $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
             if (isset($definition['js']) && !empty($definition['header'])) {
                 $header_js_libraries[] = $library;
             }
         }
         // The current list of header JS libraries are only those libraries that
         // are in the header, but their dependencies must also be loaded for them
         // to function correctly, so update the list with those.
         $header_js_libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($header_js_libraries);
         foreach ($libraries_to_load as $library) {
             list($extension, $name) = explode('/', $library, 2);
             $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
             if (isset($definition['js'])) {
                 foreach ($definition['js'] as $options) {
                     $options += $default_options;
                     // 'scope' is a calculated option, based on which libraries are
                     // marked to be loaded from the header (see above).
                     $options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer';
                     // Preprocess can only be set if caching is enabled and no
                     // attributes are set.
                     $options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE;
                     // Always add a tiny value to the weight, to conserve the insertion
                     // order.
                     $options['weight'] += count($javascript) / 1000;
                     // Local and external files must keep their name as the associative
                     // key so the same JavaScript file is not added twice.
                     $javascript[$options['data']] = $options;
                 }
             }
         }
         // Allow modules and themes to alter the JavaScript assets.
         $this->moduleHandler->alter('js', $javascript, $assets);
         $this->themeManager->alter('js', $javascript, $assets);
         // Sort JavaScript assets, so that they appear in the correct order.
         uasort($javascript, 'static::sort');
         // Prepare the return value: filter JavaScript assets per scope.
         $js_assets_header = [];
         $js_assets_footer = [];
         foreach ($javascript as $key => $item) {
             if ($item['scope'] == 'header') {
                 $js_assets_header[$key] = $item;
             } elseif ($item['scope'] == 'footer') {
                 $js_assets_footer[$key] = $item;
             }
         }
         if ($optimize) {
             $collection_optimizer = \Drupal::service('asset.js.collection_optimizer');
             $js_assets_header = $collection_optimizer->optimize($js_assets_header);
             $js_assets_footer = $collection_optimizer->optimize($js_assets_footer);
         }
         // If the core/drupalSettings library is being loaded or is already
         // loaded, get the JavaScript settings assets, and convert them into a
         // single "regular" JavaScript asset.
         $libraries_to_load = $this->getLibrariesToLoad($assets);
         $settings_required = in_array('core/drupalSettings', $libraries_to_load) || in_array('core/drupalSettings', $this->libraryDependencyResolver->getLibrariesWithDependencies($assets->getAlreadyLoadedLibraries()));
         $settings_have_changed = count($libraries_to_load) > 0 || count($assets->getSettings()) > 0;
         // Initialize settings to FALSE since they are not needed by default. This
         // distinguishes between an empty array which must still allow
         // hook_js_settings_alter() to be run.
         $settings = FALSE;
         if ($settings_required && $settings_have_changed) {
             $settings = $this->getJsSettingsAssets($assets);
             // Allow modules to add cached JavaScript settings.
             foreach ($this->moduleHandler->getImplementations('js_settings_build') as $module) {
                 $function = $module . '_' . 'js_settings_build';
                 $function($settings, $assets);
             }
         }
         $settings_in_header = in_array('core/drupalSettings', $header_js_libraries);
         $this->cache->set($cid, [$js_assets_header, $js_assets_footer, $settings, $settings_in_header], CacheBackendInterface::CACHE_PERMANENT, ['library_info']);
     }
     if ($settings !== FALSE) {
         // Attached settings override both library definitions and
         // hook_js_settings_build().
         $settings = NestedArray::mergeDeepArray([$settings, $assets->getSettings()], TRUE);
         // Allow modules and themes to alter the JavaScript settings.
         $this->moduleHandler->alter('js_settings', $settings, $assets);
         $this->themeManager->alter('js_settings', $settings, $assets);
         // Update the $assets object accordingly, so that it reflects the final
         // settings.
         $assets->setSettings($settings);
         $settings_as_inline_javascript = ['type' => 'setting', 'group' => JS_SETTING, 'weight' => 0, 'browsers' => [], 'data' => $settings];
         $settings_js_asset = ['drupalSettings' => $settings_as_inline_javascript];
         // Prepend to the list of JS assets, to render it first. Preferably in
         // the footer, but in the header if necessary.
         if ($settings_in_header) {
             $js_assets_header = $settings_js_asset + $js_assets_header;
         } else {
             $js_assets_footer = $settings_js_asset + $js_assets_footer;
         }
     }
     return [$js_assets_header, $js_assets_footer];
 }
Esempio n. 18
0
 /**
  * Gets the path of the active theme.
  *
  * @return string
  *   The path to the active theme.
  */
 public function getActiveThemePath()
 {
     return $this->themeManager->getActiveTheme()->getPath();
 }
Esempio n. 19
0
 /**
  * Initializes a theme with a certain name.
  *
  * This function does to much magic, so it should be replaced by another
  * services which holds the current active theme information.
  *
  * @param string $theme_name
  *   (optional) The name of the theme for which to construct the registry.
  */
 protected function init($theme_name = NULL)
 {
     if ($this->initialized) {
         return;
     }
     // Unless instantiated for a specific theme, use globals.
     if (!isset($theme_name)) {
         $this->theme = $this->themeManager->getActiveTheme();
     } else {
         $this->theme = $this->themeInitialization->getActiveThemeByName($theme_name);
         $this->themeInitialization->loadActiveTheme($this->theme);
     }
 }
Esempio n. 20
0
 /**
  * {@inheritdoc}
  */
 public function getCssAssets(AttachedAssetsInterface $assets, $optimize)
 {
     $theme_info = $this->themeManager->getActiveTheme();
     $css = [];
     foreach ($this->getLibrariesToLoad($assets) as $library) {
         list($extension, $name) = explode('/', $library, 2);
         $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
         if (isset($definition['css'])) {
             foreach ($definition['css'] as $options) {
                 $options += array('type' => 'file', 'group' => CSS_AGGREGATE_DEFAULT, 'weight' => 0, 'every_page' => FALSE, 'media' => 'all', 'preprocess' => TRUE, 'browsers' => array());
                 $options['browsers'] += array('IE' => TRUE, '!IE' => TRUE);
                 // Files with a query string cannot be preprocessed.
                 if ($options['type'] === 'file' && $options['preprocess'] && strpos($options['data'], '?') !== FALSE) {
                     $options['preprocess'] = FALSE;
                 }
                 // Always add a tiny value to the weight, to conserve the insertion
                 // order.
                 $options['weight'] += count($css) / 1000;
                 // Add the data to the CSS array depending on the type.
                 switch ($options['type']) {
                     case 'file':
                         // Local CSS files are keyed by basename; if a file with the same
                         // basename is added more than once, it gets overridden.
                         // By default, take over the filename as basename.
                         if (!isset($options['basename'])) {
                             $options['basename'] = drupal_basename($options['data']);
                         }
                         $css[$options['basename']] = $options;
                         break;
                     default:
                         // External files are keyed by their full URI, so the same CSS
                         // file is not added twice.
                         $css[$options['data']] = $options;
                 }
             }
         }
     }
     // Allow modules and themes to alter the CSS assets.
     $this->moduleHandler->alter('css', $css, $assets);
     $this->themeManager->alter('css', $css, $assets);
     // Sort CSS items, so that they appear in the correct order.
     uasort($css, 'static::sort');
     // Allow themes to remove CSS files by basename.
     if ($stylesheet_remove = $theme_info->getStyleSheetsRemove()) {
         foreach ($css as $key => $options) {
             if (isset($options['basename']) && isset($stylesheet_remove[$options['basename']])) {
                 unset($css[$key]);
             }
         }
     }
     // Allow themes to conditionally override CSS files by basename.
     if ($stylesheet_override = $theme_info->getStyleSheetsOverride()) {
         foreach ($css as $key => $options) {
             if (isset($options['basename']) && isset($stylesheet_override[$options['basename']])) {
                 $css[$key]['data'] = $stylesheet_override[$options['basename']];
             }
         }
     }
     if ($optimize) {
         $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css);
     }
     return $css;
 }