TextFormatter.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 4.1.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Error\Debug;
  17. use InvalidArgumentException;
  18. /**
  19. * A Debugger formatter for generating unstyled plain text output.
  20. *
  21. * Provides backwards compatible output with the historical output of
  22. * `Debugger::exportVar()`
  23. *
  24. * @internal
  25. */
  26. class TextFormatter implements FormatterInterface
  27. {
  28. /**
  29. * @inheritDoc
  30. */
  31. public function formatWrapper(string $contents, array $location): string
  32. {
  33. $template = <<<TEXT
  34. %s
  35. ########## DEBUG ##########
  36. %s
  37. ###########################
  38. TEXT;
  39. $lineInfo = '';
  40. if (isset($location['file'], $location['file'])) {
  41. $lineInfo = sprintf('%s (line %s)', $location['file'], $location['line']);
  42. }
  43. return sprintf($template, $lineInfo, $contents);
  44. }
  45. /**
  46. * Convert a tree of NodeInterface objects into a plain text string.
  47. *
  48. * @param \Cake\Error\Debug\NodeInterface $node The node tree to dump.
  49. * @return string
  50. */
  51. public function dump(NodeInterface $node): string
  52. {
  53. $indent = 0;
  54. return $this->export($node, $indent);
  55. }
  56. /**
  57. * Convert a tree of NodeInterface objects into a plain text string.
  58. *
  59. * @param \Cake\Error\Debug\NodeInterface $var The node tree to dump.
  60. * @param int $indent The current indentation level.
  61. * @return string
  62. */
  63. protected function export(NodeInterface $var, int $indent): string
  64. {
  65. if ($var instanceof ScalarNode) {
  66. return match ($var->getType()) {
  67. 'bool' => $var->getValue() ? 'true' : 'false',
  68. 'null' => 'null',
  69. 'string' => "'" . (string)$var->getValue() . "'",
  70. default => "({$var->getType()}) {$var->getValue()}",
  71. };
  72. }
  73. if ($var instanceof ArrayNode) {
  74. return $this->exportArray($var, $indent + 1);
  75. }
  76. if ($var instanceof ClassNode || $var instanceof ReferenceNode) {
  77. return $this->exportObject($var, $indent + 1);
  78. }
  79. if ($var instanceof SpecialNode) {
  80. return $var->getValue();
  81. }
  82. throw new InvalidArgumentException('Unknown node received ' . $var::class);
  83. }
  84. /**
  85. * Export an array type object
  86. *
  87. * @param \Cake\Error\Debug\ArrayNode $var The array to export.
  88. * @param int $indent The current indentation level.
  89. * @return string Exported array.
  90. */
  91. protected function exportArray(ArrayNode $var, int $indent): string
  92. {
  93. $out = '[';
  94. $break = "\n" . str_repeat(' ', $indent);
  95. $end = "\n" . str_repeat(' ', $indent - 1);
  96. $vars = [];
  97. foreach ($var->getChildren() as $item) {
  98. $val = $item->getValue();
  99. $vars[] = $break . $this->export($item->getKey(), $indent) . ' => ' . $this->export($val, $indent);
  100. }
  101. if ($vars !== []) {
  102. return $out . implode(',', $vars) . $end . ']';
  103. }
  104. return $out . ']';
  105. }
  106. /**
  107. * Handles object to string conversion.
  108. *
  109. * @param \Cake\Error\Debug\ClassNode|\Cake\Error\Debug\ReferenceNode $var Object to convert.
  110. * @param int $indent Current indentation level.
  111. * @return string
  112. * @see \Cake\Error\Debugger::exportVar()
  113. */
  114. protected function exportObject(ClassNode|ReferenceNode $var, int $indent): string
  115. {
  116. $out = '';
  117. $props = [];
  118. if ($var instanceof ReferenceNode) {
  119. return "object({$var->getValue()}) id:{$var->getId()} {}";
  120. }
  121. $out .= "object({$var->getValue()}) id:{$var->getId()} {";
  122. $break = "\n" . str_repeat(' ', $indent);
  123. $end = "\n" . str_repeat(' ', $indent - 1) . '}';
  124. foreach ($var->getChildren() as $property) {
  125. $visibility = $property->getVisibility();
  126. $name = $property->getName();
  127. if ($visibility && $visibility !== 'public') {
  128. $props[] = "[{$visibility}] {$name} => " . $this->export($property->getValue(), $indent);
  129. } else {
  130. $props[] = "{$name} => " . $this->export($property->getValue(), $indent);
  131. }
  132. }
  133. if ($props !== []) {
  134. return $out . $break . implode($break, $props) . $end;
  135. }
  136. return $out . '}';
  137. }
  138. }