TextFormatter.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 RuntimeException;
  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. switch ($var->getType()) {
  67. case 'bool':
  68. return $var->getValue() ? 'true' : 'false';
  69. case 'null':
  70. return 'null';
  71. case 'string':
  72. return "'" . (string)$var->getValue() . "'";
  73. default:
  74. return "({$var->getType()}) {$var->getValue()}";
  75. }
  76. }
  77. if ($var instanceof ArrayNode) {
  78. return $this->exportArray($var, $indent + 1);
  79. }
  80. if ($var instanceof ClassNode || $var instanceof ReferenceNode) {
  81. return $this->exportObject($var, $indent + 1);
  82. }
  83. if ($var instanceof SpecialNode) {
  84. return (string)$var->getValue();
  85. }
  86. throw new RuntimeException('Unknown node received ' . get_class($var));
  87. }
  88. /**
  89. * Export an array type object
  90. *
  91. * @param \Cake\Error\Debug\ArrayNode $var The array to export.
  92. * @param int $indent The current indentation level.
  93. * @return string Exported array.
  94. */
  95. protected function exportArray(ArrayNode $var, int $indent): string
  96. {
  97. $out = '[';
  98. $break = "\n" . str_repeat(" ", $indent);
  99. $end = "\n" . str_repeat(" ", $indent - 1);
  100. $vars = [];
  101. foreach ($var->getChildren() as $item) {
  102. $val = $item->getValue();
  103. $vars[] = $break . $this->export($item->getKey(), $indent) . ' => ' . $this->export($val, $indent);
  104. }
  105. if (count($vars)) {
  106. return $out . implode(',', $vars) . $end . ']';
  107. }
  108. return $out . ']';
  109. }
  110. /**
  111. * Handles object to string conversion.
  112. *
  113. * @param \Cake\Error\Debug\ClassNode|\Cake\Error\Debug\ReferenceNode $var Object to convert.
  114. * @param int $indent Current indentation level.
  115. * @return string
  116. * @see \Cake\Error\Debugger::exportVar()
  117. */
  118. protected function exportObject($var, int $indent): string
  119. {
  120. $out = '';
  121. $props = [];
  122. if ($var instanceof ReferenceNode) {
  123. return "object({$var->getValue()}) id:{$var->getId()} {}";
  124. }
  125. $out .= "object({$var->getValue()}) id:{$var->getId()} {";
  126. $break = "\n" . str_repeat(" ", $indent);
  127. $end = "\n" . str_repeat(" ", $indent - 1) . '}';
  128. foreach ($var->getChildren() as $property) {
  129. $visibility = $property->getVisibility();
  130. $name = $property->getName();
  131. if ($visibility && $visibility !== 'public') {
  132. $props[] = "[{$visibility}] {$name} => " . $this->export($property->getValue(), $indent);
  133. } else {
  134. $props[] = "{$name} => " . $this->export($property->getValue(), $indent);
  135. }
  136. }
  137. if (count($props)) {
  138. return $out . $break . implode($break, $props) . $end;
  139. }
  140. return $out . '}';
  141. }
  142. }