Back to Nested class

Method store

public bool
store
(mixed $updateNulls = false)
Method to store a node in the database table.
Parameters
  • bool $updateNulls True to update null values as well.
Returns
  • bool True on success.
Since
  • 1.7.0
Class: Nested
Project: Joomla

Method store - Source code

/**
 * Method to store a node in the database table.
 *
 * @param   boolean  $updateNulls  True to update null values as well.
 *
 * @return  boolean  True on success.
 *
 * @since   1.7.0
 */
public function store($updateNulls = false)
{
    $k = $this->_tbl_key;
    // Pre-processing by observers
    $event = AbstractEvent::create('onTableBeforeStore', ['subject' => $this, 'updateNulls' => $updateNulls, 'k' => $k]);
    $this->getDispatcher()->dispatch('onTableBeforeStore', $event);
    if ($this->_debug) {
        echo "\n" . \get_class($this) . "::store\n";
        $this->_logtable(true, false);
    }
    /*
     * 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)->select($this->_tbl_key . ', parent_id, level, lft, rgt')->from($this->_tbl)->where('parent_id = 0')->order('lft DESC');
                $query->setLimit(1);
                $this->_db->setQuery($query);
                $reference = $this->_db->loadObject();
                if ($this->_debug) {
                    $this->_logtable(false);
                }
            } 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($reference, 2, $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)->update($this->_tbl)->set('lft = lft + 2')->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->clear()->update($this->_tbl)->set('rgt = rgt + 2')->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 \UnexpectedValueException(sprintf('%s::store() used a negative _location_id', \get_class($this)));
            $this->setError($e);
            return false;
        }
    } else {
        // If the location has been set, move the node to its new location.
        if ($this->_location_id > 0) {
            // Skip recursiveUpdatePublishedColumn method, it will be called later.
            if (!$this->moveByReference($this->_location_id, $this->_location, $this->{$k}, false)) {
                // Error message set in move method.
                return false;
            }
        }
        // Lock the table for writing.
        if (!$this->_lock()) {
            // Error message set in lock method.
            return false;
        }
    }
    // We do not want parent::store to update observers since tables are locked and we are updating it from this
    // level of store():
    $oldDispatcher = clone $this->getDispatcher();
    $blankDispatcher = new Dispatcher();
    $this->setDispatcher($blankDispatcher);
    $result = parent::store($updateNulls);
    // Restore previous callable dispatcher state:
    $this->setDispatcher($oldDispatcher);
    if ($result) {
        if ($this->_debug) {
            $this->_logtable();
        }
    }
    // Unlock the table for writing.
    $this->_unlock();
    if ($result && $this->hasField('published')) {
        $this->recursiveUpdatePublishedColumn($this->{$k});
    }
    // Post-processing by observers
    $event = AbstractEvent::create('onTableAfterStore', ['subject' => $this, 'result' => &$result]);
    $this->getDispatcher()->dispatch('onTableAfterStore', $event);
    return $result;
}