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

include_once('classes/core/CoreObject.class.php');
include_once('classes/core/menus/Menu.class.php');
include_once('classes/core/pages/PagesManager.class.php');
include_once('classes/core/menuNodes/MenuNodesManager.class.php');
include_once('classes/core/DBManipulator.class.php');
include_once('classes/core/ACL/ACL.class.php');
include_once('classes/core/ACL/ACLEntry.class.php');
include_once('classes/core/ACL/ACLManager.class.php');

/**
* Manage the instances of Menu objects.
*
* @access   public
* @author	Cedric Francoys <cedric.francoys@easy-cms.org>
* @version 	MenusManager.class,v 0.1 
* @package	Menus
*/
class MenusManager extends CoreObject {

  var $dbManipulator;
	var $pagesManager;
	var $menuNodesManager;
	var $templatesManager;
	var $aclManager;	
	var $langId;
	
	/**
	 * @var array
	 */
  var $menusTable;


  function MenusManager(&$dbManipulator, &$aclManager, &$pagesManager, &$menuNodesManager, &$templatesManager, &$langId) {
    $this->debug('MenusManager::MenusManager, status : function invoked', 10, DBG_OPEN);
    $this->dbManipulator = &$dbManipulator;
		$this->langId = &$langId;
		$this->menusTable = array();
		$this->pagesManager = &$pagesManager;
		$this->menuNodesManager = &$menuNodesManager;
		$this->templatesManager = &$templatesManager;
		$this->aclManager = &$aclManager;
    $this->debug('MenusManager::MenusManager, status : function completed', 10, DBG_CLOSE);
  }
	
	function &getDBManipulator(){
		return $this->dbManipulator;
	}

	function &getMenuNodesManager(){
		return $this->menuNodesManager;
	}

	function &getTemplatesManager(){
		return $this->templatesManager;
	}

	function &getAclManager(){
		return $this->aclManager;
	}
	
	function &getPagesManager(){
		return $this->pagesManager;
	}
	
	function &getLangId(){
		return $this->langId;
	}

	function setMenuNodesManager(&$menuNodesManager){
		$this->menuNodesManager = &$menuNodesManager;
	}

  function loadMenu($id) {
    $this->debug('MenusManager::loadMenu, status : function invoked ('.$id.')', 10, DBG_OPEN);
    $loaded = false;
		if (($result = &$this->dbManipulator->getRecord(MENUS_TABLE, $id)) < 0 ){
			$this->debug("MenusManager::loadMenu, error : unable to get menu ($id)", 3);
		}
		else {
			while(($row = &$this->dbManipulator->fetchArray($result))){
  			$rootPageId = $row['root_page_id'];
  			$nameId     = $row['name_id'];
  			$templateId = $row['template_id'];
  			$sortField  = $row['sort_field'];
  			$sortOrder  = $row['sort_order'];
  			$sortingType= $row['sorting_type'];
  			$aclId      = $row['acl_id'];
  			$countShown = $row['count_shown'];
  			$maxLevel   = $row['max_level'];
  			$deleted    = $row['deleted'];
  			$published  = $row['published'];

  			$this->menusTable[$id] = &new Menu($id, $nameId, $templateId, $rootPageId, $sortField, $sortOrder);
  			$this->menusTable[$id]->setMenuSortingType($sortingType);
  			$this->menusTable[$id]->setMenuCountShown($countShown);
  			$this->menusTable[$id]->setMenuMaxLevel($maxLevel);
  			$this->menusTable[$id]->setMenuDeleted($deleted);
  			$this->menusTable[$id]->setMenuPublished($published);
  			$this->menusTable[$id]->setMenuAclId($aclId);
  			$this->menusTable[$id]->setMenuAcl($this->aclManager->getACL($aclId));
  			$this->menusTable[$id]->setMenuMenuNodesManager($this->menuNodesManager);
  			$this->menusTable[$id]->setMenuTemplatesManager($this->templatesManager);
        $this->loadMenuTranslation($id);
        $this->menusTable[$id]->loadcontent();
      }
      $loaded = false;
    }

    $this->debug('MenusManager::loadMenu, status : function completed', 10, DBG_CLOSE);
		return 1;	
  }

