<?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 ACL
 */

include_once('config.inc.php');
include_once('classes/core/DBAccessorObject.class.php');
include_once('classes/core/DBManipulator.class.php');
include_once('classes/core/ACL/ACL.class.php');

/**
 * Manage the instances of ACL objects.
 *
 * @access     public
 * @author	   Cedric Francoys <cedric.francoys@easy-cms.org>
 * @version	   ACLManager.class, Sat Feb 12 16:09:53 CET 2005
 * @package	   Core
 * @subpackage ACL
 */
class ACLManager extends DBAccessorObject {
	/**
	 * Array of ACL objects
	 *
	 * @access private
	 * @var    array
	 */
  var $ACLTable;

	/**#@+
	 * @access public
	 */
	/**
	 * Class Constructor
	 *
	 * @param object instance of DBManipulator<i>Driver</i>
	 */
  function ACLManager(&$dbManipulator) {
		parent::DBAccessorObject($dbManipulator);
		$this->ACLTable = array();
  }


	/**
	 * Loads ACL
	 *
	 * @param  mixed $id integer or indexed array
	 * @return boolean
	 */
	function loadACL($id, $loadList=true) {
		$db = &$this->getDBManipulator();

		$aclList = (array)$id;

		foreach ($aclList as $aclId) {
      $deleted = 0;
  		if (!($res = $db->getRecord(ACL_TABLE, $aclId))) {
        // error
      }
      else {
	   		if (!($row = $db->fetchArray($res))) {
          // error
	   		}
	   		else {
          $deleted = $row['deleted'];
	   		}
      }
			$this->ACLTable[$aclId] = &new ACL($aclId, $deleted);
		}

		$csv  = implode(',', $aclList);
		$cond = '`acl_id` in ('.$csv.')';

		if ($res = $db->getRecord(ACL_GROUPS_TABLE, -1, $cond)) {
			while ($record = $db->fetchArray($res)) {
				$aclId = (int)$record['acl_id'];
				$this->ACLTable[$aclId]->addGroupEntry($record);
			}
		}
		else {
			$this->debug('ACLManager::loadACL, error : unable to load groups for ACL(id='.$csv.')', 3);
			return false;
		}

		if ($res = $db->getRecord(ACL_USERS_TABLE, -1, $cond)) {
			while ($record = $db->fetchArray($res)) {
				$aclId = (int)$record['acl_id'];
				$this->ACLTable[$aclId]->addUserEntry($record);
			}
		}
		else {
			$this->debug('ACLManager::loadACL, error : unable to load users for ACL(id='.$csv.')', 3);
			return false;
		}

		$this->debug('ACLManager::loadACL, success : ACL(id='.$csv.') loaded', 9);

		return true;
	}

	/**
	 * ACL Exists
	 *
	 * Checks if ACL is defined into manager
	 *
	 * @param  integer $aclId ACL Id
	 * @return boolean
	 */
	function ACLExists($aclId) {
		return isset($this->ACLTable[$aclId]);
	}

	/**
	 * Deletes ACL
	 *
	 * Remove ACL from database and manager
	 *
	 * @author vinadelmar <vinadelmar@users.sourceforge.net>
	 * @param  integer $aclId
	 * @return boolean
	 */
	function deleteACL($aclId) {
		if (!$this->ACLExists($aclId)) {
			return false;
		}
    $acl = &$this->getACL($aclId);
    $acl->setAclDeleted(1);
    $this->storeACL($aclId);
    /**
     * code need verifications : setting deleted bit of ACL to 1 instead of removing the associated records
     *
		if (!$db->delRecord(ACL_TABLE, $aclId) || !$db->getAffectedRows()) {
			$this->debug('ACLManager::deleteACL, error : unable to delete ACL(id='.$aclId.')', 3);
			return false;
		}

		$res = $db->delRecord(ACL_GROUPS_TABLE, $aclId, '', 'acl_id');

		if ($res && $db->getAffectedRows()) {
			$this->debug('ACLManager::deleteACL, success : users deleted from ACL(id='.$aclId.')', 9);
		}

		$res = $db->delRecord(ACL_USERS_TABLE, $aclId, '', 'acl_id');

		if ($res && $db->getAffectedRows()) {
			$this->debug('ACLManager::deleteACL, success : groups deleted from ACL(id='.$aclId.')', 9);
		}
    */
		return true;
	}

