Location: PHPKode > scripts > Bookmarks class > Controller.php
<?php
/*
 * This file is part of the Booby project.
 * The booby project is located at the following location:
 * http://www.nauta.be/booby/
 *
 * Copyright (c) 2003 - 2004 Barry Nauta
 *
 * The Booby project is released under the General Public License
 * More detailes in the file 'gpl.html' or on the following
 * website: http://www.gnu.org and look for licenses
 *
 * Enjoy :-)
 */
@session_start ();
include ('base/checkLogin.php');
include_once ('base/config/preferenceConfiguration.php');
include ('menuItems.php');
include ('ext/Savant-1.4.1/Savant.php');
include_once ('base/util/globalFunctions.php');// added by Michael
/**
 * The Controller (abstract base class)
 *
 * @author Barry Nauta
 * @date July 2003 
 * @class 
 * @package be.nauta.booby.base
 * @copyright
 *
 * Copyright (c) 2003 - 2004 Barry Nauta <br />
 *
 * The Booby project is released under the General Public License
 * More detailes on the following
 * website: <code>http://www.gnu.org</code>
 * and look for licenses
 */
class Controller
{
	/**
	 * Specific preferences which can contain user definable parameters
	 * #protected
	 * @variable array preferences
	 */
	var $preferences;
	/**
	 * The template engine
	 * @private
	 * @variable object renderEngine
	 */
	var $renderEngine;

	/**
	 * The current action that is being processed
	 * @variable string action
	 */
	var $action;

	/**
	 * The identifier of the current item
	 * @variable integer itemId
	 */
	var $itemId;

	/**
	 * The identifier of the current item's parent
	 * @variable integer parentId
	 */
	var $parentId;

	/**
	 * Parameters, placeholder for almost anything
	 * @variable hashtable parameters
	 */
	var $parameters;

	/**
	 * The operations class
	 * @see Operations
	 * @variable object operations
	 */
	var $operations;

	/**
	 * The name of the renderer that will be used for processing
	 * @variable string renderer
	 */
	var $renderer;

	/**
	 * The objects that are the result of the action. The renderer typically
	 * renders these objects
	 * @variable array renderObjects
	 */
	var $renderObjects;

	/**
	 * The factory used to construct dedicated items
	 * @variable object itemFactory
	 */
	var $itemFactory;

	/**
	 * This name will be used for file lookup and equals the name of the 
	 * subdirectory of the item under the plugins directory
	 * @variable string pluginName the name of the plugin that is controlled
	 */
	var $pluginName;
	
	/**
	 * The name of the item that is controller by this controller. This name will be used to
	 * retrieve the appropriate view. For instance if the itemName is 'Bookmark' and the current
	 * action is 'add', the file 'addBookmark.tpl.php' might be resolved.
	 *
	 * @variable string itemName the name of the item that is controlled by this controller
	 */
	var $itemName;
	
	/**
	 * The title to display in the browser title bar
	 * @variable string title the title of the current plugin (usually preceded by 'Booby - ')
	 */
	var $title;
	
	// added by Michael
	/**
	 * The object responsable for access rights
	 * @variable RightsManager rightsManager the rightsManager object used
	 */
	var $rightsManager;	
	
	// added by Michael
	/**
	 * The navigation Mode : can be "private" (only items owned by the visitor are shown) 
	 * or "public" (all public items are shown). 
	 * @variable string navigationMode
	 */
	var $navigationMode;	
	
