<?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/CoreObject.class.php');
include_once('classes/core/DBManipulator.class.php');
include_once('classes/core/ACL/ACLManager.class.php');
include_once('classes/core/ACL/ACL.class.php');
include_once('classes/core/users/User.class.php');
include_once('classes/core/users/UsersManager.class.php');
include_once('classes/core/types/Type.class.php');
include_once('classes/core/types/TypesManager.class.php');
include_once('classes/core/containers/ContainersManager.class.php');
include_once('classes/core/contents/ContentsManager.class.php');
include_once('classes/core/templates/Template.class.php');
include_once('classes/core/templates/TemplatesManager.class.php');
include_once('classes/utils/SortedList.class.php');
include_once('classes/utils/SortedListIterator.class.php');
include_once('interface/egManager.class.php');
include_once('interface/egContainer.class.php');
include_once('interface/egContextMenu.class.php');

/**
 * Container Class
 *
 * A container holds infos about template, sort order, number to be shown and
 * exhaustive list of contents that are to be displayed in this container.
 *
 * @access     public
 * @author	   Cedric Francoys <cedric.francoys@easy-cms.org>
 * @version	   Container.class, Sat Nov 13 11:37:29 CET 2004
 * @package    Core
 * @subpackage Containers
 */
class Container extends CoreObject {
	/**
	 * @var integer
	 */
  var $id;

	/**
	 * @var integer
	 */
	var $nameId;

	/**
	 * @var string
	 */
	var $typeName;

	/**
	 * @var integer
	 */
	var $templateId;

	/**
	 * @var integer
	 */
	var $sortingType;

	/**
	 * @var string
	 */
	var $sortField;

	/**
	 * @var integer
	 */
	var $sortOrder;

	/**
	 * @var integer
	 */
	var $shownFrom;

	/**
	 * @var integer
	 */
	var $countShown;

	/**
	 * @var integer
	 */
	var $cloneId;

	/**
	 * @var integer
	 */
	var $deleted;

	/**
	 * @var integer
	 */
	var $published;

	/**
	 * @var integer
	 */
	var $aclId;

	/**
	 * @var array
	 */
	var $namesTable;

	/**
	 * @var object
	 */
	var $template;

	/**
	 * @var object
	 */
	var $acl;

	/**
	 * @var integer
	 */
	var $containersListId;

	/**
	 * @var
	 */
	var $contentTypeDescr;

	/**
	 * @var array
	 */
	var $contentsTable;

	/**
	 * @var array
	 */
	var $objectsList;

  var $type;
  
  var $repository;


	/**
	 * Constructor
	 *
	 * @param integer $id Container Id
	 * @param integer $nameId Container Name Id
	 * @param string $typeName Container Type Name
	 * @param integer $templateId Container Template Id
	 * @param integer $sortingType Sorting Type
	 * @param string $sortField Sort Field
	 * @param integer $sortOrder Sort Order
	 * @param integer $shownFrom Show From the nth Content
	 * @param integer $countShown Show n Contents
	 * @param integer $cloneId Original Container Id (if any)
	 * @param integer $deleted Is Container Deleted
	 * @param integer $aclId Container ACL Id
	 */
	function Container($id=0, $nameId=0, $typeName='', $templateId=0, $sortingType=0, $sortField='', $sortOrder=0, $shownFrom=0, $countShown=0, $cloneId=0, $deleted=0, $aclId=0) {
    $this->debug('Container::Container, status : function invoked', 10, DBG_OPEN);
		$this->setContainerId($id);
		$this->setContainerNameId($nameId);
		$this->setContainerTypeName($typeName);
		$this->setContainerTemplateId($templateId);
		$this->setContainerSortingType($sortingType);
		$this->setContainerSortField($sortField);
		$this->setContainerSortOrder($sortOrder);
		$this->setContainerShownFrom($shownFrom);
		$this->setContainerCountShown($countShown);
		$this->setContainerCloneId($cloneId);
		$this->setContainerDeleted($deleted);
		$this->setContainerAclId($aclId);
    $this->setContainerRepository('');
    $this->setContainerType(CONTAINER_TYPE_NORMAL);
		$this->namesTable = array();
		$this->contentsTable = array();
    $this->debug('Container::Container, status : function completed', 10, DBG_CLOSE);
	}

