1: | <?php |
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | |
25: | |
26: | namespace Kint; |
27: | |
28: | use InvalidArgumentException; |
29: | use Kint\Object\BlobObject; |
30: | use ReflectionNamedType; |
31: | use ReflectionType; |
32: | |
33: | |
34: | |
35: | |
36: | final class Utils |
37: | { |
38: | |
39: | |
40: | |
41: | private function __construct() |
42: | { |
43: | } |
44: | |
45: | |
46: | |
47: | |
48: | |
49: | |
50: | |
51: | |
52: | public static function getHumanReadableBytes($value) |
53: | { |
54: | static $unit = array('B', 'KB', 'MB', 'GB', 'TB'); |
55: | |
56: | $i = \floor(\log($value, 1024)); |
57: | $i = \min($i, 4); |
58: | |
59: | return array( |
60: | 'value' => (float) ($value / \pow(1024, $i)), |
61: | 'unit' => $unit[$i], |
62: | ); |
63: | } |
64: | |
65: | public static function isSequential(array $array) |
66: | { |
67: | return \array_keys($array) === \range(0, \count($array) - 1); |
68: | } |
69: | |
70: | public static function composerGetExtras($key = 'kint') |
71: | { |
72: | $extras = array(); |
73: | |
74: | if (0 === \strpos(KINT_DIR, 'phar://')) { |
75: | |
76: | return $extras; |
77: | } |
78: | |
79: | $folder = KINT_DIR.'/vendor'; |
80: | |
81: | for ($i = 0; $i < 4; ++$i) { |
82: | $installed = $folder.'/composer/installed.json'; |
83: | |
84: | if (\file_exists($installed) && \is_readable($installed)) { |
85: | $packages = \json_decode(\file_get_contents($installed), true); |
86: | |
87: | foreach ($packages as $package) { |
88: | if (isset($package['extra'][$key]) && \is_array($package['extra'][$key])) { |
89: | $extras = \array_replace($extras, $package['extra'][$key]); |
90: | } |
91: | } |
92: | |
93: | $folder = \dirname($folder); |
94: | |
95: | if (\file_exists($folder.'/composer.json') && \is_readable($folder.'/composer.json')) { |
96: | $composer = \json_decode(\file_get_contents($folder.'/composer.json'), true); |
97: | |
98: | if (isset($composer['extra'][$key]) && \is_array($composer['extra'][$key])) { |
99: | $extras = \array_replace($extras, $composer['extra'][$key]); |
100: | } |
101: | } |
102: | |
103: | break; |
104: | } |
105: | |
106: | $folder = \dirname($folder); |
107: | } |
108: | |
109: | return $extras; |
110: | } |
111: | |
112: | |
113: | |
114: | |
115: | public static function composerSkipFlags() |
116: | { |
117: | $extras = self::composerGetExtras(); |
118: | |
119: | if (!empty($extras['disable-facade']) && !\defined('KINT_SKIP_FACADE')) { |
120: | \define('KINT_SKIP_FACADE', true); |
121: | } |
122: | |
123: | if (!empty($extras['disable-helpers']) && !\defined('KINT_SKIP_HELPERS')) { |
124: | \define('KINT_SKIP_HELPERS', true); |
125: | } |
126: | } |
127: | |
128: | public static function isTrace(array $trace) |
129: | { |
130: | if (!self::isSequential($trace)) { |
131: | return false; |
132: | } |
133: | |
134: | static $bt_structure = array( |
135: | 'function' => 'string', |
136: | 'line' => 'integer', |
137: | 'file' => 'string', |
138: | 'class' => 'string', |
139: | 'object' => 'object', |
140: | 'type' => 'string', |
141: | 'args' => 'array', |
142: | ); |
143: | |
144: | $file_found = false; |
145: | |
146: | foreach ($trace as $frame) { |
147: | if (!\is_array($frame) || !isset($frame['function'])) { |
148: | return false; |
149: | } |
150: | |
151: | foreach ($frame as $key => $val) { |
152: | if (!isset($bt_structure[$key])) { |
153: | return false; |
154: | } |
155: | |
156: | if (\gettype($val) !== $bt_structure[$key]) { |
157: | return false; |
158: | } |
159: | |
160: | if ('file' === $key) { |
161: | $file_found = true; |
162: | } |
163: | } |
164: | } |
165: | |
166: | return $file_found; |
167: | } |
168: | |
169: | public static function traceFrameIsListed(array $frame, array $matches) |
170: | { |
171: | if (isset($frame['class'])) { |
172: | $called = array(\strtolower($frame['class']), \strtolower($frame['function'])); |
173: | } else { |
174: | $called = \strtolower($frame['function']); |
175: | } |
176: | |
177: | return \in_array($called, $matches, true); |
178: | } |
179: | |
180: | public static function normalizeAliases(array &$aliases) |
181: | { |
182: | static $name_regex = '[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*'; |
183: | |
184: | foreach ($aliases as $index => &$alias) { |
185: | if (\is_array($alias) && 2 === \count($alias)) { |
186: | $alias = \array_values(\array_filter($alias, 'is_string')); |
187: | |
188: | if (2 === \count($alias) && |
189: | \preg_match('/^'.$name_regex.'$/', $alias[1]) && |
190: | \preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias[0]) |
191: | ) { |
192: | $alias = array( |
193: | \strtolower(\ltrim($alias[0], '\\')), |
194: | \strtolower($alias[1]), |
195: | ); |
196: | } else { |
197: | unset($aliases[$index]); |
198: | continue; |
199: | } |
200: | } elseif (\is_string($alias)) { |
201: | if (\preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias)) { |
202: | $alias = \explode('\\', \strtolower($alias)); |
203: | $alias = \end($alias); |
204: | } else { |
205: | unset($aliases[$index]); |
206: | continue; |
207: | } |
208: | } else { |
209: | unset($aliases[$index]); |
210: | } |
211: | } |
212: | |
213: | $aliases = \array_values($aliases); |
214: | } |
215: | |
216: | public static function truncateString($input, $length = PHP_INT_MAX, $end = '...', $encoding = false) |
217: | { |
218: | $length = (int) $length; |
219: | $endlength = BlobObject::strlen($end); |
220: | |
221: | if ($endlength >= $length) { |
222: | throw new InvalidArgumentException('Can\'t truncate a string to '.$length.' characters if ending with string '.$endlength.' characters long'); |
223: | } |
224: | |
225: | if (BlobObject::strlen($input, $encoding) > $length) { |
226: | return BlobObject::substr($input, 0, $length - $endlength, $encoding).$end; |
227: | } |
228: | |
229: | return $input; |
230: | } |
231: | |
232: | public static function getTypeString(ReflectionType $type) |
233: | { |
234: | if ($type instanceof ReflectionNamedType) { |
235: | return $type->getName(); |
236: | } |
237: | |
238: | return (string) $type; |
239: | } |
240: | } |
241: | |