[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |