Current File : /home/pacjaorg/public_html/nsa/libraries/src/Table/Usergroup.php |
<?php
/**
* Joomla! Content Management System
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\CMS\Table;
\defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Language\Text;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\Exception\ExecutionFailureException;
use Joomla\Database\ParameterType;
/**
* Usergroup table class.
*
* @since 1.7.0
*/
class Usergroup extends Table
{
/**
* Constructor
*
* @param DatabaseDriver $db Database driver object.
*
* @since 1.7.0
*/
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__usergroups', 'id', $db);
}
/**
* Method to check the current record to save
*
* @return boolean True on success
*
* @since 1.7.0
*/
public function check()
{
try
{
parent::check();
}
catch (\Exception $e)
{
$this->setError($e->getMessage());
return false;
}
// Validate the title.
if ((trim($this->title)) == '')
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_TITLE'));
return false;
}
// The parent_id can not be equal to the current id
if ($this->id === (int) $this->parent_id)
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_PARENT_ID_NOT_VALID'));
return false;
}
// Check for a duplicate parent_id, title.
// There is a unique index on the (parent_id, title) field in the table.
$db = $this->_db;
$parentId = (int) $this->parent_id;
$title = trim($this->title);
$id = (int) $this->id;
$query = $db->getQuery(true)
->select('COUNT(title)')
->from($this->_tbl)
->where($db->quoteName('title') . ' = :title')
->where($db->quoteName('parent_id') . ' = :parentid')
->where($db->quoteName('id') . ' <> :id')
->bind(':title', $title)
->bind(':parentid', $parentId, ParameterType::INTEGER)
->bind(':id', $id, ParameterType::INTEGER);
$db->setQuery($query);
if ($db->loadResult() > 0)
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_TITLE_EXISTS'));
return false;
}
// We do not allow to move non public to root and public to non-root
if (!empty($this->id))
{
$table = self::getInstance('Usergroup', 'JTable', array('dbo' => $this->getDbo()));
$table->load($this->id);
if ((!$table->parent_id && $this->parent_id) || ($table->parent_id && !$this->parent_id))
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_PARENT_ID_NOT_VALID'));
return false;
}
}
// New entry should always be greater 0
elseif (!$this->parent_id)
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_PARENT_ID_NOT_VALID'));
return false;
}
// The new parent_id has to be a valid group
if ($this->parent_id)
{
$table = self::getInstance('Usergroup', 'JTable', array('dbo' => $this->getDbo()));
$table->load($this->parent_id);
if ($table->id != $this->parent_id)
{
$this->setError(Text::_('JLIB_DATABASE_ERROR_USERGROUP_PARENT_ID_NOT_VALID'));
return false;
}
}
return true;
}
/**
* Method to recursively rebuild the nested set tree.
*
* @param integer $parentId The root of the tree to rebuild.
* @param integer $left The left id to start with in building the tree.
*
* @return boolean True on success
*
* @since 1.7.0
*/
public function rebuild($parentId = 0, $left = 0)
{
// Get the database object
$db = $this->_db;
$query = $db->getQuery(true);
$parentId = (int) $parentId;
// Get all children of this node
$query->clear()
->select($db->quoteName('id'))
->from($db->quoteName($this->_tbl))
->where($db->quoteName('parent_id') . ' = :parentid')
->bind(':parentid', $parentId, ParameterType::INTEGER)
->order([$db->quoteName('parent_id'), $db->quoteName('title')]);
$db->setQuery($query);
$children = $db->loadColumn();
// The right value of this node is the left value + 1
$right = $left + 1;
// Execute this function recursively over all children
for ($i = 0, $n = \count($children); $i < $n; $i++)
{
// $right is the current right value, which is incremented on recursion return
$right = $this->rebuild($children[$i], $right);
// If there is an update failure, return false to break out of the recursion
if ($right === false)
{
return false;
}
}
$left = (int) $left;
$right = (int) $right;
// We've got the left value, and now that we've processed
// the children of this node we also know the right value
$query->clear()
->update($db->quoteName($this->_tbl))
->set($db->quoteName('lft') . ' = :lft')
->set($db->quoteName('rgt') . ' = :rgt')
->where($db->quoteName('id') . ' = :id')
->bind(':lft', $left, ParameterType::INTEGER)
->bind(':rgt', $right, ParameterType::INTEGER)
->bind(':id', $parentId, ParameterType::INTEGER);
$db->setQuery($query);
// If there is an update failure, return false to break out of the recursion
try
{
$db->execute();
}
catch (ExecutionFailureException $e)
{
return false;
}
// Return the right value of this node + 1
return $right + 1;
}
/**
* Inserts a new row if id is zero or updates an existing row in the database table
*
* @param boolean $updateNulls If false, null object variables are not updated
*
* @return boolean True if successful, false otherwise and an internal error message is set
*
* @since 1.7.0
*/
public function store($updateNulls = false)
{
if ($result = parent::store($updateNulls))
{
// Rebuild the nested set tree.
$this->rebuild();
}
return $result;
}
/**
* Delete this object and its dependencies
*
* @param integer $oid The primary key of the user group to delete.
*
* @return mixed Boolean or Exception.
*
* @since 1.7.0
* @throws \RuntimeException on database error.
* @throws \UnexpectedValueException on data error.
*/
public function delete($oid = null)
{
if ($oid)
{
$this->load($oid);
}
if ($this->id == 0)
{
throw new \UnexpectedValueException('Usergroup not found');
}
if ($this->parent_id == 0)
{
throw new \UnexpectedValueException('Root usergroup cannot be deleted.');
}
if ($this->lft == 0 || $this->rgt == 0)
{
throw new \UnexpectedValueException('Left-Right data inconsistency. Cannot delete usergroup.');
}
$db = $this->_db;
$lft = (int) $this->lft;
$rgt = (int) $this->rgt;
// Select the usergroup ID and its children
$query = $db->getQuery(true)
->select($db->quoteName('c.id'))
->from($db->quoteName($this->_tbl, 'c'))
->where($db->quoteName('c.lft') . ' >= :lft')
->where($db->quoteName('c.rgt') . ' <= :rgt')
->bind(':lft', $lft, ParameterType::INTEGER)
->bind(':rgt', $rgt, ParameterType::INTEGER);
$db->setQuery($query);
$ids = $db->loadColumn();
if (empty($ids))
{
throw new \UnexpectedValueException('Left-Right data inconsistency. Cannot delete usergroup.');
}
// Delete the usergroup and its children
$query->clear()
->delete($db->quoteName($this->_tbl))
->whereIn($db->quoteName('id'), $ids);
$db->setQuery($query);
$db->execute();
// Rebuild the nested set tree.
$this->rebuild();
// Delete the usergroup in view levels
$replace = array();
foreach ($ids as $id)
{
$replace[] = ',' . $db->quote("[$id,") . ',' . $db->quote('[');
$replace[] = ',' . $db->quote(",$id,") . ',' . $db->quote(',');
$replace[] = ',' . $db->quote(",$id]") . ',' . $db->quote(']');
$replace[] = ',' . $db->quote("[$id]") . ',' . $db->quote('[]');
}
$query->clear()
->select(
[
$db->quoteName('id'),
$db->quoteName('rules'),
]
)
->from($db->quoteName('#__viewlevels'));
$db->setQuery($query);
$rules = $db->loadObjectList();
$matchIds = [];
foreach ($rules as $rule)
{
foreach ($ids as $id)
{
if (strstr($rule->rules, '[' . $id) || strstr($rule->rules, ',' . $id) || strstr($rule->rules, $id . ']'))
{
$matchIds[] = $rule->id;
}
}
}
if (!empty($matchIds))
{
$query->clear()
->update($db->quoteName('#__viewlevels'))
->set($db->quoteName('rules') . ' = ' . str_repeat('REPLACE(', 4 * \count($ids)) . $db->quoteName('rules') . implode(')', $replace) . ')')
->whereIn($db->quoteName('id'), $matchIds);
$db->setQuery($query);
$db->execute();
}
// Delete the user to usergroup mappings for the group(s) from the database.
$query->clear()
->delete($db->quoteName('#__user_usergroup_map'))
->whereIn($db->quoteName('group_id'), $ids);
$db->setQuery($query);
$db->execute();
return true;
}
}