File indexing completed on 2024-04-28 06:00:02

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Layout
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /**
0023  * Provide Layout support for MVC applications
0024  *
0025  * @category   Zend
0026  * @package    Zend_Layout
0027  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0028  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0029  */
0030 class Zend_Layout
0031 {
0032     /**
0033      * Placeholder container for layout variables
0034      * @var Zend_View_Helper_Placeholder_Container
0035      */
0036     protected $_container;
0037 
0038     /**
0039      * Key used to store content from 'default' named response segment
0040      * @var string
0041      */
0042     protected $_contentKey = 'content';
0043 
0044     /**
0045      * Are layouts enabled?
0046      * @var bool
0047      */
0048     protected $_enabled = true;
0049 
0050     /**
0051      * Helper class
0052      * @var string
0053      */
0054     protected $_helperClass = 'Zend_Layout_Controller_Action_Helper_Layout';
0055 
0056     /**
0057      * Inflector used to resolve layout script
0058      * @var Zend_Filter_Inflector
0059      */
0060     protected $_inflector;
0061 
0062     /**
0063      * Flag: is inflector enabled?
0064      * @var bool
0065      */
0066     protected $_inflectorEnabled = true;
0067 
0068     /**
0069      * Inflector target
0070      * @var string
0071      */
0072     protected $_inflectorTarget = ':script.:suffix';
0073 
0074     /**
0075      * Layout view
0076      * @var string
0077      */
0078     protected $_layout = 'layout';
0079 
0080     /**
0081      * Layout view script path
0082      * @var string
0083      */
0084     protected $_viewScriptPath = null;
0085 
0086     protected $_viewBasePath = null;
0087     protected $_viewBasePrefix = 'Layout_View';
0088 
0089     /**
0090      * Flag: is MVC integration enabled?
0091      * @var bool
0092      */
0093     protected $_mvcEnabled = true;
0094 
0095     /**
0096      * Instance registered with MVC, if any
0097      * @var Zend_Layout
0098      */
0099     protected static $_mvcInstance;
0100 
0101     /**
0102      * Flag: is MVC successful action only flag set?
0103      * @var bool
0104      */
0105     protected $_mvcSuccessfulActionOnly = true;
0106 
0107     /**
0108      * Plugin class
0109      * @var string
0110      */
0111     protected $_pluginClass = 'Zend_Layout_Controller_Plugin_Layout';
0112 
0113     /**
0114      * @var Zend_View_Interface
0115      */
0116     protected $_view;
0117 
0118     /**
0119      * View script suffix for layout script
0120      * @var string
0121      */
0122     protected $_viewSuffix = 'phtml';
0123 
0124     /**
0125      * Constructor
0126      *
0127      * Accepts either:
0128      * - A string path to layouts
0129      * - An array of options
0130      * - A Zend_Config object with options
0131      *
0132      * Layout script path, either as argument or as key in options, is
0133      * required.
0134      *
0135      * If mvcEnabled flag is false from options, simply sets layout script path.
0136      * Otherwise, also instantiates and registers action helper and controller
0137      * plugin.
0138      *
0139      * @param  string|array|Zend_Config $options
0140      * @return void
0141      */
0142     public function __construct($options = null, $initMvc = false)
0143     {
0144         if (null !== $options) {
0145             if (is_string($options)) {
0146                 $this->setLayoutPath($options);
0147             } elseif (is_array($options)) {
0148                 $this->setOptions($options);
0149             } elseif ($options instanceof Zend_Config) {
0150                 $this->setConfig($options);
0151             } else {
0152                 // require_once 'Zend/Layout/Exception.php';
0153                 throw new Zend_Layout_Exception('Invalid option provided to constructor');
0154             }
0155         }
0156 
0157         $this->_initVarContainer();
0158 
0159         if ($initMvc) {
0160             $this->_setMvcEnabled(true);
0161             $this->_initMvc();
0162         } else {
0163             $this->_setMvcEnabled(false);
0164         }
0165     }
0166 
0167     /**
0168      * Static method for initialization with MVC support
0169      *
0170      * @param  string|array|Zend_Config $options
0171      * @return Zend_Layout
0172      */
0173     public static function startMvc($options = null)
0174     {
0175         if (null === self::$_mvcInstance) {
0176             self::$_mvcInstance = new self($options, true);
0177         } else {
0178             if (is_string($options)) {
0179                 self::$_mvcInstance->setLayoutPath($options);
0180             } elseif (is_array($options) || $options instanceof Zend_Config) {
0181                 self::$_mvcInstance->setOptions($options);
0182             }
0183         }
0184 
0185         return self::$_mvcInstance;
0186     }
0187 
0188     /**
0189      * Retrieve MVC instance of Zend_Layout object
0190      *
0191      * @return Zend_Layout|null
0192      */
0193     public static function getMvcInstance()
0194     {
0195         return self::$_mvcInstance;
0196     }
0197 
0198     /**
0199      * Reset MVC instance
0200      *
0201      * Unregisters plugins and helpers, and destroys MVC layout instance.
0202      *
0203      * @return void
0204      */
0205     public static function resetMvcInstance()
0206     {
0207         if (null !== self::$_mvcInstance) {
0208             $layout = self::$_mvcInstance;
0209             $pluginClass = $layout->getPluginClass();
0210             $front = Zend_Controller_Front::getInstance();
0211             if ($front->hasPlugin($pluginClass)) {
0212                 $front->unregisterPlugin($pluginClass);
0213             }
0214 
0215             if (Zend_Controller_Action_HelperBroker::hasHelper('layout')) {
0216                 Zend_Controller_Action_HelperBroker::removeHelper('layout');
0217             }
0218 
0219             unset($layout);
0220             self::$_mvcInstance = null;
0221         }
0222     }
0223 
0224     /**
0225      * Set options en masse
0226      *
0227      * @param  array|Zend_Config $options
0228      * @return void
0229      */
0230     public function setOptions($options)
0231     {
0232         if ($options instanceof Zend_Config) {
0233             $options = $options->toArray();
0234         } elseif (!is_array($options)) {
0235             // require_once 'Zend/Layout/Exception.php';
0236             throw new Zend_Layout_Exception('setOptions() expects either an array or a Zend_Config object');
0237         }
0238 
0239         foreach ($options as $key => $value) {
0240             $method = 'set' . ucfirst($key);
0241             if (method_exists($this, $method)) {
0242                 $this->$method($value);
0243             }
0244         }
0245     }
0246 
0247     /**
0248      * Initialize MVC integration
0249      *
0250      * @return void
0251      */
0252     protected function _initMvc()
0253     {
0254         $this->_initPlugin();
0255         $this->_initHelper();
0256     }
0257 
0258     /**
0259      * Initialize front controller plugin
0260      *
0261      * @return void
0262      */
0263     protected function _initPlugin()
0264     {
0265         $pluginClass = $this->getPluginClass();
0266         // require_once 'Zend/Controller/Front.php';
0267         $front = Zend_Controller_Front::getInstance();
0268         if (!$front->hasPlugin($pluginClass)) {
0269             if (!class_exists($pluginClass)) {
0270                 // require_once 'Zend/Loader.php';
0271                 Zend_Loader::loadClass($pluginClass);
0272             }
0273             $front->registerPlugin(
0274                 // register to run last | BUT before the ErrorHandler (if its available)
0275                 new $pluginClass($this),
0276                 99
0277             );
0278         }
0279     }
0280 
0281     /**
0282      * Initialize action helper
0283      *
0284      * @return void
0285      */
0286     protected function _initHelper()
0287     {
0288         $helperClass = $this->getHelperClass();
0289         // require_once 'Zend/Controller/Action/HelperBroker.php';
0290         if (!Zend_Controller_Action_HelperBroker::hasHelper('layout')) {
0291             if (!class_exists($helperClass)) {
0292                 // require_once 'Zend/Loader.php';
0293                 Zend_Loader::loadClass($helperClass);
0294             }
0295             Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-90, new $helperClass($this));
0296         }
0297     }
0298 
0299     /**
0300      * Set options from a config object
0301      *
0302      * @param  Zend_Config $config
0303      * @return Zend_Layout
0304      */
0305     public function setConfig(Zend_Config $config)
0306     {
0307         $this->setOptions($config->toArray());
0308         return $this;
0309     }
0310 
0311     /**
0312      * Initialize placeholder container for layout vars
0313      *
0314      * @return Zend_View_Helper_Placeholder_Container
0315      */
0316     protected function _initVarContainer()
0317     {
0318         if (null === $this->_container) {
0319             // require_once 'Zend/View/Helper/Placeholder/Registry.php';
0320             $this->_container = Zend_View_Helper_Placeholder_Registry::getRegistry()->getContainer(__CLASS__);
0321         }
0322 
0323         return $this->_container;
0324     }
0325 
0326     /**
0327      * Set layout script to use
0328      *
0329      * Note: enables layout by default, can be disabled
0330      *
0331      * @param  string $name
0332      * @param  boolean $enabled
0333      * @return Zend_Layout
0334      */
0335     public function setLayout($name, $enabled = true)
0336     {
0337         $this->_layout = (string) $name;
0338         if ($enabled) {
0339             $this->enableLayout();
0340         }
0341         return $this;
0342     }
0343 
0344     /**
0345      * Get current layout script
0346      *
0347      * @return string
0348      */
0349     public function getLayout()
0350     {
0351         return $this->_layout;
0352     }
0353 
0354     /**
0355      * Disable layout
0356      *
0357      * @return Zend_Layout
0358      */
0359     public function disableLayout()
0360     {
0361         $this->_enabled = false;
0362         return $this;
0363     }
0364 
0365     /**
0366      * Enable layout
0367      *
0368      * @return Zend_Layout
0369      */
0370     public function enableLayout()
0371     {
0372         $this->_enabled = true;
0373         return $this;
0374     }
0375 
0376     /**
0377      * Is layout enabled?
0378      *
0379      * @return bool
0380      */
0381     public function isEnabled()
0382     {
0383         return $this->_enabled;
0384     }
0385 
0386 
0387     public function setViewBasePath($path, $prefix = 'Layout_View')
0388     {
0389         $this->_viewBasePath = $path;
0390         $this->_viewBasePrefix = $prefix;
0391         return $this;
0392     }
0393 
0394     public function getViewBasePath()
0395     {
0396         return $this->_viewBasePath;
0397     }
0398 
0399     public function setViewScriptPath($path)
0400     {
0401         $this->_viewScriptPath = $path;
0402         return $this;
0403     }
0404 
0405     public function getViewScriptPath()
0406     {
0407         return $this->_viewScriptPath;
0408     }
0409 
0410     /**
0411      * Set layout script path
0412      *
0413      * @param  string $path
0414      * @return Zend_Layout
0415      */
0416     public function setLayoutPath($path)
0417     {
0418         return $this->setViewScriptPath($path);
0419     }
0420 
0421     /**
0422      * Get current layout script path
0423      *
0424      * @return string
0425      */
0426     public function getLayoutPath()
0427     {
0428         return $this->getViewScriptPath();
0429     }
0430 
0431     /**
0432      * Set content key
0433      *
0434      * Key in namespace container denoting default content
0435      *
0436      * @param  string $contentKey
0437      * @return Zend_Layout
0438      */
0439     public function setContentKey($contentKey)
0440     {
0441         $this->_contentKey = (string) $contentKey;
0442         return $this;
0443     }
0444 
0445     /**
0446      * Retrieve content key
0447      *
0448      * @return string
0449      */
0450     public function getContentKey()
0451     {
0452         return $this->_contentKey;
0453     }
0454 
0455     /**
0456      * Set MVC enabled flag
0457      *
0458      * @param  bool $mvcEnabled
0459      * @return Zend_Layout
0460      */
0461     protected function _setMvcEnabled($mvcEnabled)
0462     {
0463         $this->_mvcEnabled = ($mvcEnabled) ? true : false;
0464         return $this;
0465     }
0466 
0467     /**
0468      * Retrieve MVC enabled flag
0469      *
0470      * @return bool
0471      */
0472     public function getMvcEnabled()
0473     {
0474         return $this->_mvcEnabled;
0475     }
0476 
0477     /**
0478      * Set MVC Successful Action Only flag
0479      *
0480      * @param bool $successfulActionOnly
0481      * @return Zend_Layout
0482      */
0483     public function setMvcSuccessfulActionOnly($successfulActionOnly)
0484     {
0485         $this->_mvcSuccessfulActionOnly = ($successfulActionOnly) ? true : false;
0486         return $this;
0487     }
0488 
0489     /**
0490      * Get MVC Successful Action Only Flag
0491      *
0492      * @return bool
0493      */
0494     public function getMvcSuccessfulActionOnly()
0495     {
0496         return $this->_mvcSuccessfulActionOnly;
0497     }
0498 
0499     /**
0500      * Set view object
0501      *
0502      * @param  Zend_View_Interface $view
0503      * @return Zend_Layout
0504      */
0505     public function setView(Zend_View_Interface $view)
0506     {
0507         $this->_view = $view;
0508         return $this;
0509     }
0510 
0511     /**
0512      * Retrieve helper class
0513      *
0514      * @return string
0515      */
0516     public function getHelperClass()
0517     {
0518         return $this->_helperClass;
0519     }
0520 
0521     /**
0522      * Set helper class
0523      *
0524      * @param  string $helperClass
0525      * @return Zend_Layout
0526      */
0527     public function setHelperClass($helperClass)
0528     {
0529         $this->_helperClass = (string) $helperClass;
0530         return $this;
0531     }
0532 
0533     /**
0534      * Retrieve plugin class
0535      *
0536      * @return string
0537      */
0538     public function getPluginClass()
0539     {
0540         return $this->_pluginClass;
0541     }
0542 
0543     /**
0544      * Set plugin class
0545      *
0546      * @param  string $pluginClass
0547      * @return Zend_Layout
0548      */
0549     public function setPluginClass($pluginClass)
0550     {
0551         $this->_pluginClass = (string) $pluginClass;
0552         return $this;
0553     }
0554 
0555     /**
0556      * Get current view object
0557      *
0558      * If no view object currently set, retrieves it from the ViewRenderer.
0559      *
0560      * @todo Set inflector from view renderer at same time
0561      * @return Zend_View_Interface
0562      */
0563     public function getView()
0564     {
0565         if (null === $this->_view) {
0566             // require_once 'Zend/Controller/Action/HelperBroker.php';
0567             $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
0568             if (null === $viewRenderer->view) {
0569                 $viewRenderer->initView();
0570             }
0571             $this->setView($viewRenderer->view);
0572         }
0573         return $this->_view;
0574     }
0575 
0576     /**
0577      * Set layout view script suffix
0578      *
0579      * @param  string $viewSuffix
0580      * @return Zend_Layout
0581      */
0582     public function setViewSuffix($viewSuffix)
0583     {
0584         $this->_viewSuffix = (string) $viewSuffix;
0585         return $this;
0586     }
0587 
0588     /**
0589      * Retrieve layout view script suffix
0590      *
0591      * @return string
0592      */
0593     public function getViewSuffix()
0594     {
0595         return $this->_viewSuffix;
0596     }
0597 
0598     /**
0599      * Retrieve inflector target
0600      *
0601      * @return string
0602      */
0603     public function getInflectorTarget()
0604     {
0605         return $this->_inflectorTarget;
0606     }
0607 
0608     /**
0609      * Set inflector target
0610      *
0611      * @param  string $inflectorTarget
0612      * @return Zend_Layout
0613      */
0614     public function setInflectorTarget($inflectorTarget)
0615     {
0616         $this->_inflectorTarget = (string) $inflectorTarget;
0617         return $this;
0618     }
0619 
0620     /**
0621      * Set inflector to use when resolving layout names
0622      *
0623      * @param  Zend_Filter_Inflector $inflector
0624      * @return Zend_Layout
0625      */
0626     public function setInflector(Zend_Filter_Inflector $inflector)
0627     {
0628         $this->_inflector = $inflector;
0629         return $this;
0630     }
0631 
0632     /**
0633      * Retrieve inflector
0634      *
0635      * @return Zend_Filter_Inflector
0636      */
0637     public function getInflector()
0638     {
0639         if (null === $this->_inflector) {
0640             // require_once 'Zend/Filter/Inflector.php';
0641             $inflector = new Zend_Filter_Inflector();
0642             $inflector->setTargetReference($this->_inflectorTarget)
0643                       ->addRules(array(':script' => array('Word_CamelCaseToDash', 'StringToLower')))
0644                       ->setStaticRuleReference('suffix', $this->_viewSuffix);
0645             $this->setInflector($inflector);
0646         }
0647 
0648         return $this->_inflector;
0649     }
0650 
0651     /**
0652      * Enable inflector
0653      *
0654      * @return Zend_Layout
0655      */
0656     public function enableInflector()
0657     {
0658         $this->_inflectorEnabled = true;
0659         return $this;
0660     }
0661 
0662     /**
0663      * Disable inflector
0664      *
0665      * @return Zend_Layout
0666      */
0667     public function disableInflector()
0668     {
0669         $this->_inflectorEnabled = false;
0670         return $this;
0671     }
0672 
0673     /**
0674      * Return status of inflector enabled flag
0675      *
0676      * @return bool
0677      */
0678     public function inflectorEnabled()
0679     {
0680         return $this->_inflectorEnabled;
0681     }
0682 
0683     /**
0684      * Set layout variable
0685      *
0686      * @param  string $key
0687      * @param  mixed $value
0688      * @return void
0689      */
0690     public function __set($key, $value)
0691     {
0692         $this->_container[$key] = $value;
0693     }
0694 
0695     /**
0696      * Get layout variable
0697      *
0698      * @param  string $key
0699      * @return mixed
0700      */
0701     public function __get($key)
0702     {
0703         if (isset($this->_container[$key])) {
0704             return $this->_container[$key];
0705         }
0706 
0707         return null;
0708     }
0709 
0710     /**
0711      * Is a layout variable set?
0712      *
0713      * @param  string $key
0714      * @return bool
0715      */
0716     public function __isset($key)
0717     {
0718         return (isset($this->_container[$key]));
0719     }
0720 
0721     /**
0722      * Unset a layout variable?
0723      *
0724      * @param  string $key
0725      * @return void
0726      */
0727     public function __unset($key)
0728     {
0729         if (isset($this->_container[$key])) {
0730             unset($this->_container[$key]);
0731         }
0732     }
0733 
0734     /**
0735      * Assign one or more layout variables
0736      *
0737      * @param  mixed $spec Assoc array or string key; if assoc array, sets each
0738      * key as a layout variable
0739      * @param  mixed $value Value if $spec is a key
0740      * @return Zend_Layout
0741      * @throws Zend_Layout_Exception if non-array/string value passed to $spec
0742      */
0743     public function assign($spec, $value = null)
0744     {
0745         if (is_array($spec)) {
0746             $orig = $this->_container->getArrayCopy();
0747             $merged = array_merge($orig, $spec);
0748             $this->_container->exchangeArray($merged);
0749             return $this;
0750         }
0751 
0752         if (is_string($spec)) {
0753             $this->_container[$spec] = $value;
0754             return $this;
0755         }
0756 
0757         // require_once 'Zend/Layout/Exception.php';
0758         throw new Zend_Layout_Exception('Invalid values passed to assign()');
0759     }
0760 
0761     /**
0762      * Render layout
0763      *
0764      * Sets internal script path as last path on script path stack, assigns
0765      * layout variables to view, determines layout name using inflector, and
0766      * renders layout view script.
0767      *
0768      * $name will be passed to the inflector as the key 'script'.
0769      *
0770      * @param  mixed $name
0771      * @return mixed
0772      */
0773     public function render($name = null)
0774     {
0775         if (null === $name) {
0776             $name = $this->getLayout();
0777         }
0778 
0779         if ($this->inflectorEnabled() && (null !== ($inflector = $this->getInflector())))
0780         {
0781             $name = $this->_inflector->filter(array('script' => $name));
0782         }
0783 
0784         $view = $this->getView();
0785 
0786         if (null !== ($path = $this->getViewScriptPath())) {
0787             if (method_exists($view, 'addScriptPath')) {
0788                 $view->addScriptPath($path);
0789             } else {
0790                 $view->setScriptPath($path);
0791             }
0792         } elseif (null !== ($path = $this->getViewBasePath())) {
0793             $view->addBasePath($path, $this->_viewBasePrefix);
0794         }
0795 
0796         return $view->render($name);
0797     }
0798 }