ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:25.34 GB of 70.42 GB (35.99%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ http/ yalagina/ libraries/ joomla/ database/ - drwxr-xr-x

Directory:
Viewing file:     tablenested.php (47.9 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

jimport('joomla.database.table');

/**
 * Table class supporting modified pre-order tree traversal behavior.
 *
 * @package     Joomla.Platform
 * @subpackage  Database
 * @link        http://docs.joomla.org/JTableNested
 * @since       11.1
 */
class JTableNested extends JTable
{
    
/**
     * Object property holding the primary key of the parent node.  Provides
     * adjacency list data for nodes.
     *
     * @var    integer
     * @since  11.1
     */
    
public $parent_id;

    
/**
     * Object property holding the depth level of the node in the tree.
     *
     * @var    integer
     * @since  11.1
     */
    
public $level;

    
/**
     * Object property holding the left value of the node for managing its
     * placement in the nested sets tree.
     *
     * @var    integer
     * @since  11.1
     */
    
public $lft;

    
/**
     * Object property holding the right value of the node for managing its
     * placement in the nested sets tree.
     *
     * @var    integer
     * @since  11.1
     */
    
public $rgt;

    
/**
     * Object property holding the alias of this node used to constuct the
     * full text path, forward-slash delimited.
     *
     * @var    string
     * @since  11.1
     */
    
public $alias;

    
/**
     * Object property to hold the location type to use when storing the row.
     * Possible values are: ['before', 'after', 'first-child', 'last-child'].
     *
     * @var    string
     * @since  11.1
     */
    
protected $_location;

    
/**
     * Object property to hold the primary key of the location reference node to
     * use when storing the row.  A combination of location type and reference
     * node describes where to store the current node in the tree.
     *
     * @var    integer
     * @since  11.1
     */
    
protected $_location_id;

    
/**
     * An array to cache values in recursive processes.
     *
     * @var    array
     * @since  11.1
     */
    
protected $_cache = array();

    
/**
     * Debug level
     *
     * @var    integer
     * @since  11.1
     */
    
protected $_debug 0;

    
/**
     * Sets the debug level on or off
     *
     * @param   integer  $level  0 = off, 1 = on
     *
     * @return  void
     *
     * @since   11.1
     */
    
public function debug($level)
    {
        
$this->_debug intval($level);
    }

    
/**
     * Method to get an array of nodes from a given node to its root.
     *
     * @param   integer  $pk          Primary key of the node for which to get the path.
     * @param   boolean  $diagnostic  Only select diagnostic data for the nested sets.
     *
     * @return  mixed    Boolean false on failure or array of node objects on success.
     *
     * @link    http://docs.joomla.org/JTableNested/getPath
     * @since   11.1
     */
    
public function getPath($pk null$diagnostic false)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Get the path from the node to the root.
        
$query $this->_db->getQuery(true);
        
$select = ($diagnostic) ? 'p.' $k ', p.parent_id, p.level, p.lft, p.rgt' 'p.*';
        
$query->select($select);
        
$query->from($this->_tbl ' AS n, ' $this->_tbl ' AS p');
        
$query->where('n.lft BETWEEN p.lft AND p.rgt');
        
$query->where('n.' $k ' = ' . (int) $pk);
        
$query->order('p.lft');

        
$this->_db->setQuery($query);
        
$path $this->_db->loadObjectList();

        
// Check for a database error.
        
if ($this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GET_PATH_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        return 
$path;
    }

    
/**
     * Method to get a node and all its child nodes.
     *
     * @param   integer  $pk          Primary key of the node for which to get the tree.
     * @param   boolean  $diagnostic  Only select diagnostic data for the nested sets.
     *
     * @return  mixed    Boolean false on failure or array of node objects on success.
     *
     * @link    http://docs.joomla.org/JTableNested/getTree
     * @since   11.1
     */
    
public function getTree($pk null$diagnostic false)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Get the node and children as a tree.
        
$query $this->_db->getQuery(true);
        
$select = ($diagnostic) ? 'n.' $k ', n.parent_id, n.level, n.lft, n.rgt' 'n.*';
        
$query->select($select);
        
$query->from($this->_tbl ' AS n, ' $this->_tbl ' AS p');
        
$query->where('n.lft BETWEEN p.lft AND p.rgt');
        
$query->where('p.' $k ' = ' . (int) $pk);
        
$query->order('n.lft');
        
$this->_db->setQuery($query);
        
$tree $this->_db->loadObjectList();

        
// Check for a database error.
        
if ($this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GET_TREE_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        return 
$tree;
    }

    
/**
     * Method to determine if a node is a leaf node in the tree (has no children).
     *
     * @param   integer  $pk  Primary key of the node to check.
     *
     * @return  boolean  True if a leaf node.
     *
     * @link    http://docs.joomla.org/JTableNested/isLeaf
     * @since   11.1
     */
    
public function isLeaf($pk null)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Get the node by primary key.
        
if (!$node $this->_getNode($pk))
        {
            
// Error message set in getNode method.
            
return false;
        }

        
// The node is a leaf node.
        
return (($node->rgt $node->lft) == 1);
    }

    
/**
     * Method to set the location of a node in the tree object.  This method does not
     * save the new location to the database, but will set it in the object so
     * that when the node is stored it will be stored in the new location.
     *
     * @param   integer  $referenceId  The primary key of the node to reference new location by.
     * @param   string   $position     Location type string. ['before', 'after', 'first-child', 'last-child']
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/setLocation
     * @since   11.1
     */
    
public function setLocation($referenceId$position 'after')
    {
        
// Make sure the location is valid.
        
if (($position != 'before') && ($position != 'after') && ($position != 'first-child') && ($position != 'last-child'))
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_INVALID_LOCATION'get_class($this)));
            
$this->setError($e);
            return 
false;
        }

        
// Set the location properties.
        
$this->_location $position;
        
$this->_location_id $referenceId;

        return 
true;
    }

    
/**
     * Method to move a row in the ordering sequence of a group of rows defined by an SQL WHERE clause.
     * Negative numbers move the row up in the sequence and positive numbers move it down.
     *
     * @param   integer  $delta  The direction and magnitude to move the row in the ordering sequence.
     * @param   string   $where  WHERE clause to use for limiting the selection of rows to compact the
     * ordering values.
     *
     * @return  mixed    Boolean true on success.
     *
     * @link    http://docs.joomla.org/JTable/move
     * @since   11.1
     */
    
public function move($delta$where '')
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk $this->$k;

        
$query $this->_db->getQuery(true);
        
$query->select($k);
        
$query->from($this->_tbl);
        
$query->where('parent_id = ' $this->parent_id);
        if (
$where)
        {
            
$query->where($where);
        }
        
$position 'after';
        if (
$delta 0)
        {
            
$query->where('rgt > ' $this->rgt);
            
$query->order('rgt ASC');
            
$position 'after';
        }
        else
        {
            
$query->where('lft < ' $this->lft);
            
$query->order('lft DESC');
            
$position 'before';
        }

        
$this->_db->setQuery($query);
        
$referenceId $this->_db->loadResult();

        if (
$referenceId)
        {
            return 
$this->moveByReference($referenceId$position$pk);
        }
        else
        {
            return 
false;
        }
    }

    
