[geeklog-cvs] MVCnPHP ArrayLoader.php,NONE,1.1.2.1 BaseLoader.php,NONE,1.1.2.1 BaseView.php,NONE,1.1.2.1 CommandFactory.php,NONE,1.1.2.1 CommandInterface.php,NONE,1.1.2.1 Controller.php,NONE,1.1.2.1 Form.php,NONE,1.1.2.1 LoaderFactory.php,NONE,1.1.2.1 Mapping.php,NONE,1.1.2.1 Validator.php,NONE,1.1.2.1 ViewFactory.php,NONE,1.1.2.1 ViewInterface.php,NONE,1.1.2.1 XMLLoader.php,NONE,1.1.2.1 XMLParser.php,NONE,1.1.2.1 buildPackage.php,NONE,1.1.2.1 package.xml,NONE,1.1.2.1 CHANGELOG,1.5,1.6

tony at iowaoutdoors.org tony at iowaoutdoors.org
Tue Dec 14 15:03:21 EST 2004


Update of /var/cvs/MVCnPHP
In directory www:/tmp/cvs-serv19464

Modified Files:
	CHANGELOG 
Added Files:
      Tag: rel-1-0-php5-port
	ArrayLoader.php BaseLoader.php BaseView.php CommandFactory.php 
	CommandInterface.php Controller.php Form.php LoaderFactory.php 
	Mapping.php Validator.php ViewFactory.php ViewInterface.php 
	XMLLoader.php XMLParser.php buildPackage.php package.xml 
Log Message:
The 1.0 code was refactored and all file name changed.
----------------------------------------------------------------------


--- NEW FILE: CommandInterface.php ---
<?php

/**
* MVCnPHP - BaseCommand.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: CommandInterface.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Abstract class to be extended by all commands
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
interface MVCnPHP_CommandInterface {
    /**
    * Executes this command
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Name of forward to send processing to
    *
    */
    public function execute();
}

?>
--- NEW FILE: buildPackage.php ---
<?php

require_once 'PEAR/PackageFileManager.php';
$fm = new PEAR_PackageFileManager();
$options = array(
                'packagefile' => 'package.xml',
                'state' => 'beta',
                'version' => '2.0.0',
                'notes' => 'Development snapshot, not for production use.',
                'filelistgenerator' => 'file',
                'baseinstalldir' => 'Geeklog/MVCnPHP',
                'package' => 'Geeklog_MVCnPHP',
                'summary' => 'An MVC implementation in PHP',
                'description' => 'This is a Model-View-Controller (MVC) implementation in PHP.  It
                	is not meant to be a reimplementation of, say, Struts but it does provide the 
                	basic features of an MVC implementation.',
                'doctype' => 'http://pear.php.net/dtd/package-1.0',
                'packagedirectory' => '/home/tony/www/Geeklog-2/system/MVCnPHP/',
                'license' => 'PHP License',
                'changelogoldtonew' => true,
                'roles' =>
                  array(
                      'php' => 'php',
                      'txt' => 'doc',
                      '*' => 'data',
                       ),
                'dir_roles' =>
                  array(
                      'sql' => 'data',
                      'examples' => 'doc',
                      'tests' => 'test',
                       )
                );
$e = $fm->setOptions($options);
if (PEAR::isError($e)) {
    echo $e->getMessage();
    die();
}
$fm->addMaintainer('tbibbs', 'lead', 'Tony Bibbs', 'tony at geeklog.net');

$e = $fm->writePackageFile();
if (PEAR::isError($e)) {
    echo $e->getMessage();
    die();
}

?>

--- NEW FILE: Mapping.php ---
<?php

/**
* MVCnPHP - Mapping.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: Mapping.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* This is the mapping object.  This holds all pertinent mapping data for
* a specific model or view. NOTE: not all available mappings are loaded
* for each request, only those needed for the current request.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_Mapping {
    /**
    * @access private
    * @var string
    */
    private $name = null;
    
    /**
    * @access private
    * @var string
    */
    private $type = null;
    
    /**
    * @access private
    * @var string
    */
    private $typePath = null;
    
    /**
    * @access private
    * @var string
    */
    private $forwards = null;
    
    /**
    * @access private
    * @var string
    */
    private $baseURL = null;
    
    /**
    * Sets the base URL for any redirects
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $url Base url for all redirects
    *
    */
    public function setBaseURL($url)
    {
        $this->baseURL = $url;
    }
    
    /**
    * Gets the base URL for any redirects
    * Any forwards to other URL's must be relative to the
    * base URL provided
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Base url
    *
    */
    public function getBaseURL()
    {
        return $this->baseURL;
    }
    
    /**
    * Sets the name for the model or view this mapping
    * belongs to.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $name Name of model or view
    *
    */
    public function setName($name)
    {
        $this->name = $name;
    }
    
    /**
    * Gets the name for the model or view this mapping
    * belongs to.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Name of the model or view
    *
    */
    public function getName()
    {
        return $this->name;
    }
    
    /**
    * Sets the type of object this mapping belongs to (model or view)
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $type Type of object (model or view)
    *
    */
    public function setType($type)
    {
        $this->type = $type;
    }
    
    /**
    * Gets the type of object this mapping belongs to (model or view)
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Type of object (model or view)
    *
    */
    public function getType()
    {
        return $this->type;
    }
    
    /**
    * Sets all forwards associated with this mapping.  Note
    * that you won't have forwards for any views
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param array $forwards Array of forwards tied to this object
    *
    */
    public function setForwards($forwards)
    {
        $this->forwards = $forwards;
    }
    
    public function getForwards()
    {
    	return $this->forwards;
    }
    
    /**
    * Retrieves the requested forward
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $name Name of forward to get
    * @return array|boolean The forward data or false if not found
    *
    */
    public function getForward($name)
    {
        if (!empty($this->forwards[$name])) {
            return $this->forwards[$name];
        } else {
            return false;
        }
    }
    
    /**
    * Sets the path where the models or views can be found
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $path Absolute path ending with trailing slash
    *
    */
    public function setTypePath($path)
    {
        $this->typePath = $path;
    }

    /**
    * Gets the absolute path where the code for this model or view this
    * mapping belongs to can be found
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Path to model or view directory
    *
    */
    public function getPath()
    {
        return $this->typePath;
    }
}

