Location: PHPKode > scripts > Lightweight Club Calendar > lc-calendar-0.9.4/core/lcc_core.class.php
<?php
/**
* LCC core - class file
*
* PHP Version 4
*
* @author <hide@address.com>
* @copyright Copyright (c) 2006, Benedikt Hallinger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, 51 Franklin St, Fifth Floor,
* Boston, MA  02110-1301  USA
*/

// Version of LCC
define('LCC_VERSION', '0.9.4');

/**
* Require LCC stuff that the core needs
*/
require_once dirname(__FILE__).'/lcc_message.class.php';            // message class
require_once dirname(__FILE__).'/lcc_view.class.php';               // View class
require_once dirname(__FILE__).'/lcc_driver.class.php';             // generic Driver all specific drivers will derive from
require_once dirname(__FILE__).'/lcc_userdriver.class.php';         // generic UserDriver the specific drivers will derive from
require_once dirname(__FILE__).'/lcc_eventdriver.class.php';        // generic EventDriver the specific drivers will derive from
require_once dirname(__FILE__).'/lcc_notedriver.class.php';         // generic NoteDriver the specific drivers will derive from
@include_once 'Calendar/Day.php';
class_exists('Calendar') or die('<b>LCC SETUP ERROR:</b> PEAR::Calendar not found! Please make sure that it is properly installed.');

/**
* Start a new Session or restore old one
*/
@session_start();


/**
* This is the core class of LCC.
*
* It manages the application and its configuration.
* Also this represents the access control layer.
*
* Start LCC as following:
* <code>
* $lcc_core = new LCC_Core($core_config);
* $lcc_core->startApplication();
* </code>
* For more information (the above example is very simple) on how to get LCC
* started refer to the documentation!
*/
class LCC_Core
{
	/**
	* LCCs core configuration
	*
	* The default config is initialised inside the Constructor of LCC_Core
	* to be able to assign some dynamic default values such as secure (full) paths.
	*
	* @var array
	* @access private
	*/
	var $_config = array();
	
	/**
	* LCC Default Access Control List
	*
	* Syntax:   $permission[{KEY}] = array({VALUE}, array(list of groupnames);
	* Example:  $permission['event_add'] = array(20, array('members','friends'));
	*           => this allows users in groups 'members' and 'friends' or users with
	*              equal or more level than 20 to add a new event.
	*
	* Beware that the syntax can vary, depending on the functionality.
	* See the default values here for more information.
	*
	* @var array
	* @access private
	* @see setACL()
	*/
	var $_acl = array(
			'calendar_view'                  => array(  0, array()),  // Viewing the calendar
			'event_view'                     => array(  0, array()),  // Viewing detail view of events
			'event_add'                      => array(100, array()),  // Adding new events
			'event_mod'                      => array(100, array()),  // Modify all existing events
			'event_mod_own'                  => array(  0, array()),  // Modify own events
			'event_del'                      => array(100, array()),  // Delete existing events
			'event_del_own'                  => array(  0, array()),  // Delete own events
			'event_subscribe_yes'            => array( 10, array()),  // Subscribe to an event
			'event_subscribe_no'             => array( 10, array()),  // Subscribe to an event
			'event_subscribe_unknown'        => array( 10, array()),  // Subscribe to an event
			'event_subscribe_group_yes'      => array( 10, array()),  // Subscribe group to an event
			'event_subscribe_group_no'       => array( 10, array()),  // Subscribe group to an event
			'event_subscribe_group_unknown'  => array( 10, array()),  // Subscribe group to an event
			'note_view'                      => array( 10, array()),  // View notes of events
			'note_add'                       => array( 10, array()),  // Add a note to any event
			'note_add_own'                   => array( 10, array()),  // Add a note to own events
			'note_mod'                       => array(100, array()),  // Modify any note
			'note_mod_own'                   => array( 10, array()),  // Modify own note
			'note_del'                       => array(100, array()),  // Delete any note
			'note_del_own'                   => array( 10, array()),  // Delete own notes
		);

	/**
	* Instance of the UserDriver
	*
	* This is the place where {@link getUserDriverInstance()}
	* will store a instance of the driver for further lookups
	*
	* @access private
	*/
	var $_userDriverInstance = false;

	/**
	* Instance of the EventDriver
	*
	* This is the place where {@link getEventDriverInstance()}
	* will store a instance of the driver for further lookups
	*
	* @access private
	*/
	var $_eventDriverInstance = false;
	
	/**
	* Instance of the NoteDriver
	*
	* This is the place where {@link getNoteDriverInstance()}
	* will store a instance of the driver for further lookups
	*
	* @access private
	*/
	var $_noteDriverInstance = false;

	
	/**
	* A reference to a UserDriver object representing the curent login
	*
	* It is fetched by {@link getAuthedUser()}
	*
	* @var LCC_UserDriver
	* @access private
	**/
	var $_authedUser = false;

	/**
	* Instance of LCC_View
	*
	* The core uses this to perform the output stuff.
	* Dont access ist directly but use {@link getViewInstance()}!
	* @access private
	*/
	var $_lccView = false;
	
	
	/**
	* Constructor - start LCC
	*
	* Use this method to initialize LCC.
	* This initializes the default config.
	*
	* You are able to override some or all of the parts of the default config,
	* just pass the parts of the array in $config.
	*
	* @param array $config      (optional) Parts of LCCs configuration as described in the documentation
	* @see $_config
	*/
	function LCC_Core($config = array())
	{
		// Set LCC Default config
		$this->_config = array(
			'data_dir'                    => dirname(__FILE__).'/../data/',    // What is the directory to store data in?
			'driver_dir'                  => dirname(__FILE__).'/../drivers/', // Wehre the drivers reside (with trailing slash)
			'design_dir'                  => dirname(__FILE__).'/../designs/', // Wehre the designs reside
			'design'                      => 'default',       // What UI to use
			'start_of_week'               => 1,               // What day is the first day of the week?
			'caching'                     => false,           // Use smartys caching? (NOT IMPLEMENTED YET)
			'guest_ok'                    => false,           // If true, create a guest login if not already logged in
			'guest_username'              => 'Anonymous',     // What username to assign to guest if $guest_ok=true
			'action_start'                => 'show_calendar'  // What LCC action should be called on start?
		);

		// override default config
		$this->setConfig($config);
	}

	/**
	* Returns the version of this LCC instance
	*
	* @return string
	* @static
	*/
	function getVersion()
	{
		return LCC_VERSION;
	}
	