	function getClassName(){
		return 'Container';
	}


  function setContainerType($type=CONTAINER_TYPE_NORMAL) {
    $this->type = $type;
  }
  
  function setContainerRepository($repository='') {
    $this->repository = $repository;
  }
  
  function getContainerType() {
    return $this->type;
  }
  
  function getContainerRepository() {
    return $this->repository;
  }

	/**
	 * Gets Container Id
	 *
	 * @return integer
	 */
	function getContainerId(){
		return $this->id;
	}

	/**
	 * Sets Container Id
	 *
	 * @param integer $id Container Id
	 */
	function setContainerId($id){
		$this->id = $id;
	}

	/**
	 * Gets Container Name Id
	 *
	 * @return integer
	 */
	function getContainerNameId(){
		return $this->nameId;
	}

	/**
	 * Sets Container Name Id
	 *
	 * @param integer $nameId
	 */
	function setContainerNameId($nameId){
		$this->nameId = $nameId;
	}

	/**
	 * Gets Container Type Name
	 *
	 * Indicates which kind of Content the Container will hold
	 *
	 * @return string
	 */
	function getContainerTypeName(){
		if($this->getContainerType() == CONTAINER_TYPE_PHOTO_GALLERY) {
		  return 'gallery_photo';
		}
		return $this->typeName;
	}

	/**
	 * Sets Container Type Name
	 *
	 * Indicates which kind of Content the Container will hold
	 *
	 * @param string $typeName
	 */
	function setContainerTypeName($typeName){
		$this->typeName = $typeName;
	}

	/**
	 * Gets Container Template Id
	 *
	 * @return integer
	 */
	function getContainerTemplateId(){
		return $this->templateId;
	}

	/**
	 * Sets Container Template Id
	 *
	 * @param integer $templateId
	 */
	function setContainerTemplateId($templateId){
		$this->templateId = $templateId;
	}

	/**
	 * Sets Container "SortingType" Property
	 *
	 * Indicates if we must operate a field or index based sort
	 *
	 * @return integer
	 */
	function getContainerSortingType(){
		return $this->sortingType;
	}

	/**
	 * Sets Container "SortingType" Property
	 *
	 * Indicates if we must operate a field or index based sort
	 *
	 * @param integer $sortingType
	 */
	function setContainerSortingType($sortingType){
		$this->sortingType = $sortingType;
	}

	/**
	 * Sets Container "SortField" Property
	 *
	 * Indicates on which Content field applies the sort
	 *
	 * @return string
	 */
	function getContainerSortField(){
		return $this->sortField;
	}

	/**
	 * Sets Container "SortField" Property
	 *
	 * Indicates on which Content field applies the sort
	 *
	 * @param string $sortField
	 */
	function setContainerSortField($sortField){
		$this->sortField = $sortField;
	}

	/**
	 * Gets Container "SortOrder" Property
	 *
	 * Sort order is ascending or descending
	 *
	 * @return integer
	 */
	function getContainerSortOrder(){
		return $this->sortOrder;
	}

	/**
	 * Sets Container "SortOrder" Property
	 *
	 * Sort order is ascending or descending
	 *
	 * @param integer $sortOrder
	 */
	function setContainerSortOrder($sortOrder){
		$this->sortOrder = $sortOrder;
	}

	/**
	 * Gets Container "ShownFrom" Property
	 *
	 * Indicates at which position of the Content list, we start displaying
	 * Content objects
	 *
	 * @return integer
	 */
	function getContainerShownFrom(){
		return $this->shownFrom;
	}

	/**
	 * Sets Container "ShownFrom" Property
	 *
	 * Indicates at which position of the Content list, we start displaying
	 * Content objects
	 *
	 * @param integer $shownFrom
	 */
	function setContainerShownFrom($shownFrom){
		$this->shownFrom = $shownFrom;
	}