/**
     * Method to move a node and its children to a new location in the tree.
     *
     * @param   integer  $referenceId  The primary key of the node to reference new location by.
     * @param   string   $position     Location type string. ['before', 'after', 'first-child', 'last-child']
     * @param   integer  $pk           The primary key of the node to move.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/moveByReference
     * @since   11.1
     */

    
public function moveByReference($referenceId$position 'after'$pk null)
    {
        if (
$this->_debug)
        {
            echo 
"\nMoving ReferenceId:$referenceId, Position:$position, PK:$pk";
        }

        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Get the node by id.
        
if (!$node $this->_getNode($pk))
        {
            
// Error message set in getNode method.
            
return false;
        }

        
// Get the ids of child nodes.
        
$query $this->_db->getQuery(true);
        
$query->select($k);
        
$query->from($this->_tbl);
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);
        
$children $this->_db->loadColumn();

        
// Check for a database error.
        
if ($this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_MOVE_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }
        if (
$this->_debug)
        {
            
$this->_logtable(false);
        }

        
// Cannot move the node to be a child of itself.
        
if (in_array($referenceId$children))
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_INVALID_NODE_RECURSION'get_class($this)));
            
$this->setError($e);
            return 
false;
        }

        
// Lock the table for writing.
        
if (!$this->_lock())
        {
            return 
false;
        }

        
/*
         * Move the sub-tree out of the nested sets by negating its left and right values.
         */
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft * (-1), rgt = rgt * (-1)');
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
/*
         * Close the hole in the tree that was opened by removing the sub-tree from the nested sets.
         */
        // Compress the left values.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft - ' . (int) $node->width);
        
$query->where('lft > ' . (int) $node->rgt);
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
// Compress the right values.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('rgt = rgt - ' . (int) $node->width);
        
$query->where('rgt > ' . (int) $node->rgt);
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
// We are moving the tree relative to a reference node.
        
if ($referenceId)
        {
            
// Get the reference node by primary key.
            
if (!$reference $this->_getNode($referenceId))
            {
                
// Error message set in getNode method.
                
$this->_unlock();
                return 
false;
            }

            
// Get the reposition data for shifting the tree and re-inserting the node.
            
if (!$repositionData $this->_getTreeRepositionData($reference$node->width$position))
            {
                
// Error message set in getNode method.
                
$this->_unlock();
                return 
false;
            }
        }
        
// We are moving the tree to be the last child of the root node
        
else
        {
            
// Get the last root node as the reference node.
            
$query $this->_db->getQuery(true);
            
$query->select($this->_tbl_key ', parent_id, level, lft, rgt');
            
$query->from($this->_tbl);
            
$query->where('parent_id = 0');
            
$query->order('lft DESC');
            
$this->_db->setQuery($query01);
            
$reference $this->_db->loadObject();

            
// Check for a database error.
            
if ($this->_db->getErrorNum())
            {
                
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_MOVE_FAILED'get_class($this), $this->_db->getErrorMsg()));
                
$this->setError($e);
                
$this->_unlock();
                return 
false;
            }
            if (
$this->_debug)
            {
                
$this->_logtable(false);
            }

            
// Get the reposition data for re-inserting the node after the found root.
            
if (!$repositionData $this->_getTreeRepositionData($reference$node->width'last-child'))
            {
                
// Error message set in getNode method.
                
$this->_unlock();
                return 
false;
            }
        }

        
/*
         * Create space in the nested sets at the new location for the moved sub-tree.
         */
        // Shift left values.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft + ' . (int) $node->width);
        
