Commit e270e0bf authored by catch's avatar catch
Browse files

Issue #3488176 by nicxvan, godotislate: Convert system_theme to OOP and handle install time call

(cherry picked from commit 42fda133)
parent ccafe37f
Loading
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -451,12 +451,6 @@
	'count' => 1,
	'path' => __DIR__ . '/includes/theme.inc',
];
$ignoreErrors[] = [
	// identifier: missingType.return
	'message' => '#^Function drupal_common_theme\\(\\) has no return type specified\\.$#',
	'count' => 1,
	'path' => __DIR__ . '/includes/theme.inc',
];
$ignoreErrors[] = [
	// identifier: missingType.return
	'message' => '#^Function drupal_find_theme_templates\\(\\) has no return type specified\\.$#',
+0 −153
Original line number Diff line number Diff line
@@ -1801,156 +1801,3 @@ function _field_multiple_value_form_sort_helper($a, $b) {
  $b_weight = (is_array($b) && isset($b['_weight']['#value']) ? $b['_weight']['#value'] : 0);
  return $a_weight - $b_weight;
}

/**
 * Provides theme registration for themes across .inc files.
 */
function drupal_common_theme() {
  return [
    // From theme.inc.
    'html' => [
      'render element' => 'html',
    ],
    'page' => [
      'render element' => 'page',
    ],
    'page_title' => [
      'variables' => ['title' => NULL],
    ],
    'region' => [
      'render element' => 'elements',
    ],
    'time' => [
      'variables' => ['timestamp' => NULL, 'text' => NULL, 'attributes' => []],
    ],
    'datetime_form' => [
      'render element' => 'element',
    ],
    'datetime_wrapper' => [
      'render element' => 'element',
    ],
    'status_messages' => [
      'variables' => ['status_headings' => [], 'message_list' => NULL],
    ],
    'links' => [
      'variables' => ['links' => [], 'attributes' => ['class' => ['links']], 'heading' => [], 'set_active_class' => FALSE],
    ],
    'dropbutton_wrapper' => [
      'variables' => ['children' => NULL],
    ],
    'image' => [
      // HTML 4 and XHTML 1.0 always require an alt attribute. The HTML 5 draft
      // allows the alt attribute to be omitted in some cases. Therefore,
      // default the alt attribute to an empty string, but allow code providing
      // variables to image.html.twig templates to pass explicit NULL for it to
      // be omitted. Usually, neither omission nor an empty string satisfies
      // accessibility requirements, so it is strongly encouraged for code
      // building variables for image.html.twig templates to pass a meaningful
      // value for the alt variable.
      // - https://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
      // - https://www.w3.org/TR/xhtml1/dtds.html
      // - http://dev.w3.org/html5/spec/Overview.html#alt
      // The title attribute is optional in all cases, so it is omitted by
      // default.
      'variables' => ['uri' => NULL, 'width' => NULL, 'height' => NULL, 'alt' => '', 'title' => NULL, 'attributes' => [], 'sizes' => NULL, 'srcset' => [], 'style_name' => NULL],
    ],
    'breadcrumb' => [
      'variables' => ['links' => []],
    ],
    'table' => [
      'variables' => ['header' => NULL, 'rows' => NULL, 'footer' => NULL, 'attributes' => [], 'caption' => NULL, 'colgroups' => [], 'sticky' => FALSE, 'responsive' => TRUE, 'empty' => ''],
    ],
    'tablesort_indicator' => [
      'variables' => ['style' => NULL],
    ],
    'mark' => [
      'variables' => ['status' => MARK_NEW],
    ],
    'item_list' => [
      'variables' => ['items' => [], 'title' => '', 'list_type' => 'ul', 'wrapper_attributes' => [], 'attributes' => [], 'empty' => NULL, 'context' => []],
    ],
    'feed_icon' => [
      'variables' => ['url' => NULL, 'title' => NULL, 'attributes' => []],
    ],
    'progress_bar' => [
      'variables' => ['label' => NULL, 'percent' => NULL, 'message' => NULL],
    ],
    'indentation' => [
      'variables' => ['size' => 1],
    ],
    // From theme.maintenance.inc.
    'maintenance_page' => [
      'render element' => 'page',
    ],
    'install_page' => [
      'render element' => 'page',
    ],
    'maintenance_task_list' => [
      'variables' => ['items' => NULL, 'active' => NULL, 'variant' => NULL],
    ],
    'authorize_report' => [
      'variables' => ['messages' => [], 'attributes' => []],
      'includes' => ['core/includes/theme.maintenance.inc'],
      'template' => 'authorize-report',
    ],
    'pager' => [
      'render element' => 'pager',
    ],
    'menu' => [
      'variables' => ['menu_name' => NULL, 'items' => [], 'attributes' => []],
    ],
    'menu_local_task' => [
      'render element' => 'element',
    ],
    'menu_local_action' => [
      'render element' => 'element',
    ],
    'menu_local_tasks' => [
      'variables' => ['primary' => [], 'secondary' => []],
    ],
    // From form.inc.
    'input' => [
      'render element' => 'element',
    ],
    'select' => [
      'render element' => 'element',
    ],
    'fieldset' => [
      'render element' => 'element',
    ],
    'details' => [
      'render element' => 'element',
    ],
    'radios' => [
      'render element' => 'element',
    ],
    'checkboxes' => [
      'render element' => 'element',
    ],
    'form' => [
      'render element' => 'element',
    ],
    'textarea' => [
      'render element' => 'element',
    ],
    'form_element' => [
      'render element' => 'element',
    ],
    'form_element_label' => [
      'render element' => 'element',
    ],
    'vertical_tabs' => [
      'render element' => 'element',
    ],
    'container' => [
      'render element' => 'element',
    ],
    // From field system.
    'field' => [
      'render element' => 'element',
    ],
    'field_multiple_value_form' => [
      'render element' => 'element',
    ],
  ];
}
+22 −9
Original line number Diff line number Diff line
@@ -390,10 +390,17 @@ protected function build() {
    if ($cached = $this->cache->get('theme_registry:build:modules')) {
      $cache = $cached->data;
    }
    else {
      if (defined('MAINTENANCE_MODE') && constant('MAINTENANCE_MODE') === 'install') {
        // System is still set here so preprocess can be updated in install.
        $this->processExtension($cache, 'system', 'install', 'system', $this->moduleList->getPath('system'));
      }
      else {
        $this->moduleHandler->invokeAllWith('theme', function (callable $callback, string $module) use (&$cache) {
          $this->processExtension($cache, $module, 'module', $module, $this->moduleList->getPath($module));
        });
      }

      // Only cache this registry if all modules are loaded.
      if ($this->moduleHandler->isLoaded()) {
        $this->cache->set("theme_registry:build:modules", $cache);
@@ -464,12 +471,12 @@ protected function build() {
   *   The name of the module, theme engine, base theme engine, theme or base
   *   theme implementing hook_theme().
   * @param string $type
   *   One of 'module', 'theme_engine', 'base_theme_engine', 'theme', or
   *   'base_theme'. Unlike regular hooks that can only be implemented by
   *   modules, each of these can implement hook_theme(). This function is
   *   called in aforementioned order and new entries override older ones. For
   *   example, if a theme hook is both defined by a module and a theme, then
   *   the definition in the theme will be used.
   *   One of 'module', 'theme_engine', 'base_theme_engine', 'theme',
   *   'base_theme', or 'install'. Unlike regular hooks that can only be
   *   implemented by modules, each of these can implement hook_theme(). This
   *   function is called in aforementioned order and new entries override
   *   older ones. For example, if a theme hook is both defined by a module and
   *   a theme, then the definition in the theme will be used.
   * @param string $theme
   *   The actual name of theme, module, etc. that is being processed.
   * @param string $path
@@ -502,6 +509,12 @@ protected function processExtension(array &$cache, $name, $type, $theme, $path)
    if ($type === 'module') {
      $result = $this->moduleHandler->invoke($name, 'theme', $args);
    }
    elseif ($type === 'install') {
      $result = ThemeCommonElements::commonElements();
      // Reset to module so that preprocess hooks are handled in install.
      $type = 'module';
      $args = [$cache, $type, $theme, $path];
    }
    else {
      $function = $name . '_theme';
      if (function_exists($function)) {
+252 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Theme;

/**
 * Provide common theme render elements.
 */
class ThemeCommonElements {

  /**
   * Base theme array.
   *
   * @return array
   *   System theme array.
   */
  public static function commonElements(): array {
    return [
      'html' => [
        'render element' => 'html',
      ],
      'page' => [
        'render element' => 'page',
      ],
      'page_title' => [
        'variables' => [
          'title' => NULL,
        ],
      ],
      'region' => [
        'render element' => 'elements',
      ],
      'time' => [
        'variables' => [
          'timestamp' => NULL,
          'text' => NULL,
          'attributes' => [],
        ],
      ],
      'datetime_form' => [
        'render element' => 'element',
      ],
      'datetime_wrapper' => [
        'render element' => 'element',
      ],
      'status_messages' => [
        'variables' => [
          'status_headings' => [],
          'message_list' => NULL,
        ],
      ],
      'links' => [
        'variables' => [
          'links' => [],
          'attributes' => [
            'class' => ['links'],
          ],
          'heading' => [],
          'set_active_class' => FALSE,
        ],
      ],
      'dropbutton_wrapper' => [
        'variables' => [
          'children' => NULL,
        ],
      ],
      'image' => [
        // HTML 4 and XHTML 1.0 always require an alt attribute. The HTML 5 draft
        // allows the alt attribute to be omitted in some cases. Therefore,
        // default the alt attribute to an empty string, but allow code providing
        // variables to image.html.twig templates to pass explicit NULL for it to
        // be omitted. Usually, neither omission nor an empty string satisfies
        // accessibility requirements, so it is strongly encouraged for code
        // building variables for image.html.twig templates to pass a meaningful
        // value for the alt variable.
        // - https://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
        // - https://www.w3.org/TR/xhtml1/dtds.html
        // - http://dev.w3.org/html5/spec/Overview.html#alt
        // The title attribute is optional in all cases, so it is omitted by
        // default.
        'variables' => [
          'uri' => NULL,
          'width' => NULL,
          'height' => NULL,
          'alt' => '',
          'title' => NULL,
          'attributes' => [],
          'sizes' => NULL,
          'srcset' => [],
          'style_name' => NULL,
        ],
      ],
      'breadcrumb' => [
        'variables' => [
          'links' => [],
        ],
      ],
      'table' => [
        'variables' => [
          'header' => NULL,
          'rows' => NULL,
          'footer' => NULL,
          'attributes' => [],
          'caption' => NULL,
          'colgroups' => [],
          'sticky' => FALSE,
          'responsive' => TRUE,
          'empty' => '',
        ],
      ],
      'tablesort_indicator' => [
        'variables' => [
          'style' => NULL,
        ],
      ],
      'mark' => [
        'variables' => [
          'status' => MARK_NEW,
        ],
      ],
      'item_list' => [
        'variables' => [
          'items' => [],
          'title' => '',
          'list_type' => 'ul',
          'wrapper_attributes' => [],
          'attributes' => [],
          'empty' => NULL,
          'context' => [],
        ],
      ],
      'feed_icon' => [
        'variables' => [
          'url' => NULL,
          'title' => NULL,
          'attributes' => [],
        ],
      ],
      'progress_bar' => [
        'variables' => [
          'label' => NULL,
          'percent' => NULL,
          'message' => NULL,
        ],
      ],
      'indentation' => [
        'variables' => ['size' => 1],
      ],
      // From theme.maintenance.inc.
      'maintenance_page' => [
        'render element' => 'page',
      ],
      'install_page' => [
        'render element' => 'page',
      ],
      'maintenance_task_list' => [
        'variables' => [
          'items' => NULL,
          'active' => NULL,
          'variant' => NULL,
        ],
      ],
      'authorize_report' => [
        'variables' => [
          'messages' => [],
          'attributes' => [],
        ],
        'includes' => ['core/includes/theme.maintenance.inc'],
        'template' => 'authorize-report',
      ],
      'pager' => [
        'render element' => 'pager',
      ],
      'menu' => [
        'variables' => [
          'menu_name' => NULL,
          'items' => [],
          'attributes' => [],
        ],
      ],
      'menu_local_task' => [
        'render element' => 'element',
      ],
      'menu_local_action' => [
        'render element' => 'element',
      ],
      'menu_local_tasks' => [
        'variables' => [
          'primary' => [],
          'secondary' => [],
        ],
      ],
      // From form.inc.
      'input' => [
        'render element' => 'element',
      ],
      'select' => [
        'render element' => 'element',
      ],
      'fieldset' => [
        'render element' => 'element',
      ],
      'details' => [
        'render element' => 'element',
      ],
      'radios' => [
        'render element' => 'element',
      ],
      'checkboxes' => [
        'render element' => 'element',
      ],
      'form' => [
        'render element' => 'element',
      ],
      'textarea' => [
        'render element' => 'element',
      ],
      'form_element' => [
        'render element' => 'element',
      ],
      'form_element_label' => [
        'render element' => 'element',
      ],
      'vertical_tabs' => [
        'render element' => 'element',
      ],
      'container' => [
        'render element' => 'element',
      ],
      // From field system.
      'field' => [
        'render element' => 'element',
      ],
      'field_multiple_value_form' => [
        'render element' => 'element',
      ],
      'off_canvas_page_wrapper' => [
        'variables' => [
          'children' => NULL,
        ],
      ],
      'status_report_grouped' => [
        'variables' => [
          'grouped_requirements' => NULL,
          'requirements' => NULL,
        ],
      ],
    ];
  }

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

namespace Drupal\system\Hook;

use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Theme\ThemeCommonElements;

/**
 * Hook implementations for system.
 */
class ThemeHook {

  /**
   * Implements hook_theme().
   */
  #[Hook('theme')]
  public function theme(): array {
    $themeCommonElements = ThemeCommonElements::commonElements();

    $systemTheme = [
      // Normally theme suggestion templates are only picked up when they are in
      // themes. We explicitly define theme suggestions here so that the block
      // templates in core/modules/system/templates are picked up.
      'block__system_branding_block' => [
        'render element' => 'elements',
        'base hook' => 'block',
      ],
      'block__system_messages_block' => [
        'base hook' => 'block',
      ],
      'block__system_menu_block' => [
        'render element' => 'elements',
        'base hook' => 'block',
      ],
      'system_themes_page' => [
        'variables' => [
          'theme_groups' => [],
          'theme_group_titles' => [],
        ],
        'file' => 'system.admin.inc',
      ],
      'system_config_form' => [
        'render element' => 'form',
      ],
      'confirm_form' => [
        'render element' => 'form',
      ],
      'system_modules_details' => [
        'render element' => 'form',
        'file' => 'system.admin.inc',
      ],
      'system_modules_uninstall' => [
        'render element' => 'form',
        'file' => 'system.admin.inc',
      ],
      'status_report_page' => [
        'variables' => [
          'counters' => [],
          'general_info' => [],
          'requirements' => NULL,
        ],
      ],
      'status_report' => [
        'variables' => [
          'grouped_requirements' => NULL,
          'requirements' => NULL,
        ],
      ],
      'status_report_counter' => [
        'variables' => [
          'amount' => NULL,
          'text' => NULL,
          'severity' => NULL,
        ],
      ],
      'status_report_general_info' => [
        'variables' => [
          'drupal' => [],
          'cron' => [],
          'database_system' => [],
          'database_system_version' => [],
          'php' => [],
          'php_memory_limit' => [],
          'webserver' => [],
        ],
      ],
      'admin_page' => [
        'variables' => [
          'blocks' => NULL,
        ],
        'file' => 'system.admin.inc',
      ],
      'admin_block' => [
        'variables' => [
          'block' => NULL,
          'attributes' => [],
        ],
        'file' => 'system.admin.inc',
      ],
      'admin_block_content' => [
        'variables' => [
          'content' => NULL,
        ],
        'file' => 'system.admin.inc',
      ],
      'system_admin_index' => [
        'variables' => [
          'menu_items' => NULL,
        ],
        'file' => 'system.admin.inc',
      ],
      'entity_add_list' => [
        'variables' => [
          'bundles' => [],
          'add_bundle_message' => NULL,
        ],
        'template' => 'entity-add-list',
      ],
      'system_security_advisories_fetch_error_message' => [
        'file' => 'system.theme.inc',
        'variables' => [
          'error_message' => [],
        ],
      ],
      'entity_page_title' => [
        'variables' => [
          'attributes' => [],
          'title' => NULL,
          'entity' => NULL,
          'view_mode' => NULL,
        ],
      ],
    ];

    return array_merge($themeCommonElements, $systemTheme);
  }

}
Loading