From d362073c6184ef635dd153488f3f550406d0d5c2 Mon Sep 17 00:00:00 2001
From: Kristiaan Van den Eynde <magentix@gmail.com>
Date: Wed, 29 Jan 2014 14:05:11 +0100
Subject: [PATCH] Issue #2158057 by kristiaanvandeneynde, rogical: UUID
 support for default value in taxonomy term reference field
 settings.

---
 includes/modules/taxonomy.inc   |  102 +++++++++++++++++++++++++--------------
 includes/uuid_bean.features.inc |    4 --
 includes/uuid_node.features.inc |    4 --
 includes/uuid_term.features.inc |   75 +++++++++++++---------------
 uuid_features.module            |   28 ++++-------
 5 files changed, 109 insertions(+), 104 deletions(-)

diff --git a/includes/modules/taxonomy.inc b/includes/modules/taxonomy.inc
index d7fdd7e..659bfad 100644
--- a/includes/modules/taxonomy.inc
+++ b/includes/modules/taxonomy.inc
@@ -1,61 +1,91 @@
 <?php
 /**
  * @file
- * uuid_node hooks on behalf of the taxonomy module.
+ * field_instance features component hooks on behalf of the taxonomy module.
  */
 
 /**
- * Implements hook_uuid_node_features_export_render().
+ * Implements hook_features_pipe_COMPONENT_alter().
  */
