[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Plugins/Emoticons/ -> Configurator.php (source)

   1  <?php
   2  
   3  /**
   4  * @package   s9e\TextFormatter
   5  * @copyright Copyright (c) 2010-2022 The s9e authors
   6  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
   7  */
   8  namespace s9e\TextFormatter\Plugins\Emoticons;
   9  
  10  use ArrayAccess;
  11  use Countable;
  12  use Iterator;
  13  use s9e\TextFormatter\Configurator\Helpers\ConfigHelper;
  14  use s9e\TextFormatter\Configurator\Helpers\RegexpBuilder;
  15  use s9e\TextFormatter\Configurator\Items\Regexp;
  16  use s9e\TextFormatter\Configurator\JavaScript\RegexpConvertor;
  17  use s9e\TextFormatter\Configurator\Traits\CollectionProxy;
  18  use s9e\TextFormatter\Plugins\ConfiguratorBase;
  19  use s9e\TextFormatter\Plugins\Emoticons\Configurator\EmoticonCollection;
  20  use s9e\TextFormatter\Utils\XPath;
  21  
  22  /**
  23  * @method mixed   add(string $key, mixed $value) Add an item to this collection
  24  * @method array   asConfig()
  25  * @method void    clear()                        Empty this collection
  26  * @method bool    contains(mixed $value)         Test whether a given value is present in this collection
  27  * @method integer count()
  28  * @method mixed   current()
  29  * @method void    delete(string $key)            Delete an item from this collection
  30  * @method bool    exists(string $key)            Test whether an item of given key exists
  31  * @method mixed   get(string $key)               Return a value from this collection
  32  * @method mixed   indexOf(mixed $value)          Find the index of a given value
  33  * @method integer|string key()
  34  * @method mixed   next()
  35  * @method string  normalizeKey(string $key)      Normalize an item's key
  36  * @method string  normalizeValue(string $value)  Normalize an emoticon's template
  37  * @method bool    offsetExists(string|integer $offset)
  38  * @method mixed   offsetGet(string|integer $offset)
  39  * @method void    offsetSet(string|integer $offset, mixed $value)
  40  * @method void    offsetUnset(string|integer $offset)
  41  * @method string  onDuplicate(string|null $action) Query and set the action to take when add() is called with a key that already exists
  42  * @method void    rewind()
  43  * @method mixed   set(string $key, mixed $value) Set and overwrite a value in this collection
  44  * @method bool    valid()
  45  */
  46  class Configurator extends ConfiguratorBase implements ArrayAccess, Countable, Iterator
  47  {
  48      use CollectionProxy;
  49  
  50      /**
  51      * @var EmoticonCollection
  52      */
  53      protected $collection;
  54  
  55      /**
  56      * @var string PCRE subpattern used in a negative lookbehind assertion before the emoticons
  57      */
  58      public $notAfter = '';
  59  
  60      /**
  61      * @var string PCRE subpattern used in a negative lookahead assertion after the emoticons
  62      */
  63      public $notBefore = '';
  64  
  65      /**
  66      * @var string XPath expression that, if true, forces emoticons to be rendered as text
  67      */
  68      public $notIfCondition;
  69  
  70      /**
  71      * {@inheritdoc}
  72      */
  73      protected $onDuplicateAction = 'replace';
  74  
  75      /**
  76      * @var string Name of the tag used by this plugin
  77      */
  78      protected $tagName = 'E';
  79  
  80      /**
  81      * Plugin's setup
  82      *
  83      * Will create the tag used by this plugin
  84      */
  85  	protected function setUp()
  86      {
  87          $this->collection = new EmoticonCollection;
  88  
  89          if (!$this->configurator->tags->exists($this->tagName))
  90          {
  91              $this->configurator->tags->add($this->tagName);
  92          }
  93      }
  94  
  95      /**
  96      * Create the template used for emoticons
  97      *
  98      * @return void
  99      */
 100  	public function finalize()
 101      {
 102          $tag = $this->getTag();
 103  
 104          if (!isset($tag->template))
 105          {
 106              $tag->template = $this->getTemplate();
 107          }
 108      }
 109  
 110      /**
 111      * @return array
 112      */
 113  	public function asConfig()
 114      {
 115          if (!count($this->collection))
 116          {
 117              return;
 118          }
 119  
 120          // Grab the emoticons from the collection
 121          $codes = array_keys(iterator_to_array($this->collection));
 122  
 123          // Build the regexp used to match emoticons
 124          $regexp = '/';
 125  
 126          if ($this->notAfter !== '')
 127          {
 128              $regexp .= '(?<!' . $this->notAfter . ')';
 129          }
 130  
 131          $regexp .= RegexpBuilder::fromList($codes);
 132  
 133          if ($this->notBefore !== '')
 134          {
 135              $regexp .= '(?!' . $this->notBefore . ')';
 136          }
 137  
 138          $regexp .= '/S';
 139  
 140          // Set the Unicode mode if Unicode properties are used
 141          if (preg_match('/\\\\[pP](?>\\{\\^?\\w+\\}|\\w\\w?)/', $regexp))
 142          {
 143              $regexp .= 'u';
 144          }
 145  
 146          // Force the regexp to use atomic grouping for performance
 147          $regexp = preg_replace('/(?<!\\\\)((?>\\\\\\\\)*)\\(\\?:/', '$1(?>', $regexp);
 148  
 149          // Prepare the config array
 150          $config = [
 151              'quickMatch' => $this->quickMatch,
 152              'regexp'     => $regexp,
 153              'tagName'    => $this->tagName
 154          ];
 155  
 156          // If notAfter is used, we need to create a JavaScript-specific regexp that does not use a
 157          // lookbehind assertion, and we add the notAfter subpattern to the config as a variant
 158          if ($this->notAfter !== '')
 159          {
 160              // Skip the first assertion by skipping the first N characters, where N equals the
 161              // length of $this->notAfter plus 1 for the first "/" and 5 for "(?<!)"
 162              $lpos = 6 + strlen($this->notAfter);
 163              $rpos = strrpos($regexp, '/');
 164              $jsRegexp = RegexpConvertor::toJS('/' . substr($regexp, $lpos, $rpos - $lpos) . '/', true);
 165  
 166              $config['regexp'] = new Regexp($regexp);
 167              $config['regexp']->setJS($jsRegexp);
 168  
 169              $config['notAfter'] = new Regexp('/' . $this->notAfter . '/');
 170          }
 171  
 172          // Try to find a quickMatch if none is set
 173          if ($this->quickMatch === false)
 174          {
 175              $config['quickMatch'] = ConfigHelper::generateQuickMatchFromList($codes);
 176          }
 177  
 178          return $config;
 179      }
 180  
 181      /**
 182      * {@inheritdoc}
 183      */
 184  	public function getJSHints()
 185      {
 186          return ['EMOTICONS_NOT_AFTER' => (int) !empty($this->notAfter)];
 187      }
 188  
 189      /**
 190      * Generate the dynamic template that renders all emoticons
 191      *
 192      * @return string
 193      */
 194  	public function getTemplate()
 195      {
 196          // Build the <xsl:choose> node
 197          $xsl = '<xsl:choose>';
 198  
 199          // First, test whether the emoticon should be rendered as text if applicable
 200          if (!empty($this->notIfCondition))
 201          {
 202              $xsl .= '<xsl:when test="' . htmlspecialchars($this->notIfCondition, ENT_COMPAT) . '">'
 203                    . '<xsl:value-of select="."/>'
 204                    . '</xsl:when>'
 205                    . '<xsl:otherwise>'
 206                    . '<xsl:choose>';
 207          }
 208  
 209          // Iterate over codes, create an <xsl:when> for each emote
 210          foreach ($this->collection as $code => $template)
 211          {
 212              $xsl .= '<xsl:when test=".=' . htmlspecialchars(XPath::export($code), ENT_COMPAT) . '">'
 213                    . $template
 214                    . '</xsl:when>';
 215          }
 216  
 217          // Finish it with an <xsl:otherwise> that displays the unknown codes as text
 218          $xsl .= '<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>';
 219  
 220          // Close the emote switch
 221          $xsl .= '</xsl:choose>';
 222  
 223          // Close the "notIf" condition if applicable
 224          if (!empty($this->notIfCondition))
 225          {
 226              $xsl .= '</xsl:otherwise></xsl:choose>';
 227          }
 228  
 229          return $xsl;
 230      }
 231  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1