$query->where($repositionData->left_where);
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
// Shift right values.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('rgt = rgt + ' . (int) $node->width);
        
$query->where($repositionData->right_where);
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
/*
         * Calculate the offset between where the node used to be in the tree and
         * where it needs to be in the tree for left ids (also works for right ids).
         */
        
$offset $repositionData->new_lft $node->lft;
        
$levelOffset $repositionData->new_level $node->level;

        
// Move the nodes back into position in the tree using the calculated offsets.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('rgt = ' . (int) $offset ' - rgt');
        
$query->set('lft = ' . (int) $offset ' - lft');
        
$query->set('level = level + ' . (int) $levelOffset);
        
$query->where('lft < 0');
        
$this->_db->setQuery($query);

        
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');

        
// Set the correct parent id for the moved node if required.
        
if ($node->parent_id != $repositionData->new_parent_id)
        {
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);

            
// Update the title and alias fields if they exist for the table.
            
if (property_exists($this'title') && $this->title !== null)
            {
                
$query->set('title = ' $this->_db->Quote($this->title));
            }
            if (
property_exists($this'alias') && $this->alias !== null)
            {
                
$query->set('alias = ' $this->_db->Quote($this->alias));
            }

            
$query->set('parent_id = ' . (int) $repositionData->new_parent_id);
            
$query->where($this->_tbl_key ' = ' . (int) $node->$k);
            
$this->_db->setQuery($query);

            
$this->_runQuery($query'JLIB_DATABASE_ERROR_MOVE_FAILED');
        }

        
// Unlock the table for writing.
        
$this->_unlock();

        
// Set the object values.
        
$this->parent_id $repositionData->new_parent_id;
        
$this->level $repositionData->new_level;
        
$this->lft $repositionData->new_lft;
        
$this->rgt $repositionData->new_rgt;

        return 
true;
    }

    
/**
     * Method to delete a node and, optionally, its child nodes from the table.
     *
     * @param   integer  $pk        The primary key of the node to delete.
     * @param   boolean  $children  True to delete child nodes, false to move them up a level.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/delete
     * @since   11.1
     */
    
public function delete($pk null$children true)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Lock the table for writing.
        
if (!$this->_lock())
        {
            
// Error message set in lock method.
            
return false;
        }

        
// If tracking assets, remove the asset first.
        
if ($this->_trackAssets)
        {
            
$name $this->_getAssetName();
            
$asset JTable::getInstance('Asset');

            
// Lock the table for writing.
            
if (!$asset->_lock())
            {
                
// Error message set in lock method.
                
return false;
            }

            if (
$asset->loadByName($name))
            {
                
// Delete the node in assets table.
                
if (!$asset->delete(null$children))
                {
                    
$this->setError($asset->getError());
                    
$asset->_unlock();
                    return 
false;
                }
                
$asset->_unlock();
            }
            else
            {
                
$this->setError($asset->getError());
                
$asset->_unlock();
                return 
false;
            }
        }

        
// Get the node by id.
        
if (!$node $this->_getNode($pk))
        {
            
// Error message set in getNode method.
            
$this->_unlock();
            return 
false;
        }

        
// Should we delete all children along with the node?
        
if ($children)
        {
            
// Delete the node and all of its children.
            
$query $this->_db->getQuery(true);
            
$query->delete();
            
$query->from($this->_tbl);
            
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Compress the left values.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('lft = lft - ' . (int) $node->width);
            
$query->where('lft > ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Compress the right values.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('rgt = rgt - ' . (int) $node->width);
            
$query->where('rgt > ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');
        }
        
// Leave the children and move them up a level.
        
else
        {
            
// Delete the node.
            
$query $this->_db->getQuery(true);
            
$query->delete();
            
$query->from($this->_tbl);
            
$query->where('lft = ' . (int) $node->lft);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Shift all node's children up a level.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('lft = lft - 1');
            
$query->set('rgt = rgt - 1');
            
$query->set('level = level - 1');
            
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Adjust all the parent values for direct children of the deleted node.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('parent_id = ' . (int) $node->parent_id);
            
$query->where('parent_id = ' . (int) $node->$k);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Shift all of the left values that are right of the node.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('lft = lft - 2');
            
$query->where('lft > ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');

            
// Shift all of the right values that are right of the node.
            
$query $this->_db->getQuery(true);
            
$query->update($this->_tbl);
            
$query->set('rgt = rgt - 2');
            
$query->where('rgt > ' . (int) $node->rgt);
            
$this->_runQuery($query'JLIB_DATABASE_ERROR_DELETE_FAILED');
        }

        
// Unlock the table for writing.
        
$this->_unlock();

        return 
true;
    }

    
/**
     * Asset that the nested set data is valid.
     *
     * @return  boolean  True if the instance is sane and able to be stored in the database.
     *
     * @link    http://docs.joomla.org/JTable/check
     * @since   11.1
     */
    
public function check()
    {
        
$this->parent_id = (int) $this->parent_id;
        if (
$this->parent_id 0)
        {
            
$query $this->_db->getQuery(true);
            
$query->select('COUNT(' $this->_tbl_key ')');
            
$query->from($this->_tbl);
            
$query->where($this->_tbl_key ' = ' $this->parent_id);
            
$this->_db->setQuery($query);

            if (
$this->_db->loadResult())
            {
                return 
true;
            }
            else
            {
                if (
$this->_db->getErrorNum())
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_CHECK_FAILED'get_class($this), $this->_db->getErrorMsg()));
                    
$this->setError($e);
                }
                else
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_INVALID_PARENT_ID'get_class($this)));
                    
$this->setError($e);
                }
            }
        }
        else
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_INVALID_PARENT_ID'get_class($this)));
            