	/**
	 * Gets Languages
	 *
	 * Returns associative array of available languages
	 *
	 * @return array
	 * @todo discussion about the right place for this function (managers interface ? / dbManipulator ?)
	 */
	function getLangsArray() {
		$dbManipulator = &$this->getDBManipulator();
		$result        = $dbManipulator->getRecord(LANGUAGES_TABLE, -1, '', 'id', 'name');
		if (!$result) {
			return null;
		}
		$langsArray = array();
		while ($row = $dbManipulator->fetchArray($result)) {
			$langId = $row['id'];
			$langsArray[$langId] = $row['name'];
		}
		return $langsArray;
	}

	/**
	 * Stores Menu
	 *
	 * @param  integer $menuId
	 * @return integer Menu ID or <0 if error
	 */
  function storeMenu($menu_id)	{
    $this->debug('MenusManager::storeMenu, status : function invoked ('.$menu_id.')', 10, DBG_OPEN);
    $result = -1;

    $dbManipulator = &$this->getDBManipulator();
		$this->storeMenuTranslation($menu_id);
		$menu = &$this->getMenu($menu_id);

		if (is_null($menu)) {
			$this->debug('MenusManager::storeMenu, error : unknown menu ('.$menu_id.')', 3);
			$result = -1;
		}
    else {
  		$fieldsArray = array(
  			 'template_id'  => $menu->getMenuTemplateId(),
  			 'root_page_id' => $menu->getMenuRootPageId(),
  			 'sorting_type' => $menu->getMenuSortingType(),
  			 'sort_field'   => $menu->getMenuSortField(),
  			 'sort_order'   => $menu->getMenuSortOrder(),
  			 'max_level'    => $menu->getMenuMaxLevel(),
  			 'count_shown'  => $menu->getMenuCountShown(),
  			 'name_id'      => $menu->getMenuNameId(),
  			 'published'    => $menu->getMenuPublished(),
  			 'deleted'      => $menu->getMenuDeleted(),
  			 'acl_id'       => $menu->getMenuAclId()
  		);

  		// new menu : id 0 is not allowed in the DB
  		if($menu_id == 0){
  			if (!$dbManipulator->addRecord(MENUS_TABLE, $fieldsArray)) {
  				$this->debug('MenusManager::storeMenu, error : unable to create new menu', 1);
  				$result = -1;
  			}
  			else {
    			$newId = $dbManipulator->getLastId();
    			$menu->setMenuId($newId);
    			// register the menu with its new id
    			$this->setMenu($menu);
    			// free the temporary menu entry (0)
    			unset($this->menusTable[0]);
          $this->menusTable[0] = null;
    			$result = $newId;
    			// add a new root_menu_node

      		$fieldsArray = array(
      			 'menu_id'         => $newId,
      			 'page_id'         => $menu->getMenuRootPageId(),
      			 'parent_node_id'  => '0',
      			 'deleted'         => '0',
      			 'index'           => '1'
      		);
					if (($dbManipulator->addRecord(MENU_NODES_TABLE, $fieldsArray)) === false) {
						$this->debug('MenusManager::storeMenu, error : unable to add root menu node for menu ('.$newId.')', 3);
					}
        }
  		}
  		else {
  			if (!$this->dbManipulator->setRecord(MENUS_TABLE, $menu_id, $fieldsArray)) {
  				$this->debug('MenusManager::storeMenu, error : unable to update menu #'.$menu_id, 3);
  				$result = -1;
  			}
  			else {
          $result = $menu_id;
  			}
  		}
    }
    $this->debug('MenusManager::storeMenu, status : function completed', 10, DBG_CLOSE);
		return $result;
  }
	
  function removeMenu($id) {
  }


	/**
	 * Loads Menu Translation
	 *
	 * @param  integer $menuId
	 * @return boolean
	 */
	function loadMenuTranslation($menuId){
    $this->debug('MenusManager::loadMenuTranslation, status : function invoked ('.$menuId.')', 10, DBG_OPEN);
		$db = &$this->getDBManipulator();
		$loaded = false;
		if($menu = &$this->getMenu($menuId)){
			if($res = $db->getRecord(NAMES_TABLE, $menu->getMenuNameId())){
				if($fields = $db->fetchArray($res)){
					$langId = (int)$fields['lang_id'];
					$label = $fields['value'];
					$menu->setMenuName($label, $langId);
					$loaded = true;
				}
			}
      else {
				$this->debug("MenusManager::loadMenuTranslation, error : unknown menu ($menuId)", 2);
      }
		}
    $this->debug('MenusManager::loadMenuTranslation, status : function completed', 10, DBG_CLOSE);
		return $loaded;
	}

