taxonomy_csv.term.api.inc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /**
  3. * @file
  4. * Find, get and set full or detail term items.
  5. */
  6. /**
  7. * Find a term by its name and load it. This function manages duplicates.
  8. *
  9. * If the term has got duplicates, only first one (lower tid) will be returned.
  10. *
  11. * @note
  12. * Need to maintain a specific function and a direct query, because
  13. * taxonomy_term_load_multiple doesn't manage parents and duplicates.
  14. * db_query() is prefered, because it's four times faster than db_select(),
  15. * EntityFieldQuery and taxonomy_get_term_by_name() (these last two don't manage
  16. * parents'). Anyway terms are loaded to get all fields, specialy parents.
  17. *
  18. * @param $term
  19. * The term object to find. It's not necessarily a standard term object. It's
  20. * an object which needs only a name and eventually a vid, a parent id and a
  21. * language. Of course, if tid is set, the found term is the existing one.
  22. * @param $all_vocabularies
  23. * (Optional) Boolean. Search in all vocabularies or only in $term->vid
  24. * vocabulary (default), which need to be set.
  25. * @param $parent_tid
  26. * (Optional) The direct parent term id where to restrict search.
  27. * Used for structure import. Default to NULL (no parent restriction).
  28. *
  29. * @return
  30. * Formatted found term object, or FALSE if not found or error.
  31. */
  32. function taxonomy_csv_term_find($term, $all_vocabularies = FALSE, $parent_tid = NULL) {
  33. if (isset($term->tid) && $term->tid) {
  34. return taxonomy_term_load($term->tid);
  35. }
  36. static $flag_i18n = NULL;
  37. if (is_NULL($flag_i18n)) {
  38. $flag_i18n = module_exists('i18n_taxonomy');
  39. }
  40. if (isset($term->name)) {
  41. $name = drupal_strtolower(trim($term->name));
  42. // Only term id is selected, because taxonomy_term_load is used next in
  43. // order to take advantage of taxonomy cache.
  44. $sql = '
  45. SELECT t.tid
  46. FROM {taxonomy_term_data} t
  47. INNER JOIN {taxonomy_term_hierarchy} h ON t.tid = h.tid
  48. WHERE :name LIKE LOWER(t.name)
  49. ';
  50. $args = array();
  51. $args[':name'] = $name;
  52. if (isset($term->vid)
  53. && $term->vid
  54. && !$all_vocabularies) {
  55. $sql .= ' AND t.vid = :vid';
  56. $args[':vid'] = $term->vid;
  57. }
  58. if ($flag_i18n && isset($term->language)) {
  59. $sql .= ' AND t.language = :language';
  60. $args[':language'] = $term->language;
  61. }
  62. if ($parent_tid) {
  63. $sql .= ' AND h.parent = :parent';
  64. $args[':parent'] = $parent_tid;
  65. }
  66. $sql .= ' ORDER BY t.tid ASC LIMIT 1';
  67. $result = db_query($sql, $args)->fetchField();
  68. if ($result) {
  69. return taxonomy_term_load($result);
  70. }
  71. }
  72. // Not found or error.
  73. return FALSE;
  74. }
  75. /**
  76. * Find duplicate terms in a vocabulary or in all vocabularies.
  77. *
  78. * @todo
  79. * Use taxonomy_term_load_multiple or regular Drupal 7 query.
  80. *
  81. * @param $vid
  82. * (Optional) Vocabulary to check in.
  83. *
  84. * @return
  85. * An array of term names, indexed by tid.
  86. */
  87. function taxonomy_csv_term_find_duplicate($vid = 0) {
  88. $terms = array();
  89. $sql = '
  90. SELECT t1.tid, t1.name
  91. FROM {taxonomy_term_data} t1
  92. LEFT OUTER JOIN {taxonomy_term_data} t2 ON t1.tid != t2.tid AND LOWER(t1.name) = LOWER(t2.name)
  93. WHERE t2.tid IS NOT NULL
  94. ';
  95. $args = array();
  96. if ($vid) {
  97. $sql .= ' AND t1.vid = :vid AND t2.vid = :vid ';
  98. $args[':vid'] = $vid;
  99. }
  100. $sql .= ' ORDER BY t1.tid ASC ';
  101. $result = db_query($sql, $args)->fetchAllKeyed();
  102. return $result;
  103. }
  104. /**
  105. * Return the first path to the root of a term.
  106. *
  107. * @note
  108. * Drupal and taxonomy_csv use 'parent' property, but taxonomy_get_tree() uses
  109. * 'parents'.
  110. *
  111. * @param $term
  112. * A term object with 'parent' property.
  113. * @param $tree
  114. * A tree array as obtained with taxonomy_get_tree().
  115. *
  116. * @return
  117. * Array of term objects matching to the path of a term to its root term.
  118. * If a term is a root term, return an empty array.
  119. */
  120. function taxonomy_csv_term_get_first_path($term, &$tree) {
  121. $path = array();
  122. // Items need to be ordered from 0 to get first parent easy.
  123. if (isset($term->parent)) {
  124. $term->parent = array_values($term->parent);
  125. }
  126. // Sometime, taxonomy_term_load() return a 'parents', not a 'parent'.
  127. elseif (isset($term->parents)) {
  128. $term->parent = $term->parents;
  129. unset($term->parents);
  130. }
  131. // To use a counter prevents infinite loop when the hierarchy is inconsistent.
  132. $i = 0;
  133. while ($i < 100
  134. // A term root has no parent.
  135. && isset($term->parent)
  136. && !empty($term->parent)
  137. && $term->parent[0] <> 0
  138. ) {
  139. $tid = $term->parent[0];
  140. if ($tid === 0) {
  141. break;
  142. }
  143. // Get the full term from the tree.
  144. foreach ($tree as $parent) {
  145. if ($parent->tid == $tid) {
  146. break;
  147. }
  148. }
  149. if (isset($parent->parents)) {
  150. $parent->parent = array_values($parent->parents);
  151. unset($parent->parents);
  152. }
  153. $path[] = $term = $parent;
  154. $i++;
  155. }
  156. // The path is reversed in order to begin with root term.
  157. return array_reverse($path);
  158. }
  159. /**
  160. * Delete multiple terms.
  161. *
  162. * @param $tids
  163. * An array of taxonomy term IDs.
  164. *
  165. * @return
  166. * TRUE.
  167. */
  168. function taxonomy_csv_term_delete_multiple($tids) {
  169. if (!is_array($tids)) {
  170. return FALSE;
  171. }
  172. foreach ($tids as $tid) {
  173. taxonomy_term_delete($tid);
  174. }
  175. return TRUE;
  176. }