Deprecated: Constant E_STRICT is deprecated in /home/pastorz/old-espace-client/vendor/symfony/error-handler/ErrorHandler.php on line 58

Deprecated: Constant E_STRICT is deprecated in /home/pastorz/old-espace-client/vendor/symfony/error-handler/ErrorHandler.php on line 76
Symfony Profiler

vendor/symfony/twig-bridge/Extension/CodeExtension.php line 164

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bridge\Twig\Extension;
  11. use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
  12. use Twig\Extension\AbstractExtension;
  13. use Twig\TwigFilter;
  14. /**
  15.  * Twig extension relate to PHP code and used by the profiler and the default exception templates.
  16.  *
  17.  * @author Fabien Potencier <fabien@symfony.com>
  18.  */
  19. final class CodeExtension extends AbstractExtension
  20. {
  21.     private $fileLinkFormat;
  22.     private $charset;
  23.     private $projectDir;
  24.     /**
  25.      * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
  26.      */
  27.     public function __construct($fileLinkFormatstring $projectDirstring $charset)
  28.     {
  29.         $this->fileLinkFormat $fileLinkFormat ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
  30.         $this->projectDir str_replace('\\''/'$projectDir).'/';
  31.         $this->charset $charset;
  32.     }
  33.     /**
  34.      * {@inheritdoc}
  35.      */
  36.     public function getFilters(): array
  37.     {
  38.         return [
  39.             new TwigFilter('abbr_class', [$this'abbrClass'], ['is_safe' => ['html']]),
  40.             new TwigFilter('abbr_method', [$this'abbrMethod'], ['is_safe' => ['html']]),
  41.             new TwigFilter('format_args', [$this'formatArgs'], ['is_safe' => ['html']]),
  42.             new TwigFilter('format_args_as_text', [$this'formatArgsAsText']),
  43.             new TwigFilter('file_excerpt', [$this'fileExcerpt'], ['is_safe' => ['html']]),
  44.             new TwigFilter('format_file', [$this'formatFile'], ['is_safe' => ['html']]),
  45.             new TwigFilter('format_file_from_text', [$this'formatFileFromText'], ['is_safe' => ['html']]),
  46.             new TwigFilter('format_log_message', [$this'formatLogMessage'], ['is_safe' => ['html']]),
  47.             new TwigFilter('file_link', [$this'getFileLink']),
  48.             new TwigFilter('file_relative', [$this'getFileRelative']),
  49.         ];
  50.     }
  51.     public function abbrClass(string $class): string
  52.     {
  53.         $parts explode('\\'$class);
  54.         $short array_pop($parts);
  55.         return sprintf('<abbr title="%s">%s</abbr>'$class$short);
  56.     }
  57.     public function abbrMethod(string $method): string
  58.     {
  59.         if (str_contains($method'::')) {
  60.             [$class$method] = explode('::'$method2);
  61.             $result sprintf('%s::%s()'$this->abbrClass($class), $method);
  62.         } elseif ('Closure' === $method) {
  63.             $result sprintf('<abbr title="%s">%1$s</abbr>'$method);
  64.         } else {
  65.             $result sprintf('<abbr title="%s">%1$s</abbr>()'$method);
  66.         }
  67.         return $result;
  68.     }
  69.     /**
  70.      * Formats an array as a string.
  71.      */
  72.     public function formatArgs(array $args): string
  73.     {
  74.         $result = [];
  75.         foreach ($args as $key => $item) {
  76.             if ('object' === $item[0]) {
  77.                 $parts explode('\\'$item[1]);
  78.                 $short array_pop($parts);
  79.                 $formattedValue sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)'$item[1], $short);
  80.             } elseif ('array' === $item[0]) {
  81.                 $formattedValue sprintf('<em>array</em>(%s)'\is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
  82.             } elseif ('null' === $item[0]) {
  83.                 $formattedValue '<em>null</em>';
  84.             } elseif ('boolean' === $item[0]) {
  85.                 $formattedValue '<em>'.strtolower(var_export($item[1], true)).'</em>';
  86.             } elseif ('resource' === $item[0]) {
  87.                 $formattedValue '<em>resource</em>';
  88.             } else {
  89.                 $formattedValue str_replace("\n"''htmlspecialchars(var_export($item[1], true), \ENT_COMPAT \ENT_SUBSTITUTE$this->charset));
  90.             }
  91.             $result[] = \is_int($key) ? $formattedValue sprintf("'%s' => %s"$key$formattedValue);
  92.         }
  93.         return implode(', '$result);
  94.     }
  95.     /**
  96.      * Formats an array as a string.
  97.      */
  98.     public function formatArgsAsText(array $args): string
  99.     {
  100.         return strip_tags($this->formatArgs($args));
  101.     }
  102.     /**
  103.      * Returns an excerpt of a code file around the given line number.
  104.      */
  105.     public function fileExcerpt(string $fileint $lineint $srcContext 3): ?string
  106.     {
  107.         if (is_file($file) && is_readable($file)) {
  108.             // highlight_file could throw warnings
  109.             // see https://bugs.php.net/25725
  110.             $code = @highlight_file($filetrue);
  111.             if (\PHP_VERSION_ID >= 80300) {
  112.                 // remove main pre/code tags
  113.                 $code preg_replace('#^<pre.*?>\s*<code.*?>(.*)</code>\s*</pre>#s''\\1'$code);
  114.                 // split multiline code tags
  115.                 $code preg_replace_callback('#<code ([^>]++)>((?:[^<]*+\\n)++[^<]*+)</code>#', function ($m) {
  116.                     return "<code $m[1]>".str_replace("\n""</code>\n<code $m[1]>"$m[2]).'</code>';
  117.                 }, $code);
  118.                 // Convert spaces to html entities to preserve indentation when rendered
  119.                 $code str_replace(' ''&nbsp;'$code);
  120.                 $content explode("\n"$code);
  121.             } else {
  122.                 // remove main code/span tags
  123.                 $code preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s''\\1'$code);
  124.                 // split multiline spans
  125.                 $code preg_replace_callback('#<span ([^>]++)>((?:[^<]*+<br \/>)++[^<]*+)</span>#', function ($m) {
  126.                     return "<span $m[1]>".str_replace('<br />'"</span><br /><span $m[1]>"$m[2]).'</span>';
  127.                 }, $code);
  128.                 $content explode('<br />'$code);
  129.             }
  130.             $lines = [];
  131.             if ($srcContext) {
  132.                 $srcContext \count($content);
  133.             }
  134.             for ($i max($line $srcContext1), $max min($line $srcContext\count($content)); $i <= $max; ++$i) {
  135.                 $lines[] = '<li'.($i == $line ' class="selected"' '').'><a class="anchor" id="line'.$i.'"></a><code>'.self::fixCodeMarkup($content[$i 1]).'</code></li>';
  136.             }
  137.             return '<ol start="'.max($line $srcContext1).'">'.implode("\n"$lines).'</ol>';
  138.         }
  139.         return null;
  140.     }
  141.     /**
  142.      * Formats a file path.
  143.      */
  144.     public function formatFile(string $fileint $linestring $text null): string
  145.     {
  146.         $file trim($file);
  147.         if (null === $text) {
  148.             $text $file;
  149.             if (null !== $rel $this->getFileRelative($text)) {
  150.                 $rel explode('/'$rel2);
  151.                 $text sprintf('<abbr title="%s%2$s">%s</abbr>%s'$this->projectDir$rel[0], '/'.($rel[1] ?? ''));
  152.             }
  153.         }
  154.         if ($line) {
  155.             $text .= ' at line '.$line;
  156.         }
  157.         if (false !== $link $this->getFileLink($file$line)) {
  158.             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);
  159.         }
  160.         return $text;
  161.     }
  162.     /**
  163.      * Returns the link for a given file/line pair.
  164.      *
  165.      * @return string|false
  166.      */
  167.     public function getFileLink(string $fileint $line)
  168.     {
  169.         if ($fmt $this->fileLinkFormat) {
  170.             return \is_string($fmt) ? strtr($fmt, ['%f' => $file'%l' => $line]) : $fmt->format($file$line);
  171.         }
  172.         return false;
  173.     }
  174.     public function getFileRelative(string $file): ?string
  175.     {
  176.         $file str_replace('\\''/'$file);
  177.         if (null !== $this->projectDir && str_starts_with($file$this->projectDir)) {
  178.             return ltrim(substr($file\strlen($this->projectDir)), '/');
  179.         }
  180.         return null;
  181.     }
  182.     public function formatFileFromText(string $text): string
  183.     {
  184.         return preg_replace_callback('/in ("|&quot;)?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
  185.             return 'in '.$this->formatFile($match[2], $match[3]);
  186.         }, $text);
  187.     }
  188.     /**
  189.      * @internal
  190.      */
  191.     public function formatLogMessage(string $message, array $context): string
  192.     {
  193.         if ($context && str_contains($message'{')) {
  194.             $replacements = [];
  195.             foreach ($context as $key => $val) {
  196.                 if (\is_scalar($val)) {
  197.                     $replacements['{'.$key.'}'] = $val;
  198.                 }
  199.             }
  200.             if ($replacements) {
  201.                 $message strtr($message$replacements);
  202.             }
  203.         }
  204.         return htmlspecialchars($message\ENT_COMPAT \ENT_SUBSTITUTE$this->charset);
  205.     }
  206.     protected static function fixCodeMarkup(string $line): string
  207.     {
  208.         // </span> ending tag from previous line
  209.         $opening strpos($line'<span');
  210.         $closing strpos($line'</span>');
  211.         if (false !== $closing && (false === $opening || $closing $opening)) {
  212.             $line substr_replace($line''$closing7);
  213.         }
  214.         // missing </span> tag at the end of line
  215.         $opening strpos($line'<span');
  216.         $closing strpos($line'</span>');
  217.         if (false !== $opening && (false === $closing || $closing $opening)) {
  218.             $line .= '</span>';
  219.         }
  220.         return trim($line);
  221.     }
  222. }