Drupal 8:修复损坏的多站点配置设置

我最近写了一篇有关使用Configuration Split模块设置多站点配置设置的文章。该文章是在我研究了如何设置配置拆分并使用它们在Drupal中创建多站点设置之后写的。我在进行这项研究时意识到的一件事是,尽管使用这种设置非常容易进行设置,但也很容易出错并创建确实不起作用的设置。

在过去的几个月中,我反复遇到开发人员构建的Drupal站点,这些站点试图创建多站点设置并弄错了。这会导致无法正确导入的配置损坏或完成后破坏站点,无法使用的嵌套配置,甚至安装的配置文件实际上并未安装任何内容。在一种情况下(在我开始在站点上工作之前),登台配置进入了生产平台,这导致在沙盒环境下付款。一团糟!

这使我处于不得不重新构建这些站点以使它们再次作为多站点工作的情况。因此,最近我对如何使杂乱且损坏的配置重新进入工作状态有了很多的了解。到目前为止,只有几种方法可以解决这种情况,我将尝试在这里解决。

硬分割

“硬拆分”是每个站点成为其自己的拆分的位置,没有默认配置的概念。这也许是最容易创建的,但是它的确意味着将站点与其余站点的配置分开。缺点是,如果要在所有站点上部署一些通用配置,则需要在事后将其手动应用于硬拆分站点。

要使此工作正常进行,只需一次设置每个站点,然后使用drush cex导出其配置。然后,您采用此配置并将其复制到站点配置目录。

然后,您创建配置拆分,该拆分将站点上的所有配置都列入黑名单。您可以通过在配置拆分管理区域中选择所有模块和所有其他活动配置来执行此操作。

完成后,您应该拥有一个主配置目录,其中仅包含您的配置拆分设置和站点的一系列目录。由于每个站点都有其配置,因此您不能再创建“默认”配置。如果您尝试执行此操作,则会发现配置拆分模块将在导出站点的配置时连续删除您的默认配置。

合并拆分

这需要从两个(或多个)站点中获取配置,并将它们组合在一起以创建默认配置。这意味着每个站点只需要覆盖它需要自定义的内容。

这听起来很容易,但是如果您要从此站点进行操作,那么设置和设置起来就更加复杂了。一旦站点的配置不同步(或不存在),就需要解决一些问题以使其恢复正常状态。

一般来说,记住一个“默认”网站是一个非常好的主意。该站点将用作父配置,其他站点将偏离或遵循该站点。理想情况下,您需要使用一个现有站点并使用它,但是您可以生成一个默认站点并使用它来运行。

也许最重要的事情就是对配置进行 手动调整 。例如,如果一个站点启用了模块,但所有其他站点均未启用该模块,则这些站点将更加相似。当查看内容相关的配置(例如内容类型或字段)时,这可能会变得很复杂。如果需要,请进行一些内容编辑/删除,以便您可以编辑/删除相关的内容类型或字段。在极端的示例中,您可以将内容从一种类型迁移到另一种类型,以使此工作正常进行,但应努力实现统一配置。这样做时请记住父站点,如果可能,请尝试使内容与父站点保持一致。

调整配置后,您应该将所有配置导出到单独的目录中,就像在硬拆分策略中一样。唯一的区别在于,配置拆分文件现在应该保持默认状态。

完成之后,就可以开始合并配置了。这是通过查看每个站点中的配置并确定应该执行的操作来完成的。然后,您可以采取一些不同的措施。

  • 如果配置存在于一个站点中,而不存在于其他任何站点中,则将其保留下来,然后将其添加到该站点的配置拆分黑名单中。

  • 如果配置存在于所有站点中,并且它们之间没有区别,则可以将配置放在默认配置区域中。然后可以从所有站点中删除该配置。

  • 如果站点中存在该配置,并且该配置不同,则将该配置添加到受影响站点的配置拆分灰色列表中,并使用默认配置进行复制。

  • 如果配置存在于站点中,并且唯一的区别是uuid,那么我们需要区别对待。站点使用uuid来标识站点中的配置,因此,如果不更改该uuid,将无法移动它。合并此配置的方法是移动文件,然后将主站点uuid用作所有其他站点的新uuid。这可以通过使用更新挂钩来完成,该挂钩可以添加到安装配置文件或模块中,以便在配置导入完成之前被触发。

这是可能生成的更新挂钩的示例。

<?php
 
/**
 * 修复某些配置上的uuid信息。
 */
function my_module_update_8001() {
  $fieldChanges = [
    'node.type.landing_page' => '2034e796-4d2c-43f0-9135-1afc93052380',
  ];
 
  foreach ($fieldChanges as $field => $uuid) {
    $config = \Drupal::service('config.factory')->getEditable($field);
    $config->set('uuid', $uuid)->save();
  }
}

这仅显示了单个配置文件的更改,但是真正的Drupal站点可能会在此处包含数百个条目。

这的最后一步是允许站点忽略不需要的任何配置。您可以使用“配置忽略”模块来执行此操作,该模块使站点可以忽略配置的某些部分。此列表看起来很难放在一起,但是通过尝试在现场导入配置,您可以看到将要导入的新配置。然后,您可以从此列表中创建一个配置忽略文件,其中包含默认情况下存在但站点中不存在的每项配置。

这是一个配置忽略文件的示例,该文件将阻止安装名为“新闻”的内容类型。这是一个愚蠢的示例,因为它没有考虑此内容类型的字段或存储,一个真正的忽略文件可能会有50多个条目。

ignored_config_entities:
  0: node.type.news
_core:
  default_config_hash: ...

通过此操作,我们可以创建另一个更新挂钩,该挂钩将在特定站点上安装配置忽略文件。这与该站点的配置拆分的当前状态有关,因为我们不想意外地将此忽略项安装到其他站点。

/**
 *强制导入站点的配置忽略配置。
 */
function my_module_update_8002() {
  global $config;
  if ($config['config_split.config_split.thesite']['status'] == TRUE) {
    $config_path = realpath('../config/thesite');
    $source = new FileStorage($config_path);
    $config_storage = \Drupal::service('config.storage');
    $config_storage->write('config_ignore.settings', $source->read('config_ignore.settings'));
  }
}

手动找出所有这些可能要花费许多小时,并且最终会导致挫败感。这就是为什么我开始创建一个工具来自动执行此操作的原因。配置拆分合并是在我发现自己盯着一个巨大的配置问题并需要一种快速解决它的方法时创建的。当时我只有两个站点可以使用,因此该工具目前仅适用于两种配置。我计划更新该工具,以考虑到许多不同的站点,并且还将合并配置忽略。

什么对您有用?

因此,我在这里经历了几个不同的示例,但是我非常热衷于看看其他人如何解决了与此类似的问题。我使用这两种方法来设置现在可用的现有站点。

我也很担心为什么我看到如此多的Drupal网站设置。我知道要使多站点设置正常工作很复杂,但是所有内容都内置在Drupal中才能使工作正常。我计划再写一些关于Drupal配置的文章,以展示它如何与我一起工作。