0

I need to implement a boolean field for a vocabulary that determines whether terms within a vocabulary appear in autocomplete results for a taxonomy term reference field's autocomplete widget. The function taxonomy_autocomplete(...) has the query that I want to modify. But how can I modify the query or override the results of the autocomplete json callback?

I know how to add the boolean field to the vocabulary but not how to filter autocomplete results. The idea is to let users enter new terms but not have their new terms appear in autocomplete results unless approved by an admin.

1

Here is how I've added a new term custom widget:

/**
 * Implements hook_field_widget_info().
 */
function deepestlevel_taxonomy_widget_field_widget_info() {

  return array(
    'textfield' => array(
      'label' => t('deepestlevel_taxonomy_widget - Only deepest level'),
      'field types' => array('taxonomy_term_reference'),
      'settings' => array(
        'size' => 60,
        'autocomplete_path' => 'deepestlevel_taxonomy_widget/autocomplete',
      ),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function deepestlevel_taxonomy_widget_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

  $tags = array();
  foreach ($items as $item) {
    $tags[$item['tid']] = isset($item['taxonomy_term']) ? $item['taxonomy_term'] : taxonomy_term_load($item['tid']);
  }

  $element += array(
    '#type' => 'textfield',
    '#default_value' => taxonomy_implode_tags($tags),
    '#autocomplete_path' => 'deepestlevel_taxonomy_widget/autocomplete'. '/' . $field['field_name'],
    // '#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $field['field_name'],
    '#size' => $instance['widget']['settings']['size'],
    '#maxlength' => 1024,
    '#element_validate' => array('taxonomy_autocomplete_validate'),
  );

  return $element;
}

/**
 * Implements hook_menu().
 */
function deepestlevel_taxonomy_widget_menu() {
  $items['deepestlevel_taxonomy_widget/autocomplete'] = array(
    'title' => 'Autocomplete taxonomy deepest level',
    'page callback' => 'deepestlevel_taxonomy_widget',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

// THIS IS THE OVERRIDE CALLBACK copied from core taxonomy.pages.inc
// function taxonomy_autocomplete($field_name, $tags_typed = '') {
function deepestlevel_taxonomy_widget($field_name, $tags_typed = '') {

// NEW CODE HERE

}
0

The solution was to create a module that adds an 'enabled' property to term entities and implements a version of the 'autocomplete' widget with a custom callback to filter the results.

hook_schema_alter() tells Drupal that the entity has the new property but we have to manually add the database column in hook_install() and remove it in hook_uninstall().

/*
 * Implements hook_schema_alter() - adds boolean field to disable terms by default
 */
function term_disabler_schema_alter(&$schema) {
  $schema['taxonomy_term_data']['fields']['enabled'] = array(
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
    'description' => 'Does this term appear in the enabled-only autocomplete widget?',
  );
}

/*
 * Implements hook_install()
 */
function term_disabler_install() {    
  db_add_field('taxonomy_term_data', 'enabled', array(
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
      'default' => 0,
      'description' => 'Does this term appear in the enabled-only autocomplete widget?',
    )
  );
}


/*
 * Implements hook_uninstall()
 */
function term_disabler_uninstall() {
  db_drop_field('taxonomy_term_data', 'enabled');
}

The form 'taxonomy_form_term' is altered by the hook term_disabler_form_taxonomy_form_term_alter() which adds a checkboxs and a submit callback to save the value.

/*
 * Implements hook_form_FORM_ID_alter()
 */
function term_disabler_form_taxonomy_form_term_alter(&$form, &$form_state, $form_id) {

  $form['term-enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enabled'),
    '#weight' => -1,
    '#default_value' => $form['#term']['enabled'],
  );

  $form['#submit'][] = '_term_disabler_taxonomy_form_term_submit';

}


/*
 * Submit handler saves the checkbox state with the term entity
 */
function _term_disabler_taxonomy_form_term_submit(&$form, &$form_state) {

  $tid = $form['#term']['tid'];
  $enabled = $form_state['values']['term-enabled'];

  $query = db_update('taxonomy_term_data')
    ->condition('tid', $tid)
    ->fields(array('enabled' => $enabled))
    ->execute();

  drupal_set_message($query . ' rows updated');
}

A custom widget with the same form and validate callbacks as taxonomy autocomplete has a different 'autocomplete_path' pointing to a new URL. The page callback at the new URL is identical to taxonomy/autocomplete with the addition of one line when the query is being built:

$query->condition('t.enabled', 1);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.