/** * {@inheritdoc} */ public function alter(&$cache, &$context1 = NULL, &$context2 = NULL) { // Sort the registry alphabetically (for easier debugging). ksort($cache); // Ensure paths to templates are set properly. This allows templates to // be moved around in a theme without having to constantly ensuring that // the theme's hook_theme() definitions have the correct static "path" set. foreach ($this->currentTheme->getAncestry() as $ancestor) { $current_theme = $ancestor->getName() === $this->currentTheme->getName(); $theme_path = $ancestor->getPath(); foreach ($ancestor->fileScan('/\\.html\\.twig$/', 'templates') as $file) { $hook = str_replace('-', '_', str_replace('.html.twig', '', $file->filename)); $path = dirname($file->uri); $incomplete = !isset($cache[$hook]) || strrpos($hook, '__'); if (!isset($cache[$hook])) { $cache[$hook] = []; } $cache[$hook]['path'] = $path; $cache[$hook]['type'] = $current_theme ? 'theme' : 'base_theme'; $cache[$hook]['theme path'] = $theme_path; if ($incomplete) { $cache[$hook]['incomplete preprocess functions'] = TRUE; } } } // Discover all the theme's preprocess plugins. $preprocess_manager = new PreprocessManager($this->currentTheme); $plugins = $preprocess_manager->getDefinitions(); ksort($plugins, SORT_NATURAL); // Iterate over the preprocess plugins. foreach ($plugins as $plugin_id => $definition) { $incomplete = !isset($cache[$plugin_id]) || strrpos($plugin_id, '__'); if (!isset($cache[$plugin_id])) { $cache[$plugin_id] = []; } array_walk($cache, function (&$info, $hook) use($plugin_id, $definition) { if ($hook === $plugin_id || strpos($hook, $plugin_id . '__') === 0) { if (!isset($info['preprocess functions'])) { $info['preprocess functions'] = []; } // Due to a limitation in \Drupal\Core\Theme\ThemeManager::render, // callbacks must be functions and not classes. We always specify // "materialize_preprocess" here and then assign the plugin ID to a // separate property that we can later intercept and properly invoke. // @todo Revisit if/when preprocess callbacks can be any callable. Materialize::addCallback($info['preprocess functions'], 'materialize_preprocess', $definition['replace'], $definition['action']); $info['preprocess functions'] = array_unique($info['preprocess functions']); $info['materialize preprocess'] = $plugin_id; } }); if ($incomplete) { $cache[$plugin_id]['incomplete preprocess functions'] = TRUE; } } // Allow core to post process. $this->postProcessExtension($cache, $this->theme); }
/** * Creates the discovery object. * * @param \Drupal\materialize\Theme $theme * The theme to use for discovery. * @param string|bool $subdir * The plugin's subdirectory, for example Plugin/views/filter. * @param string|null $plugin_interface * (optional) The interface each plugin should implement. * @param string $plugin_definition_annotation_name * (optional) Name of the annotation that contains the plugin definition. * Defaults to 'Drupal\Component\Annotation\Plugin'. */ public function __construct(Theme $theme, $subdir, $plugin_interface = NULL, $plugin_definition_annotation_name = 'Drupal\\Component\\Annotation\\Plugin') { // Get the active theme. $this->theme = $theme; // Determine the namespaces to search for. $namespaces = []; foreach ($theme->getAncestry() as $ancestor) { $namespaces['Drupal\\' . $ancestor->getName()] = [DRUPAL_ROOT . '/' . $ancestor->getPath() . '/src']; } $this->namespaces = new \ArrayObject($namespaces); $this->subdir = $subdir; $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name; $this->pluginInterface = $plugin_interface; $this->themeHandler = \Drupal::service('theme_handler'); $this->themeManager = \Drupal::service('theme.manager'); }
/** * {@inheritdoc} */ public function save($has_trusted_data = FALSE) { parent::save($has_trusted_data); $this->theme->getCache('settings')->deleteAll(); return $this; }
/** * Retrieves a specific theme's stored config settings. * * @param \Drupal\materialize\Theme $theme * A theme object. * @param bool $active_theme * Flag indicating whether or not $theme is the active theme. * * @return array * A array diff of overridden config theme settings. */ public function getThemeConfig(Theme $theme, $active_theme = FALSE) { $config = new \Drupal\Core\Theme\ThemeSettings($theme->getName()); // Retrieve configured theme-specific settings, if any. try { if ($theme_settings = \Drupal::config($theme->getName() . '.settings')->get()) { // Remove the schema version if not the active theme. if (!$active_theme) { unset($theme_settings['schema']); } $config->merge($theme_settings); } } catch (StorageException $e) { } // If the theme does not support a particular feature, override the // global setting and set the value to NULL. $info = $theme->getInfo(); if (!empty($info['features'])) { foreach (_system_default_theme_features() as $feature) { if (!in_array($feature, $info['features'])) { $config->set('features.' . $feature, NULL); } } } // Generate the path to the logo image. if ($config->get('features.logo')) { $logo_url = FALSE; foreach (['svg', 'png', 'jpg'] as $type) { if (file_exists($theme->getPath() . "/logo.{$type}")) { $logo_url = file_create_url($theme->getPath() . "/logo.{$type}"); break; } } if ($config->get('logo.use_default') && $logo_url) { $config->set('logo.url', $logo_url); } elseif (($logo_path = $config->get('logo.path')) && file_exists($logo_path)) { $config->set('logo.url', file_create_url($logo_path)); } } // Generate the path to the favicon. if ($config->get('features.favicon')) { $favicon_url = $theme->getPath() . '/favicon.ico'; if ($config->get('favicon.use_default') && file_exists($favicon_url)) { $config->set('favicon.url', file_create_url($favicon_url)); } elseif ($favicon_path = $config->get('favicon.path')) { $config->set('favicon.url', file_create_url($favicon_path)); } } // Retrieve the config data. $data = $config->get(); // Retrieve a diff of settings that override the defaults. $diff = DiffArray::diffAssocRecursive($data, $this->defaults); // Ensure core features are always present in the diff. The theme settings // form will not work properly otherwise. // @todo Just rebuild the features section of the form? foreach (['favicon', 'features', 'logo'] as $key) { $arrays = []; $arrays[] = isset($this->defaults[$key]) ? $this->defaults[$key] : []; $arrays[] = isset($data[$key]) ? $data[$key] : []; $diff[$key] = NestedArray::mergeDeepArray($arrays, TRUE); } return $diff; }