vendor/symfony/debug/Exception/FlattenException.php line 26

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\Component\Debug\Exception;
  11. use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
  12. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  13. /**
  14.  * FlattenException wraps a PHP Error or Exception to be able to serialize it.
  15.  *
  16.  * Basically, this class removes all objects from the trace.
  17.  *
  18.  * @author Fabien Potencier <fabien@symfony.com>
  19.  *
  20.  * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\FlattenException instead.
  21.  */
  22. class FlattenException
  23. {
  24.     private $message;
  25.     private $code;
  26.     private $previous;
  27.     private $trace;
  28.     private $traceAsString;
  29.     private $class;
  30.     private $statusCode;
  31.     private $headers;
  32.     private $file;
  33.     private $line;
  34.     /**
  35.      * @return static
  36.      */
  37.     public static function create(\Exception $exception$statusCode null, array $headers = [])
  38.     {
  39.         return static::createFromThrowable($exception$statusCode$headers);
  40.     }
  41.     /**
  42.      * @return static
  43.      */
  44.     public static function createFromThrowable(\Throwable $exceptionint $statusCode null, array $headers = [])
  45.     {
  46.         $e = new static();
  47.         $e->setMessage($exception->getMessage());
  48.         $e->setCode($exception->getCode());
  49.         if ($exception instanceof HttpExceptionInterface) {
  50.             $statusCode $exception->getStatusCode();
  51.             $headers array_merge($headers$exception->getHeaders());
  52.         } elseif ($exception instanceof RequestExceptionInterface) {
  53.             $statusCode 400;
  54.         }
  55.         if (null === $statusCode) {
  56.             $statusCode 500;
  57.         }
  58.         $e->setStatusCode($statusCode);
  59.         $e->setHeaders($headers);
  60.         $e->setTraceFromThrowable($exception);
  61.         $e->setClass($exception instanceof FatalThrowableError $exception->getOriginalClassName() : \get_class($exception));
  62.         $e->setFile($exception->getFile());
  63.         $e->setLine($exception->getLine());
  64.         $previous $exception->getPrevious();
  65.         if ($previous instanceof \Throwable) {
  66.             $e->setPrevious(static::createFromThrowable($previous));
  67.         }
  68.         return $e;
  69.     }
  70.     public function toArray()
  71.     {
  72.         $exceptions = [];
  73.         foreach (array_merge([$this], $this->getAllPrevious()) as $exception) {
  74.             $exceptions[] = [
  75.                 'message' => $exception->getMessage(),
  76.                 'class' => $exception->getClass(),
  77.                 'trace' => $exception->getTrace(),
  78.             ];
  79.         }
  80.         return $exceptions;
  81.     }
  82.     public function getStatusCode()
  83.     {
  84.         return $this->statusCode;
  85.     }
  86.     /**
  87.      * @return $this
  88.      */
  89.     public function setStatusCode($code)
  90.     {
  91.         $this->statusCode $code;
  92.         return $this;
  93.     }
  94.     public function getHeaders()
  95.     {
  96.         return $this->headers;
  97.     }
  98.     /**
  99.      * @return $this
  100.      */
  101.     public function setHeaders(array $headers)
  102.     {
  103.         $this->headers $headers;
  104.         return $this;
  105.     }
  106.     public function getClass()
  107.     {
  108.         return $this->class;
  109.     }
  110.     /**
  111.      * @return $this
  112.      */
  113.     public function setClass($class)
  114.     {
  115.         $this->class 'c' === $class[0] && === strpos($class"class@anonymous\0") ? get_parent_class($class).'@anonymous' $class;
  116.         return $this;
  117.     }
  118.     public function getFile()
  119.     {
  120.         return $this->file;
  121.     }
  122.     /**
  123.      * @return $this
  124.      */
  125.     public function setFile($file)
  126.     {
  127.         $this->file $file;
  128.         return $this;
  129.     }
  130.     public function getLine()
  131.     {
  132.         return $this->line;
  133.     }
  134.     /**
  135.      * @return $this
  136.      */
  137.     public function setLine($line)
  138.     {
  139.         $this->line $line;
  140.         return $this;
  141.     }
  142.     public function getMessage()
  143.     {
  144.         return $this->message;
  145.     }
  146.     /**
  147.      * @return $this
  148.      */
  149.     public function setMessage($message)
  150.     {
  151.         if (false !== strpos($message"class@anonymous\0")) {
  152.             $message preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
  153.                 return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' $m[0];
  154.             }, $message);
  155.         }
  156.         $this->message $message;
  157.         return $this;
  158.     }
  159.     public function getCode()
  160.     {
  161.         return $this->code;
  162.     }
  163.     /**
  164.      * @return $this
  165.      */
  166.     public function setCode($code)
  167.     {
  168.         $this->code $code;
  169.         return $this;
  170.     }
  171.     public function getPrevious()
  172.     {
  173.         return $this->previous;
  174.     }
  175.     /**
  176.      * @return $this
  177.      */
  178.     public function setPrevious(self $previous)
  179.     {
  180.         $this->previous $previous;
  181.         return $this;
  182.     }
  183.     public function getAllPrevious()
  184.     {
  185.         $exceptions = [];
  186.         $e $this;
  187.         while ($e $e->getPrevious()) {
  188.             $exceptions[] = $e;
  189.         }
  190.         return $exceptions;
  191.     }
  192.     public function getTrace()
  193.     {
  194.         return $this->trace;
  195.     }
  196.     /**
  197.      * @deprecated since 4.1, use {@see setTraceFromThrowable()} instead.
  198.      */
  199.     public function setTraceFromException(\Exception $exception)
  200.     {
  201.         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.'__METHOD__), E_USER_DEPRECATED);
  202.         $this->setTraceFromThrowable($exception);
  203.     }
  204.     public function setTraceFromThrowable(\Throwable $throwable)
  205.     {
  206.         $this->traceAsString $throwable->getTraceAsString();
  207.         return $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine());
  208.     }
  209.     /**
  210.      * @return $this
  211.      */
  212.     public function setTrace($trace$file$line)
  213.     {
  214.         $this->trace = [];
  215.         $this->trace[] = [
  216.             'namespace' => '',
  217.             'short_class' => '',
  218.             'class' => '',
  219.             'type' => '',
  220.             'function' => '',
  221.             'file' => $file,
  222.             'line' => $line,
  223.             'args' => [],
  224.         ];
  225.         foreach ($trace as $entry) {
  226.             $class '';
  227.             $namespace '';
  228.             if (isset($entry['class'])) {
  229.                 $parts explode('\\'$entry['class']);
  230.                 $class array_pop($parts);
  231.                 $namespace implode('\\'$parts);
  232.             }
  233.             $this->trace[] = [
  234.                 'namespace' => $namespace,
  235.                 'short_class' => $class,
  236.                 'class' => isset($entry['class']) ? $entry['class'] : '',
  237.                 'type' => isset($entry['type']) ? $entry['type'] : '',
  238.                 'function' => isset($entry['function']) ? $entry['function'] : null,
  239.                 'file' => isset($entry['file']) ? $entry['file'] : null,
  240.                 'line' => isset($entry['line']) ? $entry['line'] : null,
  241.                 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [],
  242.             ];
  243.         }
  244.         return $this;
  245.     }
  246.     private function flattenArgs(array $argsint $level 0int &$count 0): array
  247.     {
  248.         $result = [];
  249.         foreach ($args as $key => $value) {
  250.             if (++$count 1e4) {
  251.                 return ['array''*SKIPPED over 10000 entries*'];
  252.             }
  253.             if ($value instanceof \__PHP_Incomplete_Class) {
  254.                 // is_object() returns false on PHP<=7.1
  255.                 $result[$key] = ['incomplete-object'$this->getClassNameFromIncomplete($value)];
  256.             } elseif (\is_object($value)) {
  257.                 $result[$key] = ['object', \get_class($value)];
  258.             } elseif (\is_array($value)) {
  259.                 if ($level 10) {
  260.                     $result[$key] = ['array''*DEEP NESTED ARRAY*'];
  261.                 } else {
  262.                     $result[$key] = ['array'$this->flattenArgs($value$level 1$count)];
  263.                 }
  264.             } elseif (null === $value) {
  265.                 $result[$key] = ['null'null];
  266.             } elseif (\is_bool($value)) {
  267.                 $result[$key] = ['boolean'$value];
  268.             } elseif (\is_int($value)) {
  269.                 $result[$key] = ['integer'$value];
  270.             } elseif (\is_float($value)) {
  271.                 $result[$key] = ['float'$value];
  272.             } elseif (\is_resource($value)) {
  273.                 $result[$key] = ['resource'get_resource_type($value)];
  274.             } else {
  275.                 $result[$key] = ['string', (string) $value];
  276.             }
  277.         }
  278.         return $result;
  279.     }
  280.     private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value): string
  281.     {
  282.         $array = new \ArrayObject($value);
  283.         return $array['__PHP_Incomplete_Class_Name'];
  284.     }
  285.     public function getTraceAsString()
  286.     {
  287.         return $this->traceAsString;
  288.     }
  289.     public function getAsString()
  290.     {
  291.         $message '';
  292.         $next false;
  293.         foreach (array_reverse(array_merge([$this], $this->getAllPrevious())) as $exception) {
  294.             if ($next) {
  295.                 $message .= 'Next ';
  296.             } else {
  297.                 $next true;
  298.             }
  299.             $message .= $exception->getClass();
  300.             if ('' != $exception->getMessage()) {
  301.                 $message .= ': '.$exception->getMessage();
  302.             }
  303.             $message .= ' in '.$exception->getFile().':'.$exception->getLine().
  304.                 "\nStack trace:\n".$exception->getTraceAsString()."\n\n";
  305.         }
  306.         return rtrim($message);
  307.     }
  308. }