├── .laminas-ci.json
├── COPYRIGHT.md
├── src
├── Exception
│ ├── ExceptionInterface.php
│ ├── RecursionException.php
│ ├── RuntimeException.php
│ ├── BadMethodCallException.php
│ └── InvalidArgumentException.php
├── Expr.php
├── Json.php
├── Decoder.php
└── Encoder.php
├── phpcs.xml.dist
├── LICENSE.md
├── composer.json
├── README.md
└── composer.lock
/.laminas-ci.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_php_platform_requirements": {
3 | "8.4": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/COPYRIGHT.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)
2 |
--------------------------------------------------------------------------------
/src/Exception/ExceptionInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | src
17 | test
18 |
19 |
20 |
21 |
22 |
23 | src/
24 |
25 |
26 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | - Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | - Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | - Neither the name of Laminas Foundation nor the names of its contributors may
14 | be used to endorse or promote products derived from this software without
15 | specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/src/Expr.php:
--------------------------------------------------------------------------------
1 |
17 | * $foo = array(
18 | * 'integer' => 9,
19 | * 'string' => 'test string',
20 | * 'function' => Laminas\Json\Expr(
21 | * 'function () { window.alert("javascript function encoded by Laminas\Json\Json") }'
22 | * ),
23 | * );
24 | *
25 | * echo Laminas\Json\Json::encode($foo, false, ['enableJsonExprFinder' => true]);
26 | *
27 | *
28 | * The above returns the following JSON (formatted for readability):
29 | *
30 | *
31 | * {
32 | * "integer": 9,
33 | * "string": "test string",
34 | * "function": function () {window.alert("javascript function encoded by Laminas\Json\Json")}
35 | * }
36 | *
37 | */
38 | class Expr implements Stringable
39 | {
40 | /**
41 | * Storage for javascript expression.
42 | *
43 | * @var string
44 | */
45 | protected $expression;
46 |
47 | /**
48 | * @param string $expression The expression to represent.
49 | */
50 | public function __construct($expression)
51 | {
52 | $this->expression = (string) $expression;
53 | }
54 |
55 | /**
56 | * Cast to string
57 | *
58 | * @return string holded javascript expression.
59 | */
60 | public function __toString(): string
61 | {
62 | return $this->expression;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laminas/laminas-json",
3 | "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP",
4 | "license": "BSD-3-Clause",
5 | "keywords": [
6 | "laminas",
7 | "json"
8 | ],
9 | "homepage": "https://laminas.dev",
10 | "support": {
11 | "docs": "https://docs.laminas.dev/laminas-json/",
12 | "issues": "https://github.com/laminas/laminas-json/issues",
13 | "source": "https://github.com/laminas/laminas-json",
14 | "rss": "https://github.com/laminas/laminas-json/releases.atom",
15 | "chat": "https://laminas.dev/chat",
16 | "forum": "https://discourse.laminas.dev"
17 | },
18 | "config": {
19 | "sort-packages": true,
20 | "allow-plugins": {
21 | "dealerdirect/phpcodesniffer-composer-installer": true
22 | }
23 | },
24 | "abandoned": true,
25 | "require": {
26 | "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
27 | },
28 | "require-dev": {
29 | "laminas/laminas-coding-standard": "~2.4.0",
30 | "laminas/laminas-stdlib": "^2.7.7 || ^3.19",
31 | "phpunit/phpunit": "^9.5.25"
32 | },
33 | "suggest": {
34 | "laminas/laminas-json-server": "For implementing JSON-RPC servers",
35 | "laminas/laminas-xml2json": "For converting XML documents to JSON"
36 | },
37 | "autoload": {
38 | "psr-4": {
39 | "Laminas\\Json\\": "src/"
40 | }
41 | },
42 | "autoload-dev": {
43 | "psr-4": {
44 | "LaminasTest\\Json\\": "test/"
45 | }
46 | },
47 | "scripts": {
48 | "check": [
49 | "@cs-check",
50 | "@test"
51 | ],
52 | "cs-check": "phpcs",
53 | "cs-fix": "phpcbf",
54 | "test": "phpunit --colors=always",
55 | "test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
56 | },
57 | "conflict": {
58 | "zendframework/zend-json": "*"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # laminas-json
2 |
3 | > [!CAUTION]
4 | > This package is **abandoned** and will receive no further development.
5 | >
6 | > See the Technical Steering Committee [meeting minutes](https://github.com/laminas/technical-steering-committee/blob/main/meetings/minutes/2024-11-04-TSC-Minutes.md#archive--abandon-various-legacy-libraries).
7 |
8 | > ## 🇷🇺 Русским гражданам
9 | >
10 | > Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
11 | >
12 | > У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
13 | >
14 | > Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
15 | >
16 | > ## 🇺🇸 To Citizens of Russia
17 | >
18 | > We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
19 | >
20 | > One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
21 | >
22 | > You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
23 |
24 | `Laminas\Json` provides convenience methods for serializing native PHP to JSON and
25 | decoding JSON to native PHP. For more information on JSON, visit the JSON
26 | [project site](http://www.json.org/).
27 |
28 | ## Installation
29 |
30 | Run the following to install this library:
31 |
32 | ```bash
33 | $ composer require laminas/laminas-json
34 | ```
35 |
36 | ## Documentation
37 |
38 | Browse the documentation online at https://docs.laminas.dev/laminas-json/
39 |
--------------------------------------------------------------------------------
/src/Json.php:
--------------------------------------------------------------------------------
1 | toJson();
102 | }
103 |
104 | if (method_exists($valueToEncode, 'toArray')) {
105 | return static::encode($valueToEncode->toArray(), $cycleCheck, $options);
106 | }
107 | }
108 |
109 | // Pre-process and replace javascript expressions with placeholders
110 | $javascriptExpressions = new SplQueue();
111 | if (
112 | isset($options['enableJsonExprFinder'])
113 | && $options['enableJsonExprFinder'] === true
114 | ) {
115 | $valueToEncode = static::recursiveJsonExprFinder($valueToEncode, $javascriptExpressions);
116 | }
117 |
118 | // Encoding
119 | $prettyPrint = isset($options['prettyPrint']) && ($options['prettyPrint'] === true);
120 | $encodedResult = self::encodeValue($valueToEncode, $cycleCheck, $options, $prettyPrint);
121 |
122 | // Post-process to revert back any Laminas\Json\Expr instances.
123 | $encodedResult = self::injectJavascriptExpressions($encodedResult, $javascriptExpressions);
124 |
125 | return $encodedResult;
126 | }
127 |
128 | /**
129 | * Discover and replace javascript expressions with temporary placeholders.
130 | *
131 | * Check each value to determine if it is a Laminas\Json\Expr; if so, replace the value with
132 | * a magic key and add the javascript expression to the queue.
133 | *
134 | * NOTE this method is recursive.
135 | *
136 | * NOTE: This method is used internally by the encode method.
137 | *
138 | * @see encode
139 | *
140 | * @param mixed $value a string - object property to be encoded
141 | * @param null|string|int $currentKey
142 | * @return mixed
143 | */
144 | protected static function recursiveJsonExprFinder(
145 | mixed $value,
146 | SplQueue $javascriptExpressions,
147 | $currentKey = null
148 | ) {
149 | if ($value instanceof Expr) {
150 | // TODO: Optimize with ascii keys, if performance is bad
151 | $magicKey = "____" . $currentKey . "_" . count($javascriptExpressions);
152 |
153 | $javascriptExpressions->enqueue([
154 | // If currentKey is integer, encodeUnicodeString call is not required.
155 | 'magicKey' => is_int($currentKey) ? $magicKey : Encoder::encodeUnicodeString($magicKey),
156 | 'value' => $value,
157 | ]);
158 |
159 | return $magicKey;
160 | }
161 |
162 | if (is_array($value)) {
163 | foreach ($value as $k => $v) {
164 | $value[$k] = static::recursiveJsonExprFinder($value[$k], $javascriptExpressions, $k);
165 | }
166 | return $value;
167 | }
168 |
169 | if (is_object($value)) {
170 | foreach ($value as $k => $v) {
171 | $value->$k = static::recursiveJsonExprFinder($value->$k, $javascriptExpressions, $k);
172 | }
173 | return $value;
174 | }
175 |
176 | return $value;
177 | }
178 |
179 | /**
180 | * Pretty-print JSON string
181 | *
182 | * Use 'indent' option to select indentation string; by default, four
183 | * spaces are used.
184 | *
185 | * @param string $json Original JSON string
186 | * @param array $options Encoding options
187 | * @return string
188 | */
189 | public static function prettyPrint($json, array $options = [])
190 | {
191 | $indentString = $options['indent'] ?? ' ';
192 |
193 | $json = trim($json);
194 | $length = strlen($json);
195 | $stack = [];
196 |
197 | $result = '';
198 | $inLiteral = false;
199 |
200 | for ($i = 0; $i < $length; ++$i) {
201 | switch ($json[$i]) {
202 | case '{':
203 | case '[':
204 | if ($inLiteral) {
205 | break;
206 | }
207 |
208 | $stack[] = $json[$i];
209 |
210 | $result .= $json[$i];
211 | while (isset($json[$i + 1]) && preg_match('/\s/', $json[$i + 1])) {
212 | ++$i;
213 | }
214 | if (isset($json[$i + 1]) && $json[$i + 1] !== '}' && $json[$i + 1] !== ']') {
215 | $result .= "\n" . str_repeat($indentString, count($stack));
216 | }
217 |
218 | continue 2;
219 | case '}':
220 | case ']':
221 | if ($inLiteral) {
222 | break;
223 | }
224 |
225 | $last = end($stack);
226 | if (
227 | ($last === '{' && $json[$i] === '}')
228 | || ($last === '[' && $json[$i] === ']')
229 | ) {
230 | array_pop($stack);
231 | }
232 |
233 | $result .= $json[$i];
234 | while (isset($json[$i + 1]) && preg_match('/\s/', $json[$i + 1])) {
235 | ++$i;
236 | }
237 | if (isset($json[$i + 1]) && ($json[$i + 1] === '}' || $json[$i + 1] === ']')) {
238 | $result .= "\n" . str_repeat($indentString, count($stack) - 1);
239 | }
240 |
241 | continue 2;
242 | case '"':
243 | $result .= '"';
244 |
245 | if (! $inLiteral) {
246 | $inLiteral = true;
247 | } else {
248 | $backslashes = 0;
249 | $n = $i;
250 | while ($json[--$n] === '\\') {
251 | ++$backslashes;
252 | }
253 |
254 | if (($backslashes % 2) === 0) {
255 | $inLiteral = false;
256 |
257 | while (isset($json[$i + 1]) && preg_match('/\s/', $json[$i + 1])) {
258 | ++$i;
259 | }
260 |
261 | if (isset($json[$i + 1]) && ($json[$i + 1] === '}' || $json[$i + 1] === ']')) {
262 | $result .= "\n" . str_repeat($indentString, count($stack) - 1);
263 | }
264 | }
265 | }
266 | continue 2;
267 | case ':':
268 | if (! $inLiteral) {
269 | $result .= ': ';
270 | continue 2;
271 | }
272 | break;
273 | case ',':
274 | if (! $inLiteral) {
275 | $result .= ',' . "\n" . str_repeat($indentString, count($stack));
276 | continue 2;
277 | }
278 | break;
279 | default:
280 | if (! $inLiteral && preg_match('/\s/', $json[$i])) {
281 | continue 2;
282 | }
283 | break;
284 | }
285 |
286 | $result .= $json[$i];
287 |
288 | if ($inLiteral) {
289 | continue;
290 | }
291 |
292 | while (isset($json[$i + 1]) && preg_match('/\s/', $json[$i + 1])) {
293 | ++$i;
294 | }
295 |
296 | if (isset($json[$i + 1]) && ($json[$i + 1] === '}' || $json[$i + 1] === ']')) {
297 | $result .= "\n" . str_repeat($indentString, count($stack) - 1);
298 | }
299 | }
300 |
301 | return $result;
302 | }
303 |
304 | /**
305 | * Decode a value using the PHP built-in json_decode function.
306 | *
307 | * @param string $encodedValue
308 | * @param int $objectDecodeType
309 | * @return mixed
310 | * @throws RuntimeException
311 | */
312 | private static function decodeViaPhpBuiltIn($encodedValue, $objectDecodeType)
313 | {
314 | $decoded = json_decode($encodedValue, (bool) $objectDecodeType);
315 |
316 | switch (json_last_error()) {
317 | case JSON_ERROR_NONE:
318 | return $decoded;
319 | case JSON_ERROR_DEPTH:
320 | throw new RuntimeException('Decoding failed: Maximum stack depth exceeded');
321 | case JSON_ERROR_CTRL_CHAR:
322 | throw new RuntimeException('Decoding failed: Unexpected control character found');
323 | case JSON_ERROR_SYNTAX:
324 | throw new RuntimeException('Decoding failed: Syntax error');
325 | default:
326 | throw new RuntimeException('Decoding failed');
327 | }
328 | }
329 |
330 | /**
331 | * Encode a value to JSON.
332 | *
333 | * Intermediary step between injecting JavaScript expressions.
334 | *
335 | * Delegates to either the PHP built-in json_encode operation, or the
336 | * Encoder component, based on availability of the built-in and/or whether
337 | * or not the component encoder is requested.
338 | *
339 | * @param bool $cycleCheck
340 | * @param array $options
341 | * @param bool $prettyPrint
342 | * @return string
343 | */
344 | private static function encodeValue(mixed $valueToEncode, $cycleCheck, array $options, $prettyPrint)
345 | {
346 | if (function_exists('json_encode') && static::$useBuiltinEncoderDecoder !== true) {
347 | return self::encodeViaPhpBuiltIn($valueToEncode, $prettyPrint);
348 | }
349 |
350 | return self::encodeViaEncoder($valueToEncode, $cycleCheck, $options, $prettyPrint);
351 | }
352 |
353 | /**
354 | * Encode a value to JSON using the PHP built-in json_encode function.
355 | *
356 | * Uses the encoding options:
357 | *
358 | * - JSON_HEX_TAG
359 | * - JSON_HEX_APOS
360 | * - JSON_HEX_QUOT
361 | * - JSON_HEX_AMP
362 | *
363 | * If $prettyPrint is boolean true, also uses JSON_PRETTY_PRINT.
364 | *
365 | * @param bool $prettyPrint
366 | * @return string|false Boolean false return value if json_encode is not
367 | * available, or the $useBuiltinEncoderDecoder flag is enabled.
368 | */
369 | private static function encodeViaPhpBuiltIn(mixed $valueToEncode, $prettyPrint = false)
370 | {
371 | if (! function_exists('json_encode') || static::$useBuiltinEncoderDecoder === true) {
372 | return false;
373 | }
374 |
375 | $encodeOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP;
376 |
377 | if ($prettyPrint) {
378 | $encodeOptions |= JSON_PRETTY_PRINT;
379 | }
380 |
381 | return json_encode($valueToEncode, $encodeOptions);
382 | }
383 |
384 | /**
385 | * Encode a value to JSON using the Encoder class.
386 | *
387 | * Passes the value, cycle check flag, and options to Encoder::encode().
388 | *
389 | * Once the result is returned, determines if pretty printing is required,
390 | * and, if so, returns the result of that operation, otherwise returning
391 | * the encoded value.
392 | *
393 | * @param bool $cycleCheck
394 | * @param array $options
395 | * @param bool $prettyPrint
396 | * @return string
397 | */
398 | private static function encodeViaEncoder(mixed $valueToEncode, $cycleCheck, array $options, $prettyPrint)
399 | {
400 | $encodedResult = Encoder::encode($valueToEncode, $cycleCheck, $options);
401 |
402 | if ($prettyPrint) {
403 | return self::prettyPrint($encodedResult, ['indent' => ' ']);
404 | }
405 |
406 | return $encodedResult;
407 | }
408 |
409 | /**
410 | * Inject javascript expressions into the encoded value.
411 | *
412 | * Loops through each, substituting the "magicKey" of each with its
413 | * associated value.
414 | *
415 | * @param string $encodedValue
416 | * @return string
417 | */
418 | private static function injectJavascriptExpressions($encodedValue, SplQueue $javascriptExpressions)
419 | {
420 | foreach ($javascriptExpressions as $expression) {
421 | $encodedValue = str_replace(
422 | sprintf('"%s"', $expression['magicKey']),
423 | $expression['value'],
424 | (string) $encodedValue
425 | );
426 | }
427 |
428 | return $encodedValue;
429 | }
430 | }
431 |
--------------------------------------------------------------------------------
/src/Decoder.php:
--------------------------------------------------------------------------------
1 | = 0x20) && ($ordChrsC <= 0x7F):
122 | $utf8 .= $chrs[$i];
123 | break;
124 | case ($ordChrsC & 0xE0) === 0xC0:
125 | // characters U-00000080 - U-000007FF, mask 110XXXXX
126 | //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
127 | $utf8 .= substr($chrs, $i, 2);
128 | ++$i;
129 | break;
130 | case ($ordChrsC & 0xF0) === 0xE0:
131 | // characters U-00000800 - U-0000FFFF, mask 1110XXXX
132 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
133 | $utf8 .= substr($chrs, $i, 3);
134 | $i += 2;
135 | break;
136 | case ($ordChrsC & 0xF8) === 0xF0:
137 | // characters U-00010000 - U-001FFFFF, mask 11110XXX
138 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
139 | $utf8 .= substr($chrs, $i, 4);
140 | $i += 3;
141 | break;
142 | case ($ordChrsC & 0xFC) === 0xF8:
143 | // characters U-00200000 - U-03FFFFFF, mask 111110XX
144 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
145 | $utf8 .= substr($chrs, $i, 5);
146 | $i += 4;
147 | break;
148 | case ($ordChrsC & 0xFE) === 0xFC:
149 | // characters U-04000000 - U-7FFFFFFF, mask 1111110X
150 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
151 | $utf8 .= substr($chrs, $i, 6);
152 | $i += 5;
153 | break;
154 | }
155 | }
156 |
157 | return $utf8;
158 | }
159 |
160 | /**
161 | * Constructor
162 | *
163 | * @param string $source String source to decode
164 | * @param int $decodeType How objects should be decoded -- see
165 | * {@link Json::TYPE_ARRAY} and {@link Json::TYPE_OBJECT} for * valid
166 | * values
167 | * @throws InvalidArgumentException
168 | */
169 | protected function __construct($source, $decodeType)
170 | {
171 | // Set defaults
172 | $this->source = self::decodeUnicodeString($source);
173 | $this->sourceLength = strlen($this->source);
174 | $this->token = self::EOF;
175 | $this->offset = 0;
176 |
177 | $this->decodeType = match ($decodeType) {
178 | Json::TYPE_ARRAY, Json::TYPE_OBJECT => $decodeType,
179 | default => throw new InvalidArgumentException(sprintf(
180 | 'Unknown decode type "%s", please use one of the Json::TYPE_* constants',
181 | $decodeType
182 | )),
183 | };
184 |
185 | // Set pointer at first token
186 | $this->getNextToken();
187 | }
188 |
189 | /**
190 | * Decode a JSON source string.
191 | *
192 | * Decodes a JSON encoded string; the value returned will be one of the
193 | * following:
194 | *
195 | * - integer
196 | * - float
197 | * - boolean
198 | * - null
199 | * - stdClass
200 | * - array
201 | * - array of one or more of the above types
202 | *
203 | * By default, decoded objects will be returned as a stdClass object;
204 | * to return associative arrays instead, pass {@link Json::TYPE_ARRAY}
205 | * to the $objectDecodeType parameter.
206 | *
207 | * @param string $source String to be decoded.
208 | * @param int $objectDecodeType How objects should be decoded; should be
209 | * either or {@link Json::TYPE_ARRAY} or {@link Json::TYPE_OBJECT};
210 | * defaults to Json::TYPE_OBJECT.
211 | * @return mixed
212 | */
213 | public static function decode($source, $objectDecodeType = Json::TYPE_OBJECT)
214 | {
215 | $decoder = new static($source, $objectDecodeType);
216 | return $decoder->decodeValue();
217 | }
218 |
219 | /**
220 | * Recursive routine for supported toplevel types.
221 | *
222 | * @return mixed
223 | */
224 | protected function decodeValue()
225 | {
226 | switch ($this->token) {
227 | case self::DATUM:
228 | $result = $this->tokenValue;
229 | $this->getNextToken();
230 | return $result;
231 | case self::LBRACE:
232 | return $this->decodeObject();
233 | case self::LBRACKET:
234 | return $this->decodeArray();
235 | default:
236 | return;
237 | }
238 | }
239 |
240 | /**
241 | * Decodes an object of the form { "attribute: value, "attribute2" : value, ... }
242 | *
243 | * If Laminas\Json\Encoder was used to encode the original object, then
244 | * a special attribute called __className will specify a class
245 | * name with which to wrap the data contained within the encoded source.
246 | *
247 | * Decodes to either an array or stdClass object, based on the value of
248 | * {@link $decodeType}. If invalid $decodeType present, returns as an
249 | * array.
250 | *
251 | * @return array|stdClass
252 | * @throws RuntimeException
253 | */
254 | protected function decodeObject()
255 | {
256 | $members = [];
257 | $tok = $this->getNextToken();
258 |
259 | while ($tok && $tok !== self::RBRACE) {
260 | if ($tok !== self::DATUM || ! is_string($this->tokenValue)) {
261 | throw new RuntimeException(sprintf('Missing key in object encoding: %s', $this->source));
262 | }
263 |
264 | $key = $this->tokenValue;
265 | $tok = $this->getNextToken();
266 |
267 | if ($tok !== self::COLON) {
268 | throw new RuntimeException(sprintf('Missing ":" in object encoding: %s', $this->source));
269 | }
270 |
271 | $this->getNextToken();
272 | $members[$key] = $this->decodeValue();
273 | $tok = $this->token;
274 |
275 | if ($tok === self::RBRACE) {
276 | break;
277 | }
278 |
279 | if ($tok !== self::COMMA) {
280 | throw new RuntimeException(sprintf('Missing "," in object encoding: %s', $this->source));
281 | }
282 |
283 | $tok = $this->getNextToken();
284 | }
285 |
286 | switch ($this->decodeType) {
287 | case Json::TYPE_OBJECT:
288 | // Create new stdClass and populate with $members
289 | $result = new stdClass();
290 | foreach ($members as $key => $value) {
291 | if ($key === '') {
292 | $key = '_empty_';
293 | }
294 | $result->$key = $value;
295 | }
296 | break;
297 | case Json::TYPE_ARRAY:
298 | // intentionally fall-through
299 | default:
300 | $result = $members;
301 | break;
302 | }
303 |
304 | $this->getNextToken();
305 | return $result;
306 | }
307 |
308 | /**
309 | * Decodes the JSON array format [element, element2, ..., elementN]
310 | *
311 | * @return array
312 | * @throws RuntimeException
313 | */
314 | protected function decodeArray()
315 | {
316 | $result = [];
317 | $tok = $this->getNextToken(); // Move past the '['
318 | $index = 0;
319 |
320 | while ($tok && $tok !== self::RBRACKET) {
321 | $result[$index++] = $this->decodeValue();
322 |
323 | $tok = $this->token;
324 |
325 | if ($tok === self::RBRACKET || ! $tok) {
326 | break;
327 | }
328 |
329 | if ($tok !== self::COMMA) {
330 | throw new RuntimeException(sprintf('Missing "," in array encoding: %s', $this->source));
331 | }
332 |
333 | $tok = $this->getNextToken();
334 | }
335 |
336 | $this->getNextToken();
337 | return $result;
338 | }
339 |
340 | /**
341 | * Removes whitespace characters from the source input.
342 | */
343 | protected function eatWhitespace()
344 | {
345 | if (
346 | preg_match('/([\t\b\f\n\r ])*/s', $this->source, $matches, PREG_OFFSET_CAPTURE, $this->offset)
347 | && $matches[0][1] === $this->offset
348 | ) {
349 | $this->offset += strlen($matches[0][0]);
350 | }
351 | }
352 |
353 | /**
354 | * Retrieves the next token from the source stream.
355 | *
356 | * @return int Token constant value specified in class definition.
357 | * @throws RuntimeException
358 | */
359 | protected function getNextToken()
360 | {
361 | $this->token = self::EOF;
362 | $this->tokenValue = null;
363 | $this->eatWhitespace();
364 |
365 | if ($this->offset >= $this->sourceLength) {
366 | return self::EOF;
367 | }
368 |
369 | $str = $this->source;
370 | $strLength = $this->sourceLength;
371 | $i = $this->offset;
372 | $start = $i;
373 |
374 | switch ($str[$i]) {
375 | case '{':
376 | $this->token = self::LBRACE;
377 | break;
378 | case '}':
379 | $this->token = self::RBRACE;
380 | break;
381 | case '[':
382 | $this->token = self::LBRACKET;
383 | break;
384 | case ']':
385 | $this->token = self::RBRACKET;
386 | break;
387 | case ',':
388 | $this->token = self::COMMA;
389 | break;
390 | case ':':
391 | $this->token = self::COLON;
392 | break;
393 | case '"':
394 | $result = '';
395 | do {
396 | $i++;
397 | if ($i >= $strLength) {
398 | break;
399 | }
400 |
401 | $chr = $str[$i];
402 |
403 | if ($chr === '"') {
404 | break;
405 | }
406 |
407 | if ($chr !== '\\') {
408 | $result .= $chr;
409 | continue;
410 | }
411 |
412 | $i++;
413 |
414 | if ($i >= $strLength) {
415 | break;
416 | }
417 |
418 | $chr = $str[$i];
419 | match ($chr) {
420 | '"' => $result .= '"',
421 | '\\' => $result .= '\\',
422 | '/' => $result .= '/',
423 | 'b' => $result .= "\x08",
424 | 'f' => $result .= "\x0c",
425 | 'n' => $result .= "\x0a",
426 | 'r' => $result .= "\x0d",
427 | 't' => $result .= "\x09",
428 | '\'' => $result .= '\'',
429 | default => throw new RuntimeException(sprintf('Illegal escape sequence "%s"', $chr)),
430 | };
431 | } while ($i < $strLength);
432 |
433 | $this->token = self::DATUM;
434 | $this->tokenValue = $result;
435 | break;
436 | case 't':
437 | if (($i + 3) < $strLength && $start === strpos($str, "true", $start)) {
438 | $this->token = self::DATUM;
439 | }
440 | $this->tokenValue = true;
441 | $i += 3;
442 | break;
443 | case 'f':
444 | if (($i + 4) < $strLength && $start === strpos($str, "false", $start)) {
445 | $this->token = self::DATUM;
446 | }
447 | $this->tokenValue = false;
448 | $i += 4;
449 | break;
450 | case 'n':
451 | if (($i + 3) < $strLength && $start === strpos($str, "null", $start)) {
452 | $this->token = self::DATUM;
453 | }
454 | $this->tokenValue = null;
455 | $i += 3;
456 | break;
457 | }
458 |
459 | if ($this->token !== self::EOF) {
460 | $this->offset = $i + 1; // Consume the last token character
461 | return $this->token;
462 | }
463 |
464 | $chr = $str[$i];
465 |
466 | if ($chr !== '-' && $chr !== '.' && ($chr < '0' || $chr > '9')) {
467 | throw new RuntimeException('Illegal Token');
468 | }
469 |
470 | if (
471 | preg_match('/-?([0-9])*(\.[0-9]*)?((e|E)((-|\+)?)[0-9]+)?/s', $str, $matches, PREG_OFFSET_CAPTURE, $start)
472 | && $matches[0][1] === $start
473 | ) {
474 | $datum = $matches[0][0];
475 |
476 | if (! is_numeric($datum)) {
477 | throw new RuntimeException(sprintf('Illegal number format: %s', $datum));
478 | }
479 |
480 | if (preg_match('/^0\d+$/', $datum)) {
481 | throw new RuntimeException(sprintf('Octal notation not supported by JSON (value: %o)', $datum));
482 | }
483 |
484 | $val = intval($datum);
485 | $fVal = floatval($datum);
486 |
487 | // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator
488 | $this->tokenValue = $val == $fVal ? $val : $fVal;
489 | $this->token = self::DATUM;
490 | $this->offset = $start + strlen($datum);
491 | }
492 |
493 | return $this->token;
494 | }
495 |
496 | /**
497 | * Convert a string from one UTF-16 char to one UTF-8 char.
498 | *
499 | * Normally should be handled by mb_convert_encoding, but provides a slower
500 | * PHP-only method for installations that lack the multibyte string
501 | * extension.
502 | *
503 | * This method is from the Solar Framework by Paul M. Jones.
504 | *
505 | * @link http://solarphp.com
506 | *
507 | * @param string $utf16 UTF-16 character
508 | * @return string UTF-8 character
509 | */
510 | protected static function utf162utf8($utf16)
511 | {
512 | // Check for mb extension otherwise do by hand.
513 | if (function_exists('mb_convert_encoding')) {
514 | return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
515 | }
516 |
517 | $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
518 | return match (true) {
519 | // This case should never be reached, because we are in ASCII range;
520 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
521 | (0x7F & $bytes) === $bytes => chr(0x7F & $bytes),
522 |
523 | // Return a 2-byte UTF-8 character;
524 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
525 | (0x07FF & $bytes) === $bytes => chr(0xC0 | (($bytes >> 6) & 0x1F))
526 | . chr(0x80 | ($bytes & 0x3F)),
527 |
528 | // Return a 3-byte UTF-8 character;
529 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
530 | (0xFFFF & $bytes) === $bytes => chr(0xE0 | (($bytes >> 12) & 0x0F))
531 | . chr(0x80 | (($bytes >> 6) & 0x3F))
532 | . chr(0x80 | ($bytes & 0x3F)),
533 |
534 | // ignoring UTF-32 for now, sorry
535 | default => '',
536 | };
537 | }
538 | }
539 |
--------------------------------------------------------------------------------
/src/Encoder.php:
--------------------------------------------------------------------------------
1 | jsonSerialize();
71 | }
72 |
73 | return $encoder->encodeValue($value);
74 | }
75 |
76 | /**
77 | * Encode a value to JSON.
78 | *
79 | * Recursive method which determines the type of value to be encoded
80 | * and then dispatches to the appropriate method.
81 | *
82 | * $values are either
83 | * - objects (returns from {@link encodeObject()})
84 | * - arrays (returns from {@link encodeArray()})
85 | * - scalars (returns from {@link encodeDatum()})
86 | *
87 | * @param mixed $value The value to be encoded.
88 | * @return string Encoded value.
89 | */
90 | protected function encodeValue(mixed &$value)
91 | {
92 | if (is_object($value)) {
93 | return $this->encodeObject($value);
94 | }
95 |
96 | if (is_array($value)) {
97 | return $this->encodeArray($value);
98 | }
99 |
100 | return $this->encodeDatum($value);
101 | }
102 |
103 | /**
104 | * Encode an object to JSON by encoding each of the public properties.
105 | *
106 | * A special property is added to the JSON object called '__className' that
107 | * contains the classname of $value; this can be used by consumers of the
108 | * resulting JSON to cast to the specific class.
109 | *
110 | * @param object $value
111 | * @return string
112 | * @throws RecursionException If recursive checks are enabled and the
113 | * object has been serialized previously.
114 | */
115 | protected function encodeObject(&$value)
116 | {
117 | if ($this->cycleCheck) {
118 | if ($this->wasVisited($value)) {
119 | if (
120 | ! isset($this->options['silenceCyclicalExceptions'])
121 | || $this->options['silenceCyclicalExceptions'] !== true
122 | ) {
123 | throw new RecursionException(sprintf(
124 | 'Cycles not supported in JSON encoding; cycle introduced by class "%s"',
125 | $value::class
126 | ));
127 | }
128 |
129 | return '"* RECURSION (' . str_replace('\\', '\\\\', $value::class) . ') *"';
130 | }
131 |
132 | $this->visited[] = $value;
133 | }
134 |
135 | $props = '';
136 |
137 | if (method_exists($value, 'toJson')) {
138 | $props = ',' . preg_replace("/^\{(.*)\}$/", "\\1", $value->toJson());
139 | } else {
140 | if ($value instanceof IteratorAggregate) {
141 | $propCollection = $value->getIterator();
142 | } elseif ($value instanceof Iterator) {
143 | $propCollection = $value;
144 | } else {
145 | $propCollection = get_object_vars($value);
146 | }
147 |
148 | foreach ($propCollection as $name => $propValue) {
149 | if (! isset($propValue)) {
150 | continue;
151 | }
152 |
153 | $props .= ','
154 | . $this->encodeValue($name)
155 | . ':'
156 | . $this->encodeValue($propValue);
157 | }
158 | }
159 |
160 | $className = $value::class;
161 | return '{"__className":'
162 | . $this->encodeString($className)
163 | . $props . '}';
164 | }
165 |
166 | /**
167 | * Determine if an object has been serialized already.
168 | *
169 | * @return bool
170 | */
171 | protected function wasVisited(mixed &$value)
172 | {
173 | if (in_array($value, $this->visited, true)) {
174 | return true;
175 | }
176 |
177 | return false;
178 | }
179 |
180 | /**
181 | * JSON encode an array value.
182 | *
183 | * Recursively encodes each value of an array and returns a JSON encoded
184 | * array string.
185 | *
186 | * Arrays are defined as integer-indexed arrays starting at index 0, where
187 | * the last index is (count($array) -1); any deviation from that is
188 | * considered an associative array, and will be passed to
189 | * {@link encodeAssociativeArray()}.
190 | *
191 | * @param array $array
192 | * @return string
193 | */
194 | protected function encodeArray($array)
195 | {
196 | // Check for associative array
197 | if (! empty($array) && (array_keys($array) !== range(0, count($array) - 1))) {
198 | // Associative array
199 | return $this->encodeAssociativeArray($array);
200 | }
201 |
202 | // Indexed array
203 | $tmpArray = [];
204 | $result = '[';
205 | $length = count($array);
206 |
207 | for ($i = 0; $i < $length; $i++) {
208 | $tmpArray[] = $this->encodeValue($array[$i]);
209 | }
210 |
211 | $result .= implode(',', $tmpArray);
212 | $result .= ']';
213 |
214 | return $result;
215 | }
216 |
217 | /**
218 | * Encode an associative array to JSON.
219 | *
220 | * JSON does not have a concept of associative arrays; as such, we encode
221 | * them to objects.
222 | *
223 | * @param array $array Array to encode.
224 | * @return string
225 | */
226 | protected function encodeAssociativeArray($array)
227 | {
228 | $tmpArray = [];
229 | $result = '{';
230 |
231 | foreach ($array as $key => $value) {
232 | $tmpArray[] = sprintf(
233 | '%s:%s',
234 | $this->encodeString((string) $key),
235 | $this->encodeValue($value)
236 | );
237 | }
238 |
239 | $result .= implode(',', $tmpArray);
240 | $result .= '}';
241 | return $result;
242 | }
243 |
244 | /**
245 | * JSON encode a scalar data type (string, number, boolean, null).
246 | *
247 | * If value type is not a string, number, boolean, or null, the string
248 | * 'null' is returned.
249 | *
250 | * @return string
251 | */
252 | protected function encodeDatum(mixed $value)
253 | {
254 | if (is_int($value) || is_float($value)) {
255 | return str_replace(',', '.', (string) $value);
256 | }
257 |
258 | if (is_string($value)) {
259 | return $this->encodeString($value);
260 | }
261 |
262 | if (is_bool($value)) {
263 | return $value ? 'true' : 'false';
264 | }
265 |
266 | return 'null';
267 | }
268 |
269 | /**
270 | * JSON encode a string value by escaping characters as necessary.
271 | *
272 | * @param string $string
273 | * @return string
274 | */
275 | protected function encodeString($string)
276 | {
277 | // @codingStandardsIgnoreStart
278 | // Escape these characters with a backslash or unicode escape:
279 | // " \ / \n \r \t \b \f
280 | $search = ['\\', "\n", "\t", "\r", "\b", "\f", '"', '\'', '&', '<', '>', '/'];
281 | $replace = ['\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\\u0022', '\\u0027', '\\u0026', '\\u003C', '\\u003E', '\\/'];
282 | $string = str_replace($search, $replace, $string);
283 | // @codingStandardsIgnoreEnd
284 |
285 | // Escape certain ASCII characters:
286 | // 0x08 => \b
287 | // 0x0c => \f
288 | $string = str_replace([chr(0x08), chr(0x0C)], ['\b', '\f'], $string);
289 | $string = self::encodeUnicodeString($string);
290 |
291 | return '"' . $string . '"';
292 | }
293 |
294 | /**
295 | * Encode the constants associated with the ReflectionClass parameter.
296 | *
297 | * The encoding format is based on the class2 format.
298 | *
299 | * @return string Encoded constant block in class2 format
300 | */
301 | private static function encodeConstants(ReflectionClass $class)
302 | {
303 | $result = "constants:{";
304 | $constants = $class->getConstants();
305 |
306 | if (empty($constants)) {
307 | return $result . '}';
308 | }
309 |
310 | $tmpArray = [];
311 | foreach ($constants as $key => $value) {
312 | $tmpArray[] = sprintf('%s: %s', $key, self::encode($value));
313 | }
314 |
315 | $result .= implode(', ', $tmpArray);
316 |
317 | return $result . "}";
318 | }
319 |
320 | /**
321 | * Encode the public methods of the ReflectionClass in the class2 format
322 | *
323 | * @return string Encoded method fragment.
324 | */
325 | private static function encodeMethods(ReflectionClass $class)
326 | {
327 | $result = 'methods:{';
328 | $started = false;
329 |
330 | foreach ($class->getMethods() as $method) {
331 | if (! $method->isPublic() || ! $method->isUserDefined()) {
332 | continue;
333 | }
334 |
335 | if ($started) {
336 | $result .= ',';
337 | }
338 | $started = true;
339 |
340 | $result .= sprintf('%s:function(', $method->getName());
341 |
342 | if ('__construct' === $method->getName()) {
343 | $result .= '){}';
344 | continue;
345 | }
346 |
347 | $argsStarted = false;
348 | $argNames = "var argNames=[";
349 |
350 | foreach ($method->getParameters() as $param) {
351 | if ($argsStarted) {
352 | $result .= ',';
353 | }
354 |
355 | $result .= $param->getName();
356 |
357 | if ($argsStarted) {
358 | $argNames .= ',';
359 | }
360 |
361 | $argNames .= sprintf('"%s"', $param->getName());
362 | $argsStarted = true;
363 | }
364 | $argNames .= "];";
365 |
366 | $result .= "){"
367 | . $argNames
368 | . 'var result = ZAjaxEngine.invokeRemoteMethod('
369 | . "this, '"
370 | . $method->getName()
371 | . "',argNames,arguments);"
372 | . 'return(result);}';
373 | }
374 |
375 | return $result . "}";
376 | }
377 |
378 | /**
379 | * Encode the public properties of the ReflectionClass in the class2 format.
380 | *
381 | * @return string Encode properties list
382 | */
383 | private static function encodeVariables(ReflectionClass $class)
384 | {
385 | $propValues = get_class_vars($class->getName());
386 | $result = "variables:{";
387 | $tmpArray = [];
388 |
389 | foreach ($class->getProperties() as $prop) {
390 | if (! $prop->isPublic()) {
391 | continue;
392 | }
393 |
394 | $name = $prop->getName();
395 | $tmpArray[] = sprintf('%s:%s', $name, self::encode($propValues[$name]));
396 | }
397 |
398 | $result .= implode(',', $tmpArray);
399 |
400 | return $result . "}";
401 | }
402 |
403 | /**
404 | * Encodes the given $className into the class2 model of encoding PHP classes into JavaScript class2 classes.
405 | *
406 | * NOTE: Currently only public methods and variables are proxied onto the
407 | * client machine
408 | *
409 | * @param string $className The name of the class, the class must be
410 | * instantiable using a null constructor.
411 | * @param string $package Optional package name appended to JavaScript
412 | * proxy class name.
413 | * @return string The class2 (JavaScript) encoding of the class.
414 | * @throws InvalidArgumentException
415 | */
416 | public static function encodeClass($className, $package = '')
417 | {
418 | $class = new ReflectionClass($className);
419 | if (! $class->isInstantiable()) {
420 | throw new InvalidArgumentException(sprintf(
421 | '"%s" must be instantiable',
422 | $className
423 | ));
424 | }
425 |
426 | return sprintf(
427 | 'Class.create(\'%s%s\',{%s,%s,%s});',
428 | $package,
429 | $className,
430 | self::encodeConstants($class),
431 | self::encodeMethods($class),
432 | self::encodeVariables($class)
433 | );
434 | }
435 |
436 | /**
437 | * Encode several classes at once.
438 | *
439 | * Returns JSON encoded classes, using {@link encodeClass()}.
440 | *
441 | * @param string[] $classNames
442 | * @param string $package
443 | * @return string
444 | */
445 | public static function encodeClasses(array $classNames, $package = '')
446 | {
447 | $result = '';
448 | foreach ($classNames as $className) {
449 | $result .= static::encodeClass($className, $package);
450 | }
451 |
452 | return $result;
453 | }
454 |
455 | /**
456 | * Encode Unicode Characters to \u0000 ASCII syntax.
457 | *
458 | * This algorithm was originally developed for the Solar Framework by Paul
459 | * M. Jones.
460 | *
461 | * @link http://solarphp.com/
462 | * @link https://github.com/solarphp/core/blob/master/Solar/Json.php
463 | *
464 | * @param string $value
465 | * @return string
466 | */
467 | public static function encodeUnicodeString($value)
468 | {
469 | $strlenVar = strlen($value);
470 | $ascii = "";
471 |
472 | // Iterate over every character in the string, escaping with a slash or
473 | // encoding to UTF-8 where necessary.
474 | for ($i = 0; $i < $strlenVar; $i++) {
475 | $ordVarC = ord($value[$i]);
476 |
477 | switch (true) {
478 | case ($ordVarC >= 0x20) && ($ordVarC <= 0x7F):
479 | // characters U-00000000 - U-0000007F (same as ASCII)
480 | $ascii .= $value[$i];
481 | break;
482 |
483 | case ($ordVarC & 0xE0) === 0xC0:
484 | // characters U-00000080 - U-000007FF, mask 110XXXXX
485 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
486 | $char = pack('C*', $ordVarC, ord($value[$i + 1]));
487 | $i += 1;
488 | $utf16 = self::utf82utf16($char);
489 | $ascii .= sprintf('\u%04s', bin2hex($utf16));
490 | break;
491 |
492 | case ($ordVarC & 0xF0) === 0xE0:
493 | // characters U-00000800 - U-0000FFFF, mask 1110XXXX
494 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
495 | $char = pack(
496 | 'C*',
497 | $ordVarC,
498 | ord($value[$i + 1]),
499 | ord($value[$i + 2])
500 | );
501 | $i += 2;
502 | $utf16 = self::utf82utf16($char);
503 | $ascii .= sprintf('\u%04s', bin2hex($utf16));
504 | break;
505 |
506 | case ($ordVarC & 0xF8) === 0xF0:
507 | // characters U-00010000 - U-001FFFFF, mask 11110XXX
508 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
509 | $char = pack(
510 | 'C*',
511 | $ordVarC,
512 | ord($value[$i + 1]),
513 | ord($value[$i + 2]),
514 | ord($value[$i + 3])
515 | );
516 | $i += 3;
517 | $utf16 = self::utf82utf16($char);
518 | $ascii .= sprintf('\u%04s', bin2hex($utf16));
519 | break;
520 |
521 | case ($ordVarC & 0xFC) === 0xF8:
522 | // characters U-00200000 - U-03FFFFFF, mask 111110XX
523 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
524 | $char = pack(
525 | 'C*',
526 | $ordVarC,
527 | ord($value[$i + 1]),
528 | ord($value[$i + 2]),
529 | ord($value[$i + 3]),
530 | ord($value[$i + 4])
531 | );
532 | $i += 4;
533 | $utf16 = self::utf82utf16($char);
534 | $ascii .= sprintf('\u%04s', bin2hex($utf16));
535 | break;
536 |
537 | case ($ordVarC & 0xFE) === 0xFC:
538 | // characters U-04000000 - U-7FFFFFFF, mask 1111110X
539 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
540 | $char = pack(
541 | 'C*',
542 | $ordVarC,
543 | ord($value[$i + 1]),
544 | ord($value[$i + 2]),
545 | ord($value[$i + 3]),
546 | ord($value[$i + 4]),
547 | ord($value[$i + 5])
548 | );
549 | $i += 5;
550 | $utf16 = self::utf82utf16($char);
551 | $ascii .= sprintf('\u%04s', bin2hex($utf16));
552 | break;
553 | }
554 | }
555 |
556 | return $ascii;
557 | }
558 |
559 | /**
560 | * Convert a string from one UTF-8 char to one UTF-16 char.
561 | *
562 | * Normally should be handled by mb_convert_encoding, but provides a slower
563 | * PHP-only method for installations that lack the multibyte string
564 | * extension.
565 | *
566 | * This method is from the Solar Framework by Paul M. Jones.
567 | *
568 | * @link http://solarphp.com
569 | *
570 | * @param string $utf8 UTF-8 character
571 | * @return string UTF-16 character
572 | */
573 | protected static function utf82utf16($utf8)
574 | {
575 | // Check for mb extension otherwise do by hand.
576 | if (function_exists('mb_convert_encoding')) {
577 | return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
578 | }
579 | return match (strlen($utf8)) {
580 | // This case should never be reached, because we are in ASCII range;
581 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
582 | 1 => $utf8,
583 |
584 | // Return a UTF-16 character from a 2-byte UTF-8 char;
585 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
586 | 2 => chr(0x07 & (ord($utf8[0]) >> 2)) . chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1]))),
587 |
588 | // Return a UTF-16 character from a 3-byte UTF-8 char;
589 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
590 | 3 => chr((0xF0 & (ord($utf8[0]) << 4))
591 | | (0x0F & (ord($utf8[1]) >> 2))) . chr((0xC0 & (ord($utf8[1]) << 6))
592 | | (0x7F & ord($utf8[2]))),
593 |
594 | // ignoring UTF-32 for now, sorry
595 | default => '',
596 | };
597 | }
598 | }
599 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "cc2a865b63a5f1c025c814ec3c253e06",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "dealerdirect/phpcodesniffer-composer-installer",
12 | "version": "v0.7.2",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
16 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
21 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "composer-plugin-api": "^1.0 || ^2.0",
26 | "php": ">=5.3",
27 | "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
28 | },
29 | "require-dev": {
30 | "composer/composer": "*",
31 | "php-parallel-lint/php-parallel-lint": "^1.3.1",
32 | "phpcompatibility/php-compatibility": "^9.0"
33 | },
34 | "type": "composer-plugin",
35 | "extra": {
36 | "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
37 | },
38 | "autoload": {
39 | "psr-4": {
40 | "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
41 | }
42 | },
43 | "notification-url": "https://packagist.org/downloads/",
44 | "license": [
45 | "MIT"
46 | ],
47 | "authors": [
48 | {
49 | "name": "Franck Nijhof",
50 | "email": "franck.nijhof@dealerdirect.com",
51 | "homepage": "http://www.frenck.nl",
52 | "role": "Developer / IT Manager"
53 | },
54 | {
55 | "name": "Contributors",
56 | "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors"
57 | }
58 | ],
59 | "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
60 | "homepage": "http://www.dealerdirect.com",
61 | "keywords": [
62 | "PHPCodeSniffer",
63 | "PHP_CodeSniffer",
64 | "code quality",
65 | "codesniffer",
66 | "composer",
67 | "installer",
68 | "phpcbf",
69 | "phpcs",
70 | "plugin",
71 | "qa",
72 | "quality",
73 | "standard",
74 | "standards",
75 | "style guide",
76 | "stylecheck",
77 | "tests"
78 | ],
79 | "support": {
80 | "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
81 | "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
82 | },
83 | "time": "2022-02-04T12:51:07+00:00"
84 | },
85 | {
86 | "name": "doctrine/instantiator",
87 | "version": "2.0.0",
88 | "source": {
89 | "type": "git",
90 | "url": "https://github.com/doctrine/instantiator.git",
91 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
92 | },
93 | "dist": {
94 | "type": "zip",
95 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
96 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
97 | "shasum": ""
98 | },
99 | "require": {
100 | "php": "^8.1"
101 | },
102 | "require-dev": {
103 | "doctrine/coding-standard": "^11",
104 | "ext-pdo": "*",
105 | "ext-phar": "*",
106 | "phpbench/phpbench": "^1.2",
107 | "phpstan/phpstan": "^1.9.4",
108 | "phpstan/phpstan-phpunit": "^1.3",
109 | "phpunit/phpunit": "^9.5.27",
110 | "vimeo/psalm": "^5.4"
111 | },
112 | "type": "library",
113 | "autoload": {
114 | "psr-4": {
115 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
116 | }
117 | },
118 | "notification-url": "https://packagist.org/downloads/",
119 | "license": [
120 | "MIT"
121 | ],
122 | "authors": [
123 | {
124 | "name": "Marco Pivetta",
125 | "email": "ocramius@gmail.com",
126 | "homepage": "https://ocramius.github.io/"
127 | }
128 | ],
129 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
130 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
131 | "keywords": [
132 | "constructor",
133 | "instantiate"
134 | ],
135 | "support": {
136 | "issues": "https://github.com/doctrine/instantiator/issues",
137 | "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
138 | },
139 | "funding": [
140 | {
141 | "url": "https://www.doctrine-project.org/sponsorship.html",
142 | "type": "custom"
143 | },
144 | {
145 | "url": "https://www.patreon.com/phpdoctrine",
146 | "type": "patreon"
147 | },
148 | {
149 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
150 | "type": "tidelift"
151 | }
152 | ],
153 | "time": "2022-12-30T00:23:10+00:00"
154 | },
155 | {
156 | "name": "laminas/laminas-coding-standard",
157 | "version": "2.4.0",
158 | "source": {
159 | "type": "git",
160 | "url": "https://github.com/laminas/laminas-coding-standard.git",
161 | "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc"
162 | },
163 | "dist": {
164 | "type": "zip",
165 | "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/eb076dd86aa93dd424856b150c9b6f76c1fdfabc",
166 | "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc",
167 | "shasum": ""
168 | },
169 | "require": {
170 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
171 | "php": "^7.4 || ^8.0",
172 | "slevomat/coding-standard": "^7.0",
173 | "squizlabs/php_codesniffer": "^3.6",
174 | "webimpress/coding-standard": "^1.2"
175 | },
176 | "conflict": {
177 | "phpstan/phpdoc-parser": ">=1.6.0"
178 | },
179 | "type": "phpcodesniffer-standard",
180 | "autoload": {
181 | "psr-4": {
182 | "LaminasCodingStandard\\": "src/LaminasCodingStandard/"
183 | }
184 | },
185 | "notification-url": "https://packagist.org/downloads/",
186 | "license": [
187 | "BSD-3-Clause"
188 | ],
189 | "description": "Laminas Coding Standard",
190 | "homepage": "https://laminas.dev",
191 | "keywords": [
192 | "Coding Standard",
193 | "laminas"
194 | ],
195 | "support": {
196 | "chat": "https://laminas.dev/chat",
197 | "docs": "https://docs.laminas.dev/laminas-coding-standard/",
198 | "forum": "https://discourse.laminas.dev",
199 | "issues": "https://github.com/laminas/laminas-coding-standard/issues",
200 | "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom",
201 | "source": "https://github.com/laminas/laminas-coding-standard"
202 | },
203 | "funding": [
204 | {
205 | "url": "https://funding.communitybridge.org/projects/laminas-project",
206 | "type": "community_bridge"
207 | }
208 | ],
209 | "time": "2022-08-24T17:45:47+00:00"
210 | },
211 | {
212 | "name": "laminas/laminas-stdlib",
213 | "version": "3.19.0",
214 | "source": {
215 | "type": "git",
216 | "url": "https://github.com/laminas/laminas-stdlib.git",
217 | "reference": "6a192dd0882b514e45506f533b833b623b78fff3"
218 | },
219 | "dist": {
220 | "type": "zip",
221 | "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/6a192dd0882b514e45506f533b833b623b78fff3",
222 | "reference": "6a192dd0882b514e45506f533b833b623b78fff3",
223 | "shasum": ""
224 | },
225 | "require": {
226 | "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
227 | },
228 | "conflict": {
229 | "zendframework/zend-stdlib": "*"
230 | },
231 | "require-dev": {
232 | "laminas/laminas-coding-standard": "^2.5",
233 | "phpbench/phpbench": "^1.2.15",
234 | "phpunit/phpunit": "^10.5.8",
235 | "psalm/plugin-phpunit": "^0.18.4",
236 | "vimeo/psalm": "^5.20.0"
237 | },
238 | "type": "library",
239 | "autoload": {
240 | "psr-4": {
241 | "Laminas\\Stdlib\\": "src/"
242 | }
243 | },
244 | "notification-url": "https://packagist.org/downloads/",
245 | "license": [
246 | "BSD-3-Clause"
247 | ],
248 | "description": "SPL extensions, array utilities, error handlers, and more",
249 | "homepage": "https://laminas.dev",
250 | "keywords": [
251 | "laminas",
252 | "stdlib"
253 | ],
254 | "support": {
255 | "chat": "https://laminas.dev/chat",
256 | "docs": "https://docs.laminas.dev/laminas-stdlib/",
257 | "forum": "https://discourse.laminas.dev",
258 | "issues": "https://github.com/laminas/laminas-stdlib/issues",
259 | "rss": "https://github.com/laminas/laminas-stdlib/releases.atom",
260 | "source": "https://github.com/laminas/laminas-stdlib"
261 | },
262 | "funding": [
263 | {
264 | "url": "https://funding.communitybridge.org/projects/laminas-project",
265 | "type": "community_bridge"
266 | }
267 | ],
268 | "time": "2024-01-19T12:39:49+00:00"
269 | },
270 | {
271 | "name": "myclabs/deep-copy",
272 | "version": "1.11.1",
273 | "source": {
274 | "type": "git",
275 | "url": "https://github.com/myclabs/DeepCopy.git",
276 | "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
277 | },
278 | "dist": {
279 | "type": "zip",
280 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
281 | "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
282 | "shasum": ""
283 | },
284 | "require": {
285 | "php": "^7.1 || ^8.0"
286 | },
287 | "conflict": {
288 | "doctrine/collections": "<1.6.8",
289 | "doctrine/common": "<2.13.3 || >=3,<3.2.2"
290 | },
291 | "require-dev": {
292 | "doctrine/collections": "^1.6.8",
293 | "doctrine/common": "^2.13.3 || ^3.2.2",
294 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
295 | },
296 | "type": "library",
297 | "autoload": {
298 | "files": [
299 | "src/DeepCopy/deep_copy.php"
300 | ],
301 | "psr-4": {
302 | "DeepCopy\\": "src/DeepCopy/"
303 | }
304 | },
305 | "notification-url": "https://packagist.org/downloads/",
306 | "license": [
307 | "MIT"
308 | ],
309 | "description": "Create deep copies (clones) of your objects",
310 | "keywords": [
311 | "clone",
312 | "copy",
313 | "duplicate",
314 | "object",
315 | "object graph"
316 | ],
317 | "support": {
318 | "issues": "https://github.com/myclabs/DeepCopy/issues",
319 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
320 | },
321 | "funding": [
322 | {
323 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
324 | "type": "tidelift"
325 | }
326 | ],
327 | "time": "2023-03-08T13:26:56+00:00"
328 | },
329 | {
330 | "name": "nikic/php-parser",
331 | "version": "v4.17.1",
332 | "source": {
333 | "type": "git",
334 | "url": "https://github.com/nikic/PHP-Parser.git",
335 | "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
336 | },
337 | "dist": {
338 | "type": "zip",
339 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
340 | "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
341 | "shasum": ""
342 | },
343 | "require": {
344 | "ext-tokenizer": "*",
345 | "php": ">=7.0"
346 | },
347 | "require-dev": {
348 | "ircmaxell/php-yacc": "^0.0.7",
349 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
350 | },
351 | "bin": [
352 | "bin/php-parse"
353 | ],
354 | "type": "library",
355 | "extra": {
356 | "branch-alias": {
357 | "dev-master": "4.9-dev"
358 | }
359 | },
360 | "autoload": {
361 | "psr-4": {
362 | "PhpParser\\": "lib/PhpParser"
363 | }
364 | },
365 | "notification-url": "https://packagist.org/downloads/",
366 | "license": [
367 | "BSD-3-Clause"
368 | ],
369 | "authors": [
370 | {
371 | "name": "Nikita Popov"
372 | }
373 | ],
374 | "description": "A PHP parser written in PHP",
375 | "keywords": [
376 | "parser",
377 | "php"
378 | ],
379 | "support": {
380 | "issues": "https://github.com/nikic/PHP-Parser/issues",
381 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
382 | },
383 | "time": "2023-08-13T19:53:39+00:00"
384 | },
385 | {
386 | "name": "phar-io/manifest",
387 | "version": "2.0.3",
388 | "source": {
389 | "type": "git",
390 | "url": "https://github.com/phar-io/manifest.git",
391 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
392 | },
393 | "dist": {
394 | "type": "zip",
395 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
396 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
397 | "shasum": ""
398 | },
399 | "require": {
400 | "ext-dom": "*",
401 | "ext-phar": "*",
402 | "ext-xmlwriter": "*",
403 | "phar-io/version": "^3.0.1",
404 | "php": "^7.2 || ^8.0"
405 | },
406 | "type": "library",
407 | "extra": {
408 | "branch-alias": {
409 | "dev-master": "2.0.x-dev"
410 | }
411 | },
412 | "autoload": {
413 | "classmap": [
414 | "src/"
415 | ]
416 | },
417 | "notification-url": "https://packagist.org/downloads/",
418 | "license": [
419 | "BSD-3-Clause"
420 | ],
421 | "authors": [
422 | {
423 | "name": "Arne Blankerts",
424 | "email": "arne@blankerts.de",
425 | "role": "Developer"
426 | },
427 | {
428 | "name": "Sebastian Heuer",
429 | "email": "sebastian@phpeople.de",
430 | "role": "Developer"
431 | },
432 | {
433 | "name": "Sebastian Bergmann",
434 | "email": "sebastian@phpunit.de",
435 | "role": "Developer"
436 | }
437 | ],
438 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
439 | "support": {
440 | "issues": "https://github.com/phar-io/manifest/issues",
441 | "source": "https://github.com/phar-io/manifest/tree/2.0.3"
442 | },
443 | "time": "2021-07-20T11:28:43+00:00"
444 | },
445 | {
446 | "name": "phar-io/version",
447 | "version": "3.2.1",
448 | "source": {
449 | "type": "git",
450 | "url": "https://github.com/phar-io/version.git",
451 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
452 | },
453 | "dist": {
454 | "type": "zip",
455 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
456 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
457 | "shasum": ""
458 | },
459 | "require": {
460 | "php": "^7.2 || ^8.0"
461 | },
462 | "type": "library",
463 | "autoload": {
464 | "classmap": [
465 | "src/"
466 | ]
467 | },
468 | "notification-url": "https://packagist.org/downloads/",
469 | "license": [
470 | "BSD-3-Clause"
471 | ],
472 | "authors": [
473 | {
474 | "name": "Arne Blankerts",
475 | "email": "arne@blankerts.de",
476 | "role": "Developer"
477 | },
478 | {
479 | "name": "Sebastian Heuer",
480 | "email": "sebastian@phpeople.de",
481 | "role": "Developer"
482 | },
483 | {
484 | "name": "Sebastian Bergmann",
485 | "email": "sebastian@phpunit.de",
486 | "role": "Developer"
487 | }
488 | ],
489 | "description": "Library for handling version information and constraints",
490 | "support": {
491 | "issues": "https://github.com/phar-io/version/issues",
492 | "source": "https://github.com/phar-io/version/tree/3.2.1"
493 | },
494 | "time": "2022-02-21T01:04:05+00:00"
495 | },
496 | {
497 | "name": "phpstan/phpdoc-parser",
498 | "version": "1.5.1",
499 | "source": {
500 | "type": "git",
501 | "url": "https://github.com/phpstan/phpdoc-parser.git",
502 | "reference": "981cc368a216c988e862a75e526b6076987d1b50"
503 | },
504 | "dist": {
505 | "type": "zip",
506 | "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50",
507 | "reference": "981cc368a216c988e862a75e526b6076987d1b50",
508 | "shasum": ""
509 | },
510 | "require": {
511 | "php": "^7.2 || ^8.0"
512 | },
513 | "require-dev": {
514 | "php-parallel-lint/php-parallel-lint": "^1.2",
515 | "phpstan/extension-installer": "^1.0",
516 | "phpstan/phpstan": "^1.5",
517 | "phpstan/phpstan-strict-rules": "^1.0",
518 | "phpunit/phpunit": "^9.5",
519 | "symfony/process": "^5.2"
520 | },
521 | "type": "library",
522 | "autoload": {
523 | "psr-4": {
524 | "PHPStan\\PhpDocParser\\": [
525 | "src/"
526 | ]
527 | }
528 | },
529 | "notification-url": "https://packagist.org/downloads/",
530 | "license": [
531 | "MIT"
532 | ],
533 | "description": "PHPDoc parser with support for nullable, intersection and generic types",
534 | "support": {
535 | "issues": "https://github.com/phpstan/phpdoc-parser/issues",
536 | "source": "https://github.com/phpstan/phpdoc-parser/tree/1.5.1"
537 | },
538 | "time": "2022-05-05T11:32:40+00:00"
539 | },
540 | {
541 | "name": "phpunit/php-code-coverage",
542 | "version": "9.2.29",
543 | "source": {
544 | "type": "git",
545 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
546 | "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76"
547 | },
548 | "dist": {
549 | "type": "zip",
550 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76",
551 | "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76",
552 | "shasum": ""
553 | },
554 | "require": {
555 | "ext-dom": "*",
556 | "ext-libxml": "*",
557 | "ext-xmlwriter": "*",
558 | "nikic/php-parser": "^4.15",
559 | "php": ">=7.3",
560 | "phpunit/php-file-iterator": "^3.0.3",
561 | "phpunit/php-text-template": "^2.0.2",
562 | "sebastian/code-unit-reverse-lookup": "^2.0.2",
563 | "sebastian/complexity": "^2.0",
564 | "sebastian/environment": "^5.1.2",
565 | "sebastian/lines-of-code": "^1.0.3",
566 | "sebastian/version": "^3.0.1",
567 | "theseer/tokenizer": "^1.2.0"
568 | },
569 | "require-dev": {
570 | "phpunit/phpunit": "^9.3"
571 | },
572 | "suggest": {
573 | "ext-pcov": "PHP extension that provides line coverage",
574 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
575 | },
576 | "type": "library",
577 | "extra": {
578 | "branch-alias": {
579 | "dev-master": "9.2-dev"
580 | }
581 | },
582 | "autoload": {
583 | "classmap": [
584 | "src/"
585 | ]
586 | },
587 | "notification-url": "https://packagist.org/downloads/",
588 | "license": [
589 | "BSD-3-Clause"
590 | ],
591 | "authors": [
592 | {
593 | "name": "Sebastian Bergmann",
594 | "email": "sebastian@phpunit.de",
595 | "role": "lead"
596 | }
597 | ],
598 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
599 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
600 | "keywords": [
601 | "coverage",
602 | "testing",
603 | "xunit"
604 | ],
605 | "support": {
606 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
607 | "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
608 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29"
609 | },
610 | "funding": [
611 | {
612 | "url": "https://github.com/sebastianbergmann",
613 | "type": "github"
614 | }
615 | ],
616 | "time": "2023-09-19T04:57:46+00:00"
617 | },
618 | {
619 | "name": "phpunit/php-file-iterator",
620 | "version": "3.0.6",
621 | "source": {
622 | "type": "git",
623 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
624 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
625 | },
626 | "dist": {
627 | "type": "zip",
628 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
629 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
630 | "shasum": ""
631 | },
632 | "require": {
633 | "php": ">=7.3"
634 | },
635 | "require-dev": {
636 | "phpunit/phpunit": "^9.3"
637 | },
638 | "type": "library",
639 | "extra": {
640 | "branch-alias": {
641 | "dev-master": "3.0-dev"
642 | }
643 | },
644 | "autoload": {
645 | "classmap": [
646 | "src/"
647 | ]
648 | },
649 | "notification-url": "https://packagist.org/downloads/",
650 | "license": [
651 | "BSD-3-Clause"
652 | ],
653 | "authors": [
654 | {
655 | "name": "Sebastian Bergmann",
656 | "email": "sebastian@phpunit.de",
657 | "role": "lead"
658 | }
659 | ],
660 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
661 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
662 | "keywords": [
663 | "filesystem",
664 | "iterator"
665 | ],
666 | "support": {
667 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
668 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
669 | },
670 | "funding": [
671 | {
672 | "url": "https://github.com/sebastianbergmann",
673 | "type": "github"
674 | }
675 | ],
676 | "time": "2021-12-02T12:48:52+00:00"
677 | },
678 | {
679 | "name": "phpunit/php-invoker",
680 | "version": "3.1.1",
681 | "source": {
682 | "type": "git",
683 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
684 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
685 | },
686 | "dist": {
687 | "type": "zip",
688 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
689 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
690 | "shasum": ""
691 | },
692 | "require": {
693 | "php": ">=7.3"
694 | },
695 | "require-dev": {
696 | "ext-pcntl": "*",
697 | "phpunit/phpunit": "^9.3"
698 | },
699 | "suggest": {
700 | "ext-pcntl": "*"
701 | },
702 | "type": "library",
703 | "extra": {
704 | "branch-alias": {
705 | "dev-master": "3.1-dev"
706 | }
707 | },
708 | "autoload": {
709 | "classmap": [
710 | "src/"
711 | ]
712 | },
713 | "notification-url": "https://packagist.org/downloads/",
714 | "license": [
715 | "BSD-3-Clause"
716 | ],
717 | "authors": [
718 | {
719 | "name": "Sebastian Bergmann",
720 | "email": "sebastian@phpunit.de",
721 | "role": "lead"
722 | }
723 | ],
724 | "description": "Invoke callables with a timeout",
725 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
726 | "keywords": [
727 | "process"
728 | ],
729 | "support": {
730 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
731 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
732 | },
733 | "funding": [
734 | {
735 | "url": "https://github.com/sebastianbergmann",
736 | "type": "github"
737 | }
738 | ],
739 | "time": "2020-09-28T05:58:55+00:00"
740 | },
741 | {
742 | "name": "phpunit/php-text-template",
743 | "version": "2.0.4",
744 | "source": {
745 | "type": "git",
746 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
747 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
748 | },
749 | "dist": {
750 | "type": "zip",
751 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
752 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
753 | "shasum": ""
754 | },
755 | "require": {
756 | "php": ">=7.3"
757 | },
758 | "require-dev": {
759 | "phpunit/phpunit": "^9.3"
760 | },
761 | "type": "library",
762 | "extra": {
763 | "branch-alias": {
764 | "dev-master": "2.0-dev"
765 | }
766 | },
767 | "autoload": {
768 | "classmap": [
769 | "src/"
770 | ]
771 | },
772 | "notification-url": "https://packagist.org/downloads/",
773 | "license": [
774 | "BSD-3-Clause"
775 | ],
776 | "authors": [
777 | {
778 | "name": "Sebastian Bergmann",
779 | "email": "sebastian@phpunit.de",
780 | "role": "lead"
781 | }
782 | ],
783 | "description": "Simple template engine.",
784 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
785 | "keywords": [
786 | "template"
787 | ],
788 | "support": {
789 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
790 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
791 | },
792 | "funding": [
793 | {
794 | "url": "https://github.com/sebastianbergmann",
795 | "type": "github"
796 | }
797 | ],
798 | "time": "2020-10-26T05:33:50+00:00"
799 | },
800 | {
801 | "name": "phpunit/php-timer",
802 | "version": "5.0.3",
803 | "source": {
804 | "type": "git",
805 | "url": "https://github.com/sebastianbergmann/php-timer.git",
806 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
807 | },
808 | "dist": {
809 | "type": "zip",
810 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
811 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
812 | "shasum": ""
813 | },
814 | "require": {
815 | "php": ">=7.3"
816 | },
817 | "require-dev": {
818 | "phpunit/phpunit": "^9.3"
819 | },
820 | "type": "library",
821 | "extra": {
822 | "branch-alias": {
823 | "dev-master": "5.0-dev"
824 | }
825 | },
826 | "autoload": {
827 | "classmap": [
828 | "src/"
829 | ]
830 | },
831 | "notification-url": "https://packagist.org/downloads/",
832 | "license": [
833 | "BSD-3-Clause"
834 | ],
835 | "authors": [
836 | {
837 | "name": "Sebastian Bergmann",
838 | "email": "sebastian@phpunit.de",
839 | "role": "lead"
840 | }
841 | ],
842 | "description": "Utility class for timing",
843 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
844 | "keywords": [
845 | "timer"
846 | ],
847 | "support": {
848 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
849 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
850 | },
851 | "funding": [
852 | {
853 | "url": "https://github.com/sebastianbergmann",
854 | "type": "github"
855 | }
856 | ],
857 | "time": "2020-10-26T13:16:10+00:00"
858 | },
859 | {
860 | "name": "phpunit/phpunit",
861 | "version": "9.6.13",
862 | "source": {
863 | "type": "git",
864 | "url": "https://github.com/sebastianbergmann/phpunit.git",
865 | "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be"
866 | },
867 | "dist": {
868 | "type": "zip",
869 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be",
870 | "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be",
871 | "shasum": ""
872 | },
873 | "require": {
874 | "doctrine/instantiator": "^1.3.1 || ^2",
875 | "ext-dom": "*",
876 | "ext-json": "*",
877 | "ext-libxml": "*",
878 | "ext-mbstring": "*",
879 | "ext-xml": "*",
880 | "ext-xmlwriter": "*",
881 | "myclabs/deep-copy": "^1.10.1",
882 | "phar-io/manifest": "^2.0.3",
883 | "phar-io/version": "^3.0.2",
884 | "php": ">=7.3",
885 | "phpunit/php-code-coverage": "^9.2.28",
886 | "phpunit/php-file-iterator": "^3.0.5",
887 | "phpunit/php-invoker": "^3.1.1",
888 | "phpunit/php-text-template": "^2.0.3",
889 | "phpunit/php-timer": "^5.0.2",
890 | "sebastian/cli-parser": "^1.0.1",
891 | "sebastian/code-unit": "^1.0.6",
892 | "sebastian/comparator": "^4.0.8",
893 | "sebastian/diff": "^4.0.3",
894 | "sebastian/environment": "^5.1.3",
895 | "sebastian/exporter": "^4.0.5",
896 | "sebastian/global-state": "^5.0.1",
897 | "sebastian/object-enumerator": "^4.0.3",
898 | "sebastian/resource-operations": "^3.0.3",
899 | "sebastian/type": "^3.2",
900 | "sebastian/version": "^3.0.2"
901 | },
902 | "suggest": {
903 | "ext-soap": "To be able to generate mocks based on WSDL files",
904 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
905 | },
906 | "bin": [
907 | "phpunit"
908 | ],
909 | "type": "library",
910 | "extra": {
911 | "branch-alias": {
912 | "dev-master": "9.6-dev"
913 | }
914 | },
915 | "autoload": {
916 | "files": [
917 | "src/Framework/Assert/Functions.php"
918 | ],
919 | "classmap": [
920 | "src/"
921 | ]
922 | },
923 | "notification-url": "https://packagist.org/downloads/",
924 | "license": [
925 | "BSD-3-Clause"
926 | ],
927 | "authors": [
928 | {
929 | "name": "Sebastian Bergmann",
930 | "email": "sebastian@phpunit.de",
931 | "role": "lead"
932 | }
933 | ],
934 | "description": "The PHP Unit Testing framework.",
935 | "homepage": "https://phpunit.de/",
936 | "keywords": [
937 | "phpunit",
938 | "testing",
939 | "xunit"
940 | ],
941 | "support": {
942 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
943 | "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
944 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13"
945 | },
946 | "funding": [
947 | {
948 | "url": "https://phpunit.de/sponsors.html",
949 | "type": "custom"
950 | },
951 | {
952 | "url": "https://github.com/sebastianbergmann",
953 | "type": "github"
954 | },
955 | {
956 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
957 | "type": "tidelift"
958 | }
959 | ],
960 | "time": "2023-09-19T05:39:22+00:00"
961 | },
962 | {
963 | "name": "sebastian/cli-parser",
964 | "version": "1.0.1",
965 | "source": {
966 | "type": "git",
967 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
968 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
969 | },
970 | "dist": {
971 | "type": "zip",
972 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
973 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
974 | "shasum": ""
975 | },
976 | "require": {
977 | "php": ">=7.3"
978 | },
979 | "require-dev": {
980 | "phpunit/phpunit": "^9.3"
981 | },
982 | "type": "library",
983 | "extra": {
984 | "branch-alias": {
985 | "dev-master": "1.0-dev"
986 | }
987 | },
988 | "autoload": {
989 | "classmap": [
990 | "src/"
991 | ]
992 | },
993 | "notification-url": "https://packagist.org/downloads/",
994 | "license": [
995 | "BSD-3-Clause"
996 | ],
997 | "authors": [
998 | {
999 | "name": "Sebastian Bergmann",
1000 | "email": "sebastian@phpunit.de",
1001 | "role": "lead"
1002 | }
1003 | ],
1004 | "description": "Library for parsing CLI options",
1005 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
1006 | "support": {
1007 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
1008 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
1009 | },
1010 | "funding": [
1011 | {
1012 | "url": "https://github.com/sebastianbergmann",
1013 | "type": "github"
1014 | }
1015 | ],
1016 | "time": "2020-09-28T06:08:49+00:00"
1017 | },
1018 | {
1019 | "name": "sebastian/code-unit",
1020 | "version": "1.0.8",
1021 | "source": {
1022 | "type": "git",
1023 | "url": "https://github.com/sebastianbergmann/code-unit.git",
1024 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
1025 | },
1026 | "dist": {
1027 | "type": "zip",
1028 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
1029 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
1030 | "shasum": ""
1031 | },
1032 | "require": {
1033 | "php": ">=7.3"
1034 | },
1035 | "require-dev": {
1036 | "phpunit/phpunit": "^9.3"
1037 | },
1038 | "type": "library",
1039 | "extra": {
1040 | "branch-alias": {
1041 | "dev-master": "1.0-dev"
1042 | }
1043 | },
1044 | "autoload": {
1045 | "classmap": [
1046 | "src/"
1047 | ]
1048 | },
1049 | "notification-url": "https://packagist.org/downloads/",
1050 | "license": [
1051 | "BSD-3-Clause"
1052 | ],
1053 | "authors": [
1054 | {
1055 | "name": "Sebastian Bergmann",
1056 | "email": "sebastian@phpunit.de",
1057 | "role": "lead"
1058 | }
1059 | ],
1060 | "description": "Collection of value objects that represent the PHP code units",
1061 | "homepage": "https://github.com/sebastianbergmann/code-unit",
1062 | "support": {
1063 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
1064 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
1065 | },
1066 | "funding": [
1067 | {
1068 | "url": "https://github.com/sebastianbergmann",
1069 | "type": "github"
1070 | }
1071 | ],
1072 | "time": "2020-10-26T13:08:54+00:00"
1073 | },
1074 | {
1075 | "name": "sebastian/code-unit-reverse-lookup",
1076 | "version": "2.0.3",
1077 | "source": {
1078 | "type": "git",
1079 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1080 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
1081 | },
1082 | "dist": {
1083 | "type": "zip",
1084 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1085 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1086 | "shasum": ""
1087 | },
1088 | "require": {
1089 | "php": ">=7.3"
1090 | },
1091 | "require-dev": {
1092 | "phpunit/phpunit": "^9.3"
1093 | },
1094 | "type": "library",
1095 | "extra": {
1096 | "branch-alias": {
1097 | "dev-master": "2.0-dev"
1098 | }
1099 | },
1100 | "autoload": {
1101 | "classmap": [
1102 | "src/"
1103 | ]
1104 | },
1105 | "notification-url": "https://packagist.org/downloads/",
1106 | "license": [
1107 | "BSD-3-Clause"
1108 | ],
1109 | "authors": [
1110 | {
1111 | "name": "Sebastian Bergmann",
1112 | "email": "sebastian@phpunit.de"
1113 | }
1114 | ],
1115 | "description": "Looks up which function or method a line of code belongs to",
1116 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1117 | "support": {
1118 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
1119 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
1120 | },
1121 | "funding": [
1122 | {
1123 | "url": "https://github.com/sebastianbergmann",
1124 | "type": "github"
1125 | }
1126 | ],
1127 | "time": "2020-09-28T05:30:19+00:00"
1128 | },
1129 | {
1130 | "name": "sebastian/comparator",
1131 | "version": "4.0.8",
1132 | "source": {
1133 | "type": "git",
1134 | "url": "https://github.com/sebastianbergmann/comparator.git",
1135 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
1136 | },
1137 | "dist": {
1138 | "type": "zip",
1139 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
1140 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
1141 | "shasum": ""
1142 | },
1143 | "require": {
1144 | "php": ">=7.3",
1145 | "sebastian/diff": "^4.0",
1146 | "sebastian/exporter": "^4.0"
1147 | },
1148 | "require-dev": {
1149 | "phpunit/phpunit": "^9.3"
1150 | },
1151 | "type": "library",
1152 | "extra": {
1153 | "branch-alias": {
1154 | "dev-master": "4.0-dev"
1155 | }
1156 | },
1157 | "autoload": {
1158 | "classmap": [
1159 | "src/"
1160 | ]
1161 | },
1162 | "notification-url": "https://packagist.org/downloads/",
1163 | "license": [
1164 | "BSD-3-Clause"
1165 | ],
1166 | "authors": [
1167 | {
1168 | "name": "Sebastian Bergmann",
1169 | "email": "sebastian@phpunit.de"
1170 | },
1171 | {
1172 | "name": "Jeff Welch",
1173 | "email": "whatthejeff@gmail.com"
1174 | },
1175 | {
1176 | "name": "Volker Dusch",
1177 | "email": "github@wallbash.com"
1178 | },
1179 | {
1180 | "name": "Bernhard Schussek",
1181 | "email": "bschussek@2bepublished.at"
1182 | }
1183 | ],
1184 | "description": "Provides the functionality to compare PHP values for equality",
1185 | "homepage": "https://github.com/sebastianbergmann/comparator",
1186 | "keywords": [
1187 | "comparator",
1188 | "compare",
1189 | "equality"
1190 | ],
1191 | "support": {
1192 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1193 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
1194 | },
1195 | "funding": [
1196 | {
1197 | "url": "https://github.com/sebastianbergmann",
1198 | "type": "github"
1199 | }
1200 | ],
1201 | "time": "2022-09-14T12:41:17+00:00"
1202 | },
1203 | {
1204 | "name": "sebastian/complexity",
1205 | "version": "2.0.2",
1206 | "source": {
1207 | "type": "git",
1208 | "url": "https://github.com/sebastianbergmann/complexity.git",
1209 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
1210 | },
1211 | "dist": {
1212 | "type": "zip",
1213 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
1214 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
1215 | "shasum": ""
1216 | },
1217 | "require": {
1218 | "nikic/php-parser": "^4.7",
1219 | "php": ">=7.3"
1220 | },
1221 | "require-dev": {
1222 | "phpunit/phpunit": "^9.3"
1223 | },
1224 | "type": "library",
1225 | "extra": {
1226 | "branch-alias": {
1227 | "dev-master": "2.0-dev"
1228 | }
1229 | },
1230 | "autoload": {
1231 | "classmap": [
1232 | "src/"
1233 | ]
1234 | },
1235 | "notification-url": "https://packagist.org/downloads/",
1236 | "license": [
1237 | "BSD-3-Clause"
1238 | ],
1239 | "authors": [
1240 | {
1241 | "name": "Sebastian Bergmann",
1242 | "email": "sebastian@phpunit.de",
1243 | "role": "lead"
1244 | }
1245 | ],
1246 | "description": "Library for calculating the complexity of PHP code units",
1247 | "homepage": "https://github.com/sebastianbergmann/complexity",
1248 | "support": {
1249 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
1250 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
1251 | },
1252 | "funding": [
1253 | {
1254 | "url": "https://github.com/sebastianbergmann",
1255 | "type": "github"
1256 | }
1257 | ],
1258 | "time": "2020-10-26T15:52:27+00:00"
1259 | },
1260 | {
1261 | "name": "sebastian/diff",
1262 | "version": "4.0.5",
1263 | "source": {
1264 | "type": "git",
1265 | "url": "https://github.com/sebastianbergmann/diff.git",
1266 | "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
1267 | },
1268 | "dist": {
1269 | "type": "zip",
1270 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
1271 | "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
1272 | "shasum": ""
1273 | },
1274 | "require": {
1275 | "php": ">=7.3"
1276 | },
1277 | "require-dev": {
1278 | "phpunit/phpunit": "^9.3",
1279 | "symfony/process": "^4.2 || ^5"
1280 | },
1281 | "type": "library",
1282 | "extra": {
1283 | "branch-alias": {
1284 | "dev-master": "4.0-dev"
1285 | }
1286 | },
1287 | "autoload": {
1288 | "classmap": [
1289 | "src/"
1290 | ]
1291 | },
1292 | "notification-url": "https://packagist.org/downloads/",
1293 | "license": [
1294 | "BSD-3-Clause"
1295 | ],
1296 | "authors": [
1297 | {
1298 | "name": "Sebastian Bergmann",
1299 | "email": "sebastian@phpunit.de"
1300 | },
1301 | {
1302 | "name": "Kore Nordmann",
1303 | "email": "mail@kore-nordmann.de"
1304 | }
1305 | ],
1306 | "description": "Diff implementation",
1307 | "homepage": "https://github.com/sebastianbergmann/diff",
1308 | "keywords": [
1309 | "diff",
1310 | "udiff",
1311 | "unidiff",
1312 | "unified diff"
1313 | ],
1314 | "support": {
1315 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1316 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
1317 | },
1318 | "funding": [
1319 | {
1320 | "url": "https://github.com/sebastianbergmann",
1321 | "type": "github"
1322 | }
1323 | ],
1324 | "time": "2023-05-07T05:35:17+00:00"
1325 | },
1326 | {
1327 | "name": "sebastian/environment",
1328 | "version": "5.1.5",
1329 | "source": {
1330 | "type": "git",
1331 | "url": "https://github.com/sebastianbergmann/environment.git",
1332 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
1333 | },
1334 | "dist": {
1335 | "type": "zip",
1336 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
1337 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
1338 | "shasum": ""
1339 | },
1340 | "require": {
1341 | "php": ">=7.3"
1342 | },
1343 | "require-dev": {
1344 | "phpunit/phpunit": "^9.3"
1345 | },
1346 | "suggest": {
1347 | "ext-posix": "*"
1348 | },
1349 | "type": "library",
1350 | "extra": {
1351 | "branch-alias": {
1352 | "dev-master": "5.1-dev"
1353 | }
1354 | },
1355 | "autoload": {
1356 | "classmap": [
1357 | "src/"
1358 | ]
1359 | },
1360 | "notification-url": "https://packagist.org/downloads/",
1361 | "license": [
1362 | "BSD-3-Clause"
1363 | ],
1364 | "authors": [
1365 | {
1366 | "name": "Sebastian Bergmann",
1367 | "email": "sebastian@phpunit.de"
1368 | }
1369 | ],
1370 | "description": "Provides functionality to handle HHVM/PHP environments",
1371 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1372 | "keywords": [
1373 | "Xdebug",
1374 | "environment",
1375 | "hhvm"
1376 | ],
1377 | "support": {
1378 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1379 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
1380 | },
1381 | "funding": [
1382 | {
1383 | "url": "https://github.com/sebastianbergmann",
1384 | "type": "github"
1385 | }
1386 | ],
1387 | "time": "2023-02-03T06:03:51+00:00"
1388 | },
1389 | {
1390 | "name": "sebastian/exporter",
1391 | "version": "4.0.5",
1392 | "source": {
1393 | "type": "git",
1394 | "url": "https://github.com/sebastianbergmann/exporter.git",
1395 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
1396 | },
1397 | "dist": {
1398 | "type": "zip",
1399 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
1400 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
1401 | "shasum": ""
1402 | },
1403 | "require": {
1404 | "php": ">=7.3",
1405 | "sebastian/recursion-context": "^4.0"
1406 | },
1407 | "require-dev": {
1408 | "ext-mbstring": "*",
1409 | "phpunit/phpunit": "^9.3"
1410 | },
1411 | "type": "library",
1412 | "extra": {
1413 | "branch-alias": {
1414 | "dev-master": "4.0-dev"
1415 | }
1416 | },
1417 | "autoload": {
1418 | "classmap": [
1419 | "src/"
1420 | ]
1421 | },
1422 | "notification-url": "https://packagist.org/downloads/",
1423 | "license": [
1424 | "BSD-3-Clause"
1425 | ],
1426 | "authors": [
1427 | {
1428 | "name": "Sebastian Bergmann",
1429 | "email": "sebastian@phpunit.de"
1430 | },
1431 | {
1432 | "name": "Jeff Welch",
1433 | "email": "whatthejeff@gmail.com"
1434 | },
1435 | {
1436 | "name": "Volker Dusch",
1437 | "email": "github@wallbash.com"
1438 | },
1439 | {
1440 | "name": "Adam Harvey",
1441 | "email": "aharvey@php.net"
1442 | },
1443 | {
1444 | "name": "Bernhard Schussek",
1445 | "email": "bschussek@gmail.com"
1446 | }
1447 | ],
1448 | "description": "Provides the functionality to export PHP variables for visualization",
1449 | "homepage": "https://www.github.com/sebastianbergmann/exporter",
1450 | "keywords": [
1451 | "export",
1452 | "exporter"
1453 | ],
1454 | "support": {
1455 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1456 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
1457 | },
1458 | "funding": [
1459 | {
1460 | "url": "https://github.com/sebastianbergmann",
1461 | "type": "github"
1462 | }
1463 | ],
1464 | "time": "2022-09-14T06:03:37+00:00"
1465 | },
1466 | {
1467 | "name": "sebastian/global-state",
1468 | "version": "5.0.6",
1469 | "source": {
1470 | "type": "git",
1471 | "url": "https://github.com/sebastianbergmann/global-state.git",
1472 | "reference": "bde739e7565280bda77be70044ac1047bc007e34"
1473 | },
1474 | "dist": {
1475 | "type": "zip",
1476 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
1477 | "reference": "bde739e7565280bda77be70044ac1047bc007e34",
1478 | "shasum": ""
1479 | },
1480 | "require": {
1481 | "php": ">=7.3",
1482 | "sebastian/object-reflector": "^2.0",
1483 | "sebastian/recursion-context": "^4.0"
1484 | },
1485 | "require-dev": {
1486 | "ext-dom": "*",
1487 | "phpunit/phpunit": "^9.3"
1488 | },
1489 | "suggest": {
1490 | "ext-uopz": "*"
1491 | },
1492 | "type": "library",
1493 | "extra": {
1494 | "branch-alias": {
1495 | "dev-master": "5.0-dev"
1496 | }
1497 | },
1498 | "autoload": {
1499 | "classmap": [
1500 | "src/"
1501 | ]
1502 | },
1503 | "notification-url": "https://packagist.org/downloads/",
1504 | "license": [
1505 | "BSD-3-Clause"
1506 | ],
1507 | "authors": [
1508 | {
1509 | "name": "Sebastian Bergmann",
1510 | "email": "sebastian@phpunit.de"
1511 | }
1512 | ],
1513 | "description": "Snapshotting of global state",
1514 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1515 | "keywords": [
1516 | "global state"
1517 | ],
1518 | "support": {
1519 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1520 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6"
1521 | },
1522 | "funding": [
1523 | {
1524 | "url": "https://github.com/sebastianbergmann",
1525 | "type": "github"
1526 | }
1527 | ],
1528 | "time": "2023-08-02T09:26:13+00:00"
1529 | },
1530 | {
1531 | "name": "sebastian/lines-of-code",
1532 | "version": "1.0.3",
1533 | "source": {
1534 | "type": "git",
1535 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1536 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
1537 | },
1538 | "dist": {
1539 | "type": "zip",
1540 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1541 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1542 | "shasum": ""
1543 | },
1544 | "require": {
1545 | "nikic/php-parser": "^4.6",
1546 | "php": ">=7.3"
1547 | },
1548 | "require-dev": {
1549 | "phpunit/phpunit": "^9.3"
1550 | },
1551 | "type": "library",
1552 | "extra": {
1553 | "branch-alias": {
1554 | "dev-master": "1.0-dev"
1555 | }
1556 | },
1557 | "autoload": {
1558 | "classmap": [
1559 | "src/"
1560 | ]
1561 | },
1562 | "notification-url": "https://packagist.org/downloads/",
1563 | "license": [
1564 | "BSD-3-Clause"
1565 | ],
1566 | "authors": [
1567 | {
1568 | "name": "Sebastian Bergmann",
1569 | "email": "sebastian@phpunit.de",
1570 | "role": "lead"
1571 | }
1572 | ],
1573 | "description": "Library for counting the lines of code in PHP source code",
1574 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1575 | "support": {
1576 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1577 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
1578 | },
1579 | "funding": [
1580 | {
1581 | "url": "https://github.com/sebastianbergmann",
1582 | "type": "github"
1583 | }
1584 | ],
1585 | "time": "2020-11-28T06:42:11+00:00"
1586 | },
1587 | {
1588 | "name": "sebastian/object-enumerator",
1589 | "version": "4.0.4",
1590 | "source": {
1591 | "type": "git",
1592 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1593 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
1594 | },
1595 | "dist": {
1596 | "type": "zip",
1597 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
1598 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
1599 | "shasum": ""
1600 | },
1601 | "require": {
1602 | "php": ">=7.3",
1603 | "sebastian/object-reflector": "^2.0",
1604 | "sebastian/recursion-context": "^4.0"
1605 | },
1606 | "require-dev": {
1607 | "phpunit/phpunit": "^9.3"
1608 | },
1609 | "type": "library",
1610 | "extra": {
1611 | "branch-alias": {
1612 | "dev-master": "4.0-dev"
1613 | }
1614 | },
1615 | "autoload": {
1616 | "classmap": [
1617 | "src/"
1618 | ]
1619 | },
1620 | "notification-url": "https://packagist.org/downloads/",
1621 | "license": [
1622 | "BSD-3-Clause"
1623 | ],
1624 | "authors": [
1625 | {
1626 | "name": "Sebastian Bergmann",
1627 | "email": "sebastian@phpunit.de"
1628 | }
1629 | ],
1630 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1631 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1632 | "support": {
1633 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1634 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
1635 | },
1636 | "funding": [
1637 | {
1638 | "url": "https://github.com/sebastianbergmann",
1639 | "type": "github"
1640 | }
1641 | ],
1642 | "time": "2020-10-26T13:12:34+00:00"
1643 | },
1644 | {
1645 | "name": "sebastian/object-reflector",
1646 | "version": "2.0.4",
1647 | "source": {
1648 | "type": "git",
1649 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1650 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
1651 | },
1652 | "dist": {
1653 | "type": "zip",
1654 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1655 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1656 | "shasum": ""
1657 | },
1658 | "require": {
1659 | "php": ">=7.3"
1660 | },
1661 | "require-dev": {
1662 | "phpunit/phpunit": "^9.3"
1663 | },
1664 | "type": "library",
1665 | "extra": {
1666 | "branch-alias": {
1667 | "dev-master": "2.0-dev"
1668 | }
1669 | },
1670 | "autoload": {
1671 | "classmap": [
1672 | "src/"
1673 | ]
1674 | },
1675 | "notification-url": "https://packagist.org/downloads/",
1676 | "license": [
1677 | "BSD-3-Clause"
1678 | ],
1679 | "authors": [
1680 | {
1681 | "name": "Sebastian Bergmann",
1682 | "email": "sebastian@phpunit.de"
1683 | }
1684 | ],
1685 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1686 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1687 | "support": {
1688 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1689 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
1690 | },
1691 | "funding": [
1692 | {
1693 | "url": "https://github.com/sebastianbergmann",
1694 | "type": "github"
1695 | }
1696 | ],
1697 | "time": "2020-10-26T13:14:26+00:00"
1698 | },
1699 | {
1700 | "name": "sebastian/recursion-context",
1701 | "version": "4.0.5",
1702 | "source": {
1703 | "type": "git",
1704 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1705 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
1706 | },
1707 | "dist": {
1708 | "type": "zip",
1709 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
1710 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
1711 | "shasum": ""
1712 | },
1713 | "require": {
1714 | "php": ">=7.3"
1715 | },
1716 | "require-dev": {
1717 | "phpunit/phpunit": "^9.3"
1718 | },
1719 | "type": "library",
1720 | "extra": {
1721 | "branch-alias": {
1722 | "dev-master": "4.0-dev"
1723 | }
1724 | },
1725 | "autoload": {
1726 | "classmap": [
1727 | "src/"
1728 | ]
1729 | },
1730 | "notification-url": "https://packagist.org/downloads/",
1731 | "license": [
1732 | "BSD-3-Clause"
1733 | ],
1734 | "authors": [
1735 | {
1736 | "name": "Sebastian Bergmann",
1737 | "email": "sebastian@phpunit.de"
1738 | },
1739 | {
1740 | "name": "Jeff Welch",
1741 | "email": "whatthejeff@gmail.com"
1742 | },
1743 | {
1744 | "name": "Adam Harvey",
1745 | "email": "aharvey@php.net"
1746 | }
1747 | ],
1748 | "description": "Provides functionality to recursively process PHP variables",
1749 | "homepage": "https://github.com/sebastianbergmann/recursion-context",
1750 | "support": {
1751 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1752 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
1753 | },
1754 | "funding": [
1755 | {
1756 | "url": "https://github.com/sebastianbergmann",
1757 | "type": "github"
1758 | }
1759 | ],
1760 | "time": "2023-02-03T06:07:39+00:00"
1761 | },
1762 | {
1763 | "name": "sebastian/resource-operations",
1764 | "version": "3.0.3",
1765 | "source": {
1766 | "type": "git",
1767 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1768 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
1769 | },
1770 | "dist": {
1771 | "type": "zip",
1772 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1773 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1774 | "shasum": ""
1775 | },
1776 | "require": {
1777 | "php": ">=7.3"
1778 | },
1779 | "require-dev": {
1780 | "phpunit/phpunit": "^9.0"
1781 | },
1782 | "type": "library",
1783 | "extra": {
1784 | "branch-alias": {
1785 | "dev-master": "3.0-dev"
1786 | }
1787 | },
1788 | "autoload": {
1789 | "classmap": [
1790 | "src/"
1791 | ]
1792 | },
1793 | "notification-url": "https://packagist.org/downloads/",
1794 | "license": [
1795 | "BSD-3-Clause"
1796 | ],
1797 | "authors": [
1798 | {
1799 | "name": "Sebastian Bergmann",
1800 | "email": "sebastian@phpunit.de"
1801 | }
1802 | ],
1803 | "description": "Provides a list of PHP built-in functions that operate on resources",
1804 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1805 | "support": {
1806 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1807 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
1808 | },
1809 | "funding": [
1810 | {
1811 | "url": "https://github.com/sebastianbergmann",
1812 | "type": "github"
1813 | }
1814 | ],
1815 | "time": "2020-09-28T06:45:17+00:00"
1816 | },
1817 | {
1818 | "name": "sebastian/type",
1819 | "version": "3.2.1",
1820 | "source": {
1821 | "type": "git",
1822 | "url": "https://github.com/sebastianbergmann/type.git",
1823 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
1824 | },
1825 | "dist": {
1826 | "type": "zip",
1827 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
1828 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
1829 | "shasum": ""
1830 | },
1831 | "require": {
1832 | "php": ">=7.3"
1833 | },
1834 | "require-dev": {
1835 | "phpunit/phpunit": "^9.5"
1836 | },
1837 | "type": "library",
1838 | "extra": {
1839 | "branch-alias": {
1840 | "dev-master": "3.2-dev"
1841 | }
1842 | },
1843 | "autoload": {
1844 | "classmap": [
1845 | "src/"
1846 | ]
1847 | },
1848 | "notification-url": "https://packagist.org/downloads/",
1849 | "license": [
1850 | "BSD-3-Clause"
1851 | ],
1852 | "authors": [
1853 | {
1854 | "name": "Sebastian Bergmann",
1855 | "email": "sebastian@phpunit.de",
1856 | "role": "lead"
1857 | }
1858 | ],
1859 | "description": "Collection of value objects that represent the types of the PHP type system",
1860 | "homepage": "https://github.com/sebastianbergmann/type",
1861 | "support": {
1862 | "issues": "https://github.com/sebastianbergmann/type/issues",
1863 | "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
1864 | },
1865 | "funding": [
1866 | {
1867 | "url": "https://github.com/sebastianbergmann",
1868 | "type": "github"
1869 | }
1870 | ],
1871 | "time": "2023-02-03T06:13:03+00:00"
1872 | },
1873 | {
1874 | "name": "sebastian/version",
1875 | "version": "3.0.2",
1876 | "source": {
1877 | "type": "git",
1878 | "url": "https://github.com/sebastianbergmann/version.git",
1879 | "reference": "c6c1022351a901512170118436c764e473f6de8c"
1880 | },
1881 | "dist": {
1882 | "type": "zip",
1883 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
1884 | "reference": "c6c1022351a901512170118436c764e473f6de8c",
1885 | "shasum": ""
1886 | },
1887 | "require": {
1888 | "php": ">=7.3"
1889 | },
1890 | "type": "library",
1891 | "extra": {
1892 | "branch-alias": {
1893 | "dev-master": "3.0-dev"
1894 | }
1895 | },
1896 | "autoload": {
1897 | "classmap": [
1898 | "src/"
1899 | ]
1900 | },
1901 | "notification-url": "https://packagist.org/downloads/",
1902 | "license": [
1903 | "BSD-3-Clause"
1904 | ],
1905 | "authors": [
1906 | {
1907 | "name": "Sebastian Bergmann",
1908 | "email": "sebastian@phpunit.de",
1909 | "role": "lead"
1910 | }
1911 | ],
1912 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1913 | "homepage": "https://github.com/sebastianbergmann/version",
1914 | "support": {
1915 | "issues": "https://github.com/sebastianbergmann/version/issues",
1916 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
1917 | },
1918 | "funding": [
1919 | {
1920 | "url": "https://github.com/sebastianbergmann",
1921 | "type": "github"
1922 | }
1923 | ],
1924 | "time": "2020-09-28T06:39:44+00:00"
1925 | },
1926 | {
1927 | "name": "slevomat/coding-standard",
1928 | "version": "7.2.1",
1929 | "source": {
1930 | "type": "git",
1931 | "url": "https://github.com/slevomat/coding-standard.git",
1932 | "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90"
1933 | },
1934 | "dist": {
1935 | "type": "zip",
1936 | "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90",
1937 | "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90",
1938 | "shasum": ""
1939 | },
1940 | "require": {
1941 | "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7",
1942 | "php": "^7.2 || ^8.0",
1943 | "phpstan/phpdoc-parser": "^1.5.1",
1944 | "squizlabs/php_codesniffer": "^3.6.2"
1945 | },
1946 | "require-dev": {
1947 | "phing/phing": "2.17.3",
1948 | "php-parallel-lint/php-parallel-lint": "1.3.2",
1949 | "phpstan/phpstan": "1.4.10|1.7.1",
1950 | "phpstan/phpstan-deprecation-rules": "1.0.0",
1951 | "phpstan/phpstan-phpunit": "1.0.0|1.1.1",
1952 | "phpstan/phpstan-strict-rules": "1.2.3",
1953 | "phpunit/phpunit": "7.5.20|8.5.21|9.5.20"
1954 | },
1955 | "type": "phpcodesniffer-standard",
1956 | "extra": {
1957 | "branch-alias": {
1958 | "dev-master": "7.x-dev"
1959 | }
1960 | },
1961 | "autoload": {
1962 | "psr-4": {
1963 | "SlevomatCodingStandard\\": "SlevomatCodingStandard"
1964 | }
1965 | },
1966 | "notification-url": "https://packagist.org/downloads/",
1967 | "license": [
1968 | "MIT"
1969 | ],
1970 | "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.",
1971 | "support": {
1972 | "issues": "https://github.com/slevomat/coding-standard/issues",
1973 | "source": "https://github.com/slevomat/coding-standard/tree/7.2.1"
1974 | },
1975 | "funding": [
1976 | {
1977 | "url": "https://github.com/kukulich",
1978 | "type": "github"
1979 | },
1980 | {
1981 | "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard",
1982 | "type": "tidelift"
1983 | }
1984 | ],
1985 | "time": "2022-05-25T10:58:12+00:00"
1986 | },
1987 | {
1988 | "name": "squizlabs/php_codesniffer",
1989 | "version": "3.7.2",
1990 | "source": {
1991 | "type": "git",
1992 | "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
1993 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
1994 | },
1995 | "dist": {
1996 | "type": "zip",
1997 | "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
1998 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
1999 | "shasum": ""
2000 | },
2001 | "require": {
2002 | "ext-simplexml": "*",
2003 | "ext-tokenizer": "*",
2004 | "ext-xmlwriter": "*",
2005 | "php": ">=5.4.0"
2006 | },
2007 | "require-dev": {
2008 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
2009 | },
2010 | "bin": [
2011 | "bin/phpcs",
2012 | "bin/phpcbf"
2013 | ],
2014 | "type": "library",
2015 | "extra": {
2016 | "branch-alias": {
2017 | "dev-master": "3.x-dev"
2018 | }
2019 | },
2020 | "notification-url": "https://packagist.org/downloads/",
2021 | "license": [
2022 | "BSD-3-Clause"
2023 | ],
2024 | "authors": [
2025 | {
2026 | "name": "Greg Sherwood",
2027 | "role": "lead"
2028 | }
2029 | ],
2030 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
2031 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
2032 | "keywords": [
2033 | "phpcs",
2034 | "standards",
2035 | "static analysis"
2036 | ],
2037 | "support": {
2038 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
2039 | "source": "https://github.com/squizlabs/PHP_CodeSniffer",
2040 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
2041 | },
2042 | "funding": [
2043 | {
2044 | "url": "https://github.com/PHPCSStandards",
2045 | "type": "github"
2046 | },
2047 | {
2048 | "url": "https://github.com/jrfnl",
2049 | "type": "github"
2050 | },
2051 | {
2052 | "url": "https://opencollective.com/php_codesniffer",
2053 | "type": "open_collective"
2054 | }
2055 | ],
2056 | "time": "2023-02-22T23:07:41+00:00"
2057 | },
2058 | {
2059 | "name": "theseer/tokenizer",
2060 | "version": "1.2.1",
2061 | "source": {
2062 | "type": "git",
2063 | "url": "https://github.com/theseer/tokenizer.git",
2064 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
2065 | },
2066 | "dist": {
2067 | "type": "zip",
2068 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
2069 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
2070 | "shasum": ""
2071 | },
2072 | "require": {
2073 | "ext-dom": "*",
2074 | "ext-tokenizer": "*",
2075 | "ext-xmlwriter": "*",
2076 | "php": "^7.2 || ^8.0"
2077 | },
2078 | "type": "library",
2079 | "autoload": {
2080 | "classmap": [
2081 | "src/"
2082 | ]
2083 | },
2084 | "notification-url": "https://packagist.org/downloads/",
2085 | "license": [
2086 | "BSD-3-Clause"
2087 | ],
2088 | "authors": [
2089 | {
2090 | "name": "Arne Blankerts",
2091 | "email": "arne@blankerts.de",
2092 | "role": "Developer"
2093 | }
2094 | ],
2095 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2096 | "support": {
2097 | "issues": "https://github.com/theseer/tokenizer/issues",
2098 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
2099 | },
2100 | "funding": [
2101 | {
2102 | "url": "https://github.com/theseer",
2103 | "type": "github"
2104 | }
2105 | ],
2106 | "time": "2021-07-28T10:34:58+00:00"
2107 | },
2108 | {
2109 | "name": "webimpress/coding-standard",
2110 | "version": "1.3.1",
2111 | "source": {
2112 | "type": "git",
2113 | "url": "https://github.com/webimpress/coding-standard.git",
2114 | "reference": "b26557e2386711ecb74f22718f4b4bde5ddbc899"
2115 | },
2116 | "dist": {
2117 | "type": "zip",
2118 | "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/b26557e2386711ecb74f22718f4b4bde5ddbc899",
2119 | "reference": "b26557e2386711ecb74f22718f4b4bde5ddbc899",
2120 | "shasum": ""
2121 | },
2122 | "require": {
2123 | "php": "^7.3 || ^8.0",
2124 | "squizlabs/php_codesniffer": "^3.7.2"
2125 | },
2126 | "require-dev": {
2127 | "phpunit/phpunit": "^9.6.4"
2128 | },
2129 | "type": "phpcodesniffer-standard",
2130 | "extra": {
2131 | "dev-master": "1.2.x-dev",
2132 | "dev-develop": "1.3.x-dev"
2133 | },
2134 | "autoload": {
2135 | "psr-4": {
2136 | "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/"
2137 | }
2138 | },
2139 | "notification-url": "https://packagist.org/downloads/",
2140 | "license": [
2141 | "BSD-2-Clause"
2142 | ],
2143 | "description": "Webimpress Coding Standard",
2144 | "keywords": [
2145 | "Coding Standard",
2146 | "PSR-2",
2147 | "phpcs",
2148 | "psr-12",
2149 | "webimpress"
2150 | ],
2151 | "support": {
2152 | "issues": "https://github.com/webimpress/coding-standard/issues",
2153 | "source": "https://github.com/webimpress/coding-standard/tree/1.3.1"
2154 | },
2155 | "funding": [
2156 | {
2157 | "url": "https://github.com/michalbundyra",
2158 | "type": "github"
2159 | }
2160 | ],
2161 | "time": "2023-03-09T15:05:18+00:00"
2162 | }
2163 | ],
2164 | "aliases": [],
2165 | "minimum-stability": "stable",
2166 | "stability-flags": [],
2167 | "prefer-stable": false,
2168 | "prefer-lowest": false,
2169 | "platform": {
2170 | "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
2171 | },
2172 | "platform-dev": [],
2173 | "plugin-api-version": "2.6.0"
2174 | }
2175 |
--------------------------------------------------------------------------------