	/**
	 * Constructor. Fetches the action, the itemId and the parentId from 
	 * the request and assigns these parameters to the controller
	 * @param string theRenderEngine the renderEngine to use 
	 * (currently Smarty and phpSavant are supported)
	 */
	function Controller ()
	{
		// changed by Michael : added 2 lines :
		if (isset($_SESSION['navigationMode'])) $this->navigationMode = $_SESSION['navigationMode'];
		else $this->navigationMode = 'private'; // default. Put in config file / db?

		$this->itemId = 0;
		$this->parentId = 0;
		$this->parameters = array ();
 		// Fetch the action parameter from the request
		if (isset ($_GET['action']))
		{
			$this->action = $_GET['action'];
		}
		else if (isset ($_POST['action']))
		{
			$this->action = $_POST['action'];
		}
 		// Fetch the itemId parameter
		if (isset ($_GET['itemId']))
		{
			$this->itemId = $_GET['itemId'];
		}
		else if (isset ($_POST['itemId']))
		{
			$this->itemId = $_POST['itemId'];
			//die ($this->itemId);
		}
 		// Fetch the parentId parameter
		if (isset ($_GET['parentId']))
		{
			$this->parentId = $_GET['parentId'];
		}
		else if (isset ($_POST['parentId']))
		{
			$this->parentId = $_POST['parentId'];
		}
		$this->renderEngine =& new Savant ();
	}
	
	
	/**
	 * Returns the specific URL for this Controller
	 *
	 * @return string URL of this controller
	 */
	function getURL ()
	{
		return $this->getItemName () . "Controller.php";
	}

	/**
	 * Returns the template that is currently in use
	 *
	 * @return string the template that is currently in use
	 */
	function getTemplate ()
	{
		return $_SESSION['booby_template'];
	}

	/**
	 * Returns the name of the renderer that will be used
	 * for further processing
	 *
	 * @return string the renderer
	 */
	function getRenderer ()
	{
		return $this->renderer.'.tpl.php';
	}

	/**
	 * Returns the renderobjects that will be displayed
	 *
	 * @return array the render objects
	 */
	function getRenderObjects ()
	{
		return $this->renderObjects;
	}

	/**
	 * Sets the action that is requested by the user
	 *
	 * @param string theAction the requested action
	 */
	function setAction ($theAction)
	{
		$this->action = $theAction;
	}

	/**
	 * Returns the action that is requested by the user
	 *
	 * @return string theAction the requested action
	 */
	function getAction ()
	{
		return $this->action;
	}

	/**
	 * Retrieves the parentId of the item that is currently in use
	 *
	 * @return integer the parentId that is currently in use
	 */
	function getParentId ()
	{
		return $this->parentId;
	}

	/**
	 * Retrieves the itemId that is currently in use
	 *
	 * @return integer the itemId that is currently in use
	 */
	function getItemId ()
	{
		return $this->itemId;
	}

	/**
  	 * Returns the actions defined for this item only
	 * Abstract function.
 	 *
 	 * @return array an array of item specific actions (like search, 
	 * import etc.)
 	 */
	function getActions ()
	{
		return null;
	}

	/**
	 * Add a parameter to the existing parameter hashTable
	 *
	 * @param string key the key for the parameter
	 * @param string value the value of the parameter
	 */
	function addParameter ($key, $value)
	{
		$this->parameters [$key] = $value;
	}

	/**
	 * Retrieves the dictionary file by first tryin the language specific
	 * dictionary file, defaulting to the english version if the language specific file for
	 * the item does not exist and returns the contents as an array
	 * @return array the dictionary
	 */
	function getDictionary ()
	{
		// First load the english BASE dictionary file. This file MUST exist
		include ('base/lang/dictionary_EN.php');
		// If a language specific BASE dictionary exist, load this one as well.
		if (file_exists ('base/lang/dictionary_'.$_SESSION['language'] . '.php'))
		{
			include ('base/lang/dictionary_'.$_SESSION['language'] . '.php');
		}
		
		// Now load the english PLUGIN dictionary. This file MUST exist as well.
		include ('plugins/'.$this->pluginName.'/lang/dictionary_EN.php');
		// If a language specific PLUGIN dictionary exist, load this one as well.
		if (file_exists ('plugins/'.$this->pluginName.'/lang/dictionary_'.$_SESSION['language'] . '.php'))
		{
			include ('plugins/'.$this->pluginName.'/lang/dictionary_'.$_SESSION['language'] . '.php');
		}
		// Ok, we're done
		return $dictionary;  
	}
	
	/**
	 * Returns the filename that will be given to the template for display
	 * @return string the filename of the template file to show.
	 */
	function getTemplateFile ()
	{
		// Allow the template to override a specific file. If this file exist (the file in the
		// template directory), it will be loaded, otherwise the default (in the plugin directory)
		// will be loaded
		$renderer = 'templates/'.$this->getTemplate ().'/'.$this->getRenderer (); 
		if (!(file_exists ($renderer)))
		{
			$renderer = 'plugins/' . $this->pluginName.'/view/'.$this->getRenderer ();
		}
		return $renderer;
	}
	
