The page you are looking at now is at this URL: http://pastoid.com/b0f
This paste was last updated on February 23, 2010 at 3:19 pm.
Index: vocabulary.php =================================================================== --- vocabulary.php (revision 4038) +++ vocabulary.php (working copy) @@ -357,7 +357,130 @@ } + public function append_to( $term, $parent_term = null ) + { + return move_term( $term, $parent_term ); // actually probably should have before_term in here too, or is that not an append? + } + /** + * Moves a term within the vocabulary. Returns a Term object. null parameters append the term to the end of any hierarchies. + * @return Term The Term object added + **/ + public function move_term( $term, $parent_term = null, $before_term = null ) + { + // 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; + + $nodes_moving = ( $source_right - $source_left + 1 ) / 2; // parent and descendants + + // we also need the destination right. + + DB::begin_transaction(); + + if ( $this->hierarchical ) { + // Check first if this is to be inserted to the left of a term + if ( null != $before_term ) { + $destination_right = $before_term->mptt_left - 1; + // there should be no need to check for parent term if before_term is being used. + } + else { + // If no parent is specified, put the new term after the last term + if ( null != $parent_term ) { + $parent_term_left = $parent_term->mptt_left; + $parent_term_right = $parent_term->mptt_right; + } + } + } + else { + // check before term only. parent should be null. Or do we throw an exception? + if ( null != $before_term ) { + $before_left = $before_term->mptt_left; + } + else { + // send it all the way to the right. + $rightmost_right = DB::get_value( 'SELECT mptt_right FROM {terms} WHERE vocabulary_id=? ORDER BY mptt_right DESC LIMIT 1', array($this->id) ); +// /* would this be faster? */ $rightmost_right = DB::get_value( 'SELECT MAX(mptt_right) FROM {terms} WHERE vocabulary_id=?', array($this->id) ); +// once we have this, we can subtract number of nodes * 2 from everything between source_mptt_left and this, then start renumbering and end up at this. + } + } + + // Move the existing nodes out of the way by making mptt_left and mptt_right negative + // Cannot finish before redoing this to bring the terms positive again. + $res = displace_term( $term, ( -1 - $source_right ) ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } +/* + $difference = $nodes_moving; + + $between_lefts = array( $source_node->mptt_left, $destination_node->mptt_left ); + sort( $between_lefts ); // must be in numeric order for BETWEEN + + $between_rights = array( $source_node->mptt_right, $destination_node->mptt_right ); + sort( $between_rights ); // must be in numeric order for BETWEEN + +*/ + $difference = $source_right - $source_left; + + // move the nodes between source and end of the vocabulary + $params = array( $difference, $this->id, $source_left ); + $res = DB::query( 'UPDATE {terms} SET mptt_left=mptt_left-? WHERE vocabulary_id=? AND mptt_left > ?', $params ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } + $params = array( $difference, $this->id, $source_right ); + $res = DB::query( 'UPDATE {terms} SET mptt_right=mptt_right-? WHERE vocabulary_id=? AND mptt_right > ?', $params ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } + + // make room for the displaced nodes + $params = array( $difference, $this->id, $destination_left ); + $res = DB::query( 'UPDATE {terms} SET mptt_left=mptt_left+? WHERE vocabulary_id=? AND mptt_left >= ?', $params ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } + $params = array( $difference, $this->id, $destination_right ); + $res = DB::query( 'UPDATE {terms} SET mptt_right=mptt_right+? WHERE vocabulary_id=? AND mptt_right >= ?', $params ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } + + + // Move the existing nodes back into the space left for them + // Cannot finish before redoing this to bring the terms positive again. + $res = displace_term( $term, $destination_term_right ); + if( ! $res ) { + DB::rollback(); + return FALSE; + } + + // Update the node + $result = $moving_term->update(); // update() not insert(), right? + if ( $result ) { + DB::commit(); + return $moving_term; + } + else { + DB::rollback(); + return FALSE; + } + + } + return FALSE; // probably should put this in an else. + } + + /** * Gets the term object by id. No parameter returns the root Term object. * @param integer $term_id The id of the term to fetch, or null for the root node * @return Term The Term object requested @@ -492,11 +615,27 @@ return TRUE; } + /** + * Temporarily set a term and its descendants aside from the rest of a vocabulary. + * If this is not done a second time, corruption will result. + * + **/ + private function displace_term( $term, $difference ) + { + // took this from delete_term below + if ( is_string( $term ) ) { + $term = $this->get_term( $term ); + } + + $params = array( $difference, $difference, $this->id, $term->mptt_left, $term->mptt_right ); + return DB::query( 'UPDATE {terms} SET mptt_left = mptt_left + ?, mptt_right = mptt_right + ? WHERE vocabulary_id = ? AND mptt_left BETWEEN ? AND ?', $params ); + } +
| Referring Domain | Hits |
|---|---|
| Unknown Referer | 108 |
| pastoid.com | 2 |
| drunkenmonkey.org | 1 |
Tip: Use Pastoid to shorten URLs with this bookmarklet: Pastoid This