Deprecated: Constant E_STRICT is deprecated in /home/normanv/www/annuairepro/vendor/symfony/error-handler/ErrorHandler.php on line 58

Deprecated: Constant E_STRICT is deprecated in /home/normanv/www/annuairepro/vendor/symfony/error-handler/ErrorHandler.php on line 76
Symfony Profiler

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

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'], 'pre_escape' => 'html']),
  40.             new TwigFilter('abbr_method', [$this'abbrMethod'], ['is_safe' => ['html'], 'pre_escape' => '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.                 $item[1] = htmlspecialchars($item[1], \ENT_COMPAT \ENT_SUBSTITUTE$this->charset);
  78.                 $parts explode('\\'$item[1]);
  79.                 $short array_pop($parts);
  80.                 $formattedValue sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)'$item[1], $short);
  81.             } elseif ('array' === $item[0]) {
  82.                 $formattedValue sprintf('<em>array</em>(%s)'\is_array($item[1]) ? $this->formatArgs($item[1]) : htmlspecialchars(var_export($item[1], true), \ENT_COMPAT \ENT_SUBSTITUTE$this->charset));
  83.             } elseif ('null' === $item[0]) {
  84.                 $formattedValue '<em>null</em>';
  85.             } elseif ('boolean' === $item[0]) {
  86.                 $formattedValue '<em>'.strtolower(htmlspecialchars(var_export($item[1], true), \ENT_COMPAT \ENT_SUBSTITUTE$this->charset)).'</em>';
  87.             } elseif ('resource' === $item[0]) {
  88.                 $formattedValue '<em>resource</em>';
  89.             } else {
  90.                 $formattedValue str_replace("\n"''htmlspecialchars(var_export($item[1], true), \ENT_COMPAT \ENT_SUBSTITUTE$this->charset));
  91.             }
  92.             $result[] = \is_int($key) ? $formattedValue sprintf("'%s' => %s"htmlspecialchars($key\ENT_COMPAT \ENT_SUBSTITUTE$this->charset), $formattedValue);
  93.         }
  94.         return implode(', '$result);
  95.     }
  96.     /**
  97.      * Formats an array as a string.
  98.      */
  99.     public function formatArgsAsText(array $args): string
  100.     {
  101.         return strip_tags($this->formatArgs($args));
  102.     }
  103.     /**
  104.      * Returns an excerpt of a code file around the given line number.
  105.      */
  106.     public function fileExcerpt(string $fileint $lineint $srcContext 3): ?string
  107.     {
  108.         if (is_file($file) && is_readable($file)) {
  109.             // highlight_file could throw warnings
  110.             // see https://bugs.php.net/25725
  111.             $code = @highlight_file($filetrue);
  112.             if (\PHP_VERSION_ID >= 80300) {
  113.                 // remove main pre/code tags
  114.                 $code preg_replace('#^<pre.*?>\s*<code.*?>(.*)</code>\s*</pre>#s''\\1'$code);
  115.                 // split multiline code tags
  116.                 $code preg_replace_callback('#<code ([^>]++)>((?:[^<]*+\\n)++[^<]*+)</code>#', function ($m) {
  117.                     return "<code $m[1]>".str_replace("\n""</code>\n<code $m[1]>"$m[2]).'</code>';
  118.                 }, $code);
  119.                 // Convert spaces to html entities to preserve indentation when rendered
  120.                 $code str_replace(' ''&nbsp;'$code);
  121.                 $content explode("\n"$code);
  122.             } else {
  123.                 // remove main code/span tags
  124.                 $code preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s''\\1'$code);
  125.                 // split multiline spans
  126.                 $code preg_replace_callback('#<span ([^>]++)>((?:[^<]*+<br \/>)++[^<]*+)</span>#', function ($m) {
  127.                     return "<span $m[1]>".str_replace('<br />'"</span><br /><span $m[1]>"$m[2]).'</span>';
  128.                 }, $code);
  129.                 $content explode('<br />'$code);
  130.             }
  131.             $lines = [];
  132.             if ($srcContext) {
  133.                 $srcContext \count($content);
  134.             }
  135.             for ($i max($line $srcContext1), $max min($line $srcContext\count($content)); $i <= $max; ++$i) {
  136.                 $lines[] = '<li'.($i == $line ' class="selected"' '').'><a class="anchor" id="line'.$i.'"></a><code>'.self::fixCodeMarkup($content[$i 1]).'</code></li>';
  137.             }
  138.             return '<ol start="'.max($line $srcContext1).'">'.implode("\n"$lines).'</ol>';
  139.         }
  140.         return null;
  141.     }
  142.     /**
  143.      * Formats a file path.
  144.      */
  145.     public function formatFile(string $fileint $linestring $text null): string
  146.     {
  147.         $file trim($file);
  148.         if (null === $text) {
  149.             if (null !== $rel $this->getFileRelative($file)) {
  150.                 $rel explode('/'htmlspecialchars($rel\ENT_COMPAT \ENT_SUBSTITUTE$this->charset), 2);
  151.                 $text sprintf('<abbr title="%s%2$s">%s</abbr>%s'htmlspecialchars($this->projectDir\ENT_COMPAT \ENT_SUBSTITUTE$this->charset), $rel[0], '/'.($rel[1] ?? ''));
  152.             } else {
  153.                 $text htmlspecialchars($file\ENT_COMPAT \ENT_SUBSTITUTE$this->charset);
  154.             }
  155.         } else {
  156.             $text htmlspecialchars($text\ENT_COMPAT \ENT_SUBSTITUTE$this->charset);
  157.         }
  158.         if ($line) {
  159.             $text .= ' at line '.$line;
  160.         }
  161.         if (false !== $link $this->getFileLink($file$line)) {
  162.             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);
  163.         }
  164.         return $text;
  165.     }
  166.     /**
  167.      * Returns the link for a given file/line pair.
  168.      *
  169.      * @return string|false
  170.      */
  171.     public function getFileLink(string $fileint $line)
  172.     {
  173.         if ($fmt $this->fileLinkFormat) {
  174.             return \is_string($fmt) ? strtr($fmt, ['%f' => $file'%l' => $line]) : $fmt->format($file$line);
  175.         }
  176.         return false;
  177.     }
  178.     public function getFileRelative(string $file): ?string
  179.     {
  180.         $file str_replace('\\''/'$file);
  181.         if (null !== $this->projectDir && str_starts_with($file$this->projectDir)) {
  182.             return ltrim(substr($file\strlen($this->projectDir)), '/');
  183.         }
  184.         return null;
  185.     }
  186.     public function formatFileFromText(string $text): string
  187.     {
  188.         return preg_replace_callback('/in ("|&quot;)?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
  189.             return 'in '.$this->formatFile($match[2], $match[3]);
  190.         }, $text);
  191.     }
  192.     /**
  193.      * @internal
  194.      */
  195.     public function formatLogMessage(string $message, array $context): string
  196.     {
  197.         if ($context && str_contains($message'{')) {
  198.             $replacements = [];
  199.             foreach ($context as $key => $val) {
  200.                 if (\is_scalar($val)) {
  201.                     $replacements['{'.$key.'}'] = $val;
  202.                 }
  203.             }
  204.             if ($replacements) {
  205.                 $message strtr($message$replacements);
  206.             }
  207.         }
  208.         return htmlspecialchars($message\ENT_COMPAT \ENT_SUBSTITUTE$this->charset);
  209.     }
  210.     protected static function fixCodeMarkup(string $line): string
  211.     {
  212.         // </span> ending tag from previous line
  213.         $opening strpos($line'<span');
  214.         $closing strpos($line'</span>');
  215.         if (false !== $closing && (false === $opening || $closing $opening)) {
  216.             $line substr_replace($line''$closing7);
  217.         }
  218.         // missing </span> tag at the end of line
  219.         $opening strpos($line'<span');
  220.         $closing strpos($line'</span>');
  221.         if (false !== $opening && (false === $closing || $closing $opening)) {
  222.             $line .= '</span>';
  223.         }
  224.         return trim($line);
  225.     }
  226. }