	/**
	 * Gets Container "CountShown" Property
	 *
	 * Indicates how many Content objects have to be displayed
	 *
	 * @return integer
	 */
	function getContainerCountShown(){
		return $this->countShown;
	}

	/**
	 * Sets Container "CountShown" Property
	 *
	 * Indicates how many Content objects have to be displayed
	 *
	 * @param integer $countShown
	 */
	function setContainerCountShown($countShown){
		$this->countShown = $countShown;
	}

	/**
	 * Gets Container Clone Id
	 *
	 * If a Container is a clone, it loads its content from another Container
	 *
	 * @return integer
	 */
	function getContainerCloneId(){
		return $this->cloneId;
	}

	/**
	 * Sets Container Clone Id
	 *
	 * If a Container is a clone, it loads its content from another Container
	 *
	 * @param integer $cloneId
	 */
	function setContainerCloneId($cloneId){
		$this->cloneId = $cloneId;
	}

	/**
	 * Gets Container Deleted
	 *
	 * @return integer
	 */
	function getContainerDeleted(){
		return $this->deleted;
	}

	/**
	 * Sets Container Deleted
	 *
	 * @param integer $deleted
	 */
	function setContainerDeleted($deleted){
		$this->deleted = $deleted;
	}

	/**
	 * Gets Container Acl Id
	 *
	 * @return integer
	 */
	function getContainerAclId(){
		return $this->aclId;
	}

	/**
	 * alias for getContainerAclId
	 *
	 * @return integer
	 */
	function getAclId() {
		return $this->aclId;
	}

	/**
	 * Sets Container Acl Id
	 *
	 * @param integer $aclId
	 */
	function setContainerAclId($aclId){
		$this->aclId = $aclId;
	}

	/**
	 * Gets Container Name
	 *
	 * @return string
	 */
	function getContainerName($langId){
    $this->debug('Container::getContainerName, status : function invoked', 10, DBG_OPEN);
		$name = '';
		if(isset($this->namesTable[$langId])){
			$name = $this->namesTable[$langId];
		}
    $this->debug('Container::getContainerName, status : function completed', 10, DBG_CLOSE);
		return $name;
	}

	/**
	 * Sets Container Name
	 *
	 * @param string $name
	 */
	function setContainerName($name, $langId){
    $this->debug('Container::setContainerName, status : function invoked', 10, DBG_OPEN);
		$this->namesTable[$langId] = $name;
    $this->debug('Container::setContainerName, status : function completed', 10, DBG_CLOSE);
	}

	/**
	 * Gets Container Template
	 *
	 * @return object
	 */
	function &getContainerTemplate(){
    $this->debug('Container::getContainerTemplate, status : function invoked', 10, DBG_OPEN);
    $template = null;
		if (!isset($this->template)) {
      $this->debug('Container::getContainerTemplate, warning : template not set for container ('.$this->id.')', 4);
    }
    else {
      $template = &$this->template;
    }
    $this->debug('Container::getContainerTemplate, status : function completed', 10, DBG_CLOSE);
		return $template;
	}

	/**
	 * Sets Containter Template
	 *
	 * @param object $template
	 */
	function setContainerTemplate(&$template){
		$this->template = &$template;
	}

	/**
	 * Gets Container ACL
	 *
	 * @return object
	 */
	function &getContainerAcl(){
    $this->debug('Container::getContainerAcl, status : function invoked', 10, DBG_OPEN);
    $acl = null;
		if (!isset($this->acl)) {
      $this->debug('Container::getContainerAcl, warning : acl not set for container ('.$this->id.')', 4);
    }
    else {
      $acl = &$this->acl;
    }
    $this->debug('Container::getContainerAcl, status : function completed', 10, DBG_CLOSE);
		return $acl;
	}

	/**
	 * Sets Container ACL
	 *
	 * @param object $acl
	 */
	function setContainerAcl(&$acl){
		$this->acl = &$acl;
	}

	/**
	 * Sets Container Published
	 *
	 * @param object $published
	 */
	function setContainerPublished($published){
		$this->published = $published;
	}

