/lib/Zend/Markup/Renderer/RendererAbstract.php
PHP | 702 lines | 461 code | 54 blank | 187 comment | 46 complexity | fa85f0d36b7f82f50a0fd4077368f552 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
- <?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_Markup
- * @subpackage Renderer
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: RendererAbstract.php 22197 2010-05-19 13:32:25Z kokx $
- */
- /**
- * @see Zend_config
- */
- #require_once 'Zend/Config.php';
- /**
- * @see Zend_Filter
- */
- #require_once 'Zend/Filter.php';
- /**
- * @see Zend_Markup_Renderer_TokenConverterInterface
- */
- #require_once 'Zend/Markup/Renderer/TokenConverterInterface.php';
- /**
- * Defines the basic rendering functionality
- *
- * @category Zend
- * @package Zend_Markup
- * @subpackage Renderer
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- abstract class Zend_Markup_Renderer_RendererAbstract
- {
- const TYPE_CALLBACK = 4;
- const TYPE_REPLACE = 8;
- const TYPE_ALIAS = 16;
- /**
- * Tag info
- *
- * @var array
- */
- protected $_markups = array();
- /**
- * Parser
- *
- * @var Zend_Markup_Parser_ParserInterface
- */
- protected $_parser;
- /**
- * What filter to use
- *
- * @var bool
- */
- protected $_filter;
- /**
- * Filter chain
- *
- * @var Zend_Filter
- */
- protected $_defaultFilter;
- /**
- * The current group
- *
- * @var string
- */
- protected $_group;
- /**
- * Groups definition
- *
- * @var array
- */
- protected $_groups = array();
- /**
- * Plugin loader for tags
- *
- * @var Zend_Loader_PluginLoader
- */
- protected $_pluginLoader;
- /**
- * The current token
- *
- * @var Zend_Markup_Token
- */
- protected $_token;
- /**
- * Encoding
- *
- * @var string
- */
- protected static $_encoding = 'UTF-8';
- /**
- * Constructor
- *
- * @param array|Zend_Config $options
- *
- * @return void
- */
- public function __construct($options = array())
- {
- if ($options instanceof Zend_Config) {
- $options = $options->toArray();
- }
- if (isset($options['encoding'])) {
- $this->setEncoding($options['encoding']);
- }
- if (isset($options['parser'])) {
- $this->setParser($options['parser']);
- }
- if (!isset($options['useDefaultFilters']) || ($options['useDefaultFilters'] === true)) {
- $this->addDefaultFilters();
- }
- if (isset($options['defaultFilter'])) {
- $this->addDefaultFilter($options['defaultFilter']);
- }
- }
- /**
- * Set the parser
- *
- * @param Zend_Markup_Parser_ParserInterface $parser
- * @return Zend_Markup_Renderer_RendererAbstract
- */
- public function setParser(Zend_Markup_Parser_ParserInterface $parser)
- {
- $this->_parser = $parser;
- return $this;
- }
- /**
- * Get the parser
- *
- * @return Zend_Markup_Parser_ParserInterface
- */
- public function getParser()
- {
- return $this->_parser;
- }
- /**
- * Get the plugin loader
- *
- * @return Zend_Loader_PluginLoader
- */
- public function getPluginLoader()
- {
- return $this->_pluginLoader;
- }
- /**
- * Set the renderer's encoding
- *
- * @param string $encoding
- *
- * @return void
- */
- public static function setEncoding($encoding)
- {
- self::$_encoding = $encoding;
- }
- /**
- * Get the renderer's encoding
- *
- * @return string
- */
- public static function getEncoding()
- {
- return self::$_encoding;
- }
- /**
- * Add a new markup
- *
- * @param string $name
- * @param string $type
- * @param array $options
- *
- * @return Zend_Markup_Renderer_RendererAbstract
- */
- public function addMarkup($name, $type, array $options)
- {
- if (!isset($options['group']) && ($type ^ self::TYPE_ALIAS)) {
- #require_once 'Zend/Markup/Renderer/Exception.php';
- throw new Zend_Markup_Renderer_Exception("There is no render group defined.");
- }
- // add the filter
- if (isset($options['filter'])) {
- if ($options['filter'] instanceof Zend_Filter_Interface) {
- $filter = $options['filter'];
- } elseif ($options['filter'] === true) {
- $filter = $this->getDefaultFilter();
- } else {
- $filter = false;
- }
- } else {
- $filter = $this->getDefaultFilter();
- }
- // check the type
- if ($type & self::TYPE_CALLBACK) {
- // add a callback tag
- if (isset($options['callback'])) {
- if (!($options['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
- #require_once 'Zend/Markup/Renderer/Exception.php';
- throw new Zend_Markup_Renderer_Exception("Not a valid tag callback.");
- }
- if (method_exists($options['callback'], 'setRenderer')) {
- $options['callback']->setRenderer($this);
- }
- } else {
- $options['callback'] = null;
- }
- $options['type'] = $type;
- $options['filter'] = $filter;
- $this->_markups[$name] = $options;
- } elseif ($type & self::TYPE_ALIAS) {
- // add an alias
- if (empty($options['name'])) {
- #require_once 'Zend/Markup/Renderer/Exception.php';
- throw new Zend_Markup_Renderer_Exception(
- 'No alias was provided but tag was defined as such');
- }
- $this->_markups[$name] = array(
- 'type' => self::TYPE_ALIAS,
- 'name' => $options['name']
- );
- } else {
- if ($type && array_key_exists('empty', $options) && $options['empty']) {
- // add a single replace markup
- $options['type'] = $type;
- $options['filter'] = $filter;
- $this->_markups[$name] = $options;
- } else {
- // add a replace markup
- $options['type'] = $type;
- $options['filter'] = $filter;
- $this->_markups[$name] = $options;
- }
- }
- return $this;
- }
- /**
- * Remove a markup
- *
- * @param string $name
- *
- * @return void
- */
- public function removeMarkup($name)
- {
- unset($this->_markups[$name]);
- }
- /**
- * Remove the default tags
- *
- * @return void
- */
- public function clearMarkups()
- {
- $this->_markups = array();
- }
- /**
- * Render function
- *
- * @param Zend_Markup_TokenList|string $tokenList
- * @return string
- */
- public function render($value)
- {
- if ($value instanceof Zend_Markup_TokenList) {
- $tokenList = $value;
- } else {
- $tokenList = $this->getParser()->parse($value);
- }
- $root = $tokenList->current();
- $this->_filter = $this->getDefaultFilter();
- return $this->_render($root);
- }
- /**
- * Render a single token
- *
- * @param Zend_Markup_Token $token
- * @return string
- */
- protected function _render(Zend_Markup_Token $token)
- {
- $return = '';
- $this->_token = $token;
- // if this tag has children, execute them
- if ($token->hasChildren()) {
- foreach ($token->getChildren() as $child) {
- $return .= $this->_execute($child);
- }
- }
- return $return;
- }
- /**
- * Get the group of a token
- *
- * @param Zend_Markup_Token $token
- * @return string|bool
- */
- protected function _getGroup(Zend_Markup_Token $token)
- {
- if (!isset($this->_markups[$token->getName()])) {
- return false;
- }
- $tag = $this->_markups[$token->getName()];
- // alias processing
- while ($tag['type'] & self::TYPE_ALIAS) {
- $tag = $this->_markups[$tag['name']];
- }
- return isset($tag['group']) ? $tag['group'] : false;
- }
- /**
- * Execute the token
- *
- * @param Zend_Markup_Token $token
- * @return string
- */
- protected function _execute(Zend_Markup_Token $token)
- {
- // first return the normal text tags
- if ($token->getType() == Zend_Markup_Token::TYPE_NONE) {
- return $this->_filter($token->getTag());
- }
- // if the token doesn't have a notation, return the plain text
- if (!isset($this->_markups[$token->getName()])) {
- $oldToken = $this->_token;
- $return = $this->_filter($token->getTag()) . $this->_render($token) . $token->getStopper();
- $this->_token = $oldToken;
- return $return;
- }
- $name = $this->_getMarkupName($token);
- $markup = (!$name) ? false : $this->_markups[$name];
- $empty = (is_array($markup) && array_key_exists('empty', $markup) && $markup['empty']);
- // check if the tag has content
- if (!$empty && !$token->hasChildren()) {
- return '';
- }
- // check for the context
- if (is_array($markup) && !in_array($markup['group'], $this->_groups[$this->_group])) {
- $oldToken = $this->_token;
- $return = $this->_filter($token->getTag()) . $this->_render($token) . $token->getStopper();
- $this->_token = $oldToken;
- return $return;
- }
- // check for the filter
- if (!isset($markup['filter'])
- || (!($markup['filter'] instanceof Zend_Filter_Interface) && ($markup['filter'] !== false))) {
- $this->_markups[$name]['filter'] = $this->getDefaultFilter();
- }
- // save old values to reset them after the work is done
- $oldFilter = $this->_filter;
- $oldGroup = $this->_group;
- $return = '';
- // set the filter and the group
- $this->_filter = $this->getFilter($name);
- if ($group = $this->_getGroup($token)) {
- $this->_group = $group;
- }
- // callback
- if (is_array($markup) && ($markup['type'] & self::TYPE_CALLBACK)) {
- // load the callback if the tag doesn't exist
- if (!($markup['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
- $class = $this->getPluginLoader()->load($name);
- $markup['callback'] = new $class;
- if (!($markup['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
- #require_once 'Zend/Markup/Renderer/Exception.php';
- throw new Zend_Markup_Renderer_Exception("Callback for tag '$name' found, but it isn't valid.");
- }
- if (method_exists($markup['callback'], 'setRenderer')) {
- $markup['callback']->setRenderer($this);
- }
- }
- if ($markup['type'] && !$empty) {
- $return = $markup['callback']->convert($token, $this->_render($token));
- } else {
- $return = $markup['callback']->convert($token, null);
- }
- } else {
- // replace
- if ($markup['type'] && !$empty) {
- $return = $this->_executeReplace($token, $markup);
- } else {
- $return = $this->_executeSingleReplace($token, $markup);
- }
- }
- // reset to the old values
- $this->_filter = $oldFilter;
- $this->_group = $oldGroup;
- return $return;
- }
- /**
- * Filter method
- *
- * @param string $value
- *
- * @return string
- */
- protected function _filter($value)
- {
- if ($this->_filter instanceof Zend_Filter_Interface) {
- return $this->_filter->filter($value);
- }
- return $value;
- }
- /**
- * Get the markup name
- *
- * @param Zend_Markup_Token
- *
- * @return string
- */
- protected function _getMarkupName(Zend_Markup_Token $token)
- {
- $name = $token->getName();
- if (empty($name)) {
- return false;
- }
- return $this->_resolveMarkupName($name);
- }
- /**
- * Resolve aliases for a markup name
- *
- * @param string $name
- *
- * @return string
- */
- protected function _resolveMarkupName($name)
- {
- while (($type = $this->_getMarkupType($name))
- && ($type & self::TYPE_ALIAS)
- ) {
- $name = $this->_markups[$name]['name'];
- }
- return $name;
- }
- /**
- * Retrieve markup type
- *
- * @param string $name
- * @return false|int
- */
- protected function _getMarkupType($name)
- {
- if (!isset($this->_markups[$name])) {
- return false;
- }
- if (!isset($this->_markups[$name]['type'])) {
- return false;
- }
- return $this->_markups[$name]['type'];
- }
- /**
- * Execute a replace token
- *
- * @param Zend_Markup_Token $token
- * @param array $tag
- * @return string
- */
- protected function _executeReplace(Zend_Markup_Token $token, $tag)
- {
- return $tag['start'] . $this->_render($token) . $tag['end'];
- }
- /**
- * Execute a single replace token
- *
- * @param Zend_Markup_Token $token
- * @param array $tag
- * @return string
- */
- protected function _executeSingleReplace(Zend_Markup_Token $token, $tag)
- {
- return $tag['replace'];
- }
- /**
- * Get the default filter
- *
- * @return void
- */
- public function getDefaultFilter()
- {
- if (null === $this->_defaultFilter) {
- $this->addDefaultFilters();
- }
- return $this->_defaultFilter;
- }
- /**
- * Add a default filter
- *
- * @param string $filter
- *
- * @return void
- */
- public function addDefaultFilter(Zend_Filter_Interface $filter, $placement = Zend_Filter::CHAIN_APPEND)
- {
- if (!($this->_defaultFilter instanceof Zend_Filter)) {
- $defaultFilter = new Zend_Filter();
- $defaultFilter->addFilter($filter);
- $this->_defaultFilter = $defaultFilter;
- }
- $this->_defaultFilter->addFilter($filter, $placement);
- }
- /**
- * Set the default filter
- *
- * @param Zend_Filter_Interface $filter
- *
- * @return void
- */
- public function setDefaultFilter(Zend_Filter_Interface $filter)
- {
- $this->_defaultFilter = $filter;
- }
- /**
- * Get the filter for an existing markup
- *
- * @param string $markup
- *
- * @return Zend_Filter_Interface
- */
- public function getFilter($markup)
- {
- $markup = $this->_resolveMarkupName($markup);
- if (!isset($this->_markups[$markup]['filter'])
- || !($this->_markups[$markup]['filter'] instanceof Zend_Filter_Interface)
- ) {
- if (isset($this->_markups[$markup]['filter']) && $this->_markups[$markup]['filter']) {
- $this->_markups[$markup]['filter'] = $this->getDefaultFilter();
- } else {
- return false;
- }
- }
- return $this->_markups[$markup]['filter'];
- }
- /**
- * Add a filter for an existing markup
- *
- * @param Zend_Filter_Interface $filter
- * @param string $markup
- * @param string $placement
- *
- * @return Zend_Markup_Renderer_RendererAbstract
- */
- public function addFilter(Zend_Filter_Interface $filter, $markup, $placement = Zend_Filter::CHAIN_APPEND)
- {
- $markup = $this->_resolveMarkupName($markup);
- $oldFilter = $this->getFilter($markup);
- // if this filter is the default filter, clone it first
- if ($oldFilter === $this->getDefaultFilter()) {
- $oldFilter = clone $oldFilter;
- }
- if (!($oldFilter instanceof Zend_Filter)) {
- $this->_markups[$markup]['filter'] = new Zend_Filter();
- if ($oldFilter instanceof Zend_Filter_Interface) {
- $this->_markups[$markup]['filter']->addFilter($oldFilter);
- }
- } else {
- $this->_markups[$markup]['filter'] = $oldFilter;
- }
- $this->_markups[$markup]['filter']->addFilter($filter, $placement);
- return $this;
- }
- /**
- * Set the filter for an existing
- *
- * @param Zend_Filter_Interface $filter
- * @param string $markup
- *
- * @return Zend_Markup_Renderer_RendererAbstract
- */
- public function setFilter(Zend_Filter_Interface $filter, $markup)
- {
- $markup = $this->_resolveMarkupName($markup);
- $this->_markups[$markup]['filter'] = $filter;
- return $this;
- }
- /**
- * Add a render group
- *
- * @param string $name
- * @param array $allowedInside
- * @param array $allowsInside
- *
- * @return void
- */
- public function addGroup($name, array $allowedInside = array(), array $allowsInside = array())
- {
- $this->_groups[$name] = $allowsInside;
- foreach ($allowedInside as $group) {
- $this->_groups[$group][] = $name;
- }
- }
- /**
- * Get group definitions
- *
- * @return array
- */
- public function getGroups()
- {
- return $this->_groups;
- }
- /**
- * Set the default filters
- *
- * @return void
- */
- abstract public function addDefaultFilters();
- }