Index: taxonomy_export.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_export/taxonomy_export.install,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 taxonomy_export.install
--- taxonomy_export.install	19 Jun 2009 00:04:48 -0000	1.1.2.1
+++ taxonomy_export.install	12 Nov 2009 09:52:55 -0000
@@ -21,3 +21,10 @@
 
   return $requirements;
 }
+
+/**
+ * Implementation of hook_uninstall()
+ */
+function taxonomy_export_uninstall() {
+  variable_del('taxonomy_export_loaded_vocabularies');
+}
Index: taxonomy_export.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_export/taxonomy_export.module,v
retrieving revision 1.1
diff -u -r1.1 taxonomy_export.module
--- taxonomy_export.module	18 Jun 2009 23:36:43 -0000	1.1
+++ taxonomy_export.module	12 Nov 2009 09:53:46 -0000
@@ -44,3 +44,86 @@
 
   return $items;
 }
+                                                      
+/**
+ * Implementation of hook_features_api().
+ */
+function taxonomy_export_features_api() {
+  $base = array(
+    'file' => drupal_get_path('module', 'taxonomy_export') .'/taxonomy_export.export.inc',
+    'default_hook' => 'taxonomy_export_defaults',
+    'default_file' => FEATURES_DEFAULTS_CUSTOM,
+    'default_filename' => 'features.taxonomy_export',
+    'feature_source' => TRUE,
+  );
+  
+  return array(
+    'vocabularies' => $base,
+    'terms' => $base,   
+  ); 
+}
+
+/**
+ * Load default vocabularies
+ */
+function taxonomy_export_features_api() {
+  $loaded = variable_get('taxonomy_export_loaded_vocabularies', array());
+  $vocabularies = module_invoke_all('taxonomy_export_defaults');
+  
+  foreach ($vocabularies as $munged_name => $vocabulary) {
+    if (! isset($loaded[$munged_name])) {
+      $terms = NULL;
+      if (isset($vocabulary['terms'])) {
+        $terms = $vocabulary['terms'];
+        unset($vocabulary['terms']);
+      }
+      
+      taxonomy_save_vocabulary($vocabulary);
+      $loaded[$munged_name] = $vocabulary['vid'];
+      
+      if ($terms) {
+        // Parent map keeps track of existing TID hierarchy, allowing it to
+        // be recreated.
+        $parent_tid_map = array();
+
+        // Pass #1, create all the terms
+        foreach ($terms as $key => &$term) {
+          $parent_tid_map[$term['tid']] = $key;
+
+          $term_array = $term;
+          $term_array['tid'] = NULL;
+          $term_array['vid'] = $vocabulary['vid'];
+          $term_array['parent'] = array(0 => 0);
+          taxonomy_save_term($term_array);
+
+          // Update the original $taxonomy_export structure with the new TID,
+          // VID, and parent attributes.
+          $term['tid'] = $term_array['tid'];
+          $term['vid'] = $term_array['vid'];
+
+          // taxonomy_get_tree() returns the hierarchy in a "parents" attribute
+          // while taxonomy_save_term() requires a "parent" attribute ...
+          $term['parent'] = $term['parents'];
+        }
+
+        // Pass #2, rebuild the term hierarchy
+        foreach ($terms as $key => $term) {
+          if ($term['parent'][0] == 0) {
+            continue;
+          }
+
+          foreach ($term['parent'] as $pkey => $ptid) {
+            // The parent TIDs are still relative to the old imported TIDs, use
+            // the $parent_tid_map created earlier to lookup the new TID for this
+            // parent.
+            $term['parent'][$pkey] = $terms[$parent_tid_map[$ptid]]['tid'];
+          }
+
+          taxonomy_save_term($term);
+        }
+      }
+    }
+  }
+  
+  variable_set('taxonomy_export_loaded_vocabularies', $loaded);
+}
--- taxonomy_export.export.inc
+++ taxonomy_export.export.inc
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Implementation of hook_features_export().
+ */
+function vocabularies_features_export($data, &$export, $module_name = '', $type = 'vocabularies') {
+  $pipe = array();
+  $vocabularies = taxonomy_get_vocabularies();
+  
+  foreach ($data as $vid) {
+    if (isset($vocabularies[$vid])) {
+      $export['features'][$type][$vid] = $vocabularies[$vid]->name;
+    }
+  }
+  
+  $export['dependencies'][$type] = 'taxonomy_export';
+  return $pipe;
+}
+
+/**
+ * Implementation of hook_features_export().
+ */
+function terms_features_export($data, &$export, $module_name = '') {
+  return vocabularies_features_export($data, $export, $module_name, 'terms');
+}
+
+/**
+ * Implementation of hook_features_export_options().
+ */
+function vocabularies_features_export_options() {
+  $options = array_map(create_function('$voc', 'return $voc->name;'), taxonomy_get_vocabularies());
+  return $options;
+}
+
+/**
+ * Implementation of hook_features_export_options().
+ */
+function terms_features_export_options() {
+  return vocabularies_features_export_options();
+}
+
+/**
+ * Implementation of hook_features_export_render().
+ */
+function vocabularies_features_export_render($module = 'foo', $data, $type = 'vocabularies') {
+  static $vocabularies = array();
+  
+  $output = array();
+  $output[] = '  $vocabularies = array();';
+  $output[] = '';
+  
+  foreach (array_keys($data) as $vid) {
+    // Even if vocabulary has not been checked in 'vocabularies' tab but only in 'terms' tab,
+    // it is added. Indeed it has no sense to try to import terms without a vocabulary.
+    if (! isset($vocabularies[$vid]) && ($vocabulary = taxonomy_vocabulary_load($vid))) {
+      $vocabularies[$vid] = (array) $vocabulary;
+      // Clobber the VID, currently "updating" existing vocabularies is
+      // unsupported, new vocabularies will always be created.
+      unset($vocabularies[$vid]['vid']);
+    
+      // Add Translation mode for vocabulary if Multilingual options enabled for taxonomy.
+      if (module_exists('i18ntaxonomy')) {
+        $vocabularies[$vid]['i18nmode'] = i18ntaxonomy_vocabulary($form_state['values']['vid']);
+      }
+    }
+    
+    if ($type == 'terms' && ! isset($vocabularies[$vid]['terms'])) {
+      $vocabularies[$vid]['terms'] = array_map(create_function('$term', 'return (array) $term;'), taxonomy_get_tree($vid));
+    }
+  }
+
+  ksort($vocabularies);
+  foreach ($vocabularies as $vocabulary) {
+    // $munged_vocabulary_name is used to avoid import several times a vocabulary
+    // through hook_taxonomy_export_defaults().
+    $munged_vocabulary_name = strtolower(preg_replace('/[^A-Za-z0-9-]/', '_', $vocabulary['name']));
+    $output[] = '  $vocabularies['. $munged_vocabulary_name  .'] = '. features_var_export($vocabulary, '  ') .';';
+    $output[] = '';
+  }
+  
+  $output = implode("\n", $output);
+  return array('taxonomy_export_defaults' => $output);
+}
+
+/**
+ * Implementation of hook_features_export_render().
+ */
+function terms_features_export_render($module = 'foo', $data, $type = 'vocabularies') {
+  return vocabularies_features_export_render($module, $data, 'terms');
+}
+
+/**
+ * Implementation of hook_features_revert().
+ */
+function vocabularies_features_revert($module = NULL) {
+  if (module_hook($module, 'taxonomy_export_defaults')) {
+    $vocabularies = module_invoke($module, 'taxonomy_export_defaults');
+    $loaded = variable_get('taxonomy_export_loaded_vocabularies', array());
+
+    foreach (array_keys($vocabularies) as $munged_name) {
+      if (isset($loaded[$munged_name])) {
+        taxonomy_del_vocabulary($loaded[$munged_name]);
+        unset($loaded[$munged_name]);
+      }
+    }
+    
+    variable_set('taxonomy_export_loaded_vocabularies', $loaded);
+  }
+  else {
+    drupal_set_message(t('Could not load default vocabularies.'), 'error');
+    return FALSE;
+  }
+  return TRUE;
+}
+