	function getContainerPublished(){
		return $this->published;
	}

	function isPublished(){
		return (bool) $this->getContainerPublished();
	}

	/**
	 * Gets ContainersList Id
	 *
	 * Indicates if Container is contained into a ContainersList
	 *
	 * return integer
	 */
	function getContainersListId(){
		return $this->containersListId;
	}

	/**
	 * Sets Containers List
	 *
	 * Indicates if Container is contained into a ContainersList
	 *
	 * @param integer $containersListId
	 */
	function setContainersListId($containersListId){
		$this->containersListId = $containersListId;
	}

	/**
	 * Gets Content Table
	 *
	 * @return array
	 */
	function &getContentsTable(){
    $this->debug('Container::getContentsTable, status : function invoked', 10, DBG_OPEN);
    $table = null;
		if (!isset($this->contentsTable)) {
      $this->debug('Container::getContentsTable, warning : contentsTable not set', 4);
		}
		else {
      $table = &$this->contentsTable;
		}
    $this->debug('Container::getContentsTable, status : function completed', 10, DBG_CLOSE);
		return $table;
	}

	/**
	 * Sets Content Table
	 *
	 * @param array $table Array of Content objects
	 */
	function setContentsTable(&$table){
		$this->contentsTable = &$table;
	}

	/**
	 * Gets Content Count
	 *
	 * Number of Content object holded by Container
	 *
	 * @return integer
	 */
	function getContentsCount(){
    $this->debug('Container::getContentsCount, status : function invoked', 10, DBG_OPEN);
    $count = -1;
		if (!isset($this->contentsTable)) {
      $this->debug('Container::getContentsCount, warning : contentsTable not set', 4);
		}
    else {
      $count = count($this->contentsTable);
    }
    $this->debug('Container::getContentsCount, status : function completed', 10, DBG_CLOSE);
		return $count;
	}

	/**
	 * Adds a content object to the contentsTable
	 *
	 * @param object $content
	 */
	function addContent(&$content){
    $this->debug('Container::addContent, status : function invoked', 10, DBG_OPEN);
		if(!is_object($content)) {
			$this->debug('Container::addContent, error : trying to add a non-object to the contentsTable.', 3);
		}
		else {
		  $this->contentsTable[] = &$content;
		}
    $this->debug('Container::addContent, status : function completed', 10, DBG_CLOSE);
	}

	/**
	 * Gets Content
	 *
	 * @author vinadelmar
	 * @since  2006-08-30
	 * @param  integer $contentId Content Id
	 * @return object
	 */
	function &getContent($contentId){
    $this->debug('Container::getContent, status : function invoked', 10, DBG_OPEN);
    $content = null;
		if (!isset($this->contentsTable[$contentId])) {
      $this->debug('Container::getContent, warning : content ('.$contentId.') not in container', 3);
		}
		else {
		  $content = &$this->contentsTable[$contentId];
		}
    $this->debug('Container::getContent, status : function completed', 10, DBG_CLOSE);
		return $content;
	}


	function getContainerValuesTable() {
    $this->debug('Container::getContainerValuesTable, status : function invoked', 10, DBG_OPEN);
    $valuesTable = array();

    foreach($this->namesTable as $langId => $name) {
      $valuesTable[$langId]['name'] = $name;
    }

		$valuesTable['id'] = $this->getContainerId();
		$valuesTable['clone_id'] = $this->getContainerCloneId();
		$valuesTable['name_id'] = $this->getContainerNameId();
		$valuesTable['type_name'] = $this->getContainerTypeName();
		$valuesTable['sorting_type'] = $this->getContainerSortingType();
		$valuesTable['sort_field'] = $this->getContainerSortField();
		$valuesTable['sort_order'] = $this->getContainerSortOrder();
		$valuesTable['count_shown'] = $this->getContainerCountShown();
		$valuesTable['shown_from'] = $this->getContainerShownFrom();
		$valuesTable['template_id'] = $this->getContainerTemplateId();
		$valuesTable['acl_id'] = $this->getContainerAclId();
		$valuesTable['deleted'] = $this->getContainerDeleted();
		$valuesTable['type'] = $this->getContainerType();
		$valuesTable['repository'] = $this->getContainerRepository();
    $this->debug('Container::getContainerValuesTable, status : function completed', 10, DBG_CLOSE);
    return $valuesTable;
  }

