Seditio Source
Root |
./othercms/phpBB3/vendor/s9e/text-formatter/src/Configurator/Helpers/AVTHelper.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\Configurator\Helpers;

use
DOMAttr;
use
RuntimeException;

abstract class
AVTHelper
{
   
/**
    * Parse an attribute value template
    *
    * @link https://www.w3.org/TR/1999/REC-xslt-19991116#dt-attribute-value-template
    *
    * @param  string $attrValue Attribute value
    * @return array             Array of tokens
    */
   
public static function parse($attrValue)
    {
       
preg_match_all('((*MARK:literal)(?:[^{]|\\{\\{)++|(*MARK:expression)\\{(?:[^}"\']|"[^"]*+"|\'[^\']*+\')++\\}|(*MARK:junk).++)s', $attrValue, $matches);

       
$tokens  = [];
        foreach (
$matches[0] as $i => $str)
        {
            if (
$matches['MARK'][$i] === 'expression')
            {
               
$tokens[] = ['expression', substr($str, 1, -1)];
            }
            else
            {
               
$tokens[] = ['literal', strtr($str, ['{{' => '{', '}}' => '}'])];
            }
        }

        return
$tokens;
    }

   
/**
    * Replace the value of an attribute via the provided callback
    *
    * The callback will receive an array containing the type and value of each token in the AVT.
    * Its return value should use the same format
    *
    * @param  DOMAttr  $attribute
    * @param  callable $callback
    * @return void
    */
   
public static function replace(DOMAttr $attribute, callable $callback)
    {
       
$tokens = self::parse($attribute->value);
        foreach (
$tokens as $k => $token)
        {
           
$tokens[$k] = $callback($token);
        }

       
$attribute->value = htmlspecialchars(self::serialize($tokens), ENT_NOQUOTES, 'UTF-8');
    }

   
/**
    * Serialize an array of AVT tokens back into an attribute value
    *
    * @param  array  $tokens
    * @return string
    */
   
public static function serialize(array $tokens)
    {
       
$attrValue = '';
        foreach (
$tokens as $token)
        {
            if (
$token[0] === 'literal')
            {
               
$attrValue .= preg_replace('([{}])', '$0$0', $token[1]);
            }
            elseif (
$token[0] === 'expression')
            {
               
$attrValue .= '{' . $token[1] . '}';
            }
            else
            {
                throw new
RuntimeException('Unknown token type');
            }
        }

        return
$attrValue;
    }

   
/**
    * Transform given attribute value template into an XSL fragment
    *
    * @param  string $attrValue
    * @return string
    */
   
public static function toXSL($attrValue)
    {
       
$xsl = '';
        foreach (
self::parse($attrValue) as list($type, $content))
        {
            if (
$type === 'expression')
            {
               
$xsl .= '<xsl:value-of select="' . htmlspecialchars($content, ENT_COMPAT, 'UTF-8') . '"/>';
            }
            elseif (
trim($content) !== $content)
            {
               
$xsl .= '<xsl:text>' . htmlspecialchars($content, ENT_NOQUOTES, 'UTF-8') . '</xsl:text>';
            }
            else
            {
               
$xsl .= htmlspecialchars($content, ENT_NOQUOTES, 'UTF-8');
            }
        }

        return
$xsl;
    }
}