uuid.core.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <?php
  2. /**
  3. * @file
  4. * Implementation of UUID hooks for all core modules.
  5. *
  6. * @todo
  7. * Replace all these hook implementations with a generic solution that uses
  8. * info from hook_entity_field_info() and hook_entity_property_info(). That
  9. * info should contain info about how UUIDs are mapped.
  10. */
  11. /**
  12. * @defgroup uuid_property Propery implementations
  13. * @{
  14. */
  15. /**
  16. * Implements hook_entity_uuid_load().
  17. */
  18. function node_entity_uuid_load(&$entities, $entity_type) {
  19. if ($entity_type == 'node') {
  20. entity_property_id_to_uuid($entities, 'user', array('uid', 'revision_uid'));
  21. entity_property_id_to_uuid($entities, 'node', 'tnid');
  22. }
  23. }
  24. /**
  25. * Implements hook_entity_uuid_presave().
  26. */
  27. function node_entity_uuid_presave(&$entity, $entity_type) {
  28. if ($entity_type == 'node') {
  29. entity_property_uuid_to_id($entity, 'user', array('uid', 'revision_uid'));
  30. entity_property_uuid_to_id($entity, 'node', 'tnid');
  31. }
  32. }
  33. /**
  34. * Implements hook_entity_uuid_load().
  35. */
  36. function book_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
  37. if ($entity_type == 'node') {
  38. if (!empty($entity->book)) {
  39. $entity->book['bid'] = current(entity_get_uuid_by_id($entity_type, array($entity->book['bid'])));
  40. }
  41. }
  42. }
  43. /**
  44. * Implements hook_entity_uuid_presave().
  45. */
  46. function book_entity_uuid_presave(&$entity, $entity_type) {
  47. if ($entity_type == 'node') {
  48. if (!empty($entity->book)) {
  49. $entity->book['bid'] = current(entity_get_id_by_uuid($entity_type, array($entity->book['bid'])));
  50. if (!$entity->book['bid']) {
  51. $entity->book['bid'] = 'new';
  52. }
  53. }
  54. }
  55. }
  56. /**
  57. * Implements hook_entity_uuid_presave().
  58. */
  59. function user_entity_uuid_presave(&$entity, $entity_type) {
  60. if ($entity_type == 'user') {
  61. if (!empty($entity->picture)) {
  62. $uuids = entity_get_id_by_uuid('file', array($entity->picture['uuid']));
  63. $fid = current($uuids);
  64. if (!$entity->is_new) {
  65. $entity->picture = file_load($fid);
  66. }
  67. else {
  68. $entity->picture = $fid;
  69. }
  70. }
  71. }
  72. }
  73. /**
  74. * Implements hook_entity_uuid_load().
  75. */
  76. function comment_entity_uuid_load(&$entities, $entity_type) {
  77. switch ($entity_type) {
  78. case 'node':
  79. entity_property_id_to_uuid($entities, 'user', 'last_comment_uid');
  80. break;
  81. case 'comment':
  82. entity_property_id_to_uuid($entities, 'user', array('uid', 'u_uid'));
  83. entity_property_id_to_uuid($entities, 'node', 'nid');
  84. break;
  85. }
  86. }
  87. /**
  88. * Implements hook_entity_uuid_presave().
  89. */
  90. function comment_entity_uuid_presave(&$entity, $entity_type) {
  91. switch ($entity_type) {
  92. case 'node':
  93. entity_property_uuid_to_id($entity, 'user', 'last_comment_uid');
  94. break;
  95. case 'comment':
  96. entity_property_uuid_to_id($entity, 'user', array('uid', 'u_uid'));
  97. entity_property_uuid_to_id($entity, 'node', 'nid');
  98. break;
  99. }
  100. }
  101. /**
  102. * Implements hook_entity_uuid_load().
  103. */
  104. function file_entity_uuid_load(&$entities, $entity_type) {
  105. if ($entity_type == 'file') {
  106. entity_property_id_to_uuid($entities, 'user', 'uid');
  107. }
  108. }
  109. /**
  110. * Implements hook_entity_uuid_presave().
  111. */
  112. function file_entity_uuid_presave(&$entity, $entity_type) {
  113. if ($entity_type == 'file') {
  114. entity_property_uuid_to_id($entity, 'user', 'uid');
  115. // Write the new file to the local filesystem.
  116. if (isset($entity->file_contents)) {
  117. // Don't try to write it if it uses a stream wrapper that isn't writeable
  118. // (for example, if it is a remotely-hosted video).
  119. $scheme = file_uri_scheme($entity->uri);
  120. $wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE);
  121. if (empty($wrappers[$scheme])) {
  122. return;
  123. }
  124. // Check for an existing file with the same URI.
  125. $existing_files = file_load_multiple(array(), array('uri' => $entity->uri));
  126. $existing = (object) array('uri' => NULL, 'uuid' => NULL);
  127. if (count($existing_files)) {
  128. $existing = reset($existing_files);
  129. }
  130. // If this is a new file and there is an existing file with the same URI,
  131. // but a different uuid then rename this file.
  132. if ($entity->is_new && $entity->uri == $existing->uri && $entity->uuid != $existing->uuid) {
  133. $uri = $entity->uri;
  134. $replace = FILE_EXISTS_RENAME;
  135. }
  136. // If this has an id, meaning UUID has already matched the uuid to an
  137. // existing file, but it has a URI that matches a file with a different
  138. // uuid, then load the file with the matching uuid and use the URI from
  139. // that file. The existing file with the matching uuid is most likely a
  140. // file that was previously renamed, e.g. as in the condition above, to
  141. // avoid conflict. The uuid matches because they are the same file, but
  142. // the URI does not because an incrementing number was added as part of
  143. // the renaming.
  144. elseif ($entity->uri == $existing->uri && $entity->uuid != $existing->uuid) {
  145. $file = file_load($entity->fid);
  146. $uri = $file->uri;
  147. $replace = FILE_EXISTS_REPLACE;
  148. }
  149. // Otherwise create a new file or replace the existing file contents.
  150. else {
  151. $uri = $entity->uri;
  152. $replace = FILE_EXISTS_REPLACE;
  153. }
  154. $directory = drupal_dirname($uri);
  155. file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
  156. $entity->uri = file_unmanaged_save_data(base64_decode($entity->file_contents), $uri, $replace);
  157. }
  158. }
  159. }
  160. /**
  161. * Implements hook_entity_uuid_load().
  162. */
  163. function taxonomy_entity_uuid_load(&$entities, $entity_type) {
  164. if ($entity_type == 'taxonomy_term') {
  165. foreach ($entities as &$entity) {
  166. if (isset($entity->parent)) {
  167. if (!is_array($entity->parent)) {
  168. $entity->parent = array($entity->parent);
  169. }
  170. $uuids = entity_get_uuid_by_id('taxonomy_term', $entity->parent);
  171. $entity->parent = array_values($uuids);
  172. }
  173. unset($entity->vid);
  174. }
  175. }
  176. }
  177. /**
  178. * Implements hook_entity_uuid_presave().
  179. */
  180. function taxonomy_entity_uuid_presave(&$entity, $entity_type) {
  181. if ($entity_type == 'taxonomy_term') {
  182. if (isset($entity->parent)) {
  183. if (!is_array($entity->parent)) {
  184. $entity->parent = array($entity->parent);
  185. }
  186. $ids = entity_get_id_by_uuid('taxonomy_term', $entity->parent);
  187. $entity->parent = array_values($ids);
  188. }
  189. $vocabulary = taxonomy_vocabulary_machine_name_load($entity->vocabulary_machine_name);
  190. $entity->vid = $vocabulary->vid;
  191. }
  192. }
  193. /**
  194. * Implements hook_entity_uuid_load().
  195. */
  196. function field_entity_uuid_load(&$entities, $entity_type) {
  197. foreach ($entities as $i => $entity) {
  198. list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
  199. $instances = field_info_instances($entity_type, $bundle_name);
  200. foreach ($instances as $field_name => $instance) {
  201. $field = field_info_field($field_name);
  202. if (!empty($field) && isset($entity->{$field_name})) {
  203. foreach ($entity->{$field_name} as $langcode => &$items) {
  204. // Invoke 'hook_field_uuid_load'. We can't use module_invoke() since
  205. // that is not passing by reference.
  206. $function = $field['module'] . '_field_uuid_load';
  207. if (function_exists($function)) {
  208. $function($entity_type, $entity, $field, $instance, $langcode, $items);
  209. }
  210. }
  211. }
  212. }
  213. }
  214. }
  215. /**
  216. * Implements hook_entity_uuid_presave().
  217. */
  218. function field_entity_uuid_presave(&$entity, $entity_type) {
  219. list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
  220. $instances = field_info_instances($entity_type, $bundle_name);
  221. foreach ($instances as $field_name => $instance) {
  222. $field = field_info_field($field_name);
  223. if (!empty($field) && isset($entity->{$field_name})) {
  224. foreach ($entity->{$field_name} as $langcode => &$items) {
  225. // Invoke 'hook_field_uuid_load'. We can't use module_invoke() since
  226. // that is not passing by reference.
  227. $function = $field['module'] . '_field_uuid_presave';
  228. if (function_exists($function)) {
  229. $function($entity_type, $entity, $field, $instance, $langcode, $items);
  230. }
  231. }
  232. }
  233. }
  234. }
  235. /**
  236. * @} End of "Property implementations"
  237. */
  238. /**
  239. * @defgroup uuid_field Field implementations
  240. * @{
  241. */
  242. /**
  243. * Implements hook_field_uuid_load().
  244. */
  245. function taxonomy_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  246. entity_property_id_to_uuid($items, 'taxonomy_term', 'tid');
  247. }
  248. /**
  249. * Implements hook_field_uuid_presave().
  250. */
  251. function taxonomy_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  252. entity_property_uuid_to_id($items, 'taxonomy_term', 'tid');
  253. }
  254. /**
  255. * Implements hook_field_uuid_load().
  256. */
  257. function file_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  258. entity_property_id_to_uuid($items, 'file', 'fid');
  259. entity_property_id_to_uuid($items, 'user', 'uid');
  260. }
  261. /**
  262. * Implements hook_field_uuid_presave().
  263. */
  264. function file_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  265. entity_property_uuid_to_id($items, 'file', 'fid');
  266. entity_property_uuid_to_id($items, 'user', 'uid');
  267. }
  268. /**
  269. * Implements hook_field_uuid_load().
  270. */
  271. function image_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  272. file_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, $items);
  273. }
  274. /**
  275. * Implements hook_field_uuid_presave().
  276. */
  277. function image_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  278. file_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, $items);
  279. }
  280. /**
  281. * Implements hook_field_uuid_load().
  282. */
  283. function node_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  284. entity_property_id_to_uuid($items, 'node', 'nid');
  285. }
  286. /**
  287. * Implements hook_field_uuid_presave().
  288. */
  289. function node_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  290. entity_property_uuid_to_id($items, 'node', 'nid');
  291. }
  292. /**
  293. * Implements hook_field_uuid_load().
  294. */
  295. function user_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  296. entity_property_id_to_uuid($items, 'user', 'uid');
  297. }
  298. /**
  299. * Implements hook_field_uuid_presave().
  300. */
  301. function user_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  302. entity_property_uuid_to_id($items, 'user', 'uid');
  303. }
  304. /**
  305. * Implements hook_field_uuid_load().
  306. */
  307. function entityreference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  308. // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
  309. // can't handle a single $item.
  310. entity_property_id_to_uuid($items, $field['settings']['target_type'], 'target_id');
  311. }
  312. /**
  313. * Implements hook_field_uuid_presave().
  314. */
  315. function entityreference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  316. // TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
  317. // can't handle a single $item.
  318. entity_property_uuid_to_id($items, $field['settings']['target_type'], 'target_id');
  319. }
  320. /**
  321. * Implements hook_entity_uuid_load().
  322. */
  323. function field_collection_entity_uuid_load(&$entities, $entity_type) {
  324. if ($entity_type == 'field_collection_item') {
  325. entity_property_id_to_uuid($entities, 'field_collection_item', 'value');
  326. }
  327. }
  328. /**
  329. * Implements hook_entity_uuid_presave().
  330. */
  331. function field_collection_entity_uuid_presave(&$entity, $entity_type) {
  332. if ($entity_type == 'field_collection_item') {
  333. entity_property_uuid_to_id($entity, 'field_collection_item', 'value');
  334. }
  335. }
  336. /**
  337. * Implements hook_field_uuid_load().
  338. */
  339. function field_collection_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
  340. entity_property_id_to_uuid($items, 'field_collection_item', 'value');
  341. }
  342. /**
  343. * Implements hook_field_uuid_presave().
  344. */
  345. function field_collection_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  346. entity_property_uuid_to_id($items, 'field_collection_item', 'value');
  347. }
  348. /**
  349. * @} End of "Field implementations"
  350. */
  351. /**
  352. * @defgroup uuid_export Export alterations
  353. * @{
  354. */
  355. /**
  356. * Implements hook_uuid_entities_features_export_entity_alter().
  357. */
  358. function node_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
  359. if ($entity_type == 'node') {
  360. foreach (array('data', 'name', 'picture', 'revision_uid', 'last_comment_timestamp') as $property) {
  361. if (property_exists($entity, $property)) {
  362. unset($entity->{$property});
  363. }
  364. }
  365. }
  366. }
  367. /**
  368. * Implementations hook_uuid_entities_features_export_entity_alter().
  369. */
  370. function user_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
  371. if ($entity_type == 'user') {
  372. foreach (array('data', 'access', 'login') as $property) {
  373. if (property_exists($entity, $property)) {
  374. unset($entity->{$property});
  375. }
  376. }
  377. }
  378. }
  379. /**
  380. * Implements hook_uuid_entities_features_export_alter().
  381. */
  382. function file_uuid_entities_features_export_field_alter($entity_type, $entity, $field, $instance, $langcode, &$items) {
  383. foreach ($items as &$item) {
  384. if (isset($item['timestamp'])) {
  385. unset($item['timestamp']);
  386. }
  387. }
  388. }
  389. /**
  390. * Implements hook_uuid_entities_features_export_entity_alter().
  391. */
  392. function workbench_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
  393. foreach (array('workbench_moderation', 'my_revision', 'workbench_access', 'workbench_access_scheme', 'workbench_access_by_role') as $property) {
  394. if (isset($entity->{$property})) {
  395. unset($entity->{$property});
  396. }
  397. }
  398. }
  399. /**
  400. * @} End of "Export alterations"
  401. */