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

include_once('classes/core/DBAccessorObject.class.php');
include_once('classes/core/DBManipulator.class.php');
include_once('classes/core/containers/Container.class.php');
include_once('classes/core/contents/ContentsManager.class.php');
include_once('classes/core/contents/Content.class.php');

/**
 * Manage the instances of Container objects.
 *
 * @access     public
 * @author	   Cedric Francoys <cedric.francoys@easy-cms.org>
 * @version	   ContainersManager.class, Sat Nov 13 11:39:53 CET 2004
 * @package	   Core
 * @subpackage Containers
 */
class ContainersManager extends DBAccessorObject {
	/**
	 * @var object
	 */
	var $typesManager;

	/**
	 * @var object
	 */
	var $templatesManager;

	/**
	 * @var object
	 */
  var $aclManager;

	/**
	 * @var object
	 */
	var $contentsManager;

	/**
	 * Array of Container objects
	 *
	 * @var array
	 */
	var $containersTable;

	/**
	 * Class constructor
	 *
	 * @param object  $dbManipulator
	 * @param object  $aclManager
	 * @param object  $typesManager
	 * @param object  $contentsManager
	 * @param object  $templatesManager
	 */
	function ContainersManager(&$dbManipulator, &$aclManager, &$typesManager, &$contentsManager, &$templatesManager){
    $this->debug('ContainersManager::ContainersManager, status : function invoked', 10, DBG_OPEN);
		parent::DBAccessorObject($dbManipulator);
		$this->aclManager       = &$aclManager;
		$this->typesManager     = &$typesManager;
		$this->contentsManager  = &$contentsManager;
		$this->templatesManager = &$templatesManager;
		$this->containersTable  = array();
    $this->debug('ContainersManager::ContainersManager, status : function completed', 10, DBG_CLOSE);
	}

	/**
	 * Return instance of types manager object
	 *
	 * @return object
	 */
	function &getTypesManager() {
		return $this->typesManager;
	}

	/**
	 * Return instance of acl manager object
	 *
	 * @return object
	 */
	function &getAclManager() {
		return $this->aclManager;
	}

