All pastes #523169 Raw Edit

Someone

public text v1 · immutable
#523169 ·published 2007-05-30 18:08 UTC
rendered paste body
<?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;
    }
}