View source
<?php
function lineage_taxonomy($op, $type, $array = NULL) {
if ($type == 'vocabulary') {
return;
}
switch ($op) {
case 'delete':
lineage_delete_term($array['tid']);
break;
case 'insert':
case 'update':
if (arg() != array(
'admin',
'content',
'taxonomy',
$array['vid'],
)) {
lineage_update_term($array);
}
break;
}
}
function lineage_form_taxonomy_overview_terms_alter(&$form, &$form_state) {
$form['#submit'] = array(
'lineage_taxonomy_overview_terms_submit',
);
}
function lineage_taxonomy_overview_terms_submit(&$form, &$form_state) {
if ($form_state['clicked_button']['#value'] == t('Reset to alphabetical')) {
if ($form_state['values']['reset_alphabetical'] === TRUE) {
taxonomy_vocabulary_confirm_reset_alphabetical_submit($form, $form_state);
lineage_update_all($form_state['values']['vid']);
return;
}
$form_state['rebuild'] = TRUE;
$form_state['confirm_reset_alphabetical'] = TRUE;
return;
}
$order = array_flip(array_keys($form['#post']));
$form_state['values'] = array_merge($order, $form_state['values']);
$vocabulary = $form['#vocabulary'];
$hierarchy = 0;
$changed_terms = array();
$tree = taxonomy_get_tree($vocabulary['vid']);
if (empty($tree)) {
return;
}
$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];
}
$level_weights = array();
foreach ($form_state['values'] as $tid => $values) {
if (isset($form[$tid]['#term'])) {
$term = $form[$tid]['#term'];
if ($values['parent'] == 0 && $term['weight'] != $weight) {
$term['weight'] = $weight;
$changed_terms[$term['tid']] = $term;
}
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;
}
}
if ($values['parent'] != $term['parent']) {
$term['parent'] = $values['parent'];
$changed_terms[$term['tid']] = $term;
}
$hierarchy = $term['parent'] != 0 ? 1 : $hierarchy;
$weight++;
}
}
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;
}
foreach ($changed_terms as $term) {
taxonomy_save_term($term);
}
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($vid = FALSE) {
$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";
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;
}
function lineage_update_term($term, $all = FALSE) {
if (is_array($term)) {
$term = (object) $term;
}
if (!$all) {
$r = db_query("\n SELECT tl.lineage, td.tid, td.name, td.weight, td.vid, th.parent\n FROM {term_data} td\n LEFT JOIN {term_lineage} tl ON tl.tid = td.tid\n LEFT JOIN {term_hierarchy} th ON td.tid = th.tid\n WHERE td.vid = %d\n AND td.tid <> %d\n LIMIT 1;", $term->vid, $term->tid);
$other_term = db_fetch_object($r);
if ($other_term->lineage != lineage_string($other_term)) {
$count = lineage_update_all($term->vid);
return $count;
}
}
$base = _lineage_get_parent_lineage($term->parent);
return count(lineage_update_term_r($term, $base));
}
function lineage_update_term_r($term, $base, $tids = array()) {
$base['base'] .= lineage_string($term);
db_query("DELETE FROM {term_lineage} WHERE tid = %d", $term->tid);
db_query("INSERT INTO {term_lineage} (tid, lineage, depth) VALUES (%d, '%s', %d)", $term->tid, $base['base'], $base['depth']);
$base['depth']++;
$tids[$term->tid] = TRUE;
$result = db_query("SELECT td.tid, td.name, td.weight, td.vid FROM {term_hierarchy} th INNER JOIN {term_data} td ON td.tid = th.tid WHERE th.parent = %d", $term->tid);
while ($child = db_fetch_object($result)) {
if (!isset($tids[$child->tid])) {
$tids = lineage_update_term_r($child, $base, $tids);
}
}
return $tids;
}
function lineage_delete_term($tid) {
db_query("DELETE FROM {term_lineage} WHERE tid = %d", $tid);
}
function lineage_string($term) {
$w = _lineage_weights($term->vid);
return sprintf("%0" . $w['digits'] . "d", $term->weight + $w['offset']) . "-" . $term->name . "\n";
}
function lineage_strip_weight($term_string) {
$term_name = preg_replace("([0-9]+-)", "", $term_string, 1);
if ($term_name != $term_string) {
return $term_name;
}
else {
_lineage_format_warning();
return FALSE;
}
}
function lineage_get_weight($term_string) {
$matches = array();
if (preg_match("([0-9]+-)", $term_string, $matches)) {
return substr($matches[0], 0, -1);
}
else {
_lineage_format_warning();
return FALSE;
}
}
function _lineage_get_parent_lineage($tid) {
$result = db_query("SELECT td.tid, td.name, td.weight, td.vid, th.parent FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE td.tid = %d", $tid);
if ($term = db_fetch_object($result)) {
$ret = _lineage_get_parent_lineage($term->parent);
$ret['base'] .= lineage_string($term);
$ret['depth'] += 1;
return $ret;
}
return array();
}
function lineage_views_api() {
return array(
'api' => 2.0,
);
}
function _lineage_weights($vid) {
static $weights = array();
if (!isset($weights[$vid])) {
$min_r = db_query("SELECT MIN(weight) FROM {term_data} WHERE vid = %d", $vid);
$weights[$vid]['min'] = db_result($min_r);
$weights[$vid]['offset'] = $weights[$vid]['min'] < 0 ? abs($weights[$vid]['min']) : 0;
$max_r = db_query("SELECT MAX(weight) FROM {term_data} WHERE vid = %d", $vid);
$weights[$vid]['max'] = db_result($max_r);
$weights[$vid]['digits'] = floor(log($weights[$vid]['max'] + $weights[$vid]['offset'] + 1));
if ($weights[$vid]['digits'] == 0) {
$weights[$vid]['digits']++;
}
}
return $weights[$vid];
}
function _lineage_format_warning() {
drupal_set_message(t("Warning: your lineage data appears to be in an old format. Try disabling and re-enabling the module, or run update.php."), 'warning', FALSE);
}