Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

lexer.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 10.16 KiB


 001  <?php
 002  /**
 003  *
 004  * This file is part of the phpBB Forum Software package.
 005  *
 006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 007  * @license GNU General Public License, version 2 (GPL-2.0)
 008  *
 009  * For full copyright and license information, please see
 010  * the docs/CREDITS.txt file.
 011  *
 012  */
 013   
 014  namespace phpbb\template\twig;
 015   
 016  class lexer extends \Twig_Lexer
 017  {
 018      public function tokenize($code, $filename = null)
 019      {
 020          // Our phpBB tags
 021          // Commented out tokens are handled separately from the main replace
 022          $phpbb_tags = array(
 023              /*'BEGIN',
 024              'BEGINELSE',
 025              'END',
 026              'IF',
 027              'ELSE',
 028              'ELSEIF',
 029              'ENDIF',
 030              'DEFINE',
 031              'UNDEFINE',*/
 032              'ENDDEFINE',
 033              'INCLUDE',
 034              'INCLUDEPHP',
 035              'INCLUDEJS',
 036              'INCLUDECSS',
 037              'PHP',
 038              'ENDPHP',
 039              'EVENT',
 040          );
 041   
 042          // Twig tag masks
 043          $twig_tags = array(
 044              'autoescape',
 045              'endautoescape',
 046              'if',
 047              'elseif',
 048              'else',
 049              'endif',
 050              'block',
 051              'endblock',
 052              'use',
 053              'extends',
 054              'embed',
 055              'filter',
 056              'endfilter',
 057              'flush',
 058              'for',
 059              'endfor',
 060              'macro',
 061              'endmacro',
 062              'import',
 063              'from',
 064              'sandbox',
 065              'endsandbox',
 066              'set',
 067              'endset',
 068              'spaceless',
 069              'endspaceless',
 070              'verbatim',
 071              'endverbatim',
 072          );
 073   
 074          // Fix tokens that may have inline variables (e.g. <!-- DEFINE $TEST = '{FOO}')
 075          $code = $this->strip_surrounding_quotes(array(
 076              'INCLUDE',
 077              'INCLUDEPHP',
 078              'INCLUDEJS',
 079              'INCLUDECSS',
 080          ), $code);
 081          $code = $this->fix_inline_variable_tokens(array(
 082              'DEFINE \$[a-zA-Z0-9_]+ =',
 083              'INCLUDE',
 084              'INCLUDEPHP',
 085              'INCLUDEJS',
 086              'INCLUDECSS',
 087          ), $code);
 088          $code = $this->add_surrounding_quotes(array(
 089              'INCLUDE',
 090              'INCLUDEPHP',
 091              'INCLUDEJS',
 092              'INCLUDECSS',
 093          ), $code);
 094   
 095          // Fix our BEGIN statements
 096          $code = $this->fix_begin_tokens($code);
 097   
 098          // Fix our IF tokens
 099          $code = $this->fix_if_tokens($code);
 100   
 101          // Fix our DEFINE tokens
 102          $code = $this->fix_define_tokens($code);
 103   
 104          // Replace all of our starting tokens, <!-- TOKEN --> with Twig style, {% TOKEN %}
 105          // This also strips outer parenthesis, <!-- IF (blah) --> becomes <!-- IF blah -->
 106          $code = preg_replace('#<!-- (' . implode('|', $phpbb_tags) . ')(?: (.*?) ?)?-->#', '{% $1 $2 %}', $code);
 107   
 108          // Replace all of our twig masks with Twig code (e.g. <!-- BLOCK .+ --> with {% block $1 %})
 109          $code = $this->replace_twig_tag_masks($code, $twig_tags);
 110   
 111          // Replace all of our language variables, {L_VARNAME}, with Twig style, {{ lang('NAME') }}
 112          // Appends any filters after lang()
 113          $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2 }}', $code);
 114   
 115          // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }}
 116          // Appends any filters after lang(), but before addslashes
 117          $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2|addslashes }}', $code);
 118   
 119          // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }}
 120          // Appends any filters
 121          $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ $1$2 }}', $code);
 122   
 123          return parent::tokenize($code, $filename);
 124      }
 125   
 126      /**
 127      * Strip surrounding quotes
 128      *
 129      * First step to fix tokens that may have inline variables
 130      * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE {TEST}.html
 131      *
 132      * @param array $tokens array of tokens to search for (imploded to a regular expression)
 133      * @param string $code
 134      * @return string
 135      */
 136      protected function strip_surrounding_quotes($tokens, $code)
 137      {
 138          // Remove matching quotes at the beginning/end if a statement;
 139          // E.g. 'asdf'"' -> asdf'"
 140          // E.g. "asdf'"" -> asdf'"
 141          // E.g. 'asdf'" -> 'asdf'"
 142          return preg_replace('#<!-- (' . implode('|', $tokens) . ') (([\'"])?(.*?)\1) -->#', '<!-- $1 $2 -->', $code);
 143      }
 144   
 145      /**
 146      * Fix tokens that may have inline variables
 147      *
 148      * Second step to fix tokens that may have inline variables
 149      * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE ' ~ {TEST} ~ '.html
 150      *
 151      * @param array $tokens array of tokens to search for (imploded to a regular expression)
 152      * @param string $code
 153      * @return string
 154      */
 155      protected function fix_inline_variable_tokens($tokens, $code)
 156      {
 157          $callback = function($matches)
 158          {
 159              // Replace template variables with start/end to parse variables (' ~ TEST ~ '.html)
 160              $matches[2] = preg_replace('#{([a-zA-Z0-9_\.$]+)}#', "'~ \$1 ~'", $matches[2]);
 161   
 162              return "<!-- {$matches[1]} {$matches[2]} -->";
 163          };
 164   
 165          return preg_replace_callback('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', $callback, $code);
 166      }
 167   
 168      /**
 169      * Add surrounding quotes
 170      *
 171      * Last step to fix tokens that may have inline variables
 172      * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE '' ~ {TEST} ~ '.html'
 173      *
 174      * @param array $tokens array of tokens to search for (imploded to a regular expression)
 175      * @param string $code
 176      * @return string
 177      */
 178      protected function add_surrounding_quotes($tokens, $code)
 179      {
 180          return preg_replace('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', '<!-- $1 \'$2\' -->', $code);
 181      }
 182   
 183      /**
 184      * Fix begin tokens (convert our BEGIN to Twig for)
 185      *
 186      * Not meant to be used outside of this context, public because the anonymous function calls this
 187      *
 188      * @param string $code
 189      * @param array $parent_nodes (used in recursion)
 190      * @return string
 191      */
 192      public function fix_begin_tokens($code, $parent_nodes = array())
 193      {
 194          // PHP 5.3 cannot use $this in an anonymous function, so use this as a work-around
 195          $parent_class = $this;
 196          $callback = function ($matches) use ($parent_class, $parent_nodes)
 197          {
 198              $hard_parents = explode('.', $matches[1]);
 199              array_pop($hard_parents); // ends with .
 200              if ($hard_parents)
 201              {
 202                  $parent_nodes = array_merge($hard_parents, $parent_nodes);
 203              }
 204   
 205              $name = $matches[2];
 206              $subset = trim(substr($matches[3], 1, -1)); // Remove parenthesis
 207              $body = $matches[4];
 208   
 209              // Replace <!-- BEGINELSE -->
 210              $body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body);
 211   
 212              // Is the designer wanting to call another loop in a loop?
 213              // <!-- BEGIN loop -->
 214              // <!-- BEGIN !loop2 -->
 215              // <!-- END !loop2 -->
 216              // <!-- END loop -->
 217              // 'loop2' is actually on the same nesting level as 'loop' you assign
 218              // variables to it with template->assign_block_vars('loop2', array(...))
 219              if (strpos($name, '!') === 0)
 220              {
 221                  // Count the number if ! occurrences
 222                  $count = substr_count($name, '!');
 223                  for ($i = 0; $i < $count; $i++)
 224                  {
 225                      array_pop($parent_nodes);
 226                      $name = substr($name, 1);
 227                  }
 228              }
 229   
 230              // Remove all parent nodes, e.g. foo, bar from foo.bar.foobar.VAR
 231              foreach ($parent_nodes as $node)
 232              {
 233                  $body = preg_replace('#([^a-zA-Z0-9_])' . $node . '\.([a-zA-Z0-9_]+)\.#', '$1$2.', $body);
 234              }
 235   
 236              // Add current node to list of parent nodes for child nodes
 237              $parent_nodes[] = $name;
 238   
 239              // Recursive...fix any child nodes
 240              $body = $parent_class->fix_begin_tokens($body, $parent_nodes);
 241   
 242              // Need the parent variable name
 243              array_pop($parent_nodes);
 244              $parent = (!empty($parent_nodes)) ? end($parent_nodes) . '.' : '';
 245   
 246              if ($subset !== '')
 247              {
 248                  $subset = '|subset(' . $subset . ')';
 249              }
 250   
 251              $parent = ($parent) ?: 'loops.';
 252              // Turn into a Twig for loop
 253              return "{% for {$name} in {$parent}{$name}{$subset} %}{$body}{% endfor %}";
 254          };
 255   
 256          return preg_replace_callback('#<!-- BEGIN ((?:[a-zA-Z0-9_]+\.)*)([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1\2 -->#s', $callback, $code);
 257      }
 258   
 259      /**
 260      * Fix IF statements
 261      *
 262      * @param string $code
 263      * @return string
 264      */
 265      protected function fix_if_tokens($code)
 266      {
 267          // Replace ELSE IF with ELSEIF
 268          $code = preg_replace('#<!-- ELSE IF (.+?) -->#', '<!-- ELSEIF $1 -->', $code);
 269   
 270          // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces)
 271          $code = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $code);
 272   
 273          $callback = function($matches)
 274          {
 275              $inner = $matches[2];
 276              // Replace $TEST with definition.TEST
 277              $inner = preg_replace('#(\s\(*!?)\$([a-zA-Z_0-9]+)#', '$1definition.$2', $inner);
 278   
 279              // Replace .foo with loops.foo|length
 280              $inner = preg_replace('#(\s\(*!?)\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', '$1loops.$2|length$3', $inner);
 281   
 282              // Replace .foo.bar with foo.bar|length
 283              $inner = preg_replace('#(\s\(*!?)\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', '$1$2|length$3', $inner);
 284   
 285              return "<!-- {$matches[1]}IF{$inner}-->";
 286          };
 287   
 288          return preg_replace_callback('#<!-- (ELSE)?IF((.*?) (?:\(*!?[\$|\.]([^\s]+)(.*?))?)-->#', $callback, $code);
 289      }
 290   
 291      /**
 292      * Fix DEFINE statements and {$VARNAME} variables
 293      *
 294      * @param string $code
 295      * @return string
 296      */
 297      protected function fix_define_tokens($code)
 298      {
 299          /**
 300          * Changing $VARNAME to definition.varname because set is only local
 301          * context (e.g. DEFINE $TEST will only make $TEST available in current
 302          * template and any child templates, but not any parent templates).
 303          *
 304          * DEFINE handles setting it properly to definition in its node, but the
 305          * variables reading FROM it need to be altered to definition.VARNAME
 306          *
 307          * Setting up definition as a class in the array passed to Twig
 308          * ($context) makes set definition.TEST available in the global context
 309          */
 310   
 311          // Replace <!-- DEFINE $NAME with {% DEFINE definition.NAME
 312          $code = preg_replace('#<!-- DEFINE \$(.*?) -->#', '{% DEFINE $1 %}', $code);
 313   
 314          // Changing UNDEFINE NAME to DEFINE NAME = null to save from creating an extra token parser/node
 315          $code = preg_replace('#<!-- UNDEFINE \$(.*?)-->#', '{% DEFINE $1= null %}', $code);
 316   
 317          // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }}
 318          $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code);
 319   
 320          // Replace all of our variables, ~ $VARNAME ~, with Twig style, ~ definition.VARNAME ~
 321          $code = preg_replace('#~ \$([a-zA-Z0-9_\.]+) ~#', '~ definition.$1 ~', $code);
 322   
 323          return $code;
 324      }
 325   
 326      /**
 327      * Replace Twig tag masks with Twig tag calls
 328      *
 329      * E.g. <!-- BLOCK foo --> with {% block foo %}
 330      *
 331      * @param string $code
 332      * @param array $twig_tags All tags we want to create a mask for
 333      * @return string
 334      */
 335      protected function replace_twig_tag_masks($code, $twig_tags)
 336      {
 337          $callback = function ($matches)
 338          {
 339              $matches[1] = strtolower($matches[1]);
 340   
 341              return "{% {$matches[1]}{$matches[2]}%}";
 342          };
 343   
 344          foreach ($twig_tags as &$tag)
 345          {
 346              $tag = strtoupper($tag);
 347          }
 348   
 349          // twig_tags is an array of the twig tags, which are all lowercase, but we use all uppercase tags
 350          $code = preg_replace_callback('#<!-- (' . implode('|', $twig_tags) . ')(.*?)-->#',$callback, $code);
 351   
 352          return $code;
 353      }
 354  }
 355