<?php
/*
 * This file is part of the easy-CMS project.
 * easy-CMS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * easy-CMS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with easy-CMS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

/**
 * @package    Core
 * @subpackage Groups
 */
 
/**
 */
include_once('classes/core/CoreObject.class.php');
include_once('classes/core/DBAccessorObject.class.php');
include_once('classes/core/groups/Group.class.php');

/**
 * Groups Manager Class
 *
 * Manages instances of Group objects
 *
 * @author     vinadelmar <vinadelmar@users.sourceforge.net>
 * @since      2006-02-15
 * @version    0.4.2
 * @package    Core
 * @subpackage Groups
 */
class GroupsManager extends DBAccessorObject {
	/**
	 * Group Objects Array
	 *
	 * @access private
	 * @var    array
	 */
	var $groupsTable;
	
	/**#@+
	 * @access public
	 */
	/**
	 * Constructor
	 *
	 * @param object
	 */
	function GroupsManager(&$dbManipulator) {
		parent::DBAccessorObject($dbManipulator);
		$this->groupsTable = array();
	}
	
	/**
	 * Gets Groups Table
	 *
	 * Returns array of Group objects defined in manager
	 *
	 * @return array
	 */
	function &getGroupsTable() {
		return $this->groupsTable;
	}
	
	/**
	 * Checks Group
	 *
	 * Checks if group is defined in {@link $groupsTable}
	 *
	 * @param  integer $groupId
	 * @return boolean
	 */
	function groupExists($groupId) {
		return isset($this->groupsTable[$groupId]);
	}
	
	/**
	 * Loads Group	 
	 *
	 * @access private
	 * @param  integer $groupId
	 * @param  boolean $loadUsersMembershipList
	 * @return boolean
	 */
	function loadGroup($groupId, $loadUsersMembershipList=false) {
		$groupsIdList = (array)$groupId;
		$db = &$this->getDBManipulator();
		$cond = '`id` in ('.implode(',', $groupsIdList).')';
		$res = $db->getRecord(GROUPS_TABLE, -1, $cond);
		if (!$res || !$db->getNumRows()) {
			return false;
		}
		while ($row = $db->fetchArray($res)) {
			$id          = $row['id'];
			$name        = $row['name'];
			$description = $row['description'];
			$disabled    = $row['disabled'];
			$group = &new Group($id, $name, $description, $disabled);
			$this->addGroup($group);
		}
		if ($loadUsersMembershipList) {
			$this->loadUsersMembershipList($groupsIdList);
		}
		return true;
	}
	
	/**
	 * Loads Users Membership List
	 *
	 * @param  mixed $groupId integer|array
	 * @return boolean
	 */
	function loadUsersMembershipList($groupId) {
		$groupsIdList = array();
		foreach((array) $groupId as $id) {
			if ($this->groupExists($id)) {
				$groupsIdList[] = $id;
			}
		}
		if (count($groupsIdList) < 1) {
			return false;
		}
		$db = &$this->getDBManipulator();
		$cond = '`group_id` in ('.implode(',', $groupsIdList).')';
		$res = $db->getRecord(GROUP_USERS_TABLE, -1, $cond);
		if (!$res || !$db->getNumRows()) {
			return false;
		}
		while ($row = $db->fetchArray($res)) {
			$groupId = (int)$row['group_id'];
			$userId = (int)$row['user_id'];
			$this->groupsTable[$groupId]->addUserMembership($userId);
		}
		return true;
	}
	
	/**
	 * Gets Groups List
	 *
	 * Returns direct access array GroupId => GroupName
	 *
	 * @return array null if error
	 */
	function getGroupsListForDisplay() {
		$dbManipulator = &$this->getDBManipulator();
		$groupsArray = array();
		
		$result = $dbManipulator->getRecord(GROUPS_TABLE, 0, '', 'id', '`name`');
		
		if (!$result) {
			return null;
		}
		
		while ($row = $dbManipulator->fetchArray($result)) {
			$groupId = (int)$row['id'];
			$groupName = $row['name'];
			$groupsArray[$groupId] = $groupName;
		}
		
		return $groupsArray;
	}
	
