View source
<?php
class UuidEntityException extends Exception {
}
function uuid_get_core_entity_info() {
$info = array();
$info['user'] = array(
'base table' => 'users',
'entity keys' => array(
'uuid' => 'uuid',
),
);
$info['node'] = array(
'base table' => 'node',
'revision table' => 'node_revision',
'entity keys' => array(
'uuid' => 'uuid',
'revision uuid' => 'vuuid',
),
);
if (module_exists('comment')) {
$info['comment'] = array(
'base table' => 'comment',
'entity keys' => array(
'uuid' => 'uuid',
),
);
}
if (module_exists('file')) {
$info['file'] = array(
'base table' => 'file_managed',
'entity keys' => array(
'uuid' => 'uuid',
),
);
}
if (module_exists('taxonomy')) {
$info['taxonomy_term'] = array(
'base table' => 'taxonomy_term_data',
'entity keys' => array(
'uuid' => 'uuid',
),
);
}
if (module_exists('field_collection')) {
$info['field_collection_item'] = array(
'base table' => 'field_collection_item',
'entity keys' => array(
'uuid' => 'uuid',
),
);
}
return $info;
}
function uuid_entity_info_alter(&$info) {
foreach (uuid_get_core_entity_info() as $entity_type => $core_info) {
$info[$entity_type]['uuid'] = TRUE;
$info[$entity_type]['entity keys']['uuid'] = $core_info['entity keys']['uuid'];
if (!empty($core_info['entity keys']['revision uuid'])) {
$info[$entity_type]['entity keys']['revision uuid'] = $core_info['entity keys']['revision uuid'];
}
}
}
function uuid_entity_property_info_alter(&$info) {
foreach (entity_get_info() as $entity_type => $entity_info) {
if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && !empty($entity_info['entity keys']['uuid']) && empty($info[$entity_type]['properties'][$entity_info['entity keys']['uuid']])) {
$info[$entity_type]['properties'][$entity_info['entity keys']['uuid']] = array(
'label' => t('UUID'),
'type' => 'text',
'description' => t('The universally unique ID.'),
'schema field' => $entity_info['entity keys']['uuid'],
);
if (!empty($entity_info['entity keys']['revision uuid']) && empty($info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']])) {
$info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']] = array(
'label' => t('Revision UUID'),
'type' => 'text',
'description' => t("The revision's universally unique ID."),
'schema field' => $entity_info['entity keys']['revision uuid'],
);
}
}
}
}
function uuid_entity_presave($entity, $entity_type) {
$info = entity_get_info($entity_type);
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
$uuid_key = $info['entity keys']['uuid'];
if (empty($entity->{$uuid_key})) {
$entity->{$uuid_key} = uuid_generate();
}
if (!empty($info['entity keys']['revision uuid'])) {
$vuuid_key = $info['entity keys']['revision uuid'];
if (!empty($entity->uuid_services) && isset($entity->{$vuuid_key})) {
$vuuid_exists = (bool) entity_get_id_by_uuid($entity_type, array(
$entity->{$vuuid_key},
), TRUE);
if ($vuuid_exists) {
$entity->revision = FALSE;
}
}
if (isset($entity->revision) && $entity->revision == TRUE && empty($entity->uuid_services) || empty($entity->{$vuuid_key})) {
$entity->{$vuuid_key} = uuid_generate();
}
}
}
}
function entity_uuid_load($entity_type, $uuids = array(), $conditions = array(), $reset = FALSE) {
$entity_info[$entity_type] = entity_get_info($entity_type);
$revision_key = $entity_info[$entity_type]['entity keys']['revision'];
if (isset($entity_info[$entity_type]['entity keys']['revision uuid'])) {
$revision_uuid_key = $entity_info[$entity_type]['entity keys']['revision uuid'];
}
if (isset($revision_uuid_key) && isset($conditions[$revision_uuid_key])) {
$revision_id = entity_get_id_by_uuid($entity_type, array(
$conditions[$revision_uuid_key],
), TRUE);
$conditions[$revision_key] = $revision_id[$conditions[$revision_uuid_key]];
unset($conditions[$revision_uuid_key]);
}
$ids = entity_get_id_by_uuid($entity_type, $uuids);
$results = entity_load($entity_type, $ids, $conditions, $reset);
$entities = array();
foreach ($results as $key => $entity) {
$entities[$key] = clone $entity;
}
entity_make_entity_universal($entity_type, $entities);
return $entities;
}
function entity_make_entity_universal($entity_type, $entities) {
if (!empty($entities)) {
$hook = 'entity_uuid_load';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$function($entities, $entity_type);
}
}
}
}
function entity_uuid_save($entity_type, $entity) {
if (!module_exists('entity')) {
throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array(
'%function' => __FUNCTION__,
'!link' => 'http://drupal.org/project/entity',
)));
}
$info = entity_get_info($entity_type);
$uuid_key = $info['entity keys']['uuid'];
if (empty($entity->{$uuid_key}) || !uuid_is_valid($entity->{$uuid_key})) {
watchdog('Entity UUID', 'Attempted to save an entity with an invalid UUID', array(), WATCHDOG_ERROR);
return FALSE;
}
if ($entity_type == 'node' && !isset($entity->revision) && in_array('revision', variable_get('node_options_' . $entity->type, array()))) {
$entity->revision = 1;
}
entity_make_entity_local($entity_type, $entity);
$result = entity_save($entity_type, $entity);
$hook = 'entity_uuid_save';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$function($entity, $entity_type);
}
}
return $result;
}
function entity_make_entity_local($entity_type, $entity) {
$info = entity_get_info($entity_type);
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
$id_key = $info['entity keys']['id'];
$uuid_key = $info['entity keys']['uuid'];
if (empty($entity->{$uuid_key}) || !uuid_is_valid($entity->{$uuid_key})) {
throw new UuidEntityException(t('Trying to save a @type entity with empty or invalid UUID.', array(
'@type' => $info['label'],
)));
}
$ids = entity_get_id_by_uuid($entity_type, array(
$entity->{$uuid_key},
));
$id = reset($ids);
if (empty($id)) {
unset($entity->{$id_key});
$entity->is_new = TRUE;
}
else {
$entity->{$id_key} = $id;
$entity->is_new = FALSE;
}
if (!empty($info['entity keys']['revision uuid'])) {
$vid_key = $info['entity keys']['revision'];
$vuuid_key = $info['entity keys']['revision uuid'];
$vid = NULL;
if (isset($entity->{$vuuid_key})) {
$vids = entity_get_id_by_uuid($entity_type, array(
$entity->{$vuuid_key},
), TRUE);
$vid = reset($vids);
}
if (empty($vid) && isset($entity->{$vid_key})) {
unset($entity->{$vid_key});
}
elseif (!empty($vid)) {
$entity->{$vid_key} = $vid;
}
if ($entity_type == 'node' && !isset($entity->vid) && !$entity->is_new) {
$entity->vid = db_select('node', 'n')
->condition('n.nid', $entity->nid)
->fields('n', array(
'vid',
))
->execute()
->fetchField();
}
}
$hook = 'entity_uuid_presave';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$function($entity, $entity_type);
}
}
}
else {
throw new UuidEntityException(t("Trying to operate on a @type entity, which doesn\\'t support UUIDs.", array(
'@type' => $info['label'],
)));
}
}
function entity_uuid_delete($entity_type, $uuid) {
if (!module_exists('entity')) {
throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array(
'%function' => __FUNCTION__,
'!link' => 'http://drupal.org/project/entity',
)));
}
$info = entity_get_info($entity_type);
if (isset($info['uuid']) && $info['uuid'] == TRUE) {
$ids = entity_get_id_by_uuid($entity_type, array(
$uuid,
));
$id = reset($ids);
$entity = entity_load($entity_type, array(
$id,
));
$hook = 'entity_uuid_delete';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$function($entity, $entity_type);
}
}
if (empty($entity)) {
return FALSE;
}
return entity_delete($entity_type, $id);
}
else {
throw new UuidEntityException(t("Trying to delete a @type entity, which doesn\\'t support UUIDs.", array(
'@type' => $info['label'],
)));
}
}
function entity_get_id_by_uuid($entity_type, $uuids, $revision = FALSE) {
if (empty($uuids)) {
return array();
}
$cached_ids = entity_uuid_id_cache($entity_type, $uuids, $revision);
if (count($cached_ids) == count($uuids)) {
return $cached_ids;
}
$uuids = array_diff($uuids, $cached_ids);
$info = entity_get_info($entity_type);
if (empty($info['uuid'])) {
return array();
}
if (!$revision) {
$table = $info['base table'];
$id_key = $info['entity keys']['id'];
$uuid_key = $info['entity keys']['uuid'];
}
elseif (isset($info['revision table'])) {
$table = $info['revision table'];
$id_key = $info['entity keys']['revision'];
$uuid_key = $info['entity keys']['revision uuid'];
}
else {
return array();
}
$result = db_select($table, 't')
->fields('t', array(
$uuid_key,
$id_key,
))
->condition($uuid_key, array_values($uuids), 'IN')
->execute()
->fetchAllKeyed();
$cache =& drupal_static('entity_uuid_id_cache', array());
$cache[$entity_type][(int) $revision] += $result;
return $result + $cached_ids;
}
function entity_uuid_id_cache($entity_type, $ids, $revision) {
$cache =& drupal_static(__FUNCTION__, array());
if (empty($cache[$entity_type][(int) $revision])) {
$cache[$entity_type][(int) $revision] = array();
}
$cached_ids = $cache[$entity_type][(int) $revision];
return array_intersect_key($cached_ids, array_flip($ids));
}
function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
if (empty($ids)) {
return array();
}
$cached_ids = array_flip(entity_uuid_id_cache($entity_type, $ids, $revision));
if (count($cached_ids) == count($ids)) {
return $cached_ids;
}
$ids = array_diff($ids, $cached_ids);
$info = entity_get_info($entity_type);
if (empty($info['uuid'])) {
return array();
}
if (!$revision) {
$table = $info['base table'];
$id_key = $info['entity keys']['id'];
$uuid_key = $info['entity keys']['uuid'];
}
elseif (isset($info['revision table'])) {
$table = $info['revision table'];
$id_key = $info['entity keys']['revision'];
$uuid_key = $info['entity keys']['revision uuid'];
}
else {
return array();
}
$result = db_select($table, 't')
->fields('t', array(
$id_key,
$uuid_key,
))
->condition($id_key, array_values($ids), 'IN')
->execute()
->fetchAllKeyed();
$cache =& drupal_static('entity_uuid_id_cache', array());
$cache[$entity_type][(int) $revision] += array_flip($result);
return $result + $cached_ids;
}
function entity_property_id_to_uuid(&$objects, $entity_type, $properties) {
if (!is_array($objects)) {
$things = array(
&$objects,
);
}
else {
$things =& $objects;
}
if (!is_array($properties)) {
$properties = array(
$properties,
);
}
$ids = array();
$values = array();
$i = 0;
foreach ($things as &$object) {
foreach ($properties as $property) {
if (is_object($object) && isset($object->{$property})) {
$values[$i] =& $object->{$property};
}
elseif (is_array($object) && isset($object[$property])) {
$values[$i] =& $object[$property];
}
else {
$i++;
continue;
}
if (!($entity_type == 'user' && ($values[$i] == 0 || $values[$i] == 1))) {
$ids[] = $values[$i];
}
$i++;
}
}
$uuids = entity_get_uuid_by_id($entity_type, $ids);
foreach ($values as $i => $value) {
if (isset($uuids[$value])) {
$values[$i] = $uuids[$value];
}
}
}
function entity_property_uuid_to_id(&$objects, $entity_type, $properties) {
if (!is_array($objects)) {
$things = array(
&$objects,
);
}
else {
$things =& $objects;
}
if (!is_array($properties)) {
$properties = array(
$properties,
);
}
$uuids = array();
$values = array();
$i = 0;
foreach ($things as &$object) {
foreach ($properties as $property) {
if (is_object($object) && isset($object->{$property})) {
$values[$i] =& $object->{$property};
}
elseif (is_array($object) && isset($object[$property])) {
$values[$i] =& $object[$property];
}
else {
$i++;
continue;
}
if (uuid_is_valid($values[$i])) {
$uuids[] = $values[$i];
}
$i++;
}
}
$ids = entity_get_id_by_uuid($entity_type, $uuids);
foreach ($values as $i => $value) {
if (isset($ids[$value])) {
$values[$i] = $ids[$value];
}
}
}