taxonomy_csv.vocabulary.api.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * @file
  4. * Prepare and manage vocabularies.
  5. */
  6. /**
  7. * Creates vocabulary by its name and returns vocabulary object.
  8. *
  9. * @param $name
  10. * (Optional) Name of vocabulary to create.
  11. *
  12. * @return
  13. * Created vocabulary object.
  14. */
  15. function taxonomy_csv_vocabulary_create($name = '') {
  16. $name = _taxonomy_csv_vocabulary_name_create($name);
  17. // Create an empty vocabulary with default Drupal 7 fields.
  18. // Hierarchy is updated later.
  19. $vocabulary = (object) array(
  20. 'name' => $name,
  21. 'machine_name' => taxonomy_csv_vocabulary_machine_name_create($name),
  22. 'description' => t('Vocabulary created automatically by Taxonomy csv import/export module'),
  23. 'hierarchy' => 2,
  24. 'module' => 'taxonomy',
  25. 'weight' => 0,
  26. );
  27. $result = taxonomy_vocabulary_save($vocabulary);
  28. return $vocabulary;
  29. }
  30. /**
  31. * Helper to create an unused vocabulary name from a string.
  32. */
  33. function _taxonomy_csv_vocabulary_name_create($name = '') {
  34. $name = preg_replace('/.csv$/', '', trim(basename(strval($name))));
  35. $name = (drupal_strlen($name) == 0) ?
  36. t('Auto created vocabulary') :
  37. // Limit to 250 characters.
  38. drupal_substr($name, 0, 250);
  39. // Invent a unused vocabulary name.
  40. if (taxonomy_csv_vocabulary_name_check($name)
  41. || taxonomy_csv_vocabulary_machine_name_check(taxonomy_csv_vocabulary_machine_name_create($name))) {
  42. for (
  43. $i = 2;
  44. (taxonomy_csv_vocabulary_name_check("$name $i"))
  45. || taxonomy_csv_vocabulary_machine_name_check(taxonomy_csv_vocabulary_machine_name_create("$name $i"));
  46. $i++) {
  47. }
  48. $name = "$name $i";
  49. }
  50. return $name;
  51. }
  52. /**
  53. * Creates a machine name from a string.
  54. *
  55. * The name is created by replacing non alphanumeric character by an underscore.
  56. * Machine name is defined as first 16 cleaned characters of name and a random
  57. * five characters serial. Fields module prepends 'taxonomy_' to name and check
  58. * if total lenght is 21 characters max.
  59. *
  60. * @param $name
  61. * The string to process.
  62. *
  63. * @return
  64. * The processed string.
  65. */
  66. function taxonomy_csv_vocabulary_machine_name_create($name) {
  67. // Get last vid.
  68. $vid = 1 + db_query('SELECT max(vid) FROM {taxonomy_vocabulary}')->fetchField();
  69. $machine_name = drupal_substr(preg_replace('/_+/i', '_', preg_replace('/[^a-z0-9\\_]/i', '_', drupal_strtolower(trim(strval($name))))), 0, 16) . $vid . '_' . strval(rand(10000, 99999));
  70. return drupal_substr($machine_name, 0, 21);
  71. }
  72. /**
  73. * Checks if a name is a vocabulary machine_name.
  74. */
  75. function taxonomy_csv_vocabulary_machine_name_check($name) {
  76. return (taxonomy_vocabulary_machine_name_load($name) != FALSE);
  77. }
  78. /**
  79. * Check if a name is a vocabulary name.
  80. */
  81. function taxonomy_csv_vocabulary_name_check($name) {
  82. return (taxonomy_vocabulary_load_multiple(FALSE, array('name' => $name)) != FALSE);
  83. }
  84. /**
  85. * Return an array of all term ids of a given vocabulary.
  86. *
  87. * @param $vid
  88. * The vocabulary id from where to fetch term ids.
  89. *
  90. * @return
  91. * Array of term ids.
  92. */
  93. function taxonomy_csv_vocabulary_get_tids($vid) {
  94. // Tids are available in drupal_static('taxonomy_get_tree:terms'), but we
  95. // prefer to use an entity query to avoid issue with cache, if not updated.
  96. $query = new EntityFieldQuery;
  97. $query
  98. ->entityCondition('entity_type', 'taxonomy_term')
  99. ->propertyCondition('vid', $vid)
  100. ;
  101. $result = $query->execute();
  102. return (isset($result['taxonomy_term'])) ?
  103. array_keys($result['taxonomy_term']) :
  104. array();
  105. }
  106. /**
  107. * Return an array of all full terms of a given vocabulary.
  108. *
  109. * @param $vid
  110. * The vocabulary id from where to fetch term ids.
  111. *
  112. * @return
  113. * Array of full term.
  114. */
  115. function taxonomy_csv_vocabulary_get_terms($vid) {
  116. $result = taxonomy_csv_vocabulary_get_tids($vid);
  117. return taxonomy_term_load_multiple($result);
  118. }
  119. /**
  120. * Calculate number of terms in a vocabulary or in all vocabularies.
  121. *
  122. * @param $vocabulary_id
  123. * (Optional) Id or array of ids of the chosen vocabularies. If not specified,
  124. * count terms in all vocabularies.
  125. *
  126. * @return
  127. * Number of terms in specified vocabularies or in all vocabularies.
  128. */
  129. function taxonomy_csv_vocabulary_count_terms($vocabulary_id = 0) {
  130. if (!is_array($vocabulary_id)) {
  131. $vocabulary_id = array($vocabulary_id);
  132. }
  133. $sql = "
  134. SELECT COUNT(*)
  135. FROM {taxonomy_term_data}
  136. ";
  137. $args = array();
  138. if (($vocabulary_id != array(0)) && ($vocabulary_id != array('0'))) {
  139. $sql .= ' WHERE vid IN (:vid) ';
  140. $args[':vid'] = $vocabulary_id;
  141. }
  142. $result = db_query($sql, $args)->fetchField();
  143. return $result;
  144. }
  145. /**
  146. * Add or create a field to attach to a vocabulary.
  147. *
  148. * @param $vocabulary_machine_name
  149. * Vocabulary machine_name.
  150. * @param $field
  151. * Field array to attach.
  152. *
  153. * @return
  154. * TRUE if success, FALSE else.
  155. */
  156. function taxonomy_csv_vocabulary_field_attach($vocabulary_machine_name, $field) {
  157. // Check if vocabulary exist.
  158. $vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_machine_name);
  159. if ($vocabulary) {
  160. // Check if field exists in order to create or to update it.
  161. // No other check is made.
  162. $prior_field = field_info_field($field['field_name']);
  163. // The field doesn't exist, so creates it.
  164. if (empty($prior_field)) {
  165. $field = field_create_field($field);
  166. }
  167. // The field exists: check if an update is needed. Update is needed only
  168. // with taxonomy_term_reference, because this type requires to use specific
  169. // vocabularies.
  170. elseif ($field['type'] == 'taxonomy_term_reference') {
  171. $flag = FALSE;
  172. foreach ($prior_field['settings']['allowed_values'] as $allowed_values) {
  173. // Don't add new allowed values if they exist already.
  174. if ($allowed_values == $field['settings']['allowed_values'][0]) {
  175. $flag = TRUE;
  176. break;
  177. }
  178. }
  179. if (!$flag) {
  180. $prior_field['settings']['allowed_values'][] = $field['settings']['allowed_values'][0];
  181. $result = field_update_field($prior_field);
  182. }
  183. $field = field_info_field($field['field_name']);
  184. }
  185. // The field exists and doesn't need to be updated.
  186. // Field is already created, so use it.
  187. else {
  188. $field = $prior_field;
  189. }
  190. // Check if field is already instanced to vocabulary so attach it if needed.
  191. $prior_instance = field_info_instance('taxonomy_term', $field['field_name'], $vocabulary->machine_name);
  192. if (empty($prior_instance)) {
  193. $result = field_create_instance(array(
  194. 'field_name' => $field['field_name'],
  195. 'entity_type' => 'taxonomy_term',
  196. 'bundle' => $vocabulary->machine_name,
  197. 'label' => (isset($field['label']) ? $field['label'] : $field['field_name']),
  198. 'description' => (isset($field['description']) ? $field['description'] : ''),
  199. ));
  200. }
  201. return TRUE;
  202. }
  203. return FALSE;
  204. }