Commit 325f82b3 authored by catch's avatar catch
Browse files

fix: #3560833 Create better way to manage theme setting alters

By: nicxvan
By: berdir
By: godotislate
(cherry picked from commit d73f225c)
parent 39b7aee6
Loading
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -221,7 +221,9 @@ protected function collectThemeHookImplementations($dir, $theme, $currentThemePr
      $fileExtension = $fileinfo->getExtension();
      $filename = $fileinfo->getPathname();

      if ($fileExtension === 'php') {
      $isThemeSettings = str_ends_with($filename, 'theme-settings.php');

      if ($fileExtension === 'php' && !$isThemeSettings) {
        $cached = $hookFileCache->get($filename);
        if ($cached) {
          $class = $cached['class'];
@@ -351,6 +353,9 @@ protected static function filterIterator(\SplFileInfo $fileInfo, $key, \Recursiv
      // glob() doesn't support streams but scandir() does.
      return !in_array($fileInfo->getFilename(), ['tests', 'js', 'css', 'templates']) && !array_filter(scandir($key), static fn($filename) => str_ends_with($filename, '.info.yml'));
    }
    if ($fileInfo->getFilename() === 'theme-settings.php') {
      return TRUE;
    }
    return in_array($extension, ['inc', 'theme']);
  }

+8 −7
Original line number Diff line number Diff line
@@ -378,7 +378,11 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
      $default_theme = $default_active_theme->getName();
      /** @var \Drupal\Core\Theme\ThemeInitialization $theme_initialization */
      $theme_initialization = \Drupal::service('theme.initialization');
      $this->themeManager->setActiveTheme($theme_initialization->getActiveThemeByName($theme));

      // We need to account for viewing themes that are not currently active so
      // we temporarily set the theme we are viewing as active.
      $editing_active_theme = $theme_initialization->getActiveThemeByName($theme);
      $this->themeManager->setActiveTheme($editing_active_theme);

      // Process the theme and all its base themes.
      foreach ($theme_keys as $theme) {
@@ -399,13 +403,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
            $form_state->addBuildInfo('files', $files);
          }
        }
      }

      // Call theme-specific settings.
        $function = $theme . '_form_system_theme_settings_alter';
        if (function_exists($function)) {
          $function($form, $form_state);
        }
      }
      $this->themeManager->alterForTheme($editing_active_theme, 'form_system_theme_settings', $form, $form_state);

      // Restore the original current theme.
      if (isset($default_theme)) {
+58 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\test_theme_theme\Hook;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ThemeSettingsProvider;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Hook implementations for test_theme_theme.
 */
class TestThemeThemeHooks {

  use StringTranslationTrait;

  public function __construct(
    protected EntityTypeManagerInterface $entityTypeManager,
    protected ThemeSettingsProvider $themeSettingsProvider,
  ) {}

  /**
   * Implements hook_form_system_theme_settings_alter().
   */
  #[Hook('form_system_theme_settings_alter')]
  public function formSystemThemeSettingsAlter(&$form, FormStateInterface $form_state): void {
    $form['custom_logo'] = [
      '#type' => 'managed_file',
      '#title' => $this->t('Secondary logo.'),
      '#default_value' => $this->themeSettingsProvider->getSetting('custom_logo'),
      '#progress_indicator' => 'bar',
      '#progress_message' => $this->t('Processing...'),
      '#upload_location' => 'public://test',
      '#upload_validators' => [
        'FileExtension' => [
          'extensions' => 'gif png jpg jpeg',
        ],
      ],
    ];
    $form['#submit'][] = static::class . ':themeSettingsSubmit';
  }

  /**
   * Test theme form settings submission handler.
   */
  public function themeSettingsSubmit(&$form, FormStateInterface $form_state): void {
    if ($file_id = $form_state->getValue(['custom_logo', '0'])) {
      /** @var Drupal\file\Entity\FileInterface $file */
      $file = $this->entityTypeManager->getStorage('file')->load($file_id);
      $file->setPermanent();
      $file->save();
    }
  }

}
+0 −43
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Test to ensure theme compatibility with managed files.
 */

declare(strict_types=1);

use Drupal\Core\Extension\ThemeSettingsProvider;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;

/**
 * Implements hook_form_system_theme_settings_alter().
 */
function test_theme_theme_form_system_theme_settings_alter(&$form, FormStateInterface $form_state): void {

  $form['custom_logo'] = [
    '#type' => 'managed_file',
    '#title' => t('Secondary logo.'),
    '#default_value' => \Drupal::service(ThemeSettingsProvider::class)->getSetting('custom_logo'),
    '#progress_indicator' => 'bar',
    '#progress_message'   => t('Processing...'),
    '#upload_location' => 'public://test',
    '#upload_validators'  => [
      'FileExtension' => ['extensions' => 'gif png jpg jpeg'],
    ],
  ];

  $form['#submit'][] = 'test_theme_theme_form_system_theme_settings_submit';
}

/**
 * Test theme form settings submission handler.
 */
function test_theme_theme_form_system_theme_settings_submit(&$form, FormStateInterface $form_state): void {
  if ($file_id = $form_state->getValue(['custom_logo', '0'])) {
    $file = File::load($file_id);
    $file->setPermanent();
    $file->save();
  }
}