[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Renderers/ -> PHP.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\Renderers;
   9  
  10  use DOMNode;
  11  use DOMXPath;
  12  use RuntimeException;
  13  use s9e\TextFormatter\Renderer;
  14  use s9e\TextFormatter\Utils\XPath;
  15  
  16  abstract class PHP extends Renderer
  17  {
  18      /**
  19      * @var array[] Stack of dictionaries used by the Quick renderer [[attrName => attrValue]]
  20      */
  21      protected $attributes;
  22  
  23      /**
  24      * @var array Dictionary of replacements used by the Quick renderer [id => [match, replace]]
  25      */
  26      protected $dynamic;
  27  
  28      /**
  29      * @var bool Whether to enable the Quick renderer
  30      */
  31      public $enableQuickRenderer = false;
  32  
  33      /**
  34      * @var string Renderer's output
  35      */
  36      protected $out;
  37  
  38      /**
  39      * @var string Regexp that matches XML elements to be rendered by the quick renderer
  40      */
  41      protected $quickRegexp = '((?!))';
  42  
  43      /**
  44      * @var string Regexp that matches nodes that SHOULD NOT be rendered by the quick renderer
  45      */
  46      protected $quickRenderingTest = '((?<=<)[!?])';
  47  
  48      /**
  49      * @var array Dictionary of static replacements used by the Quick renderer [id => replacement]
  50      */
  51      protected $static;
  52  
  53      /**
  54      * @var DOMXPath XPath object used to query the document being rendered
  55      */
  56      protected $xpath;
  57  
  58      /**
  59      * Render given DOMNode
  60      *
  61      * @param  DOMNode $node
  62      * @return void
  63      */
  64      abstract protected function renderNode(DOMNode $node);
  65  
  66  	public function __sleep()
  67      {
  68          return ['enableQuickRenderer', 'params'];
  69      }
  70  
  71      /**
  72      * Render the content of given node
  73      *
  74      * Matches the behaviour of an xsl:apply-templates element
  75      *
  76      * @param  DOMNode $root  Context node
  77      * @param  string  $query XPath query used to filter which child nodes to render
  78      * @return void
  79      */
  80      protected function at(DOMNode $root, $query = null)
  81      {
  82          if ($root->nodeType === XML_TEXT_NODE)
  83          {
  84              // Text nodes are outputted directly
  85              $this->out .= htmlspecialchars($root->textContent, ENT_NOQUOTES);
  86          }
  87          else
  88          {
  89              $nodes = (isset($query)) ? $this->xpath->query($query, $root) : $root->childNodes;
  90              foreach ($nodes as $node)
  91              {
  92                  $this->renderNode($node);
  93              }
  94          }
  95      }
  96  
  97      /**
  98      * Test whether given XML can be rendered with the Quick renderer
  99      *
 100      * @param  string $xml
 101      * @return bool
 102      */
 103  	protected function canQuickRender($xml)
 104      {
 105          return ($this->enableQuickRenderer && !preg_match($this->quickRenderingTest, $xml) && substr($xml, -4) === '</r>');
 106      }
 107  
 108      /**
 109      * Ensure that a tag pair does not contain a start tag of itself
 110      *
 111      * Detects malformed matches such as <X><X></X>
 112      *
 113      * @param  string $id
 114      * @param  string $xml
 115      * @return void
 116      */
 117  	protected function checkTagPairContent($id, $xml)
 118      {
 119          if (strpos($xml, '<' . $id, 1) !== false)
 120          {
 121              throw new RuntimeException;
 122          }
 123      }
 124  
 125      /**
 126      * Return a parameter's value as an XPath expression
 127      *
 128      * @param  string $paramName
 129      * @return string
 130      */
 131  	protected function getParamAsXPath($paramName)
 132      {
 133          return (isset($this->params[$paramName])) ? XPath::export($this->params[$paramName]) : "''";
 134      }
 135  
 136      /**
 137      * Extract the text content from given XML
 138      *
 139      * NOTE: numeric character entities are decoded beforehand, we don't need to decode them here
 140      *
 141      * @param  string $xml Original XML
 142      * @return string      Text content, with special characters decoded
 143      */
 144  	protected function getQuickTextContent($xml)
 145      {
 146          return htmlspecialchars_decode(strip_tags($xml));
 147      }
 148  
 149      /**
 150      * Test whether given array has any non-null values
 151      *
 152      * @param  array $array
 153      * @return bool
 154      */
 155  	protected function hasNonNullValues(array $array)
 156      {
 157          foreach ($array as $v)
 158          {
 159              if (isset($v))
 160              {
 161                  return true;
 162              }
 163          }
 164  
 165          return false;
 166      }
 167  
 168      /**
 169      * Capture and return the attributes of an XML element
 170      *
 171      * NOTE: XML character entities are left as-is
 172      *
 173      * @param  string $xml Element in XML form
 174      * @return array       Dictionary of [attrName => attrValue]
 175      */
 176  	protected function matchAttributes($xml)
 177      {
 178          if (strpos($xml, '="') === false)
 179          {
 180              return [];
 181          }
 182  
 183          // Match all name-value pairs until the first right bracket
 184          preg_match_all('(([^ =]++)="([^"]*))S', substr($xml, 0, strpos($xml, '>')), $m);
 185  
 186          return array_combine($m[1], $m[2]);
 187      }
 188  
 189      /**
 190      * Render an intermediate representation using the Quick renderer
 191      *
 192      * @param  string $xml Intermediate representation
 193      * @return string
 194      */
 195  	protected function renderQuick($xml)
 196      {
 197          $this->attributes = [];
 198          $xml = $this->decodeSMP($xml);
 199          $html = preg_replace_callback(
 200              $this->quickRegexp,
 201              [$this, 'renderQuickCallback'],
 202              substr($xml, 1 + strpos($xml, '>'), -4)
 203          );
 204  
 205          return str_replace('<br/>', '<br>', $html);
 206      }
 207  
 208      /**
 209      * Render a string matched by the Quick renderer
 210      *
 211      * This stub should be overwritten by generated renderers
 212      *
 213      * @param  string[] $m
 214      * @return string
 215      */
 216  	protected function renderQuickCallback(array $m)
 217      {
 218          if (isset($m[3]))
 219          {
 220              return $this->renderQuickSelfClosingTag($m);
 221          }
 222  
 223          if (isset($m[2]))
 224          {
 225              // Single tag
 226              $id = $m[2];
 227          }
 228          else
 229          {
 230              // Tag pair
 231              $id = $m[1];
 232              $this->checkTagPairContent($id, $m[0]);
 233          }
 234  
 235          if (isset($this->static[$id]))
 236          {
 237              return $this->static[$id];
 238          }
 239          if (isset($this->dynamic[$id]))
 240          {
 241              return preg_replace($this->dynamic[$id][0], $this->dynamic[$id][1], $m[0], 1);
 242          }
 243  
 244          return $this->renderQuickTemplate($id, $m[0]);
 245      }
 246  
 247      /**
 248      * Render a self-closing tag using the Quick renderer
 249      *
 250      * @param  string[] $m
 251      * @return string
 252      */
 253  	protected function renderQuickSelfClosingTag(array $m)
 254      {
 255          unset($m[3]);
 256  
 257          $m[0] = substr($m[0], 0, -2) . '>';
 258          $html = $this->renderQuickCallback($m);
 259  
 260          $m[0] = '</' . $m[2] . '>';
 261          $m[2] = '/' . $m[2];
 262          $html .= $this->renderQuickCallback($m);
 263  
 264          return $html;
 265      }
 266  
 267      /**
 268      * Render a string matched by the Quick renderer using a generated PHP template
 269      *
 270      * This stub should be overwritten by generated renderers
 271      *
 272      * @param  integer $id  Tag's ID (tag name optionally preceded by a slash)
 273      * @param  string  $xml Tag's XML or tag pair's XML including their content
 274      * @return string       Rendered template
 275      */
 276  	protected function renderQuickTemplate($id, $xml)
 277      {
 278          throw new RuntimeException('Not implemented');
 279      }
 280  
 281      /**
 282      * {@inheritdoc}
 283      */
 284  	protected function renderRichText($xml)
 285      {
 286          $this->setLocale();
 287  
 288          try
 289          {
 290              if ($this->canQuickRender($xml))
 291              {
 292                  $html = $this->renderQuick($xml);
 293                  $this->restoreLocale();
 294  
 295                  return $html;
 296              }
 297          }
 298          catch (RuntimeException $e)
 299          {
 300              // Do nothing
 301          }
 302  
 303          $dom         = $this->loadXML($xml);
 304          $this->out   = '';
 305          $this->xpath = new DOMXPath($dom);
 306          $this->at($dom->documentElement);
 307          $html        = $this->out;
 308          $this->reset();
 309          $this->restoreLocale();
 310  
 311          return $html;
 312      }
 313  
 314      /**
 315      * Reset object properties that are populated during rendering
 316      *
 317      * @return void
 318      */
 319  	protected function reset()
 320      {
 321          unset($this->attributes);
 322          unset($this->out);
 323          unset($this->xpath);
 324      }
 325  }


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