Commit f1b7d9b2 authored by catch's avatar catch
Browse files

task: #3490846 Deprecate hook_requirements

By: nicxvan
By: berdir
(cherry picked from commit ed8ade4c)
parent 62362fa4
Loading
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -702,8 +702,10 @@ function drupal_check_module($module) {
    require_once $file;
  }
  // Check requirements.
  $requirements = install_check_class_requirements($extension);
  if (empty($requirements)) {
    $requirements = \Drupal::moduleHandler()->invoke($module, 'requirements', ['install']) ?? [];
  $requirements = array_merge($requirements, install_check_class_requirements($extension));
  }

  if (!empty($requirements) && RequirementSeverity::maxSeverityFromRequirements($requirements) === RequirementSeverity::Error) {
    // Print any error messages.
+26 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Hook\Attribute;

/**
 * Prevents procedural requirements hook from executing.
 *
 * This allows the use of the legacy hook_requirements() and
 * hook_requirements_alter() alongside the OOP replacements.
 *
 * Marking requirements hooks as #LegacyRequirementsHook will prevent them
 * from running on Drupal 11.3.0 and later.
 *
 * Note that Drupal 11.2 supports both legacy and new OOP requirements hooks
 * and will invoke both as this attribute is not recognized there.
 *
 * On older versions of Drupal which are not aware of the new requirement hooks,
 * only the legacy hook implementation is executed.
 *
 * Adding this attribute will also skip deprecation messages on Drupal 11.3 and
 * later.
 */
#[\Attribute(\Attribute::TARGET_FUNCTION)]
class LegacyRequirementsHook {}
+30 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
use Drupal\Core\Hook\Attribute\LegacyHook;
use Drupal\Core\Hook\Attribute\LegacyModuleImplementsAlter;
use Drupal\Core\Hook\Attribute\ProceduralHookScanStop;
use Drupal\Core\Hook\Attribute\LegacyRequirementsHook;
use Drupal\Core\Hook\Attribute\RemoveHook;
use Drupal\Core\Hook\Attribute\ReorderHook;
use Drupal\Core\Hook\OrderOperation\OrderOperation;
@@ -526,7 +527,8 @@ protected function collectModuleHookImplementations($dir, $module, $current_modu
              break;
            }

            if (!StaticReflectionParser::hasAttribute($attributes, LegacyHook::class) && (preg_match($current_module_preg, $function, $matches) || preg_match($all_modules_preg, $function, $matches)) && !StaticReflectionParser::hasAttribute($attributes, LegacyModuleImplementsAlter::class)) {
            $legacy_attributes = [LegacyHook::class, LegacyModuleImplementsAlter::class, LegacyRequirementsHook::class];
            if (!static::hasAnyAttribute($attributes, $legacy_attributes) && (preg_match($current_module_preg, $function, $matches) || preg_match($all_modules_preg, $function, $matches))) {
              // Skip hooks that are not supported by the new hook system, they
              // do not need to be added to the BC layer. Note that is different
              // from static::checkForProceduralOnlyHooks(). hook_requirements
@@ -567,6 +569,29 @@ protected function collectModuleHookImplementations($dir, $module, $current_modu
    }
  }

  /**
   * Returns whether the existing attributes match any of the expected ones.
   *
   * @param array $existingAttributes
   *   List of attribute classes.
   * @param array $attributesLookingFor
   *   List of expected attribute classes.
   *
   * @return bool
   *   Whether an expected attribute class exists.
   */
  public static function hasAnyAttribute(array $existingAttributes, array $attributesLookingFor): bool {
    foreach ($existingAttributes as $existingAttribute) {
      foreach ($attributesLookingFor as $attributeLookingFor) {
        if (is_a($existingAttribute, $attributeLookingFor, TRUE)) {
          return TRUE;
        }
      }
    }

    return FALSE;
  }

  /**
   * Filter iterator callback. Allows include files and .php files in src/Hook.
   */
@@ -609,6 +634,10 @@ protected function addProceduralImplementation(\SplFileInfo $fileinfo, string $h
      $this->moduleImplementsAlters[] = $function;
      include_once $fileinfo->getPathname();
    }
    elseif (in_array($hook, ['requirements', 'requirements_alter'])) {
      $message = "$function without a #[LegacyRequirementsHook] attribute is deprecated in drupal:11.3.0 and removed in drupal:13.0.0. See https://www.drupal.org/node/3549685";
      @trigger_error($message, E_USER_DEPRECATED);
    }
    $this->proceduralImplementations[$hook][] = $module;
    if ($fileinfo->getExtension() !== 'module') {
      $this->includes[$function] = $fileinfo->getPathname();
+18 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Install hooks for the install requirements test module.
 */

declare(strict_types=1);

use Drupal\Core\Hook\Attribute\LegacyRequirementsHook;

/**
 * Implements hook_requirements()
 */
#[LegacyRequirementsHook]
function module_install_requirements_requirements(): array {
  throw new \Exception('This is a legacy hook and must not be called');
}
+9 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
namespace Drupal\module_install_requirements\Install\Requirements;

use Drupal\Core\Extension\InstallRequirementsInterface;
use Drupal\Core\Extension\Requirement\RequirementSeverity;

/**
 * Provides method for checking requirements during install time.
@@ -17,7 +18,14 @@ class ModuleInstallRequirements implements InstallRequirementsInterface {
  public static function getRequirements(): array {
    $GLOBALS['module_install_requirements'] = 'module_install_requirements';

    return [];
    return [
      'test.runtime.install' => [
        'title' => t('InstallOk'),
        'value' => t('None'),
        'description' => t('Install OK.'),
        'severity' => RequirementSeverity::OK,
      ],
    ];
  }

}
Loading