Seditio Source
Root |
./othercms/phpBB3/vendor/s9e/text-formatter/src/Parser/FilterProcessing.php
<?php

/**
* @package   s9e\TextFormatter
* @copyright Copyright (c) 2010-2021 The s9e authors
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace s9e\TextFormatter\Parser;

use
s9e\TextFormatter\Parser;

class
FilterProcessing
{
   
/**
    * Execute all the attribute preprocessors of given tag
    *
    * @private
    *
    * @param  Tag   $tag       Source tag
    * @param  array $tagConfig Tag's config
    * @return void
    */
   
public static function executeAttributePreprocessors(Tag $tag, array $tagConfig)
    {
        if (empty(
$tagConfig['attributePreprocessors']))
        {
            return;
        }

        foreach (
$tagConfig['attributePreprocessors'] as list($attrName, $regexp, $map))
        {
            if (
$tag->hasAttribute($attrName))
            {
               
self::executeAttributePreprocessor($tag, $attrName, $regexp, $map);
            }
        }
    }

   
/**
    * Filter the attributes of given tag
    *
    * @private
    *
    * @param  Tag    $tag            Tag being checked
    * @param  array  $tagConfig      Tag's config
    * @param  array  $registeredVars Array of registered vars for use in attribute filters
    * @param  Logger $logger         This parser's Logger instance
    * @return void
    */
   
public static function filterAttributes(Tag $tag, array $tagConfig, array $registeredVars, Logger $logger)
    {
       
$attributes = [];
        foreach (
$tagConfig['attributes'] as $attrName => $attrConfig)
        {
           
$attrValue = false;
            if (
$tag->hasAttribute($attrName))
            {
               
$vars = [
                   
'attrName'       => $attrName,
                   
'attrValue'      => $tag->getAttribute($attrName),
                   
'logger'         => $logger,
                   
'registeredVars' => $registeredVars
               
];
               
$attrValue = self::executeAttributeFilterChain($attrConfig['filterChain'], $vars);
            }

            if (
$attrValue !== false)
            {
               
$attributes[$attrName] = $attrValue;
            }
            elseif (isset(
$attrConfig['defaultValue']))
            {
               
$attributes[$attrName] = $attrConfig['defaultValue'];
            }
            elseif (!empty(
$attrConfig['required']))
            {
               
$tag->invalidate();
            }
        }
       
$tag->setAttributes($attributes);
    }

   
/**
    * Execute a tag's filterChain
    *
    * @private
    *
    * @param  Tag    $tag        Tag to filter
    * @param  Parser $parser     Parser
    * @param  array  $tagsConfig Tags' config
    * @param  Tag[]  $openTags   List of open tags
    * @return void
    */
   
public static function filterTag(Tag $tag, Parser $parser, array $tagsConfig, array $openTags)
    {
       
$tagName   = $tag->getName();
       
$tagConfig = $tagsConfig[$tagName];

       
// Record the tag being processed into the logger it can be added to the context of
        // messages logged during the execution
       
$logger = $parser->getLogger();
       
$logger->setTag($tag);

       
// Prepare the variables that are accessible to filters
       
$text = $parser->getText();
       
$vars = [
           
'innerText'      => '',
           
'logger'         => $logger,
           
'openTags'       => $openTags,
           
'outerText'      => substr($text, $tag->getPos(), $tag->getLen()),
           
'parser'         => $parser,
           
'registeredVars' => $parser->registeredVars,
           
'tag'            => $tag,
           
'tagConfig'      => $tagConfig,
           
'tagText'        => substr($text, $tag->getPos(), $tag->getLen()),
           
'text'           => $text
       
];
       
$endTag = $tag->getEndTag();
        if (
$endTag)
        {
           
$vars['innerText'] = substr($text, $tag->getPos() + $tag->getLen(), $endTag->getPos() - $tag->getPos() - $tag->getLen());
           
$vars['outerText'] = substr($text, $tag->getPos(), $endTag->getPos() + $endTag->getLen() - $tag->getPos());
        }
        foreach (
$tagConfig['filterChain'] as $filter)
        {
            if (
$tag->isInvalid())
            {
                break;
            }
           
self::executeFilter($filter, $vars);
        }

       
// Remove the tag from the logger
       
$logger->unsetTag();
    }

   
/**
    * Execute an attribute's filterChain
    *
    * @param  array $filterChain Attribute's filterChain
    * @param  array $vars        Callback vars
    * @return mixed              Filtered value
    */
   
protected static function executeAttributeFilterChain(array $filterChain, array $vars)
    {
       
$vars['logger']->setAttribute($vars['attrName']);
        foreach (
$filterChain as $filter)
        {
           
$vars['attrValue'] = self::executeFilter($filter, $vars);
            if (
$vars['attrValue'] === false)
            {
                break;
            }
        }
       
$vars['logger']->unsetAttribute();

        return
$vars['attrValue'];
    }

   
/**
    * Execute an attribute preprocessor
    *
    * @param  Tag      $tag
    * @param  string   $attrName
    * @param  string   $regexp
    * @param  string[] $map
    * @return void
    */
   
protected static function executeAttributePreprocessor(Tag $tag, $attrName, $regexp, $map)
    {
       
$attrValue = $tag->getAttribute($attrName);
       
$captures  = self::getNamedCaptures($attrValue, $regexp, $map);
        foreach (
$captures as $k => $v)
        {
           
// Attribute preprocessors cannot overwrite other attributes but they can
            // overwrite themselves
           
if ($k === $attrName || !$tag->hasAttribute($k))
            {
               
$tag->setAttribute($k, $v);
            }
        }
    }

   
/**
    * Execute a filter
    *
    * @see s9e\TextFormatter\Configurator\Items\ProgrammableCallback
    *
    * @param  array $filter Programmed callback
    * @param  array $vars   Variables to be used when executing the callback
    * @return mixed         Whatever the callback returns
    */
   
protected static function executeFilter(array $filter, array $vars)
    {
       
// Add vars from the registeredVars array to the list of vars
       
$vars += ['registeredVars' => []];
       
$vars += $vars['registeredVars'];

       
// Prepare the list of arguments
       
$args = [];
        if (isset(
$filter['params']))
        {
            foreach (
$filter['params'] as $k => $v)
            {
               
$args[] = $vars[$k] ?? $v;
            }
        }

        return
call_user_func_array($filter['callback'], $args);
    }

   
/**
    * Execute a regexp and return the values of the mapped captures
    *
    * @param  string   $str
    * @param  string   $regexp
    * @param  string[] $map
    * @return array
    */
   
protected static function getNamedCaptures($str, $regexp, $map)
    {
        if (!
preg_match($regexp, $str, $m))
        {
            return [];
        }

       
$values = [];
        foreach (
$map as $i => $k)
        {
            if (isset(
$m[$i]) && $m[$i] !== '')
            {
               
$values[$k] = $m[$i];
            }
        }

        return
$values;
    }
}