	/**
	* Returns the value for a configuration item of the core
	*
	* This could be used by drivers, for example.
	*
	* @param string $key    The key in question
	* @return array
	* @see LCC_Core(), $_config
	*/
	function getConfig($key)
	{
		if(array_key_exists($key, $this->_config)){
			return $this->_config[$key];
		} else {
			die('<b>LCC_CORE ERROR:</b> LCC core does not know the configuration key "'.$key.'"!');
		}
	}
	
	/**
	* Set LCC core config
	*
	* With this method you can overwrite parts of the LCC core
	* default config.
	* It performes some basic modifications such as ensuring an ending slash
	* configuration items specififying a directory
	*
	* @param array $config      parts of config
	* @see $config
	*/
	function setConfig($config = array())
	{
		foreach ($config as $key => $value) {
			if (!is_array($value)) {
				if(array_key_exists($key, $this->_config)){
					// ensure trailing slashes for directorys
					if (($key == 'data_dir' || $key == 'driver_dir' || $key == 'design_dir') && substr($value,-1,1) != '/') {
						$value .= '/';
					}
					
					if ($key == 'start_of_week' && ($value < 0 || $value > 7)) {
						die('<b>LCC_CORE ERROR:</b> Configuration item "star_of_week" must be between 0 and 6!');
					}
					$this->_config[$key] = $value;
				} else {
					die('<b>LCC_CORE ERROR:</b> LCC core does not know the configuration key "'.$key.'"!');
				}
			} else {
				die('<b>LCC_CORE ERROR:</b> The value for "'.$key.'" is not allowed to be an array!');
			}
		}
	}

