FeedsTermProcessor.inc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * @file
  4. * FeedsTermProcessor class.
  5. */
  6. /**
  7. * Feeds processor plugin. Create taxonomy terms from feed items.
  8. */
  9. class FeedsTermProcessor extends FeedsProcessor {
  10. /**
  11. * Define entity type.
  12. */
  13. public function entityType() {
  14. return 'taxonomy_term';
  15. }
  16. /**
  17. * Implements parent::entityInfo().
  18. */
  19. protected function entityInfo() {
  20. $info = parent::entityInfo();
  21. $info['label plural'] = t('Terms');
  22. return $info;
  23. }
  24. /**
  25. * Creates a new term in memory and returns it.
  26. */
  27. protected function newEntity(FeedsSource $source) {
  28. $vocabulary = $this->vocabulary();
  29. $term = new stdClass();
  30. $term->vid = $vocabulary->vid;
  31. $term->vocabulary_machine_name = $vocabulary->machine_name;
  32. $term->format = isset($this->config['input_format']) ? $this->config['input_format'] : filter_fallback_format();
  33. return $term;
  34. }
  35. /**
  36. * Loads an existing term.
  37. */
  38. protected function entityLoad(FeedsSource $source, $tid) {
  39. return taxonomy_term_load($tid);
  40. }
  41. /**
  42. * Validates a term.
  43. */
  44. protected function entityValidate($term) {
  45. if (empty($term->name)) {
  46. throw new FeedsValidationException(t('Term name missing.'));
  47. }
  48. }
  49. /**
  50. * Saves a term.
  51. *
  52. * We de-array parent fields with only one item.
  53. * This stops leftandright module from freaking out.
  54. */
  55. protected function entitySave($term) {
  56. if (isset($term->parent)) {
  57. if (is_array($term->parent) && count($term->parent) == 1) {
  58. $term->parent = reset($term->parent);
  59. }
  60. if (isset($term->tid) && ($term->parent == $term->tid || (is_array($term->parent) && in_array($term->tid, $term->parent)))) {
  61. throw new FeedsValidationException(t("A term can't be its own child. GUID:@guid", array('@guid' => $term->feeds_item->guid)));
  62. }
  63. }
  64. taxonomy_term_save($term);
  65. }
  66. /**
  67. * Deletes a series of terms.
  68. */
  69. protected function entityDeleteMultiple($tids) {
  70. foreach ($tids as $tid) {
  71. taxonomy_term_delete($tid);
  72. }
  73. }
  74. /**
  75. * Override parent::configDefaults().
  76. */
  77. public function configDefaults() {
  78. return array(
  79. 'vocabulary' => 0,
  80. ) + parent::configDefaults();
  81. }
  82. /**
  83. * Override parent::configForm().
  84. */
  85. public function configForm(&$form_state) {
  86. $options = array(0 => t('Select a vocabulary'));
  87. foreach (taxonomy_get_vocabularies() as $vocab) {
  88. $options[$vocab->machine_name] = $vocab->name;
  89. }
  90. $form = parent::configForm($form_state);
  91. $form['vocabulary'] = array(
  92. '#type' => 'select',
  93. '#title' => t('Import to vocabulary'),
  94. '#description' => t('Choose the vocabulary to import into. <strong>CAUTION:</strong> when deleting terms through the "Delete items" tab, Feeds will delete <em>all</em> terms from this vocabulary.'),
  95. '#options' => $options,
  96. '#default_value' => $this->config['vocabulary'],
  97. );
  98. return $form;
  99. }
  100. /**
  101. * Override parent::configFormValidate().
  102. */
  103. public function configFormValidate(&$values) {
  104. if (empty($values['vocabulary'])) {
  105. form_set_error('vocabulary', t('Choose a vocabulary'));
  106. }
  107. }
  108. /**
  109. * Override setTargetElement to operate on a target item that is a taxonomy term.
  110. */
  111. public function setTargetElement(FeedsSource $source, $target_term, $target_element, $value) {
  112. switch ($target_element) {
  113. case 'parent':
  114. if (!empty($value)) {
  115. $terms = taxonomy_get_term_by_name($value);
  116. $parent_tid = '';
  117. foreach ($terms as $term) {
  118. if ($term->vid == $target_term->vid) {
  119. $parent_tid = $term->tid;
  120. }
  121. }
  122. if (!empty($parent_tid)) {
  123. $target_term->parent[] = $parent_tid;
  124. }
  125. else {
  126. $target_term->parent[] = 0;
  127. }
  128. }
  129. else {
  130. $target_term->parent[] = 0;
  131. }
  132. break;
  133. case 'parentguid':
  134. // value is parent_guid field value
  135. $query = db_select('feeds_item')
  136. ->fields('feeds_item', array('entity_id'))
  137. ->condition('entity_type', $this->entityType());
  138. $parent_tid = $query->condition('guid', $value)->execute()->fetchField();
  139. $target_term->parent[] = ($parent_tid) ? $parent_tid : 0;
  140. break;
  141. case 'weight':
  142. if (!empty($value)) {
  143. $weight = intval($value);
  144. }
  145. else {
  146. $weight = 0;
  147. }
  148. $target_term->weight = $weight;
  149. break;
  150. default:
  151. parent::setTargetElement($source, $target_term, $target_element, $value);
  152. break;
  153. }
  154. }
  155. /**
  156. * Return available mapping targets.
  157. */
  158. public function getMappingTargets() {
  159. $targets = parent::getMappingTargets();
  160. $targets += array(
  161. 'name' => array(
  162. 'name' => t('Term name'),
  163. 'description' => t('Name of the taxonomy term.'),
  164. 'optional_unique' => TRUE,
  165. ),
  166. 'parent' => array(
  167. 'name' => t('Parent: Term name'),
  168. 'description' => t('The name of the parent taxonomy term.'),
  169. 'optional_unique' => TRUE,
  170. ),
  171. 'parentguid' => array(
  172. 'name' => t('Parent: GUID'),
  173. 'description' => t('The GUID of the parent taxonomy term.'),
  174. 'optional_unique' => TRUE,
  175. ),
  176. 'weight' => array(
  177. 'name' => t('Term weight'),
  178. 'description' => t('Weight of the taxonomy term.'),
  179. 'optional_unique' => TRUE,
  180. ),
  181. 'description' => array(
  182. 'name' => t('Term description'),
  183. 'description' => t('Description of the taxonomy term.'),
  184. ),
  185. );
  186. // Let implementers of hook_feeds_term_processor_targets() add their targets.
  187. try {
  188. self::loadMappers();
  189. $entity_type = $this->entityType();
  190. $bundle = $this->vocabulary()->machine_name;
  191. drupal_alter('feeds_processor_targets', $targets, $entity_type, $bundle);
  192. }
  193. catch (Exception $e) {
  194. // Do nothing.
  195. }
  196. return $targets;
  197. }
  198. /**
  199. * Get id of an existing feed item term if available.
  200. */
  201. protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
  202. if ($tid = parent::existingEntityId($source, $result)) {
  203. return $tid;
  204. }
  205. // The only possible unique target is name.
  206. foreach ($this->uniqueTargets($source, $result) as $target => $value) {
  207. if ($target == 'name') {
  208. $vocabulary = $this->vocabulary();
  209. if ($tid = db_query("SELECT tid FROM {taxonomy_term_data} WHERE name = :name AND vid = :vid", array(':name' => $value, ':vid' => $vocabulary->vid))->fetchField()) {
  210. return $tid;
  211. }
  212. }
  213. }
  214. return 0;
  215. }
  216. /**
  217. * Return vocabulary to map to.
  218. */
  219. public function vocabulary() {
  220. if (isset($this->config['vocabulary'])) {
  221. if ($vocabulary = taxonomy_vocabulary_machine_name_load($this->config['vocabulary'])) {
  222. return $vocabulary;
  223. }
  224. }
  225. throw new Exception(t('No vocabulary defined for Taxonomy Term processor.'));
  226. }
  227. }