-function taxonomy_uuid_node_features_export_alter(&$export, &$pipe, $node) {
-  if (!empty($node->taxonomy)) {
-    foreach ($node->taxonomy as $term) {
-      $vocabulary = taxonomy_vocabulary_load($term->vid);
-      $voc_uuid = $vocabulary->machine_name;
-      $pipe['uuid_vocabulary'][$voc_uuid] = $voc_uuid;
-
-      $term_uuid = $term->uuid;
-      $pipe['uuid_term'][$term_uuid] = $term_uuid;
+function taxonomy_features_pipe_field_instance_alter(&$pipe, $data, &$export) {
+  module_load_include('inc', 'features', 'features.export');
+  $map = features_get_default_map('uuid_term', 'uuid');
+
+  foreach ($data as $identifier) {
+    if ($instance = features_field_instance_load($identifier)) {
+      $field_info = field_info_field($instance['field_name']);
+
+      // Only act on taxonomy term reference fields with defaults.
+      if ($field_info['type'] == 'taxonomy_term_reference' && !empty($instance['default_value'])) {
+        foreach ($instance['default_value'] as $value) {
+          $term = taxonomy_term_load($value['tid']);
+
+          if (!empty($term->uuid)) {
+            // If this uuid_term is already provided by another module,
+            // remove the uuid_term and add the other module as a dependency.
+            if (isset($map[$term->uuid]) && $map[$term->uuid] != $export['module_name']) {
+              if (isset($export['features']['uuid_term'][$term->uuid])) {
+                unset($export['features']['uuid_term'][$term->uuid]);
+              }
+              $module = $map[$term->uuid];
+              $export['dependencies'][$module] = $module;
+            }
+            // Otherwise, add the uuid_term to the pipe.
+            else {
+              $pipe['uuid_term'][] = $term->uuid;
+            }
+          }
+        }
+      }
     }
   }
 }
 
 /**
- * Implements hook_uuid_node_features_export_render_alter().
+ * Implements hook_field_instance_features_export_render_alter().
  */
-function taxonomy_uuid_node_features_export_render_alter(&$export, &$node, $module) {
-  if (!empty($node->taxonomy)) {
-    $export->uuid_term = array();
-    foreach ($node->taxonomy as $term) {
-      $export->uuid_term[] = $term->uuid;
+function taxonomy_field_instance_features_export_render_alter(&$instance) {
+  $field_info = field_info_field($instance['field_name']);
+
+  // Only act on taxonomy term reference fields with defaults.
+  if ($field_info['type'] == 'taxonomy_term_reference' && !empty($instance['default_value'])) {
+    $default_values = array();
+
+    foreach ($instance['default_value'] as $value) {
+      $term = taxonomy_term_load($value['tid']);
+
+      if (!empty($term->uuid)) {
+        $default_values[] = array('uuid' => $term->uuid);
+      }
+      else {
+        watchdog('uuid_features', 'The uuid of term %tid could not be found.', array('%tid' => $term->tid));
+      }
     }
+
+    $instance['default_value'] = $default_values;
   }
 }
 
 /**
- * Implements hook_uuid_node_features_rebuild_alter().
- * Build a taxonomy array suitable for node_save() from the uuid_term array.
+ * Implements hook_field_instance_features_rebuild_alter().
  */
-function taxonomy_uuid_node_features_rebuild_alter(&$node, $module) {
-  if (!empty($node->uuid_term)) {
-    $node->taxonomy = array();
-    foreach ($node->uuid_term as $uuid) {
-      $tid = uuid_taxonomy_term_find($uuid);
-      if (empty($tid)) {
-        // If no tid was found, then the term doesn't exist, and most likely
-        // the uuid_term rebuild needs to run first.
-        // TODO: figure out how to weight feature components.
-        uuid_term_features_rebuild($module);
-
-        // Now try again.
-        $tid = uuid_taxonomy_term_find($uuid);
-        if (empty($tid)) {
+function taxonomy_field_instance_features_rebuild_alter(&$instance) {
+  $field_info = field_info_field($instance['field_name']);
+
+  // Only act on taxonomy term reference fields with defaults.
+  if ($field_info['type'] == 'taxonomy_term_reference' && !empty($instance['default_value'])) {
+    foreach ($instance['default_value'] as $key => $value) {
+      if (!empty($value['uuid'])) {
+        $terms = entity_uuid_load('taxonomy_term', array($value['uuid']));
+        $tid = key($terms);
+
+        if (!empty($tid)) {
+          $instance['default_value'][$key]['tid'] = $tid;
+        }
+        else {
           watchdog('uuid_features', 'The term specified by %uuid could not be found.', array('%uuid' => $uuid));
-          continue;
         }
       }
-
-      $node->taxonomy[] = $tid;
     }
   }
 }
diff --git a/includes/uuid_bean.features.inc b/includes/uuid_bean.features.inc
index 475e453..fbfa247 100644
--- a/includes/uuid_bean.features.inc
+++ b/includes/uuid_bean.features.inc
@@ -37,8 +37,6 @@ function uuid_bean_features_export($data, &$export, $module_name = '') {
   $export['dependencies']['bean_uuid'] = 'bean_uuid';
   $export['dependencies']['uuid_features'] = 'uuid_features';
 
-  uuid_features_load_module_includes();
-
   $bids = entity_get_id_by_uuid('bean', $data);
   foreach ($bids as $uuid => $bid) {
     // Load the bean matching the $bid.
@@ -85,8 +83,6 @@ function uuid_bean_features_export($data, &$export, $module_name = '') {
 function uuid_bean_features_export_render($module, $data) {
   $translatables = $code = array();
 
-  uuid_features_load_module_includes();
-
   $code[] = '  $beans = array();';
   $code[] = '';
   foreach ($data as $uuid) {
diff --git a/includes/uuid_node.features.inc b/includes/uuid_node.features.inc
index 54974d2..e977112 100755
--- a/includes/uuid_node.features.inc
+++ b/includes/uuid_node.features.inc
@@ -37,8 +37,6 @@ function uuid_node_features_export($data, &$export, $module_name = '') {
 
   $export['dependencies']['uuid_features'] = 'uuid_features';
 
-  uuid_features_load_module_includes();
-
   $nids = entity_get_id_by_uuid('node', $data);
   foreach ($nids as $uuid => $nid) {
     // Load the existing node, with a fresh cache.
@@ -66,8 +64,6 @@ function uuid_node_features_export($data, &$export, $module_name = '') {
 function uuid_node_features_export_render($module, $data) {
   $translatables = $code = array();
 
-  uuid_features_load_module_includes();
-
   $code[] = '  $nodes = array();';
   $code[] = '';
   $nids = entity_get_id_by_uuid('node', $data);
diff --git a/includes/uuid_term.features.inc b/includes/uuid_term.features.inc
index efe0b31..69091ca 100644
--- a/includes/uuid_term.features.inc
+++ b/includes/uuid_term.features.inc
@@ -31,58 +31,51 @@ function uuid_term_features_export_options() {
  * Implements hook_features_export().
  */
 function uuid_term_features_export($data, &$export, $module_name = '') {
+  $pipe = array();
+
   $export['dependencies']['taxonomy'] = 'taxonomy';
   $export['dependencies']['uuid'] = 'uuid';
   $export['dependencies']['uuid_features'] = 'uuid_features';
 
-  foreach ($data as $uuid) {
-    uuid_term_features_get_dependencies($export, $uuid);
-  }
-  return array();
-}
+  $tax_map = features_get_default_map('taxonomy');
+  $term_map = features_get_default_map('uuid_term', 'uuid');
 
-/**
- * Adds terms and its dependencies to the export.
- *
- * Parents and term references are handled recursively, other references are not
- * yet supported.
- */
-function uuid_term_features_get_dependencies(&$export, $uuid) {
-  $terms = entity_uuid_load('taxonomy_term', array($uuid));
-  if (!isset($export['features']['uuid_term'])) {
-    $export['features']['uuid_term'] = array();
-  }
-  if (!isset($export['features']['taxonomy'])) {
-    $export['features']['taxonomy'] = array();
-  }
-  if (count($terms)) {
-    $term = reset($terms);
-    $export['features']['uuid_term'][$uuid] = $uuid;
-    $export['features']['taxonomy'][$term->vocabulary_machine_name] = $term->vocabulary_machine_name;
-    // Recursively add all parents and the references of the parents.
-    foreach (taxonomy_get_parents($term->tid) as $parent) {
-      if (!in_array($parent->uuid, $export['features']['uuid_term'])) {
-        uuid_term_features_get_dependencies($export, $parent->uuid);
+  foreach (entity_uuid_load('taxonomy_term', $data) as $term) {
+    $export['features']['uuid_term'][$term->uuid] = $term->uuid;
+
+    // If the parent taxonomy is already provided by another module,
+    // remove the taxonomy and add the other module as a dependency.
+    if (isset($tax_map[$term->vocabulary_machine_name]) && $tax_map[$term->vocabulary_machine_name] != $module_name) {
+      if (isset($export['features']['taxonomy'][$term->vocabulary_machine_name])) {
+        unset($export['features']['taxonomy'][$term->vocabulary_machine_name]);
       }
+      $module = $tax_map[$term->vocabulary_machine_name];
+      $export['dependencies'][$module] = $module;
     }
-    // Get term references.
-    $instances = field_info_instances('taxonomy_term', $term->vocabulary_machine_name);
-    foreach ($instances as $field_name => $instance) {
-      $field = field_info_field($field_name);
-      if ($field['type'] == 'taxonomy_term_reference') {
-        if (isset($term->$field_name)) {
-          foreach ($term->$field_name as $lang => $values) {
-            foreach ($values as $value) {
-              // $value['tid'] already contains the UUID.
-              if (!in_array($value['tid'], $export['features']['uuid_term'])) {
-                uuid_term_features_get_dependencies($export, $value['tid']);
-              }
-            }
-          }
+    // Otherwise, add the taxonomy to the pipe.
+    else {
+      $pipe['taxonomy'][] = $term->vocabulary_machine_name;
+    }
+
+    // Add the term's parents.
+    foreach (taxonomy_get_parents($term->tid) as $parent) {
+      // If the parent term is already provided by another module,
+      // remove the term and add the other module as a dependency.
+      if (isset($term_map[$parent->uuid]) && $term_map[$parent->uuid] != $module_name) {
+        if (isset($export['features']['uuid_term'][$parent->uuid])) {
+          unset($export['features']['uuid_term'][$parent->uuid]);
         }
+        $module = $term_map[$parent->uuid];
+        $export['dependencies'][$module] = $module;
+      }
+      // Otherwise, add the parent term to the pipe.
+      else {
+        $pipe['uuid_term'][] = $parent->uuid;
       }
     }
   }
+
+  return $pipe;
 }
 
 /**
diff --git a/uuid_features.module b/uuid_features.module
index c42f4ef..42f16fd 100644
--- a/uuid_features.module
+++ b/uuid_features.module
@@ -1,6 +1,15 @@
 <?php
 
 /**
+ * Load all polyfills for other modules.
+ */
+require_once 'includes/modules/content.inc';
+require_once 'includes/modules/filefield.inc';
+require_once 'includes/modules/nodereference.inc';
+require_once 'includes/modules/taxonomy.inc';
+require_once 'includes/modules/userreference.inc';
+
+/**
  * Implements hook_menu().
  */
 function uuid_features_menu() {
@@ -71,25 +80,6 @@ function uuid_features_features_api() {
 }
 
 /**
- * Load all include files for enabled modules that this module provides
- * on-behalf-of functionality for.
- */
-function uuid_features_load_module_includes() {
-  static $loaded = FALSE;
-
-  if (!$loaded) {
-    $inc_path = drupal_get_path('module', 'uuid_features') . '/includes/modules';
-    foreach (module_list() as $module) {
-      $file = "$inc_path/$module.inc";
-      if (file_exists($file)) {
-        include_once DRUPAL_ROOT . '/' . $file;
-      }
-    }
-    $loaded = TRUE;
-  }
-}
-
-/**
  * Implements hook_features_pipe_COMPONENT_alter().
  *
  * When exporting a vocabulary, include its terms.
-- 
1.7.9.4