?>
--- NEW FILE: BaseView.php ---
<?php

/**
* MVCnPHP - BaseView.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: BaseView.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

require_once 'ViewInterface.php';

/**
* Interface class for views
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
abstract class MVCnPHP_BaseView implements MVCnPHP_ViewInterface {
    /**
    * @access private
    * @var int
    */
    public $outputMethod = MVC_PRINT;
    
    /**
    * Returns if view should be printed
    *
    * View can be printed using echo or returned as a string.
    * This method is a tool used by the controller to determine
    * if it needs to return a string or not
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return boolean True if view is printed, otherwise false
    *
    */
    public function printView()
    {
        if ($this->outputMethod == MVC_PRINT) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
    * Sets views output method
    *
    * View can either be printed immediately using PHP's
    * echo command or the view can be returned as a string
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param int $method One of two constanst, _PRINT or _STRING
    *
    */
    public function setOutputMethod($method)
    {
        if ($method == MVC_PRINT) {
            $this->outputMethod = MVC_PRINT;
        } else {
            $this->outputMethod = MVC_STRING;
        }
    }
}

?>
Index: CHANGELOG
===================================================================
RCS file: /var/cvs/MVCnPHP/CHANGELOG,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** CHANGELOG	23 Mar 2004 02:39:06 -0000	1.5
--- CHANGELOG	14 Dec 2004 20:03:19 -0000	1.6
***************
*** 1,9 ****
  $Id$
  
- 
- 
  MVCnPHP Change Log
  -------------------
  
  3/22/2004
  -----------
--- 1,14 ----
  $Id$
  
  MVCnPHP Change Log
  -------------------
  
+ 12/14/2004
+ -----------
+ - Ported over to PHP5
+ - Introduced loose namespaces (PHP5 doesn't support namespaces yet)
+ - Removed sample applications and Quick Form code.
+ - Various bug fixes.
+ 
  3/22/2004
  -----------

--- NEW FILE: Form.php ---
<?php

/**
* MVCnPHP - Form.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: Form.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* This is a basic form class that can aid in form validation and
* manipulation.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_Form {
    /**
    * @access private
    * @var array
    */
    private $values = null;
    
    /**
    * Constructor
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param array $formArray Array of form fieds (typical $_GET, $_POST or $_REQUEST)
    *
    */
    public function Form($formArray)
    {
        $this->values = $formArray;
    }
    
    /**
    * Returns if the given variable name exists in form
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable
    * @return boolean True if found, otherwise false
    *
    */
    public function contains($varName)
    {
        return isset($this->values[$varName]);
    }
    
    /**
    * Gets value for given variable name
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable to get value for
    * @return variant Value of form variable
    *
    */    
    public function get($varName)
    {
        if (!$this->contains($varName)) {
            return null;
        }
        return $this->values[$varName];
    } 
    
    /**
    * Deletes a form variable
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable to delete
    *
    */
    public function remove($varName)
    {
        if ($this->contains($varName)) {
            unset($this->values[$varName]);
        }
    }
    
    /**
    * Sets a field to given value
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of field to set
    * @param string $value Value to set field to
    *
    */
    public function set($varName, $value)
    {
        $this->values[$varName] = $value;
    }
    
    /**
    * Returns value array
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array Values array
    *
    */
    public function &getValues()
    {
        return $this->values;
    }
}

?>
--- NEW FILE: ViewFactory.php ---
<?php

/**
* MVCnPHP - ViewFactory.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: ViewFactory.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* This implements the factory design pattern and is
* responsible for building view objects
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_ViewFactory {
    /**
    * Builds the requested view object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $path Path to directory holding views
    * @param string $name Name of view to create
    * @return object viewobject
    *
    */
    public function &getView($path, $name)
    {
        $filename = $path . $name . '.php';
        if (file_exists($filename)) {
            require_once($filename);
            $name = $name;
            return new $name();
        } else {
        	throw new Exception('Bad set of parameters to ViewFactory::getView');
        }
    }
}

?>
--- NEW FILE: ArrayLoader.php ---
<?php