$this->setError($e);
        }

        return 
false;
    }

    
/**
     * Method to store a node in the database table.
     *
     * @param   boolean  $updateNulls  True to update null values as well.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/store
     * @since   11.1
     */
    
public function store($updateNulls false)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;

        if (
$this->_debug)
        {
            echo 
"\n" get_class($this) . "::store\n";
            
$this->_logtable(truefalse);
        }
        
/*
         * If the primary key is empty, then we assume we are inserting a new node into the
         * tree.  From this point we would need to determine where in the tree to insert it.
         */
        
if (empty($this->$k))
        {
            
/*
             * We are inserting a node somewhere in the tree with a known reference
             * node.  We have to make room for the new node and set the left and right
             * values before we insert the row.
             */
            
if ($this->_location_id >= 0)
            {
                
// Lock the table for writing.
                
if (!$this->_lock())
                {
                    
// Error message set in lock method.
                    
return false;
                }

                
// We are inserting a node relative to the last root node.
                
if ($this->_location_id == 0)
                {
                    
// Get the last root node as the reference node.
                    
$query $this->_db->getQuery(true);
                    
$query->select($this->_tbl_key ', parent_id, level, lft, rgt');
                    
$query->from($this->_tbl);
                    
$query->where('parent_id = 0');
                    
$query->order('lft DESC');
                    
$this->_db->setQuery($query01);
                    
$reference $this->_db->loadObject();

                    
// Check for a database error.
                    
if ($this->_db->getErrorNum())
                    {
                        
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED'get_class($this), $this->_db->getErrorMsg()));
                        
$this->setError($e);
                        
$this->_unlock();
                        return 
false;
                    }
                    if (
$this->_debug)
                    {
                        
$this->_logtable(false);
                    }
                }
                
// We have a real node set as a location reference.
                
else
                {
                    
// Get the reference node by primary key.
                    
if (!$reference $this->_getNode($this->_location_id))
                    {
                        
// Error message set in getNode method.
                        
$this->_unlock();
                        return 
false;
                    }
                }

                
// Get the reposition data for shifting the tree and re-inserting the node.
                
if (!($repositionData $this->_getTreeRepositionData($reference2$this->_location)))
                {
                    
// Error message set in getNode method.
                    
$this->_unlock();
                    return 
false;
                }

                
// Create space in the tree at the new location for the new node in left ids.
                
$query $this->_db->getQuery(true);
                
$query->update($this->_tbl);
                
$query->set('lft = lft + 2');
                
$query->where($repositionData->left_where);
                
$this->_runQuery($query'JLIB_DATABASE_ERROR_STORE_FAILED');

                
// Create space in the tree at the new location for the new node in right ids.
                
$query $this->_db->getQuery(true);
                
$query->update($this->_tbl);
                
$query->set('rgt = rgt + 2');
                
$query->where($repositionData->right_where);
                
$this->_runQuery($query'JLIB_DATABASE_ERROR_STORE_FAILED');

                
// Set the object values.
                
$this->parent_id $repositionData->new_parent_id;
                
$this->level $repositionData->new_level;
                
$this->lft $repositionData->new_lft;
                
$this->rgt $repositionData->new_rgt;
            }
            else
            {
                
// Negative parent ids are invalid
                
$e = new JException(JText::_('JLIB_DATABASE_ERROR_INVALID_PARENT_ID'));
                
$this->setError($e);
                return 
false;
            }
        }
        
/*
         * If we have a given primary key then we assume we are simply updating this
         * node in the tree.  We should assess whether or not we are moving the node
         * or just updating its data fields.
         */
        
else
        {
            
// If the location has been set, move the node to its new location.
            
if ($this->_location_id 0)
            {
                if (!
$this->moveByReference($this->_location_id$this->_location$this->$k))
                {
                    
// Error message set in move method.
                    
return false;
                }
            }

            
// Lock the table for writing.
            
if (!$this->_lock())
            {
                
// Error message set in lock method.
                
return false;
            }
        }

        
// Store the row to the database.
        
if (!parent::store($updateNulls))
        {
            
$this->_unlock();
            return 
false;
        }
        if (
$this->_debug)
        {
            
$this->_logtable();
        }

        
// Unlock the table for writing.
        
$this->_unlock();

        return 
true;
    }

    
/**
     * Method to set the publishing state for a node or list of nodes in the database
     * table.  The method respects rows checked out by other users and will attempt
     * to checkin rows that it can after adjustments are made. The method will not
     * allow you to set a publishing state higher than any ancestor node and will
     * not allow you to set a publishing state on a node with a checked out child.
     *
     * @param   mixed    $pks     An optional array of primary key values to update.  If not
     *                            set the instance property value is used.
     * @param   integer  $state   The publishing state. eg. [0 = unpublished, 1 = published]
     * @param   integer  $userId  The user id of the user performing the operation.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/publish
     * @since   11.1
     */
    
public function publish($pks null$state 1$userId 0)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;

        
// Sanitize input.
        
JArrayHelper::toInteger($pks);
        
$userId = (int) $userId;
        
$state = (int) $state;
        