	/**
	 * Loads Container
	 *
	 * @param  mixed   $id container id
	 * @param  boolean $loadContent
	 * @param  boolean $loadDeleted
	 * @param  integer $langId
	 * @param  boolean $loadAcl
	 * @param  boolean $loadTemplate
	 * @return boolean
	 */
	function loadContainer($containerId, $loadContent=true, $loadDeleted=false, $langId=LOAD_ALL_LANGUAGES,	$loadAcl=true, $loadTemplate=true, $loadTranslation=true){
    $this->debug('ContainersManager::loadContainer, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$cond = '`id` in ('.implode(',', (array)$containerId).')';
		$loaded = false;
		if(($res = $db->getRecord(CONTAINERS_TABLE, -1, $cond)) === false) {
      $this->debug('ContainersManager::loadContainer, warning : unable to get container ('.$containerId.')', 3);
		}
		else {
			while($fields = $db->fetchArray($res)) {
				$id          = $fields['id'];
				$nameId      = $fields['name_id'];
				$typeName    = $fields['type_name'];
				$templateId  = $fields['template_id'];
				$sortingType = $fields['sorting_type'];
				$sortField   = $fields['sort_field'];
				$sortOrder   = $fields['sort_order'];
				$shownFrom   = $fields['shown_from'];
				$countShown  = $fields['count_shown'];
				$cloneId     = $fields['clone_id'];
				$deleted     = $fields['deleted'];
				$published   = $fields['published'];
				$aclId       = $fields['acl_id'];
				
				$type        = $fields['type'];
				$repository  = $fields['repository'];
				
				if((!$loadDeleted && !$deleted) || $loadDeleted){
					$this->containersTable[$id] = &new Container($id, $nameId, $typeName, $templateId, $sortingType, $sortField, $sortOrder, $shownFrom, $countShown, $cloneId, $deleted, $aclId);
					$this->containersTable[$id]->setContainerPublished($published);
					$this->containersTable[$id]->setContainerType($type);
					$this->containersTable[$id]->setContainerRepository($repository);
					if($loadContent) {
						$this->loadContainerContents($id);
					}
					if($loadTemplate) {
						$this->loadContainerTemplate($id);
					}
					if($loadAcl) {
						$this->loadContainerAcl($id);
					}
					if($loadTranslation) {
						$this->loadContainerTranslation($id);
					}
				}
				$loaded = true;
			}
		}
    $this->debug('ContainersManager::loadContainer, status : function completed', 10, DBG_CLOSE);
		return $loaded;
 	}

	/**
	 * Loads Container's Contents
	 *
	 * @param  integer $containerId Container Id
	 * @return boolean
	 */
	function loadContainerContents($containerId){
    $this->debug('ContainersManager::loadContainerContents, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$loaded = false;
    if(!$containerId) {
      return false;
    }
		if($container = &$this->getContainer($containerId)){
			$typeName = $container->getContainerTypeName();
			$cloneId = $container->getContainerCloneId();
			$loadId = $containerId;
			if($cloneId > 0) {
				$loadId = $cloneId;
			}
			/* check container type */
			$repositoryArray = array();
			$containerRepository = $container->getContainerRepository();
			switch($container->getContainerType()) {
        case CONTAINER_TYPE_PHOTO_GALLERY :
          if(strlen($containerRepository)) {
            $repositoryPath = $containerRepository;
            if(is_dir($repositoryPath)) {
							$dirHandler = opendir($repositoryPath);
	        	  while ($fileName = readdir($dirHandler)) {
	              if ($fileName != '.' && $fileName != '..' && !is_dir($repositoryPath.'/'.$fileName)) {
	                // store items in a temporary array
									$repositoryArray[] = $containerRepository."/".$fileName;
	              }
	            }
            }
          }
          break;
      }

			if(($res = $db->getRecord(CONTAINER_CONTENTS_TABLE, $loadId, '', 'container_id')) === false) {
        trigger_error('ContainersManager::loadContainerContents, error : error while retrieving contents list for container ('.$loadId.')', E_USER_ERROR);
			}
			else {
				$contentsIdList = array();
				while($fields = $db->fetchArray($res)){
          $index = $fields['index'];
					$contentsIdList[$index] = $fields['content_id'];
				}
        ksort($contentsIdList);
				if($this->contentsManager->loadContent($contentsIdList, $typeName)){
					foreach($contentsIdList as $contentId){
						if($content = &$this->contentsManager->getContent($contentId, $typeName)) {
							$loaded = true;
							switch($container->getContainerType()) {
      					case CONTAINER_TYPE_PHOTO_GALLERY :
      					  $imageObj = &$content->getContentFieldValue(1, 'image');
      					  if(($key = array_search($imageObj->getValue(), $repositoryArray)) !== false) {
      					    unset($repositoryArray[$key]);
      					  }
      					  if(strpos($imageObj->getValue(), $containerRepository) === false || !is_file($imageObj->getValue())) {
										// image does not belong to the current container repository or associated file has been deleted
      					  	unset($content);
      					  	continue;
      					  }
      					  break;
							}
							$container->addContent($content);
							unset($content);
						}
					}
				}
				
				// create new contents if needed
				$containerAclId = $container->getContainerAclId();
				$newContentsArray = array();
				
				switch($container->getContainerType()) {
	        case CONTAINER_TYPE_PHOTO_GALLERY :
	          foreach($repositoryArray as $itemPath) {
	            $loaded = true;
							$newContent = &$this->contentsManager->getNewContent('gallery_photo', $containerAclId);
	            $imageObj 	= &new Image($itemPath);
	            $titleObj 	= &new String('');
	            $commentObj = &new Text('');
	            $dateObj 		= &new Date(date('y-m-d'));
	            $langArray = $this->getLangsArray();
	            $valuesTable = array();
	            foreach($langArray as $langId=>$langName) {
	            	$newContent->setContentFieldValue($langId, 'image', $imageObj);
	            	$newContent->setContentFieldValue($langId, 'title', $titleObj);
	            	$newContent->setContentFieldValue($langId, 'comment', $commentObj);
	            	$newContent->setContentFieldValue($langId, 'date', $dateObj);
	            }
	            $newId = $this->contentsManager->storeContent(0, 'gallery_photo');
	            $newContent = &$this->contentsManager->getContent($newId, 'gallery_photo');
	      			$container->addContent($newContent);
	      			unset($newContent);
	          }
	          if(count($repositoryArray)) {
	            $this->storeContainer($containerId);
	          }
				    break;
      	}
			}
		}
    $this->debug('ContainersManager::loadContainerContents, status : function completed', 10, DBG_CLOSE);
		return $loaded;
	}

	/**
	 * Loads Container's Template
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
	function loadContainerTemplate($containerId){
    $this->debug('ContainersManager::loadContainerTemplate, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$loaded = false;
		if($container = &$this->getContainer($containerId)){
			$templateId = $container->getContainerTemplateId();
			if($template = &$this->templatesManager->getTemplate($templateId)){
				$container->setContainerTemplate($template);
				$loaded = true;
			}
		}
    $this->debug('ContainersManager::loadContainerTemplate, status : function completed', 10, DBG_CLOSE);
		return $loaded;
	}

	/**
	 * Loads Container's ACL
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
	function loadContainerAcl($containerId) {
    $this->debug('ContainersManager::loadContainerAcl, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$loaded = false;
		if($container = &$this->getContainer($containerId)){
			$aclId = $container->getContainerAclId();
			if($acl = &$this->aclManager->getACL($aclId)){
				$container->setContainerAcl($acl);
				$loaded = true;
			}
		}
    $this->debug('ContainersManager::loadContainerAcl, status : function completed', 10, DBG_CLOSE);
		return $loaded;
	}

	/**
	 * Loads Container Translation
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
	function loadContainerTranslation($containerId){
    $this->debug('ContainersManager::loadContainerTranslation, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$loaded = false;
		if($container = &$this->getContainer($containerId)){
			if($res = $db->getRecord(NAMES_TABLE, $container->getContainerNameId())){
				while($fields = $db->fetchArray($res)){
					$langId = (int)$fields['lang_id'];
					$label = $fields['value'];
					$container->setContainerName($label, $langId);
					$loaded = true;
				}
			}
		}
    $this->debug('ContainersManager::loadContainerTranslation, status : function completed', 10, DBG_CLOSE);
		return $loaded;
	}

	/**
	 * Stores container and its contents list
	 *
	 * @param  integer $containerId
	 * @param  boolean $formerCloneBool Tells if container formerly was a clone
	 * @return integer Container ID or <0 if error
	 */
  function storeContainer($containerId, $formerCloneBool=false) {
    $this->debug('ContainersManager::storeContainer, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$this->storeLanguageDependencies($containerId);

		if (is_null($container = &$this->getContainer($containerId))) {
      trigger_error('ContainersManager::storeContainer, error : unable to get container ('.$containerId.')', E_USER_ERROR);
			$containerId = -1;
		}
    else {
  		$fieldsArray = array(
  			 'sorting_type' => $container->getContainerSortingType()
  			,'sort_field'   => $container->getContainerSortField()
  			,'sort_order'   => $container->getContainerSortOrder()
  			,'count_shown'  => $container->getContainerCountShown()
  			,'shown_from'   => $container->getContainerShownFrom()
  			,'template_id'  => $container->getContainerTemplateId()
  			,'clone_id'     => $container->getContainerCloneId()
  			,'name_id'      => $container->getContainerNameId()
  			,'type_name'    => $container->getContainerTypeName()
  			,'deleted'      => $container->getContainerDeleted()
  			,'published'    => $container->getContainerPublished()
  			,'type'				  => $container->getContainerType()
  			,'repository'   => $container->getContainerRepository()
		    ,'acl_id'       => $container->getContainerAclId()
  		);

      // check if the clone_id matches an existing container
      if(!is_numeric($fieldsArray['clone_id'])) {
        $fieldsArray['clone_id'] = 0;
      }
      else {
        if($fieldsArray['clone_id'] <= 0 || !$this->containerExists($fieldsArray['clone_id'])) {
          $fieldsArray['clone_id'] = 0;
        }
      }

      if(!is_numeric($fieldsArray['count_shown'])) {
        $fieldsArray['count_shown'] = 0;
      }

      if(!is_numeric($fieldsArray['shown_from'])) {
        $fieldsArray['shown_from'] = 0;
      }

  		// new container : id 0 is not allowed in the DB
  		if ($containerId == 0) {
  			if (!$this->dbManipulator->addRecord(CONTAINERS_TABLE, $fieldsArray)) {
  				$this->debug('ContainersManager::storeContainer, error : unable to create new container', 1);
  				$containerId = -1;
  			}
        else {
    			$new_id = $this->dbManipulator->getLastId();
    			$container->setContainerId($new_id);
    			$this->setContainer($container);
    			// free the temporary container entry (0)
    			unset($this->containersTable[0]);
    			$this->containersTable[0] = null;
    			// return a value > 0, the id of the new container
    			$this->debug('ContainersManager::storeContainer, new container created successfully', 9);
   				$containerId = $new_id;
        }
  		}
  		else {
  			if (!$this->dbManipulator->setRecord(CONTAINERS_TABLE, $containerId, $fieldsArray)) {
  				$this->debug('ContainersManager::storeContainer, error : unable to update container ('.$containerId.')', 1);
  				$containerId = -1;
  			}
  		}

      if(!isset($new_id) && $containerId > 0) {

    		$cloneId = $fieldsArray['clone_id'];

    		// if was not a clone previously
    		if ($cloneId || !$formerCloneBool) {

      		$loadId = $containerId;
      		if($cloneId > 0) {
      			$loadId = $cloneId;
      		}

      		// make contents list
      		$result = $this->dbManipulator->getRecord(CONTAINER_CONTENTS_TABLE, $loadId, '', 'container_id', '`index`');

      		if (!$result) {
      			$this->debug('ContainersManager::storeContainer, error : unable to get contents list for container #'.$loadId, 2);
      			$containerId = -1;
      		}
      		else {
      			$contentsTableBool = array();
      			while($row = $this->dbManipulator->fetchArray($result)){
      				$contentId = $row['content_id'];
      				$contentsTableBool[$contentId] = true;
      			}

        		$contentsTable = &$container->getContentsTable();
        		$count = count($contentsTable);

        		for ($i = 0; $i < $count; ++$i) {
        			$contentId = $contentsTable[$i]->getContentId();

        			$fieldsArray = array();
        			$fieldsArray['index'] = $i+1;

        			if(isset($contentsTableBool[$contentId])) {
        				if (!$this->dbManipulator->setRecord(CONTAINER_CONTENTS_TABLE, $loadId, $fieldsArray, '`content_id`='.$contentId, 'container_id')) {
        					$this->debug("ContainersManager.storeContainer, error : unable to set record for list of container '$loadId'.", 2);
        					$containerId = -1;
        				}
        			}
        			else {
        				$fieldsArray['content_id']   = $contentId;
        				$fieldsArray['container_id'] = $loadId;

        				$result = $this->dbManipulator->sendQuery("SELECT max(`index`) as `index` FROM `".CONTAINER_CONTENTS_TABLE."` WHERE `container_id` = $loadId;");
        				if(!($row = $this->dbManipulator->fetchArray($result))){
        					$containerId = -1;
        				}
        				else {
          				$fieldsArray['index'] = $row['index']+1;

          				if (!($result = $this->dbManipulator->addRecord(CONTAINER_CONTENTS_TABLE, $fieldsArray))) {
          					$this->debug('ContainersManager::storeContainer, error : unable to new entry in contents list of container #'.$loadId, 2);
          					$containerId = -1;
          			 	}
                }
        			}
        		}
          }
        }
      }
    }
    $this->debug('ContainersManager::storeContainer, status : function completed', 10, DBG_CLOSE);
		return $containerId;
	}

	function loadLanguageDependencies($containerId) {
    $this->debug('ContainersManager::loadLanguageDependencies, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$varsTable["name"] = &$this->containersTable[$containerId]->getNameId();

		foreach($varsTable as $key => $value){
			if (($result = $this->dbManipulator->getRecord(NAMES_TABLE, $value, "lang_id=".$this->getLangId())) < 0 ){
				$fieldsArray[$key] = '';
				$this->debug("ContainersManager::loadLanguageDependencies, error : container '$containerId' unknown name for language '".$this->getLangId()."'.", 3);
			}
			else{
				if (!($row = &$this->dbManipulator->fetchArray($result))){
					$fieldsArray[$key] = '';
					$this->debug("ContainersManager::loadLanguageDependencies, warning : container '$containerId' unknown $key for language '".$this->getLangId()."' (".$key."_id is $value).", 3);
				}
				else
					$fieldsArray[$key] = $row["value"];
			}
		}

		$this->containersTable[$containerId]->setValues($fieldsArray);
    $this->debug('ContainersManager::loadLanguageDependencies, status : function completed', 10, DBG_CLOSE);
	}

	/**
	 * Stores Container Translation
	 *
	 * @param  integer $containerId
	 * @param  integer $langId Language Id
	 * @return boolean
	 */
	function storeContainerTranslation($containerId, $langId) {
    $this->debug('ContainersManager::storeContainerTranslation, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$container = &$this->getContainer($containerId, false);
    $result = true;
		if (!$container) {
			$result = false;
		}
		else {
  		if ($containerId == 0) {
  		// create new label id's for the container fields
  			$labels = array(
  				'name'        => ''
  			);
  			$containerValues = array();
  			foreach ($labels as $key => $value) {
  				$record = array();
  				$record['lang_id'] = '1';
  				$record['value'] = '';
  				$res = $db->addRecord(NAMES_TABLE, $record);
  				if ($res && $db->getLastId()) {
  					$containerValues[$key.'_id'] = $db->getLastId();
  				}
  			}
  			$container->setContainerValues($containerValues);
  		}
  		$labels = array(
  			 'name' => $container->getContainerNameId()
  		);
  		$containerValues = array();
  		$valuesTableLang = &$container->getContainerValuesTable();
    	foreach($valuesTableLang as $langId => $valuesTable) {
  			if(!is_int($langId)) {
  				continue;
  			}
  			foreach ($labels as $key => $labelId) {
  				$record = array();
  				$record['value'] = $this->html_encode($valuesTable[$key]);
  				//$record['value'] = $valuesTable[$key];
  				if ($labelId == 0) {
  					// create new record
  					$record['lang_id'] = $langId;
  					$res = $db->addRecord(NAMES_TABLE, $record);
  					if ($res && $db->getLastId()) {
  						$containerValues[$key.'_id'] = $db->getLastId();
  					}
  				}
  				else {
  					// update record or create new record
  					$res = $db->getRecord(NAMES_TABLE, $labelId, '`lang_id`='.$langId);
  					if ($res && $db->getNumRows()) {
  						$res = $db->setRecord(NAMES_TABLE, $labelId, $record, '`lang_id`='.$langId);
  					}
  					elseif ($res && !$db->getNumRows()) {
  						$record['id'] = $labelId;
  						$record['lang_id'] = $langId;
  						$res = $db->addRecord(NAMES_TABLE, $record);
  					}
  				}
  			}
  		}
  		$container->setContainerValues($containerValues);
    }
    $this->debug('ContainersManager::storeContainerTranslation, status : function completed', 10, DBG_CLOSE);
		return true;
  }

	function storeLanguageDependencies($containerId, $langId=LOAD_ALL_LANGUAGES) {
    $this->debug('ContainersManager::storeLanguageDependencies, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
    $this->storeContainerTranslation($containerId, $langId);
    $this->debug('ContainersManager::storeLanguageDependencies, status : function completed', 10, DBG_CLOSE);
  }

	/**
	 * Stores Language Dependencies
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
	function _storeLanguageDependencies($containerId) {
    $this->debug('ContainersManager::_storeLanguageDependencies, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
    $result = true;
		if (($container = &$this->getContainer($containerId)) == null) {
			$this->debug('ContainersManager::_storeLanguageDependencies, error : container ('.$containerId.') not defined', 1);
			$result = false;
		}
    else {
  		// new container
  		if ($containerId == 0) {
  			$varsTable = array();
  			$varsTable['name'] = $container->getContainerName();

  			$containerFieldsArray = array();

  			foreach($varsTable as $key => $value){
  				$labelFieldsArray = array();
  				$labelFieldsArray['value'] = $value;
  				$labelFieldsArray['lang_id'] = $this->getLangId();
          if (!$this->dbManipulator->addRecord(NAMES_TABLE, $labelFieldsArray)) {
  					$this->debug('ContainersManager::_storeLanguageDependencies, error : unable to create new label', 1);
  					$result = false;
            break;
  				}
  				$containerFieldsArray[$key.'_id'] = $this->dbManipulator->getLastId();
  			}
  			if($result === true) {
    			$container->setValues($containerFieldsArray);
    			$this->debug("ContainersManager::_storeLanguageDependencies, new labels created successfully", 9);
        }
  		}
  		else {
  			$containerNameId = $container->getContainerNameId();
  			$containerName = $container->getContainerName();

  			$varsTable = array();
  			$varsTable[$containerNameId] = $containerName;

  			foreach ($varsTable as $key => $value) {
  				$labelFieldsArray = array();
  				$labelFieldsArray['value'] = $value;

  				if ($this->dbManipulator->recordExists(NAMES_TABLE, $key, '`lang_id`='.$this->getLangId())) {
  	        		if (!$this->dbManipulator->setRecord(NAMES_TABLE, $key, $labelFieldsArray, '`lang_id`='.$this->getLangId(), 'id')){
  						$this->debug("ContainersManager::_storeLanguageDependencies, status : error.", 1);
  						return -1;
  					}
  				}
  				else {
  					$labelFieldsArray['id'] = $key;
  					$labelFieldsArray['lang_id'] = $this->getLangId();
  	        		if (!$this->dbManipulator->addRecord(NAMES_TABLE, $labelFieldsArray)) {
  						$this->debug("ContainersManager.storeLanguageDependencies, status : error.", 1);
  						return -1;
  					}
  				}

  				$this->debug("ContainersManager.storeLanguageDependencies, labels updated successfully.", 10);
  			}
  		}
    }
    $this->debug('ContainersManager::_storeLanguageDependencies, status : function completed', 10, DBG_CLOSE);
		return $result;
	}

	/**
	 * Removes Container
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
  function removeContainer($containerId) {
    $this->debug('ContainersManager::removeContainer, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
    $result = true;
		if (!($container = &$this->getContainer($containerId))) {
			$this->debug('ContainersManager::removeContainer, error : trying to remove unexisting container #'.$containerId, 3);
			$result = false;
		}
		else {
  		$container->setContainerDeleted(1);
      if (!$this->storeContainer($containerId)) {
        $result = false;
      }
    }
    $this->debug('ContainersManager::removeContainer, status : function completed', 10, DBG_CLOSE);
		return $result;
  }

	/**
	 * Adds Content Into Container
	 *
	 * @param  integer $containerId
	 * @param  integer $contentId
	 * @return boolean
	 */
	function addContent($containerId, $contentId){
    $this->debug('ContainersManager::addContent, status : function invoked ('.$containerId.', '.$contentId.')', 10, DBG_OPEN);
    $result = true;
		$dbManipulator = &$this->getDBManipulator();
		if($container = &$this->getContainer($containerId)){
			$fields = array();
			$fields['container_id']  = $containerId;
			$fields['content_id']    = $contentId;

			$result = $dbManipulator->sendQuery("SELECT max(`index`) as `index` FROM `".CONTAINER_CONTENTS_TABLE."` WHERE `container_id` = $containerId;");
			if(!($row = $dbManipulator->fetchArray($result))){
				$result = false;
			}
      else {
  			$fields['index'] = $row['index']+1;
  			if(!$dbManipulator->addRecord(CONTAINER_CONTENTS_TABLE, $fields)){
  				$result = false;
  			}
      }
		}
    $this->debug('ContainersManager::addContent, status : function completed', 10, DBG_CLOSE);
		return $result;
	}

	/**
	 * Removes Content From Container
	 *
	 * @param  integer $containerId
	 * @param  integer $contentId
	 * @return boolean
	 */
	function removeContent($containerId, $contentId){
    $this->debug('ContainersManager::removeContent, status : function invoked ('.$containerId.','.$contentId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$removed = false;
		if($db->delRecord(CONTAINER_CONTENTS_TABLE, $containerId, "`content_id`=$contentId", 'container_id')){
			$removed = true;
		}
    $this->debug('ContainersManager::removeContent, status : function completed', 10, DBG_CLOSE);
		return $removed;
  }

  function checkContainer($containerId) {
  	return isset($this->containersTable[$containerId]);
  }

	/**
	 * Tells if a container is present in the database
	 *
	 * @param  integer $containerId
	 * @return boolean
	 */
	function containerExists($containerId) {
		// try to load the container
		$this->getContainer($containerId);
		// returns true if the container exists
		return $this->checkContainer($containerId);
	}

  	/**
	 * Gets Container
	 *
 	 * @param  integer $containerId
	 * @param  boolean $loadContent
 	 * @return mixed object or null
	 */
	function &getContainer($containerId, $loadContent=true, $reload=false){
    $this->debug('ContainersManager::getContainer, status : function invoked ('.$containerId.')', 10, DBG_OPEN);
    $container = null;
  	if ($reload || !$this->checkContainer($containerId)){
			if (!$this->loadContainer($containerId, $loadContent)){
				trigger_error('ContainersManager::getContainer, error : unable to get container ('.$containerId.')', E_USER_ERROR);
			}
			else {
        $container = &$this->containersTable[$containerId];
			}
		}
    else {
      $container = &$this->containersTable[$containerId];
    }
    $this->debug('ContainersManager::getContainer, status : function completed', 10, DBG_CLOSE);
  	return $container;
	}

	/**
	 * Sets Container into manager
	 *
	 * @param  object $container
	 * @return boolean
	 */
	function setContainer(&$container) {
    $this->debug('ContainersManager::setContainer, status : function invoked', 10, DBG_OPEN);
    $result = true;
		$container_id = $container->getContainerId();
		if($container_id >= 0) {
  		$this->containersTable[$container_id] = &$container;
    }
    else {
      trigger_error('ContainersManager::setContainer, error : container id < 0', E_USER_ERROR);
      $result = false;
    }
    $this->debug('ContainersManager::setContainer, status : function completed', 10, DBG_CLOSE);
		return $result;
	}

	/**
	 * Adds a Container into manager
	 *
	 * @param  object $container
	 * @return boolean
	 */
	function addContainer(&$container) {
    $this->debug('ContainersManager::addContainer, status : function invoked', 10, DBG_OPEN);
		if ($this->checkContainer($container->getContainerId())){
			$this->debug("ContainersManager::addContainer, warning : container (".$container->getContainerId().") already loaded in container manager : value overwritten.", 5);
		}
    $result = $this->setContainer($container);
    $this->debug('ContainersManager::addContainer, status : function completed (', 10, DBG_CLOSE);
		return $result;
	}

	/**
	 * Gets ContainersList ACL
	 *
	 * @param  integer $aclId ACL Id
	 * @return object
	 */
	function &getContainerAcl($aclId) {
    $this->debug('ContainersManager::getContainerAcl, status : function invoked ('.$aclId.')', 10, DBG_OPEN);
		$acl = &$this->aclManager->getACL($aclId);
    $this->debug('ContainersManager::getContainerAcl, status : function completed', 10, DBG_CLOSE);
		return $acl;
	}
	
	/**
	 * Gets New Container
	 *
	 * Returns a new Container object
	 *
	 * @param  integer $aclId
	 * @return object
	 */
	function &getNewContainer($aclId=0) {
    $this->debug('ContainersManager::getNewContainer, status : function invoked ('.$aclId.')', 10, DBG_OPEN);
		$id          = 0;
		$nameId      = 0;
		$typeName    = '';
		$templateId  = 0;
		$sortingType = 1;
		$sortField   = '';
		$sortOrder   = 1;
		$shownFrom   = 0;
		$countShown  = 0;
		$cloneId     = 0;
		$deleted     = 0;
		$type        = CONTAINER_TYPE_NORMAL;

		$this->containersTable[0] = &new Container($id, $nameId, $typeName,	$templateId, $sortingType, $sortField, $sortOrder, $shownFrom, $countShown, $cloneId, $deleted, $aclId);
    $this->containersTable[0]->setContainerPublished(PUBLICATION_DEFAULT_VALUE);
    $this->containersTable[0]->setContainerType($type);
    $this->debug('ContainersManager::getNewContainer, status : function completed', 10, DBG_CLOSE);
		return $this->containersTable[0];
	}

	function getParentObjectValuesArray($containerId, $pageId, $frameId) {
    $this->debug('ContainersManager::getParentObjectValuesArray, status : function invoked', 10, DBG_OPEN);
    $result = null;

		if (($result_array = $this->dbManipulator->queryGetPageOfContainer($pageId, $frameId, $containerId)) == false) {
			$this->debug("ContainersManager::getParentObjectValuesArray : warning, unable to get parent page for container $containerId", 3);
		}
    else {
  		if ($this->dbManipulator->getNumRows() <= 0) {
  			$result_array = $this->dbManipulator->queryGetContainersListOfContainer($containerId);

  			if (($result_array == false) || ($this->dbManipulator->getNumRows() == 0)) {
    			$this->debug("ContainersManager::getParentObjectValuesArray : warning, unable to get parent containers list for container $containerId", 3);
  			}
  			else {
		      $result = $this->dbManipulator->fetchArray($result_array);
  			}
  		}
  		else {
        $result = $this->dbManipulator->fetchArray($result_array);
  		}
    }

    $this->debug('ContainersManager::getParentObjectValuesArray, status : function completed', 10, DBG_CLOSE);
		return $result;
	}

	/**
	 * Gets Languages
	 *
	 * Returns associative array of available languages
	 *
	 * @return array
	 * @todo discussion about the right place for this function (managers interface ? / dbManipulator ?)
	 */
	function getLangsArray() {
    $this->debug('ContainersManager::getLangsArray, status : function invoked', 10, DBG_OPEN);
		$dbManipulator = &$this->getDBManipulator();
    $langsArray = null;
		if (($result_array = $dbManipulator->getRecord(LANGUAGES_TABLE, -1, '', 'id', 'name')) == false) {
			$this->debug("ContainersManager::updateContainerACL : error, unable to set new acl id for container $containerId", 3);
		}
		else {
  		$langsArray = array();
  		while ($row = $dbManipulator->fetchArray($result_array)) {
  			$langId = $row['id'];
  			$langsArray[$langId] = $row['name'];
  		}
    }
    $this->debug('ContainersManager::getLangsArray, status : function completed', 10, DBG_CLOSE);
		return $langsArray;
	}

  /**
   * Updates Container ACL
   *
   * @param  integer $containerId Container Id
   * @param  integer $aclId New ACL Id
   * @return boolean
   */
  function updateContainerACL($containerId, $aclId){
    $this->debug('ContainersManager::updateContainerACL, status : function invoked ('.$containerId.', '.$aclId.')', 10, DBG_OPEN);
    $result = true;
		$container  = &$this->getContainer($containerId);
		$oldAclId   = $container->getContainerAclId();

    $db = &$this->getDBManipulator();
    $fields = array('acl_id' => $aclId);

    if(!$db->setRecord(CONTAINERS_TABLE, -1, $fields, "`id`='$containerId'")){
			$this->debug("ContainersManager::updateContainerACL : error, unable to set new acl id for container $containerId", 3);
			$result = false;
		}
    else {
      if($container->getContainerCloneId() == 0) {
    		$contentsTable = &$container->getContentsTable();
    		if(count($contentsTable) == 0) {
    			$this->loadContainerContents($containerId);
    			$contentsTable = &$container->getContentsTable();
    		}

    		for($i = 0; $i < count($contentsTable); ++$i) {
    			$content = &$contentsTable[$i];
    			if($content->getContentAclId() == $oldAclId) {
    				$this->contentsManager->updateContentACL($content->getContentId(), $content->getContentTypeName(), $aclId);
    			}
    		}
      }
      else {
        $this->debug('ContainersManager::updateContainerACL, notice : container ('.$containerId.') is a clone : skipping update of child nodes', 5);
      }
    }
    $this->debug('ContainersManager::updateContainerACL, status : function completed', 10, DBG_CLOSE);
		return $result;
  }

	/**
	 * Returns all available content types
	 *
	 * @author vinadelmar
	 * @since  2006-06-10
	 * @return array
	 */
	function getContentTypesArray() {
    $this->debug('ContainersManager::getContentTypesArray, status : function invoked', 10, DBG_OPEN);
		$contentTypesArray = null;

		$prefix = TYPE_TABLES_PREFIX;

		if (($result = $this->dbManipulator->getTables($prefix)) != false) {
      $contentTypesArray = array();
		  $prefix_len = strlen($prefix);
  		while ($row = $this->dbManipulator->fetchArray($result)) {
        $contentTypesArray[] = substr($row[0], $prefix_len);
  		}
		}
    $this->debug('ContainersManager::getContentTypesArray, status : function completed', 10, DBG_CLOSE);
		return $contentTypesArray;
	}

}
?>