Back to Nested class

Method delete

public bool
delete
(mixed $pk = null, mixed $children = true)
Method to delete a node and, optionally, its child nodes from the table.
Parameters
  • int $pk The primary key of the node to delete.
  • bool $children True to delete child nodes, false to move them up a level.
Returns
  • bool True on success.
Since
  • 1.7.0
Class: Nested
Project: Joomla

Method delete - Source code

/**
 * 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.
 *
 * @since   1.7.0
 */
public function delete($pk = null, $children = true)
{
    $k = $this->_tbl_key;
    $pk = \is_null($pk) ? $this->{$k} : $pk;
    // Pre-processing by observers
    $event = new Event('onBeforeDelete', ['pk' => $pk]);
    $this->getDispatcher()->dispatch('onBeforeDelete', $event);
    // If tracking assets, remove the asset first.
    if ($this->_trackAssets) {
        $name = $this->_getAssetName();
        /** @var Asset $asset */
        $asset = Table::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo()));
        if ($asset->loadByName($name)) {
            // Delete the node in assets table.
            if (!$asset->delete(null, $children)) {
                $this->setError($asset->getError());
                return false;
            }
        } else {
            $this->setError($asset->getError());
            return false;
        }
    }
    // Lock the table for writing.
    if (!$this->_lock()) {
        // Error message set in lock method.
        return false;
    }
    // Get the node by id.
    $node = $this->_getNode($pk);
    if (empty($node)) {
        // Error message set in getNode method.
        $this->_unlock();
        return false;
    }
    $query = $this->_db->getQuery(true);
    // Should we delete all children along with the node?
    if ($children) {
        // Delete the node and all of its children.
        $query->clear()->delete($this->_tbl)->where('lft BETWEEN ' . (int) $node->lft . ' AND ' . (int) $node->rgt);
        $this->_runQuery($query, 'JLIB_DATABASE_ERROR_DELETE_FAILED');
        // Compress the left values.
        $query->clear()->update($this->_tbl)->set('lft = lft - ' . (int) $node->width)->where('lft > ' . (int) $node->rgt);
        $this->_runQuery($query, 'JLIB_DATABASE_ERROR_DELETE_FAILED');
        // Compress the right values.
        $query->clear()->update($this->_tbl)->set('rgt = rgt - ' . (int) $node->width)->where('rgt > ' . (int) $node->rgt);
        $this->_runQuery($query, 'JLIB_DATABASE_ERROR_DELETE_FAILED');
    } else {
        // Delete the node.
        $query->clear()->delete($this->_tbl)->where('lft = ' . (int) $node->lft);
        $this->_runQuery($query, 'JLIB_DATABASE_ERROR_DELETE_FAILED');
        // Shift all node's children up a level.
        $query->clear()->update($this->_tbl)->set('lft = lft - 1')->set('rgt = rgt - 1')->set('level = level - 1')->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->clear()->update($this->_tbl)->set('parent_id = ' . (int) $node->parent_id)->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->clear()->update($this->_tbl)->set('lft = lft - 2')->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->clear()->update($this->_tbl)->set('rgt = rgt - 2')->where('rgt > ' . (int) $node->rgt);
        $this->_runQuery($query, 'JLIB_DATABASE_ERROR_DELETE_FAILED');
    }
    // Unlock the table for writing.
    $this->_unlock();
    // Post-processing by observers
    $event = new Event('onAfterDelete', ['pk' => $pk]);
    $this->getDispatcher()->dispatch('onAfterDelete', $event);
    return true;
}