vendor/symfony/twig-bridge/DataCollector/TwigDataCollector.php line 88

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\DataCollector;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpKernel\DataCollector\DataCollector;
  14. use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
  15. use Twig\Environment;
  16. use Twig\Error\LoaderError;
  17. use Twig\Markup;
  18. use Twig\Profiler\Dumper\HtmlDumper;
  19. use Twig\Profiler\Profile;
  20. /**
  21.  * TwigDataCollector.
  22.  *
  23.  * @author Fabien Potencier <fabien@symfony.com>
  24.  *
  25.  * @final since Symfony 4.4
  26.  */
  27. class TwigDataCollector extends DataCollector implements LateDataCollectorInterface
  28. {
  29.     private $profile;
  30.     private $twig;
  31.     private $computed;
  32.     public function __construct(Profile $profileEnvironment $twig null)
  33.     {
  34.         $this->profile $profile;
  35.         $this->twig $twig;
  36.     }
  37.     /**
  38.      * {@inheritdoc}
  39.      *
  40.      * @param \Throwable|null $exception
  41.      */
  42.     public function collect(Request $requestResponse $response/*, \Throwable $exception = null*/)
  43.     {
  44.     }
  45.     /**
  46.      * {@inheritdoc}
  47.      */
  48.     public function reset()
  49.     {
  50.         $this->profile->reset();
  51.         $this->computed null;
  52.         $this->data = [];
  53.     }
  54.     /**
  55.      * {@inheritdoc}
  56.      */
  57.     public function lateCollect()
  58.     {
  59.         $this->data['profile'] = serialize($this->profile);
  60.         $this->data['template_paths'] = [];
  61.         if (null === $this->twig) {
  62.             return;
  63.         }
  64.         $templateFinder = function (Profile $profile) use (&$templateFinder) {
  65.             if ($profile->isTemplate()) {
  66.                 try {
  67.                     $template $this->twig->load($name $profile->getName());
  68.                 } catch (LoaderError $e) {
  69.                     $template null;
  70.                 }
  71.                 if (null !== $template && '' !== $path $template->getSourceContext()->getPath()) {
  72.                     $this->data['template_paths'][$name] = $path;
  73.                 }
  74.             }
  75.             foreach ($profile as $p) {
  76.                 $templateFinder($p);
  77.             }
  78.         };
  79.         $templateFinder($this->profile);
  80.     }
  81.     public function getTime()
  82.     {
  83.         return $this->getProfile()->getDuration() * 1000;
  84.     }
  85.     public function getTemplateCount()
  86.     {
  87.         return $this->getComputedData('template_count');
  88.     }
  89.     public function getTemplatePaths()
  90.     {
  91.         return $this->data['template_paths'];
  92.     }
  93.     public function getTemplates()
  94.     {
  95.         return $this->getComputedData('templates');
  96.     }
  97.     public function getBlockCount()
  98.     {
  99.         return $this->getComputedData('block_count');
  100.     }
  101.     public function getMacroCount()
  102.     {
  103.         return $this->getComputedData('macro_count');
  104.     }
  105.     public function getHtmlCallGraph()
  106.     {
  107.         $dumper = new HtmlDumper();
  108.         $dump $dumper->dump($this->getProfile());
  109.         // needed to remove the hardcoded CSS styles
  110.         $dump str_replace([
  111.             '<span style="background-color: #ffd">',
  112.             '<span style="color: #d44">',
  113.             '<span style="background-color: #dfd">',
  114.             '<span style="background-color: #ddf">',
  115.         ], [
  116.             '<span class="status-warning">',
  117.             '<span class="status-error">',
  118.             '<span class="status-success">',
  119.             '<span class="status-info">',
  120.         ], $dump);
  121.         return new Markup($dump'UTF-8');
  122.     }
  123.     public function getProfile()
  124.     {
  125.         if (null === $this->profile) {
  126.             $this->profile unserialize($this->data['profile'], ['allowed_classes' => ['Twig_Profiler_Profile''Twig\Profiler\Profile']]);
  127.         }
  128.         return $this->profile;
  129.     }
  130.     private function getComputedData(string $index)
  131.     {
  132.         if (null === $this->computed) {
  133.             $this->computed $this->computeData($this->getProfile());
  134.         }
  135.         return $this->computed[$index];
  136.     }
  137.     private function computeData(Profile $profile)
  138.     {
  139.         $data = [
  140.             'template_count' => 0,
  141.             'block_count' => 0,
  142.             'macro_count' => 0,
  143.         ];
  144.         $templates = [];
  145.         foreach ($profile as $p) {
  146.             $d $this->computeData($p);
  147.             $data['template_count'] += ($p->isTemplate() ? 0) + $d['template_count'];
  148.             $data['block_count'] += ($p->isBlock() ? 0) + $d['block_count'];
  149.             $data['macro_count'] += ($p->isMacro() ? 0) + $d['macro_count'];
  150.             if ($p->isTemplate()) {
  151.                 if (!isset($templates[$p->getTemplate()])) {
  152.                     $templates[$p->getTemplate()] = 1;
  153.                 } else {
  154.                     ++$templates[$p->getTemplate()];
  155.                 }
  156.             }
  157.             foreach ($d['templates'] as $template => $count) {
  158.                 if (!isset($templates[$template])) {
  159.                     $templates[$template] = $count;
  160.                 } else {
  161.                     $templates[$template] += $count;
  162.                 }
  163.             }
  164.         }
  165.         $data['templates'] = $templates;
  166.         return $data;
  167.     }
  168.     /**
  169.      * {@inheritdoc}
  170.      */
  171.     public function getName()
  172.     {
  173.         return 'twig';
  174.     }
  175. }