Commit 4c2e6b41 authored by Dries's avatar Dries

- Patch #1637370 by danielnolde, sun, djdevin, Berdir: Added UUID support to core entity types.

parent 1f31a38f
......@@ -21,6 +21,13 @@ class File extends Entity {
*/
public $fid;
/**
* The file UUID.
*
* @var string
*/
public $uuid;
/**
* The file language code.
*
......
......@@ -91,6 +91,12 @@ function comment_schema() {
'not null' => TRUE,
'description' => 'Primary Key: Unique comment ID.',
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'pid' => array(
'type' => 'int',
'not null' => TRUE,
......@@ -183,6 +189,9 @@ function comment_schema() {
'comment_created' => array('created'),
),
'primary key' => array('cid'),
'unique keys' => array(
'uuid' => array('uuid'),
),
'foreign keys' => array(
'comment_node' => array(
'table' => 'node',
......@@ -281,6 +290,32 @@ function comment_update_8000() {
db_add_index('comment', 'comment_nid_langcode', array('nid', 'langcode'));
}
/**
* Create a UUID column for comments.
*
* @todo UUID upgrade path: http://drupal.org/node/1642526
*/
function comment_update_8001() {
$spec = array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
);
$keys = array(
'unique keys' => array(
'uuid' => array('uuid'),
),
);
// Account for sites having the contributed UUID module installed.
if (db_field_exists('comment', 'uuid')) {
db_change_field('comment', 'uuid', 'uuid', $spec, $keys);
}
else {
db_add_field('comment', 'uuid', $spec, $keys);
}
}
/**
* @} End of "addtogroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.
......
......@@ -111,6 +111,7 @@ function comment_entity_info() {
'id' => 'cid',
'bundle' => 'node_type',
'label' => 'subject',
'uuid' => 'uuid',
),
'bundles' => array(),
'view modes' => array(
......
......@@ -21,6 +21,13 @@ class Comment extends Entity {
*/
public $cid;
/**
* The comment UUID.
*
* @var string
*/
public $uuid;
/**
* The parent comment ID if this is a reply to a comment.
*
......
......@@ -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 systems.
* - 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',
......
......@@ -5,7 +5,9 @@
* Entity API for handling entities like nodes or users.
*/
use Drupal\entity\EntityFieldQuery;
use Drupal\entity\EntityMalformedException;
use Drupal\entity\EntityStorageException;
use Drupal\entity\EntityInterface;
/**
......@@ -216,6 +218,57 @@ function entity_load($entity_type, $id, $reset = FALSE) {
return isset($entities[$id]) ? $entities[$id] : FALSE;
}
/**
* Loads an entity by UUID.
*
* Note that some entity types may not support UUIDs.
*
* @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.
*
* @throws Drupal\entity\EntityStorageException
* Thrown in case the requested entity type does not support UUIDs.
*
* @see hook_entity_info()
*
* @todo D8: Make it easier to query entities by property; e.g., enhance
* EntityStorageControllerInterface with a ::loadByProperty() method.
*/
function entity_load_by_uuid($entity_type, $uuid, $reset = FALSE) {
$entity_info = entity_get_info($entity_type);
if (empty($entity_info['entity keys']['uuid'])) {
throw new EntityStorageException("Entity type $entity_type does not support UUIDs.");
}
$uuid_key = $entity_info['entity keys']['uuid'];
// Look up the entity ID for the given UUID.
$entity_query = new EntityFieldQuery();
$result = $entity_query
->entityCondition('entity_type', $entity_type)
->propertyCondition($uuid_key, $uuid)
->range(0, 1)
->execute();
if (empty($result[$entity_type])) {
return FALSE;
}
$controller = entity_get_controller($entity_type);
if ($reset) {
$controller->resetCache();
}
$id = key($result[$entity_type]);
$entities = $controller->load(array($id));
return isset($entities[$id]) ? $entities[$id] : FALSE;
}
/**
* Loads multiple entities from the database.
*
......
......@@ -8,6 +8,8 @@
namespace Drupal\entity;
use PDO;
use Drupal\Component\Uuid\Uuid;
/**
* Defines a base entity controller class.
......@@ -58,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.
*
......@@ -95,6 +106,14 @@ public function __construct($entityType) {
$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 +385,16 @@ protected function cacheSet($entities) {
*/
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);
// Assign a new UUID if there is none yet.
if ($this->uuidKey && !isset($entity->{$this->uuidKey})) {
$uuid = new Uuid();
$entity->{$this->uuidKey} = $uuid->generate();
}
return $entity;
}
/**
......
......@@ -43,6 +43,12 @@ function entity_test_schema() {
'not null' => TRUE,
'description' => 'Primary Key: Unique entity-test item ID.',
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'name' => array(
'description' => 'The name of the test entity.',
'type' => 'varchar',
......@@ -72,6 +78,9 @@ function entity_test_schema() {
'uid' => array('users' => 'uid'),
),
'primary key' => array('id'),
'unique keys' => array(
'uuid' => array('uuid'),
),
);
return $schema;
}
......@@ -17,6 +17,7 @@ function entity_test_entity_info() {
'fieldable' => TRUE,
'entity keys' => array(
'id' => 'id',
'uuid' => 'uuid',
),
);
// Optionally specify a translation handler for testing translations.
......
......@@ -28,6 +28,13 @@ class Node extends Entity {
*/
public $vid;
/**
* The node UUID.
*
* @var string
*/
public $uuid;
/**
* The node content type (bundle).
*
......
......@@ -18,6 +18,12 @@ function node_schema() {
'unsigned' => TRUE,
'not null' => TRUE,
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
// Defaults to NULL in order to avoid a brief period of potential
// deadlocks on the index.
'vid' => array(
......@@ -117,6 +123,7 @@ function node_schema() {
),
'unique keys' => array(
'vid' => array('vid'),
'uuid' => array('uuid'),
),
'foreign keys' => array(
'node_revision' => array(
......@@ -567,6 +574,32 @@ function node_update_8003() {
}
}
/**
* Create a UUID column for nodes.
*
* @todo UUID upgrade path: http://drupal.org/node/1642526
*/
function node_update_8004() {
$spec = array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
);
$keys = array(
'unique keys' => array(
'uuid' => array('uuid'),
),
);
// Account for sites having the contributed UUID module installed.
if (db_field_exists('node', 'uuid')) {
db_change_field('node', 'uuid', 'uuid', $spec, $keys);
}
else {
db_add_field('node', 'uuid', $spec, $keys);
}
}
/**
* @} End of "addtogroup updates-7.x-to-8.x"
* The next series of updates should start at 9000.
......
......@@ -204,6 +204,7 @@ function node_entity_info() {
'revision' => 'vid',
'bundle' => 'type',
'label' => 'title',
'uuid' => 'uuid',
),
'bundle keys' => array(
'bundle' => 'type',
......
......@@ -852,6 +852,12 @@ function system_schema() {
'unsigned' => TRUE,
'not null' => TRUE,
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'uid' => array(
'description' => 'The {users}.uid of the user who is associated with the file.',
'type' => 'int',
......@@ -917,6 +923,7 @@ function system_schema() {
'timestamp' => array('timestamp'),
),
'unique keys' => array(
'uuid' => array('uuid'),
'uri' => array('uri'),
),
'primary key' => array('fid'),
......@@ -2001,6 +2008,32 @@ function system_update_8014() {
$config->save();
}
/**
* Create a UUID column for managed files.
*
* @todo UUID upgrade path: http://drupal.org/node/1642526
*/
function system_update_8015() {
$spec = array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
);
$keys = array(
'unique keys' => array(
'uuid' => array('uuid'),
),
);
// Account for sites having the contributed UUID module installed.
if (db_field_exists('file_managed', 'uuid')) {
db_change_field('file_managed', 'uuid', 'uuid', $spec, $keys);
}
else {
db_add_field('file_managed', 'uuid', $spec, $keys);
}
}
/**
* @} End of "defgroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.
......
......@@ -281,6 +281,7 @@ function system_entity_info() {
'entity keys' => array(
'id' => 'fid',
'label' => 'filename',
'uuid' => 'uuid',
),
'static cache' => FALSE,
),
......
......@@ -21,6 +21,13 @@ class Term extends Entity {
*/
public $tid;
/**
* The term UUID.
*
* @var string
*/
public $uuid;
/**
* The taxonomy vocabulary ID this term belongs to.
*
......
......@@ -32,6 +32,12 @@ function taxonomy_schema() {
'not null' => TRUE,
'description' => 'Primary Key: Unique term ID.',
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'vid' => array(
'type' => 'int',
'unsigned' => TRUE,
......@@ -75,6 +81,9 @@ function taxonomy_schema() {
),
),
'primary key' => array('tid'),
'unique keys' => array(
'uuid' => array('uuid'),
),
'foreign keys' => array(
'vocabulary' => array(
'table' => 'taxonomy_vocabulary',
......@@ -300,3 +309,29 @@ function taxonomy_update_8001() {
}
}
}
/**
* Create a UUID column for taxonomy terms.
*
* @todo UUID upgrade path: http://drupal.org/node/1642526
*/
function taxonomy_update_8002() {
$spec = array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
);
$keys = array(
'unique keys' => array(
'uuid' => array('uuid'),
),
);
// Account for sites having the contributed UUID module installed.
if (db_field_exists('taxonomy_term_data', 'uuid')) {
db_change_field('taxonomy_term_data', 'uuid', 'uuid', $spec, $keys);
}
else {
db_add_field('taxonomy_term_data', 'uuid', $spec, $keys);
}
}
......@@ -120,6 +120,7 @@ function taxonomy_entity_info() {
'id' => 'tid',
'bundle' => 'vocabulary_machine_name',
'label' => 'name',
'uuid' => 'uuid',
),
'bundle keys' => array(
'bundle' => 'machine_name',
......
......@@ -21,6 +21,13 @@ class User extends Entity {
*/
public $uid;
/**
* The user UUID.
*
* @var string
*/
public $uuid;
/**
* The unique user name.
*
......
......@@ -132,6 +132,12 @@ function user_schema() {
'description' => 'Primary Key: Unique user ID.',
'default' => 0,
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'name' => array(
'type' => 'varchar',
'length' => 60,
......@@ -246,6 +252,7 @@ function user_schema() {
'picture' => array('picture'),
),
'unique keys' => array(
'uuid' => array('uuid'),
'name' => array('name'),
),
'primary key' => array('uid'),
......@@ -441,6 +448,32 @@ function user_update_8002() {
->execute();
}
/**
* Create a UUID column for users.
*
* @todo UUID upgrade path: http://drupal.org/node/1642526
*/
function user_update_8003() {
$spec = array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
);
$keys = array(
'unique keys' => array(
'uuid' => array('uuid'),
),
);
// Account for sites having the contributed UUID module installed.
if (db_field_exists('users', 'uuid')) {
db_change_field('users', 'uuid', 'uuid', $spec, $keys);
}
else {
db_add_field('users', 'uuid', $spec, $keys);
}
}
/**
* @} End of "addtogroup updates-7.x-to-8.x".
*/
......@@ -154,6 +154,7 @@ function user_entity_info() {
'entity class' => 'Drupal\user\User',
'entity keys' => array(
'id' => 'uid',
'uuid' => 'uuid',
),
'bundles' => array(
'user' => array(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment