diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index 60f214b..eec3035 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -356,7 +356,7 @@ field.formatter.settings.entity_reference_label: type: boolean label: 'Link label to the referenced entity' -bundle_config_entity: +bundle_entity_with_plural_labels: type: config_entity label: 'Bundle' mapping: diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php index ed1fda1..dc17e05 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleBase.php @@ -2,12 +2,8 @@ namespace Drupal\Core\Config\Entity; -use Drupal\Component\Render\FormattableMarkup; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Config\ConfigNameException; use Drupal\Core\Entity\EntityStorageInterface; -use Drupal\Core\StringTranslation\PluralTranslatableMarkup; -use Drupal\Core\StringTranslation\TranslatableMarkup; /** * A base class for config entity types that act as bundles. @@ -15,28 +11,7 @@ * Entity types that want to use this base class must use bundle_of in their * annotation to specify for which entity type they are providing bundles for. */ -abstract class ConfigEntityBundleBase extends ConfigEntityBase implements ConfigEntityBundleInterface { - - /** - * The indefinite singular name of the bundle. - */ - protected $label_singular; - - /** - * The indefinite plural name of the bundle. - * - * @var string - */ - protected $label_plural; - - /** - * A definite singular/plural count label. - * - * Plural variants are separated by EXT (PluralTranslatableMarkup::DELIMITER). - * - * @var string - */ - protected $label_count; +abstract class ConfigEntityBundleBase extends ConfigEntityBase { /** * Deletes display if a bundle is deleted. @@ -91,50 +66,6 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti } /** - * {@inheritdoc} - */ - public function getSingularLabel() { - // Provide a fallback in case label_singular is not set yet. - if (empty($this->label_singular)) { - if ($label = $this->label()) { - $this->label_singular = Unicode::strtolower($label); - } - } - return $this->label_singular; - } - - /** - * {@inheritdoc} - */ - public function getPluralLabel() { - // Provide a fallback in case label_plural is not set yet. - if (empty($this->label_plural)) { - if ($label = $this->label()) { - $arguments = ['@label' => Unicode::strtolower($label)]; - $options = ['langcode' => $this->language()->getId()]; - $this->label_plural = new TranslatableMarkup('@label items', $arguments, $options); - } - } - return $this->label_plural; - } - - /** - * {@inheritdoc} - */ - public function getCountLabel($count) { - $index = $this->getPluralIndex($count); - $label_count = empty($this->label_count) ? [] : explode(PluralTranslatableMarkup::DELIMITER, $this->label_count); - if (isset($label_count[$index])) { - return new FormattableMarkup($label_count[$index], ['@count' => $count]); - } - $arguments = [ - '@singular' => $this->getSingularLabel(), - '@plural' => $this->getPluralLabel(), - ]; - return new PluralTranslatableMarkup($count, '1 @singular', '@count @plural', $arguments); - } - - /** * Acts on an entity before the presave hook is invoked. * * Used before the entity is saved and before invoking the presave hook. @@ -181,31 +112,4 @@ protected function loadDisplays($entity_type_id) { return array(); } - /** - * Gets the plural index through the gettext formula. - * - * @param int $count - * Number to return plural for. - * - * @return int - * The numeric index of the plural variant to use for this $langcode and - * $count combination or -1 if the language was not found or does not have a - * plural formula. - * - * @todo Remove this method and use PluralTranslatableMarkup::getPluralIndex() - * when https://www.drupal.org/node/2766857 gets committed. - */ - protected function getPluralIndex($count) { - // We have to test both if the function and the service exist since in - // certain situations it is possible that locale code might be loaded but - // the service does not exist. For example, where the parent test site has - // locale installed but the child site does not. - // @todo Refactor in https://www.drupal.org/node/2660338 so this code does - // not depend on knowing that the Locale module exists. - if (function_exists('locale_get_plural') && \Drupal::hasService('locale.plural.formula')) { - return locale_get_plural($count); - } - return -1; - } - } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleInterface.php b/core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsInterface.php similarity index 84% rename from core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleInterface.php rename to core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsInterface.php index ac8a6be..a7362d2 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBundleInterface.php +++ b/core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsInterface.php @@ -3,9 +3,9 @@ namespace Drupal\Core\Config\Entity; /** - * Provides an interface for bundle configuration entities. + * Allows bundle configuration entities to support label plural variants. */ -interface ConfigEntityBundleInterface { +interface EntityBundleWithPluralLabelsInterface { /** * Gets the singular label of the bundle. diff --git a/core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsTrait.php b/core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsTrait.php new file mode 100644 index 0000000..180e7cb --- /dev/null +++ b/core/lib/Drupal/Core/Config/Entity/EntityBundleWithPluralLabelsTrait.php @@ -0,0 +1,106 @@ +label_singular)) { + if ($label = $this->label()) { + $this->label_singular = Unicode::strtolower($label); + } + } + return $this->label_singular; + } + + /** + * {@inheritdoc} + */ + public function getPluralLabel() { + // Provide a fallback in case label_plural is not set yet. + if (empty($this->label_plural)) { + if ($label = $this->label()) { + $arguments = ['@label' => Unicode::strtolower($label)]; + $options = ['langcode' => $this->language()->getId()]; + $this->label_plural = new TranslatableMarkup('@label items', $arguments, $options); + } + } + return $this->label_plural; + } + + /** + * {@inheritdoc} + */ + public function getCountLabel($count) { + $index = static::getPluralIndex($count); + $label_count = empty($this->label_count) ? [] : explode(PluralTranslatableMarkup::DELIMITER, $this->label_count); + if (isset($label_count[$index])) { + return new FormattableMarkup($label_count[$index], ['@count' => $count]); + } + $arguments = [ + '@singular' => $this->getSingularLabel(), + '@plural' => $this->getPluralLabel(), + ]; + return new PluralTranslatableMarkup($count, '1 @singular', '@count @plural', $arguments); + } + + /** + * Gets the plural index through the gettext formula. + * + * @param int $count + * Number to return plural for. + * + * @return int + * The numeric index of the plural variant to use for this $langcode and + * $count combination or -1 if the language was not found or does not have a + * plural formula. + * + * @todo Remove this method when https://www.drupal.org/node/2766857 gets in. + */ + protected static function getPluralIndex($count) { + // We have to test both if the function and the service exist since in + // certain situations it is possible that locale code might be loaded but + // the service does not exist. For example, where the parent test site has + // locale installed but the child site does not. + // @todo Refactor in https://www.drupal.org/node/2660338 so this code does + // not depend on knowing that the Locale module exists. + if (function_exists('locale_get_plural') && \Drupal::hasService('locale.plural.formula')) { + return locale_get_plural($count); + } + return -1; + } + +} diff --git a/core/modules/node/config/schema/node.schema.yml b/core/modules/node/config/schema/node.schema.yml index 8cc21c0..14d8939 100644 --- a/core/modules/node/config/schema/node.schema.yml +++ b/core/modules/node/config/schema/node.schema.yml @@ -9,7 +9,7 @@ node.settings: label: 'Use administration theme when editing or creating content' node.type.*: - type: bundle_config_entity + type: bundle_entity_with_plural_labels label: 'Content type' mapping: name: diff --git a/core/modules/node/node.post_update.php b/core/modules/node/node.post_update.php new file mode 100644 index 0000000..5c5d74b --- /dev/null +++ b/core/modules/node/node.post_update.php @@ -0,0 +1,31 @@ +set('label_singular', NULL) + ->set('label_plural', NULL) + ->set('label_count', NULL) + ->save(); + } +} + +/** + * @} End of "addtogroup updates-8.2.x". + */ diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php index 91d8a90..d2ab474 100644 --- a/core/modules/node/src/Entity/NodeType.php +++ b/core/modules/node/src/Entity/NodeType.php @@ -3,6 +3,8 @@ namespace Drupal\node\Entity; use Drupal\Core\Config\Entity\ConfigEntityBundleBase; +use Drupal\Core\Config\Entity\EntityBundleWithPluralLabelsInterface; +use Drupal\Core\Config\Entity\EntityBundleWithPluralLabelsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\node\NodeTypeInterface; @@ -41,10 +43,15 @@ * "new_revision", * "preview_mode", * "display_submitted", + * "label_singular", + * "label_plural", + * "label_count", * } * ) */ -class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface { +class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface, EntityBundleWithPluralLabelsInterface { + + use EntityBundleWithPluralLabelsTrait; /** * The machine name of this node type. diff --git a/core/modules/node/src/Tests/Update/NodeUpdateTest.php b/core/modules/node/src/Tests/Update/NodeUpdateTest.php new file mode 100644 index 0000000..5328a41 --- /dev/null +++ b/core/modules/node/src/Tests/Update/NodeUpdateTest.php @@ -0,0 +1,44 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + ]; + } + + /** + * Tests node_post_update_plural_variants(). + * + * @see node_post_update_plural_variants() + */ + public function testPostUpdatePluralVariants() { + // Check that plural label variant properties are not present. + $node_type = $this->config('node.type.page')->getRawData(); + $this->assertFalse(array_key_exists('label_singular', $node_type)); + $this->assertFalse(array_key_exists('label_plural', $node_type)); + $this->assertFalse(array_key_exists('label_count', $node_type)); + + $this->runUpdates(); + + // Check that plural label variant properties were added as NULL. + $node_type = $this->config('node.type.page')->getRawData(); + $this->assertTrue($node_type['label_singular'] === NULL); + $this->assertTrue($node_type['label_plural'] === NULL); + $this->assertTrue($node_type['label_count'] === NULL); + } + +} diff --git a/core/modules/system/system.module b/core/modules/system/system.module index f34d6b7..2f627be 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -9,7 +9,6 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Cache\Cache; -use Drupal\Core\Config\Entity\ConfigEntityBundleInterface; use Drupal\Core\Queue\QueueGarbageCollectionInterface; use Drupal\Core\Database\Query\AlterableInterface; use Drupal\Core\Extension\Extension; @@ -1417,33 +1416,6 @@ function system_entity_type_build(array &$entity_types) { } /** - * Implements hook_entity_type_alter(). - */ -function system_entity_type_alter(array &$entity_types) { - /** @var Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */ - $typed_config_manager = \Drupal::service('config.typed'); - - /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */ - foreach ($entity_types as $entity_type_id => $entity_type) { - // Automatically add label_singular, label_plural, label_count properties to - // config_export annotation list for bundle entity types that support label - // plural variants. The check is performed by inspecting the bundle entity - // type config schema. - if (is_subclass_of($entity_type->getClass(), ConfigEntityBundleInterface::class)) { - $name = "{$entity_type->getConfigPrefix()}.$entity_type_id"; - $definition = $typed_config_manager->getDefinition($name); - $config_export = $entity_type->get('config_export'); - foreach (['label_singular', 'label_plural', 'label_count'] as $key) { - if (!empty($definition['mapping'][$key]) && !in_array($key, $config_export)) { - $config_export[] = $key; - } - } - $entity_type->set('config_export', $config_export); - } - } -} - -/** * Implements hook_block_view_BASE_BLOCK_ID_alter(). */ function system_block_view_system_main_block_alter(array &$build, BlockPluginInterface $block) {