--- taxonomy_xml.module	2006-05-05 22:13:44.000000000 +0200
+++ new\taxonomy_xml.module	2006-06-28 18:09:48.000000000 +0200
@@ -1,7 +1,20 @@
 <?php
-/* $Id: taxonomy_xml.module,v 1.3 2006/05/05 20:13:44 etopian Exp $ */
+/* $Id */
 
 /**
+    TODO: fix vocabulary-node association: wrong node types??
+    TODO: fix GLOBALS variables Name (use standard notation)
+    
+	28/06/2006 by thePanz:
+    - import: checking if term already exists using name and hierarchy
+		- import: using file_read_contents() instead of using file handlers
+		- export: default filename is "taxonomy_VocabularyName.xml"
+		- export: XML is more human-readable: added indents and line feed
+    - export: using $_SERVER[] superglobal for browser checking
+		- displayed information on import process
+        - displayed warning if non vocabulary is present
+        - Fixed some help text (export)
+        
     Copyright (c) 2006  Sami Khan <sami@etopian.com>
     Copyright (c) 2005  Sheldon Rampton <sheldon@prwatch.org>
                                                                                 
@@ -18,8 +31,6 @@
  */
 
 
-
-
 /**
  * Implementation of hook_help().
  */
@@ -32,7 +43,7 @@ function taxonomy_xml_help($section) {
 	  "use the \"add to vocabulary\" selector below. If you select \"determined by source file,\" the add to vocabulary will be specified by the XML document itself. ".
 	  "(To avoid duplications, already-existing terms will not be added.)");
     case 'admin/taxonomy/export':