// If $state > 1, then we allow state changes even if an ancestor has lower state
        // (for example, can change a child state to Archived (2) if an ancestor is Published (1)
        
$compareState = ($state 1) ? $state;

        
// If there are no primary keys set check to see if the instance key is set.
        
if (empty($pks))
        {
            if (
$this->$k)
            {
                
$pks explode(','$this->$k);
            }
            
// Nothing to set publishing state on, return false.
            
else
            {
                
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED'get_class($this)));
                
$this->setError($e);
                return 
false;
            }
        }

        
// Determine if there is checkout support for the table.
        
$checkoutSupport = (property_exists($this'checked_out') || property_exists($this'checked_out_time'));

        
// Iterate over the primary keys to execute the publish action if possible.
        
foreach ($pks as $pk)
        {
            
// Get the node by primary key.
            
if (!$node $this->_getNode($pk))
            {
                
// Error message set in getNode method.
                
return false;
            }

            
// If the table has checkout support, verify no children are checked out.
            
if ($checkoutSupport)
            {
                
// Ensure that children are not checked out.
                
$query $this->_db->getQuery(true);
                
$query->select('COUNT(' $k ')');
                
$query->from($this->_tbl);
                
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
                
$query->where('(checked_out <> 0 AND checked_out <> ' . (int) $userId ')');
                
$this->_db->setQuery($query);

                
// Check for checked out children.
                
if ($this->_db->loadResult())
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_CHILD_ROWS_CHECKED_OUT'get_class($this)));
                    
$this->setError($e);
                    return 
false;
                }
            }

            
// If any parent nodes have lower published state values, we cannot continue.
            
if ($node->parent_id)
            {
                
// Get any ancestor nodes that have a lower publishing state.
                
$query $this->_db->getQuery(true)->select('n.' $k)->from($this->_db->quoteName($this->_tbl) . ' AS n')
                    ->
where('n.lft < ' . (int) $node->lft)->where('n.rgt > ' . (int) $node->rgt)->where('n.parent_id > 0')
                    ->
where('n.published < ' . (int) $compareState);

                
// Just fetch one row (one is one too many).
                
$this->_db->setQuery($query01);

                
$rows $this->_db->loadColumn();

                
// Check for a database error.
                
if ($this->_db->getErrorNum())
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_PUBLISH_FAILED'get_class($this), $this->_db->getErrorMsg()));
                    
$this->setError($e);
                    return 
false;
                }

                if (!empty(
$rows))
                {
                    
$e = new JException(JText::_('JLIB_DATABASE_ERROR_ANCESTOR_NODES_LOWER_STATE'));
                    
$this->setError($e);
                    return 
false;
                }
            }

            
// Update and cascade the publishing state.
            
$query $this->_db->getQuery(true)->update($this->_db->quoteName($this->_tbl))->set('published = ' . (int) $state)
                ->
where('(lft > ' . (int) $node->lft ' AND rgt < ' . (int) $node->rgt ')' ' OR ' $k ' = ' . (int) $pk);
            
$this->_db->setQuery($query);

            
// Check for a database error.
            
if (!$this->_db->query())
            {
                
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_PUBLISH_FAILED'get_class($this), $this->_db->getErrorMsg()));
                
$this->setError($e);
                return 
false;
            }

            
// If checkout support exists for the object, check the row in.
            
if ($checkoutSupport)
            {
                
$this->checkin($pk);
            }
        }

        
// If the JTable instance value is in the list of primary keys that were set, set the instance.
        
if (in_array($this->$k$pks))
        {
            
$this->published $state;
        }

        
$this->setError('');
        return 
true;
    }

    
/**
     * Method to move a node one position to the left in the same level.
     *
     * @param   integer  $pk  Primary key of the node to move.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/orderUp
     * @since   11.1
     */
    
public function orderUp($pk)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Lock the table for writing.
        
if (!$this->_lock())
        {
            
// Error message set in lock method.
            
return false;
        }

        
// Get the node by primary key.
        
if (!$node $this->_getNode($pk))
        {
            
// Error message set in getNode method.
            
$this->_unlock();
            return 
false;
        }

        
// Get the left sibling node.
        
if (!$sibling $this->_getNode($node->lft 1'right'))
        {
            
// Error message set in getNode method.
            
$this->_unlock();
            return 
false;
        }

        
// Get the primary keys of child nodes.
        
$query $this->_db->getQuery(true);
        
$query->select($this->_tbl_key);
        
$query->from($this->_tbl);
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);
        
$children $this->_db->loadColumn();

        
// Check for a database error.
        
if ($this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERUP_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Shift left and right values for the node and it's children.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft - ' . (int) $sibling->width);
        
$query->set('rgt = rgt - ' . (int) $sibling->width);
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERUP_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Shift left and right values for the sibling and it's children.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft + ' . (int) $node->width);
        
$query->set('rgt = rgt + ' . (int) $node->width);
        
$query->where('lft BETWEEN ' . (int) $sibling->lft ' AND ' . (int) $sibling->rgt);
        
$query->where($this->_tbl_key ' NOT IN (' implode(','$children) . ')');
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERUP_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Unlock the table for writing.
        
$this->_unlock();

        return 
true;
    }

    
/**
     * Method to move a node one position to the right in the same level.
     *
     * @param   integer  $pk  Primary key of the node to move.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/orderDown
     * @since   11.1
     */
    
