vendor/symfony/serializer/DataCollector/SerializerDataCollector.php line 36

  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\Component\Serializer\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 Symfony\Component\Serializer\Debug\TraceableSerializer;
  16. use Symfony\Component\VarDumper\Cloner\Data;
  17. /**
  18.  * @author Mathias Arlaud <mathias.arlaud@gmail.com>
  19.  *
  20.  * @internal
  21.  */
  22. class SerializerDataCollector extends DataCollector implements LateDataCollectorInterface
  23. {
  24.     private array $collected = [];
  25.     public function reset(): void
  26.     {
  27.         $this->data = [];
  28.         $this->collected = [];
  29.     }
  30.     public function collect(Request $requestResponse $response\Throwable $exception null): void
  31.     {
  32.         // Everything is collected during the request, and formatted on kernel terminate.
  33.     }
  34.     public function getName(): string
  35.     {
  36.         return 'serializer';
  37.     }
  38.     public function getData(): Data|array
  39.     {
  40.         return $this->data;
  41.     }
  42.     public function getHandledCount(): int
  43.     {
  44.         return array_sum(array_map('count'$this->data));
  45.     }
  46.     public function getTotalTime(): float
  47.     {
  48.         $totalTime 0;
  49.         foreach ($this->data as $handled) {
  50.             $totalTime += array_sum(array_map(fn (array $el): float => $el['time'], $handled));
  51.         }
  52.         return $totalTime;
  53.     }
  54.     public function collectSerialize(string $traceIdmixed $datastring $format, array $contextfloat $time, array $caller): void
  55.     {
  56.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  57.         $this->collected[$traceId] = array_merge(
  58.             $this->collected[$traceId] ?? [],
  59.             compact('data''format''context''time''caller'),
  60.             ['method' => 'serialize'],
  61.         );
  62.     }
  63.     public function collectDeserialize(string $traceIdmixed $datastring $typestring $format, array $contextfloat $time, array $caller): void
  64.     {
  65.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  66.         $this->collected[$traceId] = array_merge(
  67.             $this->collected[$traceId] ?? [],
  68.             compact('data''format''type''context''time''caller'),
  69.             ['method' => 'deserialize'],
  70.         );
  71.     }
  72.     public function collectNormalize(string $traceIdmixed $data, ?string $format, array $contextfloat $time, array $caller): void
  73.     {
  74.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  75.         $this->collected[$traceId] = array_merge(
  76.             $this->collected[$traceId] ?? [],
  77.             compact('data''format''context''time''caller'),
  78.             ['method' => 'normalize'],
  79.         );
  80.     }
  81.     public function collectDenormalize(string $traceIdmixed $datastring $type, ?string $format, array $contextfloat $time, array $caller): void
  82.     {
  83.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  84.         $this->collected[$traceId] = array_merge(
  85.             $this->collected[$traceId] ?? [],
  86.             compact('data''format''type''context''time''caller'),
  87.             ['method' => 'denormalize'],
  88.         );
  89.     }
  90.     public function collectEncode(string $traceIdmixed $data, ?string $format, array $contextfloat $time, array $caller): void
  91.     {
  92.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  93.         $this->collected[$traceId] = array_merge(
  94.             $this->collected[$traceId] ?? [],
  95.             compact('data''format''context''time''caller'),
  96.             ['method' => 'encode'],
  97.         );
  98.     }
  99.     public function collectDecode(string $traceIdmixed $data, ?string $format, array $contextfloat $time, array $caller): void
  100.     {
  101.         unset($context[TraceableSerializer::DEBUG_TRACE_ID]);
  102.         $this->collected[$traceId] = array_merge(
  103.             $this->collected[$traceId] ?? [],
  104.             compact('data''format''context''time''caller'),
  105.             ['method' => 'decode'],
  106.         );
  107.     }
  108.     public function collectNormalization(string $traceIdstring $normalizerfloat $time): void
  109.     {
  110.         $method 'normalize';
  111.         $this->collected[$traceId]['normalization'][] = compact('normalizer''method''time');
  112.     }
  113.     public function collectDenormalization(string $traceIdstring $normalizerfloat $time): void
  114.     {
  115.         $method 'denormalize';
  116.         $this->collected[$traceId]['normalization'][] = compact('normalizer''method''time');
  117.     }
  118.     public function collectEncoding(string $traceIdstring $encoderfloat $time): void
  119.     {
  120.         $method 'encode';
  121.         $this->collected[$traceId]['encoding'][] = compact('encoder''method''time');
  122.     }
  123.     public function collectDecoding(string $traceIdstring $encoderfloat $time): void
  124.     {
  125.         $method 'decode';
  126.         $this->collected[$traceId]['encoding'][] = compact('encoder''method''time');
  127.     }
  128.     public function lateCollect(): void
  129.     {
  130.         $this->data = [
  131.             'serialize' => [],
  132.             'deserialize' => [],
  133.             'normalize' => [],
  134.             'denormalize' => [],
  135.             'encode' => [],
  136.             'decode' => [],
  137.         ];
  138.         foreach ($this->collected as $collected) {
  139.             if (!isset($collected['data'])) {
  140.                 continue;
  141.             }
  142.             $data = [
  143.                 'data' => $this->cloneVar($collected['data']),
  144.                 'dataType' => get_debug_type($collected['data']),
  145.                 'type' => $collected['type'] ?? null,
  146.                 'format' => $collected['format'],
  147.                 'time' => $collected['time'],
  148.                 'context' => $this->cloneVar($collected['context']),
  149.                 'normalization' => [],
  150.                 'encoding' => [],
  151.                 'caller' => $collected['caller'] ?? null,
  152.             ];
  153.             if (isset($collected['normalization'])) {
  154.                 $mainNormalization array_pop($collected['normalization']);
  155.                 $data['normalizer'] = ['time' => $mainNormalization['time']] + $this->getMethodLocation($mainNormalization['normalizer'], $mainNormalization['method']);
  156.                 foreach ($collected['normalization'] as $normalization) {
  157.                     if (!isset($data['normalization'][$normalization['normalizer']])) {
  158.                         $data['normalization'][$normalization['normalizer']] = ['time' => 0'calls' => 0] + $this->getMethodLocation($normalization['normalizer'], $normalization['method']);
  159.                     }
  160.                     ++$data['normalization'][$normalization['normalizer']]['calls'];
  161.                     $data['normalization'][$normalization['normalizer']]['time'] += $normalization['time'];
  162.                 }
  163.             }
  164.             if (isset($collected['encoding'])) {
  165.                 $mainEncoding array_pop($collected['encoding']);
  166.                 $data['encoder'] = ['time' => $mainEncoding['time']] + $this->getMethodLocation($mainEncoding['encoder'], $mainEncoding['method']);
  167.                 foreach ($collected['encoding'] as $encoding) {
  168.                     if (!isset($data['encoding'][$encoding['encoder']])) {
  169.                         $data['encoding'][$encoding['encoder']] = ['time' => 0'calls' => 0] + $this->getMethodLocation($encoding['encoder'], $encoding['method']);
  170.                     }
  171.                     ++$data['encoding'][$encoding['encoder']]['calls'];
  172.                     $data['encoding'][$encoding['encoder']]['time'] += $encoding['time'];
  173.                 }
  174.             }
  175.             $this->data[$collected['method']][] = $data;
  176.         }
  177.     }
  178.     private function getMethodLocation(string $classstring $method): array
  179.     {
  180.         $reflection = new \ReflectionClass($class);
  181.         return [
  182.             'class' => $reflection->getShortName(),
  183.             'file' => $reflection->getFileName(),
  184.             'line' => $reflection->getMethod($method)->getStartLine(),
  185.         ];
  186.     }
  187. }