	/**
	 * Display which basically means that the template will be invoked
	 */
	function display ()
	{
		global $menuItems, $menu;

		$this->renderEngine->assign('title', $this->getTitle ());
		$this->renderEngine->assign('menuItems', $menuItems);
		$this->renderEngine->assign('menu', $menu);
		$this->renderEngine->assign('dictionary', $this->getDictionary ());

		$this->renderEngine->assign('itemId', $this->getItemId ());
		$this->renderEngine->assign('parentId', $this->getParentId ());
		$this->renderEngine->assign('item',
			$this->getItem ($this->getUserName(), 
			$this->getItemId ()));
		$this->renderEngine->assign('parent',
			$this->getItem ($this->getUserName(), 
			$this->getParentId ()));
		$this->renderEngine->assign('parameters', 
			$this->getParameters ());
		$this->renderEngine->assign('action', 
			$this->getAction ());
		$this->renderEngine->assign('renderObjects', 
			$this->getRenderObjects ());
		$this->renderEngine->assign('renderActions', 
			$this->getActions ());
			
		$this->renderEngine->assign ('pluginName', $this->pluginName);
		$this->renderEngine->assign ('renderer', $this->getTemplateFile ());
		if (1)
		//if (isset ($_GET['debug']))
		{
			error_reporting(E_ALL);			
			$this->renderEngine->display('templates/'.$this->getTemplate().'/template.tpl.php');
			// todo add more
		}
		else
		{
			error_reporting(E_ERROR);
			@$this->renderEngine->display('templates/'.$this->getTemplate().'/template.tpl.php');
		}
	}


	/**
	 * Returns this controllers parameters
	 *
	 * @return hashtable the parameters (key/value based)
	 */
	function getParameters ()
	{
		return $this->parameters;
	}

	/**
	 * Returns the factory that knows how to create dedicated items
	 *
	 * @return object the item factory
	 */
	function getItemFactory ()
	{
		return $this->itemFactory;
	}

	/**
	 * Gets a specific item for a user (request is forwarded to the 
	 * operations class)
	 *
	 * @param string userId the identifier for the user
	 * @param string itemId the identifier for the item
	 * @return object the item for specified user with specified itemId
	 */
	function getItem ($userId, $itemId)
	{
		return $this->operations->getItem ($userId, $itemId);
	}

	/**
	 * Adds an item for a user (request is forwarded to the operations
	 * class)
	 *
	 * @param integer userId the identifier for the user
	 * @param object item the item to be added
	 */
	function addItem ($userId, $item)
	{
		return $this->operations->addItem ($userId, $item);
	}

	/**
	 * Retrieves the children of a specified item (request is forwarded 
	 * to the operations class)
	 *
	 * @param string userId the identifier of the user that issues the
	 * request
	 * @param integer itemId the identifier of the item for which we would
	 * like to have its children
	 * @return array all children for specified user and itemId
	 */
	function getChildren ($userId, $itemId)
	{
		return $this->operations->getChildren ($userId, $itemId);
	}

	/**
	 * Default action to add an item
	 */
	function addAction ()
	{
		$this->renderer = 'add'.$this->getItemName();
		$this->renderObjects = $this->operations->getItem
			($this->getUserName (), $this->getParentId ());
	}

	/**
	 * Items parameters has been provided, now really add it
	 * @protected
	 * @modified Michael Haussmann
	 */
	function addItemAction ()
	{
		$item = $this->itemFactory->requestToItem ();
		$errors = $this->itemFactory->requestToItemErrors ();
		if (empty($errors))
		{
			$this->operations->addItem ($this->getUserName (), 
				$item);
			$this->getShowItemsParameters ();
		}
		else
		{
			$this->addParameter("errors", $errors);
			$this->renderer = 'add'.$this->getItemName ();
			$this->renderObjects = $item;
		}		
	}

	/**
	 * Default modify Action
	 */
	function modifyAction ()
	{
		$this->renderer = 'modify'.$this->getItemName ();
		$this->renderObjects =	$this->operations->
			getItem ($this->getUserName (),	$this->itemId);
	}