public function orderDown($pk)
    {
        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Lock the table for writing.
        
if (!$this->_lock())
        {
            
// Error message set in lock method.
            
return false;
        }

        
// Get the node by primary key.
        
if (!$node $this->_getNode($pk))
        {
            
// Error message set in getNode method.
            
$this->_unlock();
            return 
false;
        }

        
// Get the right sibling node.
        
if (!$sibling $this->_getNode($node->rgt 1'left'))
        {
            
// Error message set in getNode method.
            
$query->unlock($this->_db);
            
$this->_locked false;
            return 
false;
        }

        
// Get the primary keys of child nodes.
        
$query $this->_db->getQuery(true);
        
$query->select($this->_tbl_key);
        
$query->from($this->_tbl);
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);
        
$children $this->_db->loadColumn();

        
// Check for a database error.
        
if ($this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERDOWN_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Shift left and right values for the node and it's children.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft + ' . (int) $sibling->width);
        
$query->set('rgt = rgt + ' . (int) $sibling->width);
        
$query->where('lft BETWEEN ' . (int) $node->lft ' AND ' . (int) $node->rgt);
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERDOWN_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Shift left and right values for the sibling and it's children.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = lft - ' . (int) $node->width);
        
$query->set('rgt = rgt - ' . (int) $node->width);
        
$query->where('lft BETWEEN ' . (int) $sibling->lft ' AND ' . (int) $sibling->rgt);
        
$query->where($this->_tbl_key ' NOT IN (' implode(','$children) . ')');
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_ORDERDOWN_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }

        
// Unlock the table for writing.
        
$this->_unlock();

        return 
true;
    }

    
/**
     * Gets the ID of the root item in the tree
     *
     * @return  mixed  The ID of the root row, or false and the internal error is set.
     *
     * @since   11.1
     */
    
public function getRootId()
    {
        
// Get the root item.
        
$k $this->_tbl_key;

        
// Test for a unique record with parent_id = 0
        
$query $this->_db->getQuery(true);
        
$query->select($k);
        
$query->from($this->_tbl);
        
$query->where('parent_id = 0');
        
$this->_db->setQuery($query);

        
$result $this->_db->loadColumn();

        if (
$this->_db->getErrorNum())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GETROOTID_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        if (
count($result) == 1)
        {
            
$parentId $result[0];
        }
        else
        {
            
// Test for a unique record with lft = 0
            
$query $this->_db->getQuery(true);
            
$query->select($k);
            
$query->from($this->_tbl);
            
$query->where('lft = 0');
            
$this->_db->setQuery($query);

            
$result $this->_db->loadColumn();
            if (
$this->_db->getErrorNum())
            {
                
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GETROOTID_FAILED'get_class($this), $this->_db->getErrorMsg()));
                
$this->setError($e);
                return 
false;
            }

            if (
count($result) == 1)
            {
                
$parentId $result[0];
            }
            elseif (
property_exists($this'alias'))
            {
                
// Test for a unique record alias = root
                
$query $this->_db->getQuery(true);
                
$query->select($k);
                
$query->from($this->_tbl);
                
$query->where('alias = ' $this->_db->quote('root'));
                
$this->_db->setQuery($query);

                
$result $this->_db->loadColumn();
                if (
$this->_db->getErrorNum())
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GETROOTID_FAILED'get_class($this), $this->_db->getErrorMsg()));
                    
$this->setError($e);
                    return 
false;
                }

                if (
count($result) == 1)
                {
                    
$parentId $result[0];
                }
                else
                {
                    
$e = new JException(JText::_('JLIB_DATABASE_ERROR_ROOT_NODE_NOT_FOUND'));
                    
$this->setError($e);
                    return 
false;
                }
            }
            else
            {
                
$e = new JException(JText::_('JLIB_DATABASE_ERROR_ROOT_NODE_NOT_FOUND'));
                
$this->setError($e);
                return 
false;
            }
        }

        return 
$parentId;
    }

    
/**
     * Method to recursively rebuild the whole nested set tree.
     *
     * @param   integer  $parentId  The root of the tree to rebuild.
     * @param   integer  $leftId    The left id to start with in building the tree.
     * @param   integer  $level     The level to assign to the current nodes.
     * @param   string   $path      The path to the current nodes.
     *
     * @return  integer  1 + value of root rgt on success, false on failure
     *
     * @link    http://docs.joomla.org/JTableNested/rebuild
     * @since   11.1
     */
    
