‪TYPO3CMS  11.5
DebuggerUtility.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
32 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
33 
41 {
42  public const ‪PLAINTEXT_INDENT = ' ';
43  public const ‪HTML_INDENT = '&nbsp;&nbsp;&nbsp;';
44 
48  protected static ‪$renderedObjects;
49 
55  protected static ‪$blacklistedClassNames = [
56  'PHPUnit_Framework_MockObject_InvocationMocker',
57  ReflectionService::class,
58  // @deprecated since v11, will be removed in v12.
59  ObjectManager::class,
60  DataMapper::class,
61  PersistenceManager::class,
62  QueryObjectModelFactory::class,
63  ContentObjectRenderer::class,
64  ];
65 
71  protected static ‪$blacklistedPropertyNames = ['warning'];
72 
78  protected static ‪$stylesheetEchoed = false;
79 
85  protected static ‪$maxDepth = 8;
86 
90  protected static function ‪clearState(): void
91  {
92  self::$renderedObjects = new ‪ObjectStorage();
93  }
94 
104  protected static function ‪renderDump($value, int $level, bool $plainText, bool $ansiColors): string
105  {
106  $dump = '';
107  if (is_string($value)) {
108  $croppedValue = strlen($value) > 2000 ? substr($value, 0, 2000) . '...' : $value;
109  if ($plainText) {
110  $dump = ‪self::ansiEscapeWrap('"' . implode(PHP_EOL . str_repeat(self::PLAINTEXT_INDENT, $level + 1), str_split($croppedValue, 76)) . '"', '33', $ansiColors) . ' (' . strlen($value) . ' chars)';
111  } else {
112  $lines = str_split($croppedValue, 76);
113  $lines = array_map(static function (string $line): string {
114  return htmlspecialchars($line, ENT_COMPAT);
115  }, $lines);
116  $dump = sprintf('\'<span class="extbase-debug-string">%s</span>\' (%s chars)', implode('<br />' . str_repeat(self::HTML_INDENT, $level + 1), $lines), strlen($value));
117  }
118  } elseif (is_numeric($value)) {
119  $dump = sprintf('%s (%s)', self::ansiEscapeWrap((string)$value, '35', $ansiColors), gettype($value));
120  } elseif (is_bool($value)) {
121  $dump = $value ? ‪self::ansiEscapeWrap('TRUE', '32', $ansiColors) : self::‪ansiEscapeWrap('FALSE', '32', $ansiColors);
122  } elseif ($value === null || is_resource($value)) {
123  $dump = gettype($value);
124  } elseif (is_array($value)) {
125  $dump = ‪self::renderArray($value, $level + 1, $plainText, $ansiColors);
126  } elseif (is_object($value)) {
127  if ($value instanceof \Closure) {
128  $dump = ‪self::renderClosure($value, $level + 1, $plainText, $ansiColors);
129  } else {
130  $dump = ‪self::renderObject($value, $level + 1, $plainText, $ansiColors);
131  }
132  }
133  return $dump;
134  }
135 
145  protected static function ‪renderArray(array $array, int $level, bool $plainText = false, bool $ansiColors = false): string
146  {
147  $content = '';
148  $count = count($array);
149 
150  if ($plainText) {
151  $header = ‪self::ansiEscapeWrap('array', '36', $ansiColors);
152  } else {
153  $header = '<span class="extbase-debug-type">array</span>';
154  }
155  $header .= $count > 0 ? '(' . $count . ' item' . ($count > 1 ? 's' : '') . ')' : '(empty)';
156  if ($level >= self::$maxDepth) {
157  if ($plainText) {
158  $header .= ' ' . ‪self::ansiEscapeWrap('max depth', '47;30', $ansiColors);
159  } else {
160  $header .= '<span class="extbase-debug-filtered">max depth</span>';
161  }
162  } else {
163  $content = ‪self::renderCollection($array, $level, $plainText, $ansiColors);
164  if (!$plainText) {
165  $header = ($level > 1 && $count > 0 ? '<input type="checkbox" /><span class="extbase-debug-header" >' : '<span>') . $header . '</span >';
166  }
167  }
168  if ($level > 1 && $count > 0 && !$plainText) {
169  $dump = '<span class="extbase-debugger-tree">' . $header . '<span class="extbase-debug-content">' . $content . '</span></span>';
170  } else {
171  $dump = $header . $content;
172  }
173  return $dump;
174  }
175 
185  protected static function ‪renderObject(object $object, int $level, bool $plainText = false, bool $ansiColors = false): string
186  {
187  if ($object instanceof LazyLoadingProxy) {
188  $object = $object->_loadRealInstance();
189  if (!is_object($object)) {
190  return gettype($object);
191  }
192  }
193  $header = ‪self::renderHeader($object, $level, $plainText, $ansiColors);
194  if ($level < self::$maxDepth && !self::isBlacklisted($object) && !(self::isAlreadyRendered($object) && $plainText !== true)) {
195  $content = ‪self::renderContent($object, $level, $plainText, $ansiColors);
196  } else {
197  $content = '';
198  }
199  if ($plainText) {
200  return $header . $content;
201  }
202  return '<span class="extbase-debugger-tree">' . $header . '<span class="extbase-debug-content">' . $content . '</span></span>';
203  }
204 
214  protected static function ‪renderClosure(\Closure $object, int $level, bool $plainText = false, bool $ansiColors = false): string
215  {
216  $header = ‪self::renderHeader($object, $level, $plainText, $ansiColors);
217  if ($level < self::$maxDepth && (!self::isAlreadyRendered($object) || $plainText)) {
218  $content = ‪self::renderContent($object, $level, $plainText, $ansiColors);
219  } else {
220  $content = '';
221  }
222  if ($plainText) {
223  return $header . $content;
224  }
225  return '<span class="extbase-debugger-tree"><input type="checkbox" /><span class="extbase-debug-header">' . $header . '</span><span class="extbase-debug-content">' . $content . '</span></span>';
226  }
227 
234  protected static function ‪isBlacklisted(object $value): bool
235  {
236  if ($value instanceof \ReflectionProperty) {
237  $result = in_array($value->getName(), self::$blacklistedPropertyNames, true);
238  } else {
239  $result = in_array(get_class($value), self::$blacklistedClassNames, true);
240  }
241  return $result;
242  }
243 
250  protected static function ‪isAlreadyRendered(object $object): bool
251  {
252  return self::$renderedObjects->contains($object);
253  }
254 
264  protected static function ‪renderHeader(object $object, int $level, bool $plainText, bool $ansiColors): string
265  {
266  $dump = '';
267  $persistenceType = null;
268  $className = get_class($object);
269  $classReflection = new \ReflectionClass($className);
270  if ($plainText) {
271  $dump .= ‪self::ansiEscapeWrap($className, '36', $ansiColors);
272  } else {
273  $dump .= '<span class="extbase-debug-type">' . htmlspecialchars($className, ENT_COMPAT) . '</span>';
274  }
275  if (!$object instanceof \Closure) {
276  if ($object instanceof SingletonInterface) {
277  $scope = 'singleton';
278  } else {
279  $scope = 'prototype';
280  }
281  if ($plainText) {
282  $dump .= ' ' . ‪self::ansiEscapeWrap($scope, '44;37', $ansiColors);
283  } else {
284  $dump .= '<span class="extbase-debug-scope">' . $scope . '</span>';
285  }
286  if ($object instanceof AbstractDomainObject) {
287  if ($object->_isDirty()) {
288  $persistenceType = 'modified';
289  } elseif ($object->_isNew()) {
290  $persistenceType = 'transient';
291  } else {
292  $persistenceType = 'persistent';
293  }
294  }
295  if ($object instanceof ObjectStorage && $object->_isDirty()) {
296  $persistenceType = 'modified';
297  }
298  if ($object instanceof AbstractEntity) {
299  $domainObjectType = 'entity';
300  } elseif ($object instanceof AbstractValueObject) {
301  $domainObjectType = 'valueobject';
302  } else {
303  $domainObjectType = 'object';
304  }
305  $persistenceType = $persistenceType === null ? '' : $persistenceType . ' ';
306  if ($plainText) {
307  $dump .= ' ' . ‪self::ansiEscapeWrap($persistenceType . $domainObjectType, '42;30', $ansiColors);
308  } else {
309  $dump .= '<span class="extbase-debug-ptype">' . $persistenceType . $domainObjectType . '</span>';
310  }
311  }
312  if (strpos(implode('|', self::$blacklistedClassNames), get_class($object)) > 0) {
313  if ($plainText) {
314  $dump .= ' ' . ‪self::ansiEscapeWrap('filtered', '47;30', $ansiColors);
315  } else {
316  $dump .= '<span class="extbase-debug-filtered">filtered</span>';
317  }
318  } elseif (self::$renderedObjects->contains($object) && !$plainText) {
319  $dump = '<a href="javascript:;" onclick="document.location.hash=\'#' . spl_object_hash($object) . '\';" class="extbase-‪debug-seeabove">' . $dump . '<span class="extbase-‪debug-filtered">see above</span></a>';
320  } elseif ($level >= self::$maxDepth && !$object instanceof \DateTimeInterface) {
321  if ($plainText) {
322  $dump .= ' ' . self::ansiEscapeWrap('max depth', '47;30', $ansiColors);
323  } else {
324  $dump .= '<span class="extbase-‪debug-filtered">max depth</span>';
325  }
326  } elseif ($level > 1 && !$object instanceof \DateTimeInterface && !$plainText) {
327  if (($object instanceof \Countable && empty($object)) || empty($classReflection->getProperties())) {
328  $dump = '<span>' . $dump . '</span>';
329  } else {
330  $dump = '<input type="checkbox" id="' . spl_object_hash($object) . '" /><span class="extbase-‪debug-header">' . $dump . '</span>';
331  }
332  }
333  if ($object instanceof \Countable) {
334  $objectCount = count($object);
335  $dump .= $objectCount > 0 ? ' (' . $objectCount . ' items)' : ' (empty)';
336  }
337  if ($object instanceof \DateTimeInterface) {
338  $dump .= ' (' . $object->format(\DateTimeInterface::RFC3339) . ', ' . $object->getTimestamp() . ')';
339  }
340  if ($object instanceof DomainObjectInterface && !$object->_isNew()) {
341  $dump .= ' (uid=' . $object->getUid() . ', pid=' . $object->getPid() . ')';
342  }
343  return $dump;
344  }
345 
353  protected static function renderContent(object $object, int $level, bool $plainText, bool $ansiColors): string
354  {
355  $dump = '';
356  if ($object instanceof \Iterator || $object instanceof \ArrayObject) {
357  $dump .= self::renderCollection($object, $level, $plainText, $ansiColors);
358  } else {
359  self::$renderedObjects->attach($object);
360  if (!$plainText) {
361  $dump .= '<a name="' . spl_object_hash($object) . '" id="' . spl_object_hash($object) . '"></a>';
362  }
363  if ($object instanceof \Closure) {
364  $dump .= PHP_EOL . str_repeat(self::PLAINTEXT_INDENT, $level)
365  . ($plainText ? '' : '<span class="extbase-‪debug-closure">')
366  . self::ansiEscapeWrap('function (', '33', $ansiColors) . ($plainText ? '' : '</span>');
367 
368  $reflectionFunction = new \ReflectionFunction($object);
369  $params = [];
370  foreach ($reflectionFunction->getParameters() as $parameter) {
371  $parameterDump = '';
372  $type = $parameter->getType();
373  // @todo Following code adds for parameter of type array or a class the classname or array
374  // to the output. All other introduced possible parameter types are not respected yet.
375  // This should be extended, and also respect possible type combinations like
376  // union types and union intersect types.
377  if ($type instanceof \ReflectionNamedType && $type->isBuiltin() && $type->getName() === 'array') {
378  if ($plainText) {
379  $parameterDump .= self::ansiEscapeWrap('array ', '36', $ansiColors);
380  } else {
381  $parameterDump .= '<span class="extbase-‪debug-type">array </span>';
382  }
383  } elseif ($type instanceof \ReflectionNamedType && !$type->isBuiltin() && !empty($type->getName())) {
384  if ($plainText) {
385  $parameterDump .= self::ansiEscapeWrap($type->getName() . ' ', '36', $ansiColors);
386  } else {
387  $parameterDump .= '<span class="extbase-‪debug-type">'
388  . htmlspecialchars($type->getName(), ENT_COMPAT) . '</span>';
389  }
390  }
391  if ($parameter->isPassedByReference()) {
392  $parameterDump .= '&';
393  }
394  if ($parameter->isVariadic()) {
395  $parameterDump .= '...';
396  }
397  if ($plainText) {
398  $parameterDump .= self::ansiEscapeWrap('$' . $parameter->name, '37', $ansiColors);
399  } else {
400  $parameterDump .= '<span class="extbase-‪debug-property">'
401  . htmlspecialchars('$' . $parameter->name, ENT_COMPAT) . '</span>';
402  }
403  if ($parameter->isDefaultValueAvailable()) {
404  $parameterDump .= ' = ';
405  if ($plainText) {
406  $parameterDump .= self::ansiEscapeWrap(var_export($parameter->getDefaultValue(), true), '33', $ansiColors);
407  } else {
408  $parameterDump .= '<span class="extbase-‪debug-string">'
409  . htmlspecialchars(var_export($parameter->getDefaultValue(), true), ENT_COMPAT) . '</span>';
410  }
411  }
412  $params[] = $parameterDump;
413  }
414  $dump .= implode(', ', $params);
415  if ($plainText) {
416  $dump .= self::ansiEscapeWrap(') {' . PHP_EOL, '33', $ansiColors);
417  } else {
418  $dump .= '<span class="extbase-‪debug-closure">) {' . PHP_EOL . '</span>';
419  }
420  $lines = (array)file((string)$reflectionFunction->getFileName());
421  for ($l = (int)$reflectionFunction->getStartLine(); $l < (int)$reflectionFunction->getEndLine() - 1; ++$l) {
422  $line = (string)($lines[$l] ?? '');
423  $dump .= $plainText ? $line : htmlspecialchars($line, ENT_COMPAT);
424  }
425  $dump .= str_repeat(self::PLAINTEXT_INDENT, $level);
426  if ($plainText) {
427  $dump .= self::ansiEscapeWrap('}' . PHP_EOL, '33', $ansiColors);
428  } else {
429  $dump .= '<span class="extbase-‪debug-closure">}</span>';
430  }
431  } else {
432  if (get_class($object) === \stdClass::class) {
433  $objReflection = new \ReflectionObject($object);
434  $properties = $objReflection->getProperties();
435  } else {
436  $classReflection = new \ReflectionClass(get_class($object));
437  $properties = $classReflection->getProperties();
438  }
439  foreach ($properties as $property) {
440  if (self::isBlacklisted($property)) {
441  continue;
442  }
443  $dump .= PHP_EOL . str_repeat(self::PLAINTEXT_INDENT, $level);
444  if ($plainText) {
445  $dump .= self::ansiEscapeWrap($property->getName(), '37', $ansiColors);
446  } else {
447  $dump .= '<span class="extbase-‪debug-property">'
448  . htmlspecialchars($property->getName(), ENT_COMPAT) . '</span>';
449  }
450  $dump .= ' => ';
451  $property->setAccessible(true);
452  $visibility = ($property->isProtected() ? 'protected' : ($property->isPrivate() ? 'private' : 'public'));
453  if ($plainText) {
454  $dump .= self::ansiEscapeWrap($visibility, '42;30', $ansiColors) . ' ';
455  } else {
456  $dump .= '<span class="extbase-‪debug-visibility">' . $visibility . '</span>';
457  }
458  if (!$property->isInitialized($object)) {
459  if ($plainText) {
460  $dump .= self::ansiEscapeWrap('uninitialized', '45;37', $ansiColors) . ' ';
461  } else {
462  $dump .= '<span class="extbase-‪debug-uninitialized">uninitialized</span> ';
463  }
464  continue;
465  }
466  $dump .= self::renderDump($property->getValue($object), $level, $plainText, $ansiColors);
467  if ($object instanceof AbstractDomainObject && !$object->_isNew() && $object->_isDirty($property->getName())) {
468  if ($plainText) {
469  $dump .= ' ' . self::ansiEscapeWrap('modified', '43;30', $ansiColors);
470  } else {
471  $dump .= '<span class="extbase-‪debug-dirty">modified</span>';
472  }
473  }
474  }
475  }
476  }
477  return $dump;
478  }
479 
487  protected static function renderCollection(iterable $collection, int $level, bool $plainText, bool $ansiColors): string
488  {
489  $dump = '';
490  foreach ($collection as $key => $value) {
491  $key = (string)$key;
492 
493  $dump .= PHP_EOL . str_repeat(self::PLAINTEXT_INDENT, $level);
494  if ($plainText) {
495  $dump .= self::ansiEscapeWrap($key, '37', $ansiColors);
496  } else {
497  $dump .= '<span class="extbase-‪debug-property">' . htmlspecialchars($key, ENT_COMPAT) . '</span>';
498  }
499  $dump .= ' => ';
500  $dump .= self::renderDump($value, $level, $plainText, $ansiColors);
501  }
502  if ($collection instanceof \Iterator && !$collection instanceof \Generator) {
503  $collection->rewind();
504  }
505  return $dump;
506  }
507 
516  protected static function ansiEscapeWrap(string $string, string $ansiColors, bool $enable = true): string
517  {
518  if ($enable) {
519  return '[' . $ansiColors . 'm' . $string . '';
520  }
521  return $string;
522  }
523 
537  public static function var_dump(
538  $variable,
539  ?string $title = null,
540  int $maxDepth = 8,
541  bool $plainText = false,
542  bool $ansiColors = true,
543  bool $return = false,
544  ?array $blacklistedClassNames = null,
545  ?array $blacklistedPropertyNames = null
546  ): string {
547  self::$maxDepth = $maxDepth;
548  if ($title === null) {
549  $title = 'Extbase Variable Dump';
550  }
551  $ansiColors = $plainText && $ansiColors;
552  if ($ansiColors === true) {
553  $title = '' . $title . '';
554  }
555  $backupBlacklistedClassNames = self::$blacklistedClassNames;
556  if (is_array($blacklistedClassNames)) {
557  self::$blacklistedClassNames = $blacklistedClassNames;
558  }
559  $backupBlacklistedPropertyNames = self::$blacklistedPropertyNames;
560  if (is_array($blacklistedPropertyNames)) {
561  self::$blacklistedPropertyNames = $blacklistedPropertyNames;
562  }
563  self::clearState();
564  $css = '';
565  if (!$plainText && self::$stylesheetEchoed === false) {
566  $css = '
567  <style>
568  .extbase-debugger-tree{position:relative}
569  .extbase-debugger-tree input{position:absolute !important;float: none !important;top:0;left:0;height:14px;width:14px;margin:0 !important;cursor:pointer;opacity:0;z-index:2}
570  .extbase-debugger-tree input~.extbase-debug-content{display:none}
571  .extbase-debugger-tree .extbase-debug-header:before{position:relative;top:3px;content:"";padding:0;line-height:10px;height:12px;width:12px;text-align:center;margin:0 3px 0 0;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkViZW5lXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTIgMTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDEyIDEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6Izg4ODg4ODt9PC9zdHlsZT48cGF0aCBpZD0iQm9yZGVyIiBjbGFzcz0ic3QwIiBkPSJNMTEsMTFIMFYwaDExVjExeiBNMTAsMUgxdjloOVYxeiIvPjxnIGlkPSJJbm5lciI+PHJlY3QgeD0iMiIgeT0iNSIgY2xhc3M9InN0MCIgd2lkdGg9IjciIGhlaWdodD0iMSIvPjxyZWN0IHg9IjUiIHk9IjIiIGNsYXNzPSJzdDAiIHdpZHRoPSIxIiBoZWlnaHQ9IjciLz48L2c+PC9zdmc+);display:inline-block}
572  .extbase-debugger-tree input:checked~.extbase-debug-content{display:inline}
573  .extbase-debugger-tree input:checked~.extbase-debug-header:before{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkViZW5lXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTIgMTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDEyIDEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6Izg4ODg4ODt9PC9zdHlsZT48cGF0aCBpZD0iQm9yZGVyIiBjbGFzcz0ic3QwIiBkPSJNMTEsMTFIMFYwaDExVjExeiBNMTAsMUgxdjloOVYxeiIvPjxnIGlkPSJJbm5lciI+PHJlY3QgeD0iMiIgeT0iNSIgY2xhc3M9InN0MCIgd2lkdGg9IjciIGhlaWdodD0iMSIvPjwvZz48L3N2Zz4=)}
574  .extbase-debugger{display:block;text-align:left;background:#2a2a2a;border:1px solid #2a2a2a;box-shadow:0 3px 0 rgba(0,0,0,.5);color:#000;margin:20px;overflow:hidden;border-radius:4px}
575  .extbase-debugger-floating{position:relative;z-index:99990}
576  .extbase-debugger-top{background:#444;font-size:12px;font-family:monospace;color:#f1f1f1;padding:6px 15px}
577  .extbase-debugger-center{padding:0 15px;margin:15px 0;background-image:repeating-linear-gradient(to bottom,transparent 0,transparent 20px,#252525 20px,#252525 40px)}
578  .extbase-debugger-center,.extbase-debugger-center .extbase-debug-string,.extbase-debugger-center a,.extbase-debugger-center p,.extbase-debugger-center pre,.extbase-debugger-center strong{font-size:12px;font-weight:400;font-family:monospace;line-height:20px;color:#f1f1f1}
579  .extbase-debugger-center pre{background-color:transparent;margin:0;padding:0;border:0;word-wrap:break-word;color:#999}
580  .extbase-debugger-center .extbase-debug-string{color:#ce9178;white-space:normal}
581  .extbase-debugger-center .extbase-debug-type{color:#569CD6;padding-right:4px}
582  .extbase-debugger-center .extbase-debug-unregistered{background-color:#dce1e8}
583  .extbase-debugger-center .extbase-debug-filtered,.extbase-debugger-center .extbase-debug-proxy,.extbase-debugger-center .extbase-debug-ptype,.extbase-debugger-center .extbase-debug-visibility,.extbase-debugger-center .extbase-debug-uninitialized,.extbase-debugger-center .extbase-debug-scope{color:#fff;font-size:10px;line-height:12px;padding:2px 4px;margin-right:2px;position:relative;top:-1px}
584  .extbase-debugger-center .extbase-debug-scope{background-color:#497AA2}
585  .extbase-debugger-center .extbase-debug-ptype{background-color:#698747}
586  .extbase-debugger-center .extbase-debug-visibility{background-color:#6c0787}
587  .extbase-debugger-center .extbase-debug-uninitialized{background-color:#698747}
588  .extbase-debugger-center .extbase-debug-dirty{background-color:#FFFFB6}
589  .extbase-debugger-center .extbase-debug-filtered{background-color:#4F4F4F}
590  .extbase-debugger-center .extbase-debug-seeabove{text-decoration:none;font-style:italic}
591  .extbase-debugger-center .extbase-debug-property{color:#f1f1f1}
592  .extbase-debugger-center .extbase-debug-closure{color:#9BA223;}
593  </style>';
594  self::$stylesheetEchoed = true;
595  }
596  if ($plainText) {
597  $output = $title . PHP_EOL . self::renderDump($variable, 0, true, $ansiColors) . PHP_EOL . PHP_EOL;
598  } else {
599  $output = '
600  <div class="extbase-debugger ' . ($return ? 'extbase-debugger-inline' : 'extbase-debugger-floating') . '">
601  <div class="extbase-debugger-top">' . htmlspecialchars($title, ENT_COMPAT) . '</div>
602  <div class="extbase-debugger-center">
603  <pre dir="ltr">' . self::renderDump($variable, 0, false, false) . '</pre>
604  </div>
605  </div>
606  ';
607  }
608  self::$blacklistedClassNames = $backupBlacklistedClassNames;
609  self::$blacklistedPropertyNames = $backupBlacklistedPropertyNames;
610  if ($return === true) {
611  return $css . $output;
612  }
613  echo $css . $output;
614 
615  return '';
616  }
617 }
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\clearState
‪static clearState()
Definition: DebuggerUtility.php:85
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\PLAINTEXT_INDENT
‪const PLAINTEXT_INDENT
Definition: DebuggerUtility.php:42
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderDump
‪static string renderDump($value, int $level, bool $plainText, bool $ansiColors)
Definition: DebuggerUtility.php:99
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\$stylesheetEchoed
‪static bool $stylesheetEchoed
Definition: DebuggerUtility.php:74
‪TYPO3\CMS\Extbase\Persistence\ObjectStorage\_isDirty
‪bool _isDirty()
Definition: ObjectStorage.php:365
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
Definition: QueryObjectModelFactory.php:27
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
Definition: DataMapper.php:51
‪TYPO3\CMS\Extbase\DomainObject\AbstractEntity
Definition: AbstractEntity.php:22
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\$maxDepth
‪static int $maxDepth
Definition: DebuggerUtility.php:80
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\$renderedObjects
‪static TYPO3 CMS Extbase Persistence ObjectStorage $renderedObjects
Definition: DebuggerUtility.php:47
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\$blacklistedClassNames
‪static array $blacklistedClassNames
Definition: DebuggerUtility.php:53
‪TYPO3\CMS\Extbase\Persistence\ObjectStorage
Definition: ObjectStorage.php:32
‪TYPO3\CMS\Extbase\Reflection\ReflectionService
Definition: ReflectionService.php:28
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderContent
‪static string renderContent(object $object, int $level, bool $plainText, bool $ansiColors)
Definition: DebuggerUtility.php:348
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\ansiEscapeWrap
‪static string ansiEscapeWrap(string $string, string $ansiColors, bool $enable=true)
Definition: DebuggerUtility.php:511
‪TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
Definition: AbstractValueObject.php:24
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface
Definition: DomainObjectInterface.php:29
‪TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
Definition: PersistenceManager.php:28
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
Definition: AbstractDomainObject.php:31
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderHeader
‪static string renderHeader(object $object, int $level, bool $plainText, bool $ansiColors)
Definition: DebuggerUtility.php:259
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderClosure
‪static string renderClosure(\Closure $object, int $level, bool $plainText=false, bool $ansiColors=false)
Definition: DebuggerUtility.php:209
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility
Definition: DebuggerUtility.php:41
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\$blacklistedPropertyNames
‪static array $blacklistedPropertyNames
Definition: DebuggerUtility.php:68
‪debug
‪debug($variable='', $title=null, $group=null)
Definition: GlobalDebugFunctions.php:19
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\isBlacklisted
‪static bool isBlacklisted(object $value)
Definition: DebuggerUtility.php:229
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\HTML_INDENT
‪const HTML_INDENT
Definition: DebuggerUtility.php:43
‪TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy
Definition: LazyLoadingProxy.php:29
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderArray
‪static string renderArray(array $array, int $level, bool $plainText=false, bool $ansiColors=false)
Definition: DebuggerUtility.php:140
‪TYPO3\CMS\Extbase\Utility
Definition: DebuggerUtility.php:18
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\isAlreadyRendered
‪static bool isAlreadyRendered(object $object)
Definition: DebuggerUtility.php:245
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:31
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderObject
‪static string renderObject(object $object, int $level, bool $plainText=false, bool $ansiColors=false)
Definition: DebuggerUtility.php:180
‪TYPO3\CMS\Extbase\Utility\DebuggerUtility\renderCollection
‪static string renderCollection(iterable $collection, int $level, bool $plainText, bool $ansiColors)
Definition: DebuggerUtility.php:482