diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index 896b08e..c43ad8d 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -123,7 +123,12 @@ public function createInstance($plugin_id, array $configuration, $name = NULL, $ if (!isset($class)) { throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id)); } - return new $class($configuration, $name, $parent); + if (class_implements($class, '\Drupal\Core\Plugin\ContainerFactoryPluginInterface')) { + return $class::create(\Drupal::getContainer(), $configuration, $name, $type_definition, $parent); + } + else { + return new $class($configuration, $name, $parent); + } } /** diff --git a/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php index 0ff36d7..a8eea56 100644 --- a/core/lib/Drupal/Core/Entity/Field/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Field.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\Field\FieldInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\Core\TypedData\ItemList; /** @@ -39,8 +40,8 @@ class Field extends ItemList implements FieldInterface { /** * Overrides TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { - parent::__construct($definition, $name, $parent); + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager) { + parent::__construct($definition, $name, $parent, $typed_data_manager); // Always initialize one empty item as most times a value for at least one // item will be present. That way prototypes created by // \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance() will diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index c51d5a1..076fde8 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\TypedData\Plugin\DataType\Map; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\user; /** @@ -25,8 +26,8 @@ /** * Overrides \Drupal\Core\TypedData\TypedData::__construct(). */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { - parent::__construct($definition, $name, $parent); + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager) { + parent::__construct($definition, $name, $parent, $typed_data_manager); // Initialize computed properties by default, such that they get cloned // with the whole item. foreach ($this->getPropertyDefinitions() as $name => $definition) { diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 86b43f5..ea07e2e 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -13,7 +13,7 @@ /** * Class responsible for initializing each language type. */ -class LanguageManager { +class LanguageManager implements \Serializable { /** * A request object. @@ -302,4 +302,26 @@ public static function getStandardLanguageList() { ); } + /** + * {@inheritdoc} + */ + public function serialize() { + $manager = clone $this; + // Clear the request file bag. + if (!empty($manager->request->files)) { + $manager->request->files->replace(array()); + } + return serialize(get_object_vars($manager)); + } + + /** + * {@inheritdoc} + */ + public function unserialize($serialized) { + $data = unserialize($serialized); + foreach ($data as $key => $value) { + $this->{$key} = $value; + } + } + } diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index 180003c..f91aca6 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -122,7 +122,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::typedData()->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 f54f8ed..4598141 100644 --- a/core/lib/Drupal/Core/TypedData/TypedData.php +++ b/core/lib/Drupal/Core/TypedData/TypedData.php @@ -8,6 +8,9 @@ namespace Drupal\Core\TypedData; use Drupal\Component\Plugin\PluginInspectionInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\TypedData\TypedDataManager; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * The abstract base class for typed data. @@ -15,7 +18,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 implements TypedDataInterface, PluginInspectionInterface, ContainerFactoryPluginInterface { /** * The data definition. @@ -39,6 +42,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 array $definition @@ -49,13 +59,43 @@ * @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() */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager) { $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, array $plugin_definition, TypedDataInterface $parent = NULL) { + return new static( + $configuration, + $plugin_id, + $parent, + $container->get('typed_data') + ); } /** @@ -76,7 +116,7 @@ public function getPluginId() { * {@inheritdoc} */ public function getPluginDefinition() { - return \Drupal::typedData()->getDefinition($this->definition['type']); + return $this->typedDataManager->getDefinition($this->definition['type']); } /** @@ -115,16 +155,14 @@ public function getString() { * Implements \Drupal\Core\TypedData\TypedDataInterface::getConstraints(). */ public function getConstraints() { - // @todo: Add the typed data manager as proper dependency. - return \Drupal::typedData()->getConstraints($this->definition); + return $this->typedDataManager->getConstraints($this->definition); } /** * Implements \Drupal\Core\TypedData\TypedDataInterface::validate(). */ public function validate() { - // @todo: Add the typed data manager as proper dependency. - return \Drupal::typedData()->getValidator()->validate($this); + return $this->typedDataManager->getValidator()->validate($this); } /** diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index f217fa5..671e0b3 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -93,7 +93,12 @@ public function createInstance($plugin_id, array $configuration, $name = NULL, $ if (!isset($class)) { throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id)); } - return new $class($configuration, $name, $parent); + if (class_implements($class, '\Drupal\Core\Plugin\ContainerFactoryPluginInterface')) { + return $class::create(\Drupal::getContainer(), $configuration, $name, $type_definition, $parent); + } + else { + return new $class($configuration, $name, $parent); + } } /** diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php index 29ce028..eb3db42 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php @@ -8,6 +8,7 @@ namespace Drupal\field\Plugin\Type\FieldType; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\Core\Entity\Field\Field; use Drupal\field\Field as FieldAPI; @@ -26,8 +27,8 @@ class ConfigField extends Field implements ConfigFieldInterface { /** * {@inheritdoc} */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { - parent::__construct($definition, $name, $parent); + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager) { + parent::__construct($definition, $name, $parent, $typed_data_manager); if (isset($definition['instance'])) { $this->instance = $definition['instance']; } diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php index 8cba49a..e0b7e2c 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php @@ -10,6 +10,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Config\TypedConfigManager; use Drupal\Core\Config\StorageInterface; +use Drupal\Core\TypedData\TypedDataManager; /** * Manages localized configuration type plugins. @@ -36,6 +37,14 @@ class LocaleConfigManager extends TypedConfigManager { protected $translations; /** + * The typed data plugin manager. + * + * @var \Drupal\Core\TypedData\TypedDataManager + */ + protected $typedDataManager; + + + /** * Creates a new typed configuration manager. * * @param \Drupal\Core\Config\StorageInterface $configStorage @@ -47,12 +56,15 @@ class LocaleConfigManager extends TypedConfigManager { * data. * @param \Drupal\locale\StringStorageInterface $localeStorage * The locale storage to use for reading string translations. + * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager + * The typed data manager service. */ - public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage) { + public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage, TypedDataManager $typed_data_manager) { // Note we use the install storage for the parent constructor. parent::__construct($configStorage, $schemaStorage); $this->installStorage = $installStorage; $this->localeStorage = $localeStorage; + $this->typedDataManager = $typed_data_manager; } /** @@ -73,7 +85,7 @@ public function get($name) { $definition = $this->getDefinition($name); // Unless the configuration has a explicit language code we assume English. $langcode = isset($default['langcode']) ? $default['langcode'] : 'en'; - $wrapper = new LocaleTypedConfig($definition, $name, $langcode, $this); + $wrapper = new LocaleTypedConfig($definition, $name, $langcode, $this, $this->typedDataManager); $wrapper->setValue($data); return $wrapper; } diff --git a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php index 5d6b200..226d104 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php @@ -9,6 +9,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\TypedData\ContextAwareInterface; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\Core\Config\Schema\Element; use Drupal\Core\Config\Schema\ArrayElement; @@ -49,9 +50,11 @@ class LocaleTypedConfig extends Element { * Language code for the source configuration data. * @param \Drupal\locale\LocaleConfigManager $localeConfig; * The locale configuration manager object. + * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager + * The typed data plugin manager. */ - public function __construct(array $definition, $name, $langcode, \Drupal\locale\LocaleConfigManager $localeConfig) { - parent::__construct($definition, $name); + public function __construct(array $definition, $name, $langcode, \Drupal\locale\LocaleConfigManager $localeConfig, TypedDataManager $typed_data_manager) { + parent::__construct($definition, $name, NULL, $typed_data_manager); $this->langcode = $langcode; $this->localeConfig = $localeConfig; } diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml index f632704..64dc3fc 100644 --- a/core/modules/locale/locale.services.yml +++ b/core/modules/locale/locale.services.yml @@ -6,7 +6,7 @@ services: arguments: ['@language_manager', '@config.context'] locale.config.typed: class: Drupal\locale\LocaleConfigManager - arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage'] + arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage', '@typed_data'] locale.storage: class: Drupal\locale\StringDatabaseStorage arguments: ['@database'] diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php index 9a1910f..c2638b9 100644 --- a/core/modules/text/lib/Drupal/text/TextProcessed.php +++ b/core/modules/text/lib/Drupal/text/TextProcessed.php @@ -9,6 +9,7 @@ use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedData; +use Drupal\Core\TypedData\TypedDataManager; use Drupal\Core\TypedData\ReadOnlyException; use InvalidArgumentException; @@ -35,10 +36,10 @@ class TextProcessed extends TypedData { protected $format; /** - * Overrides TypedData::__construct(). + * {@inheritdoc} */ - public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL) { - parent::__construct($definition, $name, $parent); + public function __construct(array $definition, $name = NULL, TypedDataInterface $parent = NULL, TypedDataManager $typed_data_manager) { + parent::__construct($definition, $name, $parent, $typed_data_manager); if (!isset($definition['settings']['text source'])) { throw new InvalidArgumentException("The definition's 'source' key has to specify the name of the text property to be processed.");