	/**
	 * Gets Container Value
	 *
	 * @param  string $fieldName
	 * @return mixed
	 */
	function getContainerValue($fieldName, $langId=1) {
    $this->debug('Container::getContainerValue, status : function invoked', 10, DBG_OPEN);
    $value = null;
    switch($fieldName) {
  		case 'id' :
  			$value = $this->getContainerId();
  			break;
  		case 'clone_id' :
  			$value = $this->getContainerCloneId();
        break;
  		case 'name_id' :
  			$value = $this->getContainerNameId();
        break;
  		case 'name' :
  			$value = $this->getContainerName($langId);
        break;
  		case 'sorting_type' :
  			$value = $this->getContainerSortingType();
        break;
  		case 'sort_field' :
  			$value = $this->getContainerSortField();
        break;
  		case 'sort_order' :
  			$value = $this->getContainerSortOrder();
        break;
  		case 'count_shown' :
  			$value = $this->getContainerCountShown();
        break;
  		case 'shown_from' :
  			$value = $this->getContainerShownFrom();
        break;
  		case 'template_id' :
  			$value = $this->getContainerTemplateId();
        break;
  		case 'type_name' :
  			$value = $this->getContainerTypeName();
        break;
  		case 'acl_id' :
  			$value = $this->getContainerAclId();
        break;
  		case 'deleted' :
  			$value = $this->getContainerDeleted();
        break;
  		case 'published' :
  			$value = $this->getContainerPublished();
        break;
  		case 'type' :
  			$value = $this->getContainerType();
        break;
  		case 'repository' :
  			$value = $this->getContainerRepository();
        break;
      default :
        $this->debug('Container::getContainerValue, warning : unknown field ('.$fieldName.')', 4);
        break;
    }
    $this->debug('Container::getContainerValue, status : function completed', 10, DBG_CLOSE);
		return $value;
	}

	/**
	 * Gets Container Value
	 *
	 * @param  string $fieldName
	 * @return mixed
	 */
	function getValue($fieldName) {
		return $this->getContainerValue($fieldName);
	}

	/**
	 * Sets Container Values
	 *
	 * @param array $array
	 */
  function setContainerValues($array) {
    $this->debug('Container::setContainerValues, status : function invoked', 10, DBG_OPEN);
		if(!is_array($array)) {
      $this->debug('Container::setContainerValues, warning : parameter is not an array', 3);
		}
		else {
      foreach($array as $key => $valuesTable) {
  			if(is_int($key)) {
  				$langId = $key;
  				if(isset($valuesTable['name'])) {
  					$this->setContainerName($valuesTable['name'], $langId);
  				}
  			}
      }
  		if(isset($array['id'])) {
  			$this->setContainerId($array['id']);
      }
  		if(isset($array['clone_id'])) {
  			$this->setContainerCloneId($array['clone_id']);
      }
  		if(isset($array['name_id'])) {
  			$this->setContainerNameId($array['name_id']);
      }
  		if(isset($array['type_name'])) {
  			$this->setContainerTypeName($array['type_name']);
      }
  		if(isset($array['sorting_type'])) {
  			$this->setContainerSortingType($array['sorting_type']);
      }
  		if(isset($array['sort_field'])) {
  			$this->setContainerSortField($array['sort_field']);
      }
  		if(isset($array['sort_order'])) {
  			$this->setContainerSortOrder($array['sort_order']);
      }
  		if(isset($array['count_shown'])) {
  			$this->setContainerCountShown($array['count_shown']);
      }
  		if(isset($array['shown_from'])) {
  			$this->setContainerShownFrom($array['shown_from']);
      }
  		if(isset($array['template_id'])) {
  			$this->setContainerTemplateId($array['template_id']);
      }
  		if(isset($array['acl_id'])) {
  			$this->setContainerAclId($array['acl_id']);
      }
  		if(isset($array['deleted'])) {
  			$this->setContainerDeleted($array['deleted']);
      }
  		if(isset($array['published'])) {
  			$this->setContainerPublished($array['published']);
      }
  		if(isset($array['type'])) {
  			$this->setContainerType($array['type']);
      }
  		if(isset($array['repository'])) {
  			$this->setContainerRepository($array['repository']);
      }
    }
    $this->debug('Container::setContainerValues, status : function completed', 10, DBG_CLOSE);
	}

