vid); } $form['#vocabulary'] = $vocabulary; $form['#tree'] = TRUE; $form['#parent_fields'] = FALSE; $form['header']['info'] = array( '#markup' => '

' . t('Drag and drop taxonomy terms below. Ctrl + click on an arrow will expand the term and all its children') . '

', ); $form['header']['messages'] = array( '#markup' => '
', ); $root_entries = 0; // Elements at the root level on this page. $delta = 0; $term_deltas = array(); $tree = taxonomy_get_tree($vocabulary->vid); $form_state['storage']['tree'] = $tree; $term = current($tree); $form['taxonomy_wrangler_messages'] = array( '#type' => 'markup', '#markup' => '', ); // The original form handled setting the order after a validation error. // Since we aren't supporting the non-ajax form, it has been removed. // Build the actual form. foreach ($tree as $orig_key => $term) { $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0; $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid]; // Save the term for the current page so we don't have to load it a second time. $form[$key]['#term'] = (array) $term; if (isset($term->parents)) { $form[$key]['#term']['parent'] = $term->parent = $term->parents[0]; unset($form[$key]['#term']['parents'], $term->parents); } $form[$key]['view'] = array('#type' => 'link', '#title' => $term->name, '#href' => "taxonomy/term/$term->tid"); if ($vocabulary->hierarchy < 2 && count($tree) > 1) { $form['#parent_fields'] = TRUE; $form[$key]['view']['#options']['attributes']['data-tid'] = $term->tid; $form[$key]['view']['#options']['attributes']['data-parent'] = $term->tid; $form[$key]['view']['#options']['attributes']['data-depth'] = $term->depth; $form[$key]['view']['#options']['attributes']['data-weight'] = $term->weight; } $form[$key]['edit'] = array('#type' => 'link', '#title' => t('edit'), '#href' => 'taxonomy/term/' . $term->tid . '/edit', '#options' => array('query' => drupal_get_destination())); } $form['#empty_text'] = t('No terms available. Add term.', array('@link' => url('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add'))); // Hidden input field for ajax. $form['term_data'] = array( '#type' => 'hidden', '#default_value' => '{}', ); if ($vocabulary->hierarchy < 2 && count($tree) > 1) { $form['actions'] = array('#type' => 'actions', '#tree' => FALSE); $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('Save'), '#ajax' => array( 'callback' => 'taxonomy_wrangler_terms_overview_ajax_handler', ), ); $form['actions']['reset_alphabetical'] = array( '#type' => 'submit', '#value' => t('Reset to alphabetical'), ); } $module_path = drupal_get_path('module', 'taxonomy_wrangler'); $form['#attached']['css'][] = $module_path . '/css/taxonomy_wrangler.css'; $form['#attached']['js'][] = $module_path . '/js/taxonomy_wrangler.js'; return $form; } /** * Validate callback for taxonomy_wrangler_overview_terms. */ function taxonomy_wrangler_overview_terms_validate($form, &$form_state) { if ($form_state['triggering_element']['#value'] != t('Reset to alphabetical')) { if (isset($form_state['values']['term_data'])) { $updated_terms_json = json_decode($form_state['values']['term_data']); if ($updated_terms_json == NULL) { drupal_set_message(t('an error occurred parsing submitted values.'), 'error'); } else { $form_state['storage']['updated_terms'] = array(); $values_to_update = array('parent', 'weight'); if (!empty($updated_terms_json->termData)) { $form_state['storage']['raw_term_data'] = $updated_terms_json->termData; foreach ($updated_terms_json->termData as $updated_term) { $term = taxonomy_term_load($updated_term->tid); foreach ($values_to_update as $prop) { if (isset($updated_term->{$prop})) { $term->{$prop} = (int) $updated_term->{$prop}; } } $form_state['storage']['updated_terms'][$term->tid] = $term; } } } } } } /** * Submit callback for taxonomy_wrangler_overview_terms. */ function taxonomy_wrangler_overview_terms_submit($form, &$form_state) { if ($form_state['triggering_element']['#value'] == t('Reset to alphabetical')) { module_load_include('inc', 'taxonomy', 'taxonomy.admin'); // Execute the reset action. if ($form_state['values']['reset_alphabetical'] === TRUE) { return taxonomy_vocabulary_confirm_reset_alphabetical_submit($form, $form_state); } // Rebuild the form to confirm the reset action. $form_state['rebuild'] = TRUE; $form_state['confirm_reset_alphabetical'] = TRUE; return; } else { if (!empty($form_state['storage']['updated_terms'])) { foreach ($form_state['storage']['updated_terms'] as $term) { taxonomy_term_save($term); } } } } /** * Ajax handler for taxonomy_wrangler_overview_terms. */ function taxonomy_wrangler_terms_overview_ajax_handler($form, &$form_state) { $commands = array(); $messages = '
'; $messages .= theme('status_messages'); $messages .= '
'; $commands[] = ajax_command_replace('#taxonomy-wrangler-messages-server', $messages); // Send timestamps back to browser so it can update the row status. $timestamps = array(); if (!empty($form_state['storage']['raw_term_data'])) { foreach($form_state['storage']['raw_term_data'] as $term) { if (isset($term->updated)) { $timestamps[$term->tid] = (float) $term->updated; } } } $commands[] = ajax_command_settings(array( 'taxonomyWrangler' => array('updatedTimestamps' => $timestamps), )); return array('#type' => 'ajax', '#commands' => $commands); } /** * Returns HTML for a terms overview form as a sortable list of terms. * * @param $variables * An associative array containing: * - form: A render element representing the form. * * @see taxonomy_overview_terms() * @ingroup themeable */ function theme_taxonomy_wrangler_overview_terms($variables) { $form = $variables['form']; // Add drag and drop if parent fields are present in the form. if ($form['#parent_fields']) { taxonomy_wrangler_add_tabledrag('taxonomy-wrangler', 'match', 'parent', 'parent', 'parent', 'tid', FALSE); taxonomy_wrangler_add_tabledrag('taxonomy-wrangler', 'depth', 'group', 'depth', NULL, NULL, FALSE); drupal_add_css(drupal_get_path('module', 'taxonomy') . '/taxonomy.css'); } taxonomy_wrangler_add_tabledrag('taxonomy-wrangler', 'order', 'sibling', 'weight'); $errors = form_get_errors() != FALSE ? form_get_errors() : array(); $rows = array(); $element_children = element_children($form); $is_root = TRUE; foreach ($element_children as $i => $key) { if (isset($form[$key]['#term'])) { $term = &$form[$key]; $next_key = isset($element_children[$i + 1]) ? $element_children[$i + 1] : FALSE; $is_parent = FALSE; if (isset($form[$next_key]['#term']) && $form[$next_key]['#term']['depth'] > $term['#term']['depth'] && !$is_root) { $is_parent = TRUE; } $row = array(); $row[] = (isset($term['#term']['depth']) && $term['#term']['depth'] > 0 ? theme('indentation', array('size' => $term['#term']['depth'])) : ''); $accordion_classes = array('taxonomy-wrangler-accordion-item'); if ($is_root) { $accordion_classes[] = 'taxonomy-wrangler-accordion-item--root'; $is_root = FALSE; } elseif ($is_parent) { $accordion_classes[] = 'taxonomy-wrangler-accordion-item--parent'; } else { $accordion_classes[] = 'taxonomy-wrangler-accordion-item--child'; } $row[0] .= ''; $row[0] .= drupal_render($term['view']); if ($form['#parent_fields']) { $term['tid']['#attributes']['class'] = array('term-id'); $term['parent']['#attributes']['class'] = array('term-parent'); $term['depth']['#attributes']['class'] = array('term-depth'); $row[0] .= drupal_render($term['parent']) . drupal_render($term['tid']) . drupal_render($term['depth']); } $term['weight']['#attributes']['class'] = array('term-weight'); $row[] = drupal_render($term['weight']); $row[] = drupal_render($term['edit']); $row = array( 'data' => $row, 'data-tid' => $term['#term']['tid'], 'data-parent' => $term['#term']['parent'], 'data-depth' => $term['#term']['depth'], 'data-weight' => $term['#term']['weight'], 'data-haschildren' => $is_parent, ); $rows[$key] = $row; } } // Add necessary classes to rows. $row_position = 0; foreach ($rows as $key => $row) { $rows[$key]['class'] = array(); if (isset($form['#parent_fields'])) { $rows[$key]['class'][] = 'draggable'; } // Add an error class if this row contains a form error. foreach ($errors as $error_key => $error) { if (strpos($error_key, $key) === 0) { $rows[$key]['class'][] = 'error'; } } $rows[$key]['class'][] = 'taxonomy-wrangler-term-row'; $rows[$key]['class'][] = 'term-weight-row'; $row_position++; } if (empty($rows)) { $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => '3')); } $output = drupal_render($form['header']); //unset($form['header']); $header = array(t('Name'), t('Weight'), t('Operations')); $output .= theme('table', array( 'header' => $header, 'rows' => $rows, 'attributes' => array( 'id' => 'taxonomy-wrangler', 'class' => array('taxonomy-wrangler', 'taxonomy-wrangler-accordion'), ), )); $output .= drupal_render_children($form); return $output; }