From 6fc4eb9f945ecd7c2bea4742e3febe4632c88e99 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Wed, 3 Jun 2009 19:34:53 +0000
Subject: [PATCH] - Patch #343788 by catch: taxonomy module doesn't use its own
 APIs.

---
 modules/taxonomy/taxonomy.module | 45 ++++++++++++--------------------
 modules/taxonomy/taxonomy.test   | 44 ++++++++++++++++++++++++++-----
 2 files changed, 53 insertions(+), 36 deletions(-)

diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index e3b3c363836..7c6889c03d1 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -504,7 +504,6 @@ function taxonomy_terms_static_reset() {
   drupal_static_reset('taxonomy_get_tree');
   drupal_static_reset('taxonomy_get_synonym_root');
   drupal_static_reset('taxonomy_term_load_multiple');
-  drupal_static_reset('taxonomy_get_term_data');
 }
 
 /**
@@ -1119,13 +1118,7 @@ function taxonomy_term_count_nodes($tid, $type = NULL) {
  *   An array of matching term objects.
  */
 function taxonomy_get_term_by_name($name) {
-  $query = db_select('taxonomy_term_data', 't');
-  $query->addTag('term_access');
-
-  return $query
-    ->fields('t')
-    ->where("LOWER(t.name) = LOWER(:name)", array(':name' => trim($name)))
-    ->execute()->fetchAll();
+  return taxonomy_term_load_multiple(array(), array('name' => trim($name)));
 }
 
 /**
@@ -1328,9 +1321,14 @@ function taxonomy_term_load_multiple($tids = array(), $conditions = array()) {
 
   // Remove any loaded terms from the array if they don't match $conditions.
   if ($conditions) {
+    // Name matching is case insensitive, note that with some collations 
+    // LOWER() and drupal_strtolower() may return different results.
     foreach ($terms as $term) {
       $term_values = (array) $term;
-      if (array_diff_assoc($conditions, $term_values)) {
+      if (isset($conditions['name']) && drupal_strtolower($conditions['name'] != drupal_strtolower($term_values['name']))) {
+        unset($terms[$term->tid]);
+      }
+      elseif (array_diff_assoc($conditions, $term_values)) {
         unset($terms[$term->tid]);
       }
     }
@@ -1350,6 +1348,11 @@ function taxonomy_term_load_multiple($tids = array(), $conditions = array()) {
 
     // If the conditions array is populated, add those to the query.
     if ($conditions) {
+      // When name is passed as a condition use LIKE.
+      if (isset($conditions['name'])) {
+        $query->condition('t.name', $conditions['name'], 'LIKE');
+        unset($conditions['name']);
+      }
       foreach ($conditions as $field => $value) {
         $query->condition('t.' . $field, $value);
       }
@@ -1398,22 +1401,6 @@ function taxonomy_term_load($tid) {
   return $term ? $term[$tid] : FALSE;
 }
 
-/**
- * Return a term object from the taxonomy_term_data table.
- * @param $tid
- *   A term's ID
- * @return Object
- *  A term object. Results are statically cached.
- */
-function taxonomy_get_term_data($tid) {
-  $terms = &drupal_static(__FUNCTION__, array());
-
-  if (!isset($terms[$tid])) {
-    $terms[$tid] = db_query('SELECT * FROM {taxonomy_term_data} WHERE tid = :tid', array(':tid' => $tid))->fetch();
-  }
-  return $terms[$tid];
-}
-
 /**
  * Create a select form element for a given taxonomy vocabulary.
  *
@@ -1511,10 +1498,10 @@ function taxonomy_select_nodes($tids = array(), $operator = 'or', $depth = 0, $p
   if ($depth === 'all') {
     $depth = NULL;
   }
-  foreach ($tids as $index => $tid) {
-    $term = taxonomy_get_term_data($tid);
-    $tree = taxonomy_get_tree($term->vid, $tid, $depth);
-    $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
+  $terms = taxonomy_term_load_multiple($tids);
+  foreach ($terms as $term) {
+    $tree = taxonomy_get_tree($term->vid, $term->tid, $depth);
+    $descendant_tids[] = array_merge(array($term->tid), array_map('_taxonomy_get_tid_from_term', $tree));
   }
 
   $query = db_select('node', 'n');
diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test
index a1ce27127fb..24f12bd5014 100644
--- a/modules/taxonomy/taxonomy.test
+++ b/modules/taxonomy/taxonomy.test
@@ -525,7 +525,7 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     // Create the term to edit.
     $this->drupalPost('admin/content/taxonomy/' . $this->vocabulary->vid . '/add', $edit, t('Save'));
 
-    $term = taxonomy_get_term_by_name($edit['name']);
+    $term = reset(taxonomy_get_term_by_name($edit['name']));
     $this->assertNotNull($term, t('Term found in database'));
 
     // Submitting a term takes us to the add page; we need the List page.
@@ -546,21 +546,52 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     );
 
     // Edit the term.
-    $this->drupalPost('taxonomy/term/' . $term[0]->tid . '/edit', $edit, t('Save'));
+    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
 
     // View the term and check that it is correct.
-    $this->drupalGet('taxonomy/term/' . $term[0]->tid);
+    $this->drupalGet('taxonomy/term/' . $term->tid);
     $this->assertText($edit['name'], t('The randomly generated term name is present.'));
     $this->assertText($edit['description'], t('The randomly generated term description is present.'));
 
     // Delete the term.
-    $this->drupalPost('taxonomy/term/' . $term[0]->tid . '/edit', array(), t('Delete'));
+    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', array(), t('Delete'));
     $this->drupalPost(NULL, NULL, t('Delete'));
 
     // Assert that the term no longer exists.
-    $this->drupalGet('taxonomy/term/' . $term[0]->tid);
+    $this->drupalGet('taxonomy/term/' . $term->tid);
     $this->assertResponse(404, t('The taxonomy term page was not found'));
   }
+
+  /**
+   * Test taxonomy_get_term_by_name().
+   */
+  function testTaxonomyGetTermByName() {
+    $term = $this->createTerm($this->vocabulary->vid);
+
+    // Load the term with the exact name.
+    $terms = taxonomy_get_term_by_name($term->name);
+    $this->assertTrue(isset($terms[$term->tid]), t('Term loaded using exact name.'));
+
+    // Load the term with space concatenated.
+    $terms  = taxonomy_get_term_by_name('  ' . $term->name . '   ');
+    $this->assertTrue(isset($terms[$term->tid]), t('Term loaded with extra whitespace.'));
+
+    // Load the term with name uppercased.
+    $terms = taxonomy_get_term_by_name(strtoupper($term->name));
+    $this->assertTrue(isset($terms[$term->tid]), t('Term loaded with uppercased name.'));
+
+    // Load the term with name lowercased.
+    $terms = taxonomy_get_term_by_name(strtolower($term->name));
+    $this->assertTrue(isset($terms[$term->tid]), t('Term loaded with lowercased name.'));
+
+    // Try to load an invalid term name.
+    $terms = taxonomy_get_term_by_name('Banana');
+    $this->assertFalse($terms);
+
+    // Try to load the term using a substring of the name.
+    $terms = taxonomy_get_term_by_name(drupal_substr($term->name, 2));
+    $this->assertFalse($terms);
+  }
 }
 
 /**
@@ -664,8 +695,7 @@ class TaxonomyHooksTestCase extends DrupalWebTestCase {
       'antonyms' => 'Long',
     );
     $this->drupalPost('admin/content/taxonomy/1/add', $edit, t('Save'));
-    $terms = taxonomy_get_term_by_name($edit['name']);
-    $term = taxonomy_term_load($terms[0]->tid);
+    $term = reset(taxonomy_get_term_by_name($edit['name']));
     $this->assertEqual($term->antonyms[0], $edit['antonyms'], t('Antonyms were loaded into the term object'));
 
     // Update the term with a different antonym.