  function setValues($array) {
		$this->setContainerValues($array);
	}

	/**
	 * Compares Containers
	 *
	 * @param  object $container Container Object
	 * @param  string $field Comparison Field
	 * @return integer
	 */
	function compareTo(&$container, $field, $langId=1){
    $this->debug('Container::compareTo, status : function invoked', 10, DBG_OPEN);
    $result = 1;
		if ($field == '') {
      $this->debug('Container::compareTo, warning : no field specified for comparison', 3);
		}
		else {
  		$value1 = $this->getContainerValue($field, $langId);
  		$value2 = $container->getContainerValue($field, $langId);
  		if (is_numeric($value1) && is_numeric($value2)) {
  			$value1 = sprintf("%05d", $value1);
  			$value2 = sprintf("%05d", $value2);
  		}
      $result = strcmp($value1, $value2);
    }
    $this->debug('Container::compareTo, status : function completed', 10, DBG_CLOSE);
		return $result;
	}

  	// deprecated
	function loadContent() {
		$this->sortContents();
	}

  function sortContents($langId) {
    $this->debug('Container::sortContents, status : function invoked', 10, DBG_OPEN);
    if (is_array($this->contentsTable)) {
			$count = $this->getContentsCount();
			$sortField = $this->getContainerSortField();
			$sortOrder = $this->getContainerSortOrder();
			$this->objectsList = array();
			for($i = 0; $i < $count; ++$i) {
				$content = &$this->contentsTable[$i];
				$field = &$content->getContentFieldValue($langId, $sortField);
				//$this->objectsList[$i] = substr(html_entity_decode(strip_tags($field->getValue()), ENT_QUOTES, "UTF-8"), 0, 20);
				$this->objectsList[$i] = substr(html_entity_decode(strip_tags($field->getValue()), ENT_QUOTES), 0, 20);
			}
			if($sortOrder == SORT_ASCENDING) {
				asort($this->objectsList);
			}
			else {
				arsort($this->objectsList);
			}
    }
    $this->debug('Container::sortContents, status : function completed', 10, DBG_CLOSE);
  }

	/**
	 * Exports Container Into XML
	 *
	 * @param  object $user User Object
	 * @param  integer $langId Language Id
	 * @param  string $mode
	 * @return string
	 */
 	function toXML(&$user, $langId, $mode) {
    $this->debug('Container::toXML, status : function invoked', 10, DBG_OPEN);
		$containerId = $this->getContainerId();
		$cloneId = $this->getContainerCloneId();

		$max = $this->getContainerCountShown();
		$min = $this->getContainerShownFrom();

		$limit = $max+$min;
		$count = $this->getContentsCount();

		// start from position 0
		$i = 0;
		if ($min > 0) {
			$i = $min;
		}

		$xml  = "<container>\n";

		if ($this->acl->userHasViewRight($user) && ($mode == EDIT_MODE || $this->isPublished())) {
			$xml .= "<name><![CDATA[".$this->getContainerName($langId)."]]></name>\n";
			$xml .= "<id>".$containerId."</id>\n";
			$xml .= "<clone-id>".$cloneId."</clone-id>\n";

			$xml .= "<contents>\n";

			// sorting by list
			if ($this->getContainerSortingType() == SORTING_BY_LIST) {
        $j = $i;
				for (; $i < $count && ($max == 0 || $j < $limit); ++$i) {
					if(!isset($this->contentsTable[$i]) || !is_object($this->contentsTable[$i])) {
						continue;
					}
					if($mode == EDIT_MODE || $this->contentsTable[$i]->isPublished()) {
            ++$j;
  					$xml .= $this->contentsTable[$i]->toXML($user, $langId, $containerId, $cloneId, $mode);
					}
				}
			}
			// sorting by field
			else {
				$this->sortContents($langId);
				$sortField = $this->getContainerSortField();
				if (is_array($this->objectsList)) {
					reset($this->objectsList);
					for ($j = 0; $j < $i; ++$j) {
						next($this->objectsList);
					}
          $j = $i;
					for (; $i < $count && ($max == 0 || $j < $limit); ++$i) {
						$index = key($this->objectsList);
            if($mode == EDIT_MODE || $this->contentsTable[$index]->isPublished()) {
              ++$j;
						  $xml .= $this->contentsTable[$index]->toXML($user, $langId, $containerId, $cloneId, $mode);
            }
						next($this->objectsList);
					}
				}
			}
			$xml .= "</contents>\n";
		}
		
		$xml .= "</container>\n";
		
    $this->debug('Container::toXML, status : function completed', 10, DBG_CLOSE);
		return $xml;
	}

