diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php index 7419a15..a3f1cda 100644 --- a/core/modules/filter/src/Entity/FilterFormat.php +++ b/core/modules/filter/src/Entity/FilterFormat.php @@ -14,6 +14,7 @@ use Drupal\filter\FilterFormatInterface; use Drupal\filter\FilterPluginCollection; use Drupal\filter\Plugin\FilterInterface; +use Drupal\user\RoleInterface; /** * Represents a text format. @@ -427,6 +428,27 @@ public function onDependencyRemoval(array $dependencies) { /** * {@inheritdoc} */ + public function calculateDependencies() { + parent::calculateDependencies(); + + // The permission name is FALSE when this is a fallback text format and that + // doesn't depend on any user role. + if (!$permission = $this->getPermissionName()) { + return $this->dependencies; + } + $roles = user_roles(TRUE, $permission); + // Filter out 'authenticated' role. + unset($roles[RoleInterface::AUTHENTICATED_ID]); + foreach ($roles as $rid => $role) { + $this->addDependency($role->getConfigDependencyKey(), $role->getConfigDependencyName()); + } + + return $this->dependencies; + } + + /** + * {@inheritdoc} + */ protected function calculatePluginDependencies(PluginInspectionInterface $instance) { // Only add dependencies for plugins that are actually configured. This is // necessary because the filter plugin collection will return all available diff --git a/core/modules/filter/src/Tests/FilterSettingsTest.php b/core/modules/filter/src/Tests/FilterSettingsTest.php index 9b95336..21320a2 100644 --- a/core/modules/filter/src/Tests/FilterSettingsTest.php +++ b/core/modules/filter/src/Tests/FilterSettingsTest.php @@ -7,7 +7,10 @@ namespace Drupal\filter\Tests; +use Drupal\Component\Utility\Unicode; +use Drupal\filter\Entity\FilterFormat; use Drupal\simpletest\KernelTestBase; +use Drupal\user\Entity\Role; /** * Tests filter settings. @@ -21,7 +24,7 @@ class FilterSettingsTest extends KernelTestBase { * * @var array */ - public static $modules = array('filter'); + public static $modules = ['filter', 'user', 'system']; /** * Tests explicit and implicit default settings for filters. @@ -62,4 +65,75 @@ function testFilterDefaults() { ))); } } + + /** + * Tests dependencies. + */ + public function testDependencies() { + /** @var \Drupal\Core\Config\ConfigFactoryInterface $factory */ + $factory = $this->container->get('config.factory'); + $this->installEntitySchema('user'); + + // Create a text formats. + /** @var \Drupal\filter\FilterFormatInterface $format */ + $format = FilterFormat::create([ + 'format' => Unicode::strtolower($this->randomMachineName()), + 'name' => $this->randomString(), + ]); + + // Create 2 arbitrary roles allowed to use the text format $format. + /** @var \Drupal\user\RoleInterface[] $roles */ + $roles = []; + for ($i = 0; $i < 2; $i++) { + $roles[$i] = Role::create([ + 'id' => Unicode::strtolower($this->randomMachineName()), + 'label' => $this->randomString(), + 'permissions' => [$format->getPermissionName()], + ]); + $roles[$i]->save(); + } + + // Save the format. + $format->save(); + + // The format should be dependent on both role config entities. + $dependencies = $format->getDependencies()['config']; + $this->assertIdentical(count($dependencies), 2); + $this->assertTrue(in_array($roles[0]->getConfigDependencyName(), $dependencies)); + $this->assertTrue(in_array($roles[1]->getConfigDependencyName(), $dependencies)); + + // Mark this text format as fallback format. + $settings = $factory->getEditable('filter.settings'); + $settings->set('fallback_format', $format->id())->save(); + + // Recalculate dependencies by saving the text format. + $format->save(); + + // The format should not depend anymore on the two roles because now this + // text format is the fallback format. + $this->assertTrue(empty($format->getDependencies()['config'])); + + // Set the fallback format to different format. + $settings + ->set('fallback_format', Unicode::strtolower($this->randomMachineName())) + ->save(); + $format->save(); + + // The format should be again dependent on both role config entities. + $dependencies = $format->getDependencies()['config']; + $this->assertIdentical(count($dependencies), 2); + $this->assertTrue(in_array($roles[0]->getConfigDependencyName(), $dependencies)); + $this->assertTrue(in_array($roles[1]->getConfigDependencyName(), $dependencies)); + + // Delete the second role. + $roles[1]->delete(); + $format->save(); + + // The format should be dependent only on first role. + $dependencies = $format->getDependencies()['config']; + $this->assertIdentical(count($dependencies), 1); + $this->assertTrue(in_array($roles[0]->getConfigDependencyName(), $dependencies)); + $this->assertFalse(in_array($roles[1]->getConfigDependencyName(), $dependencies)); + } + }