	function getGroupsIdList() {
		$dbManipulator = &$this->getDBManipulator();
		$groupsArray = array();

		$result = $dbManipulator->getRecord(GROUPS_TABLE, 0, '', 'id', '`name`');

		if (!$result) {
			return null;
		}

		while ($row = $dbManipulator->fetchArray($result)) {
			$groupsArray[] = (int)$row['id'];
		}

		return $groupsArray;
	}

	/**
	 * Gets Group
	 *
	 * Returns group matching given group id in {@link groupsList}
	 *
	 * @param  integer $groupId
	 * @return mixed group object or false if error
	 */
	function &getGroup($groupId, $loadUsersMembershipList=false) {
		if (!$this->groupExists($groupId)) {
			if (!$this->loadGroup($groupId, $loadUsersMembershipList)) {
				$this->debug('GroupsManager::getGroup(), error : unable to get group #'.$groupId, 3);
				return null;
			}
		}
		//$this->debug('GroupsManager::getGroup(), success : got group #'.$groupId, 9);
		return $this->groupsTable[$groupId];
	}
	
	/**
	 * Adds Group Into Manager
	 *
	 * @param object $group
	 */
	function addGroup(&$group) {
		$id = $group->getGroupId();
		$this->groupsTable[$id] = &$group;
	}
	
	/**
	 * Sets Group Into Manager
	 *
	 * @param  object $group
	 * @return boolean
	 */
	function setGroup(&$group) {
		$groupId = $group->getGroupId();
		$this->groupsTable[$groupId] = &$group;
	}

	/**
	 * Gets New Group
	 *
	 * Creates new group into manager
	 *
	 * @return object
	 */
	function &getNewGroup() {
		$group = &new Group();
		$this->addGroup($group);
		return $group;
	}
	

	/**
	 * Remove Group
	 *
	 * Remove a group from the DB
	 *
	 * @param  integer $id Group Id
	 * @return boolean
	 */
	function removeGroup($id) {
		if (!($group = &$this->getGroup($id))) {
			$this->debug("GroupsManager.removeGroup, error : trying to remove unexisting group '$id'.", 3);
			return false;
		}
    $db = &$this->getDBManipulator();
    if(!($db->delRecord(GROUPS_TABLE, $id))) {
			$this->debug("GroupsManager.removeGroup, error : unable to query user removal for group '$id'.", 3);
			return false;
    }

		return true;
	}

	/**
	 * Stores Group
	 *
	 * Updates or adds Group into table
	 *
	 * @param  integer $groupId Group Id
	 * @return integer Group Id or 0 if error
	 */
	function storeGroup($groupId) {
		if (!($group = &$this->getGroup($groupId))) {
			return 0;
		}
		$record = array();
		$record['name'] = $group->getGroupName();
		$record['description'] = $group->getGroupDescription();
		$record['disabled'] = $group->getGroupDisabled();

		$db = &$this->getDBManipulator();
		if ($groupId == 0) {
			$res = $db->addRecord(GROUPS_TABLE, $record);
			if (!$res || !$db->getAffectedRows()) {
				return 0;
			}
			$groupId = $db->getLastId();
			$group->setGroupId($groupId);
		}
    else {
			if (!$db->setRecord(GROUPS_TABLE, $groupId, $record)) {
				return 0;
			}
		}

		$usersIdList = array();
		$currUsersIdList = array();
		foreach($group->getUsersMembershipList() as $userId => $membership) {
			if($membership) {
				$usersIdList[] = $userId;
			}
		}

		if ($res = $db->getRecord(GROUP_USERS_TABLE, $groupId, '', 'group_id')) {
			while ($row = $db->fetchArray($res)) {
				$currUsersIdList[] = $row['user_id'];
			}
			$addList = array_diff($usersIdList, $currUsersIdList);
			$removeList = array_diff($currUsersIdList, $usersIdList);
			foreach ($addList as $userId) {
				$record = array();
				$record['group_id'] = $groupId;
				$record['user_id']  = $userId;
				$db->addRecord(GROUP_USERS_TABLE, $record);
			}

			foreach ($removeList as $userId) {
				$db->delRecord(GROUP_USERS_TABLE, $userId, '`group_id`='.$groupId, 'user_id');
			}
		}

		return $groupId;
	}
}
?>