	/**
	 * Gets Container Controls
	 *
	 * @param  object $user User Object
	 * @param  string $mode
	 * @return string
	 */
	function getControls(&$user, $mode=VIEW_MODE) {
    $this->debug('Container::getControls, status : function invoked', 10, DBG_OPEN);
		$containerId      = $this->getContainerId();
		$cloneId          = $this->getContainerCloneId();
		$typeName         = $this->getContainerTypeName();
		$containersListId = $this->getContainersListId();

		$html = '';

		if ($this->acl->userHasEditRight($user) && $mode == EDIT_MODE) {

			if(!isset($GLOBALS['contextMenuContainer'])) {
	      $menu = &new egContextMenu("menu_container", 0, 0, 150, 350);
				// add content
        $menu->addListItem(new egMenuItem("mnu_ct_1", LANG_CONTAINER_MENU_ADD, "/interface/icons/add.png", "containerMenuAddOption();"));
		    $menu->addSeparator();
				// move up
	      $menu->addListItem(new egMenuItem("mnu_ct_2", LANG_CONTAINER_MENU_MOVE_UP, "/interface/icons/move_up.png", "containerMenuMoveUpOption();"));
				// move down
	      $menu->addListItem(new egMenuItem("mnu_ct_3", LANG_CONTAINER_MENU_MOVE_DOWN, "/interface/icons/move_down.png", "containerMenuMoveDownOption();"));
		    $menu->addSeparator();
				// remove container
        $menu->addListItem(new egMenuItem("mnu_ct_4", LANG_CONTAINER_MENU_REMOVE, "/interface/icons/remove.png", "containerMenuRemoveOption();"));
		    $menu->addSeparator();
				// container properties
		    $menu->addListItem(new egMenuItem("mnu_ct_5", LANG_CONTAINER_MENU_EDIT, "/interface/icons/edit.png", "containerMenuEditOption();"));

	      $main = &new egContainer("eg_ctn_menu_container", 0, 0, 0, 0);

	      $main->addObject($menu);

	      $manager = &egManager::getInstance();
	    	$manager->addContainer($main);

				$GLOBALS['contextMenuContainer'] = &$menu;
			}
			if($cloneId != 0){
				$html .= "<a class=\"easy-CMS_UI_propertiesIcon\" href=\"javascript:selectContainer('$containerId','$cloneId','$typeName','$containersListId');egShowContextMenu(contextMenu_menu_container);\"><img src=\"/interface/icons/properties.png\" /></a>";
			}
			else {
				$html .= "<a class=\"easy-CMS_UI_propertiesIcon\" href=\"javascript:selectContainer('$containerId','$containerId','$typeName','$containersListId');egShowContextMenu(contextMenu_menu_container);\"><img src=\"/interface/icons/properties.png\" /></a>";
			}
    }
    $this->debug('Container::getControls, status : function completed', 10, DBG_CLOSE);
		return $html;
	}