/**
 * MVCnPHP - ArrayLoader.class.php
 *
 * This source file is subject to version 2.02 of the PHP license,
 * that is bundled with this package in the file LICENSE, and is
 * available at through the world-wide-web at
 * http://www.php.net/license/2_02.txt.
 * If you did not receive a copy of the PHP license and are unable to
 * obtain it through the world-wide-web, please send a note to
 * license at php.net so we can mail you a copy immediately.
 *
 * @author Tony Bibbs <tony at geeklog.net>
 * @copyright Tony Bibbs 2003
 * @package net.geeklog.mvc
 * @version $Id: ArrayLoader.php,v 1.1.2.1 2004/12/14 20:03:18 tony Exp $
 *
 */

/**
* Base Loader class which does most of the work
*/
require_once 'BaseLoader.class.php';

/**
* This loader creates a mapping from an PHP array
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
* @see LoaderFactory
*
*/
class MVCnPHP_ArrayLoader extends MVCnPHP_BaseLoader {
    
    /**
    * Gets config data for given object in the form of
    * a mapping object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $name Name of object to get mapping for
    * @param string $viewsDir Directory where controllers views are stored
    * @param string $commandsDir DIrectory where controllers commands are stored
    * @param string $baseURL Base URL, all redirects are relative to this URL
    * @param array $arrayData Array of configuration data
    * @return object Mapping object
    *
    */
    public function &getMapping($name, $viewsDir, $commandsDir, $baseURL, $arrayData = '')
    {
        if (!is_array($arrayData) AND !is_array($this->arrayData)) {
            return false;
        }
        
        if (empty($this->arrayData)) {
            $this->arrayData = $arrayData;
        }
        return parent::getMapping($name, $viewsDir, $commandsDir, $baseURL, $this->arrayData);
    }
}

?>
--- NEW FILE: XMLLoader.php ---
<?php

/**
* MVCnPHP - XMLLoader.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: XMLLoader.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Base Loader class which does most of the work
*/
require_once 'BaseLoader.php';

/**
* MVC XML parser
*/
require_once 'XMLParser.php';

/**
* This loader creates a mapping from an XML file
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_XMLLoader extends MVCnPHP_BaseLoader {
    
    /**
    * Gets config data for given object in the form of
    * a mapping object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $name Name of object to get mapping for
    * @param array $arrayData Array of configuration data
    * @return object Mapping object
    *
    */
    public function getMapping($name, $viewsDir, $commandsDir, $baseURL, $arrayData = '')
    {
        if (!file_exists($arrayData) AND !is_array($this->arrayData)) {
            return false;
        }
        if (empty($this->arrayData)) {                
            $xmlData = file_get_contents($arrayData);
            $this->arrayData = $this->XMLToArray($xmlData);
        }
        return parent::getMapping($name, $viewsDir, $commandsDir, $baseURL, $this->arrayData);
    }
    
    /**
    * Parses XML string into loader's expected array format
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $xmlData XML to be parsed
    *
    */
    private function XMLToArray($xmlData)
    {
        $parser = new MVCnPHP_XMLParser($xmlData);
        $elements = $parser->getElementIndexes();
        $configData = Array();
        foreach ($elements as $curIndex) {
            switch ($parser->getTag($curIndex)) {
                case 'VIEW':
                    $view = $parser->getAttribute($curIndex, 'id');
                    $default = $parser->getAttribute($curIndex, 'default');
                    $configData[MVC_VIEWS][$view][MVC_NAME] = $parser->getAttribute($curIndex, 'name');
                    if ($default) {
                        $configData[MVC_VIEWS][$view][MVC_DEFAULT] = true;
                    }
                    break;
                case 'COMMAND':
                    $command = $parser->getAttribute($curIndex, 'id');
                    $default = $parser->getAttribute($curIndex, 'default');
                    $configData[MVC_COMMANDS][$command][MVC_NAME] = $parser->getAttribute($curIndex, 'name');
                    if ($default) {
                        $configData[MVC_COMMANDS][$command][MVC_DEFAULT] = true;
                    }
                    break;
                case 'FORWARD':
                    $name = $parser->getAttribute($curIndex, 'id');
                    $parentTag = $parser->getTag($parser->getAttribute($curIndex, 'parent'));
                    $parentIDAttr = $parser->getAttribute($parser->getAttribute($curIndex, 'parent'), 'id');
                    if ($parentTag == 'VIEW') {
                        $configData[MVC_VIEWS][$parentIDAttr][MVC_FORWARDS][$name][MVC_TARGET] = $parser->getValue($curIndex);
                        $configData[MVC_VIEWS][$parentIDAttr][MVC_FORWARDS][$name][MVC_TYPE] = $parser->getAttribute($curIndex, 'type');
                    } else {
                        if ($parentTag == 'COMMAND') {
                            $configData[MVC_COMMANDS][$parentIDAttr][MVC_FORWARDS][$name][MVC_TARGET] = $parser->getValue($curIndex);
                            $configData[MVC_COMMANDS][$parentIDAttr][MVC_FORWARDS][$name][MVC_TYPE] = $parser->getAttribute($curIndex, 'type');
                        } else {
                        	throw new Exception('Hit unexpected XML tag in XMLLoader::_XMLToArray');
                        }    
                    }
                    break;
                default:
            }
        }
        return $configData;
    }    
}

?>
--- NEW FILE: ViewInterface.php ---
<?php

