Pastoid

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.

Pasted Coderaw

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 );
+	}
+
 
 

Toggle wordwrap

Referring DomainHits
Unknown Referer 108
pastoid.com 2
drunkenmonkey.org 1
Is this paste spam?
<Hide