	/**
	 * Exports Container Into HTML
	 *
	 * @param  object $user User
	 * @param  integer $langId
	 * @param  string $mode
	 * @param  boolean $drawBorder
	 * @return string
	 */
 	function toHTML(&$user, $langId, $mode=VIEW_MODE, $drawBorder=true) {
    $this->debug('Container::toHTML, status : function invoked', 10, DBG_OPEN);
		$html = '';
		if ($user == null) {
			$this->debug('Container::toHTML, error : user not defined', 2);
		}
		else {
  		$containerId = $this->getContainerId();
  		$cloneId = $this->getContainerCloneId();

  		if ($this->acl->userHasViewRight($user) && ($mode == EDIT_MODE || $this->isPublished())) {
  			$xml = &$this->toXML($user, $langId, $mode);

  			if (!is_object($this->template)) {
          $this->debug("Container.toHTML, error : Container(id='.$containerId.') has no template.", 2);
  			}
  			else {
          $html = &$this->template->processXML($xml, $mode);
    		  $max = &$this->getContainerCountShown();
    		  $min = &$this->getContainerShownFrom();
    			$limit = $max+$min;
    			$count = $this->getContentsCount();

    			// start from position 0
    			if($min > 0) {
    				$i = $min-1;
    			}
    			else {
    				$i = 0;
    			}

    			// sorting by list
    			if ($this->getContainerSortingType() == SORTING_BY_LIST) {
    				if (is_array($this->contentsTable)) {
    					for(; $i < $count && ($max == 0 || $i < $limit); ++$i) {
    						if(!isset($this->contentsTable[$i]) || !is_object($this->contentsTable[$i])) {
    							continue;
    						}
    						$content = &$this->contentsTable[$i];
    						$contentId = $content->getContentId();

    						$html .= $content->getControls($user, $containerId, $cloneId, $mode);
    					}
    				}
    			}
    			// sorting by field
    			else {
    				$sortField = $this->getContainerSortField();
    				if(is_array($this->objectsList)) {
    					reset($this->objectsList);
    					for($j = 0; $j < $i; ++$j) {
    						next($this->objectsList);
    					}
    					for (; $i < $count && ($max == 0 || $i < $limit); ++$i) {
    						$index = key($this->objectsList);
    						$content = &$this->contentsTable[$index];
    						next($this->objectsList);
    						$html .= $content->getControls($user, $containerId, $cloneId, $mode);
    					}
    				}
       		}

    			if ($this->acl->userHasEditRight($user) && $mode == EDIT_MODE && $drawBorder) {
    				$head = "";
    				$tail = "";

    				$head .= "<div class=\"easy-CMS_UI_outer_frame\">\n";
    				$head .= "<div class=\"easy-CMS_UI_leftBorder\">\n";
    				$head .= "<div class=\"easy-CMS_UI_rightBorder\">\n";
    				$head .= "	<div class=\"easy-CMS_UI_header\">\n";
    				$head .= "  <div class=\"easy-CMS_UI_headerInner\">\n";
    				$head .= "		<div class=\"easy-CMS_UI_left\"><div class=\"easy-CMS_UI_title\">".$this->getContainerName($langId)."</div></div>\n";
    				$head .= "		<div class=\"easy-CMS_UI_right\">\n";
    				$head .= "			<div class=\"easy-CMS_UI_properties\">\n";
    				$head .= $this->getControls($user, EDIT_MODE);
    				$head .= "			</div>\n";
    				$head .= "		</div>\n";
    				$head .= "  </div>\n";
    				$head .= "	</div>\n";
    				$head .= "	<div class=\"easy-CMS_UI_inner_frame\">\n";

    				$tail .= "	</div>\n";
    				$tail .= "</div>\n";
    				$tail .= "</div>\n";
    				$tail .= "</div>\n";
    				$html = $head.$html.$tail;
    			}
    		}
      }
    }
    $this->debug('Container::toHTML, status : function completed', 10, DBG_CLOSE);
		return $html;
	}
}
?>