/**
* MVCnPHP - BaseView.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: ViewInterface.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Interface class for views
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
interface MVCnPHP_ViewInterface {
    /**
    * Returns if view should be printed
    *
    * View can be printed using echo or returned as a string.
    * This method is a tool used by the controller to determine
    * if it needs to return a string or not
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return boolean True if view is printed, otherwise false
    *
    */
    public function printView();
    
    /**
    * Sets views output method
    *
    * View can either be printed immediately using PHP's
    * echo command or the view can be returned as a string
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param int $method One of two constanst, _PRINT or _STRING
    *
    */
    public function setOutputMethod($method);
    
    /**
    * Renders a view in either printed HTML or
    * as an HTML string back to caller
    *
    * @author Tony Bibbs <tony AT geeklog DOT>
    * @access public
    * @return string OPTIONAL: not always returned
    *
    */
    public function getView();
}

?>
--- NEW FILE: LoaderFactory.php ---
<?php

/**
* MVCnPHP - LoaderFactory.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: LoaderFactory.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Builds MVC Config Loaders
*
* I doubt much more besides arrays and XML files
* will be used but just in case I used the factory
* pattern in here to enable easily adding new configuration
* data structures
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_LoaderFactory {
    /**
    * Builds requested MVC configuration loaders.
    *
    * Config loaders each represent one way of parsing
    * an MVC configuration data structure into the objects
    * needed by the controller.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $path Path to base MVC directory
    * @param int $configType Constant, either MVC_XML or MVC_ARRAY
    * @return object MVC config loader
    *
    */
    public function getLoader($configType = MVC_XML)
    {
        $filename = $configType . '.php';
        require_once $filename;
        $loaderClassName = 'MVCnPHP_' . $configType;
        return new $loaderClassName();
    }
}

?>
--- NEW FILE: BaseLoader.php ---
<?php

/**
* MVCnPHP - BaseLoader.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: BaseLoader.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Mapping class which holds all data mapped to a given
* model or view
*/
require_once 'Mapping.php';

/**
* This is an abstract loader class which provides
* 90% of all functionality to the various loaders since
* we assume all config data will eventually be turned into
* a PHP array
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
abstract class MVCnPHP_BaseLoader {
    /**
    * @access protected
    * @var array
    */
    protected $arrayData = null;

    /**
    * Gets config data for given object in the form of
    * a mapping object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $name Name of object to get mapping for
    * @param array $arrayData Array of configuration data
    * @return object Mapping object
    *
    */
    public function &getMapping($name, $viewsDir, $commandsDir, $baseURL, $arrayData = '')
    {
    	
        $mapping = new MVCnPHP_Mapping();

        if ($name == 'default') {
            $name = $this->getDefaultMapping();
        }
        
        if (!empty($arrayData[MVC_VIEWS][$name])) {
            $mapping->setName($arrayData[MVC_VIEWS][$name][MVC_NAME]);
            
            $mapping->setType('view');
            $mapping->setTypePath($viewsDir);
        } elseif (!empty($arrayData[MVC_COMMANDS][$name])) {
            $mapping->setName($arrayData[MVC_COMMANDS][$name][MVC_NAME]);
            $mapping->setType('command');
            $mapping->setTypePath($commandsDir);
        }

        $mapping->setBaseURL($baseURL);
        $mapping->setForwards($this->getForwards($name, $mapping->getType()));
        
        return $mapping;
    }
    
    /**
    * If no object was specified in the request, this will return
    * the default mapping if one was specified in the configuration
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @return array Mapping data for given model or view
    *
    */
    private function getDefaultMapping()
    {
        foreach ($this->arrayData[MVC_VIEWS] as $curView) {
            $curView = current($this->arrayData[MVC_VIEWS]);
            if ($curView[MVC_DEFAULT] == true) {
                return key($this->arrayData[MVC_VIEWS]);
            }
            next($this->arrayData[MVC_VIEWS]);
        }
    }
    
    /**
    * Gets all forwards for a given object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $name Name of model to get forwards for
    * @param string $type Type of object (command or view)
    * @return array Forwards for given model
    *
    */
    private function getForwards($name, $type)
    {
    	if ($type == 'view') {
            return $this->arrayData[MVC_VIEWS][$name][MVC_FORWARDS];
        } else {
            return $this->arrayData[MVC_COMMANDS][$name][MVC_FORWARDS];
        }
    }   
}
--- NEW FILE: Controller.php ---
<?php

/**
* MVCnPHP - Controller.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: Controller.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* Constants used within this MVC framework
*/
require_once 'Constants.php';

/**
* Loader factory will create a configuration loader.
* Right now we only support PHP arrays and XML files
*/
require_once 'LoaderFactory.php';

