You are here

function _taxonomy_edge_taxonomy_term_update in Taxonomy Edge 7.2

Same name and namespace in other branches
  1. 8 taxonomy_edge.module \_taxonomy_edge_taxonomy_term_update()
  2. 6 taxonomy_edge.module \_taxonomy_edge_taxonomy_term_update()
  3. 7 taxonomy_edge.module \_taxonomy_edge_taxonomy_term_update()

Update a term in the edge tree.

Parameters

type $term:

3 calls to _taxonomy_edge_taxonomy_term_update()
taxonomy_edge_process_queue_item in ./taxonomy_edge.module
Cron queue worker Process edge for a queued term.
taxonomy_edge_reorder_submit in ./taxonomy_edge.module
Copy/paste from core taxonomy module. This is the penalty for not having a proper abstraction layer! And for not invoking update hook on terms when changing their parents!
taxonomy_edge_taxonomy_term_update in ./taxonomy_edge.module
Implements hook_taxonomy_term_update().

File

./taxonomy_edge.module, line 548
Selecting all children of a given taxonomy term can be a pain. This module makes it easier to do this, by maintaining a complete list of edges for each term using the adjecency matrix graph theory.

Code

function _taxonomy_edge_taxonomy_term_update($term) {
  $tx = db_transaction();

  // Invalidate sorted tree in case of name/weight change
  $modified =& drupal_static('taxonomy_edge_save_check_modified', TRUE);
  if ($modified) {
    taxonomy_edge_invalidate_order($term->vid);
  }
  if (!isset($term->parent)) {

    // Parent not set, no need to update hierarchy.
    return;
  }

  // Derive proper parents.
  // After this $new contains parents to be added
  // and $del contains parents to removed.
  $parents = _taxonomy_edge_unify_parents($term->parent);
  $old_parents = db_query("\n    SELECT p2.tid\n    FROM {taxonomy_term_edge_path} p\n    INNER JOIN {taxonomy_term_edge} e ON p.pid = e.pid AND e.distance = 1\n    INNER JOIN {taxonomy_term_edge_path} p2 ON e.parent = p2.pid\n    WHERE p.tid = :tid\n  ", array(
    ':tid' => $term->tid,
  ))
    ->fetchAll(PDO::FETCH_NUM);
  $old_parents = _taxonomy_edge_unify_parents($old_parents);
  $new = array_diff($parents, $old_parents);
  $del = array_diff($old_parents, $parents);

  // If hierarchy hasn't changed, then don't do anything
  if (!$del && !$new) {
    return;
  }

  // Move is easier/cheaper than delete/insert. Find trees that can be moved.
  $move = array();
  while ($new && $del) {
    $move[array_shift($del)] = array_shift($new);
  }

  // watchdog('taxonomy_edge', 'Updating taxonomy-edge for %tid [%parent]', array('%tid' => $tid, '%parent' => join(',', $parents)), WATCHDOG_DEBUG);
  if ($new) {
    $old_pids = taxonomy_edge_locate_paths($term->tid, array(
      reset($old_parents),
    ));
    $old_pid = reset($old_pids);
    foreach ($new as $tid) {
      $new_pids = db_query("SELECT p.pid FROM taxonomy_term_edge_path p WHERE p.tid = :tid", array(
        ':tid' => $tid,
      ))
        ->fetchAll(PDO::FETCH_ASSOC);
      foreach ($new_pids as $new_pid) {
        _taxonomy_edge_copy_subtree($term->vid, $old_pid, $new_pid['pid']);
      }
    }
  }
  if ($move) {

    // We don't move from old tids to new tids. We move from old pids to new pids.
    // Because of multiple parents, both old tids and new tids can have multiple pids.
    $old_pids = taxonomy_edge_locate_paths($term->tid, array_keys($move));
    foreach ($old_pids as $parent => $old_pid) {
      $new_pids = db_query("SELECT p.pid FROM taxonomy_term_edge_path p WHERE p.tid = :tid", array(
        ':tid' => $move[$parent],
      ))
        ->fetchAll(PDO::FETCH_ASSOC);
      foreach ($new_pids as $new_pid) {
        _taxonomy_edge_move_subtree($term->vid, $old_pid, $new_pid['pid']);
      }
    }
  }

  // Remove invalid edges.
  if ($del) {
    if ($pids = taxonomy_edge_locate_paths($term->tid, $del)) {
      $table = db_query_temporary("SELECT e.eid, e.pid FROM {taxonomy_term_edge} e WHERE e.parent IN (:pid)", array(
        ':pid' => $pids,
      ));
      $db_type = Database::getConnection()
        ->databaseType();
      switch ($db_type) {
        case 'mysql':
        case 'mysqli':
          db_query("DELETE e.* FROM {taxonomy_term_edge} e JOIN {$table} d ON d.eid = e.eid");
          db_query("DELETE p.* FROM {taxonomy_term_edge_path} p JOIN {$table} d ON d.pid = p.pid");
          break;
        default:
          db_query("DELETE FROM {taxonomy_term_edge} WHERE eid IN (SELECT t.eid FROM {$table} t)");
          db_query("DELETE FROM {taxonomy_term_edge_path} WHERE pid IN (SELECT t.pid FROM {$table} t)");
          break;
      }
    }
  }

  // Don't invalidate again if we have already done so.
  if (!$modified) {
    taxonomy_edge_invalidate_order($term->vid);
  }
}