<?php
/**
* @package Joomla.Platform
* @subpackage Database
*
* @copyright Copyright (C) 2005 - 2011 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');
/**
* Usergroup table class.
*
* @package Joomla.Platform
* @subpackage Database
* @since 11.1
*/
class JTableUsergroup extends JTable
{
/**
* Constructor
*
* @param database &$db A database connector object
*
* @return JTableUsergroup
*
* @since 11.1
*/
public function __construct(&$db)
{
parent::__construct('#__usergroups', 'id', $db);
}
/**
* Method to check the current record to save
*
* @return boolean True on success
*
* @since 11.1
*/
public function check()
{
// Validate the title.
if ((trim($this->title)) == '') {
$this->setError(JText::_('JLIB_DATABASE_ERROR_USERGROUP_TITLE'));
return false;
}
// Check for a duplicate parent_id, title.
// There is a unique index on the (parend_id, title) field in the table.
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(title)')
->from($this->_tbl)
->where('title = '.$db->quote(trim($this->title)))
->where('parent_id = '.(int) $this->parent_id)
->where('id <> '.(int) $this->id);
$db->setQuery($query);
if ($db->loadResult() > 0) {
$this->setError(JText::_('JLIB_DATABASE_ERROR_USERGROUP_TITLE_EXISTS'));
return false;
}
return true;
}
/**
* Method to recursively rebuild the nested set tree.
*
* @param integer $parent_id 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 11.1
*/
public function rebuild($parent_id = 0, $left = 0)
{
// get the database object
$db = &$this->_db;
// get all children of this node
$db->setQuery(
'SELECT id FROM '. $this->_tbl .
' WHERE parent_id='. (int)$parent_id .
' ORDER BY parent_id, title'
);
$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;
}
}
// we've got the left value, and now that we've processed
// the children of this node we also know the right value
$db->setQuery(
'UPDATE '. $this->_tbl .
' SET lft='. (int)$left .', rgt='. (int)$right .
' WHERE id='. (int)$parent_id
);
// if there is an update failure, return false to break out of the recursion
if (!$db->query()) {
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 11.1
*/
function store($updateNulls = false)
{
if ($result = parent::store($updateNulls)) {
// Rebuild the nested set tree.
$this->rebuild();
}
return $result;
}
/**
* Delete this object and its dependancies
*
* @param integer $oid The primary key of the user group to delete.
*
* @return mixed Boolean or Exception.
*
* @since 11.1
*/
function delete($oid = null)
{
$k = $this->_tbl_key;
if ($oid) {
$this->load($oid);
}
if ($this->id == 0) {
return new JException(JText::_('JGLOBAL_CATEGORY_NOT_FOUND'));
}
if ($this->parent_id == 0) {
return new JException(JText::_('JLIB_DATABASE_ERROR_DELETE_ROOT_CATEGORIES'));
}
if ($this->lft == 0 or $this->rgt == 0) {
return new JException(JText::_('JLIB_DATABASE_ERROR_DELETE_CATEGORY'));
}
$db = $this->getDbo();
// Select the category ID and it's children
$db->setQuery(
'SELECT c.id' .
' FROM '.$db->quoteName($this->_tbl).' AS c' .
' WHERE c.lft >= '.(int) $this->lft.' AND c.rgt <= '.$this->rgt
);
$ids = $db->loadColumn();
if (empty($ids)) {
return new JException(JText::_('JLIB_DATABASE_ERROR_DELETE_CATEGORY'));
}
// Delete the category dependencies
// @todo Remove all related threads, posts and subscriptions
// Delete the category and its children
$db->setQuery(
'DELETE FROM '.$db->quoteName($this->_tbl).
' WHERE id IN ('.implode(',', $ids).')'
);
if (!$db->query()) {
$this->setError($db->getErrorMsg());
return false;
}
// 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 = $db->getQuery(true);
$query->set('rules='.str_repeat('replace(',4*count($ids)).'rules'.implode('',$replace));
$query->update('#__viewlevels');
$query->where('rules REGEXP "(,|\\\\[)('.implode('|', $ids).')(,|\\\\])"');
$db->setQuery($query);
if (!$db->query()) {
$this->setError($db->getErrorMsg());
return false;
}
// Delete the user to usergroup mappings for the group(s) from the database.
$db->setQuery(
'DELETE FROM `#__user_usergroup_map`' .
' WHERE `group_id` IN ('.implode(',', $ids).')'
);
$db->query();
// Check for a database error.
if ($db->getErrorNum()) {
$this->setError($db->getErrorMsg());
return false;
}
return true;
}
}