/**
* The controller part of the MVC
*
* This class controls processing for the program
* indiscriminately.  The focus is always on the underlying
* views or commands.  This class allows you to store application
* messages such as status messages (e.g. something was saved
* successfully) or error messages from failed validation or
* security reasons.  By default these are stored in the $_SESSION
* superglobal in $_SESSION['MVC_MESSAGE'] and $_SESSION['MVC_ERRORS']
* respectively (note: the later is an array).  If your application is
* not using PHP4 sessions you will want to follow the directions given
* in the documentation for Controller::_clearMessages
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_Controller {

    /**
    * @access private
    * @var int
    */
    private $allowedFormMethod = null;
    
    /**
    * @access private
    * @var array
    */
    private $request = null;
    
    /**
    * @access private
    * @var string
    */
    private $object = null;
    
    /**
    * @access private
    * @var object
    */
    private $mapLoader = null;
    
    /**
    * @access private
    * @var object
    */
    private $mapping = null;
    
    /**
    * @access private
    * @var string
    */
    private $mvcBase = null;
    
    /**
    * @access private
    * @var string
    */
    private $viewDir = null;
    
    /**
    * @access private
    * @var string
    */
    private $commandDir = null;
    
    /**
    * @access private
    * @var string
    */
    private $baseURL = null;
    
    /**
    * @access private
    * @var int
    */
    private $configType = null;
    
    /**
    * @access private
    * @var array
    */
    private $configData = null;
    
    /**
    * Constructor
    *
    * Loads MVC configuration data and sets up data needed for
    * further processing
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param variant $configData Configuration data
    * @param string $configType Denotes type of config data structure, MVC_ARRAY or MVC_XML
    * @param string $allowedFormMethod Controller can accept MVC_GET, MVC_POST or MVC_BOTH
    *
    */
    public function __construct($configData, $configType = MVC_XML, $allowedFormMethod = MVC_BOTH)
    {
        $this->clearMessages();
        
        switch ($allowedFormMethod) {
            case MVC_GET:
                $this->request = &$_GET;
                break;
            case MVC_POST:
                $this->request = &$_POST;
                break;
            default:
                $this->request = &$_REQUEST;
        }
        if (!empty($this->request['cmd'])) {
            $this->object = $this->request['cmd'];
        } else {
            $this->object = 'default';
        }
        $this->configType = $configType;
        $this->configData = $configData;
        $this->allowedFormMethod = $allowedFormMethod;
    }
    
    /**
    * Sets location of the base MVC package so other MVC classes can be
    * loaded at a later time.
    *
    * @author Tony Bibbs
    * @access public
    * @param string $path Path to MVC base dir, must end with trailing slash
    * @return boolean True if view path is set, otherwise false
    *
    */
    public function setMVCBase($path)
    {
        if (!is_dir($path)) {
        	throw new Exception('Bad path in Controller::setMVCBase');
        }
        $this->mvcBase = $path;
        return true;
    }
    
    /**
    * Sets location of views for this controller
    *
    * @author Tony Bibbs
    * @access public
    * @param string $path Path to view dir, must end with trailing slash
    * @return boolean True if view path is set, otherwise false
    *
    */
    public function setViewDir($path)
    {
        if (!is_dir($path)) {
            return false;
        }
        $this->viewDir = $path;
        return true;
    }
    
    /**
    * Sets location of commands for this controller
    *
    * @author Tony Bibbs
    * @access public
    * @param string $path Path to command dir, must end with trailing slash
    * @return boolean True if view path is set, otherwise false
    *
    */
    public function setCommandDir($path)
    {
        if (!is_dir($path)) {
            return false;
        }
        $this->commandDir = $path;
        return true;
    }
    
    /**
    * Sets base URL for this controller
    *
    * The base url allows all subsequent references to URL's to be relative
    * to the URL specified here
    *
    * @author Tony Bibbs
    * @access public
    * @param string $url Base URL
    *
    */
    public function setBaseURL($url)
    {
        $this->baseURL = $url;
    }
    
    /**
    * Process a request (or forward)
    *
    * NOTE this now supports the concept of a global forward for
    * descendants of the validator class.  A global forward is a
    * slick way for validators to return control to the calling
    * command or view without having define a bunch of them in
    * the configuration file.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Optional, may return HTML string of view
    *
    */
    public function processRequest()
    {
        // Ensure user isn't submitted data via an illegal method
        $this->checkMethod();
        
        if (empty($this->mapping)) {
            $this->loadMapping($this->configType, $this->configData);
        }
        
        // We should have latest here a valid mapping object
        if (is_null($this->mapping->getName())) {
        	throw new Exception('Unexpected return from MVC command or MVC view.  Got no valid mapping object');
		}

        if ($this->mapping->getType() == 'view') {
            require_once 'ViewFactory.php';
            
            try {
            	$view = &MVCnPHP_ViewFactory::getView($this->mapping->getPath(), $this->mapping->getName());
            } catch (Exception $e) {
            	$msg = $e->getMessage();
	            // It is possible that the constructor for a view may want to do a forward
            	if ($this->isForward($msg)) {
	                $this->forwardControl($msg);
	                unset($msg);
	            }
	            $tmpArray = explode(':', $msg);            
	            if ($tmpArray[0] == 'doForward') {
	                $this->mapping = &$this->mapLoader->getMapping($tmpArray[1], $this->viewDir, $this->commandDir, $this->baseURL);
	                $this->processRequest();
	                exit;
	            }
	            throw $e;
            }
            
            // Got view object fine, now try rendering it
            $retval = $view->getView();
            
            // Check that we didn't receive any forwards at this point.
            if ($this->isForward($retval)) {
                $this->forwardControl($retval);
                unset($retval);
            }
            $tmpArray = explode(':', $retval);
            if ($tmpArray[0] == 'doForward') {
                $this->mapping = &$this->mapLoader->getMapping($tmpArray[1], $this->viewDir, $this->commandDir, $this->baseURL);
                $this->processRequest();
                exit;
            }
            if (!$view->printView()) {
                return $retval;
            }
        } else {
            require_once 'CommandFactory.php';
            
            try {
            	$tmp = &MVCnPHP_CommandFactory::getCommand($this->mapping->getPath(), $this->mapping->getName());
            } catch (Exception $e) {
            	$msg = $e->getMessage();
            	if ($this->isForward($msg)) {
	                $this->forwardControl($msg);
	                unset($msg);
	            }
	            $tmpArray = explode(':', $msg);            
	            if ($tmpArray[0] == 'doForward') {
	                $this->mapping = &$this->mapLoader->getMapping($tmpArray[1], $this->viewDir, $this->commandDir, $this->baseURL);
	                $this->processRequest();
	                exit;
	            }
	            throw $e;
            }
            
            // Must've got an actual command object, try running it
            $strForward = $tmp->execute();
            
            // Now check for a forward.
            if ($this->isForward($strForward)) {
            	$this->forwardControl($strForward);
            	unset($retval);
            }

            $tmpArray = explode(':', $strForward);
            
            if ($tmpArray[0] == 'doForward') {
                $this->mapping = &$this->mapLoader->getMapping($tmpArray[1], $this->viewDir, $this->commandDir, $this->baseURL);
                $this->processRequest();
                exit;
            }
            
            // OK if we got here then we got an undefined forward of some kind
            //if (!empty($strForward)) {
            	//print_r($tmp); print_r($_SESSION['forwards']); $_SESSION['forwards'] = ''; exit;
            	//throw new Exception('Unexpected return from MVC command or MVC view.  Got ' . $strForward);
            //}
        }
    }
  
    /**
    * Clears any existing errors or messages
    *
    * This method assumes the application is using PHP4 sessions
    * to store MVC errors and messages.  If that is not the case,
    * the application should create a new class that extends this
    * controller and override this function to clear the messages
    * in the way desired.
    *
    * @author Tony Bibs <tony at geeklog.net>
    * @access private
    *
    */
    public function clearMessages()
    {
        unset($_REQUEST[MVC_MESSAGES]);
        unset($_REQUEST[MVC_ERRORS]);
    }
    
    /**
    * Ensures only supported methods are used
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    *
    */
    public function checkMethod()
    {
        switch ($this->allowedFormMethod) {
            case MVC_GET:
                if (count($_POST) > 0) {
                	throw new Exception('POST method is not supported by this controller');
                }
            case MVC_POST:
                if (count($_GET) > 0) {
                	throw new Exception('GET method is not supported by this controller');
                }
        }
    }
    
    /**
    * Loads the mapping data for a model or view
    *
    * This will load only the mapping data needed by the
    * current object.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $configType Dontes the type of config data structure
    * @param variant $configData this is the data or file pointer for config data
    *
    */
    public function loadMapping($configType, $configData)
    {
        if (empty($this->mapLoader)) {
            $this->mapLoader = &MVCnPHP_LoaderFactory::getLoader($configType);
            
        }
        $this->mapping = $this->mapLoader->getMapping($this->object, $this->viewDir, $this->commandDir, $this->baseURL, $configData);

        // Maybe, we've gotten an invalid mapping object, so we try to 
        // load the default view
        if (is_null($this->mapping->getName())) {
            $this->object = 'default';
	  
            // We can also call $this->loadMapping after we've set the object to 'default'
            // but this may end in an endless loop, so we try to load the default view only once
            $this->mapping = &$this->mapLoader->getMapping($this->object, $this->viewDir, $this->commandDir, $this->baseURL, $configData);
        }
    }
    
    /**
    * Determines if string is a name of an existing forward.
    *
    * Because views can return the HTML string it won't be obvious
    * if the call to the view's getView() is a forward or actually
    * HTML.  This function makes that determintation.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $name Name of forward to look for
    * @return boolean True if forward is found, otherwise false
    *
    */
    public function isForward($name)
    {
        if ($this->mapping->getForward($name)) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
    * Forwards control onto another command or view
    *
    * A model will typically try to forward control to a view
    * (less likely, but possible, another command) after processing.
    * This object handles that forwarding and can even handle forwarding
    * to a different URL if configured to do so.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $name Name of next model or view to go to
    *
    */
    public function forwardControl($name)
    {
        $forward = $this->mapping->getForward($name);
        if ($forward[MVC_TYPE] == 'redirect') {
            $url = $this->mapping->getBaseURL() . $forward[MVC_TARGET];
            header('Location: ' . $url);
        } else {
            $this->object = $forward[MVC_TARGET];
            $this->mapping = &$this->mapLoader->getMapping($this->object, $this->viewDir, $this->commandDir, $this->baseURL);
            $this->processRequest();
        }
    }
    
}

