Unverified Commit be276ecb authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3035288 by andypost, berdir, markhalliwell, alexpott, acbramley,...

Issue #3035288 by andypost, berdir, markhalliwell, alexpott, acbramley, nicxvan, claudiu.cristea: Deprecate theme_get_setting()
parent 596a88e1
Loading
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1344,7 +1344,7 @@ services:
    arguments: ['@router.route_provider']
  bare_html_page_renderer:
    class: Drupal\Core\Render\BareHtmlPageRenderer
    arguments: ['@renderer', '@html_response.attachments_processor']
    arguments: ['@renderer', '@html_response.attachments_processor', '@Drupal\Core\Extension\ThemeSettingsProvider']
    lazy: true
  Drupal\Core\Render\BareHtmlPageRendererInterface: '@bare_html_page_renderer'
  private_key:
@@ -2003,3 +2003,5 @@ services:
      ]
    tags:
      - { name: needs_destruction }
  Drupal\Core\Extension\ThemeSettingsProvider:
    autowire: true
+16 −83
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 */

use Drupal\Core\Datetime\DatePreprocess;
use Drupal\Core\Extension\ThemeSettingsProvider;
use Drupal\Core\Field\FieldPreprocess;
use Drupal\Core\Pager\PagerPreprocess;
use Drupal\Core\Breadcrumb\BreadcrumbPreprocess;
@@ -16,10 +17,8 @@
use Drupal\Core\Theme\ImagePreprocess;
use Drupal\Core\Theme\ThemePreprocess;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\StorageException;
use Drupal\Core\Template\AttributeHelper;
use Drupal\Core\Theme\ThemeCommonElements;
use Drupal\Core\Theme\ThemeSettings;

/**
 * @defgroup content_flags Content markers
@@ -67,16 +66,15 @@
/**
 * Returns an array of default theme features.
 *
 * @see \Drupal\Core\Extension\ThemeExtensionList::$defaults
 * @deprecated in drupal:11.3.0 and is removed from drupal:13.0.0. Use
 *   \Drupal\Core\Extension\ThemeSettingsProvider::DEFAULT_THEME_FEATURES
 *   instead.
 *
 * @see https://www.drupal.org/node/3554127
 */
function _system_default_theme_features() {
  return [
    'favicon',
    'logo',
    'node_user_picture',
    'comment_user_picture',
    'comment_user_verification',
  ];
  @trigger_error('_system_default_theme_features() is deprecated in drupal:11.3.0 and is removed from drupal:13.0.0. Use \Drupal\Core\Extension\ThemeSettingsProvider::DEFAULT_THEME_FEATURES instead. See https://www.drupal.org/node/3554127', E_USER_DEPRECATED);
  return ThemeSettingsProvider::DEFAULT_THEME_FEATURES;
}

/**
@@ -203,81 +201,16 @@ function drupal_find_theme_templates($cache, $extension, $path): array {
 *
 * @return mixed
 *   The value of the requested setting, NULL if the setting does not exist.
 *
 * @deprecated in drupal:11.3.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service('Drupal\Core\Extension\ThemeSettingsProvider')->getSetting()
 *   instead.
 *
 * @see https://www.drupal.org/node/3035289
 */
