Commit 0fdc2dab authored by catch's avatar catch
Browse files

fix: #3613607 Add RecipeRunner::isApplying() to determine if a recipe is being...

fix: #3613607 Add RecipeRunner::isApplying() to determine if a recipe is being applied, without confusing it with a config sync

By: alexpott
By: penyaskito
By: phenaproxima
By: gábor hojtsy
parent c2dc9ad5
Loading
Loading
Loading
Loading
Loading
+2 −1
Changes for core/lib/Drupal/Core/Config/ConfigInstaller.php: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
use Drupal\Core\Config\Entity\ConfigDependencyManager;
use Drupal\Core\Extension\ExtensionPathResolver;
use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\Recipe\RecipeRunner;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
@@ -390,7 +391,7 @@ protected function createConfiguration($collection, array $config_to_create) {
        // Add a hash to configuration created through the installer so it is
        // possible to know if the configuration was created by installing an
        // extension and to track which version of the default config was used.
        if (!$this->isSyncing() && $collection == StorageInterface::DEFAULT_COLLECTION) {
        if ((!$this->isSyncing() || RecipeRunner::isApplying()) && $collection == StorageInterface::DEFAULT_COLLECTION) {
          $config_to_create[$name] = [
            '_core' => [
              'default_config_hash' => Crypt::hashBase64(serialize($config_to_create[$name])),
+49 −0
Changes for core/lib/Drupal/Core/Recipe/RecipeRunner.php: 49 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -31,15 +31,34 @@
 */
final class RecipeRunner {

  /**
   * Whether a recipe is currently being applied.
   */
  protected static bool $isApplying = FALSE;

  /**
   * Determines whether a recipe is currently being applied.
   *
   * @return bool
   *   TRUE if a recipe is currently being applied, FALSE if not.
   */
  public static function isApplying(): bool {
    return static::$isApplying;
  }

  /**
   * @param \Drupal\Core\Recipe\Recipe $recipe
   *   The recipe to apply.
   */
  public static function processRecipe(Recipe $recipe): void {
    $set_is_applying = static::tryToSetIsApplying();
    static::processRecipes($recipe->recipes);
    static::processInstall($recipe->install, $recipe->config->getConfigStorage());
    static::processConfiguration($recipe);
    static::processContent($recipe->content);
    if ($set_is_applying) {
      static::$isApplying = FALSE;
    }
    static::triggerEvent($recipe);
  }

@@ -295,6 +314,7 @@ public static function installModules(array $modules, StorageInterface|Recipe $r
    if (empty($modules)) {
      throw new \InvalidArgumentException('No modules provided.');
    }
    $set_is_applying = static::tryToSetIsApplying();
    if ($recipeConfigStorage instanceof Recipe) {
      $recipeConfigStorage = $recipeConfigStorage->config->getConfigStorage();
    }
@@ -333,6 +353,9 @@ public static function installModules(array $modules, StorageInterface|Recipe $r
    else {
      $context['results']['module'] = $modules;
    }
    if ($set_is_applying) {
      static::$isApplying = FALSE;
    }
  }

  /**
@@ -346,6 +369,7 @@ public static function installModules(array $modules, StorageInterface|Recipe $r
   *   The batch context if called by a batch.
   */
  public static function installTheme(string $theme, StorageInterface|Recipe $recipeConfigStorage, ?array &$context = NULL): void {
    $set_is_applying = static::tryToSetIsApplying();
    if ($recipeConfigStorage instanceof Recipe) {
      $recipeConfigStorage = $recipeConfigStorage->config->getConfigStorage();
    }
@@ -363,6 +387,9 @@ public static function installTheme(string $theme, StorageInterface|Recipe $reci
    \Drupal::service('config.installer')->setSyncing(FALSE);
    $context['message'] = t('Installed %theme theme.', ['%theme' => \Drupal::service('extension.list.theme')->getName($theme)]);
    $context['results']['theme'][] = $theme;
    if ($set_is_applying) {
      static::$isApplying = FALSE;
    }
  }

  /**
@@ -374,9 +401,13 @@ public static function installTheme(string $theme, StorageInterface|Recipe $reci
   *   The batch context if called by a batch.
   */
  public static function installConfig(Recipe $recipe, ?array &$context = NULL): void {
    $set_is_applying = static::tryToSetIsApplying();
    static::processConfiguration($recipe);
    $context['message'] = t('Installed configuration for %recipe recipe.', ['%recipe' => $recipe->name]);
    $context['results']['config'][] = $recipe->name;
    if ($set_is_applying) {
      static::$isApplying = FALSE;
    }
  }

  /**
@@ -388,9 +419,27 @@ public static function installConfig(Recipe $recipe, ?array &$context = NULL): v
   *   The batch context if called by a batch.
   */
  public static function installContent(Recipe $recipe, ?array &$context = NULL): void {
    $set_is_applying = static::tryToSetIsApplying();
    static::processContent($recipe->content);
    $context['message'] = t('Created content for %recipe recipe.', ['%recipe' => $recipe->name]);
    $context['results']['content'][] = $recipe->name;
    if ($set_is_applying) {
      static::$isApplying = FALSE;
    }
  }

  /**
   * Tries to set the isApplying flag to TRUE.
   *
   * @return bool
   *   TRUE if this call set the flag, FALSE if it was already set.
   */
  private static function tryToSetIsApplying(): bool {
    if (!static::$isApplying) {
      static::$isApplying = TRUE;
      return TRUE;
    }
    return FALSE;
  }

  /**
+7 −0
Changes for core/modules/system/tests/modules/recipe_is_applying_test/config/schema/recipe_is_applying_test.schema.yml: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
recipe_is_applying_test.settings:
  type: config_object
  label: 'Recipe isApplying test settings'
  mapping:
    recipe:
      type: string
      label: 'Recipe'
+5 −0
Changes for core/modules/system/tests/modules/recipe_is_applying_test/recipe_is_applying_test.info.yml: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
name: 'Recipe isApplying test'
type: module
description: 'Records the value of RecipeRunner::isApplying() during recipe application.'
package: Testing
version: VERSION
+6 −0
Changes for core/modules/system/tests/modules/recipe_is_applying_test/recipe_is_applying_test.services.yml: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
services:
  _defaults:
    autowire: true
    autoconfigure: true
  recipe_is_applying_test.event_subscriber:
    class: Drupal\recipe_is_applying_test\EventSubscriber\RecipeIsApplyingTestSubscriber
Loading