?>
--- NEW FILE: Validator.php ---
<?php

/**
* MVCnPHP - Validator.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: Validator.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* MVC base command object
*/
require_once 'BaseCommand.php';

/**
* MVC form object
*/
require_once 'Form.php';

/**
* This is a validator class meant to ease the tasks
* often done by validation logic
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_Validator extends MVCnPHP_BaseCommand {
    /**
    * @access private
    * @var object
    */
    private $form = null;
    
    /**
    * Constructor
    *
    * Initializes form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function __construct()
    {
        $this->_form = new MVCnPHP_Form($_REQUEST);
    }
    
    /**
    * Determines if the submitted form has a value for a given
    * variable name
    *
    * This is a simple pass thru to the form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable
    * @return boolean True if found, otherwise false
    *
    */
    public function contains($varName)
    {
        return $this->_form->contains($varName);
    }
    
    /**
    * Gets value for given variable name
    *
    * This is a simple pass thru to the form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable to get value for
    * @return variant Value of form variable
    *
    */   
    public function get($varName)
    {
        return $this->_form->get($varName);
    }
    
    /**
    * Deletes a form variable
    *
    * This is a simple pass thru to the form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of form variable to delete
    *
    */
    public function remove($varName)
    {
        $this->_form->remove($varName);
    }
    
    /**
    * Sets a field to given value
    *
    * This is a simple pass thru to the form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $varName Name of field to set
    * @param string $value Value to set field to
    *
    */
    public function set($varName, $value)
    {
        $this->_form->set($varName, $value);
    }
    
    /**
    * Returns value array
    *
    * This is a simple pass thru to the form object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array Values array
    *
    */
    public function &getValues()
    {
        return $this->_form->getValues();
    }
}

