src/Model/Behavior/AncestorBehavior.php
public function moveNode($id, $parent_id, $position = null)
	{
		$primaryKey = $this->_table->getSchema()->primaryKey();
		$primaryKey = count($primaryKey) == 1 ? $primaryKey[0] : $primaryKey;

		$parent_id_fieldname = $this->getConfig('model_parent_id_fieldname');
		$sort_fieldname      = $this->getConfig('model_sort_fieldname');

		$connection = $this->_table->getConnection();
		$connection->begin();

		$result = true;

		/*
		 * Get moved node
		 */
		$node = $this->_table->get($id);

		/*
		 * Get current nodes positions of (new) siblings
		 */
		$current_children = $this->_table->query()->where([$parent_id_fieldname => $parent_id])->order([$sort_fieldname => 'asc']);

		$new_sort_children = [];

		foreach($current_children as $current_position => $current_child)
		{
			if($current_child->{$primaryKey} != $id)
			{
				$new_sort_children[] = $current_child;
			}
		}

		/*
		 * Default position is after all siblings
		 */
		$position = isset($position)                       ? $position : $current_children->count();
		$position = $position >= 0                         ? $position : 0;
		$position = $position <= count($new_sort_children) ? $position : count($new_sort_children);

		/*
		 * Insert moved node at position
		 */
		array_splice($new_sort_children, $position, 0, array($node));

		/*
		 * If node has a new parent -> save it
		 */
		if($node->{$parent_id_fieldname} != $parent_id)
		{
			$query = $this->_table->query()->update()->set([$parent_id_fieldname => $parent_id])->where([$primaryKey => $id]);
			if(!$query->execute())
			{
				$result = false;
			}
		}

		/*
		 * Update positions
		 */
		foreach($new_sort_children as $index => $new_sort_child)
		{
			$query = $this->_table->query()->update()->set([$sort_fieldname => ($index * 10)])->where([$primaryKey => $new_sort_child->{$primaryKey}]);
			if(!$query->execute())
			{
				$result = false;
			}
		}

		/***********/

		if($result)
		{
			$connection->commit();
		}
		else
		{
			$connection->rollback();
		}

		return $result;
	}
public function moveNode($id, $parent_id, $position = null)
	{
		$primaryKey = $this->_table->getSchema()->primaryKey();
		$primaryKey = count($primaryKey) == 1 ? $primaryKey[0] : $primaryKey;

		$parent_id_fieldname = $this->getConfig('model_parent_id_fieldname');
		$sort_fieldname      = $this->getConfig('model_sort_fieldname');

		$connection = $this->_table->getConnection();
		$connection->begin();

		$result = true;

		/*
		 * Get moved node
		 */
		$node = $this->_table->get($id);

		/*
		 * Get current nodes positions of (new) siblings
		 */
		$current_children = $this->_table->query()->where([$parent_id_fieldname => $parent_id])->order([$sort_fieldname => 'asc']);

		$new_sort_children = [];

		foreach($current_children as $current_position => $current_child)
		{
			if($current_child->{$primaryKey} != $id)
			{
				$new_sort_children[] = $current_child;
			}
		}

		/*
		 * Default position is after all siblings
		 */
		$position = isset($position)                       ? $position : $current_children->count();
		$position = $position >= 0                         ? $position : 0;
		$position = $position <= count($new_sort_children) ? $position : count($new_sort_children);

		/*
		 * Insert moved node at position
		 */
		array_splice($new_sort_children, $position, 0, array($node));

		/*
		 * If node has a new parent -> save it
		 */
		if($node->{$parent_id_fieldname} != $parent_id)
		{
			$query = $this->_table->query()->update()->set([$parent_id_fieldname => $parent_id])->where([$primaryKey => $id]);
			if(!$query->execute())
			{
				$result = false;
			}
		}

		/*
		 * Update positions
		 */
		foreach($new_sort_children as $index => $new_sort_child)
		{
			$query = $this->_table->query()->update()->set([$sort_fieldname => ($index * 10)])->where([$primaryKey => $new_sort_child->{$primaryKey}]);
			if(!$query->execute())
			{
				$result = false;
			}
		}

		/***********/

		if($result)
		{
			$connection->commit();
		}
		else
		{
			$connection->rollback();
		}

		return $result;
	}
public function moveNode ( $ id , $ parent_id , $ position = null ) { $ primaryKey = $ this -> _table -> getSchema ( ) -> primaryKey ( ) ; $ primaryKey = count ( $ primaryKey ) == 1 ? $ primaryKey [ 0 ] : $ primaryKey ; $ parent_id_fieldname = $ this -> getConfig ( 'model_parent_id_fieldname' ) ; $ sort_fieldname = $ this -> getConfig ( 'model_sort_fieldname' ) ; $ connection = $ this -> _table -> getConnection ( ) ; $ connection -> begin ( ) ; $ result = true ; /*
		 * Get moved node
		 */ $ node = $ this -> _table -> get ( $ id ) ; /*
		 * Get current nodes positions of (new) siblings
		 */ $ current_children = $ this -> _table -> query ( ) -> where ( [ $ parent_id_fieldname => $ parent_id ] ) -> order ( [ $ sort_fieldname => 'asc' ] ) ; $ new_sort_children = [ ] ; foreach ( $ current_children as $ current_position => $ current_child ) { if ( $ current_child -> { $ primaryKey } != $ id ) { $ new_sort_children [ ] = $ current_child ; } } /*
		 * Default position is after all siblings
		 */ $ position = isset ( $ position ) ? $ position : $ current_children -> count ( ) ; $ position = $ position >= 0 ? $ position : 0 ; $ position = $ position <= count ( $ new_sort_children ) ? $ position : count ( $ new_sort_children ) ; /*
		 * Insert moved node at position
		 */ array_splice ( $ new_sort_children , $ position , 0 , array ( $ node ) ) ; /*
		 * If node has a new parent -> save it
		 */ if ( $ node -> { $ parent_id_fieldname } != $ parent_id ) { $ query = $ this -> _table -> query ( ) -> update ( ) -> set ( [ $ parent_id_fieldname => $ parent_id ] ) -> where ( [ $ primaryKey => $ id ] ) ; if ( ! $ query -> execute ( ) ) { $ result = false ; } } /*
		 * Update positions
		 */ foreach ( $ new_sort_children as $ index => $ new_sort_child ) { $ query = $ this -> _table -> query ( ) -> update ( ) -> set ( [ $ sort_fieldname => ( $ index * 10 ) ] ) -> where ( [ $ primaryKey => $ new_sort_child -> { $ primaryKey } ] ) ; if ( ! $ query -> execute ( ) ) { $ result = false ; } } /***********/ if ( $ result ) { $ connection -> commit ( ) ; } else { $ connection -> rollback ( ) ; } return $ result ; }
Move a node under the same parent node or under a new node.
New position of the node can be specified

@param int $id ID of the node to move
@param int $parent_id ID of the (new) parent node
@param int $position New position of the node. Position is zero based.
@return boolean
Move a node under the same parent node or under a new node . New position of the node can be specified