public function rebuild($parentId null$leftId 0$level 0$path '')
    {
        
// If no parent is provided, try to find it.
        
if ($parentId === null)
        {
            
// Get the root item.
            
$parentId $this->getRootId();
            if (
$parentId === false)
            {
                return 
false;
            }

        }

        
// Build the structure of the recursive query.
        
if (!isset($this->_cache['rebuild.sql']))
        {
            
$query $this->_db->getQuery(true);
            
$query->select($this->_tbl_key ', alias');
            
$query->from($this->_tbl);
            
$query->where('parent_id = %d');

            
// If the table has an ordering field, use that for ordering.
            
if (property_exists($this'ordering'))
            {
                
$query->order('parent_id, ordering, lft');
            }
            else
            {
                
$query->order('parent_id, lft');
            }
            
$this->_cache['rebuild.sql'] = (string) $query;
        }

        
// Make a shortcut to database object.

        // Assemble the query to find all children of this node.
        
$this->_db->setQuery(sprintf($this->_cache['rebuild.sql'], (int) $parentId));
        
$children $this->_db->loadObjectList();

        
// The right value of this node is the left value + 1
        
$rightId $leftId 1;

        
// execute this function recursively over all children
        
foreach ($children as $node)
        {
            
// $rightId is the current right value, which is incremented on recursion return.
            // Increment the level for the children.
            // Add this item's alias to the path (but avoid a leading /)
            
$rightId $this->rebuild($node->{$this->_tbl_key}, $rightId$level 1$path . (empty($path) ? '' '/') . $node->alias);

            
// If there is an update failure, return false to break out of the recursion.
            
if ($rightId === false)
            {
                return 
false;
            }
        }

        
// We've got the left value, and now that we've processed
        // the children of this node we also know the right value.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('lft = ' . (int) $leftId);
        
$query->set('rgt = ' . (int) $rightId);
        
$query->set('level = ' . (int) $level);
        
$query->set('path = ' $this->_db->quote($path));
        
$query->where($this->_tbl_key ' = ' . (int) $parentId);
        
$this->_db->setQuery($query);

        
// If there is an update failure, return false to break out of the recursion.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_REBUILD_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        
// Return the right value of this node + 1.
        
return $rightId 1;
    }

    
/**
     * Method to rebuild the node's path field from the alias values of the
     * nodes from the current node to the root node of the tree.
     *
     * @param   integer  $pk  Primary key of the node for which to get the path.
     *
     * @return  boolean  True on success.
     *
     * @link    http://docs.joomla.org/JTableNested/rebuildPath
     * @since   11.1
     */
    
public function rebuildPath($pk null)
    {
        
// If there is no alias or path field, just return true.
        
if (!property_exists($this'alias') || !property_exists($this'path'))
        {
            return 
true;
        }

        
// Initialise variables.
        
$k $this->_tbl_key;
        
$pk = (is_null($pk)) ? $this->$k $pk;

        
// Get the aliases for the path from the node to the root node.
        
$query $this->_db->getQuery(true);
        
$query->select('p.alias');
        
$query->from($this->_tbl ' AS n, ' $this->_tbl ' AS p');
        
$query->where('n.lft BETWEEN p.lft AND p.rgt');
        
$query->where('n.' $this->_tbl_key ' = ' . (int) $pk);
        
$query->order('p.lft');
        
$this->_db->setQuery($query);

        
$segments $this->_db->loadColumn();

        
// Make sure to remove the root path if it exists in the list.
        
if ($segments[0] == 'root')
        {
            
array_shift($segments);
        }

        
// Build the path.
        
$path trim(implode('/'$segments), ' /\\');

        
// Update the path field for the node.
        
$query $this->_db->getQuery(true);
        
$query->update($this->_tbl);
        
$query->set('path = ' $this->_db->quote($path));
        
$query->where($this->_tbl_key ' = ' . (int) $pk);
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_REBUILDPATH_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        
// Update the current record's path to the new one:
        
$this->path $path;

        return 
true;
    }

    
/**
     * Method to update order of table rows
     *
     * @param   array  $idArray    id numbers of rows to be reordered.
     * @param   array  $lft_array  lft values of rows to be reordered.
     *
     * @return  integer  1 + value of root rgt on success, false on failure.
     *
     * @since   11.1
     */
    
public function saveorder($idArray null$lft_array null)
    {
        
// Validate arguments
        
if (is_array($idArray) && is_array($lft_array) && count($idArray) == count($lft_array))
        {
            for (
$i 0$count count($idArray); $i $count$i++)
            {
                
// Do an update to change the lft values in the table for each id
                
$query $this->_db->getQuery(true);
                
$query->update($this->_tbl);
                
$query->where($this->_tbl_key ' = ' . (int) $idArray[$i]);
                
$query->set('lft = ' . (int) $lft_array[$i]);
                
$this->_db->setQuery($query);

                
// Check for a database error.
                
if (!$this->_db->query())
                {
                    
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_REORDER_FAILED'get_class($this), $this->_db->getErrorMsg()));
                    
$this->setError($e);
                    
$this->_unlock();
                    return 
false;
                }

                if (
$this->_debug)
                {
                    
$this->_logtable();
                }

            }

            return 
$this->rebuild();
        }
        else
        {
            return 
false;
        }
    }

    
/**
     * Method to get nested set properties for a node in the tree.
     *
     * @param   integer  $id   Value to look up the node by.
     * @param   string   $key  Key to look up the node by.
     *
     * @return  mixed    Boolean false on failure or node object on success.
     *
     * @since   11.1
     */
    
