views_handler_filter_term_node_tid.inc

  1. 3.x modules/taxonomy/views_handler_filter_term_node_tid.inc
  2. 2.x modules/taxonomy/views_handler_filter_term_node_tid.inc

File

modules/taxonomy/views_handler_filter_term_node_tid.inc
View source
  1. <?php
  2. /**
  3. * Filter by term id
  4. */
  5. class views_handler_filter_term_node_tid extends views_handler_filter_many_to_one {
  6. function has_extra_options() { return TRUE; }
  7. function get_value_options() { /* don't overwrite the value options */ }
  8. function option_definition() {
  9. $options = parent::option_definition();
  10. $options['type'] = array('default' => 'textfield');
  11. $options['limit'] = array('default' => TRUE);
  12. $options['vid'] = array('default' => 0);
  13. return $options;
  14. }
  15. function extra_options_form(&$form, &$form_state) {
  16. $vocabularies = taxonomy_get_vocabularies();
  17. foreach ($vocabularies as $voc) {
  18. $options[$voc->vid] = check_plain($voc->name);
  19. }
  20. if ($this->options['limit']) {
  21. // We only do this when the form is displayed.
  22. if ($this->options['vid'] == 0) {
  23. $first_vocabulary = reset($vocabularies);
  24. $this->options['vid'] = $first_vocabulary->vid;
  25. }
  26. $form['vid'] = array(
  27. '#prefix' => '<div class="views-left-40">',
  28. '#suffix' => '</div>',
  29. '#type' => 'radios',
  30. '#title' => t('Vocabulary'),
  31. '#options' => $options,
  32. '#description' => t('Select which vocabulary to show terms for in the regular options.'),
  33. '#default_value' => $this->options['vid'],
  34. );
  35. }
  36. $form['markup_start'] = array(
  37. '#value' => '<div class="views-left-40">',
  38. );
  39. $form['type'] = array(
  40. '#type' => 'radios',
  41. '#title' => t('Selection type'),
  42. '#options' => array('select' => t('Dropdown'), 'textfield' => t('Autocomplete')),
  43. '#default_value' => $this->options['type'],
  44. );
  45. $form['hierarchy'] = array(
  46. '#type' => 'checkbox',
  47. '#title' => t('Show hierarchy in dropdown'),
  48. '#default_value' => !empty($this->options['hierarchy']),
  49. '#process' => array('views_process_dependency'),
  50. '#dependency' => array('radio:options[type]' => array('select')),
  51. );
  52. $form['markup_end'] = array(
  53. '#value' => '</div>',
  54. );
  55. }
  56. function value_form(&$form, &$form_state) {
  57. $vocabulary = taxonomy_vocabulary_load($this->options['vid']);
  58. if (empty($vocabulary) && $this->options['limit']) {
  59. $form['markup'] = array(
  60. '#prefix' => '<div class="form-item">',
  61. '#suffix' => '</div>',
  62. '#value' => t('An invalid vocabulary is selected. Please change it in the options.'),
  63. );
  64. return;
  65. }
  66. if ($this->options['type'] == 'textfield') {
  67. $default = '';
  68. if ($this->value) {
  69. $result = db_query("SELECT * FROM {term_data} td WHERE td.tid IN (" . implode(', ', $this->value) . ')');
  70. while ($term = db_fetch_object($result)) {
  71. if ($default) {
  72. $default .= ', ';
  73. }
  74. $default .= $term->name;
  75. }
  76. }
  77. $form['value'] = array(
  78. '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
  79. '#type' => 'textfield',
  80. '#default_value' => $default,
  81. );
  82. if ($this->options['limit']) {
  83. $form['value']['#autocomplete_path'] = 'taxonomy/autocomplete/' . $vocabulary->vid;
  84. }
  85. }
  86. else {
  87. if (!empty($this->options['hierarchy']) && $this->options['limit']) {
  88. $tree = taxonomy_get_tree($vocabulary->vid);
  89. $options = array();
  90. if ($tree) {
  91. foreach ($tree as $term) {
  92. $choice = new stdClass();
  93. $choice->option = array($term->tid => str_repeat('-', $term->depth) . $term->name);
  94. $options[] = $choice;
  95. }
  96. }
  97. }
  98. else {
  99. $options = array();
  100. if ($this->options['limit']) {
  101. $result = db_query(db_rewrite_sql("SELECT t.* FROM {term_data} t WHERE t.vid = %d ORDER BY t.weight, t.name", 't', 'tid'), $vocabulary->vid);
  102. }
  103. else {
  104. $result = db_query(db_rewrite_sql("SELECT td.* FROM {term_data} td INNER JOIN {vocabulary} v ON td.vid = v.vid ORDER BY v.weight, v.name, td.weight, td.name", 'td', 'tid'));
  105. }
  106. while ($term = db_fetch_object($result)) {
  107. $options[$term->tid] = $term->name;
  108. }
  109. }
  110. $default_value = (array) $this->value;
  111. if (!empty($form_state['exposed'])) {
  112. $identifier = $this->options['expose']['identifier'];
  113. if (!empty($this->options['expose']['reduce'])) {
  114. $options = $this->reduce_value_options($options);
  115. if (empty($this->options['expose']['single']) && !empty($this->options['expose']['optional'])) {
  116. $default_value = array();
  117. }
  118. }
  119. if (!empty($this->options['expose']['single'])) {
  120. if (!empty($this->options['expose']['optional']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) {
  121. $default_value = 'All';
  122. }
  123. else if (empty($default_value)) {
  124. $keys = array_keys($options);
  125. $default_value = array_shift($keys);
  126. }
  127. else {
  128. $copy = $default_value;
  129. $default_value = array_shift($copy);
  130. }
  131. }
  132. }
  133. $form['value'] = array(
  134. '#type' => 'select',
  135. '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
  136. '#multiple' => TRUE,
  137. '#options' => $options,
  138. '#size' => min(9, count($options)),
  139. '#default_value' => $default_value,
  140. );
  141. if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
  142. $form_state['input'][$identifier] = $default_value;
  143. }
  144. }
  145. if (empty($form_state['exposed'])) {
  146. // Retain the helper option
  147. $this->helper->options_form($form, $form_state);
  148. }
  149. }
  150. function value_validate(&$form, &$form_state) {
  151. // We only validate if they've chosen the text field style.
  152. if ($this->options['type'] != 'textfield') {
  153. return;
  154. }
  155. $values = drupal_explode_tags($form_state['values']['options']['value']);
  156. $tids = $this->validate_term_strings($form['value'], $values);
  157. if ($tids) {
  158. $form_state['values']['options']['value'] = $tids;
  159. }
  160. }
  161. function accept_exposed_input($input) {
  162. if (empty($this->options['exposed'])) {
  163. return TRUE;
  164. }
  165. // If it's optional and there's no value don't bother filtering.
  166. if ($this->options['expose']['optional'] && empty($this->validated_exposed_input)) {
  167. return FALSE;
  168. }
  169. $rc = parent::accept_exposed_input($input);
  170. if ($rc) {
  171. // If we have previously validated input, override.
  172. if (isset($this->validated_exposed_input)) {
  173. $this->value = $this->validated_exposed_input;
  174. }
  175. }
  176. return $rc;
  177. }
  178. function exposed_validate(&$form, &$form_state) {
  179. if (empty($this->options['exposed'])) {
  180. return;
  181. }
  182. $identifier = $this->options['expose']['identifier'];
  183. // We only validate if they've chosen the text field style.
  184. if ($this->options['type'] != 'textfield') {
  185. if ($form_state['values'][$identifier] != 'All') {
  186. $this->validated_exposed_input = (array) $form_state['values'][$identifier];
  187. }
  188. return;
  189. }
  190. if (empty($this->options['expose']['identifier'])) {
  191. return;
  192. }
  193. $values = drupal_explode_tags($form_state['values'][$identifier]);
  194. $tids = $this->validate_term_strings($form[$identifier], $values);
  195. if ($tids) {
  196. $this->validated_exposed_input = $tids;
  197. }
  198. }
  199. /**
  200. * Validate the user string. Since this can come from either the form
  201. * or the exposed filter, this is abstracted out a bit so it can
  202. * handle the multiple input sources.
  203. */
  204. function validate_term_strings(&$form, $values) {
  205. if (empty($values)) {
  206. return array();
  207. }
  208. $tids = array();
  209. $placeholders = array();
  210. $args = array();
  211. $results = array();
  212. foreach ($values as $value) {
  213. $missing[strtolower($value)] = TRUE;
  214. $args[] = $value;
  215. $placeholders[] = "'%s'";
  216. }
  217. if (!$args) {
  218. return;
  219. }
  220. // add the taxonomy vid to the argument list.
  221. $args[] = $this->options['vid'];
  222. $result = db_query("SELECT * FROM {term_data} td WHERE td.name IN (" . implode(', ', $placeholders) . ") AND td.vid = %d", $args);
  223. while ($term = db_fetch_object($result)) {
  224. unset($missing[strtolower($term->name)]);
  225. $tids[] = $term->tid;
  226. }
  227. if ($missing) {
  228. form_error($form, format_plural(count($missing), 'Unable to find term: @terms', 'Unable to find terms: @terms', array('@terms' => implode(', ', array_keys($missing)))));
  229. }
  230. return $tids;
  231. }
  232. function value_submit($form, &$form_state) {
  233. // prevent array_filter from messing up our arrays in parent submit.
  234. }
  235. function expose_form_right(&$form, &$form_state) {
  236. parent::expose_form_right($form, $form_state);
  237. if ($this->options['type'] != 'select') {
  238. unset($form['expose']['reduce']);
  239. }
  240. }
  241. function admin_summary() {
  242. // set up $this->value_options for the parent summary
  243. $this->value_options = array();
  244. if ($this->value) {
  245. $result = db_query("SELECT * FROM {term_data} td WHERE td.tid IN (" . implode(', ', $this->value) . ")");
  246. while ($term = db_fetch_object($result)) {
  247. $this->value_options[$term->tid] = $term->name;
  248. }
  249. }
  250. return parent::admin_summary();
  251. }
  252. }