 function storeMenuTranslation($menuId) {
		$db = $this->getDBManipulator();
		$menu = &$this->getMenu($menuId, false);

		if (!$menu) {
			return false;
		}
		if ($menuId == 0) {
		// create new label id's for the menu fields
			$labels = array(
				'name'        => ''
			);
			$menuValues = array();
			foreach ($labels as $key => $value) {
				$record = array();
				$record['lang_id'] = '1';
				$record['value'] = '';
				$res = $db->addRecord(NAMES_TABLE, $record);
				if ($res && $db->getLastId()) {
					$menuValues[$key.'_id'] = $db->getLastId();
				}
			}
			$menu->setMenuValues($menuValues);
		}
		$labels = array(
			 'name'        => $menu->getMenuNameId()
		);
		$menuValues = array();
		$valuesTableLang = &$menu->getMenuValuesTable();
  	foreach($valuesTableLang as $langId => $valuesTable) {
			if(!is_int($langId)) {
				continue;
			}
			foreach ($labels as $key => $labelId) {
				$record = array();
				$record['value'] = $this->html_encode($valuesTable[$key]);
				if ($labelId == 0) {
					// create new record
					$record['lang_id'] = $langId;
					$res = $db->addRecord(NAMES_TABLE, $record);
					if ($res && $db->getLastId()) {
						$menuValues[$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);
					}
				}
			}
		}
		$menu->setMenuValues($menuValues);
		return true;
  }

	/**
	 * @return boolean
	 */
  function checkMenu($menuId) {
    return isset($this->menusTable[$menuId]);
  }

  function &getMenu($id) {
    if (!$this->checkMenu($id)){
			if ($this->loadMenu($id) < 0) {
				return null;
      }
		}		
		return $this->menusTable[$id];
  }


	function &getMenuTemplates() {
    $db = &$this->getDBManipulator();
		$menuTemplatesArray = array();
	  $result = &$db->getRecord(TEMPLATES_TABLE, -1, "type='easy_cms_page'");
	  while($row = &$db->fetchArray($result)){
       $menuTemplatesArray[$row['id']] = $row['name'];
    }
    return $menuTemplatesArray;
  }

	/**
	 * Gets New Menu
	 *
	 * @param integer $aclId
	 */
	function &getNewMenu($aclId=0) {
		$id          = 0;
		$nameId      = 0;
		$templateId  = 0;
		$rootPageId  = 0;
		$sortField   = '';
		$sortOrder   = 1;
		$sortingType = 1;

		$this->menusTable[0] = &new Menu($id, $nameId, $templateId, $rootPageId, $sortField, $sortOrder);
    $this->menusTable[0]->setMenuAclId($aclId);
    $this->menusTable[0]->setMenuSortingType($sortingType);
    $this->menusTable[0]->setMenuPublished(PUBLICATION_DEFAULT_VALUE);
		return $this->menusTable[0];
	}
	
  function setMenu(&$menu) {
    if ($this->checkMenu($menu->getId())){
			$this->debug("MenusManager.setMenu, warning : menu of id '".$menu->getId()."' already loaded in menu manager.", 3);
		}
    $this->menusTable[$menu->getId()] = &$menu;
		$this->debug("MenusManager.setMenu, status : success.", 10);		
		return 1;
	}	
	
	function menuExists($menu_id) {
		// try to load the menu
		$this->getMenu($menu_id);
		// returns true if the menu exists
		return $this->checkMenu($menu_id);
	}
	
	/**
	 * Updates Menu ACL
	 * 
	 * @param  integer $id Menu Id
	 * @param  integer $aclId ACL Id	 	 	 
	 */	 	
	function updateMenuACL($menuId, $aclId){
    $result = true;
		$db = &$this->getDBManipulator();
		$fields = array('acl_id' => $aclId);

		if(($db->setRecord(MENUS_TABLE, $menuId, $fields)) === false){
      // error
      $result = false;
		}
		return $result;
	}
}
?>