From 997fdadc5a0ce3d9a6f773e097be3d16996252bb Mon Sep 17 00:00:00 2001
From: theduke <theduke@644976.no-reply.drupal.org>
Date: Sat, 31 Mar 2012 11:25:03 +0200
Subject: [PATCH] Issue 726490 by theduke: Improved taxonomy term deletion
 with multiple parents and added two unit tests.

---
 core/modules/taxonomy/taxonomy.module |   11 ++++-
 core/modules/taxonomy/taxonomy.test   |   91 +++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 1 deletions(-)

diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 47cde42..8b5da84 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -763,11 +763,20 @@ function taxonomy_term_delete($tid) {
         // See if any of the term's children are about to be become orphans:
         if ($children = taxonomy_term_load_children($tid)) {
           foreach ($children as $child) {
-            // If the term has multiple parents, we don't delete it.
             $parents = taxonomy_term_load_parents($child->tid);
+
+            // If the child has only one parent, we delete it.
             if (count($parents) == 1) {
               $orphans[] = $child->tid;
             }
+            // If the child has multiple parents,
+            // we do not delete it, but we remove the parent reference.
+            elseif (count($parents) > 1) {
+              db_delete('taxonomy_term_hierarchy')
+                ->condition('tid', $child->tid)
+                ->condition('parent', $tid)
+                ->execute();
+            }
           }
         }
 
diff --git a/core/modules/taxonomy/taxonomy.test b/core/modules/taxonomy/taxonomy.test
index de50f2a..66a1132 100644
--- a/core/modules/taxonomy/taxonomy.test
+++ b/core/modules/taxonomy/taxonomy.test
@@ -484,6 +484,97 @@ class TaxonomyTermUnitTest extends TaxonomyWebTestCase {
     $this->assertEqual(2, $depth_count[2], 'Two elements in taxonomy tree depth 2.');
     $this->assertEqual(1, $depth_count[3], 'One element in taxonomy tree depth 3.');
    }
+   
+   /**
+    * Test taxonomy behaviour when deleting terms in a hierarchy with 
+    * a linear structure (only one parent per term).
+    */
+   function testTermDeleteSingleParent() {
+     // Create a new vocabulary with 6 terms.
+     $vocabulary = $this->createVocabulary();
+     $term = array();
+     for ($i = 0; $i < 6; $i++) {
+       $term[$i] = $this->createTerm($vocabulary);
+     }
+     
+     // $term[1] is a child of 0.
+     $term[1]->parent = array($term[0]->tid);
+     taxonomy_term_save($term[1]);
+     
+     // $term[3] is a child of 2.
+     $term[3]->parent = array($term[2]->tid);
+     taxonomy_term_save($term[3]);
+     // $term[4] is a child of 3.
+     $term[4]->parent = array($term[3]->tid);
+     taxonomy_term_save($term[4]);
+     // $term[5] is a child of 4.
+     $term[5]->parent = array($term[4]->tid);
+     taxonomy_term_save($term[5]);
+     
+     /**
+      * Expected tree:
+      * term[0] | depth: 0
+      * --term[1] | depth: 1
+      * 
+      * term[2] | depth: 0
+      * --term[3] | depth: 1
+      * ----term[4] | depth: 2
+      * ------ term[5] | depth: 3
+      */
+     
+     // Ensure that the children of a term are deleted on parent deletion.
+     taxonomy_term_delete($term[0]->tid);
+     $termOne = taxonomy_term_load($term[1]->tid);
+     $this->assertFalse($termOne, 'Child of term was automatically deleted on parent deletion.');
+     
+     // repeat the test with deeper tree
+     taxonomy_term_delete($term[2]->tid);
+     $terms = taxonomy_term_load_multiple(array($term[3]->tid, $term[4]->tid, $term[5]->tid));
+     $this->assertTrue(empty($terms), 'Children of term were automatically deleted on parent deletion.');
+   }
+   
+   /**
+   * Test taxonomy behaviour when deleting terms in a hierarchy with
+   * a non-linear structure (terms with multiple parents).
+   */
+   function testTermDeleteMultipleParents() {
+     // Create a new vocabulary with 3 terms.
+     $vocabulary = $this->createVocabulary();
+     $term = array();
+     for ($i = 0; $i < 3; $i++) {
+       $term[$i] = $this->createTerm($vocabulary);
+     }
+      
+     // $term[2] is a child of 0 and 1.
+     $term[2]->parent = array($term[0]->tid, $term[1]->tid);
+     taxonomy_term_save($term[2]);
+     /**
+      * Expected tree:
+      * term[0] 
+      * --term[2]
+      * term[1]
+      * --term[2] 
+      */
+      
+     // Ensure that a child term does NOT get auto-deleted when it has another parent,
+     // and that it stays connected to the parent.
+     taxonomy_term_delete($term[1]->tid);
+     $children = taxonomy_term_load_children($term[0]->tid);
+     $this->assertFalse(empty($children), 'Child of term was not deleted since it had another parent.');
+      
+     // Ensure that the parent reference to the deleted parent was removed.
+     $result = db_select('taxonomy_term_hierarchy', 't')
+      ->fields('t')
+      ->condition('tid', $term[2]->tid)
+      ->condition('parent', $term[1]->tid)
+      ->execute();
+     
+     $this->assertEqual(
+       0,
+       $result->rowCount(), 
+       'Term parent reference was correctly deleted from taxonomy_term_hierarchy.'
+     );
+   }
 }
 
 /**
-- 
1.7.5.4

