web/Zend/Layout.php
changeset 0 4eba9c11703f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/Zend/Layout.php	Mon Dec 13 18:29:26 2010 +0100
@@ -0,0 +1,798 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Layout
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Layout.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * Provide Layout support for MVC applications
+ *
+ * @category   Zend
+ * @package    Zend_Layout
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Layout
+{
+    /**
+     * Placeholder container for layout variables
+     * @var Zend_View_Helper_Placeholder_Container
+     */
+    protected $_container;
+
+    /**
+     * Key used to store content from 'default' named response segment
+     * @var string
+     */
+    protected $_contentKey = 'content';
+
+    /**
+     * Are layouts enabled?
+     * @var bool
+     */
+    protected $_enabled = true;
+
+    /**
+     * Helper class
+     * @var string
+     */
+    protected $_helperClass = 'Zend_Layout_Controller_Action_Helper_Layout';
+
+    /**
+     * Inflector used to resolve layout script
+     * @var Zend_Filter_Inflector
+     */
+    protected $_inflector;
+
+    /**
+     * Flag: is inflector enabled?
+     * @var bool
+     */
+    protected $_inflectorEnabled = true;
+
+    /**
+     * Inflector target
+     * @var string
+     */
+    protected $_inflectorTarget = ':script.:suffix';
+
+    /**
+     * Layout view
+     * @var string
+     */
+    protected $_layout = 'layout';
+
+    /**
+     * Layout view script path
+     * @var string
+     */
+    protected $_viewScriptPath = null;
+
+    protected $_viewBasePath = null;
+    protected $_viewBasePrefix = 'Layout_View';
+
+    /**
+     * Flag: is MVC integration enabled?
+     * @var bool
+     */
+    protected $_mvcEnabled = true;
+
+    /**
+     * Instance registered with MVC, if any
+     * @var Zend_Layout
+     */
+    protected static $_mvcInstance;
+
+    /**
+     * Flag: is MVC successful action only flag set?
+     * @var bool
+     */
+    protected $_mvcSuccessfulActionOnly = true;
+
+    /**
+     * Plugin class
+     * @var string
+     */
+    protected $_pluginClass = 'Zend_Layout_Controller_Plugin_Layout';
+
+    /**
+     * @var Zend_View_Interface
+     */
+    protected $_view;
+
+    /**
+     * View script suffix for layout script
+     * @var string
+     */
+    protected $_viewSuffix = 'phtml';
+
+    /**
+     * Constructor
+     *
+     * Accepts either:
+     * - A string path to layouts
+     * - An array of options
+     * - A Zend_Config object with options
+     *
+     * Layout script path, either as argument or as key in options, is
+     * required.
+     *
+     * If mvcEnabled flag is false from options, simply sets layout script path.
+     * Otherwise, also instantiates and registers action helper and controller
+     * plugin.
+     *
+     * @param  string|array|Zend_Config $options
+     * @return void
+     */
+    public function __construct($options = null, $initMvc = false)
+    {
+        if (null !== $options) {
+            if (is_string($options)) {
+                $this->setLayoutPath($options);
+            } elseif (is_array($options)) {
+                $this->setOptions($options);
+            } elseif ($options instanceof Zend_Config) {
+                $this->setConfig($options);
+            } else {
+                require_once 'Zend/Layout/Exception.php';
+                throw new Zend_Layout_Exception('Invalid option provided to constructor');
+            }
+        }
+
+        $this->_initVarContainer();
+
+        if ($initMvc) {
+            $this->_setMvcEnabled(true);
+            $this->_initMvc();
+        } else {
+            $this->_setMvcEnabled(false);
+        }
+    }
+
+    /**
+     * Static method for initialization with MVC support
+     *
+     * @param  string|array|Zend_Config $options
+     * @return Zend_Layout
+     */
+    public static function startMvc($options = null)
+    {
+        if (null === self::$_mvcInstance) {
+            self::$_mvcInstance = new self($options, true);
+        }
+
+        if (is_string($options)) {
+            self::$_mvcInstance->setLayoutPath($options);
+        } elseif (is_array($options) || $options instanceof Zend_Config) {
+            self::$_mvcInstance->setOptions($options);
+        }
+
+        return self::$_mvcInstance;
+    }
+
+    /**
+     * Retrieve MVC instance of Zend_Layout object
+     *
+     * @return Zend_Layout|null
+     */
+    public static function getMvcInstance()
+    {
+        return self::$_mvcInstance;
+    }
+
+    /**
+     * Reset MVC instance
+     *
+     * Unregisters plugins and helpers, and destroys MVC layout instance.
+     *
+     * @return void
+     */
+    public static function resetMvcInstance()
+    {
+        if (null !== self::$_mvcInstance) {
+            $layout = self::$_mvcInstance;
+            $pluginClass = $layout->getPluginClass();
+            $front = Zend_Controller_Front::getInstance();
+            if ($front->hasPlugin($pluginClass)) {
+                $front->unregisterPlugin($pluginClass);
+            }
+
+            if (Zend_Controller_Action_HelperBroker::hasHelper('layout')) {
+                Zend_Controller_Action_HelperBroker::removeHelper('layout');
+            }
+
+            unset($layout);
+            self::$_mvcInstance = null;
+        }
+    }
+
+    /**
+     * Set options en masse
+     *
+     * @param  array|Zend_Config $options
+     * @return void
+     */
+    public function setOptions($options)
+    {
+        if ($options instanceof Zend_Config) {
+            $options = $options->toArray();
+        } elseif (!is_array($options)) {
+            require_once 'Zend/Layout/Exception.php';
+            throw new Zend_Layout_Exception('setOptions() expects either an array or a Zend_Config object');
+        }
+
+        foreach ($options as $key => $value) {
+            $method = 'set' . ucfirst($key);
+            if (method_exists($this, $method)) {
+                $this->$method($value);
+            }
+        }
+    }
+
+    /**
+     * Initialize MVC integration
+     *
+     * @return void
+     */
+    protected function _initMvc()
+    {
+        $this->_initPlugin();
+        $this->_initHelper();
+    }
+
+    /**
+     * Initialize front controller plugin
+     *
+     * @return void
+     */
+    protected function _initPlugin()
+    {
+        $pluginClass = $this->getPluginClass();
+        require_once 'Zend/Controller/Front.php';
+        $front = Zend_Controller_Front::getInstance();
+        if (!$front->hasPlugin($pluginClass)) {
+            if (!class_exists($pluginClass)) {
+                require_once 'Zend/Loader.php';
+                Zend_Loader::loadClass($pluginClass);
+            }
+            $front->registerPlugin(
+                // register to run last | BUT before the ErrorHandler (if its available)
+                new $pluginClass($this),
+                99
+            );
+        }
+    }
+
+    /**
+     * Initialize action helper
+     *
+     * @return void
+     */
+    protected function _initHelper()
+    {
+        $helperClass = $this->getHelperClass();
+        require_once 'Zend/Controller/Action/HelperBroker.php';
+        if (!Zend_Controller_Action_HelperBroker::hasHelper('layout')) {
+            if (!class_exists($helperClass)) {
+                require_once 'Zend/Loader.php';
+                Zend_Loader::loadClass($helperClass);
+            }
+            Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-90, new $helperClass($this));
+        }
+    }
+
+    /**
+     * Set options from a config object
+     *
+     * @param  Zend_Config $config
+     * @return Zend_Layout
+     */
+    public function setConfig(Zend_Config $config)
+    {
+        $this->setOptions($config->toArray());
+        return $this;
+    }
+
+    /**
+     * Initialize placeholder container for layout vars
+     *
+     * @return Zend_View_Helper_Placeholder_Container
+     */
+    protected function _initVarContainer()
+    {
+        if (null === $this->_container) {
+            require_once 'Zend/View/Helper/Placeholder/Registry.php';
+            $this->_container = Zend_View_Helper_Placeholder_Registry::getRegistry()->getContainer(__CLASS__);
+        }
+
+        return $this->_container;
+    }
+
+    /**
+     * Set layout script to use
+     *
+     * Note: enables layout by default, can be disabled
+     *
+     * @param  string $name
+     * @param  boolean $enabled
+     * @return Zend_Layout
+     */
+    public function setLayout($name, $enabled = true)
+    {
+        $this->_layout = (string) $name;
+        if ($enabled) {
+            $this->enableLayout();
+        }
+        return $this;
+    }
+
+    /**
+     * Get current layout script
+     *
+     * @return string
+     */
+    public function getLayout()
+    {
+        return $this->_layout;
+    }
+
+    /**
+     * Disable layout
+     *
+     * @return Zend_Layout
+     */
+    public function disableLayout()
+    {
+        $this->_enabled = false;
+        return $this;
+    }
+
+    /**
+     * Enable layout
+     *
+     * @return Zend_Layout
+     */
+    public function enableLayout()
+    {
+        $this->_enabled = true;
+        return $this;
+    }
+
+    /**
+     * Is layout enabled?
+     *
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return $this->_enabled;
+    }
+
+
+    public function setViewBasePath($path, $prefix = 'Layout_View')
+    {
+        $this->_viewBasePath = $path;
+        $this->_viewBasePrefix = $prefix;
+        return $this;
+    }
+
+    public function getViewBasePath()
+    {
+        return $this->_viewBasePath;
+    }
+
+    public function setViewScriptPath($path)
+    {
+        $this->_viewScriptPath = $path;
+        return $this;
+    }
+
+    public function getViewScriptPath()
+    {
+        return $this->_viewScriptPath;
+    }
+
+    /**
+     * Set layout script path
+     *
+     * @param  string $path
+     * @return Zend_Layout
+     */
+    public function setLayoutPath($path)
+    {
+        return $this->setViewScriptPath($path);
+    }
+
+    /**
+     * Get current layout script path
+     *
+     * @return string
+     */
+    public function getLayoutPath()
+    {
+        return $this->getViewScriptPath();
+    }
+
+    /**
+     * Set content key
+     *
+     * Key in namespace container denoting default content
+     *
+     * @param  string $contentKey
+     * @return Zend_Layout
+     */
+    public function setContentKey($contentKey)
+    {
+        $this->_contentKey = (string) $contentKey;
+        return $this;
+    }
+
+    /**
+     * Retrieve content key
+     *
+     * @return string
+     */
+    public function getContentKey()
+    {
+        return $this->_contentKey;
+    }
+
+    /**
+     * Set MVC enabled flag
+     *
+     * @param  bool $mvcEnabled
+     * @return Zend_Layout
+     */
+    protected function _setMvcEnabled($mvcEnabled)
+    {
+        $this->_mvcEnabled = ($mvcEnabled) ? true : false;
+        return $this;
+    }
+
+    /**
+     * Retrieve MVC enabled flag
+     *
+     * @return bool
+     */
+    public function getMvcEnabled()
+    {
+        return $this->_mvcEnabled;
+    }
+
+    /**
+     * Set MVC Successful Action Only flag
+     *
+     * @param bool $successfulActionOnly
+     * @return Zend_Layout
+     */
+    public function setMvcSuccessfulActionOnly($successfulActionOnly)
+    {
+        $this->_mvcSuccessfulActionOnly = ($successfulActionOnly) ? true : false;
+        return $this;
+    }
+
+    /**
+     * Get MVC Successful Action Only Flag
+     *
+     * @return bool
+     */
+    public function getMvcSuccessfulActionOnly()
+    {
+        return $this->_mvcSuccessfulActionOnly;
+    }
+
+    /**
+     * Set view object
+     *
+     * @param  Zend_View_Interface $view
+     * @return Zend_Layout
+     */
+    public function setView(Zend_View_Interface $view)
+    {
+        $this->_view = $view;
+        return $this;
+    }
+
+    /**
+     * Retrieve helper class
+     *
+     * @return string
+     */
+    public function getHelperClass()
+    {
+        return $this->_helperClass;
+    }
+
+    /**
+     * Set helper class
+     *
+     * @param  string $helperClass
+     * @return Zend_Layout
+     */
+    public function setHelperClass($helperClass)
+    {
+        $this->_helperClass = (string) $helperClass;
+        return $this;
+    }
+
+    /**
+     * Retrieve plugin class
+     *
+     * @return string
+     */
+    public function getPluginClass()
+    {
+        return $this->_pluginClass;
+    }
+
+    /**
+     * Set plugin class
+     *
+     * @param  string $pluginClass
+     * @return Zend_Layout
+     */
+    public function setPluginClass($pluginClass)
+    {
+        $this->_pluginClass = (string) $pluginClass;
+        return $this;
+    }
+
+    /**
+     * Get current view object
+     *
+     * If no view object currently set, retrieves it from the ViewRenderer.
+     *
+     * @todo Set inflector from view renderer at same time
+     * @return Zend_View_Interface
+     */
+    public function getView()
+    {
+        if (null === $this->_view) {
+            require_once 'Zend/Controller/Action/HelperBroker.php';
+            $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
+            if (null === $viewRenderer->view) {
+                $viewRenderer->initView();
+            }
+            $this->setView($viewRenderer->view);
+        }
+        return $this->_view;
+    }
+
+    /**
+     * Set layout view script suffix
+     *
+     * @param  string $viewSuffix
+     * @return Zend_Layout
+     */
+    public function setViewSuffix($viewSuffix)
+    {
+        $this->_viewSuffix = (string) $viewSuffix;
+        return $this;
+    }
+
+    /**
+     * Retrieve layout view script suffix
+     *
+     * @return string
+     */
+    public function getViewSuffix()
+    {
+        return $this->_viewSuffix;
+    }
+
+    /**
+     * Retrieve inflector target
+     *
+     * @return string
+     */
+    public function getInflectorTarget()
+    {
+        return $this->_inflectorTarget;
+    }
+
+    /**
+     * Set inflector target
+     *
+     * @param  string $inflectorTarget
+     * @return Zend_Layout
+     */
+    public function setInflectorTarget($inflectorTarget)
+    {
+        $this->_inflectorTarget = (string) $inflectorTarget;
+        return $this;
+    }
+
+    /**
+     * Set inflector to use when resolving layout names
+     *
+     * @param  Zend_Filter_Inflector $inflector
+     * @return Zend_Layout
+     */
+    public function setInflector(Zend_Filter_Inflector $inflector)
+    {
+        $this->_inflector = $inflector;
+        return $this;
+    }
+
+    /**
+     * Retrieve inflector
+     *
+     * @return Zend_Filter_Inflector
+     */
+    public function getInflector()
+    {
+        if (null === $this->_inflector) {
+            require_once 'Zend/Filter/Inflector.php';
+            $inflector = new Zend_Filter_Inflector();
+            $inflector->setTargetReference($this->_inflectorTarget)
+                      ->addRules(array(':script' => array('Word_CamelCaseToDash', 'StringToLower')))
+                      ->setStaticRuleReference('suffix', $this->_viewSuffix);
+            $this->setInflector($inflector);
+        }
+
+        return $this->_inflector;
+    }
+
+    /**
+     * Enable inflector
+     *
+     * @return Zend_Layout
+     */
+    public function enableInflector()
+    {
+        $this->_inflectorEnabled = true;
+        return $this;
+    }
+
+    /**
+     * Disable inflector
+     *
+     * @return Zend_Layout
+     */
+    public function disableInflector()
+    {
+        $this->_inflectorEnabled = false;
+        return $this;
+    }
+
+    /**
+     * Return status of inflector enabled flag
+     *
+     * @return bool
+     */
+    public function inflectorEnabled()
+    {
+        return $this->_inflectorEnabled;
+    }
+
+    /**
+     * Set layout variable
+     *
+     * @param  string $key
+     * @param  mixed $value
+     * @return void
+     */
+    public function __set($key, $value)
+    {
+        $this->_container[$key] = $value;
+    }
+
+    /**
+     * Get layout variable
+     *
+     * @param  string $key
+     * @return mixed
+     */
+    public function __get($key)
+    {
+        if (isset($this->_container[$key])) {
+            return $this->_container[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * Is a layout variable set?
+     *
+     * @param  string $key
+     * @return bool
+     */
+    public function __isset($key)
+    {
+        return (isset($this->_container[$key]));
+    }
+
+    /**
+     * Unset a layout variable?
+     *
+     * @param  string $key
+     * @return void
+     */
+    public function __unset($key)
+    {
+        if (isset($this->_container[$key])) {
+            unset($this->_container[$key]);
+        }
+    }
+
+    /**
+     * Assign one or more layout variables
+     *
+     * @param  mixed $spec Assoc array or string key; if assoc array, sets each
+     * key as a layout variable
+     * @param  mixed $value Value if $spec is a key
+     * @return Zend_Layout
+     * @throws Zend_Layout_Exception if non-array/string value passed to $spec
+     */
+    public function assign($spec, $value = null)
+    {
+        if (is_array($spec)) {
+            $orig = $this->_container->getArrayCopy();
+            $merged = array_merge($orig, $spec);
+            $this->_container->exchangeArray($merged);
+            return $this;
+        }
+
+        if (is_string($spec)) {
+            $this->_container[$spec] = $value;
+            return $this;
+        }
+
+        require_once 'Zend/Layout/Exception.php';
+        throw new Zend_Layout_Exception('Invalid values passed to assign()');
+    }
+
+    /**
+     * Render layout
+     *
+     * Sets internal script path as last path on script path stack, assigns
+     * layout variables to view, determines layout name using inflector, and
+     * renders layout view script.
+     *
+     * $name will be passed to the inflector as the key 'script'.
+     *
+     * @param  mixed $name
+     * @return mixed
+     */
+    public function render($name = null)
+    {
+        if (null === $name) {
+            $name = $this->getLayout();
+        }
+
+        if ($this->inflectorEnabled() && (null !== ($inflector = $this->getInflector())))
+        {
+            $name = $this->_inflector->filter(array('script' => $name));
+        }
+
+        $view = $this->getView();
+
+        if (null !== ($path = $this->getViewScriptPath())) {
+            if (method_exists($view, 'addScriptPath')) {
+                $view->addScriptPath($path);
+            } else {
+                $view->setScriptPath($path);
+            }
+        } elseif (null !== ($path = $this->getViewBasePath())) {
+            $view->addBasePath($path, $this->_viewBasePrefix);
+        }
+
+        return $view->render($name);
+    }
+}