Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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

CodeExtension.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 9.13 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Bridge\Twig\Extension;
013   
014  use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
015  use Twig\Extension\AbstractExtension;
016  use Twig\TwigFilter;
017   
018  /**
019   * Twig extension relate to PHP code and used by the profiler and the default exception templates.
020   *
021   * @author Fabien Potencier <fabien@symfony.com>
022   */
023  class CodeExtension extends AbstractExtension
024  {
025      private $fileLinkFormat;
026      private $rootDir;
027      private $charset;
028   
029      /**
030       * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
031       * @param string                   $rootDir        The project root directory
032       * @param string                   $charset        The charset
033       */
034      public function __construct($fileLinkFormat, $rootDir, $charset)
035      {
036          $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
037          $this->rootDir = str_replace('/', \DIRECTORY_SEPARATOR, \dirname($rootDir)).\DIRECTORY_SEPARATOR;
038          $this->charset = $charset;
039      }
040   
041      /**
042       * {@inheritdoc}
043       */
044      public function getFilters()
045      {
046          return [
047              new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]),
048              new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html']]),
049              new TwigFilter('format_args', [$this, 'formatArgs'], ['is_safe' => ['html']]),
050              new TwigFilter('format_args_as_text', [$this, 'formatArgsAsText']),
051              new TwigFilter('file_excerpt', [$this, 'fileExcerpt'], ['is_safe' => ['html']]),
052              new TwigFilter('format_file', [$this, 'formatFile'], ['is_safe' => ['html']]),
053              new TwigFilter('format_file_from_text', [$this, 'formatFileFromText'], ['is_safe' => ['html']]),
054              new TwigFilter('format_log_message', [$this, 'formatLogMessage'], ['is_safe' => ['html']]),
055              new TwigFilter('file_link', [$this, 'getFileLink']),
056          ];
057      }
058   
059      public function abbrClass($class)
060      {
061          $parts = explode('\\', $class);
062          $short = array_pop($parts);
063   
064          return sprintf('<abbr title="%s">%s</abbr>', $class, $short);
065      }
066   
067      public function abbrMethod($method)
068      {
069          if (false !== strpos($method, '::')) {
070              list($class, $method) = explode('::', $method, 2);
071              $result = sprintf('%s::%s()', $this->abbrClass($class), $method);
072          } elseif ('Closure' === $method) {
073              $result = sprintf('<abbr title="%s">%1$s</abbr>', $method);
074          } else {
075              $result = sprintf('<abbr title="%s">%1$s</abbr>()', $method);
076          }
077   
078          return $result;
079      }
080   
081      /**
082       * Formats an array as a string.
083       *
084       * @param array $args The argument array
085       *
086       * @return string
087       */
088      public function formatArgs($args)
089      {
090          $result = [];
091          foreach ($args as $key => $item) {
092              if ('object' === $item[0]) {
093                  $parts = explode('\\', $item[1]);
094                  $short = array_pop($parts);
095                  $formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
096              } elseif ('array' === $item[0]) {
097                  $formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
098              } elseif ('null' === $item[0]) {
099                  $formattedValue = '<em>null</em>';
100              } elseif ('boolean' === $item[0]) {
101                  $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
102              } elseif ('resource' === $item[0]) {
103                  $formattedValue = '<em>resource</em>';
104              } else {
105                  $formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset));
106              }
107   
108              $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
109          }
110   
111          return implode(', ', $result);
112      }
113   
114      /**
115       * Formats an array as a string.
116       *
117       * @param array $args The argument array
118       *
119       * @return string
120       */
121      public function formatArgsAsText($args)
122      {
123          return strip_tags($this->formatArgs($args));
124      }
125   
126      /**
127       * Returns an excerpt of a code file around the given line number.
128       *
129       * @param string $file       A file path
130       * @param int    $line       The selected line number
131       * @param int    $srcContext The number of displayed lines around or -1 for the whole file
132       *
133       * @return string An HTML string
134       */
135      public function fileExcerpt($file, $line, $srcContext = 3)
136      {
137          if (is_file($file) && is_readable($file)) {
138              // highlight_file could throw warnings
139              // see https://bugs.php.net/25725
140              $code = @highlight_file($file, true);
141              // remove main code/span tags
142              $code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code);
143              // split multiline spans
144              $code = preg_replace_callback('#<span ([^>]++)>((?:[^<]*+<br \/>)++[^<]*+)</span>#', function ($m) {
145                  return "<span $m[1]>".str_replace('<br />', "</span><br /><span $m[1]>", $m[2]).'</span>';
146              }, $code);
147              $content = explode('<br />', $code);
148   
149              $lines = [];
150              if (0 > $srcContext) {
151                  $srcContext = \count($content);
152              }
153   
154              for ($i = max($line - $srcContext, 1), $max = min($line + $srcContext, \count($content)); $i <= $max; ++$i) {
155                  $lines[] = '<li'.($i == $line ? ' class="selected"' : '').'><a class="anchor" name="line'.$i.'"></a><code>'.self::fixCodeMarkup($content[$i - 1]).'</code></li>';
156              }
157   
158              return '<ol start="'.max($line - $srcContext, 1).'">'.implode("\n", $lines).'</ol>';
159          }
160   
161          return null;
162      }
163   
164      /**
165       * Formats a file path.
166       *
167       * @param string $file An absolute file path
168       * @param int    $line The line number
169       * @param string $text Use this text for the link rather than the file path
170       *
171       * @return string
172       */
173      public function formatFile($file, $line, $text = null)
174      {
175          $file = trim($file);
176   
177          if (null === $text) {
178              $text = str_replace('/', \DIRECTORY_SEPARATOR, $file);
179              if (0 === strpos($text, $this->rootDir)) {
180                  $text = substr($text, \strlen($this->rootDir));
181                  $text = explode(\DIRECTORY_SEPARATOR, $text, 2);
182                  $text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', $this->rootDir, $text[0], isset($text[1]) ? \DIRECTORY_SEPARATOR.$text[1] : '');
183              }
184          }
185   
186          if (0 < $line) {
187              $text .= ' at line '.$line;
188          }
189   
190          if (false !== $link = $this->getFileLink($file, $line)) {
191              return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $text);
192          }
193   
194          return $text;
195      }
196   
197      /**
198       * Returns the link for a given file/line pair.
199       *
200       * @param string $file An absolute file path
201       * @param int    $line The line number
202       *
203       * @return string|false A link or false
204       */
205      public function getFileLink($file, $line)
206      {
207          if ($fmt = $this->fileLinkFormat) {
208              return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line);
209          }
210   
211          return false;
212      }
213   
214      public function formatFileFromText($text)
215      {
216          return preg_replace_callback('/in ("|&quot;)?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
217              return 'in '.$this->formatFile($match[2], $match[3]);
218          }, $text);
219      }
220   
221      /**
222       * @internal
223       */
224      public function formatLogMessage($message, array $context)
225      {
226          if ($context && false !== strpos($message, '{')) {
227              $replacements = [];
228              foreach ($context as $key => $val) {
229                  if (is_scalar($val)) {
230                      $replacements['{'.$key.'}'] = $val;
231                  }
232              }
233   
234              if ($replacements) {
235                  $message = strtr($message, $replacements);
236              }
237          }
238   
239          return htmlspecialchars($message, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset);
240      }
241   
242      /**
243       * {@inheritdoc}
244       */
245      public function getName()
246      {
247          return 'code';
248      }
249   
250      protected static function fixCodeMarkup($line)
251      {
252          // </span> ending tag from previous line
253          $opening = strpos($line, '<span');
254          $closing = strpos($line, '</span>');
255          if (false !== $closing && (false === $opening || $closing < $opening)) {
256              $line = substr_replace($line, '', $closing, 7);
257          }
258   
259          // missing </span> tag at the end of line
260          $opening = strpos($line, '<span');
261          $closing = strpos($line, '</span>');
262          if (false !== $opening && (false === $closing || $closing > $opening)) {
263              $line .= '</span>';
264          }
265   
266          return trim($line);
267      }
268  }
269