?>
--- NEW FILE: package.xml ---
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
<package version="1.0">
  <name>Geeklog_MVCnPHP</name>
  <summary>An MVC implementation in PHP</summary>
  <description>This is a Model-View-Controller (MVC) implementation in PHP.  It
                	is not meant to be a reimplementation of, say, Struts but it does provide the 
                	basic features of an MVC implementation.</description>
  <maintainers>
    <maintainer>
      <user>tbibbs</user>
      <name>Tony Bibbs</name>
      <email>tony at geeklog.net</email>
      <role>lead</role>
    </maintainer>
  </maintainers>
  <release>
    <version>2.0.0</version>
    <date>2004-12-14</date>
    <license>PHP License</license>
    <state>beta</state>
    <notes>Development snapshot, not for production use.</notes>
    <filelist>
      <file role="data" baseinstalldir="Geeklog/MVCnPHP" md5sum="bb8ceec495c6734167bacf14fa2f15bd" name="CVS/Entries"/>
      <file role="data" baseinstalldir="Geeklog/MVCnPHP" md5sum="2c9c744d1f586a73d85d4ca4859d94bb" name="CVS/Entries.Log"/>
      <file role="data" baseinstalldir="Geeklog/MVCnPHP" md5sum="b041e729af8e74ec508a976e2dbec3d3" name="CVS/Repository"/>
      <file role="data" baseinstalldir="Geeklog/MVCnPHP" md5sum="f70f73be70f56b5cfae0c9edf90c8a71" name="CVS/Root"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="0497f9805dfc49ea00a0c2a53070903f" name="ArrayLoader.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="9f49475f55288cb26a3ecfc2688ae2e5" name="BaseLoader.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="ee786af31a8ce10c594f229a071c5362" name="BaseView.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="037d7c1a33d98ddc30109e5fb93ba35b" name="buildPackage.php"/>
      <file role="data" baseinstalldir="Geeklog/MVCnPHP" md5sum="6bd65b88f1d582ee606d8de320d1c1e0" name="CHANGELOG"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="cd56807fcdd0b2ceef64e60e5647ff78" name="CommandFactory.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="41ccd9abea6ccba494d4fa8edc33fa7e" name="CommandInterface.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="eed9acf687e8ef52286dd751395b34b1" name="Constants.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="86ee6608d8aba2056a6dcda85ef23b3d" name="Controller.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="8666cd5b6efd59c88da63d6a10c93e7e" name="Form.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="78a8f5cc165245784ed0b1d6a66691c8" name="LoaderFactory.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="4736f85a5c03b7742eecebe9afa90a81" name="Mapping.php"/>
      <file role="doc" baseinstalldir="Geeklog/MVCnPHP" md5sum="0ae99555d19cbed5d77294eaed969537" name="README.txt"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="b0dc91c6cb44390de77874319a3a4cde" name="Validator.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="daad610caeb2004595d02d26a5a36f63" name="ViewFactory.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="7bb60ea76d7c2158d76ced374c62a107" name="ViewInterface.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="02f5583626659d5c6755dd319039f48d" name="XMLLoader.php"/>
      <file role="php" baseinstalldir="Geeklog/MVCnPHP" md5sum="faa964f85be1320ea719b091ee7d3f8c" name="XMLParser.php"/>
    </filelist>
  </release>
  <changelog>
    <release>
      <version>2.0.0</version>
      <date>2004-12-14</date>
      <license>PHP License</license>
      <state>beta</state>
      <notes>Development snapshot, not for production use.</notes>
    </release>
  </changelog>
</package>

--- NEW FILE: XMLParser.php ---
<?php

