Commit 7dedb6ca authored by webchick's avatar webchick

Issue #1969572 by neclimdul, larowlan, hussainweb, dawehner, damiankloip,...

Issue #1969572 by neclimdul, larowlan, hussainweb, dawehner, damiankloip, ParisLiakos, pwieck, Berdir, socketwench: Make Uuid a service.
parent b72614fe
......@@ -70,7 +70,7 @@ services:
- { name: persist }
config.context.factory:
class: Drupal\Core\Config\Context\ConfigContextFactory
arguments: ['@event_dispatcher']
arguments: ['@event_dispatcher', '@uuid']
config.context:
class: Drupal\Core\Config\Context\ContextInterface
tags:
......
......@@ -76,7 +76,8 @@ function ($value) use ($name) {
\Drupal::service('event_dispatcher'),
\Drupal::service('config.factory'),
\Drupal::entityManager(),
\Drupal::lock()
\Drupal::lock(),
\Drupal::service('uuid')
);
$installer->import();
}
......
......@@ -375,7 +375,8 @@ function install_begin_request(&$install_state) {
$container->register('config.storage', 'Drupal\Core\Config\InstallStorage');
$container->register('config.context.factory', 'Drupal\Core\Config\Context\ConfigContextFactory')
->addArgument(new Reference('event_dispatcher'));
->addArgument(new Reference('event_dispatcher'))
->addArgument(new Reference('uuid'));
$container->register('config.context', 'Drupal\Core\Config\Context\ContextInterface')
->setFactoryService(new Reference('config.context.factory'))
......@@ -435,6 +436,9 @@ function install_begin_request(&$install_state) {
$container->register('url_generator', 'Drupal\Core\Routing\NullGenerator');
// Register UUID.
CoreServiceProvider::registerUuid($container);
// Register the CSS and JavaScript asset collection renderers.
$container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer');
$container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer');
......
......@@ -582,7 +582,7 @@ function update_prepare_d8_language() {
// Convert languages to config entities.
$result = db_query('SELECT * FROM {language}');
$uuid = new Uuid();
$uuid = \Drupal::service('uuid');
foreach ($result as $language) {
\Drupal::config('language.entity.' . $language->langcode)
->set('id', $language->langcode)
......@@ -1535,7 +1535,7 @@ function update_variables_to_state(array $variable_map) {
* A $primary_key values of rows to be updated.
*/
function update_add_uuids(&$sandbox, $table, $primary_key, $values) {
$uuid = new Uuid();
$uuid = \Drupal::service('uuid');
foreach ($values as $value) {
db_update($table)
->fields(array(
......
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\Component\Uuid\Com.
* Contains \Drupal\Component\Uuid\Com.
*/
namespace Drupal\Component\Uuid;
......
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\Component\Uuid\Pecl.
* Contains \Drupal\Component\Uuid\Pecl.
*/
namespace Drupal\Component\Uuid;
......
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\Component\Uuid\Php.
* Contains \Drupal\Component\Uuid\Php.
*/
namespace Drupal\Component\Uuid;
......@@ -46,4 +46,5 @@ public function generate() {
return $uuid;
}
}
......@@ -2,48 +2,21 @@
/**
* @file
* Definition of Drupal\Component\Uuid\Uuid.
* Contains \Drupal\Component\Uuid\Uuid.
*/
namespace Drupal\Component\Uuid;
/**
* Factory class for UUIDs.
*
* Determines which UUID implementation to use, and uses that to generate
* and validate UUIDs.
* UUID Helper methods.
*/
class Uuid {
/**
* Holds the UUID implementation.
*
* @var Drupal\Component\Uuid\UuidInterface
*/
protected $plugin;
/**
* Instantiates the correct UUID object.
*/
public function __construct() {
$class = $this->determinePlugin();
$this->plugin = new $class();
}
/**
* Generates a universally unique identifier.
*
* @see Drupal\Component\Uuid\UuidInterface::generate()
*/
public function generate() {
return $this->plugin->generate();
}
/**
* Checks that a string appears to be in the format of a UUID.
*
* Plugins should not implement validation, since UUIDs should be in a
* consistent format across all plugins.
* Implementations should not implement validation, since UUIDs should be in
* a consistent format across all implementations.
*
* @param string $uuid
* The string to test.
......@@ -51,37 +24,8 @@ public function generate() {
* @return bool
* TRUE if the string is well formed, FALSE otherwise.
*/
public function isValid($uuid) {
return preg_match("/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/", $uuid);
public static function isValid($uuid) {
return (bool) preg_match("/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/", $uuid);
}
/**
* Determines the optimal implementation to use for generating UUIDs.
*
* The selection is made based on the enabled PHP extensions with the
* most performant available option chosen.
*
* @return string
* The class name for the optimal UUID generator.
*/
protected function determinePlugin() {
static $plugin;
if (!empty($plugin)) {
return $plugin;
}
$plugin = 'Drupal\Component\Uuid\Php';
// Debian/Ubuntu uses the (broken) OSSP extension as their UUID
// implementation. The OSSP implementation is not compatible with the
// PECL functions.
if (function_exists('uuid_create') && !function_exists('uuid_make')) {
$plugin = 'Drupal\Component\Uuid\Pecl';
}
// Try to use the COM implementation for Windows users.
elseif (function_exists('com_create_guid')) {
$plugin = 'Drupal\Component\Uuid\Com';
}
return $plugin;
}
}
......@@ -10,6 +10,7 @@
use Drupal\Core\Config\Context\FreeConfigContext;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Component\Uuid\UuidInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
......@@ -94,6 +95,13 @@ class ConfigImporter {
*/
protected $validated;
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Constructs a configuration import object.
*
......@@ -108,18 +116,21 @@ class ConfigImporter {
* The entity manager used to import config entities.
* @param \Drupal\Core\Lock\LockBackendInterface
* The lock backend to ensure multiple imports do not occur at the same time.
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
* The UUID service.
*/
public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, LockBackendInterface $lock) {
public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, LockBackendInterface $lock, UuidInterface $uuid_service) {
$this->storageComparer = $storage_comparer;
$this->eventDispatcher = $event_dispatcher;
$this->configFactory = $config_factory;
$this->entityManager = $entity_manager;
$this->lock = $lock;
$this->uuidService = $uuid_service;
$this->processed = $this->storageComparer->getEmptyChangelist();
// Use an override free context for importing so that overrides to do not
// pollute the imported data. The context is hard coded to ensure this is
// the case.
$this->context = new FreeConfigContext($this->eventDispatcher);
$this->context = new FreeConfigContext($this->eventDispatcher, $this->uuidService);
}
/**
......
......@@ -10,7 +10,7 @@
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigEvent;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Uuid\Uuid;
use Drupal\Component\Uuid\UuidInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
/**
......@@ -49,14 +49,24 @@ class ConfigContext implements ContextInterface {
*/
protected $uuid;
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Constructs the configuration context.
*
* @param \Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher
* An event dispatcher instance to use for configuration events.
* @param \Drupal\Component\Uuid\UuidInterface
* The UUID service.
*/
public function __construct(EventDispatcher $event_dispatcher) {
public function __construct(EventDispatcher $event_dispatcher, UuidInterface $uuid) {
$this->eventDispatcher = $event_dispatcher;
$this->uuidService = $uuid;
}
/**
......@@ -89,8 +99,7 @@ public function set($key, $value) {
* Implements \Drupal\Core\Config\Context\ContextInterface::setUuid().
*/
public function setUuid() {
$uuid = new Uuid();
$this->uuid = $uuid->generate();
$this->uuid = $this->uuidService->generate();
}
/**
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigException;
use Drupal\Component\Uuid\UuidInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
/**
......@@ -27,14 +28,24 @@ class ConfigContextFactory {
*/
protected $eventDispatcher;
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Constructs the configuration context.
*
* @param \Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher
* An event dispatcher instance to use for configuration events.
* @param \Drupal\Component\Uuid\UuidInterface
* The UUID service.
*/
public function __construct(EventDispatcher $event_dispatcher) {
public function __construct(EventDispatcher $event_dispatcher, UuidInterface $uuid) {
$this->eventDispatcher = $event_dispatcher;
$this->uuidService = $uuid;
}
/**
......@@ -52,7 +63,7 @@ public function get($class = NULL) {
$class = 'Drupal\Core\Config\Context\ConfigContext';
}
if (class_exists($class)) {
$context = new $class($this->eventDispatcher);
$context = new $class($this->eventDispatcher, $this->uuidService);
}
else {
throw new ConfigException(sprintf('Unknown config context class: %s', $class));
......
......@@ -7,7 +7,6 @@
namespace Drupal\Core\Config\Entity;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageControllerBase;
......@@ -15,6 +14,7 @@
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Component\Uuid\UuidInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -41,6 +41,13 @@ class ConfigStorageController extends EntityStorageControllerBase {
*/
protected $uuidKey = 'uuid';
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Name of the entity's status key or FALSE if a status is not supported.
*
......@@ -82,8 +89,10 @@ class ConfigStorageController extends EntityStorageControllerBase {
* The config storage service.
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory
* The entity query factory.
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
* The UUID service.
*/
public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory) {
public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory, UuidInterface $uuid_service) {
parent::__construct($entity_type, $entity_info);
$this->idKey = $this->entityInfo['entity_keys']['id'];
......@@ -98,6 +107,7 @@ public function __construct($entity_type, array $entity_info, ConfigFactory $con
$this->configFactory = $config_factory;
$this->configStorage = $config_storage;
$this->entityQueryFactory = $entity_query_factory;
$this->uuidService = $uuid_service;
}
/**
......@@ -109,7 +119,8 @@ public static function createInstance(ContainerInterface $container, $entity_typ
$entity_info,
$container->get('config.factory'),
$container->get('config.storage'),
$container->get('entity.query')
$container->get('entity.query'),
$container->get('uuid')
);
}
......@@ -323,8 +334,7 @@ public function create(array $values) {
// Assign a new UUID if there is none yet.
if (!isset($entity->{$this->uuidKey})) {
$uuid = new Uuid();
$entity->{$this->uuidKey} = $uuid->generate();
$entity->{$this->uuidKey} = $this->uuidService->generate();
}
$entity->postCreate($this);
......
......@@ -50,6 +50,7 @@ public function register(ContainerBuilder $container) {
$container->addScope(new Scope('request'));
$this->registerTwig($container);
$this->registerModuleHandler($container);
$this->registerUuid($container);
$container->addCompilerPass(new RegisterRouteFiltersPass());
// Add a compiler pass for registering event subscribers.
......@@ -133,4 +134,31 @@ public static function registerTwig(ContainerBuilder $container) {
->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')));
}
/**
* Determines and registers the UUID service.
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
* The container.
*
* @return string
* Class name for the UUID service.
*/
public static function registerUuid(ContainerBuilder $container) {
$uuid_class = 'Drupal\Component\Uuid\Php';
// Debian/Ubuntu uses the (broken) OSSP extension as their UUID
// implementation. The OSSP implementation is not compatible with the
// PECL functions.
if (function_exists('uuid_create') && !function_exists('uuid_make')) {
$uuid_class = 'Drupal\Component\Uuid\Pecl';
}
// Try to use the COM implementation for Windows users.
elseif (function_exists('com_create_guid')) {
$uuid_class = 'Drupal\Component\Uuid\Com';
}
$container->register('uuid', $uuid_class);
return $uuid_class;
}
}
......@@ -7,6 +7,7 @@
namespace Drupal\Core\Entity;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Language\Language;
......@@ -29,6 +30,13 @@
*/
class DatabaseStorageController extends FieldableEntityStorageControllerBase {
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Name of entity's revision database table field, if it supports revisions.
*
......@@ -76,7 +84,8 @@ public static function createInstance(ContainerInterface $container, $entity_typ
$entity_type,
$entity_info,
$container->get('database'),
$container->get('field.info')
$container->get('field.info'),
$container->get('uuid')
);
}
......@@ -91,12 +100,15 @@ public static function createInstance(ContainerInterface $container, $entity_typ
* The database connection to be used.
* @param \Drupal\field\FieldInfo $field_info
* The field info service.
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
* The UUID service.
*/
public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info) {
public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service) {
parent::__construct($entity_type, $entity_info);
$this->database = $database;
$this->fieldInfo = $field_info;
$this->uuidService = $uuid_service;
// Check if the entity type supports IDs.
if (isset($this->entityInfo['entity_keys']['id'])) {
......@@ -380,8 +392,7 @@ public function create(array $values) {
// Assign a new UUID if there is none yet.
if ($this->uuidKey && !isset($entity->{$this->uuidKey})) {
$uuid = new Uuid();
$entity->{$this->uuidKey} = $uuid->generate();
$entity->{$this->uuidKey} = $this->uuidService->generate();
}
$entity->postCreate($this);
......
......@@ -13,7 +13,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\DatabaseStorageController;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Component\Uuid\Uuid;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Database\Connection;
/**
......@@ -52,8 +52,8 @@ class DatabaseStorageControllerNG extends DatabaseStorageController {
/**
* Overrides DatabaseStorageController::__construct().
*/
public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info) {
parent::__construct($entity_type,$entity_info, $database, $field_info);
public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service) {
parent::__construct($entity_type,$entity_info, $database, $field_info, $uuid_service);
$this->bundleKey = !empty($this->entityInfo['entity_keys']['bundle']) ? $this->entityInfo['entity_keys']['bundle'] : FALSE;
$this->entityClass = $this->entityInfo['class'];
......
......@@ -7,7 +7,6 @@
namespace Drupal\Core\Entity;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
use Drupal\Core\Language\Language;
use Drupal\Core\TypedData\TranslatableInterface;
......@@ -448,8 +447,8 @@ public function createDuplicate() {
// Check if the entity type supports UUIDs and generate a new one if so.
if (!empty($entity_info['entity_keys']['uuid'])) {
$uuid = new Uuid();
$duplicate->{$entity_info['entity_keys']['uuid']} = $uuid->generate();
// @todo Inject the UUID service into the Entity class once possible.
$duplicate->{$entity_info['entity_keys']['uuid']} = \Drupal::service('uuid')->generate();
}
return $duplicate;
}
......
......@@ -55,6 +55,7 @@ class EntityNG extends Entity {
*
* @todo: Add methods for getting original fields and for determining
* changes.
* @todo: Provide a better way for defining default values.
*
* @var array
*/
......@@ -712,7 +713,8 @@ public function createDuplicate() {
// Check if the entity type supports UUIDs and generate a new one if so.
if (!empty($entity_info['entity_keys']['uuid'])) {
$duplicate->{$entity_info['entity_keys']['uuid']}->applyDefaultValue();
// @todo Inject the UUID service into the Entity class once possible.
$duplicate->{$entity_info['entity_keys']['uuid']}->value = \Drupal::service('uuid')->generate();
}
// Check whether the entity type supports revisions and initialize it if so.
......
......@@ -9,7 +9,6 @@
use Drupal\Core\TypedData\Annotation\DataType;
use Drupal\Core\Annotation\Translation;
use Drupal\Component\Uuid\Uuid;
/**
* Defines the 'uuid_field' entity field item.
......@@ -35,7 +34,7 @@ class UuidItem extends StringItem {
*/
public function applyDefaultValue($notify = TRUE) {
// Default to one field item with a generated UUID.
$uuid = new Uuid();
$uuid = \Drupal::service('uuid');
$this->setValue(array('value' => $uuid->generate()), $notify);
return $this;
}
......
......@@ -4,7 +4,7 @@
* @file
* Install, update and uninstall functions for the block module.
*/
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Language\Language;
/**
......@@ -198,7 +198,7 @@ function block_update_8007() {
// Populate the {custom_block} and {custom_block_revision} table.
$results = db_select('block_custom', 'bc')->fields('bc')->execute();
$uuid = new Uuid();
$uuid = \Drupal::service('uuid');
$execute = FALSE;
$block_insert = db_insert('custom_block')->fields(array(
'id',
......
......@@ -9,7 +9,6 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\DatabaseStorageControllerNG;
use Drupal\Component\Uuid\Uuid;
/**
* Defines the controller class for comments.
......
......@@ -7,6 +7,7 @@
namespace Drupal\config\Form;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Config\StorageInterface;
......@@ -64,6 +65,13 @@ class ConfigSync extends FormBase {
*/
protected $urlGenerator;
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuidService;
/**
* Constructs the object.
*
......@@ -81,8 +89,10 @@ class ConfigSync extends FormBase {
* Entity manager.
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The url generator service.
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
* The UUID Service.
*/
public function __construct(StorageInterface $sourceStorage, StorageInterface $targetStorage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, UrlGeneratorInterface $url_generator) {
public function __construct(StorageInterface $sourceStorage, StorageInterface $targetStorage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, UrlGeneratorInterface $url_generator, UuidInterface $uuid_service) {
$this->sourceStorage = $sourceStorage;
$this->targetStorage = $targetStorage;
$this->lock = $lock;
......@@ -90,6 +100,7 @@ public function __construct(StorageInterface $sourceStorage, StorageInterface $t
$this->configFactory = $config_factory;
$this->entity_manager = $entity_manager;
$this->urlGenerator = $url_generator;
$this->uuidService = $uuid_service;
}
/**
......@@ -103,7 +114,8 @@ public static function create(ContainerInterface $container) {
$container->get('event_dispatcher'),
$container->get('config.factory'),