synonyms_views_handler_filter_term_tid.inc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. /**
  3. * @file
  4. * Definition of synonyms_views_handler_filter_term_tid class.
  5. */
  6. /**
  7. * Synonyms friendly taxonomy filter handler.
  8. */
  9. class synonyms_views_handler_filter_term_tid extends views_handler_filter_term_node_tid {
  10. function extra_options_form(&$form, &$form_state) {
  11. parent::extra_options_form($form, $form_state);
  12. $form['type']['#options']['synonyms_autocomplete'] = t('Synonyms friendly autocomplete');
  13. }
  14. function value_form(&$form, &$form_state) {
  15. $restore_value = $this->options['type'] == 'synonyms_autocomplete';
  16. if ($restore_value) {
  17. $this->options['type'] = 'textfield';
  18. }
  19. parent::value_form($form, $form_state);
  20. if ($restore_value) {
  21. // We need to determine the entity type onto which this field is attached
  22. // that is used in this view.
  23. $entity_type_base_table = $this->view->base_table;
  24. // TODO: it would be nice to consider the existence of relationships, but
  25. // I just couldn't figure it out at that time.
  26. $entity_info = entity_get_info();
  27. $field_entity_type = FALSE;
  28. $field = field_info_field($this->definition['field_name']);
  29. foreach ($field['bundles'] as $entity_type => $bundles) {
  30. if ($entity_info[$entity_type]['base table'] == $entity_type_base_table) {
  31. $field_entity_type = $entity_type;
  32. break;
  33. }
  34. }
  35. if (!$field_entity_type) {
  36. // Seems like we failed to determine the entity type which is used for
  37. // this field in the view. Well, it's not a fatal fail, we'll just use
  38. // whatever then.
  39. $field_entity_type = array_keys($field['bundles']);
  40. $field_entity_type = $field_entity_type[0];
  41. }
  42. // We just grab the first instance of this field within the determined
  43. // entity type.
  44. $bundle = $field['bundles'][$field_entity_type][0];
  45. $instance = field_info_instance($field_entity_type, $field['field_name'], $bundle);
  46. if ($instance['widget']['type'] == 'synonyms_autocomplete') {
  47. $widget = $instance['widget']['settings'];
  48. }
  49. else {
  50. $widget = field_info_widget_settings('synonyms_autocomplete');
  51. }
  52. $autocomplete_path = $widget['synonyms_autocomplete_path'];
  53. $size = $widget['size'];
  54. $form['value']['#autocomplete_path'] = $autocomplete_path . '/' . $this->definition['field_name'] . '/' . $field_entity_type . '/' . $bundle;
  55. $form['value']['#size'] = $size;
  56. $form['value']['#auto_creation'] = FALSE;
  57. $form['value']['#attributes']['class'][] = 'synonyms-autocomplete';
  58. $form['value']['#attached']['js'][drupal_get_path('module', 'synonyms') . '/js/synonyms-autocomplete.js'] = array();
  59. $this->options['type'] = 'synonyms_autocomplete';
  60. }
  61. }
  62. function value_validate($form, &$form_state) {
  63. if ($this->options['type'] == 'synonyms_autocomplete') {
  64. $values = drupal_explode_tags($form_state['values']['options']['value']);
  65. $tids = $this->synonyms_validate_term_strings($form['value'], $values);
  66. if ($tids) {
  67. $form_state['values']['options']['value'] = $tids;
  68. }
  69. }
  70. else {
  71. parent::value_validate($form, $form_state);
  72. }
  73. }
  74. function exposed_validate(&$form, &$form_state) {
  75. if ($this->options['type'] == 'synonyms_autocomplete') {
  76. if (empty($this->options['exposed'])) {
  77. return;
  78. }
  79. if (empty($this->options['expose']['identifier'])) {
  80. return;
  81. }
  82. $identifier = $this->options['expose']['identifier'];
  83. $values = drupal_explode_tags($form_state['values'][$identifier]);
  84. $tids = $this->synonyms_validate_term_strings($form[$identifier], $values);
  85. if ($tids) {
  86. $this->validated_exposed_input = $tids;
  87. }
  88. }
  89. else {
  90. parent::exposed_validate($form, $form_state);
  91. }
  92. }
  93. /**
  94. * Validate the user string.
  95. *
  96. * In a great extend it does the same job as parent::validate_term_strings(),
  97. * just that this implementation is synonyms-aware.
  98. *
  99. * @param $element
  100. * The form element which is used, either the views ui or the exposed
  101. * filters.
  102. * @param $values
  103. * The taxonomy names/synonyms which will be converted to tids.
  104. *
  105. * @return array
  106. * The taxonomy ids for all validated terms.
  107. */
  108. protected function synonyms_validate_term_strings($element, $values) {
  109. if (empty($values)) {
  110. return array();
  111. }
  112. $values = array_map('drupal_strtolower', $values);
  113. $missing = array_flip($values);
  114. $tids = array();
  115. $vocabulary = taxonomy_vocabulary_machine_name_load($this->options['vocabulary']);
  116. // Firstly looking up the entered tags as if they were term names. Then,
  117. // the remaining tags are looked up as if they were synonyms of terms.
  118. // Lastly, if any tags are left at this point, we mark form validation
  119. // error.
  120. $query = db_select('taxonomy_term_data', 'td');
  121. $query->fields('td', array('tid', 'name'));
  122. $query->condition('td.vid', $vocabulary->vid);
  123. $query->condition('td.name', $values);
  124. $query->addTag('term_access');
  125. $result = $query->execute();
  126. foreach ($result as $term) {
  127. unset($missing[drupal_strtolower($term->name)]);
  128. $tids[] = $term->tid;
  129. }
  130. $behavior_implementations = synonyms_behavior_get('autocomplete', 'taxonomy_term', $vocabulary->machine_name, TRUE);
  131. foreach ($behavior_implementations as $behavior_implementation) {
  132. if (!empty($missing)) {
  133. $condition = db_or();
  134. foreach ($missing as $tag => $v) {
  135. $condition->condition(AbstractSynonymsSynonymsBehavior::COLUMN_PLACEHOLDER, $tag);
  136. }
  137. $synonyms = synonyms_synonyms_find_behavior($condition, $behavior_implementation);
  138. foreach ($synonyms as $synonym) {
  139. $synonym->synonym = drupal_strtolower($synonym->synonym);
  140. unset($missing[$synonym->synonym]);
  141. $tids[] = $synonym->entity_id;
  142. }
  143. }
  144. }
  145. if (!empty($missing) && !empty($this->options['error_message'])) {
  146. form_error($element, format_plural(count($missing), 'Unable to find term: @terms', 'Unable to find terms: @terms', array('@terms' => implode(', ', array_keys($missing)))));
  147. }
  148. return $tids;
  149. }
  150. }