	/**
	 * Items parameters has been provided, no really modify it
	 * @protected
	 * @modified Michael Haussmann
	 */
	function modifyItemAction ()
	{
		$dictionary = $this->getDictionary ();
		$baseItem = $this->operations->getItem ($this->getUserName (),	$this->itemId);
		$item = $this->itemFactory->requestToItem($baseItem);
		
		$itemOwner = $this->operations->getItemOwner ($item->itemId);

		if ($itemOwner != $this->getUserName ())
		{
			$this->renderEngine->assign ("message", $dictionary['modify_not_owner']);
		}
		else
		{
			$errors = $this->itemFactory->requestToItemErrors ();
			if (empty($errors))
			{
				//die (print_r ($item));
				$this->operations->modifyItem($this->getUserName (), $item);
			}
			else
			{
				$this->addParameter("errors", $errors);
				$this->renderer = 'modify'.$this->getItemName ();
				$this->renderObjects = $item;
			}
		}
	}

	/**
	 * Search for items
	 * #protected
	 */
	/**
	 * Search for items
	 * @protected
	 * @modifed Michael Haussmann
	 */
	function searchItemAction ()
	{
	   if($this->navigationMode == 'public') 
	   {
	    	$this->renderObjects = $this->operations->searchPublicItems
   					($this->getUserName (), 
					$_POST['field'], $_POST['value']);
	   }
	   else
	   {
			$this->renderObjects = $this->operations->searchItems
   					($this->getUserName (), 
					$_POST['field'], $_POST['value']);
	   }
	   $this->renderer = 'show'.$this->getItemName ().'s';
	}


	/**
	 * Default move action
	 * @protected
	 */
	function moveAction ()
	{
		// this is a shortcut. Give the first descendants of the root
		// as renderObjects. These will be evaluated afterwards...
		// Of course, the tree needs to be totally expanded
		$root = $this->getItem ($this->getUserName(), 0);
		$rootItems = $this->operations->getChildrenThatAreParent
			($this->getUserName(), $root->itemId);

		for ($i=0; $i<count($rootItems); $i++)
		{
			$this->addChildrenThatAreParent ($rootItems[$i]);
		}
		$this->renderObjects = $rootItems;
		$this->item = $this->operations->getItem ($this->getUserName (),
				$this->itemId);
		$this->renderer = 'move'.$this->getItemName ();
	}

	/**
	 * Default move action
	 * @param array multipleItemIds (i.e. 1, 5, 7)
	 * @protected
	 */
	function moveMultipleAction ($multipleItemIds)
	{
		// this is a shortcut. Give the first descendants of the root
		// as renderObjects. These will be evaluated afterwards...
		// Of course, the tree needs to be totally expanded
		$root = $this->getItem ($this->getUserName(), 0);
		$rootItems = $this->operations->getChildrenThatAreParent
			($this->getUserName(), $root->itemId);

		for ($i=0; $i<count($rootItems); $i++)
		{
			$this->addChildrenThatAreParent ($rootItems[$i]);
		}
		$this->renderObjects = $rootItems;
		$this->renderer = 'moveMultiple'.$this->getItemName ();
		$this->renderEngine->assign ('itemIds', $multipleItemIds);
	}

	/**
	 * @protected
	 */
	function multipleSelectAction ()
	{
		$this->getShowItemsParameters ();
		$this->renderer = 'multipleSelect'.$this->getItemName ();
	}
	
	/**
	 * Items parameters have been provided, now really move it
	 * @protected
	 */
	function moveItemAction ()
	{
		$itemOwner = $this->operations->getItemOwner ($this->getItemId());
		if ($itemOwner != $this->getUserName ())
		{
			$dictionary = $this->getDictionary ();
			$this->renderEngine->assign ("message", $dictionary['modify_not_owner']);
		}
		else
		{
			$this->operations->moveItem ($this->getUserName (),
				$this->itemId,	$this->parentId);
		}
	}

