PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 2.8.6
Kubio AI Page Builder v2.8.6
2.9.0 2.8.6 2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / vendor / sebastian / exporter / src / Exporter.php
kubio / vendor / sebastian / exporter / src Last commit date
Exporter.php 1 year ago
Exporter.php
347 lines
1 <?php declare(strict_types=1);
2 /*
3 * This file is part of sebastian/exporter.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
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 SebastianBergmann\Exporter;
11
12 use function bin2hex;
13 use function count;
14 use function function_exists;
15 use function get_class;
16 use function get_resource_type;
17 use function gettype;
18 use function implode;
19 use function ini_get;
20 use function ini_set;
21 use function is_array;
22 use function is_float;
23 use function is_object;
24 use function is_resource;
25 use function is_string;
26 use function mb_strlen;
27 use function mb_substr;
28 use function preg_match;
29 use function spl_object_hash;
30 use function sprintf;
31 use function str_repeat;
32 use function str_replace;
33 use function strlen;
34 use function substr;
35 use function var_export;
36 use SebastianBergmann\RecursionContext\Context;
37 use SplObjectStorage;
38
39 /**
40 * A nifty utility for visualizing PHP variables.
41 *
42 * <code>
43 * <?php
44 * use SebastianBergmann\Exporter\Exporter;
45 *
46 * $exporter = new Exporter;
47 * print $exporter->export(new Exception);
48 * </code>
49 */
50 class Exporter
51 {
52 /**
53 * Exports a value as a string.
54 *
55 * The output of this method is similar to the output of print_r(), but
56 * improved in various aspects:
57 *
58 * - NULL is rendered as "null" (instead of "")
59 * - TRUE is rendered as "true" (instead of "1")
60 * - FALSE is rendered as "false" (instead of "")
61 * - Strings are always quoted with single quotes
62 * - Carriage returns and newlines are normalized to \n
63 * - Recursion and repeated rendering is treated properly
64 *
65 * @param int $indentation The indentation level of the 2nd+ line
66 *
67 * @return string
68 */
69 public function export($value, $indentation = 0)
70 {
71 return $this->recursiveExport($value, $indentation);
72 }
73
74 /**
75 * @param array<mixed> $data
76 * @param Context $context
77 *
78 * @return string
79 */
80 public function shortenedRecursiveExport(&$data, ?Context $context = null)
81 {
82 $result = [];
83 $exporter = new self();
84
85 if (!$context) {
86 $context = new Context;
87 }
88
89 $array = $data;
90 $context->add($data);
91
92 foreach ($array as $key => $value) {
93 if (is_array($value)) {
94 if ($context->contains($data[$key]) !== false) {
95 $result[] = '*RECURSION*';
96 } else {
97 $result[] = sprintf(
98 'array(%s)',
99 $this->shortenedRecursiveExport($data[$key], $context)
100 );
101 }
102 } else {
103 $result[] = $exporter->shortenedExport($value);
104 }
105 }
106
107 return implode(', ', $result);
108 }
109
110 /**
111 * Exports a value into a single-line string.
112 *
113 * The output of this method is similar to the output of
114 * SebastianBergmann\Exporter\Exporter::export().
115 *
116 * Newlines are replaced by the visible string '\n'.
117 * Contents of arrays and objects (if any) are replaced by '...'.
118 *
119 * @return string
120 *
121 * @see SebastianBergmann\Exporter\Exporter::export
122 */
123 public function shortenedExport($value)
124 {
125 if (is_string($value)) {
126 $string = str_replace("\n", '', $this->export($value));
127
128 if (function_exists('mb_strlen')) {
129 if (mb_strlen($string) > 40) {
130 $string = mb_substr($string, 0, 30) . '...' . mb_substr($string, -7);
131 }
132 } else {
133 if (strlen($string) > 40) {
134 $string = substr($string, 0, 30) . '...' . substr($string, -7);
135 }
136 }
137
138 return $string;
139 }
140
141 if (is_object($value)) {
142 return sprintf(
143 '%s Object (%s)',
144 get_class($value),
145 count($this->toArray($value)) > 0 ? '...' : ''
146 );
147 }
148
149 if (is_array($value)) {
150 return sprintf(
151 'Array (%s)',
152 count($value) > 0 ? '...' : ''
153 );
154 }
155
156 return $this->export($value);
157 }
158
159 /**
160 * Converts an object to an array containing all of its private, protected
161 * and public properties.
162 *
163 * @return array
164 */
165 public function toArray($value)
166 {
167 if (!is_object($value)) {
168 return (array) $value;
169 }
170
171 $array = [];
172
173 foreach ((array) $value as $key => $val) {
174 // Exception traces commonly reference hundreds to thousands of
175 // objects currently loaded in memory. Including them in the result
176 // has a severe negative performance impact.
177 if ("\0Error\0trace" === $key || "\0Exception\0trace" === $key) {
178 continue;
179 }
180
181 // properties are transformed to keys in the following way:
182 // private $property => "\0Classname\0property"
183 // protected $property => "\0*\0property"
184 // public $property => "property"
185 if (preg_match('/^\0.+\0(.+)$/', (string) $key, $matches)) {
186 $key = $matches[1];
187 }
188
189 // See https://github.com/php/php-src/commit/5721132
190 if ($key === "\0gcdata") {
191 continue;
192 }
193
194 $array[$key] = $val;
195 }
196
197 // Some internal classes like SplObjectStorage don't work with the
198 // above (fast) mechanism nor with reflection in Zend.
199 // Format the output similarly to print_r() in this case
200 if ($value instanceof SplObjectStorage) {
201 foreach ($value as $key => $val) {
202 $array[spl_object_hash($val)] = [
203 'obj' => $val,
204 'inf' => $value->getInfo(),
205 ];
206 }
207 }
208
209 return $array;
210 }
211
212 /**
213 * Recursive implementation of export.
214 *
215 * @param mixed $value The value to export
216 * @param int $indentation The indentation level of the 2nd+ line
217 * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects
218 *
219 * @return string
220 *
221 * @see SebastianBergmann\Exporter\Exporter::export
222 */
223 protected function recursiveExport(&$value, $indentation, $processed = null)
224 {
225 if ($value === null) {
226 return 'null';
227 }
228
229 if ($value === true) {
230 return 'true';
231 }
232
233 if ($value === false) {
234 return 'false';
235 }
236
237 if (is_float($value)) {
238 $precisionBackup = ini_get('precision');
239
240 ini_set('precision', '-1');
241
242 try {
243 $valueStr = (string) $value;
244
245 if ((string) (int) $value === $valueStr) {
246 return $valueStr . '.0';
247 }
248
249 return $valueStr;
250 } finally {
251 ini_set('precision', $precisionBackup);
252 }
253 }
254
255 if (gettype($value) === 'resource (closed)') {
256 return 'resource (closed)';
257 }
258
259 if (is_resource($value)) {
260 return sprintf(
261 'resource(%d) of type (%s)',
262 $value,
263 get_resource_type($value)
264 );
265 }
266
267 if (is_string($value)) {
268 // Match for most non printable chars somewhat taking multibyte chars into account
269 if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) {
270 return 'Binary String: 0x' . bin2hex($value);
271 }
272
273 return "'" .
274 str_replace(
275 '<lf>',
276 "\n",
277 str_replace(
278 ["\r\n", "\n\r", "\r", "\n"],
279 ['\r\n<lf>', '\n\r<lf>', '\r<lf>', '\n<lf>'],
280 $value
281 )
282 ) .
283 "'";
284 }
285
286 $whitespace = str_repeat(' ', 4 * $indentation);
287
288 if (!$processed) {
289 $processed = new Context;
290 }
291
292 if (is_array($value)) {
293 if (($key = $processed->contains($value)) !== false) {
294 return 'Array &' . $key;
295 }
296
297 $array = $value;
298 $key = $processed->add($value);
299 $values = '';
300
301 if (count($array) > 0) {
302 foreach ($array as $k => $v) {
303 $values .= sprintf(
304 '%s %s => %s' . "\n",
305 $whitespace,
306 $this->recursiveExport($k, $indentation),
307 $this->recursiveExport($value[$k], $indentation + 1, $processed)
308 );
309 }
310
311 $values = "\n" . $values . $whitespace;
312 }
313
314 return sprintf('Array &%s (%s)', $key, $values);
315 }
316
317 if (is_object($value)) {
318 $class = get_class($value);
319
320 if ($hash = $processed->contains($value)) {
321 return sprintf('%s Object &%s', $class, $hash);
322 }
323
324 $hash = $processed->add($value);
325 $values = '';
326 $array = $this->toArray($value);
327
328 if (count($array) > 0) {
329 foreach ($array as $k => $v) {
330 $values .= sprintf(
331 '%s %s => %s' . "\n",
332 $whitespace,
333 $this->recursiveExport($k, $indentation),
334 $this->recursiveExport($v, $indentation + 1, $processed)
335 );
336 }
337
338 $values = "\n" . $values . $whitespace;
339 }
340
341 return sprintf('%s Object &%s (%s)', $class, $hash, $values);
342 }
343
344 return var_export($value, true);
345 }
346 }
347