799 lines
18 KiB
PHP
799 lines
18 KiB
PHP
<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
* @version $Id: Layout.php 19089 2009-11-20 14:16:17Z bate $
|
|
*/
|
|
|
|
/**
|
|
* Provide Layout support for MVC applications
|
|
*
|
|
* @category Zend
|
|
* @package Zend_Layout
|
|
* @copyright Copyright (c) 2005-2009 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);
|
|
}
|
|
}
|