--- lineage.module 2008-09-05 02:15:48.000000000 -0500 +++ lineage-new.module 2009-10-25 08:13:20.000000000 -0500 @@ -14,23 +14,149 @@ function lineage_taxonomy($op, $type, $a break; case 'insert': case 'update': - lineage_update_term($array); + // Skip if we are on the admin reordering pages; + // it will happen be triggered by our submit handler after processing. + $arg = arg(); + if (arg() != array('admin','content','taxonomy',$array['vid'])) { + lineage_update_term($array); + } break; } } +/** + * Implements hook_form_taxonomy_overview_terms_alter(). + */ +function lineage_form_taxonomy_overview_terms_alter(&$form,&$form_state) { + // Override submit handler. + $form['#submit'] = array('lineage_taxonomy_overview_terms_submit'); +} + +/** + * Submit handler for taxonomy_overview_terms (the admin term reordering form). + * Overrides handling so that we can update lineages after the new term + * weights are processed. + * This function is mostly a clone of taxonomy_overview_terms_submit, with + * the addition of lineage_update_all calls in the appropriate places. + */ +function lineage_taxonomy_overview_terms_submit(&$form,&$form_state) { + if ($form_state['clicked_button']['#value'] == t('Reset to alphabetical')) { + // Execute the reset action. + if ($form_state['values']['reset_alphabetical'] === TRUE) { + taxonomy_vocabulary_confirm_reset_alphabetical_submit($form, $form_state); + lineage_update_all($form_state['values']['vid']); + return; + } + // Rebuild the form to confirm the reset action. + $form_state['rebuild'] = TRUE; + $form_state['confirm_reset_alphabetical'] = TRUE; + return; + } + + $order = array_flip(array_keys($form['#post'])); // Get the $_POST order. + $form_state['values'] = array_merge($order, $form_state['values']); // Update our original form with the new order. + + $vocabulary = $form['#vocabulary']; + $hierarchy = 0; // Update the current hierarchy type as we go. + + $changed_terms = array(); + $tree = taxonomy_get_tree($vocabulary['vid']); + + if (empty($tree)) { + return; + } + + // Build a list of all terms that need to be updated on previous pages. + $weight = 0; + $term = (array)$tree[0]; + while ($term['tid'] != $form['#first_tid']) { + if ($term['parents'][0] == 0 && $term['weight'] != $weight) { + $term['parent'] = $term['parents'][0]; + $term['weight'] = $weight; + $changed_terms[$term['tid']] = $term; + } + $weight++; + $hierarchy = $term['parents'][0] != 0 ? 1 : $hierarchy; + $term = (array)$tree[$weight]; + } + + // Renumber the current page weights and assign any new parents. + $level_weights = array(); + foreach ($form_state['values'] as $tid => $values) { + if (isset($form[$tid]['#term'])) { + $term = $form[$tid]['#term']; + // Give terms at the root level a weight in sequence with terms on previous pages. + if ($values['parent'] == 0 && $term['weight'] != $weight) { + $term['weight'] = $weight; + $changed_terms[$term['tid']] = $term; + } + // Terms not at the root level can safely start from 0 because they're all on this page. + elseif ($values['parent'] > 0) { + $level_weights[$values['parent']] = isset($level_weights[$values['parent']]) ? $level_weights[$values['parent']] + 1 : 0; + if ($level_weights[$values['parent']] != $term['weight']) { + $term['weight'] = $level_weights[$values['parent']]; + $changed_terms[$term['tid']] = $term; + } + } + // Update any changed parents. + if ($values['parent'] != $term['parent']) { + $term['parent'] = $values['parent']; + $changed_terms[$term['tid']] = $term; + } + $hierarchy = $term['parent'] != 0 ? 1 : $hierarchy; + $weight++; + } + } + + // Build a list of all terms that need to be updated on following pages. + for ($weight; $weight < count($tree); $weight++) { + $term = (array)$tree[$weight]; + if ($term['parents'][0] == 0 && $term['weight'] != $weight) { + $term['parent'] = $term['parents'][0]; + $term['weight'] = $weight; + $changed_terms[$term['tid']] = $term; + } + $hierarchy = $term['parents'][0] != 0 ? 1 : $hierarchy; + } + + // Save all updated terms. + foreach ($changed_terms as $term) { + taxonomy_save_term($term); + } + + // Update the vocabulary hierarchy to flat or single hierarchy. + if ($vocabulary['hierarchy'] != $hierarchy) { + $vocabulary['hierarchy'] = $hierarchy; + taxonomy_save_vocabulary($vocabulary); + } + + lineage_update_all($vocabulary['vid']); +} + function lineage_enable() { drupal_set_message(t("Updated @number taxonomy records.", array('@number' => lineage_update_all()))); } -function lineage_update_all() { - $count = 0; +/** + * Updates all lineage records. + * @param $vid=false If passed, limit to records for only one vocabulary. + * @return $count The number of records updated. + */ +function lineage_update_all($vid=false) { + // If we are only updating one vocabulary, select only those terms. + $base_q = "SELECT td.tid, td.name, td.weight, td.vid FROM {term_data} td LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE th.parent = 0"; - $result = db_query("SELECT td.tid, td.name, td.weight FROM {term_data} td LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE th.parent = 0"); - while ($term = db_fetch_object($result)) { - $count += lineage_update_term($term); + if ($vid) { + $result = db_query($base_q." AND td.vid = '%d'",$vid); + } + else { + $result = db_query($base_q); } + $count = 0; + while ($term = db_fetch_object($result)) { + $count += lineage_update_term($term,true); + } return $count; }