diff --git a/core/lib/Drupal/Core/File/File.php b/core/lib/Drupal/Core/File/File.php index b35f5ee..2e5e67d 100644 --- a/core/lib/Drupal/Core/File/File.php +++ b/core/lib/Drupal/Core/File/File.php @@ -22,6 +22,13 @@ class File extends Entity { public $fid; /** + * The file UUID. + * + * @var string + */ + public $uuid; + + /** * The file language code. * * @var string diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 4b3c9fc..e8abd13 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -91,6 +91,13 @@ function comment_schema() { 'not null' => TRUE, 'description' => 'Primary Key: Unique comment ID.', ), + 'uuid' => array( + 'description' => 'The universally unique identifier for a comment.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), 'pid' => array( 'type' => 'int', 'not null' => TRUE, @@ -181,6 +188,7 @@ function comment_schema() { 'comment_uid' => array('uid'), 'comment_nid_langcode' => array('nid', 'langcode'), 'comment_created' => array('created'), + 'uuid' => array('uuid'), ), 'primary key' => array('cid'), 'foreign keys' => array( @@ -282,6 +290,27 @@ function comment_update_8000() { } /** + * Create a UUID column for comment table. + * + * @todo UUID upgrade path on existing records: http://drupal.org/node/1642526 + */ +function comment_update_8001() { + db_add_field('comment', 'uuid', array( + 'description' => 'The universally unique identifier for a comment.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + array( + 'indexes' => array( + 'uuid' => array('uuid'), + ) + ) + ); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index a6230f2..815fce3 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -109,6 +109,7 @@ function comment_entity_info() { 'id' => 'cid', 'bundle' => 'node_type', 'label' => 'subject', + 'uuid' => 'uuid', ), 'bundles' => array(), 'view modes' => array( diff --git a/core/modules/comment/lib/Drupal/comment/Comment.php b/core/modules/comment/lib/Drupal/comment/Comment.php index 101a679..ed2e6e7 100644 --- a/core/modules/comment/lib/Drupal/comment/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Comment.php @@ -22,6 +22,13 @@ class Comment extends Entity { public $cid; /** + * The node UUID. + * + * @var string + */ + public $uuid; + + /** * The parent comment ID if this is a reply to a comment. * * @var integer diff --git a/core/modules/entity/entity.api.php b/core/modules/entity/entity.api.php index 02d8754..31f7897 100644 --- a/core/modules/entity/entity.api.php +++ b/core/modules/entity/entity.api.php @@ -76,6 +76,9 @@ * 'subject' should be specified here. If complex logic is required to * build the label, a 'label callback' should be defined instead (see * the 'label callback' section above for details). + * - uuid (optional): The name of the property that contains the universally + * unique identifier of the entity, which is used to distinctly identify + * an entity across different Drupal installations. * - bundle keys: An array describing how the Field API can extract the * information it needs from the bundle objects for this type (e.g * $vocabulary objects for terms; not applicable for nodes). This entry can @@ -147,6 +150,7 @@ function hook_entity_info() { 'id' => 'nid', 'revision' => 'vid', 'bundle' => 'type', + 'uuid' => 'uuid', ), 'bundle keys' => array( 'bundle' => 'type', diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module index a66b1e8..d0774cd 100644 --- a/core/modules/entity/entity.module +++ b/core/modules/entity/entity.module @@ -217,6 +217,54 @@ function entity_load($entity_type, $id, $reset = FALSE) { } /** + * Load entity from the database by given UUID. + * + * If an entity type supports a UUID-type entity identifier, this function can + * find an entity by that UUID-type entity identifier. + * Not all entities support that kind of UUID-type entity identifier + * (which can be defined in hook_entity_info). + * + * @param string $entity_type + * The entity type to load, e.g. node or user. + * @param string $uuid + * The uuid of the entity to load. + * @param bool $reset + * Whether to reset the internal cache for the requested entity type. + * + * @return EntityInterface|FALSE + * The entity object, or FALSE if there is no entity with the given UUID. + * + * @see hook_entity_info() + * + */ +function entity_load_by_uuid($entity_type, $uuid, $reset = FALSE) { + $entity = FALSE; + + // Only consider entities that have a "uuid"-type key declared via + // hook_entity_info. + $entity_info = entity_get_info($entity_type); + if (is_array($entity_info) && isset($entity_info['entity keys']) && isset($entity_info['entity keys']['uuid'])) { + $uuid_key_name = $entity_info['entity keys']['uuid']; + + // Retrieve entity record for given uuid to get its entity id. + $entity_query = new Drupal\entity\EntityFieldQuery(); + $entity_query_result = $entity_query->entityCondition('entity_type', $entity_type) + ->propertyCondition($uuid_key_name, $uuid) + ->range(0, 1) + ->execute(); + + // Mine result for entity id and load the entity by its id. + if (is_array($entity_query_result) && isset($entity_query_result[$entity_type])) { + $entity_ids = array_keys($entity_query_result[$entity_type]); + $entity_id = array_shift($entity_ids); + $entity = entity_load($entity_type, $entity_id, $reset); + } + } + + return $entity; +} + +/** * Loads multiple entities from the database. * * This function should be used whenever you need to load more than one entity diff --git a/core/modules/entity/lib/Drupal/entity/DatabaseStorageController.php b/core/modules/entity/lib/Drupal/entity/DatabaseStorageController.php index 8d89341..c0dc76c 100644 --- a/core/modules/entity/lib/Drupal/entity/DatabaseStorageController.php +++ b/core/modules/entity/lib/Drupal/entity/DatabaseStorageController.php @@ -8,6 +8,7 @@ namespace Drupal\entity; use PDO; +use Drupal\Component\Uuid\Uuid; /** * Defines a base entity controller class. @@ -59,6 +60,15 @@ class DatabaseStorageController implements EntityStorageControllerInterface { protected $idKey; /** + * Name of entity's UUID database table field, if it supports UUIDs. + * + * Has the value FALSE if this entity does not use UUIDs. + * + * @var string + */ + protected $uuidKey; + + /** * Name of entity's revision database table field, if it supports revisions. * * Has the value FALSE if this entity does not use revisions. @@ -95,6 +105,14 @@ class DatabaseStorageController implements EntityStorageControllerInterface { $this->hookLoadArguments = array(); $this->idKey = $this->entityInfo['entity keys']['id']; + // Check if the entity type supports UUIDs. + if (!empty($this->entityInfo['entity keys']['uuid'])) { + $this->uuidKey = $this->entityInfo['entity keys']['uuid']; + } + else { + $this->uuidKey = FALSE; + } + // Check if the entity type supports revisions. if (!empty($this->entityInfo['entity keys']['revision'])) { $this->revisionKey = $this->entityInfo['entity keys']['revision']; @@ -366,7 +384,14 @@ class DatabaseStorageController implements EntityStorageControllerInterface { */ public function create(array $values) { $class = isset($this->entityInfo['entity class']) ? $this->entityInfo['entity class'] : 'Drupal\entity\Entity'; - return new $class($values, $this->entityType); + + $entity = new $class($values, $this->entityType); + + // Generate and assign UUID. + $uuid = new Uuid(); + $entity->uuid = $uuid->generate(); + + return $entity; } /** diff --git a/core/modules/node/lib/Drupal/node/Node.php b/core/modules/node/lib/Drupal/node/Node.php index cee6967..fad5c4f 100644 --- a/core/modules/node/lib/Drupal/node/Node.php +++ b/core/modules/node/lib/Drupal/node/Node.php @@ -29,6 +29,13 @@ class Node extends Entity { public $vid; /** + * The node UUID. + * + * @var string + */ + public $uuid; + + /** * The node content type (bundle). * * @var string diff --git a/core/modules/node/node.install b/core/modules/node/node.install index 7382320..9620b31 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -27,6 +27,13 @@ function node_schema() { 'not null' => FALSE, 'default' => NULL, ), + 'uuid' => array( + 'description' => 'The universally unique identifier for a node.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), 'type' => array( 'description' => 'The {node_type}.type of this node.', 'type' => 'varchar', @@ -114,6 +121,7 @@ function node_schema() { 'uid' => array('uid'), 'tnid' => array('tnid'), 'translate' => array('translate'), + 'uuid' => array('uuid'), ), 'unique keys' => array( 'vid' => array('vid'), @@ -568,6 +576,27 @@ function node_update_8003() { } /** + * Create a UUID column for node table. + * + * @todo UUID upgrade path on existing records: http://drupal.org/node/1642526 + */ +function node_update_8004() { + db_add_field('node', 'uuid', array( + 'description' => 'The universally unique identifier for a node.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + array( + 'indexes' => array( + 'uuid' => array('uuid'), + ) + ) + ); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x" * The next series of updates should start at 9000. */ diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 49d20a7..9f77373 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -204,6 +204,7 @@ function node_entity_info() { 'revision' => 'vid', 'bundle' => 'type', 'label' => 'title', + 'uuid' => 'uuid', ), 'bundle keys' => array( 'bundle' => 'type', diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 9ba7c4c..f826d3d 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -866,6 +866,13 @@ function system_schema() { 'unsigned' => TRUE, 'not null' => TRUE, ), + 'uuid' => array( + 'description' => 'The universally unique identifier for a file.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), 'uid' => array( 'description' => 'The {users}.uid of the user who is associated with the file.', 'type' => 'int', @@ -929,6 +936,7 @@ function system_schema() { 'uid' => array('uid'), 'status' => array('status'), 'timestamp' => array('timestamp'), + 'uuid' => array('uuid'), ), 'unique keys' => array( 'uri' => array('uri'), @@ -1925,6 +1933,27 @@ function system_update_8010() { } /** + * Create a UUID column for file_managed table. + * + * @todo UUID upgrade path on existing records: http://drupal.org/node/1642526 + */ +function system_update_8011() { + db_add_field('file_managed', 'uuid', array( + 'description' => 'The universally unique identifier for a file.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + array( + 'indexes' => array( + 'uuid' => array('uuid'), + ) + ) + ); +} + +/** * @} End of "defgroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/system/system.module b/core/modules/system/system.module index b9558e5..1de28fe 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -279,6 +279,7 @@ function system_entity_info() { 'entity keys' => array( 'id' => 'fid', 'label' => 'filename', + 'uuid' => 'uuid', ), 'static cache' => FALSE, ), diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php index f036f18..929422c 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php @@ -22,6 +22,13 @@ class Term extends Entity { public $tid; /** + * The term UUID. + * + * @var string + */ + public $uuid; + + /** * The taxonomy vocabulary ID this term belongs to. * * @var integer diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install index 14b6956..a973fd0 100644 --- a/core/modules/taxonomy/taxonomy.install +++ b/core/modules/taxonomy/taxonomy.install @@ -32,6 +32,13 @@ function taxonomy_schema() { 'not null' => TRUE, 'description' => 'Primary Key: Unique term ID.', ), + 'uuid' => array( + 'description' => 'The universally unique identifier for a term.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), 'vid' => array( 'type' => 'int', 'unsigned' => TRUE, @@ -85,6 +92,7 @@ function taxonomy_schema() { 'taxonomy_tree' => array('vid', 'weight', 'name'), 'vid_name' => array('vid', 'name'), 'name' => array('name'), + 'uuid' => array('uuid'), ), ); @@ -300,3 +308,24 @@ function taxonomy_update_8001() { } } } + +/** + * Create a UUID column for taxonomy_term_data table. + * + * @todo UUID upgrade path on existing records: http://drupal.org/node/1642526 + */ +function taxonomy_update_8002() { + db_add_field('taxonomy_term_data', 'uuid', array( + 'description' => 'The universally unique identifier for a term.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + array( + 'indexes' => array( + 'uuid' => array('uuid'), + ) + ) + ); +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 6697a0a..b31bab9 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -120,6 +120,7 @@ function taxonomy_entity_info() { 'id' => 'tid', 'bundle' => 'vocabulary_machine_name', 'label' => 'name', + 'uuid' => 'uuid', ), 'bundle keys' => array( 'bundle' => 'machine_name', diff --git a/core/modules/user/lib/Drupal/user/User.php b/core/modules/user/lib/Drupal/user/User.php index 992923c..25e27f1 100644 --- a/core/modules/user/lib/Drupal/user/User.php +++ b/core/modules/user/lib/Drupal/user/User.php @@ -22,6 +22,13 @@ class User extends Entity { public $uid; /** + * The user UUID. + * + * @var string + */ + public $uuid; + + /** * The unique user name. * * @var string diff --git a/core/modules/user/user.install b/core/modules/user/user.install index 5ec57da..2fb3c54 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -132,6 +132,13 @@ function user_schema() { 'description' => 'Primary Key: Unique user ID.', 'default' => 0, ), + 'uuid' => array( + 'description' => 'The universally unique identifier for a user.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), 'name' => array( 'type' => 'varchar', 'length' => 60, @@ -244,6 +251,7 @@ function user_schema() { 'created' => array('created'), 'mail' => array('mail'), 'picture' => array('picture'), + 'uuid' => array('uuid'), ), 'unique keys' => array( 'name' => array('name'), @@ -442,5 +450,26 @@ function user_update_8002() { } /** + * Create a UUID column for users table. + * + * @todo UUID upgrade path on existing records: http://drupal.org/node/1642526 + */ +function user_update_8003() { + db_add_field('users', 'uuid', array( + 'description' => 'The universally unique identifier for a user.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + array( + 'indexes' => array( + 'uuid' => array('uuid'), + ) + ) + ); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x". */ diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 89706c4..b41f359 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -154,6 +154,7 @@ function user_entity_info() { 'entity class' => 'Drupal\user\User', 'entity keys' => array( 'id' => 'uid', + 'uuid' => 'uuid', ), 'bundles' => array( 'user' => array(