-      return t("XML documents for each vocabulary and its terms in this website's %taxonomies can be downloaded from the list below.",
+      return t("You can export XML documents for each vocabulary and its terms in this website's %taxonomies. Choose the vocabulary from the list below.",
 			   array('%taxonomies' => l(t("taxonomies"), "admin/help/taxonomy")));
     case 'admin/help#taxonomy_xml':
       return t("This module makes it possible to import and export vocabularies and taxonomy terms via XML (requires taxonomy.module). ".
@@ -75,13 +86,20 @@ function taxonomy_xml_menu($may_cache) {
  * taxonomy_xml_export
  */
 function taxonomy_xml_export() {
-  // return the list 
+  // return the list of vocabularies
+  $output = '';
   $vocabularies = module_invoke('taxonomy', 'get_vocabularies');
-  $output .= "<ul>";
-  foreach ($vocabularies as $vocabulary) {
-    $output .= "<li>" . l($vocabulary->name, "taxonomy_xml/$vocabulary->vid") . "</li>\n";
+  
+  if(empty($vocabularies)){
+    $output .= t('There are no vocabularies present');
+  }
+  else{
+    $output .= "\n<ul>";
+    foreach ($vocabularies as $vocabulary) {
+      $output .= "\n\t<li>". l($vocabulary->name, "taxonomy_xml/$vocabulary->vid") . '</li>';
+    }
+    $output .= "\n</ul>";
   }
-  $output .= "</ul>";
   return $output;
 }
 
@@ -90,8 +108,15 @@ function taxonomy_xml_export() {
  */
 function taxonomy_xml_file() {
   $vid = arg(1);
+  
+  //retriving Vocabulary name
+  $vocabulary = (array) (module_invoke('taxonomy', 'get_vocabulary', $vid));
+  $vname = str_replace(' ','',trim($vocabulary['name']));
+  unset($vocabulary);
+  
   $file = taxonomy_xml_create($vid);
-  if (!empty($HTTP_USER_AGENT) && (strpos($HTTP_USER_AGENT, 'MSIE 5.5') || strpos($HTTP_USER_AGENT, 'Opera'))) {
+  
+  if (!empty($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.5') || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera'))) {
     header('Content-Type: application/dummy');
   } else {
     header('Content-Type: application/octet-stream');
@@ -100,7 +125,7 @@ function taxonomy_xml_file() {
     echo 'Some data has already been output to browser, can\'t send file';
   }
   header('Content-Length: ' . strlen($file));
-  header("Content-Disposition: attachment; filename=taxonomy_$vid.xml");
+  header("Content-Disposition: attachment; filename=taxonomy_$vname.xml");
   echo $file;
 }
 
@@ -109,7 +134,8 @@ function taxonomy_xml_file() {
  * taxonomy_xml_import
  */
 function taxonomy_xml_import() {
- 
+  $output = '';
+  
   $op = $_POST["op"];
   $edit = $_POST["edit"];
   
@@ -117,9 +143,9 @@ function taxonomy_xml_import() {
     $op = arg(1);
   }
   switch ($op) {
-    case 'load':
-      $output = taxonomy_xml_import_load($edit);
+    case 'load': taxonomy_xml_import_load($edit);
     case 'import':
+	
     default:
       $output .= taxonomy_xml_import_form($edit);
   }
@@ -131,29 +157,29 @@ function taxonomy_xml_import() {
  */
 function taxonomy_xml_import_load($edit) {
   if ($file = file_check_upload(xml)) {
-    $fd = fopen($file->filepath, "rb");
-    if (!$fd) {
-      $output = '<p>' . t('Vocabulary import failed: file %filename cannot be read.', array('%filename' => "<em>$file->filename</em>")) . "</p>\n";
-    } else {
-      $info = fstat($fd);
-      $len = $info["size"];
-      $text = fread($fd, $len);
-
-      fclose($fd);
-	   $output = '<p>' . t('Loaded file %filename.', array('%filename' => "<i>$file->filename</i>")) . "</p>\n";
-     
-	   $output .= taxonomy_xml_parse($text, $edit['vid'], $edit['term']);
+
+	if(!is_readable($file->filepath)){
+		drupal_set_message(t('Vocabulary import failed: file %filename cannot be read.', array('%filename' => "<em>$file->filename</em>")),
+							'error');
+    }
+	else {
+		$text = file_get_contents($file->filepath);
+		//drupal_set_message(t('Loaded file %filename.', array('%filename' => "<i>$file->filename</i>")));
+		drupal_set_message(taxonomy_xml_parse($text, $edit['vid'], $edit['term']));
     }
-  } else {
-    $output = '<p>' . t('Vocabulary import failed: file was not uploaded.') . "</p>\n";
   }
-  return '<div id="taxonomy_xml_import_results">' . $output . "</div>\n";
+  else{
+	drupal_set_message(t('Vocabulary import failed: file was not uploaded.'),'error');
+  }
+ 
+  return true;
 }
 
 /**
  * taxonomy_xml_import_form
  */
 function taxonomy_xml_import_form($edit) {
+  $output = '';
   if (!$edit['vid']) {
     $edit['vid'] = 0;
   }
@@ -174,7 +200,14 @@ function taxonomy_xml_import_form($edit)
     '#title' => ('Select a term from the vocabulary.'),
     '#description' => t("Allows a selection of a term in the vocabulary to be the parent of the imported taxonomy."),
   );*/
-
+  /*
+  $form["preserve_ids"] = array(
+    '#type' => 'checkbox',
+    '#title' => t("Preserve old term and vocabulary ID's"),
+    '#default_value' => true,
+    '#description' => t("Allow of inserting vocabularies and terms using old ID's")  
+  );
+  */
 
   $form["xml"] = array(
     '#type' => 'file',
@@ -191,8 +224,7 @@ function taxonomy_xml_import_form($edit)
   $form['#action'] = url('admin/taxonomy/import');
   $form['#attributes'] = array('enctype' => 'multipart/form-data');
   
-  $output = drupal_get_form('taxonomy_import', $form);
-  
+  $output .= drupal_get_form('taxonomy_import', $form);
   return $output;
 }
 
@@ -220,28 +252,30 @@ function taxonomy_xml_create($vid, $pare
   $tree = module_invoke('taxonomy', 'get_tree', $vid, $parent, $depth, $max_depth);
   if ($tree) {
     $vocabulary = module_invoke('taxonomy', 'get_vocabulary', $vid);
-    $output .= "<vocabulary>\n";
+    $output .= "<vocabulary>";
     foreach ($vocabulary as $key => $value) {
+	  $output .= "\n\t<$key>";
 	  if (is_array($value)) {
-        $output .= "<$key>" . check_plain(implode(',', $value)) . "</$key>";
+        $output .= check_plain(implode(',', $value));
       } else {
-        $output .= "<$key>" . check_plain($value) . "</$key>";
+        $output .= check_plain($value);
       }
+	  $output .= "</$key>";
     }
     foreach ($tree as $term) {
-	  $output .= "<term>";
+	  $output .= "\n\t<term>";
       foreach ($term as $key => $value) {
 	    if ($key == 'parents') {
           foreach ($value as $parent) {
-		    $output .= "<parent>" . check_plain($parent) . "</parent>";
+		    $output .= "\n\t\t<parent>" . check_plain($parent) . "</parent>";
 		  }
 		} else {
-          $output .= "<$key>" . check_plain($value) . "</$key>";
+          $output .= "\n\t\t<$key>" . check_plain($value) . "</$key>";
         }
       }
-      $output .= "</term>";
+      $output .= "\n\t</term>";
     }
-    $output .= "</vocabulary>\n";
+    $output .= "\n</vocabulary>";
   }
   return $output;
 }
@@ -280,7 +314,7 @@ function taxonomy_xml_element_end($parse
  * Call-back function used by the XML parser.
  */
 function taxonomy_xml_element_data($parser, $data) {
-  global $vocabulary, $element, $terms, $term, $image, $tag;
+  global $vocabulary, $element, $terms, $term, $tag;
 
   switch ($element) {
     case 'term':
@@ -289,17 +323,17 @@ function taxonomy_xml_element_data($pars
           $terms[$term][$tag][] = $data;
         }
       } else {
-        $terms[$term][$tag] .= $data;
+        $terms[$term][$tag] .= rtrim($data);
       }
       break;
     default:
-      $vocabulary[$tag] .= $data;
+      $vocabulary[$tag] .= rtrim($data);
   }
 }
 
 function taxonomy_xml_parse(&$data, $vid, $parent_tid = NULL) {
   global $terms, $vocabulary;
-
+  
   // Unset the global variables before we use them:
   unset($GLOBALS['element'], $GLOBALS['term'], $GLOBALS['tag']);
   $terms = array();
@@ -321,7 +355,6 @@ function taxonomy_xml_parse(&$data, $vid
   
   // If an existing vocabulary has been chosen or has the same name as the vocabulary being added,
   // terms should be added to the existing vocabulary. Otherwise a new vocabulary should be created.
-  
   if($vid == 0){
     $name = $vocabulary['name'];
     $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name)));
@@ -335,37 +368,53 @@ function taxonomy_xml_parse(&$data, $vid
   }else{
     $vocabulary = (array) (module_invoke('taxonomy', 'get_vocabulary', $vid));
   }
-
   
+  $terms_new_tid = array();
+  $terms_existing = array();
+  
+  //sorting XML to first insert root nodes
+  usort($terms,"_taxonomy_xml_terms_reorder");
+ 
   foreach ($terms as $term) {
     $term['vid'] = $vocabulary['vid'];
     $term['old_tid'] = $term['tid'];
   	unset($term['tid']);
   	if (is_array($term['parent'])) {
-        foreach ($term['parent'] as $key => $value) {
-          if ($value) {
-            $term['parent'][$key] = $new_tid[$value];
-          }
+      foreach ($term['parent'] as $key => $value) {
+        if ($value) {
+          $term['parent'][$key] = $terms_new_tid[$value];
         }
       }
+    }
+      
     // If the term doesn't already exist in this vocabulary, add it.
+    // Checking term hierarchy
   	$term_exists = false;
-    $existing_terms = module_invoke('taxonomy', 'get_term_by_name', $term['name']);
+    $terms_existing = module_invoke('taxonomy', 'get_term_by_name', $term['name']);
   	
-    if(count($existing_terms > 0)){
-      foreach ($existing_terms as $existing_term) {
+    if(count($terms_existing) > 0){
+      foreach ($terms_existing as $existing_term) {
     	  if ($existing_term->vid == $term['vid']) {
-          $term_exists = true;
-          //not quite sure what this statement does:
-          $new_tid[$term['old_tid']] = $existing_term->tid;
-          $skipped_terms[$existing_term->name] = 1;
+          //terms already exists in DB, checking if it has the same parents
+          $term_parents = (array) module_invoke('taxonomy','get_parents',$existing_term->tid);
+          
+          //searching if term's parents are the same
+          while(current($term['parent']) && !$term_exists ){
+            if(array_key_exists(key($term['parent']),$term_parents)){
+              $term_exists = true;
+              // Skipping existing term and saving termID for later import
+              $terms_new_tid[$term['old_tid']] = $existing_term->tid;
+              $skipped_terms[$existing_term->name] = 1;
+            }
+            next($term['parent']);
+          }
         }
     	}
   
     }
     if (!$term_exists){
         taxonomy_save_term($term);
-        $new_tid[$term['old_tid']] = $term['tid'];
+        $terms_new_tid[$term['old_tid']] = $term['tid'];
         $new_terms[] = $term['name'];
      }    
   }
@@ -373,7 +422,7 @@ function taxonomy_xml_parse(&$data, $vid
 
   $output .= '<p>' . t('Vocabulary') .  ' "' . $vocabulary['name'] . '": ';
   if ($new_terms) {
-    $output .= t('added term(s)') . ' <i>' . implode(', ', $new_terms) . '.</i> ';
+    $output .= t('added term(s)') . ': <i>' . implode(', ', $new_terms) . '</i>.';
   } else {
     $output .= t('no terms added. ');
   }
@@ -381,7 +430,20 @@ function taxonomy_xml_parse(&$data, $vid
     $output .= t('Ignored duplicate term(s)') . ' <i>' . implode(', ', array_keys($skipped_terms)) . '.</i>';
   }
   $output .=  "</p>\n";
-  return '<div id="taxonomy_xml_parse_results">' . $output . "</div>\n";
+  return $output;
+}
+
+/**
+ * Sorting XML to FIRST insert root nodes
+ */
+function _taxonomy_xml_terms_reorder($item1, $item2){
+  if (isSet($item1['parent']) && !isSet($item2['parent'])){
+    return 1;
+  }
+  else{
+    // TODO: check for order of 2nd level parents...
+    return -1;
+  }
 }
 
 