	/**
	 * Items parameters has been provided, no really delete
	 * @protected
	 */
	function deleteItemAction ()
	{
		$dictionary = $this->getDictionary ();
		$itemOwner = $this->operations->getItemOwner ($this->itemId);
		if ($itemOwner != $this->getUserName ())
		{
			$this->renderEngine->assign ("message", $dictionary['delete_not_owner']);
		}
		else
		{
			$this->operations->deleteItem ($this->getUserName (), 
				$this->itemId);
		}
	}

	/**
	 * Retrieves the parameters for a normal 'show' action which is
	 * often requested after another action (like delete/modify)
	 * @modified Michael Haussmann
	 */
	function getShowItemsParameters ()
	{
		// These 3 lines are used to provide the complete path of items, from current up to root
		$currentRoot = $this->operations->getItem ($this->getUserName (),$this->parentId);
		$ancestors = $this->operations->getAncestors ($currentRoot);
		$this->addParameter ("ancestors", array_reverse($ancestors));
//		$this->addParameter ("ancestors", $ancestors);
		
		if($this->navigationMode == 'public') return $this->getShowPublicItemsParameters();
		else return $this->getShowPrivateItemsParameters();
	}

	/**
	 * Retrieves the parameters for a normal 'show' action, 
	 * for the public navigationMode.
	 * @author Michael Haussmann
	 */
	function getShowPublicItemsParameters ()
	{
		$this->renderer = 'show'.$this->getItemName().'s';
		$rootItems = $this->operations->getPublicChildren
			($this->getUserName (), $this->getParentId ());
		$expand = $this->getExpanded ();
		if ($expand != null)
		{
			$this->addParameter ("expand", $expand);
		}

		for ($i=0; $i<count($rootItems); $i++)
		{
			$this->addExpandedPublicChildren ($rootItems[$i]);
		}
		$this->renderObjects = $rootItems;
	}
	
	/**
	 * Retrieves the parameters for a normal 'show' action, 
	 * for the private navigationMode.
	 *
	 * modified by MICHAEL
	 */
	function getShowPrivateItemsParameters ()
	{
		$this->renderer = 'show'.$this->getItemName().'s';
		$rootItems = $this->operations->getChildren
			($this->getUserName (), $this->getParentId ());

		$expand = $this->getExpanded ();
		if ($expand != null)
		{
			$this->addParameter ("expand", $expand);
		}

		for ($i=0; $i<count($rootItems); $i++)
		{
			$this->addExpandedChildren ($rootItems[$i]);
		}
		$this->renderObjects = $rootItems;
	}

	
	/**
	 * Sorts the items based on specified criteria
	 * @param integer parentId the id of the parent of which we would like to sort items
	 * @param string field the field on which we would like to sort
	 * @param string sortOrder either <code>ASC</code> or <code>DESC</code>
	 */
	function sortAction ($parentId, $field, $sortOrder)
	{
		$this->renderer = 'show'.$this->getItemName().'s';
		
		if($this->navigationMode == 'public') 
		{
			$this->renderObjects = $this->operations->getPublicSortedItems (
				$this->getUserName(), $parentId, $field, $sortOrder);		
		}
		else
		{
			$this->renderObjects = $this->operations->getSortedItems (
				$this->getUserName(), $parentId, $field, $sortOrder);	
		}
	}
	
	
	/**
	 * Sorts the items based on specified criteria
	 * @param string field the field on which we would like to sort
	 * @param string sortOrder either <code>ASC</code> or <code>DESC</code>
	 */
	function sortAllAction ($field, $sortOrder)
	{
		$this->renderer = 'show'.$this->getItemName().'s';
		if($this->navigationMode == 'public') 
		{
			$this->renderObjects = $this->operations->getAllPublicSortedItems (
				$this->getUserName(), $field, $sortOrder);	
		}
		else
		{
			$this->renderObjects = $this->operations->getAllSortedItems (
				$this->getUserName(), $field, $sortOrder);	
		}	
	}
	
	
	/**
	 * Adds the children of this item in the array, but only if this item
	 * is expanded itself
	 * @private
	 *
	 * @param object item the item
	 */
	function addExpandedChildren (&$item)
	{
		if ($item->isParent () && $this->isExpanded ($item->itemId))
		{
			$items = $this->operations->getChildren
				($this->getUserName (),$item->itemId);
			for ($i=0; $i<count($items); $i++)
			{
				$this->addExpandedChildren ($items[$i]);
				$item->addChild ($items[$i]);
			}
		}
	}

