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

Issue #3490843 by nicxvan, smustgrave, oily, joachim, berdir, alexpott,...

Issue #3490843 by nicxvan, smustgrave, oily, joachim, berdir, alexpott, nikolay shapovalov, dww: Create class to replace hook_requirements('install')
parent fae1be90
Loading
Loading
Loading
Loading
Loading
+51 −3
Changes for core/includes/install.inc: 51 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -9,7 +9,9 @@
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Database\Database;
use Drupal\Core\Extension\Dependency;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\Extension\InstallRequirementsInterface;
use Drupal\Core\Installer\InstallerKernel;
use Symfony\Component\HttpFoundation\RedirectResponse;

@@ -616,6 +618,8 @@ function drupal_check_profile($profile) {
      if (function_exists($function)) {
        $requirements = array_merge($requirements, $function('install'));
      }

      $requirements = array_merge($requirements, install_check_class_requirements($module_list[$module]));
    }
  }

@@ -625,6 +629,9 @@ function drupal_check_profile($profile) {
    $requirements = array_merge($requirements, $function('install'));
  }

  $extension = \Drupal::service('extension.list.profile')->get($profile);
  $requirements = array_merge($requirements, install_check_class_requirements($extension));

  return $requirements;
}

@@ -660,13 +667,16 @@ function drupal_requirements_severity(&$requirements) {
function drupal_check_module($module) {
  /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
  $module_list = \Drupal::service('extension.list.module');
  $file = DRUPAL_ROOT . '/' . $module_list->getPath($module) . "/$module.install";
  $extension = $module_list->get($module);
  $file = \Drupal::root() . '/' . $extension->getPath() . "/$module.install";
  if (is_file($file)) {
    require_once $file;
  }
  // Check requirements
  $requirements = \Drupal::moduleHandler()->invoke($module, 'requirements', ['install']);
  if (is_array($requirements) && drupal_requirements_severity($requirements) == REQUIREMENT_ERROR) {
  $requirements = \Drupal::moduleHandler()->invoke($module, 'requirements', ['install']) ?? [];
  $requirements = array_merge($requirements, install_check_class_requirements($extension));

  if (!empty($requirements) && drupal_requirements_severity($requirements) == REQUIREMENT_ERROR) {
    // Print any error messages
    foreach ($requirements as $requirement) {
      if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
@@ -790,3 +800,41 @@ function install_profile_info($profile, $langcode = 'en') {
  }
  return $cache[$profile][$langcode];
}

/**
 * Checks a module or profile requirements.
 *
 * See \Drupal\Core\Extension\InstallRequirementsInterface for more information.
 *
 * @param \Drupal\Core\Extension $extension
 *   The extension to check install requirements for.
 *
 * @return array
 *   The requirements.
 *
 * @internal
 */
function install_check_class_requirements(Extension $extension): array {
  $extension_path = $extension->getPath();
  $extension_name = $extension->getName();
  $dir = \Drupal::root() . "/$extension_path/src/Install/Requirements";
  $requirements = [];
  if (is_dir($dir)) {
    $fileSystemIterator = new FilesystemIterator($dir);
    foreach ($fileSystemIterator as $fileInfo) {
      if ($fileInfo->isFile() && $fileInfo->getExtension() === 'php') {
        $filename = $fileInfo->getFilename();
        $requirements_path = $dir . '/' . $filename;
        require_once $requirements_path;

        $namespace = "Drupal\\$extension_name\\Install\\Requirements";
        $class_name = $namespace . '\\' . $fileInfo->getBasename('.php');
        if (class_exists($class_name) && class_implements($class_name, InstallRequirementsInterface::class)) {
          $requirements = $class_name::getRequirements();
        }
      }
    }

  }
  return $requirements;
}
+48 −0
Changes for core/lib/Drupal/Core/Extension/InstallRequirementsInterface.php: 48 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Extension;

/**
 * Provides method for checking requirements during install time.
 */
interface InstallRequirementsInterface {

  /**
   * Check installation requirements.
   *
   * Classes implementing this must be in the Install/Requirements namespace.
   * For example src/Install/Requirements/ModuleNameRequirements.php.
   *
   * During the 'install' phase, modules can for example assert that
   * library or server versions are available or sufficient.
   * Note that the installation of a module can happen during installation of
   * Drupal itself (by install.php) with an installation profile or later by hand.
   * As a consequence, install-time requirements must be checked without access
   * to the full Drupal API, because it is not available during install.php.
   * If a requirement has a severity of REQUIREMENT_ERROR, install.php will abort
   * or at least the module will not install.
   * Other severity levels have no effect on the installation.
   * Module dependencies do not belong to these installation requirements,
   * but should be defined in the module's .info.yml file.
   *
   * During installation, if you need to load a class from your module,
   * you'll need to include the class file directly.
   *
   * @return array
   *   An associative array where the keys are arbitrary but must be unique (it
   *   is suggested to use the module short name as a prefix) and the values are
   *   themselves associative arrays with the following elements:
   *   - title: The name of the requirement.
   *   - value: This should only be used for version numbers, do not set it if
   *     not applicable.
   *   - description: The description of the requirement/status.
   *   - severity: (optional) The requirement's result/severity level, one of:
   *     - REQUIREMENT_INFO: For info only.
   *     - REQUIREMENT_OK: The requirement is satisfied.
   *     - REQUIREMENT_WARNING: The requirement failed with a warning.
   *     - REQUIREMENT_ERROR: The requirement failed with an error.
   *     Defaults to REQUIREMENT_OK when installing.
   */
  public static function getRequirements(): array;

}
+5 −0
Changes for core/modules/system/tests/modules/module_install_requirements/module_install_requirements.info.yml: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
name: 'Test Install Requirements Class'
type: module
description: 'Support module for testing install requirements.'
package: Testing
version: VERSION
+23 −0
Changes for core/modules/system/tests/modules/module_install_requirements/src/Install/Requirements/ModuleInstallRequirements.php: 23 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\module_install_requirements\Install\Requirements;

use Drupal\Core\Extension\InstallRequirementsInterface;

/**
 * Provides method for checking requirements during install time.
 */
class ModuleInstallRequirements implements InstallRequirementsInterface {

  /**
   * {@inheritdoc}
   */
  public static function getRequirements(): array {
    $GLOBALS['module_install_requirements'] = 'module_install_requirements';

    return [];
  }

}
+5 −0
Changes for core/modules/system/tests/modules/module_install_unmet_requirements/module_install_unmet_requirements.info.yml: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
name: 'Test Install Requirements Class'
type: module
description: 'Support module for testing install unmet requirements.'
package: Testing
version: VERSION
Loading