Location: PHPKode > projects > Mocovie web framework > mocovi/library/autoload/MvcFactory.php
<?php
/**
 *  Copyright (C) 2010  Kai Dorschner
 *
 *  This program 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Kai Dorschner <the-hide@address.com>
 * @copyright Copyright 2010, Kai Dorschner
 * @license http://www.gnu.org/licenses/gpl.html GPLv3
 * @package mocovi
 * @subpackage helpers
 */

/**
 * Including the three elements.
 */
class_exists('Model')	or require $GLOBALS['library'].'autoload/Model.php';
class_exists('View')	or require $GLOBALS['library'].'autoload/View.php';
class_exists('Control')	or require $GLOBALS['library'].'autoload/Control.php';

/**
 * Control and build MVC system.
 *
 * Manage, {@link model}, {@link view} and {@link control} in this class,
 * provide them with options and let them work together and build an output.
 *
 * @package mocovi
 */
class MvcFactory
{

	/**
	 * Containing the current Document Object Model of this page.
	 *
	 * @access protected
	 */
	protected $pagedom;

	/**
	 * Contains the page model with it's options.
	 *
	 * @see model()
	 * @access protected
	 */
	protected $model;

	/**
	 * Contains the output view with it's options.
	 *
	 * @see view()
	 * @access protected
	 */
	protected $view;

	/**
	 * Contains the controls with their options.
	 *
	 * @see control()
	 * @access protected
	 */
	protected $control = array();

	/**
	 * Generates a new empty DOM with pretty output.
	 *
	 * @param string $version The version for the empty XML document
	 * @param string $encoding The encoding for the empty XML document
	 * @return void
	 * @access public
	 */
	public function __construct($version = '1.0', $encoding = 'utf-8')
	{
		$this->pagedom = new DomDocument($version, $encoding);
		$this->pagedom->preserveWhiteSpace = false; // Let's have a nice output
		$this->pagedom->formatOutput = true;

		View::mediaMapping($GLOBALS['media']); //Overwrites the media type when it maches with defined mapping rules.

		Translator::setLanguage($GLOBALS['language']);
		foreach(new DirectoryIterator($GLOBALS['commonTranslations']) as $translation)
			if(!$translation->isDot())
				Translator::setTranslationFile($translation->getPathName()); // Global Translation files
		if(is_dir($GLOBALS['userTranslations']))
			foreach(new DirectoryIterator($GLOBALS['userTranslations']) as $translation)
				if(!$translation->isDot())
					Translator::setTranslationFile($translation->getPathName()); // User Translation files
		Translator::setTranslation($GLOBALS['filesystem']->getPageTranslation($GLOBALS['page'])); // Page wide translation

	}

	/**
	 * Instantiates a new model and sets its options.
	 *
	 * @param string $node Reference of the model node
	 * @param array $options Contains the options for the class
	 * @return void
	 * @see applyOptions()
	 * @access public
	 */
	public function model($node, array $options = array())
	{
		$this->model = Model::getInstance($node);
		$this->applyOptions($this->model, $options);
		$this->control();
		return $this;
	}

	/**
	 * Instantiates a new view and sets its options.
	 *
	 * @see applyOptions()
	 * @access public
	 * @return void
	 * @param array $options Contains the options for the class
	 */
	public function view(array $options = array())
	{
		if(!is_file($path = $GLOBALS['userViews'].$options['theme'].'/'.$options['media'].'.xsl'))				// Theme specific template
			if(!is_file($path = $GLOBALS['userViews'].$options['media'].'.xsl'))								// Domain template
				if(!is_file($path = $GLOBALS['commonViews'].$options['theme'].'/'.$options['media'].'.xsl'))	// Theme specific global template
					$path = $GLOBALS['commonViews'].$options['media'].'.xsl';									// Global template
		if(!is_file($path))																						// if there is still no template present
			throw new MvcException('Template for media format "'.$options['media'].'" is not available.');
		$this->view = View::getInstance($path);
		$this->applyOptions($this->view, $options);
		return $this;
	}

	/**
	 * Instantiates a new control.
	 *
	 * @return void
	 * @see $control
	 * @see $model
	 * @see model::getControls()
	 * @access public
	 */
	public function control()
	{
		if(is_object($this->model))
		{
			ControlFactory::addPool(new DirectoryIterator($GLOBALS['commonControls']));
			if(is_dir($GLOBALS['userControls']))
				ControlFactory::addPool(new DirectoryIterator($GLOBALS['userControls']));
			$this->control = $this->model->getControls();
		}
		else
			throw new MvcException('You have to define the model first.');
		return $this;
	}

	/**
	 * Execute controls and return the generated XML resource tree.
	 *
	 * All three elements must be created first. When this is done this elements
	 * are combined and will result in the page with the predefined
	 * destination formatting.
	 * Additionally system meta data is set into the page model
	 * language or something else necessary for the XSL.
	 *
	 * @return string The XML Document
	 * @see $model
	 * @see $view
	 * @see $control
	 * @see $pagedom
	 * @access public
	 */
	public function build()
	{
		if(!$this->are_objects($this->model, $this->view) || !is_array($this->control))
			throw new MvcException('Before you can build the page you have to create all three elements: Model, View and Control.');
		//Execute controls and return the generated XML resource tree
		if($this->control[0] instanceof Control)
		{
			$this->control[0]
				->load($this->pagedom)
				->run();
		}
		else
			throw new Exception('Cannot run control because it\'s not a subclass of "Control"');
		return $this->view->transform($this->pagedom);
	}

	/**
	 * Applying options to an object.
	 *
	 * @param object Reference of the object
	 * @param array Contains the options for the object
	 * @return void
	 * @access protected
	 */
	protected function applyOptions(&$object, array &$options)
	{
		foreach($options as $property => $value)
			$object->$property = $value;
		return $this;
	}

	/**
	 * The is_object(); function from PHP for more elements in an array.
	 *
	 * Applies the PHP internal is_object(); function to all elements
	 * in an array.
	 *
	 * @return boolean	True if all elements are objects, false if only one
	 *					element isn't an object
	 * @access protected
	 */
	protected function are_objects()
	{
		$args = func_get_args();
		foreach($args as $arg) if(!is_object($arg)) return false;
		return true;
	}
}
Return current item: Mocovie web framework