	/**
	 * Adds the public children of this item in the array, but only if this item
	 * is expanded itself
	 * @private
	 *
	 * @param object item the item
	 * @author Michael Haussmann
	 */
	function addExpandedPublicChildren (&$item)
	{
		if ($item->isParent () && $this->isExpanded ($item->itemId))
		{
			$items = $this->operations->getPublicChildren
				($this->getUserName (),$item->itemId);
			for ($i=0; $i<count($items); $i++)
			{
				$this->addExpandedPublicChildren ($items[$i]);
				$item->addChild ($items[$i]);
			}
		}
	}
	
	/**
	 * Adds the children of this item in the array
	 * @private
	 *
	 * @param object item the item
	 */
	function addChildrenThatAreParent (&$item)
	{
		if ($item->isParent ())
		{
			$items = $this->operations->getChildrenThatAreParent
				($this->getUserName (),$item->itemId);
			for ($i=0; $i<count($items); $i++)
			{
				$this->addChildrenThatAreParent ($items[$i]);
				$item->addChild ($items[$i]);
			}
		}
	}

	/**
	 * Adds the public children of this item in the array
	 * @private
	 *
	 * @param object item the item
	 * @author Michael Haussmann
	 */
	function addPublicChildrenThatAreParent (&$item)
	{
		if ($item->isParent ())
		{
			$items = $this->operations->getPublicChildrenThatAreParent
				($this->getUserName (),$item->itemId);
			for ($i=0; $i<count($items); $i++)
			{
				$this->addPublicChildrenThatAreParent ($items[$i]);
				$item->addChild ($items[$i]);
			}
		}
	}

	/**
	 * returns whether the specified itemId is expanded
	 * @private
	 *
	 * @param integer itemId the identifier which needs to be checked
	 * @return boolean <code>true</code> if this id is in the expanded 
	 * list, <code>false</code> otherwise
	 */
	function isExpanded ($itemId)
	{
		$expanded = explode (",", $this->getExpanded ());
		if ($this->getExpanded () == null)
		{
			return false;
		}
		// wildcard implementation
		if (count ($expanded == 1) && $expanded[0] == "*")
		{
			return true;
		}
		while (list ($key, $val) = each($expanded))
		{
			// yep, in the expanded list
			if ($val == $itemId)
			{
				// we might want to remove it from
				// the expanded list and put it in
				// the parsedExpanded list
				return true;
			}
		}
        	return false;
	}

	/**
	 * Returns the title of this Controller
	 *
	 * @return string the title of this controller
	 */
	function getTitle ()
	{
		return $this->title;
	}

	/**
	 * Returns the name of the item that is controller by this controller
	 *
	 * @return string the name of the item that is controlled by this controller
	 */
	function getItemName ()
	{
		return $this->itemName;
	}

	/**
	 * Returns the name of the plugin that is controlled by this controller. This name will be
	 * used for file lookup and equals the name of the subdirectory of the item under the
	 * plugins directory
	 *
	 * @return string the name of the plugin that is controlled by this controller
	 */
	function getPluginName ()
	{
		return $this->pluginName;
	}

	/**
	 * Returns the list of current expanded items for the controller
	 *
	 * @return string list of commanseperated item numbers
	 */
	function getExpanded ()
	{
	}
	
	function getUserName ()
	{
		return $_SESSION['boobyUsername'];
	}
	
	/**
	 * Direct action,  useful to simply implement simple but different actions.
	 * Simply calls a renderer named by the first parameter.
	 * Optionnaly instanciates the current Item, as renderObjects attribut. Default is false.
	 * 
	 * @param $actionName string the name of the renderer to be called
	 * @param $doRenderItem boolean if the current Item has to be instanciated. Optional. Default is false.
	 * @author Michael Haussmann
	 */
	function directAction ($actionName, $doRenderItem=false)
	{
		$this->renderer = $actionName.$this->getItemName();
		if($doRenderItem) $this->renderObjects = $this->operations->
			getItem ($this->getUserName (),	$this->itemId);
	}
	
}
?>
Return current item: Bookmarks class