	/**
	 * Parent gives its ACL to its Children
	 *
	 * @param  integer $aclId
	 * @return integer acl id or 0
	 * @deprecated
	 */
	function restoreInheritance($aclId) {
		$child = &$this->getACL($aclId);

		if (is_null($child)) {
			return 0;
		}

		$childParentId = $child->getAclParentId();

		if (!$childParentId) {
			return 0;
		}

		$parent = &$this->getACL($childParentId);

		if (is_null($parent)) {
			return 0;
		}

		return $parent->getAclId();
	}

	/**
	 * Stores ACL
	 *
	 * @param  integer $aclId
	 * @return integer
	 */
	function storeACL($aclId) {
		$this->debug('ACLManager::storeACL, status : method invoked', 10);

    $acl = &$this->getACL($aclId);
    
		$fieldsArray = array();
		
		// new acl
		if ($aclId == 0) {
			$res = $this->dbManipulator->addRecord(ACL_TABLE, $fieldsArray);

			if (!$res || !$this->dbManipulator->getAffectedRows()) {
				return 0;
			}

			$aclId = $this->dbManipulator->getLastId();

			$acl = &$this->getACL(0);
			$acl->setAclId($aclId);
			$this->setACL($acl);
		}
		else {
  		if(($acl = &$this->getACL($aclId))) {
        $fieldsArray['deleted'] = $acl->getAclDeleted();
  			if (!$this->dbManipulator->setRecord(ACL_TABLE, $aclId, $fieldsArray)) {
  				$this->debug('ACLManager::storeACL, error : unable to update ACL ('.$aclId.')', 1);
  			}
  		}

			$acl = &$this->ACLTable[$aclId];
			// remove old entries in DB
			if(($result = $this->dbManipulator->delRecord(ACL_USERS_TABLE, $aclId, '', 'acl_id')) === false) {
				return 0;
			}
			if(($result = $this->dbManipulator->delRecord(ACL_GROUPS_TABLE, $aclId, '', 'acl_id')) === false) {
				return 0;
			}
		}

		// (re)insert entries in DB
		foreach ($acl->getGroupsAclEntryTable() as $groupId => $aclEntry) {
			if (!$aclEntry->isEmpty()) {
				$fieldsArray = $aclEntry->getValues();
				$fieldsArray['acl_id'] = $aclId;
				$fieldsArray['group_id'] = $groupId;

				if(($res = $this->dbManipulator->addRecord(ACL_GROUPS_TABLE, $fieldsArray)) === false) {
					return 0;
				}
			}
		}

		foreach ($acl->getUsersAclEntryTable() as $userId => $entry) {
			if (!$entry->isEmpty()) {
				$fieldsArray = $entry->getValues();
				$fieldsArray['acl_id'] = $aclId;
				$fieldsArray['user_id'] = $userId;

				if(($result = $this->dbManipulator->addRecord(ACL_USERS_TABLE, $fieldsArray)) === false) {
					return 0;
				}
			}
		}

		return $aclId;
	}


	/**
	 * Removes ACL
	 *
	 * Removes ACL from manager
	 *
	 * @param  integer $id ACL Id
	 * @return boolean
	 */
  function removeACL($id) {
    $result = true;
		if (!$this->ACLExists($id)) {
			$this->debug('ACLManager::removeACL, error : unknown ACL ('.$id.')', 3);
			$result = false;
		}
		unset($this->ACLTable[$id]);
		return $result;
  }

	/**
	 * Gets ACL
	 *
	 * Checks if ACL is not already defined into manager, if not try to load it
	 *
 	 * @param  integer $id ACL Id
 	 * @param  boolean $loadList Loads ACLEntry objects too
 	 * @return object null if error
	 */
  function &getACL($aclId, $loadList=true, $reload=false) {
		if ($reload || !$this->ACLExists($aclId)) {
			if (!$this->loadACL($aclId, $loadList)) {
				$this->debug('ACLManager::getACL, error : unable to get ACL #'.$aclId, 3);
				return null;
			}
		}
		$this->debug('ACLManager::getACL, success : got ACL #'.$aclId, 9);
		return $this->ACLTable[$aclId];
  }

	/**
	 * Saves ACL
	 *
	 * Saves ACL into manager
	 *
	 * @param  object $acl ACL
	 * @return boolean
	 */
  function setACL(&$acl, $force=false) {
		$aclId = $acl->getAclId();
		if (!$this->ACLExists($aclId) || $force) {
			$this->ACLTable[$aclId] = &$acl;
		}
		return true;
	}

	function &getNewACL() {
		$this->ACLTable[0] = &new ACL();
		return $this->ACLTable[0];
	}

	function loadCSV()
	{
	}
}
?>