function theme_get_setting($setting_name, $theme = NULL) {
  /** @var \Drupal\Core\Theme\ThemeSettings[] $cache */
  $cache = &drupal_static(__FUNCTION__, []);

  // If no key is given, use the current theme if we can determine it.
  if (!isset($theme)) {
    $theme = \Drupal::theme()->getActiveTheme()->getName();
  }

  if (empty($cache[$theme])) {
    // Create a theme settings object.
    $cache[$theme] = new ThemeSettings($theme);
    // Get the global settings from configuration.
    $cache[$theme]->setData(\Drupal::config('system.theme.global')->get());

    // Get the values for the theme-specific settings from the .info.yml files
    // of the theme and all its base themes.
    $themes = \Drupal::service('theme_handler')->listInfo();
    if (isset($themes[$theme])) {
      $theme_object = $themes[$theme];

      // Retrieve configured theme-specific settings, if any.
      try {
        if ($theme_settings = \Drupal::config($theme . '.settings')->get()) {
          $cache[$theme]->merge($theme_settings);
        }
      }
      catch (StorageException) {
      }

      // If the theme does not support a particular feature, override the global
      // setting and set the value to NULL.
      if (!empty($theme_object->info['features'])) {
        foreach (_system_default_theme_features() as $feature) {
          if (!in_array($feature, $theme_object->info['features'])) {
            $cache[$theme]->set('features.' . $feature, NULL);
          }
        }
      }

      /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
      $file_url_generator = \Drupal::service('file_url_generator');

      // Generate the path to the logo image.
      if ($cache[$theme]->get('logo.use_default')) {
        $logo = \Drupal::service('theme.initialization')->getActiveThemeByName($theme)->getLogo();
        $cache[$theme]->set('logo.url', $file_url_generator->generateString($logo));
      }
      elseif ($logo_path = $cache[$theme]->get('logo.path')) {
        $cache[$theme]->set('logo.url', $file_url_generator->generateString($logo_path));
      }

      // Generate the path to the favicon.
      if ($cache[$theme]->get('features.favicon')) {
        $favicon_path = $cache[$theme]->get('favicon.path');
        if ($cache[$theme]->get('favicon.use_default')) {
          if (file_exists($favicon = $theme_object->getPath() . '/favicon.ico')) {
            $cache[$theme]->set('favicon.url', $file_url_generator->generateString($favicon));
          }
          else {
            $cache[$theme]->set('favicon.url', $file_url_generator->generateString('core/misc/favicon.ico'));
          }
        }
        elseif ($favicon_path) {
          $cache[$theme]->set('favicon.url', $file_url_generator->generateString($favicon_path));
        }
        else {
          $cache[$theme]->set('features.favicon', FALSE);
        }
      }
    }
  }

  return $cache[$theme]->get($setting_name);
  @trigger_error('theme_get_setting() is deprecated in drupal:11.3.0 and is removed from drupal:13.0.0. Use \Drupal::service(\'\Drupal\Core\Extension\ThemeSettingsProvider\')->getSetting() instead. See https://www.drupal.org/node/3035289', E_USER_DEPRECATED);
  return \Drupal::service(ThemeSettingsProvider::class)->getSetting($setting_name, $theme);
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class ThemeExtensionList extends ExtensionList {
    ],
    'description' => '',
    // The following array should be kept inline with
    // _system_default_theme_features().
    // ThemeSettingsProvider::DEFAULT_THEME_FEATURES.
    'features' => [
      'favicon',
      'logo',
+0 −8
Original line number Diff line number Diff line
@@ -154,10 +154,6 @@ public function install(array $theme_list, $install_dependencies = TRUE) {
        ->set("theme.$key", 0)
        ->save(TRUE);

      // Reset theme settings.
      $theme_settings = &drupal_static('theme_get_setting');
      unset($theme_settings[$key]);

      // Reset theme listing.
      $this->themeHandler->reset();

@@ -215,10 +211,6 @@ public function uninstall(array $theme_list) {
      // The value is not used; the weight is ignored for themes currently.
      $extension_config->clear("theme.$key");

      // Reset theme settings.
      $theme_settings = &drupal_static('theme_get_setting');
      unset($theme_settings[$key]);

      // Remove all configuration belonging to the theme.
      $this->configManager->uninstall('theme', $key);
    }
+139 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Extension;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\StorageException;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Theme\ThemeSettings;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Default implementation of the theme settings provider service.
 */
class ThemeSettingsProvider {

  /**
   * An array of default theme features.
   *
   * @see \Drupal\Core\Extension\ThemeExtensionList::$defaults
   */
  public const array DEFAULT_THEME_FEATURES = [
    'favicon',
    'logo',
    'node_user_picture',
    'comment_user_picture',
    'comment_user_verification',
  ];

  /**
   * Builds a new service instance.
   */
  public function __construct(
    protected readonly ThemeManagerInterface $themeManager,
    protected readonly ThemeInitializationInterface $themeInitialization,
    protected readonly ThemeHandlerInterface $themeHandler,
    protected readonly ConfigFactoryInterface $configFactory,
    protected readonly FileUrlGeneratorInterface $fileUrlGenerator,
    #[Autowire(service: 'cache.memory')]
    protected readonly CacheBackendInterface $memoryCache,
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public function getSetting(string $setting_name, ?string $theme = NULL): mixed {
    // If no key is given, use the current theme if we can determine it.
    if (!isset($theme)) {
      $theme = $this->themeManager->getActiveTheme()->getName();
    }

    $cid = 'theme_settings:' . $theme;
    $cacheItem = $this->memoryCache->get($cid);
    if ($cacheItem) {
      /** @var \Drupal\Core\Theme\ThemeSettings $themeSettings */
      $themeSettings = $cacheItem->data;
    }
    else {
      $themeSettings = $this->buildThemeSettings($theme);
      $this->memoryCache->set($cid, $themeSettings, tags: [
        'config:core.extension',
        'config:system.theme.global',
        sprintf('config:%s.settings', $theme),
      ]);
    }
    return $themeSettings->get($setting_name);
  }

  /**
   * Build a ThemeSettings object for a given theme.
   */
  protected function buildThemeSettings(string $theme): ThemeSettings {
    // Create a theme settings object.
    $themeSettings = new ThemeSettings($theme);
    // Get the global settings from configuration.
    $themeSettings->setData($this->configFactory->get('system.theme.global')->get());

    // Get the values for the theme-specific settings from the .info.yml files
    // of the theme and all its base themes.
    $themes = $this->themeHandler->listInfo();
    if (isset($themes[$theme])) {
      $themeObject = $themes[$theme];

      // Retrieve configured theme-specific settings, if any.
      try {
        if ($themeConfigSettings = $this->configFactory->get($theme . '.settings')->get()) {
          $themeSettings->merge($themeConfigSettings);
        }
      }
      catch (StorageException) {
      }

      // If the theme does not support a particular feature, override the
      // global setting and set the value to NULL.
      if (!empty($themeObject->info['features'])) {
        foreach (self::DEFAULT_THEME_FEATURES as $feature) {
          if (!in_array($feature, $themeObject->info['features'])) {
            $themeSettings->set('features.' . $feature, NULL);
          }
        }
      }

      // Generate the path to the logo image.
      if ($themeSettings->get('logo.use_default')) {
        $logo = $this->themeInitialization->getActiveThemeByName($theme)->getLogo();
        $themeSettings->set('logo.url', $this->fileUrlGenerator->generateString($logo));
      }
      elseif ($logo_path = $themeSettings->get('logo.path')) {
        $themeSettings->set('logo.url', $this->fileUrlGenerator->generateString($logo_path));
      }

      // Generate the path to the favicon.
      if ($themeSettings->get('features.favicon')) {
        $faviconPath = $themeSettings->get('favicon.path');
        if ($themeSettings->get('favicon.use_default')) {
          if (file_exists($favicon = $themeObject->getPath() . '/favicon.ico')) {
            $themeSettings->set('favicon.url', $this->fileUrlGenerator->generateString($favicon));
          }
          else {
            $themeSettings->set('favicon.url', $this->fileUrlGenerator->generateString('core/misc/favicon.ico'));
          }
        }
        elseif ($faviconPath) {
          $themeSettings->set('favicon.url', $this->fileUrlGenerator->generateString($faviconPath));
        }
        else {
          $themeSettings->set('features.favicon', FALSE);
        }
      }
    }
    return $themeSettings;
  }

}
Loading