taxonomy.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. /**
  3. * @file
  4. * Mapper that exposes a node's taxonomy vocabularies as mapping targets.
  5. */
  6. /**
  7. * Implements hook_feeds_parser_sources_alter().
  8. *
  9. * @todo: Upgrade to 7.
  10. */
  11. function taxonomy_feeds_parser_sources_alter(&$sources, $content_type) {
  12. if (!empty($content_type)) {
  13. foreach (taxonomy_get_vocabularies($content_type) as $vocabulary) {
  14. $sources['parent:taxonomy:' . $vocabulary->machine_name] = array(
  15. 'name' => t('Feed node: Taxonomy: @vocabulary', array('@vocabulary' => $vocabulary->name)),
  16. 'description' => t('Taxonomy terms from feed node in given vocabulary.'),
  17. 'callback' => 'taxonomy_feeds_get_source',
  18. );
  19. }
  20. }
  21. }
  22. /**
  23. * Callback, returns taxonomy from feed node.
  24. */
  25. function taxonomy_feeds_get_source(FeedsSource $source, FeedsParserResult $result, $key) {
  26. if ($node = node_load($source->feed_nid)) {
  27. $terms = taxonomy_feeds_node_get_terms($node);
  28. $vocabularies = taxonomy_vocabulary_load_multiple(array(), array('machine_name' => str_replace('parent:taxonomy:', '', $key)));
  29. $vocabulary = array_shift($vocabularies);
  30. $result = array();
  31. foreach ($terms as $tid => $term) {
  32. if ($term->vid == $vocabulary->vid) {
  33. $result[] = new FeedsTermElement($term);
  34. }
  35. }
  36. return $result;
  37. }
  38. }
  39. /**
  40. * Implements hook_feeds_processor_targets_alter().
  41. */
  42. function taxonomy_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
  43. foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
  44. $info = field_info_field($name);
  45. if ($info['type'] == 'taxonomy_term_reference') {
  46. $targets[$name] = array(
  47. 'name' => check_plain($instance['label']),
  48. 'callback' => 'taxonomy_feeds_set_target',
  49. 'description' => t('The @label field of the node.', array('@label' => $instance['label'])),
  50. );
  51. }
  52. }
  53. }
  54. /**
  55. * Callback for mapping. Here is where the actual mapping happens.
  56. *
  57. * @todo Do not create new terms for non-autotag fields.
  58. */
  59. function taxonomy_feeds_set_target($source, $entity, $target, $terms) {
  60. if (empty($terms)) {
  61. return;
  62. }
  63. // Handle non-multiple values.
  64. if (!is_array($terms)) {
  65. $terms = array($terms);
  66. }
  67. $info = field_info_field($target);
  68. // See http://drupal.org/node/881530
  69. if (isset($info['settings']['allowed_values'][0]['vocabulary'])) {
  70. $vocabulary = taxonomy_vocabulary_machine_name_load($info['settings']['allowed_values'][0]['vocabulary']);
  71. }
  72. else {
  73. $vocabulary = taxonomy_vocabulary_load($info['settings']['allowed_values'][0]['vid']);
  74. }
  75. $i = 0;
  76. $entity->$target = isset($entity->$target) ? $entity->$target : array();
  77. foreach ($terms as $term) {
  78. $tid = 0;
  79. if ($term instanceof FeedsTermElement) {
  80. $tid = $term->tid;
  81. }
  82. elseif (is_numeric($term)) {
  83. $tid = $term;
  84. }
  85. elseif (is_string($term)) {
  86. $tid = taxonomy_term_check_term($term, $vocabulary->vid);
  87. }
  88. if ($tid) {
  89. $entity->{$target}['und'][$i]['tid'] = $tid;
  90. }
  91. if ($info['cardinality'] == 1) {
  92. break;
  93. }
  94. $i++;
  95. }
  96. }
  97. /**
  98. * Find all terms associated with the given node, within one vocabulary.
  99. */
  100. function taxonomy_feeds_node_get_terms($node, $key = 'tid') {
  101. $terms = &drupal_static(__FUNCTION__);
  102. if (!isset($terms[$node->nid][$key])) {
  103. // Get tids from all taxonomy_term_reference fields.
  104. $tids = array();
  105. $fields = field_info_fields();
  106. foreach ($fields as $field_name => $field) {
  107. if ($field['type'] == 'taxonomy_term_reference' && field_info_instance('node', $field_name, $node->type)) {
  108. if (($items = field_get_items('node', $node, $field_name)) && is_array($items)) {
  109. $tids = array_merge($tids, array_map('_taxonomy_extract_tid', $items));
  110. }
  111. }
  112. }
  113. // Load terms and cache them in static var.
  114. $curr_terms = taxonomy_term_load_multiple($tids);
  115. $terms[$node->nid][$key] = array();
  116. foreach ($curr_terms as $term) {
  117. $terms[$node->nid][$key][$term->$key] = $term;
  118. }
  119. }
  120. return $terms[$node->nid][$key];
  121. }
  122. /**
  123. * Helper function used in taxonomy_feeds_node_get_terms(). Extracts
  124. * tid from array item returned by field_get_items().
  125. *
  126. * @param $item tid information in a form of single element array (key == 'tid', value == tid we're looking for)
  127. *
  128. * @return tid extracted from $item.
  129. *
  130. * @see taxonomy_feeds_node_get_terms()
  131. * @see field_get_items()
  132. */
  133. function _taxonomy_extract_tid($item) {
  134. return $item['tid'];
  135. }
  136. /**
  137. * Checks whether a term identified by name and vocabulary exists. Creates a
  138. * new term if it does not exist.
  139. *
  140. * @param $name
  141. * A term name.
  142. * @param $vid
  143. * A vocabulary id.
  144. *
  145. * @return
  146. * A term id.
  147. */
  148. function taxonomy_term_check_term($name, $vid) {
  149. $name = trim($name);
  150. $term = taxonomy_term_lookup_term($name, $vid);
  151. if (empty($term)) {
  152. $term = new stdClass();
  153. $term->name = $name;
  154. $term->vid = $vid;
  155. taxonomy_term_save($term);
  156. return $term->tid;
  157. }
  158. return $term->tid;
  159. }
  160. /**
  161. * Looks up a term, assumes SQL storage backend.
  162. */
  163. function taxonomy_term_lookup_term($name, $vid) {
  164. return db_select('taxonomy_term_data', 'td')
  165. ->fields('td', array('tid', 'name'))
  166. ->condition('name', $name)
  167. ->condition('vid', $vid)
  168. ->execute()
  169. ->fetchObject();
  170. }