--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/Zend/Markup/Renderer/RendererAbstract.php Mon Dec 13 18:29:26 2010 +0100
@@ -0,0 +1,702 @@
+<?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();
+
+}