diff --git a/taxonomy_manager.module b/taxonomy_manager.module index 99acdb4..119f1cf 100755 --- a/taxonomy_manager.module +++ b/taxonomy_manager.module @@ -1001,7 +1001,7 @@ function taxonomy_manager_tree_validate($form, &$form_state) { else if (is_numeric($form['#value'])) { $selected[$form['#value']] = $form['#value']; } - + $vid = $form['#vid']; foreach ($selected as $tid) { if (!_taxonomy_manager_tree_term_valid($tid, $vid)) { @@ -1061,6 +1061,150 @@ function _taxonomy_manager_term_get_lang($tid) { } /** + * Implements hook_field_widget_info(). + * + * Allows the taxonomy_manager_tree form element to be used within Drupal 7 Field API. + */ +function taxonomy_manager_field_widget_info() { + return array( + 'taxonomy_manager_tree' => array( + 'label' => t('Taxonomy manager tree'), + 'description' => t('Allows selection of terms via a dynamic tree of checkboxes, where parent + terms can be expanded and child terms loaded via AJAX.'), + 'field types' => array('taxonomy_term_reference'), + 'behaviors' => array( + 'multiple values' => FIELD_BEHAVIOR_CUSTOM, + ), + ), + ); +} + +/** + * Implements hook_field_widget_form(). + * + * Describes a form widget built on the taxonomy_manager_tree type form element, usable with + * taxonomy term reference fields via Field API. + * + * @param $form + * @param $form_state + * @param $field + * @param $instance + * @param $langcode + * @param $items + * @param $delta + * @param $element + * + * @return array a form definition + */ +function taxonomy_manager_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { + $default = array(); + if (is_array($items) && !empty($items)) { + foreach($items as $item) { + $default[$item['tid']] = $item['tid']; + } + } + $element += array( + '#type' => 'taxonomy_manager_tree', + '#vid' => substr($field['settings']['allowed_values'][0]['vocabulary'], 11), + '#required' => FALSE, + '#tree_is_required' => $field['settings']['required'], + '#multiple' => ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) ? + TRUE: FALSE, + '#pager' => TRUE, + '#title' => $instance['label'], + '#description' => $instance['description'], + '#default_value' => $default, + '#terms_to_expand' => $default, + ); + if (isset($element['#title']) && !empty($element['#title'])) { + $element['#prefix'] = '' . t($element['#title']) . '
'; + unset($element['#title']); + } + if (isset($element['#description']) && !empty($element['#description'])) { + $element['#suffix'] = '
' . t($element['#description']) . '
'; + unset($element['#description']); + } + + // Need to override the normal validation function, which won't be available in the $form array + // until after build. + $element['#after_build'][] = '_taxonomy_manager_field_api_widget_after_build'; + + return $element; +} + +/** + * Sets the Field API widget to use the correct validation function, which will format selected + * items the way taxonomy term reference fields expect them. + * + * @param $element + * @param $form_state + */ +function _taxonomy_manager_field_api_widget_after_build(&$element, &$form_state) { + $element['#element_validate'] = array('taxonomy_manager_field_api_widget_validate'); + return $element; +} + +/** + * Validation handler for Field API widget. Gets selected terms and formats them the way they are + * expected to appear by taxonomy term reference fields. Also skips making sure selections are + * valid, since taxonomy term reference fields can perform their own (field-level) validation. + * + * @param $element + * @param $form_state + */ +function taxonomy_manager_field_api_widget_validate($element, &$form_state) { + $direct_parents = array(); + $selected = array(); + if ($element['#multiple']) { + $selected = _taxonomy_manager_tree_get_selected_terms($element['#value'], $direct_parents); + } + else if (is_numeric($element['#value'])) { + $selected[$element['#value']] = $element['#value']; + } + else { + $selected = _taxonomy_manager_tree_get_selected_terms($element['#value'], $direct_parents); + // Ensure there is only one selected term. + if (count($selected) > 1) { + $tid = key($selected); + $selected = array($tid => $tid); + } + } + // Reformat array of selected terms to the format expected by the taxonomy term reference field. + $items = array(); + foreach($selected as $tid) { + $items[] = (array) taxonomy_term_load($tid); + } + // Sort items alphabetically + usort($items, '_taxonomy_manager_sort_selected_items'); + // Send to $form_state + form_set_value($element, $items, $form_state); +} + +/** + * Helper function to sort taxonomy term objects (cast as arrays) alphabetically. + */ +function _taxonomy_manager_sort_selected_items($term1, $term2) { + return strcasecmp($term1['name'], $term2['name']); +} + +/** + * Implements hook_form_id_alter(). + * + * Only allow single-value or unlimited-value fields when using the Taxonomy manager tree field widget. + * + * @param $form + * @param $form_state + */ +function taxonomy_manager_form_field_ui_field_edit_form_alter(&$form, &$form_state) { + if ($form['#instance']['widget']['type'] == 'taxonomy_manager_tree') { + $form['field']['cardinality']['#options'] = array( + FIELD_CARDINALITY_UNLIMITED => t('Unlimited'), + 1 => 1, + ); + } +} + +/** * theme function for root element * * @param $element