diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
commit | 8ca6cc32b2c789a3149861159ad258f2cb9491e3 (patch) | |
tree | 2492de6f1528dd44eaa169a5c1555026d9cb75ec /library/vendor/Zend/Controller/Action | |
parent | Initial commit. (diff) | |
download | icingaweb2-upstream.tar.xz icingaweb2-upstream.zip |
Adding upstream version 2.11.4.upstream/2.11.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/vendor/Zend/Controller/Action')
14 files changed, 4700 insertions, 0 deletions
diff --git a/library/vendor/Zend/Controller/Action/Exception.php b/library/vendor/Zend/Controller/Action/Exception.php new file mode 100644 index 0000000..1c3438d --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Exception.php @@ -0,0 +1,37 @@ +<?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_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + + +/** + * @see Zend_Controller_Exception + */ + + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Exception extends Zend_Controller_Exception +{} diff --git a/library/vendor/Zend/Controller/Action/Helper/Abstract.php b/library/vendor/Zend/Controller/Action/Helper/Abstract.php new file mode 100644 index 0000000..e630be3 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/Abstract.php @@ -0,0 +1,155 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action + */ + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +abstract class Zend_Controller_Action_Helper_Abstract +{ + /** + * $_actionController + * + * @var Zend_Controller_Action $_actionController + */ + protected $_actionController = null; + + /** + * @var mixed $_frontController + */ + protected $_frontController = null; + + /** + * setActionController() + * + * @param Zend_Controller_Action $actionController + * @return Zend_Controller_ActionHelper_Abstract Provides a fluent interface + */ + public function setActionController(Zend_Controller_Action $actionController = null) + { + $this->_actionController = $actionController; + return $this; + } + + /** + * Retrieve current action controller + * + * @return Zend_Controller_Action + */ + public function getActionController() + { + return $this->_actionController; + } + + /** + * Retrieve front controller instance + * + * @return Zend_Controller_Front + */ + public function getFrontController() + { + return Zend_Controller_Front::getInstance(); + } + + /** + * Hook into action controller initialization + * + * @return void + */ + public function init() + { + } + + /** + * Hook into action controller preDispatch() workflow + * + * @return void + */ + public function preDispatch() + { + } + + /** + * Hook into action controller postDispatch() workflow + * + * @return void + */ + public function postDispatch() + { + } + + /** + * getRequest() - + * + * @return Zend_Controller_Request_Abstract $request + */ + public function getRequest() + { + $controller = $this->getActionController(); + if (null === $controller) { + $controller = $this->getFrontController(); + } + + return $controller->getRequest(); + } + + /** + * getResponse() - + * + * @return Zend_Controller_Response_Abstract $response + */ + public function getResponse() + { + $controller = $this->getActionController(); + if (null === $controller) { + $controller = $this->getFrontController(); + } + + return $controller->getResponse(); + } + + /** + * getName() + * + * @return string + */ + public function getName() + { + $fullClassName = get_class($this); + if (strpos($fullClassName, '_') !== false) { + $helperName = strrchr($fullClassName, '_'); + return ltrim($helperName, '_'); + } elseif (strpos($fullClassName, '\\') !== false) { + $helperName = strrchr($fullClassName, '\\'); + return ltrim($helperName, '\\'); + } else { + return $fullClassName; + } + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/ActionStack.php b/library/vendor/Zend/Controller/Action/Helper/ActionStack.php new file mode 100644 index 0000000..30fb633 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/ActionStack.php @@ -0,0 +1,133 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * Add to action stack + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_ActionStack extends Zend_Controller_Action_Helper_Abstract +{ + /** + * @var Zend_Controller_Plugin_ActionStack + */ + protected $_actionStack; + + /** + * Constructor + * + * Register action stack plugin + * + * @return void + */ + public function __construct() + { + $front = Zend_Controller_Front::getInstance(); + if (!$front->hasPlugin('Zend_Controller_Plugin_ActionStack')) { + /** + * @see Zend_Controller_Plugin_ActionStack + */ + $this->_actionStack = new Zend_Controller_Plugin_ActionStack(); + $front->registerPlugin($this->_actionStack, 97); + } else { + $this->_actionStack = $front->getPlugin('Zend_Controller_Plugin_ActionStack'); + } + } + + /** + * Push onto the stack + * + * @param Zend_Controller_Request_Abstract $next + * @return Zend_Controller_Action_Helper_ActionStack Provides a fluent interface + */ + public function pushStack(Zend_Controller_Request_Abstract $next) + { + $this->_actionStack->pushStack($next); + return $this; + } + + /** + * Push a new action onto the stack + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ActionStack + */ + public function actionToStack($action, $controller = null, $module = null, array $params = array()) + { + if ($action instanceof Zend_Controller_Request_Abstract) { + return $this->pushStack($action); + } elseif (!is_string($action)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('ActionStack requires either a request object or minimally a string action'); + } + + $request = $this->getRequest(); + + if ($request instanceof Zend_Controller_Request_Abstract === false){ + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('Request object not set yet'); + } + + $controller = (null === $controller) ? $request->getControllerName() : $controller; + $module = (null === $module) ? $request->getModuleName() : $module; + + /** + * @see Zend_Controller_Request_Simple + */ + $newRequest = new Zend_Controller_Request_Simple($action, $controller, $module, $params); + + return $this->pushStack($newRequest); + } + + /** + * Perform helper when called as $this->_helper->actionStack() from an action controller + * + * Proxies to {@link simple()} + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return boolean + */ + public function direct($action, $controller = null, $module = null, array $params = array()) + { + return $this->actionToStack($action, $controller, $module, $params); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/AjaxContext.php b/library/vendor/Zend/Controller/Action/Helper/AjaxContext.php new file mode 100644 index 0000000..3074a40 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/AjaxContext.php @@ -0,0 +1,79 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_ContextSwitch + */ + +/** + * Simplify AJAX context switching based on requested format + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_AjaxContext extends Zend_Controller_Action_Helper_ContextSwitch +{ + /** + * Controller property to utilize for context switching + * @var string + */ + protected $_contextKey = 'ajaxable'; + + /** + * Constructor + * + * Add HTML context + * + * @return void + */ + public function __construct() + { + parent::__construct(); + $this->addContext('html', array('suffix' => 'ajax')); + } + + /** + * Initialize AJAX context switching + * + * Checks for XHR requests; if detected, attempts to perform context switch. + * + * @param string $format + * @return void + */ + public function initContext($format = null) + { + $this->_currentContext = null; + + $request = $this->getRequest(); + if (!method_exists($request, 'isXmlHttpRequest') || + !$this->getRequest()->isXmlHttpRequest()) + { + return; + } + + return parent::initContext($format); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/AutoComplete/Abstract.php b/library/vendor/Zend/Controller/Action/Helper/AutoComplete/Abstract.php new file mode 100644 index 0000000..7cd4ad0 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/AutoComplete/Abstract.php @@ -0,0 +1,146 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * Create and send autocompletion lists + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +abstract class Zend_Controller_Action_Helper_AutoComplete_Abstract extends Zend_Controller_Action_Helper_Abstract +{ + /** + * Suppress exit when sendJson() called + * + * @var boolean + */ + public $suppressExit = false; + + /** + * Validate autocompletion data + * + * @param mixed $data + * @return boolean + */ + abstract public function validateData($data); + + /** + * Prepare autocompletion data + * + * @param mixed $data + * @param boolean $keepLayouts + * @return mixed + */ + abstract public function prepareAutoCompletion($data, $keepLayouts = false); + + /** + * Disable layouts and view renderer + * + * @return Zend_Controller_Action_Helper_AutoComplete_Abstract Provides a fluent interface + */ + public function disableLayouts() + { + /** + * @see Zend_Layout + */ + if (null !== ($layout = Zend_Layout::getMvcInstance())) { + $layout->disableLayout(); + } + + Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true); + + return $this; + } + + /** + * Encode data to JSON + * + * @param mixed $data + * @param bool $keepLayouts + * @throws Zend_Controller_Action_Exception + * @return string + */ + public function encodeJson($data, $keepLayouts = false) + { + if ($this->validateData($data)) { + return Zend_Controller_Action_HelperBroker::getStaticHelper('Json')->encodeJson($data, $keepLayouts); + } + + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('Invalid data passed for autocompletion'); + } + + /** + * Send autocompletion data + * + * Calls prepareAutoCompletion, populates response body with this + * information, and sends response. + * + * @param mixed $data + * @param bool $keepLayouts + * @return string|void + */ + public function sendAutoCompletion($data, $keepLayouts = false) + { + $data = $this->prepareAutoCompletion($data, $keepLayouts); + + $response = $this->getResponse(); + $response->setBody($data); + + if (!$this->suppressExit) { + $response->sendResponse(); + exit; + } + + return $data; + } + + /** + * Strategy pattern: allow calling helper as broker method + * + * Prepares autocompletion data and, if $sendNow is true, immediately sends + * response. + * + * @param mixed $data + * @param bool $sendNow + * @param bool $keepLayouts + * @return string|void + */ + public function direct($data, $sendNow = true, $keepLayouts = false) + { + if ($sendNow) { + return $this->sendAutoCompletion($data, $keepLayouts); + } + + return $this->prepareAutoCompletion($data, $keepLayouts); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/Cache.php b/library/vendor/Zend/Controller/Action/Helper/Cache.php new file mode 100644 index 0000000..32afc77 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/Cache.php @@ -0,0 +1,286 @@ +<?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_Controller + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * @see Zend_Controller_Action_Exception + */ + +/** + * @see Zend_Cache_Manager + */ + +/** + * @category Zend + * @package Zend_Controller + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_Cache + extends Zend_Controller_Action_Helper_Abstract +{ + + /** + * Local Cache Manager object used by Helper + * + * @var Zend_Cache_Manager + */ + protected $_manager = null; + + /** + * Indexed map of Actions to attempt Page caching on by Controller + * + * @var array + */ + protected $_caching = array(); + + /** + * Indexed map of Tags by Controller and Action + * + * @var array + */ + protected $_tags = array(); + + /** + * Indexed map of Extensions by Controller and Action + * + * @var array + */ + protected $_extensions = array(); + + /** + * Track output buffering condition + */ + protected $_obStarted = false; + + /** + * Tell the helper which actions are cacheable and under which + * tags (if applicable) they should be recorded with + * + * @param array $actions + * @param array $tags + * @return void + */ + public function direct(array $actions, array $tags = array(), $extension = null) + { + $controller = $this->getRequest()->getControllerName(); + $actions = array_unique($actions); + if (!isset($this->_caching[$controller])) { + $this->_caching[$controller] = array(); + } + if (!empty($tags)) { + $tags = array_unique($tags); + if (!isset($this->_tags[$controller])) { + $this->_tags[$controller] = array(); + } + } + foreach ($actions as $action) { + $this->_caching[$controller][] = $action; + if (!empty($tags)) { + $this->_tags[$controller][$action] = array(); + foreach ($tags as $tag) { + $this->_tags[$controller][$action][] = $tag; + } + } + } + if ($extension) { + if (!isset($this->_extensions[$controller])) { + $this->_extensions[$controller] = array(); + } + foreach ($actions as $action) { + $this->_extensions[$controller][$action] = $extension; + } + } + } + + /** + * Remove a specific page cache static file based on its + * relative URL from the application's public directory. + * The file extension is not required here; usually matches + * the original REQUEST_URI that was cached. + * + * @param string $relativeUrl + * @param bool $recursive + * @return mixed + */ + public function removePage($relativeUrl, $recursive = false) + { + $cache = $this->getCache(Zend_Cache_Manager::PAGECACHE); + $encodedCacheId = $this->_encodeCacheId($relativeUrl); + + if ($recursive) { + $backend = $cache->getBackend(); + if (($backend instanceof Zend_Cache_Backend) + && method_exists($backend, 'removeRecursively') + ) { + $result = $backend->removeRecursively($encodedCacheId); + if (is_null($result) ) { + $result = $backend->removeRecursively($relativeUrl); + } + return $result; + } + } + + $result = $cache->remove($encodedCacheId); + if (is_null($result) ) { + $result = $cache->remove($relativeUrl); + } + return $result; + } + + /** + * Remove a specific page cache static file based on its + * relative URL from the application's public directory. + * The file extension is not required here; usually matches + * the original REQUEST_URI that was cached. + * + * @param array $tags + * @return mixed + */ + public function removePagesTagged(array $tags) + { + return $this->getCache(Zend_Cache_Manager::PAGECACHE) + ->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags); + } + + /** + * Commence page caching for any cacheable actions + * + * @return void + */ + public function preDispatch() + { + $controller = $this->getRequest()->getControllerName(); + $action = $this->getRequest()->getActionName(); + $stats = ob_get_status(true); + foreach ($stats as $status) { + if ($status['name'] == 'Zend_Cache_Frontend_Page::_flush' + || $status['name'] == 'Zend_Cache_Frontend_Capture::_flush') { + $obStarted = true; + } + } + if (!isset($obStarted) && isset($this->_caching[$controller]) && + in_array($action, $this->_caching[$controller])) { + $reqUri = $this->getRequest()->getRequestUri(); + $tags = array(); + if (isset($this->_tags[$controller][$action]) + && !empty($this->_tags[$controller][$action])) { + $tags = array_unique($this->_tags[$controller][$action]); + } + $extension = null; + if (isset($this->_extensions[$controller][$action])) { + $extension = $this->_extensions[$controller][$action]; + } + $this->getCache(Zend_Cache_Manager::PAGECACHE) + ->start($this->_encodeCacheId($reqUri), $tags, $extension); + } + } + + /** + * Encode a Cache ID as hexadecimal. This is a workaround because Backend ID validation + * is trapped in the Frontend classes. Will try to get this reversed for ZF 2.0 + * because it's a major annoyance to have IDs so restricted! + * + * @return string + * @param string $requestUri + */ + protected function _encodeCacheId($requestUri) + { + return bin2hex($requestUri); + } + + /** + * Set an instance of the Cache Manager for this helper + * + * @param Zend_Cache_Manager $manager + * @return void + */ + public function setManager(Zend_Cache_Manager $manager) + { + $this->_manager = $manager; + return $this; + } + + /** + * Get the Cache Manager instance or instantiate the object if not + * exists. Attempts to load from bootstrap if available. + * + * @return Zend_Cache_Manager + */ + public function getManager() + { + if ($this->_manager !== null) { + return $this->_manager; + } + $front = Zend_Controller_Front::getInstance(); + if ($front->getParam('bootstrap') + && $front->getParam('bootstrap')->getResource('CacheManager')) { + return $front->getParam('bootstrap') + ->getResource('CacheManager'); + } + $this->_manager = new Zend_Cache_Manager; + return $this->_manager; + } + + /** + * Return a list of actions for the current Controller marked for + * caching + * + * @return array + */ + public function getCacheableActions() + { + return $this->_caching; + } + + /** + * Return a list of tags set for all cacheable actions + * + * @return array + */ + public function getCacheableTags() + { + return $this->_tags; + } + + /** + * Proxy non-matched methods back to Zend_Cache_Manager where + * appropriate + * + * @param string $method + * @param array $args + * @return mixed + */ + public function __call($method, $args) + { + if (method_exists($this->getManager(), $method)) { + return call_user_func_array( + array($this->getManager(), $method), $args + ); + } + throw new Zend_Controller_Action_Exception('Method does not exist:' + . $method); + } + +} diff --git a/library/vendor/Zend/Controller/Action/Helper/ContextSwitch.php b/library/vendor/Zend/Controller/Action/Helper/ContextSwitch.php new file mode 100644 index 0000000..6caeec9 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/ContextSwitch.php @@ -0,0 +1,1377 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * Simplify context switching based on requested format + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_ContextSwitch extends Zend_Controller_Action_Helper_Abstract +{ + /** + * Trigger type constants + */ + const TRIGGER_INIT = 'TRIGGER_INIT'; + const TRIGGER_POST = 'TRIGGER_POST'; + + /** + * Supported contexts + * @var array + */ + protected $_contexts = array(); + + /** + * JSON auto-serialization flag + * @var boolean + */ + protected $_autoJsonSerialization = true; + + /** + * Controller property key to utilize for context switching + * @var string + */ + protected $_contextKey = 'contexts'; + + /** + * Request parameter containing requested context + * @var string + */ + protected $_contextParam = 'format'; + + /** + * Current context + * @var string + */ + protected $_currentContext; + + /** + * Default context (xml) + * @var string + */ + protected $_defaultContext = 'xml'; + + /** + * Whether or not to disable layouts when switching contexts + * @var boolean + */ + protected $_disableLayout = true; + + /** + * Methods that require special configuration + * @var array + */ + protected $_specialConfig = array( + 'setSuffix', + 'setHeaders', + 'setCallbacks', + ); + + /** + * Methods that are not configurable via setOptions and setConfig + * @var array + */ + protected $_unconfigurable = array( + 'setOptions', + 'setConfig', + 'setHeader', + 'setCallback', + 'setContext', + 'setActionContext', + 'setActionContexts', + ); + + /** + * @var Zend_Controller_Action_Helper_ViewRenderer + */ + protected $_viewRenderer; + + /** + * Original view suffix prior to detecting context switch + * @var string + */ + protected $_viewSuffixOrig; + + /** + * Constructor + * + * @param array|Zend_Config $options + * @return void + */ + public function __construct($options = null) + { + if ($options instanceof Zend_Config) { + $this->setConfig($options); + } elseif (is_array($options)) { + $this->setOptions($options); + } + + if (empty($this->_contexts)) { + $this->addContexts(array( + 'json' => array( + 'suffix' => 'json', + 'headers' => array('Content-Type' => 'application/json'), + 'callbacks' => array( + 'init' => 'initJsonContext', + 'post' => 'postJsonContext' + ) + ), + 'xml' => array( + 'suffix' => 'xml', + 'headers' => array('Content-Type' => 'application/xml'), + ) + )); + } + + $this->init(); + } + + /** + * Initialize at start of action controller + * + * Reset the view script suffix to the original state, or store the + * original state. + * + * @return void + */ + public function init() + { + if (null === $this->_viewSuffixOrig) { + $this->_viewSuffixOrig = $this->_getViewRenderer()->getViewSuffix(); + } else { + $this->_getViewRenderer()->setViewSuffix($this->_viewSuffixOrig); + } + } + + /** + * Configure object from array of options + * + * @param array $options + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setOptions(array $options) + { + if (isset($options['contexts'])) { + $this->setContexts($options['contexts']); + unset($options['contexts']); + } + + foreach ($options as $key => $value) { + $method = 'set' . ucfirst($key); + if (in_array($method, $this->_unconfigurable)) { + continue; + } + + if (in_array($method, $this->_specialConfig)) { + $method = '_' . $method; + } + + if (method_exists($this, $method)) { + $this->$method($value); + } + } + return $this; + } + + /** + * Set object state from config object + * + * @param Zend_Config $config + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setConfig(Zend_Config $config) + { + return $this->setOptions($config->toArray()); + } + + /** + * Strategy pattern: return object + * + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function direct() + { + return $this; + } + + /** + * Initialize context detection and switching + * + * @param mixed $format + * @throws Zend_Controller_Action_Exception + * @return void + */ + public function initContext($format = null) + { + $this->_currentContext = null; + + $controller = $this->getActionController(); + $request = $this->getRequest(); + $action = $request->getActionName(); + + // Return if no context switching enabled, or no context switching + // enabled for this action + $contexts = $this->getActionContexts($action); + if (empty($contexts)) { + return; + } + + // Return if no context parameter provided + if (!$context = $request->getParam($this->getContextParam())) { + if ($format === null) { + return; + } + $context = $format; + $format = null; + } + + // Check if context allowed by action controller + if (!$this->hasActionContext($action, $context)) { + return; + } + + // Return if invalid context parameter provided and no format or invalid + // format provided + if (!$this->hasContext($context)) { + if (empty($format) || !$this->hasContext($format)) { + + return; + } + } + + // Use provided format if passed + if (!empty($format) && $this->hasContext($format)) { + $context = $format; + } + + $suffix = $this->getSuffix($context); + + $this->_getViewRenderer()->setViewSuffix($suffix); + + $headers = $this->getHeaders($context); + if (!empty($headers)) { + $response = $this->getResponse(); + foreach ($headers as $header => $content) { + $response->setHeader($header, $content); + } + } + + if ($this->getAutoDisableLayout()) { + /** + * @see Zend_Layout + */ + $layout = Zend_Layout::getMvcInstance(); + if (null !== $layout) { + $layout->disableLayout(); + } + } + + if (null !== ($callback = $this->getCallback($context, self::TRIGGER_INIT))) { + if (is_string($callback) && method_exists($this, $callback)) { + $this->$callback(); + } elseif (is_string($callback) && function_exists($callback)) { + $callback(); + } elseif (is_array($callback)) { + call_user_func($callback); + } else { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Invalid context callback registered for context "%s"', $context)); + } + } + + $this->_currentContext = $context; + } + + /** + * JSON context extra initialization + * + * Turns off viewRenderer auto-rendering + * + * @return void + */ + public function initJsonContext() + { + if (!$this->getAutoJsonSerialization()) { + return; + } + + $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); + $view = $viewRenderer->view; + if ($view instanceof Zend_View_Interface) { + $viewRenderer->setNoRender(true); + } + } + + /** + * Should JSON contexts auto-serialize? + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setAutoJsonSerialization($flag) + { + $this->_autoJsonSerialization = (bool) $flag; + return $this; + } + + /** + * Get JSON context auto-serialization flag + * + * @return boolean + */ + public function getAutoJsonSerialization() + { + return $this->_autoJsonSerialization; + } + + /** + * Set suffix from array + * + * @param array $spec + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + protected function _setSuffix(array $spec) + { + foreach ($spec as $context => $suffixInfo) { + if (!is_string($context)) { + $context = null; + } + + if (is_string($suffixInfo)) { + $this->setSuffix($context, $suffixInfo); + continue; + } elseif (is_array($suffixInfo)) { + if (isset($suffixInfo['suffix'])) { + $suffix = $suffixInfo['suffix']; + $prependViewRendererSuffix = true; + + if ((null === $context) && isset($suffixInfo['context'])) { + $context = $suffixInfo['context']; + } + + if (isset($suffixInfo['prependViewRendererSuffix'])) { + $prependViewRendererSuffix = $suffixInfo['prependViewRendererSuffix']; + } + + $this->setSuffix($context, $suffix, $prependViewRendererSuffix); + continue; + } + + $count = count($suffixInfo); + switch (true) { + case (($count < 2) && (null === $context)): + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('Invalid suffix information provided in config'); + case ($count < 2): + $suffix = array_shift($suffixInfo); + $this->setSuffix($context, $suffix); + break; + case (($count < 3) && (null === $context)): + $context = array_shift($suffixInfo); + $suffix = array_shift($suffixInfo); + $this->setSuffix($context, $suffix); + break; + case (($count == 3) && (null === $context)): + $context = array_shift($suffixInfo); + $suffix = array_shift($suffixInfo); + $prependViewRendererSuffix = array_shift($suffixInfo); + $this->setSuffix($context, $suffix, $prependViewRendererSuffix); + break; + case ($count >= 2): + $suffix = array_shift($suffixInfo); + $prependViewRendererSuffix = array_shift($suffixInfo); + $this->setSuffix($context, $suffix, $prependViewRendererSuffix); + break; + } + } + } + return $this; + } + + /** + * Customize view script suffix to use when switching context. + * + * Passing an empty suffix value to the setters disables the view script + * suffix change. + * + * @param string $context Context type for which to set suffix + * @param string $suffix Suffix to use + * @param boolean $prependViewRendererSuffix Whether or not to prepend the new suffix to the viewrenderer suffix + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setSuffix($context, $suffix, $prependViewRendererSuffix = true) + { + if (!isset($this->_contexts[$context])) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Cannot set suffix; invalid context type "%s"', $context)); + } + + if (empty($suffix)) { + $suffix = ''; + } + + if (is_array($suffix)) { + if (isset($suffix['prependViewRendererSuffix'])) { + $prependViewRendererSuffix = $suffix['prependViewRendererSuffix']; + } + if (isset($suffix['suffix'])) { + $suffix = $suffix['suffix']; + } else { + $suffix = ''; + } + } + + $suffix = (string) $suffix; + + if ($prependViewRendererSuffix) { + if (empty($suffix)) { + $suffix = $this->_getViewRenderer()->getViewSuffix(); + } else { + $suffix .= '.' . $this->_getViewRenderer()->getViewSuffix(); + } + } + + $this->_contexts[$context]['suffix'] = $suffix; + return $this; + } + + /** + * Retrieve suffix for given context type + * + * @param string $type Context type + * @throws Zend_Controller_Action_Exception + * @return string + */ + public function getSuffix($type) + { + if (!isset($this->_contexts[$type])) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Cannot retrieve suffix; invalid context type "%s"', $type)); + } + + return $this->_contexts[$type]['suffix']; + } + + /** + * Does the given context exist? + * + * @param string $context + * @param boolean $throwException + * @throws Zend_Controller_Action_Exception if context does not exist and throwException is true + * @return bool + */ + public function hasContext($context, $throwException = false) + { + if (is_string($context)) { + if (isset($this->_contexts[$context])) { + return true; + } + } elseif (is_array($context)) { + $error = false; + foreach ($context as $test) { + if (!isset($this->_contexts[$test])) { + $error = (string) $test; + break; + } + } + if (false === $error) { + return true; + } + $context = $error; + } elseif (true === $context) { + return true; + } + + if ($throwException) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Context "%s" does not exist', $context)); + } + + return false; + } + + /** + * Add header to context + * + * @param string $context + * @param string $header + * @param string $content + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function addHeader($context, $header, $content) + { + $context = (string) $context; + $this->hasContext($context, true); + + $header = (string) $header; + $content = (string) $content; + + if (isset($this->_contexts[$context]['headers'][$header])) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Cannot add "%s" header to context "%s": already exists', $header, $context)); + } + + $this->_contexts[$context]['headers'][$header] = $content; + return $this; + } + + /** + * Customize response header to use when switching context + * + * Passing an empty header value to the setters disables the response + * header. + * + * @param string $type Context type for which to set suffix + * @param string $header Header to set + * @param string $content Header content + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setHeader($context, $header, $content) + { + $this->hasContext($context, true); + $context = (string) $context; + $header = (string) $header; + $content = (string) $content; + + $this->_contexts[$context]['headers'][$header] = $content; + return $this; + } + + /** + * Add multiple headers at once for a given context + * + * @param string $context + * @param array $headers + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function addHeaders($context, array $headers) + { + foreach ($headers as $header => $content) { + $this->addHeader($context, $header, $content); + } + + return $this; + } + + /** + * Set headers from context => headers pairs + * + * @param array $options + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + protected function _setHeaders(array $options) + { + foreach ($options as $context => $headers) { + if (!is_array($headers)) { + continue; + } + $this->setHeaders($context, $headers); + } + + return $this; + } + + /** + * Set multiple headers at once for a given context + * + * @param string $context + * @param array $headers + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setHeaders($context, array $headers) + { + $this->clearHeaders($context); + foreach ($headers as $header => $content) { + $this->setHeader($context, $header, $content); + } + + return $this; + } + + /** + * Retrieve context header + * + * Returns the value of a given header for a given context type + * + * @param string $context + * @param string $header + * @return string|null + */ + public function getHeader($context, $header) + { + $this->hasContext($context, true); + $context = (string) $context; + $header = (string) $header; + if (isset($this->_contexts[$context]['headers'][$header])) { + return $this->_contexts[$context]['headers'][$header]; + } + + return null; + } + + /** + * Retrieve context headers + * + * Returns all headers for a context as key/value pairs + * + * @param string $context + * @return array + */ + public function getHeaders($context) + { + $this->hasContext($context, true); + $context = (string) $context; + return $this->_contexts[$context]['headers']; + } + + /** + * Remove a single header from a context + * + * @param string $context + * @param string $header + * @return boolean + */ + public function removeHeader($context, $header) + { + $this->hasContext($context, true); + $context = (string) $context; + $header = (string) $header; + if (isset($this->_contexts[$context]['headers'][$header])) { + unset($this->_contexts[$context]['headers'][$header]); + return true; + } + + return false; + } + + /** + * Clear all headers for a given context + * + * @param string $context + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function clearHeaders($context) + { + $this->hasContext($context, true); + $context = (string) $context; + $this->_contexts[$context]['headers'] = array(); + return $this; + } + + /** + * Validate trigger and return in normalized form + * + * @param string $trigger + * @throws Zend_Controller_Action_Exception + * @return string + */ + protected function _validateTrigger($trigger) + { + $trigger = strtoupper($trigger); + if ('TRIGGER_' !== substr($trigger, 0, 8)) { + $trigger = 'TRIGGER_' . $trigger; + } + + if (!in_array($trigger, array(self::TRIGGER_INIT, self::TRIGGER_POST))) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Invalid trigger "%s"', $trigger)); + } + + return $trigger; + } + + /** + * Set a callback for a given context and trigger + * + * @param string $context + * @param string $trigger + * @param string|array $callback + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setCallback($context, $trigger, $callback) + { + $this->hasContext($context, true); + $trigger = $this->_validateTrigger($trigger); + + if (!is_string($callback)) { + if (!is_array($callback) || (2 != count($callback))) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('Invalid callback specified'); + } + } + + $this->_contexts[$context]['callbacks'][$trigger] = $callback; + return $this; + } + + /** + * Set callbacks from array of context => callbacks pairs + * + * @param array $options + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + protected function _setCallbacks(array $options) + { + foreach ($options as $context => $callbacks) { + if (!is_array($callbacks)) { + continue; + } + + $this->setCallbacks($context, $callbacks); + } + return $this; + } + + /** + * Set callbacks for a given context + * + * Callbacks should be in trigger/callback pairs. + * + * @param string $context + * @param array $callbacks + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setCallbacks($context, array $callbacks) + { + $this->hasContext($context, true); + $context = (string) $context; + if (!isset($this->_contexts[$context]['callbacks'])) { + $this->_contexts[$context]['callbacks'] = array(); + } + + foreach ($callbacks as $trigger => $callback) { + $this->setCallback($context, $trigger, $callback); + } + return $this; + } + + /** + * Get a single callback for a given context and trigger + * + * @param string $context + * @param string $trigger + * @return string|array|null + */ + public function getCallback($context, $trigger) + { + $this->hasContext($context, true); + $trigger = $this->_validateTrigger($trigger); + if (isset($this->_contexts[$context]['callbacks'][$trigger])) { + return $this->_contexts[$context]['callbacks'][$trigger]; + } + + return null; + } + + /** + * Get all callbacks for a given context + * + * @param string $context + * @return array + */ + public function getCallbacks($context) + { + $this->hasContext($context, true); + return $this->_contexts[$context]['callbacks']; + } + + /** + * Clear a callback for a given context and trigger + * + * @param string $context + * @param string $trigger + * @return boolean + */ + public function removeCallback($context, $trigger) + { + $this->hasContext($context, true); + $trigger = $this->_validateTrigger($trigger); + if (isset($this->_contexts[$context]['callbacks'][$trigger])) { + unset($this->_contexts[$context]['callbacks'][$trigger]); + return true; + } + + return false; + } + + /** + * Clear all callbacks for a given context + * + * @param string $context + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function clearCallbacks($context) + { + $this->hasContext($context, true); + $this->_contexts[$context]['callbacks'] = array(); + return $this; + } + + /** + * Set name of parameter to use when determining context format + * + * @param string $name + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setContextParam($name) + { + $this->_contextParam = (string) $name; + return $this; + } + + /** + * Return context format request parameter name + * + * @return string + */ + public function getContextParam() + { + return $this->_contextParam; + } + + /** + * Indicate default context to use when no context format provided + * + * @param string $type + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setDefaultContext($type) + { + if (!isset($this->_contexts[$type])) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Cannot set default context; invalid context type "%s"', $type)); + } + + $this->_defaultContext = $type; + return $this; + } + + /** + * Return default context + * + * @return string + */ + public function getDefaultContext() + { + return $this->_defaultContext; + } + + /** + * Set flag indicating if layout should be disabled + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setAutoDisableLayout($flag) + { + $this->_disableLayout = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve auto layout disable flag + * + * @return boolean + */ + public function getAutoDisableLayout() + { + return $this->_disableLayout; + } + + /** + * Add new context + * + * @param string $context Context type + * @param array $spec Context specification + * @throws Zend_Controller_Action_Exception + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function addContext($context, array $spec) + { + if ($this->hasContext($context)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Cannot add context "%s"; already exists', $context)); + } + $context = (string) $context; + + $this->_contexts[$context] = array(); + + $this->setSuffix($context, (isset($spec['suffix']) ? $spec['suffix'] : '')) + ->setHeaders($context, (isset($spec['headers']) ? $spec['headers'] : array())) + ->setCallbacks($context, (isset($spec['callbacks']) ? $spec['callbacks'] : array())); + return $this; + } + + /** + * Overwrite existing context + * + * @param string $context Context type + * @param array $spec Context specification + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setContext($context, array $spec) + { + $this->removeContext($context); + return $this->addContext($context, $spec); + } + + /** + * Add multiple contexts + * + * @param array $contexts + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function addContexts(array $contexts) + { + foreach ($contexts as $context => $spec) { + $this->addContext($context, $spec); + } + return $this; + } + + /** + * Set multiple contexts, after first removing all + * + * @param array $contexts + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setContexts(array $contexts) + { + $this->clearContexts(); + foreach ($contexts as $context => $spec) { + $this->addContext($context, $spec); + } + return $this; + } + + /** + * Retrieve context specification + * + * @param string $context + * @return array|null + */ + public function getContext($context) + { + if ($this->hasContext($context)) { + return $this->_contexts[(string) $context]; + } + return null; + } + + /** + * Retrieve context definitions + * + * @return array + */ + public function getContexts() + { + return $this->_contexts; + } + + /** + * Remove a context + * + * @param string $context + * @return boolean + */ + public function removeContext($context) + { + if ($this->hasContext($context)) { + unset($this->_contexts[(string) $context]); + return true; + } + return false; + } + + /** + * Remove all contexts + * + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function clearContexts() + { + $this->_contexts = array(); + return $this; + } + + /** + * Return current context, if any + * + * @return null|string + */ + public function getCurrentContext() + { + return $this->_currentContext; + } + + /** + * Post dispatch processing + * + * Execute postDispatch callback for current context, if available + * + * @throws Zend_Controller_Action_Exception + * @return void + */ + public function postDispatch() + { + $context = $this->getCurrentContext(); + if (null !== $context) { + if (null !== ($callback = $this->getCallback($context, self::TRIGGER_POST))) { + if (is_string($callback) && method_exists($this, $callback)) { + $this->$callback(); + } elseif (is_string($callback) && function_exists($callback)) { + $callback(); + } elseif (is_array($callback)) { + call_user_func($callback); + } else { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf('Invalid postDispatch context callback registered for context "%s"', $context)); + } + } + } + } + + /** + * JSON post processing + * + * JSON serialize view variables to response body + * + * @return void + */ + public function postJsonContext() + { + if (!$this->getAutoJsonSerialization()) { + return; + } + + $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); + $view = $viewRenderer->view; + if ($view instanceof Zend_View_Interface) { + /** + * @see Zend_Json + */ + if(method_exists($view, 'getVars')) { + $vars = Zend_Json::encode($view->getVars()); + $this->getResponse()->setBody($vars); + } else { + throw new Zend_Controller_Action_Exception('View does not implement the getVars() method needed to encode the view into JSON'); + } + } + } + + /** + * Add one or more contexts to an action + * + * @param string $action + * @param string|array $context + * @return Zend_Controller_Action_Helper_ContextSwitch|void Provides a fluent interface + */ + public function addActionContext($action, $context) + { + $this->hasContext($context, true); + $controller = $this->getActionController(); + if (null === $controller) { + return; + } + $action = (string) $action; + $contextKey = $this->_contextKey; + + if (!isset($controller->$contextKey)) { + $controller->$contextKey = array(); + } + + if (true === $context) { + $contexts = $this->getContexts(); + $controller->{$contextKey}[$action] = array_keys($contexts); + return $this; + } + + $context = (array) $context; + if (!isset($controller->{$contextKey}[$action])) { + $controller->{$contextKey}[$action] = $context; + } else { + $controller->{$contextKey}[$action] = array_merge( + $controller->{$contextKey}[$action], + $context + ); + } + + return $this; + } + + /** + * Set a context as available for a given controller action + * + * @param string $action + * @param string|array $context + * @return Zend_Controller_Action_Helper_ContextSwitch|void Provides a fluent interface + */ + public function setActionContext($action, $context) + { + $this->hasContext($context, true); + $controller = $this->getActionController(); + if (null === $controller) { + return; + } + $action = (string) $action; + $contextKey = $this->_contextKey; + + if (!isset($controller->$contextKey)) { + $controller->$contextKey = array(); + } + + if (true === $context) { + $contexts = $this->getContexts(); + $controller->{$contextKey}[$action] = array_keys($contexts); + } else { + $controller->{$contextKey}[$action] = (array) $context; + } + + return $this; + } + + /** + * Add multiple action/context pairs at once + * + * @param array $contexts + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function addActionContexts(array $contexts) + { + foreach ($contexts as $action => $context) { + $this->addActionContext($action, $context); + } + return $this; + } + + /** + * Overwrite and set multiple action contexts at once + * + * @param array $contexts + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function setActionContexts(array $contexts) + { + foreach ($contexts as $action => $context) { + $this->setActionContext($action, $context); + } + return $this; + } + + /** + * Does a particular controller action have the given context(s)? + * + * @param string $action + * @param string|array $context + * @throws Zend_Controller_Action_Exception + * @return boolean + */ + public function hasActionContext($action, $context) + { + $this->hasContext($context, true); + $controller = $this->getActionController(); + if (null === $controller) { + return false; + } + $action = (string) $action; + $contextKey = $this->_contextKey; + + if (!isset($controller->{$contextKey})) { + return false; + } + + $allContexts = $controller->{$contextKey}; + + if (!is_array($allContexts)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception("Invalid contexts found for controller"); + } + + if (!isset($allContexts[$action])) { + return false; + } + + if (true === $allContexts[$action]) { + return true; + } + + $contexts = $allContexts[$action]; + + if (!is_array($contexts)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception(sprintf("Invalid contexts found for action '%s'", $action)); + } + + if (is_string($context) && in_array($context, $contexts)) { + return true; + } elseif (is_array($context)) { + $found = true; + foreach ($context as $test) { + if (!in_array($test, $contexts)) { + $found = false; + break; + } + } + return $found; + } + + return false; + } + + /** + * Get contexts for a given action or all actions in the controller + * + * @param string $action + * @return array + */ + public function getActionContexts($action = null) + { + $controller = $this->getActionController(); + if (null === $controller) { + return array(); + } + $contextKey = $this->_contextKey; + + if (!isset($controller->$contextKey)) { + return array(); + } + + if (null !== $action) { + $action = (string) $action; + if (isset($controller->{$contextKey}[$action])) { + return $controller->{$contextKey}[$action]; + } else { + return array(); + } + } + + return $controller->$contextKey; + } + + /** + * Remove one or more contexts for a given controller action + * + * @param string $action + * @param string|array $context + * @return boolean + */ + public function removeActionContext($action, $context) + { + if ($this->hasActionContext($action, $context)) { + $controller = $this->getActionController(); + $contextKey = $this->_contextKey; + $action = (string) $action; + $contexts = $controller->$contextKey; + $actionContexts = $contexts[$action]; + $contexts = (array) $context; + foreach ($contexts as $context) { + $index = array_search($context, $actionContexts); + if (false !== $index) { + unset($controller->{$contextKey}[$action][$index]); + } + } + return true; + } + return false; + } + + /** + * Clear all contexts for a given controller action or all actions + * + * @param string $action + * @return Zend_Controller_Action_Helper_ContextSwitch Provides a fluent interface + */ + public function clearActionContexts($action = null) + { + $controller = $this->getActionController(); + $contextKey = $this->_contextKey; + + if (!isset($controller->$contextKey) || empty($controller->$contextKey)) { + return $this; + } + + if (null === $action) { + $controller->$contextKey = array(); + return $this; + } + + $action = (string) $action; + if (isset($controller->{$contextKey}[$action])) { + unset($controller->{$contextKey}[$action]); + } + + return $this; + } + + /** + * Retrieve ViewRenderer + * + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + protected function _getViewRenderer() + { + if (null === $this->_viewRenderer) { + $this->_viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); + } + + return $this->_viewRenderer; + } +} + diff --git a/library/vendor/Zend/Controller/Action/Helper/Json.php b/library/vendor/Zend/Controller/Action/Helper/Json.php new file mode 100644 index 0000000..5b77f12 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/Json.php @@ -0,0 +1,130 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * Simplify AJAX context switching based on requested format + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_Json extends Zend_Controller_Action_Helper_Abstract +{ + /** + * Suppress exit when sendJson() called + * @var boolean + */ + public $suppressExit = false; + + /** + * Create JSON response + * + * Encodes and returns data to JSON. Content-Type header set to + * 'application/json', and disables layouts and viewRenderer (if being + * used). + * + * @param mixed $data + * @param boolean $keepLayouts + * @param boolean|array $keepLayouts + * @param boolean $encodeData Provided data is already JSON + * NOTE: if boolean, establish $keepLayouts to true|false + * if array, admit params for Zend_Json::encode as enableJsonExprFinder=>true|false + * if $keepLayouts and parmas for Zend_Json::encode are required + * then, the array can contains a 'keepLayout'=>true|false and/or 'encodeData'=>true|false + * that will not be passed to Zend_Json::encode method but will be passed + * to Zend_View_Helper_Json + * @throws Zend_Controller_Action_Helper_Json + * @return string + */ + public function encodeJson($data, $keepLayouts = false, $encodeData = true) + { + /** + * @see Zend_View_Helper_Json + */ + $jsonHelper = new Zend_View_Helper_Json(); + $data = $jsonHelper->json($data, $keepLayouts, $encodeData); + + if (!$keepLayouts) { + /** + * @see Zend_Controller_Action_HelperBroker + */ + Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true); + } + + return $data; + } + + /** + * Encode JSON response and immediately send + * + * @param mixed $data + * @param boolean|array $keepLayouts + * @param $encodeData Encode $data as JSON? + * NOTE: if boolean, establish $keepLayouts to true|false + * if array, admit params for Zend_Json::encode as enableJsonExprFinder=>true|false + * if $keepLayouts and parmas for Zend_Json::encode are required + * then, the array can contains a 'keepLayout'=>true|false and/or 'encodeData'=>true|false + * that will not be passed to Zend_Json::encode method but will be passed + * to Zend_View_Helper_Json + * @return string|void + */ + public function sendJson($data, $keepLayouts = false, $encodeData = true) + { + $data = $this->encodeJson($data, $keepLayouts, $encodeData); + $response = $this->getResponse(); + $response->setBody($data); + + if (!$this->suppressExit) { + $response->sendResponse(); + exit; + } + + return $data; + } + + /** + * Strategy pattern: call helper as helper broker method + * + * Allows encoding JSON. If $sendNow is true, immediately sends JSON + * response. + * + * @param mixed $data + * @param boolean $sendNow + * @param boolean $keepLayouts + * @param boolean $encodeData Encode $data as JSON? + * @return string|void + */ + public function direct($data, $sendNow = true, $keepLayouts = false, $encodeData = true) + { + if ($sendNow) { + return $this->sendJson($data, $keepLayouts, $encodeData); + } + return $this->encodeJson($data, $keepLayouts, $encodeData); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/Redirector.php b/library/vendor/Zend/Controller/Action/Helper/Redirector.php new file mode 100644 index 0000000..8ff7c3e --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/Redirector.php @@ -0,0 +1,531 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_Redirector extends Zend_Controller_Action_Helper_Abstract +{ + /** + * HTTP status code for redirects + * @var int + */ + protected $_code = 302; + + /** + * Whether or not calls to _redirect() should exit script execution + * @var boolean + */ + protected $_exit = true; + + /** + * Whether or not _redirect() should attempt to prepend the base URL to the + * passed URL (if it's a relative URL) + * @var boolean + */ + protected $_prependBase = true; + + /** + * Url to which to redirect + * @var string + */ + protected $_redirectUrl = null; + + /** + * Whether or not to use an absolute URI when redirecting + * @var boolean + */ + protected $_useAbsoluteUri = false; + + /** + * Whether or not to close the session before exiting + * @var boolean + */ + protected $_closeSessionOnExit = true; + + /** + * Retrieve HTTP status code to emit on {@link _redirect()} call + * + * @return int + */ + public function getCode() + { + return $this->_code; + } + + /** + * Validate HTTP status redirect code + * + * @param int $code + * @throws Zend_Controller_Action_Exception on invalid HTTP status code + * @return true + */ + protected function _checkCode($code) + { + $code = (int)$code; + if ((300 > $code) || (307 < $code) || (304 == $code) || (306 == $code)) { + throw new Zend_Controller_Action_Exception('Invalid redirect HTTP status code (' . $code . ')'); + } + + return true; + } + + /** + * Set HTTP status code for {@link _redirect()} behaviour + * + * @param int $code + * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface + */ + public function setCode($code) + { + $this->_checkCode($code); + $this->_code = $code; + return $this; + } + + /** + * Retrieve flag for whether or not {@link _redirect()} will exit when finished. + * + * @return boolean + */ + public function getExit() + { + return $this->_exit; + } + + /** + * Set exit flag for {@link _redirect()} behaviour + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface + */ + public function setExit($flag) + { + $this->_exit = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve flag for whether or not {@link _redirect()} will prepend the + * base URL on relative URLs + * + * @return boolean + */ + public function getPrependBase() + { + return $this->_prependBase; + } + + /** + * Set 'prepend base' flag for {@link _redirect()} behaviour + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface + */ + public function setPrependBase($flag) + { + $this->_prependBase = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve flag for whether or not {@link redirectAndExit()} shall close the session before + * exiting. + * + * @return boolean + */ + public function getCloseSessionOnExit() + { + return $this->_closeSessionOnExit; + } + + /** + * Set flag for whether or not {@link redirectAndExit()} shall close the session before exiting. + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface + */ + public function setCloseSessionOnExit($flag) + { + $this->_closeSessionOnExit = ($flag) ? true : false; + return $this; + } + + /** + * Return use absolute URI flag + * + * @return boolean + */ + public function getUseAbsoluteUri() + { + return $this->_useAbsoluteUri; + } + + /** + * Set use absolute URI flag + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface + */ + public function setUseAbsoluteUri($flag = true) + { + $this->_useAbsoluteUri = ($flag) ? true : false; + return $this; + } + + /** + * Set redirect in response object + * + * @return void + */ + protected function _redirect($url) + { + if ($this->getUseAbsoluteUri() && !preg_match('#^(https?|ftp)://#', $url)) { + $host = (isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:''); + $proto = (isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=="off") ? 'https' : 'http'; + $port = (isset($_SERVER['SERVER_PORT'])?$_SERVER['SERVER_PORT']:80); + $uri = $proto . '://' . $host; + if ((('http' == $proto) && (80 != $port)) || (('https' == $proto) && (443 != $port))) { + // do not append if HTTP_HOST already contains port + if (strrchr($host, ':') === false) { + $uri .= ':' . $port; + } + } + $url = $uri . '/' . ltrim($url, '/'); + } + $this->_redirectUrl = $url; + $this->getResponse()->setRedirect($url, $this->getCode()); + } + + /** + * Retrieve currently set URL for redirect + * + * @return string + */ + public function getRedirectUrl() + { + return $this->_redirectUrl; + } + + /** + * Determine if the baseUrl should be prepended, and prepend if necessary + * + * @param string $url + * @return string + */ + protected function _prependBase($url) + { + if ($this->getPrependBase()) { + $request = $this->getRequest(); + if ($request instanceof Zend_Controller_Request_Http) { + $base = rtrim($request->getBaseUrl(), '/'); + if (!empty($base) && ('/' != $base)) { + $url = $base . '/' . ltrim($url, '/'); + } else { + $url = '/' . ltrim($url, '/'); + } + } + } + + return $url; + } + + /** + * Set a redirect URL of the form /module/controller/action/params + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return void + */ + public function setGotoSimple($action, $controller = null, $module = null, array $params = array()) + { + $dispatcher = $this->getFrontController()->getDispatcher(); + $request = $this->getRequest(); + $curModule = $request->getModuleName(); + $useDefaultController = false; + + if (null === $controller && null !== $module) { + $useDefaultController = true; + } + + if (null === $module) { + $module = $curModule; + } + + if ($module == $dispatcher->getDefaultModule()) { + $module = ''; + } + + if (null === $controller && !$useDefaultController) { + $controller = $request->getControllerName(); + if (empty($controller)) { + $controller = $dispatcher->getDefaultControllerName(); + } + } + + $params[$request->getModuleKey()] = $module; + $params[$request->getControllerKey()] = $controller; + $params[$request->getActionKey()] = $action; + + $router = $this->getFrontController()->getRouter(); + $url = $router->assemble($params, 'default', true); + + $this->_redirect($url); + } + + /** + * Build a URL based on a route + * + * @param array $urlOptions + * @param string $name Route name + * @param boolean $reset + * @param boolean $encode + * @return void + */ + public function setGotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) + { + $router = $this->getFrontController()->getRouter(); + $url = $router->assemble($urlOptions, $name, $reset, $encode); + + $this->_redirect($url); + } + + /** + * Set a redirect URL string + * + * By default, emits a 302 HTTP status header, prepends base URL as defined + * in request object if url is relative, and halts script execution by + * calling exit(). + * + * $options is an optional associative array that can be used to control + * redirect behaviour. The available option keys are: + * - exit: boolean flag indicating whether or not to halt script execution when done + * - prependBase: boolean flag indicating whether or not to prepend the base URL when a relative URL is provided + * - code: integer HTTP status code to use with redirect. Should be between 300 and 307. + * + * _redirect() sets the Location header in the response object. If you set + * the exit flag to false, you can override this header later in code + * execution. + * + * If the exit flag is true (true by default), _redirect() will write and + * close the current session, if any. + * + * @param string $url + * @param array $options + * @return void + */ + public function setGotoUrl($url, array $options = array()) + { + // prevent header injections + $url = str_replace(array("\n", "\r"), '', $url); + + if (null !== $options) { + if (isset($options['exit'])) { + $this->setExit(($options['exit']) ? true : false); + } + if (isset($options['prependBase'])) { + $this->setPrependBase(($options['prependBase']) ? true : false); + } + if (isset($options['code'])) { + $this->setCode($options['code']); + } + } + + // If relative URL, decide if we should prepend base URL + if (!preg_match('|^[a-z]+://|', $url)) { + $url = $this->_prependBase($url); + } + + $this->_redirect($url); + } + + /** + * Perform a redirect to an action/controller/module with params + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return void + */ + public function gotoSimple($action, $controller = null, $module = null, array $params = array()) + { + $this->setGotoSimple($action, $controller, $module, $params); + + if ($this->getExit()) { + $this->redirectAndExit(); + } + } + + /** + * Perform a redirect to an action/controller/module with params, forcing an immdiate exit + * + * @param mixed $action + * @param mixed $controller + * @param mixed $module + * @param array $params + * @return void + */ + public function gotoSimpleAndExit($action, $controller = null, $module = null, array $params = array()) + { + $this->setGotoSimple($action, $controller, $module, $params); + $this->redirectAndExit(); + } + + /** + * Redirect to a route-based URL + * + * Uses route's assemble method to build the URL; route is specified by $name; + * default route is used if none provided. + * + * @param array $urlOptions Array of key/value pairs used to assemble URL + * @param string $name + * @param boolean $reset + * @param boolean $encode + * @return void + */ + public function gotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) + { + $this->setGotoRoute($urlOptions, $name, $reset, $encode); + + if ($this->getExit()) { + $this->redirectAndExit(); + } + } + + /** + * Redirect to a route-based URL, and immediately exit + * + * Uses route's assemble method to build the URL; route is specified by $name; + * default route is used if none provided. + * + * @param array $urlOptions Array of key/value pairs used to assemble URL + * @param string $name + * @param boolean $reset + * @return void + */ + public function gotoRouteAndExit(array $urlOptions = array(), $name = null, $reset = false) + { + $this->setGotoRoute($urlOptions, $name, $reset); + $this->redirectAndExit(); + } + + /** + * Perform a redirect to a url + * + * @param string $url + * @param array $options + * @return void + */ + public function gotoUrl($url, array $options = array()) + { + $this->setGotoUrl($url, $options); + + if ($this->getExit()) { + $this->redirectAndExit(); + } + } + + /** + * Set a URL string for a redirect, perform redirect, and immediately exit + * + * @param string $url + * @param array $options + * @return void + */ + public function gotoUrlAndExit($url, array $options = array()) + { + $this->setGotoUrl($url, $options); + $this->redirectAndExit(); + } + + /** + * exit(): Perform exit for redirector + * + * @return void + */ + public function redirectAndExit() + { + if ($this->getCloseSessionOnExit()) { + // Close session, if started + if (class_exists('Zend_Session', false) && Zend_Session::isStarted()) { + Zend_Session::writeClose(); + } elseif (isset($_SESSION)) { + session_write_close(); + } + } + + $this->getResponse()->sendHeaders(); + exit(); + } + + /** + * direct(): Perform helper when called as + * $this->_helper->redirector($action, $controller, $module, $params) + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return void + */ + public function direct($action, $controller = null, $module = null, array $params = array()) + { + $this->gotoSimple($action, $controller, $module, $params); + } + + /** + * Overloading + * + * Overloading for old 'goto', 'setGoto', and 'gotoAndExit' methods + * + * @param string $method + * @param array $args + * @return mixed + * @throws Zend_Controller_Action_Exception for invalid methods + */ + public function __call($method, $args) + { + $method = strtolower($method); + if ('goto' == $method) { + return call_user_func_array(array($this, 'gotoSimple'), $args); + } + if ('setgoto' == $method) { + return call_user_func_array(array($this, 'setGotoSimple'), $args); + } + if ('gotoandexit' == $method) { + return call_user_func_array(array($this, 'gotoSimpleAndExit'), $args); + } + + throw new Zend_Controller_Action_Exception(sprintf('Invalid method "%s" called on redirector', $method)); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/Url.php b/library/vendor/Zend/Controller/Action/Helper/Url.php new file mode 100644 index 0000000..f98bfa5 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/Url.php @@ -0,0 +1,116 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * Helper for creating URLs for redirects and other tasks + * + * @uses Zend_Controller_Action_Helper_Abstract + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_Url extends Zend_Controller_Action_Helper_Abstract +{ + /** + * Create URL based on default route + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return string + */ + public function simple($action, $controller = null, $module = null, array $params = null) + { + $request = $this->getRequest(); + + if (null === $controller) { + $controller = $request->getControllerName(); + } + + if (null === $module) { + $module = $request->getModuleName(); + } + + $url = $controller . '/' . $action; + if ($module != $this->getFrontController()->getDispatcher()->getDefaultModule()) { + $url = $module . '/' . $url; + } + + if ('' !== ($baseUrl = $this->getFrontController()->getBaseUrl())) { + $url = $baseUrl . '/' . $url; + } + + if (null !== $params) { + $paramPairs = array(); + foreach ($params as $key => $value) { + $paramPairs[] = urlencode($key) . '/' . urlencode($value); + } + $paramString = implode('/', $paramPairs); + $url .= '/' . $paramString; + } + + $url = '/' . ltrim($url, '/'); + + return $url; + } + + /** + * Assembles a URL based on a given route + * + * This method will typically be used for more complex operations, as it + * ties into the route objects registered with the router. + * + * @param array $urlOptions Options passed to the assemble method of the Route object. + * @param mixed $name The name of a Route to use. If null it will use the current Route + * @param boolean $reset + * @param boolean $encode + * @return string Url for the link href attribute. + */ + public function url($urlOptions = array(), $name = null, $reset = false, $encode = true) + { + $router = $this->getFrontController()->getRouter(); + return $router->assemble($urlOptions, $name, $reset, $encode); + } + + /** + * Perform helper when called as $this->_helper->url() from an action controller + * + * Proxies to {@link simple()} + * + * @param string $action + * @param string $controller + * @param string $module + * @param array $params + * @return string + */ + public function direct($action, $controller = null, $module = null, array $params = null) + { + return $this->simple($action, $controller, $module, $params); + } +} diff --git a/library/vendor/Zend/Controller/Action/Helper/ViewRenderer.php b/library/vendor/Zend/Controller/Action/Helper/ViewRenderer.php new file mode 100644 index 0000000..948ecc4 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Helper/ViewRenderer.php @@ -0,0 +1,996 @@ +<?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_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_Helper_Abstract + */ + +/** + * @see Zend_View + */ + +/** + * View script integration + * + * Zend_Controller_Action_Helper_ViewRenderer provides transparent view + * integration for action controllers. It allows you to create a view object + * once, and populate it throughout all actions. Several global options may be + * set: + * + * - noController: if set true, render() will not look for view scripts in + * subdirectories named after the controller + * - viewSuffix: what view script filename suffix to use + * + * The helper autoinitializes the action controller view preDispatch(). It + * determines the path to the class file, and then determines the view base + * directory from there. It also uses the module name as a class prefix for + * helpers and views such that if your module name is 'Search', it will set the + * helper class prefix to 'Search_View_Helper' and the filter class prefix to ; + * 'Search_View_Filter'. + * + * Usage: + * <code> + * // In your bootstrap: + * Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_ViewRenderer()); + * + * // In your action controller methods: + * $viewHelper = $this->_helper->getHelper('view'); + * + * // Don't use controller subdirectories + * $viewHelper->setNoController(true); + * + * // Specify a different script to render: + * $this->_helper->viewRenderer('form'); + * + * </code> + * + * @uses Zend_Controller_Action_Helper_Abstract + * @package Zend_Controller + * @subpackage Zend_Controller_Action_Helper + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Action_Helper_Abstract +{ + /** + * @var Zend_View_Interface + */ + public $view; + + /** + * Word delimiters + * @var array + */ + protected $_delimiters; + + /** + * @var Zend_Filter_Inflector + */ + protected $_inflector; + + /** + * Inflector target + * @var string + */ + protected $_inflectorTarget = ''; + + /** + * Current module directory + * @var string + */ + protected $_moduleDir = ''; + + /** + * Whether or not to autorender using controller name as subdirectory; + * global setting (not reset at next invocation) + * @var boolean + */ + protected $_neverController = false; + + /** + * Whether or not to autorender postDispatch; global setting (not reset at + * next invocation) + * @var boolean + */ + protected $_neverRender = false; + + /** + * Whether or not to use a controller name as a subdirectory when rendering + * @var boolean + */ + protected $_noController = false; + + /** + * Whether or not to autorender postDispatch; per controller/action setting (reset + * at next invocation) + * @var boolean + */ + protected $_noRender = false; + + /** + * Characters representing path delimiters in the controller + * @var string|array + */ + protected $_pathDelimiters; + + /** + * Which named segment of the response to utilize + * @var string + */ + protected $_responseSegment = null; + + /** + * Which action view script to render + * @var string + */ + protected $_scriptAction = null; + + /** + * View object basePath + * @var string + */ + protected $_viewBasePathSpec = ':moduleDir/views'; + + /** + * View script path specification string + * @var string + */ + protected $_viewScriptPathSpec = ':controller/:action.:suffix'; + + /** + * View script path specification string, minus controller segment + * @var string + */ + protected $_viewScriptPathNoControllerSpec = ':action.:suffix'; + + /** + * View script suffix + * @var string + */ + protected $_viewSuffix = 'phtml'; + + /** + * Constructor + * + * Optionally set view object and options. + * + * @param Zend_View_Interface $view + * @param array $options + * @return void + */ + public function __construct(Zend_View_Interface $view = null, array $options = array()) + { + if (null !== $view) { + $this->setView($view); + } + + if (!empty($options)) { + $this->_setOptions($options); + } + } + + /** + * Clone - also make sure the view is cloned. + * + * @return void + */ + public function __clone() + { + if (isset($this->view) && $this->view instanceof Zend_View_Interface) { + $this->view = clone $this->view; + + } + } + + /** + * Set the view object + * + * @param Zend_View_Interface $view + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setView(Zend_View_Interface $view) + { + $this->view = $view; + return $this; + } + + /** + * Get current module name + * + * @return string + */ + public function getModule() + { + $request = $this->getRequest(); + $module = $request->getModuleName(); + if (null === $module) { + $module = $this->getFrontController()->getDispatcher()->getDefaultModule(); + } + + return $module; + } + + /** + * Get module directory + * + * @throws Zend_Controller_Action_Exception + * @return string + */ + public function getModuleDirectory() + { + $module = $this->getModule(); + $moduleDir = $this->getFrontController()->getControllerDirectory($module); + if ((null === $moduleDir) || is_array($moduleDir)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('ViewRenderer cannot locate module directory for module "' . $module . '"'); + } + $this->_moduleDir = dirname($moduleDir); + return $this->_moduleDir; + } + + /** + * Get inflector + * + * @return Zend_Filter_Inflector + */ + public function getInflector() + { + if (null === $this->_inflector) { + /** + * @see Zend_Filter_Inflector + */ + /** + * @see Zend_Filter_PregReplace + */ + /** + * @see Zend_Filter_Word_UnderscoreToSeparator + */ + $this->_inflector = new Zend_Filter_Inflector(); + $this->_inflector->setStaticRuleReference('moduleDir', $this->_moduleDir) // moduleDir must be specified before the less specific 'module' + ->addRules(array( + ':module' => array('Word_CamelCaseToDash', 'StringToLower'), + ':controller' => array('Word_CamelCaseToDash', new Zend_Filter_Word_UnderscoreToSeparator('/'), 'StringToLower', new Zend_Filter_PregReplace('/\./', '-')), + ':action' => array('Word_CamelCaseToDash', new Zend_Filter_PregReplace('#[^a-z0-9' . preg_quote('/', '#') . ']+#i', '-'), 'StringToLower'), + )) + ->setStaticRuleReference('suffix', $this->_viewSuffix) + ->setTargetReference($this->_inflectorTarget); + } + + // Ensure that module directory is current + $this->getModuleDirectory(); + + return $this->_inflector; + } + + /** + * Set inflector + * + * @param Zend_Filter_Inflector $inflector + * @param boolean $reference Whether the moduleDir, target, and suffix should be set as references to ViewRenderer properties + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setInflector(Zend_Filter_Inflector $inflector, $reference = false) + { + $this->_inflector = $inflector; + if ($reference) { + $this->_inflector->setStaticRuleReference('suffix', $this->_viewSuffix) + ->setStaticRuleReference('moduleDir', $this->_moduleDir) + ->setTargetReference($this->_inflectorTarget); + } + return $this; + } + + /** + * Set inflector target + * + * @param string $target + * @return void + */ + protected function _setInflectorTarget($target) + { + $this->_inflectorTarget = (string) $target; + } + + /** + * Set internal module directory representation + * + * @param string $dir + * @return void + */ + protected function _setModuleDir($dir) + { + $this->_moduleDir = (string) $dir; + } + + /** + * Get internal module directory representation + * + * @return string + */ + protected function _getModuleDir() + { + return $this->_moduleDir; + } + + /** + * Generate a class prefix for helper and filter classes + * + * @return string + */ + protected function _generateDefaultPrefix() + { + $default = 'Zend_View'; + if (null === $this->_actionController) { + return $default; + } + + $class = get_class($this->_actionController); + + if (!strstr($class, '_')) { + return $default; + } + + $module = $this->getModule(); + if ('default' == $module) { + return $default; + } + + $prefix = substr($class, 0, strpos($class, '_')) . '_View'; + + return $prefix; + } + + /** + * Retrieve base path based on location of current action controller + * + * @return string + */ + protected function _getBasePath() + { + if (null === $this->_actionController) { + return './views'; + } + + $inflector = $this->getInflector(); + $this->_setInflectorTarget($this->getViewBasePathSpec()); + + $dispatcher = $this->getFrontController()->getDispatcher(); + $request = $this->getRequest(); + + $parts = array( + 'module' => (($moduleName = $request->getModuleName()) != '') ? $dispatcher->formatModuleName($moduleName) : $moduleName, + 'controller' => $request->getControllerName(), + 'action' => $dispatcher->formatActionName($request->getActionName()) + ); + + $path = $inflector->filter($parts); + return $path; + } + + /** + * Set options + * + * @param array $options + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + protected function _setOptions(array $options) + { + foreach ($options as $key => $value) + { + switch ($key) { + case 'neverRender': + case 'neverController': + case 'noController': + case 'noRender': + $property = '_' . $key; + $this->{$property} = ($value) ? true : false; + break; + case 'responseSegment': + case 'scriptAction': + case 'viewBasePathSpec': + case 'viewScriptPathSpec': + case 'viewScriptPathNoControllerSpec': + case 'viewSuffix': + $property = '_' . $key; + $this->{$property} = (string) $value; + break; + default: + break; + } + } + + return $this; + } + + /** + * Initialize the view object + * + * $options may contain the following keys: + * - neverRender - flag dis/enabling postDispatch() autorender (affects all subsequent calls) + * - noController - flag indicating whether or not to look for view scripts in subdirectories named after the controller + * - noRender - flag indicating whether or not to autorender postDispatch() + * - responseSegment - which named response segment to render a view script to + * - scriptAction - what action script to render + * - viewBasePathSpec - specification to use for determining view base path + * - viewScriptPathSpec - specification to use for determining view script paths + * - viewScriptPathNoControllerSpec - specification to use for determining view script paths when noController flag is set + * - viewSuffix - what view script filename suffix to use + * + * @param string $path + * @param string $prefix + * @param array $options + * @throws Zend_Controller_Action_Exception + * @return void + */ + public function initView($path = null, $prefix = null, array $options = array()) + { + if (null === $this->view) { + $this->setView(new Zend_View()); + } + + // Reset some flags every time + $options['noController'] = (isset($options['noController'])) ? $options['noController'] : false; + $options['noRender'] = (isset($options['noRender'])) ? $options['noRender'] : false; + $this->_scriptAction = null; + $this->_responseSegment = null; + + // Set options first; may be used to determine other initializations + $this->_setOptions($options); + + // Get base view path + if (empty($path)) { + $path = $this->_getBasePath(); + if (empty($path)) { + /** + * @see Zend_Controller_Action_Exception + */ + throw new Zend_Controller_Action_Exception('ViewRenderer initialization failed: retrieved view base path is empty'); + } + } + + if (null === $prefix) { + $prefix = $this->_generateDefaultPrefix(); + } + + // Determine if this path has already been registered + $currentPaths = $this->view->getScriptPaths(); + $path = str_replace(array('/', '\\'), '/', $path); + $pathExists = false; + foreach ($currentPaths as $tmpPath) { + $tmpPath = str_replace(array('/', '\\'), '/', $tmpPath); + if (strstr($tmpPath, $path)) { + $pathExists = true; + break; + } + } + if (!$pathExists) { + $this->view->addBasePath($path, $prefix); + } + + // Register view with action controller (unless already registered) + if ((null !== $this->_actionController) && (null === $this->_actionController->view)) { + $this->_actionController->view = $this->view; + $this->_actionController->viewSuffix = $this->_viewSuffix; + } + } + + /** + * init - initialize view + * + * @return void + */ + public function init() + { + if ($this->getFrontController()->getParam('noViewRenderer')) { + return; + } + + $this->initView(); + } + + /** + * Set view basePath specification + * + * Specification can contain one or more of the following: + * - :moduleDir - current module directory + * - :controller - name of current controller in the request + * - :action - name of current action in the request + * - :module - name of current module in the request + * + * @param string $path + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setViewBasePathSpec($path) + { + $this->_viewBasePathSpec = (string) $path; + return $this; + } + + /** + * Retrieve the current view basePath specification string + * + * @return string + */ + public function getViewBasePathSpec() + { + return $this->_viewBasePathSpec; + } + + /** + * Set view script path specification + * + * Specification can contain one or more of the following: + * - :moduleDir - current module directory + * - :controller - name of current controller in the request + * - :action - name of current action in the request + * - :module - name of current module in the request + * + * @param string $path + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setViewScriptPathSpec($path) + { + $this->_viewScriptPathSpec = (string) $path; + return $this; + } + + /** + * Retrieve the current view script path specification string + * + * @return string + */ + public function getViewScriptPathSpec() + { + return $this->_viewScriptPathSpec; + } + + /** + * Set view script path specification (no controller variant) + * + * Specification can contain one or more of the following: + * - :moduleDir - current module directory + * - :controller - name of current controller in the request + * - :action - name of current action in the request + * - :module - name of current module in the request + * + * :controller will likely be ignored in this variant. + * + * @param string $path + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setViewScriptPathNoControllerSpec($path) + { + $this->_viewScriptPathNoControllerSpec = (string) $path; + return $this; + } + + /** + * Retrieve the current view script path specification string (no controller variant) + * + * @return string + */ + public function getViewScriptPathNoControllerSpec() + { + return $this->_viewScriptPathNoControllerSpec; + } + + /** + * Get a view script based on an action and/or other variables + * + * Uses values found in current request if no values passed in $vars. + * + * If {@link $_noController} is set, uses {@link $_viewScriptPathNoControllerSpec}; + * otherwise, uses {@link $_viewScriptPathSpec}. + * + * @param string $action + * @param array $vars + * @return string + */ + public function getViewScript($action = null, array $vars = array()) + { + $request = $this->getRequest(); + if ((null === $action) && (!isset($vars['action']))) { + $action = $this->getScriptAction(); + if (null === $action) { + $action = $request->getActionName(); + } + $vars['action'] = $action; + } elseif (null !== $action) { + $vars['action'] = $action; + } + + $replacePattern = array('/[^a-z0-9]+$/i', '/^[^a-z0-9]+/i'); + $vars['action'] = preg_replace($replacePattern, '', $vars['action']); + + $inflector = $this->getInflector(); + if ($this->getNoController() || $this->getNeverController()) { + $this->_setInflectorTarget($this->getViewScriptPathNoControllerSpec()); + } else { + $this->_setInflectorTarget($this->getViewScriptPathSpec()); + } + return $this->_translateSpec($vars); + } + + /** + * Set the neverRender flag (i.e., globally dis/enable autorendering) + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setNeverRender($flag = true) + { + $this->_neverRender = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve neverRender flag value + * + * @return boolean + */ + public function getNeverRender() + { + return $this->_neverRender; + } + + /** + * Set the noRender flag (i.e., whether or not to autorender) + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setNoRender($flag = true) + { + $this->_noRender = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve noRender flag value + * + * @return boolean + */ + public function getNoRender() + { + return $this->_noRender; + } + + /** + * Set the view script to use + * + * @param string $name + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setScriptAction($name) + { + $this->_scriptAction = (string) $name; + return $this; + } + + /** + * Retrieve view script name + * + * @return string + */ + public function getScriptAction() + { + return $this->_scriptAction; + } + + /** + * Set the response segment name + * + * @param string $name + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setResponseSegment($name) + { + if (null === $name) { + $this->_responseSegment = null; + } else { + $this->_responseSegment = (string) $name; + } + + return $this; + } + + /** + * Retrieve named response segment name + * + * @return string + */ + public function getResponseSegment() + { + return $this->_responseSegment; + } + + /** + * Set the noController flag (i.e., whether or not to render into controller subdirectories) + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setNoController($flag = true) + { + $this->_noController = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve noController flag value + * + * @return boolean + */ + public function getNoController() + { + return $this->_noController; + } + + /** + * Set the neverController flag (i.e., whether or not to render into controller subdirectories) + * + * @param boolean $flag + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setNeverController($flag = true) + { + $this->_neverController = ($flag) ? true : false; + return $this; + } + + /** + * Retrieve neverController flag value + * + * @return boolean + */ + public function getNeverController() + { + return $this->_neverController; + } + + /** + * Set view script suffix + * + * @param string $suffix + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setViewSuffix($suffix) + { + $this->_viewSuffix = (string) $suffix; + return $this; + } + + /** + * Get view script suffix + * + * @return string + */ + public function getViewSuffix() + { + return $this->_viewSuffix; + } + + /** + * Set options for rendering a view script + * + * @param string $action View script to render + * @param string $name Response named segment to render to + * @param boolean $noController Whether or not to render within a subdirectory named after the controller + * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface + */ + public function setRender($action = null, $name = null, $noController = null) + { + if (null !== $action) { + $this->setScriptAction($action); + } + + if (null !== $name) { + $this->setResponseSegment($name); + } + + if (null !== $noController) { + $this->setNoController($noController); + } + + return $this; + } + + /** + * Inflect based on provided vars + * + * 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 array $vars + * @return string + */ + protected function _translateSpec(array $vars = array()) + { + $inflector = $this->getInflector(); + $request = $this->getRequest(); + $dispatcher = $this->getFrontController()->getDispatcher(); + + // Format module name + $module = $dispatcher->formatModuleName($request->getModuleName()); + + // Format controller name + $filter = new Zend_Filter_Word_CamelCaseToDash(); + $controller = $filter->filter($request->getControllerName()); + $controller = $dispatcher->formatControllerName($controller); + if ('Controller' == substr($controller, -10)) { + $controller = substr($controller, 0, -10); + } + + // Format action name + $action = $dispatcher->formatActionName($request->getActionName()); + + $params = compact('module', 'controller', 'action'); + foreach ($vars as $key => $value) { + switch ($key) { + case 'module': + case 'controller': + case 'action': + case 'moduleDir': + case 'suffix': + $params[$key] = (string) $value; + break; + default: + break; + } + } + + if (isset($params['suffix'])) { + $origSuffix = $this->getViewSuffix(); + $this->setViewSuffix($params['suffix']); + } + if (isset($params['moduleDir'])) { + $origModuleDir = $this->_getModuleDir(); + $this->_setModuleDir($params['moduleDir']); + } + + $filtered = $inflector->filter($params); + + if (isset($params['suffix'])) { + $this->setViewSuffix($origSuffix); + } + if (isset($params['moduleDir'])) { + $this->_setModuleDir($origModuleDir); + } + + return $filtered; + } + + /** + * Render a view script (optionally to a named response segment) + * + * Sets the noRender flag to true when called. + * + * @param string $script + * @param string $name + * @return void + */ + public function renderScript($script, $name = null) + { + if (null === $name) { + $name = $this->getResponseSegment(); + } + + $this->getResponse()->appendBody( + $this->view->render($script), + $name + ); + + $this->setNoRender(); + } + + /** + * Render a view based on path specifications + * + * Renders a view based on the view script path specifications. + * + * @param string $action + * @param string $name + * @param boolean $noController + * @return void + */ + public function render($action = null, $name = null, $noController = null) + { + $this->setRender($action, $name, $noController); + $path = $this->getViewScript(); + $this->renderScript($path, $name); + } + + /** + * Render a script based on specification variables + * + * Pass an action, and one or more specification variables (view script suffix) + * to determine the view script path, and render that script. + * + * @param string $action + * @param array $vars + * @param string $name + * @return void + */ + public function renderBySpec($action = null, array $vars = array(), $name = null) + { + if (null !== $name) { + $this->setResponseSegment($name); + } + + $path = $this->getViewScript($action, $vars); + + $this->renderScript($path); + } + + /** + * postDispatch - auto render a view + * + * Only autorenders if: + * - _noRender is false + * - action controller is present + * - request has not been re-dispatched (i.e., _forward() has not been called) + * - response is not a redirect + * + * @return void + */ + public function postDispatch() + { + if ($this->_shouldRender()) { + $this->render(); + } + } + + /** + * Should the ViewRenderer render a view script? + * + * @return boolean + */ + protected function _shouldRender() + { + return (!$this->getFrontController()->getParam('noViewRenderer') + && !$this->_neverRender + && !$this->_noRender + && (null !== $this->_actionController) + && $this->getRequest()->isDispatched() + && !$this->getResponse()->isRedirect() + ); + } + + /** + * Use this helper as a method; proxies to setRender() + * + * @param string $action + * @param string $name + * @param boolean $noController + * @return void + */ + public function direct($action = null, $name = null, $noController = null) + { + $this->setRender($action, $name, $noController); + } +} diff --git a/library/vendor/Zend/Controller/Action/HelperBroker.php b/library/vendor/Zend/Controller/Action/HelperBroker.php new file mode 100644 index 0000000..ff94dca --- /dev/null +++ b/library/vendor/Zend/Controller/Action/HelperBroker.php @@ -0,0 +1,373 @@ +<?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_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Controller_Action_HelperBroker_PriorityStack + */ + +/** + * @see Zend_Loader + */ + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_HelperBroker +{ + /** + * $_actionController - ActionController reference + * + * @var Zend_Controller_Action + */ + protected $_actionController; + + /** + * @var Zend_Loader_PluginLoader_Interface + */ + protected static $_pluginLoader; + + /** + * $_helpers - Helper array + * + * @var Zend_Controller_Action_HelperBroker_PriorityStack + */ + protected static $_stack = null; + + /** + * Set PluginLoader for use with broker + * + * @param Zend_Loader_PluginLoader_Interface $loader + * @return void + */ + public static function setPluginLoader($loader) + { + if ((null !== $loader) && (!$loader instanceof Zend_Loader_PluginLoader_Interface)) { + throw new Zend_Controller_Action_Exception('Invalid plugin loader provided to HelperBroker'); + } + self::$_pluginLoader = $loader; + } + + /** + * Retrieve PluginLoader + * + * @return Zend_Loader_PluginLoader + */ + public static function getPluginLoader() + { + if (null === self::$_pluginLoader) { + self::$_pluginLoader = new Zend_Loader_PluginLoader(array( + 'Zend_Controller_Action_Helper' => 'Zend/Controller/Action/Helper/', + )); + } + return self::$_pluginLoader; + } + + /** + * addPrefix() - Add repository of helpers by prefix + * + * @param string $prefix + */ + static public function addPrefix($prefix) + { + $prefix = rtrim($prefix, '_'); + $path = str_replace('_', DIRECTORY_SEPARATOR, $prefix); + self::getPluginLoader()->addPrefixPath($prefix, $path); + } + + /** + * addPath() - Add path to repositories where Action_Helpers could be found. + * + * @param string $path + * @param string $prefix Optional; defaults to 'Zend_Controller_Action_Helper' + * @return void + */ + static public function addPath($path, $prefix = 'Zend_Controller_Action_Helper') + { + self::getPluginLoader()->addPrefixPath($prefix, $path); + } + + /** + * addHelper() - Add helper objects + * + * @param Zend_Controller_Action_Helper_Abstract $helper + * @return void + */ + static public function addHelper(Zend_Controller_Action_Helper_Abstract $helper) + { + self::getStack()->push($helper); + return; + } + + /** + * resetHelpers() + * + * @return void + */ + static public function resetHelpers() + { + self::$_stack = null; + return; + } + + /** + * Retrieve or initialize a helper statically + * + * Retrieves a helper object statically, loading on-demand if the helper + * does not already exist in the stack. Always returns a helper, unless + * the helper class cannot be found. + * + * @param string $name + * @return Zend_Controller_Action_Helper_Abstract + */ + public static function getStaticHelper($name) + { + $name = self::_normalizeHelperName($name); + $stack = self::getStack(); + + if (!isset($stack->{$name})) { + self::_loadHelper($name); + } + + return $stack->{$name}; + } + + /** + * getExistingHelper() - get helper by name + * + * Static method to retrieve helper object. Only retrieves helpers already + * initialized with the broker (either via addHelper() or on-demand loading + * via getHelper()). + * + * Throws an exception if the referenced helper does not exist in the + * stack; use {@link hasHelper()} to check if the helper is registered + * prior to retrieving it. + * + * @param string $name + * @return Zend_Controller_Action_Helper_Abstract + * @throws Zend_Controller_Action_Exception + */ + public static function getExistingHelper($name) + { + $name = self::_normalizeHelperName($name); + $stack = self::getStack(); + + if (!isset($stack->{$name})) { + throw new Zend_Controller_Action_Exception('Action helper "' . $name . '" has not been registered with the helper broker'); + } + + return $stack->{$name}; + } + + /** + * Return all registered helpers as helper => object pairs + * + * @return array + */ + public static function getExistingHelpers() + { + return self::getStack()->getHelpersByName(); + } + + /** + * Is a particular helper loaded in the broker? + * + * @param string $name + * @return boolean + */ + public static function hasHelper($name) + { + $name = self::_normalizeHelperName($name); + return isset(self::getStack()->{$name}); + } + + /** + * Remove a particular helper from the broker + * + * @param string $name + * @return boolean + */ + public static function removeHelper($name) + { + $name = self::_normalizeHelperName($name); + $stack = self::getStack(); + if (isset($stack->{$name})) { + unset($stack->{$name}); + } + + return false; + } + + /** + * Lazy load the priority stack and return it + * + * @return Zend_Controller_Action_HelperBroker_PriorityStack + */ + public static function getStack() + { + if (self::$_stack == null) { + self::$_stack = new Zend_Controller_Action_HelperBroker_PriorityStack(); + } + + return self::$_stack; + } + + /** + * Constructor + * + * @param Zend_Controller_Action $actionController + * @return void + */ + public function __construct(Zend_Controller_Action $actionController) + { + $this->_actionController = $actionController; + foreach (self::getStack() as $helper) { + $helper->setActionController($actionController); + $helper->init(); + } + } + + /** + * notifyPreDispatch() - called by action controller dispatch method + * + * @return void + */ + public function notifyPreDispatch() + { + foreach (self::getStack() as $helper) { + $helper->preDispatch(); + } + } + + /** + * notifyPostDispatch() - called by action controller dispatch method + * + * @return void + */ + public function notifyPostDispatch() + { + foreach (self::getStack() as $helper) { + $helper->postDispatch(); + } + } + + /** + * getHelper() - get helper by name + * + * @param string $name + * @return Zend_Controller_Action_Helper_Abstract + */ + public function getHelper($name) + { + $name = self::_normalizeHelperName($name); + $stack = self::getStack(); + + if (!isset($stack->{$name})) { + self::_loadHelper($name); + } + + $helper = $stack->{$name}; + + $initialize = false; + if (null === ($actionController = $helper->getActionController())) { + $initialize = true; + } elseif ($actionController !== $this->_actionController) { + $initialize = true; + } + + if ($initialize) { + $helper->setActionController($this->_actionController) + ->init(); + } + + return $helper; + } + + /** + * Method overloading + * + * @param string $method + * @param array $args + * @return mixed + * @throws Zend_Controller_Action_Exception if helper does not have a direct() method + */ + public function __call($method, $args) + { + $helper = $this->getHelper($method); + if (!method_exists($helper, 'direct')) { + throw new Zend_Controller_Action_Exception('Helper "' . $method . '" does not support overloading via direct()'); + } + return call_user_func_array(array($helper, 'direct'), $args); + } + + /** + * Retrieve helper by name as object property + * + * @param string $name + * @return Zend_Controller_Action_Helper_Abstract + */ + public function __get($name) + { + return $this->getHelper($name); + } + + /** + * Normalize helper name for lookups + * + * @param string $name + * @return string + */ + protected static function _normalizeHelperName($name) + { + if (strpos($name, '_') !== false) { + $name = str_replace(' ', '', ucwords(str_replace('_', ' ', $name))); + } + + return ucfirst($name); + } + + /** + * Load a helper + * + * @param string $name + * @return void + */ + protected static function _loadHelper($name) + { + try { + $class = self::getPluginLoader()->load($name); + } catch (Zend_Loader_PluginLoader_Exception $e) { + throw new Zend_Controller_Action_Exception('Action Helper by name ' . $name . ' not found', 0, $e); + } + + $helper = new $class(); + + if (!$helper instanceof Zend_Controller_Action_Helper_Abstract) { + throw new Zend_Controller_Action_Exception('Helper name ' . $name . ' -> class ' . $class . ' is not of type Zend_Controller_Action_Helper_Abstract'); + } + + self::getStack()->push($helper); + } +} diff --git a/library/vendor/Zend/Controller/Action/HelperBroker/PriorityStack.php b/library/vendor/Zend/Controller/Action/HelperBroker/PriorityStack.php new file mode 100644 index 0000000..c957b10 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/HelperBroker/PriorityStack.php @@ -0,0 +1,272 @@ +<?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_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggregate, ArrayAccess, Countable +{ + + protected $_helpersByPriority = array(); + protected $_helpersByNameRef = array(); + protected $_nextDefaultPriority = 1; + + /** + * Magic property overloading for returning helper by name + * + * @param string $helperName The helper name + * @return Zend_Controller_Action_Helper_Abstract + */ + public function __get($helperName) + { + if (!array_key_exists($helperName, $this->_helpersByNameRef)) { + return false; + } + + return $this->_helpersByNameRef[$helperName]; + } + + /** + * Magic property overloading for returning if helper is set by name + * + * @param string $helperName The helper name + * @return Zend_Controller_Action_Helper_Abstract + */ + public function __isset($helperName) + { + return array_key_exists($helperName, $this->_helpersByNameRef); + } + + /** + * Magic property overloading for unsetting if helper is exists by name + * + * @param string $helperName The helper name + */ + public function __unset($helperName) + { + $this->offsetUnset($helperName); + } + + /** + * push helper onto the stack + * + * @param Zend_Controller_Action_Helper_Abstract $helper + * @return Zend_Controller_Action_HelperBroker_PriorityStack + */ + public function push(Zend_Controller_Action_Helper_Abstract $helper) + { + $this->offsetSet($this->getNextFreeHigherPriority(), $helper); + return $this; + } + + /** + * Return something iterable + * + * @return Traversable + */ + public function getIterator(): Traversable + { + return new ArrayObject($this->_helpersByPriority); + } + + /** + * offsetExists() + * + * @param int|string $priorityOrHelperName + * @return bool + */ + public function offsetExists($priorityOrHelperName): bool + { + if (is_string($priorityOrHelperName)) { + return array_key_exists($priorityOrHelperName, $this->_helpersByNameRef); + } else { + return array_key_exists($priorityOrHelperName, $this->_helpersByPriority); + } + } + + /** + * offsetGet() + * + * @param int|string $priorityOrHelperName + * @return Zend_Controller_Action_Helper_Abstract + */ + public function offsetGet($priorityOrHelperName): Zend_Controller_Action_Helper_Abstract + { + if (!$this->offsetExists($priorityOrHelperName)) { + throw new Zend_Controller_Action_Exception('A helper with priority ' . $priorityOrHelperName . ' does not exist.'); + } + + if (is_string($priorityOrHelperName)) { + return $this->_helpersByNameRef[$priorityOrHelperName]; + } else { + return $this->_helpersByPriority[$priorityOrHelperName]; + } + } + + /** + * offsetSet() + * + * @param int $priority + * @param Zend_Controller_Action_Helper_Abstract $helper + */ + public function offsetSet($priority, $helper): void + { + $priority = (int) $priority; + + if (!$helper instanceof Zend_Controller_Action_Helper_Abstract) { + throw new Zend_Controller_Action_Exception('$helper must extend Zend_Controller_Action_Helper_Abstract.'); + } + + if (array_key_exists($helper->getName(), $this->_helpersByNameRef)) { + // remove any object with the same name to retain BC compailitbility + // @todo At ZF 2.0 time throw an exception here. + $this->offsetUnset($helper->getName()); + } + + if (array_key_exists($priority, $this->_helpersByPriority)) { + $priority = $this->getNextFreeHigherPriority($priority); // ensures LIFO + trigger_error("A helper with the same priority already exists, reassigning to $priority", E_USER_WARNING); + } + + $this->_helpersByPriority[$priority] = $helper; + $this->_helpersByNameRef[$helper->getName()] = $helper; + + if ($priority == ($nextFreeDefault = $this->getNextFreeHigherPriority($this->_nextDefaultPriority))) { + $this->_nextDefaultPriority = $nextFreeDefault; + } + + krsort($this->_helpersByPriority); // always make sure priority and LIFO are both enforced + } + + /** + * offsetUnset() + * + * @param int|string $priorityOrHelperName Priority integer or the helper name + */ + public function offsetUnset($priorityOrHelperName): void + { + if (!$this->offsetExists($priorityOrHelperName)) { + throw new Zend_Controller_Action_Exception('A helper with priority or name ' . $priorityOrHelperName . ' does not exist.'); + } + + if (is_string($priorityOrHelperName)) { + $helperName = $priorityOrHelperName; + $helper = $this->_helpersByNameRef[$helperName]; + $priority = array_search($helper, $this->_helpersByPriority, true); + } else { + $priority = $priorityOrHelperName; + $helperName = $this->_helpersByPriority[$priorityOrHelperName]->getName(); + } + + unset($this->_helpersByNameRef[$helperName]); + unset($this->_helpersByPriority[$priority]); + } + + /** + * return the count of helpers + * + * @return int + */ + public function count(): int + { + return count($this->_helpersByPriority); + } + + /** + * Find the next free higher priority. If an index is given, it will + * find the next free highest priority after it. + * + * @param int $indexPriority OPTIONAL + * @return int + */ + public function getNextFreeHigherPriority($indexPriority = null) + { + if ($indexPriority == null) { + $indexPriority = $this->_nextDefaultPriority; + } + + $priorities = array_keys($this->_helpersByPriority); + + while (in_array($indexPriority, $priorities)) { + $indexPriority++; + } + + return $indexPriority; + } + + /** + * Find the next free lower priority. If an index is given, it will + * find the next free lower priority before it. + * + * @param int $indexPriority + * @return int + */ + public function getNextFreeLowerPriority($indexPriority = null) + { + if ($indexPriority == null) { + $indexPriority = $this->_nextDefaultPriority; + } + + $priorities = array_keys($this->_helpersByPriority); + + while (in_array($indexPriority, $priorities)) { + $indexPriority--; + } + + return $indexPriority; + } + + /** + * return the highest priority + * + * @return int + */ + public function getHighestPriority() + { + return max(array_keys($this->_helpersByPriority)); + } + + /** + * return the lowest priority + * + * @return int + */ + public function getLowestPriority() + { + return min(array_keys($this->_helpersByPriority)); + } + + /** + * return the helpers referenced by name + * + * @return array + */ + public function getHelpersByName() + { + return $this->_helpersByNameRef; + } + +} diff --git a/library/vendor/Zend/Controller/Action/Interface.php b/library/vendor/Zend/Controller/Action/Interface.php new file mode 100644 index 0000000..db35463 --- /dev/null +++ b/library/vendor/Zend/Controller/Action/Interface.php @@ -0,0 +1,69 @@ +<?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_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @category Zend + * @package Zend_Controller + * @subpackage Zend_Controller_Action + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +interface Zend_Controller_Action_Interface +{ + /** + * Class constructor + * + * The request and response objects should be registered with the + * controller, as should be any additional optional arguments; these will be + * available via {@link getRequest()}, {@link getResponse()}, and + * {@link getInvokeArgs()}, respectively. + * + * When overriding the constructor, please consider this usage as a best + * practice and ensure that each is registered appropriately; the easiest + * way to do so is to simply call parent::__construct($request, $response, + * $invokeArgs). + * + * After the request, response, and invokeArgs are set, the + * {@link $_helper helper broker} is initialized. + * + * Finally, {@link init()} is called as the final action of + * instantiation, and may be safely overridden to perform initialization + * tasks; as a general rule, override {@link init()} instead of the + * constructor to customize an action controller's instantiation. + * + * @param Zend_Controller_Request_Abstract $request + * @param Zend_Controller_Response_Abstract $response + * @param array $invokeArgs Any additional invocation arguments + * @return void + */ + public function __construct(Zend_Controller_Request_Abstract $request, + Zend_Controller_Response_Abstract $response, + array $invokeArgs = array()); + + /** + * Dispatch the requested action + * + * @param string $action Method name of action + * @return void + */ + public function dispatch($action); +} |