Newer
Older
Earl Miles
committed
<?php
/**
* Filter by term id
*/
class views_handler_filter_term_node_tid extends views_handler_filter_many_to_one {
function can_group() { return FALSE; }
Earl Miles
committed
function has_extra_options() { return TRUE; }
function get_value_options() { /* don't overwrite the value options */ }
function option_definition() {
$options = parent::option_definition();
$options['type'] = array('default' => 'textfield');
$options['limit'] = array('default' => TRUE);
Earl Miles
committed
$options['vid'] = array('default' => 0);
$options['hierarchy'] = array('default' => 0);
Earl Miles
committed
$options['error_message'] = array('default' => TRUE);
Earl Miles
committed
return $options;
}
function extra_options_form(&$form, &$form_state) {
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $voc) {
$options[$voc->vid] = check_plain($voc->name);
Earl Miles
committed
}
// We only do this when the form is displayed.
$first_vocabulary = reset($vocabularies);
$this->options['vid'] = $first_vocabulary->vid;
Earl Miles
committed
$form['vid'] = array(
'#prefix' => '<div class="views-left-40">',
'#suffix' => '</div>',
'#type' => 'radios',
'#title' => t('Vocabulary'),
'#options' => $options,
'#description' => t('Select which vocabulary to show terms for in the regular options.'),
'#default_value' => $this->options['vid'],
);
}
Earl Miles
committed
$form['markup_start'] = array(
'#value' => '<div class="views-left-40">',
);
$form['type'] = array(
'#type' => 'radios',
'#title' => t('Selection type'),
'#options' => array('select' => t('Dropdown'), 'textfield' => t('Autocomplete')),
'#default_value' => $this->options['type'],
);
$form['hierarchy'] = array(
'#type' => 'checkbox',
'#title' => t('Show hierarchy in dropdown'),
'#default_value' => !empty($this->options['hierarchy']),
'#process' => array('views_process_dependency'),
'#dependency' => array('radio:options[type]' => array('select')),
);
$form['markup_end'] = array(
'#value' => '</div>',
);
}
function value_form(&$form, &$form_state) {
$vocabulary = taxonomy_vocabulary_load($this->options['vid']);
if (empty($vocabulary) && $this->options['limit']) {
Earl Miles
committed
$form['markup'] = array(
'#prefix' => '<div class="form-item">',
'#suffix' => '</div>',
'#value' => t('An invalid vocabulary is selected. Please change it in the options.'),
);
return;
}
if ($this->options['type'] == 'textfield') {
$default = '';
if ($this->value) {
$result = db_query("SELECT * FROM {term_data} td WHERE td.tid IN (" . implode(', ', $this->value) . ')');
while ($term = db_fetch_object($result)) {
if ($default) {
$default .= ', ';
}
$default .= $term->name;
}
}
$form['value'] = array(
'#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
Earl Miles
committed
'#type' => 'textfield',
'#default_value' => $default,
);
if ($this->options['limit']) {
$form['value']['#autocomplete_path'] = 'taxonomy/autocomplete/' . $vocabulary->vid;
}
Earl Miles
committed
}
else {
if (!empty($this->options['hierarchy']) && $this->options['limit']) {
Earl Miles
committed
$tree = taxonomy_get_tree($vocabulary->vid);
$options = array();
if ($tree) {
foreach ($tree as $term) {
$choice = new stdClass();
$choice->option = array($term->tid => str_repeat('-', $term->depth) . $term->name);
$options[] = $choice;
}
}
}
else {
$options = array();
Daniel Wehner
committed
$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);
Earl Miles
committed
$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'));
Earl Miles
committed
while ($term = db_fetch_object($result)) {
$options[$term->tid] = $term->name;
}
}
$default_value = (array) $this->value;
if (!empty($form_state['exposed'])) {
$identifier = $this->options['expose']['identifier'];
Earl Miles
committed
if (!empty($this->options['expose']['reduce'])) {
$options = $this->reduce_value_options($options);
if (empty($this->options['expose']['single']) && !empty($this->options['expose']['optional'])) {
$default_value = array();
}
}
if (!empty($this->options['expose']['single'])) {
if (!empty($this->options['expose']['optional']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) {
$default_value = 'All';
}
else if (empty($default_value)) {
$keys = array_keys($options);
$default_value = array_shift($keys);
}
else {
$copy = $default_value;
$default_value = array_shift($copy);
}
}
}
Earl Miles
committed
$form['value'] = array(
'#type' => 'select',
'#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'),
Earl Miles
committed
'#multiple' => TRUE,
'#options' => $options,
'#size' => min(9, count($options)),
'#default_value' => $default_value,
Earl Miles
committed
);
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
$form_state['input'][$identifier] = $default_value;
}
Earl Miles
committed
}
Earl Miles
committed
if (empty($form_state['exposed'])) {
// Retain the helper option
$this->helper->options_form($form, $form_state);
}
}
Daniel Wehner
committed
function validate() {
// Override the validation handler defined by filter_in_operator and do nothing.
// @todo: Someone could refactor this handler to support get_value_options and do some custom validation for the autocompletion here.
}
Earl Miles
committed
function value_validate($form, &$form_state) {
Earl Miles
committed
// We only validate if they've chosen the text field style.
if ($this->options['type'] != 'textfield') {
return;
}
$values = drupal_explode_tags($form_state['values']['options']['value']);
$tids = $this->validate_term_strings($form['value'], $values);
if ($tids) {
$form_state['values']['options']['value'] = $tids;
}
}
function accept_exposed_input($input) {
if (empty($this->options['exposed'])) {
return TRUE;
}
// If view is an attachment and is inheriting exposed filters, then assume
// exposed input has already been validated
if (isset($this->view->is_attachment) && $this->view->display_handler->uses_exposed()) {
$this->validated_exposed_input = (array)$this->view->exposed_raw_input[$this->options['expose']['identifier']];
}
Earl Miles
committed
// If it's optional and there's no value don't bother filtering.
if ($this->options['expose']['optional'] && empty($this->validated_exposed_input)) {
return FALSE;
}
Earl Miles
committed
Earl Miles
committed
$rc = parent::accept_exposed_input($input);
Earl Miles
committed
if ($rc) {
// If we have previously validated input, override.
if (isset($this->validated_exposed_input)) {
$this->value = $this->validated_exposed_input;
}
}
return $rc;
}
function exposed_validate(&$form, &$form_state) {
if (empty($this->options['exposed'])) {
return;
}
$identifier = $this->options['expose']['identifier'];
// We only validate if they've chosen the text field style.
if ($this->options['type'] != 'textfield') {
if ($form_state['values'][$identifier] != 'All') {
$this->validated_exposed_input = (array) $form_state['values'][$identifier];
Earl Miles
committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
}
return;
}
if (empty($this->options['expose']['identifier'])) {
return;
}
$values = drupal_explode_tags($form_state['values'][$identifier]);
$tids = $this->validate_term_strings($form[$identifier], $values);
if ($tids) {
$this->validated_exposed_input = $tids;
}
}
/**
* Validate the user string. Since this can come from either the form
* or the exposed filter, this is abstracted out a bit so it can
* handle the multiple input sources.
*/
function validate_term_strings(&$form, $values) {
if (empty($values)) {
return array();
}
$tids = array();
$placeholders = array();
$args = array();
$results = array();
foreach ($values as $value) {
$missing[strtolower($value)] = TRUE;
$args[] = $value;
$placeholders[] = "'%s'";
}
if (!$args) {
return;
}
Earl Miles
committed
// add the taxonomy vid to the argument list.
$args[] = $this->options['vid'];
Earl Miles
committed
$result = db_query("SELECT * FROM {term_data} td WHERE td.name IN (" . implode(', ', $placeholders) . ") AND td.vid = %d", $args);
Earl Miles
committed
while ($term = db_fetch_object($result)) {
unset($missing[strtolower($term->name)]);
$tids[] = $term->tid;
}
Earl Miles
committed
if ($missing && !empty($this->options['error_message'])) {
Earl Miles
committed
form_error($form, format_plural(count($missing), 'Unable to find term: @terms', 'Unable to find terms: @terms', array('@terms' => implode(', ', array_keys($missing)))));
}
Earl Miles
committed
elseif ($missing && empty($this->options['error_message'])) {
$tids = array(0);
}
Earl Miles
committed
return $tids;
}
function value_submit($form, &$form_state) {
// prevent array_filter from messing up our arrays in parent submit.
}
function expose_form_right(&$form, &$form_state) {
parent::expose_form_right($form, $form_state);
if ($this->options['type'] != 'select') {
unset($form['expose']['reduce']);
}
Earl Miles
committed
$form['error_message'] = array(
'#type' => 'checkbox',
'#title' => t('Display error message'),
'#default_value' => !empty($this->options['error_message']),
);
Earl Miles
committed
}
function admin_summary() {
// set up $this->value_options for the parent summary
$this->value_options = array();
if ($this->value) {
$result = db_query("SELECT * FROM {term_data} td WHERE td.tid IN (" . implode(', ', $this->value) . ")");
while ($term = db_fetch_object($result)) {
$this->value_options[$term->tid] = $term->name;
}
}
return parent::admin_summary();
}
}