[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb\textformatter\s9e; 15 16 use phpbb\textformatter\s9e\factory; 17 use s9e\TextFormatter\Configurator\Helpers\TemplateLoader; 18 use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; 19 20 class bbcode_merger 21 { 22 /** 23 * @var \s9e\TextFormatter\Configurator $configurator Configurator instance used to inspect BBCodes 24 */ 25 protected $configurator; 26 27 /** 28 * @param factory $factory 29 */ 30 public function __construct(factory $factory) 31 { 32 $this->configurator = $factory->get_configurator(); 33 } 34 35 /** 36 * Merge two BBCode definitions 37 * 38 * All of the arrays contain a "usage" element and a "template" element 39 * 40 * @throws InvalidArgumentException if a definition cannot be interpreted 41 * @throws RuntimeException if something unexpected occurs 42 * 43 * @param array $without BBCode definition without an attribute 44 * @param array $with BBCode definition with an attribute 45 * @return array Merged definition 46 */ 47 public function merge_bbcodes(array $without, array $with) 48 { 49 $without = $this->create_bbcode($without); 50 $with = $this->create_bbcode($with); 51 52 // Select the appropriate strategy for merging this BBCode 53 if (!$this->is_optional_bbcode($without, $with) && $this->is_content_bbcode($without, $with)) 54 { 55 $merged = $this->merge_content_bbcode($without, $with); 56 } 57 else 58 { 59 $merged = $this->merge_optional_bbcode($without, $with); 60 } 61 62 $merged['template'] = $this->normalize_template($merged['template']); 63 64 return $merged; 65 } 66 67 /** 68 * Create a custom BBCode for inspection 69 * 70 * @param array $definition Original BBCode definition 71 * @return array Updated definition containing a BBCode object and a Tag 72 */ 73 protected function create_bbcode(array $definition) 74 { 75 $bbcode = $this->configurator->BBCodes->addCustom( 76 $definition['usage'], 77 new UnsafeTemplate($definition['template']) 78 ); 79 80 $definition['bbcode'] = $bbcode; 81 $definition['tag'] = $this->configurator->tags[$bbcode->tagName]; 82 83 return $definition; 84 } 85 86 /** 87 * Indent given template for readability 88 * 89 * @param string $template 90 * @return string 91 */ 92 protected function indent_template($template) 93 { 94 $dom = TemplateLoader::load($template); 95 $dom->formatOutput = true; 96 $template = TemplateLoader::save($dom); 97 98 // Remove the first level of indentation if the template starts with whitespace 99 if (preg_match('(^\\n +)', $template, $m)) 100 { 101 $template = str_replace($m[0], "\n", $template); 102 } 103 104 return trim($template); 105 } 106 107 /** 108 * Test whether the two definitions form a "content"-style BBCode 109 * 110 * Such BBCodes include the [url] BBCode, which uses its text content as 111 * attribute if none is provided 112 * 113 * @param array $without BBCode definition without an attribute 114 * @param array $with BBCode definition with an attribute 115 * @return bool 116 */ 117 protected function is_content_bbcode(array $without, array $with) 118 { 119 // Test whether we find the same non-TEXT token between "]" and "[" in the usage 120 // as between ">" and "<" in the template 121 return (preg_match('(\\]\\s*(\\{(?!TEXT)[^}]+\\})\\s*\\[)', $without['usage'], $m) 122 && preg_match('(>[^<]*?' . preg_quote($m[1]) . '[^>]*?<)s', $without['template'])); 123 } 124 125 /** 126 * Test whether the two definitions form BBCode with an optional attribute 127 * 128 * @param array $without BBCode definition without an attribute 129 * @param array $with BBCode definition with an attribute 130 * @return bool 131 */ 132 protected function is_optional_bbcode(array $without, array $with) 133 { 134 // Remove the default attribute from the definition 135 $with['usage'] = preg_replace('(=[^\\]]++)', '', $with['usage']); 136 137 // Test whether both definitions are the same, regardless of case 138 return strcasecmp($without['usage'], $with['usage']) === 0; 139 } 140 141 /** 142 * Merge the two BBCode definitions of a "content"-style BBCode 143 * 144 * @param array $without BBCode definition without an attribute 145 * @param array $with BBCode definition with an attribute 146 * @return array Merged definition 147 */ 148 protected function merge_content_bbcode(array $without, array $with) 149 { 150 // Convert [x={X}] into [x={X;useContent}] 151 $usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1); 152 153 // Use the template from the definition that uses an attribute 154 $template = $with['tag']->template; 155 156 return ['usage' => $usage, 'template' => $template]; 157 } 158 159 /** 160 * Merge the two BBCode definitions of a BBCode with an optional argument 161 * 162 * Such BBCodes include the [quote] BBCode, which takes an optional argument 163 * but otherwise does not behave differently 164 * 165 * @param array $without BBCode definition without an attribute 166 * @param array $with BBCode definition with an attribute 167 * @return array Merged definition 168 */ 169 protected function merge_optional_bbcode(array $without, array $with) 170 { 171 // Convert [X={X}] into [X={X?}] 172 $usage = preg_replace('(\\})', '?}', $with['usage'], 1); 173 174 // Build a template for both versions 175 $template = '<xsl:choose><xsl:when test="@' . $with['bbcode']->defaultAttribute . '">' . $with['tag']->template . '</xsl:when><xsl:otherwise>' . $without['tag']->template . '</xsl:otherwise></xsl:choose>'; 176 177 return ['usage' => $usage, 'template' => $template]; 178 } 179 180 /** 181 * Normalize a template 182 * 183 * @param string $template 184 * @return string 185 */ 186 protected function normalize_template($template) 187 { 188 // Normalize the template to simplify it 189 $template = $this->configurator->templateNormalizer->normalizeTemplate($template); 190 191 // Convert xsl:value-of elements back to {L_} tokens where applicable 192 $template = preg_replace('(<xsl:value-of select="\\$(L_\\w+)"/>)', '{$1}', $template); 193 194 // Beautify the template 195 $template = $this->indent_template($template); 196 197 return $template; 198 } 199 }
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 |