<?php
/**
* SpotSec Framework
*
* LICENSE
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @category SpotSec
* @package SpotSec_Controller
* @subpackage Action
* @copyright Copyright (c) 2006 SpotSec Networks
* @license GNU Public License
* @link http://www.spotsec.com
*/
/**
* Zend_Controller_Action
*/
require_once('Zend/Controller/Action/Helper/Abstract.php');
/**
* Zend_Loader
*/
require_once('Zend/Loader.php');
/**
* Zend Action Helper include_path injector
*
* Must be the last registered plugin that modifies the request through preDispatch()
*
* @author Geoffrey Tran
* @license GNU Public License
* @category SpotSec
* @package SpotSec_Controller
* @subpackage Action
* @copyright Copyright 2006, SpotSec Networks
*/
class SpotSec_Controller_Action_Helper_ModelLoader extends Zend_Controller_Action_Helper_Abstract
{
/**
* Models base path
*
* @var string
*/
protected $_modelsBasePath = ':moduleDir/models';
/**
* Models controller directory path
*
* @var string
*/
protected $_modelsControllerPath = ':moduleDir/models/:controller';
/**
* Changes made to include_path()
*
* @var array
*/
protected $_changedIncludePath = array();
/**
* Construct
*
* @param string $modelsBasePath Base path
*/
public function __construct($modelsBasePath = ':moduleDir/models', $modelsControllerPath = ':controller')
{
$this->_modelsBasePath = (string) $modelsBasePath;
$this->_modelsControllerPath = (string) $modelsControllerPath;
}
/**
* direct(): Perform helper when called as
* $this->_helper->ModelLoader($model, $module, $controller);
*
* @param string $model
* @param string $module
* @param string $controller
*/
public function direct($model, $module = null, $controller = null)
{
$this->load($model, $module, $controller);
}
/**
* Called before an action is dispatched by Zend_Controller_Dispatcher.
*
* This callback allows for proxy or filter behavior. By altering the
* request and resetting its dispatched flag (via
* {@link Zend_Controller_Request_Abstract::setDispatched() setDispatched(false)}),
* the current action may be skipped.
*
* @return void
*/
public function preDispatch()
{
$frontController = Zend_Controller_Front::getInstance();
$dispatcher = $frontController->getDispatcher();
if (! $dispatcher->isDispatchable($this->getRequest())) {
return;
}
// Remove old include paths that was set then add new one
$this->_resetIncludePath();
$this->_setIncludePath();
}
/**
* Load a model
*
* Load model from different module
*
* @param string $model
* @param string $module
* @param string $controller
*/
public function load($model, $module = null, $controller = null)
{
if (!empty($module) || !empty($controller)) {
$this->_setIncludePath(array(
'moduleDir' => $front->getControllerDirectory($module),
'controller' => $controller
));
}
Zend_Loader::loadClass($model);
}
/**
* Adds new model directory to include path
*
* @param array $vars Vars to overrride (@see translateSpec())
*/
protected function _setIncludePath(array $vars = array())
{
$modelsIncludePath = array(
PATH_SEPARATOR . $this->_translateSpec($this->_modelsBasePath, $vars),
PATH_SEPARATOR . $this->_translateSpec($this->_modelsBasePath . '/' .$this->_modelsControllerPath, $vars)
);
set_include_path(get_include_path() . implode($modelsIncludePath));
}
/**
* Clean the include path of any entries that was added by this class
*
*/
protected function _resetIncludePath()
{
set_include_path(
count($this->_changedIncludePath)
? str_replace($this->_changedIncludePath, '', get_include_path())
: get_include_path()
);
$this->_changedIncludePath = array();
}
/**
* Inject values into a spec string
*
* Allowed variables are:
* - :moduleDir - current module directory
* - :module - current module name
* - :controller - current controller name
* - :action - current action name
* - :suffix - view script file suffix
*
* @param string $spec
* @param array $vars
* @return string
*/
protected function _translateSpec($spec, array $vars = array())
{
$front = Zend_Controller_Front::getInstance();
$request = $this->getRequest();
$module = $request->getModuleName();
$controller = $request->getControllerName();
$action = $request->getActionName();
// Need to get default module name if null returned, so that we get a
// controller directory
if (null === $module) {
$module = $front->getDispatcher()->getDefaultModule();
}
$moduleDir = $front->getControllerDirectory($module);
if ((null === $moduleDir) || is_array($moduleDir)) {
throw new Zend_Controller_Exception('ModelsIncludePath cannot locate module directory');
}
foreach ($vars as $key => $value) {
switch ($key) {
case 'module':
case 'controller':
case 'action':
case 'moduleDir':
$$key = (string) $value;
break;
default:
break;
}
}
// Module, controller, and action names need normalized delimiters
if (null === $this->_delimiters) {
$dispatcher = $front->getDispatcher();
$wordDelimiters = $dispatcher->getWordDelimiter();
$pathDelimiters = $dispatcher->getPathDelimiter();
$this->_delimiters = array_unique(array_merge($wordDelimiters, (array) $pathDelimiters));
}
$moduleDir = dirname($moduleDir);
$replacements = array(
':moduleDir' => $moduleDir,
':module' => str_replace($this->_delimiters, '-', $module),
':controller' => str_replace($this->_delimiters, '-', $controller),
':action' => str_replace($this->_delimiters, '-', $action)
);
$value = str_replace(array_keys($replacements), array_values($replacements), $spec);
return $value;
}
}