diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index 2032f4c..d8b035e 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -141,7 +141,12 @@ public function createInstance($data_type, array $configuration = array()) { if (!isset($class)) { throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type)); } - return new $class($data_definition, $configuration['name'], $configuration['parent']); + if (in_array('Drupal\Core\Plugin\ContainerFactoryPluginInterface', class_implements($class))) { + return $class::create(\Drupal::getContainer(), $data_definition, $configuration['name'], $configuration['parent']); + } + else { + return new $class($data_definition, $configuration['name'], $configuration['parent']); + } } /** diff --git a/core/lib/Drupal/Core/DependencyInjection/DependencySerialization.php b/core/lib/Drupal/Core/DependencyInjection/DependencySerialization.php index 256ce74..c167555 100644 --- a/core/lib/Drupal/Core/DependencyInjection/DependencySerialization.php +++ b/core/lib/Drupal/Core/DependencyInjection/DependencySerialization.php @@ -31,7 +31,7 @@ public function __sleep() { // If a class member was instantiated by the dependency injection // container, only store its ID so it can be used to get a fresh object // on unserialization. - $this->_serviceIds[$key] = $value->_serviceId; + $this->_serviceIds += array($key => $value->_serviceId); unset($vars[$key]); } // Special case the container, which might not have a service ID. diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index 481eebe..f7b94f0 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -126,7 +126,7 @@ public function get($property_name) { $value = $this->values[$property_name]; } // If the property is unknown, this will throw an exception. - $this->properties[$property_name] = \Drupal::typedDataManager()->getPropertyInstance($this, $property_name, $value); + $this->properties[$property_name] = $this->typedDataManager->getPropertyInstance($this, $property_name, $value); } return $this->properties[$property_name]; } diff --git a/core/lib/Drupal/Core/TypedData/TypedData.php b/core/lib/Drupal/Core/TypedData/TypedData.php index fce21d9..97e7825 100644 --- a/core/lib/Drupal/Core/TypedData/TypedData.php +++ b/core/lib/Drupal/Core/TypedData/TypedData.php @@ -8,6 +8,10 @@ namespace Drupal\Core\TypedData; use Drupal\Component\Plugin\PluginInspectionInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\TypedData\TypedDataManager; +use Drupal\Core\DependencyInjection\DependencySerialization; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * The abstract base class for typed data. @@ -15,7 +19,7 @@ * Classes deriving from this base class have to declare $value * or override getValue() or setValue(). */ -abstract class TypedData implements TypedDataInterface, PluginInspectionInterface { +abstract class TypedData extends DependencySerialization implements TypedDataInterface, PluginInspectionInterface, ContainerFactoryPluginInterface { /** * The data definition. @@ -39,6 +43,13 @@ protected $parent; /** + * The typed data plugin manager. + * + * @var \Drupal\Core\TypedData\TypedDataManager + */ + protected $typedDataManager; + + /** * Constructs a TypedData object given its definition and context. * * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition @@ -49,6 +60,8 @@ * @param \Drupal\Core\TypedData\TypedDataInterface $parent * (optional) The parent object of the data property, or NULL if it is the * root of a typed data tree. Defaults to NULL. + * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager + * The typed data plugin manager. * * @see \Drupal\Core\TypedData\TypedDataManager::create() * @@ -56,10 +69,38 @@ * class-based definitions, type-hint $definition to * DataDefinitionInterface. https://drupal.org/node/1928868 */ - public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager = NULL) { $this->definition = $definition; $this->parent = $parent; $this->name = $name; + $this->typedDataManager = $typed_data_manager; + } + + /** + * Creates an instance of the plugin. + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container + * The container to pull out services used in the plugin. + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin ID for the plugin instance. + * @param array $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\TypedData\TypedDataInterface $parent + * (optional) The parent object of the data property, or NULL if it is the + * root of a typed data tree. Defaults to NULL. + * + * @return static + * Returns an instance of this plugin. + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, TypedDataInterface $parent = NULL) { + return new static( + $plugin_definition, + $plugin_id, + $parent, + $container->get('typed_data_manager') + ); } /** @@ -73,7 +114,7 @@ public function getPluginId() { * {@inheritdoc} */ public function getPluginDefinition() { - return \Drupal::typedDataManager()->getDefinition($this->definition->getDataType()); + return $this->typedDataManager->getDefinition($this->definition->getDataType()); } /** @@ -112,8 +153,7 @@ public function getString() { * {@inheritdoc} */ public function getConstraints() { - // @todo: Add the typed data manager as proper dependency. - $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager(); + $constraint_manager = $this->typedDataManager->getValidationConstraintManager(); $constraints = array(); foreach ($this->definition->getConstraints() as $name => $options) { $constraints[] = $constraint_manager->create($name, $options); @@ -125,8 +165,7 @@ public function getConstraints() { * {@inheritdoc} */ public function validate() { - // @todo: Add the typed data manager as proper dependency. - return \Drupal::typedDataManager()->getValidator()->validate($this); + return $this->typedDataManager->getValidator()->validate($this); } /** @@ -188,4 +227,5 @@ public function getPropertyPath() { public function getParent() { return $this->parent; } + } diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index 024eaeb..0d03a8a 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -98,7 +98,13 @@ public function createInstance($data_type, array $configuration = array()) { if (!isset($class)) { throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type)); } - return new $class($data_definition, $configuration['name'], $configuration['parent']); + + if (in_array('Drupal\Core\Plugin\ContainerFactoryPluginInterface', class_implements($class))) { + return $class::create(\Drupal::getContainer(), $data_definition, $configuration['name'], $configuration['parent']); + } + else { + return new $class($data_definition, $configuration['name'], $configuration['parent']); + } } /** diff --git a/core/modules/locale/src/LocaleTypedConfig.php b/core/modules/locale/src/LocaleTypedConfig.php index dd24d99..36e39a9 100644 --- a/core/modules/locale/src/LocaleTypedConfig.php +++ b/core/modules/locale/src/LocaleTypedConfig.php @@ -8,6 +8,7 @@ namespace Drupal\locale; use Drupal\Core\TypedData\ContextAwareInterface; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\Config\Schema\Element; use Drupal\Core\Config\Schema\ArrayElement; @@ -49,7 +50,7 @@ class LocaleTypedConfig extends Element { * @param \Drupal\locale\LocaleConfigManager $localeConfig; * The locale configuration manager object. */ - public function __construct($definition, $name, $langcode, LocaleConfigManager $localeConfig) { + public function __construct(DataDefinitionInterface $definition, $name, $langcode, LocaleConfigManager $localeConfig) { parent::__construct($definition, $name); $this->langcode = $langcode; $this->localeConfig = $localeConfig; diff --git a/core/modules/text/src/TextProcessed.php b/core/modules/text/src/TextProcessed.php index 3666d29..f740f9b 100644 --- a/core/modules/text/src/TextProcessed.php +++ b/core/modules/text/src/TextProcessed.php @@ -28,7 +28,7 @@ class TextProcessed extends TypedData { protected $processed = NULL; /** - * Overrides TypedData::__construct(). + * {@inheritdoc} */ public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) { parent::__construct($definition, $name, $parent);