.
*/
/**
* Handles template tag registry.
*
* @since 4.6.0
* @package Tag
*/
namespace Textpattern\Tag;
class Registry implements \Textpattern\Container\ReusableInterface
{
/**
* Stores registered tags and attributes.
*
* @var array
*/
private $tags = array();
private $atts = array();
private $params = array();
private $attr = array();
/**
* Registers a tag.
*
*
* Txp::get('\Textpattern\Tag\Registry')->register(array('class', 'method'), 'tag');
*
*
* @param callback $callback The tag callback
* @param string|null $tag The tag name
* @return \Textpattern\Tag\Registry
*/
public function register($callback, $tag = null)
{
// is_callable only checks syntax here to avoid autoloading
if (is_callable($callback, true)) {
if ($tag === null && is_string($callback)) {
$tag = $callback;
} elseif (is_array($tag)) {
list($tag, $atts) = $tag + array(null, null);
}
if ($tag) {
$this->tags[$tag] = $callback;
$params = array_slice(func_get_args(), 2);
if (!empty($params)) {
$this->params[$tag] = $params;
}
if (isset($atts)) {
$this->atts[$tag] = (array)$atts;
}
}
}
return $this;
}
/**
* Registers an attribute.
*
*
* Txp::get('\Textpattern\Tag\Registry')->registerAtt(array('class', 'method'), 'tag');
*
*
* @param callback $callback The attribute callback
* @param string|null $tag The attribute name
* @return \Textpattern\Tag\Registry
*/
public function registerAttr($callback, $tag = null)
{
// is_callable only checks syntax here to avoid autoloading
if (is_bool($callback)) {
foreach (do_list_unique($tag) as $tag) {
$this->attr[$tag] = $callback;
}
} elseif ($callback && is_callable($callback, true)) {
if ($tag === null && is_string($callback)) {
$this->attr[$callback] = $callback;
} else {
foreach (do_list_unique($tag) as $tag) {
$this->attr[$tag] = $callback;
}
}
}
return $this;
}
/**
* Processes a tag by name.
*
* @param string $tag The tag
* @param array|null $atts An array of Attributes
* @param string|null $thing The contained statement
* @return string|bool The tag's results (string) or FALSE on unknown tags
*/
public function process($tag, array $atts = null, $thing = null)
{
if ($this->isRegistered($tag)) {
$atts = (array)$atts;
if (isset($this->atts[$tag])) {
$atts += $this->atts[$tag];
}
//TODO: switch to args unpacking for php 5.6+
return isset($this->params[$tag]) ?
// (string) call_user_func($this->tags[$tag], (array)$atts, $thing, ...$this->params[$tag]) :
(string) call_user_func_array($this->tags[$tag], array_merge(array($atts, $thing), $this->params[$tag])) :
(string) call_user_func($this->tags[$tag], $atts, $thing);
} else {
return false;
}
}
/**
* Processes an attribute by name.
*
* @param string $tag The attribute
* @param string|null $atts The value of attribute
* @param string|null $thing The processed statement
* @return string|bool The tag's results (string) or FALSE on unknown tags
*/
public function processAttr($tag, $atts = null, $thing = null)
{
if ($this->isRegisteredAttr($tag)) {
return (string) call_user_func($this->attr[$tag], $atts, $thing);
} else {
return false;
}
}
/**
* Checks if a tag is registered.
*
* @param string $tag The tag
* @return bool TRUE if the tag exists
*/
public function isRegistered($tag)
{
return isset($this->tags[$tag]) && is_callable($this->tags[$tag]);
}
/**
* Checks if an attribute is registered.
*
* @param string $tag The tag
* @return bool TRUE if the tag exists
*/
public function isRegisteredAttr($tag)
{
return isset($this->attr[$tag]) && is_callable($this->attr[$tag]);
}
/**
* Lists registered tags.
*
* @param bool $is_attr tag or attr?
* @return array
*/
public function getRegistered($is_attr = false)
{
return $is_attr ? $this->attr : $this->tags;
}
/**
* Tags getter.
*
* @param string $tag
* @return callable
*/
public function getTag($tag)
{
return $this->isRegistered($tag) ? $this->tags[$tag] : false;
}
}