[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/http-kernel/DataCollector/ -> DumpDataCollector.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\HttpKernel\DataCollector;
  13  
  14  use Symfony\Component\HttpFoundation\Request;
  15  use Symfony\Component\HttpFoundation\RequestStack;
  16  use Symfony\Component\HttpFoundation\Response;
  17  use Symfony\Component\Stopwatch\Stopwatch;
  18  use Symfony\Component\VarDumper\Cloner\Data;
  19  use Symfony\Component\VarDumper\Cloner\VarCloner;
  20  use Symfony\Component\VarDumper\Dumper\CliDumper;
  21  use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
  22  use Symfony\Component\VarDumper\Dumper\HtmlDumper;
  23  use Twig\Template;
  24  
  25  /**
  26   * @author Nicolas Grekas <p@tchwork.com>
  27   */
  28  class DumpDataCollector extends DataCollector implements DataDumperInterface
  29  {
  30      private $stopwatch;
  31      private $fileLinkFormat;
  32      private $dataCount = 0;
  33      private $isCollected = true;
  34      private $clonesCount = 0;
  35      private $clonesIndex = 0;
  36      private $rootRefs;
  37      private $charset;
  38      private $requestStack;
  39      private $dumper;
  40      private $dumperIsInjected;
  41  
  42      public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, $charset = null, RequestStack $requestStack = null, DataDumperInterface $dumper = null)
  43      {
  44          $this->stopwatch = $stopwatch;
  45          $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
  46          $this->charset = $charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8';
  47          $this->requestStack = $requestStack;
  48          $this->dumper = $dumper;
  49          $this->dumperIsInjected = null !== $dumper;
  50  
  51          // All clones share these properties by reference:
  52          $this->rootRefs = array(
  53              &$this->data,
  54              &$this->dataCount,
  55              &$this->isCollected,
  56              &$this->clonesCount,
  57          );
  58      }
  59  
  60      public function __clone()
  61      {
  62          $this->clonesIndex = ++$this->clonesCount;
  63      }
  64  
  65      public function dump(Data $data)
  66      {
  67          if ($this->stopwatch) {
  68              $this->stopwatch->start('dump');
  69          }
  70          if ($this->isCollected && !$this->dumper) {
  71              $this->isCollected = false;
  72          }
  73  
  74          $trace = DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS;
  75          if (\PHP_VERSION_ID >= 50400) {
  76              $trace = debug_backtrace($trace, 7);
  77          } else {
  78              $trace = debug_backtrace($trace);
  79          }
  80  
  81          $file = $trace[0]['file'];
  82          $line = $trace[0]['line'];
  83          $name = false;
  84          $fileExcerpt = false;
  85  
  86          for ($i = 1; $i < 7; ++$i) {
  87              if (isset($trace[$i]['class'], $trace[$i]['function'])
  88                  && 'dump' === $trace[$i]['function']
  89                  && 'Symfony\Component\VarDumper\VarDumper' === $trace[$i]['class']
  90              ) {
  91                  $file = $trace[$i]['file'];
  92                  $line = $trace[$i]['line'];
  93  
  94                  while (++$i < 7) {
  95                      if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && 0 !== strpos($trace[$i]['function'], 'call_user_func')) {
  96                          $file = $trace[$i]['file'];
  97                          $line = $trace[$i]['line'];
  98  
  99                          break;
 100                      } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof Template) {
 101                          $template = $trace[$i]['object'];
 102                          $name = $template->getTemplateName();
 103                          $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false);
 104                          $info = $template->getDebugInfo();
 105                          if (isset($info[$trace[$i - 1]['line']])) {
 106                              $line = $info[$trace[$i - 1]['line']];
 107                              $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : null;
 108  
 109                              if ($src) {
 110                                  $src = explode("\n", $src);
 111                                  $fileExcerpt = array();
 112  
 113                                  for ($i = max($line - 3, 1), $max = min($line + 3, \count($src)); $i <= $max; ++$i) {
 114                                      $fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.$this->htmlEncode($src[$i - 1]).'</code></li>';
 115                                  }
 116  
 117                                  $fileExcerpt = '<ol start="'.max($line - 3, 1).'">'.implode("\n", $fileExcerpt).'</ol>';
 118                              }
 119                          }
 120                          break;
 121                      }
 122                  }
 123                  break;
 124              }
 125          }
 126  
 127          if (false === $name) {
 128              $name = str_replace('\\', '/', $file);
 129              $name = substr($name, strrpos($name, '/') + 1);
 130          }
 131  
 132          if ($this->dumper) {
 133              $this->doDump($data, $name, $file, $line);
 134          }
 135  
 136          $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
 137          ++$this->dataCount;
 138  
 139          if ($this->stopwatch) {
 140              $this->stopwatch->stop('dump');
 141          }
 142      }
 143  
 144      public function collect(Request $request, Response $response, \Exception $exception = null)
 145      {
 146          // Sub-requests and programmatic calls stay in the collected profile.
 147          if ($this->dumper || ($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) {
 148              return;
 149          }
 150  
 151          // In all other conditions that remove the web debug toolbar, dumps are written on the output.
 152          if (!$this->requestStack
 153              || !$response->headers->has('X-Debug-Token')
 154              || $response->isRedirection()
 155              || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html'))
 156              || 'html' !== $request->getRequestFormat()
 157              || false === strripos($response->getContent(), '</body>')
 158          ) {
 159              if ($response->headers->has('Content-Type') && false !== strpos($response->headers->get('Content-Type'), 'html')) {
 160                  $this->dumper = new HtmlDumper('php://output', $this->charset);
 161              } else {
 162                  $this->dumper = new CliDumper('php://output', $this->charset);
 163              }
 164  
 165              foreach ($this->data as $dump) {
 166                  $this->doDump($dump['data'], $dump['name'], $dump['file'], $dump['line']);
 167              }
 168          }
 169      }
 170  
 171      public function serialize()
 172      {
 173          if ($this->clonesCount !== $this->clonesIndex) {
 174              return 'a:0:{}';
 175          }
 176  
 177          $this->data[] = $this->fileLinkFormat;
 178          $this->data[] = $this->charset;
 179          $ser = serialize($this->data);
 180          $this->data = array();
 181          $this->dataCount = 0;
 182          $this->isCollected = true;
 183          if (!$this->dumperIsInjected) {
 184              $this->dumper = null;
 185          }
 186  
 187          return $ser;
 188      }
 189  
 190      public function unserialize($data)
 191      {
 192          parent::unserialize($data);
 193          $charset = array_pop($this->data);
 194          $fileLinkFormat = array_pop($this->data);
 195          $this->dataCount = \count($this->data);
 196          self::__construct($this->stopwatch, $fileLinkFormat, $charset);
 197      }
 198  
 199      public function getDumpsCount()
 200      {
 201          return $this->dataCount;
 202      }
 203  
 204      public function getDumps($format, $maxDepthLimit = -1, $maxItemsPerDepth = -1)
 205      {
 206          $data = fopen('php://memory', 'r+b');
 207  
 208          if ('html' === $format) {
 209              $dumper = new HtmlDumper($data, $this->charset);
 210          } else {
 211              throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format));
 212          }
 213          $dumps = array();
 214  
 215          foreach ($this->data as $dump) {
 216              if (method_exists($dump['data'], 'withMaxDepth')) {
 217                  $dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth));
 218              } else {
 219                  // getLimitedClone is @deprecated, to be removed in 3.0
 220                  $dumper->dump($dump['data']->getLimitedClone($maxDepthLimit, $maxItemsPerDepth));
 221              }
 222              $dump['data'] = stream_get_contents($data, -1, 0);
 223              ftruncate($data, 0);
 224              rewind($data);
 225              $dumps[] = $dump;
 226          }
 227  
 228          return $dumps;
 229      }
 230  
 231      public function getName()
 232      {
 233          return 'dump';
 234      }
 235  
 236      public function __destruct()
 237      {
 238          if (0 === $this->clonesCount-- && !$this->isCollected && $this->data) {
 239              $this->clonesCount = 0;
 240              $this->isCollected = true;
 241  
 242              $h = headers_list();
 243              $i = \count($h);
 244              array_unshift($h, 'Content-Type: '.ini_get('default_mimetype'));
 245              while (0 !== stripos($h[$i], 'Content-Type:')) {
 246                  --$i;
 247              }
 248  
 249              if (!\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true) && stripos($h[$i], 'html')) {
 250                  $this->dumper = new HtmlDumper('php://output', $this->charset);
 251              } else {
 252                  $this->dumper = new CliDumper('php://output', $this->charset);
 253              }
 254  
 255              foreach ($this->data as $i => $dump) {
 256                  $this->data[$i] = null;
 257                  $this->doDump($dump['data'], $dump['name'], $dump['file'], $dump['line']);
 258              }
 259  
 260              $this->data = array();
 261              $this->dataCount = 0;
 262          }
 263      }
 264  
 265      private function doDump($data, $name, $file, $line)
 266      {
 267          if (\PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) {
 268              $contextDumper = function ($name, $file, $line, $fileLinkFormat) {
 269                  if ($this instanceof HtmlDumper) {
 270                      if ($file) {
 271                          $s = $this->style('meta', '%s');
 272                          $name = strip_tags($this->style('', $name));
 273                          $file = strip_tags($this->style('', $file));
 274                          if ($fileLinkFormat) {
 275                              $link = strtr(strip_tags($this->style('', $fileLinkFormat)), array('%f' => $file, '%l' => (int) $line));
 276                              $name = sprintf('<a href="%s" title="%s">'.$s.'</a>', $link, $file, $name);
 277                          } else {
 278                              $name = sprintf('<abbr title="%s">'.$s.'</abbr>', $file, $name);
 279                          }
 280                      } else {
 281                          $name = $this->style('meta', $name);
 282                      }
 283                      $this->line = $name.' on line '.$this->style('meta', $line).':';
 284                  } else {
 285                      $this->line = $this->style('meta', $name).' on line '.$this->style('meta', $line).':';
 286                  }
 287                  $this->dumpLine(0);
 288              };
 289              $contextDumper = $contextDumper->bindTo($this->dumper, $this->dumper);
 290              $contextDumper($name, $file, $line, $this->fileLinkFormat);
 291          } else {
 292              $cloner = new VarCloner();
 293              $this->dumper->dump($cloner->cloneVar($name.' on line '.$line.':'));
 294          }
 295          $this->dumper->dump($data);
 296      }
 297  
 298      private function htmlEncode($s)
 299      {
 300          $html = '';
 301  
 302          $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset);
 303          $dumper->setDumpHeader('');
 304          $dumper->setDumpBoundaries('', '');
 305  
 306          $cloner = new VarCloner();
 307          $dumper->dump($cloner->cloneVar($s));
 308  
 309          return substr(strip_tags($html), 1, -1);
 310      }
 311  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1