protected function _getNode($id$key null)
    {
        
// Determine which key to get the node base on.
        
switch ($key)
        {
            case 
'parent':
                
$k 'parent_id';
                break;
            case 
'left':
                
$k 'lft';
                break;
            case 
'right':
                
$k 'rgt';
                break;
            default:
                
$k $this->_tbl_key;
                break;
        }

        
// Get the node data.
        
$query $this->_db->getQuery(true);
        
$query->select($this->_tbl_key ', parent_id, level, lft, rgt');
        
$query->from($this->_tbl);
        
$query->where($k ' = ' . (int) $id);
        
$this->_db->setQuery($query01);

        
$row $this->_db->loadObject();

        
// Check for a database error or no $row returned
        
if ((!$row) || ($this->_db->getErrorNum()))
        {
            
$e = new JException(JText::sprintf('JLIB_DATABASE_ERROR_GETNODE_FAILED'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            return 
false;
        }

        
// Do some simple calculations.
        
$row->numChildren = (int) ($row->rgt $row->lft 1) / 2;
        
$row->width = (int) $row->rgt $row->lft 1;

        return 
$row;
    }

    
/**
     * Method to get various data necessary to make room in the tree at a location
     * for a node and its children.  The returned data object includes conditions
     * for SQL WHERE clauses for updating left and right id values to make room for
     * the node as well as the new left and right ids for the node.
     *
     * @param   object   $referenceNode  A node object with at least a 'lft' and 'rgt' with
     * which to make room in the tree around for a new node.
     * @param   integer  $nodeWidth      The width of the node for which to make room in the tree.
     * @param   string   $position       The position relative to the reference node where the room
     * should be made.
     *
     * @return  mixed    Boolean false on failure or data object on success.
     *
     * @since   11.1
     */
    
protected function _getTreeRepositionData($referenceNode$nodeWidth$position 'before')
    {
        
// Make sure the reference an object with a left and right id.
        
if (!is_object($referenceNode) && isset($referenceNode->lft) && isset($referenceNode->rgt))
        {
            return 
false;
        }

        
// A valid node cannot have a width less than 2.
        
if ($nodeWidth 2)
        {
            return 
false;
        }

        
// Initialise variables.
        
$k $this->_tbl_key;
        
$data = new stdClass;

        
// Run the calculations and build the data object by reference position.
        
switch ($position)
        {
            case 
'first-child':
                
$data->left_where 'lft > ' $referenceNode->lft;
                
$data->right_where 'rgt >= ' $referenceNode->lft;

                
$data->new_lft $referenceNode->lft 1;
                
$data->new_rgt $referenceNode->lft $nodeWidth;
                
$data->new_parent_id $referenceNode->$k;
                
$data->new_level $referenceNode->level 1;
                break;

            case 
'last-child':
                
$data->left_where 'lft > ' . ($referenceNode->rgt);
                
$data->right_where 'rgt >= ' . ($referenceNode->rgt);

                
$data->new_lft $referenceNode->rgt;
                
$data->new_rgt $referenceNode->rgt $nodeWidth 1;
                
$data->new_parent_id $referenceNode->$k;
                
$data->new_level $referenceNode->level 1;
                break;

            case 
'before':
                
$data->left_where 'lft >= ' $referenceNode->lft;
                
$data->right_where 'rgt >= ' $referenceNode->lft;

                
$data->new_lft $referenceNode->lft;
                
$data->new_rgt $referenceNode->lft $nodeWidth 1;
                
$data->new_parent_id $referenceNode->parent_id;
                
$data->new_level $referenceNode->level;
                break;

            default:
            case 
'after':
                
$data->left_where 'lft > ' $referenceNode->rgt;
                
$data->right_where 'rgt > ' $referenceNode->rgt;

                
$data->new_lft $referenceNode->rgt 1;
                
$data->new_rgt $referenceNode->rgt $nodeWidth;
                
$data->new_parent_id $referenceNode->parent_id;
                
$data->new_level $referenceNode->level;
                break;
        }

        if (
$this->_debug)
        {
            echo 
"\nRepositioning Data for $position"\n-----------------------------------" "\nLeft Where:    $data->left_where"
                
"\nRight Where:   $data->right_where"\nNew Lft:       $data->new_lft"\nNew Rgt:       $data->new_rgt"
                
"\nNew Parent ID: $data->new_parent_id"\nNew Level:     $data->new_level"\n";
        }

        return 
$data;
    }

    
/**
     * Method to create a log table in the buffer optionally showing the query and/or data.
     *
     * @param   boolean  $showData   True to show data
     * @param   boolean  $showQuery  True to show query
     *
     * @return  void
     *
     * @since   11.1
     */
    
protected function _logtable($showData true$showQuery true)
    {
        
$sep "\n" str_pad(''40'-');
        
$buffer '';
        if (
$showQuery)
        {
            
$buffer .= "\n" $this->_db->getQuery() . $sep;
        }

        if (
$showData)
        {
            
$query $this->_db->getQuery(true);
            
$query->select($this->_tbl_key ', parent_id, lft, rgt, level');
            
$query->from($this->_tbl);
            
$query->order($this->_tbl_key);
            
$this->_db->setQuery($query);

            
$rows $this->_db->loadRowList();
            
$buffer .= sprintf("\n| %4s | %4s | %4s | %4s |"$this->_tbl_key'par''lft''rgt');
            
$buffer .= $sep;

            foreach (
$rows as $row)
            {
                
$buffer .= sprintf("\n| %4s | %4s | %4s | %4s |"$row[0], $row[1], $row[2], $row[3]);
            }
            
$buffer .= $sep;
        }
        echo 
$buffer;
    }

    
/**
     * Method to run an update query and check for a database error
     *
     * @param   string  $query         The query.
     * @param   string  $errorMessage  Unused.
     *
     * @return  boolean  False on exception
     *
     * @since   11.1
     */
    
protected function _runQuery($query$errorMessage)
    {
        
$this->_db->setQuery($query);

        
// Check for a database error.
        
if (!$this->_db->query())
        {
            
$e = new JException(JText::sprintf('$errorMessage'get_class($this), $this->_db->getErrorMsg()));
            
$this->setError($e);
            
$this->_unlock();
            return 
false;
        }
        if (
$this->_debug)
        {
            
$this->_logtable();
        }
    }

}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2363 seconds