Habari\Vocabulary::move_term PHP Метод

move_term() публичный Метод

The MPTT operations can seem complex, but they're actually pretty simple: 1: Find our insertion point: Either at the very end of the vocabulary, or before / after the given term 2: Create a gap at that point: We'll bump everything at that point or after up enough to fit in the term we're moving 3: Move the term: We know the offset between the old point and the new point, so move the range up that number of spaces. 4: Close the original gap: Now we've got all our terms moved, but we need to bump everything back down to close the gap it left, similar to #2.
public move_term ( Term $term, Term | null $target_term = null, boolean $before = false ) : Term
$term Term The term to move.
$target_term Term | null The term to move $term before or after, or null to move it to the very end of the vocabulary.
$before boolean True to move $term BEFORE $target_term, false (the default) to move $term AFTER $target_term.
Результат Term The Term object moved
    public function move_term($term, $target_term = null, $before = false)
    {
        // We assume that the arguments passed are valid terms. Check them before calling this.
        // If there are terms in the vocabulary, work out the reference point
        if (!$this->is_empty()) {
            $source_left = $term->mptt_left;
            $source_right = $term->mptt_right;
            $range = $source_right - $source_left + 1;
            DB::begin_transaction();
            // Determine the insertion point mptt_target
            if ($target_term == null) {
                // if no target is specified, put the new term after the last term
                $mptt_target = DB::get_value('SELECT MAX(mptt_right) FROM {terms} WHERE vocabulary_id = :id', array(':id' => $this->id));
                $mptt_target = $mptt_target + 1;
                // the left is one greater than the highest right
            } else {
                // if we're putting it before
                if ($before) {
                    $mptt_target = $target_term->mptt_left;
                    // we're actually taking the place of the target term's left
                } else {
                    $mptt_target = $target_term->mptt_right + 1;
                    // we just need to start at the next number
                }
            }
            // Create space in the tree for the insertion
            $params = array('vocab_id' => $this->id, 'range' => $range, 'mptt_target' => $mptt_target);
            $res = DB::query('UPDATE {terms} SET mptt_left = mptt_left + :range WHERE vocabulary_id = :vocab_id AND mptt_left >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            $res = DB::query('UPDATE {terms} SET mptt_right = mptt_right + :range WHERE vocabulary_id = :vocab_id AND mptt_right >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            // if we're moving it "down" ("forward"?) in the vocabulary, we just created a gap that changed our term's left and right values
            if ($mptt_target < $source_left) {
                $source_left = $source_left + $range;
                $source_right = $source_right + $range;
            }
            // figure out how far our nodes are moving
            $offset = $mptt_target - $source_left;
            // move our lucky nodes into the space we just created
            $params = array(':offset' => $offset, ':vocab_id' => $this->id, ':source_left' => $source_left, ':source_right' => $source_right);
            $res = DB::query('
				UPDATE {terms}
				SET
					mptt_left = mptt_left + :offset,
					mptt_right = mptt_right + :offset
				WHERE
					vocabulary_id = :vocab_id AND
					mptt_left >= :source_left AND
					mptt_right <= :source_right
				', $params);
            // Close the gap in the tree created by moving those nodes out
            $params = array('range' => $range, 'vocab_id' => $this->id, 'source_left' => $source_left);
            $res = DB::query('UPDATE {terms} SET mptt_left = mptt_left - :range WHERE vocabulary_id = :vocab_id AND mptt_left > :source_left', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            $params = array('range' => $range, 'vocab_id' => $this->id, 'source_right' => $source_right);
            $res = DB::query('UPDATE {terms} SET mptt_right = mptt_right - :range WHERE vocabulary_id = :vocab_id AND mptt_right > :source_right', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            // Success!
            DB::commit();
            return $this->get_term($term->id);
        }
        return false;
    }