diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php index f801c28..4a3b896 100644 --- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php +++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php @@ -6,17 +6,12 @@ */ namespace Drupal\Core\Config\Schema; - -use \ArrayAccess; -use \ArrayIterator; -use \Countable; -use \IteratorAggregate; -use \Traversable; +use Drupal\Core\TypedData\TraversableTypedDataInterface; /** * Defines a generic configuration element that contains multiple properties. */ -abstract class ArrayElement extends Element implements IteratorAggregate, ArrayAccess, Countable { +abstract class ArrayElement extends Element implements \IteratorAggregate, TraversableTypedDataInterface, \ArrayAccess, \Countable { /** * Parsed elements. @@ -26,8 +21,8 @@ /** * Gets an array of contained elements. * - * @return array - * Array of \Drupal\Core\Config\Schema\ArrayElement objects. + * @return \Drupal\Core\TypedData\TypedDataInterface[] + * An array of elements contained in this element. */ protected function getElements() { if (!isset($this->elements)) { @@ -49,8 +44,8 @@ protected function getAllKeys() { /** * Builds an array of contained elements. * - * @return array - * Array of \Drupal\Core\Config\Schema\ArrayElement objects. + * @return \Drupal\Core\TypedData\TypedDataInterface + * An array of elements contained in this element. */ protected abstract function parse(); @@ -111,7 +106,7 @@ public function count() { * Implements IteratorAggregate::getIterator(); */ public function getIterator() { - return new ArrayIterator($this->getElements()); + return new \ArrayIterator($this->getElements()); } } diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php index 4d2bd11..0fccd47 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php @@ -9,6 +9,7 @@ use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\TypedData\PrimitiveInterface; +use Drupal\Core\TypedData\TraversableTypedDataInterface; use Drupal\Core\TypedData\Type\BooleanInterface; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\Core\TypedData\Type\FloatInterface; @@ -108,7 +109,7 @@ protected function checkValue($key, $value) { } else { $errors = array(); - if (!$element instanceof ArrayElement) { + if (!$element instanceof TraversableTypedDataInterface) { $errors[$error_key] = 'Non-scalar value but not defined as an array (such as mapping or sequence).'; } diff --git a/core/lib/Drupal/Core/Config/Schema/Sequence.php b/core/lib/Drupal/Core/Config/Schema/Sequence.php index e5b6a35..630bb50 100644 --- a/core/lib/Drupal/Core/Config/Schema/Sequence.php +++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php @@ -22,7 +22,7 @@ class Sequence extends ArrayElement implements ListInterface { protected $itemDefinition; /** - * Overrides ArrayElement::parse() + * {@inheritdoc} */ protected function parse() { // Creates a new data definition object for each item from the generic type diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php index 1397485..0a5b38a 100644 --- a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php @@ -23,7 +23,7 @@ * * @ingroup typed_data */ -interface ComplexDataInterface extends \Traversable, TypedDataInterface { +interface ComplexDataInterface extends TraversableTypedDataInterface { /** * Gets a property object. diff --git a/core/lib/Drupal/Core/TypedData/ListInterface.php b/core/lib/Drupal/Core/TypedData/ListInterface.php index ce59dfb..2c5dbc7 100644 --- a/core/lib/Drupal/Core/TypedData/ListInterface.php +++ b/core/lib/Drupal/Core/TypedData/ListInterface.php @@ -20,7 +20,7 @@ * * @ingroup typed_data */ -interface ListInterface extends TypedDataInterface, \ArrayAccess, \Countable, \Traversable { +interface ListInterface extends TraversableTypedDataInterface, \ArrayAccess, \Countable { /** * Determines whether the list contains any non-empty items. diff --git a/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php new file mode 100644 index 0000000..d42557e --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php @@ -0,0 +1,13 @@ +parent = $parent; $this->name = $name; } diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php index 74d083f..7b038e5 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -26,7 +26,7 @@ * @param string|null $name * (optional) The name of the created property, or NULL if it is the root * of a typed data tree. Defaults to NULL. - * @param \Drupal\Core\TypedData\TypedDataInterface $parent + * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $parent * (optional) The parent object of the data property, or NULL if it is the * root of a typed data tree. Defaults to NULL. * @@ -36,7 +36,7 @@ * * @see \Drupal\Core\TypedData\TypedDataManager::create() */ - public static function createInstance($definition, $name = NULL, TypedDataInterface $parent = NULL); + public static function createInstance($definition, $name = NULL, TraversableTypedDataInterface $parent = NULL); /** * Gets the data definition. @@ -122,7 +122,7 @@ public function getName(); /** * Returns the parent data structure; i.e. either complex data or a list. * - * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface + * @return \Drupal\Core\TypedData\TraversableTypedDataInterface|null * The parent data structure, either complex data or a list; or NULL if this * is the root of the typed data tree. */ @@ -134,7 +134,7 @@ public function getParent(); * Returns the root data for a tree of typed data objects; e.g. for an entity * field item the root of the tree is its parent entity object. * - * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface + * @return \Drupal\Core\TypedData\TraversableTypedDataInterface * The root data structure, either complex data or a list. */ public function getRoot(); @@ -159,9 +159,9 @@ public function getPropertyPath(); * @param string|null $name * (optional) The name of the property or the delta of the list item, * or NULL if it is the root of a typed data tree. Defaults to NULL. - * @param \Drupal\Core\TypedData\TypedDataInterface|null $parent + * @param \Drupal\Core\TypedData\TraversableTypedDataInterface|null $parent * (optional) The parent object of the data property, or NULL if it is the * root of a typed data tree. Defaults to NULL. */ - public function setContext($name = NULL, TypedDataInterface $parent = NULL); + public function setContext($name = NULL, TraversableTypedDataInterface $parent = NULL); } diff --git a/core/modules/config_translation/src/ConfigMapperManager.php b/core/modules/config_translation/src/ConfigMapperManager.php index 9a0b46e..09b6498 100644 --- a/core/modules/config_translation/src/ConfigMapperManager.php +++ b/core/modules/config_translation/src/ConfigMapperManager.php @@ -10,7 +10,6 @@ use Drupal\Component\Utility\String; use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException; use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\Config\Schema\ArrayElement; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ThemeHandlerInterface; @@ -20,6 +19,7 @@ use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; use Drupal\Core\Plugin\Factory\ContainerFactory; +use Drupal\Core\TypedData\TraversableTypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface; use Symfony\Component\Routing\RouteCollection; @@ -176,7 +176,7 @@ public function hasTranslatable($name) { protected function findTranslatable(TypedDataInterface $element) { // In case this is a sequence or a mapping check whether any child element // is translatable. - if ($element instanceof ArrayElement) { + if ($element instanceof TraversableTypedDataInterface) { foreach ($element as $child_element) { if ($this->findTranslatable($child_element)) { return TRUE; diff --git a/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php b/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php index c28b663..cdf89b5 100644 --- a/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php +++ b/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php @@ -170,9 +170,12 @@ protected function getElement(array $definition) { * A nested schema element, containing the passed-in elements. */ protected function getNestedElement(array $elements) { - // ConfigMapperManager::findTranslatable() checks for the abstract class - // \Drupal\Core\Config\Schema\ArrayElement, but mocking that directly does - // not work. + // ConfigMapperManager::findTranslatable() checks for + // \Drupal\Core\TypedData\TraversableTypedDataInterface, but mocking that + // directly does not work, because we need to implement \IteratorAggregate + // in order for getIterator() to be called. Therefore we need to mock + // \Drupal\Core\Config\Schema\ArrayElement, but that is abstract, so we + // need to mock one of the subclasses of it. $nested_element = $this->getMockBuilder('Drupal\Core\Config\Schema\Mapping') ->disableOriginalConstructor() ->getMock(); diff --git a/core/modules/locale/src/LocaleTypedConfig.php b/core/modules/locale/src/LocaleTypedConfig.php index ab373fe..ee0b470 100644 --- a/core/modules/locale/src/LocaleTypedConfig.php +++ b/core/modules/locale/src/LocaleTypedConfig.php @@ -10,8 +10,9 @@ use Drupal\Core\TypedData\ContextAwareInterface; use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\Config\Schema\Element; -use Drupal\Core\Config\Schema\ArrayElement; use Drupal\Core\Config\TypedConfigManagerInterface; +use Drupal\Core\TypedData\TraversableTypedDataInterface; +use Drupal\Core\TypedData\TypedDataInterface; /** * Defines the locale configuration wrapper object. @@ -114,9 +115,8 @@ protected function canTranslate($from_langcode, $to_langcode) { /** * Gets translated configuration data for a typed configuration element. * - * @param mixed $element - * Typed configuration element, either \Drupal\Core\Config\Schema\Element or - * \Drupal\Core\Config\Schema\ArrayElement. + * @param \Drupal\Core\TypedData\TypedDataInterface $element + * Typed configuration element. * @param array $options * Array with translation options that must contain the keys defined in * \Drupal\locale\LocaleTypedConfig::translateElement(). @@ -125,9 +125,9 @@ protected function canTranslate($from_langcode, $to_langcode) { * Configuration data translated to the requested language if available, * an empty array otherwise. */ - protected function getElementTranslation($element, array $options) { + protected function getElementTranslation(TypedDataInterface $element, array $options) { $translation = array(); - if ($element instanceof ArrayElement) { + if ($element instanceof TraversableTypedDataInterface) { $translation = $this->getArrayTranslation($element, $options); } elseif ($this->translateElement($element, $options)) { @@ -137,9 +137,9 @@ protected function getElementTranslation($element, array $options) { } /** - * Gets translated configuration data for an element of type ArrayElement. + * Gets translated configuration data for a traversable element. * - * @param \Drupal\Core\Config\Schema\ArrayElement $element + * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $element * Typed configuration array element. * @param array $options * Array with translation options that must contain the keys defined in @@ -148,7 +148,7 @@ protected function getElementTranslation($element, array $options) { * @return array * Configuration data translated to the requested language. */ - protected function getArrayTranslation(ArrayElement $element, array $options) { + protected function getArrayTranslation(TraversableTypedDataInterface $element, array $options) { $translation = array(); foreach ($element as $key => $property) { $value = $this->getElementTranslation($property, $options); @@ -179,7 +179,7 @@ protected function getArrayTranslation(ArrayElement $element, array $options) { * @return bool * Whether the element fits the translation criteria. */ - protected function translateElement(\Drupal\Core\TypedData\TypedDataInterface $element, array $options) { + protected function translateElement(TypedDataInterface $element, array $options) { if ($this->canTranslate($options['source'], $options['target'])) { $definition = $element->getDataDefinition(); $value = $element->getValue();