	/**
	* Loads a driver
	*
	* This is only for code factorisation. The driver is loaded
	* according to the driverType given. This method is called by the driver-specific methods,
	* like loadNoteDriver(), loadEventDriver() and so on...
	*
	* @access private
	* @param string $driverType     Name of the driver to be loaded. Must be in $_drivers array.
	* @param string $driverClass    Name of the class of the driver (eg "LCC_EventDriver_File", or just "File")
	* @param array  $driverConfig   Configuration of the driver (see drivers documentation)
	* @return DriverInstance        References to the loaded driver.
	*/
	function &_loadDriver($driverType, $driverClass, $driverConfig)
	{
		$supported_drivers = array('event', 'note', 'user'); // Possible drivers to be loaded
		$driver = false;
		
		// checks if driver type is in the drivers list
		if ( in_array(strtolower($driverType), $supported_drivers) )
		{
			if (empty($driverClass)) die('<b>LCC CORE ERROR:</b> Could not load NoteDriver: you must provide a driver name!');
			
			// Correct the driverType if it's lowercase or mistyped
			$driverType = ucfirst( strtolower($driverType) );

			// Correct if classname is not in long form
			if (!preg_match("/^LCC_" . $driverType . "Driver_(.+)/i", $driverClass)){
				$driverClass = 'LCC_' . $driverType . 'Driver_'.$driverClass;
			}
			// Check if Driver File was already loaded
			// If not, inlcude it
			if (!class_exists($driverClass)) {
				if (preg_match("/LCC_" . $driverType . "Driver_(.+)/i", $driverClass, $matches)){
					$filename = $this->getConfig('driver_dir').'/' . strtolower($driverType) . '/'.strtolower($matches[1]).'.class.php';
					if (is_readable($filename)) {
						include_once $filename;
						if (!class_exists($driverClass)) {
							die('<b>LCC CORE ERROR:</b> Unable to load ' . $driverType  . 'Driver "'.$driverClass.'", but class file was found.<br>Ensure
								that the filename matches the lowercased driver name! (eg "file.class.php" matches LCC_' . $driverType . 'Driver_File)');
						}
					} else {
						die('<b>LCC CORE ERROR:</b> Unable to load ' . $driverType . 'Driver classfile: "'.$filename.'"<br>Ensure the driver file is there and readable or include it yourself!');
					}
				} else {
					die('<b>LCC CORE ERROR:</b> Could not derive filename of classfile containing ' . $driverType . 'Driver! "'.$driverClass.'" does not start with "LCC_' . $driverType . 'Driver_"!');
				}
			}
			
			// Initialisation
			$driver = new $driverClass();

			// Check if class is compatible to core
			$driver->_checkDriver();

			// store reference to LCC_Core
			$driver->lcc_core =& $this;
			
			// invoke user defined init() method if present
			if (method_exists($driver, 'init')) {
				$driver->init();
			}
			
			// overwrite drivers default config
			$driver->setConfig($driverConfig);
			
			// invoke user defined configure() method if present
			if (method_exists($driver, 'configure')) {
				$driver->configure();
			}
			
			// Let's pass the freshly made driver to the calling loading method
			return $driver;
		} else {
			die('<b>LCC CORE ERROR:</b> Unauthorized driver type "' . $driverType . '".');
		}

			return $driver; // as it's unloaded, will return false
	}

	/**
	* Loads a EventDriver so LCC knows how to get/store event data
	*
	* The EventDriver gives LCC the ability to do lookups on the datasource
	* of the selected EventDriver. This way LCC can store the Event data in
	* various storage places like files and databases.
	* If this method isn't explicitely called, then the File driver will be used.
	*
	* To ensure compatibility with the core, several checks are performed on the
	* eventdriver. If something isn't okay LCC will die.
	*
	* If the classfile of the driver is not already loaded, this method
	* tries to include it from the configured driver directory (see @link $_config).
	*
	* @param string $driverClass   Name of the class of the driver (eg "LCC_EventDriver_File" or just "File")
	* @param array  $driverConfig  Configuration of the driver (see drivers documentation)
	* @return LCC_EventDriver   Reference to the loaded driver
	*/
	function &loadEventDriver($driverClass, $driverConfig)
	{
		$this->_eventDriverInstance = $this->_loadDriver('event', $driverClass, $driverConfig);
		return $this->_eventDriverInstance;
	}
	
	/**
	* Returns a instance to the selected EventDriver
	*
	* The core uses this instance to do other lookups in the backend.
	* If no EventDriver is loaded via {@link loadEventDriver()} then
	* the standard "File" driver will be used with its standard configuration.
	*
	* @return LCC_EventDriver       reference to selected EventDriver
	*/
	function &getEventDriverInstance()
	{
		if (!is_a($this->_eventDriverInstance, 'LCC_EventDriver')) {
			$this->loadEventDriver('LCC_EventDriver_File', array());
		}
		return $this->_eventDriverInstance;
	}
	
	/**
	* Loads a NoteDriver so LCC knows how to get/store note data
	*
	* The NoteDriver gives LCC the ability to do lookups on the datasource
	* of the selected NoteDriver. This way LCC can store the notes data in
	* various storage places like files and databases.
	* If this method isn't explicitely called, then the File driver will be used.
	*
	* To ensure compatibility with the core, several checks are performed on the
	* eventdriver. If something isn't okay LCC will die.
	*
	* If the classfile of the driver is not already loaded, this method
	* tries to include it from the configured driver directory (see @link $_config).
	*
	* @param string $driverClass   Name of the class of the driver (eg "LCC_EventDriver_File" or just "File")
	* @param array  $driverConfig  Configuration of the driver (see drivers documentation)
	* @return LCC_NoteDriver   Referece to the loaded driver
	*/
	function &loadNoteDriver($driverClass, $driverConfig)
	{
		$this->_noteDriverInstance = $this->_loadDriver('note', $driverClass, $driverConfig);

		return $this->_noteDriverInstance;
	}
	
	/**
	* Returns a instance to the selected NoteDriver
	*
	* The core uses this instance to do other lookups in the backend.
	* If no EventDriver is loaded via {@link loadNoteDriver()} then
	* the standard "File" driver will be used with its standard configuration.
	*
	* @return LCC_NoteDriver       reference to selected NoteDriver
	*/
	function &getNoteDriverInstance()
	{
		if (!is_a($this->_noteDriverInstance, 'LCC_NoteDriver')) {
			$this->loadNoteDriver('LCC_NoteDriver_File', array());
		}
		return $this->_noteDriverInstance;
	}

	/**
	* Loads a UserDriver so LCC knows how to get user/group data
	*
	* The Userdriver gives LCC the ability to do lookups on the datasource
	* of an external application to get knowledge what users are configured
	* there, what groups exist and which rights the users have.
	*
	* To ensure compatibility with the core, several checks are performed on the
	* userdriver. If something isn't okay LCC will die.
	*
	* If the classfile of the driver is not already loaded, this method
	* tries to include it from the configured driver directory (see @link $_config).
	*
	* @param string $driverClass   Name of the class of the driver (eg "LCC_UserDriver_Simple" or just "Simple")
	* @param array  $driverConfig  Configuration of the driver (see drivers documentation)
	* @return LCC_UserDriver       Reference to the loaded driver
	*/
	function &loadUserDriver($driverClass, $driverConfig)
	{
		// storing for further reference
		$this->_userDriverInstance = $this->_loadDriver('user', $driverClass, $driverConfig);

		return $this->_userDriverInstance;
	}
	
	/**
	* Returns a instance to the loaded UserDriver
	*
	* The core uses this instance to do other lookups in the backend.
	*
	* @return LCC_UserDriver       reference to loaded UserDriver
	*/
	function &getUserDriverInstance()
	{
		if (is_a($this->_userDriverInstance, 'LCC_UserDriver')) {
			return $this->_userDriverInstance;
		} else {
			die('<b>LCC CORE ERROR:</b> No UserDriver loaded! Use "loadUserDriver()" to load an Userdriver!');
		}
	}

	/**
	* Set access control list
	*
	* With this method you can overwrite parts of the default acl.
	*
	* Some checks are performed so it is ensured that no corrupt stuff is written to
	* the internal acl list.
	*
	* @param string $action       Name of the action
	* @param int    $level        What Level is needed for that action
	* @param array  $groups       What groups are needed for that action (no group = empty array)
	* @see $_acl, checkRight(), verifyPermission()
	*/
	function setACL($action, $level, $groups)
	{
		if (!is_array($groups)) {
			die('<b>LCC_CORE ERROR:</b> setACL(): $groups must be an array of groups, even if empty or only one group name!');
		}
		if (!is_int($level)) {
			die('<b>LCC_CORE ERROR:</b> setACL(): $level must be a number!');
		}
		if (!array_key_exists($action, $this->_acl)){
			die('<b>LCC_CORE ERROR:</b> LCC core does not know the ACL action "'.$action.'"!');
		}
		
		$this->_acl[$action] = array($level, $groups);
	}
	
	/**
	* Checks if a user (or the current user) is allowed to perform a specific action.
	*
	* The permission is granted if both the user has enough level AND
	* is a member in the groups needed for that action.
	* If the action doesn't require group membership, only
	* the level will be evaluated.
	*
	* The list of actions is visible in {@link $_acl}, or see "configuring_lcc.txt"
	*
	* @param string  $action
	* @param string  $username  if omitted, then it defaults to the currently logged in user.
	* @return boolean
	*/
	function checkRight($action, $username = false)
	{
		$sufficient_group = false;
		$sufficient_level = false;

		if (!$username) {
			$username = $this->getAuthedUser();
		}

		if (strlen($username) > 0) {
			if (array_key_exists($action, $this->_acl)) {
				$userdriver =& $this->getUserDriverInstance();

				$level  = $userdriver->getLevel($username);
				if ($level === false) die('<b>LCC_CORE ERROR:</b> Could not get userlevel for user '.$username);

				$groups = $userdriver->getGroups($username);
				if ($groups === false) die('<b>LCC_CORE ERROR:</b> Could not get groups for user '.$username);
			
				$level_needed  = $this->_acl[$action][0];
				$groups_needed = $this->_acl[$action][1];
		
				// check for level
				if ($level >= $level_needed) {
					// User is higher level than needed
					$sufficient_level = true;
				}
				
				// check for groups
				// privilegue is granted, if either no groups are needet for the action or
				// if the user is in one needed group
				if (count($groups_needed) > 0) {
					foreach ($groups as $group) {
						if (in_array($group, $groups_needed)) {
							$sufficient_group = true;
							break; // No need to go further : the user has the rights.
						}
					}
				} else {
					$sufficient_group = true;
				}


			} else {
				die('<b>LCC_CORE ERROR:</b> LCC core does not know the ACL action "'.$action.'"!');
			}
		}


		return $sufficient_level && $sufficient_group;
	}
	
	/**
	* Check right of current authenticated user (Blocking)
	*
	* This is a convinience shorthand for {@link checkRight()}.
	* If privilegues are not sufficient, a nice error message will be printed
	* and script execution stopped.
	*
	* @param string  $action
	* @return true    True or end of script execution
	*/
	function verifyPermission($action)
	{
		$username = $this->getAuthedUser();
		$view =& $this->getViewInstance();
		
		if (!$this->checkRight($action, $username)) {
			$msg = new LCC_Message($view->getLang('lcc_error_missing_privilegues'), 'status_failed');
			$view =& $this->getViewInstance();
			$view->addMessage($msg);
			$view->render();
			exit;
		} else {
			return true;
		}
	}
	
	/**
	* Returns the username of the currently logged in user (Blocking)
	*
	* This method tries to fetch the username of the currently logged in user.
	* It performes this task by calling the fetchLogin() method of the
	* selected userDriver.
	* If something went wrong in the driver, two different things can happen:
	* 1) If the core is configured to create a guest login, it will do so.
	*    Configuration items are: 'guest_ok', 'guest_username'
	*    The guest account will be created using the {@link LCC_UserDriver_Simple "simple" userdriver}
	*    with level = 0 and no groups assigned.
	*
	* 2) the method prints an error message and exits.
	*
	* If "non blocking" mode is requested, then FALSE will be returned on error.
	* This mode gets used by the view instance to assign the username to the templates
	*
	* @param bool $non_blocking       if set to true, no error will be printed but FALSE returned on error
	* @return string
	*/
	function getAuthedUser($non_blocking = false)
	{
		if (!$this->_authedUser) {
			$userdriver =& $this->getUserDriverInstance();
			$username   =  $userdriver->fetchLogin();
			if ($username === false || !is_string($username) || strlen($username) == 0) {
				// Failed getting username - should we instanciate a guest account?
				if ($this->getConfig('guest_ok')) {
					$guest_config = array(
						'username' => $this->getConfig('guest_username')
					);
					$this->loadUserDriver('Simple', $guest_config);

					// try to fetch username to be sure everything worked okay:
					$username = $userdriver->fetchLogin();
					if ($username === false || !is_string($username) || strlen($username) == 0) {
						if (!$non_blocking) {
							$view =& $this->getViewInstance();
							$msg = new LCC_Message('<b>Error creating guest login!</b><br>'.$view->getLang('lcc_error_missing_login'), 'status_failed');
							$view->addMessage($msg);
							$view =& $this->getViewInstance();
							$view->render();
							exit;
						}
					} else {
						$this->_authedUser = $username;
					}
				} else {
					if (!$non_blocking) {
						$view =& $this->getViewInstance();
						$msg = new LCC_Message($view->getLang('lcc_error_missing_login'), 'status_failed');
						$view->addMessage($msg);
						$view =& $this->getViewInstance();
						$view->render();
						exit;
					}
				}
			} else {
				$this->_authedUser = $username;
			}
		}

		return $this->_authedUser; // false by default, and if unchanged within 'if' statement. Otherwise, will be the username.
	}
	
	/**
	* Returns a reference to the LCC_View instance
	*
	* If no instance is found so far, a new one will be created.
	* The instance is configured via the LCC_Core, but since this
	* returns a reference, you can take the instance and modify it.
	* But be sure to get it via the "&" operator!
	*
	* @return LCC_View
	*/
	function &getViewInstance()
	{
		if (!is_a($this->_lccView, 'LCC_View')) {
			$this->_lccView = new LCC_View($this);
		}
		return $this->_lccView;
	}
	
	/**
	* Print out the style definition for the selected Design
	*
	* This method does just route this call to the LCC_View instance,
	* which is truly responsible for output stuff
	*/
	function printCSS()
	{
		$view =& $this->getViewInstance();
		$view->printCSS();
	}


	/*
	* Following: All Actions LCC can perform
	*
	* This Actions are called through the selected Design
	* (UI = UserInterface) and routet to the core via calling
	* startApplication();
	*/

	/**
	* Execute LCC Action
	*
	* This retriggers {@link startApplication} to enable you to
	* perform different tasks from the templates.
	* You can use this for example, to display the notes
	* if the user looks at the details of an event
	*
	* @param string $lcc_action         LCC Action that should be performed
	* @param array $parms               Optional parameters for the action, $key=>$value pairs
	* @param boolean $direct_rendering  Enable/disable direct rendering (you should not need to set this)
	*/
	function performAction($lcc_action, $parms = array(), $direct_rendering = true)
	{
		if (is_string($lcc_action) && !empty($lcc_action)) {
			$oldget = $_GET;
			$_GET = array();
			$_GET['lcc_action'] = $lcc_action;
			foreach ($parms as $arg => $value) {
				if (!is_array($arg) && !is_array($value)) {
					$_GET[$arg] = $value;
				} else {
					die('LCC_CORE ERROR: performAction() can only use strings as parameters!');
				}
			}
			if ($direct_rendering) {
				$view =& $this->getViewInstance();
				$view->setDirectRendering($direct_rendering);
				$this->startApplication();
				$_GET = $oldget;
				$view->setDirectRendering(false);
				return $view->flushDirectRenderingCache(); // return what was rendered dircetly
			} else {
				$this->startApplication();
				$_GET = $oldget;
			}
		}
	}

	/**
	* Application handling
	*
	* Perform Actions requested by the user and print out
	* the page that results from this requests.
	* This method should be invoked by the external php script that
	* initializes LCC.
	*/
	function startApplication()
	{
		$view        =& $this->getViewInstance();
		$eventDriver =& $this->getEventDriverInstance();
		$noteDriver  =& $this->getNoteDriverInstance();
		$userDriver  =& $this->getUserDriverInstance();
		$authed_user =& $this->getAuthedUser();
		
		// Get actions, that need to be performed
		switch ($_GET['lcc_action']) {
			
			/*
			* Show detail view of a event
			*/
			case 'show_event':
				$this->verifyPermission('event_view');
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id'])) {
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_id']);
					if ($event_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
					} else {
						$view->printEventDetails($event_data);
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Show notes of event
			*/
			case 'show_notes':
				$this->verifyPermission('note_view');
				if (isset($_GET['lcc_eventid']) && !empty($_GET['lcc_eventid'])) {
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_eventid']);
					if ($event_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
					} else {
						$notes = $noteDriver->getNotes($event_data['id']);
						$notes_data = array();
						if (!is_array($notes)) {
							die('<b>LCC_Core action show_notes:</b> There was a error in the selected NoteDriver fetching the notes for an event!');
						} else {
							// resolve notes data
							foreach ($notes as $id) {
								$note_data = $noteDriver->getAllData($id);
								if ($note_data === false) {
									die('<b>LCC_Core action show_notes:</b> There was a error in the selected NoteDriver fetching the datafor a note!');
								} else {
									$notes_data[$note_data['id']] = $note_data;
								}
							}
							$view->printNotes($notes_data);
						}
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Delete existing events
			*/
			case 'delete_event':
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id'])) {
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_id']);
					if ($event_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
					} else {
						// Evaluate ACL
						// check if we got global deletion right or
						// if we are allowed to delete our own event, if this is our own event
						if (!$this->checkRight('event_del')) {
							// no global deletion right; test if this is our event
							if ($event_data['author'] === $authed_user) {
								$this->verifyPermission('event_del_own');
							} else {
								$this->verifyPermission('event_del'); // this drops a error since we dont have this right
							}
						}
						
						// We have the permission to delete events
						// First, let's delete the attached notes!
						$notes = $noteDriver->getNotes($_GET['lcc_id']);
						// Loops through the event notes. If none, then there won't be any turn.
						if (false !== $notes) {
							foreach ($notes as $note_id) {
								if ( !$noteDriver->deleteNote($note_id) ) {
									// Displays a message only on error, otherwise, cleanup quietly
									$msg = new LCC_Message($view->getLang('lcc_error_note_deletion', 'status_failed'));
									$view->addMessage($msg);
								}
							}
						}

						$notes = $noteDriver->getNotes($_GET['lcc_id']); // The array should be empty by now.

						if (empty($notes) && $eventDriver->deleteEvent($_GET['lcc_id'])) {
							// Show msg and display calendar view
							$msg = new LCC_Message($view->getLang('lcc_success_event_deletion'), 'status_ok');
							$view->addMessage($msg);
							$view->printMonthCalendar();
						} else {
							// Show msg and event data again
							$msg = new LCC_Message($view->getLang('lcc_error_event_deletion'), 'status_failed');
							$view->addMessage($msg);
							$this->verifyPermission('event_view');
							$view->printEventDetails($event_data);
						}
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Edit event handles adding new events and modifying old ones
			*/
			case 'edit_event':
				// See, if we need to create a new event
				// (by default, we assume it's a new one)
				$write_to_id = null;
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id'])) {
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_id']);
					if ($event_data !== false) {
						$write_to_id = $_GET['lcc_id'];  // use provided id
					} else {
						// drop error since event does not exist
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
						break;
					}
				}
				
				// Check ACL Security for action
				// and assign old event data if necessary
				if (null === $write_to_id) {
					$this->verifyPermission('event_add');
					$view->assign('data', false);
				} else {
					// check if we got global modification right or
					// if we are allowed to modify our own event, if this is our own event
					if (!$this->checkRight('event_mod')) {
						// no global mod right; test if this is our event
						if ($event_data['author'] === $authed_user) {
							$this->verifyPermission('event_mod_own');
						} else {
							$this->verifyPermission('event_mod'); // this drops a error since we dont have this right
						}
					}
					$view->assign_by_ref('data', $event_data);
				}
				
				// check what needs to be done now
				// if we got new data, we need to apply it to the backend,
				// if not, we need to display the editable view
				if (isset($_POST['lcc_new_data']) && is_array($_POST['lcc_new_data'])) {
					// Trim values
					foreach ($_POST['lcc_new_data'] as $field => $value) {
						$_POST['lcc_new_data'][$field] = trim($value);
					}
					
					// check for mandatory fields:
					$mandatory_errors  = $eventDriver->checkMandatory($_POST['lcc_new_data']);
					
					// check for write protection and syntax:
					$validation_errors = array();
					foreach ($_POST['lcc_new_data'] as $field => $value) {
						if ($eventDriver->checkField($field, 'writable')) {
							// Field is writable, check syntax
							if (!$eventDriver->checkField($field, 'validate', $value)) {
								array_push($validation_errors, $field); // mark this field as not-okay
							}
						} else {
							// We simply ignore this field at update if it isn't writable
							// The design should take care to set the field to "disabled"
							// because the users won't recognize its readonly state perhaps
							unset($_POST['lcc_new_data'][$field]);
						}
					}
					
					// check for date/time mismatch if fields are validated:
					// otherwise date conversion may drop an error
					$mismatch_errors = array();
					if (count($validation_errors) == 0 && count($mandatory_errors) == 0) {
						// Support for german date syntax dd.mm.yyyy, which is not understood by strtotime()
						if (preg_match('/^(\d\d?)\.(\d\d?)\.(\d{4})$/', $_POST['lcc_new_data']['start_date'], $matches)) {
							$_POST['lcc_new_data']['start_date'] = $matches[3].'-'.$matches[2].'-'.$matches[1];
						}
						if (preg_match('/^(\d\d?)\.(\d\d?)\.(\d{4})$/', $_POST['lcc_new_data']['end_date'], $matches)) {
							$_POST['lcc_new_data']['end_date'] = $matches[3].'-'.$matches[2].'-'.$matches[1];
						}

						// Convert to timestamps for easier validation
						// Times are relative to dates, so always bigger or equal
						$date_start = strtotime($_POST['lcc_new_data']['start_date']);
						$date_end   = strtotime($_POST['lcc_new_data']['end_date']);
						$time_start = strtotime($_POST['lcc_new_data']['start_time'], $date_start);
						$time_end   = strtotime($_POST['lcc_new_data']['end_time'], $date_end);

						// Validate conversion to timestamp
						if ($date_start >= 0 && $date_end >= 0 && $time_start >= 0 && $time_end >= 0 ) {
							
							// Validate logical correctness, if timestamp conversion was okay
							if ($end_date < $start_date) {
								array_push($mismatch_errors, 'end_date'); // mark this field as not-okay
							} else {
								// Date is okay, validate time, if event start and event end is at the
								// same day. Additionally start and end time must be given given
								// because time is only informal then
								// (non-informal state should be enforced via mandatory field switch)
								$sameday = ($date_end - $date_start < 86400) ? true : false;
								if ($sameday && $time_start != $time_end && $time_start > $date_start && $time_end > $date_end) {
									if ($time_end <= $time_start) {
										array_push($mismatch_errors, 'end_time'); // mark this field as not-okay
									}
								}
							}
						
						} else {
							// die because of hard-error
							die('<b>LCC_Core action edit_event:</b> Date/Time could not be converted to timestamp!
								Ensure Proper format for date/time fields using setFieldSecurity()! (must support strtotime())');
						}
					}
					
					// if there were errors, we need to show them together with the entered data
					// else we apply data to the backend and show a ok-message
					if (count($mandatory_errors) == 0 && count($validation_errors) == 0 && count($mismatch_errors) == 0) {
						// Assign editing metadata
						if (null === $write_to_id) {
							// new event
							$_POST['lcc_new_data']['author']               = $authed_user;
							$_POST['lcc_new_data']['created']              = time();
							$_POST['lcc_new_data']['last_modified']        = '';
							$_POST['lcc_new_data']['last_modified_author'] = '';
							$_POST['lcc_new_data']['subscribed_yes']       = '';
							$_POST['lcc_new_data']['subscribed_no']        = '';
							$_POST['lcc_new_data']['subscribed_unknown']   = '';
						} else {
							// existing event
							$_POST['lcc_new_data']['author']               = $event_data['author'];
							$_POST['lcc_new_data']['created']              = $event_data['created'];
							$_POST['lcc_new_data']['last_modified']        = time();
							$_POST['lcc_new_data']['last_modified_author'] = $authed_user;
							$_POST['lcc_new_data']['subscribed_yes']       = $event_data['subscribed_yes'];
							$_POST['lcc_new_data']['subscribed_no']        = $event_data['subscribed_no'];
							$_POST['lcc_new_data']['subscribed_unknown']   = $event_data['subscribed_unknown'];
						}
						
						// Assign converted date data to data,
						// in order to store timestamps in the backend
						$_POST['lcc_new_data']['start_date'] = $date_start;
						$_POST['lcc_new_data']['end_date']   = $date_end;
						
						// Assign combined event dates so this metadata gets stored
						$_POST['lcc_new_data']['event_start'] = $time_start;
						$_POST['lcc_new_data']['event_end']   = $time_end;
						
						

						$written_id = $eventDriver->storeData($write_to_id, $_POST['lcc_new_data']);
						if ($written_id === false) {
							$msg = new LCC_Message($view->getLang('lcc_error_event_storage'), 'status_failed');
							$view->addMessage($msg);
						} else {
							// looked good, fetch data and assign to template
							$new_event_data = $eventDriver->getAllData($written_id);
							if ($new_event_data === false) {
								// no such event !? probably the eventDriver didn't return the right id after storage?
								die('<b>LCC_Core action edit_event:</b> The Event with ID "'.$written_id.'" (returned from the selected EventDriver->storeData()) could not be found in event backend!<br>
								Storage probably went okay, but the selected EventDriver "'.get_class($eventDriver).'" looks broken!');
							} else {
								$view->assign_by_ref('data', $new_event_data);
								$msg = new LCC_Message($view->getLang('lcc_success_event_storage'), 'status_ok');
								$view->addMessage($msg);
							}
						}
					} else {
						// Output errors
						// The core makes some dynamic lookups to the language file
						// TODO: code factorization.
						if (count($mandatory_errors) > 0) {
							$errortext = '<b>'.$view->getLang('lcc_error_field_mandatory').'</b>';
							foreach ($mandatory_errors as $field) {
								$errortext .= $view->getLang('lcc_event_desc_'.$field).', ';
							}
							$msg = new LCC_Message(substr($errortext, 0, -2), 'status_failed');
							$view->addMessage($msg);
						}
						if (count($validation_errors) > 0) {
							$errortext = '<b>'.$view->getLang('lcc_error_field_invalid').'</b><br>';
							foreach ($validation_errors as $field) {
								$errortext .= $view->getLang('lcc_event_desc_'.$field).': '.$view->getLang('lcc_event_msg_'.$field).'<br>';
							}
							$msg = new LCC_Message(substr($errortext, 0, -4), 'status_failed');
							$view->addMessage($msg);
						}
						if (count($mismatch_errors) > 0) {
							foreach ($mismatch_errors as $field) {
								$errortext .= $view->getLang('lcc_event_desc_'.$field).': '.$view->getLang('lcc_error_date_mismatch').'<br>';
							}
							$msg = new LCC_Message(substr($errortext, 0, -4), 'status_failed');
							$view->addMessage($msg);
						}
					}
				}
				$view->display('event_editable.tpl');
			break;
			
			/*
			* Subscribe yourself to an event or change subscription
			*/
			case 'event_subscribe':
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id']) &&
				    isset($_GET['lcc_interest']) && !empty($_GET['lcc_interest'])) {
				    // firtstly check permission for that interest
					switch ($_GET['lcc_interest']) {
						case 'yes':
							$this->verifyPermission('event_subscribe_yes');
						break;
						case 'no':
							$this->verifyPermission('event_subscribe_no');
						break;
						case 'unknown':
							$this->verifyPermission('event_subscribe_unknown');
						break;
						default:
							die('<b>LCC_Core action event_subscribe:</b> Illegal interest selected!');
					}
				
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_id']);
					if ($event_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
					} else {
						$result = $eventDriver->subscribeUser($_GET['lcc_id'], $authed_user, $_GET['lcc_interest']);
						if ($result) {
							$msg = new LCC_Message($view->getLang('lcc_success_event_subscription'), 'status_ok');
						} else {
							$msg = new LCC_Message($view->getLang('lcc_error_event_subscription'), 'status_failed');
						}

						$view->addMessage($msg);
						$this->verifyPermission('event_view');
						$view->printEventDetails($event_data);
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Subscribe your group members to an event
			*/
			case 'event_subscribe_group':
				if (isset($_GET['lcc_group']) && !empty($_GET['lcc_group']) &&
				    isset($_GET['lcc_id']) && !empty($_GET['lcc_id']) &&
				    isset($_GET['lcc_interest']) && !empty($_GET['lcc_interest'])) {
					// firtstly check permission for that interest
					switch ($_GET['lcc_interest']) {
						case 'yes':
							$this->verifyPermission('event_subscribe_group_yes');
						break;
						case 'no':
							$this->verifyPermission('event_subscribe_group_no');
						break;
						case 'unknown':
							$this->verifyPermission('event_subscribe_group_unknown');
						break;
						default:
							die('<b>LCC_Core action event_subscribe_group:</b> Illegal interest selected!');
					}
					// Now check group leadership
					$leaded_groups = $userDriver->getGroupsLeaded($authed_user);
					if (!in_array($_GET['lcc_group'], $leaded_groups)) {
						$msg = new LCC_Message($view->getLang('lcc_error_missing_privilegues'), 'status_failed');
						$view->addMessage($msg);
						$view->render();
						exit;
					}
				
					// ID was passed; see if the ID exists
					$event_data = $eventDriver->getAllData($_GET['lcc_id']);
					if ($event_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
						$view->addMessage($msg);
					} else {
						// Fetch group users
						$group_users = $userDriver->getGroupMembers($_GET['lcc_group']);
						if (is_array($group_users)) {
							$errors = 0;
							// Subscribe the users
							foreach ($group_users as $user) {
								$result = $eventDriver->subscribeUser($_GET['lcc_id'], $user, $_GET['lcc_interest']);
								if (!$result) {
									$errors++;
								}
							}
							if ($errors == 0) {
								$msg = new LCC_Message($view->getLang('lcc_success_event_subscription'), 'status_ok');
							} else {
								$msg = new LCC_Message($view->getLang('lcc_error_event_subscription'), 'status_failed');
							}

							$view->addMessage($msg);
							$this->verifyPermission('event_view');
							$view->printEventDetails($event_data);
						}
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Edit/Add a note to an event
			*
			* At least a lcc_eventid must be submitted!
			*/
			case 'edit_note':
				// see, if we need to create a new note
				// (by default, we assume it's a new one)
				$write_to_id = null;
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id'])) {
					// ID was passed; see if the ID exists
					$note_data = $noteDriver->getAllData($_GET['lcc_id']);
					if ($note_data !== false) {
						$write_to_id = $_GET['lcc_id'];  // use provided id
					} else {
						// drop error since note does not exist
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_note'), 'status_failed');
						$view->addMessage($msg);
						break;
					}
				}
				
				// See if event exists
				// FIXME: duplicated code again :P -> needs to be checked if factorisation is okay
				$event_data = false; // as ever, we assume a error by default
				if (isset($_GET['lcc_eventid']) && !empty($_GET['lcc_eventid'])) {
					$event_data = $eventDriver->getAllData($_GET['lcc_eventid']);
				}

				if ($event_data === false) {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
					$view->addMessage($msg);
					$view->render();
					return;
				}
				
				// Check ACL Security for action
				// and assign old note data if necessary
				if (null !== $write_to_id) {
					if (!$this->checkRight('note_add')) {
						// if we didn't have global add right, we
						// might be able to add to our own event
						if ($event_data['author'] === $authed_user) {
							$this->verifyPermission('note_add_own');
						} else {
							// This will drop a die since we didn't have this right
							$this->verifyPermission('note_add');
						}
					}

				} else {
					// check if we got global modification right or
					// if we are allowed to modify our own note
					if (!$this->checkRight('note_mod')) {
						// no global mod right; test if this is our note
						if ($note_data['author'] === $authed_user) {
							$this->verifyPermission('note_mod_own');
						} else {
							// This will drop a die since we didn't have this right
							$this->verifyPermission('note_mod_own');
						}
					}
				}
				
				// check what needs to be done now
				// if we got new data, we need to apply it to the backend,
				// if not, we need to display the editable view
				// TODO: As far as I can tell, this is a copy of the edit_event... So maybe there's a way to
				// factorize all (or at least : a large part) of that.
				if (isset($_POST['lcc_new_data']) && is_array($_POST['lcc_new_data'])) {
					// Trim values
					foreach ($_POST['lcc_new_data'] as $field => $value) {
						$_POST['lcc_new_data'][$field] = trim($value);
					}
					
					// check for mandatory fields:
					$mandatory_errors  = $noteDriver->checkMandatory($_POST['lcc_new_data']);
					
					// check for write protection and syntax:
					$validation_errors = array();
					foreach ($_POST['lcc_new_data'] as $field => $value) {
						if ($noteDriver->checkField($field, 'writable')) {
							// Field is writable, check syntax
							if (!$noteDriver->checkField($field, 'validate', $value)) {
								array_push($validation_errors, $field); // mark this field as not-okay
							}
						} else {
							// We simply ignore this field at update if it isn't writable
							// The design should take care to set the field to "disabled"
							// because the users won't recognize its readonly state perhaps
							unset($_POST['lcc_new_data'][$field]);
						}
					}
					
					// check for date/time mismatch if fields are validated:
					// otherwise date conversion may drop an error
					$mismatch_errors = array();
					if (count($validation_errors) == 0) {
						// Here for upward compatibility; no date fields are in the users realm
						// For validating dates, see edit_event action above
					}
					
					// if there were errors, we need to show them together with the entered data
					// else we apply data to the backend and show a ok-message
					if (count($mandatory_errors) == 0 && count($validation_errors) == 0 && count($mismatch_errors) == 0) {
						// Assign editing metadata
						$_POST['lcc_new_data']['event_id'] = $event_data['id'];
						if (null === $write_to_id) {
							$_POST['lcc_new_data']['author']               = $authed_user;
							$_POST['lcc_new_data']['created']              = time();
							$_POST['lcc_new_data']['last_modified']        = '';
							$_POST['lcc_new_data']['last_modified_author'] = '';
						} else {
							$_POST['lcc_new_data']['author']               = $event_data['author'];
							$_POST['lcc_new_data']['created']              = $event_data['created'];
							$_POST['lcc_new_data']['last_modified']        = time();
							$_POST['lcc_new_data']['last_modified_author'] = $authed_user;
						}


						$written_id = $noteDriver->storeData($write_to_id, $_POST['lcc_new_data']);
						if ($written_id === false) {
							$msg = new LCC_Message($view->getLang('lcc_error_note_storage'), 'status_failed');
							$view->addMessage($msg);
						} else {
							// looked good!
							// Print message and return to event details of the event
							unset($_POST['lcc_new_data']); // clear new data so smarty thinks nothing was submitted
							$msg = new LCC_Message($view->getLang('lcc_success_note_storage'), 'status_ok');
							$view->addMessage($msg);
							$this->verifyPermission('event_view');
							$view->printEventDetails($event_data);
						}
					} else {
						// Output errors
						// The core makes some dynamic lookups to the language file
						if (count($mandatory_errors) > 0) {
							$errortext = '<b>'.$view->getLang('lcc_error_field_mandatory').'</b>';
							foreach ($mandatory_errors as $field) {
								$errortext .= $view->getLang('lcc_note_desc_'.$field).', ';
							}
							$msg = new LCC_Message(substr($errortext, 0, -2), 'status_failed');
							$view->addMessage($msg);
						}
						if (count($validation_errors) > 0) {
							$errortext = '<b>'.$view->getLang('lcc_error_field_invalid').'</b><br>';
							foreach ($validation_errors as $field) {
								$errortext .= $view->getLang('lcc_note_desc_'.$field).': '.$view->getLang('lcc_note_msg_'.$field).'<br>';
							}
							$msg = new LCC_Message(substr($errortext, 0, -4), 'status_failed');
							$view->addMessage($msg);
						}
						if (count($mismatch_errors) > 0) {
							foreach ($mismatch_errors as $field) {
								$errortext .= $view->getLang('lcc_note_desc_'.$field).': '.$view->getLang('lcc_error_date_mismatch').'<br>';
							}
							$msg = new LCC_Message(substr($errortext, 0, -4), 'status_failed');
							$view->addMessage($msg);
						}
						$view->printNoteForm($note_data);
					}
				} else {
					// just display editable view
					$view->printNoteForm($note_data);
				}
			break;
			
			/*
			* Delete existing notes
			*/
			case 'delete_note':
				if (isset($_GET['lcc_id']) && !empty($_GET['lcc_id'])) {
					// ID was passed; see if the ID exists
					$note_data = $noteDriver->getAllData($_GET['lcc_id']);
					if ($note_data === false) {
						$msg = new LCC_Message($view->getLang('lcc_error_no_such_note'), 'status_failed');
						$view->addMessage($msg);
					} else {
						// Evaluate ACL
						// check if we got global deletion right or
						// if we are allowed to delete our own event, if this is our own event
						if (!$this->checkRight('note_del')) {
							// no global deletion right; test if this is our event
							if ($note_data['author'] === $authed_user) {
								$this->verifyPermission('note_del_own');
							} else {
								// Drop an error since we have no mod right
								$this->verifyPermission('note_del');
							}
						}
						
						// See if event exists
						// TODO: Check if code factorisation is possible
						if (isset($_GET['lcc_eventid']) && !empty($_GET['lcc_eventid'])) {
							$event_data = $eventDriver->getAllData($_GET['lcc_eventid']);
							if ($event_data === false) {
								$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
								$view->addMessage($msg);
								$view->render();
								return;
							}
						} else {
							$msg = new LCC_Message($view->getLang('lcc_error_no_such_event'), 'status_failed');
							$view->addMessage($msg);
							$view->render();
							return;
						}
						
						// TODO: Factorize. (love that).
						if ($noteDriver->deleteNote($_GET['lcc_id'])) {
							// Show msg and display calendar view
							$msg = new LCC_Message($view->getLang('lcc_success_note_deletion'), 'status_ok');
							$view->addMessage($msg);
							$this->verifyPermission('event_view');
							$view->printEventDetails($event_data);
						} else {
							// Show msg and event data again
							$msg = new LCC_Message($view->getLang('lcc_error_note_deletion'), 'status_failed');
							$view->addMessage($msg);
							$this->verifyPermission('event_view');
							$view->printEventDetails($event_data);
						}
					}
				} else {
					$msg = new LCC_Message($view->getLang('lcc_error_no_such_note'), 'status_failed');
					$view->addMessage($msg);
				}
			break;
			
			/*
			* Display calendar
			*/
			case 'show_calendar':
				// Just print out the calendar view with the selected dates (if set)
				$this->verifyPermission('calendar_view');
				$view->printMonthCalendar();
			break;
			
			/*
			* Default action
			*/
			default:
				// perform default action
				return $this->performAction($this->_config['action_start'], array(), false);
		}
		
		// Finally send HTML to the client
		$view->render();
	}
	
	
	/**
	* Get upcoming events for the next X days
	*
	* This method can be used to get the id's of the events
	* starting the next X days.
	*
	* @param int $days        Number of days to look forward
	* @param int $limit       (optional) limit events returned (0=unlimited)
	* @param string $date     (optional) ISO-8601 format (YYYY-MM-DD) determining the start date, if not set, defaults to TODAY
	* @return array    Array containing the data of the events. Array keys are the Event IDs
	* @todo maybe we should write a method printUpcomingEvents() that uses a template for this, so end users need not to echo the stuff and build links themselves
	*/
	function getUpcomingEvents($days, $limit = 0, $date = null)
	{
		$return = array();
		$eventDriver =& $this->getEventDriverInstance();
		
		// Ensure $limit and $days is correct
		if ($limit < 0) $limit = 0;
		if ($days < 0)  $days  = 0;
		if (!$date)     $date  = date("Y-m-d", time());
		
		// We use PEAR::Calendar to make day shifting more easy and reliable
		$day = new Calendar_Day(0, 0, 0);
		$day->setTimestamp(strtotime($date) - 86400); // minus one day because we use "next day" in the while loop

		// Now loop through the days and get the IDs of the events for the specific days
		while (($day = $day->nextDay('object')) && ($limit == 0 || count($return) < $limit) && $days > 0) {
			$days--;
			$events_ids = $eventDriver->getEventsForDate($day->getTimestamp());
			if ($events_ids === false || !is_array($events_ids)) {
				die('LCC_CORE ERROR: Unable to get Events for Date! EventDriver dropped an error.');
			} else {
				// fetch data for events
				foreach ($events_ids as $id) {
					if (count($return) < $limit || $limit == 0) {
						$event_data = $eventDriver->getAllData($id);
						
						// If returned data is invalid, do nothing
						if (is_array($event_data) && count($event_data) > 0) {
							$return[$id] = $event_data;
						}
					}
				}
			}
		}
		return $return;
	}
	
	/**
	* Function to build parameters for actions suitable for $LCC_CORE->performAction()
	*
	* This is neccessary because SMARTY does not support the array() syntax.
	*
	* Call the function the following way:
	* {$LCC_CORE->performAction('action_name', $LCC_CORE->buildActionParams(p_key1, p_val1, p_key2, p_val2, ...))}
	*
	* @return array
	*/
	function buildActionParams()
	{
		$args = func_get_args();
		if (count($args) % 2 > 0) die('buildActionParms() wrong parameter count');
		
		$param_list = array();
		$param = null;
		foreach ($args as $arg) {
			if ($param === null) {
				$param = $arg;
			} else {
				$param_list[$param] = $arg;
				$param = null;
			}
		}
		return $param_list;
	}
}
?>
Return current item: Lightweight Club Calendar