/**
* MVCnPHP - MVC_XMLParser.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: XMLParser.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* This class parses MVC configuration files
*
* NOTE: for you Java/Struts lovers out there, this is in now
* way deemed consistent with their implementation.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_XMLParser {
    /**
    * @access private
    * @var array
    */
    private $elements = null;
    
    /**
    * @access private
    * @var array
    */
    private $attributes = null;
    
    /**
    * @access private
    * @var array
    */
    private $values = null;
    
    /**
    * @access private
    * @var int
    */
    private $curElement = null;
    
    /**
    * @access private
    * @var int
    */
    private $level = 0;
    
    /**
    * @access private
    * @var object
    */
    private $parser = null;
    
    /**
    * Constructor
    *
    * Initializes object properties and, if the XML has been supplied
    * it will parse it immediately instead of waiting for an explicit
    * call to parseXML
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $xmlString XML to parse
    *
    */
    public function __construct($xmlString = '')
    {
        $this->elements = Array();
        $this->attributes = Array();
        $this->values = Array();
        if (!empty($xmlString)) {
            $this->parseXML($xmlString);
        }
    }
    
    /**
    * Parses the given MVC XML file
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $xmlString XML to parse
    *
    */
    public function parseXML($xmlString)
    {
        // Create Expat parser object
        $this->parser = xml_parser_create();
        
        // Lets expat know this class will handle the parsing
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, 'handleStartElement', 'handleEndElement');
        xml_set_character_data_handler($this->parser, 'handleData');
        
        // Actually parse the XML now.
        if (!xml_parse($this->parser, $xmlString)) {
            throw new Exception(sprintf("XML error: %s at line %d",
                xml_error_string(xml_get_error_code($this->parser)),
                xml_get_current_line_number($this->parser)));
        }
        xml_parser_free($this->parser);
    }
    
    /**
    * Called by expat functions to handle a start tag in XML stream
    *
    * This grabs a reference to the parent tag and any pertinent data
    * such as the tag name and any associate XML attributes
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param object $parser Reference to Expat parser object
    * @param string $name Name of XML tag that was encountered
    * @param array $attributes Any associated XML attributes
    *
    */
    private function handleStartElement($parser, $name, $attributes)
    {
        // This tidbit of code grabs the index into _elements for
        // the parent and sets that as an attribute
        if ($this->level > 1) {
            $attributes['PARENT'] = $this->curElement;
        } else {
            $attributes['PARENT'] = $this->level;
        }
        $this->numSiblings = $this->getNumSiblings($attributes['PARENT']);
        //$attributes['NUMSIBLINGS'] = $this->numSiblings;
        $this->level++;
        $this->elements[] = $name;
        $this->curElement = count($this->elements) - 1;
        $this->attributes[$this->curElement] = $attributes;
        
    }
    
    /**
    * Called by expat functions to handle an end tag in XML stream
    *
    * This adjusts some pointers that allow us to get handles to parent
    * XML tags
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * 
    */
    private function handleEndElement()
    {
        $this->level--;
        $this->curElement = $this->curElement - ($this->numSiblings + 1);
    }
    
    /**
    * Called by expat functions to handle the data taken
    * from XML stream
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param object $parser Expat parser object
    * @param string $data Data to handle
    *
    */
    private function handleData($parser, $data)
    {
        // NOTE: the use of trim() here is necessary as
        // empty() will not produce desired results
        if (empty($this->curElement) OR !trim($data)) return;
        $this->values[$this->curElement] = $data;
    }
    
    private function getNumSiblings($parent)
    {
        if ($parent == 1) return 0;
        $numSiblings = 0;
        foreach ($this->attributes as $curAtt) {
            if ($curAtt['PARENT'] == $parent) {
                $numSiblings++;
            }
        }
        return $numSiblings;
    }
    
    /**
    * Gets the XML tag represented by given index
    *
    * @author TonyBibbs <tony at geeklog.net>
    * @access public
    * @return string XML Tag name
    *
    */
    public function getTag($index)
    {
        return $this->elements[$index];
    }
    
    /**
    * Gets all indexes for _elements array
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array Keys for _elements array
    *
    */
    public function getElementIndexes()
    {
        return array_keys($this->elements);
    }
    
    /**
    * Gets an attribute for given index
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param int $index Index representing an XML tag in _elements array
    * @param string $attribute Name of attribute to get
    * @return string Requested attribute
    *
    */
    public function getAttribute($index, $attribute)
    {
        return $this->attributes[$index][strtoupper($attribute)];
    }
    
    /**
    * Returns value for given index
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param int $index Index into _elements array
    * @return string Value for given index
    *
    */
    public function getValue($index)
    {
        return $this->values[$index];
    }
}

?>
--- NEW FILE: CommandFactory.php ---
<?php

/**
* MVCnPHP - CommandFactory.class.php
*
* This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license at php.net so we can mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright Tony Bibbs 2003
* @package net.geeklog.mvc
* @version $Id: CommandFactory.php,v 1.1.2.1 2004/12/14 20:03:19 tony Exp $
*
*/

/**
* This implements the factory design pattern and is
* responsible for building command objects
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.mvc
*
*/
class MVCnPHP_CommandFactory {
    /**
    * Builds the requested command object
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $path Path to directory holding commands
    * @param string $name Name of command to create
    * @return object Command object
    *
    */
    public function &getCommand($path, $name)
    {
        if (!isset($name)) {
            throw new Exception('No command name given to CommandFactory::getCommand');
        }
        $filename = $path . $name . '.php';
        
        if (file_exists($filename)) {
            require_once $filename;
            $name = $name;
            return new $name();
        } else {
        	throw new Exception('Bad set of parameters to CommandFactory::getCommand');
        }
    }
}

?>



More information about the geeklog-cvs mailing list