From beabe4ec4aa9c8694883e29d6b140ec2f715e6ed Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 09:59:34 +0200 Subject: [PATCH 001/159] Add Array.tail function --- src/Array/tail.php | 34 ++++++++++++++++++++++++++++++++++ tests/Array/TailTest.php | 21 +++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/Array/tail.php create mode 100644 tests/Array/TailTest.php diff --git a/src/Array/tail.php b/src/Array/tail.php new file mode 100644 index 0000000..52798df --- /dev/null +++ b/src/Array/tail.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Gets all but the first element of `array`. + * + * @category Array + * + * @param array $array The array to query. + * + * @return array the slice of `array`. + * + * @example + * + * tail([1, 2, 3]) + * // => [2, 3] + * + */ +function tail(array $array): array +{ + array_shift($array); + + return $array; +} \ No newline at end of file diff --git a/tests/Array/TailTest.php b/tests/Array/TailTest.php new file mode 100644 index 0000000..c16d221 --- /dev/null +++ b/tests/Array/TailTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\tail; +use PHPUnit\Framework\TestCase; + +class TailTest extends TestCase +{ + public function testTail() + { + $this->assertSame([2, 3], tail([1, 2, 3])); + } +} \ No newline at end of file From 1dbe046e86d26c1f44ac51ec44ff7c833444f8d3 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 10:03:20 +0200 Subject: [PATCH 002/159] Add Array.take function --- src/Array/take.php | 47 ++++++++++++++++++++++++++++++++++++++++ tests/Array/TakeTest.php | 24 ++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/Array/take.php create mode 100644 tests/Array/TakeTest.php diff --git a/src/Array/take.php b/src/Array/take.php new file mode 100644 index 0000000..f29be25 --- /dev/null +++ b/src/Array/take.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @category Array + * + * @param array $array The array to query. + * @param int $n The number of elements to take. + * + * @return array the slice of `array`. + * @example + * + * take([1, 2, 3]) + * // => [1] + * + * take([1, 2, 3], 2) + * // => [1, 2] + * + * take([1, 2, 3], 5) + * // => [1, 2, 3] + * + * take([1, 2, 3], 0) + * // => [] + * + */ +function take(array $array, int $n = 1): array +{ + if (1 > $n) { + return []; + } + + array_splice($array, $n); + + return $array; +} \ No newline at end of file diff --git a/tests/Array/TakeTest.php b/tests/Array/TakeTest.php new file mode 100644 index 0000000..0e844f1 --- /dev/null +++ b/tests/Array/TakeTest.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\take; + +class TakeTest extends TestCase +{ + public function testTake() + { + $this->assertSame([1], take([1, 2, 3])); + $this->assertSame([1, 2], take([1, 2, 3], 2)); + $this->assertSame([1, 2, 3], take([1, 2, 3], 5)); + $this->assertSame([], take([1, 2, 3], 0)); + } +} \ No newline at end of file From d36c9e6b34ec116008f6e452dc82d8c1f184fc8d Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 10:09:22 +0200 Subject: [PATCH 003/159] Add Array.takeRight function --- src/Array/takeRight.php | 45 +++++++++++++++++++++++++++++++++++ tests/Array/TakeRightTest.php | 24 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/Array/takeRight.php create mode 100644 tests/Array/TakeRightTest.php diff --git a/src/Array/takeRight.php b/src/Array/takeRight.php new file mode 100644 index 0000000..80dd58e --- /dev/null +++ b/src/Array/takeRight.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @category Array + * + * @param array $array The array to query. + * @param int $n The number of elements to take. + * + * @return array the slice of `array`. + * @example + * + * takeRight([1, 2, 3]) + * // => [3] + * + * takeRight([1, 2, 3], 2) + * // => [2, 3] + * + * takeRight([1, 2, 3], 5) + * // => [1, 2, 3] + * + * takeRight([1, 2, 3], 0) + * // => [] + * + */ +function takeRight(array $array, int $n = 1): array +{ + if (1 > $n) { + return []; + } + + return array_slice($array, -$n); +} \ No newline at end of file diff --git a/tests/Array/TakeRightTest.php b/tests/Array/TakeRightTest.php new file mode 100644 index 0000000..7437bb1 --- /dev/null +++ b/tests/Array/TakeRightTest.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\takeRight; + +class TakeRightTest extends TestCase +{ + public function testTakeRight() + { + $this->assertSame([3], takeRight([1, 2, 3])); + $this->assertSame([2, 3], takeRight([1, 2, 3], 2)); + $this->assertSame([1, 2, 3], takeRight([1, 2, 3], 5)); + $this->assertSame([], takeRight([1, 2, 3], 0)); + } +} \ No newline at end of file From 9e7bae1f8846f2556f9e0943625572aefc96b9a6 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 10:16:14 +0200 Subject: [PATCH 004/159] Add Array.takeWhile function --- src/Array/takeWhile.php | 53 +++++++++++++++++++++++++++++++++++ tests/Array/TakeWhileTest.php | 27 ++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/Array/takeWhile.php create mode 100644 tests/Array/TakeWhileTest.php diff --git a/src/Array/takeWhile.php b/src/Array/takeWhile.php new file mode 100644 index 0000000..8e679a2 --- /dev/null +++ b/src/Array/takeWhile.php @@ -0,0 +1,53 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @category Array + * + * @param array $array The array to query. + * @param mixed $predicate The function invoked per iteration. + * + * @return array the slice of `array`. + * + * @example + * + * $users = [ + * [ 'user' => 'barney', 'active' => true ], + * [ 'user' => 'fred', 'active' => true ], + * [ 'user' => 'pebbles', 'active' => false ] + * ] + * + * takeWhile($users, function($value) { return $value['active']; }) + * // => objects for ['barney', 'fred'] + * + */ +function takeWhile(array $array, $predicate): array +{ + $result = []; + + $iteratee = baseIteratee($predicate); + + foreach ($array as $index => $value) { + if ($iteratee($value, $index, $array)) { + $result[$index] = $value; + } + } + + return $result; +} \ No newline at end of file diff --git a/tests/Array/TakeWhileTest.php b/tests/Array/TakeWhileTest.php new file mode 100644 index 0000000..dfd677f --- /dev/null +++ b/tests/Array/TakeWhileTest.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\takeWhile; + +class TakeWhileTest extends TestCase +{ + public function testTakeWhile() + { + $users = [ + ['user' => 'barney', 'active' => true], + ['user' => 'fred', 'active' => true], + ['user' => 'pebbles', 'active' => false], + ]; + + $this->assertSame([['user' => 'barney', 'active' => true], ['user' => 'fred', 'active' => true]], takeWhile($users, function ($value) { return $value['active']; })); + } +} \ No newline at end of file From 3e77675d0e2ef4dc4f924ee233701fa7f494262c Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 11:44:29 +0200 Subject: [PATCH 005/159] Add Array.takeRightWhile function --- src/Array/takeRightWhile.php | 52 ++++++++++++++++++++++++++++++ tests/Array/TakeRightWhileTest.php | 27 ++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/Array/takeRightWhile.php create mode 100644 tests/Array/TakeRightWhileTest.php diff --git a/src/Array/takeRightWhile.php b/src/Array/takeRightWhile.php new file mode 100644 index 0000000..1b0bcdb --- /dev/null +++ b/src/Array/takeRightWhile.php @@ -0,0 +1,52 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @category Array + * + * @param array $array The array to query. + * @param callable $predicate The function invoked per iteration. + * + * @return array the slice of `array`. + * + * @example + * + * $users = [ + * [ 'user' => 'barney', 'active' => false ], + * [ 'user' => 'fred', 'active' => true ], + * [ 'user' => 'pebbles', 'active' => true ] + * ]; + * + * takeRightWhile($users, function($value) { return $value['active']; }) + * // => objects for ['fred', 'pebbles'] + * + */ +function takeRightWhile(array $array, $predicate): array +{ + $iteratee = baseIteratee($predicate); + $result = []; + + foreach (array_reverse($array, true) as $index => $value) { + if ($iteratee($value, $index, $array)) { + $result[$index] = $value; + } + } + + return array_reverse($result); +} \ No newline at end of file diff --git a/tests/Array/TakeRightWhileTest.php b/tests/Array/TakeRightWhileTest.php new file mode 100644 index 0000000..a9b6c2f --- /dev/null +++ b/tests/Array/TakeRightWhileTest.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\takeRightWhile; + +class TakeRightWhileTest extends TestCase +{ + public function testTakeRightWhile() + { + $users = [ + ['user' => 'barney', 'active' => false], + ['user' => 'fred', 'active' => true], + ['user' => 'pebbles', 'active' => true], + ]; + + $this->assertSame([['user' => 'fred', 'active' => true], ['user' => 'pebbles', 'active' => true]], takeRightWhile($users, function ($value) { return $value['active']; })); + } +} \ No newline at end of file From 798f8791677cca41f372d55429c770454f42eb20 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 Dec 2017 11:48:11 +0200 Subject: [PATCH 006/159] Add Array.union function --- src/Array/union.php | 34 ++++++++++++++++++++++++++++++++++ tests/Array/UnionTest.php | 21 +++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/Array/union.php create mode 100644 tests/Array/UnionTest.php diff --git a/src/Array/union.php b/src/Array/union.php new file mode 100644 index 0000000..8df4986 --- /dev/null +++ b/src/Array/union.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @category Array + * + * @param array[] $arrays The arrays to inspect. + * + * @return array the new array of combined values. + * + * @example + * + * union([2], [1, 2]) + * // => [2, 1] + * + */ +function union(array ...$arrays): array +{ + return array_unique(array_merge(...$arrays)); +} \ No newline at end of file diff --git a/tests/Array/UnionTest.php b/tests/Array/UnionTest.php new file mode 100644 index 0000000..23ee752 --- /dev/null +++ b/tests/Array/UnionTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\union; +use PHPUnit\Framework\TestCase; + +class UnionTest extends TestCase +{ + public function testUnion() + { + $this->assertSame([2, 1], union([2], [1, 2])); + } +} \ No newline at end of file From c95eb8878c59de47fd72a9320a34680b0163047e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 20 Dec 2017 22:27:47 +0200 Subject: [PATCH 007/159] Change organization name to lodash-php --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f82291f..23bd559 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "solidworx/lodash-php", + "name": "lodash-php/lodash-php", "description": "A port of Lodash to PHP", "keywords": [ "lodash", From 1dae51041aa69c1e426af6abffe392bc8143af62 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 21 Dec 2017 10:10:10 +0200 Subject: [PATCH 008/159] Update README --- README.md | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++- bin/build | 4 +- 2 files changed, 197 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d048312..abc871a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Lodash-PHP tries to mimick lodash.js as close as possible Install Lodash-PHP through composer: ```bash -$ composer require solidworx/lodash-php +$ composer require lodash-php/lodash-php ``` # Usage @@ -1053,6 +1053,200 @@ Creates a slice of `array` from `start` up to, but not including, `end`. @return array the slice of `array`. +### tail + +Gets all but the first element of `array`. + + + +**Arguments:** + +@param array $array The array to query. + + + +**Return:** + +@return array the slice of `array`. + +Example: +```php + [2, 3] + +``` +### take + +Creates a slice of `array` with `n` elements taken from the beginning. + + + +**Arguments:** + +@param array $array The array to query. + +@param int $n The number of elements to take. + + + +**Return:** + +@return array the slice of `array`. + +Example: +```php + [1] + +take([1, 2, 3], 2) +// => [1, 2] + +take([1, 2, 3], 5) +// => [1, 2, 3] + +take([1, 2, 3], 0) +// => [] + +``` +### takeRight + +Creates a slice of `array` with `n` elements taken from the end. + + + +**Arguments:** + +@param array $array The array to query. + +@param int $n The number of elements to take. + + + +**Return:** + +@return array the slice of `array`. + +Example: +```php + [3] + +takeRight([1, 2, 3], 2) +// => [2, 3] + +takeRight([1, 2, 3], 5) +// => [1, 2, 3] + +takeRight([1, 2, 3], 0) +// => [] + +``` +### takeRightWhile + +Creates a slice of `array` with elements taken from the end. Elements are +taken until `predicate` returns falsey. The predicate is invoked with +three arguments: (value, index, array). + + + +**Arguments:** + +@param array $array The array to query. + +@param callable $predicate The function invoked per iteration. + + + +**Return:** + +@return array the slice of `array`. + +Example: +```php + 'barney', 'active' => false ], + [ 'user' => 'fred', 'active' => true ], + [ 'user' => 'pebbles', 'active' => true ] +]; + +takeRightWhile($users, function($value) { return $value['active']; }) +// => objects for ['fred', 'pebbles'] + +``` +### takeWhile + +Creates a slice of `array` with elements taken from the beginning. Elements +are taken until `predicate` returns falsey. The predicate is invoked with +three arguments: (value, index, array). + + + +**Arguments:** + +@param array $array The array to query. + +@param mixed $predicate The function invoked per iteration. + + + +**Return:** + +@return array the slice of `array`. + +Example: +```php + 'barney', 'active' => true ], + [ 'user' => 'fred', 'active' => true ], + [ 'user' => 'pebbles', 'active' => false ] +] + +takeWhile($users, function($value) { return $value['active']; }) +// => objects for ['barney', 'fred'] + +``` +### union + +Creates an array of unique values, in order, from all given arrays using +[`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) +for equality comparisons. + + + +**Arguments:** + +@param array[] $arrays The arrays to inspect. + + + +**Return:** + +@return array the new array of combined values. + +Example: +```php + [2, 1] + +``` ## Collection ### each diff --git a/bin/build b/bin/build index 2b80eaa..d0c789d 100755 --- a/bin/build +++ b/bin/build @@ -74,7 +74,7 @@ Lodash-PHP tries to mimick lodash.js as close as possible Install Lodash-PHP through composer: ```bash -$ composer require solidworx/lodash-php +$ composer require lodash-php/lodash-php ``` # Usage @@ -121,4 +121,4 @@ foreach ($readme as $category => $functions) { } } -file_put_contents(dirname(__DIR__).'/README.md', $content); \ No newline at end of file +file_put_contents(dirname(__DIR__).'/README.md', $content); From e8b3042e40bbb580b62f2bdcb0ee8685414e19d0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 5 Jan 2018 18:13:39 +0200 Subject: [PATCH 009/159] Add Array.uniq function --- src/Array/uniq.php | 35 +++++++++++++++++++++++++++++++++++ tests/Array/UniqTest.php | 21 +++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/Array/uniq.php create mode 100644 tests/Array/UniqTest.php diff --git a/src/Array/uniq.php b/src/Array/uniq.php new file mode 100644 index 0000000..e292325 --- /dev/null +++ b/src/Array/uniq.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @category Array + * + * @param array $array The array to inspect. + * + * @return array the new duplicate free array. + * @example + * + * uniq([2, 1, 2]) + * // => [2, 1]s + * + */ +function uniq(array $array = null): array +{ + return \array_unique($array); +} \ No newline at end of file diff --git a/tests/Array/UniqTest.php b/tests/Array/UniqTest.php new file mode 100644 index 0000000..c087cd4 --- /dev/null +++ b/tests/Array/UniqTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\uniq; +use PHPUnit\Framework\TestCase; + +class UniqTest extends TestCase +{ + public function testUniq() + { + $this->assertSame([2, 1], uniq([2, 1, 2])); + } +} \ No newline at end of file From 031aac9d42dbaa7eb6972c6003d85d402c578642 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 10:29:11 +0200 Subject: [PATCH 010/159] Add Array.unionBy function --- src/Array/unionBy.php | 45 ++++++++++++++++++++++++++++ src/internal/baseFlatten.php | 4 +-- src/internal/baseUniq.php | 57 ++++++++++++++++++++++++++++++++++++ tests/Array/UnionByTest.php | 22 ++++++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 src/Array/unionBy.php create mode 100644 src/internal/baseUniq.php create mode 100644 tests/Array/UnionByTest.php diff --git a/src/Array/unionBy.php b/src/Array/unionBy.php new file mode 100644 index 0000000..4af0fd2 --- /dev/null +++ b/src/Array/unionBy.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseFlatten; +use function _\internal\baseIteratee; +use function _\internal\baseUniq; + +/** + * This method is like `union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which uniqueness is computed. Result values are chosen from the first + * array in which the value occurs. The iteratee is invoked with one argument: + * (value). + * + * @category Array + * + * @param array[] $arrays The arrays to inspect. + * @param callable $iteratee The iteratee invoked per element. + * + * @return array the new array of combined values. + * + * @example + * + * unionBy([2.1], [1.2, 2.3], 'floor') + * // => [2.1, 1.2] + * + * // The `_::property` iteratee shorthand. + * unionBy([['x' => 1]], [['x' => 2], ['x' => 1]], 'x'); + * // => [['x' => 1], ['x' => 2]] + * + */ +function unionBy(...$arrays): array +{ + return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); +} \ No newline at end of file diff --git a/src/internal/baseFlatten.php b/src/internal/baseFlatten.php index 9072d37..05542b2 100644 --- a/src/internal/baseFlatten.php +++ b/src/internal/baseFlatten.php @@ -32,7 +32,7 @@ function baseFlatten(?array $array, float $depth, callable $predicate = null, bo return $result; } - $predicate = $predicate ?? '_\internal\isFlattenable'; + $predicate = $predicate ?? '\_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { @@ -43,7 +43,7 @@ function baseFlatten(?array $array, float $depth, callable $predicate = null, bo $result = \array_merge($result, $value); } } else if (!$isStrict) { - $result[count($result)] = $value; + $result[\count($result)] = $value; } } diff --git a/src/internal/baseUniq.php b/src/internal/baseUniq.php new file mode 100644 index 0000000..611c47d --- /dev/null +++ b/src/internal/baseUniq.php @@ -0,0 +1,57 @@ + + * @copyright Copyright (c) 2018 + */ + +function baseUniq(array $array, callable $iteratee = null, callable $comparator = null) +{ + $index = -1; + $includes = '\_\internal\arrayIncludes'; + $length = \count($array); + $isCommon = true; + $result = []; + $seen = $result; + + if ($comparator) { + $isCommon = false; + $includes = '\_\internal\arrayIncludesWith'; + } else { + $seen = $iteratee ? [] : $result; + } + + while (++$index < $length) { + $value = $array[$index]; + $computed = $iteratee ? $iteratee($value) : $value; + + $value = ($comparator || $value !== 0) ? $value : 0; + + if ($isCommon && $computed) { + $seenIndex = \count($seen); + while ($seenIndex--) { + if ($seen[$seenIndex] === $computed) { + continue 2; + } + } + if ($iteratee) { + $seen[] = $computed; + } + + $result[] = $value; + } else if (!$includes($seen, $computed, $comparator)) { + if ($seen !== $result) { + $seen[] = $computed; + } + $result[] = $value; + } + } + + return $result; +} diff --git a/tests/Array/UnionByTest.php b/tests/Array/UnionByTest.php new file mode 100644 index 0000000..01d02c4 --- /dev/null +++ b/tests/Array/UnionByTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\unionBy; +use PHPUnit\Framework\TestCase; + +class UnionByTest extends TestCase +{ + public function testUnionBy() + { + $this->assertSame([2.1, 1.2], unionBy([2.1], [1.2, 2.3], 'floor')); + $this->assertSame([['x' => 1], ['x' => 2]], unionBy([['x' => 1]], [['x' => 2], ['x' => 1]], 'x')); + } +} \ No newline at end of file From 99a9a0cdff6232befc72fea079400e1011cded02 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 10:50:38 +0200 Subject: [PATCH 011/159] Add Array.unionWith function --- src/Array/unionWith.php | 40 +++++++++++++++++++++++++++++++++++ src/internal/baseUniq.php | 2 +- tests/Array/UnionWithTest.php | 24 +++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/Array/unionWith.php create mode 100644 tests/Array/UnionWithTest.php diff --git a/src/Array/unionWith.php b/src/Array/unionWith.php new file mode 100644 index 0000000..5960598 --- /dev/null +++ b/src/Array/unionWith.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseFlatten; +use function _\internal\baseUniq; + +/** + * This method is like `union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. Result values are chosen from + * the first array in which the value occurs. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @category Array + * + * @param array[] $arrays The arrays to inspect. + * @param callable $comparator The comparator invoked per element. + * + * @return array the new array of combined values. + * @example + * + * $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]] + * $others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]] + * + * unionWith($objects, $others, '_::isEqual') + * // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] + */ +function unionWith(... $arrays): array +{ + return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); +} \ No newline at end of file diff --git a/src/internal/baseUniq.php b/src/internal/baseUniq.php index 611c47d..0be1b46 100644 --- a/src/internal/baseUniq.php +++ b/src/internal/baseUniq.php @@ -45,7 +45,7 @@ function baseUniq(array $array, callable $iteratee = null, callable $comparator } $result[] = $value; - } else if (!$includes($seen, $computed, $comparator)) { + } else if (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } diff --git a/tests/Array/UnionWithTest.php b/tests/Array/UnionWithTest.php new file mode 100644 index 0000000..b130188 --- /dev/null +++ b/tests/Array/UnionWithTest.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\unionWith; + +class UnionWithTest extends TestCase +{ + public function testUnionWith() + { + $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]]; + $others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]]; + + $this->assertSame([['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]], unionWith($objects, $others, '_::isEqual')); + } +} \ No newline at end of file From fe935d3e86b7f7435de98b182ab4ec4cec028682 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 10:52:41 +0200 Subject: [PATCH 012/159] Add Array.uniqBy function --- src/Array/uniqBy.php | 39 ++++++++++++++++++++++++++++++++++++++ tests/Array/UniqByTest.php | 21 ++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/Array/uniqBy.php create mode 100644 tests/Array/UniqByTest.php diff --git a/src/Array/uniqBy.php b/src/Array/uniqBy.php new file mode 100644 index 0000000..aeaa7fe --- /dev/null +++ b/src/Array/uniqBy.php @@ -0,0 +1,39 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; +use function _\internal\baseUniq; + +/** + * This method is like `uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @category Array + * + * @param array $array The array to inspect. + * @param mixed $iteratee The iteratee invoked per element. + * + * @return array the new duplicate free array. + * @see uniq, uniqWith + * @example + * + * uniqBy([2.1, 1.2, 2.3], 'floor') + * // => [2.1, 1.2] + */ +function uniqBy(array $array, $iteratee): array +{ + return baseUniq($array, baseIteratee($iteratee)); +} \ No newline at end of file diff --git a/tests/Array/UniqByTest.php b/tests/Array/UniqByTest.php new file mode 100644 index 0000000..4d2b898 --- /dev/null +++ b/tests/Array/UniqByTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\uniqBy; +use PHPUnit\Framework\TestCase; + +class UniqByTest extends TestCase +{ + public function testUniqBy() + { + $this->assertSame([2.1, 1.2], uniqBy([2.1, 1.2, 2.3], 'floor')); + } +} \ No newline at end of file From 9961047db3cd0787d1f566da8a24d8842ce54f18 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 10:55:29 +0200 Subject: [PATCH 013/159] Add Array.uniqWith function --- src/Array/uniqWith.php | 39 ++++++++++++++++++++++++++++++++++++ tests/Array/UniqWithTest.php | 22 ++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/Array/uniqWith.php create mode 100644 tests/Array/UniqWithTest.php diff --git a/src/Array/uniqWith.php b/src/Array/uniqWith.php new file mode 100644 index 0000000..911cdad --- /dev/null +++ b/src/Array/uniqWith.php @@ -0,0 +1,39 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseUniq; + +/** + * This method is like `uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @category Array + * + * @param array $array The array to inspect. + * @param callable $comparator The comparator invoked per element. + * + * @return array the new duplicate free array. + * @example + * + * $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 2]] + * + * uniqWith($objects, '_::isEqual') + * // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]] + * + */ +function uniqWith(array $array, callable $comparator): array +{ + return baseUniq($array, null, $comparator); +} \ No newline at end of file diff --git a/tests/Array/UniqWithTest.php b/tests/Array/UniqWithTest.php new file mode 100644 index 0000000..c82dab6 --- /dev/null +++ b/tests/Array/UniqWithTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\uniqWith; + +class UniqWithTest extends TestCase +{ + public function testUniqWith() + { + $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 2]]; + $this->assertSame([['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]], uniqWith($objects, '_::isEqual')); + } +} \ No newline at end of file From 107ce214bf63a36ed498200a0643b99f548d7721 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:00:18 +0200 Subject: [PATCH 014/159] Add Array.zip and Array.unzip functions --- src/Array/unzip.php | 55 +++++++++++++++++++++++++++++++++++ src/Array/zip.php | 35 ++++++++++++++++++++++ src/internal/arrayMap.php | 25 ++++++++++++++++ src/internal/baseProperty.php | 4 +-- src/internal/baseRest.php | 17 +++++++++++ src/internal/baseTimes.php | 24 +++++++++++++++ src/internal/overRest.php | 36 +++++++++++++++++++++++ tests/Array/UnzipTest.php | 22 ++++++++++++++ tests/Array/ZipTest.php | 21 +++++++++++++ 9 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 src/Array/unzip.php create mode 100644 src/Array/zip.php create mode 100644 src/internal/arrayMap.php create mode 100644 src/internal/baseRest.php create mode 100644 src/internal/baseTimes.php create mode 100644 src/internal/overRest.php create mode 100644 tests/Array/UnzipTest.php create mode 100644 tests/Array/ZipTest.php diff --git a/src/Array/unzip.php b/src/Array/unzip.php new file mode 100644 index 0000000..b742586 --- /dev/null +++ b/src/Array/unzip.php @@ -0,0 +1,55 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\arrayMap; +use function _\internal\baseProperty; +use function _\internal\baseTimes; + +/** + * This method is like `zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @category Array + * + * @param array $array The array of grouped elements to process. + * + * @return array the new array of regrouped elements. + * @example + * + * $zipped = zip(['a', 'b'], [1, 2], [true, false]) + * // => [['a', 1, true], ['b', 2, false]] + * + * unzip($zipped) + * // => [['a', 'b'], [1, 2], [true, false]] + * + */ +function unzip(array $array): array +{ + if (!\count($array)) { + return []; + } + + $length = 0; + $array = \array_filter($array, function ($group) use (&$length) { + if (\is_array($group)) { + $length = max(\count($group), $length); + + return true; + } + }); + + return baseTimes($length, function ($index) use ($array) { + return arrayMap($array, baseProperty($index)); + }); +} \ No newline at end of file diff --git a/src/Array/zip.php b/src/Array/zip.php new file mode 100644 index 0000000..34d4790 --- /dev/null +++ b/src/Array/zip.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseRest; + +/** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @category Array + * + * @param array[] $arrays The arrays to process. + * + * @return array the new array of grouped elements. + * @example + * + * zip(['a', 'b'], [1, 2], [true, false]) + * // => [['a', 1, true], ['b', 2, false]] + * + */ +function zip(array ...$arrays): array +{ + return baseRest('\_\unzip')(...$arrays); +} \ No newline at end of file diff --git a/src/internal/arrayMap.php b/src/internal/arrayMap.php new file mode 100644 index 0000000..f0f86fd --- /dev/null +++ b/src/internal/arrayMap.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function arrayMap(?array $array, callable $iteratee) +{ + $index = -1; + $length = null === $array ? 0 : \count($array); + $result = []; + + while (++$index < $length) { + $result[$index] = $iteratee($array[$index], $index, $array); + } + + return $result; +} \ No newline at end of file diff --git a/src/internal/baseProperty.php b/src/internal/baseProperty.php index cd14aa7..7d4c64e 100644 --- a/src/internal/baseProperty.php +++ b/src/internal/baseProperty.php @@ -14,11 +14,11 @@ /** * The base implementation of `_.property` without support for deep paths. * - * @param string $key The key of the property to get. + * @param mixed $key The key of the property to get. * * @return callable Returns the new accessor function. */ -function baseProperty(string $key) +function baseProperty($key) { return function ($object) use ($key) { return null === $object ? null : $object[$key]; diff --git a/src/internal/baseRest.php b/src/internal/baseRest.php new file mode 100644 index 0000000..cf53480 --- /dev/null +++ b/src/internal/baseRest.php @@ -0,0 +1,17 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function baseRest(callable $func, $start = null) +{ + return overRest($func, $start, '\_\identity'); +} \ No newline at end of file diff --git a/src/internal/baseTimes.php b/src/internal/baseTimes.php new file mode 100644 index 0000000..67a44a4 --- /dev/null +++ b/src/internal/baseTimes.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function baseTimes(int $n, callable $iteratee) +{ + $index = -1; + $result = []; + + while (++$index < $n) { + $result[$index] = $iteratee($index); + } + + return $result; +} \ No newline at end of file diff --git a/src/internal/overRest.php b/src/internal/overRest.php new file mode 100644 index 0000000..667262f --- /dev/null +++ b/src/internal/overRest.php @@ -0,0 +1,36 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function overRest(callable $func, $start, callable $transform) +{ + $start = max($start ?? -1, 0); + + return function () use ($func, $start, $transform) { + $args = \func_get_args(); + $index = -1; + $length = \max(\count($args) - $start, 0); + $array = []; + + while (++$index < $length) { + $array[$index] = $args[$start + $index]; + } + $index = -1; + $otherArgs = []; + while (++$index < $start) { + $otherArgs[$index] = $args[$index]; + } + $otherArgs[$start] = $transform($array); + + return $func(...$otherArgs); + }; +} \ No newline at end of file diff --git a/tests/Array/UnzipTest.php b/tests/Array/UnzipTest.php new file mode 100644 index 0000000..d28392d --- /dev/null +++ b/tests/Array/UnzipTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\unzip; + +class UnzipTest extends TestCase +{ + public function testUnzip() + { + $zipped = [['a', 1, true], ['b', 2, false]]; + $this->assertSame([['a', 'b'], [1, 2], [true, false]], unzip($zipped)); + } +} \ No newline at end of file diff --git a/tests/Array/ZipTest.php b/tests/Array/ZipTest.php new file mode 100644 index 0000000..cfa1ee2 --- /dev/null +++ b/tests/Array/ZipTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\zip; + +class ZipTest extends TestCase +{ + public function testZip() + { + $this->assertSame([['a', 1, true], ['b', 2, false]], zip(['a', 'b'], [1, 2], [true, false])); + } +} \ No newline at end of file From 2f9df19587c9e53228b0fc00f95952f30204e82a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:19:02 +0200 Subject: [PATCH 015/159] Add Math.add function --- src/Math/add.php | 37 ++++++++++++++++++++++++++++ src/internal/createMathOperation.php | 37 ++++++++++++++++++++++++++++ tests/Math/AddTest.php | 21 ++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 src/Math/add.php create mode 100644 src/internal/createMathOperation.php create mode 100644 tests/Math/AddTest.php diff --git a/src/Math/add.php b/src/Math/add.php new file mode 100644 index 0000000..5a5fc5b --- /dev/null +++ b/src/Math/add.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use function _\internal\createMathOperation; + +/** + * Adds two numbers. + * + * @category Math + * + * @param int|float|string $augend The first number in an addition. + * @param int|float|string $addend The second number in an addition. + * + * @returns int|float Returns the total. + * + * @example + * + * add(6, 4); + * // => 10 + * + */ +function add($augend, $addend) +{ + return createMathOperation(function ($augend, $addend) { + return $augend + $addend; + }, 0)($augend, $addend); +} \ No newline at end of file diff --git a/src/internal/createMathOperation.php b/src/internal/createMathOperation.php new file mode 100644 index 0000000..f5beff5 --- /dev/null +++ b/src/internal/createMathOperation.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function createMathOperation(callable $operator, $defaultValue) +{ + return function ($value, $other) use ($defaultValue, $operator) { + if (null === $value && null === $other) { + return $defaultValue; + } + + $result = null; + + if (null !== $value) { + $result = $value; + } + + if (null !== $other) { + if (null === $result) { + return $other; + } + + $result = $operator($value, $other); + } + + return $result; + }; +} \ No newline at end of file diff --git a/tests/Math/AddTest.php b/tests/Math/AddTest.php new file mode 100644 index 0000000..c5cc06b --- /dev/null +++ b/tests/Math/AddTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\add; + +class AddTest extends TestCase +{ + public function testAdd() + { + $this->assertSame(10, add(6, 4)); + } +} \ No newline at end of file From 00aa2834ec9a27192cd021d8924d57834820baf8 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:25:17 +0200 Subject: [PATCH 016/159] Add Array.unzipWith function --- src/Array/unzipWith.php | 51 +++++++++++++++++++++++++++++++++++ tests/Array/UnzipWithTest.php | 22 +++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/Array/unzipWith.php create mode 100644 tests/Array/UnzipWithTest.php diff --git a/src/Array/unzipWith.php b/src/Array/unzipWith.php new file mode 100644 index 0000000..ef55fd8 --- /dev/null +++ b/src/Array/unzipWith.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\arrayMap; + +/** + * This method is like `unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @category Array + * + * @param array $array The array of grouped elements to process. + * @param callable $iteratee The function to combine regrouped values. + * + * @return array the new array of regrouped elements. + * @example + * + * $zipped = zip([1, 2], [10, 20], [100, 200]) + * // => [[1, 10, 100], [2, 20, 200]] + * + * unzipWith(zipped, '_::add') + * // => [3, 30, 300] + * + */ +function unzipWith(array $array, callable $iteratee): array +{ + + if (!\count($array)) { + return []; + } + + $result = unzip($array); + if (null === $iteratee) { + return $result; + } + + return arrayMap($result, function ($group) use ($iteratee) { + return $iteratee(...$group); + }); +} \ No newline at end of file diff --git a/tests/Array/UnzipWithTest.php b/tests/Array/UnzipWithTest.php new file mode 100644 index 0000000..04a9714 --- /dev/null +++ b/tests/Array/UnzipWithTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\unzipWith; +use PHPUnit\Framework\TestCase; + +class UnzipWithTest extends TestCase +{ + public function testUnzipWith() + { + $zipped = [[1, 10, 100], [2, 20, 200]]; + $this->assertSame([3, 30, 300], unzipWith($zipped, '_::add')); + } +} \ No newline at end of file From d68a275c28776ace3ee84c10aa22806649fd8d28 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:39:51 +0200 Subject: [PATCH 017/159] Add Array.without function --- src/Array/without.php | 38 +++++++++++++++++++++++++++++++++++++ src/Array/zip.php | 2 +- src/internal/baseRest.php | 2 +- src/internal/overRest.php | 4 ++-- tests/Array/WithoutTest.php | 21 ++++++++++++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 src/Array/without.php create mode 100644 tests/Array/WithoutTest.php diff --git a/src/Array/without.php b/src/Array/without.php new file mode 100644 index 0000000..64d38e5 --- /dev/null +++ b/src/Array/without.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseRest; + +/** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `pull`, this method returns a new array. + * + * @category Array + * + * @param array $array The array to inspect. + * @param mixed[] $values The values to exclude. + * + * @return array the new array of filtered values. + * @example + * + * without([2, 1, 2, 3], 1, 2) + * // => [3] + * + */ +function without(array $array, ...$values): array +{ + return baseRest('\_\difference')($array, $values); +} \ No newline at end of file diff --git a/src/Array/zip.php b/src/Array/zip.php index 34d4790..b50bb3c 100644 --- a/src/Array/zip.php +++ b/src/Array/zip.php @@ -31,5 +31,5 @@ */ function zip(array ...$arrays): array { - return baseRest('\_\unzip')(...$arrays); + return baseRest('\_\unzip')($arrays); } \ No newline at end of file diff --git a/src/internal/baseRest.php b/src/internal/baseRest.php index cf53480..bf7e16b 100644 --- a/src/internal/baseRest.php +++ b/src/internal/baseRest.php @@ -11,7 +11,7 @@ namespace _\internal; -function baseRest(callable $func, $start = null) +function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } \ No newline at end of file diff --git a/src/internal/overRest.php b/src/internal/overRest.php index 667262f..8f4e9ee 100644 --- a/src/internal/overRest.php +++ b/src/internal/overRest.php @@ -11,7 +11,7 @@ namespace _\internal; -function overRest(callable $func, $start, callable $transform) +function overRest(callable $func, $start, callable $transform): callable { $start = max($start ?? -1, 0); @@ -31,6 +31,6 @@ function overRest(callable $func, $start, callable $transform) } $otherArgs[$start] = $transform($array); - return $func(...$otherArgs); + return $func(...$otherArgs[$start]); }; } \ No newline at end of file diff --git a/tests/Array/WithoutTest.php b/tests/Array/WithoutTest.php new file mode 100644 index 0000000..bc030d3 --- /dev/null +++ b/tests/Array/WithoutTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\without; + +class WithoutTest extends TestCase +{ + public function testWithout() + { + $this->assertSame([3], without([2, 1, 2, 3], 1, 2)); + } +} \ No newline at end of file From eec42aca5690233dd41e84a44ab36b05e6ff77d7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:50:04 +0200 Subject: [PATCH 018/159] Fix dockblock --- src/Array/uniqBy.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Array/uniqBy.php b/src/Array/uniqBy.php index aeaa7fe..012d557 100644 --- a/src/Array/uniqBy.php +++ b/src/Array/uniqBy.php @@ -27,13 +27,13 @@ * @param mixed $iteratee The iteratee invoked per element. * * @return array the new duplicate free array. - * @see uniq, uniqWith * @example - * + * * uniqBy([2.1, 1.2, 2.3], 'floor') * // => [2.1, 1.2] + * */ function uniqBy(array $array, $iteratee): array { return baseUniq($array, baseIteratee($iteratee)); -} \ No newline at end of file +} From 3fe0fb900baa0271e67ea8c6c0febad69c59dab6 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:52:54 +0200 Subject: [PATCH 019/159] Fix dockblocks --- src/Math/add.php | 2 +- src/internal/stringSize.php | 9 ++++++--- src/internal/stringToArray.php | 2 +- src/internal/toKey.php | 2 +- src/internal/unicodeSize.php | 2 +- src/internal/unicodeToArray.php | 2 +- src/internal/unicodeWords.php | 6 +++--- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Math/add.php b/src/Math/add.php index 5a5fc5b..28ff7c1 100644 --- a/src/Math/add.php +++ b/src/Math/add.php @@ -21,7 +21,7 @@ * @param int|float|string $augend The first number in an addition. * @param int|float|string $addend The second number in an addition. * - * @returns int|float Returns the total. + * @return int|float Returns the total. * * @example * diff --git a/src/internal/stringSize.php b/src/internal/stringSize.php index 4957576..0abe8e7 100644 --- a/src/internal/stringSize.php +++ b/src/internal/stringSize.php @@ -15,9 +15,12 @@ * Gets the number of symbols in `string`. * * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. + * + * @param string string The string to inspect. + * + * @return int Returns the string size. */ -function stringSize(string $string) { +function stringSize(string $string): int +{ return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } \ No newline at end of file diff --git a/src/internal/stringToArray.php b/src/internal/stringToArray.php index f451361..a131447 100644 --- a/src/internal/stringToArray.php +++ b/src/internal/stringToArray.php @@ -18,7 +18,7 @@ * * @param string $string The string to convert. * - * @returns array Returns the converted array. + * @return array Returns the converted array. */ function stringToArray(string $string): array { diff --git a/src/internal/toKey.php b/src/internal/toKey.php index e44522f..18fafdd 100644 --- a/src/internal/toKey.php +++ b/src/internal/toKey.php @@ -16,7 +16,7 @@ * * @param mixed value The value to inspect. * - * @returns string Returns the key. + * @return string Returns the key. */ function toKey($value): string { diff --git a/src/internal/unicodeSize.php b/src/internal/unicodeSize.php index af7f993..0cfb263 100644 --- a/src/internal/unicodeSize.php +++ b/src/internal/unicodeSize.php @@ -18,7 +18,7 @@ * * @param string $string The string inspect. * - * @returns int Returns the string size. + * @return int Returns the string size. */ function unicodeSize($string): int { diff --git a/src/internal/unicodeToArray.php b/src/internal/unicodeToArray.php index bcf5f3e..b63030f 100644 --- a/src/internal/unicodeToArray.php +++ b/src/internal/unicodeToArray.php @@ -18,7 +18,7 @@ * * @param string $string The string to convert. * - * @returns array Returns the converted array. + * @return array Returns the converted array. */ function unicodeToArray(string $string): array { diff --git a/src/internal/unicodeWords.php b/src/internal/unicodeWords.php index 25602f6..6003608 100644 --- a/src/internal/unicodeWords.php +++ b/src/internal/unicodeWords.php @@ -16,10 +16,10 @@ * * @private * - * @param {string} The string to inspect. - * @returns {Array} Returns the words of `string`. + * @param string The string to inspect. + * @return array Returns the words of `string`. */ -function unicodeWords(string $string) +function unicodeWords(string $string): array { $regex = '#'.\implode('|', [ rsUpper.'?'.rsLower.'+'.rsOptContrLower.'(?='.\implode('|', [rsBreak, rsUpper, '$']).')', From f306a5a38c93a066bb1b541b078ac5d80c7b4c28 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 8 Jan 2018 12:53:19 +0200 Subject: [PATCH 020/159] Update README with new functions --- README.md | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) diff --git a/README.md b/README.md index abc871a..8d51d3d 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ _::each([1, 2, 3], function (int $item) { - [Collection](#collection) - [Date](#date) - [Lang](#lang) +- [Math](#math) - [Number](#number) - [String](#string) - [Util](#util) @@ -1246,6 +1247,282 @@ Example: union([2], [1, 2]) // => [2, 1] +``` +### unionBy + +This method is like `union` except that it accepts `iteratee` which is +invoked for each element of each `arrays` to generate the criterion by +which uniqueness is computed. Result values are chosen from the first +array in which the value occurs. The iteratee is invoked with one argument: +(value). + + + +**Arguments:** + +@param array[] $arrays The arrays to inspect. + +@param callable $iteratee The iteratee invoked per element. + + + +**Return:** + +@return array the new array of combined values. + +Example: +```php + [2.1, 1.2] + +// The `_::property` iteratee shorthand. +unionBy([['x' => 1]], [['x' => 2], ['x' => 1]], 'x'); +// => [['x' => 1], ['x' => 2]] + +``` +### unionWith + +This method is like `union` except that it accepts `comparator` which +is invoked to compare elements of `arrays`. Result values are chosen from +the first array in which the value occurs. The comparator is invoked +with two arguments: (arrVal, othVal). + + + +**Arguments:** + +@param array[] $arrays The arrays to inspect. + +@param callable $comparator The comparator invoked per element. + + + +**Return:** + +@return array the new array of combined values. + +Example: +```php + 1, 'y' => 2], ['x' => 2, 'y' => 1]] +$others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]] + +unionWith($objects, $others, '_::isEqual') +// => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] +``` +### uniq + +Creates a duplicate-free version of an array, using +[`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) +for equality comparisons, in which only the first occurrence of each element +is kept. The order of result values is determined by the order they occur +in the array. + + + +**Arguments:** + +@param array $array The array to inspect. + + + +**Return:** + +@return array the new duplicate free array. + +Example: +```php + [2, 1]s + +``` +### uniqBy + +This method is like `uniq` except that it accepts `iteratee` which is +invoked for each element in `array` to generate the criterion by which +uniqueness is computed. The order of result values is determined by the +order they occur in the array. The iteratee is invoked with one argument: +(value). + + + +**Arguments:** + +@param array $array The array to inspect. + +@param mixed $iteratee The iteratee invoked per element. + + + +**Return:** + +@return array the new duplicate free array. + +Example: +```php + [2.1, 1.2] + +``` +### uniqWith + +This method is like `uniq` except that it accepts `comparator` which +is invoked to compare elements of `array`. The order of result values is +determined by the order they occur in the array.The comparator is invoked +with two arguments: (arrVal, othVal). + + + +**Arguments:** + +@param array $array The array to inspect. + +@param callable $comparator The comparator invoked per element. + + + +**Return:** + +@return array the new duplicate free array. + +Example: +```php + 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 2]] + +uniqWith($objects, '_::isEqual') +// => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]] + +``` +### unzip + +This method is like `zip` except that it accepts an array of grouped +elements and creates an array regrouping the elements to their pre-zip +configuration. + + + +**Arguments:** + +@param array $array The array of grouped elements to process. + + + +**Return:** + +@return array the new array of regrouped elements. + +Example: +```php + [['a', 1, true], ['b', 2, false]] + +unzip($zipped) +// => [['a', 'b'], [1, 2], [true, false]] + +``` +### unzipWith + +This method is like `unzip` except that it accepts `iteratee` to specify +how regrouped values should be combined. The iteratee is invoked with the +elements of each group: (. + +..group). + +**Arguments:** + +@param array $array The array of grouped elements to process. + +@param callable $iteratee The function to combine regrouped values. + + + +**Return:** + +@return array the new array of regrouped elements. + +Example: +```php + [[1, 10, 100], [2, 20, 200]] + +unzipWith(zipped, '_::add') +// => [3, 30, 300] + +``` +### without + +Creates an array excluding all given values using +[`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) +for equality comparisons. + +**Note:** Unlike `pull`, this method returns a new array. + +**Arguments:** + +@param array $array The array to inspect. + +@param array $values The values to exclude. + + + +**Return:** + +@return array the new array of filtered values. + +Example: +```php + [3] + +``` +### zip + +Creates an array of grouped elements, the first of which contains the +first elements of the given arrays, the second of which contains the +second elements of the given arrays, and so on. + + + +**Arguments:** + +@param array[] $arrays The arrays to process. + + + +**Return:** + +@return array the new array of grouped elements. + +Example: +```php + [['a', 1, true], ['b', 2, false]] + ``` ## Collection @@ -1467,6 +1744,35 @@ isError(new \Exception()) isError(\Exception::Class) // => false +``` +## Math + +### add + +Adds two numbers. + + + +**Arguments:** + +@param int|float|string $augend The first number in an addition. + +@param int|float|string $addend The second number in an addition. + + + +**Return:** + +@return int|float Returns the total. + +Example: +```php + 10 + ``` ## Number From b875afe6e175957814a5aac5069f548a267ac507 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 23 Jan 2018 15:18:43 +0200 Subject: [PATCH 021/159] Allow more versions of sebastian/comparator --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 23bd559..d1209ea 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "require": { "php": "^7.1", - "sebastian/comparator": "^2.1", + "sebastian/comparator": "^1.2 | ^2.0 | ^2.1", "symfony/property-access": "^2.7 | ^3.0 | ^4.0" }, "require-dev": { From a5423476bcd03d8397bba2121bf2c207bc19a54e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 23 Jan 2018 15:27:47 +0200 Subject: [PATCH 022/159] Add Array.zipObject function --- src/Array/zipObject.php | 45 +++++++++++++++++++++++++++++++++++ tests/Array/ZipObjectTest.php | 21 ++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/Array/zipObject.php create mode 100644 tests/Array/ZipObjectTest.php diff --git a/src/Array/zipObject.php b/src/Array/zipObject.php new file mode 100644 index 0000000..fcfbd16 --- /dev/null +++ b/src/Array/zipObject.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * This method is like `fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @category Array + * + * @param array $props The property identifiers. + * @param array $values The property values. + * + * @return object the new object. + * + * @example + * + * zipObject(['a', 'b'], [1, 2]) + * // => { 'a': 1, 'b': 2 } + * + */ +function zipObject(array $props = [], array $values = []) +{ + $result = new \stdClass; + $index = -1; + $length = \count($props); + $props = \array_values($props); + $values = \array_values($values); + + while (++$index < $length) { + $value = $values[$index] ?? null; + $result->{$props[$index]} = $value; + } + + return $result; +} \ No newline at end of file diff --git a/tests/Array/ZipObjectTest.php b/tests/Array/ZipObjectTest.php new file mode 100644 index 0000000..7c649ea --- /dev/null +++ b/tests/Array/ZipObjectTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\zipObject; +use PHPUnit\Framework\TestCase; + +class ZipObjectTest extends TestCase +{ + public function testZipObject() + { + $this->assertEquals((object) ['a' => 1, 'b' => 2], zipObject(['a', 'b'], [1, 2])); + } +} \ No newline at end of file From acc05d9fa28a432cd320046ba91f730b2a7015da Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 23 Jan 2018 15:37:12 +0200 Subject: [PATCH 023/159] Add Array.zipWith function --- src/Array/zipObject.php | 6 +++++- src/Array/zipWith.php | 36 ++++++++++++++++++++++++++++++++++++ tests/Array/ZipWithTest.php | 21 +++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/Array/zipWith.php create mode 100644 tests/Array/ZipWithTest.php diff --git a/src/Array/zipObject.php b/src/Array/zipObject.php index fcfbd16..be0134a 100644 --- a/src/Array/zipObject.php +++ b/src/Array/zipObject.php @@ -25,7 +25,11 @@ * @example * * zipObject(['a', 'b'], [1, 2]) - * // => { 'a': 1, 'b': 2 } + * /* => object(stdClass)#210 (2) { + * ["a"] => int(1) + * ["b"] => int(2) + * } + * *\/ * */ function zipObject(array $props = [], array $values = []) diff --git a/src/Array/zipWith.php b/src/Array/zipWith.php new file mode 100644 index 0000000..b30bf7f --- /dev/null +++ b/src/Array/zipWith.php @@ -0,0 +1,36 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * This method is like `zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @category Array + * + * @param array[] $arrays The arrays to process. + * @param callable $iteratee The function to combine grouped values. + * + * @return array the new array of grouped elements. + * @example + * + * zipWith([1, 2], [10, 20], [100, 200], function($a, $b, $c) { return $a + $b + $c; }) + * // => [111, 222] + * + */ +function zipWith(...$arrays): array +{ + $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; + + return unzipWith($arrays, $iteratee); +} diff --git a/tests/Array/ZipWithTest.php b/tests/Array/ZipWithTest.php new file mode 100644 index 0000000..8b2462b --- /dev/null +++ b/tests/Array/ZipWithTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\zipWith; +use PHPUnit\Framework\TestCase; + +class ZipWithTest extends TestCase +{ + public function testZipWith() + { + $this->assertSame([111, 222], zipWith([1, 2], [10, 20], [100, 200], function($a, $b, $c) { return $a + $b + $c; })); + } +} \ No newline at end of file From b2e02a76cd8100b96f91704a868e4d9594f7f17b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 23 Jan 2018 22:32:10 +0200 Subject: [PATCH 024/159] Add Lang.eq function --- src/Lang/eq.php | 45 ++++++++++++++++++++++ tests/Lang/EqTest.php | 90 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 src/Lang/eq.php create mode 100644 tests/Lang/EqTest.php diff --git a/src/Lang/eq.php b/src/Lang/eq.php new file mode 100644 index 0000000..1c032fa --- /dev/null +++ b/src/Lang/eq.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +/** + * Performs a comparison between two values to determine if they are equivalent. + * + * @param mixed $value The value to compare. + * @param mixed $other The other value to compare. + * + * @return boolean Returns `true` if the values are equivalent, else `false`. + * @example + * + * $object = (object) ['a' => 1]; + * $other = (object) ['a' => 1]; + * + * eq($object, $object); + * // => true + * + * eq($object, $other); + * // => false + * + * eq('a', 'a'); + * // => true + * + * eq(['a'], (object) ['a']); + * // => false + * + * eq(INF, INF); + * // => true + * + */ +function eq($value, $other): bool +{ + return $value === $other; +} \ No newline at end of file diff --git a/tests/Lang/EqTest.php b/tests/Lang/EqTest.php new file mode 100644 index 0000000..8e20571 --- /dev/null +++ b/tests/Lang/EqTest.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\eq; + +class EqTest extends TestCase +{ + /** + * @dataProvider equalValues + */ + public function testIsEqual($value, $other) + { + $this->assertTrue(eq($value, $other)); + } + + /** + * @dataProvider notEqualValues + */ + public function testIsNotEqual($value, $other) + { + $this->assertFalse(eq($value, $other)); + } + + public function notEqualValues() + { + $ob1 = new StdClass(); + $ob1->a = 'b'; + $ob2 = new StdClass(); + + $ob3 = new StdClass(); + $ob4 = new StdClass(); + + return [ + [ + null, 'a', + ], + [ + 0, 1, + ], + [ + [1], [], + ], + [ + ['a' => 21], ['a' => 22], + ], + [ + ['a' => 21], ['a' => '21'], + ], + [ + $ob1, $ob2, + ], + + [ + $ob3, $ob4, + ], + [ + new DateTime('NOW'), new DateTime('NOW'), + ], + ]; + } + + public function equalValues() + { + $date = new DateTime('NOW'); + + return [ + [ + 'a', 'a', + ], + [ + 1, 1, + ], + [ + [], [], + ], + [ + $date, $date, + ], + ]; + } +} \ No newline at end of file From 797179683991cfebd72a98c7fd0ae432110d867e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 16:29:23 +0200 Subject: [PATCH 025/159] Add Function.memoize function --- composer.json | 2 + src/CacheInterface.php | 27 +++++++ src/Function/memoize.php | 99 ++++++++++++++++++++++++++ src/Hash.php | 59 +++++++++++++++ src/ListCache.php | 82 +++++++++++++++++++++ src/MapCache.php | 83 +++++++++++++++++++++ src/internal/Traits/CacheDataTrait.php | 24 +++++++ src/internal/assocIndexOf.php | 26 +++++++ src/internal/isKey.php | 4 +- tests/Function/MemoizeTest.php | 34 +++++++++ 10 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 src/CacheInterface.php create mode 100644 src/Function/memoize.php create mode 100644 src/Hash.php create mode 100644 src/ListCache.php create mode 100644 src/MapCache.php create mode 100644 src/internal/Traits/CacheDataTrait.php create mode 100644 src/internal/assocIndexOf.php create mode 100644 tests/Function/MemoizeTest.php diff --git a/composer.json b/composer.json index d1209ea..f0125a8 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,8 @@ "autoload": { "files": [ "src/internal/unicode.php", + "src/internal/Traits/CacheDataTrait.php", + "src/CacheInterface.php", "src/bootstrap.php" ] }, diff --git a/src/CacheInterface.php b/src/CacheInterface.php new file mode 100644 index 0000000..57951b7 --- /dev/null +++ b/src/CacheInterface.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +interface CacheInterface +{ + public function set($key, $value): CacheInterface; + + public function get($key); + + public function has($key): bool; + + public function clear(); + + public function delete($key); + + public function getSize(); +} \ No newline at end of file diff --git a/src/Function/memoize.php b/src/Function/memoize.php new file mode 100644 index 0000000..a06d780 --- /dev/null +++ b/src/Function/memoize.php @@ -0,0 +1,99 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @category Function + * + * @param callable $func The function to have its output memoized. + * @param callable $resolver The function to resolve the cache key. + * + * @returns callable Returns the new memoized function. + * + * @example + * + * $object = ['a' => 1, 'b' => 2]; + * $other = ['c' => 3, 'd' => 4]; + * + * $values = memoize('_\values'); + * $values($object); + * // => [1, 2] + * + * $values($other); + * // => [3, 4] + * + * $object['a'] = 2; + * $values($object); + * // => [1, 2] + * + * // Modify the result cache. + * $values->cache->set($object, ['a', 'b']); + * $values($object); + * // => ['a', 'b'] + */ +function memoize(callable $func = null, callable $resolver = null) +{ + $memoized = new class ($func, $resolver ?? null) + { + /** + * @var CacheInterface + */ + public $cache; + + private $resolver; + + private $func; + + public function __construct(callable $func, ?callable $resolver) + { + $this->resolver = $resolver; + $this->func = $func; + } + + public function __invoke() + { + $args = \func_get_args(); + + if ($this->resolver) { + $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); + } else { + $key = &$args[0]; + } + + $cache = $this->cache; + + if ($cache->has($key)) { + return $cache->get($key); + } + + $result = ($this->func)(...$args); + $this->cache = $this->cache->set($key, $result) ?: $this->cache; + + return $result; + } + }; + + $memoized->cache = new MapCache; + + return $memoized; +} \ No newline at end of file diff --git a/src/Hash.php b/src/Hash.php new file mode 100644 index 0000000..0c2d656 --- /dev/null +++ b/src/Hash.php @@ -0,0 +1,59 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use _\internal\Traits\CacheDataTrait; + +final class Hash implements CacheInterface +{ + use CacheDataTrait; + + public function __construct() + { + $this->clear(); + } + + public function set($key, $value): CacheInterface + { + $this->size += $this->has($key) ? 0 : 1; + $this->__data__[$key] = $value; + + return $this; + } + + public function get($key) + { + return $this->__data__[$key] ?? null; + } + + public function has($key): bool + { + return \array_key_exists($key, $this->__data__); + } + + public function clear() + { + $this->__data__ = []; + $this->size = 0; + } + + public function delete($key) + { + $result = $this->has($key); + + unset($this->__data__[$key]); + + $this->size -= $result ? 1 : 0; + + return $result; + } +} \ No newline at end of file diff --git a/src/ListCache.php b/src/ListCache.php new file mode 100644 index 0000000..fdb1eca --- /dev/null +++ b/src/ListCache.php @@ -0,0 +1,82 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use _\internal\Traits\CacheDataTrait; +use function _\internal\assocIndexOf; + +final class ListCache implements CacheInterface +{ + use CacheDataTrait; + + public function __construct(iterable $entries = null) + { + $this->clear(); + + if (null !== $entries) { + foreach ($entries as $key => $entry) { + $this->set($key, $entry); + } + } + } + + final public function set($key, $value): CacheInterface + { + $index = assocIndexOf($this->__data__, $key); + + if ($index < 0) { + ++$this->size; + $this->__data__[] = [$key, $value]; + } else { + $this->__data__[$index][1] = $value; + } + + return $this; + } + + final public function get($key) + { + $index = assocIndexOf($this->__data__, $key); + + return $index < 0 ? null : $this->__data__[$index][1]; + } + + final public function has($key): bool + { + return assocIndexOf($this->__data__, $key) > -1; + } + + final public function clear() + { + $this->__data__ = []; + $this->size = 0; + } + + final public function delete($key) + { + $index = assocIndexOf($this->__data__, $key); + + if ($index < 0) { + return false; + } + + $lastIndex = \count($this->__data__) - 1; + if ($index === $lastIndex) { + \array_pop($data); + } else { + \array_splice($this->__data__, $index, 1); + } + --$this->size; + + return true; + } +} \ No newline at end of file diff --git a/src/MapCache.php b/src/MapCache.php new file mode 100644 index 0000000..3cba3f0 --- /dev/null +++ b/src/MapCache.php @@ -0,0 +1,83 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use _\internal\Traits\CacheDataTrait; + +final class MapCache implements CacheInterface +{ + use CacheDataTrait; + + public function __construct(iterable $entries = null) + { + $this->clear(); + + if (null !== $entries) { + foreach ($entries as $key => $entry) { + $this->set($key, $entry); + } + } + } + + final public function set($key, $value): CacheInterface + { + $data = $this->getMapData($key); + $size = $data->getSize(); + + $data->set($key, $value); + $this->size += $data->getSize() === $size ? 0 : 1; + + return $this; + } + + final public function get($key) + { + return $this->getMapData($key)->get($key); + } + + final public function has($key): bool + { + return $this->getMapData($key)->has($key); + } + + final public function clear() + { + $this->size = 0; + $this->__data__ = [ + 'hash' => new Hash, + 'map' => new ListCache, + 'string' => new Hash, + ]; + } + + final public function delete($key) + { + $result = $this->getMapData($key)->delete($key); + $this->size -= $result ? 1 : 0; + + return $result; + } + + private function isKey($key) + { + return \is_scalar($key); + } + + private function getMapData($key): CacheInterface + { + if ($this->isKey($key)) { + return $this->__data__[\is_string($key) ? 'string' : 'hash']; + } + + return $this->__data__['map']; + } +} \ No newline at end of file diff --git a/src/internal/Traits/CacheDataTrait.php b/src/internal/Traits/CacheDataTrait.php new file mode 100644 index 0000000..77f3106 --- /dev/null +++ b/src/internal/Traits/CacheDataTrait.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal\Traits; + +trait CacheDataTrait +{ + private $__data__; + + private $size; + + public function getSize(): int + { + return $this->size; + } +} \ No newline at end of file diff --git a/src/internal/assocIndexOf.php b/src/internal/assocIndexOf.php new file mode 100644 index 0000000..04ddd33 --- /dev/null +++ b/src/internal/assocIndexOf.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\eq; + +function assocIndexOf(array $array, $key): int +{ + $length = \count($array); + while ($length--) { + if (eq($array[$length][0], $key)) { + return $length; + } + } + + return -1; +} \ No newline at end of file diff --git a/src/internal/isKey.php b/src/internal/isKey.php index 5d4019a..4ffeb01 100644 --- a/src/internal/isKey.php +++ b/src/internal/isKey.php @@ -12,7 +12,7 @@ namespace _\internal; /** Used to match property names within property paths. */ -const reIsDeepProp = '/\.|\[(?:[^[\]]*|(["\'])(?:(?!\1)[^\\]|\\.)*?\1)\]/'; +const reIsDeepProp = '#\.|\[(?:[^[\]]*|(["\'])(?:(?!\1)[^\\\\]|\\.)*?\1)\]#'; const reIsPlainProp = '/^\w*$/'; /** @@ -29,7 +29,7 @@ function isKey($value, $object = []): bool return false; } - if (\is_scalar($value)) { + if (\is_numeric($value)) { return true; } diff --git a/tests/Function/MemoizeTest.php b/tests/Function/MemoizeTest.php new file mode 100644 index 0000000..535bacc --- /dev/null +++ b/tests/Function/MemoizeTest.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\memoize; + +class MemoizeTest extends TestCase +{ + public function testMemoize() + { + $object = (object) ['a' => 1, 'b' => 2]; + $other = (object) ['c' => 3, 'd' => 4]; + + $values = memoize('get_object_vars'); + $this->assertSame(['a' => 1, 'b' => 2], $values($object)); + $this->assertSame(['c' => 3, 'd' => 4], $values($other)); + + $object->a = 2; + + $this->assertSame(['a' => 1, 'b' => 2], $values($object)); + + // Modify the result cache. + $values->cache->set($object, ['a', 'b']); + $this->assertSame(['a', 'b'], $values($object)); + } +} \ No newline at end of file From b11ce0cc620fe315bbfe089cebae0a3d0b7edca0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 20:20:53 +0200 Subject: [PATCH 026/159] Add Array.sortedObjectDeep function --- src/Array/zipObjectDeep.php | 58 +++++++++++++++++++++++++++++++ src/internal/baseSet.php | 56 +++++++++++++++++++++++++++++ src/internal/castPath.php | 21 +++++++++++ src/internal/memoizeCapped.php | 28 +++++++++++++++ src/internal/stringToPath.php | 36 +++++++++++++++++++ tests/Array/ZipObjectDeepTest.php | 21 +++++++++++ 6 files changed, 220 insertions(+) create mode 100644 src/Array/zipObjectDeep.php create mode 100644 src/internal/baseSet.php create mode 100644 src/internal/castPath.php create mode 100644 src/internal/memoizeCapped.php create mode 100644 src/internal/stringToPath.php create mode 100644 tests/Array/ZipObjectDeepTest.php diff --git a/src/Array/zipObjectDeep.php b/src/Array/zipObjectDeep.php new file mode 100644 index 0000000..bb01141 --- /dev/null +++ b/src/Array/zipObjectDeep.php @@ -0,0 +1,58 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseSet; + +/** + * This method is like `zipObject` except that it supports property paths. + * + * @category Array + * + * @param array $props The property identifiers. + * @param array $values The property values. + * + * @return object the new object. + * @example + * + * zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]) + * /* => class stdClass#20 (1) { + * public $a => class stdClass#19 (1) { + * public $b => + * array(2) { + * [0] => class stdClass#17 (1) { + * public $c => int(1) + * } + * [1] => class stdClass#18 (1) { + * public $d => int(2) + * } + * } + * } + * } + * *\/ + * + */ +function zipObjectDeep(array $props = [], array $values = []): object +{ + $result = new \stdClass; + $index = -1; + $length = \count($props); + $props = \array_values($props); + $values = \array_values($values); + + while (++$index < $length) { + $value = $values[$index] ?? null; + baseSet($result, $props[$index], $value); + } + + return $result; +} \ No newline at end of file diff --git a/src/internal/baseSet.php b/src/internal/baseSet.php new file mode 100644 index 0000000..23f77c9 --- /dev/null +++ b/src/internal/baseSet.php @@ -0,0 +1,56 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function baseSet($object, $path, $value, callable $customizer = null) +{ + if (!\is_object($object)) { + return $object; + } + + $path = castPath($path, $object); + + $index = -1; + $length = \count($path); + $lastIndex = $length - 1; + $nested = $object; + + while ($nested !== null && ++$index < $length) { + $key = toKey($path[$index]); + + if ($index !== $lastIndex) { + $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); + $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; + if (null === $newValue) { + $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); + } + + if (\is_array($nested)) { + $nested[$key] = $newValue; + } else { + $nested->{$key} = $newValue; + } + + if (\is_array($nested)) { + $nested = &$nested[$key]; + } else { + $nested = &$nested->$key; + } + + continue; + } + + $nested->{$key} = $value; + } + + return $object; +} \ No newline at end of file diff --git a/src/internal/castPath.php b/src/internal/castPath.php new file mode 100644 index 0000000..d08b020 --- /dev/null +++ b/src/internal/castPath.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function castPath($value, $object): array +{ + if (\is_array($value)) { + return $value; + } + + return isKey($value, $object) ? [$value] : stringToPath((string) $value); +} \ No newline at end of file diff --git a/src/internal/memoizeCapped.php b/src/internal/memoizeCapped.php new file mode 100644 index 0000000..9f86d66 --- /dev/null +++ b/src/internal/memoizeCapped.php @@ -0,0 +1,28 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\memoize; + +function memoizeCapped(callable $func) +{ + $MaxMemoizeSize = 500; + $result = memoize($func, function ($key) use ($MaxMemoizeSize) { + if ($this->cache->getSize() === $MaxMemoizeSize) { + $this->cache->clear(); + } + + return $key; + }); + + return $result; +} \ No newline at end of file diff --git a/src/internal/stringToPath.php b/src/internal/stringToPath.php new file mode 100644 index 0000000..3a01708 --- /dev/null +++ b/src/internal/stringToPath.php @@ -0,0 +1,36 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +const reLeadingDot = '/^\./'; +const rePropName = '#[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["\'])((?:(?!\2)[^\\\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))#'; + +/** Used to match backslashes in property paths. */ +const reEscapeChar = '/\\(\\)?/g'; + +function stringToPath(...$args) +{ + return memoizeCapped(function ($string) { + $result = []; + if (\preg_match(reLeadingDot, $string)) { + $result[] = ''; + } + + \preg_match_all(rePropName, $string, $matches, PREG_SPLIT_DELIM_CAPTURE); + + foreach ($matches as $match) { + $result[] = $match[1] ?? $match[0]; + } + + return $result; + })(...$args); +} \ No newline at end of file diff --git a/tests/Array/ZipObjectDeepTest.php b/tests/Array/ZipObjectDeepTest.php new file mode 100644 index 0000000..9ca9c05 --- /dev/null +++ b/tests/Array/ZipObjectDeepTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\zipObjectDeep; + +class ZipObjectDeepTest extends TestCase +{ + public function testZipObjectDeep() + { + $this->assertEquals((object) ['a' => (object) ['b' => [(object) ['c' => 1], (object) ['d' => 2]]]], zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2])); + } +} \ No newline at end of file From 41dcc099665c6058554fa812824d1b9c1a74581c Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 20:26:24 +0200 Subject: [PATCH 027/159] Skip non-function in build script --- bin/build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/build b/bin/build index d0c789d..d2aea5f 100755 --- a/bin/build +++ b/bin/build @@ -23,6 +23,10 @@ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sources, continue; } + if (!\is_callable("_\\$function")) { + continue; + } + $reflection = new ReflectionFunction("_\\$function"); $docblock = $factory->create($reflection->getDocComment()); From 0e9a503d57d6617dbf56bc3e31433eb08e0aac1a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 20:26:40 +0200 Subject: [PATCH 028/159] Update function dockblocks --- src/Function/memoize.php | 5 +++-- src/Lang/eq.php | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Function/memoize.php b/src/Function/memoize.php index a06d780..78413b7 100644 --- a/src/Function/memoize.php +++ b/src/Function/memoize.php @@ -28,10 +28,10 @@ * @param callable $func The function to have its output memoized. * @param callable $resolver The function to resolve the cache key. * - * @returns callable Returns the new memoized function. + * @return callable Returns the new memoized function. * * @example - * + * * $object = ['a' => 1, 'b' => 2]; * $other = ['c' => 3, 'd' => 4]; * @@ -50,6 +50,7 @@ * $values->cache->set($object, ['a', 'b']); * $values($object); * // => ['a', 'b'] + * */ function memoize(callable $func = null, callable $resolver = null) { diff --git a/src/Lang/eq.php b/src/Lang/eq.php index 1c032fa..b4e2331 100644 --- a/src/Lang/eq.php +++ b/src/Lang/eq.php @@ -17,6 +17,8 @@ * @param mixed $value The value to compare. * @param mixed $other The other value to compare. * + * @category Lang + * * @return boolean Returns `true` if the values are equivalent, else `false`. * @example * From 8259493a3440c51cae9b10fdbc686b68813677fa Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 20:27:02 +0200 Subject: [PATCH 029/159] Update README with new funtions --- README.md | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/README.md b/README.md index 8d51d3d..d2e4235 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ _::each([1, 2, 3], function (int $item) { - [Array](#array) - [Collection](#collection) - [Date](#date) +- [Function](#function) - [Lang](#lang) - [Math](#math) - [Number](#number) @@ -1523,6 +1524,107 @@ Example: zip(['a', 'b'], [1, 2], [true, false]) // => [['a', 1, true], ['b', 2, false]] +``` +### zipObject + +This method is like `fromPairs` except that it accepts two arrays, +one of property identifiers and one of corresponding values. + + + +**Arguments:** + +@param array $props The property identifiers. + +@param array $values The property values. + + + +**Return:** + +@return object the new object. + +Example: +```php + object(stdClass)#210 (2) { +["a"] => int(1) +["b"] => int(2) +} +*\/ + +``` +### zipObjectDeep + +This method is like `zipObject` except that it supports property paths. + + + +**Arguments:** + +@param array $props The property identifiers. + +@param array $values The property values. + + + +**Return:** + +@return object the new object. + +Example: +```php + class stdClass#20 (1) { + public $a => class stdClass#19 (1) { + public $b => + array(2) { + [0] => class stdClass#17 (1) { + public $c => int(1) + } + [1] => class stdClass#18 (1) { + public $d => int(2) + } + } + } + } +*\/ + +``` +### zipWith + +This method is like `zip` except that it accepts `iteratee` to specify +how grouped values should be combined. The iteratee is invoked with the +elements of each group: (. + +..group). + +**Arguments:** + +@param array[] $arrays The arrays to process. + +@param callable $iteratee The function to combine grouped values. + + + +**Return:** + +@return array the new array of grouped elements. + +Example: +```php + [111, 222] + ``` ## Collection @@ -1677,9 +1779,103 @@ Example: now(); // => 1511180325735 +``` +## Function + +### memoize + +Creates a function that memoizes the result of `func`. If `resolver` is +provided, it determines the cache key for storing the result based on the +arguments provided to the memoized function. By default, the first argument +provided to the memoized function is used as the map cache key + +**Note:** The cache is exposed as the `cache` property on the memoized +function. Its creation may be customized by replacing the `_.memoize.Cache` +constructor with one whose instances implement the +[`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) +method interface of `clear`, `delete`, `get`, `has`, and `set`. + +**Arguments:** + +@param callable $func The function to have its output memoized. + +@param callable $resolver The function to resolve the cache key. + + + +**Return:** + +@return callable Returns the new memoized function. + +Example: +```php + 1, 'b' => 2]; +$other = ['c' => 3, 'd' => 4]; + +$values = memoize('_\values'); +$values($object); +// => [1, 2] + +$values($other); +// => [3, 4] + +$object['a'] = 2; +$values($object); +// => [1, 2] + +// Modify the result cache. +$values->cache->set($object, ['a', 'b']); +$values($object); +// => ['a', 'b'] + ``` ## Lang +### eq + +Performs a comparison between two values to determine if they are equivalent. + + + +**Arguments:** + +@param mixed $value The value to compare. + +@param mixed $other The other value to compare. + + + +**Return:** + +@return bool Returns `true` if the values are equivalent, else `false`. + +Example: +```php + 1]; +$other = (object) ['a' => 1]; + +eq($object, $object); +// => true + +eq($object, $other); +// => false + +eq('a', 'a'); +// => true + +eq(['a'], (object) ['a']); +// => false + +eq(INF, INF); +// => true + +``` ### isEqual Performs a deep comparison between two values to determine if they are From b6956391fcdcfcfd3a0c1a2f0b77c2f61e7db56a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 24 Jan 2018 21:29:14 +0200 Subject: [PATCH 030/159] Fix CS --- src/Array/chunk.php | 2 +- src/Array/concat.php | 2 +- src/Array/difference.php | 2 +- src/Array/differenceBy.php | 2 +- src/Array/differenceWith.php | 2 +- src/Array/drop.php | 2 +- src/Array/dropRight.php | 2 +- src/Array/dropRightWhile.php | 2 +- src/Array/dropWhile.php | 2 +- src/Array/findIndex.php | 2 +- src/Array/findLastIndex.php | 2 +- src/Array/flatten.php | 2 +- src/Array/flattenDeep.php | 2 +- src/Array/flattenDepth.php | 2 +- src/Array/fromPairs.php | 2 +- src/Array/head.php | 2 +- src/Array/indexOf.php | 2 +- src/Array/initial.php | 2 +- src/Array/intersection.php | 2 +- src/Array/intersectionBy.php | 2 +- src/Array/intersectionWith.php | 2 +- src/Array/last.php | 2 +- src/Array/lastIndexOf.php | 2 +- src/Array/nth.php | 2 +- src/Array/pull.php | 2 +- src/Array/pullAll.php | 2 +- src/Array/pullAllBy.php | 2 +- src/Array/pullAllWith.php | 2 +- src/Array/pullAt.php | 2 +- src/Array/remove.php | 2 +- src/Array/slice.php | 2 +- src/Array/tail.php | 2 +- src/Array/take.php | 2 +- src/Array/takeRight.php | 2 +- src/Array/takeRightWhile.php | 2 +- src/Array/takeWhile.php | 2 +- src/Array/union.php | 2 +- src/Array/unionBy.php | 2 +- src/Array/unionWith.php | 2 +- src/Array/uniq.php | 2 +- src/Array/uniqWith.php | 2 +- src/Array/unzip.php | 2 +- src/Array/unzipWith.php | 3 +-- src/Array/without.php | 2 +- src/Array/zip.php | 2 +- src/Array/zipObject.php | 2 +- src/Array/zipObjectDeep.php | 2 +- src/CacheInterface.php | 2 +- src/Collection/each.php | 2 +- src/Collection/map.php | 6 +++--- src/Collection/sortBy.php | 2 +- src/Date/now.php | 2 +- src/Function/memoize.php | 5 ++--- src/Hash.php | 2 +- src/Lang/eq.php | 2 +- src/Lang/isEqual.php | 2 +- src/Lang/isError.php | 2 +- src/ListCache.php | 2 +- src/Lodash.php | 2 +- src/MapCache.php | 2 +- src/Math/add.php | 2 +- src/Number/clamp.php | 2 +- src/Number/inRange.php | 2 +- src/Number/random.php | 4 ++-- src/String/camelCase.php | 2 +- src/String/capitalize.php | 2 +- src/String/deburr.php | 2 +- src/String/endsWith.php | 4 ++-- src/String/escape.php | 2 +- src/String/kebabCase.php | 2 +- src/String/lowerCase.php | 2 +- src/String/lowerFirst.php | 2 +- src/String/pad.php | 2 +- src/String/padStart.php | 2 +- src/String/parseInt.php | 4 ++-- src/String/repeat.php | 2 +- src/String/replace.php | 2 +- src/String/snakeCase.php | 2 +- src/String/split.php | 2 +- src/String/startCase.php | 2 +- src/String/startsWith.php | 4 ++-- src/String/template.php | 10 ++++------ src/String/toLower.php | 2 +- src/String/trim.php | 2 +- src/String/trimEnd.php | 2 +- src/String/trimStart.php | 2 +- src/String/truncate.php | 4 ++-- src/String/unescape.php | 2 +- src/String/upperCase.php | 2 +- src/String/upperFirst.php | 2 +- src/String/words.php | 2 +- src/Util/attempt.php | 2 +- src/Util/identity.php | 2 +- src/Util/property.php | 3 +-- src/internal/Traits/CacheDataTrait.php | 2 +- src/internal/arrayIncludes.php | 2 +- src/internal/arrayIncludesWith.php | 2 +- src/internal/arrayMap.php | 2 +- src/internal/assocIndexOf.php | 2 +- src/internal/baseFlatten.php | 4 ++-- src/internal/baseIndexOfWith.php | 2 +- src/internal/baseIntersection.php | 2 +- src/internal/baseIteratee.php | 2 +- src/internal/baseMatches.php | 2 +- src/internal/baseMatchesProperty.php | 2 +- src/internal/baseProperty.php | 2 +- src/internal/basePullAll.php | 2 +- src/internal/baseRest.php | 2 +- src/internal/baseSet.php | 2 +- src/internal/baseTimes.php | 2 +- src/internal/baseUniq.php | 2 +- src/internal/castPath.php | 2 +- src/internal/castSlice.php | 2 +- src/internal/createMathOperation.php | 2 +- src/internal/hasUnicode.php | 2 +- src/internal/isFlattenable.php | 2 +- src/internal/isIterateeCall.php | 2 +- src/internal/isKey.php | 2 +- src/internal/memoizeCapped.php | 2 +- src/internal/overRest.php | 2 +- src/internal/stringSize.php | 2 +- src/internal/stringToArray.php | 2 +- src/internal/stringToPath.php | 2 +- src/internal/toKey.php | 2 +- src/internal/unicode.php | 2 +- src/internal/unicodeSize.php | 2 +- src/internal/unicodeWords.php | 2 +- tests/Array/ChunkTest.php | 2 +- tests/Array/CompactTest.php | 2 +- tests/Array/ConcatTest.php | 2 +- tests/Array/DifferenceByTest.php | 2 +- tests/Array/DifferenceTest.php | 2 +- tests/Array/DifferenceWithTest.php | 2 +- tests/Array/DropRightTest.php | 2 +- tests/Array/DropRightWhileTest.php | 6 ++++-- tests/Array/DropTest.php | 2 +- tests/Array/DropWhileTest.php | 6 ++++-- tests/Array/FindIndexTest.php | 6 ++++-- tests/Array/FindLastIndexTest.php | 10 +++++++--- tests/Array/FlattenDeepTest.php | 2 +- tests/Array/FlattenDepthTest.php | 2 +- tests/Array/FlattenTest.php | 2 +- tests/Array/FromPairsTest.php | 2 +- tests/Array/HeadTest.php | 2 +- tests/Array/IndexOfTest.php | 2 +- tests/Array/InitialTest.php | 2 +- tests/Array/IntersectionByTest.php | 2 +- tests/Array/IntersectionTest.php | 2 +- tests/Array/IntersectionWithTest.php | 2 +- tests/Array/LastIndexOfTest.php | 2 +- tests/Array/LastTest.php | 2 +- tests/Array/NthTest.php | 2 +- tests/Array/PullAllByTest.php | 2 +- tests/Array/PullAllTest.php | 2 +- tests/Array/PullAllWithTest.php | 2 +- tests/Array/PullAtTest.php | 2 +- tests/Array/PullTest.php | 2 +- tests/Array/RemoveTest.php | 6 ++++-- tests/Array/SliceTest.php | 2 +- tests/Array/TailTest.php | 2 +- tests/Array/TakeRightTest.php | 2 +- tests/Array/TakeRightWhileTest.php | 6 ++++-- tests/Array/TakeTest.php | 2 +- tests/Array/TakeWhileTest.php | 6 ++++-- tests/Array/UnionByTest.php | 2 +- tests/Array/UnionTest.php | 2 +- tests/Array/UnionWithTest.php | 2 +- tests/Array/UniqByTest.php | 2 +- tests/Array/UniqTest.php | 2 +- tests/Array/UniqWithTest.php | 2 +- tests/Array/UnzipTest.php | 2 +- tests/Array/UnzipWithTest.php | 2 +- tests/Array/WithoutTest.php | 2 +- tests/Array/ZipObjectDeepTest.php | 2 +- tests/Array/ZipObjectTest.php | 2 +- tests/Array/ZipTest.php | 2 +- tests/Array/ZipWithTest.php | 6 ++++-- tests/Collection/EachTest.php | 10 +++++++--- tests/Collection/MapTest.php | 2 +- tests/Collection/SortByTest.php | 6 ++++-- tests/Date/NowTest.php | 2 +- tests/Function/MemoizeTest.php | 2 +- tests/Lang/EqTest.php | 5 ++++- tests/Lang/IsEqualTest.php | 2 +- tests/Lang/IsErrorTest.php | 2 +- tests/Math/AddTest.php | 2 +- tests/Number/ClampTest.php | 2 +- tests/Number/InRangeTest.php | 2 +- tests/Number/RandomTest.php | 2 +- tests/String/CamelCaseTest.php | 2 +- tests/String/CapitalizeTest.php | 2 +- tests/String/DeburrTest.php | 2 +- tests/String/EndsWithTest.php | 2 +- tests/String/EscapeRegExpTest.php | 2 +- tests/String/EscapeTest.php | 2 +- tests/String/KebabCaseTest.php | 2 +- tests/String/LowerCaseTest.php | 2 +- tests/String/LowerFirstTest.php | 2 +- tests/String/PadEndTest.php | 2 +- tests/String/PadStartTest.php | 2 +- tests/String/PadTest.php | 2 +- tests/String/ParseIntTest.php | 2 +- tests/String/RepeatTest.php | 2 +- tests/String/ReplaceTest.php | 2 +- tests/String/SnakeCaseTest.php | 2 +- tests/String/SplitTest.php | 2 +- tests/String/StartCaseTest.php | 2 +- tests/String/StartsWithTest.php | 2 +- tests/String/TemplateTest.php | 2 +- tests/String/ToLowerTest.php | 2 +- tests/String/ToUpperTest.php | 2 +- tests/String/TrimEndTest.php | 2 +- tests/String/TrimStartTest.php | 2 +- tests/String/TrimTest.php | 2 +- tests/String/TruncateTest.php | 2 +- tests/String/UnescapeTest.php | 2 +- tests/String/UpperCaseTest.php | 2 +- tests/String/UpperFirstTest.php | 2 +- tests/String/WordsTest.php | 2 +- tests/Util/AttemptTest.php | 2 +- tests/Util/IdentityTest.php | 2 +- tests/Util/PropertyTest.php | 2 +- 222 files changed, 273 insertions(+), 251 deletions(-) diff --git a/src/Array/chunk.php b/src/Array/chunk.php index 034349e..5e98626 100644 --- a/src/Array/chunk.php +++ b/src/Array/chunk.php @@ -38,4 +38,4 @@ function chunk(?array $array, int $number): array } return \array_chunk($array ?? [], $number, false); -} \ No newline at end of file +} diff --git a/src/Array/concat.php b/src/Array/concat.php index 94a7465..fe84ff0 100644 --- a/src/Array/concat.php +++ b/src/Array/concat.php @@ -40,4 +40,4 @@ function concat($array, ...$values): array }; return \array_merge($check($array), ...\array_map($check, $values)); -} \ No newline at end of file +} diff --git a/src/Array/difference.php b/src/Array/difference.php index ad15a4c..9bdba36 100644 --- a/src/Array/difference.php +++ b/src/Array/difference.php @@ -35,4 +35,4 @@ function difference(array $array, array ...$values): array { return \array_values(\array_diff($array, ...$values)); -} \ No newline at end of file +} diff --git a/src/Array/differenceBy.php b/src/Array/differenceBy.php index ba7aabd..89a7492 100644 --- a/src/Array/differenceBy.php +++ b/src/Array/differenceBy.php @@ -65,4 +65,4 @@ function differenceBy(array $array, ...$values): array } return $result; -} \ No newline at end of file +} diff --git a/src/Array/differenceWith.php b/src/Array/differenceWith.php index d64ea02..e77725e 100644 --- a/src/Array/differenceWith.php +++ b/src/Array/differenceWith.php @@ -65,4 +65,4 @@ function differenceWith(array $array, ...$values): array } return $result; -} \ No newline at end of file +} diff --git a/src/Array/drop.php b/src/Array/drop.php index 4b3e53e..86bd80b 100644 --- a/src/Array/drop.php +++ b/src/Array/drop.php @@ -40,4 +40,4 @@ function drop(array $array, int $n = 1): array { return \array_slice($array, $n); -} \ No newline at end of file +} diff --git a/src/Array/dropRight.php b/src/Array/dropRight.php index 69d2177..3e578e3 100644 --- a/src/Array/dropRight.php +++ b/src/Array/dropRight.php @@ -45,4 +45,4 @@ function dropRight(array $array, int $n = 1): array } return \array_slice($array, 0, $count - $n); -} \ No newline at end of file +} diff --git a/src/Array/dropRightWhile.php b/src/Array/dropRightWhile.php index 76df132..b637215 100644 --- a/src/Array/dropRightWhile.php +++ b/src/Array/dropRightWhile.php @@ -47,4 +47,4 @@ function dropRightWhile(array $array, callable $predicate): array } return $array; -} \ No newline at end of file +} diff --git a/src/Array/dropWhile.php b/src/Array/dropWhile.php index e0f0d41..ce62b5f 100644 --- a/src/Array/dropWhile.php +++ b/src/Array/dropWhile.php @@ -48,4 +48,4 @@ function dropWhile(array $array, callable $predicate): array } return $array; -} \ No newline at end of file +} diff --git a/src/Array/findIndex.php b/src/Array/findIndex.php index 04cb61d..36b9737 100644 --- a/src/Array/findIndex.php +++ b/src/Array/findIndex.php @@ -70,4 +70,4 @@ function findIndex(array $array, $predicate, int $fromIndex = null): int } return -1; -} \ No newline at end of file +} diff --git a/src/Array/findLastIndex.php b/src/Array/findLastIndex.php index 1bf43e2..a8f32f5 100644 --- a/src/Array/findLastIndex.php +++ b/src/Array/findLastIndex.php @@ -55,4 +55,4 @@ function findLastIndex(array $array, $predicate, int $fromIndex = null): int } return -1; -} \ No newline at end of file +} diff --git a/src/Array/flatten.php b/src/Array/flatten.php index 46eb08f..7c4a002 100644 --- a/src/Array/flatten.php +++ b/src/Array/flatten.php @@ -29,4 +29,4 @@ function flatten(array $array = null): array { return baseFlatten($array, 1); -} \ No newline at end of file +} diff --git a/src/Array/flattenDeep.php b/src/Array/flattenDeep.php index 73c62f6..45e96a6 100644 --- a/src/Array/flattenDeep.php +++ b/src/Array/flattenDeep.php @@ -30,4 +30,4 @@ function flattenDeep(array $array): array { return baseFlatten($array, INF); -} \ No newline at end of file +} diff --git a/src/Array/flattenDepth.php b/src/Array/flattenDepth.php index 9f96b44..27e07e6 100644 --- a/src/Array/flattenDepth.php +++ b/src/Array/flattenDepth.php @@ -36,4 +36,4 @@ function flattenDepth(array $array, int $depth = 1): array { return baseFlatten($array, $depth); -} \ No newline at end of file +} diff --git a/src/Array/fromPairs.php b/src/Array/fromPairs.php index 6384743..d9dcfbb 100644 --- a/src/Array/fromPairs.php +++ b/src/Array/fromPairs.php @@ -42,4 +42,4 @@ function fromPairs(array $pairs): \stdClass } return $result; -} \ No newline at end of file +} diff --git a/src/Array/head.php b/src/Array/head.php index ecdeb5f..b8bd6a8 100644 --- a/src/Array/head.php +++ b/src/Array/head.php @@ -41,4 +41,4 @@ function head(array $array) function first(array $array) { return head($array); -} \ No newline at end of file +} diff --git a/src/Array/indexOf.php b/src/Array/indexOf.php index ac1e8bc..db81dbe 100644 --- a/src/Array/indexOf.php +++ b/src/Array/indexOf.php @@ -56,4 +56,4 @@ function indexOf(array $array, $value, int $fromIndex = null): int } return -1; -} \ No newline at end of file +} diff --git a/src/Array/initial.php b/src/Array/initial.php index 9e7f1eb..5f25bab 100644 --- a/src/Array/initial.php +++ b/src/Array/initial.php @@ -28,4 +28,4 @@ function initial(array $array): array { \array_pop($array); return $array; -} \ No newline at end of file +} diff --git a/src/Array/intersection.php b/src/Array/intersection.php index 99d2cf1..d0b7186 100644 --- a/src/Array/intersection.php +++ b/src/Array/intersection.php @@ -30,4 +30,4 @@ function intersection(array ...$arrays): array { return \array_intersect(...$arrays); -} \ No newline at end of file +} diff --git a/src/Array/intersectionBy.php b/src/Array/intersectionBy.php index e1177b3..066a2a3 100644 --- a/src/Array/intersectionBy.php +++ b/src/Array/intersectionBy.php @@ -42,4 +42,4 @@ function intersectionBy(...$arrays/*, callable $iteratee*/): array $iteratee = \array_pop($arrays); return baseIntersection($arrays, baseIteratee($iteratee)); -} \ No newline at end of file +} diff --git a/src/Array/intersectionWith.php b/src/Array/intersectionWith.php index a2eac29..330413a 100644 --- a/src/Array/intersectionWith.php +++ b/src/Array/intersectionWith.php @@ -45,4 +45,4 @@ function intersectionWith(...$arrays /*, callable $comparator = null*/): array } return baseIntersection($arrays, null, $comparator); -} \ No newline at end of file +} diff --git a/src/Array/last.php b/src/Array/last.php index 45f2628..77ff437 100644 --- a/src/Array/last.php +++ b/src/Array/last.php @@ -28,4 +28,4 @@ function last(array $array) { return \end($array) ?: null; -} \ No newline at end of file +} diff --git a/src/Array/lastIndexOf.php b/src/Array/lastIndexOf.php index 42498f8..f1ba610 100644 --- a/src/Array/lastIndexOf.php +++ b/src/Array/lastIndexOf.php @@ -50,4 +50,4 @@ function lastIndexOf(array $array, $value, int $fromIndex = null): int } return -1; -} \ No newline at end of file +} diff --git a/src/Array/nth.php b/src/Array/nth.php index 61c5842..32d142c 100644 --- a/src/Array/nth.php +++ b/src/Array/nth.php @@ -34,4 +34,4 @@ function nth(array $array, int $n) { return \array_values($array)[$n < 0 ? \count($array) + $n : $n] ?? null; -} \ No newline at end of file +} diff --git a/src/Array/pull.php b/src/Array/pull.php index aca39a5..8ad6e98 100644 --- a/src/Array/pull.php +++ b/src/Array/pull.php @@ -43,4 +43,4 @@ function pull(array &$array, ...$values): array $array = \array_values($array); // Re-index array return $array; -} \ No newline at end of file +} diff --git a/src/Array/pullAll.php b/src/Array/pullAll.php index b15b023..d2880b9 100644 --- a/src/Array/pullAll.php +++ b/src/Array/pullAll.php @@ -34,4 +34,4 @@ function pullAll(array &$array, array $values): array { return pull($array, ...$values); -} \ No newline at end of file +} diff --git a/src/Array/pullAllBy.php b/src/Array/pullAllBy.php index f871245..b1e458f 100644 --- a/src/Array/pullAllBy.php +++ b/src/Array/pullAllBy.php @@ -39,4 +39,4 @@ function pullAllBy(array &$array, array $values, $iteratee): array { return basePullAll($array, $values, baseIteratee($iteratee)); -} \ No newline at end of file +} diff --git a/src/Array/pullAllWith.php b/src/Array/pullAllWith.php index c5088bb..2c9c20b 100644 --- a/src/Array/pullAllWith.php +++ b/src/Array/pullAllWith.php @@ -39,4 +39,4 @@ function pullAllWith(array &$array, array $values, callable $comparator): array { return basePullAll($array, $values, null, $comparator); -} \ No newline at end of file +} diff --git a/src/Array/pullAt.php b/src/Array/pullAt.php index 6fd5f3f..19e53bc 100644 --- a/src/Array/pullAt.php +++ b/src/Array/pullAt.php @@ -53,4 +53,4 @@ function pullAt(array &$array, $indexes): array $array = \array_values($array); return $pulled; -} \ No newline at end of file +} diff --git a/src/Array/remove.php b/src/Array/remove.php index df7dae1..70ff6cc 100644 --- a/src/Array/remove.php +++ b/src/Array/remove.php @@ -52,4 +52,4 @@ function remove(array &$array, callable $predicate): array $array = \array_values($array); // Re-index array return $resultArray; -} \ No newline at end of file +} diff --git a/src/Array/slice.php b/src/Array/slice.php index e882e83..33382db 100644 --- a/src/Array/slice.php +++ b/src/Array/slice.php @@ -25,4 +25,4 @@ function slice(array $array, int $start, int $end = null): array { return \array_slice($array, $start, $end); -} \ No newline at end of file +} diff --git a/src/Array/tail.php b/src/Array/tail.php index 52798df..085e287 100644 --- a/src/Array/tail.php +++ b/src/Array/tail.php @@ -31,4 +31,4 @@ function tail(array $array): array array_shift($array); return $array; -} \ No newline at end of file +} diff --git a/src/Array/take.php b/src/Array/take.php index f29be25..7f7d9dc 100644 --- a/src/Array/take.php +++ b/src/Array/take.php @@ -44,4 +44,4 @@ function take(array $array, int $n = 1): array array_splice($array, $n); return $array; -} \ No newline at end of file +} diff --git a/src/Array/takeRight.php b/src/Array/takeRight.php index 80dd58e..1655c6d 100644 --- a/src/Array/takeRight.php +++ b/src/Array/takeRight.php @@ -42,4 +42,4 @@ function takeRight(array $array, int $n = 1): array } return array_slice($array, -$n); -} \ No newline at end of file +} diff --git a/src/Array/takeRightWhile.php b/src/Array/takeRightWhile.php index 1b0bcdb..da898ba 100644 --- a/src/Array/takeRightWhile.php +++ b/src/Array/takeRightWhile.php @@ -49,4 +49,4 @@ function takeRightWhile(array $array, $predicate): array } return array_reverse($result); -} \ No newline at end of file +} diff --git a/src/Array/takeWhile.php b/src/Array/takeWhile.php index 8e679a2..6e6218f 100644 --- a/src/Array/takeWhile.php +++ b/src/Array/takeWhile.php @@ -50,4 +50,4 @@ function takeWhile(array $array, $predicate): array } return $result; -} \ No newline at end of file +} diff --git a/src/Array/union.php b/src/Array/union.php index 8df4986..d8aebcb 100644 --- a/src/Array/union.php +++ b/src/Array/union.php @@ -31,4 +31,4 @@ function union(array ...$arrays): array { return array_unique(array_merge(...$arrays)); -} \ No newline at end of file +} diff --git a/src/Array/unionBy.php b/src/Array/unionBy.php index 4af0fd2..a8f0dc6 100644 --- a/src/Array/unionBy.php +++ b/src/Array/unionBy.php @@ -42,4 +42,4 @@ function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); -} \ No newline at end of file +} diff --git a/src/Array/unionWith.php b/src/Array/unionWith.php index 5960598..5ac71d9 100644 --- a/src/Array/unionWith.php +++ b/src/Array/unionWith.php @@ -37,4 +37,4 @@ function unionWith(... $arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); -} \ No newline at end of file +} diff --git a/src/Array/uniq.php b/src/Array/uniq.php index e292325..ffe09f0 100644 --- a/src/Array/uniq.php +++ b/src/Array/uniq.php @@ -32,4 +32,4 @@ function uniq(array $array = null): array { return \array_unique($array); -} \ No newline at end of file +} diff --git a/src/Array/uniqWith.php b/src/Array/uniqWith.php index 911cdad..0f98a2c 100644 --- a/src/Array/uniqWith.php +++ b/src/Array/uniqWith.php @@ -36,4 +36,4 @@ function uniqWith(array $array, callable $comparator): array { return baseUniq($array, null, $comparator); -} \ No newline at end of file +} diff --git a/src/Array/unzip.php b/src/Array/unzip.php index b742586..60220c0 100644 --- a/src/Array/unzip.php +++ b/src/Array/unzip.php @@ -52,4 +52,4 @@ function unzip(array $array): array return baseTimes($length, function ($index) use ($array) { return arrayMap($array, baseProperty($index)); }); -} \ No newline at end of file +} diff --git a/src/Array/unzipWith.php b/src/Array/unzipWith.php index ef55fd8..fc9a5ca 100644 --- a/src/Array/unzipWith.php +++ b/src/Array/unzipWith.php @@ -35,7 +35,6 @@ */ function unzipWith(array $array, callable $iteratee): array { - if (!\count($array)) { return []; } @@ -48,4 +47,4 @@ function unzipWith(array $array, callable $iteratee): array return arrayMap($result, function ($group) use ($iteratee) { return $iteratee(...$group); }); -} \ No newline at end of file +} diff --git a/src/Array/without.php b/src/Array/without.php index 64d38e5..ed367ff 100644 --- a/src/Array/without.php +++ b/src/Array/without.php @@ -35,4 +35,4 @@ function without(array $array, ...$values): array { return baseRest('\_\difference')($array, $values); -} \ No newline at end of file +} diff --git a/src/Array/zip.php b/src/Array/zip.php index b50bb3c..c163319 100644 --- a/src/Array/zip.php +++ b/src/Array/zip.php @@ -32,4 +32,4 @@ function zip(array ...$arrays): array { return baseRest('\_\unzip')($arrays); -} \ No newline at end of file +} diff --git a/src/Array/zipObject.php b/src/Array/zipObject.php index be0134a..69fd505 100644 --- a/src/Array/zipObject.php +++ b/src/Array/zipObject.php @@ -46,4 +46,4 @@ function zipObject(array $props = [], array $values = []) } return $result; -} \ No newline at end of file +} diff --git a/src/Array/zipObjectDeep.php b/src/Array/zipObjectDeep.php index bb01141..88a6ea9 100644 --- a/src/Array/zipObjectDeep.php +++ b/src/Array/zipObjectDeep.php @@ -55,4 +55,4 @@ function zipObjectDeep(array $props = [], array $values = []): object } return $result; -} \ No newline at end of file +} diff --git a/src/CacheInterface.php b/src/CacheInterface.php index 57951b7..096a0b7 100644 --- a/src/CacheInterface.php +++ b/src/CacheInterface.php @@ -24,4 +24,4 @@ public function clear(); public function delete($key); public function getSize(); -} \ No newline at end of file +} diff --git a/src/Collection/each.php b/src/Collection/each.php index 123009b..9ef3ad5 100644 --- a/src/Collection/each.php +++ b/src/Collection/each.php @@ -51,4 +51,4 @@ function each($collection, callable $iteratee) } return $collection; -} \ No newline at end of file +} diff --git a/src/Collection/map.php b/src/Collection/map.php index 3f37f31..5b6fb6c 100644 --- a/src/Collection/map.php +++ b/src/Collection/map.php @@ -61,9 +61,9 @@ function map($collection, $iteratee): array if (\is_array($collection)) { $values = $collection; - } else if ($collection instanceof \Traversable) { + } elseif ($collection instanceof \Traversable) { $values = \iterator_to_array($collection); - } else if (\is_object($collection)) { + } elseif (\is_object($collection)) { $values = \get_object_vars($collection); } @@ -72,4 +72,4 @@ function map($collection, $iteratee): array return \array_map(function ($value, $index) use ($callable, $collection) { return $callable($value, $index, $collection); }, $values, \array_keys($values)); -} \ No newline at end of file +} diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index b87d2b6..f860ad0 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -69,4 +69,4 @@ function sortBy($collection, $iteratees) } return $result; -} \ No newline at end of file +} diff --git a/src/Date/now.php b/src/Date/now.php index 7e536e8..d619283 100644 --- a/src/Date/now.php +++ b/src/Date/now.php @@ -27,4 +27,4 @@ function now(): int { return (int) (\microtime(true) * 1000); -} \ No newline at end of file +} diff --git a/src/Function/memoize.php b/src/Function/memoize.php index 78413b7..e32658d 100644 --- a/src/Function/memoize.php +++ b/src/Function/memoize.php @@ -54,8 +54,7 @@ */ function memoize(callable $func = null, callable $resolver = null) { - $memoized = new class ($func, $resolver ?? null) - { + $memoized = new class($func, $resolver ?? null) { /** * @var CacheInterface */ @@ -97,4 +96,4 @@ public function __invoke() $memoized->cache = new MapCache; return $memoized; -} \ No newline at end of file +} diff --git a/src/Hash.php b/src/Hash.php index 0c2d656..365b8f8 100644 --- a/src/Hash.php +++ b/src/Hash.php @@ -56,4 +56,4 @@ public function delete($key) return $result; } -} \ No newline at end of file +} diff --git a/src/Lang/eq.php b/src/Lang/eq.php index b4e2331..4f1a280 100644 --- a/src/Lang/eq.php +++ b/src/Lang/eq.php @@ -44,4 +44,4 @@ function eq($value, $other): bool { return $value === $other; -} \ No newline at end of file +} diff --git a/src/Lang/isEqual.php b/src/Lang/isEqual.php index 2d32001..a0c210b 100644 --- a/src/Lang/isEqual.php +++ b/src/Lang/isEqual.php @@ -55,4 +55,4 @@ function isEqual($value, $other): bool } catch (ComparisonFailure $failure) { return false; } -} \ No newline at end of file +} diff --git a/src/Lang/isError.php b/src/Lang/isError.php index 9f46150..a31596c 100644 --- a/src/Lang/isError.php +++ b/src/Lang/isError.php @@ -35,4 +35,4 @@ function isError($value): bool } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; -} \ No newline at end of file +} diff --git a/src/ListCache.php b/src/ListCache.php index fdb1eca..89afee2 100644 --- a/src/ListCache.php +++ b/src/ListCache.php @@ -79,4 +79,4 @@ final public function delete($key) return true; } -} \ No newline at end of file +} diff --git a/src/Lodash.php b/src/Lodash.php index cf7a1cc..2c0835c 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -55,4 +55,4 @@ public static function __callStatic(string $method, array $args) { return ("_\\$method")(...$args); } -} \ No newline at end of file +} diff --git a/src/MapCache.php b/src/MapCache.php index 3cba3f0..ff4e0f4 100644 --- a/src/MapCache.php +++ b/src/MapCache.php @@ -80,4 +80,4 @@ private function getMapData($key): CacheInterface return $this->__data__['map']; } -} \ No newline at end of file +} diff --git a/src/Math/add.php b/src/Math/add.php index 28ff7c1..5d53cb4 100644 --- a/src/Math/add.php +++ b/src/Math/add.php @@ -34,4 +34,4 @@ function add($augend, $addend) return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); -} \ No newline at end of file +} diff --git a/src/Number/clamp.php b/src/Number/clamp.php index 7ef9017..d2c2993 100644 --- a/src/Number/clamp.php +++ b/src/Number/clamp.php @@ -37,4 +37,4 @@ function clamp(int $number, int $lower, int $upper): int $number = $number >= $lower ? $number : $lower; return $number; -} \ No newline at end of file +} diff --git a/src/Number/inRange.php b/src/Number/inRange.php index 8f78f26..ac58b20 100644 --- a/src/Number/inRange.php +++ b/src/Number/inRange.php @@ -56,4 +56,4 @@ function inRange(float $number, float $start = 0, float $end = 0): bool } return $number >= \min($start, $end) && $number < \max($start, $end); -} \ No newline at end of file +} diff --git a/src/Number/random.php b/src/Number/random.php index bdc158e..1bf799d 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -45,7 +45,7 @@ function random($lower = null, $upper = null, $floating = null) if (\is_bool($upper)) { $floating = $upper; $upper = null; - } else if (\is_bool($lower)) { + } elseif (\is_bool($lower)) { $floating = $lower; $lower = null; } @@ -54,7 +54,7 @@ function random($lower = null, $upper = null, $floating = null) if (null === $lower && null === $upper) { $lower = 0; $upper = 1; - } else if (null === $upper) { + } elseif (null === $upper) { $upper = $lower; $lower = 0; } diff --git a/src/String/camelCase.php b/src/String/camelCase.php index 1886062..e669e5a 100644 --- a/src/String/camelCase.php +++ b/src/String/camelCase.php @@ -37,4 +37,4 @@ function camelCase(string $string): string return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); -} \ No newline at end of file +} diff --git a/src/String/capitalize.php b/src/String/capitalize.php index 54df344..c6403f2 100644 --- a/src/String/capitalize.php +++ b/src/String/capitalize.php @@ -30,4 +30,4 @@ function capitalize(string $string): string { return \ucfirst(\mb_strtolower($string)); -} \ No newline at end of file +} diff --git a/src/String/deburr.php b/src/String/deburr.php index 10ca5a7..579ae6b 100644 --- a/src/String/deburr.php +++ b/src/String/deburr.php @@ -110,4 +110,4 @@ function ($pattern) { ); return \preg_replace(rsCombo, '', \preg_replace($patterns, \array_values(deburredLetters), $string)); -} \ No newline at end of file +} diff --git a/src/String/endsWith.php b/src/String/endsWith.php index 1b84f65..677effb 100644 --- a/src/String/endsWith.php +++ b/src/String/endsWith.php @@ -40,11 +40,11 @@ function endsWith(string $string, string $target, int $position = null): bool if ($position < 0) { $position = 0; - } else if ($position > $length) { + } elseif ($position > $length) { $position = $length; } $position -= \strlen($target); return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; -} \ No newline at end of file +} diff --git a/src/String/escape.php b/src/String/escape.php index 416a956..680ca98 100644 --- a/src/String/escape.php +++ b/src/String/escape.php @@ -40,4 +40,4 @@ function escape(string $string) { return \htmlentities($string); -} \ No newline at end of file +} diff --git a/src/String/kebabCase.php b/src/String/kebabCase.php index 0839402..bccbc43 100644 --- a/src/String/kebabCase.php +++ b/src/String/kebabCase.php @@ -35,4 +35,4 @@ function kebabCase(string $string) { return \implode('-', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); -} \ No newline at end of file +} diff --git a/src/String/lowerCase.php b/src/String/lowerCase.php index c1aeba9..0266600 100644 --- a/src/String/lowerCase.php +++ b/src/String/lowerCase.php @@ -36,4 +36,4 @@ function lowerCase(string $string) { return \implode(' ', \array_map('\strtolower', words(\preg_replace(reQuotes, '', $string)))); -} \ No newline at end of file +} diff --git a/src/String/lowerFirst.php b/src/String/lowerFirst.php index cfe8597..51d4f96 100644 --- a/src/String/lowerFirst.php +++ b/src/String/lowerFirst.php @@ -32,4 +32,4 @@ function lowerFirst(string $string): string { return \lcfirst($string); -} \ No newline at end of file +} diff --git a/src/String/pad.php b/src/String/pad.php index 7bb8cde..efb76bf 100644 --- a/src/String/pad.php +++ b/src/String/pad.php @@ -38,4 +38,4 @@ function pad(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_BOTH); -} \ No newline at end of file +} diff --git a/src/String/padStart.php b/src/String/padStart.php index c3ffb19..e7c6443 100644 --- a/src/String/padStart.php +++ b/src/String/padStart.php @@ -37,4 +37,4 @@ function padStart(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_LEFT); -} \ No newline at end of file +} diff --git a/src/String/parseInt.php b/src/String/parseInt.php index d3ea8cb..9fbe799 100644 --- a/src/String/parseInt.php +++ b/src/String/parseInt.php @@ -36,9 +36,9 @@ function parseInt($string, int $radix = null): int { if (null === $radix) { $radix = 10; - } else if ($radix) { + } elseif ($radix) { $radix = +$radix; } return \intval($string, $radix); -} \ No newline at end of file +} diff --git a/src/String/repeat.php b/src/String/repeat.php index 58ffa51..c650fd4 100644 --- a/src/String/repeat.php +++ b/src/String/repeat.php @@ -36,4 +36,4 @@ function repeat(string $string, int $n = 1): string { return \str_repeat($string, $n); -} \ No newline at end of file +} diff --git a/src/String/replace.php b/src/String/replace.php index 60e7546..a19f5bb 100644 --- a/src/String/replace.php +++ b/src/String/replace.php @@ -50,4 +50,4 @@ function replace(string $string, string $pattern, $replacement = ''): string } return \str_replace($pattern, $replacement, $string); -} \ No newline at end of file +} diff --git a/src/String/snakeCase.php b/src/String/snakeCase.php index 3369166..fcb4a50 100644 --- a/src/String/snakeCase.php +++ b/src/String/snakeCase.php @@ -32,4 +32,4 @@ function snakeCase(string $string): string { return \implode('_', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); -} \ No newline at end of file +} diff --git a/src/String/split.php b/src/String/split.php index f001b0b..0f3b06c 100644 --- a/src/String/split.php +++ b/src/String/split.php @@ -43,4 +43,4 @@ function split(string $string, string $separator, int $limit = null): array } return $result; -} \ No newline at end of file +} diff --git a/src/String/startCase.php b/src/String/startCase.php index a1f5f66..7ffb8cb 100644 --- a/src/String/startCase.php +++ b/src/String/startCase.php @@ -35,4 +35,4 @@ function startCase(string $string) { return \implode(' ', \array_map('\ucfirst', words(\preg_replace("/['\x{2019}]/u", '', $string)))); -} \ No newline at end of file +} diff --git a/src/String/startsWith.php b/src/String/startsWith.php index 4860ec8..af01975 100644 --- a/src/String/startsWith.php +++ b/src/String/startsWith.php @@ -40,9 +40,9 @@ function startsWith(string $string, string $target, int $position = null): bool if ($position < 0) { $position = 0; - } else if ($position > $length) { + } elseif ($position > $length) { $position = $length; } return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; -} \ No newline at end of file +} diff --git a/src/String/template.php b/src/String/template.php index 0063bd8..f1f99fd 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -107,8 +107,7 @@ function template(string $string, array $options = []): callable ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) use (&$options) { - list( - , + list(, $escapeValue, $interpolateValue, $esTemplateValue, @@ -143,8 +142,7 @@ function template(string $string, array $options = []): callable $imports = $options['imports'] ?? []; - return new class($string, $imports) - { + return new class($string, $imports) { public $source; private $imports; @@ -162,7 +160,7 @@ public function __invoke(array $arguments = []) foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; - } else if (\function_exists($import)) { + } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } @@ -183,4 +181,4 @@ public function __invoke(array $arguments = []) return $content; } }; -} \ No newline at end of file +} diff --git a/src/String/toLower.php b/src/String/toLower.php index 8144d68..bab4c7a 100644 --- a/src/String/toLower.php +++ b/src/String/toLower.php @@ -34,4 +34,4 @@ function toLower(string $string): string { return \strtolower($string); -} \ No newline at end of file +} diff --git a/src/String/trim.php b/src/String/trim.php index 8967999..7bef528 100644 --- a/src/String/trim.php +++ b/src/String/trim.php @@ -32,4 +32,4 @@ function trim(string $string, string $chars = ' '): string { return \trim($string, $chars); -} \ No newline at end of file +} diff --git a/src/String/trimEnd.php b/src/String/trimEnd.php index 4fc55e7..924d096 100644 --- a/src/String/trimEnd.php +++ b/src/String/trimEnd.php @@ -31,4 +31,4 @@ function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); -} \ No newline at end of file +} diff --git a/src/String/trimStart.php b/src/String/trimStart.php index fcdbd66..b2351c6 100644 --- a/src/String/trimStart.php +++ b/src/String/trimStart.php @@ -32,4 +32,4 @@ function trimStart(string $string, string $chars = ' '): string { return \ltrim($string, $chars); -} \ No newline at end of file +} diff --git a/src/String/truncate.php b/src/String/truncate.php index d03ae7c..2b6c7ed 100644 --- a/src/String/truncate.php +++ b/src/String/truncate.php @@ -103,7 +103,7 @@ function truncate($string, array $options = []) $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } - } else if (\strpos($string, $separator) !== $end) { + } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if ($index > -1) { $result = \substr($result, 0, $index); @@ -111,4 +111,4 @@ function truncate($string, array $options = []) } return $result.$omission; -} \ No newline at end of file +} diff --git a/src/String/unescape.php b/src/String/unescape.php index 7aeb89d..779cf06 100644 --- a/src/String/unescape.php +++ b/src/String/unescape.php @@ -30,4 +30,4 @@ function unescape(string $string): string { return \html_entity_decode($string); -} \ No newline at end of file +} diff --git a/src/String/upperCase.php b/src/String/upperCase.php index 378f348..149b39d 100644 --- a/src/String/upperCase.php +++ b/src/String/upperCase.php @@ -32,4 +32,4 @@ function upperCase(string $string) { return \implode(' ', \array_map('\strtoupper', words(\preg_replace(reQuotes, '', $string)))); -} \ No newline at end of file +} diff --git a/src/String/upperFirst.php b/src/String/upperFirst.php index ef27478..7343905 100644 --- a/src/String/upperFirst.php +++ b/src/String/upperFirst.php @@ -31,4 +31,4 @@ function upperFirst(string $string): string { return \ucfirst($string); -} \ No newline at end of file +} diff --git a/src/String/words.php b/src/String/words.php index 1cd00c8..1bd86c7 100644 --- a/src/String/words.php +++ b/src/String/words.php @@ -53,4 +53,4 @@ function words(string $string, string $pattern = null): array } return []; -} \ No newline at end of file +} diff --git a/src/Util/attempt.php b/src/Util/attempt.php index bc6211a..c104d41 100644 --- a/src/Util/attempt.php +++ b/src/Util/attempt.php @@ -41,4 +41,4 @@ function attempt(callable $func, ...$args) } catch (\ParseError | \Error | \Throwable | \SoapFault | \DOMException | \PDOException $e) { return $e; } -} \ No newline at end of file +} diff --git a/src/Util/identity.php b/src/Util/identity.php index 86c11b6..9b0ef5f 100644 --- a/src/Util/identity.php +++ b/src/Util/identity.php @@ -30,4 +30,4 @@ function identity($value = null) { return $value; -} \ No newline at end of file +} diff --git a/src/Util/property.php b/src/Util/property.php index 233e850..b44f40a 100644 --- a/src/Util/property.php +++ b/src/Util/property.php @@ -42,7 +42,6 @@ function property($path): callable ->getPropertyAccessor(); return function ($value, $index = 0, $collection = []) use ($path, $propertyAccess) { - $path = \implode('.', (array) $path); if (\is_array($value)) { @@ -63,4 +62,4 @@ function property($path): callable return $propertyAccess->getValue($value, $path); }; -} \ No newline at end of file +} diff --git a/src/internal/Traits/CacheDataTrait.php b/src/internal/Traits/CacheDataTrait.php index 77f3106..ceb2e8d 100644 --- a/src/internal/Traits/CacheDataTrait.php +++ b/src/internal/Traits/CacheDataTrait.php @@ -21,4 +21,4 @@ public function getSize(): int { return $this->size; } -} \ No newline at end of file +} diff --git a/src/internal/arrayIncludes.php b/src/internal/arrayIncludes.php index 5d56cbd..3c95463 100644 --- a/src/internal/arrayIncludes.php +++ b/src/internal/arrayIncludes.php @@ -16,4 +16,4 @@ function arrayIncludes(?array $array, $value) { return null !== $array && indexOf($array, $value, 0) > -1; -} \ No newline at end of file +} diff --git a/src/internal/arrayIncludesWith.php b/src/internal/arrayIncludesWith.php index 4cedfba..6b218d1 100644 --- a/src/internal/arrayIncludesWith.php +++ b/src/internal/arrayIncludesWith.php @@ -22,4 +22,4 @@ function arrayIncludesWith(?array $array, $value, callable $comparator) } return false; -} \ No newline at end of file +} diff --git a/src/internal/arrayMap.php b/src/internal/arrayMap.php index f0f86fd..2a56b5d 100644 --- a/src/internal/arrayMap.php +++ b/src/internal/arrayMap.php @@ -22,4 +22,4 @@ function arrayMap(?array $array, callable $iteratee) } return $result; -} \ No newline at end of file +} diff --git a/src/internal/assocIndexOf.php b/src/internal/assocIndexOf.php index 04ddd33..b8cb19a 100644 --- a/src/internal/assocIndexOf.php +++ b/src/internal/assocIndexOf.php @@ -23,4 +23,4 @@ function assocIndexOf(array $array, $key): int } return -1; -} \ No newline at end of file +} diff --git a/src/internal/baseFlatten.php b/src/internal/baseFlatten.php index 05542b2..482142b 100644 --- a/src/internal/baseFlatten.php +++ b/src/internal/baseFlatten.php @@ -42,10 +42,10 @@ function baseFlatten(?array $array, float $depth, callable $predicate = null, bo } else { $result = \array_merge($result, $value); } - } else if (!$isStrict) { + } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; -} \ No newline at end of file +} diff --git a/src/internal/baseIndexOfWith.php b/src/internal/baseIndexOfWith.php index 1eb7f39..5a391c5 100644 --- a/src/internal/baseIndexOfWith.php +++ b/src/internal/baseIndexOfWith.php @@ -23,4 +23,4 @@ function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) } return -1; -} \ No newline at end of file +} diff --git a/src/internal/baseIntersection.php b/src/internal/baseIntersection.php index 080a6cd..03efbf8 100644 --- a/src/internal/baseIntersection.php +++ b/src/internal/baseIntersection.php @@ -58,4 +58,4 @@ function baseIntersection($arrays, ?callable $iteratee, $comparator = null) } return $result; -} \ No newline at end of file +} diff --git a/src/internal/baseIteratee.php b/src/internal/baseIteratee.php index 22efba8..13cc2af 100644 --- a/src/internal/baseIteratee.php +++ b/src/internal/baseIteratee.php @@ -30,4 +30,4 @@ function baseIteratee($value): callable } return property($value); -} \ No newline at end of file +} diff --git a/src/internal/baseMatches.php b/src/internal/baseMatches.php index 400c027..d7c919b 100644 --- a/src/internal/baseMatches.php +++ b/src/internal/baseMatches.php @@ -33,4 +33,4 @@ function baseMatches($source): callable return false; }; -} \ No newline at end of file +} diff --git a/src/internal/baseMatchesProperty.php b/src/internal/baseMatchesProperty.php index 2f48dd9..f1d7797 100644 --- a/src/internal/baseMatchesProperty.php +++ b/src/internal/baseMatchesProperty.php @@ -19,4 +19,4 @@ function baseMatchesProperty($property, $source): callable return function ($value, $index, $collection) use ($property, $source) { return isEqual(property($property)($value, $index, $collection), $source); }; -} \ No newline at end of file +} diff --git a/src/internal/baseProperty.php b/src/internal/baseProperty.php index 7d4c64e..803596e 100644 --- a/src/internal/baseProperty.php +++ b/src/internal/baseProperty.php @@ -23,4 +23,4 @@ function baseProperty($key) return function ($object) use ($key) { return null === $object ? null : $object[$key]; }; -} \ No newline at end of file +} diff --git a/src/internal/basePullAll.php b/src/internal/basePullAll.php index 788e761..f4d0c12 100644 --- a/src/internal/basePullAll.php +++ b/src/internal/basePullAll.php @@ -34,4 +34,4 @@ function basePullAll(&$array, array $values, ?callable $iteratee, callable $comp } return $array; -} \ No newline at end of file +} diff --git a/src/internal/baseRest.php b/src/internal/baseRest.php index bf7e16b..95094d0 100644 --- a/src/internal/baseRest.php +++ b/src/internal/baseRest.php @@ -14,4 +14,4 @@ function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); -} \ No newline at end of file +} diff --git a/src/internal/baseSet.php b/src/internal/baseSet.php index 23f77c9..204a908 100644 --- a/src/internal/baseSet.php +++ b/src/internal/baseSet.php @@ -53,4 +53,4 @@ function baseSet($object, $path, $value, callable $customizer = null) } return $object; -} \ No newline at end of file +} diff --git a/src/internal/baseTimes.php b/src/internal/baseTimes.php index 67a44a4..cfc60b6 100644 --- a/src/internal/baseTimes.php +++ b/src/internal/baseTimes.php @@ -21,4 +21,4 @@ function baseTimes(int $n, callable $iteratee) } return $result; -} \ No newline at end of file +} diff --git a/src/internal/baseUniq.php b/src/internal/baseUniq.php index 0be1b46..1445b74 100644 --- a/src/internal/baseUniq.php +++ b/src/internal/baseUniq.php @@ -45,7 +45,7 @@ function baseUniq(array $array, callable $iteratee = null, callable $comparator } $result[] = $value; - } else if (!$includes($result, $computed, $comparator)) { + } elseif (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } diff --git a/src/internal/castPath.php b/src/internal/castPath.php index d08b020..6c2ea8e 100644 --- a/src/internal/castPath.php +++ b/src/internal/castPath.php @@ -18,4 +18,4 @@ function castPath($value, $object): array } return isKey($value, $object) ? [$value] : stringToPath((string) $value); -} \ No newline at end of file +} diff --git a/src/internal/castSlice.php b/src/internal/castSlice.php index 4e945b5..fcb027c 100644 --- a/src/internal/castSlice.php +++ b/src/internal/castSlice.php @@ -28,4 +28,4 @@ function castSlice(array $array, int $start, ?int $end = null): array $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); -} \ No newline at end of file +} diff --git a/src/internal/createMathOperation.php b/src/internal/createMathOperation.php index f5beff5..7f4fcf0 100644 --- a/src/internal/createMathOperation.php +++ b/src/internal/createMathOperation.php @@ -34,4 +34,4 @@ function createMathOperation(callable $operator, $defaultValue) return $result; }; -} \ No newline at end of file +} diff --git a/src/internal/hasUnicode.php b/src/internal/hasUnicode.php index 22c0ceb..117866e 100644 --- a/src/internal/hasUnicode.php +++ b/src/internal/hasUnicode.php @@ -26,4 +26,4 @@ function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; -} \ No newline at end of file +} diff --git a/src/internal/isFlattenable.php b/src/internal/isFlattenable.php index fa298e4..266f59e 100644 --- a/src/internal/isFlattenable.php +++ b/src/internal/isFlattenable.php @@ -23,4 +23,4 @@ function isFlattenable($value): bool { return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); -} \ No newline at end of file +} diff --git a/src/internal/isIterateeCall.php b/src/internal/isIterateeCall.php index 1b1c792..08b13b2 100644 --- a/src/internal/isIterateeCall.php +++ b/src/internal/isIterateeCall.php @@ -43,4 +43,4 @@ function isIterateeCall($value, $index = null, $object = null) } return false; -} \ No newline at end of file +} diff --git a/src/internal/isKey.php b/src/internal/isKey.php index 4ffeb01..4d99db8 100644 --- a/src/internal/isKey.php +++ b/src/internal/isKey.php @@ -34,4 +34,4 @@ function isKey($value, $object = []): bool } return \preg_match(reIsPlainProp, $value) || !\preg_match(reIsDeepProp, $value) || (null !== $object && isset(((object) $object)->$value)); -} \ No newline at end of file +} diff --git a/src/internal/memoizeCapped.php b/src/internal/memoizeCapped.php index 9f86d66..0eb18d0 100644 --- a/src/internal/memoizeCapped.php +++ b/src/internal/memoizeCapped.php @@ -25,4 +25,4 @@ function memoizeCapped(callable $func) }); return $result; -} \ No newline at end of file +} diff --git a/src/internal/overRest.php b/src/internal/overRest.php index 8f4e9ee..cfb46ce 100644 --- a/src/internal/overRest.php +++ b/src/internal/overRest.php @@ -33,4 +33,4 @@ function overRest(callable $func, $start, callable $transform): callable return $func(...$otherArgs[$start]); }; -} \ No newline at end of file +} diff --git a/src/internal/stringSize.php b/src/internal/stringSize.php index 0abe8e7..b8b377e 100644 --- a/src/internal/stringSize.php +++ b/src/internal/stringSize.php @@ -23,4 +23,4 @@ function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); -} \ No newline at end of file +} diff --git a/src/internal/stringToArray.php b/src/internal/stringToArray.php index a131447..ff9458f 100644 --- a/src/internal/stringToArray.php +++ b/src/internal/stringToArray.php @@ -23,4 +23,4 @@ function stringToArray(string $string): array { return hasUnicode($string) ? unicodeToArray($string) : \str_split($string); -} \ No newline at end of file +} diff --git a/src/internal/stringToPath.php b/src/internal/stringToPath.php index 3a01708..d2d8b39 100644 --- a/src/internal/stringToPath.php +++ b/src/internal/stringToPath.php @@ -33,4 +33,4 @@ function stringToPath(...$args) return $result; })(...$args); -} \ No newline at end of file +} diff --git a/src/internal/toKey.php b/src/internal/toKey.php index 18fafdd..b491944 100644 --- a/src/internal/toKey.php +++ b/src/internal/toKey.php @@ -27,4 +27,4 @@ function toKey($value): string $result = (string) $value; return ('0' === $result && (1 / $value) === -INF) ? '-0' : $result; -} \ No newline at end of file +} diff --git a/src/internal/unicode.php b/src/internal/unicode.php index eee0dc8..dd371ba 100644 --- a/src/internal/unicode.php +++ b/src/internal/unicode.php @@ -60,4 +60,4 @@ define('rsSymbol', '(?:'.implode('|', [rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral]).')'); /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ -const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; \ No newline at end of file +const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; diff --git a/src/internal/unicodeSize.php b/src/internal/unicodeSize.php index 0cfb263..7604e2f 100644 --- a/src/internal/unicodeSize.php +++ b/src/internal/unicodeSize.php @@ -23,4 +23,4 @@ function unicodeSize($string): int { return \preg_match_all(reUnicode, $string); -} \ No newline at end of file +} diff --git a/src/internal/unicodeWords.php b/src/internal/unicodeWords.php index 6003608..a962b41 100644 --- a/src/internal/unicodeWords.php +++ b/src/internal/unicodeWords.php @@ -37,4 +37,4 @@ function unicodeWords(string $string): array } return []; -} \ No newline at end of file +} diff --git a/tests/Array/ChunkTest.php b/tests/Array/ChunkTest.php index 36ae165..7eec8b4 100644 --- a/tests/Array/ChunkTest.php +++ b/tests/Array/ChunkTest.php @@ -23,4 +23,4 @@ public function testChunk() $this->assertSame([], chunk([], -12)); $this->assertSame([], chunk([], 22)); } -} \ No newline at end of file +} diff --git a/tests/Array/CompactTest.php b/tests/Array/CompactTest.php index 0ff804d..578b600 100644 --- a/tests/Array/CompactTest.php +++ b/tests/Array/CompactTest.php @@ -20,4 +20,4 @@ public function testChunk() $this->assertSame([], compact([])); $this->assertSame([], compact(null)); } -} \ No newline at end of file +} diff --git a/tests/Array/ConcatTest.php b/tests/Array/ConcatTest.php index e601367..672945e 100644 --- a/tests/Array/ConcatTest.php +++ b/tests/Array/ConcatTest.php @@ -22,4 +22,4 @@ public function testChunk() $this->assertSame([1, 2, 3, [4]], $other); $this->assertSame([1], $array); // Ensure original array doesn't get changed } -} \ No newline at end of file +} diff --git a/tests/Array/DifferenceByTest.php b/tests/Array/DifferenceByTest.php index 32acd27..ac23860 100644 --- a/tests/Array/DifferenceByTest.php +++ b/tests/Array/DifferenceByTest.php @@ -20,4 +20,4 @@ public function testChunk() $this->assertSame([1, 2], differenceBy([1, 2], [3, 4])); $this->assertSame([1.2], differenceBy([2.1, 1.2], [2.3, 3.4], 'floor')); } -} \ No newline at end of file +} diff --git a/tests/Array/DifferenceTest.php b/tests/Array/DifferenceTest.php index 149033c..5e74f5e 100644 --- a/tests/Array/DifferenceTest.php +++ b/tests/Array/DifferenceTest.php @@ -18,4 +18,4 @@ public function testChunk() { $this->assertSame([1], difference([2, 1], [2, 3])); } -} \ No newline at end of file +} diff --git a/tests/Array/DifferenceWithTest.php b/tests/Array/DifferenceWithTest.php index 89bf204..75e3032 100644 --- a/tests/Array/DifferenceWithTest.php +++ b/tests/Array/DifferenceWithTest.php @@ -22,4 +22,4 @@ public function testDifferenceWith() $this->assertSame([], differenceWith([])); $this->assertSame([1, 2], differenceWith([1, 2], [3, 4])); } -} \ No newline at end of file +} diff --git a/tests/Array/DropRightTest.php b/tests/Array/DropRightTest.php index b0a6f14..d94d99c 100644 --- a/tests/Array/DropRightTest.php +++ b/tests/Array/DropRightTest.php @@ -21,4 +21,4 @@ public function testDropRight() $this->assertSame([], dropRight([1, 2, 3], 5)); $this->assertSame([1, 2, 3], dropRight([1, 2, 3], 0)); } -} \ No newline at end of file +} diff --git a/tests/Array/DropRightWhileTest.php b/tests/Array/DropRightWhileTest.php index 2ded769..f0ced1c 100644 --- a/tests/Array/DropRightWhileTest.php +++ b/tests/Array/DropRightWhileTest.php @@ -22,6 +22,8 @@ public function testDropRightWhile() ['user' => 'pebbles', 'active' => true], ]; - $this->assertSame([[ 'user' => 'barney', 'active' => false ]], dropRightWhile($users, function($user) { return $user['active']; })); + $this->assertSame([[ 'user' => 'barney', 'active' => false ]], dropRightWhile($users, function ($user) { + return $user['active']; + })); } -} \ No newline at end of file +} diff --git a/tests/Array/DropTest.php b/tests/Array/DropTest.php index 48a94d1..67320d9 100644 --- a/tests/Array/DropTest.php +++ b/tests/Array/DropTest.php @@ -21,4 +21,4 @@ public function testDrop() $this->assertSame([], drop([1, 2, 3], 5)); $this->assertSame([1, 2, 3], drop([1, 2, 3], 0)); } -} \ No newline at end of file +} diff --git a/tests/Array/DropWhileTest.php b/tests/Array/DropWhileTest.php index bae78bb..997f761 100644 --- a/tests/Array/DropWhileTest.php +++ b/tests/Array/DropWhileTest.php @@ -22,6 +22,8 @@ public function testDropWhile() ['user' => 'pebbles', 'active' => false], ]; - $this->assertSame([['user' => 'pebbles', 'active' => false]], dropWhile($users, function ($user) { return $user['active']; })); + $this->assertSame([['user' => 'pebbles', 'active' => false]], dropWhile($users, function ($user) { + return $user['active']; + })); } -} \ No newline at end of file +} diff --git a/tests/Array/FindIndexTest.php b/tests/Array/FindIndexTest.php index df0d520..420032d 100644 --- a/tests/Array/FindIndexTest.php +++ b/tests/Array/FindIndexTest.php @@ -22,7 +22,9 @@ public function testFindIndex() ['user' => 'pebbles', 'active' => true], ]; - $this->assertSame(2, findIndex($users, function ($user) { return $user['user'] === 'pebbles'; })); + $this->assertSame(2, findIndex($users, function ($user) { + return $user['user'] === 'pebbles'; + })); $this->assertSame(1, findIndex($users, ['user' => 'fred', 'active' => false])); $this->assertSame(0, findIndex($users, ['active', false])); $this->assertSame(2, findIndex($users, 'active')); @@ -30,4 +32,4 @@ public function testFindIndex() $this->assertSame(2, findIndex($users, 'active', -2)); $this->assertSame(-1, findIndex($users, 'nothing')); } -} \ No newline at end of file +} diff --git a/tests/Array/FindLastIndexTest.php b/tests/Array/FindLastIndexTest.php index 61aacb7..df82393 100644 --- a/tests/Array/FindLastIndexTest.php +++ b/tests/Array/FindLastIndexTest.php @@ -22,8 +22,12 @@ public function testFindLastIndex() ['user' => 'pebbles', 'active' => false], ]; - $this->assertSame(2, findLastIndex($users, function ($user) { return $user['user'] === 'pebbles'; })); - $this->assertSame(-1, findLastIndex($users, function ($user) { return $user['user'] === 'wilma'; })); + $this->assertSame(2, findLastIndex($users, function ($user) { + return $user['user'] === 'pebbles'; + })); + $this->assertSame(-1, findLastIndex($users, function ($user) { + return $user['user'] === 'wilma'; + })); $this->assertSame(1, findLastIndex($users, ['user' => 'fred'], -1)); } -} \ No newline at end of file +} diff --git a/tests/Array/FlattenDeepTest.php b/tests/Array/FlattenDeepTest.php index 126d9f8..028529d 100644 --- a/tests/Array/FlattenDeepTest.php +++ b/tests/Array/FlattenDeepTest.php @@ -18,4 +18,4 @@ public function testFlattenDeep() { $this->assertSame([1, 2, 3, 4, 5], flattenDeep([1, [2, [3, [4]], 5]])); } -} \ No newline at end of file +} diff --git a/tests/Array/FlattenDepthTest.php b/tests/Array/FlattenDepthTest.php index d8a98e0..d796d64 100644 --- a/tests/Array/FlattenDepthTest.php +++ b/tests/Array/FlattenDepthTest.php @@ -20,4 +20,4 @@ public function testFlattenDepth() $this->assertSame([1, 2, [3, [4]], 5], flattenDepth($array, 1)); $this->assertSame([1, 2, 3, [4], 5], flattenDepth($array, 2)); } -} \ No newline at end of file +} diff --git a/tests/Array/FlattenTest.php b/tests/Array/FlattenTest.php index bf972c4..6e93890 100644 --- a/tests/Array/FlattenTest.php +++ b/tests/Array/FlattenTest.php @@ -18,4 +18,4 @@ public function testFlatten() { $this->assertSame([1, 2, [3, [4]], 5], flatten([1, [2, [3, [4]], 5]])); } -} \ No newline at end of file +} diff --git a/tests/Array/FromPairsTest.php b/tests/Array/FromPairsTest.php index abb09c2..726db51 100644 --- a/tests/Array/FromPairsTest.php +++ b/tests/Array/FromPairsTest.php @@ -19,4 +19,4 @@ public function testFromPairs() $this->assertEquals((object) ['a' => 1, 'b' => 2], fromPairs([['a', 1], ['b', 2]])); $this->assertEquals(new \stdClass(), fromPairs([])); } -} \ No newline at end of file +} diff --git a/tests/Array/HeadTest.php b/tests/Array/HeadTest.php index bf2ed5f..6e6a54c 100644 --- a/tests/Array/HeadTest.php +++ b/tests/Array/HeadTest.php @@ -21,4 +21,4 @@ public function testHead() $this->assertSame(null, head([])); $this->assertSame(1, first([1, 2, 3])); // Test the alias } -} \ No newline at end of file +} diff --git a/tests/Array/IndexOfTest.php b/tests/Array/IndexOfTest.php index 203de6b..b93c795 100644 --- a/tests/Array/IndexOfTest.php +++ b/tests/Array/IndexOfTest.php @@ -20,4 +20,4 @@ public function testIndexOf() $this->assertSame(3, indexOf([1, 2, 1, 2], 2, 2)); $this->assertSame(3, indexOf([1, 2, 1, 2], 2, -1)); } -} \ No newline at end of file +} diff --git a/tests/Array/InitialTest.php b/tests/Array/InitialTest.php index 0ea8860..8aec608 100644 --- a/tests/Array/InitialTest.php +++ b/tests/Array/InitialTest.php @@ -18,4 +18,4 @@ public function testInitial() { $this->assertSame([1, 2], initial([1, 2, 3])); } -} \ No newline at end of file +} diff --git a/tests/Array/IntersectionByTest.php b/tests/Array/IntersectionByTest.php index 34c4cc0..f0bb695 100644 --- a/tests/Array/IntersectionByTest.php +++ b/tests/Array/IntersectionByTest.php @@ -19,4 +19,4 @@ public function testIntersectionBy() $this->assertSame([2.1], intersectionBy([2.1, 1.2], [2.3, 3.4], 'floor')); $this->assertSame([['x' => 1]], intersectionBy([['x' => 1]], [['x' => 2], ['x' => 1]], 'x')); } -} \ No newline at end of file +} diff --git a/tests/Array/IntersectionTest.php b/tests/Array/IntersectionTest.php index 7f89c8b..f8a9448 100644 --- a/tests/Array/IntersectionTest.php +++ b/tests/Array/IntersectionTest.php @@ -18,4 +18,4 @@ public function testIntersection() { $this->assertSame([2], intersection([2, 1], [2, 3])); } -} \ No newline at end of file +} diff --git a/tests/Array/IntersectionWithTest.php b/tests/Array/IntersectionWithTest.php index fa6d258..fc73fa0 100644 --- a/tests/Array/IntersectionWithTest.php +++ b/tests/Array/IntersectionWithTest.php @@ -22,4 +22,4 @@ public function testIntersectionWith() $this->assertSame([['x' => 1, 'y' => 2]], intersectionWith($objects, $others, '_::isEqual')); $this->assertSame([['x' => 1, 'y' => 2]], intersectionWith($objects, $others)); } -} \ No newline at end of file +} diff --git a/tests/Array/LastIndexOfTest.php b/tests/Array/LastIndexOfTest.php index 09795f1..56da38a 100644 --- a/tests/Array/LastIndexOfTest.php +++ b/tests/Array/LastIndexOfTest.php @@ -20,4 +20,4 @@ public function testLastIndexOf() $this->assertSame(1, lastIndexOf([1, 2, 1, 2], 2, 2)); $this->assertSame(-1, lastIndexOf([1, 2, 1, 2], 12)); } -} \ No newline at end of file +} diff --git a/tests/Array/LastTest.php b/tests/Array/LastTest.php index c69020a..e41aa93 100644 --- a/tests/Array/LastTest.php +++ b/tests/Array/LastTest.php @@ -18,4 +18,4 @@ public function testLast() { $this->assertSame(3, last([1, 2, 3])); } -} \ No newline at end of file +} diff --git a/tests/Array/NthTest.php b/tests/Array/NthTest.php index e1978be..725f0d2 100644 --- a/tests/Array/NthTest.php +++ b/tests/Array/NthTest.php @@ -21,4 +21,4 @@ public function testNth() $this->assertSame('c', nth($array, -2)); $this->assertSame(null, nth($array, 12)); } -} \ No newline at end of file +} diff --git a/tests/Array/PullAllByTest.php b/tests/Array/PullAllByTest.php index 3714802..6682e3b 100644 --- a/tests/Array/PullAllByTest.php +++ b/tests/Array/PullAllByTest.php @@ -20,4 +20,4 @@ public function testPullAllBy() pullAllBy($array, [[ 'x' => 1 ], [ 'x' => 3 ]], 'x'); $this->assertSame([[ 'x' => 2 ]], $array); } -} \ No newline at end of file +} diff --git a/tests/Array/PullAllTest.php b/tests/Array/PullAllTest.php index cfec891..34aab23 100644 --- a/tests/Array/PullAllTest.php +++ b/tests/Array/PullAllTest.php @@ -20,4 +20,4 @@ public function testPullAll() pullAll($array, ['a', 'c']); $this->assertSame(['b', 'b'], $array); } -} \ No newline at end of file +} diff --git a/tests/Array/PullAllWithTest.php b/tests/Array/PullAllWithTest.php index cbabe04..7a0a4c1 100644 --- a/tests/Array/PullAllWithTest.php +++ b/tests/Array/PullAllWithTest.php @@ -20,4 +20,4 @@ public function testPullAllWith() pullAllWith($array, [['x' => 3, 'y' => 4]], '_\isEqual'); $this->assertSame([['x' => 1, 'y' => 2], ['x' => 5, 'y' => 6]], $array); } -} \ No newline at end of file +} diff --git a/tests/Array/PullAtTest.php b/tests/Array/PullAtTest.php index 4961244..14be4da 100644 --- a/tests/Array/PullAtTest.php +++ b/tests/Array/PullAtTest.php @@ -21,4 +21,4 @@ public function testPullAt() $this->assertSame(['a', 'c'], $array); $this->assertSame(['b', 'd'], $pulled); } -} \ No newline at end of file +} diff --git a/tests/Array/PullTest.php b/tests/Array/PullTest.php index 725f088..c3bda88 100644 --- a/tests/Array/PullTest.php +++ b/tests/Array/PullTest.php @@ -21,4 +21,4 @@ public function testPull() $this->assertSame(['b', 'b'], $array); } -} \ No newline at end of file +} diff --git a/tests/Array/RemoveTest.php b/tests/Array/RemoveTest.php index cfcd2a9..fa60b1a 100644 --- a/tests/Array/RemoveTest.php +++ b/tests/Array/RemoveTest.php @@ -17,8 +17,10 @@ class RemoveTest extends TestCase public function testRemove() { $array = [1, 2, 3, 4]; - $evens = remove($array, function ($n) { return $n % 2 === 0; }); + $evens = remove($array, function ($n) { + return $n % 2 === 0; + }); $this->assertSame([1, 3], $array); $this->assertSame([2, 4], $evens); } -} \ No newline at end of file +} diff --git a/tests/Array/SliceTest.php b/tests/Array/SliceTest.php index 3bc465f..0272dc1 100644 --- a/tests/Array/SliceTest.php +++ b/tests/Array/SliceTest.php @@ -19,4 +19,4 @@ public function testSlice() $array = ['a', 'b', 'c', 'd']; $this->assertSame(['c', 'd'], slice($array, 2)); } -} \ No newline at end of file +} diff --git a/tests/Array/TailTest.php b/tests/Array/TailTest.php index c16d221..13da9de 100644 --- a/tests/Array/TailTest.php +++ b/tests/Array/TailTest.php @@ -18,4 +18,4 @@ public function testTail() { $this->assertSame([2, 3], tail([1, 2, 3])); } -} \ No newline at end of file +} diff --git a/tests/Array/TakeRightTest.php b/tests/Array/TakeRightTest.php index 7437bb1..a749129 100644 --- a/tests/Array/TakeRightTest.php +++ b/tests/Array/TakeRightTest.php @@ -21,4 +21,4 @@ public function testTakeRight() $this->assertSame([1, 2, 3], takeRight([1, 2, 3], 5)); $this->assertSame([], takeRight([1, 2, 3], 0)); } -} \ No newline at end of file +} diff --git a/tests/Array/TakeRightWhileTest.php b/tests/Array/TakeRightWhileTest.php index a9b6c2f..7aea59e 100644 --- a/tests/Array/TakeRightWhileTest.php +++ b/tests/Array/TakeRightWhileTest.php @@ -22,6 +22,8 @@ public function testTakeRightWhile() ['user' => 'pebbles', 'active' => true], ]; - $this->assertSame([['user' => 'fred', 'active' => true], ['user' => 'pebbles', 'active' => true]], takeRightWhile($users, function ($value) { return $value['active']; })); + $this->assertSame([['user' => 'fred', 'active' => true], ['user' => 'pebbles', 'active' => true]], takeRightWhile($users, function ($value) { + return $value['active']; + })); } -} \ No newline at end of file +} diff --git a/tests/Array/TakeTest.php b/tests/Array/TakeTest.php index 0e844f1..8fda463 100644 --- a/tests/Array/TakeTest.php +++ b/tests/Array/TakeTest.php @@ -21,4 +21,4 @@ public function testTake() $this->assertSame([1, 2, 3], take([1, 2, 3], 5)); $this->assertSame([], take([1, 2, 3], 0)); } -} \ No newline at end of file +} diff --git a/tests/Array/TakeWhileTest.php b/tests/Array/TakeWhileTest.php index dfd677f..2e05a33 100644 --- a/tests/Array/TakeWhileTest.php +++ b/tests/Array/TakeWhileTest.php @@ -22,6 +22,8 @@ public function testTakeWhile() ['user' => 'pebbles', 'active' => false], ]; - $this->assertSame([['user' => 'barney', 'active' => true], ['user' => 'fred', 'active' => true]], takeWhile($users, function ($value) { return $value['active']; })); + $this->assertSame([['user' => 'barney', 'active' => true], ['user' => 'fred', 'active' => true]], takeWhile($users, function ($value) { + return $value['active']; + })); } -} \ No newline at end of file +} diff --git a/tests/Array/UnionByTest.php b/tests/Array/UnionByTest.php index 01d02c4..0dff8c9 100644 --- a/tests/Array/UnionByTest.php +++ b/tests/Array/UnionByTest.php @@ -19,4 +19,4 @@ public function testUnionBy() $this->assertSame([2.1, 1.2], unionBy([2.1], [1.2, 2.3], 'floor')); $this->assertSame([['x' => 1], ['x' => 2]], unionBy([['x' => 1]], [['x' => 2], ['x' => 1]], 'x')); } -} \ No newline at end of file +} diff --git a/tests/Array/UnionTest.php b/tests/Array/UnionTest.php index 23ee752..2d0a80b 100644 --- a/tests/Array/UnionTest.php +++ b/tests/Array/UnionTest.php @@ -18,4 +18,4 @@ public function testUnion() { $this->assertSame([2, 1], union([2], [1, 2])); } -} \ No newline at end of file +} diff --git a/tests/Array/UnionWithTest.php b/tests/Array/UnionWithTest.php index b130188..a95d2ee 100644 --- a/tests/Array/UnionWithTest.php +++ b/tests/Array/UnionWithTest.php @@ -21,4 +21,4 @@ public function testUnionWith() $this->assertSame([['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]], unionWith($objects, $others, '_::isEqual')); } -} \ No newline at end of file +} diff --git a/tests/Array/UniqByTest.php b/tests/Array/UniqByTest.php index 4d2b898..7ee23b4 100644 --- a/tests/Array/UniqByTest.php +++ b/tests/Array/UniqByTest.php @@ -18,4 +18,4 @@ public function testUniqBy() { $this->assertSame([2.1, 1.2], uniqBy([2.1, 1.2, 2.3], 'floor')); } -} \ No newline at end of file +} diff --git a/tests/Array/UniqTest.php b/tests/Array/UniqTest.php index c087cd4..da47eca 100644 --- a/tests/Array/UniqTest.php +++ b/tests/Array/UniqTest.php @@ -18,4 +18,4 @@ public function testUniq() { $this->assertSame([2, 1], uniq([2, 1, 2])); } -} \ No newline at end of file +} diff --git a/tests/Array/UniqWithTest.php b/tests/Array/UniqWithTest.php index c82dab6..65b254b 100644 --- a/tests/Array/UniqWithTest.php +++ b/tests/Array/UniqWithTest.php @@ -19,4 +19,4 @@ public function testUniqWith() $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 2]]; $this->assertSame([['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]], uniqWith($objects, '_::isEqual')); } -} \ No newline at end of file +} diff --git a/tests/Array/UnzipTest.php b/tests/Array/UnzipTest.php index d28392d..d376e53 100644 --- a/tests/Array/UnzipTest.php +++ b/tests/Array/UnzipTest.php @@ -19,4 +19,4 @@ public function testUnzip() $zipped = [['a', 1, true], ['b', 2, false]]; $this->assertSame([['a', 'b'], [1, 2], [true, false]], unzip($zipped)); } -} \ No newline at end of file +} diff --git a/tests/Array/UnzipWithTest.php b/tests/Array/UnzipWithTest.php index 04a9714..512f1dc 100644 --- a/tests/Array/UnzipWithTest.php +++ b/tests/Array/UnzipWithTest.php @@ -19,4 +19,4 @@ public function testUnzipWith() $zipped = [[1, 10, 100], [2, 20, 200]]; $this->assertSame([3, 30, 300], unzipWith($zipped, '_::add')); } -} \ No newline at end of file +} diff --git a/tests/Array/WithoutTest.php b/tests/Array/WithoutTest.php index bc030d3..935d2e7 100644 --- a/tests/Array/WithoutTest.php +++ b/tests/Array/WithoutTest.php @@ -18,4 +18,4 @@ public function testWithout() { $this->assertSame([3], without([2, 1, 2, 3], 1, 2)); } -} \ No newline at end of file +} diff --git a/tests/Array/ZipObjectDeepTest.php b/tests/Array/ZipObjectDeepTest.php index 9ca9c05..7bc582b 100644 --- a/tests/Array/ZipObjectDeepTest.php +++ b/tests/Array/ZipObjectDeepTest.php @@ -18,4 +18,4 @@ public function testZipObjectDeep() { $this->assertEquals((object) ['a' => (object) ['b' => [(object) ['c' => 1], (object) ['d' => 2]]]], zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2])); } -} \ No newline at end of file +} diff --git a/tests/Array/ZipObjectTest.php b/tests/Array/ZipObjectTest.php index 7c649ea..b4ac506 100644 --- a/tests/Array/ZipObjectTest.php +++ b/tests/Array/ZipObjectTest.php @@ -18,4 +18,4 @@ public function testZipObject() { $this->assertEquals((object) ['a' => 1, 'b' => 2], zipObject(['a', 'b'], [1, 2])); } -} \ No newline at end of file +} diff --git a/tests/Array/ZipTest.php b/tests/Array/ZipTest.php index cfa1ee2..18243cd 100644 --- a/tests/Array/ZipTest.php +++ b/tests/Array/ZipTest.php @@ -18,4 +18,4 @@ public function testZip() { $this->assertSame([['a', 1, true], ['b', 2, false]], zip(['a', 'b'], [1, 2], [true, false])); } -} \ No newline at end of file +} diff --git a/tests/Array/ZipWithTest.php b/tests/Array/ZipWithTest.php index 8b2462b..a3a06f3 100644 --- a/tests/Array/ZipWithTest.php +++ b/tests/Array/ZipWithTest.php @@ -16,6 +16,8 @@ class ZipWithTest extends TestCase { public function testZipWith() { - $this->assertSame([111, 222], zipWith([1, 2], [10, 20], [100, 200], function($a, $b, $c) { return $a + $b + $c; })); + $this->assertSame([111, 222], zipWith([1, 2], [10, 20], [100, 200], function ($a, $b, $c) { + return $a + $b + $c; + })); } -} \ No newline at end of file +} diff --git a/tests/Collection/EachTest.php b/tests/Collection/EachTest.php index 22507cd..bcd1340 100644 --- a/tests/Collection/EachTest.php +++ b/tests/Collection/EachTest.php @@ -19,11 +19,15 @@ public function testEach() $testFunc = new \stdClass(); $testFunc->total = 0; - each([1, 2], function ($value) use ($testFunc) { $testFunc->total += $value; }); + each([1, 2], function ($value) use ($testFunc) { + $testFunc->total += $value; + }); $this->assertSame(3, $testFunc->total); $testFunc->total = 0; - each((object) ['a' => 1, 'b' => 2], function ($value) use ($testFunc) { $testFunc->total += $value; }); + each((object) ['a' => 1, 'b' => 2], function ($value) use ($testFunc) { + $testFunc->total += $value; + }); $this->assertSame(3, $testFunc->total); } -} \ No newline at end of file +} diff --git a/tests/Collection/MapTest.php b/tests/Collection/MapTest.php index 0ac9fc9..c17a7ac 100644 --- a/tests/Collection/MapTest.php +++ b/tests/Collection/MapTest.php @@ -31,4 +31,4 @@ public function testChunk() $this->assertSame(['barney', 'fred'], map($users, 'user')); $this->assertSame(['barney', 'fred'], map(new \ArrayIterator($users), 'user')); } -} \ No newline at end of file +} diff --git a/tests/Collection/SortByTest.php b/tests/Collection/SortByTest.php index f926edf..f1bb3c8 100644 --- a/tests/Collection/SortByTest.php +++ b/tests/Collection/SortByTest.php @@ -23,8 +23,10 @@ public function testSortBy() ['user' => 'barney', 'age' => 34], ]; - $this->assertSame([['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]], sortBy($users, function ($o) { return $o['user']; })); + $this->assertSame([['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]], sortBy($users, function ($o) { + return $o['user']; + })); $this->assertSame([['user' => 'barney', 'age' => 34], ['user' => 'barney', 'age' => 36], ['user' => 'fred', 'age' => 40], ['user' => 'fred', 'age' => 48]], sortBy($users, ['user', 'age'])); $this->assertSame([], sortBy(null, [])); } -} \ No newline at end of file +} diff --git a/tests/Date/NowTest.php b/tests/Date/NowTest.php index 578d1ec..3307998 100644 --- a/tests/Date/NowTest.php +++ b/tests/Date/NowTest.php @@ -19,4 +19,4 @@ public function testWords() // @TODO: This test is very volatile. Get a better way of testing a timestamp $this->assertSame((int) (\microtime(true) * 1000), now()); } -} \ No newline at end of file +} diff --git a/tests/Function/MemoizeTest.php b/tests/Function/MemoizeTest.php index 535bacc..26a8938 100644 --- a/tests/Function/MemoizeTest.php +++ b/tests/Function/MemoizeTest.php @@ -31,4 +31,4 @@ public function testMemoize() $values->cache->set($object, ['a', 'b']); $this->assertSame(['a', 'b'], $values($object)); } -} \ No newline at end of file +} diff --git a/tests/Lang/EqTest.php b/tests/Lang/EqTest.php index 8e20571..01083d6 100644 --- a/tests/Lang/EqTest.php +++ b/tests/Lang/EqTest.php @@ -85,6 +85,9 @@ public function equalValues() [ $date, $date, ], + [ + INF, INF + ] ]; } -} \ No newline at end of file +} diff --git a/tests/Lang/IsEqualTest.php b/tests/Lang/IsEqualTest.php index 8ce630c..f054cfa 100644 --- a/tests/Lang/IsEqualTest.php +++ b/tests/Lang/IsEqualTest.php @@ -86,4 +86,4 @@ public function equalValues() ], ]; } -} \ No newline at end of file +} diff --git a/tests/Lang/IsErrorTest.php b/tests/Lang/IsErrorTest.php index be2af2a..4d09881 100644 --- a/tests/Lang/IsErrorTest.php +++ b/tests/Lang/IsErrorTest.php @@ -35,4 +35,4 @@ public function testIsError() $this->assertFalse(isError(new \stdClass())); $this->assertFalse(isError(\Exception::class)); } -} \ No newline at end of file +} diff --git a/tests/Math/AddTest.php b/tests/Math/AddTest.php index c5cc06b..3c3e130 100644 --- a/tests/Math/AddTest.php +++ b/tests/Math/AddTest.php @@ -18,4 +18,4 @@ public function testAdd() { $this->assertSame(10, add(6, 4)); } -} \ No newline at end of file +} diff --git a/tests/Number/ClampTest.php b/tests/Number/ClampTest.php index 09e5a1a..a116c7b 100644 --- a/tests/Number/ClampTest.php +++ b/tests/Number/ClampTest.php @@ -19,4 +19,4 @@ public function testClamp() $this->assertSame(-5, clamp(-10, -5, 5)); $this->assertSame(5, clamp(10, -5, 5)); } -} \ No newline at end of file +} diff --git a/tests/Number/InRangeTest.php b/tests/Number/InRangeTest.php index 3b73841..45fe4b3 100644 --- a/tests/Number/InRangeTest.php +++ b/tests/Number/InRangeTest.php @@ -28,4 +28,4 @@ public function testInRange() $this->assertTrue(inRange(-3, -2, -6)); $this->assertTrue(inRange(4, 12)); } -} \ No newline at end of file +} diff --git a/tests/Number/RandomTest.php b/tests/Number/RandomTest.php index 8e5e443..6ad6d00 100644 --- a/tests/Number/RandomTest.php +++ b/tests/Number/RandomTest.php @@ -25,4 +25,4 @@ public function testRandom() $this->assertTrue(is_float(random(true))); $this->assertTrue(inRange(random(10, 5), 5, 11)); } -} \ No newline at end of file +} diff --git a/tests/String/CamelCaseTest.php b/tests/String/CamelCaseTest.php index d387682..cedc95b 100644 --- a/tests/String/CamelCaseTest.php +++ b/tests/String/CamelCaseTest.php @@ -20,4 +20,4 @@ public function testWords() $this->assertSame('fooBar', camelCase('--foo-bar--')); $this->assertSame('fooBar', camelCase('__FOO_BAR__')); } -} \ No newline at end of file +} diff --git a/tests/String/CapitalizeTest.php b/tests/String/CapitalizeTest.php index 36b3762..a2f9b14 100644 --- a/tests/String/CapitalizeTest.php +++ b/tests/String/CapitalizeTest.php @@ -18,4 +18,4 @@ public function testWords() { $this->assertSame('Fred', capitalize('FRED')); } -} \ No newline at end of file +} diff --git a/tests/String/DeburrTest.php b/tests/String/DeburrTest.php index e269b0b..b5c2eac 100644 --- a/tests/String/DeburrTest.php +++ b/tests/String/DeburrTest.php @@ -18,4 +18,4 @@ public function testWords() { $this->assertSame('deja vu', deburr('déjà vu')); } -} \ No newline at end of file +} diff --git a/tests/String/EndsWithTest.php b/tests/String/EndsWithTest.php index 4e2748f..158c4c5 100644 --- a/tests/String/EndsWithTest.php +++ b/tests/String/EndsWithTest.php @@ -22,4 +22,4 @@ public function testWords() $this->assertFalse(endsWith('abc', 'b')); $this->assertTrue(endsWith('abc', 'b', 2)); } -} \ No newline at end of file +} diff --git a/tests/String/EscapeRegExpTest.php b/tests/String/EscapeRegExpTest.php index 7b37090..c26c866 100644 --- a/tests/String/EscapeRegExpTest.php +++ b/tests/String/EscapeRegExpTest.php @@ -18,4 +18,4 @@ public function testEscapeRegExp() { $this->assertSame('\[lodash\]\(https://lodash\.com/\)', escapeRegExp('[lodash](https://lodash.com/)')); } -} \ No newline at end of file +} diff --git a/tests/String/EscapeTest.php b/tests/String/EscapeTest.php index d772754..fb5671b 100644 --- a/tests/String/EscapeTest.php +++ b/tests/String/EscapeTest.php @@ -18,4 +18,4 @@ public function testEscape() { $this->assertSame('fred, barney, & pebbles', escape('fred, barney, & pebbles')); } -} \ No newline at end of file +} diff --git a/tests/String/KebabCaseTest.php b/tests/String/KebabCaseTest.php index bfcad01..d1b50c5 100644 --- a/tests/String/KebabCaseTest.php +++ b/tests/String/KebabCaseTest.php @@ -20,4 +20,4 @@ public function testKebabCase() $this->assertSame('foo-bar', kebabCase('fooBar')); $this->assertSame('foo-bar', kebabCase('__FOO_BAR__')); } -} \ No newline at end of file +} diff --git a/tests/String/LowerCaseTest.php b/tests/String/LowerCaseTest.php index 4d3d5ef..166654a 100644 --- a/tests/String/LowerCaseTest.php +++ b/tests/String/LowerCaseTest.php @@ -20,4 +20,4 @@ public function testLowerCase() $this->assertSame('foo bar', lowerCase('fooBar')); $this->assertSame('foo bar', lowerCase('__FOO_BAR__')); } -} \ No newline at end of file +} diff --git a/tests/String/LowerFirstTest.php b/tests/String/LowerFirstTest.php index bb817ff..6dedbc0 100644 --- a/tests/String/LowerFirstTest.php +++ b/tests/String/LowerFirstTest.php @@ -19,4 +19,4 @@ public function testLowerFirst() $this->assertSame('fred', lowerFirst('Fred')); $this->assertSame('fRED', lowerFirst('FRED')); } -} \ No newline at end of file +} diff --git a/tests/String/PadEndTest.php b/tests/String/PadEndTest.php index a31d30e..5ee4056 100644 --- a/tests/String/PadEndTest.php +++ b/tests/String/PadEndTest.php @@ -20,4 +20,4 @@ public function testPadEnd() $this->assertSame('abc_-_', padEnd('abc', 6, '_-')); $this->assertSame('abc', padEnd('abc', 2)); } -} \ No newline at end of file +} diff --git a/tests/String/PadStartTest.php b/tests/String/PadStartTest.php index 3679329..c208936 100644 --- a/tests/String/PadStartTest.php +++ b/tests/String/PadStartTest.php @@ -20,4 +20,4 @@ public function testPadStart() $this->assertSame('_-_abc', padStart('abc', 6, '_-')); $this->assertSame('abc', padStart('abc', 2)); } -} \ No newline at end of file +} diff --git a/tests/String/PadTest.php b/tests/String/PadTest.php index 62da82a..720c1a0 100644 --- a/tests/String/PadTest.php +++ b/tests/String/PadTest.php @@ -20,4 +20,4 @@ public function testPad() $this->assertSame('_-abc_-_', pad('abc', 8, '_-')); $this->assertSame('abc', pad('abc', 2)); } -} \ No newline at end of file +} diff --git a/tests/String/ParseIntTest.php b/tests/String/ParseIntTest.php index d47f53b..9a0147e 100644 --- a/tests/String/ParseIntTest.php +++ b/tests/String/ParseIntTest.php @@ -19,4 +19,4 @@ public function testParseInt() $this->assertSame(8, parseInt('08')); $this->assertSame(8, parseInt('08', 10)); } -} \ No newline at end of file +} diff --git a/tests/String/RepeatTest.php b/tests/String/RepeatTest.php index 316b013..e6f2aea 100644 --- a/tests/String/RepeatTest.php +++ b/tests/String/RepeatTest.php @@ -20,4 +20,4 @@ public function testRepeat() $this->assertSame('abcabc', repeat('abc', 2)); $this->assertSame('', repeat('abc', 0)); } -} \ No newline at end of file +} diff --git a/tests/String/ReplaceTest.php b/tests/String/ReplaceTest.php index 3a65730..e1bba2f 100644 --- a/tests/String/ReplaceTest.php +++ b/tests/String/ReplaceTest.php @@ -23,4 +23,4 @@ public function testReplace() return implode(' - ', [$p1, $p2, $p3]); })); } -} \ No newline at end of file +} diff --git a/tests/String/SnakeCaseTest.php b/tests/String/SnakeCaseTest.php index 307ff7e..bffefc0 100644 --- a/tests/String/SnakeCaseTest.php +++ b/tests/String/SnakeCaseTest.php @@ -20,4 +20,4 @@ public function testSnakeCase() $this->assertSame('foo_bar', snakeCase('fooBar')); $this->assertSame('foo_bar', snakeCase('--FOO-BAR--')); } -} \ No newline at end of file +} diff --git a/tests/String/SplitTest.php b/tests/String/SplitTest.php index 7d42e39..56826c7 100644 --- a/tests/String/SplitTest.php +++ b/tests/String/SplitTest.php @@ -22,4 +22,4 @@ public function testSplit() $this->assertSame(['Hello', 'World.', 'How'], split('Hello World. How are you doing?', ' ', 3)); $this->assertSame(['Hello ', '1', ' word. Sentence number ', '2', '.'], split('Hello 1 word. Sentence number 2.', '/(\d)/')); } -} \ No newline at end of file +} diff --git a/tests/String/StartCaseTest.php b/tests/String/StartCaseTest.php index 199cdcc..7bd7a95 100644 --- a/tests/String/StartCaseTest.php +++ b/tests/String/StartCaseTest.php @@ -20,4 +20,4 @@ public function testStartCase() $this->assertSame('Foo Bar', startCase('fooBar')); $this->assertSame('FOO BAR', startCase('__FOO_BAR__')); } -} \ No newline at end of file +} diff --git a/tests/String/StartsWithTest.php b/tests/String/StartsWithTest.php index 7cf0fd9..e4c15a3 100644 --- a/tests/String/StartsWithTest.php +++ b/tests/String/StartsWithTest.php @@ -22,4 +22,4 @@ public function testStartsWith() $this->assertFalse(startsWith('abc', 'b')); $this->assertTrue(startsWith('abc', 'b', 1)); } -} \ No newline at end of file +} diff --git a/tests/String/TemplateTest.php b/tests/String/TemplateTest.php index 17a1a3b..a51403d 100644 --- a/tests/String/TemplateTest.php +++ b/tests/String/TemplateTest.php @@ -42,4 +42,4 @@ public function testTemplate() $compiled = template('hello {{ user }}!'); $this->assertSame('hello mustache!', $compiled(['user' => 'mustache'])); } -} \ No newline at end of file +} diff --git a/tests/String/ToLowerTest.php b/tests/String/ToLowerTest.php index 7feffd3..74c6e4a 100644 --- a/tests/String/ToLowerTest.php +++ b/tests/String/ToLowerTest.php @@ -20,4 +20,4 @@ public function testToLower() $this->assertSame('foobar', toLower('fooBar')); $this->assertSame('__foo_bar__', toLower('__FOO_BAR__')); } -} \ No newline at end of file +} diff --git a/tests/String/ToUpperTest.php b/tests/String/ToUpperTest.php index 5522ca7..a8eab10 100644 --- a/tests/String/ToUpperTest.php +++ b/tests/String/ToUpperTest.php @@ -20,4 +20,4 @@ public function testToUpper() $this->assertSame('FOOBAR', toUpper('fooBar')); $this->assertSame('__FOO_BAR__', toUpper('__foo_bar__')); } -} \ No newline at end of file +} diff --git a/tests/String/TrimEndTest.php b/tests/String/TrimEndTest.php index 2c3d909..e387e7d 100644 --- a/tests/String/TrimEndTest.php +++ b/tests/String/TrimEndTest.php @@ -19,4 +19,4 @@ public function testTrimEnd() $this->assertSame(' abc', trimEnd(' abc ')); $this->assertSame('-_-abc', trimEnd('-_-abc-_-', '_-')); } -} \ No newline at end of file +} diff --git a/tests/String/TrimStartTest.php b/tests/String/TrimStartTest.php index d962fd3..ad31ace 100644 --- a/tests/String/TrimStartTest.php +++ b/tests/String/TrimStartTest.php @@ -19,4 +19,4 @@ public function testTrimStart() $this->assertSame('abc ', trimStart(' abc ')); $this->assertSame('abc-_-', trimStart('-_-abc-_-', '_-')); } -} \ No newline at end of file +} diff --git a/tests/String/TrimTest.php b/tests/String/TrimTest.php index 026955c..ee5ce95 100644 --- a/tests/String/TrimTest.php +++ b/tests/String/TrimTest.php @@ -19,4 +19,4 @@ public function testTrim() $this->assertSame('abc', trim(' abc ')); $this->assertSame('abc', trim('-_-abc-_-', '_-')); } -} \ No newline at end of file +} diff --git a/tests/String/TruncateTest.php b/tests/String/TruncateTest.php index bd6ed4d..c0837d1 100644 --- a/tests/String/TruncateTest.php +++ b/tests/String/TruncateTest.php @@ -25,4 +25,4 @@ public function testTruncate() $this->assertSame("hi-diddly-ho there,\u{e800}neighbo...", truncate("hi-diddly-ho there,\u{e800}neighborino")); $this->assertSame("hi-diddly-ho there, \u{e800} neigh...", truncate("hi-diddly-ho there, \u{e800} neighborino", ['separator' => '/\s?+/'])); } -} \ No newline at end of file +} diff --git a/tests/String/UnescapeTest.php b/tests/String/UnescapeTest.php index 4dca468..1e41638 100644 --- a/tests/String/UnescapeTest.php +++ b/tests/String/UnescapeTest.php @@ -18,4 +18,4 @@ public function testUnescape() { $this->assertSame('fred, barney, & pebbles', unescape('fred, barney, & pebbles')); } -} \ No newline at end of file +} diff --git a/tests/String/UpperCaseTest.php b/tests/String/UpperCaseTest.php index 41f488c..af860d8 100644 --- a/tests/String/UpperCaseTest.php +++ b/tests/String/UpperCaseTest.php @@ -20,4 +20,4 @@ public function testUpperCase() $this->assertSame('FOO BAR', upperCase('fooBar')); $this->assertSame('FOO BAR', upperCase('__foo_bar__')); } -} \ No newline at end of file +} diff --git a/tests/String/UpperFirstTest.php b/tests/String/UpperFirstTest.php index cd5cd43..ef2222b 100644 --- a/tests/String/UpperFirstTest.php +++ b/tests/String/UpperFirstTest.php @@ -19,4 +19,4 @@ public function testUpperFirst() $this->assertSame('Fred', upperFirst('fred')); $this->assertSame('FRED', upperFirst('FRED')); } -} \ No newline at end of file +} diff --git a/tests/String/WordsTest.php b/tests/String/WordsTest.php index 603301c..7a3b28c 100644 --- a/tests/String/WordsTest.php +++ b/tests/String/WordsTest.php @@ -21,4 +21,4 @@ public function testWords() $this->assertSame([], words('fred, barney, & pebbles', '/[\d]+/')); $this->assertSame([], words("\u{e800}")); } -} \ No newline at end of file +} diff --git a/tests/Util/AttemptTest.php b/tests/Util/AttemptTest.php index feaa167..b384e03 100644 --- a/tests/Util/AttemptTest.php +++ b/tests/Util/AttemptTest.php @@ -28,4 +28,4 @@ public function testAttempt() return 'one'; }))); } -} \ No newline at end of file +} diff --git a/tests/Util/IdentityTest.php b/tests/Util/IdentityTest.php index 4ee9406..a2c35bd 100644 --- a/tests/Util/IdentityTest.php +++ b/tests/Util/IdentityTest.php @@ -20,4 +20,4 @@ public function testIdentity() $this->assertSame($object, identity($object)); } -} \ No newline at end of file +} diff --git a/tests/Util/PropertyTest.php b/tests/Util/PropertyTest.php index d07eca5..e0d7afa 100644 --- a/tests/Util/PropertyTest.php +++ b/tests/Util/PropertyTest.php @@ -26,4 +26,4 @@ public function testIdentity() $this->assertSame([2, 1], map($objects, property('a.b'))); $this->assertSame([1, 2], map(sortBy($objects, property(['a', 'b'])), 'a.b')); } -} \ No newline at end of file +} From 07ce010b0326f330fff7483ea8a02b03430bb11b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 20:28:37 +0200 Subject: [PATCH 031/159] Add Collection.countBy function --- src/Collection/countBy.php | 59 ++++++++++++++++++++++++++++++++ tests/Collection/CountByTest.php | 22 ++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/Collection/countBy.php create mode 100644 tests/Collection/CountByTest.php diff --git a/src/Collection/countBy.php b/src/Collection/countBy.php new file mode 100644 index 0000000..946bc9b --- /dev/null +++ b/src/Collection/countBy.php @@ -0,0 +1,59 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates an array composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param callable $iteratee The iteratee to transform keys. + * + * @return array Returns the composed aggregate object. + * @example + * + * countBy([6.1, 4.2, 6.3], 'floor'); + * // => ['6' => 2, '4' => 1] + * + * // The `property` iteratee shorthand. + * countBy(['one', 'two', 'three'], 'strlen'); + * // => ['3' => 2, '5' => 1] + * + */ +function countBy(iterable $collection, callable $iteratee = null): array +{ + if (!$iteratee) { + $iteratee = '_\identity'; + } + + $result = []; + + foreach ($collection as $value) { + if (!\is_scalar($value)) { + continue; + } + + $computed = $iteratee($value); + + if (!isset($result[$computed])) { + $result[$computed] = 0; + }; + + $result[$computed]++; + } + + return $result; +} \ No newline at end of file diff --git a/tests/Collection/CountByTest.php b/tests/Collection/CountByTest.php new file mode 100644 index 0000000..c2d3bd2 --- /dev/null +++ b/tests/Collection/CountByTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\countBy; +use PHPUnit\Framework\TestCase; + +class CountByTest extends TestCase +{ + public function testCountBy() + { + $this->assertSame(['6' => 2, '4' => 1], countBy([6.1, 4.2, 6.3], 'floor')); + $this->assertSame(['3' => 2, '5' => 1], countBy(['one', 'two', 'three'], 'strlen')); + } +} \ No newline at end of file From 500cd3c6d5f870bb853f9216753e6d46113d1a21 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 20:38:55 +0200 Subject: [PATCH 032/159] Add Collection.every function --- src/Collection/every.php | 67 ++++++++++++++++++++++++++++++++++ tests/Collection/EveryTest.php | 35 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/Collection/every.php create mode 100644 tests/Collection/EveryTest.php diff --git a/src/Collection/every.php b/src/Collection/every.php new file mode 100644 index 0000000..806e11b --- /dev/null +++ b/src/Collection/every.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Checks if `predicate` returns truthy for **all** elements of `array`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * **Note:** This method returns `true` for + * [empty arrays](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty arrays. + * + * @category Array + * + * @param array $array The array to iterate over. + * @param callable $predicate The function invoked per iteration. + * + * @return bool `true` if all elements pass the predicate check, else `false`. + * @example + * + * every([true, 1, null, 'yes'], function ($value) { return is_bool($value);}) + * // => false + * + * $users = [ + * ['user' => 'barney', 'age' => 36, 'active' => false], + * ['user' => 'fred', 'age' => 40, 'active' => false], + * ]; + * + * // The `matches` iteratee shorthand. + * $this->assertFalse(every($users, ['user' => 'barney', 'active' => false])); + * // false + * + * // The `matchesProperty` iteratee shorthand. + * $this->assertTrue(every($users, ['active', false])); + * // true + * + * // The `property` iteratee shorthand. + * $this->assertFalse(every($users, 'active')); + * //false + * + * + */ +function every(array $array, $predicate): bool +{ + $iteratee = baseIteratee($predicate); + + foreach ($array as $key => $value) { + if (!$iteratee($value, $key, $array)) { + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/tests/Collection/EveryTest.php b/tests/Collection/EveryTest.php new file mode 100644 index 0000000..37a3f07 --- /dev/null +++ b/tests/Collection/EveryTest.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\every; + +class EveryTest extends TestCase +{ + public function testEvery() + { + $this->assertFalse(every([true, 1, null, 'yes'], function ($value) { return is_bool($value); })); + + $users = [ + ['user' => 'barney', 'age' => 36, 'active' => false], + ['user' => 'fred', 'age' => 40, 'active' => false], + ]; + + // The `matches` iteratee shorthand. + $this->assertFalse(every($users, ['user' => 'barney', 'active' => false])); + + // The `matchesProperty` iteratee shorthand. + $this->assertTrue(every($users, ['active', false])); + + // The `property` iteratee shorthand. + $this->assertFalse(every($users, 'active')); + } +} \ No newline at end of file From deb79dcb99b758ddc9a7339ebab988273f4cafda Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 20:54:00 +0200 Subject: [PATCH 033/159] Add Collection.filter function --- src/Collection/filter.php | 71 +++++++++++++++++++++++++++++++++ tests/Collection/FilterTest.php | 35 ++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/Collection/filter.php create mode 100644 tests/Collection/FilterTest.php diff --git a/src/Collection/filter.php b/src/Collection/filter.php new file mode 100644 index 0000000..6339228 --- /dev/null +++ b/src/Collection/filter.php @@ -0,0 +1,71 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Iterates over elements of `array`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index, array). + * + * **Note:** Unlike `remove`, this method returns a new array. + * + * @category Collection + * + * @param iterable $array The array to iterate over. + * @param callable $predicate The function invoked per iteration. + * + * @return array the new filtered array. + * @example + * + * $users = [ + * [ 'user' => 'barney', 'age' => 36, 'active' => true], + * [ 'user' => 'fred', 'age' => 40, 'active' => false] + * ]; + * + * filter($users, function($o) { return !$o['active']; }); + * // => objects for ['fred'] + * + * // The `matches` iteratee shorthand. + * filter($users, ['age' => 36, 'active' => true]); + * // => objects for ['barney'] + * + * // The `matchesProperty` iteratee shorthand. + * filter($users, ['active', false]); + * // => objects for ['fred'] + * + * // The `property` iteratee shorthand. + * filter($users, 'active'); + * // => objects for ['barney'] + * + */ +function filter(iterable $array, $predicate = null): array +{ + if (null === $predicate) { + $predicate = '_\identity'; + } + + $iteratee = baseIteratee($predicate); + + $result = \array_filter( + $array, + function ($value, $key) use ($array, $iteratee) { + return $iteratee($value, $key, $array); + }, + \ARRAY_FILTER_USE_BOTH + ); + + \sort($result); + + return $result; +} \ No newline at end of file diff --git a/tests/Collection/FilterTest.php b/tests/Collection/FilterTest.php new file mode 100644 index 0000000..e590053 --- /dev/null +++ b/tests/Collection/FilterTest.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\filter; + +class FilterTest extends TestCase +{ + public function testFilter() + { + $users = [ + ['user' => 'barney', 'age' => 36, 'active' => true], + ['user' => 'fred', 'age' => 40, 'active' => false], + ]; + + $this->assertSame([['user' => 'fred', 'age' => 40, 'active' => false]], filter($users, function ($o) { return !$o['active']; })); + + // The `matches` iteratee shorthand. + $this->assertSame([['user' => 'barney', 'age' => 36, 'active' => true]], filter($users, ['age' => 36, 'active' => true])); + + // The `matchesProperty` iteratee shorthand. + $this->assertSame([['user' => 'fred', 'age' => 40, 'active' => false]], filter($users, ['active', false])); + + // The `property` iteratee shorthand. + $this->assertSame([['user' => 'barney', 'age' => 36, 'active' => true]], filter($users, 'active')); + } +} \ No newline at end of file From f9c37dac2481682e7f3c841deb4ca238604524c8 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 21:05:04 +0200 Subject: [PATCH 034/159] Add Collection.find function --- src/Collection/find.php | 69 +++++++++++++++++++++++++++++++++++ tests/Collection/FindTest.php | 36 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/Collection/find.php create mode 100644 tests/Collection/FindTest.php diff --git a/src/Collection/find.php b/src/Collection/find.php new file mode 100644 index 0000000..2c44d76 --- /dev/null +++ b/src/Collection/find.php @@ -0,0 +1,69 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @category Collection + * + * @param iterable $collection The collection to inspect. + * @param callable $predicate The function invoked per iteration. + * @param int $fromIndex The index to search from. + * + * @return mixed Returns the matched element, else `null`. + * + * @see findIndex, findKey, findLast, findLastIndex, findLastKey + * @example + * + * $users = [ + * ['user' => 'barney', 'age' => 36, 'active' => true], + * ['user' => 'fred', 'age' => 40, 'active' => false], + * ['user' => 'pebbles', 'age' => 1, 'active' => true] + * ]; + * + * find($users, function($o) { return $o['age'] < 40; }); + * // => object for 'barney' + * + * // The `matches` iteratee shorthand. + * find($users, ['age' => 1, 'active' => true]); + * // => object for 'pebbles' + * + * // The `matchesProperty` iteratee shorthand. + * find($users, ['active', false]); + * // => object for 'fred' + * + * // The `property` iteratee shorthand. + * find($users, 'active'); + * // => object for 'barney' + * + */ +function find(iterable $collection, $predicate = null, int $fromIndex = 0) +{ + if (null === $predicate) { + $predicate = '_\identity'; + } + + $iteratee = baseIteratee($predicate); + + foreach (\array_slice($collection, $fromIndex) as $key => $value) { + if ($iteratee($value, $key, $collection)) { + return $value; + } + } + + return null; +} \ No newline at end of file diff --git a/tests/Collection/FindTest.php b/tests/Collection/FindTest.php new file mode 100644 index 0000000..5845e64 --- /dev/null +++ b/tests/Collection/FindTest.php @@ -0,0 +1,36 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\find; + +class FindTest extends TestCase +{ + public function testFind() + { + $users = [ + ['user' => 'barney', 'age' => 36, 'active' => true], + ['user' => 'fred', 'age' => 40, 'active' => false], + ['user' => 'pebbles', 'age' => 1, 'active' => true], + ]; + + $this->assertSame(['user' => 'barney', 'age' => 36, 'active' => true], find($users, function ($o) { return $o['age'] < 40; })); + + // The `matches` iteratee shorthand. + $this->assertSame(['user' => 'pebbles', 'age' => 1, 'active' => true], find($users, ['age' => 1, 'active' => true])); + + // The `matchesProperty` iteratee shorthand. + $this->assertSame(['user' => 'fred', 'age' => 40, 'active' => false], find($users, ['active', false])); + + // The `property` iteratee shorthand. + $this->assertSame(['user' => 'barney', 'age' => 36, 'active' => true], find($users, 'active')); + } +} \ No newline at end of file From 35dfa270cb2cee94b23487e4ffb01903a8f1950a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 21:08:43 +0200 Subject: [PATCH 035/159] Add Collection.findLast function --- src/Collection/findLast.php | 46 +++++++++++++++++++++++++++++++ tests/Collection/FindLastTest.php | 21 ++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/Collection/findLast.php create mode 100644 tests/Collection/FindLastTest.php diff --git a/src/Collection/findLast.php b/src/Collection/findLast.php new file mode 100644 index 0000000..6627401 --- /dev/null +++ b/src/Collection/findLast.php @@ -0,0 +1,46 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * This method is like `find` except that it iterates over elements of + * `collection` from right to left. + * + * @category Collection + * @param iterable $collection The collection to inspect. + * @param callable $predicate The function invoked per iteration. + * @param int $fromIndex The index to search from. + * @return mixed Returns the matched element, else `undefined`. + * @example + * + * findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; }) + * // => 3 + * + */ +function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) +{ + if (null === $predicate) { + $predicate = '_\identity'; + } + + $iteratee = baseIteratee($predicate); + + foreach (\array_slice(\array_reverse($collection, true), $fromIndex) as $key => $value) { + if ($iteratee($value, $key, $collection)) { + return $value; + } + } + + return null; +} \ No newline at end of file diff --git a/tests/Collection/FindLastTest.php b/tests/Collection/FindLastTest.php new file mode 100644 index 0000000..0ee7a88 --- /dev/null +++ b/tests/Collection/FindLastTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\findLast; + +class FindLastTest extends TestCase +{ + public function testFindLast() + { + $this->assertSame(3, findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; })); + } +} \ No newline at end of file From 18bd6b9309692ce2301c85cc7f6b921596248baf Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 21:09:53 +0200 Subject: [PATCH 036/159] Remove un-needed default set for predicate --- src/Collection/filter.php | 4 ---- src/Collection/find.php | 4 ---- src/Collection/findLast.php | 4 ---- 3 files changed, 12 deletions(-) diff --git a/src/Collection/filter.php b/src/Collection/filter.php index 6339228..bfd013b 100644 --- a/src/Collection/filter.php +++ b/src/Collection/filter.php @@ -51,10 +51,6 @@ */ function filter(iterable $array, $predicate = null): array { - if (null === $predicate) { - $predicate = '_\identity'; - } - $iteratee = baseIteratee($predicate); $result = \array_filter( diff --git a/src/Collection/find.php b/src/Collection/find.php index 2c44d76..c53785a 100644 --- a/src/Collection/find.php +++ b/src/Collection/find.php @@ -53,10 +53,6 @@ */ function find(iterable $collection, $predicate = null, int $fromIndex = 0) { - if (null === $predicate) { - $predicate = '_\identity'; - } - $iteratee = baseIteratee($predicate); foreach (\array_slice($collection, $fromIndex) as $key => $value) { diff --git a/src/Collection/findLast.php b/src/Collection/findLast.php index 6627401..60e5ab6 100644 --- a/src/Collection/findLast.php +++ b/src/Collection/findLast.php @@ -30,10 +30,6 @@ */ function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { - if (null === $predicate) { - $predicate = '_\identity'; - } - $iteratee = baseIteratee($predicate); foreach (\array_slice(\array_reverse($collection, true), $fromIndex) as $key => $value) { From 825c8c8ae30faaa16125553993b9e817795ec293 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 25 Mar 2018 21:17:53 +0200 Subject: [PATCH 037/159] Add Collection.flatMap function --- src/Collection/flatMap.php | 40 ++++++++++++++++++++++++++++++++ tests/Collection/FlatMapTest.php | 25 ++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/Collection/flatMap.php create mode 100644 tests/Collection/FlatMapTest.php diff --git a/src/Collection/flatMap.php b/src/Collection/flatMap.php new file mode 100644 index 0000000..2fe47f0 --- /dev/null +++ b/src/Collection/flatMap.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseFlatten; + +/** + * Creates a flattened array of values by running each element in `collection` + * through `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @category Collection + * + * @param iterable collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. + * + * @return array the new flattened array. + * @example + * + * function duplicate($n) { + * return [$n, $n] + * } + * + * flatMap([1, 2], 'duplicate') + * // => [1, 1, 2, 2] + * + */ +function flatMap(iterable $collection, callable $iteratee = null): array +{ + return baseFlatten(map($collection, $iteratee), 1); +} \ No newline at end of file diff --git a/tests/Collection/FlatMapTest.php b/tests/Collection/FlatMapTest.php new file mode 100644 index 0000000..93285c7 --- /dev/null +++ b/tests/Collection/FlatMapTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\flatMap; + +class FlatMapTest extends TestCase +{ + public function testFlatMap() + { + $duplicate = function ($n) { + return [$n, $n]; + }; + + $this->assertSame([1, 1, 2, 2], flatMap([1, 2], $duplicate)); + } +} \ No newline at end of file From be7ca0afc1da25e86e7dcf23a5678f16e04adf7d Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 08:58:13 +0200 Subject: [PATCH 038/159] Add Collection.flatMapDeep function --- src/Collection/flatMapDeep.php | 39 ++++++++++++++++++++++++++++ tests/Collection/FlatMapDeepTest.php | 25 ++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/Collection/flatMapDeep.php create mode 100644 tests/Collection/FlatMapDeepTest.php diff --git a/src/Collection/flatMapDeep.php b/src/Collection/flatMapDeep.php new file mode 100644 index 0000000..5b1a34c --- /dev/null +++ b/src/Collection/flatMapDeep.php @@ -0,0 +1,39 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseFlatten; + +/** + * This method is like `flatMap` except that it recursively flattens the + * mapped results. + * + * @category Collection + * + * @param iterable collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. + * + * @return array Returns the new flattened array. + * @example + * + * function duplicate($n) { + * return [[[$n, $n]]]; + * } + * + * flatMapDeep([1, 2], 'duplicate'); + * // => [1, 1, 2, 2] + * + */ +function flatMapDeep(iterable $collection, callable $iteratee = null): array +{ + return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); +} \ No newline at end of file diff --git a/tests/Collection/FlatMapDeepTest.php b/tests/Collection/FlatMapDeepTest.php new file mode 100644 index 0000000..a000dcb --- /dev/null +++ b/tests/Collection/FlatMapDeepTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\flatMapDeep; + +class FlatMapDeepTest extends TestCase +{ + public function testFlatMapDeep() + { + $duplicate = function ($n) { + return [[[$n, $n]]]; + }; + + $this->assertSame([1, 1, 2, 2], flatMapDeep([1, 2], $duplicate)); + } +} \ No newline at end of file From eed43789f58dabf56592c64e916fc0bc1561b7f7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 09:04:53 +0200 Subject: [PATCH 039/159] Add Collection.flatMapDepth function --- src/Collection/flatMapDepth.php | 40 +++++++++++++++++++++++++++ tests/Collection/FlatMapDepthTest.php | 25 +++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/Collection/flatMapDepth.php create mode 100644 tests/Collection/FlatMapDepthTest.php diff --git a/src/Collection/flatMapDepth.php b/src/Collection/flatMapDepth.php new file mode 100644 index 0000000..835ac24 --- /dev/null +++ b/src/Collection/flatMapDepth.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseFlatten; + +/** + * This method is like `flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @category Collection + * + * @param iterable collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. + * @param int $depth The maximum recursion depth. + * + * @return array the new flattened array. + * @example + * + * function duplicate($n) { + * return [[[$n, $n]]] + * } + * + * flatMapDepth([1, 2], 'duplicate', 2) + * // => [[1, 1], [2, 2]] + * + */ +function flatMapDepth(iterable $collection, callable $iteratee = null, int $depth = 1): array +{ + return baseFlatten(map($collection, $iteratee), $depth); +} \ No newline at end of file diff --git a/tests/Collection/FlatMapDepthTest.php b/tests/Collection/FlatMapDepthTest.php new file mode 100644 index 0000000..f4897de --- /dev/null +++ b/tests/Collection/FlatMapDepthTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\flatMapDepth; +use PHPUnit\Framework\TestCase; + +class FlatMapDepthTest extends TestCase +{ + public function testFlatMapDepth() + { + $duplicate = function ($n) { + return [[[$n, $n]]]; + }; + + $this->assertSame([[1, 1], [2, 2]], flatMapDepth([1, 2], $duplicate, 2)); + } +} \ No newline at end of file From 3535c14470bd4bac7286320a968109e5b96ecf95 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 09:17:06 +0200 Subject: [PATCH 040/159] Add Collection.eachRight function --- src/Collection/eachRight.php | 45 ++++++++++++++++++++++++++++++ tests/Collection/EachRightTest.php | 31 ++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/Collection/eachRight.php create mode 100644 tests/Collection/EachRightTest.php diff --git a/src/Collection/eachRight.php b/src/Collection/eachRight.php new file mode 100644 index 0000000..b2d0d19 --- /dev/null +++ b/src/Collection/eachRight.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * This method is like `each` except that it iterates over elements of + * `collection` from right to left. + * + * @category Collection + * + * @param array|object $collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. + * + * @return array|object Returns `collection`. + * @example + * + * eachRight([1, 2], function($value) { echo $value; }) + * // => Echoes `2` then `1`. + * + */ +function eachRight($collection, callable $iteratee) +{ + $values = $collection; + + if (\is_object($collection)) { + $values = \get_object_vars($collection); + } + + foreach (\array_reverse($values, true) as $index => $value) { + if (false === $iteratee($value, $index, $collection)) { + break; + } + } + + return $collection; +} \ No newline at end of file diff --git a/tests/Collection/EachRightTest.php b/tests/Collection/EachRightTest.php new file mode 100644 index 0000000..ed62bca --- /dev/null +++ b/tests/Collection/EachRightTest.php @@ -0,0 +1,31 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\eachRight; +use PHPUnit\Framework\TestCase; + +class EachRightTest extends TestCase +{ + public function testForEachRight() + { + $test = []; + eachRight([1, 2], function ($value) use (&$test) { + $test[$value] = true; + }); + $this->assertSame([2 => true, 1 => true], $test); + + $test = []; + eachRight((object) ['a' => 1, 'b' => 2], function ($value) use (&$test) { + $test[$value] = true; + }); + $this->assertSame([2 => true, 1 => true], $test); + } +} \ No newline at end of file From 7dd9fb4483212fabea913cdce7521966f31de610 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 09:36:35 +0200 Subject: [PATCH 041/159] Add Collection.groupBy function --- src/Collection/groupBy.php | 47 +++++++++++++++++++++++++++++++ src/internal/createAggregator.php | 31 ++++++++++++++++++++ tests/Collection/GroupByTest.php | 22 +++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 src/Collection/groupBy.php create mode 100644 src/internal/createAggregator.php create mode 100644 tests/Collection/GroupByTest.php diff --git a/src/Collection/groupBy.php b/src/Collection/groupBy.php new file mode 100644 index 0000000..834820a --- /dev/null +++ b/src/Collection/groupBy.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates an array composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @category Collection + * + * @param iterable collection The collection to iterate over. + * @param callable $iteratee The iteratee to transform keys. + * + * @return array Returns the composed aggregate object. + * @example + * + * groupBy([6.1, 4.2, 6.3], 'floor'); + * // => ['6' => [6.1, 6.3], '4' => [4.2]] + * + * groupBy(['one', 'two', 'three'], 'strlen'); + * // => ['3' => ['one', 'two'], '5' => ['three']] + * + */ +function groupBy(iterable $collection, callable $iteratee): array +{ + return createAggregator(function ($result, $value, $key) { + if (!isset($result[$key])) { + $result[$key] = []; + } + + $result[$key][] = $value; + + return $result; + })($collection, $iteratee); +} \ No newline at end of file diff --git a/src/internal/createAggregator.php b/src/internal/createAggregator.php new file mode 100644 index 0000000..0bd4a43 --- /dev/null +++ b/src/internal/createAggregator.php @@ -0,0 +1,31 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\each; + +function createAggregator($setter, $initializer = null) +{ + return function ($collection, $iteratee) use ($setter, $initializer) { + $accumulator = null !== $initializer ? $initializer() : []; + + $func = function ($collection, $setter, &$accumulator, $iteratee) { + each($collection, function ($value, $key, $collection) use ($setter, &$accumulator, $iteratee) { + $accumulator = $setter($accumulator, $value, $iteratee($value), $collection); + }); + + return $accumulator; + }; + + return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); + }; +} \ No newline at end of file diff --git a/tests/Collection/GroupByTest.php b/tests/Collection/GroupByTest.php new file mode 100644 index 0000000..ff7b91f --- /dev/null +++ b/tests/Collection/GroupByTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\groupBy; + +class GroupByTest extends TestCase +{ + public function testCountBy() + { + $this->assertSame(['6' => [6.1, 6.3], '4' => [4.2]], groupBy([6.1, 4.2, 6.3], 'floor')); + $this->assertSame(['3' => ['one', 'two'], '5' => ['three']], groupBy(['one', 'two', 'three'], 'strlen')); + } +} \ No newline at end of file From 63a50d3707fc21a7aa5a1b7532e378cce26e8cfd Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 09:42:02 +0200 Subject: [PATCH 042/159] Re-use createAggregator for Collection.countBy function --- src/Collection/countBy.php | 28 +++++++++------------------- src/Collection/groupBy.php | 2 ++ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Collection/countBy.php b/src/Collection/countBy.php index 946bc9b..9890829 100644 --- a/src/Collection/countBy.php +++ b/src/Collection/countBy.php @@ -11,6 +11,8 @@ namespace _; +use function _\internal\createAggregator; + /** * Creates an array composed of keys generated from the results of running * each element of `collection` through `iteratee`. The corresponding value of @@ -33,27 +35,15 @@ * // => ['3' => 2, '5' => 1] * */ -function countBy(iterable $collection, callable $iteratee = null): array +function countBy(iterable $collection, callable $iteratee): array { - if (!$iteratee) { - $iteratee = '_\identity'; - } - - $result = []; - - foreach ($collection as $value) { - if (!\is_scalar($value)) { - continue; + return createAggregator(function ($result, $key, $value) { + if (!isset($result[$value])) { + $result[$value] = 0; } - $computed = $iteratee($value); - - if (!isset($result[$computed])) { - $result[$computed] = 0; - }; - - $result[$computed]++; - } + $result[$value]++; - return $result; + return $result; + })($collection, $iteratee); } \ No newline at end of file diff --git a/src/Collection/groupBy.php b/src/Collection/groupBy.php index 834820a..1e354c4 100644 --- a/src/Collection/groupBy.php +++ b/src/Collection/groupBy.php @@ -11,6 +11,8 @@ namespace _; +use function _\internal\createAggregator; + /** * Creates an array composed of keys generated from the results of running * each element of `collection` through `iteratee`. The order of grouped values From b8e7abf45b96311772673dc7f5c90c6b7840dc2e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 20:47:51 +0200 Subject: [PATCH 043/159] Add Collection.invokeMap function --- src/Collection/invokeMap.php | 51 ++++++++++++++++++++++++++++++ src/internal/baseInvoke.php | 23 ++++++++++++++ src/internal/parent.php | 19 +++++++++++ tests/Collection/InvokeMapTest.php | 33 +++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/Collection/invokeMap.php create mode 100644 src/internal/baseInvoke.php create mode 100644 src/internal/parent.php create mode 100644 tests/Collection/InvokeMapTest.php diff --git a/src/Collection/invokeMap.php b/src/Collection/invokeMap.php new file mode 100644 index 0000000..148b117 --- /dev/null +++ b/src/Collection/invokeMap.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseInvoke; +use function _\internal\baseRest; + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param array|callable|string $path The path of the method to invoke or the function invoked per iteration. + * @param array $args The arguments to invoke each method with. + * + * @return array the array of results. + * @example + * + * invokeMap([[5, 1, 7], [3, 2, 1]], function($result) { sort($result); return $result;}) + * // => [[1, 5, 7], [1, 2, 3]] + * + * invokeMap([123, 456], 'str_split') + * // => [['1', '2', '3'], ['4', '5', '6']] + * + */ +function invokeMap(iterable $collection, $path, array $args = []): array +{ + return baseRest(function ($collection, $path, $args) { + $isFunc = \is_callable($path); + $result = []; + + each($collection, function ($value) use (&$result, $isFunc, $path, $args) { + $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); + }); + + return $result; + })($collection, $path, $args); +} \ No newline at end of file diff --git a/src/internal/baseInvoke.php b/src/internal/baseInvoke.php new file mode 100644 index 0000000..583ae05 --- /dev/null +++ b/src/internal/baseInvoke.php @@ -0,0 +1,23 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\last; + +function baseInvoke($object, $path, $args) +{ + $path = castPath($path, $object); + $object = parent($object, $path); + $func = null === $object ? $object : [$object, toKey(last($path))]; + + return null === $func ? null : $func($object, ...$args); +} \ No newline at end of file diff --git a/src/internal/parent.php b/src/internal/parent.php new file mode 100644 index 0000000..cc246b7 --- /dev/null +++ b/src/internal/parent.php @@ -0,0 +1,19 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\{slice, get}; + +function parent($object, $path) +{ + return count($path) < 2 ? $object : get($object, slice($path, 0, -1)); +} \ No newline at end of file diff --git a/tests/Collection/InvokeMapTest.php b/tests/Collection/InvokeMapTest.php new file mode 100644 index 0000000..fddc83b --- /dev/null +++ b/tests/Collection/InvokeMapTest.php @@ -0,0 +1,33 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\invokeMap; +use PHPUnit\Framework\TestCase; + +class InvokeMapTest extends TestCase +{ + public function testInvokeMap() + { + $this->assertSame([[1, 5, 7], [1, 2, 3]], invokeMap([[5, 1, 7], [3, 2, 1]], function($result) { sort($result); return $result;})); + $this->assertSame([['1', '2', '3'], ['4', '5', '6']], invokeMap([123, 456], 'str_split')); + + $users = [ + new class () { + public function getCount() { return 12; } + }, + new class () { + public function getCount() { return 24; } + } + ]; + + $this->assertEquals([12, 24], invokeMap($users, 'getCount')); + } +} \ No newline at end of file From cea59f25fb59114d23daa989056cfe206210e3ed Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Mar 2018 20:59:04 +0200 Subject: [PATCH 044/159] Add Collection.keyBy function --- src/Collection/keyBy.php | 49 ++++++++++++++++++++++++++++++++++ tests/Collection/KeyByTest.php | 27 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/Collection/keyBy.php create mode 100644 tests/Collection/KeyByTest.php diff --git a/src/Collection/keyBy.php b/src/Collection/keyBy.php new file mode 100644 index 0000000..db94603 --- /dev/null +++ b/src/Collection/keyBy.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\createAggregator; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param callable $iteratee The iteratee to transform keys. + * + * @return array the composed aggregate object. + * @example + * + * $array = [ + * ['direction' => 'left', 'code' => 97], + * ['direction' => 'right', 'code' => 100], + * ]; + * + * keyBy($array, function ($o) { return \chr($o['code']); }) + * // => ['a' => ['direction' => 'left', 'code' => 97], 'd' => ['direction' => 'right', 'code' => 100]] + * + * keyBy($array, 'direction'); + * // => ['left' => ['direction' => 'left', 'code' => 97], 'right' => ['direction' => 'right', 'code' => 100]] + * + */ +function keyBy(iterable $collection, $iteratee): array +{ + return createAggregator(function ($result, $value, $key) { + $result[$key] = $value; + + return $result; + })($collection, $iteratee); +} \ No newline at end of file diff --git a/tests/Collection/KeyByTest.php b/tests/Collection/KeyByTest.php new file mode 100644 index 0000000..5dee637 --- /dev/null +++ b/tests/Collection/KeyByTest.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\keyBy; + +class KeyByTest extends TestCase +{ + public function testKeyBy() + { + $array = [ + ['direction' => 'left', 'code' => 97], + ['direction' => 'right', 'code' => 100], + ]; + + $this->assertSame(['a' => ['direction' => 'left', 'code' => 97], 'd' => ['direction' => 'right', 'code' => 100]], keyBy($array, function ($o) { return \chr($o['code']); })); + $this->assertSame(['left' => ['direction' => 'left', 'code' => 97], 'right' => ['direction' => 'right', 'code' => 100]], keyBy($array, 'direction')); + } +} \ No newline at end of file From be2a15a5f7d7ed7950d5fdb76cf5a8463046ac2a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 28 Mar 2018 13:30:46 +0200 Subject: [PATCH 045/159] Add Math.max function --- src/Math/max.php | 34 ++++++++++++++++++++++++++++++++++ tests/Math/MaxTest.php | 22 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/Math/max.php create mode 100644 tests/Math/MaxTest.php diff --git a/src/Math/max.php b/src/Math/max.php new file mode 100644 index 0000000..c454d02 --- /dev/null +++ b/src/Math/max.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, null is returned. + * + * @category Math + * + * @param array array The array to iterate over. + * + * @return int|null Returns the maximum value. + * @example + * + * max([4, 2, 8, 6]); + * // => 8 + * + * max([]); + * // => null + * + */ +function max(?array $array): ?int +{ + return $array ? \max($array) : null; +} \ No newline at end of file diff --git a/tests/Math/MaxTest.php b/tests/Math/MaxTest.php new file mode 100644 index 0000000..ed8ddb0 --- /dev/null +++ b/tests/Math/MaxTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\max; + +class MaxTest extends TestCase +{ + public function testMax() + { + $this->assertSame(8, max([4, 2, 8, 6])); + $this->assertSame(null, max([])); + } +} From 550b5cd176216897db69ade19b150a467d501209 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 28 Mar 2018 13:40:36 +0200 Subject: [PATCH 046/159] Add Math.maxBy function --- src/Math/maxBy.php | 54 ++++++++++++++++++++++++++++++++++++++++ tests/Math/MaxByTest.php | 23 +++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/Math/maxBy.php create mode 100644 tests/Math/MaxByTest.php diff --git a/src/Math/maxBy.php b/src/Math/maxBy.php new file mode 100644 index 0000000..97d9c7c --- /dev/null +++ b/src/Math/maxBy.php @@ -0,0 +1,54 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * This method is like `max` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @category Math + * + * @param array $array The array to iterate over. + * @param callable|string $iteratee The iteratee invoked per element. + * + * @return mixed Returns the maximum value. + * @example + * + * $objects = [['n' => 1], ['n' => 2]]; + * + * maxBy($objects, function($o) { return $o['n']; }); + * // => ['n' => 2] + * + * // The `property` iteratee shorthand. + * maxBy($objects, 'n'); + * // => ['n' => 2] + */ +function maxBy(?array $array, $iteratee) +{ + $iteratee = baseIteratee($iteratee); + $result = null; + $computed = null; + + foreach ($array as $key => $value) { + $current = $iteratee($value); + + if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { + $computed = $current; + $result = $value; + } + } + + return $result; +} \ No newline at end of file diff --git a/tests/Math/MaxByTest.php b/tests/Math/MaxByTest.php new file mode 100644 index 0000000..97fe5c6 --- /dev/null +++ b/tests/Math/MaxByTest.php @@ -0,0 +1,23 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\maxBy; + +class MaxByTest extends TestCase +{ + public function testMax() + { + $objects = [['n' => 1], ['n' => 2]]; + $this->assertSame(['n' => 2], maxBy($objects, function ($o) { return $o['n']; })); + $this->assertSame(['n' => 2], maxBy($objects, 'n')); + } +} From 27d17bda669f1404268f291f97722553edf37b94 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 2 Apr 2018 08:37:03 +0200 Subject: [PATCH 047/159] Use global max function in Array.unzip --- src/Array/unzip.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Array/unzip.php b/src/Array/unzip.php index 60220c0..60c24e5 100644 --- a/src/Array/unzip.php +++ b/src/Array/unzip.php @@ -43,7 +43,7 @@ function unzip(array $array): array $length = 0; $array = \array_filter($array, function ($group) use (&$length) { if (\is_array($group)) { - $length = max(\count($group), $length); + $length = \max(\count($group), $length); return true; } From 5d6fc91d2344e736838f493f8705ddb3ed10d2e6 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 2 Apr 2018 08:37:29 +0200 Subject: [PATCH 048/159] Add Collection.orderBy function --- src/Collection/orderBy.php | 50 ++++++++++++++++++++++++++++++++ src/Collection/sortBy.php | 12 +++++--- src/internal/baseOrderBy.php | 33 +++++++++++++++++++++ src/internal/baseUnary.php | 19 ++++++++++++ src/internal/compareMultiple.php | 35 ++++++++++++++++++++++ tests/Collection/OrderByTest.php | 28 ++++++++++++++++++ 6 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 src/Collection/orderBy.php create mode 100644 src/internal/baseOrderBy.php create mode 100644 src/internal/baseUnary.php create mode 100644 src/internal/compareMultiple.php create mode 100644 tests/Collection/OrderByTest.php diff --git a/src/Collection/orderBy.php b/src/Collection/orderBy.php new file mode 100644 index 0000000..548ccb3 --- /dev/null +++ b/src/Collection/orderBy.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseOrderBy; + +/** + * This method is like `sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param array[]|callable[]|string[] $iteratee The iteratee(s) to sort by. + * @param string[] $orders The sort orders of `iteratees`. + * + * @return array the new sorted array. + * @example + * + * $users = [ + * ['user' => 'fred', 'age' => 48], + * ['user' => 'barney', 'age' => 34], + * ['user' => 'fred', 'age' => 40], + * ['user' => 'barney', 'age' => 36] + * ] + * + * // Sort by `user` in ascending order and by `age` in descending order. + * orderBy($users, ['user', 'age'], ['asc', 'desc']) + * // => [['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]] + * + */ +function orderBy(?iterable $collection, $iteratee, $orders): array +{ + if (null === $collection) { + return []; + } + + return baseOrderBy($collection, (array) $iteratee, (array) $orders); +} \ No newline at end of file diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index f860ad0..80fdc15 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -61,11 +61,15 @@ function sortBy($collection, $iteratees) $result = $collection; foreach ($iteratees as $callable) { - usort($result, function ($a, $b) use ($callable) { - $iteratee = baseIteratee($callable); + if (\is_callable($callable)) { + usort($result, $callable); + } else { + usort($result, function ($a, $b) use ($callable) { + $iteratee = baseIteratee($callable); - return $iteratee($a) <=> $iteratee($b); - }); + return $iteratee($a, $b) <=> $iteratee($b, $a); + }); + } } return $result; diff --git a/src/internal/baseOrderBy.php b/src/internal/baseOrderBy.php new file mode 100644 index 0000000..ca231d0 --- /dev/null +++ b/src/internal/baseOrderBy.php @@ -0,0 +1,33 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\map; +use function _\sortBy; + +function baseOrderBy(iterable $collection, array $iteratees, array $orders): array +{ + $index = -1; + $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); + + $result = map($collection, function ($value) use ($iteratees, &$index) { + $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { + return $iteratee($value); + }); + + return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; + }); + + return map(sortBy($result, function ($object, $other) use ($orders) { + return compareMultiple($object, $other, $orders); + }), 'value'); +} \ No newline at end of file diff --git a/src/internal/baseUnary.php b/src/internal/baseUnary.php new file mode 100644 index 0000000..d1aa978 --- /dev/null +++ b/src/internal/baseUnary.php @@ -0,0 +1,19 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function baseUnary($func) +{ + return function ($value) use ($func) { + return $func($value); + }; +} \ No newline at end of file diff --git a/src/internal/compareMultiple.php b/src/internal/compareMultiple.php new file mode 100644 index 0000000..257f633 --- /dev/null +++ b/src/internal/compareMultiple.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function compareMultiple($object, $other, $orders) +{ + $index = -1; + $objCriteria = $object['criteria']; + $othCriteria = $other['criteria']; + $length = \count($objCriteria); + $ordersLength = \count($orders); + + while (++$index < $length) { + $result = $objCriteria[$index] <=> $othCriteria[$index]; + if ($result) { + if ($index >= $ordersLength) { + return $result; + } + $order = $orders[$index]; + + return $result * ('desc' === $order ? -1 : 1); + } + } + + return $object['index'] - $other['index']; +} \ No newline at end of file diff --git a/tests/Collection/OrderByTest.php b/tests/Collection/OrderByTest.php new file mode 100644 index 0000000..35b577a --- /dev/null +++ b/tests/Collection/OrderByTest.php @@ -0,0 +1,28 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\orderBy; + +class OrderByTest extends TestCase +{ + public function testOrderBy() + { + $users = [ + ['user' => 'fred', 'age' => 48], + ['user' => 'barney', 'age' => 34], + ['user' => 'fred', 'age' => 40], + ['user' => 'barney', 'age' => 36], + ]; + + $this->assertSame([['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]], orderBy($users, ['user', 'age'], ['asc', 'desc'])); + } +} \ No newline at end of file From fe7325ec11770ac1bb2646c79345a6cde272ba21 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 2 Apr 2018 08:45:33 +0200 Subject: [PATCH 049/159] Add Collection.partition function --- src/Collection/partition.php | 47 ++++++++++++++++++++++++++++++ tests/Collection/PartitionTest.php | 37 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/Collection/partition.php create mode 100644 tests/Collection/PartitionTest.php diff --git a/src/Collection/partition.php b/src/Collection/partition.php new file mode 100644 index 0000000..70a0274 --- /dev/null +++ b/src/Collection/partition.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\createAggregator; + +/** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param callable $predicate The function invoked per iteration. + * + * @return array the array of grouped elements. + * @see groupBy, keyBy + * @example + * + * $users = [ + * ['user' => 'barney', 'age' => 36, 'active' => false], + * ['user' => 'fred', 'age' => 40, 'active' => true], + * ['user' => 'pebbles', 'age' => 1, 'active' => false] + * ]; + * + * partition($users, function($user) { return $user['active']; }) + * // => objects for [['fred'], ['barney', 'pebbles']] + */ +function partition(iterable $collection, $predicate = null): array +{ + return createAggregator(function ($result, $value, $key) { + $result[$key ? 0 : 1][] = $value; + + return $result; + }, function () { return [[], []]; })($collection, $predicate); +} \ No newline at end of file diff --git a/tests/Collection/PartitionTest.php b/tests/Collection/PartitionTest.php new file mode 100644 index 0000000..75a022b --- /dev/null +++ b/tests/Collection/PartitionTest.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\partition; + +class PartitionTest extends TestCase +{ + public function testPartition() + { + $users = [ + ['user' => 'barney', 'age' => 36, 'active' => false], + ['user' => 'fred', 'age' => 40, 'active' => true], + ['user' => 'pebbles', 'age' => 1, 'active' => false], + ]; + + $result = [ + [ + ['user' => 'fred', 'age' => 40, 'active' => true], + ], + [ + ['user' => 'barney', 'age' => 36, 'active' => false], + ['user' => 'pebbles', 'age' => 1, 'active' => false], + ], + ]; + + $this->assertSame($result, partition($users, function ($user) { return $user['active']; })); + } +} \ No newline at end of file From df6b6c68440291f634d15b6c27047ad1787b0518 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:10:51 +0200 Subject: [PATCH 050/159] Remove callable type-hint from groupBy --- src/Collection/groupBy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Collection/groupBy.php b/src/Collection/groupBy.php index 1e354c4..2a9602e 100644 --- a/src/Collection/groupBy.php +++ b/src/Collection/groupBy.php @@ -35,7 +35,7 @@ * // => ['3' => ['one', 'two'], '5' => ['three']] * */ -function groupBy(iterable $collection, callable $iteratee): array +function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { From 4789a5e502d50083e509c99635fedec630bf2d8a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:11:20 +0200 Subject: [PATCH 051/159] Add Collection.reduce function --- src/Collection/reduce.php | 71 +++++++++++++++++++++++++++++++++ tests/Collection/ReduceTest.php | 29 ++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/Collection/reduce.php create mode 100644 tests/Collection/ReduceTest.php diff --git a/src/Collection/reduce.php b/src/Collection/reduce.php new file mode 100644 index 0000000..9b7b179 --- /dev/null +++ b/src/Collection/reduce.php @@ -0,0 +1,71 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `reduce`, `reduceRight`, and `transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param mixed $iteratee The function invoked per iteration. + * @param mixed $accumulator The initial value. + * + * @return mixed Returns the accumulated value. + * + * @example + * + * reduce([1, 2], function($sum, $n) { return $sum + $n; }, 0) + * // => 3 + * + * reduce(['a' => 1, 'b' => 2, 'c' => 1], function ($result, $value, $key) { + * if (!isset($result[$value])) { + * $result[$value] = []; + * } + * $result[$value][] = $key; + * + * return $result; + * }, []) + * // => ['1' => ['a', 'c'], '2' => ['b']] (iteration order is not guaranteed) + * + */ +function reduce(iterable $collection, $iteratee, $accumulator = null) +{ + $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { + $length = count($array); + + if ($initAccum && $length) { + $accumulator = current($array); + } + foreach ($array as $key => $value) { + $accumulator = $iteratee($accumulator, $value, $key, $array); + } + + return $accumulator; + }; + + return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); +} \ No newline at end of file diff --git a/tests/Collection/ReduceTest.php b/tests/Collection/ReduceTest.php new file mode 100644 index 0000000..b987bb8 --- /dev/null +++ b/tests/Collection/ReduceTest.php @@ -0,0 +1,29 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\reduce; + +class ReduceTest extends TestCase +{ + public function testReduce() + { + $this->assertSame(3, reduce([1, 2], function ($sum, $n) { return $sum + $n; }, 0)); + $this->assertSame(['1' => ['a', 'c'], '2' => ['b']], reduce(['a' => 1, 'b' => 2, 'c' => 1], function ($result, $value, $key) { + if (!isset($result[$value])) { + $result[$value] = []; + } + $result[$value][] = $key; + + return $result; + }, [])); + } +} \ No newline at end of file From fe6f8a25054b7fafb256967d400a2df14db29708 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:18:26 +0200 Subject: [PATCH 052/159] Add Collection.reduceRight function --- src/Collection/reduceRight.php | 39 ++++++++++++++++++++++++++++ src/internal/baseReduce.php | 27 +++++++++++++++++++ tests/Collection/ReduceRightTest.php | 22 ++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/Collection/reduceRight.php create mode 100644 src/internal/baseReduce.php create mode 100644 tests/Collection/ReduceRightTest.php diff --git a/src/Collection/reduceRight.php b/src/Collection/reduceRight.php new file mode 100644 index 0000000..14a9991 --- /dev/null +++ b/src/Collection/reduceRight.php @@ -0,0 +1,39 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; +use function _\internal\baseReduce; + +/** + * This method is like `reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param mixed $iteratee The function invoked per iteration. + * @param mixed $accumulator The initial value. + * + * @return mixed Returns the accumulated value. + * + * @example + * + * $array = [[0, 1], [2, 3], [4, 5]]; + * + * reduceRight(array, (flattened, other) => flattened.concat(other), []) + * // => [4, 5, 2, 3, 0, 1] + */ +function reduceRight(iterable $collection, $iteratee, $accumulator = null) +{ + return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); +} \ No newline at end of file diff --git a/src/internal/baseReduce.php b/src/internal/baseReduce.php new file mode 100644 index 0000000..5e7b1d1 --- /dev/null +++ b/src/internal/baseReduce.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) +{ + $length = \count($array); + + if ($initAccum && $length) { + $accumulator = \current($array); + } + + foreach ($array as $key => $value) { + $accumulator = $iteratee($accumulator, $value, $key, $array); + } + + return $accumulator; +} \ No newline at end of file diff --git a/tests/Collection/ReduceRightTest.php b/tests/Collection/ReduceRightTest.php new file mode 100644 index 0000000..2863529 --- /dev/null +++ b/tests/Collection/ReduceRightTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\reduceRight; + +class ReduceRightTest extends TestCase +{ + public function testReduceRight() + { + $array = [[0, 1], [2, 3], [4, 5]]; + $this->assertSame([4, 5, 2, 3, 0, 1], reduceRight($array, function ($flattened, $other) { return \array_merge($flattened, $other); }, [])); + } +} \ No newline at end of file From cb6557e2c710995c8575488a1ee1910e7f690c60 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:27:35 +0200 Subject: [PATCH 053/159] Add Function.negate function --- src/Function/negate.php | 38 +++++++++++++++++++++++++++++++++++ tests/Function/NegateTest.php | 26 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/Function/negate.php create mode 100644 tests/Function/NegateTest.php diff --git a/src/Function/negate.php b/src/Function/negate.php new file mode 100644 index 0000000..90352d5 --- /dev/null +++ b/src/Function/negate.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +/** + * Creates a function that negates the result of the predicate `func` + * + * @category Function + * + * @param callable $predicate The predicate to negate. + * + * @return callable Returns the new negated function. + * + * @example + * + * function isEven($n) { + * return $n % 2 == 0; + * } + * + * filter([1, 2, 3, 4, 5, 6], negate($isEven)); + * // => [1, 3, 5] + */ + +function negate(callable $predicate): callable +{ + return function () use ($predicate) { + return !$predicate(...\func_get_args()); + }; +} \ No newline at end of file diff --git a/tests/Function/NegateTest.php b/tests/Function/NegateTest.php new file mode 100644 index 0000000..2e03b0f --- /dev/null +++ b/tests/Function/NegateTest.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\filter; +use function _\negate; + +class NegateTest extends TestCase +{ + public function testNegate() + { + $isEven = function ($n) { + return $n % 2 == 0; + }; + + $this->assertSame([1, 3, 5], filter([1, 2, 3, 4, 5, 6], negate($isEven))); + } +} From 847c716f24e0ad3eeacdff0977c965e3721c3bd6 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:30:11 +0200 Subject: [PATCH 054/159] Add Collection.reject function --- src/Collection/reject.php | 41 +++++++++++++++++++++++++++++++++ tests/Collection/RejectTest.php | 26 +++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/Collection/reject.php create mode 100644 tests/Collection/RejectTest.php diff --git a/src/Collection/reject.php b/src/Collection/reject.php new file mode 100644 index 0000000..eb70956 --- /dev/null +++ b/src/Collection/reject.php @@ -0,0 +1,41 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * The opposite of `filter` this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param callable $predicate The function invoked per iteration. + * + * @return array the new filtered array. + * + * @example + * + * $users = [ + * ['user' => 'barney', 'active' => true], + * ['user' => 'fred', 'active' => false] + * ] + * + * reject($users, 'active') + * // => objects for ['fred'] + * + */ +function reject(iterable $collection, $predicate = null): array +{ + return filter($collection, negate(baseIteratee($predicate))); +} \ No newline at end of file diff --git a/tests/Collection/RejectTest.php b/tests/Collection/RejectTest.php new file mode 100644 index 0000000..e340c37 --- /dev/null +++ b/tests/Collection/RejectTest.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\reject; + +class RejectTest extends TestCase +{ + public function testReject() + { + $users = [ + ['user' => 'barney', 'active' => true], + ['user' => 'fred', 'active' => false], + ]; + + $this->assertSame([['user' => 'fred', 'active' => false]], reject($users, 'active')); + } +} \ No newline at end of file From 33033e415de875cdcf5411b4c8df4571e0d69f7b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:33:34 +0200 Subject: [PATCH 055/159] Add Collection.sample function --- src/Collection/sample.php | 31 +++++++++++++++++++++++++++++++ tests/Collection/SampleTest.php | 21 +++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/Collection/sample.php create mode 100644 tests/Collection/SampleTest.php diff --git a/src/Collection/sample.php b/src/Collection/sample.php new file mode 100644 index 0000000..dc062fd --- /dev/null +++ b/src/Collection/sample.php @@ -0,0 +1,31 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Gets a random element from `array`. + * + * @category Array + * + * @param array $array The array to sample. + * + * @return mixed Returns the random element. + * @example + * + * sample([1, 2, 3, 4]) + * // => 2 + * + */ +function sample(array $array) +{ + return $array[\array_rand($array, 1)]; +} \ No newline at end of file diff --git a/tests/Collection/SampleTest.php b/tests/Collection/SampleTest.php new file mode 100644 index 0000000..5358837 --- /dev/null +++ b/tests/Collection/SampleTest.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\sample; +use PHPUnit\Framework\TestCase; + +class SampleTest extends TestCase +{ + public function testSample() + { + $this->assertContains(sample([1, 2, 3, 4]), [1, 2, 3, 4]); + } +} \ No newline at end of file From 5fcaf9b42e61c9b28fa162c3904117ba0ac14a51 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:43:48 +0200 Subject: [PATCH 056/159] Add Collection.sampleSize function --- src/Collection/sampleSize.php | 42 +++++++++++++++++++++++++++++ tests/Collection/SampleSizeTest.php | 25 +++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/Collection/sampleSize.php create mode 100644 tests/Collection/SampleSizeTest.php diff --git a/src/Collection/sampleSize.php b/src/Collection/sampleSize.php new file mode 100644 index 0000000..521b7a1 --- /dev/null +++ b/src/Collection/sampleSize.php @@ -0,0 +1,42 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Gets `n` random elements at unique keys from `array` up to the + * size of `array`. + * + * @category Array + * + * @param array $array The array to sample. + * @param int $n The number of elements to sample. + * + * @return array the random elements. + * @example + * + * sampleSize([1, 2, 3], 2) + * // => [3, 1] + * + * sampleSize([1, 2, 3], 4) + * // => [2, 3, 1] + */ +function sampleSize(array $array, int $n = 1): array +{ + $result = []; + $count = \count($array); + + foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { + $result[] = $array[$index]; + } + + return $result; +} \ No newline at end of file diff --git a/tests/Collection/SampleSizeTest.php b/tests/Collection/SampleSizeTest.php new file mode 100644 index 0000000..128d581 --- /dev/null +++ b/tests/Collection/SampleSizeTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\sampleSize; + +class SampleSizeTest extends TestCase +{ + public function testSampleSize() + { + $this->assertCount(2, sampleSize([1, 2, 3], 2)); + $this->assertSame([], \array_diff(sampleSize([1, 2, 3], 2), [1, 2, 3])); + + $this->assertCount(3, sampleSize([1, 2, 3], 4)); + $this->assertSame([1, 2, 3], sampleSize([1, 2, 3], 4)); + } +} \ No newline at end of file From 83e92917e1ea58c7edfbaa5f51c30acd8cf5ad73 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:46:46 +0200 Subject: [PATCH 057/159] Add Collection.shuffle function --- src/Collection/shuffle.php | 32 ++++++++++++++++++++++++++++++++ tests/Collection/ShuffleTest.php | 22 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Collection/shuffle.php create mode 100644 tests/Collection/ShuffleTest.php diff --git a/src/Collection/shuffle.php b/src/Collection/shuffle.php new file mode 100644 index 0000000..b731701 --- /dev/null +++ b/src/Collection/shuffle.php @@ -0,0 +1,32 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates an array of shuffled values + * + * @category Array + * + * @param array $array The array to shuffle. + * + * @return array the new shuffled array. + * @example + * + * shuffle([1, 2, 3, 4]) + * // => [4, 1, 3, 2] + */ +function shuffle(array $array = []): array +{ + \shuffle($array); + + return $array; +} \ No newline at end of file diff --git a/tests/Collection/ShuffleTest.php b/tests/Collection/ShuffleTest.php new file mode 100644 index 0000000..dc3e0c6 --- /dev/null +++ b/tests/Collection/ShuffleTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\shuffle; +use PHPUnit\Framework\TestCase; + +class ShuffleTest extends TestCase +{ + public function testShuffle() + { + $this->assertNotSame([1, 2, 3, 4], shuffle([1, 2, 3, 4])); + $this->assertSame([1, 2, 3, 4], \array_values(shuffle([1, 2, 3, 4]))); + } +} \ No newline at end of file From 1109a4766c50976859daece43d25df1dc8e181ce Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 09:54:25 +0200 Subject: [PATCH 058/159] Add Collection.size function --- src/Collection/size.php | 53 +++++++++++++++++++++++++++++++++++ tests/Collection/SizeTest.php | 38 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/Collection/size.php create mode 100644 tests/Collection/SizeTest.php diff --git a/src/Collection/size.php b/src/Collection/size.php new file mode 100644 index 0000000..0fc29e3 --- /dev/null +++ b/src/Collection/size.php @@ -0,0 +1,53 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Gets the size of `collection` by returning its length for array + * values or the number of public properties for objects. + * + * @category Collection + * + * @param array|object|string $collection The collection to inspect. + * + * @return int Returns the collection size. + * @example + * + * size([1, 2, 3]); + * // => 3 + * + * size(new class { public $a = 1; public $b = 2; private $c = 3; }); + * // => 2 + * + * size('pebbles'); + * // => 7 + */ +function size($collection): int +{ + if (\is_string($collection)) { + return \strlen($collection); + } + + if (\is_array($collection) || $collection instanceof \Countable) { + return \count($collection); + } + + if ($collection instanceof \Traversable) { + return \count(\iterator_to_array($collection)); + } + + if (\is_object($collection)) { + return \count(\get_object_vars($collection)); + } + + return 0; +} \ No newline at end of file diff --git a/tests/Collection/SizeTest.php b/tests/Collection/SizeTest.php new file mode 100644 index 0000000..9ec5eb6 --- /dev/null +++ b/tests/Collection/SizeTest.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\size; + +class SizeTest extends TestCase +{ + public function testSize() + { + $this->assertSame(3, size([1, 2, 3])); + $this->assertSame(2, size(new class + { + public $a = 1; + + public $b = 2; + + private $c = 3; + })); + + $this->assertSame(12, size(new class implements \Countable + { + public function count() { return 12; } + })); + + $this->assertSame(4, size(new \ArrayIterator([1, 2, 3, 4]))); + + $this->assertSame(7, size('pebbles')); + } +} \ No newline at end of file From 9e3684b3be4d3e01ed4611e7b936b994e8f41dc7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 10:04:01 +0200 Subject: [PATCH 059/159] Add Collection.some function --- src/Collection/every.php | 10 +++--- src/Collection/some.php | 61 +++++++++++++++++++++++++++++++++++ tests/Collection/SomeTest.php | 29 +++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src/Collection/some.php create mode 100644 tests/Collection/SomeTest.php diff --git a/src/Collection/every.php b/src/Collection/every.php index 806e11b..a2d261a 100644 --- a/src/Collection/every.php +++ b/src/Collection/every.php @@ -25,8 +25,8 @@ * * @category Array * - * @param array $array The array to iterate over. - * @param callable $predicate The function invoked per iteration. + * @param iterable $collection The array to iterate over. + * @param callable $predicate The function invoked per iteration. * * @return bool `true` if all elements pass the predicate check, else `false`. * @example @@ -53,12 +53,12 @@ * * */ -function every(array $array, $predicate): bool +function every(iterable $collection, $predicate): bool { $iteratee = baseIteratee($predicate); - foreach ($array as $key => $value) { - if (!$iteratee($value, $key, $array)) { + foreach ($collection as $key => $value) { + if (!$iteratee($value, $key, $collection)) { return false; } } diff --git a/src/Collection/some.php b/src/Collection/some.php new file mode 100644 index 0000000..4e69e79 --- /dev/null +++ b/src/Collection/some.php @@ -0,0 +1,61 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseIteratee; + +/** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @category Collection + * + * @param iterable $collection The collection to iterate over. + * @param callable|string|array $predicate The function invoked per iteration. + * + * @return boolean Returns `true` if any element passes the predicate check, else `false`. + * @example + * + * some([null, 0, 'yes', false], , function ($value) { return \is_bool($value); })); + * // => true + * + * $users = [ + * ['user' => 'barney', 'active' => true], + * ['user' => 'fred', 'active' => false] + * ]; + * + * // The `matches` iteratee shorthand. + * some($users, ['user' => 'barney', 'active' => false ]); + * // => false + * + * // The `matchesProperty` iteratee shorthand. + * some($users, ['active', false]); + * // => true + * + * // The `property` iteratee shorthand. + * some($users, 'active'); + * // => true + * + */ +function some(iterable $collection, $predicate = null): bool +{ + $iteratee = baseIteratee($predicate); + + foreach ($collection as $key => $value) { + if ($iteratee($value, $key, $collection)) { + return true; + } + } + + return false; +} \ No newline at end of file diff --git a/tests/Collection/SomeTest.php b/tests/Collection/SomeTest.php new file mode 100644 index 0000000..bead49c --- /dev/null +++ b/tests/Collection/SomeTest.php @@ -0,0 +1,29 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\some; + +class SomeTest extends TestCase +{ + public function testSome() + { + $users = [ + ['user' => 'barney', 'active' => true], + ['user' => 'fred', 'active' => false], + ]; + + $this->assertTrue(some([null, 0, 'yes', false], function ($value) { return \is_bool($value); })); + $this->assertFalse(some($users, ['user' => 'barney', 'active' => false])); + $this->assertTrue(some($users, ['active', false])); + $this->assertTrue(some($users, 'active')); + } +} \ No newline at end of file From c81319ad4167df6019505ac71960a547072498ca Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 10:05:24 +0200 Subject: [PATCH 060/159] Fix Collection.shuffle test --- tests/Collection/ShuffleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Collection/ShuffleTest.php b/tests/Collection/ShuffleTest.php index dc3e0c6..18890b6 100644 --- a/tests/Collection/ShuffleTest.php +++ b/tests/Collection/ShuffleTest.php @@ -17,6 +17,6 @@ class ShuffleTest extends TestCase public function testShuffle() { $this->assertNotSame([1, 2, 3, 4], shuffle([1, 2, 3, 4])); - $this->assertSame([1, 2, 3, 4], \array_values(shuffle([1, 2, 3, 4]))); + $this->assertSame([], \array_diff([1, 2, 3, 4], shuffle([1, 2, 3, 4]))); } } \ No newline at end of file From dcc46d29845a29a2c43b3d6320fcb93a938bfc63 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 10:09:17 +0200 Subject: [PATCH 061/159] Remove custom callback in Collection.sortBy function --- src/Collection/sortBy.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index 80fdc15..881bab4 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -61,15 +61,11 @@ function sortBy($collection, $iteratees) $result = $collection; foreach ($iteratees as $callable) { - if (\is_callable($callable)) { - usort($result, $callable); - } else { - usort($result, function ($a, $b) use ($callable) { - $iteratee = baseIteratee($callable); + usort($result, function ($a, $b) use ($callable) { + $iteratee = baseIteratee($callable); - return $iteratee($a, $b) <=> $iteratee($b, $a); - }); - } + return $iteratee($a, $b) <=> $iteratee($b, $a); + }); } return $result; From a9e88aff972486bf59d2090da0179da19dccfb22 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 10:10:09 +0200 Subject: [PATCH 062/159] Remove @see annotations --- src/Collection/find.php | 1 - src/Collection/partition.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Collection/find.php b/src/Collection/find.php index c53785a..b1be2a8 100644 --- a/src/Collection/find.php +++ b/src/Collection/find.php @@ -26,7 +26,6 @@ * * @return mixed Returns the matched element, else `null`. * - * @see findIndex, findKey, findLast, findLastIndex, findLastKey * @example * * $users = [ diff --git a/src/Collection/partition.php b/src/Collection/partition.php index 70a0274..7c5764d 100644 --- a/src/Collection/partition.php +++ b/src/Collection/partition.php @@ -25,7 +25,6 @@ * @param callable $predicate The function invoked per iteration. * * @return array the array of grouped elements. - * @see groupBy, keyBy * @example * * $users = [ From af389264ce2883ee5756fd5d971b4ea094437e6a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 9 Apr 2018 10:10:40 +0200 Subject: [PATCH 063/159] Update README with new functions --- README.md | 1081 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 977 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index d2e4235..d61da20 100644 --- a/README.md +++ b/README.md @@ -374,6 +374,57 @@ $users = [ dropWhile($users, function($user) { return $user['active']; } ) // => objects for ['pebbles'] +``` +### every + +Checks if `predicate` returns truthy for **all** elements of `array`. + +Iteration is stopped once `predicate` returns falsey. The predicate is +invoked with three arguments: (value, index, array). + +**Note:** This method returns `true` for +[empty arrays](https://en.wikipedia.org/wiki/Empty_set) because +[everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of +elements of empty arrays. + +**Arguments:** + +@param iterable $collection The array to iterate over. + +@param callable $predicate The function invoked per iteration. + + + +**Return:** + +@return bool `true` if all elements pass the predicate check, else `false`. + +Example: +```php + false + +$users = [ + ['user' => 'barney', 'age' => 36, 'active' => false], + ['user' => 'fred', 'age' => 40, 'active' => false], +]; + +// The `matches` iteratee shorthand. +$this->assertFalse(every($users, ['user' => 'barney', 'active' => false])); +// false + +// The `matchesProperty` iteratee shorthand. +$this->assertTrue(every($users, ['active', false])); +// true + +// The `property` iteratee shorthand. +$this->assertFalse(every($users, 'active')); +//false + + ``` ### findIndex @@ -1035,6 +1086,83 @@ var_dump($array) var_dump($evens) // => [2, 4] ``` +### sample + +Gets a random element from `array`. + + + +**Arguments:** + +@param array $array The array to sample. + + + +**Return:** + +@return mixed Returns the random element. + +Example: +```php + 2 + +``` +### sampleSize + +Gets `n` random elements at unique keys from `array` up to the +size of `array`. + + + +**Arguments:** + +@param array $array The array to sample. + +@param int $n The number of elements to sample. + + + +**Return:** + +@return array the random elements. + +Example: +```php + [3, 1] + +sampleSize([1, 2, 3], 4) +// => [2, 3, 1] +``` +### shuffle + +Creates an array of shuffled values + + + +**Arguments:** + +@param array $array The array to shuffle. + + + +**Return:** + +@return array the new shuffled array. + +Example: +```php + [4, 1, 3, 2] +``` ### slice Creates a slice of `array` from `start` up to, but not including, `end`. @@ -1628,6 +1756,40 @@ zipWith([1, 2], [10, 20], [100, 200], function($a, $b, $c) { return $a + $b + $c ``` ## Collection +### countBy + +Creates an array composed of keys generated from the results of running +each element of `collection` through `iteratee`. The corresponding value of +each key is the number of times the key was returned by `iteratee`. The +iteratee is invoked with one argument: (value). + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param callable $iteratee The iteratee to transform keys. + + + +**Return:** + +@return array Returns the composed aggregate object. + +Example: +```php + ['6' => 2, '4' => 1] + +// The `property` iteratee shorthand. +countBy(['one', 'two', 'three'], 'strlen'); +// => ['3' => 2, '5' => 1] + +``` ### each Iterates over elements of `collection` and invokes `iteratee` for each element. @@ -1663,219 +1825,868 @@ each((object) ['a' => 1, 'b' => 2], function ($value, $key) { echo $key; }); // => Echoes 'a' then 'b' (iteration order is not guaranteed). ``` -### map +### eachRight -Creates an array of values by running each element in `collection` through -`iteratee`. The iteratee is invoked with three arguments: -(value, index|key, collection). +This method is like `each` except that it iterates over elements of +`collection` from right to left. -Many lodash-php methods are guarded to work as iteratees for methods like -`_::every`, `_::filter`, `_::map`, `_::mapValues`, `_::reject`, and `_::some`. -The guarded methods are: -`ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, -`fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, -`sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, -`template`, `trim`, `trimEnd`, `trimStart`, and `words` **Arguments:** @param array|object $collection The collection to iterate over. -@param callable|string|array $iteratee The function invoked per iteration. +@param callable $iteratee The function invoked per iteration. **Return:** -@return array Returns the new mapped array. +@return array|object Returns `collection`. Example: ```php Echoes `2` then `1`. -map([4, 8], $square); -// => [16, 64] +``` +### filter -map((object) ['a' => 4, 'b' => 8], $square); -// => [16, 64] (iteration order is not guaranteed) +Iterates over elements of `array`, returning an array of all elements +`predicate` returns truthy for. The predicate is invoked with three +arguments: (value, index, array). + +**Note:** Unlike `remove`, this method returns a new array. + +**Arguments:** + +@param iterable $array The array to iterate over. + +@param callable $predicate The function invoked per iteration. + + + +**Return:** + +@return array the new filtered array. + +Example: +```php + 'barney' ], - [ 'user' => 'fred' ] + [ 'user' => 'barney', 'age' => 36, 'active' => true], + [ 'user' => 'fred', 'age' => 40, 'active' => false] ]; +filter($users, function($o) { return !$o['active']; }); +// => objects for ['fred'] + +// The `matches` iteratee shorthand. +filter($users, ['age' => 36, 'active' => true]); +// => objects for ['barney'] + +// The `matchesProperty` iteratee shorthand. +filter($users, ['active', false]); +// => objects for ['fred'] + // The `property` iteratee shorthand. -map($users, 'user'); -// => ['barney', 'fred'] +filter($users, 'active'); +// => objects for ['barney'] ``` -### sortBy +### find -Creates an array of elements, sorted in ascending order by the results of -running each element in a collection through each iteratee. This method -performs a stable sort, that is, it preserves the original sort order of -equal elements. The iteratees are invoked with one argument: (value). +Iterates over elements of `collection`, returning the first element +`predicate` returns truthy for. The predicate is invoked with three +arguments: (value, index|key, collection). **Arguments:** -@param array|object $collection The collection to iterate over. +@param iterable $collection The collection to inspect. -@param callable|callable[] $iteratees The iteratees to sort by. +@param callable $predicate The function invoked per iteration. + +@param int $fromIndex The index to search from. **Return:** -@return array Returns the new sorted array. +@return mixed Returns the matched element, else `null`. Example: ```php 'fred', 'age' => 48 ], - [ 'user' => 'barney', 'age' => 36 ], - [ 'user' => 'fred', 'age' => 40 ], - [ 'user' => 'barney', 'age' => 34 ], + ['user' => 'barney', 'age' => 36, 'active' => true], + ['user' => 'fred', 'age' => 40, 'active' => false], + ['user' => 'pebbles', 'age' => 1, 'active' => true] ]; -sortBy($users, [function($o) { return $o['user']; }]); -// => [['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]] +find($users, function($o) { return $o['age'] < 40; }); +// => object for 'barney' -sortBy($users, ['user', 'age']); -// => [['user' => 'barney', 'age' => 34], ['user' => 'barney', 'age' => 36], ['user' => 'fred', 'age' => 40], ['user' => 'fred', 'age' => 48]] +// The `matches` iteratee shorthand. +find($users, ['age' => 1, 'active' => true]); +// => object for 'pebbles' -``` -## Date +// The `matchesProperty` iteratee shorthand. +find($users, ['active', false]); +// => object for 'fred' -### now +// The `property` iteratee shorthand. +find($users, 'active'); +// => object for 'barney' -Gets the timestamp of the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). +``` +### findLast + +This method is like `find` except that it iterates over elements of +`collection` from right to left. **Arguments:** +@param iterable $collection The collection to inspect. + +@param callable $predicate The function invoked per iteration. + +@param int $fromIndex The index to search from. + **Return:** -@return int Returns the timestamp. +@return mixed Returns the matched element, else `undefined`. Example: ```php 1511180325735 + use function _\findLast; +findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; }) +// => 3 + ``` -## Function +### flatMap -### memoize +Creates a flattened array of values by running each element in `collection` +through `iteratee` and flattening the mapped results. The iteratee is invoked +with three arguments: (value, index|key, collection). -Creates a function that memoizes the result of `func`. If `resolver` is -provided, it determines the cache key for storing the result based on the -arguments provided to the memoized function. By default, the first argument -provided to the memoized function is used as the map cache key -**Note:** The cache is exposed as the `cache` property on the memoized -function. Its creation may be customized by replacing the `_.memoize.Cache` -constructor with one whose instances implement the -[`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) -method interface of `clear`, `delete`, `get`, `has`, and `set`. **Arguments:** -@param callable $func The function to have its output memoized. +@param iterable $ collection The collection to iterate over. -@param callable $resolver The function to resolve the cache key. +@param callable $iteratee The function invoked per iteration. **Return:** -@return callable Returns the new memoized function. +@return array the new flattened array. Example: ```php 1, 'b' => 2]; -$other = ['c' => 3, 'd' => 4]; + use function _\flatMap; -$values = memoize('_\values'); -$values($object); -// => [1, 2] - -$values($other); -// => [3, 4] - -$object['a'] = 2; -$values($object); -// => [1, 2] +function duplicate($n) { + return [$n, $n] +} -// Modify the result cache. -$values->cache->set($object, ['a', 'b']); -$values($object); -// => ['a', 'b'] +flatMap([1, 2], 'duplicate') +// => [1, 1, 2, 2] ``` -## Lang +### flatMapDeep -### eq - -Performs a comparison between two values to determine if they are equivalent. +This method is like `flatMap` except that it recursively flattens the +mapped results. **Arguments:** -@param mixed $value The value to compare. +@param iterable $ collection The collection to iterate over. -@param mixed $other The other value to compare. +@param callable $iteratee The function invoked per iteration. **Return:** -@return bool Returns `true` if the values are equivalent, else `false`. +@return array Returns the new flattened array. Example: ```php 1]; -$other = (object) ['a' => 1]; +function duplicate($n) { + return [[[$n, $n]]]; +} -eq($object, $object); -// => true +flatMapDeep([1, 2], 'duplicate'); +// => [1, 1, 2, 2] -eq($object, $other); -// => false +``` +### flatMapDepth -eq('a', 'a'); -// => true +This method is like `flatMap` except that it recursively flattens the +mapped results up to `depth` times. -eq(['a'], (object) ['a']); -// => false -eq(INF, INF); -// => true -``` +**Arguments:** + +@param iterable $ collection The collection to iterate over. + +@param callable $iteratee The function invoked per iteration. + +@param int $depth The maximum recursion depth. + + + +**Return:** + +@return array the new flattened array. + +Example: +```php + [[1, 1], [2, 2]] + +``` +### groupBy + +Creates an array composed of keys generated from the results of running +each element of `collection` through `iteratee`. The order of grouped values +is determined by the order they occur in `collection`. The corresponding +value of each key is an array of elements responsible for generating the +key. The iteratee is invoked with one argument: (value). + + + +**Arguments:** + +@param iterable $ collection The collection to iterate over. + +@param callable $iteratee The iteratee to transform keys. + + + +**Return:** + +@return array Returns the composed aggregate object. + +Example: +```php + ['6' => [6.1, 6.3], '4' => [4.2]] + +groupBy(['one', 'two', 'three'], 'strlen'); +// => ['3' => ['one', 'two'], '5' => ['three']] + +``` +### invokeMap + +Invokes the method at `path` of each element in `collection`, returning +an array of the results of each invoked method. Any additional arguments +are provided to each invoked method. If `path` is a function, it's invoked +for, and `this` bound to, each element in `collection`. + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param array|callable|string $path The path of the method to invoke or the function invoked per iteration. + +@param array $args The arguments to invoke each method with. + + + +**Return:** + +@return array the array of results. + +Example: +```php + [[1, 5, 7], [1, 2, 3]] + +invokeMap([123, 456], 'str_split') +// => [['1', '2', '3'], ['4', '5', '6']] + +``` +### keyBy + +Creates an object composed of keys generated from the results of running +each element of `collection` through `iteratee`. The corresponding value of +each key is the last element responsible for generating the key. The +iteratee is invoked with one argument: (value). + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param callable $iteratee The iteratee to transform keys. + + + +**Return:** + +@return array the composed aggregate object. + +Example: +```php + 'left', 'code' => 97], + ['direction' => 'right', 'code' => 100], +]; + +keyBy($array, function ($o) { return \chr($o['code']); }) +// => ['a' => ['direction' => 'left', 'code' => 97], 'd' => ['direction' => 'right', 'code' => 100]] + +keyBy($array, 'direction'); +// => ['left' => ['direction' => 'left', 'code' => 97], 'right' => ['direction' => 'right', 'code' => 100]] + +``` +### map + +Creates an array of values by running each element in `collection` through +`iteratee`. The iteratee is invoked with three arguments: +(value, index|key, collection). + +Many lodash-php methods are guarded to work as iteratees for methods like +`_::every`, `_::filter`, `_::map`, `_::mapValues`, `_::reject`, and `_::some`. + +The guarded methods are: +`ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, +`fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, +`sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, +`template`, `trim`, `trimEnd`, `trimStart`, and `words` + +**Arguments:** + +@param array|object $collection The collection to iterate over. + +@param callable|string|array $iteratee The function invoked per iteration. + + + +**Return:** + +@return array Returns the new mapped array. + +Example: +```php + [16, 64] + +map((object) ['a' => 4, 'b' => 8], $square); +// => [16, 64] (iteration order is not guaranteed) + +$users = [ + [ 'user' => 'barney' ], + [ 'user' => 'fred' ] +]; + +// The `property` iteratee shorthand. +map($users, 'user'); +// => ['barney', 'fred'] + +``` +### orderBy + +This method is like `sortBy` except that it allows specifying the sort +orders of the iteratees to sort by. If `orders` is unspecified, all values +are sorted in ascending order. Otherwise, specify an order of "desc" for +descending or "asc" for ascending sort order of corresponding values. + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param array[]|callable[]|string[] $iteratee The iteratee(s) to sort by. + +@param string[] $orders The sort orders of `iteratees`. + + + +**Return:** + +@return array the new sorted array. + +Example: +```php + 'fred', 'age' => 48], + ['user' => 'barney', 'age' => 34], + ['user' => 'fred', 'age' => 40], + ['user' => 'barney', 'age' => 36] +] + +// Sort by `user` in ascending order and by `age` in descending order. +orderBy($users, ['user', 'age'], ['asc', 'desc']) +// => [['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]] + +``` +### partition + +Creates an array of elements split into two groups, the first of which +contains elements `predicate` returns truthy for, the second of which +contains elements `predicate` returns falsey for. The predicate is +invoked with one argument: (value). + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param callable $predicate The function invoked per iteration. + + + +**Return:** + +@return array the array of grouped elements. + +Example: +```php + 'barney', 'age' => 36, 'active' => false], + ['user' => 'fred', 'age' => 40, 'active' => true], + ['user' => 'pebbles', 'age' => 1, 'active' => false] +]; + +partition($users, function($user) { return $user['active']; }) +// => objects for [['fred'], ['barney', 'pebbles']] +``` +### reduce + +Reduces `collection` to a value which is the accumulated result of running +each element in `collection` thru `iteratee`, where each successive +invocation is supplied the return value of the previous. If `accumulator` +is not given, the first element of `collection` is used as the initial +value. The iteratee is invoked with four arguments: +(accumulator, value, index|key, collection). + +Many lodash methods are guarded to work as iteratees for methods like +`reduce`, `reduceRight`, and `transform`. + +The guarded methods are: +`assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, +and `sortBy` + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param mixed $iteratee The function invoked per iteration. + +@param mixed $accumulator The initial value. + + + +**Return:** + +@return mixed Returns the accumulated value. + +Example: +```php + 3 + +reduce(['a' => 1, 'b' => 2, 'c' => 1], function ($result, $value, $key) { + if (!isset($result[$value])) { + $result[$value] = []; + } + $result[$value][] = $key; + + return $result; + }, []) +// => ['1' => ['a', 'c'], '2' => ['b']] (iteration order is not guaranteed) + +``` +### reduceRight + +This method is like `reduce` except that it iterates over elements of +`collection` from right to left. + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param mixed $iteratee The function invoked per iteration. + +@param mixed $accumulator The initial value. + + + +**Return:** + +@return mixed Returns the accumulated value. + +Example: +```php + flattened.concat(other), []) +// => [4, 5, 2, 3, 0, 1] +``` +### reject + +The opposite of `filter` this method returns the elements of `collection` +that `predicate` does **not** return truthy for. + + + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param callable $predicate The function invoked per iteration. + + + +**Return:** + +@return array the new filtered array. + +Example: +```php + 'barney', 'active' => true], + ['user' => 'fred', 'active' => false] +] + +reject($users, 'active') +// => objects for ['fred'] + +``` +### size + +Gets the size of `collection` by returning its length for array +values or the number of public properties for objects. + + + +**Arguments:** + +@param array|object|string $collection The collection to inspect. + + + +**Return:** + +@return int Returns the collection size. + +Example: +```php + 3 + +size(new class { public $a = 1; public $b = 2; private $c = 3; }); +// => 2 + +size('pebbles'); +// => 7 +``` +### some + +Checks if `predicate` returns truthy for **any** element of `collection`. + +Iteration is stopped once `predicate` returns truthy. The predicate is +invoked with three arguments: (value, index|key, collection). + +**Arguments:** + +@param iterable $collection The collection to iterate over. + +@param callable|string|array $predicate The function invoked per iteration. + + + +**Return:** + +@return bool Returns `true` if any element passes the predicate check, else `false`. + +Example: +```php + true + +$users = [ + ['user' => 'barney', 'active' => true], + ['user' => 'fred', 'active' => false] +]; + +// The `matches` iteratee shorthand. +some($users, ['user' => 'barney', 'active' => false ]); +// => false + +// The `matchesProperty` iteratee shorthand. +some($users, ['active', false]); +// => true + +// The `property` iteratee shorthand. +some($users, 'active'); +// => true + +``` +### sortBy + +Creates an array of elements, sorted in ascending order by the results of +running each element in a collection through each iteratee. This method +performs a stable sort, that is, it preserves the original sort order of +equal elements. The iteratees are invoked with one argument: (value). + + + +**Arguments:** + +@param array|object $collection The collection to iterate over. + +@param callable|callable[] $iteratees The iteratees to sort by. + + + +**Return:** + +@return array Returns the new sorted array. + +Example: +```php + 'fred', 'age' => 48 ], + [ 'user' => 'barney', 'age' => 36 ], + [ 'user' => 'fred', 'age' => 40 ], + [ 'user' => 'barney', 'age' => 34 ], +]; + +sortBy($users, [function($o) { return $o['user']; }]); +// => [['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]] + +sortBy($users, ['user', 'age']); +// => [['user' => 'barney', 'age' => 34], ['user' => 'barney', 'age' => 36], ['user' => 'fred', 'age' => 40], ['user' => 'fred', 'age' => 48]] + +``` +## Date + +### now + +Gets the timestamp of the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). + + + +**Arguments:** + + + +**Return:** + +@return int Returns the timestamp. + +Example: +```php + 1511180325735 + +``` +## Function + +### memoize + +Creates a function that memoizes the result of `func`. If `resolver` is +provided, it determines the cache key for storing the result based on the +arguments provided to the memoized function. By default, the first argument +provided to the memoized function is used as the map cache key + +**Note:** The cache is exposed as the `cache` property on the memoized +function. Its creation may be customized by replacing the `_.memoize.Cache` +constructor with one whose instances implement the +[`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) +method interface of `clear`, `delete`, `get`, `has`, and `set`. + +**Arguments:** + +@param callable $func The function to have its output memoized. + +@param callable $resolver The function to resolve the cache key. + + + +**Return:** + +@return callable Returns the new memoized function. + +Example: +```php + 1, 'b' => 2]; +$other = ['c' => 3, 'd' => 4]; + +$values = memoize('_\values'); +$values($object); +// => [1, 2] + +$values($other); +// => [3, 4] + +$object['a'] = 2; +$values($object); +// => [1, 2] + +// Modify the result cache. +$values->cache->set($object, ['a', 'b']); +$values($object); +// => ['a', 'b'] + +``` +### negate + +Creates a function that negates the result of the predicate `func` + + + +**Arguments:** + +@param callable $predicate The predicate to negate. + + + +**Return:** + +@return callable Returns the new negated function. + +Example: +```php + [1, 3, 5] +``` +## Lang + +### eq + +Performs a comparison between two values to determine if they are equivalent. + + + +**Arguments:** + +@param mixed $value The value to compare. + +@param mixed $other The other value to compare. + + + +**Return:** + +@return bool Returns `true` if the values are equivalent, else `false`. + +Example: +```php + 1]; +$other = (object) ['a' => 1]; + +eq($object, $object); +// => true + +eq($object, $other); +// => false + +eq('a', 'a'); +// => true + +eq(['a'], (object) ['a']); +// => false + +eq(INF, INF); +// => true + +``` ### isEqual Performs a deep comparison between two values to determine if they are @@ -1969,6 +2780,68 @@ Example: add(6, 4); // => 10 +``` +### max + +Computes the maximum value of `array`. If `array` is empty or falsey, null is returned. + + + +**Arguments:** + +@param array $ array The array to iterate over. + + + +**Return:** + +@return int|null Returns the maximum value. + +Example: +```php + 8 + +max([]); +// => null + +``` +### maxBy + +This method is like `max` except that it accepts `iteratee` which is +invoked for each element in `array` to generate the criterion by which +the value is ranked. The iteratee is invoked with one argument: (value). + + + +**Arguments:** + +@param array $array The array to iterate over. + +@param callable|string $iteratee The iteratee invoked per element. + + + +**Return:** + +@return mixed Returns the maximum value. + +Example: +```php + 1], ['n' => 2]]; + +maxBy($objects, function($o) { return $o['n']; }); +// => ['n' => 2] + +// The `property` iteratee shorthand. +maxBy($objects, 'n'); +// => ['n' => 2] ``` ## Number From 678ea2723db9925d8de8943de1b9717a874bd15b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 6 Jun 2018 13:13:16 +0200 Subject: [PATCH 064/159] Rename bin/build to bin/generate-readme --- bin/{build => generate-readme} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bin/{build => generate-readme} (100%) diff --git a/bin/build b/bin/generate-readme similarity index 100% rename from bin/build rename to bin/generate-readme From 1a06dcc4620ac6400daa0e729fcac4998eac4697 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 10:19:41 +0200 Subject: [PATCH 065/159] Compile all functions to a single file --- bin/compile | 38 +++++++++++ composer.json | 7 +- src/bootstrap.php | 11 ++- src/compiled.php | 170 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+), 7 deletions(-) create mode 100755 bin/compile create mode 100644 src/compiled.php diff --git a/bin/compile b/bin/compile new file mode 100755 index 0000000..2422749 --- /dev/null +++ b/bin/compile @@ -0,0 +1,38 @@ +#!/usr/bin/env php +getRealPath()); + $code = preg_replace(['#\<\?php#', '#declare\(strict_types=1\);#'], '', $code, 1); + $code = preg_replace('#namespace ([a-zA-Z\\\/-_0-9]+);\s?(.*)#', 'namespace $1 { $2 }', $code); + + return $code; +} + +$code = <<getBasename(), ['bootstrap.php', 'lodash.php', 'compiled.php', 'Lodash.php'], true)) { + continue; + } + + $code .= getCode($file); +} + +file_put_contents(dirname(__DIR__).'/src/compiled.php', $code); + diff --git a/composer.json b/composer.json index f0125a8..15fde49 100644 --- a/composer.json +++ b/composer.json @@ -19,19 +19,16 @@ ], "autoload": { "files": [ - "src/internal/unicode.php", - "src/internal/Traits/CacheDataTrait.php", - "src/CacheInterface.php", "src/bootstrap.php" ] }, "require": { "php": "^7.1", - "sebastian/comparator": "^1.2 | ^2.0 | ^2.1", + "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0", "symfony/property-access": "^2.7 | ^3.0 | ^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.4", + "phpunit/phpunit": "^6.4 | ^7.0", "phpdocumentor/reflection-docblock": "^4.2" } } diff --git a/src/bootstrap.php b/src/bootstrap.php index 745a01a..1e9b200 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -9,6 +9,13 @@ * @copyright Copyright (c) 2017 */ -foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS)) as $file) { - require_once $file->getRealPath(); +if (file_exists($file = __DIR__.'/compiled.php')) { + require_once $file; +} else { + require_once __DIR__.'/internal/Traits/CacheDataTrait.php'; + require_once __DIR__.'/CacheInterface.php'; + + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS)) as $file) { + require_once $file->getRealPath(); + } } diff --git a/src/compiled.php b/src/compiled.php new file mode 100644 index 0000000..cc476d2 --- /dev/null +++ b/src/compiled.php @@ -0,0 +1,170 @@ +'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; public static function __callStatic(string $method, array $args) { return ("_\\$method")(...$args); } } } + namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } + namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } + namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = count($array); if ($initAccum && $length) { $accumulator = current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } + namespace _ { function eachRight($collection, callable $iteratee) { $values = $collection; if (\is_object($collection)) { $values = \get_object_vars($collection); } foreach (\array_reverse($values, true) as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } + namespace _ { use function _\internal\baseFlatten; function flatMapDeep(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); } } + namespace _ { use function _\internal\baseOrderBy; function orderBy(?iterable $collection, $iteratee, $orders): array { if (null === $collection) { return []; } return baseOrderBy($collection, (array) $iteratee, (array) $orders); } } + namespace _ { function size($collection): int { if (\is_string($collection)) { return \strlen($collection); } if (\is_array($collection) || $collection instanceof \Countable) { return \count($collection); } if ($collection instanceof \Traversable) { return \count(\iterator_to_array($collection)); } if (\is_object($collection)) { return \count(\get_object_vars($collection)); } return 0; } } + namespace _ { function each($collection, callable $iteratee) { $values = $collection; if (\is_object($collection)) { $values = \get_object_vars($collection); } foreach ($values as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } + namespace _ { use function _\internal\baseIteratee; use function _\internal\baseReduce; function reduceRight(iterable $collection, $iteratee, $accumulator = null) { return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); } } + namespace _ { use function _\internal\baseIteratee; function map($collection, $iteratee): array { $values = []; if (\is_array($collection)) { $values = $collection; } elseif ($collection instanceof \Traversable) { $values = \iterator_to_array($collection); } elseif (\is_object($collection)) { $values = \get_object_vars($collection); } $callable = baseIteratee($iteratee); return \array_map(function ($value, $index) use ($callable, $collection) { return $callable($value, $index, $collection); }, $values, \array_keys($values)); } } + namespace _ { use function _\internal\createAggregator; function partition(iterable $collection, $predicate = null): array { return createAggregator(function ($result, $value, $key) { $result[$key ? 0 : 1][] = $value; return $result; }, function () { return [[], []]; })($collection, $predicate); } } + namespace _ { use function _\internal\baseIteratee; function every(iterable $collection, $predicate): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if (!$iteratee($value, $key, $collection)) { return false; } } return true; } } + namespace _ { use function _\internal\baseIteratee; function find(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice($collection, $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } + namespace _ { function shuffle(array $array = []): array { \shuffle($array); return $array; } } + namespace _ { use function _\internal\baseFlatten; function flatMap(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), 1); } } + namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } + namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, $args); } } + namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } + namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( $array, function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } + namespace _ { function sample(array $array) { return $array[\array_rand($array, 1)]; } } + namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } + namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees) { if (null === $collection) { return []; }; if (\is_callable($iteratees)) { $iteratees = [$iteratees]; } $result = $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } + namespace _ { use function _\internal\createAggregator; function keyBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { $result[$key] = $value; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\createAggregator; function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { $result[$key] = []; } $result[$key][] = $value; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\baseFlatten; function flatMapDepth(iterable $collection, callable $iteratee = null, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } } + namespace _ { use function _\internal\createAggregator; function countBy(iterable $collection, callable $iteratee): array { return createAggregator(function ($result, $key, $value) { if (!isset($result[$value])) { $result[$value] = 0; } $result[$value]++; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\baseIteratee; function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\array_reverse($collection, true), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } + namespace _ { use Symfony\Component\PropertyAccess\PropertyAccess; function property($path): callable { $propertyAccess = PropertyAccess::createPropertyAccessorBuilder() ->disableExceptionOnInvalidIndex() ->getPropertyAccessor(); return function ($value, $index = 0, $collection = []) use ($path, $propertyAccess) { $path = \implode('.', (array) $path); if (\is_array($value)) { if (false !== \strpos($path, '.')) { $paths = \explode('.', $path); foreach ($paths as $path) { $value = property($path)($value, $index, $collection); } return $value; } if (\is_string($path) && $path[0] !== '[' && $path[-1] !== ']') { $path = "[$path]"; } } return $propertyAccess->getValue($value, $path); }; } } + namespace _ { function identity($value = null) { return $value; } } + namespace _ { function attempt(callable $func, ...$args) { try { return $func(...$args); } catch (\ParseError | \Error | \Throwable | \SoapFault | \DOMException | \PDOException $e) { return $e; } } } + namespace _ { use function _\internal\baseFlatten; function flattenDepth(array $array, int $depth = 1): array { return baseFlatten($array, $depth); } } + namespace _ { function difference(array $array, array ...$values): array { return \array_values(\array_diff($array, ...$values)); } } + namespace _ { use function _\internal\baseSet; function zipObjectDeep(array $props = [], array $values = []): object { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; baseSet($result, $props[$index], $value); } return $result; } } + namespace _ { use function _\internal\baseIteratee; function findLastIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); $index = $fromIndex ?? $length - 1; if ($index < 0) { $index = \max($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach (\array_reverse($array, true) as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index--; } return -1; } } + namespace _ { function lastIndexOf(array $array, $value, int $fromIndex = null): int { $index = \count($array) - 1; if (null !== $fromIndex) { $index = $fromIndex > 0 ? $fromIndex : \count($array) - 1; $array = \array_slice($array, 0, -$fromIndex + 1); }; foreach (\array_reverse($array, false) as $v) { if (isEqual($value, $v)) { return $index; } $index--; } return -1; } } + namespace _ { use function _\internal\baseIteratee; use function _\internal\basePullAll; function pullAllBy(array &$array, array $values, $iteratee): array { return basePullAll($array, $values, baseIteratee($iteratee)); } } + namespace _ { use function _\internal\baseUniq; function uniqWith(array $array, callable $comparator): array { return baseUniq($array, null, $comparator); } } + namespace _ { use function _\internal\basePullAll; function pullAllWith(array &$array, array $values, callable $comparator): array { return basePullAll($array, $values, null, $comparator); } } + namespace _ { use function _\internal\baseRest; function zip(array ...$arrays): array { return baseRest('\_\unzip')($arrays); } } + namespace _ { function compact(?array $array): array { return \array_values(\array_filter($array ?? [])); } } + namespace _ { function zipWith(...$arrays): array { $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; return unzipWith($arrays, $iteratee); } } + namespace _ { function uniq(array $array = null): array { return \array_unique($array); } } + namespace _ { function zipObject(array $props = [], array $values = []) { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; $result->{$props[$index]} = $value; } return $result; } } + namespace _ { use function _\internal\baseIteratee; use function _\internal\baseUniq; function uniqBy(array $array, $iteratee): array { return baseUniq($array, baseIteratee($iteratee)); } } + namespace _ { use function _\internal\baseIteratee; function takeRightWhile(array $array, $predicate): array { $iteratee = baseIteratee($predicate); $result = []; foreach (array_reverse($array, true) as $index => $value) { if ($iteratee($value, $index, $array)) { $result[$index] = $value; } } return array_reverse($result); } } + namespace _ { use function _\internal\baseIteratee; function takeWhile(array $array, $predicate): array { $result = []; $iteratee = baseIteratee($predicate); foreach ($array as $index => $value) { if ($iteratee($value, $index, $array)) { $result[$index] = $value; } } return $result; } } + namespace _ { function takeRight(array $array, int $n = 1): array { if (1 > $n) { return []; } return array_slice($array, -$n); } } + namespace _ { use function _\internal\baseFlatten; function differenceWith(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $comparator = \array_pop($values); $values = baseFlatten($values, 1, 'is_array', true, null); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($comparator($value, $values[$valuesIndex])) { continue 2; } } $result[] = $value; } return $result; } } + namespace _ { function initial(array $array): array { \array_pop($array); return $array; } } + namespace _ { function dropRightWhile(array $array, callable $predicate): array { \end($array); $length = \count($array); $index = \key($array); while ($length && $predicate($array[$index], $index, $array)) { array_pop($array); $length--; \end($array); $index = \key($array); } return $array; } } + namespace _ { function indexOf(array $array, $value, int $fromIndex = null): int { $inc = true; $index = 0; if (null !== $fromIndex) { $index = $fromIndex >= 0 ? $fromIndex : \count($array) - 1; if ($fromIndex < 0) { $array = \array_reverse($array, false); $inc = false; } }; foreach ($array as $v) { if (isEqual($value, $v)) { return $index; } $inc ? $index++ : $index--; } return -1; } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseProperty; use function _\internal\baseTimes; function unzip(array $array): array { if (!\count($array)) { return []; } $length = 0; $array = \array_filter($array, function ($group) use (&$length) { if (\is_array($group)) { $length = \max(\count($group), $length); return true; } }); return baseTimes($length, function ($index) use ($array) { return arrayMap($array, baseProperty($index)); }); } } + namespace _ { function slice(array $array, int $start, int $end = null): array { return \array_slice($array, $start, $end); } } + namespace _ { function drop(array $array, int $n = 1): array { return \array_slice($array, $n); } } + namespace _ { use function _\internal\baseRest; function without(array $array, ...$values): array { return baseRest('\_\difference')($array, $values); } } + namespace _ { function dropWhile(array $array, callable $predicate): array { \reset($array); $count = \count($array); $length = 0; $index = \key($array); while ($length <= $count && $predicate($array[$index], $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); } return $array; } } + namespace _ { use function _\internal\baseIntersection; function intersectionWith(...$arrays ): array { $copy = $arrays; $comparator = array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; $comparator = null; } return baseIntersection($arrays, null, $comparator); } } + namespace _ { function head(array $array) { reset($array); return current($array) ?: null; } function first(array $array) { return head($array); } } + namespace _ { function dropRight(array $array, int $n = 1): array { $count = \count($array); if ($n > $count) { $n = $count; } return \array_slice($array, 0, $count - $n); } } + namespace _ { function concat($array, ...$values): array { $check = function ($value): array { return \is_array($value) ? $value : [$value]; }; return \array_merge($check($array), ...\array_map($check, $values)); } } + namespace _ { function remove(array &$array, callable $predicate): array { $resultArray = []; $array = \array_filter($array, function ($val, $key) use ($predicate, $array, &$resultArray) { $result = $predicate($val, $key, $array); if ($result) { $resultArray[] = $val; } return !$result; }, \ARRAY_FILTER_USE_BOTH); $array = \array_values($array); return $resultArray; } } + namespace _ { function chunk(?array $array, int $number): array { if ($number < 1) { return []; } return \array_chunk($array ?? [], $number, false); } } + namespace _ { function take(array $array, int $n = 1): array { if (1 > $n) { return []; } array_splice($array, $n); return $array; } } + namespace _ { function last(array $array) { return \end($array) ?: null; } } + namespace _ { function tail(array $array): array { array_shift($array); return $array; } } + namespace _ { function pull(array &$array, ...$values): array { $array = \array_filter($array, function ($val) use ($values) { return !\in_array($val, $values, true); }); $array = \array_values($array); return $array; } } + namespace _ { function fromPairs(array $pairs): \stdClass { if (!\count($pairs)) { return new \stdClass(); } $result = new \stdClass(); foreach ($pairs as $pair) { $result->{$pair[0]} = $pair[1]; } return $result; } } + namespace _ { function intersection(array ...$arrays): array { return \array_intersect(...$arrays); } } + namespace _ { function pullAt(array &$array, $indexes): array { $indexes = (array) $indexes; $pulled = []; $array = \array_filter($array, function ($val, $key) use ($indexes, &$pulled) { $inArray = \in_array($key, $indexes); if ($inArray) { $pulled[] = $val; } return !$inArray; }, \ARRAY_FILTER_USE_BOTH); $array = \array_values($array); return $pulled; } } + namespace _ { function pullAll(array &$array, array $values): array { return pull($array, ...$values); } } + namespace _ { function union(array ...$arrays): array { return array_unique(array_merge(...$arrays)); } } + namespace _ { use function _\internal\baseFlatten; function flatten(array $array = null): array { return baseFlatten($array, 1); } } + namespace _ { use function _\internal\baseFlatten; use function _\internal\baseUniq; function unionWith(... $arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); } } + namespace _ { use function _\internal\baseIteratee; function findIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); if (!$length) { return -1; } $index = $fromIndex ?? 0; if ($index < 0) { $index = \min($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach ($array as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index++; } return -1; } } + namespace _ { use function _\internal\baseFlatten; function flattenDeep(array $array): array { return baseFlatten($array, INF); } } + namespace _ { use function _\internal\arrayMap; function unzipWith(array $array, callable $iteratee): array { if (!\count($array)) { return []; } $result = unzip($array); if (null === $iteratee) { return $result; } return arrayMap($result, function ($group) use ($iteratee) { return $iteratee(...$group); }); } } + namespace _ { function nth(array $array, int $n) { return \array_values($array)[$n < 0 ? \count($array) + $n : $n] ?? null; } } + namespace _ { use function _\internal\baseFlatten; function differenceBy(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $iteratee = \array_pop($values); $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $computed = $iteratee($value); $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($computed === $values[$valuesIndex]) { continue 2; } } $result[] = $value; } return $result; } } + namespace _ { use function _\internal\baseFlatten; use function _\internal\baseIteratee; use function _\internal\baseUniq; function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } } + namespace _ { use function _\internal\baseIntersection; use function _\internal\baseIteratee; function intersectionBy(...$arrays): array { $iteratee = \array_pop($arrays); return baseIntersection($arrays, baseIteratee($iteratee)); } } + namespace _ { function now(): int { return (int) (\microtime(true) * 1000); } } + namespace _\internal { function baseUnary($func) { return function ($value) use ($func) { return $func($value); }; } } + namespace _\internal { function stringToArray(string $string): array { return hasUnicode($string) ? unicodeToArray($string) : \str_split($string); } } + namespace _\internal { function createMathOperation(callable $operator, $defaultValue) { return function ($value, $other) use ($defaultValue, $operator) { if (null === $value && null === $other) { return $defaultValue; } $result = null; if (null !== $value) { $result = $value; } if (null !== $other) { if (null === $result) { return $other; } $result = $operator($value, $other); } return $result; }; } } + namespace _\internal { use function _\each; function createAggregator($setter, $initializer = null) { return function ($collection, $iteratee) use ($setter, $initializer) { $accumulator = null !== $initializer ? $initializer() : []; $func = function ($collection, $setter, &$accumulator, $iteratee) { each($collection, function ($value, $key, $collection) use ($setter, &$accumulator, $iteratee) { $accumulator = $setter($accumulator, $value, $iteratee($value), $collection); }); return $accumulator; }; return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); }; } } + namespace _\internal { use function _\isEqual; use function _\property; function baseMatches($source): callable { return function ($value, $index, $collection) use ($source): bool { if ($value === $source || isEqual($value, $source)) { return true; } if (\is_array($source) || $source instanceof \Traversable) { foreach ($source as $k => $v) { if (!isEqual(property($k)($value, $index, $collection), $v)) { return false; } } return true; } return false; }; } } + namespace _\internal { function baseTimes(int $n, callable $iteratee) { $index = -1; $result = []; while (++$index < $n) { $result[$index] = $iteratee($index); } return $result; } } + namespace _\internal { function arrayMap(?array $array, callable $iteratee) { $index = -1; $length = null === $array ? 0 : \count($array); $result = []; while (++$index < $length) { $result[$index] = $iteratee($array[$index], $index, $array); } return $result; } } + namespace _\internal { const rsAstralRange = '\\x{e800}-\\x{efff}'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsDingbatRange = '\\x{2700}-\\x{27bf}'; const rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; const rsMathOpRange = '\\xac\\xb1\\xd7\\xf7'; const rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; const rsPunctuationRange = '\\x{2000}-\\x{206f}'; const rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; const rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; const rsVarRange = '\\x{fe0e}\\x{fe0f}'; const rsBreakRange = rsMathOpRange.rsNonCharRange.rsPunctuationRange.rsSpaceRange; const rsApos = "[\\x{2019}]"; const rsBreak = '['.rsBreakRange.']'; const rsCombo = '['.rsComboRange.']'; const rsDigits = '\\d+'; const rsDingbat = '['.rsDingbatRange.']'; const rsLower = '['.rsLowerRange.']'; const rsMisc = '[^'.rsAstralRange.rsBreakRange.rsDigits.rsDingbatRange.rsLowerRange.rsUpperRange.']'; const rsFitz = '\\x{e83c}[\\x{effb}-\\x{efff}]'; const rsModifier = '(?:'.rsCombo.'|'.rsFitz.')'; const rsNonAstral = '[^'.rsAstralRange.']'; const rsRegional = '(?:\\x{e83c}[\\x{ede6}-\\x{edff}]){2}'; const rsSurrPair = '[\\x{e800}-\\x{ebff}][\\x{ec00}-\\x{efff}]'; const rsUpper = '['.rsUpperRange.']'; const rsZWJ = '\\x{200d}'; const rsMiscLower = '(?:'.rsLower.'|'.rsMisc.')'; const rsMiscUpper = '(?:'.rsUpper.'|'.rsMisc.')'; const rsOptContrLower = '(?:'.rsApos.'(?:d|ll|m|re|s|t|ve))?'; const rsOptContrUpper = '(?:'.rsApos.'(?:D|LL|M|RE|S|T|VE))?'; const reOptMod = rsModifier.'?'; const rsOptVar = '['.rsVarRange.']?'; define('rsOptJoin', '(?:'.rsZWJ.'(?:'.implode('|', [rsNonAstral, rsRegional, rsSurrPair]).')'.rsOptVar.reOptMod.')*'); const rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)'; const rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)'; const rsSeq = rsOptVar.reOptMod.rsOptJoin; define('rsEmoji', '(?:'.implode('|', [rsDingbat, rsRegional, rsSurrPair]).')'.rsSeq); const rsAstral = '['.rsAstralRange.']'; const rsNonAstralCombo = rsNonAstral.rsCombo.'?'; define('rsSymbol', '(?:'.implode('|', [rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral]).')'); const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; } + namespace _\internal { function toKey($value): string { if (\is_string($value)) { return $value; } $result = (string) $value; return ('0' === $result && (1 / $value) === -INF) ? '-0' : $result; } } + namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $start = max($start ?? -1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs[$start]); }; } } + namespace _\internal\Traits { trait CacheDataTrait { private $__data__; private $size; public function getSize(): int { return $this->size; } } } + namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } + namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } + namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } + namespace _\internal { function unicodeSize($string): int { return \preg_match_all(reUnicode, $string); } } + namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\internal\baseIndexOfWith' : '_\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } + namespace _\internal { function baseFlatten(?array $array, float $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '\_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { $result = \array_merge($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } + namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } + namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); } } + namespace _\internal { function arrayIncludesWith(?array $array, $value, callable $comparator) { $array = $array ?? []; foreach ($array as $v) { if ($comparator($value, $v)) { return true; } } return false; } } + namespace _\internal { const reIsDeepProp = '#\.|\[(?:[^[\]]*|(["\'])(?:(?!\1)[^\\\\]|\\.)*?\1)\]#'; const reIsPlainProp = '/^\w*$/'; function isKey($value, $object = []): bool { if (\is_array($value)) { return false; } if (\is_numeric($value)) { return true; } return \preg_match(reIsPlainProp, $value) || !\preg_match(reIsDeepProp, $value) || (null !== $object && isset(((object) $object)->$value)); } } + namespace _\internal { function baseProperty($key) { return function ($object) use ($key) { return null === $object ? null : $object[$key]; }; } } + namespace _\internal { use function _\isEqual; use function _\property; function baseMatchesProperty($property, $source): callable { return function ($value, $index, $collection) use ($property, $source) { return isEqual(property($property)($value, $index, $collection), $source); }; } } + namespace _\internal { function castPath($value, $object): array { if (\is_array($value)) { return $value; } return isKey($value, $object) ? [$value] : stringToPath((string) $value); } } + namespace _\internal { use function _\map; use function _\sortBy; function baseOrderBy(iterable $collection, array $iteratees, array $orders): array { $index = -1; $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); $result = map($collection, function ($value) use ($iteratees, &$index) { $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { return $iteratee($value); }); return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; }); return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); } } + namespace _\internal { use function _\property; function baseIteratee($value): callable { if (\is_callable($value)) { return $value; } if (null === $value) { return '_\identity'; } if (\is_array($value)) { return 2 === \count($value) && [0, 1] === \array_keys($value) ? baseMatchesProperty($value[0], $value[1]) : baseMatches($value); } return property($value); } } + namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } + namespace _\internal { use function _\eq; function assocIndexOf(array $array, $key): int { $length = \count($array); while ($length--) { if (eq($array[$length][0], $key)) { return $length; } } return -1; } } + namespace _\internal { use function _\{slice, get}; function parent($object, $path) { return count($path) < 2 ? $object : get($object, slice($path, 0, -1)); } } + namespace _\internal { use function _\indexOf; function arrayIncludes(?array $array, $value) { return null !== $array && indexOf($array, $value, 0) > -1; } } + namespace _\internal { const reLeadingDot = '/^\./'; const rePropName = '#[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["\'])((?:(?!\2)[^\\\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))#'; const reEscapeChar = '/\\(\\)?/g'; function stringToPath(...$args) { return memoizeCapped(function ($string) { $result = []; if (\preg_match(reLeadingDot, $string)) { $result[] = ''; } \preg_match_all(rePropName, $string, $matches, PREG_SPLIT_DELIM_CAPTURE); foreach ($matches as $match) { $result[] = $match[1] ?? $match[0]; } return $result; })(...$args); } } + namespace _\internal { function baseUniq(array $array, callable $iteratee = null, callable $comparator = null) { $index = -1; $includes = '\_\internal\arrayIncludes'; $length = \count($array); $isCommon = true; $result = []; $seen = $result; if ($comparator) { $isCommon = false; $includes = '\_\internal\arrayIncludesWith'; } else { $seen = $iteratee ? [] : $result; } while (++$index < $length) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator || $value !== 0) ? $value : 0; if ($isCommon && $computed) { $seenIndex = \count($seen); while ($seenIndex--) { if ($seen[$seenIndex] === $computed) { continue 2; } } if ($iteratee) { $seen[] = $computed; } $result[] = $value; } elseif (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } $result[] = $value; } } return $result; } } + namespace _\internal { function unicodeWords(string $string): array { $regex = '#'.\implode('|', [ rsUpper.'?'.rsLower.'+'.rsOptContrLower.'(?='.\implode('|', [rsBreak, rsUpper, '$']).')', rsMiscUpper.'+'.rsOptContrUpper.'(?='.\implode('|', [rsBreak, rsUpper.rsMiscLower, '$']).')', rsUpper.'?'.rsMiscLower.'+'.rsOptContrLower, rsUpper.'+'.rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji, ]).'#u'; if (\preg_match_all($regex, $string, $matches) > 0) { return $matches[0]; } return []; } } + namespace _\internal { use function _\memoize; function memoizeCapped(callable $func) { $MaxMemoizeSize = 500; $result = memoize($func, function ($key) use ($MaxMemoizeSize) { if ($this->cache->getSize() === $MaxMemoizeSize) { $this->cache->clear(); } return $key; }); return $result; } } + namespace _\internal { function baseIntersection($arrays, ?callable $iteratee, $comparator = null) { $includes = $comparator ? '_\internal\arrayIncludesWith' : '_\internal\arrayIncludes'; $length = \count($arrays[0]); $othLength = \count($arrays); $othIndex = $othLength; $caches = []; $maxLength = INF; $result = []; while ($othIndex--) { $array =& $arrays[$othIndex]; if ($othIndex && $iteratee) { $array = \array_map($iteratee, $array); } $maxLength = \min(\count($array), $maxLength); $caches[$othIndex] = !$comparator && $iteratee ? [] : null; } $array = $arrays[0]; $index = -1; $seen = $caches[0]; while (++$index < $length && \count($result) < $maxLength) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator ?: $value !== 0) ? $value : 0; if (!($seen ? isset($seen[$computed]) : $includes($result, $computed, $comparator))) { $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; if (!($cache ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { continue 2; } } if ($seen) { $seen[] = $computed; } $result[] = $value; } } return $result; } } + namespace _\internal { function baseSet($object, $path, $value, callable $customizer = null) { if (!\is_object($object)) { return $object; } $path = castPath($path, $object); $index = -1; $length = \count($path); $lastIndex = $length - 1; $nested = $object; while ($nested !== null && ++$index < $length) { $key = toKey($path[$index]); if ($index !== $lastIndex) { $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; if (null === $newValue) { $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); } if (\is_array($nested)) { $nested[$key] = $newValue; } else { $nested->{$key} = $newValue; } if (\is_array($nested)) { $nested = &$nested[$key]; } else { $nested = &$nested->$key; } continue; } $nested->{$key} = $value; } return $object; } } + namespace _\internal { function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } } + namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return null === $func ? null : $func($object, ...$args); } } + namespace _\internal { const reHasUnicode = '['.rsZWJ.rsAstralRange.rsComboRange.rsVarRange.']'; function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; } } + namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } + namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count($array); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } + namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } + namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } + namespace _ { function memoize(callable $func = null, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result) ?: $this->cache; return $result; } }; $memoized->cache = new MapCache; return $memoized; } } + namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } + namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } + namespace _ { function max(?array $array): ?int { return $array ? \max($array) : null; } } + namespace _ { function clamp(int $number, int $lower, int $upper): int { $number = $number <= $upper ? $number : $upper; $number = $number >= $lower ? $number : $lower; return $number; } } + namespace _ { function inRange(float $number, float $start = 0, float $end = 0): bool { if (0 === $end || 0.0 === $end) { $end = $start; $start = 0; } return $number >= \min($start, $end) && $number < \max($start, $end); } } + namespace _ { function random($lower = null, $upper = null, $floating = null) { if (null === $floating) { if (\is_bool($upper)) { $floating = $upper; $upper = null; } elseif (\is_bool($lower)) { $floating = $lower; $lower = null; } } if (null === $lower && null === $upper) { $lower = 0; $upper = 1; } elseif (null === $upper) { $upper = $lower; $lower = 0; } if ($lower > $upper) { $temp = $lower; $lower = $upper; $upper = $temp; } $floating = $floating || (\is_float($lower) || \is_float($upper)); if ($floating || $lower % 1 || $upper % 1) { $randMax = \mt_getrandmax(); return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } return \rand((int) $lower, (int) $upper); } } + namespace _ { function isError($value): bool { if (!\is_object($value)) { return false; } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; } } + namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } + namespace _ { function eq($value, $other): bool { return $value === $other; } } + namespace _ { function lowerFirst(string $string): string { return \lcfirst($string); } } + namespace _ { function camelCase(string $string): string { return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); } } + namespace _ { function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); } } + namespace _ { function upperFirst(string $string): string { return \ucfirst($string); } } + namespace _ { const reQuotes = "/['\x{2019}]/u"; function lowerCase(string $string) { return \implode(' ', \array_map('\strtolower', words(\preg_replace(reQuotes, '', $string)))); } } + namespace _ { const deburredLetters = [ '\xc0' => 'A', '\xc1' => 'A', '\xc2' => 'A', '\xc3' => 'A', '\xc4' => 'A', '\xc5' => 'A', '\xe0' => 'a', '\xe1' => 'a', '\xe2' => 'a', '\xe3' => 'a', '\xe4' => 'a', '\xe5' => 'a', '\xc7' => 'C', '\xe7' => 'c', '\xd0' => 'D', '\xf0' => 'd', '\xc8' => 'E', '\xc9' => 'E', '\xca' => 'E', '\xcb' => 'E', '\xe8' => 'e', '\xe9' => 'e', '\xea' => 'e', '\xeb' => 'e', '\xcc' => 'I', '\xcd' => 'I', '\xce' => 'I', '\xcf' => 'I', '\xec' => 'i', '\xed' => 'i', '\xee' => 'i', '\xef' => 'i', '\xd1' => 'N', '\xf1' => 'n', '\xd2' => 'O', '\xd3' => 'O', '\xd4' => 'O', '\xd5' => 'O', '\xd6' => 'O', '\xd8' => 'O', '\xf2' => 'o', '\xf3' => 'o', '\xf4' => 'o', '\xf5' => 'o', '\xf6' => 'o', '\xf8' => 'o', '\xd9' => 'U', '\xda' => 'U', '\xdb' => 'U', '\xdc' => 'U', '\xf9' => 'u', '\xfa' => 'u', '\xfb' => 'u', '\xfc' => 'u', '\xdd' => 'Y', '\xfd' => 'y', '\xff' => 'y', '\xc6' => 'Ae', '\xe6' => 'ae', '\xde' => 'Th', '\xfe' => 'th', '\xdf' => 'ss', '\x{0100}' => 'A', '\x{0102}' => 'A', '\x{0104}' => 'A', '\x{0101}' => 'a', '\x{0103}' => 'a', '\x{0105}' => 'a', '\x{0106}' => 'C', '\x{0108}' => 'C', '\x{010a}' => 'C', '\x{010c}' => 'C', '\x{0107}' => 'c', '\x{0109}' => 'c', '\x{010b}' => 'c', '\x{010d}' => 'c', '\x{010e}' => 'D', '\x{0110}' => 'D', '\x{010f}' => 'd', '\x{0111}' => 'd', '\x{0112}' => 'E', '\x{0114}' => 'E', '\x{0116}' => 'E', '\x{0118}' => 'E', '\x{011a}' => 'E', '\x{0113}' => 'e', '\x{0115}' => 'e', '\x{0117}' => 'e', '\x{0119}' => 'e', '\x{011b}' => 'e', '\x{011c}' => 'G', '\x{011e}' => 'G', '\x{0120}' => 'G', '\x{0122}' => 'G', '\x{011d}' => 'g', '\x{011f}' => 'g', '\x{0121}' => 'g', '\x{0123}' => 'g', '\x{0124}' => 'H', '\x{0126}' => 'H', '\x{0125}' => 'h', '\x{0127}' => 'h', '\x{0128}' => 'I', '\x{012a}' => 'I', '\x{012c}' => 'I', '\x{012e}' => 'I', '\x{0130}' => 'I', '\x{0129}' => 'i', '\x{012b}' => 'i', '\x{012d}' => 'i', '\x{012f}' => 'i', '\x{0131}' => 'i', '\x{0134}' => 'J', '\x{0135}' => 'j', '\x{0136}' => 'K', '\x{0137}' => 'k', '\x{0138}' => 'k', '\x{0139}' => 'L', '\x{013b}' => 'L', '\x{013d}' => 'L', '\x{013f}' => 'L', '\x{0141}' => 'L', '\x{013a}' => 'l', '\x{013c}' => 'l', '\x{013e}' => 'l', '\x{0140}' => 'l', '\x{0142}' => 'l', '\x{0143}' => 'N', '\x{0145}' => 'N', '\x{0147}' => 'N', '\x{014a}' => 'N', '\x{0144}' => 'n', '\x{0146}' => 'n', '\x{0148}' => 'n', '\x{014b}' => 'n', '\x{014c}' => 'O', '\x{014e}' => 'O', '\x{0150}' => 'O', '\x{014d}' => 'o', '\x{014f}' => 'o', '\x{0151}' => 'o', '\x{0154}' => 'R', '\x{0156}' => 'R', '\x{0158}' => 'R', '\x{0155}' => 'r', '\x{0157}' => 'r', '\x{0159}' => 'r', '\x{015a}' => 'S', '\x{015c}' => 'S', '\x{015e}' => 'S', '\x{0160}' => 'S', '\x{015b}' => 's', '\x{015d}' => 's', '\x{015f}' => 's', '\x{0161}' => 's', '\x{0162}' => 'T', '\x{0164}' => 'T', '\x{0166}' => 'T', '\x{0163}' => 't', '\x{0165}' => 't', '\x{0167}' => 't', '\x{0168}' => 'U', '\x{016a}' => 'U', '\x{016c}' => 'U', '\x{016e}' => 'U', '\x{0170}' => 'U', '\x{0172}' => 'U', '\x{0169}' => 'u', '\x{016b}' => 'u', '\x{016d}' => 'u', '\x{016f}' => 'u', '\x{0171}' => 'u', '\x{0173}' => 'u', '\x{0174}' => 'W', '\x{0175}' => 'w', '\x{0176}' => 'Y', '\x{0177}' => 'y', '\x{0178}' => 'Y', '\x{0179}' => 'Z', '\x{017b}' => 'Z', '\x{017d}' => 'Z', '\x{017a}' => 'z', '\x{017c}' => 'z', '\x{017e}' => 'z', '\x{0132}' => 'IJ', '\x{0133}' => 'ij', '\x{0152}' => 'Oe', '\x{0153}' => 'oe', '\x{0149}' => "'n", '\x{017f}' => 's', ]; const reLatin = '/[\xc0-\xd6\xd8-\xf6\xf8-\xff\x{0100}-\x{017f}]/u'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsCombo = '#['.rsComboRange.']#u'; function deburr(string $string): string { $patterns = \array_map( function ($pattern) { return "#$pattern#u"; }, \array_keys(deburredLetters) ); return \preg_replace(rsCombo, '', \preg_replace($patterns, \array_values(deburredLetters), $string)); } } + namespace _ { function trimStart(string $string, string $chars = ' '): string { return \ltrim($string, $chars); } } + namespace _ { function repeat(string $string, int $n = 1): string { return \str_repeat($string, $n); } } + namespace _ { function padStart(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_LEFT); } } + namespace _ { function trim(string $string, string $chars = ' '): string { return \trim($string, $chars); } } + namespace _ { function parseInt($string, int $radix = null): int { if (null === $radix) { $radix = 10; } elseif ($radix) { $radix = +$radix; } return \intval($string, $radix); } } + namespace _ { function pad(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_BOTH); } } + namespace _ { use function _\internal\unicodeWords; const asciiWords = '/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/'; const hasUnicodeWord = '/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/'; function words(string $string, string $pattern = null): array { if (null === $pattern) { if (\preg_match(hasUnicodeWord, $string)) { return unicodeWords($string); } \preg_match_all(asciiWords, $string, $matches); return $matches[0] ?? []; } if (\preg_match_all($pattern, $string, $matches) > 0) { return $matches[0]; } return []; } } + namespace _ { function unescape(string $string): string { return \html_entity_decode($string); } } + namespace _ { function startCase(string $string) { return \implode(' ', \array_map('\ucfirst', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } + namespace _ { function replace(string $string, string $pattern, $replacement = ''): string { $callback = function (array $matches) use ($replacement): ?string { if (!\array_filter($matches)) { return null; } return $replacement(...$matches); }; if (\preg_match(reRegExpChar, $pattern)) { if (!is_callable($replacement)) { return \preg_replace($pattern, $replacement, $string); } return \preg_replace_callback($pattern, $callback, $string); } return \str_replace($pattern, $replacement, $string); } } + namespace _ { function snakeCase(string $string): string { return \implode('_', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } + namespace _ { const reRegExpChar = '/([\\^$.*+?()[\]{}|])/'; function escapeRegExp(string $string): string { return \preg_replace(reRegExpChar, '\\\$0', $string); } } + namespace _ { function toUpper(string $string): string { return \strtoupper($string); } } + namespace _ { function startsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? 0 : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } + namespace _ { function capitalize(string $string): string { return \ucfirst(\mb_strtolower($string)); } } + namespace _ { use function _\internal\castSlice; use function _\internal\hasUnicode; use function _\internal\stringSize; use function _\internal\stringToArray; const DEFAULT_TRUNC_LENGTH = 30; const DEFAULT_TRUNC_OMISSION = '...'; function truncate($string, array $options = []) { $separator = $options['separator'] ?? null; $length = $options['length'] ?? DEFAULT_TRUNC_LENGTH; $omission = $options['omission'] ?? DEFAULT_TRUNC_OMISSION; $strSymbols = null; $strLength = \strlen($string); if (hasUnicode($string)) { $strSymbols = stringToArray($string); $strLength = \count($strSymbols); } if ($length >= $strLength) { return $string; } $end = $length - stringSize($omission); if ($end < 1) { return $omission; } $result = $strSymbols ? \implode('', castSlice($strSymbols, 0, $end)) : \substr($string, 0, $end); if (null === $separator) { return $result.$omission; } if ($strSymbols) { $end += \strlen($result) - $end; } if (\preg_match(reRegExpChar, $separator)) { if (\preg_match($separator, \substr($string, 0, $end))) { $match = null; $newEnd = null; $substring = $result; if (\preg_match_all($separator, $substring, $match, PREG_OFFSET_CAPTURE)) { $newEnd = \end($match[0])[1]; } $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if ($index > -1) { $result = \substr($result, 0, $index); } } return $result.$omission; } } + namespace _ { function upperCase(string $string) { return \implode(' ', \array_map('\strtoupper', words(\preg_replace(reQuotes, '', $string)))); } } + namespace _ { function endsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? $length : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } $position -= \strlen($target); return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } + namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) use (&$options) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } + namespace _ { function padEnd(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_RIGHT); } } + namespace _ { function split(string $string, string $separator, int $limit = null): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE); } $result = \explode($separator, $string); if ($limit > 0) { return \array_splice($result, 0, $limit); } return $result; } } + namespace _ { function toLower(string $string): string { return \strtolower($string); } } + namespace _ { function escape(string $string) { return \htmlentities($string); } } + namespace _ { function kebabCase(string $string) { return \implode('-', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } + namespace _ { use _\internal\Traits\CacheDataTrait; use function _\internal\assocIndexOf; final class ListCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { ++$this->size; $this->__data__[] = [$key, $value]; } else { $this->__data__[$index][1] = $value; } return $this; } final public function get($key) { $index = assocIndexOf($this->__data__, $key); return $index < 0 ? null : $this->__data__[$index][1]; } final public function has($key): bool { return assocIndexOf($this->__data__, $key) > -1; } final public function clear() { $this->__data__ = []; $this->size = 0; } final public function delete($key) { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { return false; } $lastIndex = \count($this->__data__) - 1; if ($index === $lastIndex) { \array_pop($data); } else { \array_splice($this->__data__, $index, 1); } --$this->size; return true; } } } \ No newline at end of file From a86152633b5198e4345c4ac9f845756f6250ce4e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 10:31:54 +0200 Subject: [PATCH 066/159] Replace object type-hint to support PHP < 7.2 --- src/Array/zipObjectDeep.php | 2 +- src/compiled.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Array/zipObjectDeep.php b/src/Array/zipObjectDeep.php index 88a6ea9..b21f4a6 100644 --- a/src/Array/zipObjectDeep.php +++ b/src/Array/zipObjectDeep.php @@ -41,7 +41,7 @@ * *\/ * */ -function zipObjectDeep(array $props = [], array $values = []): object +function zipObjectDeep(array $props = [], array $values = []): \stdClass { $result = new \stdClass; $index = -1; diff --git a/src/compiled.php b/src/compiled.php index cc476d2..88acbb6 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -35,7 +35,7 @@ namespace _ { function attempt(callable $func, ...$args) { try { return $func(...$args); } catch (\ParseError | \Error | \Throwable | \SoapFault | \DOMException | \PDOException $e) { return $e; } } } namespace _ { use function _\internal\baseFlatten; function flattenDepth(array $array, int $depth = 1): array { return baseFlatten($array, $depth); } } namespace _ { function difference(array $array, array ...$values): array { return \array_values(\array_diff($array, ...$values)); } } - namespace _ { use function _\internal\baseSet; function zipObjectDeep(array $props = [], array $values = []): object { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; baseSet($result, $props[$index], $value); } return $result; } } + namespace _ { use function _\internal\baseSet; function zipObjectDeep(array $props = [], array $values = []): \stdClass { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; baseSet($result, $props[$index], $value); } return $result; } } namespace _ { use function _\internal\baseIteratee; function findLastIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); $index = $fromIndex ?? $length - 1; if ($index < 0) { $index = \max($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach (\array_reverse($array, true) as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index--; } return -1; } } namespace _ { function lastIndexOf(array $array, $value, int $fromIndex = null): int { $index = \count($array) - 1; if (null !== $fromIndex) { $index = $fromIndex > 0 ? $fromIndex : \count($array) - 1; $array = \array_slice($array, 0, -$fromIndex + 1); }; foreach (\array_reverse($array, false) as $v) { if (isEqual($value, $v)) { return $index; } $index--; } return -1; } } namespace _ { use function _\internal\baseIteratee; use function _\internal\basePullAll; function pullAllBy(array &$array, array $values, $iteratee): array { return basePullAll($array, $values, baseIteratee($iteratee)); } } From 0661eee9171989a8790ccf14e4150efaf8baaf4e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 14 Aug 2018 12:35:31 +0200 Subject: [PATCH 067/159] Add Object.pick and Object.pickBy functions --- src/Object/pick.php | 38 +++++++++++++++++++++++++ src/Object/pickBy.php | 49 ++++++++++++++++++++++++++++++++ src/compiled.php | 10 ++++++- src/internal/arrayPush.php | 25 ++++++++++++++++ src/internal/baseFlatten.php | 2 +- src/internal/baseGet.php | 28 ++++++++++++++++++ src/internal/basePick.php | 19 +++++++++++++ src/internal/basePickBy.php | 30 +++++++++++++++++++ src/internal/flatRest.php | 17 +++++++++++ src/internal/shortOut.php | 48 +++++++++++++++++++++++++++++++ tests/Array/DifferenceByTest.php | 2 +- tests/Object/PickByTest.php | 23 +++++++++++++++ tests/Object/PickTest.php | 24 ++++++++++++++++ 13 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 src/Object/pick.php create mode 100644 src/Object/pickBy.php create mode 100644 src/internal/arrayPush.php create mode 100644 src/internal/baseGet.php create mode 100644 src/internal/basePick.php create mode 100644 src/internal/basePickBy.php create mode 100644 src/internal/flatRest.php create mode 100644 src/internal/shortOut.php create mode 100644 tests/Object/PickByTest.php create mode 100644 tests/Object/PickTest.php diff --git a/src/Object/pick.php b/src/Object/pick.php new file mode 100644 index 0000000..ba4b08d --- /dev/null +++ b/src/Object/pick.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _; + +use function _\internal\basePick; +use function _\internal\flatRest; + +/** + * Creates an object composed of the picked `object` properties. + * + * @category Object + * + * @param object $object The source object. + * @param string|string[] $paths The property paths to pick. + * + * @return \stdClass Returns the new object. + * @example + * + * $object = (object) ['a' => 1, 'b' => '2', 'c' => 3]; + * + * pick($object, ['a', 'c']); + * // => (object) ['a' => 1, 'c' => 3] + */ +function pick($object, $paths): \stdClass +{ + return flatRest(function ($object, ...$paths) { + return basePick($object, $paths); + })($object, $paths); +} \ No newline at end of file diff --git a/src/Object/pickBy.php b/src/Object/pickBy.php new file mode 100644 index 0000000..97befb7 --- /dev/null +++ b/src/Object/pickBy.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\arrayMap; +use function _\internal\baseIteratee; +use function _\internal\basePickBy; + +/** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @category Object + * + * @param object $object The source object. + * @param callable $predicate The function invoked per property. + * + * @return \stdClass Returns the new object. + * @example + * + * $object = (object) ['a' => 1, 'b' => 'abc', 'c' => 3]; + * + * pickBy(object, 'is_numeric'); + * // => (object) ['a' => 1, 'c' => 3] + */ +function pickBy($object, callable $predicate): \stdClass +{ + if (null === $object) { + return new \stdClass; + } + + $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { + return [$prop]; + }); + $predicate = baseIteratee($predicate); + + return basePickBy($object, $props, function ($value, $path) use ($predicate) { + return $predicate($value, $path[0]); + }); +} \ No newline at end of file diff --git a/src/compiled.php b/src/compiled.php index 88acbb6..338f855 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -96,11 +96,13 @@ namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $start = max($start ?? -1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs[$start]); }; } } namespace _\internal\Traits { trait CacheDataTrait { private $__data__; private $size; public function getSize(): int { return $this->size; } } } namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } + namespace _\internal { function flatRest(callable $func): callable { return shortOut(overRest($func, null, '\_\flatten')); } } namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } namespace _\internal { function unicodeSize($string): int { return \preg_match_all(reUnicode, $string); } } + namespace _\internal { use function _\property; function baseGet($object, $path) { $path = castPath($path, $object); $index = 0; $length = \count($path); while ($object !== null && $index < $length) { $object = property(toKey($path[$index++]))($object); } return ($index && $index === $length) ? $object : null; } } namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\internal\baseIndexOfWith' : '_\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } - namespace _\internal { function baseFlatten(?array $array, float $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '\_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { $result = \array_merge($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } + namespace _\internal { function baseFlatten(?array $array, float $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '\_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { arrayPush($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); } } namespace _\internal { function arrayIncludesWith(?array $array, $value, callable $comparator) { $array = $array ?? []; foreach ($array as $v) { if ($comparator($value, $v)) { return true; } } return false; } } @@ -109,6 +111,7 @@ namespace _\internal { use function _\isEqual; use function _\property; function baseMatchesProperty($property, $source): callable { return function ($value, $index, $collection) use ($property, $source) { return isEqual(property($property)($value, $index, $collection), $source); }; } } namespace _\internal { function castPath($value, $object): array { if (\is_array($value)) { return $value; } return isKey($value, $object) ? [$value] : stringToPath((string) $value); } } namespace _\internal { use function _\map; use function _\sortBy; function baseOrderBy(iterable $collection, array $iteratees, array $orders): array { $index = -1; $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); $result = map($collection, function ($value) use ($iteratees, &$index) { $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { return $iteratee($value); }); return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; }); return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); } } + namespace _\internal { const HOT_COUNT = 800; const HOT_SPAN = 16; function shortOut(callable $func): callable { $count = 0; $lastCalled = 0; return function () use ($func, &$count, &$lastCalled) { $stamp = microtime(true); $remaining = HOT_SPAN - ($stamp - $lastCalled); $lastCalled = $stamp; if ($remaining > 0) { if (++$count >= HOT_COUNT) { return func_get_arg(0); } } else { $count = 0; } return $func(...func_get_args()); }; } } namespace _\internal { use function _\property; function baseIteratee($value): callable { if (\is_callable($value)) { return $value; } if (null === $value) { return '_\identity'; } if (\is_array($value)) { return 2 === \count($value) && [0, 1] === \array_keys($value) ? baseMatchesProperty($value[0], $value[1]) : baseMatches($value); } return property($value); } } namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } namespace _\internal { use function _\eq; function assocIndexOf(array $array, $key): int { $length = \count($array); while ($length--) { if (eq($array[$length][0], $key)) { return $length; } } return -1; } } @@ -122,6 +125,9 @@ namespace _\internal { function baseSet($object, $path, $value, callable $customizer = null) { if (!\is_object($object)) { return $object; } $path = castPath($path, $object); $index = -1; $length = \count($path); $lastIndex = $length - 1; $nested = $object; while ($nested !== null && ++$index < $length) { $key = toKey($path[$index]); if ($index !== $lastIndex) { $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; if (null === $newValue) { $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); } if (\is_array($nested)) { $nested[$key] = $newValue; } else { $nested->{$key} = $newValue; } if (\is_array($nested)) { $nested = &$nested[$key]; } else { $nested = &$nested->$key; } continue; } $nested->{$key} = $value; } return $object; } } namespace _\internal { function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } } namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return null === $func ? null : $func($object, ...$args); } } + namespace _\internal { function basePickBy($object, $paths, callable $predicate): \stdClass { $index = -1; $length = \is_array($paths) ? \count($paths) : \strlen($paths); $result = new \stdClass(); while (++$index < $length) { $path = $paths[$index]; $value = baseGet($object, $path); if ($predicate($value, $path)) { baseSet($result, castPath($path, $object), $value); } } return $result; } } + namespace _\internal { function arrayPush(&$array, $values) { $index = -1; $length = \is_array($values) ? \count($values) : \strlen($values); $offset = \count($array); while (++$index < $length) { $array[$offset + $index] = $values[$index]; } return $array; } } + namespace _\internal { function basePick($object, $paths): \stdClass { return basePickBy($object, $paths, function($value, $path) use ($object) { return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); }); } } namespace _\internal { const reHasUnicode = '['.rsZWJ.rsAstralRange.rsComboRange.rsVarRange.']'; function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; } } namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count($array); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } @@ -137,6 +143,8 @@ namespace _ { function isError($value): bool { if (!\is_object($value)) { return false; } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; } } namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } namespace _ { function eq($value, $other): bool { return $value === $other; } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseIteratee; use function _\internal\basePickBy; function pickBy($object, callable $predicate): \stdClass { if (null === $object) { return new \stdClass; } $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { return [$prop]; }); $predicate = baseIteratee($predicate); return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); } } + namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, ...$paths) { return basePick($object, $paths); })($object, $paths); } } namespace _ { function lowerFirst(string $string): string { return \lcfirst($string); } } namespace _ { function camelCase(string $string): string { return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); } } namespace _ { function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); } } diff --git a/src/internal/arrayPush.php b/src/internal/arrayPush.php new file mode 100644 index 0000000..d0bb2ec --- /dev/null +++ b/src/internal/arrayPush.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function arrayPush(&$array, $values) +{ + $index = -1; + $length = \is_array($values) ? \count($values) : \strlen($values); + $offset = \count($array); + + while (++$index < $length) { + $array[$offset + $index] = $values[$index]; + } + + return $array; +} \ No newline at end of file diff --git a/src/internal/baseFlatten.php b/src/internal/baseFlatten.php index 482142b..b345a5d 100644 --- a/src/internal/baseFlatten.php +++ b/src/internal/baseFlatten.php @@ -40,7 +40,7 @@ function baseFlatten(?array $array, float $depth, callable $predicate = null, bo // Recursively flatten arrays (susceptible to call stack limits). $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { - $result = \array_merge($result, $value); + arrayPush($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; diff --git a/src/internal/baseGet.php b/src/internal/baseGet.php new file mode 100644 index 0000000..75051df --- /dev/null +++ b/src/internal/baseGet.php @@ -0,0 +1,28 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +use function _\property; + +function baseGet($object, $path) +{ + $path = castPath($path, $object); + + $index = 0; + $length = \count($path); + + while ($object !== null && $index < $length) { + $object = property(toKey($path[$index++]))($object); + } + + return ($index && $index === $length) ? $object : null; +} diff --git a/src/internal/basePick.php b/src/internal/basePick.php new file mode 100644 index 0000000..7542c74 --- /dev/null +++ b/src/internal/basePick.php @@ -0,0 +1,19 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function basePick($object, $paths): \stdClass +{ + return basePickBy($object, $paths, function($value, $path) use ($object) { + return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); + }); +} \ No newline at end of file diff --git a/src/internal/basePickBy.php b/src/internal/basePickBy.php new file mode 100644 index 0000000..ca6fff9 --- /dev/null +++ b/src/internal/basePickBy.php @@ -0,0 +1,30 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function basePickBy($object, $paths, callable $predicate): \stdClass +{ + $index = -1; + $length = \is_array($paths) ? \count($paths) : \strlen($paths); + $result = new \stdClass(); + + while (++$index < $length) { + $path = $paths[$index]; + $value = baseGet($object, $path); + + if ($predicate($value, $path)) { + baseSet($result, castPath($path, $object), $value); + } + } + + return $result; +} \ No newline at end of file diff --git a/src/internal/flatRest.php b/src/internal/flatRest.php new file mode 100644 index 0000000..0cee4a8 --- /dev/null +++ b/src/internal/flatRest.php @@ -0,0 +1,17 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +function flatRest(callable $func): callable +{ + return shortOut(overRest($func, null, '\_\flatten')); +} diff --git a/src/internal/shortOut.php b/src/internal/shortOut.php new file mode 100644 index 0000000..826ac6b --- /dev/null +++ b/src/internal/shortOut.php @@ -0,0 +1,48 @@ + + * @copyright Copyright (c) 2018 + */ + +namespace _\internal; + +const HOT_COUNT = 800; +const HOT_SPAN = 16; + +/** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * + * @param callable $func The function to restrict. + * + * @return callable Returns the new shortable function. + */ +function shortOut(callable $func): callable +{ + $count = 0; + $lastCalled = 0; + + return function () use ($func, &$count, &$lastCalled) { + $stamp = microtime(true); + $remaining = HOT_SPAN - ($stamp - $lastCalled); + + $lastCalled = $stamp; + if ($remaining > 0) { + if (++$count >= HOT_COUNT) { + return func_get_arg(0); + } + } else { + $count = 0; + } + + return $func(...func_get_args()); + }; +} diff --git a/tests/Array/DifferenceByTest.php b/tests/Array/DifferenceByTest.php index ac23860..ac13c82 100644 --- a/tests/Array/DifferenceByTest.php +++ b/tests/Array/DifferenceByTest.php @@ -14,7 +14,7 @@ class DifferenceByTest extends TestCase { - public function testChunk() + public function testDifferenceBy() { $this->assertSame([], differenceBy([])); $this->assertSame([1, 2], differenceBy([1, 2], [3, 4])); diff --git a/tests/Object/PickByTest.php b/tests/Object/PickByTest.php new file mode 100644 index 0000000..0ec887f --- /dev/null +++ b/tests/Object/PickByTest.php @@ -0,0 +1,23 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\pickBy; + +class PickByTest extends TestCase +{ + public function testPick() + { + $object = (object) ['a' => 1, 'b' => '2', 'c' => 3]; + + $this->assertEquals((object) ['a' => 1, 'c' => 3], pickBy($object, function ($value) { return \is_int($value); })); + } +} diff --git a/tests/Object/PickTest.php b/tests/Object/PickTest.php new file mode 100644 index 0000000..3b1f9f4 --- /dev/null +++ b/tests/Object/PickTest.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\pick; + +class PickTest extends TestCase +{ + public function testPick() + { + $object = (object) ['a' => 1, 'b' => '2', 'c' => 3]; + $this->assertEquals((object) ['a' => 1, 'c' => 3], pick($object, ['a', 'c'])); + + $this->assertEquals((object) ['a' => 1], pick($object, 'a')); + } +} From 59367b72c877512c692e359cb5be06e1dbd3013e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 14 Aug 2018 12:38:15 +0200 Subject: [PATCH 068/159] Update README --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.md b/README.md index d61da20..f4257df 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ _::each([1, 2, 3], function (int $item) { - [Lang](#lang) - [Math](#math) - [Number](#number) +- [Object](#object) - [String](#string) - [Util](#util) @@ -2964,6 +2965,63 @@ random(5, true) random(1.2, 5.2) // => a floating-point number between 1.2 and 5.2 ``` +## Object + +### pick + +Creates an object composed of the picked `object` properties. + + + +**Arguments:** + +@param object $object The source object. + +@param string|string[] $paths The property paths to pick. + + + +**Return:** + +@return \stdClass Returns the new object. + +Example: +```php + 1, 'b' => '2', 'c' => 3]; + +pick($object, ['a', 'c']); +// => (object) ['a' => 1, 'c' => 3] +``` +### pickBy + +Creates an object composed of the `object` properties `predicate` returns +truthy for. The predicate is invoked with two arguments: (value, key). + + + +**Arguments:** + +@param object $object The source object. + +@param callable $predicate The function invoked per property. + + + +**Return:** + +@return \stdClass Returns the new object. + +Example: +```php + 1, 'b' => 'abc', 'c' => 3]; + +pickBy(object, 'is_numeric'); +// => (object) ['a' => 1, 'c' => 3] +``` ## String ### camelCase From e2439a7348c6aff38d0f6b728876d84d1ba3cf58 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 09:57:57 +0200 Subject: [PATCH 069/159] Add PHPStan --- .travis.yml | 1 + composer.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 14ba5f4..ba29410 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,3 +34,4 @@ install: script: - vendor/bin/phpunit + - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=1 diff --git a/composer.json b/composer.json index 15fde49..23eba05 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ }, "require-dev": { "phpunit/phpunit": "^6.4 | ^7.0", - "phpdocumentor/reflection-docblock": "^4.2" + "phpdocumentor/reflection-docblock": "^4.2", + "phpstan/phpstan": "^0.10.3" } } From d17c68151fdcbb5fab0899ac90d3280102463fd0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 09:58:36 +0200 Subject: [PATCH 070/159] Fix level 1 violations from phpstan --- src/ListCache.php | 6 +++++- src/String/template.php | 2 +- src/compiled.php | 8 ++++---- src/internal/Traits/CacheDataTrait.php | 2 +- src/internal/parent.php | 4 +--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ListCache.php b/src/ListCache.php index 89afee2..8b9dd05 100644 --- a/src/ListCache.php +++ b/src/ListCache.php @@ -14,6 +14,10 @@ use _\internal\Traits\CacheDataTrait; use function _\internal\assocIndexOf; +/** + * @property $__data__ array + * @property $size int + */ final class ListCache implements CacheInterface { use CacheDataTrait; @@ -71,7 +75,7 @@ final public function delete($key) $lastIndex = \count($this->__data__) - 1; if ($index === $lastIndex) { - \array_pop($data); + \array_pop($this->__data__); } else { \array_splice($this->__data__, $index, 1); } diff --git a/src/String/template.php b/src/String/template.php index f1f99fd..3420116 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -106,7 +106,7 @@ function template(string $string, array $options = []): callable ($options['evaluate'] ?? reNoMatch), ]); - $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) use (&$options) { + $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { list(, $escapeValue, $interpolateValue, diff --git a/src/compiled.php b/src/compiled.php index 88acbb6..2d5fde6 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -94,7 +94,7 @@ namespace _\internal { const rsAstralRange = '\\x{e800}-\\x{efff}'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsDingbatRange = '\\x{2700}-\\x{27bf}'; const rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; const rsMathOpRange = '\\xac\\xb1\\xd7\\xf7'; const rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; const rsPunctuationRange = '\\x{2000}-\\x{206f}'; const rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; const rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; const rsVarRange = '\\x{fe0e}\\x{fe0f}'; const rsBreakRange = rsMathOpRange.rsNonCharRange.rsPunctuationRange.rsSpaceRange; const rsApos = "[\\x{2019}]"; const rsBreak = '['.rsBreakRange.']'; const rsCombo = '['.rsComboRange.']'; const rsDigits = '\\d+'; const rsDingbat = '['.rsDingbatRange.']'; const rsLower = '['.rsLowerRange.']'; const rsMisc = '[^'.rsAstralRange.rsBreakRange.rsDigits.rsDingbatRange.rsLowerRange.rsUpperRange.']'; const rsFitz = '\\x{e83c}[\\x{effb}-\\x{efff}]'; const rsModifier = '(?:'.rsCombo.'|'.rsFitz.')'; const rsNonAstral = '[^'.rsAstralRange.']'; const rsRegional = '(?:\\x{e83c}[\\x{ede6}-\\x{edff}]){2}'; const rsSurrPair = '[\\x{e800}-\\x{ebff}][\\x{ec00}-\\x{efff}]'; const rsUpper = '['.rsUpperRange.']'; const rsZWJ = '\\x{200d}'; const rsMiscLower = '(?:'.rsLower.'|'.rsMisc.')'; const rsMiscUpper = '(?:'.rsUpper.'|'.rsMisc.')'; const rsOptContrLower = '(?:'.rsApos.'(?:d|ll|m|re|s|t|ve))?'; const rsOptContrUpper = '(?:'.rsApos.'(?:D|LL|M|RE|S|T|VE))?'; const reOptMod = rsModifier.'?'; const rsOptVar = '['.rsVarRange.']?'; define('rsOptJoin', '(?:'.rsZWJ.'(?:'.implode('|', [rsNonAstral, rsRegional, rsSurrPair]).')'.rsOptVar.reOptMod.')*'); const rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)'; const rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)'; const rsSeq = rsOptVar.reOptMod.rsOptJoin; define('rsEmoji', '(?:'.implode('|', [rsDingbat, rsRegional, rsSurrPair]).')'.rsSeq); const rsAstral = '['.rsAstralRange.']'; const rsNonAstralCombo = rsNonAstral.rsCombo.'?'; define('rsSymbol', '(?:'.implode('|', [rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral]).')'); const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; } namespace _\internal { function toKey($value): string { if (\is_string($value)) { return $value; } $result = (string) $value; return ('0' === $result && (1 / $value) === -INF) ? '-0' : $result; } } namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $start = max($start ?? -1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs[$start]); }; } } - namespace _\internal\Traits { trait CacheDataTrait { private $__data__; private $size; public function getSize(): int { return $this->size; } } } + namespace _\internal\Traits { trait CacheDataTrait { private $__data__ = []; private $size; public function getSize(): int { return $this->size; } } } namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } @@ -112,7 +112,7 @@ namespace _\internal { use function _\property; function baseIteratee($value): callable { if (\is_callable($value)) { return $value; } if (null === $value) { return '_\identity'; } if (\is_array($value)) { return 2 === \count($value) && [0, 1] === \array_keys($value) ? baseMatchesProperty($value[0], $value[1]) : baseMatches($value); } return property($value); } } namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } namespace _\internal { use function _\eq; function assocIndexOf(array $array, $key): int { $length = \count($array); while ($length--) { if (eq($array[$length][0], $key)) { return $length; } } return -1; } } - namespace _\internal { use function _\{slice, get}; function parent($object, $path) { return count($path) < 2 ? $object : get($object, slice($path, 0, -1)); } } + namespace _\internal { function parent($object, $path) { return count($path) < 2 ? $object : null; } } namespace _\internal { use function _\indexOf; function arrayIncludes(?array $array, $value) { return null !== $array && indexOf($array, $value, 0) > -1; } } namespace _\internal { const reLeadingDot = '/^\./'; const rePropName = '#[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["\'])((?:(?!\2)[^\\\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))#'; const reEscapeChar = '/\\(\\)?/g'; function stringToPath(...$args) { return memoizeCapped(function ($string) { $result = []; if (\preg_match(reLeadingDot, $string)) { $result[] = ''; } \preg_match_all(rePropName, $string, $matches, PREG_SPLIT_DELIM_CAPTURE); foreach ($matches as $match) { $result[] = $match[1] ?? $match[0]; } return $result; })(...$args); } } namespace _\internal { function baseUniq(array $array, callable $iteratee = null, callable $comparator = null) { $index = -1; $includes = '\_\internal\arrayIncludes'; $length = \count($array); $isCommon = true; $result = []; $seen = $result; if ($comparator) { $isCommon = false; $includes = '\_\internal\arrayIncludesWith'; } else { $seen = $iteratee ? [] : $result; } while (++$index < $length) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator || $value !== 0) ? $value : 0; if ($isCommon && $computed) { $seenIndex = \count($seen); while ($seenIndex--) { if ($seen[$seenIndex] === $computed) { continue 2; } } if ($iteratee) { $seen[] = $computed; } $result[] = $value; } elseif (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } $result[] = $value; } } return $result; } } @@ -161,10 +161,10 @@ namespace _ { use function _\internal\castSlice; use function _\internal\hasUnicode; use function _\internal\stringSize; use function _\internal\stringToArray; const DEFAULT_TRUNC_LENGTH = 30; const DEFAULT_TRUNC_OMISSION = '...'; function truncate($string, array $options = []) { $separator = $options['separator'] ?? null; $length = $options['length'] ?? DEFAULT_TRUNC_LENGTH; $omission = $options['omission'] ?? DEFAULT_TRUNC_OMISSION; $strSymbols = null; $strLength = \strlen($string); if (hasUnicode($string)) { $strSymbols = stringToArray($string); $strLength = \count($strSymbols); } if ($length >= $strLength) { return $string; } $end = $length - stringSize($omission); if ($end < 1) { return $omission; } $result = $strSymbols ? \implode('', castSlice($strSymbols, 0, $end)) : \substr($string, 0, $end); if (null === $separator) { return $result.$omission; } if ($strSymbols) { $end += \strlen($result) - $end; } if (\preg_match(reRegExpChar, $separator)) { if (\preg_match($separator, \substr($string, 0, $end))) { $match = null; $newEnd = null; $substring = $result; if (\preg_match_all($separator, $substring, $match, PREG_OFFSET_CAPTURE)) { $newEnd = \end($match[0])[1]; } $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if ($index > -1) { $result = \substr($result, 0, $index); } } return $result.$omission; } } namespace _ { function upperCase(string $string) { return \implode(' ', \array_map('\strtoupper', words(\preg_replace(reQuotes, '', $string)))); } } namespace _ { function endsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? $length : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } $position -= \strlen($target); return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } - namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) use (&$options) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } + namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } namespace _ { function padEnd(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_RIGHT); } } namespace _ { function split(string $string, string $separator, int $limit = null): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE); } $result = \explode($separator, $string); if ($limit > 0) { return \array_splice($result, 0, $limit); } return $result; } } namespace _ { function toLower(string $string): string { return \strtolower($string); } } namespace _ { function escape(string $string) { return \htmlentities($string); } } namespace _ { function kebabCase(string $string) { return \implode('-', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } - namespace _ { use _\internal\Traits\CacheDataTrait; use function _\internal\assocIndexOf; final class ListCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { ++$this->size; $this->__data__[] = [$key, $value]; } else { $this->__data__[$index][1] = $value; } return $this; } final public function get($key) { $index = assocIndexOf($this->__data__, $key); return $index < 0 ? null : $this->__data__[$index][1]; } final public function has($key): bool { return assocIndexOf($this->__data__, $key) > -1; } final public function clear() { $this->__data__ = []; $this->size = 0; } final public function delete($key) { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { return false; } $lastIndex = \count($this->__data__) - 1; if ($index === $lastIndex) { \array_pop($data); } else { \array_splice($this->__data__, $index, 1); } --$this->size; return true; } } } \ No newline at end of file + namespace _ { use _\internal\Traits\CacheDataTrait; use function _\internal\assocIndexOf; final class ListCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { ++$this->size; $this->__data__[] = [$key, $value]; } else { $this->__data__[$index][1] = $value; } return $this; } final public function get($key) { $index = assocIndexOf($this->__data__, $key); return $index < 0 ? null : $this->__data__[$index][1]; } final public function has($key): bool { return assocIndexOf($this->__data__, $key) > -1; } final public function clear() { $this->__data__ = []; $this->size = 0; } final public function delete($key) { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { return false; } $lastIndex = \count($this->__data__) - 1; if ($index === $lastIndex) { \array_pop($this->__data__); } else { \array_splice($this->__data__, $index, 1); } --$this->size; return true; } } } \ No newline at end of file diff --git a/src/internal/Traits/CacheDataTrait.php b/src/internal/Traits/CacheDataTrait.php index ceb2e8d..4700cce 100644 --- a/src/internal/Traits/CacheDataTrait.php +++ b/src/internal/Traits/CacheDataTrait.php @@ -13,7 +13,7 @@ trait CacheDataTrait { - private $__data__; + private $__data__ = []; private $size; diff --git a/src/internal/parent.php b/src/internal/parent.php index cc246b7..815b452 100644 --- a/src/internal/parent.php +++ b/src/internal/parent.php @@ -11,9 +11,7 @@ namespace _\internal; -use function _\{slice, get}; - function parent($object, $path) { - return count($path) < 2 ? $object : get($object, slice($path, 0, -1)); + return count($path) < 2 ? $object : null; } \ No newline at end of file From d006c220fd0a4fc69c1d67e1972169a4cded8d12 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:04:01 +0200 Subject: [PATCH 071/159] Add PHPStan config --- phpstan.neon | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 phpstan.neon diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..352548d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon + +parameters: + bootstrap: %rootDir%/../../../src/bootstrap.php + excludes_analyse: + - %rootDir%/../../../src/compiled.php From fd8d24373071e789d45dfb36e50aa4e8eefb0b45 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:05:59 +0200 Subject: [PATCH 072/159] Remove phpstan/phpstan-strict-rules --- phpstan.neon | 3 --- 1 file changed, 3 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 352548d..68dead2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,3 @@ -includes: - - vendor/phpstan/phpstan-strict-rules/rules.neon - parameters: bootstrap: %rootDir%/../../../src/bootstrap.php excludes_analyse: From 7485a26ab0ba3855059736a29590e52ad094090b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:07:44 +0200 Subject: [PATCH 073/159] Exclude file from phpstan analysis --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index 68dead2..99bc546 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,3 +2,4 @@ parameters: bootstrap: %rootDir%/../../../src/bootstrap.php excludes_analyse: - %rootDir%/../../../src/compiled.php + - %rootDir%/../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage From fe008fdbaf291529721475efea778ef5c03b58e0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:11:08 +0200 Subject: [PATCH 074/159] Use larger array for _\shuffle tests --- tests/Collection/ShuffleTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Collection/ShuffleTest.php b/tests/Collection/ShuffleTest.php index 18890b6..567a093 100644 --- a/tests/Collection/ShuffleTest.php +++ b/tests/Collection/ShuffleTest.php @@ -16,7 +16,8 @@ class ShuffleTest extends TestCase { public function testShuffle() { - $this->assertNotSame([1, 2, 3, 4], shuffle([1, 2, 3, 4])); - $this->assertSame([], \array_diff([1, 2, 3, 4], shuffle([1, 2, 3, 4]))); + $arr = range(1, 10); + $this->assertNotSame($arr, shuffle($arr)); + $this->assertSame([], \array_diff($arr, shuffle($arr))); } } \ No newline at end of file From 936c10172b6f2815e8af2e45d9e93625bff6ca3b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:45:37 +0200 Subject: [PATCH 075/159] Fix docblocks and update PHPStan level to 2 --- .travis.yml | 2 +- phpstan.neon | 3 +++ src/Array/concat.php | 5 +++-- src/Array/difference.php | 4 ++-- src/Array/differenceBy.php | 8 ++++---- src/Array/differenceWith.php | 4 ++-- src/Array/fromPairs.php | 3 ++- src/Array/intersection.php | 6 ++++-- src/Array/intersectionBy.php | 4 ++-- src/Array/intersectionWith.php | 3 ++- src/Array/pull.php | 5 +++-- src/Array/union.php | 2 +- src/Array/unionBy.php | 6 +++--- src/Array/unionWith.php | 4 ++-- src/Array/without.php | 4 ++-- src/Array/zip.php | 2 +- src/Array/zipObjectDeep.php | 3 ++- src/Array/zipWith.php | 4 ++-- src/Collection/flatMap.php | 3 ++- src/Collection/flatMapDeep.php | 2 +- src/Collection/flatMapDepth.php | 2 +- src/Collection/groupBy.php | 2 +- src/ListCache.php | 4 ++-- src/Math/max.php | 2 +- src/Number/clamp.php | 6 +++--- src/Number/inRange.php | 3 ++- src/String/replace.php | 6 +++--- src/String/split.php | 2 +- src/Util/attempt.php | 2 +- src/Util/property.php | 2 +- src/internal/baseFlatten.php | 2 +- src/internal/basePullAll.php | 2 +- src/internal/isKey.php | 2 +- src/internal/stringSize.php | 2 +- src/internal/toKey.php | 2 +- src/internal/unicodeWords.php | 3 ++- 36 files changed, 67 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba29410..c3dcac7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,4 +34,4 @@ install: script: - vendor/bin/phpunit - - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=1 + - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=2 diff --git a/phpstan.neon b/phpstan.neon index 99bc546..235c766 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,3 +3,6 @@ parameters: excludes_analyse: - %rootDir%/../../../src/compiled.php - %rootDir%/../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage + ignoreErrors: + - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' + - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" diff --git a/src/Array/concat.php b/src/Array/concat.php index fe84ff0..04a800b 100644 --- a/src/Array/concat.php +++ b/src/Array/concat.php @@ -17,8 +17,9 @@ * * @category Array * - * @param array $array The array to concatenate. - * @param mixed $values The values to concatenate. + * @param array $array The array to concatenate. + * @param array $values The values to concatenate. + * * @return array Returns the new concatenated array. * * @example diff --git a/src/Array/difference.php b/src/Array/difference.php index 9bdba36..22c779c 100644 --- a/src/Array/difference.php +++ b/src/Array/difference.php @@ -21,8 +21,8 @@ * * @category Array * - * @param array $array The array to inspect. - * @param mixed[] $values The values to exclude. + * @param array $array The array to inspect. + * @param array ...$values The values to exclude. * * @return array Returns the new array of filtered values. * diff --git a/src/Array/differenceBy.php b/src/Array/differenceBy.php index 89a7492..b516ef9 100644 --- a/src/Array/differenceBy.php +++ b/src/Array/differenceBy.php @@ -24,9 +24,9 @@ * * @category Array * - * @param array $array The array to inspect. - * @param array $values The values to exclude. - * @param callable iteratee The iteratee invoked per element. + * @param array $array The array to inspect. + * @param array ...$values The values to exclude. + * @param callable $iteratee The iteratee invoked per element. * * @return array Returns the new array of filtered values. * @@ -35,7 +35,7 @@ * differenceBy([2.1, 1.2], [2.3, 3.4], 'floor') * // => [1.2] */ -function differenceBy(array $array, ...$values): array +function differenceBy(array $array, array ...$values): array { if (!$array) { return []; diff --git a/src/Array/differenceWith.php b/src/Array/differenceWith.php index e77725e..3758e70 100644 --- a/src/Array/differenceWith.php +++ b/src/Array/differenceWith.php @@ -24,7 +24,7 @@ * @category Array * * @param array $array The array to inspect. - * @param array[] $values The values to exclude. + * @param array ...$values The values to exclude. * @param callable $comparator The comparator invoked per element. * * @return array Returns the new array of filtered values. @@ -36,7 +36,7 @@ * // => [[ 'x' => 2, 'y' => 1 ]] * */ -function differenceWith(array $array, ...$values): array +function differenceWith(array $array, array ...$values): array { if (!$array) { return []; diff --git a/src/Array/fromPairs.php b/src/Array/fromPairs.php index d9dcfbb..7541e04 100644 --- a/src/Array/fromPairs.php +++ b/src/Array/fromPairs.php @@ -19,7 +19,8 @@ * * @param array $pairs The key-value pairs. * - * @return object the new object. + * @return \stdClass the new object. + * * @example * * fromPairs([['a', 1], ['b', 2]]) diff --git a/src/Array/intersection.php b/src/Array/intersection.php index d0b7186..6d05520 100644 --- a/src/Array/intersection.php +++ b/src/Array/intersection.php @@ -19,13 +19,15 @@ * * @category Array * - * @param array[] $arrays + * @param array ...$arrays * * @return array the new array of intersecting values. - * @example * + * @example + * * intersection([2, 1], [2, 3]) * // => [2] + * */ function intersection(array ...$arrays): array { diff --git a/src/Array/intersectionBy.php b/src/Array/intersectionBy.php index 066a2a3..b560306 100644 --- a/src/Array/intersectionBy.php +++ b/src/Array/intersectionBy.php @@ -23,7 +23,7 @@ * * @category Array * - * @param array[] $arrays + * @param array ...$arrays * @param callable $iteratee The iteratee invoked per element. * * @return array the new array of intersecting values. @@ -37,7 +37,7 @@ * // => [[ 'x' => 1 ]] * */ -function intersectionBy(...$arrays/*, callable $iteratee*/): array +function intersectionBy(array ...$arrays/*, callable $iteratee*/): array { $iteratee = \array_pop($arrays); diff --git a/src/Array/intersectionWith.php b/src/Array/intersectionWith.php index 330413a..69bb91f 100644 --- a/src/Array/intersectionWith.php +++ b/src/Array/intersectionWith.php @@ -21,10 +21,11 @@ * * @category Array * - * @param array[] $arrays + * @param array ...$arrays * @param callable $comparator The comparator invoked per element. * * @return array the new array of intersecting values. + * * @example * * $objects = [[ 'x' => 1, 'y' => 2 ], [ 'x' => 2, 'y' => 1 ]] diff --git a/src/Array/pull.php b/src/Array/pull.php index 8ad6e98..f585be2 100644 --- a/src/Array/pull.php +++ b/src/Array/pull.php @@ -21,10 +21,11 @@ * * @category Array * - * @param array $array The array to modify. - * @param mixed[] $values The values to remove. + * @param array $array The array to modify. + * @param array $values The values to remove. * * @return array + * * @example * * $array = ['a', 'b', 'c', 'a', 'b', 'c'] diff --git a/src/Array/union.php b/src/Array/union.php index d8aebcb..e02f4f7 100644 --- a/src/Array/union.php +++ b/src/Array/union.php @@ -18,7 +18,7 @@ * * @category Array * - * @param array[] $arrays The arrays to inspect. + * @param array ...$arrays The arrays to inspect. * * @return array the new array of combined values. * diff --git a/src/Array/unionBy.php b/src/Array/unionBy.php index a8f0dc6..d9fe6b8 100644 --- a/src/Array/unionBy.php +++ b/src/Array/unionBy.php @@ -24,8 +24,8 @@ * * @category Array * - * @param array[] $arrays The arrays to inspect. - * @param callable $iteratee The iteratee invoked per element. + * @param array ...$arrays The arrays to inspect. + * @param callable $iteratee The iteratee invoked per element. * * @return array the new array of combined values. * @@ -39,7 +39,7 @@ * // => [['x' => 1], ['x' => 2]] * */ -function unionBy(...$arrays): array +function unionBy(array ...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } diff --git a/src/Array/unionWith.php b/src/Array/unionWith.php index 5ac71d9..d213e53 100644 --- a/src/Array/unionWith.php +++ b/src/Array/unionWith.php @@ -22,7 +22,7 @@ * * @category Array * - * @param array[] $arrays The arrays to inspect. + * @param array ...$arrays The arrays to inspect. * @param callable $comparator The comparator invoked per element. * * @return array the new array of combined values. @@ -34,7 +34,7 @@ * unionWith($objects, $others, '_::isEqual') * // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] */ -function unionWith(... $arrays): array +function unionWith(array ... $arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); } diff --git a/src/Array/without.php b/src/Array/without.php index ed367ff..1528bef 100644 --- a/src/Array/without.php +++ b/src/Array/without.php @@ -22,8 +22,8 @@ * * @category Array * - * @param array $array The array to inspect. - * @param mixed[] $values The values to exclude. + * @param array $array The array to inspect. + * @param array $values The values to exclude. * * @return array the new array of filtered values. * @example diff --git a/src/Array/zip.php b/src/Array/zip.php index c163319..b234e4c 100644 --- a/src/Array/zip.php +++ b/src/Array/zip.php @@ -20,7 +20,7 @@ * * @category Array * - * @param array[] $arrays The arrays to process. + * @param array ...$arrays The arrays to process. * * @return array the new array of grouped elements. * @example diff --git a/src/Array/zipObjectDeep.php b/src/Array/zipObjectDeep.php index b21f4a6..dd8defc 100644 --- a/src/Array/zipObjectDeep.php +++ b/src/Array/zipObjectDeep.php @@ -21,7 +21,8 @@ * @param array $props The property identifiers. * @param array $values The property values. * - * @return object the new object. + * @return \stdClass the new object. + * * @example * * zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]) diff --git a/src/Array/zipWith.php b/src/Array/zipWith.php index b30bf7f..d97d0ca 100644 --- a/src/Array/zipWith.php +++ b/src/Array/zipWith.php @@ -18,7 +18,7 @@ * * @category Array * - * @param array[] $arrays The arrays to process. + * @param array ...$arrays The arrays to process. * @param callable $iteratee The function to combine grouped values. * * @return array the new array of grouped elements. @@ -28,7 +28,7 @@ * // => [111, 222] * */ -function zipWith(...$arrays): array +function zipWith(array ...$arrays): array { $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; diff --git a/src/Collection/flatMap.php b/src/Collection/flatMap.php index 2fe47f0..cec9217 100644 --- a/src/Collection/flatMap.php +++ b/src/Collection/flatMap.php @@ -20,10 +20,11 @@ * * @category Collection * - * @param iterable collection The collection to iterate over. + * @param iterable $collection The collection to iterate over. * @param callable $iteratee The function invoked per iteration. * * @return array the new flattened array. + * * @example * * function duplicate($n) { diff --git a/src/Collection/flatMapDeep.php b/src/Collection/flatMapDeep.php index 5b1a34c..85a40d0 100644 --- a/src/Collection/flatMapDeep.php +++ b/src/Collection/flatMapDeep.php @@ -19,7 +19,7 @@ * * @category Collection * - * @param iterable collection The collection to iterate over. + * @param iterable $collection The collection to iterate over. * @param callable $iteratee The function invoked per iteration. * * @return array Returns the new flattened array. diff --git a/src/Collection/flatMapDepth.php b/src/Collection/flatMapDepth.php index 835ac24..a02e995 100644 --- a/src/Collection/flatMapDepth.php +++ b/src/Collection/flatMapDepth.php @@ -19,7 +19,7 @@ * * @category Collection * - * @param iterable collection The collection to iterate over. + * @param iterable $collection The collection to iterate over. * @param callable $iteratee The function invoked per iteration. * @param int $depth The maximum recursion depth. * diff --git a/src/Collection/groupBy.php b/src/Collection/groupBy.php index 2a9602e..fab80a7 100644 --- a/src/Collection/groupBy.php +++ b/src/Collection/groupBy.php @@ -22,7 +22,7 @@ * * @category Collection * - * @param iterable collection The collection to iterate over. + * @param iterable $collection The collection to iterate over. * @param callable $iteratee The iteratee to transform keys. * * @return array Returns the composed aggregate object. diff --git a/src/ListCache.php b/src/ListCache.php index 8b9dd05..0c8931d 100644 --- a/src/ListCache.php +++ b/src/ListCache.php @@ -15,8 +15,8 @@ use function _\internal\assocIndexOf; /** - * @property $__data__ array - * @property $size int + * @property array $__data__ + * @property int $size */ final class ListCache implements CacheInterface { diff --git a/src/Math/max.php b/src/Math/max.php index c454d02..8699924 100644 --- a/src/Math/max.php +++ b/src/Math/max.php @@ -16,7 +16,7 @@ * * @category Math * - * @param array array The array to iterate over. + * @param array|null $array The array to iterate over. * * @return int|null Returns the maximum value. * @example diff --git a/src/Number/clamp.php b/src/Number/clamp.php index d2c2993..2ab5ddc 100644 --- a/src/Number/clamp.php +++ b/src/Number/clamp.php @@ -16,9 +16,9 @@ * * @category Number * - * @param int number The number to clamp. - * @param int lower The lower bound. - * @param int upper The upper bound. + * @param int $number The number to clamp. + * @param int $lower The lower bound. + * @param int $upper The upper bound. * * @return int Returns the clamped number. * diff --git a/src/Number/inRange.php b/src/Number/inRange.php index ac58b20..fae0374 100644 --- a/src/Number/inRange.php +++ b/src/Number/inRange.php @@ -19,11 +19,12 @@ * * @category Number * - * @param float number The number to check. + * @param float $number The number to check. * @param float $start The start of the range. * @param float $end The end of the range. * * @return boolean Returns `true` if `number` is in the range, else `false`. + * * @example * * inRange(3, 2, 4) diff --git a/src/String/replace.php b/src/String/replace.php index a19f5bb..a7a2242 100644 --- a/src/String/replace.php +++ b/src/String/replace.php @@ -19,9 +19,9 @@ * * @category String * - * @param string $string The string to modify. - * @param string $pattern The pattern to replace. - * @param callable|string replacement The match replacement. + * @param string $string The string to modify. + * @param string $pattern The pattern to replace. + * @param callable|string $replacement The match replacement. * * @return string Returns the modified string. * diff --git a/src/String/split.php b/src/String/split.php index 0f3b06c..e6a1c8f 100644 --- a/src/String/split.php +++ b/src/String/split.php @@ -19,7 +19,7 @@ * * @category String * - * @param string string The string to split. + * @param string $string The string to split. * @param string $separator The separator pattern to split by. * @param int $limit The length to truncate results to. * diff --git a/src/Util/attempt.php b/src/Util/attempt.php index c104d41..2b1895b 100644 --- a/src/Util/attempt.php +++ b/src/Util/attempt.php @@ -18,7 +18,7 @@ * @category Util * * @param callable $func The function to attempt. - * @param mixed[] $args The arguments to invoke `func` with. + * @param array $args The arguments to invoke `func` with. * * @return mixed|\Throwable Returns the `func` result or error object. * diff --git a/src/Util/property.php b/src/Util/property.php index b44f40a..1bc0f40 100644 --- a/src/Util/property.php +++ b/src/Util/property.php @@ -18,7 +18,7 @@ * * @category Util * - * @param array|string path The path of the property to get. + * @param array|string $path The path of the property to get. * * @return callable Returns the new accessor function. * @example diff --git a/src/internal/baseFlatten.php b/src/internal/baseFlatten.php index 482142b..a623260 100644 --- a/src/internal/baseFlatten.php +++ b/src/internal/baseFlatten.php @@ -24,7 +24,7 @@ * * @return array Returns the new flattened array. */ -function baseFlatten(?array $array, float $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array +function baseFlatten(?array $array, int $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; diff --git a/src/internal/basePullAll.php b/src/internal/basePullAll.php index f4d0c12..9b69ae3 100644 --- a/src/internal/basePullAll.php +++ b/src/internal/basePullAll.php @@ -13,7 +13,7 @@ function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { - $indexOf = $comparator ? '_\internal\baseIndexOfWith' : '_\indexOf'; + $indexOf = $comparator ? '_\\internal\\baseIndexOfWith' : '_\\indexOf'; $seen = $array; diff --git a/src/internal/isKey.php b/src/internal/isKey.php index 4d99db8..bb0ce5b 100644 --- a/src/internal/isKey.php +++ b/src/internal/isKey.php @@ -18,7 +18,7 @@ /** * Checks if `value` is a property name and not a property path. * - * @param mixed value The value to check. + * @param mixed $value The value to check. * @param object|array $object The object to query keys on. * * @return boolean Returns `true` if `value` is a property name, else `false`. diff --git a/src/internal/stringSize.php b/src/internal/stringSize.php index b8b377e..10efb63 100644 --- a/src/internal/stringSize.php +++ b/src/internal/stringSize.php @@ -16,7 +16,7 @@ * * @private * - * @param string string The string to inspect. + * @param string $string The string to inspect. * * @return int Returns the string size. */ diff --git a/src/internal/toKey.php b/src/internal/toKey.php index b491944..d7a8117 100644 --- a/src/internal/toKey.php +++ b/src/internal/toKey.php @@ -14,7 +14,7 @@ /** * Converts `value` to a string key if it's not a string. * - * @param mixed value The value to inspect. + * @param mixed $value The value to inspect. * * @return string Returns the key. */ diff --git a/src/internal/unicodeWords.php b/src/internal/unicodeWords.php index a962b41..9f2a0c3 100644 --- a/src/internal/unicodeWords.php +++ b/src/internal/unicodeWords.php @@ -16,7 +16,8 @@ * * @private * - * @param string The string to inspect. + * @param string $string The string to inspect. + * * @return array Returns the words of `string`. */ function unicodeWords(string $string): array From db19c7d83330b02060c28dad6372d704034133a7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 10:57:58 +0200 Subject: [PATCH 076/159] Bump PHPStan level to 4 --- .travis.yml | 2 +- src/Array/unzipWith.php | 2 +- src/Collection/orderBy.php | 6 +++--- src/Collection/sortBy.php | 6 +++--- src/Function/memoize.php | 2 +- src/Number/inRange.php | 6 +++--- src/Number/random.php | 6 +++--- src/internal/baseFlatten.php | 12 ++++++------ src/internal/baseIntersection.php | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index c3dcac7..7588997 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,4 +34,4 @@ install: script: - vendor/bin/phpunit - - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=2 + - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=4 diff --git a/src/Array/unzipWith.php b/src/Array/unzipWith.php index fc9a5ca..4aa6910 100644 --- a/src/Array/unzipWith.php +++ b/src/Array/unzipWith.php @@ -40,7 +40,7 @@ function unzipWith(array $array, callable $iteratee): array } $result = unzip($array); - if (null === $iteratee) { + if (!is_callable($iteratee)) { return $result; } diff --git a/src/Collection/orderBy.php b/src/Collection/orderBy.php index 548ccb3..aec6d62 100644 --- a/src/Collection/orderBy.php +++ b/src/Collection/orderBy.php @@ -21,7 +21,7 @@ * * @category Collection * - * @param iterable $collection The collection to iterate over. + * @param iterable|null $collection The collection to iterate over. * @param array[]|callable[]|string[] $iteratee The iteratee(s) to sort by. * @param string[] $orders The sort orders of `iteratees`. * @@ -40,11 +40,11 @@ * // => [['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]] * */ -function orderBy(?iterable $collection, $iteratee, $orders): array +function orderBy(?iterable $collection, array $iteratee, array $orders): array { if (null === $collection) { return []; } - return baseOrderBy($collection, (array) $iteratee, (array) $orders); + return baseOrderBy($collection, $iteratee, $orders); } \ No newline at end of file diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index 881bab4..404c38d 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -21,8 +21,8 @@ * * @category Collection * - * @param array|object $collection The collection to iterate over. - * @param callable|callable[] $iteratees The iteratees to sort by. + * @param array|object|null $collection The collection to iterate over. + * @param callable|callable[] $iteratees The iteratees to sort by. * * @return array Returns the new sorted array. * @example @@ -41,7 +41,7 @@ * // => [['user' => 'barney', 'age' => 34], ['user' => 'barney', 'age' => 36], ['user' => 'fred', 'age' => 40], ['user' => 'fred', 'age' => 48]] * */ -function sortBy($collection, $iteratees) +function sortBy($collection, $iteratees): array { if (null === $collection) { return []; diff --git a/src/Function/memoize.php b/src/Function/memoize.php index e32658d..6fa4df4 100644 --- a/src/Function/memoize.php +++ b/src/Function/memoize.php @@ -87,7 +87,7 @@ public function __invoke() } $result = ($this->func)(...$args); - $this->cache = $this->cache->set($key, $result) ?: $this->cache; + $this->cache = $this->cache->set($key, $result); return $result; } diff --git a/src/Number/inRange.php b/src/Number/inRange.php index fae0374..f1408ae 100644 --- a/src/Number/inRange.php +++ b/src/Number/inRange.php @@ -20,8 +20,8 @@ * @category Number * * @param float $number The number to check. - * @param float $start The start of the range. - * @param float $end The end of the range. + * @param float $start The start of the range. + * @param float $end The end of the range. * * @return boolean Returns `true` if `number` is in the range, else `false`. * @@ -51,7 +51,7 @@ */ function inRange(float $number, float $start = 0, float $end = 0): bool { - if (0 === $end || 0.0 === $end) { + if (0.0 === $end) { $end = $start; $start = 0; } diff --git a/src/Number/random.php b/src/Number/random.php index 1bf799d..92b3600 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -19,9 +19,9 @@ * * @category Number * - * @param int|float $lower The lower bound. - * @param int|float $upper The upper bound. - * @param bool $floating Specify returning a floating-point number. + * @param int|float|bool $lower The lower bound. + * @param int|float|bool $upper The upper bound. + * @param bool|null $floating Specify returning a floating-point number. * * @return int|float Returns the random number. * diff --git a/src/internal/baseFlatten.php b/src/internal/baseFlatten.php index a623260..cc37e81 100644 --- a/src/internal/baseFlatten.php +++ b/src/internal/baseFlatten.php @@ -16,11 +16,11 @@ * * @private * - * @param array $array The array to flatten. - * @param int $depth The maximum recursion depth. - * @param callable $predicate The function invoked per iteration [isFlattenable]. - * @param bool $isStrict Restrict to values that pass `predicate` checks. - * @param array $result The initial result value. + * @param array|null $array The array to flatten. + * @param int $depth The maximum recursion depth. + * @param callable|null $predicate The function invoked per iteration [isFlattenable]. + * @param bool|null $isStrict Restrict to values that pass `predicate` checks. + * @param array|null $result The initial result value. * * @return array Returns the new flattened array. */ @@ -32,7 +32,7 @@ function baseFlatten(?array $array, int $depth, callable $predicate = null, bool return $result; } - $predicate = $predicate ?? '\_\internal\isFlattenable'; + $predicate = $predicate ?? '_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { diff --git a/src/internal/baseIntersection.php b/src/internal/baseIntersection.php index 03efbf8..da97b4b 100644 --- a/src/internal/baseIntersection.php +++ b/src/internal/baseIntersection.php @@ -45,11 +45,11 @@ function baseIntersection($arrays, ?callable $iteratee, $comparator = null) $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; - if (!($cache ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { + if (!(!empty($cache) ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { continue 2; } } - if ($seen) { + if (empty($seen)) { $seen[] = $computed; } From b886de64e1cc28082caebec73d6cef5074aa1ff7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 15 Aug 2018 22:32:39 +0200 Subject: [PATCH 077/159] Added composer bin plugin and moved bins to vendor-bin --- .gitattributes | 1 + .gitignore | 1 + composer.json | 7 +++++-- phpstan.neon | 6 +++--- vendor-bin/phpstan/composer.json | 5 +++++ vendor-bin/phpunit/composer.json | 5 +++++ 6 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 .gitattributes create mode 100644 vendor-bin/phpstan/composer.json create mode 100644 vendor-bin/phpunit/composer.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..011ba22 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +vendor-bin/**/composer.lock binary diff --git a/.gitignore b/.gitignore index 3a9875b..9718caa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /vendor/ composer.lock +/vendor-bin/**/vendor diff --git a/composer.json b/composer.json index 23eba05..81b6a39 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,11 @@ "symfony/property-access": "^2.7 | ^3.0 | ^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.4 | ^7.0", "phpdocumentor/reflection-docblock": "^4.2", - "phpstan/phpstan": "^0.10.3" + "bamarni/composer-bin-plugin": "^1.2" + }, + "scripts": { + "post-install-cmd": ["@composer bin all install --ansi"], + "post-update-cmd": ["@composer bin all update --ansi"] } } diff --git a/phpstan.neon b/phpstan.neon index 235c766..8ef3239 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,8 @@ parameters: - bootstrap: %rootDir%/../../../src/bootstrap.php + bootstrap: %rootDir%/../../../../../src/bootstrap.php excludes_analyse: - - %rootDir%/../../../src/compiled.php - - %rootDir%/../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage + - %rootDir%/../../../../../src/compiled.php + - %rootDir%/../../../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json new file mode 100644 index 0000000..d7c0420 --- /dev/null +++ b/vendor-bin/phpstan/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "phpstan/phpstan": "^0.10.3" + } +} diff --git a/vendor-bin/phpunit/composer.json b/vendor-bin/phpunit/composer.json new file mode 100644 index 0000000..1d41d8f --- /dev/null +++ b/vendor-bin/phpunit/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "phpunit/phpunit": "^7.3" + } +} From ed8443ac954ba3a6d68ae970a99bbbcafa3da5b0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 16 Aug 2018 22:17:42 +0200 Subject: [PATCH 078/159] Fix some more PHPStan violations --- src/Array/differenceBy.php | 15 +++++++++++---- src/Array/differenceWith.php | 10 +++++++++- src/Array/unionWith.php | 15 +++++++++++++-- src/Array/uniq.php | 2 +- src/Array/unzipWith.php | 7 ++++--- src/Array/zipWith.php | 6 ++++-- src/Collection/each.php | 13 +++++-------- src/Collection/eachRight.php | 10 +++------- src/Collection/filter.php | 3 ++- src/Collection/find.php | 2 +- src/Collection/findLast.php | 9 ++++++--- src/Collection/reduce.php | 4 ++-- src/Collection/sample.php | 1 + src/Collection/sortBy.php | 2 +- src/Function/memoize.php | 7 ++++--- src/Lodash.php | 4 ++++ src/MapCache.php | 4 ++++ src/String/replace.php | 2 +- src/String/split.php | 2 +- src/String/template.php | 5 +++++ src/String/truncate.php | 2 +- src/internal/baseInvoke.php | 2 +- src/internal/baseReduce.php | 2 +- src/internal/unicodeSize.php | 4 ++-- 24 files changed, 87 insertions(+), 46 deletions(-) diff --git a/src/Array/differenceBy.php b/src/Array/differenceBy.php index b516ef9..66b7a15 100644 --- a/src/Array/differenceBy.php +++ b/src/Array/differenceBy.php @@ -24,16 +24,18 @@ * * @category Array * - * @param array $array The array to inspect. - * @param array ...$values The values to exclude. - * @param callable $iteratee The iteratee invoked per element. + * @param array $array The array to inspect. + * @param array ...$values The values to exclude. + * @param callable $iteratee The iteratee invoked per element. * * @return array Returns the new array of filtered values. * + * @throws \InvalidArgumentException * @example - * + * * differenceBy([2.1, 1.2], [2.3, 3.4], 'floor') * // => [1.2] + * */ function differenceBy(array $array, array ...$values): array { @@ -45,8 +47,13 @@ function differenceBy(array $array, array ...$values): array return difference($array, ...$values); } + /** @var callable $iteratee */ $iteratee = \array_pop($values); + if (!\is_callable($iteratee)) { + throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); + } + $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); diff --git a/src/Array/differenceWith.php b/src/Array/differenceWith.php index 3758e70..cf5b3c3 100644 --- a/src/Array/differenceWith.php +++ b/src/Array/differenceWith.php @@ -24,10 +24,13 @@ * @category Array * * @param array $array The array to inspect. - * @param array ...$values The values to exclude. + * @param array ...$values The values to exclude. * @param callable $comparator The comparator invoked per element. * * @return array Returns the new array of filtered values. + * + * @throws \InvalidArgumentException + * * @example * * $objects = [[ 'x' => 1, 'y' => 2 ], [ 'x' => 2, 'y' => 1 ]] @@ -46,8 +49,13 @@ function differenceWith(array $array, array ...$values): array return difference($array, ...$values); } + /** @var callable $comparator */ $comparator = \array_pop($values); + if (!\is_callable($comparator)) { + throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); + } + $values = baseFlatten($values, 1, 'is_array', true, null); $valuesLength = \count($values); diff --git a/src/Array/unionWith.php b/src/Array/unionWith.php index d213e53..b054ba3 100644 --- a/src/Array/unionWith.php +++ b/src/Array/unionWith.php @@ -26,15 +26,26 @@ * @param callable $comparator The comparator invoked per element. * * @return array the new array of combined values. - * @example * + * @throws \InvalidArgumentException + * + * @example + * * $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]] * $others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]] * * unionWith($objects, $others, '_::isEqual') * // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] + * */ function unionWith(array ... $arrays): array { - return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); + /** @var callable $comparator */ + $comparator = \array_pop($arrays); + + if (!\is_callable($comparator)) { + throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); + } + + return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, $comparator); } diff --git a/src/Array/uniq.php b/src/Array/uniq.php index ffe09f0..4aa7515 100644 --- a/src/Array/uniq.php +++ b/src/Array/uniq.php @@ -29,7 +29,7 @@ * // => [2, 1]s * */ -function uniq(array $array = null): array +function uniq(array $array = []): array { return \array_unique($array); } diff --git a/src/Array/unzipWith.php b/src/Array/unzipWith.php index 4aa6910..17365f8 100644 --- a/src/Array/unzipWith.php +++ b/src/Array/unzipWith.php @@ -20,10 +20,11 @@ * * @category Array * - * @param array $array The array of grouped elements to process. - * @param callable $iteratee The function to combine regrouped values. + * @param array $array The array of grouped elements to process. + * @param callable|null $iteratee The function to combine regrouped values. * * @return array the new array of regrouped elements. + * * @example * * $zipped = zip([1, 2], [10, 20], [100, 200]) @@ -33,7 +34,7 @@ * // => [3, 30, 300] * */ -function unzipWith(array $array, callable $iteratee): array +function unzipWith(array $array, ?callable $iteratee = null): array { if (!\count($array)) { return []; diff --git a/src/Array/zipWith.php b/src/Array/zipWith.php index d97d0ca..58727f0 100644 --- a/src/Array/zipWith.php +++ b/src/Array/zipWith.php @@ -18,18 +18,20 @@ * * @category Array * - * @param array ...$arrays The arrays to process. + * @param array ...$arrays The arrays to process. * @param callable $iteratee The function to combine grouped values. * * @return array the new array of grouped elements. + * * @example * * zipWith([1, 2], [10, 20], [100, 200], function($a, $b, $c) { return $a + $b + $c; }) * // => [111, 222] * */ -function zipWith(array ...$arrays): array +function zipWith(...$arrays): array { + /** @var callable|null $iteratee */ $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; return unzipWith($arrays, $iteratee); diff --git a/src/Collection/each.php b/src/Collection/each.php index 9ef3ad5..a78a041 100644 --- a/src/Collection/each.php +++ b/src/Collection/each.php @@ -22,11 +22,11 @@ * * @category Collection * - * @param array|object $collection The collection to iterate over. - * @param callable $iteratee The function invoked per iteration. + * @param array|iterable|object $collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. * * @return array|object Returns `collection`. - * @related forEachRight, forIn, forInRight, forOwn, forOwnRight + * * @example * * each([1, 2], function ($value) { echo $value; }) @@ -38,12 +38,9 @@ */ function each($collection, callable $iteratee) { - $values = $collection; - - if (\is_object($collection)) { - $values = \get_object_vars($collection); - } + $values = \is_object($collection) ? \get_object_vars($collection) : $collection; + /** @var array $values */ foreach ($values as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; diff --git a/src/Collection/eachRight.php b/src/Collection/eachRight.php index b2d0d19..cb275d3 100644 --- a/src/Collection/eachRight.php +++ b/src/Collection/eachRight.php @@ -17,8 +17,8 @@ * * @category Collection * - * @param array|object $collection The collection to iterate over. - * @param callable $iteratee The function invoked per iteration. + * @param array|iterable|object $collection The collection to iterate over. + * @param callable $iteratee The function invoked per iteration. * * @return array|object Returns `collection`. * @example @@ -29,11 +29,7 @@ */ function eachRight($collection, callable $iteratee) { - $values = $collection; - - if (\is_object($collection)) { - $values = \get_object_vars($collection); - } + $values = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach (\array_reverse($values, true) as $index => $value) { if (false === $iteratee($value, $index, $collection)) { diff --git a/src/Collection/filter.php b/src/Collection/filter.php index bfd013b..0e5603e 100644 --- a/src/Collection/filter.php +++ b/src/Collection/filter.php @@ -26,6 +26,7 @@ * @param callable $predicate The function invoked per iteration. * * @return array the new filtered array. + * * @example * * $users = [ @@ -54,7 +55,7 @@ function filter(iterable $array, $predicate = null): array $iteratee = baseIteratee($predicate); $result = \array_filter( - $array, + \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, diff --git a/src/Collection/find.php b/src/Collection/find.php index b1be2a8..9c4a760 100644 --- a/src/Collection/find.php +++ b/src/Collection/find.php @@ -54,7 +54,7 @@ function find(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); - foreach (\array_slice($collection, $fromIndex) as $key => $value) { + foreach (\array_slice(\is_array($collection) ? $collection : \iterator_to_array($collection), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } diff --git a/src/Collection/findLast.php b/src/Collection/findLast.php index 60e5ab6..ab0fe1c 100644 --- a/src/Collection/findLast.php +++ b/src/Collection/findLast.php @@ -18,10 +18,13 @@ * `collection` from right to left. * * @category Collection + * * @param iterable $collection The collection to inspect. - * @param callable $predicate The function invoked per iteration. - * @param int $fromIndex The index to search from. + * @param callable $predicate The function invoked per iteration. + * @param int $fromIndex The index to search from. + * * @return mixed Returns the matched element, else `undefined`. + * * @example * * findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; }) @@ -32,7 +35,7 @@ function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); - foreach (\array_slice(\array_reverse($collection, true), $fromIndex) as $key => $value) { + foreach (\array_slice(\array_reverse(\is_array($collection) ? $collection : \iterator_to_array($collection), true), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } diff --git a/src/Collection/reduce.php b/src/Collection/reduce.php index 9b7b179..e966cec 100644 --- a/src/Collection/reduce.php +++ b/src/Collection/reduce.php @@ -55,10 +55,10 @@ function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { - $length = count($array); + $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { - $accumulator = current($array); + $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); diff --git a/src/Collection/sample.php b/src/Collection/sample.php index dc062fd..e5d2415 100644 --- a/src/Collection/sample.php +++ b/src/Collection/sample.php @@ -19,6 +19,7 @@ * @param array $array The array to sample. * * @return mixed Returns the random element. + * * @example * * sample([1, 2, 3, 4]) diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index 404c38d..0bfc361 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -58,7 +58,7 @@ function sortBy($collection, $iteratees): array $iteratees = [$iteratees[0]]; }*/ - $result = $collection; + $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { diff --git a/src/Function/memoize.php b/src/Function/memoize.php index 6fa4df4..13ec3a1 100644 --- a/src/Function/memoize.php +++ b/src/Function/memoize.php @@ -25,8 +25,8 @@ * * @category Function * - * @param callable $func The function to have its output memoized. - * @param callable $resolver The function to resolve the cache key. + * @param callable $func The function to have its output memoized. + * @param callable|null $resolver The function to resolve the cache key. * * @return callable Returns the new memoized function. * @@ -52,9 +52,10 @@ * // => ['a', 'b'] * */ -function memoize(callable $func = null, callable $resolver = null) +function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { + /** * @var CacheInterface */ diff --git a/src/Lodash.php b/src/Lodash.php index 2c0835c..6ca5f40 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -53,6 +53,10 @@ final class _ */ public static function __callStatic(string $method, array $args) { + if (!\is_callable("_\\$method")) { + throw new \InvalidArgumentException("Function _::$method is not valid"); + } + return ("_\\$method")(...$args); } } diff --git a/src/MapCache.php b/src/MapCache.php index ff4e0f4..7726fad 100644 --- a/src/MapCache.php +++ b/src/MapCache.php @@ -13,6 +13,10 @@ use _\internal\Traits\CacheDataTrait; +/** + * @property array $__data__ + * @property int $size + */ final class MapCache implements CacheInterface { use CacheDataTrait; diff --git a/src/String/replace.php b/src/String/replace.php index a7a2242..08fab66 100644 --- a/src/String/replace.php +++ b/src/String/replace.php @@ -42,7 +42,7 @@ function replace(string $string, string $pattern, $replacement = ''): string }; if (\preg_match(reRegExpChar, $pattern)) { - if (!is_callable($replacement)) { + if (!\is_callable($replacement)) { return \preg_replace($pattern, $replacement, $string); } diff --git a/src/String/split.php b/src/String/split.php index e6a1c8f..3a4c05a 100644 --- a/src/String/split.php +++ b/src/String/split.php @@ -33,7 +33,7 @@ function split(string $string, string $separator, int $limit = null): array { if (\preg_match(reRegExpChar, $separator)) { - return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE); + return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; } $result = \explode($separator, $string); diff --git a/src/String/template.php b/src/String/template.php index 3420116..035bc66 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -165,8 +165,13 @@ public function __invoke(array $arguments = []) } } + /** @var string $file */ $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); + if ($file) { + throw new \RuntimeException('Unable to create temporary file for template'); + } + \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { diff --git a/src/String/truncate.php b/src/String/truncate.php index 2b6c7ed..cdca582 100644 --- a/src/String/truncate.php +++ b/src/String/truncate.php @@ -105,7 +105,7 @@ function truncate($string, array $options = []) } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); - if ($index > -1) { + if (false !== $index && $index > -1) { $result = \substr($result, 0, $index); } } diff --git a/src/internal/baseInvoke.php b/src/internal/baseInvoke.php index 583ae05..32a34b5 100644 --- a/src/internal/baseInvoke.php +++ b/src/internal/baseInvoke.php @@ -19,5 +19,5 @@ function baseInvoke($object, $path, $args) $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; - return null === $func ? null : $func($object, ...$args); + return \is_callable($func) ? $func($object, ...$args) : null; } \ No newline at end of file diff --git a/src/internal/baseReduce.php b/src/internal/baseReduce.php index 5e7b1d1..0eeb36d 100644 --- a/src/internal/baseReduce.php +++ b/src/internal/baseReduce.php @@ -13,7 +13,7 @@ function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { - $length = \count($array); + $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); diff --git a/src/internal/unicodeSize.php b/src/internal/unicodeSize.php index 7604e2f..47ed627 100644 --- a/src/internal/unicodeSize.php +++ b/src/internal/unicodeSize.php @@ -20,7 +20,7 @@ * * @return int Returns the string size. */ -function unicodeSize($string): int +function unicodeSize(string $string): int { - return \preg_match_all(reUnicode, $string); + return \preg_match_all(reUnicode, $string) ?: 0; } From 839249b1904a23db18bd27d7526c9b31c0a94417 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 16 Aug 2018 22:30:27 +0200 Subject: [PATCH 079/159] Add php-cs-fixer and fix CS violations --- .gitignore | 3 +- .php_cs | 17 + .travis.yml | 1 + src/Collection/countBy.php | 2 +- src/Collection/eachRight.php | 2 +- src/Collection/every.php | 2 +- src/Collection/filter.php | 2 +- src/Collection/find.php | 2 +- src/Collection/findLast.php | 2 +- src/Collection/flatMap.php | 2 +- src/Collection/flatMapDeep.php | 2 +- src/Collection/flatMapDepth.php | 2 +- src/Collection/groupBy.php | 2 +- src/Collection/invokeMap.php | 2 +- src/Collection/keyBy.php | 2 +- src/Collection/orderBy.php | 2 +- src/Collection/partition.php | 6 +- src/Collection/reduce.php | 2 +- src/Collection/reduceRight.php | 2 +- src/Collection/reject.php | 2 +- src/Collection/sample.php | 2 +- src/Collection/sampleSize.php | 2 +- src/Collection/shuffle.php | 2 +- src/Collection/size.php | 2 +- src/Collection/some.php | 2 +- src/Function/negate.php | 2 +- src/Math/max.php | 2 +- src/Math/maxBy.php | 2 +- src/internal/baseInvoke.php | 2 +- src/internal/baseOrderBy.php | 2 +- src/internal/baseReduce.php | 2 +- src/internal/baseUnary.php | 2 +- src/internal/compareMultiple.php | 2 +- src/internal/createAggregator.php | 2 +- src/internal/parent.php | 2 +- vendor-bin/php-cs-fixer/composer.json | 5 + vendor-bin/php-cs-fixer/composer.lock | 1093 +++++++++++++++++++ vendor-bin/phpstan/composer.lock | 1028 ++++++++++++++++++ vendor-bin/phpunit/composer.lock | 1423 +++++++++++++++++++++++++ 39 files changed, 3604 insertions(+), 34 deletions(-) create mode 100644 .php_cs create mode 100644 vendor-bin/php-cs-fixer/composer.json create mode 100644 vendor-bin/php-cs-fixer/composer.lock create mode 100644 vendor-bin/phpstan/composer.lock create mode 100644 vendor-bin/phpunit/composer.lock diff --git a/.gitignore b/.gitignore index 9718caa..ff8cba6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor/ -composer.lock +/composer.lock /vendor-bin/**/vendor +/.php_cs.cache \ No newline at end of file diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..641ccb6 --- /dev/null +++ b/.php_cs @@ -0,0 +1,17 @@ +in('src') + ->notName('compiled.php'); + +return PhpCsFixer\Config::create() + ->setRules( + [ + '@PSR1' => true, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'single_import_per_statement' => false, + ] + ) + ->setFinder($finder) +; diff --git a/.travis.yml b/.travis.yml index 7588997..67e4fa2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,5 +33,6 @@ install: - composer update -n "$COMPOSER_OPTIONS" script: + - vendor/bin/php-cs-fixer fix --dry-run -v - vendor/bin/phpunit - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=4 diff --git a/src/Collection/countBy.php b/src/Collection/countBy.php index 9890829..ae2dd51 100644 --- a/src/Collection/countBy.php +++ b/src/Collection/countBy.php @@ -46,4 +46,4 @@ function countBy(iterable $collection, callable $iteratee): array return $result; })($collection, $iteratee); -} \ No newline at end of file +} diff --git a/src/Collection/eachRight.php b/src/Collection/eachRight.php index cb275d3..94d3130 100644 --- a/src/Collection/eachRight.php +++ b/src/Collection/eachRight.php @@ -38,4 +38,4 @@ function eachRight($collection, callable $iteratee) } return $collection; -} \ No newline at end of file +} diff --git a/src/Collection/every.php b/src/Collection/every.php index a2d261a..6ee989a 100644 --- a/src/Collection/every.php +++ b/src/Collection/every.php @@ -64,4 +64,4 @@ function every(iterable $collection, $predicate): bool } return true; -} \ No newline at end of file +} diff --git a/src/Collection/filter.php b/src/Collection/filter.php index 0e5603e..da32f12 100644 --- a/src/Collection/filter.php +++ b/src/Collection/filter.php @@ -65,4 +65,4 @@ function ($value, $key) use ($array, $iteratee) { \sort($result); return $result; -} \ No newline at end of file +} diff --git a/src/Collection/find.php b/src/Collection/find.php index 9c4a760..e38807f 100644 --- a/src/Collection/find.php +++ b/src/Collection/find.php @@ -61,4 +61,4 @@ function find(iterable $collection, $predicate = null, int $fromIndex = 0) } return null; -} \ No newline at end of file +} diff --git a/src/Collection/findLast.php b/src/Collection/findLast.php index ab0fe1c..27c653e 100644 --- a/src/Collection/findLast.php +++ b/src/Collection/findLast.php @@ -42,4 +42,4 @@ function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) } return null; -} \ No newline at end of file +} diff --git a/src/Collection/flatMap.php b/src/Collection/flatMap.php index cec9217..fceb871 100644 --- a/src/Collection/flatMap.php +++ b/src/Collection/flatMap.php @@ -38,4 +38,4 @@ function flatMap(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), 1); -} \ No newline at end of file +} diff --git a/src/Collection/flatMapDeep.php b/src/Collection/flatMapDeep.php index 85a40d0..d3ee9fb 100644 --- a/src/Collection/flatMapDeep.php +++ b/src/Collection/flatMapDeep.php @@ -36,4 +36,4 @@ function flatMapDeep(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); -} \ No newline at end of file +} diff --git a/src/Collection/flatMapDepth.php b/src/Collection/flatMapDepth.php index a02e995..57a9278 100644 --- a/src/Collection/flatMapDepth.php +++ b/src/Collection/flatMapDepth.php @@ -37,4 +37,4 @@ function flatMapDepth(iterable $collection, callable $iteratee = null, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); -} \ No newline at end of file +} diff --git a/src/Collection/groupBy.php b/src/Collection/groupBy.php index fab80a7..2295d56 100644 --- a/src/Collection/groupBy.php +++ b/src/Collection/groupBy.php @@ -46,4 +46,4 @@ function groupBy(iterable $collection, $iteratee): array return $result; })($collection, $iteratee); -} \ No newline at end of file +} diff --git a/src/Collection/invokeMap.php b/src/Collection/invokeMap.php index 148b117..e4a413f 100644 --- a/src/Collection/invokeMap.php +++ b/src/Collection/invokeMap.php @@ -48,4 +48,4 @@ function invokeMap(iterable $collection, $path, array $args = []): array return $result; })($collection, $path, $args); -} \ No newline at end of file +} diff --git a/src/Collection/keyBy.php b/src/Collection/keyBy.php index db94603..229206b 100644 --- a/src/Collection/keyBy.php +++ b/src/Collection/keyBy.php @@ -46,4 +46,4 @@ function keyBy(iterable $collection, $iteratee): array return $result; })($collection, $iteratee); -} \ No newline at end of file +} diff --git a/src/Collection/orderBy.php b/src/Collection/orderBy.php index aec6d62..346fb75 100644 --- a/src/Collection/orderBy.php +++ b/src/Collection/orderBy.php @@ -47,4 +47,4 @@ function orderBy(?iterable $collection, array $iteratee, array $orders): array } return baseOrderBy($collection, $iteratee, $orders); -} \ No newline at end of file +} diff --git a/src/Collection/partition.php b/src/Collection/partition.php index 7c5764d..36b1353 100644 --- a/src/Collection/partition.php +++ b/src/Collection/partition.php @@ -42,5 +42,7 @@ function partition(iterable $collection, $predicate = null): array $result[$key ? 0 : 1][] = $value; return $result; - }, function () { return [[], []]; })($collection, $predicate); -} \ No newline at end of file + }, function () { + return [[], []]; + })($collection, $predicate); +} diff --git a/src/Collection/reduce.php b/src/Collection/reduce.php index e966cec..703be86 100644 --- a/src/Collection/reduce.php +++ b/src/Collection/reduce.php @@ -68,4 +68,4 @@ function reduce(iterable $collection, $iteratee, $accumulator = null) }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); -} \ No newline at end of file +} diff --git a/src/Collection/reduceRight.php b/src/Collection/reduceRight.php index 14a9991..9b3ff4b 100644 --- a/src/Collection/reduceRight.php +++ b/src/Collection/reduceRight.php @@ -36,4 +36,4 @@ function reduceRight(iterable $collection, $iteratee, $accumulator = null) { return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); -} \ No newline at end of file +} diff --git a/src/Collection/reject.php b/src/Collection/reject.php index eb70956..1a63722 100644 --- a/src/Collection/reject.php +++ b/src/Collection/reject.php @@ -38,4 +38,4 @@ function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); -} \ No newline at end of file +} diff --git a/src/Collection/sample.php b/src/Collection/sample.php index e5d2415..033b565 100644 --- a/src/Collection/sample.php +++ b/src/Collection/sample.php @@ -29,4 +29,4 @@ function sample(array $array) { return $array[\array_rand($array, 1)]; -} \ No newline at end of file +} diff --git a/src/Collection/sampleSize.php b/src/Collection/sampleSize.php index 521b7a1..684cf2e 100644 --- a/src/Collection/sampleSize.php +++ b/src/Collection/sampleSize.php @@ -39,4 +39,4 @@ function sampleSize(array $array, int $n = 1): array } return $result; -} \ No newline at end of file +} diff --git a/src/Collection/shuffle.php b/src/Collection/shuffle.php index b731701..353c16c 100644 --- a/src/Collection/shuffle.php +++ b/src/Collection/shuffle.php @@ -29,4 +29,4 @@ function shuffle(array $array = []): array \shuffle($array); return $array; -} \ No newline at end of file +} diff --git a/src/Collection/size.php b/src/Collection/size.php index 0fc29e3..91aa57b 100644 --- a/src/Collection/size.php +++ b/src/Collection/size.php @@ -50,4 +50,4 @@ function size($collection): int } return 0; -} \ No newline at end of file +} diff --git a/src/Collection/some.php b/src/Collection/some.php index 4e69e79..02d8b9d 100644 --- a/src/Collection/some.php +++ b/src/Collection/some.php @@ -58,4 +58,4 @@ function some(iterable $collection, $predicate = null): bool } return false; -} \ No newline at end of file +} diff --git a/src/Function/negate.php b/src/Function/negate.php index 90352d5..934cb0b 100644 --- a/src/Function/negate.php +++ b/src/Function/negate.php @@ -35,4 +35,4 @@ function negate(callable $predicate): callable return function () use ($predicate) { return !$predicate(...\func_get_args()); }; -} \ No newline at end of file +} diff --git a/src/Math/max.php b/src/Math/max.php index 8699924..bc61451 100644 --- a/src/Math/max.php +++ b/src/Math/max.php @@ -31,4 +31,4 @@ function max(?array $array): ?int { return $array ? \max($array) : null; -} \ No newline at end of file +} diff --git a/src/Math/maxBy.php b/src/Math/maxBy.php index 97d9c7c..091c5af 100644 --- a/src/Math/maxBy.php +++ b/src/Math/maxBy.php @@ -51,4 +51,4 @@ function maxBy(?array $array, $iteratee) } return $result; -} \ No newline at end of file +} diff --git a/src/internal/baseInvoke.php b/src/internal/baseInvoke.php index 32a34b5..0f8ad3b 100644 --- a/src/internal/baseInvoke.php +++ b/src/internal/baseInvoke.php @@ -20,4 +20,4 @@ function baseInvoke($object, $path, $args) $func = null === $object ? $object : [$object, toKey(last($path))]; return \is_callable($func) ? $func($object, ...$args) : null; -} \ No newline at end of file +} diff --git a/src/internal/baseOrderBy.php b/src/internal/baseOrderBy.php index ca231d0..d8c2d89 100644 --- a/src/internal/baseOrderBy.php +++ b/src/internal/baseOrderBy.php @@ -30,4 +30,4 @@ function baseOrderBy(iterable $collection, array $iteratees, array $orders): arr return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); -} \ No newline at end of file +} diff --git a/src/internal/baseReduce.php b/src/internal/baseReduce.php index 0eeb36d..9d0f360 100644 --- a/src/internal/baseReduce.php +++ b/src/internal/baseReduce.php @@ -24,4 +24,4 @@ function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) } return $accumulator; -} \ No newline at end of file +} diff --git a/src/internal/baseUnary.php b/src/internal/baseUnary.php index d1aa978..ddfbf80 100644 --- a/src/internal/baseUnary.php +++ b/src/internal/baseUnary.php @@ -16,4 +16,4 @@ function baseUnary($func) return function ($value) use ($func) { return $func($value); }; -} \ No newline at end of file +} diff --git a/src/internal/compareMultiple.php b/src/internal/compareMultiple.php index 257f633..ec345de 100644 --- a/src/internal/compareMultiple.php +++ b/src/internal/compareMultiple.php @@ -32,4 +32,4 @@ function compareMultiple($object, $other, $orders) } return $object['index'] - $other['index']; -} \ No newline at end of file +} diff --git a/src/internal/createAggregator.php b/src/internal/createAggregator.php index 0bd4a43..ea63c5a 100644 --- a/src/internal/createAggregator.php +++ b/src/internal/createAggregator.php @@ -28,4 +28,4 @@ function createAggregator($setter, $initializer = null) return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); }; -} \ No newline at end of file +} diff --git a/src/internal/parent.php b/src/internal/parent.php index 815b452..49b3d78 100644 --- a/src/internal/parent.php +++ b/src/internal/parent.php @@ -14,4 +14,4 @@ function parent($object, $path) { return count($path) < 2 ? $object : null; -} \ No newline at end of file +} diff --git a/vendor-bin/php-cs-fixer/composer.json b/vendor-bin/php-cs-fixer/composer.json new file mode 100644 index 0000000..4741827 --- /dev/null +++ b/vendor-bin/php-cs-fixer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "friendsofphp/php-cs-fixer": "^2.12" + } +} diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock new file mode 100644 index 0000000..47f9874 --- /dev/null +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -0,0 +1,1093 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "6164bfe4091cb1fe1c219656f116f002", + "packages": [ + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "e1809da56ce1bd1b547a752936817341ac244d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e1809da56ce1bd1b547a752936817341ac244d8e", + "reference": "e1809da56ce1bd1b547a752936817341ac244d8e", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2018-08-16T10:54:23+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-12-06T07:11:42+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.12.2", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "dcc87d5414e9d0bd316fce81a5bedb9ce720b183" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/dcc87d5414e9d0bd316fce81a5bedb9ce720b183", + "reference": "dcc87d5414e9d0bd316fce81a5bedb9ce720b183", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.0", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || >=7.0 <7.3", + "php-cs-fixer/diff": "^1.3", + "symfony/console": "^3.2 || ^4.0", + "symfony/event-dispatcher": "^3.0 || ^4.0", + "symfony/filesystem": "^3.0 || ^4.0", + "symfony/finder": "^3.0 || ^4.0", + "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0", + "symfony/stopwatch": "^3.0 || ^4.0" + }, + "conflict": { + "hhvm": "*" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.1", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.1", + "php-cs-fixer/accessible-object": "^1.0", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.0.1", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.0.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", + "phpunitgoodpractices/traits": "^1.5.1", + "symfony/phpunit-bridge": "^4.0" + }, + "suggest": { + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2018-07-06T10:37:40+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15T16:58:55+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "symfony/console", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f", + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T09:10:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "2e30335e0aafeaa86645555959572fe7cea22b43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2e30335e0aafeaa86645555959572fe7cea22b43", + "reference": "2e30335e0aafeaa86645555959572fe7cea22b43", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "1913f1962477cdbb13df951f8147d5da1fe2412c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/1913f1962477cdbb13df951f8147d5da1fe2412c", + "reference": "1913f1962477cdbb13df951f8147d5da1fe2412c", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2018-07-26T08:55:25+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/process", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "f01fc7a4493572f7f506c49dcb50ad01fb3a2f56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/f01fc7a4493572f7f506c49dcb50ad01fb3a2f56", + "reference": "f01fc7a4493572f7f506c49dcb50ad01fb3a2f56", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "966c982df3cca41324253dc0c7ffe76b6076b705" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/966c982df3cca41324253dc0c7ffe76b6076b705", + "reference": "966c982df3cca41324253dc0c7ffe76b6076b705", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:00:49+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/vendor-bin/phpstan/composer.lock b/vendor-bin/phpstan/composer.lock new file mode 100644 index 0000000..cc430f1 --- /dev/null +++ b/vendor-bin/phpstan/composer.lock @@ -0,0 +1,1028 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "885b295492a97a537399d0d309928b59", + "packages": [ + { + "name": "composer/xdebug-handler", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08", + "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2018-04-11T15:42:36+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2018-06-13T13:22:40+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v2.4.6", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "shasum": "" + }, + "require": { + "nette/di": "~2.4.7", + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "latte/latte": "~2.2", + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "tracy/tracy": "^2.4.1" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "time": "2018-05-17T12:52:20+00:00" + }, + { + "name": "nette/di", + "version": "v2.4.13", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ~3.0.0", + "nette/utils": "^2.4.3 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/bootstrap": "<2.4", + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "time": "2018-06-11T08:46:01+00:00" + }, + { + "name": "nette/finder", + "version": "v2.4.2", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", + "shasum": "" + }, + "require": { + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", + "keywords": [ + "filesystem", + "glob", + "iterator", + "nette" + ], + "time": "2018-06-28T11:49:23+00:00" + }, + { + "name": "nette/neon", + "version": "v2.4.3", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "http://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "time": "2018-03-21T12:12:21+00:00" + }, + { + "name": "nette/php-generator", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/ea90209c2e8a7cd087b2742ca553c047a8df5eff", + "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "time": "2018-08-09T14:32:27+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/3cf88781a05e0bf4618ae605361afcbaa4d5b392", + "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/finder": "^2.3 || ^3.0", + "nette/utils": "^2.4 || ^3.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "time": "2018-06-22T09:34:04+00:00" + }, + { + "name": "nette/utils", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/183069866dc477fcfbac393ed486aaa6d93d19a5", + "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/loader.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "time": "2018-05-02T17:16:08+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd088dc940a418f09cda079a9b5c7c478890fb8d", + "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2018-07-15T17:25:16+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2018-02-05T13:05:30+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "ed3223362174b8067729930439e139794e9e514a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ed3223362174b8067729930439e139794e9e514a", + "reference": "ed3223362174b8067729930439e139794e9e514a", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^2.0.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10@dev", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^3.3.0", + "symfony/process": "^3.4 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "time": "2018-06-20T17:48:01+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0", + "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-gd": "*", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "~0.8.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.10.2", + "phpstan/phpstan-php-parser": "^0.10", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.6.2" + }, + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.10-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2018-08-12T15:14:21+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "symfony/console", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f", + "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:24:31+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock new file mode 100644 index 0000000..b8ce301 --- /dev/null +++ b/vendor-bin/phpunit/composer.lock @@ -0,0 +1,1423 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "c53e40477ad5fd9b453ca1e5ff4a2b95", + "packages": [ + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2018-06-11T23:09:50+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-08-05T17:53:17+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-06-01T07:51:50+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-06-11T11:44:00+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "f9b14c17860eccb440a0352a117a81eb754cff5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9b14c17860eccb440a0352a117a81eb754cff5a", + "reference": "f9b14c17860eccb440a0352a117a81eb754cff5a", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-08-07T06:44:28+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "366541b989927187c4ca70490a35615d3fef2dce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", + "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-06-10T07:54:39+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} From 2a13b713fa1b23f6489f10e8d909efce8fbe58a7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 13:01:52 +0200 Subject: [PATCH 080/159] Update PHPStan violations and update PHPStan checks to the max level --- .php_cs | 1 + .travis.yml | 2 +- phpstan.neon | 1 + src/Array/differenceBy.php | 13 ++-- src/Array/differenceWith.php | 8 +-- src/Array/flattenDeep.php | 2 +- src/Array/intersectionBy.php | 4 +- src/Array/intersectionWith.php | 2 +- src/Array/unionBy.php | 4 +- src/Array/unionWith.php | 4 +- src/Collection/flatMap.php | 2 +- src/Collection/flatMapDeep.php | 2 +- src/Collection/flatMapDepth.php | 2 +- src/Collection/sample.php | 5 +- src/String/replace.php | 8 +-- src/String/split.php | 3 +- src/String/template.php | 2 +- src/compiled.php | 100 +++++++++++++------------- src/internal/baseIntersection.php | 2 +- src/internal/baseInvoke.php | 1 + tests/Array/DifferenceByTest.php | 2 +- tests/Array/IntersectionWithTest.php | 2 +- tests/Collection/CountByTest.php | 2 +- tests/Collection/EachRightTest.php | 2 +- tests/Collection/EveryTest.php | 6 +- tests/Collection/FilterTest.php | 6 +- tests/Collection/FindLastTest.php | 6 +- tests/Collection/FindTest.php | 6 +- tests/Collection/FlatMapDeepTest.php | 2 +- tests/Collection/FlatMapDepthTest.php | 2 +- tests/Collection/FlatMapTest.php | 2 +- tests/Collection/GroupByTest.php | 2 +- tests/Collection/InvokeMapTest.php | 21 ++++-- tests/Collection/KeyByTest.php | 6 +- tests/Collection/OrderByTest.php | 2 +- tests/Collection/PartitionTest.php | 6 +- tests/Collection/ReduceRightTest.php | 6 +- tests/Collection/ReduceTest.php | 6 +- tests/Collection/RejectTest.php | 2 +- tests/Collection/SampleSizeTest.php | 2 +- tests/Collection/SampleTest.php | 2 +- tests/Collection/ShuffleTest.php | 2 +- tests/Collection/SizeTest.php | 13 ++-- tests/Collection/SomeTest.php | 6 +- tests/Math/MaxByTest.php | 4 +- 45 files changed, 157 insertions(+), 129 deletions(-) diff --git a/.php_cs b/.php_cs index 641ccb6..0208b81 100644 --- a/.php_cs +++ b/.php_cs @@ -2,6 +2,7 @@ $finder = PhpCsFixer\Finder::create() ->in('src') + ->in('tests') ->notName('compiled.php'); return PhpCsFixer\Config::create() diff --git a/.travis.yml b/.travis.yml index 67e4fa2..3363f55 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,4 @@ install: script: - vendor/bin/php-cs-fixer fix --dry-run -v - vendor/bin/phpunit - - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=4 + - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=max diff --git a/phpstan.neon b/phpstan.neon index 8ef3239..0882dcc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,7 @@ parameters: bootstrap: %rootDir%/../../../../../src/bootstrap.php excludes_analyse: - %rootDir%/../../../../../src/compiled.php + - %rootDir%/../../../../../src/Lodash.php - %rootDir%/../../../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' diff --git a/src/Array/differenceBy.php b/src/Array/differenceBy.php index 66b7a15..8c5a7ca 100644 --- a/src/Array/differenceBy.php +++ b/src/Array/differenceBy.php @@ -24,20 +24,19 @@ * * @category Array * - * @param array $array The array to inspect. - * @param array ...$values The values to exclude. - * @param callable $iteratee The iteratee invoked per element. + * @param array $array The array to inspect. + * @param array ...$values The values to exclude. + * @param callable $iteratee The iteratee invoked per element. * * @return array Returns the new array of filtered values. * - * @throws \InvalidArgumentException * @example * * differenceBy([2.1, 1.2], [2.3, 3.4], 'floor') * // => [1.2] * */ -function differenceBy(array $array, array ...$values): array +function differenceBy(array $array, ...$values): array { if (!$array) { return []; @@ -50,10 +49,6 @@ function differenceBy(array $array, array ...$values): array /** @var callable $iteratee */ $iteratee = \array_pop($values); - if (!\is_callable($iteratee)) { - throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); - } - $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); diff --git a/src/Array/differenceWith.php b/src/Array/differenceWith.php index cf5b3c3..912e117 100644 --- a/src/Array/differenceWith.php +++ b/src/Array/differenceWith.php @@ -23,7 +23,7 @@ * * @category Array * - * @param array $array The array to inspect. + * @param array $array The array to inspect. * @param array ...$values The values to exclude. * @param callable $comparator The comparator invoked per element. * @@ -39,7 +39,7 @@ * // => [[ 'x' => 2, 'y' => 1 ]] * */ -function differenceWith(array $array, array ...$values): array +function differenceWith(array $array, ...$values): array { if (!$array) { return []; @@ -52,10 +52,6 @@ function differenceWith(array $array, array ...$values): array /** @var callable $comparator */ $comparator = \array_pop($values); - if (!\is_callable($comparator)) { - throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); - } - $values = baseFlatten($values, 1, 'is_array', true, null); $valuesLength = \count($values); diff --git a/src/Array/flattenDeep.php b/src/Array/flattenDeep.php index 45e96a6..61a9933 100644 --- a/src/Array/flattenDeep.php +++ b/src/Array/flattenDeep.php @@ -29,5 +29,5 @@ */ function flattenDeep(array $array): array { - return baseFlatten($array, INF); + return baseFlatten($array, PHP_INT_MAX); } diff --git a/src/Array/intersectionBy.php b/src/Array/intersectionBy.php index b560306..44ca1c5 100644 --- a/src/Array/intersectionBy.php +++ b/src/Array/intersectionBy.php @@ -23,7 +23,7 @@ * * @category Array * - * @param array ...$arrays + * @param array ...$arrays * @param callable $iteratee The iteratee invoked per element. * * @return array the new array of intersecting values. @@ -37,7 +37,7 @@ * // => [[ 'x' => 1 ]] * */ -function intersectionBy(array ...$arrays/*, callable $iteratee*/): array +function intersectionBy(...$arrays/*, callable $iteratee*/): array { $iteratee = \array_pop($arrays); diff --git a/src/Array/intersectionWith.php b/src/Array/intersectionWith.php index 69bb91f..be8dbd4 100644 --- a/src/Array/intersectionWith.php +++ b/src/Array/intersectionWith.php @@ -38,7 +38,7 @@ function intersectionWith(...$arrays /*, callable $comparator = null*/): array { $copy = $arrays; - $comparator = array_pop($arrays); + $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; diff --git a/src/Array/unionBy.php b/src/Array/unionBy.php index d9fe6b8..af400c6 100644 --- a/src/Array/unionBy.php +++ b/src/Array/unionBy.php @@ -24,7 +24,7 @@ * * @category Array * - * @param array ...$arrays The arrays to inspect. + * @param array ...$arrays The arrays to inspect. * @param callable $iteratee The iteratee invoked per element. * * @return array the new array of combined values. @@ -39,7 +39,7 @@ * // => [['x' => 1], ['x' => 2]] * */ -function unionBy(array ...$arrays): array +function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } diff --git a/src/Array/unionWith.php b/src/Array/unionWith.php index b054ba3..56b2071 100644 --- a/src/Array/unionWith.php +++ b/src/Array/unionWith.php @@ -22,7 +22,7 @@ * * @category Array * - * @param array ...$arrays The arrays to inspect. + * @param array ...$arrays The arrays to inspect. * @param callable $comparator The comparator invoked per element. * * @return array the new array of combined values. @@ -38,7 +38,7 @@ * // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] * */ -function unionWith(array ... $arrays): array +function unionWith(... $arrays): array { /** @var callable $comparator */ $comparator = \array_pop($arrays); diff --git a/src/Collection/flatMap.php b/src/Collection/flatMap.php index fceb871..889cead 100644 --- a/src/Collection/flatMap.php +++ b/src/Collection/flatMap.php @@ -35,7 +35,7 @@ * // => [1, 1, 2, 2] * */ -function flatMap(iterable $collection, callable $iteratee = null): array +function flatMap(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), 1); } diff --git a/src/Collection/flatMapDeep.php b/src/Collection/flatMapDeep.php index d3ee9fb..5c09dd7 100644 --- a/src/Collection/flatMapDeep.php +++ b/src/Collection/flatMapDeep.php @@ -33,7 +33,7 @@ * // => [1, 1, 2, 2] * */ -function flatMapDeep(iterable $collection, callable $iteratee = null): array +function flatMapDeep(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); } diff --git a/src/Collection/flatMapDepth.php b/src/Collection/flatMapDepth.php index 57a9278..4bdd5ad 100644 --- a/src/Collection/flatMapDepth.php +++ b/src/Collection/flatMapDepth.php @@ -34,7 +34,7 @@ * // => [[1, 1], [2, 2]] * */ -function flatMapDepth(iterable $collection, callable $iteratee = null, int $depth = 1): array +function flatMapDepth(iterable $collection, callable $iteratee, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } diff --git a/src/Collection/sample.php b/src/Collection/sample.php index 033b565..43dec1f 100644 --- a/src/Collection/sample.php +++ b/src/Collection/sample.php @@ -28,5 +28,8 @@ */ function sample(array $array) { - return $array[\array_rand($array, 1)]; + /** @var string|int $key */ + $key = \array_rand($array, 1); + + return $array[$key]; } diff --git a/src/String/replace.php b/src/String/replace.php index 08fab66..9e308f6 100644 --- a/src/String/replace.php +++ b/src/String/replace.php @@ -31,23 +31,23 @@ * // => 'Hi Barney' * */ -function replace(string $string, string $pattern, $replacement = ''): string +function replace(string $string, string $pattern, $replacement = null): string { $callback = function (array $matches) use ($replacement): ?string { if (!\array_filter($matches)) { return null; } - return $replacement(...$matches); + return \is_callable($replacement) ? $replacement(...$matches) : null; }; if (\preg_match(reRegExpChar, $pattern)) { if (!\is_callable($replacement)) { - return \preg_replace($pattern, $replacement, $string); + return \preg_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } return \preg_replace_callback($pattern, $callback, $string); } - return \str_replace($pattern, $replacement, $string); + return \str_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } diff --git a/src/String/split.php b/src/String/split.php index 3a4c05a..2ec929f 100644 --- a/src/String/split.php +++ b/src/String/split.php @@ -30,12 +30,13 @@ * // => ['a', 'b'] * */ -function split(string $string, string $separator, int $limit = null): array +function split(string $string, string $separator, int $limit = 0): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; } + /** @var array $result */ $result = \explode($separator, $string); if ($limit > 0) { diff --git a/src/String/template.php b/src/String/template.php index 035bc66..a035e74 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -168,7 +168,7 @@ public function __invoke(array $arguments = []) /** @var string $file */ $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); - if ($file) { + if (!$file) { throw new \RuntimeException('Unable to create temporary file for template'); } diff --git a/src/compiled.php b/src/compiled.php index 2d5fde6..de411dd 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -2,34 +2,34 @@ // Auto-generated file - namespace { final class _ { public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; public static function __callStatic(string $method, array $args) { return ("_\\$method")(...$args); } } } + namespace { final class _ { public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } - namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = count($array); if ($initAccum && $length) { $accumulator = current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } - namespace _ { function eachRight($collection, callable $iteratee) { $values = $collection; if (\is_object($collection)) { $values = \get_object_vars($collection); } foreach (\array_reverse($values, true) as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } - namespace _ { use function _\internal\baseFlatten; function flatMapDeep(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); } } - namespace _ { use function _\internal\baseOrderBy; function orderBy(?iterable $collection, $iteratee, $orders): array { if (null === $collection) { return []; } return baseOrderBy($collection, (array) $iteratee, (array) $orders); } } - namespace _ { function size($collection): int { if (\is_string($collection)) { return \strlen($collection); } if (\is_array($collection) || $collection instanceof \Countable) { return \count($collection); } if ($collection instanceof \Traversable) { return \count(\iterator_to_array($collection)); } if (\is_object($collection)) { return \count(\get_object_vars($collection)); } return 0; } } - namespace _ { function each($collection, callable $iteratee) { $values = $collection; if (\is_object($collection)) { $values = \get_object_vars($collection); } foreach ($values as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } - namespace _ { use function _\internal\baseIteratee; use function _\internal\baseReduce; function reduceRight(iterable $collection, $iteratee, $accumulator = null) { return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); } } + namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } + namespace _ { function eachRight($collection, callable $iteratee) { $values = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach (\array_reverse($values, true) as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } + namespace _ { use function _\internal\baseFlatten; function flatMapDeep(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); } } + namespace _ { use function _\internal\baseOrderBy; function orderBy(?iterable $collection, array $iteratee, array $orders): array { if (null === $collection) { return []; } return baseOrderBy($collection, $iteratee, $orders); } } + namespace _ { function size($collection): int { if (\is_string($collection)) { return \strlen($collection); } if (\is_array($collection) || $collection instanceof \Countable) { return \count($collection); } if ($collection instanceof \Traversable) { return \count(\iterator_to_array($collection)); } if (\is_object($collection)) { return \count(\get_object_vars($collection)); } return 0; } } + namespace _ { function each($collection, callable $iteratee) { $values = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($values as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } + namespace _ { use function _\internal\baseIteratee; use function _\internal\baseReduce; function reduceRight(iterable $collection, $iteratee, $accumulator = null) { return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); } } namespace _ { use function _\internal\baseIteratee; function map($collection, $iteratee): array { $values = []; if (\is_array($collection)) { $values = $collection; } elseif ($collection instanceof \Traversable) { $values = \iterator_to_array($collection); } elseif (\is_object($collection)) { $values = \get_object_vars($collection); } $callable = baseIteratee($iteratee); return \array_map(function ($value, $index) use ($callable, $collection) { return $callable($value, $index, $collection); }, $values, \array_keys($values)); } } - namespace _ { use function _\internal\createAggregator; function partition(iterable $collection, $predicate = null): array { return createAggregator(function ($result, $value, $key) { $result[$key ? 0 : 1][] = $value; return $result; }, function () { return [[], []]; })($collection, $predicate); } } - namespace _ { use function _\internal\baseIteratee; function every(iterable $collection, $predicate): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if (!$iteratee($value, $key, $collection)) { return false; } } return true; } } - namespace _ { use function _\internal\baseIteratee; function find(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice($collection, $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } - namespace _ { function shuffle(array $array = []): array { \shuffle($array); return $array; } } - namespace _ { use function _\internal\baseFlatten; function flatMap(iterable $collection, callable $iteratee = null): array { return baseFlatten(map($collection, $iteratee), 1); } } - namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } - namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, $args); } } - namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } - namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( $array, function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } - namespace _ { function sample(array $array) { return $array[\array_rand($array, 1)]; } } - namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } - namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees) { if (null === $collection) { return []; }; if (\is_callable($iteratees)) { $iteratees = [$iteratees]; } $result = $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } - namespace _ { use function _\internal\createAggregator; function keyBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { $result[$key] = $value; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\createAggregator; function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { $result[$key] = []; } $result[$key][] = $value; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\baseFlatten; function flatMapDepth(iterable $collection, callable $iteratee = null, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } } - namespace _ { use function _\internal\createAggregator; function countBy(iterable $collection, callable $iteratee): array { return createAggregator(function ($result, $key, $value) { if (!isset($result[$value])) { $result[$value] = 0; } $result[$value]++; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\baseIteratee; function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\array_reverse($collection, true), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } + namespace _ { use function _\internal\createAggregator; function partition(iterable $collection, $predicate = null): array { return createAggregator(function ($result, $value, $key) { $result[$key ? 0 : 1][] = $value; return $result; }, function () { return [[], []]; })($collection, $predicate); } } + namespace _ { use function _\internal\baseIteratee; function every(iterable $collection, $predicate): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if (!$iteratee($value, $key, $collection)) { return false; } } return true; } } + namespace _ { use function _\internal\baseIteratee; function find(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\is_array($collection) ? $collection : \iterator_to_array($collection), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } + namespace _ { function shuffle(array $array = []): array { \shuffle($array); return $array; } } + namespace _ { use function _\internal\baseFlatten; function flatMap(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), 1); } } + namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } + namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, $args); } } + namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } + namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } + namespace _ { function sample(array $array) { $key = \array_rand($array, 1); return $array[$key]; } } + namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } + namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees): array { if (null === $collection) { return []; }; if (\is_callable($iteratees)) { $iteratees = [$iteratees]; } $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } + namespace _ { use function _\internal\createAggregator; function keyBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { $result[$key] = $value; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\createAggregator; function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { $result[$key] = []; } $result[$key][] = $value; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\baseFlatten; function flatMapDepth(iterable $collection, callable $iteratee, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } } + namespace _ { use function _\internal\createAggregator; function countBy(iterable $collection, callable $iteratee): array { return createAggregator(function ($result, $key, $value) { if (!isset($result[$value])) { $result[$value] = 0; } $result[$value]++; return $result; })($collection, $iteratee); } } + namespace _ { use function _\internal\baseIteratee; function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\array_reverse(\is_array($collection) ? $collection : \iterator_to_array($collection), true), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } namespace _ { use Symfony\Component\PropertyAccess\PropertyAccess; function property($path): callable { $propertyAccess = PropertyAccess::createPropertyAccessorBuilder() ->disableExceptionOnInvalidIndex() ->getPropertyAccessor(); return function ($value, $index = 0, $collection = []) use ($path, $propertyAccess) { $path = \implode('.', (array) $path); if (\is_array($value)) { if (false !== \strpos($path, '.')) { $paths = \explode('.', $path); foreach ($paths as $path) { $value = property($path)($value, $index, $collection); } return $value; } if (\is_string($path) && $path[0] !== '[' && $path[-1] !== ']') { $path = "[$path]"; } } return $propertyAccess->getValue($value, $path); }; } } namespace _ { function identity($value = null) { return $value; } } namespace _ { function attempt(callable $func, ...$args) { try { return $func(...$args); } catch (\ParseError | \Error | \Throwable | \SoapFault | \DOMException | \PDOException $e) { return $e; } } } @@ -44,7 +44,7 @@ namespace _ { use function _\internal\baseRest; function zip(array ...$arrays): array { return baseRest('\_\unzip')($arrays); } } namespace _ { function compact(?array $array): array { return \array_values(\array_filter($array ?? [])); } } namespace _ { function zipWith(...$arrays): array { $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; return unzipWith($arrays, $iteratee); } } - namespace _ { function uniq(array $array = null): array { return \array_unique($array); } } + namespace _ { function uniq(array $array = []): array { return \array_unique($array); } } namespace _ { function zipObject(array $props = [], array $values = []) { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; $result->{$props[$index]} = $value; } return $result; } } namespace _ { use function _\internal\baseIteratee; use function _\internal\baseUniq; function uniqBy(array $array, $iteratee): array { return baseUniq($array, baseIteratee($iteratee)); } } namespace _ { use function _\internal\baseIteratee; function takeRightWhile(array $array, $predicate): array { $iteratee = baseIteratee($predicate); $result = []; foreach (array_reverse($array, true) as $index => $value) { if ($iteratee($value, $index, $array)) { $result[$index] = $value; } } return array_reverse($result); } } @@ -59,7 +59,7 @@ namespace _ { function drop(array $array, int $n = 1): array { return \array_slice($array, $n); } } namespace _ { use function _\internal\baseRest; function without(array $array, ...$values): array { return baseRest('\_\difference')($array, $values); } } namespace _ { function dropWhile(array $array, callable $predicate): array { \reset($array); $count = \count($array); $length = 0; $index = \key($array); while ($length <= $count && $predicate($array[$index], $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); } return $array; } } - namespace _ { use function _\internal\baseIntersection; function intersectionWith(...$arrays ): array { $copy = $arrays; $comparator = array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; $comparator = null; } return baseIntersection($arrays, null, $comparator); } } + namespace _ { use function _\internal\baseIntersection; function intersectionWith(...$arrays ): array { $copy = $arrays; $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; $comparator = null; } return baseIntersection($arrays, null, $comparator); } } namespace _ { function head(array $array) { reset($array); return current($array) ?: null; } function first(array $array) { return head($array); } } namespace _ { function dropRight(array $array, int $n = 1): array { $count = \count($array); if ($n > $count) { $n = $count; } return \array_slice($array, 0, $count - $n); } } namespace _ { function concat($array, ...$values): array { $check = function ($value): array { return \is_array($value) ? $value : [$value]; }; return \array_merge($check($array), ...\array_map($check, $values)); } } @@ -75,19 +75,19 @@ namespace _ { function pullAll(array &$array, array $values): array { return pull($array, ...$values); } } namespace _ { function union(array ...$arrays): array { return array_unique(array_merge(...$arrays)); } } namespace _ { use function _\internal\baseFlatten; function flatten(array $array = null): array { return baseFlatten($array, 1); } } - namespace _ { use function _\internal\baseFlatten; use function _\internal\baseUniq; function unionWith(... $arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, \array_pop($arrays)); } } + namespace _ { use function _\internal\baseFlatten; use function _\internal\baseUniq; function unionWith(... $arrays): array { $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); } return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, $comparator); } } namespace _ { use function _\internal\baseIteratee; function findIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); if (!$length) { return -1; } $index = $fromIndex ?? 0; if ($index < 0) { $index = \min($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach ($array as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index++; } return -1; } } - namespace _ { use function _\internal\baseFlatten; function flattenDeep(array $array): array { return baseFlatten($array, INF); } } - namespace _ { use function _\internal\arrayMap; function unzipWith(array $array, callable $iteratee): array { if (!\count($array)) { return []; } $result = unzip($array); if (null === $iteratee) { return $result; } return arrayMap($result, function ($group) use ($iteratee) { return $iteratee(...$group); }); } } + namespace _ { use function _\internal\baseFlatten; function flattenDeep(array $array): array { return baseFlatten($array, PHP_INT_MAX); } } + namespace _ { use function _\internal\arrayMap; function unzipWith(array $array, ?callable $iteratee = null): array { if (!\count($array)) { return []; } $result = unzip($array); if (!is_callable($iteratee)) { return $result; } return arrayMap($result, function ($group) use ($iteratee) { return $iteratee(...$group); }); } } namespace _ { function nth(array $array, int $n) { return \array_values($array)[$n < 0 ? \count($array) + $n : $n] ?? null; } } namespace _ { use function _\internal\baseFlatten; function differenceBy(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $iteratee = \array_pop($values); $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $computed = $iteratee($value); $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($computed === $values[$valuesIndex]) { continue 2; } } $result[] = $value; } return $result; } } namespace _ { use function _\internal\baseFlatten; use function _\internal\baseIteratee; use function _\internal\baseUniq; function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } } namespace _ { use function _\internal\baseIntersection; use function _\internal\baseIteratee; function intersectionBy(...$arrays): array { $iteratee = \array_pop($arrays); return baseIntersection($arrays, baseIteratee($iteratee)); } } namespace _ { function now(): int { return (int) (\microtime(true) * 1000); } } - namespace _\internal { function baseUnary($func) { return function ($value) use ($func) { return $func($value); }; } } + namespace _\internal { function baseUnary($func) { return function ($value) use ($func) { return $func($value); }; } } namespace _\internal { function stringToArray(string $string): array { return hasUnicode($string) ? unicodeToArray($string) : \str_split($string); } } namespace _\internal { function createMathOperation(callable $operator, $defaultValue) { return function ($value, $other) use ($defaultValue, $operator) { if (null === $value && null === $other) { return $defaultValue; } $result = null; if (null !== $value) { $result = $value; } if (null !== $other) { if (null === $result) { return $other; } $result = $operator($value, $other); } return $result; }; } } - namespace _\internal { use function _\each; function createAggregator($setter, $initializer = null) { return function ($collection, $iteratee) use ($setter, $initializer) { $accumulator = null !== $initializer ? $initializer() : []; $func = function ($collection, $setter, &$accumulator, $iteratee) { each($collection, function ($value, $key, $collection) use ($setter, &$accumulator, $iteratee) { $accumulator = $setter($accumulator, $value, $iteratee($value), $collection); }); return $accumulator; }; return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); }; } } + namespace _\internal { use function _\each; function createAggregator($setter, $initializer = null) { return function ($collection, $iteratee) use ($setter, $initializer) { $accumulator = null !== $initializer ? $initializer() : []; $func = function ($collection, $setter, &$accumulator, $iteratee) { each($collection, function ($value, $key, $collection) use ($setter, &$accumulator, $iteratee) { $accumulator = $setter($accumulator, $value, $iteratee($value), $collection); }); return $accumulator; }; return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); }; } } namespace _\internal { use function _\isEqual; use function _\property; function baseMatches($source): callable { return function ($value, $index, $collection) use ($source): bool { if ($value === $source || isEqual($value, $source)) { return true; } if (\is_array($source) || $source instanceof \Traversable) { foreach ($source as $k => $v) { if (!isEqual(property($k)($value, $index, $collection), $v)) { return false; } } return true; } return false; }; } } namespace _\internal { function baseTimes(int $n, callable $iteratee) { $index = -1; $result = []; while (++$index < $n) { $result[$index] = $iteratee($index); } return $result; } } namespace _\internal { function arrayMap(?array $array, callable $iteratee) { $index = -1; $length = null === $array ? 0 : \count($array); $result = []; while (++$index < $length) { $result[$index] = $iteratee($array[$index], $index, $array); } return $result; } } @@ -98,9 +98,9 @@ namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } - namespace _\internal { function unicodeSize($string): int { return \preg_match_all(reUnicode, $string); } } - namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\internal\baseIndexOfWith' : '_\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } - namespace _\internal { function baseFlatten(?array $array, float $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '\_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { $result = \array_merge($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } + namespace _\internal { function unicodeSize(string $string): int { return \preg_match_all(reUnicode, $string) ?: 0; } } + namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\\internal\\baseIndexOfWith' : '_\\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } + namespace _\internal { function baseFlatten(?array $array, int $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { $result = \array_merge($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); } } namespace _\internal { function arrayIncludesWith(?array $array, $value, callable $comparator) { $array = $array ?? []; foreach ($array as $v) { if ($comparator($value, $v)) { return true; } } return false; } } @@ -108,31 +108,31 @@ namespace _\internal { function baseProperty($key) { return function ($object) use ($key) { return null === $object ? null : $object[$key]; }; } } namespace _\internal { use function _\isEqual; use function _\property; function baseMatchesProperty($property, $source): callable { return function ($value, $index, $collection) use ($property, $source) { return isEqual(property($property)($value, $index, $collection), $source); }; } } namespace _\internal { function castPath($value, $object): array { if (\is_array($value)) { return $value; } return isKey($value, $object) ? [$value] : stringToPath((string) $value); } } - namespace _\internal { use function _\map; use function _\sortBy; function baseOrderBy(iterable $collection, array $iteratees, array $orders): array { $index = -1; $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); $result = map($collection, function ($value) use ($iteratees, &$index) { $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { return $iteratee($value); }); return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; }); return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); } } + namespace _\internal { use function _\map; use function _\sortBy; function baseOrderBy(iterable $collection, array $iteratees, array $orders): array { $index = -1; $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); $result = map($collection, function ($value) use ($iteratees, &$index) { $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { return $iteratee($value); }); return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; }); return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); } } namespace _\internal { use function _\property; function baseIteratee($value): callable { if (\is_callable($value)) { return $value; } if (null === $value) { return '_\identity'; } if (\is_array($value)) { return 2 === \count($value) && [0, 1] === \array_keys($value) ? baseMatchesProperty($value[0], $value[1]) : baseMatches($value); } return property($value); } } - namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } + namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } namespace _\internal { use function _\eq; function assocIndexOf(array $array, $key): int { $length = \count($array); while ($length--) { if (eq($array[$length][0], $key)) { return $length; } } return -1; } } - namespace _\internal { function parent($object, $path) { return count($path) < 2 ? $object : null; } } + namespace _\internal { function parent($object, $path) { return count($path) < 2 ? $object : null; } } namespace _\internal { use function _\indexOf; function arrayIncludes(?array $array, $value) { return null !== $array && indexOf($array, $value, 0) > -1; } } namespace _\internal { const reLeadingDot = '/^\./'; const rePropName = '#[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["\'])((?:(?!\2)[^\\\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))#'; const reEscapeChar = '/\\(\\)?/g'; function stringToPath(...$args) { return memoizeCapped(function ($string) { $result = []; if (\preg_match(reLeadingDot, $string)) { $result[] = ''; } \preg_match_all(rePropName, $string, $matches, PREG_SPLIT_DELIM_CAPTURE); foreach ($matches as $match) { $result[] = $match[1] ?? $match[0]; } return $result; })(...$args); } } namespace _\internal { function baseUniq(array $array, callable $iteratee = null, callable $comparator = null) { $index = -1; $includes = '\_\internal\arrayIncludes'; $length = \count($array); $isCommon = true; $result = []; $seen = $result; if ($comparator) { $isCommon = false; $includes = '\_\internal\arrayIncludesWith'; } else { $seen = $iteratee ? [] : $result; } while (++$index < $length) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator || $value !== 0) ? $value : 0; if ($isCommon && $computed) { $seenIndex = \count($seen); while ($seenIndex--) { if ($seen[$seenIndex] === $computed) { continue 2; } } if ($iteratee) { $seen[] = $computed; } $result[] = $value; } elseif (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } $result[] = $value; } } return $result; } } namespace _\internal { function unicodeWords(string $string): array { $regex = '#'.\implode('|', [ rsUpper.'?'.rsLower.'+'.rsOptContrLower.'(?='.\implode('|', [rsBreak, rsUpper, '$']).')', rsMiscUpper.'+'.rsOptContrUpper.'(?='.\implode('|', [rsBreak, rsUpper.rsMiscLower, '$']).')', rsUpper.'?'.rsMiscLower.'+'.rsOptContrLower, rsUpper.'+'.rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji, ]).'#u'; if (\preg_match_all($regex, $string, $matches) > 0) { return $matches[0]; } return []; } } namespace _\internal { use function _\memoize; function memoizeCapped(callable $func) { $MaxMemoizeSize = 500; $result = memoize($func, function ($key) use ($MaxMemoizeSize) { if ($this->cache->getSize() === $MaxMemoizeSize) { $this->cache->clear(); } return $key; }); return $result; } } - namespace _\internal { function baseIntersection($arrays, ?callable $iteratee, $comparator = null) { $includes = $comparator ? '_\internal\arrayIncludesWith' : '_\internal\arrayIncludes'; $length = \count($arrays[0]); $othLength = \count($arrays); $othIndex = $othLength; $caches = []; $maxLength = INF; $result = []; while ($othIndex--) { $array =& $arrays[$othIndex]; if ($othIndex && $iteratee) { $array = \array_map($iteratee, $array); } $maxLength = \min(\count($array), $maxLength); $caches[$othIndex] = !$comparator && $iteratee ? [] : null; } $array = $arrays[0]; $index = -1; $seen = $caches[0]; while (++$index < $length && \count($result) < $maxLength) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator ?: $value !== 0) ? $value : 0; if (!($seen ? isset($seen[$computed]) : $includes($result, $computed, $comparator))) { $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; if (!($cache ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { continue 2; } } if ($seen) { $seen[] = $computed; } $result[] = $value; } } return $result; } } + namespace _\internal { function baseIntersection($arrays, ?callable $iteratee, $comparator = null) { $includes = $comparator ? '_\internal\arrayIncludesWith' : '_\internal\arrayIncludes'; $length = \count($arrays[0]); $othLength = \count($arrays); $othIndex = $othLength; $caches = []; $maxLength = INF; $result = []; while ($othIndex--) { $array =& $arrays[$othIndex]; if ($othIndex && $iteratee) { $array = \array_map($iteratee, $array); } $maxLength = \min(\count($array), $maxLength); $caches[$othIndex] = !$comparator && $iteratee ? [] : null; } $array = $arrays[0]; $index = -1; $seen = $caches[0]; while (++$index < $length && \count($result) < $maxLength) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator ?: $value !== 0) ? $value : 0; if (!($seen ? \is_scalar($computed) && isset($seen[$computed]) : $includes($result, $computed, $comparator))) { $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; if (!(!empty($cache) ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { continue 2; } } if (empty($seen)) { $seen[] = $computed; } $result[] = $value; } } return $result; } } namespace _\internal { function baseSet($object, $path, $value, callable $customizer = null) { if (!\is_object($object)) { return $object; } $path = castPath($path, $object); $index = -1; $length = \count($path); $lastIndex = $length - 1; $nested = $object; while ($nested !== null && ++$index < $length) { $key = toKey($path[$index]); if ($index !== $lastIndex) { $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; if (null === $newValue) { $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); } if (\is_array($nested)) { $nested[$key] = $newValue; } else { $nested->{$key} = $newValue; } if (\is_array($nested)) { $nested = &$nested[$key]; } else { $nested = &$nested->$key; } continue; } $nested->{$key} = $value; } return $object; } } namespace _\internal { function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } } - namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return null === $func ? null : $func($object, ...$args); } } + namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return \is_callable($func) ? $func($object, ...$args) : null; } } namespace _\internal { const reHasUnicode = '['.rsZWJ.rsAstralRange.rsComboRange.rsVarRange.']'; function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; } } namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } - namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count($array); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } + namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } - namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } - namespace _ { function memoize(callable $func = null, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result) ?: $this->cache; return $result; } }; $memoized->cache = new MapCache; return $memoized; } } + namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } + namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } - namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } - namespace _ { function max(?array $array): ?int { return $array ? \max($array) : null; } } + namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } + namespace _ { function max(?array $array): ?int { return $array ? \max($array) : null; } } namespace _ { function clamp(int $number, int $lower, int $upper): int { $number = $number <= $upper ? $number : $upper; $number = $number >= $lower ? $number : $lower; return $number; } } - namespace _ { function inRange(float $number, float $start = 0, float $end = 0): bool { if (0 === $end || 0.0 === $end) { $end = $start; $start = 0; } return $number >= \min($start, $end) && $number < \max($start, $end); } } + namespace _ { function inRange(float $number, float $start = 0, float $end = 0): bool { if (0.0 === $end) { $end = $start; $start = 0; } return $number >= \min($start, $end) && $number < \max($start, $end); } } namespace _ { function random($lower = null, $upper = null, $floating = null) { if (null === $floating) { if (\is_bool($upper)) { $floating = $upper; $upper = null; } elseif (\is_bool($lower)) { $floating = $lower; $lower = null; } } if (null === $lower && null === $upper) { $lower = 0; $upper = 1; } elseif (null === $upper) { $upper = $lower; $lower = 0; } if ($lower > $upper) { $temp = $lower; $lower = $upper; $upper = $temp; } $floating = $floating || (\is_float($lower) || \is_float($upper)); if ($floating || $lower % 1 || $upper % 1) { $randMax = \mt_getrandmax(); return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } return \rand((int) $lower, (int) $upper); } } namespace _ { function isError($value): bool { if (!\is_object($value)) { return false; } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; } } namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } @@ -152,18 +152,18 @@ namespace _ { use function _\internal\unicodeWords; const asciiWords = '/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/'; const hasUnicodeWord = '/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/'; function words(string $string, string $pattern = null): array { if (null === $pattern) { if (\preg_match(hasUnicodeWord, $string)) { return unicodeWords($string); } \preg_match_all(asciiWords, $string, $matches); return $matches[0] ?? []; } if (\preg_match_all($pattern, $string, $matches) > 0) { return $matches[0]; } return []; } } namespace _ { function unescape(string $string): string { return \html_entity_decode($string); } } namespace _ { function startCase(string $string) { return \implode(' ', \array_map('\ucfirst', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } - namespace _ { function replace(string $string, string $pattern, $replacement = ''): string { $callback = function (array $matches) use ($replacement): ?string { if (!\array_filter($matches)) { return null; } return $replacement(...$matches); }; if (\preg_match(reRegExpChar, $pattern)) { if (!is_callable($replacement)) { return \preg_replace($pattern, $replacement, $string); } return \preg_replace_callback($pattern, $callback, $string); } return \str_replace($pattern, $replacement, $string); } } + namespace _ { function replace(string $string, string $pattern, $replacement = null): string { $callback = function (array $matches) use ($replacement): ?string { if (!\array_filter($matches)) { return null; } return \is_callable($replacement) ? $replacement(...$matches) : null; }; if (\preg_match(reRegExpChar, $pattern)) { if (!\is_callable($replacement)) { return \preg_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } return \preg_replace_callback($pattern, $callback, $string); } return \str_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } } namespace _ { function snakeCase(string $string): string { return \implode('_', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } namespace _ { const reRegExpChar = '/([\\^$.*+?()[\]{}|])/'; function escapeRegExp(string $string): string { return \preg_replace(reRegExpChar, '\\\$0', $string); } } namespace _ { function toUpper(string $string): string { return \strtoupper($string); } } namespace _ { function startsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? 0 : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } namespace _ { function capitalize(string $string): string { return \ucfirst(\mb_strtolower($string)); } } - namespace _ { use function _\internal\castSlice; use function _\internal\hasUnicode; use function _\internal\stringSize; use function _\internal\stringToArray; const DEFAULT_TRUNC_LENGTH = 30; const DEFAULT_TRUNC_OMISSION = '...'; function truncate($string, array $options = []) { $separator = $options['separator'] ?? null; $length = $options['length'] ?? DEFAULT_TRUNC_LENGTH; $omission = $options['omission'] ?? DEFAULT_TRUNC_OMISSION; $strSymbols = null; $strLength = \strlen($string); if (hasUnicode($string)) { $strSymbols = stringToArray($string); $strLength = \count($strSymbols); } if ($length >= $strLength) { return $string; } $end = $length - stringSize($omission); if ($end < 1) { return $omission; } $result = $strSymbols ? \implode('', castSlice($strSymbols, 0, $end)) : \substr($string, 0, $end); if (null === $separator) { return $result.$omission; } if ($strSymbols) { $end += \strlen($result) - $end; } if (\preg_match(reRegExpChar, $separator)) { if (\preg_match($separator, \substr($string, 0, $end))) { $match = null; $newEnd = null; $substring = $result; if (\preg_match_all($separator, $substring, $match, PREG_OFFSET_CAPTURE)) { $newEnd = \end($match[0])[1]; } $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if ($index > -1) { $result = \substr($result, 0, $index); } } return $result.$omission; } } + namespace _ { use function _\internal\castSlice; use function _\internal\hasUnicode; use function _\internal\stringSize; use function _\internal\stringToArray; const DEFAULT_TRUNC_LENGTH = 30; const DEFAULT_TRUNC_OMISSION = '...'; function truncate($string, array $options = []) { $separator = $options['separator'] ?? null; $length = $options['length'] ?? DEFAULT_TRUNC_LENGTH; $omission = $options['omission'] ?? DEFAULT_TRUNC_OMISSION; $strSymbols = null; $strLength = \strlen($string); if (hasUnicode($string)) { $strSymbols = stringToArray($string); $strLength = \count($strSymbols); } if ($length >= $strLength) { return $string; } $end = $length - stringSize($omission); if ($end < 1) { return $omission; } $result = $strSymbols ? \implode('', castSlice($strSymbols, 0, $end)) : \substr($string, 0, $end); if (null === $separator) { return $result.$omission; } if ($strSymbols) { $end += \strlen($result) - $end; } if (\preg_match(reRegExpChar, $separator)) { if (\preg_match($separator, \substr($string, 0, $end))) { $match = null; $newEnd = null; $substring = $result; if (\preg_match_all($separator, $substring, $match, PREG_OFFSET_CAPTURE)) { $newEnd = \end($match[0])[1]; } $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if (false !== $index && $index > -1) { $result = \substr($result, 0, $index); } } return $result.$omission; } } namespace _ { function upperCase(string $string) { return \implode(' ', \array_map('\strtoupper', words(\preg_replace(reQuotes, '', $string)))); } } namespace _ { function endsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? $length : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } $position -= \strlen($target); return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } - namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } + namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); if (!$file) { throw new \RuntimeException('Unable to create temporary file for template'); } \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } namespace _ { function padEnd(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_RIGHT); } } - namespace _ { function split(string $string, string $separator, int $limit = null): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE); } $result = \explode($separator, $string); if ($limit > 0) { return \array_splice($result, 0, $limit); } return $result; } } + namespace _ { function split(string $string, string $separator, int $limit = 0): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; } $result = \explode($separator, $string); if ($limit > 0) { return \array_splice($result, 0, $limit); } return $result; } } namespace _ { function toLower(string $string): string { return \strtolower($string); } } namespace _ { function escape(string $string) { return \htmlentities($string); } } namespace _ { function kebabCase(string $string) { return \implode('-', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } diff --git a/src/internal/baseIntersection.php b/src/internal/baseIntersection.php index da97b4b..e366d37 100644 --- a/src/internal/baseIntersection.php +++ b/src/internal/baseIntersection.php @@ -41,7 +41,7 @@ function baseIntersection($arrays, ?callable $iteratee, $comparator = null) $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator ?: $value !== 0) ? $value : 0; - if (!($seen ? isset($seen[$computed]) : $includes($result, $computed, $comparator))) { + if (!($seen ? \is_scalar($computed) && isset($seen[$computed]) : $includes($result, $computed, $comparator))) { $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; diff --git a/src/internal/baseInvoke.php b/src/internal/baseInvoke.php index 0f8ad3b..1170f84 100644 --- a/src/internal/baseInvoke.php +++ b/src/internal/baseInvoke.php @@ -17,6 +17,7 @@ function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); + /** @var callable|null $func */ $func = null === $object ? $object : [$object, toKey(last($path))]; return \is_callable($func) ? $func($object, ...$args) : null; diff --git a/tests/Array/DifferenceByTest.php b/tests/Array/DifferenceByTest.php index ac23860..ac13c82 100644 --- a/tests/Array/DifferenceByTest.php +++ b/tests/Array/DifferenceByTest.php @@ -14,7 +14,7 @@ class DifferenceByTest extends TestCase { - public function testChunk() + public function testDifferenceBy() { $this->assertSame([], differenceBy([])); $this->assertSame([1, 2], differenceBy([1, 2], [3, 4])); diff --git a/tests/Array/IntersectionWithTest.php b/tests/Array/IntersectionWithTest.php index fc73fa0..d8da175 100644 --- a/tests/Array/IntersectionWithTest.php +++ b/tests/Array/IntersectionWithTest.php @@ -19,7 +19,7 @@ public function testIntersectionWith() $objects = [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1]]; $others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]]; - $this->assertSame([['x' => 1, 'y' => 2]], intersectionWith($objects, $others, '_::isEqual')); + $this->assertSame([['x' => 1, 'y' => 2]], intersectionWith($objects, $others, '_\isEqual')); $this->assertSame([['x' => 1, 'y' => 2]], intersectionWith($objects, $others)); } } diff --git a/tests/Collection/CountByTest.php b/tests/Collection/CountByTest.php index c2d3bd2..0f7d329 100644 --- a/tests/Collection/CountByTest.php +++ b/tests/Collection/CountByTest.php @@ -19,4 +19,4 @@ public function testCountBy() $this->assertSame(['6' => 2, '4' => 1], countBy([6.1, 4.2, 6.3], 'floor')); $this->assertSame(['3' => 2, '5' => 1], countBy(['one', 'two', 'three'], 'strlen')); } -} \ No newline at end of file +} diff --git a/tests/Collection/EachRightTest.php b/tests/Collection/EachRightTest.php index ed62bca..ee68693 100644 --- a/tests/Collection/EachRightTest.php +++ b/tests/Collection/EachRightTest.php @@ -28,4 +28,4 @@ public function testForEachRight() }); $this->assertSame([2 => true, 1 => true], $test); } -} \ No newline at end of file +} diff --git a/tests/Collection/EveryTest.php b/tests/Collection/EveryTest.php index 37a3f07..bb118eb 100644 --- a/tests/Collection/EveryTest.php +++ b/tests/Collection/EveryTest.php @@ -16,7 +16,9 @@ class EveryTest extends TestCase { public function testEvery() { - $this->assertFalse(every([true, 1, null, 'yes'], function ($value) { return is_bool($value); })); + $this->assertFalse(every([true, 1, null, 'yes'], function ($value) { + return is_bool($value); + })); $users = [ ['user' => 'barney', 'age' => 36, 'active' => false], @@ -32,4 +34,4 @@ public function testEvery() // The `property` iteratee shorthand. $this->assertFalse(every($users, 'active')); } -} \ No newline at end of file +} diff --git a/tests/Collection/FilterTest.php b/tests/Collection/FilterTest.php index e590053..0adcc8c 100644 --- a/tests/Collection/FilterTest.php +++ b/tests/Collection/FilterTest.php @@ -21,7 +21,9 @@ public function testFilter() ['user' => 'fred', 'age' => 40, 'active' => false], ]; - $this->assertSame([['user' => 'fred', 'age' => 40, 'active' => false]], filter($users, function ($o) { return !$o['active']; })); + $this->assertSame([['user' => 'fred', 'age' => 40, 'active' => false]], filter($users, function ($o) { + return !$o['active']; + })); // The `matches` iteratee shorthand. $this->assertSame([['user' => 'barney', 'age' => 36, 'active' => true]], filter($users, ['age' => 36, 'active' => true])); @@ -32,4 +34,4 @@ public function testFilter() // The `property` iteratee shorthand. $this->assertSame([['user' => 'barney', 'age' => 36, 'active' => true]], filter($users, 'active')); } -} \ No newline at end of file +} diff --git a/tests/Collection/FindLastTest.php b/tests/Collection/FindLastTest.php index 0ee7a88..f018a06 100644 --- a/tests/Collection/FindLastTest.php +++ b/tests/Collection/FindLastTest.php @@ -16,6 +16,8 @@ class FindLastTest extends TestCase { public function testFindLast() { - $this->assertSame(3, findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; })); + $this->assertSame(3, findLast([1, 2, 3, 4], function ($n) { + return $n % 2 == 1; + })); } -} \ No newline at end of file +} diff --git a/tests/Collection/FindTest.php b/tests/Collection/FindTest.php index 5845e64..7d28e6d 100644 --- a/tests/Collection/FindTest.php +++ b/tests/Collection/FindTest.php @@ -22,7 +22,9 @@ public function testFind() ['user' => 'pebbles', 'age' => 1, 'active' => true], ]; - $this->assertSame(['user' => 'barney', 'age' => 36, 'active' => true], find($users, function ($o) { return $o['age'] < 40; })); + $this->assertSame(['user' => 'barney', 'age' => 36, 'active' => true], find($users, function ($o) { + return $o['age'] < 40; + })); // The `matches` iteratee shorthand. $this->assertSame(['user' => 'pebbles', 'age' => 1, 'active' => true], find($users, ['age' => 1, 'active' => true])); @@ -33,4 +35,4 @@ public function testFind() // The `property` iteratee shorthand. $this->assertSame(['user' => 'barney', 'age' => 36, 'active' => true], find($users, 'active')); } -} \ No newline at end of file +} diff --git a/tests/Collection/FlatMapDeepTest.php b/tests/Collection/FlatMapDeepTest.php index a000dcb..5a99382 100644 --- a/tests/Collection/FlatMapDeepTest.php +++ b/tests/Collection/FlatMapDeepTest.php @@ -22,4 +22,4 @@ public function testFlatMapDeep() $this->assertSame([1, 1, 2, 2], flatMapDeep([1, 2], $duplicate)); } -} \ No newline at end of file +} diff --git a/tests/Collection/FlatMapDepthTest.php b/tests/Collection/FlatMapDepthTest.php index f4897de..0cfea01 100644 --- a/tests/Collection/FlatMapDepthTest.php +++ b/tests/Collection/FlatMapDepthTest.php @@ -22,4 +22,4 @@ public function testFlatMapDepth() $this->assertSame([[1, 1], [2, 2]], flatMapDepth([1, 2], $duplicate, 2)); } -} \ No newline at end of file +} diff --git a/tests/Collection/FlatMapTest.php b/tests/Collection/FlatMapTest.php index 93285c7..17bbcd6 100644 --- a/tests/Collection/FlatMapTest.php +++ b/tests/Collection/FlatMapTest.php @@ -22,4 +22,4 @@ public function testFlatMap() $this->assertSame([1, 1, 2, 2], flatMap([1, 2], $duplicate)); } -} \ No newline at end of file +} diff --git a/tests/Collection/GroupByTest.php b/tests/Collection/GroupByTest.php index ff7b91f..78cf4e7 100644 --- a/tests/Collection/GroupByTest.php +++ b/tests/Collection/GroupByTest.php @@ -19,4 +19,4 @@ public function testCountBy() $this->assertSame(['6' => [6.1, 6.3], '4' => [4.2]], groupBy([6.1, 4.2, 6.3], 'floor')); $this->assertSame(['3' => ['one', 'two'], '5' => ['three']], groupBy(['one', 'two', 'three'], 'strlen')); } -} \ No newline at end of file +} diff --git a/tests/Collection/InvokeMapTest.php b/tests/Collection/InvokeMapTest.php index fddc83b..d1e4e11 100644 --- a/tests/Collection/InvokeMapTest.php +++ b/tests/Collection/InvokeMapTest.php @@ -16,18 +16,27 @@ class InvokeMapTest extends TestCase { public function testInvokeMap() { - $this->assertSame([[1, 5, 7], [1, 2, 3]], invokeMap([[5, 1, 7], [3, 2, 1]], function($result) { sort($result); return $result;})); + $this->assertSame([[1, 5, 7], [1, 2, 3]], invokeMap([[5, 1, 7], [3, 2, 1]], function ($result) { + sort($result); + return $result; + })); $this->assertSame([['1', '2', '3'], ['4', '5', '6']], invokeMap([123, 456], 'str_split')); $users = [ - new class () { - public function getCount() { return 12; } + new class() { + public function getCount() + { + return 12; + } }, - new class () { - public function getCount() { return 24; } + new class() { + public function getCount() + { + return 24; + } } ]; $this->assertEquals([12, 24], invokeMap($users, 'getCount')); } -} \ No newline at end of file +} diff --git a/tests/Collection/KeyByTest.php b/tests/Collection/KeyByTest.php index 5dee637..3ca8fc8 100644 --- a/tests/Collection/KeyByTest.php +++ b/tests/Collection/KeyByTest.php @@ -21,7 +21,9 @@ public function testKeyBy() ['direction' => 'right', 'code' => 100], ]; - $this->assertSame(['a' => ['direction' => 'left', 'code' => 97], 'd' => ['direction' => 'right', 'code' => 100]], keyBy($array, function ($o) { return \chr($o['code']); })); + $this->assertSame(['a' => ['direction' => 'left', 'code' => 97], 'd' => ['direction' => 'right', 'code' => 100]], keyBy($array, function ($o) { + return \chr($o['code']); + })); $this->assertSame(['left' => ['direction' => 'left', 'code' => 97], 'right' => ['direction' => 'right', 'code' => 100]], keyBy($array, 'direction')); } -} \ No newline at end of file +} diff --git a/tests/Collection/OrderByTest.php b/tests/Collection/OrderByTest.php index 35b577a..1164c0d 100644 --- a/tests/Collection/OrderByTest.php +++ b/tests/Collection/OrderByTest.php @@ -25,4 +25,4 @@ public function testOrderBy() $this->assertSame([['user' => 'barney', 'age' => 36], ['user' => 'barney', 'age' => 34], ['user' => 'fred', 'age' => 48], ['user' => 'fred', 'age' => 40]], orderBy($users, ['user', 'age'], ['asc', 'desc'])); } -} \ No newline at end of file +} diff --git a/tests/Collection/PartitionTest.php b/tests/Collection/PartitionTest.php index 75a022b..7c228ee 100644 --- a/tests/Collection/PartitionTest.php +++ b/tests/Collection/PartitionTest.php @@ -32,6 +32,8 @@ public function testPartition() ], ]; - $this->assertSame($result, partition($users, function ($user) { return $user['active']; })); + $this->assertSame($result, partition($users, function ($user) { + return $user['active']; + })); } -} \ No newline at end of file +} diff --git a/tests/Collection/ReduceRightTest.php b/tests/Collection/ReduceRightTest.php index 2863529..905fafd 100644 --- a/tests/Collection/ReduceRightTest.php +++ b/tests/Collection/ReduceRightTest.php @@ -17,6 +17,8 @@ class ReduceRightTest extends TestCase public function testReduceRight() { $array = [[0, 1], [2, 3], [4, 5]]; - $this->assertSame([4, 5, 2, 3, 0, 1], reduceRight($array, function ($flattened, $other) { return \array_merge($flattened, $other); }, [])); + $this->assertSame([4, 5, 2, 3, 0, 1], reduceRight($array, function ($flattened, $other) { + return \array_merge($flattened, $other); + }, [])); } -} \ No newline at end of file +} diff --git a/tests/Collection/ReduceTest.php b/tests/Collection/ReduceTest.php index b987bb8..75e38e9 100644 --- a/tests/Collection/ReduceTest.php +++ b/tests/Collection/ReduceTest.php @@ -16,7 +16,9 @@ class ReduceTest extends TestCase { public function testReduce() { - $this->assertSame(3, reduce([1, 2], function ($sum, $n) { return $sum + $n; }, 0)); + $this->assertSame(3, reduce([1, 2], function ($sum, $n) { + return $sum + $n; + }, 0)); $this->assertSame(['1' => ['a', 'c'], '2' => ['b']], reduce(['a' => 1, 'b' => 2, 'c' => 1], function ($result, $value, $key) { if (!isset($result[$value])) { $result[$value] = []; @@ -26,4 +28,4 @@ public function testReduce() return $result; }, [])); } -} \ No newline at end of file +} diff --git a/tests/Collection/RejectTest.php b/tests/Collection/RejectTest.php index e340c37..bbfe2e2 100644 --- a/tests/Collection/RejectTest.php +++ b/tests/Collection/RejectTest.php @@ -23,4 +23,4 @@ public function testReject() $this->assertSame([['user' => 'fred', 'active' => false]], reject($users, 'active')); } -} \ No newline at end of file +} diff --git a/tests/Collection/SampleSizeTest.php b/tests/Collection/SampleSizeTest.php index 128d581..b00bc98 100644 --- a/tests/Collection/SampleSizeTest.php +++ b/tests/Collection/SampleSizeTest.php @@ -22,4 +22,4 @@ public function testSampleSize() $this->assertCount(3, sampleSize([1, 2, 3], 4)); $this->assertSame([1, 2, 3], sampleSize([1, 2, 3], 4)); } -} \ No newline at end of file +} diff --git a/tests/Collection/SampleTest.php b/tests/Collection/SampleTest.php index 5358837..3730214 100644 --- a/tests/Collection/SampleTest.php +++ b/tests/Collection/SampleTest.php @@ -18,4 +18,4 @@ public function testSample() { $this->assertContains(sample([1, 2, 3, 4]), [1, 2, 3, 4]); } -} \ No newline at end of file +} diff --git a/tests/Collection/ShuffleTest.php b/tests/Collection/ShuffleTest.php index 567a093..76e48c7 100644 --- a/tests/Collection/ShuffleTest.php +++ b/tests/Collection/ShuffleTest.php @@ -20,4 +20,4 @@ public function testShuffle() $this->assertNotSame($arr, shuffle($arr)); $this->assertSame([], \array_diff($arr, shuffle($arr))); } -} \ No newline at end of file +} diff --git a/tests/Collection/SizeTest.php b/tests/Collection/SizeTest.php index 9ec5eb6..490bf89 100644 --- a/tests/Collection/SizeTest.php +++ b/tests/Collection/SizeTest.php @@ -17,8 +17,7 @@ class SizeTest extends TestCase public function testSize() { $this->assertSame(3, size([1, 2, 3])); - $this->assertSame(2, size(new class - { + $this->assertSame(2, size(new class { public $a = 1; public $b = 2; @@ -26,13 +25,15 @@ public function testSize() private $c = 3; })); - $this->assertSame(12, size(new class implements \Countable - { - public function count() { return 12; } + $this->assertSame(12, size(new class implements \Countable { + public function count() + { + return 12; + } })); $this->assertSame(4, size(new \ArrayIterator([1, 2, 3, 4]))); $this->assertSame(7, size('pebbles')); } -} \ No newline at end of file +} diff --git a/tests/Collection/SomeTest.php b/tests/Collection/SomeTest.php index bead49c..b8c0b99 100644 --- a/tests/Collection/SomeTest.php +++ b/tests/Collection/SomeTest.php @@ -21,9 +21,11 @@ public function testSome() ['user' => 'fred', 'active' => false], ]; - $this->assertTrue(some([null, 0, 'yes', false], function ($value) { return \is_bool($value); })); + $this->assertTrue(some([null, 0, 'yes', false], function ($value) { + return \is_bool($value); + })); $this->assertFalse(some($users, ['user' => 'barney', 'active' => false])); $this->assertTrue(some($users, ['active', false])); $this->assertTrue(some($users, 'active')); } -} \ No newline at end of file +} diff --git a/tests/Math/MaxByTest.php b/tests/Math/MaxByTest.php index 97fe5c6..77deba1 100644 --- a/tests/Math/MaxByTest.php +++ b/tests/Math/MaxByTest.php @@ -17,7 +17,9 @@ class MaxByTest extends TestCase public function testMax() { $objects = [['n' => 1], ['n' => 2]]; - $this->assertSame(['n' => 2], maxBy($objects, function ($o) { return $o['n']; })); + $this->assertSame(['n' => 2], maxBy($objects, function ($o) { + return $o['n']; + })); $this->assertSame(['n' => 2], maxBy($objects, 'n')); } } From dab895b707f47eb32bd357f71898ea25f234a45b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 13:05:26 +0200 Subject: [PATCH 081/159] Fix indentation in config --- phpstan.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 0882dcc..4b49f37 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,5 +5,5 @@ parameters: - %rootDir%/../../../../../src/Lodash.php - %rootDir%/../../../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" + - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' + - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" From 980e5ea91e7c2c8f06e525335627896c54676552 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 13:41:54 +0200 Subject: [PATCH 082/159] Fix CS --- src/Object/pick.php | 2 +- src/Object/pickBy.php | 2 +- src/internal/arrayPush.php | 2 +- src/internal/basePick.php | 4 ++-- src/internal/basePickBy.php | 2 +- tests/Object/PickByTest.php | 4 +++- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Object/pick.php b/src/Object/pick.php index ba4b08d..54d488c 100644 --- a/src/Object/pick.php +++ b/src/Object/pick.php @@ -35,4 +35,4 @@ function pick($object, $paths): \stdClass return flatRest(function ($object, ...$paths) { return basePick($object, $paths); })($object, $paths); -} \ No newline at end of file +} diff --git a/src/Object/pickBy.php b/src/Object/pickBy.php index 97befb7..d3860fb 100644 --- a/src/Object/pickBy.php +++ b/src/Object/pickBy.php @@ -46,4 +46,4 @@ function pickBy($object, callable $predicate): \stdClass return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); -} \ No newline at end of file +} diff --git a/src/internal/arrayPush.php b/src/internal/arrayPush.php index d0bb2ec..a0af2b3 100644 --- a/src/internal/arrayPush.php +++ b/src/internal/arrayPush.php @@ -22,4 +22,4 @@ function arrayPush(&$array, $values) } return $array; -} \ No newline at end of file +} diff --git a/src/internal/basePick.php b/src/internal/basePick.php index 7542c74..477ab46 100644 --- a/src/internal/basePick.php +++ b/src/internal/basePick.php @@ -13,7 +13,7 @@ function basePick($object, $paths): \stdClass { - return basePickBy($object, $paths, function($value, $path) use ($object) { + return basePickBy($object, $paths, function ($value, $path) use ($object) { return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); }); -} \ No newline at end of file +} diff --git a/src/internal/basePickBy.php b/src/internal/basePickBy.php index ca6fff9..3176a70 100644 --- a/src/internal/basePickBy.php +++ b/src/internal/basePickBy.php @@ -27,4 +27,4 @@ function basePickBy($object, $paths, callable $predicate): \stdClass } return $result; -} \ No newline at end of file +} diff --git a/tests/Object/PickByTest.php b/tests/Object/PickByTest.php index 0ec887f..5683f57 100644 --- a/tests/Object/PickByTest.php +++ b/tests/Object/PickByTest.php @@ -18,6 +18,8 @@ public function testPick() { $object = (object) ['a' => 1, 'b' => '2', 'c' => 3]; - $this->assertEquals((object) ['a' => 1, 'c' => 3], pickBy($object, function ($value) { return \is_int($value); })); + $this->assertEquals((object) ['a' => 1, 'c' => 3], pickBy($object, function ($value) { + return \is_int($value); + })); } } From 0200f48a6bdc249d923e9f0c8d8eb2400a8221c7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 13:43:46 +0200 Subject: [PATCH 083/159] Fix PHPStan violations --- src/Object/pickBy.php | 4 ++-- src/internal/baseGet.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Object/pickBy.php b/src/Object/pickBy.php index d3860fb..f0e11c9 100644 --- a/src/Object/pickBy.php +++ b/src/Object/pickBy.php @@ -21,8 +21,8 @@ * * @category Object * - * @param object $object The source object. - * @param callable $predicate The function invoked per property. + * @param object|null $object The source object. + * @param callable $predicate The function invoked per property. * * @return \stdClass Returns the new object. * @example diff --git a/src/internal/baseGet.php b/src/internal/baseGet.php index 75051df..c91a3d6 100644 --- a/src/internal/baseGet.php +++ b/src/internal/baseGet.php @@ -24,5 +24,5 @@ function baseGet($object, $path) $object = property(toKey($path[$index++]))($object); } - return ($index && $index === $length) ? $object : null; + return ($index > 0 && $index === $length) ? $object : null; } From 895ee3dd4f6434e91ef32ade07eab5898d36f98a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 13:57:35 +0200 Subject: [PATCH 084/159] Add PHP 7.3 to travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3363f55..357a4d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ matrix: env: - COMPOSER_OPTIONS="--prefer-stable" - php: 7.2 + - php: 7.3 - php: nightly allow_failures: - php: nightly From f297196cbb17183360906533c7bd4dae43829edc Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 14:05:34 +0200 Subject: [PATCH 085/159] PHP 7.3 is not yet available on Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 357a4d6..1bbaa6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ matrix: env: - COMPOSER_OPTIONS="--prefer-stable" - php: 7.2 - - php: 7.3 + # - php: 7.3 # https://github.com/travis-ci/travis-ci/issues/9717 - php: nightly allow_failures: - php: nightly From 10334f0266eb372c9e7c085116f65dffb0c451db Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 28 Aug 2018 12:35:16 +0200 Subject: [PATCH 086/159] Update PHPUnit config and update bin dependencies --- phpunit.xml.dist | 3 +- vendor-bin/php-cs-fixer/composer.lock | 57 +++++++++++++++------------ vendor-bin/phpstan/composer.lock | 14 +++---- vendor-bin/phpunit/composer.lock | 10 ++--- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3c500fe..192a663 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,8 +1,7 @@ diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock index 47f9874..957362a 100644 --- a/vendor-bin/php-cs-fixer/composer.lock +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -70,16 +70,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "e1809da56ce1bd1b547a752936817341ac244d8e" + "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e1809da56ce1bd1b547a752936817341ac244d8e", - "reference": "e1809da56ce1bd1b547a752936817341ac244d8e", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e37cbd80da64afe314c72de8d2d2fec0e40d9373", + "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373", "shasum": "" }, "require": { @@ -110,7 +110,7 @@ "Xdebug", "performance" ], - "time": "2018-08-16T10:54:23+00:00" + "time": "2018-08-23T12:00:19+00:00" }, { "name": "doctrine/annotations", @@ -236,21 +236,21 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.12.2", + "version": "v2.13.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "dcc87d5414e9d0bd316fce81a5bedb9ce720b183" + "reference": "7136aa4e0c5f912e8af82383775460d906168a10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/dcc87d5414e9d0bd316fce81a5bedb9ce720b183", - "reference": "dcc87d5414e9d0bd316fce81a5bedb9ce720b183", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7136aa4e0c5f912e8af82383775460d906168a10", + "reference": "7136aa4e0c5f912e8af82383775460d906168a10", "shasum": "" }, "require": { "composer/semver": "^1.4", - "composer/xdebug-handler": "^1.0", + "composer/xdebug-handler": "^1.2", "doctrine/annotations": "^1.2", "ext-json": "*", "ext-tokenizer": "*", @@ -292,6 +292,11 @@ "php-cs-fixer" ], "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.13-dev" + } + }, "autoload": { "psr-4": { "PhpCsFixer\\": "src/" @@ -323,7 +328,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2018-07-06T10:37:40+00:00" + "time": "2018-08-23T13:15:44+00:00" }, { "name": "paragonie/random_compat", @@ -470,7 +475,7 @@ }, { "name": "symfony/console", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", @@ -538,7 +543,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -601,16 +606,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "2e30335e0aafeaa86645555959572fe7cea22b43" + "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/2e30335e0aafeaa86645555959572fe7cea22b43", - "reference": "2e30335e0aafeaa86645555959572fe7cea22b43", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", + "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", "shasum": "" }, "require": { @@ -647,11 +652,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-08-18T16:52:46+00:00" }, { "name": "symfony/finder", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -700,7 +705,7 @@ }, { "name": "symfony/options-resolver", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -985,16 +990,16 @@ }, { "name": "symfony/process", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f01fc7a4493572f7f506c49dcb50ad01fb3a2f56" + "reference": "86cdb930a6a855b0ab35fb60c1504cb36184f843" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f01fc7a4493572f7f506c49dcb50ad01fb3a2f56", - "reference": "f01fc7a4493572f7f506c49dcb50ad01fb3a2f56", + "url": "https://api.github.com/repos/symfony/process/zipball/86cdb930a6a855b0ab35fb60c1504cb36184f843", + "reference": "86cdb930a6a855b0ab35fb60c1504cb36184f843", "shasum": "" }, "require": { @@ -1030,11 +1035,11 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-08-03T11:13:38+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", diff --git a/vendor-bin/phpstan/composer.lock b/vendor-bin/phpstan/composer.lock index cc430f1..13d5730 100644 --- a/vendor-bin/phpstan/composer.lock +++ b/vendor-bin/phpstan/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "composer/xdebug-handler", - "version": "1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08" + "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08", - "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e37cbd80da64afe314c72de8d2d2fec0e40d9373", + "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373", "shasum": "" }, "require": { @@ -48,7 +48,7 @@ "Xdebug", "performance" ], - "time": "2018-04-11T15:42:36+00:00" + "time": "2018-08-23T12:00:19+00:00" }, { "name": "jean85/pretty-package-versions", @@ -842,7 +842,7 @@ }, { "name": "symfony/console", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", @@ -910,7 +910,7 @@ }, { "name": "symfony/finder", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock index b8ce301..5542808 100644 --- a/vendor-bin/phpunit/composer.lock +++ b/vendor-bin/phpunit/composer.lock @@ -676,16 +676,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.3.1", + "version": "7.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f9b14c17860eccb440a0352a117a81eb754cff5a" + "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9b14c17860eccb440a0352a117a81eb754cff5a", - "reference": "f9b14c17860eccb440a0352a117a81eb754cff5a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34705f81bddc3f505b9599a2ef96e2b4315ba9b8", + "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8", "shasum": "" }, "require": { @@ -756,7 +756,7 @@ "testing", "xunit" ], - "time": "2018-08-07T06:44:28+00:00" + "time": "2018-08-22T06:39:21+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", From 7900274fa682e5cf57ba7a1fad211f66c2b5a9a2 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 28 Aug 2018 13:32:10 +0200 Subject: [PATCH 087/159] Add Seq.chain function (#8) --- src/Collection/sortBy.php | 2 +- src/Lodash.php | 32 +++++++++++++++++++++++++ src/Seq/chain.php | 49 +++++++++++++++++++++++++++++++++++++++ src/compiled.php | 17 +++++++------- tests/LodashTest.php | 25 ++++++++++++++++++++ tests/Seq/ChainTest.php | 35 ++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 src/Seq/chain.php create mode 100644 tests/LodashTest.php create mode 100644 tests/Seq/ChainTest.php diff --git a/src/Collection/sortBy.php b/src/Collection/sortBy.php index 0bfc361..0e2e41c 100644 --- a/src/Collection/sortBy.php +++ b/src/Collection/sortBy.php @@ -47,7 +47,7 @@ function sortBy($collection, $iteratees): array return []; }; - if (\is_callable($iteratees)) { + if (\is_callable($iteratees) || !\is_iterable($iteratees)) { $iteratees = [$iteratees]; } diff --git a/src/Lodash.php b/src/Lodash.php index 6ca5f40..a1d7d69 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -11,6 +11,8 @@ final class _ { + public $__chain__ = false; + public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; @@ -44,6 +46,13 @@ final class _ ], ]; + private $value; + + public function __construct($value) + { + $this->value = $value; + } + /** * @param string $method * @param array $args @@ -59,4 +68,27 @@ public static function __callStatic(string $method, array $args) return ("_\\$method")(...$args); } + + public function __call($method, $arguments) + { + $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); + + return $this; + } + + public function value() + { + return $this->value; + } +} + +// We can't use "_" as a function name, since it collides with the "_" function in the gettext extension +function __($value): _ +{ + return new _($value); +} + +function lodash($value): _ +{ + return new _($value); } diff --git a/src/Seq/chain.php b/src/Seq/chain.php new file mode 100644 index 0000000..63e3149 --- /dev/null +++ b/src/Seq/chain.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `->value()`. + * + * @category Seq + * + * @param mixed $value The value to wrap. + * + * @return \_ Returns the new `lodash` wrapper instance. + * @example + * + * $users = [ + * ['user' => 'barney', 'age' => 36], + * ['user' => 'fred', 'age' => 40], + * ['user' => 'pebbles', 'age' => 1 ], + * ]; + * + * $youngest = chain($users) + * ->sortBy('age') + * ->map(function($o) { + * return $o['user'] . ' is ' . $o['age']; + * }) + * ->head() + * ->value(); + * // => 'pebbles is 1' + * + */ +function chain($value): \_ +{ + /** @var \_ $result */ + $result = __($value); + $result->__chain__ = true; + + return $result; +} diff --git a/src/compiled.php b/src/compiled.php index e4730f2..8f29226 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -2,7 +2,7 @@ // Auto-generated file - namespace { final class _ { public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } } } + namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } } namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } @@ -24,7 +24,7 @@ namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } namespace _ { function sample(array $array) { $key = \array_rand($array, 1); return $array[$key]; } } namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } - namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees): array { if (null === $collection) { return []; }; if (\is_callable($iteratees)) { $iteratees = [$iteratees]; } $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } + namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees): array { if (null === $collection) { return []; }; if (\is_callable($iteratees) || !\is_iterable($iteratees)) { $iteratees = [$iteratees]; } $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } namespace _ { use function _\internal\createAggregator; function keyBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { $result[$key] = $value; return $result; })($collection, $iteratee); } } namespace _ { use function _\internal\createAggregator; function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { $result[$key] = []; } $result[$key][] = $value; return $result; })($collection, $iteratee); } } namespace _ { use function _\internal\baseFlatten; function flatMapDepth(iterable $collection, callable $iteratee, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } } @@ -83,6 +83,7 @@ namespace _ { use function _\internal\baseFlatten; function differenceBy(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $iteratee = \array_pop($values); $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $computed = $iteratee($value); $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($computed === $values[$valuesIndex]) { continue 2; } } $result[] = $value; } return $result; } } namespace _ { use function _\internal\baseFlatten; use function _\internal\baseIteratee; use function _\internal\baseUniq; function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } } namespace _ { use function _\internal\baseIntersection; use function _\internal\baseIteratee; function intersectionBy(...$arrays): array { $iteratee = \array_pop($arrays); return baseIntersection($arrays, baseIteratee($iteratee)); } } + namespace _ { function chain($value): \_ { $result = __($value); $result->__chain__ = true; return $result; } } namespace _ { function now(): int { return (int) (\microtime(true) * 1000); } } namespace _\internal { function baseUnary($func) { return function ($value) use ($func) { return $func($value); }; } } namespace _\internal { function stringToArray(string $string): array { return hasUnicode($string) ? unicodeToArray($string) : \str_split($string); } } @@ -100,7 +101,7 @@ namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } namespace _\internal { function unicodeSize(string $string): int { return \preg_match_all(reUnicode, $string) ?: 0; } } - namespace _\internal { use function _\property; function baseGet($object, $path) { $path = castPath($path, $object); $index = 0; $length = \count($path); while ($object !== null && $index < $length) { $object = property(toKey($path[$index++]))($object); } return ($index && $index === $length) ? $object : null; } } + namespace _\internal { use function _\property; function baseGet($object, $path) { $path = castPath($path, $object); $index = 0; $length = \count($path); while ($object !== null && $index < $length) { $object = property(toKey($path[$index++]))($object); } return ($index > 0 && $index === $length) ? $object : null; } } namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\\internal\\baseIndexOfWith' : '_\\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } namespace _\internal { function baseFlatten(?array $array, int $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { arrayPush($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } @@ -125,9 +126,9 @@ namespace _\internal { function baseSet($object, $path, $value, callable $customizer = null) { if (!\is_object($object)) { return $object; } $path = castPath($path, $object); $index = -1; $length = \count($path); $lastIndex = $length - 1; $nested = $object; while ($nested !== null && ++$index < $length) { $key = toKey($path[$index]); if ($index !== $lastIndex) { $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; if (null === $newValue) { $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); } if (\is_array($nested)) { $nested[$key] = $newValue; } else { $nested->{$key} = $newValue; } if (\is_array($nested)) { $nested = &$nested[$key]; } else { $nested = &$nested->$key; } continue; } $nested->{$key} = $value; } return $object; } } namespace _\internal { function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } } namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return \is_callable($func) ? $func($object, ...$args) : null; } } - namespace _\internal { function basePickBy($object, $paths, callable $predicate): \stdClass { $index = -1; $length = \is_array($paths) ? \count($paths) : \strlen($paths); $result = new \stdClass(); while (++$index < $length) { $path = $paths[$index]; $value = baseGet($object, $path); if ($predicate($value, $path)) { baseSet($result, castPath($path, $object), $value); } } return $result; } } - namespace _\internal { function arrayPush(&$array, $values) { $index = -1; $length = \is_array($values) ? \count($values) : \strlen($values); $offset = \count($array); while (++$index < $length) { $array[$offset + $index] = $values[$index]; } return $array; } } - namespace _\internal { function basePick($object, $paths): \stdClass { return basePickBy($object, $paths, function($value, $path) use ($object) { return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); }); } } + namespace _\internal { function basePickBy($object, $paths, callable $predicate): \stdClass { $index = -1; $length = \is_array($paths) ? \count($paths) : \strlen($paths); $result = new \stdClass(); while (++$index < $length) { $path = $paths[$index]; $value = baseGet($object, $path); if ($predicate($value, $path)) { baseSet($result, castPath($path, $object), $value); } } return $result; } } + namespace _\internal { function arrayPush(&$array, $values) { $index = -1; $length = \is_array($values) ? \count($values) : \strlen($values); $offset = \count($array); while (++$index < $length) { $array[$offset + $index] = $values[$index]; } return $array; } } + namespace _\internal { function basePick($object, $paths): \stdClass { return basePickBy($object, $paths, function ($value, $path) use ($object) { return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); }); } } namespace _\internal { const reHasUnicode = '['.rsZWJ.rsAstralRange.rsComboRange.rsVarRange.']'; function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; } } namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } @@ -143,8 +144,8 @@ namespace _ { function isError($value): bool { if (!\is_object($value)) { return false; } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; } } namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } namespace _ { function eq($value, $other): bool { return $value === $other; } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseIteratee; use function _\internal\basePickBy; function pickBy($object, callable $predicate): \stdClass { if (null === $object) { return new \stdClass; } $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { return [$prop]; }); $predicate = baseIteratee($predicate); return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); } } - namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, ...$paths) { return basePick($object, $paths); })($object, $paths); } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseIteratee; use function _\internal\basePickBy; function pickBy($object, callable $predicate): \stdClass { if (null === $object) { return new \stdClass; } $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { return [$prop]; }); $predicate = baseIteratee($predicate); return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); } } + namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, ...$paths) { return basePick($object, $paths); })($object, $paths); } } namespace _ { function lowerFirst(string $string): string { return \lcfirst($string); } } namespace _ { function camelCase(string $string): string { return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); } } namespace _ { function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); } } diff --git a/tests/LodashTest.php b/tests/LodashTest.php new file mode 100644 index 0000000..fae6947 --- /dev/null +++ b/tests/LodashTest.php @@ -0,0 +1,25 @@ + 'barney', 'age' => 36], + ['user' => 'fred', 'age' => 40], + ['user' => 'pebbles', 'age' => 1], + ]; + + $youngest = __($users) + ->sortBy('age') + ->map(function ($o) { + return $o['user'] . ' is ' . $o['age']; + }) + ->head() + ->value(); + + $this->assertSame('pebbles is 1', $youngest); + } +} diff --git a/tests/Seq/ChainTest.php b/tests/Seq/ChainTest.php new file mode 100644 index 0000000..f647cff --- /dev/null +++ b/tests/Seq/ChainTest.php @@ -0,0 +1,35 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\chain; +use PHPUnit\Framework\TestCase; + +class ChainTest extends TestCase +{ + public function testChain() + { + $users = [ + ['user' => 'barney', 'age' => 36], + ['user' => 'fred', 'age' => 40], + ['user' => 'pebbles', 'age' => 1], + ]; + + $youngest = chain($users) + ->sortBy('age') + ->map(function ($o) { + return $o['user'] . ' is ' . $o['age']; + }) + ->head() + ->value(); + + $this->assertSame('pebbles is 1', $youngest); + } +} From addd938581c7d9d88828095a2789cecda9dc1a85 Mon Sep 17 00:00:00 2001 From: Samuel Elh <7893147+elhardoum@users.noreply.github.com> Date: Tue, 4 Sep 2018 08:43:28 +0000 Subject: [PATCH 088/159] Added missing dollar sign to 2 code examples variables (#10) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f4257df..8b96dc9 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,10 @@ Example: $array = [1]; $other = concat($array, 2, [3], [[4]]); -var_dump(other) +var_dump($other) // => [1, 2, 3, [4]] -var_dump(array) +var_dump($array) // => [1] ``` From 6e75f93216c7efb7d682b0662b05cc00cd879b79 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 12:42:42 +0200 Subject: [PATCH 089/159] Add Function.after function --- src/Function/after.php | 46 +++++++++++++++++++++++++++++++++ src/compiled.php | 1 + tests/Function/AfterTest.php | 50 ++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 src/Function/after.php create mode 100644 tests/Function/AfterTest.php diff --git a/src/Function/after.php b/src/Function/after.php new file mode 100644 index 0000000..f1cc50d --- /dev/null +++ b/src/Function/after.php @@ -0,0 +1,46 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * The opposite of `before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @category Function + * + * @param int $n The number of calls before `func` is invoked. + * @param Callable $func The function to restrict. + * + * @return Callable Returns the new restricted function. + * + * @example + * + * $saves = ['profile', 'settings']; + * + * $done = after(count($saves), function() { + * echo 'done saving!'; + * }); + * + * forEach($saves, function($type) use($done) { + * asyncSave([ 'type' => $type, 'complete' => $done ]); + * }); + * // => Prints 'done saving!' after the two async saves have completed. + * + */ +function after(int $n, callable $func): callable +{ + return function (...$args) use (&$n, $func) { + if (--$n < 1) { + return $func(...$args); + } + }; +} \ No newline at end of file diff --git a/src/compiled.php b/src/compiled.php index 8f29226..3c7b13b 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -133,6 +133,7 @@ namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } + namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } diff --git a/tests/Function/AfterTest.php b/tests/Function/AfterTest.php new file mode 100644 index 0000000..b54db23 --- /dev/null +++ b/tests/Function/AfterTest.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\after; +use PHPUnit\Framework\TestCase; + +class AfterTest extends TestCase +{ + public function testAfter() + { + $counter = 0; + + $after = after(12, function () use (&$counter) { + $counter++; + + return $counter; + }); + + for ($i = 0; $i < 12; $i++) { + $after(); + } + + $this->assertSame(1, $counter); + } + + public function testAfterNotCalled() + { + $counter = 0; + + $after = after(12, function () use (&$counter) { + $counter++; + + return $counter; + }); + + for ($i = 0; $i < 10; $i++) { + $after(); + } + + $this->assertSame(0, $counter); + } +} \ No newline at end of file From 700e7661eb9acb16c69695e4f227a8e06c11db59 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 12:53:03 +0200 Subject: [PATCH 090/159] Add Function.ary function --- src/Function/ary.php | 38 ++++++++++++++++++++++++++++++++++++++ tests/Function/AryTest.php | 22 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/Function/ary.php create mode 100644 tests/Function/AryTest.php diff --git a/src/Function/ary.php b/src/Function/ary.php new file mode 100644 index 0000000..a4f4dae --- /dev/null +++ b/src/Function/ary.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @category Function + * + * @param callable $func The function to cap arguments for. + * @param int $n The arity cap. + * + * @return Callable Returns the new capped function. + * + * @example + * + * map(['6', '8', '10'], ary('intval', 1)); + * // => [6, 8, 10] + * + */ +function ary(callable $func, int $n): callable +{ + return function (...$args) use ($func, $n) { + \array_splice($args, $n); + + return $func(...$args); + }; +} \ No newline at end of file diff --git a/tests/Function/AryTest.php b/tests/Function/AryTest.php new file mode 100644 index 0000000..15a537d --- /dev/null +++ b/tests/Function/AryTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\ary; +use function _\map; +use PHPUnit\Framework\TestCase; + +class AryTest extends TestCase +{ + public function testAry() + { + $this->assertSame([6, 8, 10], map(['6', '8', '10'], ary('intval', 1))); + } +} \ No newline at end of file From 60b1cc8b68453c18ac4dbd79065f2918d30383f0 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 14:44:43 +0200 Subject: [PATCH 091/159] Add Function.before function --- src/Function/before.php | 44 ++++++++++++++++++++++++++++++++ tests/Function/BeforeTest.php | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/Function/before.php create mode 100644 tests/Function/BeforeTest.php diff --git a/src/Function/before.php b/src/Function/before.php new file mode 100644 index 0000000..8be63bd --- /dev/null +++ b/src/Function/before.php @@ -0,0 +1,44 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that invokes `func`, with the arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @category Function + * + * @param int $n The number of calls at which `func` is no longer invoked. + * @param callable $func The function to restrict. + * + * @return callable Returns the new restricted function. + * + * @example + * + * $users = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + * $result = uniqBy(map($users, before(5, [$repository, 'find'])), 'id') + * // => Fetch up to 4 results. + * + */ +function before(int $n, callable $func): callable +{ + $result = null; + + return function (...$args) use (&$result, &$n, &$func) { + if (--$n > 0) { + $result = $func(...$args); + } + + return $result; + }; +} \ No newline at end of file diff --git a/tests/Function/BeforeTest.php b/tests/Function/BeforeTest.php new file mode 100644 index 0000000..ed5d01a --- /dev/null +++ b/tests/Function/BeforeTest.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\before; +use function _\map; +use function _\uniqBy; +use PHPUnit\Framework\TestCase; + +class BeforeTest extends TestCase +{ + public function testBefore() + { + $counter = 0; + $func = before(5, function () use (&$counter) { + $counter++; + + return $counter; + }); + + for ($i = 0; $i < 20; $i++) { + $func(); + } + + $this->assertSame(4, $counter); + $this->assertSame(4, $func()); + } + + public function testBeforeMap() + { + $users = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + $result = uniqBy(map($users, before(5, function (int $id) { + return [ + 'id' => $id + ]; + })), 'id'); + + $this->assertSame([['id' => 1],['id' => 2],['id' => 3],['id' => 4]], $result); + } +} \ No newline at end of file From 79444f37f37d5980d1fbc2b1da346dda2cd4c116 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 14:56:40 +0200 Subject: [PATCH 092/159] Add Function.once function --- src/Function/once.php | 36 ++++++++++++++++++++++++++++++++++++ tests/Function/OnceTest.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/Function/once.php create mode 100644 tests/Function/OnceTest.php diff --git a/src/Function/once.php b/src/Function/once.php new file mode 100644 index 0000000..d1c4623 --- /dev/null +++ b/src/Function/once.php @@ -0,0 +1,36 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the arguments of the created function. + * + * @category Function + * + * @param callable $func The function to restrict. + * + * @return callable the new restricted function. + * + * @example + * + * $initialize = once('createApplication'); + * $initialize(); + * $initialize(); + * // => `createApplication` is invoked once + * + */ +function once(callable $func): callable +{ + return before(2, $func); +} \ No newline at end of file diff --git a/tests/Function/OnceTest.php b/tests/Function/OnceTest.php new file mode 100644 index 0000000..10fbc17 --- /dev/null +++ b/tests/Function/OnceTest.php @@ -0,0 +1,30 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\once; + +class OnceTest extends TestCase +{ + public function testOnce() + { + $counter = 0; + + $func = once(function () use (&$counter) { + $counter++; + }); + + $func(); + $func(); + + $this->assertSame(1, $counter); + } +} \ No newline at end of file From 16f9a04fcc9180656b40663d6667fc110d7ff4bb Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 7 Jun 2018 15:08:45 +0200 Subject: [PATCH 093/159] Add Function.overArgs function --- src/Function/overArgs.php | 72 +++++++++++++++++++++++++++++++++ tests/Function/OverArgsTest.php | 37 +++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/Function/overArgs.php create mode 100644 tests/Function/OverArgsTest.php diff --git a/src/Function/overArgs.php b/src/Function/overArgs.php new file mode 100644 index 0000000..9ec1480 --- /dev/null +++ b/src/Function/overArgs.php @@ -0,0 +1,72 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\arrayMap; +use function _\internal\baseFlatten; +use function _\internal\baseRest; +use function _\internal\baseUnary; + +/** + * Creates a function that invokes `func` with its arguments transformed. + * + * @static + * @memberOf _ + * @category Function + * + * @param callable $func The function to wrap. + * @param callable[] $transforms The argument transforms. + * + * @return callable the new function. + * + * @example + * + * function doubled($n) { + * return $n * 2; + * } + * + * function square($n) { + * return $n * $n; + * } + * + * $func = overArgs(function($x, $y) { + * return [$x, $y]; + * }, ['square', 'doubled']); + * + * $func(9, 3); + * // => [81, 6] + * + * $func(10, 5); + * // => [100, 10] + * + */ +function overArgs(callable $func, array $transforms): callable +{ + return baseRest(function ($func, $transforms) { + $transforms = (count($transforms) == 1 && \is_array($transforms[0])) + ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) + : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); + + $funcsLength = \count($transforms); + + return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { + $index = -1; + $length = \min(\count($args), $funcsLength); + + while (++$index < $length) { + $args[$index] = $transforms[$index]($args[$index]); + } + + return $func(...$args); + }); + })($func, $transforms); +} \ No newline at end of file diff --git a/tests/Function/OverArgsTest.php b/tests/Function/OverArgsTest.php new file mode 100644 index 0000000..073a665 --- /dev/null +++ b/tests/Function/OverArgsTest.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\overArgs; + +class OverArgsTest extends TestCase +{ + public function testOverArgs() + { + function doubled($n) + { + return $n * 2; + } + + function square($n) + { + return $n * $n; + } + + $func = overArgs(function ($x, $y) { + return [$x, $y]; + }, ['square', 'doubled']); + + $this->assertSame([81, 6], $func(9, 3)); + + $this->assertSame([100, 10], $func(10, 5)); + } +} \ No newline at end of file From 08197c0dae682a9ba95bfe6c00d1b15cc13ccfc7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 2 Jul 2018 13:33:41 +0200 Subject: [PATCH 094/159] Compile new functions --- src/compiled.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiled.php b/src/compiled.php index 3c7b13b..39b02f2 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -133,6 +133,10 @@ namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } + namespace _ { function before(int $n, callable $func): callable { $result = null; return function (...$args) use (&$result, &$n, &$func) { if (--$n > 0) { $result = $func(...$args); } return $result; }; } } + namespace _ { function ary(callable $func, int $n): callable { return function (...$args) use ($func, $n) { \array_splice($args, $n); return $func(...$args); }; } } + namespace _ { function once(callable $func): callable { return before(2, $func); } } namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } From c009a89acc5bbe737356b1f44c45d40aee900b65 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 18 Jul 2018 14:21:40 +0200 Subject: [PATCH 095/159] Add Function.bind function --- src/Function/bind.php | 46 +++++++++++++++++++++++++++++++++++++ tests/Function/BindTest.php | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/Function/bind.php create mode 100644 tests/Function/BindTest.php diff --git a/src/Function/bind.php b/src/Function/bind.php new file mode 100644 index 0000000..1ec80f6 --- /dev/null +++ b/src/Function/bind.php @@ -0,0 +1,46 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that invokes `func` with the `this` binding of `object` + * and `partials` prepended to the arguments it receives. + * + * @category Function + * + * @param callable $function The function to bind. + * @param object|mixed $object The `object` binding of `func`. + * @param mixed[] $partials The arguments to be partially applied. + * + * @return callable Returns the new bound function. + * @example + * + * function greet($greeting, $punctuation) { + * return $greeting . ' ' . $this->user . $punctuation; + * } + * + * $object = $object = new class { + * public $user = 'fred'; + * }; + * + * $bound = bind('greet', $object, 'hi'); + * $bound('!'); + * // => 'hi fred!' + */ +function bind(callable $function, $object, ...$partials): callable +{ + return function (...$args) use ($object, $function, $partials) { + $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); + + return $function(...array_merge($partials, $args)); + }; +} \ No newline at end of file diff --git a/tests/Function/BindTest.php b/tests/Function/BindTest.php new file mode 100644 index 0000000..9d28f18 --- /dev/null +++ b/tests/Function/BindTest.php @@ -0,0 +1,41 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\bind; + +class BindTest extends TestCase +{ + public function testBind() + { + $object = new class + { + public $user = 'fred'; + + private $age = 54; + }; + + function greet($greeting, $punctuation) + { + return $greeting.' '.$this->user.$punctuation; + } + + $bound = bind('greet', $object, 'hi'); + + $this->assertSame('hi fred!', $bound('!')); + + $bound = bind(function ($prefix, $suffix) { + return $prefix.' '.$this->age.' '.$suffix; + }, $object, 'I\'m'); + + $this->assertSame('I\'m 54 years', $bound('years')); + } +} \ No newline at end of file From 36ac97dddd376aa63192890448a7cb87fe51f8be Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 18 Jul 2018 14:31:56 +0200 Subject: [PATCH 096/159] Add Function.bindKey function --- src/Function/bindKey.php | 48 ++++++++++++++++++++++++++++++++++ tests/Function/BindKeyTest.php | 33 +++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/Function/bindKey.php create mode 100644 tests/Function/BindKeyTest.php diff --git a/src/Function/bindKey.php b/src/Function/bindKey.php new file mode 100644 index 0000000..c93a45c --- /dev/null +++ b/src/Function/bindKey.php @@ -0,0 +1,48 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that invokes the method `$function` of `$object` with `$partials` + * prepended to the arguments it receives. + * + * This method differs from `bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist + * + * @category Function + * + * @param object|mixed $object The object to invoke the method on. + * @param string $function The name of the method. + * @param mixed[] $partials The arguments to be partially applied. + * + * @return callable Returns the new bound function. + * @example + * + * $object = new class { + * private $user = 'fred'; + * function greet($greeting, $punctuation) { + * return $greeting.' '.$this->user.$punctuation; + * } + * }; + * + * $bound = bindKey($object, 'greet', 'hi'); + * $bound('!'); + * // => 'hi fred!' + */ +function bindKey($object, string $function, ...$partials): callable +{ + return function (...$args) use ($object, $function, $partials) { + $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); + + return $function(...array_merge($partials, $args)); + }; +} \ No newline at end of file diff --git a/tests/Function/BindKeyTest.php b/tests/Function/BindKeyTest.php new file mode 100644 index 0000000..fa1b9ed --- /dev/null +++ b/tests/Function/BindKeyTest.php @@ -0,0 +1,33 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\bindKey; + +class BindKeyTest extends TestCase +{ + public function testBindKey() + { + $object = new class + { + private $user = 'fred'; + + function greet($greeting, $punctuation) + { + return $greeting.' '.$this->user.$punctuation; + } + }; + + $bound = bindKey($object, 'greet', 'hi'); + + $this->assertSame('hi fred!', $bound('!')); + } +} \ No newline at end of file From 0fadbf881c8a3a74b54bf9a672808e50d823ba0a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 14 Aug 2018 12:54:24 +0200 Subject: [PATCH 097/159] Use global function for count --- src/Function/overArgs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Function/overArgs.php b/src/Function/overArgs.php index 9ec1480..12ae732 100644 --- a/src/Function/overArgs.php +++ b/src/Function/overArgs.php @@ -52,7 +52,7 @@ function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { - $transforms = (count($transforms) == 1 && \is_array($transforms[0])) + $transforms = (\count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); From 4f0aa714c8450df486f7fa320fc6febc0316437f Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 14 Aug 2018 12:57:06 +0200 Subject: [PATCH 098/159] Fix CS --- src/Function/after.php | 2 +- src/Function/ary.php | 2 +- src/Function/before.php | 2 +- src/Function/bind.php | 2 +- src/Function/bindKey.php | 2 +- src/Function/once.php | 2 +- src/Function/overArgs.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Function/after.php b/src/Function/after.php index f1cc50d..6a972c1 100644 --- a/src/Function/after.php +++ b/src/Function/after.php @@ -43,4 +43,4 @@ function after(int $n, callable $func): callable return $func(...$args); } }; -} \ No newline at end of file +} diff --git a/src/Function/ary.php b/src/Function/ary.php index a4f4dae..47d5436 100644 --- a/src/Function/ary.php +++ b/src/Function/ary.php @@ -35,4 +35,4 @@ function ary(callable $func, int $n): callable return $func(...$args); }; -} \ No newline at end of file +} diff --git a/src/Function/before.php b/src/Function/before.php index 8be63bd..1dcacd4 100644 --- a/src/Function/before.php +++ b/src/Function/before.php @@ -41,4 +41,4 @@ function before(int $n, callable $func): callable return $result; }; -} \ No newline at end of file +} diff --git a/src/Function/bind.php b/src/Function/bind.php index 1ec80f6..8c57799 100644 --- a/src/Function/bind.php +++ b/src/Function/bind.php @@ -43,4 +43,4 @@ function bind(callable $function, $object, ...$partials): callable return $function(...array_merge($partials, $args)); }; -} \ No newline at end of file +} diff --git a/src/Function/bindKey.php b/src/Function/bindKey.php index c93a45c..f72ecd4 100644 --- a/src/Function/bindKey.php +++ b/src/Function/bindKey.php @@ -45,4 +45,4 @@ function bindKey($object, string $function, ...$partials): callable return $function(...array_merge($partials, $args)); }; -} \ No newline at end of file +} diff --git a/src/Function/once.php b/src/Function/once.php index d1c4623..2ff0909 100644 --- a/src/Function/once.php +++ b/src/Function/once.php @@ -33,4 +33,4 @@ function once(callable $func): callable { return before(2, $func); -} \ No newline at end of file +} diff --git a/src/Function/overArgs.php b/src/Function/overArgs.php index 12ae732..79e2bca 100644 --- a/src/Function/overArgs.php +++ b/src/Function/overArgs.php @@ -69,4 +69,4 @@ function overArgs(callable $func, array $transforms): callable return $func(...$args); }); })($func, $transforms); -} \ No newline at end of file +} From 8bebaa991b4f416bf0056fe9606317cd04a381d8 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 14:15:29 +0200 Subject: [PATCH 099/159] Fix CS --- tests/Function/AfterTest.php | 2 +- tests/Function/AryTest.php | 2 +- tests/Function/BeforeTest.php | 2 +- tests/Function/BindKeyTest.php | 7 +++---- tests/Function/BindTest.php | 5 ++--- tests/Function/OnceTest.php | 2 +- tests/Function/OverArgsTest.php | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/Function/AfterTest.php b/tests/Function/AfterTest.php index b54db23..ed0c6bc 100644 --- a/tests/Function/AfterTest.php +++ b/tests/Function/AfterTest.php @@ -47,4 +47,4 @@ public function testAfterNotCalled() $this->assertSame(0, $counter); } -} \ No newline at end of file +} diff --git a/tests/Function/AryTest.php b/tests/Function/AryTest.php index 15a537d..ef9ca60 100644 --- a/tests/Function/AryTest.php +++ b/tests/Function/AryTest.php @@ -19,4 +19,4 @@ public function testAry() { $this->assertSame([6, 8, 10], map(['6', '8', '10'], ary('intval', 1))); } -} \ No newline at end of file +} diff --git a/tests/Function/BeforeTest.php b/tests/Function/BeforeTest.php index ed5d01a..f43a968 100644 --- a/tests/Function/BeforeTest.php +++ b/tests/Function/BeforeTest.php @@ -44,4 +44,4 @@ public function testBeforeMap() $this->assertSame([['id' => 1],['id' => 2],['id' => 3],['id' => 4]], $result); } -} \ No newline at end of file +} diff --git a/tests/Function/BindKeyTest.php b/tests/Function/BindKeyTest.php index fa1b9ed..7cfcc50 100644 --- a/tests/Function/BindKeyTest.php +++ b/tests/Function/BindKeyTest.php @@ -16,11 +16,10 @@ class BindKeyTest extends TestCase { public function testBindKey() { - $object = new class - { + $object = new class { private $user = 'fred'; - function greet($greeting, $punctuation) + public function greet($greeting, $punctuation) { return $greeting.' '.$this->user.$punctuation; } @@ -30,4 +29,4 @@ function greet($greeting, $punctuation) $this->assertSame('hi fred!', $bound('!')); } -} \ No newline at end of file +} diff --git a/tests/Function/BindTest.php b/tests/Function/BindTest.php index 9d28f18..c8e9750 100644 --- a/tests/Function/BindTest.php +++ b/tests/Function/BindTest.php @@ -16,8 +16,7 @@ class BindTest extends TestCase { public function testBind() { - $object = new class - { + $object = new class { public $user = 'fred'; private $age = 54; @@ -38,4 +37,4 @@ function greet($greeting, $punctuation) $this->assertSame('I\'m 54 years', $bound('years')); } -} \ No newline at end of file +} diff --git a/tests/Function/OnceTest.php b/tests/Function/OnceTest.php index 10fbc17..96e057e 100644 --- a/tests/Function/OnceTest.php +++ b/tests/Function/OnceTest.php @@ -27,4 +27,4 @@ public function testOnce() $this->assertSame(1, $counter); } -} \ No newline at end of file +} diff --git a/tests/Function/OverArgsTest.php b/tests/Function/OverArgsTest.php index 073a665..197fea6 100644 --- a/tests/Function/OverArgsTest.php +++ b/tests/Function/OverArgsTest.php @@ -34,4 +34,4 @@ function square($n) $this->assertSame([100, 10], $func(10, 5)); } -} \ No newline at end of file +} From 5fdb35c6401bed2ad898e9f3716ffacf81d9eae9 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 17 Aug 2018 14:21:30 +0200 Subject: [PATCH 100/159] Fix PHPStan violations --- phpstan.neon | 1 + src/Function/bind.php | 6 +++--- src/Function/bindKey.php | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 4b49f37..1757ae6 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,3 +7,4 @@ parameters: ignoreErrors: - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" + - "#Parameter \\#\\d+ \\$callable of static method Closure::fromCallable\\(\\) expects callable, array\\(object, string\\) given.#" diff --git a/src/Function/bind.php b/src/Function/bind.php index 8c57799..1adbcff 100644 --- a/src/Function/bind.php +++ b/src/Function/bind.php @@ -17,9 +17,9 @@ * * @category Function * - * @param callable $function The function to bind. - * @param object|mixed $object The `object` binding of `func`. - * @param mixed[] $partials The arguments to be partially applied. + * @param callable $function The function to bind. + * @param object|mixed $object The `object` binding of `func`. + * @param array $partials The arguments to be partially applied. * * @return callable Returns the new bound function. * @example diff --git a/src/Function/bindKey.php b/src/Function/bindKey.php index f72ecd4..ff34c0e 100644 --- a/src/Function/bindKey.php +++ b/src/Function/bindKey.php @@ -20,9 +20,9 @@ * * @category Function * - * @param object|mixed $object The object to invoke the method on. - * @param string $function The name of the method. - * @param mixed[] $partials The arguments to be partially applied. + * @param object $object The object to invoke the method on. + * @param string $function The name of the method. + * @param array $partials The arguments to be partially applied. * * @return callable Returns the new bound function. * @example From ca8947515df02a6b0c370fc2f2c62eabea315927 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 23 Nov 2018 15:55:31 +0200 Subject: [PATCH 101/159] Add Function.flip function --- src/Function/flip.php | 38 +++++++++++++++++++++++++++++++++++++ src/compiled.php | 13 ++++++++----- tests/Function/FlipTest.php | 25 ++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 src/Function/flip.php create mode 100644 tests/Function/FlipTest.php diff --git a/src/Function/flip.php b/src/Function/flip.php new file mode 100644 index 0000000..bf98c5f --- /dev/null +++ b/src/Function/flip.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that invokes `func` with arguments reversed. + * + * @category Function + * + * @param callable $func The function to flip arguments for. + * + * @return callable Returns the new flipped function. + * + * @example + * + * $flipped = flip(function() { + * return func_get_args(); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + * + */ +function flip(callable $func): callable +{ + return function (...$values) use($func) { + return \array_reverse($func(...$values), false); + }; +} \ No newline at end of file diff --git a/src/compiled.php b/src/compiled.php index 39b02f2..5ff0f71 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -133,13 +133,16 @@ namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } - namespace _ { function before(int $n, callable $func): callable { $result = null; return function (...$args) use (&$result, &$n, &$func) { if (--$n > 0) { $result = $func(...$args); } return $result; }; } } - namespace _ { function ary(callable $func, int $n): callable { return function (...$args) use ($func, $n) { \array_splice($args, $n); return $func(...$args); }; } } - namespace _ { function once(callable $func): callable { return before(2, $func); } } - namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (\count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } + namespace _ { function before(int $n, callable $func): callable { $result = null; return function (...$args) use (&$result, &$n, &$func) { if (--$n > 0) { $result = $func(...$args); } return $result; }; } } + namespace _ { function ary(callable $func, int $n): callable { return function (...$args) use ($func, $n) { \array_splice($args, $n); return $func(...$args); }; } } + namespace _ { function once(callable $func): callable { return before(2, $func); } } + namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } + namespace _ { function bindKey($object, string $function, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); return $function(...array_merge($partials, $args)); }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } + namespace _ { function flip(callable $func): callable { return function (...$values) use($func) { return \array_reverse($func(...$values), false); }; } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } + namespace _ { function bind(callable $function, $object, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); return $function(...array_merge($partials, $args)); }; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } namespace _ { function max(?array $array): ?int { return $array ? \max($array) : null; } } diff --git a/tests/Function/FlipTest.php b/tests/Function/FlipTest.php new file mode 100644 index 0000000..f13a588 --- /dev/null +++ b/tests/Function/FlipTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\flip; + +class FlipTest extends TestCase +{ + public function testFlip() + { + $flipped = flip(function () { + return func_get_args(); + }); + + $this->assertSame(['d', 'c', 'b', 'a'], $flipped('a', 'b', 'c', 'd')); + } +} \ No newline at end of file From d9f6d5879e690bc984d30ccb02a83fa7b719776e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 23 Nov 2018 16:18:46 +0200 Subject: [PATCH 102/159] Add Function.spread function --- src/Function/spread.php | 58 +++++++++++++++++++++++++++++++++++ src/compiled.php | 3 +- tests/Function/SpreadTest.php | 25 +++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/Function/spread.php create mode 100644 tests/Function/SpreadTest.php diff --git a/src/Function/spread.php b/src/Function/spread.php new file mode 100644 index 0000000..5c61c02 --- /dev/null +++ b/src/Function/spread.php @@ -0,0 +1,58 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseRest; +use function _\internal\castSlice; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * create function and an array of arguments much like + * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + * + * **Note:** This method is based on the + * [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Function + * + * @param callable func The function to spread arguments over. + * @param int $start The start position of the spread. + * + * @return callable Returns the new function. + * + * @example + * + * $say = spread(function($who, $what) { + * return $who . ' says ' . $what; + * }); + * + * $say(['fred', 'hello']); + * // => 'fred says hello' + */ +function spread(callable $func, ?int $start = null) +{ + $start = null === $start ? 0 : max((int) $start, 0); + + return baseRest(function (...$args) use ($start, $func) { + $array = $args[$start]; + $otherArgs = castSlice($args, 0, $start); + + if ($array) { + $otherArgs = \array_merge($otherArgs, $array); + } + + return $func(...$otherArgs); + }); +} \ No newline at end of file diff --git a/src/compiled.php b/src/compiled.php index 5ff0f71..a013dfa 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -140,7 +140,8 @@ namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } namespace _ { function bindKey($object, string $function, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); return $function(...array_merge($partials, $args)); }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } - namespace _ { function flip(callable $func): callable { return function (...$values) use($func) { return \array_reverse($func(...$values), false); }; } } + namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : max((int) $start, 0); return baseRest(function (...$args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); if ($array) { $otherArgs = \array_merge($otherArgs, $array); } return $func(...$otherArgs); }); } } + namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function flip(callable $func): callable { return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } namespace _ { function bind(callable $function, $object, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); return $function(...array_merge($partials, $args)); }; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } diff --git a/tests/Function/SpreadTest.php b/tests/Function/SpreadTest.php new file mode 100644 index 0000000..af7fea2 --- /dev/null +++ b/tests/Function/SpreadTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\spread; + +class SpreadTest extends TestCase +{ + public function testSpread() + { + $say = spread(function ($who, $what) { + return $who.' says '.$what; + }); + + $this->assertSame('fred says hello', $say(['fred', 'hello'])); + } +} \ No newline at end of file From 89064ccddc9f19e0b58e6e8529e8c3c414f2260d Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 23 Nov 2018 18:07:53 +0200 Subject: [PATCH 103/159] Fix CS --- src/Function/flip.php | 7 +++++-- src/Function/spread.php | 2 +- tests/Function/FlipTest.php | 2 +- tests/Function/SpreadTest.php | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Function/flip.php b/src/Function/flip.php index bf98c5f..91c1e33 100644 --- a/src/Function/flip.php +++ b/src/Function/flip.php @@ -11,6 +11,9 @@ namespace _; +use function _\internal\baseRest; +use function _\internal\castSlice; + /** * Creates a function that invokes `func` with arguments reversed. * @@ -32,7 +35,7 @@ */ function flip(callable $func): callable { - return function (...$values) use($func) { + return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; -} \ No newline at end of file +} diff --git a/src/Function/spread.php b/src/Function/spread.php index 5c61c02..5ffad59 100644 --- a/src/Function/spread.php +++ b/src/Function/spread.php @@ -55,4 +55,4 @@ function spread(callable $func, ?int $start = null) return $func(...$otherArgs); }); -} \ No newline at end of file +} diff --git a/tests/Function/FlipTest.php b/tests/Function/FlipTest.php index f13a588..2e7ef83 100644 --- a/tests/Function/FlipTest.php +++ b/tests/Function/FlipTest.php @@ -22,4 +22,4 @@ public function testFlip() $this->assertSame(['d', 'c', 'b', 'a'], $flipped('a', 'b', 'c', 'd')); } -} \ No newline at end of file +} diff --git a/tests/Function/SpreadTest.php b/tests/Function/SpreadTest.php index af7fea2..b7b6cdb 100644 --- a/tests/Function/SpreadTest.php +++ b/tests/Function/SpreadTest.php @@ -22,4 +22,4 @@ public function testSpread() $this->assertSame('fred says hello', $say(['fred', 'hello'])); } -} \ No newline at end of file +} From 0dcee2f2285f241d966d7d8308686338626dba36 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 23 Nov 2018 18:09:59 +0200 Subject: [PATCH 104/159] Fix PHPStan issues --- src/Function/spread.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Function/spread.php b/src/Function/spread.php index 5ffad59..cb1f4a2 100644 --- a/src/Function/spread.php +++ b/src/Function/spread.php @@ -27,7 +27,7 @@ * @since 3.2.0 * @category Function * - * @param callable func The function to spread arguments over. + * @param callable $func The function to spread arguments over. * @param int $start The start position of the spread. * * @return callable Returns the new function. @@ -43,7 +43,7 @@ */ function spread(callable $func, ?int $start = null) { - $start = null === $start ? 0 : max((int) $start, 0); + $start = null === $start ? 0 : \max($start, 0); return baseRest(function (...$args) use ($start, $func) { $array = $args[$start]; From e6dd1b9b95b43b61c46da9f62e902972af5beed8 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 24 Nov 2018 07:28:03 +0200 Subject: [PATCH 105/159] Fix baseRest implementation --- src/Array/without.php | 2 +- src/Array/zip.php | 2 +- src/Collection/invokeMap.php | 2 +- src/Function/overArgs.php | 2 +- src/Function/spread.php | 2 +- src/Object/pick.php | 2 +- src/internal/overRest.php | 5 +++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Array/without.php b/src/Array/without.php index 1528bef..7976e97 100644 --- a/src/Array/without.php +++ b/src/Array/without.php @@ -34,5 +34,5 @@ */ function without(array $array, ...$values): array { - return baseRest('\_\difference')($array, $values); + return baseRest('\_\difference')($array, ...$values); } diff --git a/src/Array/zip.php b/src/Array/zip.php index b234e4c..24c8cbd 100644 --- a/src/Array/zip.php +++ b/src/Array/zip.php @@ -31,5 +31,5 @@ */ function zip(array ...$arrays): array { - return baseRest('\_\unzip')($arrays); + return baseRest('\_\unzip')(...$arrays); } diff --git a/src/Collection/invokeMap.php b/src/Collection/invokeMap.php index e4a413f..b5b4ddd 100644 --- a/src/Collection/invokeMap.php +++ b/src/Collection/invokeMap.php @@ -47,5 +47,5 @@ function invokeMap(iterable $collection, $path, array $args = []): array }); return $result; - })($collection, $path, $args); + })($collection, $path, ...$args); } diff --git a/src/Function/overArgs.php b/src/Function/overArgs.php index 79e2bca..386c27e 100644 --- a/src/Function/overArgs.php +++ b/src/Function/overArgs.php @@ -58,7 +58,7 @@ function overArgs(callable $func, array $transforms): callable $funcsLength = \count($transforms); - return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { + return baseRest(function ($args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); diff --git a/src/Function/spread.php b/src/Function/spread.php index cb1f4a2..df220fd 100644 --- a/src/Function/spread.php +++ b/src/Function/spread.php @@ -45,7 +45,7 @@ function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : \max($start, 0); - return baseRest(function (...$args) use ($start, $func) { + return baseRest(function ($args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); diff --git a/src/Object/pick.php b/src/Object/pick.php index 54d488c..13abc80 100644 --- a/src/Object/pick.php +++ b/src/Object/pick.php @@ -32,7 +32,7 @@ */ function pick($object, $paths): \stdClass { - return flatRest(function ($object, ...$paths) { + return flatRest(function ($object, $paths) { return basePick($object, $paths); })($object, $paths); } diff --git a/src/internal/overRest.php b/src/internal/overRest.php index cfb46ce..a17be23 100644 --- a/src/internal/overRest.php +++ b/src/internal/overRest.php @@ -13,7 +13,8 @@ function overRest(callable $func, $start, callable $transform): callable { - $start = max($start ?? -1, 0); + $parameters = (new \ReflectionFunction($func))->getNumberOfParameters(); + $start = max($start ?? $parameters - 1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); @@ -31,6 +32,6 @@ function overRest(callable $func, $start, callable $transform): callable } $otherArgs[$start] = $transform($array); - return $func(...$otherArgs[$start]); + return $func(...$otherArgs); }; } From e2003eab4ac2fb73873505c590bd128ee777dc28 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 24 Nov 2018 07:30:25 +0200 Subject: [PATCH 106/159] Add Function.rest function --- src/Function/rest.php | 42 +++++++++++++++++++++++++++++++++++++ tests/Function/RestTest.php | 29 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/Function/rest.php create mode 100644 tests/Function/RestTest.php diff --git a/src/Function/rest.php b/src/Function/rest.php new file mode 100644 index 0000000..e350168 --- /dev/null +++ b/src/Function/rest.php @@ -0,0 +1,42 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseRest; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * @category Function + * + * @param callable $func The function to apply a rest parameter to. + * @param int|null $start The start position of the rest parameter. + * + * @return callable Returns the new function. + * + * @example + * + * $say = rest(function($what, $names) { + * return $what . ' ' . implode(', ', initial($names)) . + * (size($names) > 1 ? ', & ' : '') . last($names); + * }); + * + * $say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + * + */ +function rest(callable $func, ?int $start = null): callable +{ + return baseRest($func, $start); +} \ No newline at end of file diff --git a/tests/Function/RestTest.php b/tests/Function/RestTest.php new file mode 100644 index 0000000..5bf6152 --- /dev/null +++ b/tests/Function/RestTest.php @@ -0,0 +1,29 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\initial; +use function _\last; +use function _\rest; +use function _\size; + +class RestTest extends TestCase +{ + public function testRest() + { + $say = rest(function ($what, $names) { + return $what.' '.implode(', ', initial($names)). + (size($names) > 1 ? ', & ' : '').last($names); + }); + + $this->assertSame('hello fred, barney, & pebbles', $say('hello', 'fred', 'barney', 'pebbles')); + } +} \ No newline at end of file From fd85fcf755b3589a516a8e73ef7cd678f0731d1a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 24 Nov 2018 07:35:36 +0200 Subject: [PATCH 107/159] Add Function.delay function --- src/Function/delay.php | 40 ++++++++++++++++++++++++++++++++++++ tests/Function/DelayTest.php | 28 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/Function/delay.php create mode 100644 tests/Function/DelayTest.php diff --git a/src/Function/delay.php b/src/Function/delay.php new file mode 100644 index 0000000..faa2599 --- /dev/null +++ b/src/Function/delay.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @category Function + * + * @param callable $func The function to delay. + * @param int $wait The number of milliseconds to delay invocation. + * @param mixed[] $args + * + * @return int the timer id. + * @example + *
+ * delay(function($text) {
+ *   echo $text;
+ * }, 1000, 'later');
+ * // => Echo 'later' after one second.
+ * 
+ */ +function delay(callable $func, int $wait = 1, ...$args): int +{ + usleep($wait * 1000); + + $func(...$args); + + return 1; +} \ No newline at end of file diff --git a/tests/Function/DelayTest.php b/tests/Function/DelayTest.php new file mode 100644 index 0000000..ba38db7 --- /dev/null +++ b/tests/Function/DelayTest.php @@ -0,0 +1,28 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\delay; +use PHPUnit\Framework\TestCase; + +class DelayTest extends TestCase +{ + public function testDelay() + { + $a = 1; + $time = microtime(true); + delay(function ($increment) use(&$a) { + $a += $increment; + }, 20, 2); + + $this->assertSame(3, $a); + $this->assertTrue(((microtime(true) - $time) * 1000) > 20); + } +} \ No newline at end of file From 3ef94f47850ea4ccaa059ef29929508b12ba1ef4 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 24 Nov 2018 07:38:01 +0200 Subject: [PATCH 108/159] Add Function.unary function --- src/Function/unary.php | 32 ++++++++++++++++++++++++++++++++ tests/Function/UnaryTest.php | 22 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Function/unary.php create mode 100644 tests/Function/UnaryTest.php diff --git a/src/Function/unary.php b/src/Function/unary.php new file mode 100644 index 0000000..7876928 --- /dev/null +++ b/src/Function/unary.php @@ -0,0 +1,32 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @category Function + * + * @param callable $func The function to cap arguments for. + * + * @return callable the new capped function. + * @example + * + * map(['6', '8', '10'], unary('intval')); + * // => [6, 8, 10] + * + */ +function unary(callable $func): callable +{ + return ary($func, 1); +} \ No newline at end of file diff --git a/tests/Function/UnaryTest.php b/tests/Function/UnaryTest.php new file mode 100644 index 0000000..a1c84b3 --- /dev/null +++ b/tests/Function/UnaryTest.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\map; +use function _\unary; +use PHPUnit\Framework\TestCase; + +class UnaryTest extends TestCase +{ + public function testUnary() + { + $this->assertSame([6, 8, 10], map(['6', '8', '10'], unary('intval'))); + } +} \ No newline at end of file From 75e6d8d209ab043d5a0e2e834e3b8fa535a40689 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 26 Nov 2018 09:42:13 +0200 Subject: [PATCH 109/159] Add Function.curry function --- src/Function/curry.php | 83 ++++++++++++++++++++++++++++++++++++ src/Lodash.php | 2 + tests/Function/CurryTest.php | 31 ++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 src/Function/curry.php create mode 100644 tests/Function/CurryTest.php diff --git a/src/Function/curry.php b/src/Function/curry.php new file mode 100644 index 0000000..1bdd08e --- /dev/null +++ b/src/Function/curry.php @@ -0,0 +1,83 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @category Function + * + * @param callable $func The function to curry. + * @param int $arity The arity of `func`. + * + * @return callable Returns the new curried function. + * @example + * + * $abc = function($a, $b, $c) { + * return [$a, $b, $c]; + * }; + * + * $curried = curry($abc); + * + * $curried(1)(2)(3); + * // => [1, 2, 3] + * + * $curried(1, 2)(3); + * // => [1, 2, 3] + * + * $curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * $curried(1)(_, 3)(2); + * // => [1, 2, 3] + * + */ +function curry(callable $func, ?int $arity = null) +{ + $curry = function ($arguments) use ($func, &$curry, $arity) { + $requiredArguments = (new \ReflectionFunction($func))->getNumberOfParameters(); + $arity = $arity ?? $requiredArguments; + + return function (...$args) use ($func, $arguments, $curry, $arity) { + if (false !== \array_search(_, $arguments)) { + foreach ($arguments as $i => $argument) { + if (_ !== $argument) { + continue; + } + + $arguments[$i] = current($args); + next($args); + } + } else { + $arguments = \array_merge($arguments, $args); + } + + if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { + return $func(...$arguments); + } + + return $curry($arguments); + }; + }; + + return $curry([]); +} \ No newline at end of file diff --git a/src/Lodash.php b/src/Lodash.php index a1d7d69..d8ec4ac 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -92,3 +92,5 @@ function lodash($value): _ { return new _($value); } + +define('_', _::class); \ No newline at end of file diff --git a/tests/Function/CurryTest.php b/tests/Function/CurryTest.php new file mode 100644 index 0000000..df00d58 --- /dev/null +++ b/tests/Function/CurryTest.php @@ -0,0 +1,31 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\curry; + +class CurryTest extends TestCase +{ + public function testCurry() + { + $abc = function ($a, $b, $c = null) { + return [$a, $b, $c]; + }; + + $curried = curry($abc); + + $this->assertSame([1, 2, 3], $curried(1)(2)(3)); + $this->assertSame([1, 2, 3], $curried(1, 2)(3)); + $this->assertSame([1, 2, 3], $curried(1, 2, 3)); + $this->assertSame([1, 2, null], curry($abc, 2)(1)(2)); + $this->assertSame([1, 2, 3], $curried(1)(_, 3)(2)); + } +} \ No newline at end of file From 52c23381dc028371ef7e0c24629fc9dd16a1b963 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 22:35:51 +0200 Subject: [PATCH 110/159] Add Function.partial function --- src/Function/partial.php | 62 ++++++++++++++++++++++++++++++++++ tests/Function/PartialTest.php | 27 +++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/Function/partial.php create mode 100644 tests/Function/PartialTest.php diff --git a/src/Function/partial.php b/src/Function/partial.php new file mode 100644 index 0000000..e49b98f --- /dev/null +++ b/src/Function/partial.php @@ -0,0 +1,62 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +use function _\internal\baseRest; +use function _\internal\shortOut; + +/** + * Creates a function that invokes `func` with `partials` prepended to the + * arguments it receives. + * + * @category Function + * + * @param callable $func The function to partially apply arguments to. + * @param mixed[] $partials The arguments to be partially applied. + * + * @return callable Returns the new partially applied function. + * + * @example + * + * function greet($greeting, $name) { + * return $greeting . ' ' . $name; + * } + * + * $sayHelloTo = partial('greet', 'hello'); + * $sayHelloTo('fred'); + * // => 'hello fred' + */ +function partial(callable $func, ...$partials): callable +{ + return baseRest(function ($func, $partials) { + $wrapper = function () use ($func, $partials) { + $arguments = \func_get_args(); + $argsIndex = -1; + $argsLength = \func_num_args(); + $leftIndex = -1; + $leftLength = \count($partials); + $args = []; + + while (++$leftIndex < $leftLength) { + $args[$leftIndex] = $partials[$leftIndex]; + } + while ($argsLength--) { + $args[$leftIndex++] = $arguments[++$argsIndex]; + } + + return $func(...$args); + }; + + return shortOut($wrapper); + })($func, ...$partials); +} + diff --git a/tests/Function/PartialTest.php b/tests/Function/PartialTest.php new file mode 100644 index 0000000..cb9e2de --- /dev/null +++ b/tests/Function/PartialTest.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2017 + */ + +use PHPUnit\Framework\TestCase; +use function _\partial; + +class PartialTest extends TestCase +{ + public function testPartial() + { + function greet($greeting, $name) + { + return $greeting.' '.$name; + } + + $sayHelloTo = partial('greet', 'hello'); + $this->assertSame('hello fred', $sayHelloTo('fred')); + } +} \ No newline at end of file From 748e6f2959546d12f4882e9273346353b20f90d8 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 22:41:21 +0200 Subject: [PATCH 111/159] Add Function.wrap function --- src/Function/wrap.php | 37 +++++++++++++++++++++++++++++++++++++ tests/Function/WrapTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/Function/wrap.php create mode 100644 tests/Function/WrapTest.php diff --git a/src/Function/wrap.php b/src/Function/wrap.php new file mode 100644 index 0000000..fb6bcaf --- /dev/null +++ b/src/Function/wrap.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Creates a function that provides `value` to `wrapper` as its first + * argument. Any additional arguments provided to the function are appended + * to those provided to the `wrapper`. + * + * @category Function + * + * @param mixed value The value to wrap. + * @param callable $wrapper The wrapper function. + * + * @return callable the new function. + * @example + * + * $p = wrap('_\escape', function($func, $text) { + * return '

' . $func($text) . '

'; + * }); + * + * $p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ +function wrap($value, callable $wrapper = null): callable +{ + return partial($wrapper ?? '\_\identity', $value); +} \ No newline at end of file diff --git a/tests/Function/WrapTest.php b/tests/Function/WrapTest.php new file mode 100644 index 0000000..50ef344 --- /dev/null +++ b/tests/Function/WrapTest.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2017 + */ + +use function _\wrap; +use PHPUnit\Framework\TestCase; + +class WrapTest extends TestCase +{ + public function testWrap() + { + $p = wrap('_\escape', function($func, $text) { + return '

' . $func($text) . '

'; + }); + + $this->assertSame('

fred, barney, & pebbles

', $p('fred, barney, & pebbles')); + } +} \ No newline at end of file From ffe629c83208d50130e1b577928d10a15116c669 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 22:42:16 +0200 Subject: [PATCH 112/159] Add compiled file --- src/compiled.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/compiled.php b/src/compiled.php index a013dfa..e0167a2 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -2,7 +2,7 @@ // Auto-generated file - namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } } + namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } define('_', _::class); } namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } @@ -19,7 +19,7 @@ namespace _ { function shuffle(array $array = []): array { \shuffle($array); return $array; } } namespace _ { use function _\internal\baseFlatten; function flatMap(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), 1); } } namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } - namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, $args); } } + namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, ...$args); } } namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } namespace _ { function sample(array $array) { $key = \array_rand($array, 1); return $array[$key]; } } @@ -41,7 +41,7 @@ namespace _ { use function _\internal\baseIteratee; use function _\internal\basePullAll; function pullAllBy(array &$array, array $values, $iteratee): array { return basePullAll($array, $values, baseIteratee($iteratee)); } } namespace _ { use function _\internal\baseUniq; function uniqWith(array $array, callable $comparator): array { return baseUniq($array, null, $comparator); } } namespace _ { use function _\internal\basePullAll; function pullAllWith(array &$array, array $values, callable $comparator): array { return basePullAll($array, $values, null, $comparator); } } - namespace _ { use function _\internal\baseRest; function zip(array ...$arrays): array { return baseRest('\_\unzip')($arrays); } } + namespace _ { use function _\internal\baseRest; function zip(array ...$arrays): array { return baseRest('\_\unzip')(...$arrays); } } namespace _ { function compact(?array $array): array { return \array_values(\array_filter($array ?? [])); } } namespace _ { function zipWith(...$arrays): array { $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; return unzipWith($arrays, $iteratee); } } namespace _ { function uniq(array $array = []): array { return \array_unique($array); } } @@ -57,7 +57,7 @@ namespace _ { use function _\internal\arrayMap; use function _\internal\baseProperty; use function _\internal\baseTimes; function unzip(array $array): array { if (!\count($array)) { return []; } $length = 0; $array = \array_filter($array, function ($group) use (&$length) { if (\is_array($group)) { $length = \max(\count($group), $length); return true; } }); return baseTimes($length, function ($index) use ($array) { return arrayMap($array, baseProperty($index)); }); } } namespace _ { function slice(array $array, int $start, int $end = null): array { return \array_slice($array, $start, $end); } } namespace _ { function drop(array $array, int $n = 1): array { return \array_slice($array, $n); } } - namespace _ { use function _\internal\baseRest; function without(array $array, ...$values): array { return baseRest('\_\difference')($array, $values); } } + namespace _ { use function _\internal\baseRest; function without(array $array, ...$values): array { return baseRest('\_\difference')($array, ...$values); } } namespace _ { function dropWhile(array $array, callable $predicate): array { \reset($array); $count = \count($array); $length = 0; $index = \key($array); while ($length <= $count && $predicate($array[$index], $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); } return $array; } } namespace _ { use function _\internal\baseIntersection; function intersectionWith(...$arrays ): array { $copy = $arrays; $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; $comparator = null; } return baseIntersection($arrays, null, $comparator); } } namespace _ { function head(array $array) { reset($array); return current($array) ?: null; } function first(array $array) { return head($array); } } @@ -94,7 +94,7 @@ namespace _\internal { function arrayMap(?array $array, callable $iteratee) { $index = -1; $length = null === $array ? 0 : \count($array); $result = []; while (++$index < $length) { $result[$index] = $iteratee($array[$index], $index, $array); } return $result; } } namespace _\internal { const rsAstralRange = '\\x{e800}-\\x{efff}'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsDingbatRange = '\\x{2700}-\\x{27bf}'; const rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; const rsMathOpRange = '\\xac\\xb1\\xd7\\xf7'; const rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; const rsPunctuationRange = '\\x{2000}-\\x{206f}'; const rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; const rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; const rsVarRange = '\\x{fe0e}\\x{fe0f}'; const rsBreakRange = rsMathOpRange.rsNonCharRange.rsPunctuationRange.rsSpaceRange; const rsApos = "[\\x{2019}]"; const rsBreak = '['.rsBreakRange.']'; const rsCombo = '['.rsComboRange.']'; const rsDigits = '\\d+'; const rsDingbat = '['.rsDingbatRange.']'; const rsLower = '['.rsLowerRange.']'; const rsMisc = '[^'.rsAstralRange.rsBreakRange.rsDigits.rsDingbatRange.rsLowerRange.rsUpperRange.']'; const rsFitz = '\\x{e83c}[\\x{effb}-\\x{efff}]'; const rsModifier = '(?:'.rsCombo.'|'.rsFitz.')'; const rsNonAstral = '[^'.rsAstralRange.']'; const rsRegional = '(?:\\x{e83c}[\\x{ede6}-\\x{edff}]){2}'; const rsSurrPair = '[\\x{e800}-\\x{ebff}][\\x{ec00}-\\x{efff}]'; const rsUpper = '['.rsUpperRange.']'; const rsZWJ = '\\x{200d}'; const rsMiscLower = '(?:'.rsLower.'|'.rsMisc.')'; const rsMiscUpper = '(?:'.rsUpper.'|'.rsMisc.')'; const rsOptContrLower = '(?:'.rsApos.'(?:d|ll|m|re|s|t|ve))?'; const rsOptContrUpper = '(?:'.rsApos.'(?:D|LL|M|RE|S|T|VE))?'; const reOptMod = rsModifier.'?'; const rsOptVar = '['.rsVarRange.']?'; define('rsOptJoin', '(?:'.rsZWJ.'(?:'.implode('|', [rsNonAstral, rsRegional, rsSurrPair]).')'.rsOptVar.reOptMod.')*'); const rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)'; const rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)'; const rsSeq = rsOptVar.reOptMod.rsOptJoin; define('rsEmoji', '(?:'.implode('|', [rsDingbat, rsRegional, rsSurrPair]).')'.rsSeq); const rsAstral = '['.rsAstralRange.']'; const rsNonAstralCombo = rsNonAstral.rsCombo.'?'; define('rsSymbol', '(?:'.implode('|', [rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral]).')'); const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; } namespace _\internal { function toKey($value): string { if (\is_string($value)) { return $value; } $result = (string) $value; return ('0' === $result && (1 / $value) === -INF) ? '-0' : $result; } } - namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $start = max($start ?? -1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs[$start]); }; } } + namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $parameters = (new \ReflectionFunction($func))->getNumberOfParameters(); $start = max($start ?? $parameters - 1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs); }; } } namespace _\internal\Traits { trait CacheDataTrait { private $__data__ = []; private $size; public function getSize(): int { return $this->size; } } } namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } namespace _\internal { function flatRest(callable $func): callable { return shortOut(overRest($func, null, '\_\flatten')); } } @@ -133,16 +133,22 @@ namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (\count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function (...$args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } + namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (\count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function ($args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } namespace _ { function before(int $n, callable $func): callable { $result = null; return function (...$args) use (&$result, &$n, &$func) { if (--$n > 0) { $result = $func(...$args); } return $result; }; } } namespace _ { function ary(callable $func, int $n): callable { return function (...$args) use ($func, $n) { \array_splice($args, $n); return $func(...$args); }; } } namespace _ { function once(callable $func): callable { return before(2, $func); } } namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } namespace _ { function bindKey($object, string $function, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); return $function(...array_merge($partials, $args)); }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } - namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : max((int) $start, 0); return baseRest(function (...$args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); if ($array) { $otherArgs = \array_merge($otherArgs, $array); } return $func(...$otherArgs); }); } } - namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function flip(callable $func): callable { return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; } } + namespace _ { function delay(callable $func, int $wait = 1, ...$args): int { usleep($wait * 1000); $func(...$args); return 1; } } + namespace _ { use function _\internal\baseRest; use function _\internal\shortOut; function partial(callable $func, ...$partials): callable { return baseRest(function ($func, $partials) { $wrapper = function () use ($func, $partials) { $arguments = \func_get_args(); $argsIndex = -1; $argsLength = \func_num_args(); $leftIndex = -1; $leftLength = \count($partials); $args = []; while (++$leftIndex < $leftLength) { $args[$leftIndex] = $partials[$leftIndex]; } while ($argsLength--) { $args[$leftIndex++] = $arguments[++$argsIndex]; } return $func(...$args); }; return shortOut($wrapper); })($func, ...$partials); } } + namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : \max($start, 0); return baseRest(function ($args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); if ($array) { $otherArgs = \array_merge($otherArgs, $array); } return $func(...$otherArgs); }); } } + namespace _ { function wrap($value, callable $wrapper = null): callable { return partial($wrapper ?? '\_\identity', $value); } } + namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function flip(callable $func): callable { return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; } } + namespace _ { function unary(callable $func): callable { return ary($func, 1); } } + namespace _ { function curry(callable $func, ?int $arity = null) { $curry = function ($arguments) use ($func, &$curry, $arity) { $requiredArguments = (new \ReflectionFunction($func))->getNumberOfParameters(); $arity = $arity ?? $requiredArguments; return function (...$args) use ($func, $arguments, $curry, $arity) { if (false !== \array_search(_, $arguments)) { foreach ($arguments as $i => $argument) { if (_ !== $argument) { continue; } $arguments[$i] = current($args); next($args); } } else { $arguments = \array_merge($arguments, $args); } if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { return $func(...$arguments); } return $curry($arguments); }; }; return $curry([]); } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } + namespace _ { use function _\internal\baseRest; function rest(callable $func, ?int $start = null): callable { return baseRest($func, $start); } } namespace _ { function bind(callable $function, $object, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); return $function(...array_merge($partials, $args)); }; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } @@ -154,7 +160,7 @@ namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } namespace _ { function eq($value, $other): bool { return $value === $other; } } namespace _ { use function _\internal\arrayMap; use function _\internal\baseIteratee; use function _\internal\basePickBy; function pickBy($object, callable $predicate): \stdClass { if (null === $object) { return new \stdClass; } $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { return [$prop]; }); $predicate = baseIteratee($predicate); return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); } } - namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, ...$paths) { return basePick($object, $paths); })($object, $paths); } } + namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, $paths) { return basePick($object, $paths); })($object, $paths); } } namespace _ { function lowerFirst(string $string): string { return \lcfirst($string); } } namespace _ { function camelCase(string $string): string { return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); } } namespace _ { function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); } } From 326a3442ea35f6e96a1150aa656042ea83490695 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 22:49:20 +0200 Subject: [PATCH 113/159] Fix some PHPStan errors --- src/Function/curry.php | 2 +- src/Function/delay.php | 6 +++--- src/Function/partial.php | 4 ++-- src/Function/wrap.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Function/curry.php b/src/Function/curry.php index 1bdd08e..42a00d9 100644 --- a/src/Function/curry.php +++ b/src/Function/curry.php @@ -26,7 +26,7 @@ * @category Function * * @param callable $func The function to curry. - * @param int $arity The arity of `func`. + * @param int|null $arity The arity of `func`. * * @return callable Returns the new curried function. * @example diff --git a/src/Function/delay.php b/src/Function/delay.php index faa2599..0fc1922 100644 --- a/src/Function/delay.php +++ b/src/Function/delay.php @@ -17,9 +17,9 @@ * * @category Function * - * @param callable $func The function to delay. - * @param int $wait The number of milliseconds to delay invocation. - * @param mixed[] $args + * @param callable $func The function to delay. + * @param int $wait The number of milliseconds to delay invocation. + * @param array $args * * @return int the timer id. * @example diff --git a/src/Function/partial.php b/src/Function/partial.php index e49b98f..5bcf80f 100644 --- a/src/Function/partial.php +++ b/src/Function/partial.php @@ -20,8 +20,8 @@ * * @category Function * - * @param callable $func The function to partially apply arguments to. - * @param mixed[] $partials The arguments to be partially applied. + * @param callable $func The function to partially apply arguments to. + * @param array $partials The arguments to be partially applied. * * @return callable Returns the new partially applied function. * diff --git a/src/Function/wrap.php b/src/Function/wrap.php index fb6bcaf..6e51252 100644 --- a/src/Function/wrap.php +++ b/src/Function/wrap.php @@ -18,7 +18,7 @@ * * @category Function * - * @param mixed value The value to wrap. + * @param mixed $value The value to wrap. * @param callable $wrapper The wrapper function. * * @return callable the new function. From 6ac150ee6a76421e423b5bc279cc3011e313cf48 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 22:50:42 +0200 Subject: [PATCH 114/159] Drop PHPStan level to 6 --- .travis.yml | 2 +- phpstan.neon | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1bbaa6f..8eb8c32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,4 +36,4 @@ install: script: - vendor/bin/php-cs-fixer fix --dry-run -v - vendor/bin/phpunit - - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=max + - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=6 diff --git a/phpstan.neon b/phpstan.neon index 1757ae6..54855d3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,3 +8,4 @@ parameters: - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" - "#Parameter \\#\\d+ \\$callable of static method Closure::fromCallable\\(\\) expects callable, array\\(object, string\\) given.#" + - "#Parameter \\#1 \\$name of class ReflectionFunction constructor expects Closure\\|string, callable given#" From ccf2d2a7ace0c8489cad84fb4f1dced5950b1b5e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 23:09:17 +0200 Subject: [PATCH 115/159] Fix CS --- src/Function/curry.php | 6 ++++-- src/Function/delay.php | 2 +- src/Function/partial.php | 1 - src/Function/rest.php | 2 +- src/Function/unary.php | 2 +- src/Function/wrap.php | 2 +- src/Lodash.php | 2 +- src/compiled.php | 12 ++++++------ tests/Function/BindTest.php | 7 +++---- tests/Function/CurryTest.php | 2 +- tests/Function/DelayTest.php | 4 ++-- tests/Function/PartialTest.php | 9 ++++----- tests/Function/RestTest.php | 2 +- tests/Function/UnaryTest.php | 2 +- tests/Function/WrapTest.php | 4 ++-- 15 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/Function/curry.php b/src/Function/curry.php index 42a00d9..d4cdd1c 100644 --- a/src/Function/curry.php +++ b/src/Function/curry.php @@ -71,7 +71,9 @@ function curry(callable $func, ?int $arity = null) $arguments = \array_merge($arguments, $args); } - if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { + if ($arity <= \count(\array_filter($arguments, function ($value) { + return _ !== $value; + }))) { return $func(...$arguments); } @@ -80,4 +82,4 @@ function curry(callable $func, ?int $arity = null) }; return $curry([]); -} \ No newline at end of file +} diff --git a/src/Function/delay.php b/src/Function/delay.php index 0fc1922..5812888 100644 --- a/src/Function/delay.php +++ b/src/Function/delay.php @@ -37,4 +37,4 @@ function delay(callable $func, int $wait = 1, ...$args): int $func(...$args); return 1; -} \ No newline at end of file +} diff --git a/src/Function/partial.php b/src/Function/partial.php index 5bcf80f..2ead57a 100644 --- a/src/Function/partial.php +++ b/src/Function/partial.php @@ -59,4 +59,3 @@ function partial(callable $func, ...$partials): callable return shortOut($wrapper); })($func, ...$partials); } - diff --git a/src/Function/rest.php b/src/Function/rest.php index e350168..1402941 100644 --- a/src/Function/rest.php +++ b/src/Function/rest.php @@ -39,4 +39,4 @@ function rest(callable $func, ?int $start = null): callable { return baseRest($func, $start); -} \ No newline at end of file +} diff --git a/src/Function/unary.php b/src/Function/unary.php index 7876928..d179ba8 100644 --- a/src/Function/unary.php +++ b/src/Function/unary.php @@ -29,4 +29,4 @@ function unary(callable $func): callable { return ary($func, 1); -} \ No newline at end of file +} diff --git a/src/Function/wrap.php b/src/Function/wrap.php index 6e51252..b4b21c0 100644 --- a/src/Function/wrap.php +++ b/src/Function/wrap.php @@ -34,4 +34,4 @@ function wrap($value, callable $wrapper = null): callable { return partial($wrapper ?? '\_\identity', $value); -} \ No newline at end of file +} diff --git a/src/Lodash.php b/src/Lodash.php index d8ec4ac..d488c2a 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -93,4 +93,4 @@ function lodash($value): _ return new _($value); } -define('_', _::class); \ No newline at end of file +define('_', _::class); diff --git a/src/compiled.php b/src/compiled.php index e0167a2..93cd773 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -2,7 +2,7 @@ // Auto-generated file - namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } define('_', _::class); } + namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } define('_', _::class); } namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } @@ -140,15 +140,15 @@ namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } namespace _ { function bindKey($object, string $function, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); return $function(...array_merge($partials, $args)); }; } } namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } - namespace _ { function delay(callable $func, int $wait = 1, ...$args): int { usleep($wait * 1000); $func(...$args); return 1; } } + namespace _ { function delay(callable $func, int $wait = 1, ...$args): int { usleep($wait * 1000); $func(...$args); return 1; } } namespace _ { use function _\internal\baseRest; use function _\internal\shortOut; function partial(callable $func, ...$partials): callable { return baseRest(function ($func, $partials) { $wrapper = function () use ($func, $partials) { $arguments = \func_get_args(); $argsIndex = -1; $argsLength = \func_num_args(); $leftIndex = -1; $leftLength = \count($partials); $args = []; while (++$leftIndex < $leftLength) { $args[$leftIndex] = $partials[$leftIndex]; } while ($argsLength--) { $args[$leftIndex++] = $arguments[++$argsIndex]; } return $func(...$args); }; return shortOut($wrapper); })($func, ...$partials); } } namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : \max($start, 0); return baseRest(function ($args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); if ($array) { $otherArgs = \array_merge($otherArgs, $array); } return $func(...$otherArgs); }); } } - namespace _ { function wrap($value, callable $wrapper = null): callable { return partial($wrapper ?? '\_\identity', $value); } } + namespace _ { function wrap($value, callable $wrapper = null): callable { return partial($wrapper ?? '\_\identity', $value); } } namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function flip(callable $func): callable { return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; } } - namespace _ { function unary(callable $func): callable { return ary($func, 1); } } - namespace _ { function curry(callable $func, ?int $arity = null) { $curry = function ($arguments) use ($func, &$curry, $arity) { $requiredArguments = (new \ReflectionFunction($func))->getNumberOfParameters(); $arity = $arity ?? $requiredArguments; return function (...$args) use ($func, $arguments, $curry, $arity) { if (false !== \array_search(_, $arguments)) { foreach ($arguments as $i => $argument) { if (_ !== $argument) { continue; } $arguments[$i] = current($args); next($args); } } else { $arguments = \array_merge($arguments, $args); } if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { return $func(...$arguments); } return $curry($arguments); }; }; return $curry([]); } } + namespace _ { function unary(callable $func): callable { return ary($func, 1); } } + namespace _ { function curry(callable $func, ?int $arity = null) { $curry = function ($arguments) use ($func, &$curry, $arity) { $requiredArguments = (new \ReflectionFunction($func))->getNumberOfParameters(); $arity = $arity ?? $requiredArguments; return function (...$args) use ($func, $arguments, $curry, $arity) { if (false !== \array_search(_, $arguments)) { foreach ($arguments as $i => $argument) { if (_ !== $argument) { continue; } $arguments[$i] = current($args); next($args); } } else { $arguments = \array_merge($arguments, $args); } if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { return $func(...$arguments); } return $curry($arguments); }; }; return $curry([]); } } namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } - namespace _ { use function _\internal\baseRest; function rest(callable $func, ?int $start = null): callable { return baseRest($func, $start); } } + namespace _ { use function _\internal\baseRest; function rest(callable $func, ?int $start = null): callable { return baseRest($func, $start); } } namespace _ { function bind(callable $function, $object, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); return $function(...array_merge($partials, $args)); }; } } namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } diff --git a/tests/Function/BindTest.php b/tests/Function/BindTest.php index c8e9750..a99a4f9 100644 --- a/tests/Function/BindTest.php +++ b/tests/Function/BindTest.php @@ -22,12 +22,11 @@ public function testBind() private $age = 54; }; - function greet($greeting, $punctuation) - { + $greet = function ($greeting, $punctuation) { return $greeting.' '.$this->user.$punctuation; - } + }; - $bound = bind('greet', $object, 'hi'); + $bound = bind($greet, $object, 'hi'); $this->assertSame('hi fred!', $bound('!')); diff --git a/tests/Function/CurryTest.php b/tests/Function/CurryTest.php index df00d58..a267362 100644 --- a/tests/Function/CurryTest.php +++ b/tests/Function/CurryTest.php @@ -28,4 +28,4 @@ public function testCurry() $this->assertSame([1, 2, null], curry($abc, 2)(1)(2)); $this->assertSame([1, 2, 3], $curried(1)(_, 3)(2)); } -} \ No newline at end of file +} diff --git a/tests/Function/DelayTest.php b/tests/Function/DelayTest.php index ba38db7..65e1465 100644 --- a/tests/Function/DelayTest.php +++ b/tests/Function/DelayTest.php @@ -18,11 +18,11 @@ public function testDelay() { $a = 1; $time = microtime(true); - delay(function ($increment) use(&$a) { + delay(function ($increment) use (&$a) { $a += $increment; }, 20, 2); $this->assertSame(3, $a); $this->assertTrue(((microtime(true) - $time) * 1000) > 20); } -} \ No newline at end of file +} diff --git a/tests/Function/PartialTest.php b/tests/Function/PartialTest.php index cb9e2de..2a2c8c1 100644 --- a/tests/Function/PartialTest.php +++ b/tests/Function/PartialTest.php @@ -16,12 +16,11 @@ class PartialTest extends TestCase { public function testPartial() { - function greet($greeting, $name) - { + $greet = function ($greeting, $name) { return $greeting.' '.$name; - } + }; - $sayHelloTo = partial('greet', 'hello'); + $sayHelloTo = partial($greet, 'hello'); $this->assertSame('hello fred', $sayHelloTo('fred')); } -} \ No newline at end of file +} diff --git a/tests/Function/RestTest.php b/tests/Function/RestTest.php index 5bf6152..58ad8d0 100644 --- a/tests/Function/RestTest.php +++ b/tests/Function/RestTest.php @@ -26,4 +26,4 @@ public function testRest() $this->assertSame('hello fred, barney, & pebbles', $say('hello', 'fred', 'barney', 'pebbles')); } -} \ No newline at end of file +} diff --git a/tests/Function/UnaryTest.php b/tests/Function/UnaryTest.php index a1c84b3..b68c439 100644 --- a/tests/Function/UnaryTest.php +++ b/tests/Function/UnaryTest.php @@ -19,4 +19,4 @@ public function testUnary() { $this->assertSame([6, 8, 10], map(['6', '8', '10'], unary('intval'))); } -} \ No newline at end of file +} diff --git a/tests/Function/WrapTest.php b/tests/Function/WrapTest.php index 50ef344..008485f 100644 --- a/tests/Function/WrapTest.php +++ b/tests/Function/WrapTest.php @@ -16,10 +16,10 @@ class WrapTest extends TestCase { public function testWrap() { - $p = wrap('_\escape', function($func, $text) { + $p = wrap('_\escape', function ($func, $text) { return '

' . $func($text) . '

'; }); $this->assertSame('

fred, barney, & pebbles

', $p('fred, barney, & pebbles')); } -} \ No newline at end of file +} From cd517c76d0b13cadfd959525410f6fc8ef34a1fe Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 23:43:45 +0200 Subject: [PATCH 116/159] Fix some docblocks --- src/Array/concat.php | 4 ++-- src/Array/flatten.php | 3 ++- src/Array/initial.php | 3 ++- src/Array/nth.php | 3 ++- src/Array/pullAllBy.php | 3 ++- src/Array/remove.php | 3 ++- src/Collection/findLast.php | 2 +- src/Collection/partition.php | 3 ++- src/Collection/reduceRight.php | 1 + src/Collection/sampleSize.php | 3 ++- src/Collection/shuffle.php | 3 ++- src/Collection/size.php | 3 ++- src/Function/bind.php | 3 ++- src/Function/bindKey.php | 3 ++- src/Function/delay.php | 4 ++-- src/Function/negate.php | 1 + src/Function/partial.php | 3 ++- src/Function/spread.php | 3 ++- src/Function/wrap.php | 1 + src/Lang/isError.php | 1 + src/Math/maxBy.php | 1 + src/Number/random.php | 3 ++- src/Object/pick.php | 3 ++- src/Object/pickBy.php | 3 ++- src/String/deburr.php | 3 ++- src/String/snakeCase.php | 3 ++- src/String/toUpper.php | 1 + src/String/trimEnd.php | 3 ++- 28 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/Array/concat.php b/src/Array/concat.php index 04a800b..945f2f8 100644 --- a/src/Array/concat.php +++ b/src/Array/concat.php @@ -27,10 +27,10 @@ * $array = [1]; * $other = concat($array, 2, [3], [[4]]); * - * var_dump(other) + * var_dump($other) * // => [1, 2, 3, [4]] * - * var_dump(array) + * var_dump($array) * // => [1] *
*/ diff --git a/src/Array/flatten.php b/src/Array/flatten.php index 7c4a002..be6371b 100644 --- a/src/Array/flatten.php +++ b/src/Array/flatten.php @@ -22,9 +22,10 @@ * * @return array the new flattened array. * @example - * + * * flatten([1, [2, [3, [4]], 5]]) * // => [1, 2, [3, [4]], 5] + * */ function flatten(array $array = null): array { diff --git a/src/Array/initial.php b/src/Array/initial.php index 5f25bab..8368454 100644 --- a/src/Array/initial.php +++ b/src/Array/initial.php @@ -20,9 +20,10 @@ * * @return array the slice of `array`. * @example - * + * * initial([1, 2, 3]) * // => [1, 2] + * */ function initial(array $array): array { diff --git a/src/Array/nth.php b/src/Array/nth.php index 32d142c..4b037fa 100644 --- a/src/Array/nth.php +++ b/src/Array/nth.php @@ -22,7 +22,7 @@ * * @return mixed Returns the nth element of `array`. * @example - * + * * $array = ['a', 'b', 'c', 'd'] * * nth($array, 1) @@ -30,6 +30,7 @@ * * nth($array, -2) * // => 'c' + * */ function nth(array $array, int $n) { diff --git a/src/Array/pullAllBy.php b/src/Array/pullAllBy.php index b1e458f..5e50a76 100644 --- a/src/Array/pullAllBy.php +++ b/src/Array/pullAllBy.php @@ -29,12 +29,13 @@ * * @return array `array`. * @example - * + * * $array = [[ 'x' => 1 ], [ 'x' => 2 ], [ 'x' => 3 ], [ 'x' => 1 ]] * * pullAllBy($array, [[ 'x' => 1 ], [ 'x' => 3 ]], 'x') * var_dump($array) * // => [[ 'x' => 2 ]] + * */ function pullAllBy(array &$array, array $values, $iteratee): array { diff --git a/src/Array/remove.php b/src/Array/remove.php index 70ff6cc..a939bf5 100644 --- a/src/Array/remove.php +++ b/src/Array/remove.php @@ -26,7 +26,7 @@ * * @return array the new array of removed elements. * @example - * + * * $array = [1, 2, 3, 4] * $evens = remove($array, function ($n) { return $n % 2 === 0; }) * @@ -35,6 +35,7 @@ * * var_dump($evens) * // => [2, 4] + * */ function remove(array &$array, callable $predicate): array { diff --git a/src/Collection/findLast.php b/src/Collection/findLast.php index 27c653e..2e7cb05 100644 --- a/src/Collection/findLast.php +++ b/src/Collection/findLast.php @@ -29,7 +29,7 @@ * * findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; }) * // => 3 - * + * */ function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { diff --git a/src/Collection/partition.php b/src/Collection/partition.php index 36b1353..ac4eae5 100644 --- a/src/Collection/partition.php +++ b/src/Collection/partition.php @@ -26,7 +26,7 @@ * * @return array the array of grouped elements. * @example - * + * * $users = [ * ['user' => 'barney', 'age' => 36, 'active' => false], * ['user' => 'fred', 'age' => 40, 'active' => true], @@ -35,6 +35,7 @@ * * partition($users, function($user) { return $user['active']; }) * // => objects for [['fred'], ['barney', 'pebbles']] + * */ function partition(iterable $collection, $predicate = null): array { diff --git a/src/Collection/reduceRight.php b/src/Collection/reduceRight.php index 9b3ff4b..8a51c16 100644 --- a/src/Collection/reduceRight.php +++ b/src/Collection/reduceRight.php @@ -32,6 +32,7 @@ * * reduceRight(array, (flattened, other) => flattened.concat(other), []) * // => [4, 5, 2, 3, 0, 1] + * */ function reduceRight(iterable $collection, $iteratee, $accumulator = null) { diff --git a/src/Collection/sampleSize.php b/src/Collection/sampleSize.php index 684cf2e..199842a 100644 --- a/src/Collection/sampleSize.php +++ b/src/Collection/sampleSize.php @@ -22,12 +22,13 @@ * * @return array the random elements. * @example - * + * * sampleSize([1, 2, 3], 2) * // => [3, 1] * * sampleSize([1, 2, 3], 4) * // => [2, 3, 1] + * */ function sampleSize(array $array, int $n = 1): array { diff --git a/src/Collection/shuffle.php b/src/Collection/shuffle.php index 353c16c..5dc4242 100644 --- a/src/Collection/shuffle.php +++ b/src/Collection/shuffle.php @@ -20,9 +20,10 @@ * * @return array the new shuffled array. * @example - * + * * shuffle([1, 2, 3, 4]) * // => [4, 1, 3, 2] + * */ function shuffle(array $array = []): array { diff --git a/src/Collection/size.php b/src/Collection/size.php index 91aa57b..5116e9e 100644 --- a/src/Collection/size.php +++ b/src/Collection/size.php @@ -21,7 +21,7 @@ * * @return int Returns the collection size. * @example - * + * * size([1, 2, 3]); * // => 3 * @@ -30,6 +30,7 @@ * * size('pebbles'); * // => 7 + * */ function size($collection): int { diff --git a/src/Function/bind.php b/src/Function/bind.php index 1adbcff..e69e0bd 100644 --- a/src/Function/bind.php +++ b/src/Function/bind.php @@ -23,7 +23,7 @@ * * @return callable Returns the new bound function. * @example - * + * * function greet($greeting, $punctuation) { * return $greeting . ' ' . $this->user . $punctuation; * } @@ -35,6 +35,7 @@ * $bound = bind('greet', $object, 'hi'); * $bound('!'); * // => 'hi fred!' + * */ function bind(callable $function, $object, ...$partials): callable { diff --git a/src/Function/bindKey.php b/src/Function/bindKey.php index ff34c0e..636cec6 100644 --- a/src/Function/bindKey.php +++ b/src/Function/bindKey.php @@ -26,7 +26,7 @@ * * @return callable Returns the new bound function. * @example - * + * * $object = new class { * private $user = 'fred'; * function greet($greeting, $punctuation) { @@ -37,6 +37,7 @@ * $bound = bindKey($object, 'greet', 'hi'); * $bound('!'); * // => 'hi fred!' + * */ function bindKey($object, string $function, ...$partials): callable { diff --git a/src/Function/delay.php b/src/Function/delay.php index 5812888..53418fe 100644 --- a/src/Function/delay.php +++ b/src/Function/delay.php @@ -23,12 +23,12 @@ * * @return int the timer id. * @example - *
+ * 
  * delay(function($text) {
  *   echo $text;
  * }, 1000, 'later');
  * // => Echo 'later' after one second.
- * 
+ * */ function delay(callable $func, int $wait = 1, ...$args): int { diff --git a/src/Function/negate.php b/src/Function/negate.php index 934cb0b..4032304 100644 --- a/src/Function/negate.php +++ b/src/Function/negate.php @@ -28,6 +28,7 @@ * * filter([1, 2, 3, 4, 5, 6], negate($isEven)); * // => [1, 3, 5] + * */ function negate(callable $predicate): callable diff --git a/src/Function/partial.php b/src/Function/partial.php index 2ead57a..8ada3d7 100644 --- a/src/Function/partial.php +++ b/src/Function/partial.php @@ -26,7 +26,7 @@ * @return callable Returns the new partially applied function. * * @example - * + * * function greet($greeting, $name) { * return $greeting . ' ' . $name; * } @@ -34,6 +34,7 @@ * $sayHelloTo = partial('greet', 'hello'); * $sayHelloTo('fred'); * // => 'hello fred' + * */ function partial(callable $func, ...$partials): callable { diff --git a/src/Function/spread.php b/src/Function/spread.php index df220fd..7dfab5f 100644 --- a/src/Function/spread.php +++ b/src/Function/spread.php @@ -33,13 +33,14 @@ * @return callable Returns the new function. * * @example - * + * * $say = spread(function($who, $what) { * return $who . ' says ' . $what; * }); * * $say(['fred', 'hello']); * // => 'fred says hello' + * */ function spread(callable $func, ?int $start = null) { diff --git a/src/Function/wrap.php b/src/Function/wrap.php index b4b21c0..84df495 100644 --- a/src/Function/wrap.php +++ b/src/Function/wrap.php @@ -30,6 +30,7 @@ * * $p('fred, barney, & pebbles'); * // => '

fred, barney, & pebbles

' + * */ function wrap($value, callable $wrapper = null): callable { diff --git a/src/Lang/isError.php b/src/Lang/isError.php index a31596c..0a9598f 100644 --- a/src/Lang/isError.php +++ b/src/Lang/isError.php @@ -27,6 +27,7 @@ * * isError(\Exception::Class) * // => false + * */ function isError($value): bool { diff --git a/src/Math/maxBy.php b/src/Math/maxBy.php index 091c5af..3127605 100644 --- a/src/Math/maxBy.php +++ b/src/Math/maxBy.php @@ -34,6 +34,7 @@ * // The `property` iteratee shorthand. * maxBy($objects, 'n'); * // => ['n' => 2] + * */ function maxBy(?array $array, $iteratee) { diff --git a/src/Number/random.php b/src/Number/random.php index 92b3600..7da25a7 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -26,7 +26,7 @@ * @return int|float Returns the random number. * * @example - * + * * random(0, 5) * // => an integer between 0 and 5 * @@ -38,6 +38,7 @@ * * random(1.2, 5.2) * // => a floating-point number between 1.2 and 5.2 + * */ function random($lower = null, $upper = null, $floating = null) { diff --git a/src/Object/pick.php b/src/Object/pick.php index 13abc80..9813514 100644 --- a/src/Object/pick.php +++ b/src/Object/pick.php @@ -24,11 +24,12 @@ * * @return \stdClass Returns the new object. * @example - * + * * $object = (object) ['a' => 1, 'b' => '2', 'c' => 3]; * * pick($object, ['a', 'c']); * // => (object) ['a' => 1, 'c' => 3] + * */ function pick($object, $paths): \stdClass { diff --git a/src/Object/pickBy.php b/src/Object/pickBy.php index f0e11c9..7d85cc0 100644 --- a/src/Object/pickBy.php +++ b/src/Object/pickBy.php @@ -26,11 +26,12 @@ * * @return \stdClass Returns the new object. * @example - * + * * $object = (object) ['a' => 1, 'b' => 'abc', 'c' => 3]; * * pickBy(object, 'is_numeric'); * // => (object) ['a' => 1, 'c' => 3] + * */ function pickBy($object, callable $predicate): \stdClass { diff --git a/src/String/deburr.php b/src/String/deburr.php index 579ae6b..a850d78 100644 --- a/src/String/deburr.php +++ b/src/String/deburr.php @@ -96,9 +96,10 @@ * @return string Returns the deburred string. * * @example - * + * * deburr('déjà vu') * // => 'deja vu' + * */ function deburr(string $string): string { diff --git a/src/String/snakeCase.php b/src/String/snakeCase.php index fcb4a50..07c3d0f 100644 --- a/src/String/snakeCase.php +++ b/src/String/snakeCase.php @@ -19,7 +19,7 @@ * @param string $string The string to convert. * @return string Returns the snake cased string. * @example - * + * * snakeCase('Foo Bar') * // => 'foo_bar' * @@ -28,6 +28,7 @@ * * snakeCase('--FOO-BAR--') * // => 'foo_bar' + * */ function snakeCase(string $string): string { diff --git a/src/String/toUpper.php b/src/String/toUpper.php index 3a0779a..af61dcf 100644 --- a/src/String/toUpper.php +++ b/src/String/toUpper.php @@ -29,6 +29,7 @@ * * toUpper('__foo_bar__') * // => '__FOO_BAR__' + * */ function toUpper(string $string): string { diff --git a/src/String/trimEnd.php b/src/String/trimEnd.php index 924d096..a90e9da 100644 --- a/src/String/trimEnd.php +++ b/src/String/trimEnd.php @@ -21,12 +21,13 @@ * * @return string Returns the trimmed string. * @example - * + * * trimEnd(' abc ') * // => ' abc' * * trimEnd('-_-abc-_-', '_-') * // => '-_-abc' + * */ function trimEnd(string $string, string $chars = ' '): string { From 28e1e007c9c205f2ea27431cb824256ce00ad89c Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 23:44:16 +0200 Subject: [PATCH 117/159] Re-generate README --- README.md | 1280 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 1063 insertions(+), 217 deletions(-) diff --git a/README.md b/README.md index 8b96dc9..59136db 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ _::each([1, 2, 3], function (int $item) { - [Math](#math) - [Number](#number) - [Object](#object) +- [Seq](#seq) - [String](#string) - [Util](#util) @@ -53,10 +54,12 @@ _::each([1, 2, 3], function (int $item) { ### chunk Creates an array of elements split into groups the length of `size`. - If `array` can't be split evenly, the final chunk will be the remaining elements. + + + **Arguments:** @param array $array array The array to process. @@ -88,6 +91,7 @@ Creates an array with all falsey values removed. The values `false`, `null`, + **Arguments:** @param array $array The array to compact. @@ -114,11 +118,13 @@ and/or values. + + **Arguments:** @param array $array The array to concatenate. -@param mixed $values The values to concatenate. +@param array $values The values to concatenate. @@ -150,11 +156,15 @@ determined by the first array. **Note:** Unlike `pullAll`, this method returns a new array. + + + + **Arguments:** @param array $array The array to inspect. -@param array $values The values to exclude. +@param array ...$values The values to exclude. @@ -181,13 +191,17 @@ determined by the first array. The iteratee is invoked with one argument: **Note:** Unlike `pullAllBy`, this method returns a new array. + + + + **Arguments:** @param array $array The array to inspect. -@param array $values The values to exclude. +@param array ...$values The values to exclude. -@param callable $ iteratee The iteratee invoked per element. +@param callable $iteratee The iteratee invoked per element. @@ -199,8 +213,10 @@ Example: ```php [1.2] + ``` ### differenceWith @@ -211,11 +227,16 @@ is invoked with two arguments: (arrVal, othVal). **Note:** Unlike `pullAllWith`, this method returns a new array. + + + + + **Arguments:** -@param array $array The array to inspect. +@param array $array The array to inspect. -@param array[] $values The values to exclude. +@param array ...$values The values to exclude. @param callable $comparator The comparator invoked per element. @@ -242,6 +263,9 @@ Creates a slice of `array` with `n` elements dropped from the beginning. **NOTE:** This function will reorder and reset the array indices + + + **Arguments:** @param array $array The array to query. @@ -275,9 +299,11 @@ drop([1, 2, 3], 0) ### dropRight Creates a slice of `array` with `n` elements dropped from the end. - **NOTE:** This function will reorder and reset the array indices + + + **Arguments:** @param array $array The array to query. @@ -311,10 +337,12 @@ dropRight([1, 2, 3], 0) ### dropRightWhile Creates a slice of `array` excluding elements dropped from the end. - Elements are dropped until `predicate` returns falsey. The predicate is invoked with three arguments: (value, index, array). + + + **Arguments:** @param array $array The array to query. @@ -333,9 +361,9 @@ Example: use function _\dropRightWhile; $users = [ - [ 'user' => 'barney', 'active' => false ], - [ 'user' => 'fred', 'active' => true ], - [ 'user' => 'pebbles', 'active' => true ] +[ 'user' => 'barney', 'active' => false ], +[ 'user' => 'fred', 'active' => true ], +[ 'user' => 'pebbles', 'active' => true ] ] dropRightWhile($users, function($user) { return $user['active']; }) @@ -345,10 +373,12 @@ dropRightWhile($users, function($user) { return $user['active']; }) ### dropWhile Creates a slice of `array` excluding elements dropped from the beginning. - Elements are dropped until `predicate` returns falsey. The predicate is invoked with three arguments: (value, index, array). + + + **Arguments:** @param array $array The array to query. @@ -367,9 +397,9 @@ Example: use function _\dropWhile; $users = [ - [ 'user' => 'barney', 'active' => true ], - [ 'user' => 'fred', 'active' => true ], - [ 'user' => 'pebbles', 'active' => false ] +[ 'user' => 'barney', 'active' => true ], +[ 'user' => 'fred', 'active' => true ], +[ 'user' => 'pebbles', 'active' => false ] ] dropWhile($users, function($user) { return $user['active']; } ) @@ -379,7 +409,6 @@ dropWhile($users, function($user) { return $user['active']; } ) ### every Checks if `predicate` returns truthy for **all** elements of `array`. - Iteration is stopped once `predicate` returns falsey. The predicate is invoked with three arguments: (value, index, array). @@ -388,6 +417,9 @@ invoked with three arguments: (value, index, array). [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of elements of empty arrays. + + + **Arguments:** @param iterable $collection The array to iterate over. @@ -409,8 +441,8 @@ every([true, 1, null, 'yes'], function ($value) { return is_bool($value);}) // => false $users = [ - ['user' => 'barney', 'age' => 36, 'active' => false], - ['user' => 'fred', 'age' => 40, 'active' => false], +['user' => 'barney', 'age' => 36, 'active' => false], +['user' => 'fred', 'age' => 40, 'active' => false], ]; // The `matches` iteratee shorthand. @@ -433,6 +465,7 @@ This method is like `find` except that it returns the index of the first element + **Arguments:** @param array $array The array to inspect. @@ -453,9 +486,9 @@ Example: use function _\findIndex; $users = [ - ['user' => 'barney', 'active' => false], - ['user' => 'fred', 'active' => false], - ['user' => 'pebbles', 'active' => true], +['user' => 'barney', 'active' => false], +['user' => 'fred', 'active' => false], +['user' => 'pebbles', 'active' => true], ]; findIndex($users, function($o) { return $o['user'] s== 'barney'; }); @@ -481,6 +514,7 @@ of `collection` from right to left. + **Arguments:** @param array $array The array to inspect. @@ -501,9 +535,9 @@ Example: use function _\findLastIndex; $users = [ - ['user' => 'barney', 'active' => true ], - ['user' => 'fred', 'active' => false ], - ['user' => 'pebbles', 'active' => false ] +['user' => 'barney', 'active' => true ], +['user' => 'fred', 'active' => false ], +['user' => 'pebbles', 'active' => false ] ] findLastIndex($users, function($user) { return $user['user'] === 'pebbles'; }) @@ -516,6 +550,7 @@ Flattens `array` a single level deep. + **Arguments:** @param array $array The array to flatten. @@ -530,8 +565,10 @@ Example: ```php [1, 2, [3, [4]], 5] + ``` ### flattenDeep @@ -539,6 +576,7 @@ Recursively flattens `array`. + **Arguments:** @param array $array The array to flatten. @@ -564,6 +602,7 @@ Recursively flatten `array` up to `depth` times. + **Arguments:** @param array $array The array to flatten. @@ -597,6 +636,8 @@ from key-value `pairs`. + + **Arguments:** @param array $pairs The key-value pairs. @@ -605,7 +646,7 @@ from key-value `pairs`. **Return:** -@return object the new object. +@return \stdClass the new object. Example: ```php @@ -625,6 +666,8 @@ Gets the first element of `array`. + + **Arguments:** @param array $array The array to query. @@ -656,6 +699,7 @@ offset from the end of `array`. + **Arguments:** @param array $array The array to inspect. @@ -689,6 +733,7 @@ Gets all but the last element of `array`. + **Arguments:** @param array $array The array to query. @@ -703,8 +748,10 @@ Example: ```php [1, 2] + ``` ### intersection @@ -715,9 +762,11 @@ determined by the first array. + + **Arguments:** -@param array[] $arrays +@param array ...$arrays @@ -729,8 +778,10 @@ Example: ```php [2] + ``` ### intersectionBy @@ -742,9 +793,10 @@ determined by the first array. The iteratee is invoked with one argument: + **Arguments:** -@param array[] $arrays +@param array ...$arrays @param callable $iteratee The iteratee invoked per element. @@ -776,9 +828,11 @@ invoked with two arguments: (arrVal, othVal). + + **Arguments:** -@param array[] $arrays +@param array ...$arrays @param callable $comparator The comparator invoked per element. @@ -806,6 +860,7 @@ Gets the last element of `array`. + **Arguments:** @param array $array The array to query. @@ -832,6 +887,7 @@ This method is like `indexOf` except that it iterates over elements of + **Arguments:** @param array $array The array to inspect. @@ -866,6 +922,7 @@ element from the end is returned. + **Arguments:** @param array $array The array to query. @@ -882,6 +939,7 @@ Example: ```php 'c' + ``` ### pull @@ -899,11 +958,15 @@ for equality comparisons. **Note:** Unlike `without`, this method mutates `array`. Use `remove` to remove elements from an array by predicate. + + + + **Arguments:** @param array $array The array to modify. -@param array $values The values to remove. +@param array $values The values to remove. @@ -929,6 +992,9 @@ This method is like `pull` except that it accepts an array of values to remove. **Note:** Unlike `difference`, this method mutates `array`. + + + **Arguments:** @param array $array The array to modify. @@ -961,6 +1027,9 @@ by which they're compared. The iteratee is invoked with one argument: (value). **Note:** Unlike `differenceBy`, this method mutates `array`. + + + **Arguments:** @param array $array The array to modify. @@ -979,11 +1048,13 @@ Example: ```php 1 ], [ 'x' => 2 ], [ 'x' => 3 ], [ 'x' => 1 ]] pullAllBy($array, [[ 'x' => 1 ], [ 'x' => 3 ]], 'x') var_dump($array) // => [[ 'x' => 2 ]] + ``` ### pullAllWith @@ -993,6 +1064,9 @@ invoked with two arguments: (arrVal, othVal). **Note:** Unlike `differenceWith`, this method mutates `array`. + + + **Arguments:** @param array $array The array to modify. @@ -1026,11 +1100,14 @@ array of removed elements. **Note:** Unlike `at`, this method mutates `array`. + + + **Arguments:** @param array $array The array to modify. -@param int|int[] $indexes The indexes of elements to remove. +@param (int | int[]) $indexes The indexes of elements to remove. @@ -1062,6 +1139,9 @@ with three arguments: (value, index, array). **Note:** Unlike `filter`, this method mutates `array`. Use `pull` to pull elements from an array by value. + + + **Arguments:** @param array $array The array to modify. @@ -1078,6 +1158,7 @@ Example: ```php [2, 4] + ``` ### sample @@ -1093,6 +1175,8 @@ Gets a random element from `array`. + + **Arguments:** @param array $array The array to sample. @@ -1119,6 +1203,7 @@ size of `array`. + **Arguments:** @param array $array The array to sample. @@ -1135,11 +1220,13 @@ Example: ```php [3, 1] sampleSize([1, 2, 3], 4) // => [2, 3, 1] + ``` ### shuffle @@ -1147,6 +1234,7 @@ Creates an array of shuffled values + **Arguments:** @param array $array The array to shuffle. @@ -1161,8 +1249,10 @@ Example: ```php [4, 1, 3, 2] + ``` ### slice @@ -1190,6 +1280,8 @@ Gets all but the first element of `array`. + + **Arguments:** @param array $array The array to query. @@ -1215,6 +1307,7 @@ Creates a slice of `array` with `n` elements taken from the beginning. + **Arguments:** @param array $array The array to query. @@ -1251,6 +1344,7 @@ Creates a slice of `array` with `n` elements taken from the end. + **Arguments:** @param array $array The array to query. @@ -1289,6 +1383,8 @@ three arguments: (value, index, array). + + **Arguments:** @param array $array The array to query. @@ -1307,9 +1403,9 @@ Example: use function _\takeRightWhile; $users = [ - [ 'user' => 'barney', 'active' => false ], - [ 'user' => 'fred', 'active' => true ], - [ 'user' => 'pebbles', 'active' => true ] +[ 'user' => 'barney', 'active' => false ], +[ 'user' => 'fred', 'active' => true ], +[ 'user' => 'pebbles', 'active' => true ] ]; takeRightWhile($users, function($value) { return $value['active']; }) @@ -1324,6 +1420,8 @@ three arguments: (value, index, array). + + **Arguments:** @param array $array The array to query. @@ -1342,9 +1440,9 @@ Example: use function _\takeWhile; $users = [ - [ 'user' => 'barney', 'active' => true ], - [ 'user' => 'fred', 'active' => true ], - [ 'user' => 'pebbles', 'active' => false ] +[ 'user' => 'barney', 'active' => true ], +[ 'user' => 'fred', 'active' => true ], +[ 'user' => 'pebbles', 'active' => false ] ] takeWhile($users, function($value) { return $value['active']; }) @@ -1359,9 +1457,11 @@ for equality comparisons. + + **Arguments:** -@param array[] $arrays The arrays to inspect. +@param array ...$arrays The arrays to inspect. @@ -1388,9 +1488,11 @@ array in which the value occurs. The iteratee is invoked with one argument: + + **Arguments:** -@param array[] $arrays The arrays to inspect. +@param array ...$arrays The arrays to inspect. @param callable $iteratee The iteratee invoked per element. @@ -1422,9 +1524,12 @@ with two arguments: (arrVal, othVal). + + + **Arguments:** -@param array[] $arrays The arrays to inspect. +@param array ...$arrays The arrays to inspect. @param callable $comparator The comparator invoked per element. @@ -1438,11 +1543,13 @@ Example: ```php 1, 'y' => 2], ['x' => 2, 'y' => 1]] $others = [['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]] unionWith($objects, $others, '_::isEqual') // => [['x' => 1, 'y' => 2], ['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]] + ``` ### uniq @@ -1454,6 +1561,7 @@ in the array. + **Arguments:** @param array $array The array to inspect. @@ -1483,6 +1591,7 @@ order they occur in the array. The iteratee is invoked with one argument: + **Arguments:** @param array $array The array to inspect. @@ -1513,6 +1622,7 @@ with two arguments: (arrVal, othVal). + **Arguments:** @param array $array The array to inspect. @@ -1544,6 +1654,7 @@ configuration. + **Arguments:** @param array $array The array of grouped elements to process. @@ -1570,15 +1681,17 @@ unzip($zipped) This method is like `unzip` except that it accepts `iteratee` to specify how regrouped values should be combined. The iteratee is invoked with the -elements of each group: (. +elements of each group: (...group). + + + -..group). **Arguments:** @param array $array The array of grouped elements to process. -@param callable $iteratee The function to combine regrouped values. +@param (callable | null) $iteratee The function to combine regrouped values. @@ -1606,11 +1719,14 @@ for equality comparisons. **Note:** Unlike `pull`, this method returns a new array. + + + **Arguments:** @param array $array The array to inspect. -@param array $values The values to exclude. +@param array $values The values to exclude. @@ -1635,9 +1751,10 @@ second elements of the given arrays, and so on. + **Arguments:** -@param array[] $arrays The arrays to process. +@param array ...$arrays The arrays to process. @@ -1661,6 +1778,8 @@ one of property identifiers and one of corresponding values. + + **Arguments:** @param array $props The property identifiers. @@ -1692,6 +1811,8 @@ This method is like `zipObject` except that it supports property paths. + + **Arguments:** @param array $props The property identifiers. @@ -1702,7 +1823,7 @@ This method is like `zipObject` except that it supports property paths. **Return:** -@return object the new object. +@return \stdClass the new object. Example: ```php @@ -1711,18 +1832,18 @@ Example: zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]) /* => class stdClass#20 (1) { - public $a => class stdClass#19 (1) { - public $b => - array(2) { - [0] => class stdClass#17 (1) { - public $c => int(1) - } - [1] => class stdClass#18 (1) { - public $d => int(2) - } - } - } - } +public $a => class stdClass#19 (1) { +public $b => +array(2) { +[0] => class stdClass#17 (1) { +public $c => int(1) +} +[1] => class stdClass#18 (1) { +public $d => int(2) +} +} +} +} *\/ ``` @@ -1730,13 +1851,15 @@ zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]) This method is like `zip` except that it accepts `iteratee` to specify how grouped values should be combined. The iteratee is invoked with the -elements of each group: (. +elements of each group: (...group). + + + -..group). **Arguments:** -@param array[] $arrays The arrays to process. +@param array ...$arrays The arrays to process. @param callable $iteratee The function to combine grouped values. @@ -1766,6 +1889,7 @@ iteratee is invoked with one argument: (value). + **Arguments:** @param iterable $collection The collection to iterate over. @@ -1794,7 +1918,6 @@ countBy(['one', 'two', 'three'], 'strlen'); ### each Iterates over elements of `collection` and invokes `iteratee` for each element. - The iteratee is invoked with three arguments: (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returning `false`. @@ -1802,9 +1925,13 @@ Iteratee functions may exit iteration early by explicitly returning `false`. property are iterated like arrays. To avoid this behavior use `forIn` or `forOwn` for object iteration. + + + + **Arguments:** -@param array|object $collection The collection to iterate over. +@param (array | iterable | object) $collection The collection to iterate over. @param callable $iteratee The function invoked per iteration. @@ -1812,7 +1939,7 @@ or `forOwn` for object iteration. **Return:** -@return array|object Returns `collection`. +@return (array | object) Returns `collection`. Example: ```php @@ -1833,9 +1960,10 @@ This method is like `each` except that it iterates over elements of + **Arguments:** -@param array|object $collection The collection to iterate over. +@param (array | iterable | object) $collection The collection to iterate over. @param callable $iteratee The function invoked per iteration. @@ -1843,7 +1971,7 @@ This method is like `each` except that it iterates over elements of **Return:** -@return array|object Returns `collection`. +@return (array | object) Returns `collection`. Example: ```php @@ -1862,6 +1990,10 @@ arguments: (value, index, array). **Note:** Unlike `remove`, this method returns a new array. + + + + **Arguments:** @param iterable $array The array to iterate over. @@ -1880,8 +2012,8 @@ Example: use function _\filter; $users = [ - [ 'user' => 'barney', 'age' => 36, 'active' => true], - [ 'user' => 'fred', 'age' => 40, 'active' => false] +[ 'user' => 'barney', 'age' => 36, 'active' => true], +[ 'user' => 'fred', 'age' => 40, 'active' => false] ]; filter($users, function($o) { return !$o['active']; }); @@ -1908,6 +2040,8 @@ arguments: (value, index|key, collection). + + **Arguments:** @param iterable $collection The collection to inspect. @@ -1928,9 +2062,9 @@ Example: use function _\find; $users = [ - ['user' => 'barney', 'age' => 36, 'active' => true], - ['user' => 'fred', 'age' => 40, 'active' => false], - ['user' => 'pebbles', 'age' => 1, 'active' => true] +['user' => 'barney', 'age' => 36, 'active' => true], +['user' => 'fred', 'age' => 40, 'active' => false], +['user' => 'pebbles', 'age' => 1, 'active' => true] ]; find($users, function($o) { return $o['age'] < 40; }); @@ -1956,6 +2090,8 @@ This method is like `find` except that it iterates over elements of + + **Arguments:** @param iterable $collection The collection to inspect. @@ -1977,7 +2113,7 @@ Example: findLast([1, 2, 3, 4], function ($n) { return $n % 2 == 1; }) // => 3 - + ``` ### flatMap @@ -1987,9 +2123,11 @@ with three arguments: (value, index|key, collection). + + **Arguments:** -@param iterable $ collection The collection to iterate over. +@param iterable $collection The collection to iterate over. @param callable $iteratee The function invoked per iteration. @@ -2005,7 +2143,7 @@ Example: use function _\flatMap; function duplicate($n) { - return [$n, $n] +return [$n, $n] } flatMap([1, 2], 'duplicate') @@ -2019,9 +2157,10 @@ mapped results. + **Arguments:** -@param iterable $ collection The collection to iterate over. +@param iterable $collection The collection to iterate over. @param callable $iteratee The function invoked per iteration. @@ -2037,7 +2176,7 @@ Example: use function _\flatMapDeep; function duplicate($n) { - return [[[$n, $n]]]; +return [[[$n, $n]]]; } flatMapDeep([1, 2], 'duplicate'); @@ -2051,9 +2190,10 @@ mapped results up to `depth` times. + **Arguments:** -@param iterable $ collection The collection to iterate over. +@param iterable $collection The collection to iterate over. @param callable $iteratee The function invoked per iteration. @@ -2071,7 +2211,7 @@ Example: use function _\flatMapDepth; function duplicate($n) { - return [[[$n, $n]]] +return [[[$n, $n]]] } flatMapDepth([1, 2], 'duplicate', 2) @@ -2088,9 +2228,10 @@ key. The iteratee is invoked with one argument: (value). + **Arguments:** -@param iterable $ collection The collection to iterate over. +@param iterable $collection The collection to iterate over. @param callable $iteratee The iteratee to transform keys. @@ -2121,11 +2262,12 @@ for, and `this` bound to, each element in `collection`. + **Arguments:** @param iterable $collection The collection to iterate over. -@param array|callable|string $path The path of the method to invoke or the function invoked per iteration. +@param (array | callable | string) $path The path of the method to invoke or the function invoked per iteration. @param array $args The arguments to invoke each method with. @@ -2156,6 +2298,7 @@ iteratee is invoked with one argument: (value). + **Arguments:** @param iterable $collection The collection to iterate over. @@ -2174,8 +2317,8 @@ Example: use function _\keyBy; $array = [ - ['direction' => 'left', 'code' => 97], - ['direction' => 'right', 'code' => 100], +['direction' => 'left', 'code' => 97], +['direction' => 'right', 'code' => 100], ]; keyBy($array, function ($o) { return \chr($o['code']); }) @@ -2200,11 +2343,14 @@ The guarded methods are: `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, and `words` + + + **Arguments:** -@param array|object $collection The collection to iterate over. +@param (array | object) $collection The collection to iterate over. -@param callable|string|array $iteratee The function invoked per iteration. +@param (callable | string | array) $iteratee The function invoked per iteration. @@ -2218,7 +2364,7 @@ Example: use function _\map; function square(int $n) { - return $n * $n; +return $n * $n; } map([4, 8], $square); @@ -2228,8 +2374,8 @@ map((object) ['a' => 4, 'b' => 8], $square); // => [16, 64] (iteration order is not guaranteed) $users = [ - [ 'user' => 'barney' ], - [ 'user' => 'fred' ] +[ 'user' => 'barney' ], +[ 'user' => 'fred' ] ]; // The `property` iteratee shorthand. @@ -2246,11 +2392,12 @@ descending or "asc" for ascending sort order of corresponding values. + **Arguments:** -@param iterable $collection The collection to iterate over. +@param (iterable | null) $collection The collection to iterate over. -@param array[]|callable[]|string[] $iteratee The iteratee(s) to sort by. +@param (array[] | callable[] | string[]) $iteratee The iteratee(s) to sort by. @param string[] $orders The sort orders of `iteratees`. @@ -2266,10 +2413,10 @@ Example: use function _\orderBy; $users = [ - ['user' => 'fred', 'age' => 48], - ['user' => 'barney', 'age' => 34], - ['user' => 'fred', 'age' => 40], - ['user' => 'barney', 'age' => 36] +['user' => 'fred', 'age' => 48], +['user' => 'barney', 'age' => 34], +['user' => 'fred', 'age' => 40], +['user' => 'barney', 'age' => 36] ] // Sort by `user` in ascending order and by `age` in descending order. @@ -2286,6 +2433,7 @@ invoked with one argument: (value). + **Arguments:** @param iterable $collection The collection to iterate over. @@ -2302,14 +2450,16 @@ Example: ```php 'barney', 'age' => 36, 'active' => false], - ['user' => 'fred', 'age' => 40, 'active' => true], - ['user' => 'pebbles', 'age' => 1, 'active' => false] +['user' => 'barney', 'age' => 36, 'active' => false], +['user' => 'fred', 'age' => 40, 'active' => true], +['user' => 'pebbles', 'age' => 1, 'active' => false] ]; partition($users, function($user) { return $user['active']; }) // => objects for [['fred'], ['barney', 'pebbles']] + ``` ### reduce @@ -2327,6 +2477,10 @@ The guarded methods are: `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, and `sortBy` + + + + **Arguments:** @param iterable $collection The collection to iterate over. @@ -2350,13 +2504,13 @@ reduce([1, 2], function($sum, $n) { return $sum + $n; }, 0) // => 3 reduce(['a' => 1, 'b' => 2, 'c' => 1], function ($result, $value, $key) { - if (!isset($result[$value])) { - $result[$value] = []; - } - $result[$value][] = $key; +if (!isset($result[$value])) { +$result[$value] = []; +} +$result[$value][] = $key; - return $result; - }, []) +return $result; +}, []) // => ['1' => ['a', 'c'], '2' => ['b']] (iteration order is not guaranteed) ``` @@ -2367,6 +2521,8 @@ This method is like `reduce` except that it iterates over elements of + + **Arguments:** @param iterable $collection The collection to iterate over. @@ -2390,6 +2546,7 @@ $array = [[0, 1], [2, 3], [4, 5]]; reduceRight(array, (flattened, other) => flattened.concat(other), []) // => [4, 5, 2, 3, 0, 1] + ``` ### reject @@ -2398,6 +2555,8 @@ that `predicate` does **not** return truthy for. + + **Arguments:** @param iterable $collection The collection to iterate over. @@ -2416,8 +2575,8 @@ Example: use function _\reject; $users = [ - ['user' => 'barney', 'active' => true], - ['user' => 'fred', 'active' => false] +['user' => 'barney', 'active' => true], +['user' => 'fred', 'active' => false] ] reject($users, 'active') @@ -2431,9 +2590,10 @@ values or the number of public properties for objects. + **Arguments:** -@param array|object|string $collection The collection to inspect. +@param (array | object | string) $collection The collection to inspect. @@ -2445,6 +2605,7 @@ Example: ```php 3 @@ -2453,25 +2614,28 @@ size(new class { public $a = 1; public $b = 2; private $c = 3; }); size('pebbles'); // => 7 + ``` ### some Checks if `predicate` returns truthy for **any** element of `collection`. - Iteration is stopped once `predicate` returns truthy. The predicate is invoked with three arguments: (value, index|key, collection). + + + **Arguments:** @param iterable $collection The collection to iterate over. -@param callable|string|array $predicate The function invoked per iteration. +@param (callable | string | array) $predicate The function invoked per iteration. **Return:** -@return bool Returns `true` if any element passes the predicate check, else `false`. +@return boolean Returns `true` if any element passes the predicate check, else `false`. Example: ```php @@ -2482,8 +2646,8 @@ some([null, 0, 'yes', false], , function ($value) { return \is_bool($value); })) // => true $users = [ - ['user' => 'barney', 'active' => true], - ['user' => 'fred', 'active' => false] +['user' => 'barney', 'active' => true], +['user' => 'fred', 'active' => false] ]; // The `matches` iteratee shorthand. @@ -2508,11 +2672,12 @@ equal elements. The iteratees are invoked with one argument: (value). + **Arguments:** -@param array|object $collection The collection to iterate over. +@param (array | object | null) $collection The collection to iterate over. -@param callable|callable[] $iteratees The iteratees to sort by. +@param (callable | callable[]) $iteratees The iteratees to sort by. @@ -2526,10 +2691,10 @@ Example: use function _\sortBy; $users = [ - [ 'user' => 'fred', 'age' => 48 ], - [ 'user' => 'barney', 'age' => 36 ], - [ 'user' => 'fred', 'age' => 40 ], - [ 'user' => 'barney', 'age' => 34 ], +[ 'user' => 'fred', 'age' => 48 ], +[ 'user' => 'barney', 'age' => 36 ], +[ 'user' => 'fred', 'age' => 40 ], +[ 'user' => 'barney', 'age' => 34 ], ]; sortBy($users, [function($o) { return $o['user']; }]); @@ -2547,6 +2712,7 @@ Gets the timestamp of the number of milliseconds that have elapsed since the Uni + **Arguments:** @@ -2566,116 +2732,668 @@ now(); ``` ## Function -### memoize +### after + +The opposite of `before`; this method creates a function that invokes +`func` once it's called `n` or more times. + + -Creates a function that memoizes the result of `func`. If `resolver` is -provided, it determines the cache key for storing the result based on the -arguments provided to the memoized function. By default, the first argument -provided to the memoized function is used as the map cache key -**Note:** The cache is exposed as the `cache` property on the memoized -function. Its creation may be customized by replacing the `_.memoize.Cache` -constructor with one whose instances implement the -[`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) -method interface of `clear`, `delete`, `get`, `has`, and `set`. **Arguments:** -@param callable $func The function to have its output memoized. +@param int $n The number of calls before `func` is invoked. -@param callable $resolver The function to resolve the cache key. +@param Callable $func The function to restrict. **Return:** -@return callable Returns the new memoized function. +@return Callable Returns the new restricted function. Example: ```php 1, 'b' => 2]; -$other = ['c' => 3, 'd' => 4]; +$saves = ['profile', 'settings']; -$values = memoize('_\values'); -$values($object); -// => [1, 2] +$done = after(count($saves), function() { +echo 'done saving!'; +}); -$values($other); -// => [3, 4] +forEach($saves, function($type) use($done) { +asyncSave([ 'type' => $type, 'complete' => $done ]); +}); +// => Prints 'done saving!' after the two async saves have completed. -$object['a'] = 2; -$values($object); -// => [1, 2] +``` +### ary -// Modify the result cache. -$values->cache->set($object, ['a', 'b']); -$values($object); -// => ['a', 'b'] +Creates a function that invokes `func`, with up to `n` arguments, +ignoring any additional arguments. -``` -### negate -Creates a function that negates the result of the predicate `func` **Arguments:** -@param callable $predicate The predicate to negate. +@param callable $func The function to cap arguments for. + +@param int $n The arity cap. **Return:** -@return callable Returns the new negated function. +@return Callable Returns the new capped function. Example: ```php [6, 8, 10] -filter([1, 2, 3, 4, 5, 6], negate($isEven)); -// => [1, 3, 5] ``` -## Lang +### before + +Creates a function that invokes `func`, with the arguments +of the created function, while it's called less than `n` times. Subsequent +calls to the created function return the result of the last `func` invocation. -### eq -Performs a comparison between two values to determine if they are equivalent. **Arguments:** -@param mixed $value The value to compare. +@param int $n The number of calls at which `func` is no longer invoked. -@param mixed $other The other value to compare. +@param callable $func The function to restrict. **Return:** -@return bool Returns `true` if the values are equivalent, else `false`. +@return callable Returns the new restricted function. Example: ```php 1]; -$other = (object) ['a' => 1]; +$users = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +$result = uniqBy(map($users, before(5, [$repository, 'find'])), 'id') +// => Fetch up to 4 results. -eq($object, $object); -// => true +``` +### bind -eq($object, $other); +Creates a function that invokes `func` with the `this` binding of `object` +and `partials` prepended to the arguments it receives. + + + + +**Arguments:** + +@param callable $function The function to bind. + +@param (object | mixed) $object The `object` binding of `func`. + +@param array $partials The arguments to be partially applied. + + + +**Return:** + +@return callable Returns the new bound function. + +Example: +```php +user . $punctuation; +} + +$object = $object = new class { +public $user = 'fred'; +}; + +$bound = bind('greet', $object, 'hi'); +$bound('!'); +// => 'hi fred!' + +``` +### bindKey + +Creates a function that invokes the method `$function` of `$object` with `$partials` +prepended to the arguments it receives. + +This method differs from `bind` by allowing bound functions to reference +methods that may be redefined or don't yet exist + + + + +**Arguments:** + +@param object $object The object to invoke the method on. + +@param string $function The name of the method. + +@param array $partials The arguments to be partially applied. + + + +**Return:** + +@return callable Returns the new bound function. + +Example: +```php +user.$punctuation; +} +}; + +$bound = bindKey($object, 'greet', 'hi'); +$bound('!'); +// => 'hi fred!' + +``` +### curry + +Creates a function that accepts arguments of `func` and either invokes +`func` returning its result, if at least `arity` number of arguments have +been provided, or returns a function that accepts the remaining `func` +arguments, and so on. The arity of `func` may be specified if `func.length` +is not sufficient. + +The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, +may be used as a placeholder for provided arguments. + +**Note:** This method doesn't set the "length" property of curried functions. + + + + +**Arguments:** + +@param callable $func The function to curry. + +@param (int | null) $arity The arity of `func`. + + + +**Return:** + +@return callable Returns the new curried function. + +Example: +```php + [1, 2, 3] + +$curried(1, 2)(3); +// => [1, 2, 3] + +$curried(1, 2, 3); +// => [1, 2, 3] + +// Curried with placeholders. +$curried(1)(_, 3)(2); +// => [1, 2, 3] + +``` +### delay + +Invokes `func` after `wait` milliseconds. Any additional arguments are +provided to `func` when it's invoked. + + + + +**Arguments:** + +@param callable $func The function to delay. + +@param int $wait The number of milliseconds to delay invocation. + +@param array $args + + + +**Return:** + +@return int the timer id. + +Example: +```php + Echo 'later' after one second. + +``` +### flip + +Creates a function that invokes `func` with arguments reversed. + + + + + +**Arguments:** + +@param callable $func The function to flip arguments for. + + + +**Return:** + +@return callable Returns the new flipped function. + +Example: +```php + ['d', 'c', 'b', 'a'] + +``` +### memoize + +Creates a function that memoizes the result of `func`. If `resolver` is +provided, it determines the cache key for storing the result based on the +arguments provided to the memoized function. By default, the first argument +provided to the memoized function is used as the map cache key + +**Note:** The cache is exposed as the `cache` property on the memoized +function. Its creation may be customized by replacing the `_.memoize.Cache` +constructor with one whose instances implement the +[`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) +method interface of `clear`, `delete`, `get`, `has`, and `set`. + + + + + +**Arguments:** + +@param callable $func The function to have its output memoized. + +@param (callable | null) $resolver The function to resolve the cache key. + + + +**Return:** + +@return callable Returns the new memoized function. + +Example: +```php + 1, 'b' => 2]; +$other = ['c' => 3, 'd' => 4]; + +$values = memoize('_\values'); +$values($object); +// => [1, 2] + +$values($other); +// => [3, 4] + +$object['a'] = 2; +$values($object); +// => [1, 2] + +// Modify the result cache. +$values->cache->set($object, ['a', 'b']); +$values($object); +// => ['a', 'b'] + +``` +### negate + +Creates a function that negates the result of the predicate `func` + + + + + +**Arguments:** + +@param callable $predicate The predicate to negate. + + + +**Return:** + +@return callable Returns the new negated function. + +Example: +```php + [1, 3, 5] + +``` +### once + +Creates a function that is restricted to invoking `func` once. Repeat calls +to the function return the value of the first invocation. The `func` is +invoked with the arguments of the created function. + + + + + +**Arguments:** + +@param callable $func The function to restrict. + + + +**Return:** + +@return callable the new restricted function. + +Example: +```php + `createApplication` is invoked once + +``` +### overArgs + +Creates a function that invokes `func` with its arguments transformed. + + + + + +**Arguments:** + +@param callable $func The function to wrap. + +@param callable[] $transforms The argument transforms. + + + +**Return:** + +@return callable the new function. + +Example: +```php + [81, 6] + +$func(10, 5); +// => [100, 10] + +``` +### partial + +Creates a function that invokes `func` with `partials` prepended to the +arguments it receives. + + + + + +**Arguments:** + +@param callable $func The function to partially apply arguments to. + +@param array $partials The arguments to be partially applied. + + + +**Return:** + +@return callable Returns the new partially applied function. + +Example: +```php + 'hello fred' + +``` +### rest + +Creates a function that invokes `func` with the `this` binding of the +created function and arguments from `start` and beyond provided as +an array. + + + + + +**Arguments:** + +@param callable $func The function to apply a rest parameter to. + +@param (int | null) $start The start position of the rest parameter. + + + +**Return:** + +@return callable Returns the new function. + +Example: +```php + 1 ? ', & ' : '') . last($names); +}); + +$say('hello', 'fred', 'barney', 'pebbles'); +// => 'hello fred, barney, & pebbles' + +``` +### spread + +Creates a function that invokes `func` with the `this` binding of the +create function and an array of arguments much like +[`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + +**Note:** This method is based on the +[spread operator](https://mdn.io/spread_operator). + + + + + +**Arguments:** + +@param callable $func The function to spread arguments over. + +@param int $start The start position of the spread. + + + +**Return:** + +@return callable Returns the new function. + +Example: +```php + 'fred says hello' + +``` +### unary + +Creates a function that accepts up to one argument, ignoring any +additional arguments. + + + + +**Arguments:** + +@param callable $func The function to cap arguments for. + + + +**Return:** + +@return callable the new capped function. + +Example: +```php + [6, 8, 10] + +``` +### wrap + +Creates a function that provides `value` to `wrapper` as its first +argument. Any additional arguments provided to the function are appended +to those provided to the `wrapper`. + + + + +**Arguments:** + +@param mixed $value The value to wrap. + +@param callable $wrapper The wrapper function. + + + +**Return:** + +@return callable the new function. + +Example: +```php +' . $func($text) . '

'; +}); + +$p('fred, barney, & pebbles'); +// => '

fred, barney, & pebbles

' + +``` +## Lang + +### eq + +Performs a comparison between two values to determine if they are equivalent. + + + + +**Arguments:** + +@param mixed $value The value to compare. + +@param mixed $other The other value to compare. + + + +**Return:** + +@return boolean Returns `true` if the values are equivalent, else `false`. + +Example: +```php + 1]; +$other = (object) ['a' => 1]; + +eq($object, $object); +// => true + +eq($object, $other); // => false eq('a', 'a'); @@ -2698,6 +3416,10 @@ DateTime objects, exception objects, SPLObjectStorage, numbers, strings, typed arrays, resources, DOM Nodes. objects are compared by their own, not inherited, enumerable properties. + + + + **Arguments:** @param mixed $value The value to compare. @@ -2732,6 +3454,8 @@ Checks if `value` is an `\Exception`, `\ParseError`, \Error`, \Throwable`, \Soap + + **Arguments:** @param mixed $value The value to check. @@ -2740,7 +3464,7 @@ Checks if `value` is an `\Exception`, `\ParseError`, \Error`, \Throwable`, \Soap **Return:** -@return bool Returns `true` if `value` is an error object, else `false`. +@return boolean Returns `true` if `value` is an error object, else `false`. Example: ```php @@ -2752,6 +3476,7 @@ isError(new \Exception()) isError(\Exception::Class) // => false + ``` ## Math @@ -2761,17 +3486,19 @@ Adds two numbers. + + **Arguments:** -@param int|float|string $augend The first number in an addition. +@param (int | float | string) $augend The first number in an addition. -@param int|float|string $addend The second number in an addition. +@param (int | float | string) $addend The second number in an addition. **Return:** -@return int|float Returns the total. +@return (int | float) Returns the total. Example: ```php @@ -2788,15 +3515,16 @@ Computes the maximum value of `array`. If `array` is empty or falsey, null is re + **Arguments:** -@param array $ array The array to iterate over. +@param (array | null) $array The array to iterate over. **Return:** -@return int|null Returns the maximum value. +@return (int | null) Returns the maximum value. Example: ```php @@ -2818,11 +3546,12 @@ the value is ranked. The iteratee is invoked with one argument: (value). + **Arguments:** @param array $array The array to iterate over. -@param callable|string $iteratee The iteratee invoked per element. +@param (callable | string) $iteratee The iteratee invoked per element. @@ -2843,6 +3572,7 @@ maxBy($objects, function($o) { return $o['n']; }); // The `property` iteratee shorthand. maxBy($objects, 'n'); // => ['n' => 2] + ``` ## Number @@ -2852,13 +3582,15 @@ Clamps `number` within the inclusive `lower` and `upper` bounds. + + **Arguments:** -@param int $ number The number to clamp. +@param int $number The number to clamp. -@param int $ lower The lower bound. +@param int $lower The lower bound. -@param int $ upper The upper bound. +@param int $upper The upper bound. @@ -2882,13 +3614,16 @@ clamp(10, -5, 5) Checks if `number` is between `start` and up to, but not including, `end`. If `end` is not specified, it's set to `start` with `start` then set to `0`. - If `start` is greater than `end` the params are swapped to support negative ranges. + + + + **Arguments:** -@param float $ number The number to check. +@param float $number The number to check. @param float $start The start of the range. @@ -2898,7 +3633,7 @@ negative ranges. **Return:** -@return bool Returns `true` if `number` is in the range, else `false`. +@return boolean Returns `true` if `number` is in the range, else `false`. Example: ```php @@ -2930,29 +3665,33 @@ inRange(-3, -2, -6) ### random Produces a random number between the inclusive `lower` and `upper` bounds. - If only one argument is provided a number between `0` and the given number is returned. If `floating` is `true`, or either `lower` or `upper` are floats, a floating-point number is returned instead of an integer. + + + + **Arguments:** -@param int|float $lower The lower bound. +@param (int | float | bool) $lower The lower bound. -@param int|float $upper The upper bound. +@param (int | float | bool) $upper The upper bound. -@param bool $floating Specify returning a floating-point number. +@param (bool | null) $floating Specify returning a floating-point number. **Return:** -@return int|float Returns the random number. +@return (int | float) Returns the random number. Example: ```php an integer between 0 and 5 @@ -2964,6 +3703,7 @@ random(5, true) random(1.2, 5.2) // => a floating-point number between 1.2 and 5.2 + ``` ## Object @@ -2973,11 +3713,12 @@ Creates an object composed of the picked `object` properties. + **Arguments:** @param object $object The source object. -@param string|string[] $paths The property paths to pick. +@param (string | string[]) $paths The property paths to pick. @@ -2989,10 +3730,12 @@ Example: ```php 1, 'b' => '2', 'c' => 3]; pick($object, ['a', 'c']); // => (object) ['a' => 1, 'c' => 3] + ``` ### pickBy @@ -3001,9 +3744,10 @@ truthy for. The predicate is invoked with two arguments: (value, key). + **Arguments:** -@param object $object The source object. +@param (object | null) $object The source object. @param callable $predicate The function invoked per property. @@ -3017,10 +3761,54 @@ Example: ```php 1, 'b' => 'abc', 'c' => 3]; pickBy(object, 'is_numeric'); // => (object) ['a' => 1, 'c' => 3] + +``` +## Seq + +### chain + +Creates a `lodash` wrapper instance that wraps `value` with explicit method +chain sequences enabled. The result of such sequences must be unwrapped +with `->value()`. + + + + +**Arguments:** + +@param mixed $value The value to wrap. + + + +**Return:** + +@return \_ Returns the new `lodash` wrapper instance. + +Example: +```php + 'barney', 'age' => 36], +['user' => 'fred', 'age' => 40], +['user' => 'pebbles', 'age' => 1 ], +]; + +$youngest = chain($users) +->sortBy('age') +->map(function($o) { +return $o['user'] . ' is ' . $o['age']; +}) +->head() +->value(); +// => 'pebbles is 1' + ``` ## String @@ -3030,6 +3818,8 @@ Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + + **Arguments:** @param string $string The string to convert. @@ -3062,6 +3852,7 @@ to lower case. + **Arguments:** @param string $string The string to capitalize. @@ -3091,6 +3882,8 @@ letters to basic Latin letters and removing + + **Arguments:** @param string $string The string to deburr. @@ -3105,8 +3898,10 @@ Example: ```php 'deja vu' + ``` ### endsWith @@ -3114,6 +3909,7 @@ Checks if `string` ends with the given target string. + **Arguments:** @param string $string The string to inspect. @@ -3126,7 +3922,7 @@ Checks if `string` ends with the given target string. **Return:** -@return bool Returns `true` if `string` ends with `target`, else `false`. +@return boolean Returns `true` if `string` ends with `target`, else `false`. Example: ```php @@ -3148,6 +3944,7 @@ endsWith('abc', 'b', 2) Converts the characters "&", "<", ">", '"', and "'" in `string` to their corresponding HTML entities. + Though the ">" character is escaped for symmetry, characters like ">" and "/" don't need escaping in HTML and have no special meaning unless they're part of a tag or unquoted attribute value. See @@ -3158,6 +3955,9 @@ When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) to reduce XSS vectors. + + + **Arguments:** @param string $string The string to escape. @@ -3184,6 +3984,7 @@ Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + **Arguments:** @param string $string The string to escape. @@ -3210,6 +4011,7 @@ Converts `string` to + **Arguments:** @param string $string The string to convert. @@ -3241,6 +4043,7 @@ Converts `string`, as space separated words, to lower case. + **Arguments:** @param string $string The string to convert. @@ -3272,6 +4075,7 @@ Converts the first character of `string` to lower case. + **Arguments:** @param string $string The string to convert. @@ -3297,9 +4101,12 @@ lowerFirst('FRED') ### pad Pads `string` on the left and right sides if it's shorter than `length`. - Padding characters are truncated if they can't be evenly divided by `length`. + + + + **Arguments:** @param string $string The string to pad. @@ -3336,6 +4143,8 @@ characters are truncated if they exceed `length`. + + **Arguments:** @param string $string The string to pad. @@ -3372,6 +4181,7 @@ characters are truncated if they exceed `length`. +s **Arguments:** @param string $string ='' The string to pad. @@ -3399,7 +4209,7 @@ padStart('abc', 6, '_-') padStart('abc', 2) // => 'abc' -s + ``` ### parseInt @@ -3410,9 +4220,13 @@ hexadecimal, in which case a `radix` of `16` is used. **Note:** This method uses PHP's built-in integer casting, which does not necessarily align with the [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + + + + **Arguments:** -@param int|float|string $string The string to convert. +@param (int | float | string) $string The string to convert. @param int $radix The radix to interpret `string` by. @@ -3437,6 +4251,8 @@ Repeats the given string `n` times. + + **Arguments:** @param string $string The string to repeat. @@ -3471,13 +4287,17 @@ Replaces matches for `pattern` in `string` with `replacement`. **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace). + + + + **Arguments:** @param string $string The string to modify. @param string $pattern The pattern to replace. -@param callable|string $ replacement The match replacement. +@param (callable | string) $replacement The match replacement. @@ -3500,7 +4320,6 @@ Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). - **Arguments:** @param string $string The string to convert. @@ -3515,6 +4334,7 @@ Example: ```php 'foo_bar' @@ -3523,6 +4343,7 @@ snakeCase('fooBar') snakeCase('--FOO-BAR--') // => 'foo_bar' + ``` ### split @@ -3531,9 +4352,12 @@ Splits `string` by `separator`. **Note:** This method is based on [`String#split`](https://mdn.io/String/split). + + + **Arguments:** -@param string $ string The string to split. +@param string $string The string to split. @param string $separator The separator pattern to split by. @@ -3561,6 +4385,7 @@ Converts `string` to + **Arguments:** @param string $string The string to convert. @@ -3592,6 +4417,7 @@ Checks if `string` starts with the given target string. + **Arguments:** @param string $string The string to inspect. @@ -3604,7 +4430,7 @@ Checks if `string` starts with the given target string. **Return:** -@return bool Returns `true` if `string` starts with `target`, else `false`. +@return boolean Returns `true` if `string` starts with `target`, else `false`. Example: ```php @@ -3630,16 +4456,18 @@ properties may be accessed as free variables in the template. If a setting object is given, it takes precedence over `$templateSettings` values. +RegExp $options['escape'] = _::$templateSettings['escape'] The HTML "escape" delimiter. +RegExp $options['evaluate'] = _::$templateSettings['evaluate'] The "evaluate" delimiter. +array $options['imports'] = _::$templateSettings['imports'] An object to import into the template as free variables. +RegExp $options['interpolate'] = _::$templateSettings['interpolate'] The "interpolate" delimiter. + + **Arguments:** @param string $string The template string. @param array $options The options array. -RegExp $options['escape'] = _::$templateSettings['escape'] The HTML "escape" delimiter. -RegExp $options['evaluate'] = _::$templateSettings['evaluate'] The "evaluate" delimiter. -array $options['imports'] = _::$templateSettings['imports'] An object to import into the template as free variables. -RegExp $options['interpolate'] = _::$templateSettings['interpolate'] The "interpolate" delimiter. @@ -3699,6 +4527,7 @@ Converts `string`, as a whole, to lower case + **Arguments:** @param string $string The string to convert. @@ -3730,6 +4559,7 @@ Converts `string`, as a whole, to upper case + **Arguments:** @param string $string The string to convert. @@ -3753,6 +4583,7 @@ toUpper('fooBar') toUpper('__foo_bar__') // => '__FOO_BAR__' + ``` ### trim @@ -3760,6 +4591,7 @@ Removes leading and trailing whitespace or specified characters from `string`. + **Arguments:** @param string $string The string to trim. @@ -3790,6 +4622,7 @@ Removes trailing whitespace or specified characters from `string`. + **Arguments:** @param string $string The string to trim. @@ -3806,11 +4639,13 @@ Example: ```php ' abc' trimEnd('-_-abc-_-', '_-') // => '-_-abc' + ``` ### trimStart @@ -3818,6 +4653,7 @@ Removes leading whitespace or specified characters from `string`. + **Arguments:** @param string $string The string to trim. @@ -3845,18 +4681,21 @@ trimStart('-_-abc-_-', '_-') ### truncate Truncates `string` if it's longer than the given maximum string length. - The last characters of the truncated string are replaced with the omission string which defaults to "...". + +length = 30 The maximum string length. +omission = '...' The string to indicate text is omitted. +separator The separator pattern to truncate to. + + + **Arguments:** @param string $string The string to truncate. @param array $options The options object. -length = 30 The maximum string length. -omission = '...' The string to indicate text is omitted. -separator The separator pattern to truncate to. @@ -3873,19 +4712,19 @@ truncate('hi-diddly-ho there, neighborino') // => 'hi-diddly-ho there, neighbo...' truncate('hi-diddly-ho there, neighborino', [ - 'length' => 24, - 'separator' => ' ' +'length' => 24, +'separator' => ' ' ]) // => 'hi-diddly-ho there,...' truncate('hi-diddly-ho there, neighborino', [ - 'length' => 24, - 'separator' => '/,? +/' +'length' => 24, +'separator' => '/,? +/' ]) // => 'hi-diddly-ho there...' truncate('hi-diddly-ho there, neighborino', [ - 'omission' => ' [...]' +'omission' => ' [...]' ]) // => 'hi-diddly-ho there, neig [...]' @@ -3898,6 +4737,7 @@ their corresponding characters. + **Arguments:** @param string $string The string to unescape. @@ -3922,7 +4762,6 @@ unescape('fred, barney, & pebbles') Converts `string`, as space separated words, to upper case. - **Arguments:** @param string $string The string to convert. @@ -3954,6 +4793,7 @@ Converts the first character of `string` to upper case. + **Arguments:** @param string $string The string to convert. @@ -3982,6 +4822,8 @@ Splits `string` into an array of its words. + + **Arguments:** @param string $string The string to inspect. @@ -4015,17 +4857,19 @@ object. Any additional arguments are provided to `func` when it's invoked. + +s **Arguments:** @param callable $func The function to attempt. -@param array $args The arguments to invoke `func` with. +@param array $args The arguments to invoke `func` with. **Return:** -@return mixed|\Throwable Returns the `func` result or error object. +@return (mixed | \Throwable) Returns the `func` result or error object. Example: ```php @@ -4034,13 +4878,13 @@ Example: // Avoid throwing errors for invalid PDO data source. $elements = attempt(function () { - new \PDO(null); +new \PDO(null); }); if (isError($elements)) { - $elements = []; +$elements = []; } -s + ``` ### identity @@ -4048,6 +4892,7 @@ This method returns the first argument it receives. + **Arguments:** @param mixed $value Any value. @@ -4075,9 +4920,10 @@ Creates a function that returns the value at `path` of a given object. + **Arguments:** -@param array|string $ path The path of the property to get. +@param (array | string) $path The path of the property to get. @@ -4091,8 +4937,8 @@ Example: use function _\property; $objects = [ - [ 'a' => [ 'b' => 2 ] ], - [ 'a' => [ 'b' => 1 ] ] +[ 'a' => [ 'b' => 2 ] ], +[ 'a' => [ 'b' => 1 ] ] ]; map($objects, property('a.b')); From 6e108fb1291f9b417901748333a97da242ec132e Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 23:44:45 +0200 Subject: [PATCH 118/159] Update readme generation script to use phpstan/phpdoc-parser --- bin/generate-readme | 39 +++++++++++++++++++++++++-------------- composer.json | 3 ++- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/bin/generate-readme b/bin/generate-readme index d2aea5f..a3d3419 100755 --- a/bin/generate-readme +++ b/bin/generate-readme @@ -1,11 +1,18 @@ #!/usr/bin/env php create($reflection->getDocComment()); + $docblock = $parser->parse(new TokenIterator((new Lexer())->tokenize($reflection->getDocComment()))); - $category = (string) $docblock->getTagsByName('category')[0]; + $category = (string) current($docblock->getTagsByName('@category'))->value; $readme[$category][$function] = ''; $readme[$category][$function] .= "### $function\n\n"; - $readme[$category][$function] .= $docblock->getSummary().PHP_EOL.PHP_EOL; - $readme[$category][$function] .= $docblock->getDescription().PHP_EOL.PHP_EOL; + + foreach (array_filter($docblock->children, function (PhpDocChildNode $child): bool { + return $child instanceof PhpDocTextNode; + }) as $text) { + $readme[$category][$function] .= (string) $text.PHP_EOL; + } $readme[$category][$function] .= "**Arguments:**\n\n"; - foreach ($docblock->getTagsByName('param') as $param) { - $readme[$category][$function] .= $param->render().PHP_EOL.PHP_EOL; + foreach ($docblock->getTagsByName('@param') as $param) { + $readme[$category][$function] .= (string) $param.PHP_EOL.PHP_EOL; } $readme[$category][$function] .= PHP_EOL.PHP_EOL; $readme[$category][$function] .= "**Return:**\n\n"; - $readme[$category][$function] .= $docblock->getTagsByName('return')[0]->render(); + $readme[$category][$function] .= (string) current($docblock->getTagsByName('@return')); $readme[$category][$function] .= PHP_EOL.PHP_EOL; - if ($docblock->hasTag('example')) { + if (\preg_match('#((.|\n)*?)#', $readme[$category][$function], $matches)) { + + $readme[$category][$function] = str_replace($matches[0], '', $readme[$category][$function]); - $example = str_replace(['', ''], '', $docblock->getTagsByName('example')[0] ?? ''); + $example = $matches[1]; - if ($example) { - $readme[$category][$function] .= "Example:\n```php\n Date: Mon, 10 Dec 2018 23:51:02 +0200 Subject: [PATCH 119/159] Update vendor-bin dependencies --- vendor-bin/php-cs-fixer/composer.lock | 256 ++++++++++++++++---------- vendor-bin/phpstan/composer.lock | 209 ++++++++++++++------- vendor-bin/phpunit/composer.lock | 95 +++++----- 3 files changed, 351 insertions(+), 209 deletions(-) diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock index 957362a..0145aaa 100644 --- a/vendor-bin/php-cs-fixer/composer.lock +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -70,16 +70,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.2.1", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373" + "reference": "dc523135366eb68f22268d069ea7749486458562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e37cbd80da64afe314c72de8d2d2fec0e40d9373", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", + "reference": "dc523135366eb68f22268d069ea7749486458562", "shasum": "" }, "require": { @@ -95,7 +95,7 @@ "Composer\\XdebugHandler\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -110,7 +110,7 @@ "Xdebug", "performance" ], - "time": "2018-08-23T12:00:19+00:00" + "time": "2018-11-29T10:59:02+00:00" }, { "name": "doctrine/annotations", @@ -236,16 +236,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.13.0", + "version": "v2.13.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "7136aa4e0c5f912e8af82383775460d906168a10" + "reference": "54814c62d5beef3ba55297b9b3186ed8b8a1b161" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7136aa4e0c5f912e8af82383775460d906168a10", - "reference": "7136aa4e0c5f912e8af82383775460d906168a10", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/54814c62d5beef3ba55297b9b3186ed8b8a1b161", + "reference": "54814c62d5beef3ba55297b9b3186ed8b8a1b161", "shasum": "" }, "require": { @@ -256,7 +256,7 @@ "ext-tokenizer": "*", "php": "^5.6 || >=7.0 <7.3", "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.2 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6", "symfony/event-dispatcher": "^3.0 || ^4.0", "symfony/filesystem": "^3.0 || ^4.0", "symfony/finder": "^3.0 || ^4.0", @@ -292,11 +292,6 @@ "php-cs-fixer" ], "type": "application", - "extra": { - "branch-alias": { - "dev-master": "2.13-dev" - } - }, "autoload": { "psr-4": { "PhpCsFixer\\": "src/" @@ -313,7 +308,7 @@ "tests/TestCase.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -328,7 +323,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2018-08-23T13:15:44+00:00" + "time": "2018-10-21T00:32:10+00:00" }, { "name": "paragonie/random_compat", @@ -428,16 +423,16 @@ }, { "name": "psr/log", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { @@ -454,7 +449,7 @@ "Psr\\Log\\": "Psr/Log/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -471,24 +466,25 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2018-11-20T15:27:04+00:00" }, { "name": "symfony/console", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f" + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f", - "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f", + "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -512,7 +508,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -523,7 +519,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -539,24 +535,93 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-11-27T07:40:44+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://repo.packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/921f49c3158a276d27c0d770a5a347a3b718b328", + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -575,7 +640,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -586,7 +651,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -602,20 +667,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-07-26T09:10:45+00:00" + "time": "2018-12-01T08:52:38+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e" + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", - "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2f4c8b999b3b7cadb2a69390b01af70886753710", + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710", "shasum": "" }, "require": { @@ -625,7 +690,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -636,7 +701,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -652,20 +717,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-08-18T16:52:46+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/finder", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068" + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068", - "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", "shasum": "" }, "require": { @@ -674,7 +739,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -685,7 +750,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -701,20 +766,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "1913f1962477cdbb13df951f8147d5da1fe2412c" + "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/1913f1962477cdbb13df951f8147d5da1fe2412c", - "reference": "1913f1962477cdbb13df951f8147d5da1fe2412c", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", + "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", "shasum": "" }, "require": { @@ -723,7 +788,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -734,7 +799,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -755,11 +820,11 @@ "configuration", "options" ], - "time": "2018-07-26T08:55:25+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -791,7 +856,7 @@ "bootstrap.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -817,16 +882,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -849,7 +914,7 @@ "bootstrap.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -872,20 +937,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", "shasum": "" }, "require": { @@ -909,7 +974,7 @@ "Resources/stubs" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -931,20 +996,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T06:26:08+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", "shasum": "" }, "require": { @@ -964,7 +1029,7 @@ "bootstrap.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -986,20 +1051,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/process", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "86cdb930a6a855b0ab35fb60c1504cb36184f843" + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/86cdb930a6a855b0ab35fb60c1504cb36184f843", - "reference": "86cdb930a6a855b0ab35fb60c1504cb36184f843", + "url": "https://api.github.com/repos/symfony/process/zipball/2b341009ccec76837a7f46f59641b431e4d4c2b0", + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0", "shasum": "" }, "require": { @@ -1008,7 +1073,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1019,7 +1084,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -1035,29 +1100,30 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-08-03T11:13:38+00:00" + "time": "2018-11-20T16:22:05+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "966c982df3cca41324253dc0c7ffe76b6076b705" + "reference": "ec076716412274e51f8a7ea675d9515e5c311123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/966c982df3cca41324253dc0c7ffe76b6076b705", - "reference": "966c982df3cca41324253dc0c7ffe76b6076b705", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/ec076716412274e51f8a7ea675d9515e5c311123", + "reference": "ec076716412274e51f8a7ea675d9515e5c311123", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1068,7 +1134,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -1084,7 +1150,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:00:49+00:00" + "time": "2018-11-11T19:52:12+00:00" } ], "packages-dev": [], diff --git a/vendor-bin/phpstan/composer.lock b/vendor-bin/phpstan/composer.lock index 13d5730..0ff13a3 100644 --- a/vendor-bin/phpstan/composer.lock +++ b/vendor-bin/phpstan/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "composer/xdebug-handler", - "version": "1.2.1", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373" + "reference": "dc523135366eb68f22268d069ea7749486458562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e37cbd80da64afe314c72de8d2d2fec0e40d9373", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", + "reference": "dc523135366eb68f22268d069ea7749486458562", "shasum": "" }, "require": { @@ -33,7 +33,7 @@ "Composer\\XdebugHandler\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -48,7 +48,7 @@ "Xdebug", "performance" ], - "time": "2018-08-23T12:00:19+00:00" + "time": "2018-11-29T10:59:02+00:00" }, { "name": "jean85/pretty-package-versions", @@ -179,16 +179,16 @@ }, { "name": "nette/di", - "version": "v2.4.13", + "version": "v2.4.14", "source": { "type": "git", "url": "https://github.com/nette/di.git", - "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca" + "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", - "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "url": "https://api.github.com/repos/nette/di/zipball/923da3e2c0aa53162ef455472c0ac7787b096c5a", + "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a", "shasum": "" }, "require": { @@ -217,7 +217,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", @@ -244,7 +244,7 @@ "nette", "static" ], - "time": "2018-06-11T08:46:01+00:00" + "time": "2018-09-17T15:47:40+00:00" }, { "name": "nette/finder", @@ -433,16 +433,16 @@ }, { "name": "nette/robot-loader", - "version": "v3.0.4", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", - "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392" + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/3cf88781a05e0bf4618ae605361afcbaa4d5b392", - "reference": "3cf88781a05e0bf4618ae605361afcbaa4d5b392", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4", + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4", "shasum": "" }, "require": { @@ -461,7 +461,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -469,7 +469,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", @@ -494,20 +494,20 @@ "nette", "trait" ], - "time": "2018-06-22T09:34:04+00:00" + "time": "2018-08-13T14:19:06+00:00" }, { "name": "nette/utils", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5" + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/183069866dc477fcfbac393ed486aaa6d93d19a5", - "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5", + "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", "shasum": "" }, "require": { @@ -542,7 +542,7 @@ "src/loader.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause", "GPL-2.0", @@ -576,20 +576,20 @@ "utility", "validation" ], - "time": "2018-05-02T17:16:08+00:00" + "time": "2018-09-18T10:22:16+00:00" }, { "name": "nikic/php-parser", - "version": "v4.0.3", + "version": "v4.1.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d" + "reference": "d0230c5c77a7e3cfa69446febf340978540958c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd088dc940a418f09cda079a9b5c7c478890fb8d", - "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/d0230c5c77a7e3cfa69446febf340978540958c0", + "reference": "d0230c5c77a7e3cfa69446febf340978540958c0", "shasum": "" }, "require": { @@ -605,7 +605,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -613,7 +613,7 @@ "PhpParser\\": "lib/PhpParser" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -627,7 +627,7 @@ "parser", "php" ], - "time": "2018-07-15T17:25:16+00:00" + "time": "2018-10-10T09:24:14+00:00" }, { "name": "ocramius/package-versions", @@ -726,20 +726,20 @@ }, { "name": "phpstan/phpstan", - "version": "0.10.3", + "version": "0.10.6", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0" + "reference": "f0252a5ab6b4a293fb25f218d9c64386f272280f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0", - "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f0252a5ab6b4a293fb25f218d9c64386f272280f", + "reference": "f0252a5ab6b4a293fb25f218d9c64386f272280f", "shasum": "" }, "require": { - "composer/xdebug-handler": "^1.0", + "composer/xdebug-handler": "^1.3.0", "jean85/pretty-package-versions": "^1.0.3", "nette/bootstrap": "^2.4 || ^3.0", "nette/di": "^2.4.7 || ^3.0", @@ -751,23 +751,27 @@ "symfony/console": "~3.2 || ~4.0", "symfony/finder": "~3.2 || ~4.0" }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, "require-dev": { "brianium/paratest": "^2.0", - "consistence/coding-standard": "^3.3", + "consistence/coding-standard": "^3.5", "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", "ext-gd": "*", "ext-intl": "*", "ext-mysqli": "*", "ext-zip": "*", "jakub-onderka/php-parallel-lint": "^1.0", - "localheinz/composer-normalize": "~0.8.0", + "localheinz/composer-normalize": "~0.9.0", "phing/phing": "^2.16.0", "phpstan/phpstan-deprecation-rules": "^0.10.2", "phpstan/phpstan-php-parser": "^0.10", "phpstan/phpstan-phpunit": "^0.10", "phpstan/phpstan-strict-rules": "^0.10", "phpunit/phpunit": "^7.0", - "slevomat/coding-standard": "^4.6.2" + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" }, "bin": [ "bin/phpstan" @@ -786,25 +790,25 @@ ] } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2018-08-12T15:14:21+00:00" + "time": "2018-12-04T07:28:04+00:00" }, { "name": "psr/log", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { @@ -821,7 +825,7 @@ "Psr\\Log\\": "Psr/Log/" } }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -838,24 +842,25 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2018-11-20T15:27:04+00:00" }, { "name": "symfony/console", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f" + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f", - "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f", + "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -879,7 +884,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -890,7 +895,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -906,20 +911,88 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-11-27T07:40:44+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://repo.packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/finder", - "version": "v4.1.4", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068" + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068", - "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068", + "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", "shasum": "" }, "require": { @@ -928,7 +1001,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -939,7 +1012,7 @@ "/Tests/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -955,20 +1028,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -991,7 +1064,7 @@ "bootstrap.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "MIT" ], @@ -1014,7 +1087,7 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" } ], "packages-dev": [], diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock index 5542808..1fbb7f0 100644 --- a/vendor-bin/phpunit/composer.lock +++ b/vendor-bin/phpunit/composer.lock @@ -427,16 +427,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.0.7", + "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", - "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "shasum": "" }, "require": { @@ -447,7 +447,7 @@ "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1", + "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, @@ -460,7 +460,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-master": "6.1-dev" } }, "autoload": { @@ -468,7 +468,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -486,25 +486,28 @@ "testing", "xunit" ], - "time": "2018-06-01T07:51:50+00:00" + "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" + "reference": "050bedf145a257b1ff02746c31894800e5122946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", - "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", "shasum": "" }, "require": { "php": "^7.1" }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, "type": "library", "extra": { "branch-alias": { @@ -516,7 +519,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -533,7 +536,7 @@ "filesystem", "iterator" ], - "time": "2018-06-11T11:44:00+00:00" + "time": "2018-09-13T20:33:42+00:00" }, { "name": "phpunit/php-text-template", @@ -627,16 +630,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", "shasum": "" }, "require": { @@ -657,7 +660,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -672,20 +675,20 @@ "keywords": [ "tokenizer" ], - "time": "2018-02-01T13:16:43+00:00" + "time": "2018-10-30T05:52:18+00:00" }, { "name": "phpunit/phpunit", - "version": "7.3.2", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8" + "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34705f81bddc3f505b9599a2ef96e2b4315ba9b8", - "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/520723129e2b3fc1dc4c0953e43c9d40e1ecb352", + "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352", "shasum": "" }, "require": { @@ -706,11 +709,11 @@ "phpunit/php-timer": "^2.0", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1", + "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", + "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, "conflict": { @@ -730,7 +733,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.3-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -738,7 +741,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -756,7 +759,7 @@ "testing", "xunit" ], - "time": "2018-08-22T06:39:21+00:00" + "time": "2018-12-07T07:08:12+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -925,28 +928,28 @@ }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/febd209a219cea7b56ad799b30ebbea34b71eb8f", + "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^7.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -954,7 +957,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -971,7 +974,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2018-11-25T09:31:21+00:00" }, { "name": "sebastian/exporter", @@ -1238,25 +1241,25 @@ }, { "name": "sebastian/resource-operations", - "version": "1.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1264,7 +1267,7 @@ "src/" ] }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://repo.packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -1276,7 +1279,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2018-10-04T04:07:39+00:00" }, { "name": "sebastian/version", From b9b10cc2c1a148be36f031e66fe7ea9b42e210b2 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 10 Dec 2018 23:51:40 +0200 Subject: [PATCH 120/159] Add PHP 7.3 to travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8eb8c32..7724115 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ matrix: env: - COMPOSER_OPTIONS="--prefer-stable" - php: 7.2 - # - php: 7.3 # https://github.com/travis-ci/travis-ci/issues/9717 + - php: 7.3 - php: nightly allow_failures: - php: nightly From c122e858b69996b3f09539c8498aba01cd66646a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 3 Feb 2019 14:10:44 +0200 Subject: [PATCH 121/159] Only register the __ function if it doesn't already exist --- src/Lodash.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Lodash.php b/src/Lodash.php index d488c2a..08a6e01 100644 --- a/src/Lodash.php +++ b/src/Lodash.php @@ -82,15 +82,20 @@ public function value() } } -// We can't use "_" as a function name, since it collides with the "_" function in the gettext extension -function __($value): _ +function lodash($value): _ { return new _($value); } -function lodash($value): _ -{ - return new _($value); +// We can't use "_" as a function name, since it collides with the "_" function in the gettext extension +// Laravel uses a function __, so only register the alias if the function name is not in use +if (!function_exists('__')) { + function __($value): _ + { + return new _($value); + } } -define('_', _::class); +if (!defined('_')) { + define('_', _::class); +} From 9892ac946eadd071200151c76201ff853524e962 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 18 Feb 2019 11:49:20 +0200 Subject: [PATCH 122/159] Fix #13 - Flatten does not expand empty array --- src/compiled.php | 4 ++-- src/internal/isFlattenable.php | 2 +- tests/Array/FlattenTest.php | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiled.php b/src/compiled.php index 93cd773..41dedd3 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -2,7 +2,7 @@ // Auto-generated file - namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function __($value): _ { return new _($value); } function lodash($value): _ { return new _($value); } define('_', _::class); } + namespace { final class _ { public $__chain__ = false; public const reInterpolate = '<%=([\s\S]+?)%>'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function lodash($value): _ { return new _($value); } if (!function_exists('__')) { function __($value): _ { return new _($value); } } if (!defined('_')) { define('_', _::class); } } namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } @@ -105,7 +105,7 @@ namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\\internal\\baseIndexOfWith' : '_\\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } namespace _\internal { function baseFlatten(?array $array, int $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { arrayPush($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } - namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); } } + namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && ([] === $value || \range(0, \count($value) - 1) === \array_keys($value)); } } namespace _\internal { function arrayIncludesWith(?array $array, $value, callable $comparator) { $array = $array ?? []; foreach ($array as $v) { if ($comparator($value, $v)) { return true; } } return false; } } namespace _\internal { const reIsDeepProp = '#\.|\[(?:[^[\]]*|(["\'])(?:(?!\1)[^\\\\]|\\.)*?\1)\]#'; const reIsPlainProp = '/^\w*$/'; function isKey($value, $object = []): bool { if (\is_array($value)) { return false; } if (\is_numeric($value)) { return true; } return \preg_match(reIsPlainProp, $value) || !\preg_match(reIsDeepProp, $value) || (null !== $object && isset(((object) $object)->$value)); } } namespace _\internal { function baseProperty($key) { return function ($object) use ($key) { return null === $object ? null : $object[$key]; }; } } diff --git a/src/internal/isFlattenable.php b/src/internal/isFlattenable.php index 266f59e..f14b5b4 100644 --- a/src/internal/isFlattenable.php +++ b/src/internal/isFlattenable.php @@ -22,5 +22,5 @@ */ function isFlattenable($value): bool { - return \is_array($value) && \range(0, \count($value) - 1) === \array_keys($value); + return \is_array($value) && ([] === $value || \range(0, \count($value) - 1) === \array_keys($value)); } diff --git a/tests/Array/FlattenTest.php b/tests/Array/FlattenTest.php index 6e93890..3c28d78 100644 --- a/tests/Array/FlattenTest.php +++ b/tests/Array/FlattenTest.php @@ -17,5 +17,7 @@ class FlattenTest extends TestCase public function testFlatten() { $this->assertSame([1, 2, [3, [4]], 5], flatten([1, [2, [3, [4]], 5]])); + + $this->assertSame([1, 2, 3, 4, 5, 6], flatten([[1, 2, 3], [], [4, 5, 6]])); } } From 322f11b901e093bcffe3cda35125edbb95bf36fe Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 30 Mar 2019 09:27:12 +0200 Subject: [PATCH 123/159] Use array_values to re-index array instead of sort when filtering --- src/Collection/filter.php | 4 +--- src/compiled.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Collection/filter.php b/src/Collection/filter.php index da32f12..3c3b9bf 100644 --- a/src/Collection/filter.php +++ b/src/Collection/filter.php @@ -62,7 +62,5 @@ function ($value, $key) use ($array, $iteratee) { \ARRAY_FILTER_USE_BOTH ); - \sort($result); - - return $result; + return \array_values($result); } diff --git a/src/compiled.php b/src/compiled.php index 41dedd3..88ba034 100644 --- a/src/compiled.php +++ b/src/compiled.php @@ -21,7 +21,7 @@ namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, ...$args); } } namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } - namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); \sort($result); return $result; } } + namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); return \array_values($result); } } namespace _ { function sample(array $array) { $key = \array_rand($array, 1); return $array[$key]; } } namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees): array { if (null === $collection) { return []; }; if (\is_callable($iteratees) || !\is_iterable($iteratees)) { $iteratees = [$iteratees]; } $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } From 14771e05f0080a5ca63fdb30bafb80b3ca317251 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 20 Sep 2019 11:35:21 +0200 Subject: [PATCH 124/159] Remove compiled file from repository, which will be generated and included in distribution releases --- .gitignore | 3 +- src/compiled.php | 194 ----------------------------------------------- 2 files changed, 2 insertions(+), 195 deletions(-) delete mode 100644 src/compiled.php diff --git a/.gitignore b/.gitignore index ff8cba6..a4ecb6f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /vendor/ /composer.lock /vendor-bin/**/vendor -/.php_cs.cache \ No newline at end of file +/.php_cs.cache +/src/compiled.php diff --git a/src/compiled.php b/src/compiled.php deleted file mode 100644 index 88ba034..0000000 --- a/src/compiled.php +++ /dev/null @@ -1,194 +0,0 @@ -'; public const reEvaluate = "<%([\s\S]+?)%>"; public const reEscape = "<%-([\s\S]+?)%>"; public static $templateSettings = [ 'escape' => self::reEscape, 'evaluate' => self::reEvaluate, 'interpolate' => self::reInterpolate, 'imports' => [ '_\escape' => '__e', ], ]; private $value; public function __construct($value) { $this->value = $value; } public static function __callStatic(string $method, array $args) { if (!\is_callable("_\\$method")) { throw new \InvalidArgumentException("Function _::$method is not valid"); } return ("_\\$method")(...$args); } public function __call($method, $arguments) { $this->value = self::__callStatic($method, \array_merge([$this->value], $arguments)); return $this; } public function value() { return $this->value; } } function lodash($value): _ { return new _($value); } if (!function_exists('__')) { function __($value): _ { return new _($value); } } if (!defined('_')) { define('_', _::class); } } - namespace _ { use _\internal\Traits\CacheDataTrait; final class Hash implements CacheInterface { use CacheDataTrait; public function __construct() { $this->clear(); } public function set($key, $value): CacheInterface { $this->size += $this->has($key) ? 0 : 1; $this->__data__[$key] = $value; return $this; } public function get($key) { return $this->__data__[$key] ?? null; } public function has($key): bool { return \array_key_exists($key, $this->__data__); } public function clear() { $this->__data__ = []; $this->size = 0; } public function delete($key) { $result = $this->has($key); unset($this->__data__[$key]); $this->size -= $result ? 1 : 0; return $result; } } } - namespace _ { use _\internal\Traits\CacheDataTrait; final class MapCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $data = $this->getMapData($key); $size = $data->getSize(); $data->set($key, $value); $this->size += $data->getSize() === $size ? 0 : 1; return $this; } final public function get($key) { return $this->getMapData($key)->get($key); } final public function has($key): bool { return $this->getMapData($key)->has($key); } final public function clear() { $this->size = 0; $this->__data__ = [ 'hash' => new Hash, 'map' => new ListCache, 'string' => new Hash, ]; } final public function delete($key) { $result = $this->getMapData($key)->delete($key); $this->size -= $result ? 1 : 0; return $result; } private function isKey($key) { return \is_scalar($key); } private function getMapData($key): CacheInterface { if ($this->isKey($key)) { return $this->__data__[\is_string($key) ? 'string' : 'hash']; } return $this->__data__['map']; } } } - namespace _ { use function _\internal\baseIteratee; function reduce(iterable $collection, $iteratee, $accumulator = null) { $func = function (iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \count(\is_array($array) ? $array : \iterator_to_array($array)); if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; }; return $func($collection, baseIteratee($iteratee), $accumulator, null === $accumulator); } } - namespace _ { function eachRight($collection, callable $iteratee) { $values = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach (\array_reverse($values, true) as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } - namespace _ { use function _\internal\baseFlatten; function flatMapDeep(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), \PHP_INT_MAX); } } - namespace _ { use function _\internal\baseOrderBy; function orderBy(?iterable $collection, array $iteratee, array $orders): array { if (null === $collection) { return []; } return baseOrderBy($collection, $iteratee, $orders); } } - namespace _ { function size($collection): int { if (\is_string($collection)) { return \strlen($collection); } if (\is_array($collection) || $collection instanceof \Countable) { return \count($collection); } if ($collection instanceof \Traversable) { return \count(\iterator_to_array($collection)); } if (\is_object($collection)) { return \count(\get_object_vars($collection)); } return 0; } } - namespace _ { function each($collection, callable $iteratee) { $values = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($values as $index => $value) { if (false === $iteratee($value, $index, $collection)) { break; } } return $collection; } } - namespace _ { use function _\internal\baseIteratee; use function _\internal\baseReduce; function reduceRight(iterable $collection, $iteratee, $accumulator = null) { return baseReduce(\array_reverse($collection instanceof \Traversable ? \iterator_to_array($collection, true) : $collection, true), baseIteratee($iteratee), $accumulator, null === $accumulator); } } - namespace _ { use function _\internal\baseIteratee; function map($collection, $iteratee): array { $values = []; if (\is_array($collection)) { $values = $collection; } elseif ($collection instanceof \Traversable) { $values = \iterator_to_array($collection); } elseif (\is_object($collection)) { $values = \get_object_vars($collection); } $callable = baseIteratee($iteratee); return \array_map(function ($value, $index) use ($callable, $collection) { return $callable($value, $index, $collection); }, $values, \array_keys($values)); } } - namespace _ { use function _\internal\createAggregator; function partition(iterable $collection, $predicate = null): array { return createAggregator(function ($result, $value, $key) { $result[$key ? 0 : 1][] = $value; return $result; }, function () { return [[], []]; })($collection, $predicate); } } - namespace _ { use function _\internal\baseIteratee; function every(iterable $collection, $predicate): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if (!$iteratee($value, $key, $collection)) { return false; } } return true; } } - namespace _ { use function _\internal\baseIteratee; function find(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\is_array($collection) ? $collection : \iterator_to_array($collection), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } - namespace _ { function shuffle(array $array = []): array { \shuffle($array); return $array; } } - namespace _ { use function _\internal\baseFlatten; function flatMap(iterable $collection, callable $iteratee): array { return baseFlatten(map($collection, $iteratee), 1); } } - namespace _ { use function _\internal\baseIteratee; function reject(iterable $collection, $predicate = null): array { return filter($collection, negate(baseIteratee($predicate))); } } - namespace _ { use function _\internal\baseInvoke; use function _\internal\baseRest; function invokeMap(iterable $collection, $path, array $args = []): array { return baseRest(function ($collection, $path, $args) { $isFunc = \is_callable($path); $result = []; each($collection, function ($value) use (&$result, $isFunc, $path, $args) { $result[] = $isFunc ? $path($value, ...$args) : baseInvoke($value, $path, $args); }); return $result; })($collection, $path, ...$args); } } - namespace _ { function sampleSize(array $array, int $n = 1): array { $result = []; $count = \count($array); foreach ((array) \array_rand($array, $n > $count ? $count : $n) as $index) { $result[] = $array[$index]; } return $result; } } - namespace _ { use function _\internal\baseIteratee; function filter(iterable $array, $predicate = null): array { $iteratee = baseIteratee($predicate); $result = \array_filter( \is_array($array) ? $array : \iterator_to_array($array), function ($value, $key) use ($array, $iteratee) { return $iteratee($value, $key, $array); }, \ARRAY_FILTER_USE_BOTH ); return \array_values($result); } } - namespace _ { function sample(array $array) { $key = \array_rand($array, 1); return $array[$key]; } } - namespace _ { use function _\internal\baseIteratee; function some(iterable $collection, $predicate = null): bool { $iteratee = baseIteratee($predicate); foreach ($collection as $key => $value) { if ($iteratee($value, $key, $collection)) { return true; } } return false; } } - namespace _ { use function _\internal\baseIteratee; function sortBy($collection, $iteratees): array { if (null === $collection) { return []; }; if (\is_callable($iteratees) || !\is_iterable($iteratees)) { $iteratees = [$iteratees]; } $result = \is_object($collection) ? \get_object_vars($collection) : $collection; foreach ($iteratees as $callable) { usort($result, function ($a, $b) use ($callable) { $iteratee = baseIteratee($callable); return $iteratee($a, $b) <=> $iteratee($b, $a); }); } return $result; } } - namespace _ { use function _\internal\createAggregator; function keyBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { $result[$key] = $value; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\createAggregator; function groupBy(iterable $collection, $iteratee): array { return createAggregator(function ($result, $value, $key) { if (!isset($result[$key])) { $result[$key] = []; } $result[$key][] = $value; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\baseFlatten; function flatMapDepth(iterable $collection, callable $iteratee, int $depth = 1): array { return baseFlatten(map($collection, $iteratee), $depth); } } - namespace _ { use function _\internal\createAggregator; function countBy(iterable $collection, callable $iteratee): array { return createAggregator(function ($result, $key, $value) { if (!isset($result[$value])) { $result[$value] = 0; } $result[$value]++; return $result; })($collection, $iteratee); } } - namespace _ { use function _\internal\baseIteratee; function findLast(iterable $collection, $predicate = null, int $fromIndex = 0) { $iteratee = baseIteratee($predicate); foreach (\array_slice(\array_reverse(\is_array($collection) ? $collection : \iterator_to_array($collection), true), $fromIndex) as $key => $value) { if ($iteratee($value, $key, $collection)) { return $value; } } return null; } } - namespace _ { use Symfony\Component\PropertyAccess\PropertyAccess; function property($path): callable { $propertyAccess = PropertyAccess::createPropertyAccessorBuilder() ->disableExceptionOnInvalidIndex() ->getPropertyAccessor(); return function ($value, $index = 0, $collection = []) use ($path, $propertyAccess) { $path = \implode('.', (array) $path); if (\is_array($value)) { if (false !== \strpos($path, '.')) { $paths = \explode('.', $path); foreach ($paths as $path) { $value = property($path)($value, $index, $collection); } return $value; } if (\is_string($path) && $path[0] !== '[' && $path[-1] !== ']') { $path = "[$path]"; } } return $propertyAccess->getValue($value, $path); }; } } - namespace _ { function identity($value = null) { return $value; } } - namespace _ { function attempt(callable $func, ...$args) { try { return $func(...$args); } catch (\ParseError | \Error | \Throwable | \SoapFault | \DOMException | \PDOException $e) { return $e; } } } - namespace _ { use function _\internal\baseFlatten; function flattenDepth(array $array, int $depth = 1): array { return baseFlatten($array, $depth); } } - namespace _ { function difference(array $array, array ...$values): array { return \array_values(\array_diff($array, ...$values)); } } - namespace _ { use function _\internal\baseSet; function zipObjectDeep(array $props = [], array $values = []): \stdClass { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; baseSet($result, $props[$index], $value); } return $result; } } - namespace _ { use function _\internal\baseIteratee; function findLastIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); $index = $fromIndex ?? $length - 1; if ($index < 0) { $index = \max($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach (\array_reverse($array, true) as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index--; } return -1; } } - namespace _ { function lastIndexOf(array $array, $value, int $fromIndex = null): int { $index = \count($array) - 1; if (null !== $fromIndex) { $index = $fromIndex > 0 ? $fromIndex : \count($array) - 1; $array = \array_slice($array, 0, -$fromIndex + 1); }; foreach (\array_reverse($array, false) as $v) { if (isEqual($value, $v)) { return $index; } $index--; } return -1; } } - namespace _ { use function _\internal\baseIteratee; use function _\internal\basePullAll; function pullAllBy(array &$array, array $values, $iteratee): array { return basePullAll($array, $values, baseIteratee($iteratee)); } } - namespace _ { use function _\internal\baseUniq; function uniqWith(array $array, callable $comparator): array { return baseUniq($array, null, $comparator); } } - namespace _ { use function _\internal\basePullAll; function pullAllWith(array &$array, array $values, callable $comparator): array { return basePullAll($array, $values, null, $comparator); } } - namespace _ { use function _\internal\baseRest; function zip(array ...$arrays): array { return baseRest('\_\unzip')(...$arrays); } } - namespace _ { function compact(?array $array): array { return \array_values(\array_filter($array ?? [])); } } - namespace _ { function zipWith(...$arrays): array { $iteratee = \is_callable(\end($arrays)) ? \array_pop($arrays) : null; return unzipWith($arrays, $iteratee); } } - namespace _ { function uniq(array $array = []): array { return \array_unique($array); } } - namespace _ { function zipObject(array $props = [], array $values = []) { $result = new \stdClass; $index = -1; $length = \count($props); $props = \array_values($props); $values = \array_values($values); while (++$index < $length) { $value = $values[$index] ?? null; $result->{$props[$index]} = $value; } return $result; } } - namespace _ { use function _\internal\baseIteratee; use function _\internal\baseUniq; function uniqBy(array $array, $iteratee): array { return baseUniq($array, baseIteratee($iteratee)); } } - namespace _ { use function _\internal\baseIteratee; function takeRightWhile(array $array, $predicate): array { $iteratee = baseIteratee($predicate); $result = []; foreach (array_reverse($array, true) as $index => $value) { if ($iteratee($value, $index, $array)) { $result[$index] = $value; } } return array_reverse($result); } } - namespace _ { use function _\internal\baseIteratee; function takeWhile(array $array, $predicate): array { $result = []; $iteratee = baseIteratee($predicate); foreach ($array as $index => $value) { if ($iteratee($value, $index, $array)) { $result[$index] = $value; } } return $result; } } - namespace _ { function takeRight(array $array, int $n = 1): array { if (1 > $n) { return []; } return array_slice($array, -$n); } } - namespace _ { use function _\internal\baseFlatten; function differenceWith(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $comparator = \array_pop($values); $values = baseFlatten($values, 1, 'is_array', true, null); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($comparator($value, $values[$valuesIndex])) { continue 2; } } $result[] = $value; } return $result; } } - namespace _ { function initial(array $array): array { \array_pop($array); return $array; } } - namespace _ { function dropRightWhile(array $array, callable $predicate): array { \end($array); $length = \count($array); $index = \key($array); while ($length && $predicate($array[$index], $index, $array)) { array_pop($array); $length--; \end($array); $index = \key($array); } return $array; } } - namespace _ { function indexOf(array $array, $value, int $fromIndex = null): int { $inc = true; $index = 0; if (null !== $fromIndex) { $index = $fromIndex >= 0 ? $fromIndex : \count($array) - 1; if ($fromIndex < 0) { $array = \array_reverse($array, false); $inc = false; } }; foreach ($array as $v) { if (isEqual($value, $v)) { return $index; } $inc ? $index++ : $index--; } return -1; } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseProperty; use function _\internal\baseTimes; function unzip(array $array): array { if (!\count($array)) { return []; } $length = 0; $array = \array_filter($array, function ($group) use (&$length) { if (\is_array($group)) { $length = \max(\count($group), $length); return true; } }); return baseTimes($length, function ($index) use ($array) { return arrayMap($array, baseProperty($index)); }); } } - namespace _ { function slice(array $array, int $start, int $end = null): array { return \array_slice($array, $start, $end); } } - namespace _ { function drop(array $array, int $n = 1): array { return \array_slice($array, $n); } } - namespace _ { use function _\internal\baseRest; function without(array $array, ...$values): array { return baseRest('\_\difference')($array, ...$values); } } - namespace _ { function dropWhile(array $array, callable $predicate): array { \reset($array); $count = \count($array); $length = 0; $index = \key($array); while ($length <= $count && $predicate($array[$index], $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); } return $array; } } - namespace _ { use function _\internal\baseIntersection; function intersectionWith(...$arrays ): array { $copy = $arrays; $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { $arrays = $copy; $comparator = null; } return baseIntersection($arrays, null, $comparator); } } - namespace _ { function head(array $array) { reset($array); return current($array) ?: null; } function first(array $array) { return head($array); } } - namespace _ { function dropRight(array $array, int $n = 1): array { $count = \count($array); if ($n > $count) { $n = $count; } return \array_slice($array, 0, $count - $n); } } - namespace _ { function concat($array, ...$values): array { $check = function ($value): array { return \is_array($value) ? $value : [$value]; }; return \array_merge($check($array), ...\array_map($check, $values)); } } - namespace _ { function remove(array &$array, callable $predicate): array { $resultArray = []; $array = \array_filter($array, function ($val, $key) use ($predicate, $array, &$resultArray) { $result = $predicate($val, $key, $array); if ($result) { $resultArray[] = $val; } return !$result; }, \ARRAY_FILTER_USE_BOTH); $array = \array_values($array); return $resultArray; } } - namespace _ { function chunk(?array $array, int $number): array { if ($number < 1) { return []; } return \array_chunk($array ?? [], $number, false); } } - namespace _ { function take(array $array, int $n = 1): array { if (1 > $n) { return []; } array_splice($array, $n); return $array; } } - namespace _ { function last(array $array) { return \end($array) ?: null; } } - namespace _ { function tail(array $array): array { array_shift($array); return $array; } } - namespace _ { function pull(array &$array, ...$values): array { $array = \array_filter($array, function ($val) use ($values) { return !\in_array($val, $values, true); }); $array = \array_values($array); return $array; } } - namespace _ { function fromPairs(array $pairs): \stdClass { if (!\count($pairs)) { return new \stdClass(); } $result = new \stdClass(); foreach ($pairs as $pair) { $result->{$pair[0]} = $pair[1]; } return $result; } } - namespace _ { function intersection(array ...$arrays): array { return \array_intersect(...$arrays); } } - namespace _ { function pullAt(array &$array, $indexes): array { $indexes = (array) $indexes; $pulled = []; $array = \array_filter($array, function ($val, $key) use ($indexes, &$pulled) { $inArray = \in_array($key, $indexes); if ($inArray) { $pulled[] = $val; } return !$inArray; }, \ARRAY_FILTER_USE_BOTH); $array = \array_values($array); return $pulled; } } - namespace _ { function pullAll(array &$array, array $values): array { return pull($array, ...$values); } } - namespace _ { function union(array ...$arrays): array { return array_unique(array_merge(...$arrays)); } } - namespace _ { use function _\internal\baseFlatten; function flatten(array $array = null): array { return baseFlatten($array, 1); } } - namespace _ { use function _\internal\baseFlatten; use function _\internal\baseUniq; function unionWith(... $arrays): array { $comparator = \array_pop($arrays); if (!\is_callable($comparator)) { throw new \InvalidArgumentException(__FUNCTION__.' expects the last value passed to be callable'); } return baseUniq(baseFlatten($arrays, 1, '\is_array', true), null, $comparator); } } - namespace _ { use function _\internal\baseIteratee; function findIndex(array $array, $predicate, int $fromIndex = null): int { $length = \count($array); if (!$length) { return -1; } $index = $fromIndex ?? 0; if ($index < 0) { $index = \min($length + $index, 0); } $iteratee = baseIteratee($predicate); foreach ($array as $key => $value) { if ($iteratee($value, $key, $array)) { return $index; } $index++; } return -1; } } - namespace _ { use function _\internal\baseFlatten; function flattenDeep(array $array): array { return baseFlatten($array, PHP_INT_MAX); } } - namespace _ { use function _\internal\arrayMap; function unzipWith(array $array, ?callable $iteratee = null): array { if (!\count($array)) { return []; } $result = unzip($array); if (!is_callable($iteratee)) { return $result; } return arrayMap($result, function ($group) use ($iteratee) { return $iteratee(...$group); }); } } - namespace _ { function nth(array $array, int $n) { return \array_values($array)[$n < 0 ? \count($array) + $n : $n] ?? null; } } - namespace _ { use function _\internal\baseFlatten; function differenceBy(array $array, ...$values): array { if (!$array) { return []; } if (!\is_callable(\end($values))) { return difference($array, ...$values); } $iteratee = \array_pop($values); $values = \array_map($iteratee, baseFlatten($values, 1, 'is_array', true, null)); $valuesLength = \count($values); $result = []; foreach ($array as $value) { $computed = $iteratee($value); $valuesIndex = $valuesLength; while ($valuesIndex--) { if ($computed === $values[$valuesIndex]) { continue 2; } } $result[] = $value; } return $result; } } - namespace _ { use function _\internal\baseFlatten; use function _\internal\baseIteratee; use function _\internal\baseUniq; function unionBy(...$arrays): array { return baseUniq(baseFlatten($arrays, 1, '\is_array', true), baseIteratee(\array_pop($arrays))); } } - namespace _ { use function _\internal\baseIntersection; use function _\internal\baseIteratee; function intersectionBy(...$arrays): array { $iteratee = \array_pop($arrays); return baseIntersection($arrays, baseIteratee($iteratee)); } } - namespace _ { function chain($value): \_ { $result = __($value); $result->__chain__ = true; return $result; } } - namespace _ { function now(): int { return (int) (\microtime(true) * 1000); } } - namespace _\internal { function baseUnary($func) { return function ($value) use ($func) { return $func($value); }; } } - namespace _\internal { function stringToArray(string $string): array { return hasUnicode($string) ? unicodeToArray($string) : \str_split($string); } } - namespace _\internal { function createMathOperation(callable $operator, $defaultValue) { return function ($value, $other) use ($defaultValue, $operator) { if (null === $value && null === $other) { return $defaultValue; } $result = null; if (null !== $value) { $result = $value; } if (null !== $other) { if (null === $result) { return $other; } $result = $operator($value, $other); } return $result; }; } } - namespace _\internal { use function _\each; function createAggregator($setter, $initializer = null) { return function ($collection, $iteratee) use ($setter, $initializer) { $accumulator = null !== $initializer ? $initializer() : []; $func = function ($collection, $setter, &$accumulator, $iteratee) { each($collection, function ($value, $key, $collection) use ($setter, &$accumulator, $iteratee) { $accumulator = $setter($accumulator, $value, $iteratee($value), $collection); }); return $accumulator; }; return $func($collection, $setter, $accumulator, baseIteratee($iteratee)); }; } } - namespace _\internal { use function _\isEqual; use function _\property; function baseMatches($source): callable { return function ($value, $index, $collection) use ($source): bool { if ($value === $source || isEqual($value, $source)) { return true; } if (\is_array($source) || $source instanceof \Traversable) { foreach ($source as $k => $v) { if (!isEqual(property($k)($value, $index, $collection), $v)) { return false; } } return true; } return false; }; } } - namespace _\internal { function baseTimes(int $n, callable $iteratee) { $index = -1; $result = []; while (++$index < $n) { $result[$index] = $iteratee($index); } return $result; } } - namespace _\internal { function arrayMap(?array $array, callable $iteratee) { $index = -1; $length = null === $array ? 0 : \count($array); $result = []; while (++$index < $length) { $result[$index] = $iteratee($array[$index], $index, $array); } return $result; } } - namespace _\internal { const rsAstralRange = '\\x{e800}-\\x{efff}'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsDingbatRange = '\\x{2700}-\\x{27bf}'; const rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; const rsMathOpRange = '\\xac\\xb1\\xd7\\xf7'; const rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; const rsPunctuationRange = '\\x{2000}-\\x{206f}'; const rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; const rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; const rsVarRange = '\\x{fe0e}\\x{fe0f}'; const rsBreakRange = rsMathOpRange.rsNonCharRange.rsPunctuationRange.rsSpaceRange; const rsApos = "[\\x{2019}]"; const rsBreak = '['.rsBreakRange.']'; const rsCombo = '['.rsComboRange.']'; const rsDigits = '\\d+'; const rsDingbat = '['.rsDingbatRange.']'; const rsLower = '['.rsLowerRange.']'; const rsMisc = '[^'.rsAstralRange.rsBreakRange.rsDigits.rsDingbatRange.rsLowerRange.rsUpperRange.']'; const rsFitz = '\\x{e83c}[\\x{effb}-\\x{efff}]'; const rsModifier = '(?:'.rsCombo.'|'.rsFitz.')'; const rsNonAstral = '[^'.rsAstralRange.']'; const rsRegional = '(?:\\x{e83c}[\\x{ede6}-\\x{edff}]){2}'; const rsSurrPair = '[\\x{e800}-\\x{ebff}][\\x{ec00}-\\x{efff}]'; const rsUpper = '['.rsUpperRange.']'; const rsZWJ = '\\x{200d}'; const rsMiscLower = '(?:'.rsLower.'|'.rsMisc.')'; const rsMiscUpper = '(?:'.rsUpper.'|'.rsMisc.')'; const rsOptContrLower = '(?:'.rsApos.'(?:d|ll|m|re|s|t|ve))?'; const rsOptContrUpper = '(?:'.rsApos.'(?:D|LL|M|RE|S|T|VE))?'; const reOptMod = rsModifier.'?'; const rsOptVar = '['.rsVarRange.']?'; define('rsOptJoin', '(?:'.rsZWJ.'(?:'.implode('|', [rsNonAstral, rsRegional, rsSurrPair]).')'.rsOptVar.reOptMod.')*'); const rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)'; const rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)'; const rsSeq = rsOptVar.reOptMod.rsOptJoin; define('rsEmoji', '(?:'.implode('|', [rsDingbat, rsRegional, rsSurrPair]).')'.rsSeq); const rsAstral = '['.rsAstralRange.']'; const rsNonAstralCombo = rsNonAstral.rsCombo.'?'; define('rsSymbol', '(?:'.implode('|', [rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral]).')'); const reUnicode = rsFitz.'(?='.rsFitz.')|'.rsSymbol.rsSeq; } - namespace _\internal { function toKey($value): string { if (\is_string($value)) { return $value; } $result = (string) $value; return ('0' === $result && (1 / $value) === -INF) ? '-0' : $result; } } - namespace _\internal { function overRest(callable $func, $start, callable $transform): callable { $parameters = (new \ReflectionFunction($func))->getNumberOfParameters(); $start = max($start ?? $parameters - 1, 0); return function () use ($func, $start, $transform) { $args = \func_get_args(); $index = -1; $length = \max(\count($args) - $start, 0); $array = []; while (++$index < $length) { $array[$index] = $args[$start + $index]; } $index = -1; $otherArgs = []; while (++$index < $start) { $otherArgs[$index] = $args[$index]; } $otherArgs[$start] = $transform($array); return $func(...$otherArgs); }; } } - namespace _\internal\Traits { trait CacheDataTrait { private $__data__ = []; private $size; public function getSize(): int { return $this->size; } } } - namespace _\internal { function unicodeToArray(string $string): array { if (\preg_match_all('#'.reUnicode.'#u', $string, $matches)) { return $matches[0]; } return []; } } - namespace _\internal { function flatRest(callable $func): callable { return shortOut(overRest($func, null, '\_\flatten')); } } - namespace _\internal { function baseRest(callable $func, $start = null): callable { return overRest($func, $start, '\_\identity'); } } - namespace _\internal { use function _\property; function isIterateeCall($value, $index = null, $object = null) { if (!\is_object($object) || !\is_array($object)) { return false; } $type = \gettype($index); if (null === $index || ('integer' !== $type && 'string' !== $type)) { return false; } if (\is_array($object)) { return isset($object[$index]) && property($index)($value) === $value; } if (\is_object($object)) { return \property_exists($object, $index) && property($index)($value) === $value; } return false; } } - namespace _\internal { function unicodeSize(string $string): int { return \preg_match_all(reUnicode, $string) ?: 0; } } - namespace _\internal { use function _\property; function baseGet($object, $path) { $path = castPath($path, $object); $index = 0; $length = \count($path); while ($object !== null && $index < $length) { $object = property(toKey($path[$index++]))($object); } return ($index > 0 && $index === $length) ? $object : null; } } - namespace _\internal { function basePullAll(&$array, array $values, ?callable $iteratee, callable $comparator = null) { $indexOf = $comparator ? '_\\internal\\baseIndexOfWith' : '_\\indexOf'; $seen = $array; if ($iteratee) { $seen = \array_map($iteratee, $array); } foreach ($values as $value) { $fromIndex = 0; $computed = $iteratee ? $iteratee($value) : $value; while (($fromIndex = $indexOf($seen, $computed, $fromIndex, $comparator)) > -1) { \array_splice($array, $fromIndex, 1); if ($seen !== $array) { \array_splice($seen, $fromIndex, 1); } } } return $array; } } - namespace _\internal { function baseFlatten(?array $array, int $depth, callable $predicate = null, bool $isStrict = null, array $result = null): array { $result = $result ?? []; if ($array === null) { return $result; } $predicate = $predicate ?? '_\internal\isFlattenable'; foreach ($array as $value) { if ($depth > 0 && $predicate($value)) { if ($depth > 1) { $result = baseFlatten($value, $depth - 1, $predicate, $isStrict, $result); } else { arrayPush($result, $value); } } elseif (!$isStrict) { $result[\count($result)] = $value; } } return $result; } } - namespace _\internal { function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); $end = null === $end ? $length : $end; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } } - namespace _\internal { function isFlattenable($value): bool { return \is_array($value) && ([] === $value || \range(0, \count($value) - 1) === \array_keys($value)); } } - namespace _\internal { function arrayIncludesWith(?array $array, $value, callable $comparator) { $array = $array ?? []; foreach ($array as $v) { if ($comparator($value, $v)) { return true; } } return false; } } - namespace _\internal { const reIsDeepProp = '#\.|\[(?:[^[\]]*|(["\'])(?:(?!\1)[^\\\\]|\\.)*?\1)\]#'; const reIsPlainProp = '/^\w*$/'; function isKey($value, $object = []): bool { if (\is_array($value)) { return false; } if (\is_numeric($value)) { return true; } return \preg_match(reIsPlainProp, $value) || !\preg_match(reIsDeepProp, $value) || (null !== $object && isset(((object) $object)->$value)); } } - namespace _\internal { function baseProperty($key) { return function ($object) use ($key) { return null === $object ? null : $object[$key]; }; } } - namespace _\internal { use function _\isEqual; use function _\property; function baseMatchesProperty($property, $source): callable { return function ($value, $index, $collection) use ($property, $source) { return isEqual(property($property)($value, $index, $collection), $source); }; } } - namespace _\internal { function castPath($value, $object): array { if (\is_array($value)) { return $value; } return isKey($value, $object) ? [$value] : stringToPath((string) $value); } } - namespace _\internal { use function _\map; use function _\sortBy; function baseOrderBy(iterable $collection, array $iteratees, array $orders): array { $index = -1; $iteratees = arrayMap($iteratees, baseUnary('\_\internal\baseIteratee')); $result = map($collection, function ($value) use ($iteratees, &$index) { $criteria = arrayMap($iteratees, function ($iteratee) use ($value) { return $iteratee($value); }); return ['criteria' => $criteria, 'index' => ++$index, 'value' => $value]; }); return map(sortBy($result, function ($object, $other) use ($orders) { return compareMultiple($object, $other, $orders); }), 'value'); } } - namespace _\internal { const HOT_COUNT = 800; const HOT_SPAN = 16; function shortOut(callable $func): callable { $count = 0; $lastCalled = 0; return function () use ($func, &$count, &$lastCalled) { $stamp = microtime(true); $remaining = HOT_SPAN - ($stamp - $lastCalled); $lastCalled = $stamp; if ($remaining > 0) { if (++$count >= HOT_COUNT) { return func_get_arg(0); } } else { $count = 0; } return $func(...func_get_args()); }; } } - namespace _\internal { use function _\property; function baseIteratee($value): callable { if (\is_callable($value)) { return $value; } if (null === $value) { return '_\identity'; } if (\is_array($value)) { return 2 === \count($value) && [0, 1] === \array_keys($value) ? baseMatchesProperty($value[0], $value[1]) : baseMatches($value); } return property($value); } } - namespace _\internal { function compareMultiple($object, $other, $orders) { $index = -1; $objCriteria = $object['criteria']; $othCriteria = $other['criteria']; $length = \count($objCriteria); $ordersLength = \count($orders); while (++$index < $length) { $result = $objCriteria[$index] <=> $othCriteria[$index]; if ($result) { if ($index >= $ordersLength) { return $result; } $order = $orders[$index]; return $result * ('desc' === $order ? -1 : 1); } } return $object['index'] - $other['index']; } } - namespace _\internal { use function _\eq; function assocIndexOf(array $array, $key): int { $length = \count($array); while ($length--) { if (eq($array[$length][0], $key)) { return $length; } } return -1; } } - namespace _\internal { function parent($object, $path) { return count($path) < 2 ? $object : null; } } - namespace _\internal { use function _\indexOf; function arrayIncludes(?array $array, $value) { return null !== $array && indexOf($array, $value, 0) > -1; } } - namespace _\internal { const reLeadingDot = '/^\./'; const rePropName = '#[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["\'])((?:(?!\2)[^\\\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))#'; const reEscapeChar = '/\\(\\)?/g'; function stringToPath(...$args) { return memoizeCapped(function ($string) { $result = []; if (\preg_match(reLeadingDot, $string)) { $result[] = ''; } \preg_match_all(rePropName, $string, $matches, PREG_SPLIT_DELIM_CAPTURE); foreach ($matches as $match) { $result[] = $match[1] ?? $match[0]; } return $result; })(...$args); } } - namespace _\internal { function baseUniq(array $array, callable $iteratee = null, callable $comparator = null) { $index = -1; $includes = '\_\internal\arrayIncludes'; $length = \count($array); $isCommon = true; $result = []; $seen = $result; if ($comparator) { $isCommon = false; $includes = '\_\internal\arrayIncludesWith'; } else { $seen = $iteratee ? [] : $result; } while (++$index < $length) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator || $value !== 0) ? $value : 0; if ($isCommon && $computed) { $seenIndex = \count($seen); while ($seenIndex--) { if ($seen[$seenIndex] === $computed) { continue 2; } } if ($iteratee) { $seen[] = $computed; } $result[] = $value; } elseif (!$includes($result, $computed, $comparator)) { if ($seen !== $result) { $seen[] = $computed; } $result[] = $value; } } return $result; } } - namespace _\internal { function unicodeWords(string $string): array { $regex = '#'.\implode('|', [ rsUpper.'?'.rsLower.'+'.rsOptContrLower.'(?='.\implode('|', [rsBreak, rsUpper, '$']).')', rsMiscUpper.'+'.rsOptContrUpper.'(?='.\implode('|', [rsBreak, rsUpper.rsMiscLower, '$']).')', rsUpper.'?'.rsMiscLower.'+'.rsOptContrLower, rsUpper.'+'.rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji, ]).'#u'; if (\preg_match_all($regex, $string, $matches) > 0) { return $matches[0]; } return []; } } - namespace _\internal { use function _\memoize; function memoizeCapped(callable $func) { $MaxMemoizeSize = 500; $result = memoize($func, function ($key) use ($MaxMemoizeSize) { if ($this->cache->getSize() === $MaxMemoizeSize) { $this->cache->clear(); } return $key; }); return $result; } } - namespace _\internal { function baseIntersection($arrays, ?callable $iteratee, $comparator = null) { $includes = $comparator ? '_\internal\arrayIncludesWith' : '_\internal\arrayIncludes'; $length = \count($arrays[0]); $othLength = \count($arrays); $othIndex = $othLength; $caches = []; $maxLength = INF; $result = []; while ($othIndex--) { $array =& $arrays[$othIndex]; if ($othIndex && $iteratee) { $array = \array_map($iteratee, $array); } $maxLength = \min(\count($array), $maxLength); $caches[$othIndex] = !$comparator && $iteratee ? [] : null; } $array = $arrays[0]; $index = -1; $seen = $caches[0]; while (++$index < $length && \count($result) < $maxLength) { $value = $array[$index]; $computed = $iteratee ? $iteratee($value) : $value; $value = ($comparator ?: $value !== 0) ? $value : 0; if (!($seen ? \is_scalar($computed) && isset($seen[$computed]) : $includes($result, $computed, $comparator))) { $othIndex = $othLength; while (--$othIndex) { $cache = $caches[$othIndex]; if (!(!empty($cache) ? isset($cache[$computed]) : $includes($arrays[$othIndex], $computed, $comparator))) { continue 2; } } if (empty($seen)) { $seen[] = $computed; } $result[] = $value; } } return $result; } } - namespace _\internal { function baseSet($object, $path, $value, callable $customizer = null) { if (!\is_object($object)) { return $object; } $path = castPath($path, $object); $index = -1; $length = \count($path); $lastIndex = $length - 1; $nested = $object; while ($nested !== null && ++$index < $length) { $key = toKey($path[$index]); if ($index !== $lastIndex) { $objValue = \is_array($nested) ? ($nested[$key] ?? null) : ($nested->$key ?? null); $newValue = $customizer ? $customizer($objValue, $key, $nested) : $objValue; if (null === $newValue) { $newValue = \is_object($objValue) ? $objValue : (\is_numeric($path[$index + 1]) ? [] : new \stdClass()); } if (\is_array($nested)) { $nested[$key] = $newValue; } else { $nested->{$key} = $newValue; } if (\is_array($nested)) { $nested = &$nested[$key]; } else { $nested = &$nested->$key; } continue; } $nested->{$key} = $value; } return $object; } } - namespace _\internal { function stringSize(string $string): int { return hasUnicode($string) ? unicodeSize($string) : \strlen($string); } } - namespace _\internal { use function _\last; function baseInvoke($object, $path, $args) { $path = castPath($path, $object); $object = parent($object, $path); $func = null === $object ? $object : [$object, toKey(last($path))]; return \is_callable($func) ? $func($object, ...$args) : null; } } - namespace _\internal { function basePickBy($object, $paths, callable $predicate): \stdClass { $index = -1; $length = \is_array($paths) ? \count($paths) : \strlen($paths); $result = new \stdClass(); while (++$index < $length) { $path = $paths[$index]; $value = baseGet($object, $path); if ($predicate($value, $path)) { baseSet($result, castPath($path, $object), $value); } } return $result; } } - namespace _\internal { function arrayPush(&$array, $values) { $index = -1; $length = \is_array($values) ? \count($values) : \strlen($values); $offset = \count($array); while (++$index < $length) { $array[$offset + $index] = $values[$index]; } return $array; } } - namespace _\internal { function basePick($object, $paths): \stdClass { return basePickBy($object, $paths, function ($value, $path) use ($object) { return property_exists($object, $path) || method_exists($object, 'get'.(ucfirst($path))); }); } } - namespace _\internal { const reHasUnicode = '['.rsZWJ.rsAstralRange.rsComboRange.rsVarRange.']'; function hasUnicode(string $string): bool { return \preg_match('#'.reHasUnicode.'#u', $string) > 0; } } - namespace _\internal { function baseIndexOfWith(array $array, $value, int $fromIndex, $comparator) { $index = $fromIndex - 1; foreach (\array_slice($array, $fromIndex, null, true) as $val) { ++$index; if ($comparator($val, $value)) { return $index; } } return -1; } } - namespace _\internal { function baseReduce(iterable $array, $iteratee, $accumulator, $initAccum = null) { $length = \is_array($array) || $array instanceof \Countable ? \count($array) : 0; if ($initAccum && $length) { $accumulator = \current($array); } foreach ($array as $key => $value) { $accumulator = $iteratee($accumulator, $value, $key, $array); } return $accumulator; } } - namespace _ { interface CacheInterface { public function set($key, $value): CacheInterface; public function get($key); public function has($key): bool; public function clear(); public function delete($key); public function getSize(); } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseFlatten; use function _\internal\baseRest; use function _\internal\baseUnary; function overArgs(callable $func, array $transforms): callable { return baseRest(function ($func, $transforms) { $transforms = (\count($transforms) == 1 && \is_array($transforms[0])) ? arrayMap($transforms[0], baseUnary('\_\internal\baseIteratee')) : arrayMap(baseFlatten($transforms, 1), baseUnary('\_\internal\baseIteratee')); $funcsLength = \count($transforms); return baseRest(function ($args) use ($funcsLength, $transforms, $func) { $index = -1; $length = \min(\count($args), $funcsLength); while (++$index < $length) { $args[$index] = $transforms[$index]($args[$index]); } return $func(...$args); }); })($func, $transforms); } } - namespace _ { function before(int $n, callable $func): callable { $result = null; return function (...$args) use (&$result, &$n, &$func) { if (--$n > 0) { $result = $func(...$args); } return $result; }; } } - namespace _ { function ary(callable $func, int $n): callable { return function (...$args) use ($func, $n) { \array_splice($args, $n); return $func(...$args); }; } } - namespace _ { function once(callable $func): callable { return before(2, $func); } } - namespace _ { function after(int $n, callable $func): callable { return function (...$args) use (&$n, $func) { if (--$n < 1) { return $func(...$args); } }; } } - namespace _ { function bindKey($object, string $function, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable([$object, $function])->bindTo($object, get_class($object)); return $function(...array_merge($partials, $args)); }; } } - namespace _ { function negate(callable $predicate): callable { return function () use ($predicate) { return !$predicate(...\func_get_args()); }; } } - namespace _ { function delay(callable $func, int $wait = 1, ...$args): int { usleep($wait * 1000); $func(...$args); return 1; } } - namespace _ { use function _\internal\baseRest; use function _\internal\shortOut; function partial(callable $func, ...$partials): callable { return baseRest(function ($func, $partials) { $wrapper = function () use ($func, $partials) { $arguments = \func_get_args(); $argsIndex = -1; $argsLength = \func_num_args(); $leftIndex = -1; $leftLength = \count($partials); $args = []; while (++$leftIndex < $leftLength) { $args[$leftIndex] = $partials[$leftIndex]; } while ($argsLength--) { $args[$leftIndex++] = $arguments[++$argsIndex]; } return $func(...$args); }; return shortOut($wrapper); })($func, ...$partials); } } - namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function spread(callable $func, ?int $start = null) { $start = null === $start ? 0 : \max($start, 0); return baseRest(function ($args) use ($start, $func) { $array = $args[$start]; $otherArgs = castSlice($args, 0, $start); if ($array) { $otherArgs = \array_merge($otherArgs, $array); } return $func(...$otherArgs); }); } } - namespace _ { function wrap($value, callable $wrapper = null): callable { return partial($wrapper ?? '\_\identity', $value); } } - namespace _ { use function _\internal\baseRest; use function _\internal\castSlice; function flip(callable $func): callable { return function (...$values) use ($func) { return \array_reverse($func(...$values), false); }; } } - namespace _ { function unary(callable $func): callable { return ary($func, 1); } } - namespace _ { function curry(callable $func, ?int $arity = null) { $curry = function ($arguments) use ($func, &$curry, $arity) { $requiredArguments = (new \ReflectionFunction($func))->getNumberOfParameters(); $arity = $arity ?? $requiredArguments; return function (...$args) use ($func, $arguments, $curry, $arity) { if (false !== \array_search(_, $arguments)) { foreach ($arguments as $i => $argument) { if (_ !== $argument) { continue; } $arguments[$i] = current($args); next($args); } } else { $arguments = \array_merge($arguments, $args); } if ($arity <= \count(\array_filter($arguments, function ($value) { return _ !== $value; }))) { return $func(...$arguments); } return $curry($arguments); }; }; return $curry([]); } } - namespace _ { function memoize(callable $func, callable $resolver = null) { $memoized = new class($func, $resolver ?? null) { public $cache; private $resolver; private $func; public function __construct(callable $func, ?callable $resolver) { $this->resolver = $resolver; $this->func = $func; } public function __invoke() { $args = \func_get_args(); if ($this->resolver) { $key = \Closure::fromCallable($this->resolver)->bindTo($this)(...$args); } else { $key = &$args[0]; } $cache = $this->cache; if ($cache->has($key)) { return $cache->get($key); } $result = ($this->func)(...$args); $this->cache = $this->cache->set($key, $result); return $result; } }; $memoized->cache = new MapCache; return $memoized; } } - namespace _ { use function _\internal\baseRest; function rest(callable $func, ?int $start = null): callable { return baseRest($func, $start); } } - namespace _ { function bind(callable $function, $object, ...$partials): callable { return function (...$args) use ($object, $function, $partials) { $function = \Closure::fromCallable($function)->bindTo($object, $function instanceof \Closure ? $object : null); return $function(...array_merge($partials, $args)); }; } } - namespace _ { use function _\internal\createMathOperation; function add($augend, $addend) { return createMathOperation(function ($augend, $addend) { return $augend + $addend; }, 0)($augend, $addend); } } - namespace _ { use function _\internal\baseIteratee; function maxBy(?array $array, $iteratee) { $iteratee = baseIteratee($iteratee); $result = null; $computed = null; foreach ($array as $key => $value) { $current = $iteratee($value); if (null !== $current && (null === $computed ? ($current === $current) : $current > $computed)) { $computed = $current; $result = $value; } } return $result; } } - namespace _ { function max(?array $array): ?int { return $array ? \max($array) : null; } } - namespace _ { function clamp(int $number, int $lower, int $upper): int { $number = $number <= $upper ? $number : $upper; $number = $number >= $lower ? $number : $lower; return $number; } } - namespace _ { function inRange(float $number, float $start = 0, float $end = 0): bool { if (0.0 === $end) { $end = $start; $start = 0; } return $number >= \min($start, $end) && $number < \max($start, $end); } } - namespace _ { function random($lower = null, $upper = null, $floating = null) { if (null === $floating) { if (\is_bool($upper)) { $floating = $upper; $upper = null; } elseif (\is_bool($lower)) { $floating = $lower; $lower = null; } } if (null === $lower && null === $upper) { $lower = 0; $upper = 1; } elseif (null === $upper) { $upper = $lower; $lower = 0; } if ($lower > $upper) { $temp = $lower; $lower = $upper; $upper = $temp; } $floating = $floating || (\is_float($lower) || \is_float($upper)); if ($floating || $lower % 1 || $upper % 1) { $randMax = \mt_getrandmax(); return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } return \rand((int) $lower, (int) $upper); } } - namespace _ { function isError($value): bool { if (!\is_object($value)) { return false; } return $value instanceof \ParseError || $value instanceof \Error || $value instanceof \Throwable || $value instanceof \SoapFault || $value instanceof \DOMException || $value instanceof \PDOException; } } - namespace _ { use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; function isEqual($value, $other): bool { $factory = new Factory; $comparator = $factory->getComparatorFor($value, $other); try { $comparator->assertEquals($value, $other); return true; } catch (ComparisonFailure $failure) { return false; } } } - namespace _ { function eq($value, $other): bool { return $value === $other; } } - namespace _ { use function _\internal\arrayMap; use function _\internal\baseIteratee; use function _\internal\basePickBy; function pickBy($object, callable $predicate): \stdClass { if (null === $object) { return new \stdClass; } $props = arrayMap(\array_keys(\get_object_vars($object)), function ($prop) { return [$prop]; }); $predicate = baseIteratee($predicate); return basePickBy($object, $props, function ($value, $path) use ($predicate) { return $predicate($value, $path[0]); }); } } - namespace _ { use function _\internal\basePick; use function _\internal\flatRest; function pick($object, $paths): \stdClass { return flatRest(function ($object, $paths) { return basePick($object, $paths); })($object, $paths); } } - namespace _ { function lowerFirst(string $string): string { return \lcfirst($string); } } - namespace _ { function camelCase(string $string): string { return \lcfirst(\array_reduce(words(\preg_replace("/['\\x{2019}]/u", '', $string)), function ($result, $word) { return $result.capitalize(\strtolower($word)); }, '')); } } - namespace _ { function trimEnd(string $string, string $chars = ' '): string { return \rtrim($string, $chars); } } - namespace _ { function upperFirst(string $string): string { return \ucfirst($string); } } - namespace _ { const reQuotes = "/['\x{2019}]/u"; function lowerCase(string $string) { return \implode(' ', \array_map('\strtolower', words(\preg_replace(reQuotes, '', $string)))); } } - namespace _ { const deburredLetters = [ '\xc0' => 'A', '\xc1' => 'A', '\xc2' => 'A', '\xc3' => 'A', '\xc4' => 'A', '\xc5' => 'A', '\xe0' => 'a', '\xe1' => 'a', '\xe2' => 'a', '\xe3' => 'a', '\xe4' => 'a', '\xe5' => 'a', '\xc7' => 'C', '\xe7' => 'c', '\xd0' => 'D', '\xf0' => 'd', '\xc8' => 'E', '\xc9' => 'E', '\xca' => 'E', '\xcb' => 'E', '\xe8' => 'e', '\xe9' => 'e', '\xea' => 'e', '\xeb' => 'e', '\xcc' => 'I', '\xcd' => 'I', '\xce' => 'I', '\xcf' => 'I', '\xec' => 'i', '\xed' => 'i', '\xee' => 'i', '\xef' => 'i', '\xd1' => 'N', '\xf1' => 'n', '\xd2' => 'O', '\xd3' => 'O', '\xd4' => 'O', '\xd5' => 'O', '\xd6' => 'O', '\xd8' => 'O', '\xf2' => 'o', '\xf3' => 'o', '\xf4' => 'o', '\xf5' => 'o', '\xf6' => 'o', '\xf8' => 'o', '\xd9' => 'U', '\xda' => 'U', '\xdb' => 'U', '\xdc' => 'U', '\xf9' => 'u', '\xfa' => 'u', '\xfb' => 'u', '\xfc' => 'u', '\xdd' => 'Y', '\xfd' => 'y', '\xff' => 'y', '\xc6' => 'Ae', '\xe6' => 'ae', '\xde' => 'Th', '\xfe' => 'th', '\xdf' => 'ss', '\x{0100}' => 'A', '\x{0102}' => 'A', '\x{0104}' => 'A', '\x{0101}' => 'a', '\x{0103}' => 'a', '\x{0105}' => 'a', '\x{0106}' => 'C', '\x{0108}' => 'C', '\x{010a}' => 'C', '\x{010c}' => 'C', '\x{0107}' => 'c', '\x{0109}' => 'c', '\x{010b}' => 'c', '\x{010d}' => 'c', '\x{010e}' => 'D', '\x{0110}' => 'D', '\x{010f}' => 'd', '\x{0111}' => 'd', '\x{0112}' => 'E', '\x{0114}' => 'E', '\x{0116}' => 'E', '\x{0118}' => 'E', '\x{011a}' => 'E', '\x{0113}' => 'e', '\x{0115}' => 'e', '\x{0117}' => 'e', '\x{0119}' => 'e', '\x{011b}' => 'e', '\x{011c}' => 'G', '\x{011e}' => 'G', '\x{0120}' => 'G', '\x{0122}' => 'G', '\x{011d}' => 'g', '\x{011f}' => 'g', '\x{0121}' => 'g', '\x{0123}' => 'g', '\x{0124}' => 'H', '\x{0126}' => 'H', '\x{0125}' => 'h', '\x{0127}' => 'h', '\x{0128}' => 'I', '\x{012a}' => 'I', '\x{012c}' => 'I', '\x{012e}' => 'I', '\x{0130}' => 'I', '\x{0129}' => 'i', '\x{012b}' => 'i', '\x{012d}' => 'i', '\x{012f}' => 'i', '\x{0131}' => 'i', '\x{0134}' => 'J', '\x{0135}' => 'j', '\x{0136}' => 'K', '\x{0137}' => 'k', '\x{0138}' => 'k', '\x{0139}' => 'L', '\x{013b}' => 'L', '\x{013d}' => 'L', '\x{013f}' => 'L', '\x{0141}' => 'L', '\x{013a}' => 'l', '\x{013c}' => 'l', '\x{013e}' => 'l', '\x{0140}' => 'l', '\x{0142}' => 'l', '\x{0143}' => 'N', '\x{0145}' => 'N', '\x{0147}' => 'N', '\x{014a}' => 'N', '\x{0144}' => 'n', '\x{0146}' => 'n', '\x{0148}' => 'n', '\x{014b}' => 'n', '\x{014c}' => 'O', '\x{014e}' => 'O', '\x{0150}' => 'O', '\x{014d}' => 'o', '\x{014f}' => 'o', '\x{0151}' => 'o', '\x{0154}' => 'R', '\x{0156}' => 'R', '\x{0158}' => 'R', '\x{0155}' => 'r', '\x{0157}' => 'r', '\x{0159}' => 'r', '\x{015a}' => 'S', '\x{015c}' => 'S', '\x{015e}' => 'S', '\x{0160}' => 'S', '\x{015b}' => 's', '\x{015d}' => 's', '\x{015f}' => 's', '\x{0161}' => 's', '\x{0162}' => 'T', '\x{0164}' => 'T', '\x{0166}' => 'T', '\x{0163}' => 't', '\x{0165}' => 't', '\x{0167}' => 't', '\x{0168}' => 'U', '\x{016a}' => 'U', '\x{016c}' => 'U', '\x{016e}' => 'U', '\x{0170}' => 'U', '\x{0172}' => 'U', '\x{0169}' => 'u', '\x{016b}' => 'u', '\x{016d}' => 'u', '\x{016f}' => 'u', '\x{0171}' => 'u', '\x{0173}' => 'u', '\x{0174}' => 'W', '\x{0175}' => 'w', '\x{0176}' => 'Y', '\x{0177}' => 'y', '\x{0178}' => 'Y', '\x{0179}' => 'Z', '\x{017b}' => 'Z', '\x{017d}' => 'Z', '\x{017a}' => 'z', '\x{017c}' => 'z', '\x{017e}' => 'z', '\x{0132}' => 'IJ', '\x{0133}' => 'ij', '\x{0152}' => 'Oe', '\x{0153}' => 'oe', '\x{0149}' => "'n", '\x{017f}' => 's', ]; const reLatin = '/[\xc0-\xd6\xd8-\xf6\xf8-\xff\x{0100}-\x{017f}]/u'; const rsComboMarksRange = '\\x{0300}-\\x{036f}'; const reComboHalfMarksRange = '\\x{fe20}-\\x{fe2f}'; const rsComboSymbolsRange = '\\x{20d0}-\\x{20ff}'; const rsComboRange = rsComboMarksRange.reComboHalfMarksRange.rsComboSymbolsRange; const rsCombo = '#['.rsComboRange.']#u'; function deburr(string $string): string { $patterns = \array_map( function ($pattern) { return "#$pattern#u"; }, \array_keys(deburredLetters) ); return \preg_replace(rsCombo, '', \preg_replace($patterns, \array_values(deburredLetters), $string)); } } - namespace _ { function trimStart(string $string, string $chars = ' '): string { return \ltrim($string, $chars); } } - namespace _ { function repeat(string $string, int $n = 1): string { return \str_repeat($string, $n); } } - namespace _ { function padStart(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_LEFT); } } - namespace _ { function trim(string $string, string $chars = ' '): string { return \trim($string, $chars); } } - namespace _ { function parseInt($string, int $radix = null): int { if (null === $radix) { $radix = 10; } elseif ($radix) { $radix = +$radix; } return \intval($string, $radix); } } - namespace _ { function pad(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_BOTH); } } - namespace _ { use function _\internal\unicodeWords; const asciiWords = '/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/'; const hasUnicodeWord = '/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/'; function words(string $string, string $pattern = null): array { if (null === $pattern) { if (\preg_match(hasUnicodeWord, $string)) { return unicodeWords($string); } \preg_match_all(asciiWords, $string, $matches); return $matches[0] ?? []; } if (\preg_match_all($pattern, $string, $matches) > 0) { return $matches[0]; } return []; } } - namespace _ { function unescape(string $string): string { return \html_entity_decode($string); } } - namespace _ { function startCase(string $string) { return \implode(' ', \array_map('\ucfirst', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } - namespace _ { function replace(string $string, string $pattern, $replacement = null): string { $callback = function (array $matches) use ($replacement): ?string { if (!\array_filter($matches)) { return null; } return \is_callable($replacement) ? $replacement(...$matches) : null; }; if (\preg_match(reRegExpChar, $pattern)) { if (!\is_callable($replacement)) { return \preg_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } return \preg_replace_callback($pattern, $callback, $string); } return \str_replace($pattern, \is_string($replacement) || \is_array($replacement) ? $replacement : '', $string); } } - namespace _ { function snakeCase(string $string): string { return \implode('_', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } - namespace _ { const reRegExpChar = '/([\\^$.*+?()[\]{}|])/'; function escapeRegExp(string $string): string { return \preg_replace(reRegExpChar, '\\\$0', $string); } } - namespace _ { function toUpper(string $string): string { return \strtoupper($string); } } - namespace _ { function startsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? 0 : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } - namespace _ { function capitalize(string $string): string { return \ucfirst(\mb_strtolower($string)); } } - namespace _ { use function _\internal\castSlice; use function _\internal\hasUnicode; use function _\internal\stringSize; use function _\internal\stringToArray; const DEFAULT_TRUNC_LENGTH = 30; const DEFAULT_TRUNC_OMISSION = '...'; function truncate($string, array $options = []) { $separator = $options['separator'] ?? null; $length = $options['length'] ?? DEFAULT_TRUNC_LENGTH; $omission = $options['omission'] ?? DEFAULT_TRUNC_OMISSION; $strSymbols = null; $strLength = \strlen($string); if (hasUnicode($string)) { $strSymbols = stringToArray($string); $strLength = \count($strSymbols); } if ($length >= $strLength) { return $string; } $end = $length - stringSize($omission); if ($end < 1) { return $omission; } $result = $strSymbols ? \implode('', castSlice($strSymbols, 0, $end)) : \substr($string, 0, $end); if (null === $separator) { return $result.$omission; } if ($strSymbols) { $end += \strlen($result) - $end; } if (\preg_match(reRegExpChar, $separator)) { if (\preg_match($separator, \substr($string, 0, $end))) { $match = null; $newEnd = null; $substring = $result; if (\preg_match_all($separator, $substring, $match, PREG_OFFSET_CAPTURE)) { $newEnd = \end($match[0])[1]; } $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); if (false !== $index && $index > -1) { $result = \substr($result, 0, $index); } } return $result.$omission; } } - namespace _ { function upperCase(string $string) { return \implode(' ', \array_map('\strtoupper', words(\preg_replace(reQuotes, '', $string)))); } } - namespace _ { function endsWith(string $string, string $target, int $position = null): bool { $length = \strlen($string); $position = null === $position ? $length : +$position; if ($position < 0) { $position = 0; } elseif ($position > $length) { $position = $length; } $position -= \strlen($target); return $position >= 0 && \substr($string, $position, \strlen($target)) === $target; } } - namespace _ { const reEsTemplate = "\$\{([^\\}]*(?:\\.[^\\}]*)*)\}"; const reNoMatch = '($^)'; const reUnescapedString = "#([\'\n\r\x{2028}\x{2029}\\\])#u"; const stringEscapes = [ '\\' => '', '\n' => 'n', '\r' => 'r', '\u2028' => 'u2028', '\u2029' => 'u2029', ]; function template(string $string, array $options = []): callable { $options = \array_merge_recursive(\_::$templateSettings, $options); $interpolate = $options['interpolate'] ?? reNoMatch; $reDelimiters = \implode('|', [ ($options['escape'] ?? reNoMatch), ($interpolate === \_::reInterpolate ? reEsTemplate : reNoMatch), $interpolate, ($options['evaluate'] ?? reNoMatch), ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { list(, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; $source = ''; if ($escapeValue) { $escapeValue = \trim($escapeValue); $source .= ""; } if ($evaluateValue) { $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } return $source; }, $string); $string = \preg_replace_callback(reUnescapedString, function ($chr) { return stringEscapes[$chr[0]] ?? $chr[0]; }, $string); $imports = $options['imports'] ?? []; return new class($string, $imports) { public $source; private $imports; public function __construct(string $source, array $imports) { $this->source = $source; $this->imports = $imports; } public function __invoke(array $arguments = []) { $imports = ''; foreach ($this->imports as $import => $alias) { if (\class_exists($import)) { $imports .= "use $import as $alias;"; } elseif (\function_exists($import)) { $imports .= "use function $import as $alias;"; } } $file = \tempnam(\sys_get_temp_dir(), 'lodashphp'); if (!$file) { throw new \RuntimeException('Unable to create temporary file for template'); } \file_put_contents($file, "'.$this->source.''); $content = attempt(function () use ($file) { \ob_start(); require_once $file; return \ob_get_clean(); }); \unlink($file); return $content; } }; } } - namespace _ { function padEnd(string $string, int $length, string $chars = ' '): string { return \str_pad($string, $length, $chars, \STR_PAD_RIGHT); } } - namespace _ { function split(string $string, string $separator, int $limit = 0): array { if (\preg_match(reRegExpChar, $separator)) { return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; } $result = \explode($separator, $string); if ($limit > 0) { return \array_splice($result, 0, $limit); } return $result; } } - namespace _ { function toLower(string $string): string { return \strtolower($string); } } - namespace _ { function escape(string $string) { return \htmlentities($string); } } - namespace _ { function kebabCase(string $string) { return \implode('-', \array_map('\strtolower', words(\preg_replace("/['\x{2019}]/u", '', $string)))); } } - namespace _ { use _\internal\Traits\CacheDataTrait; use function _\internal\assocIndexOf; final class ListCache implements CacheInterface { use CacheDataTrait; public function __construct(iterable $entries = null) { $this->clear(); if (null !== $entries) { foreach ($entries as $key => $entry) { $this->set($key, $entry); } } } final public function set($key, $value): CacheInterface { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { ++$this->size; $this->__data__[] = [$key, $value]; } else { $this->__data__[$index][1] = $value; } return $this; } final public function get($key) { $index = assocIndexOf($this->__data__, $key); return $index < 0 ? null : $this->__data__[$index][1]; } final public function has($key): bool { return assocIndexOf($this->__data__, $key) > -1; } final public function clear() { $this->__data__ = []; $this->size = 0; } final public function delete($key) { $index = assocIndexOf($this->__data__, $key); if ($index < 0) { return false; } $lastIndex = \count($this->__data__) - 1; if ($index === $lastIndex) { \array_pop($this->__data__); } else { \array_splice($this->__data__, $index, 1); } --$this->size; return true; } } } \ No newline at end of file From e5d4207fea314a4bb02417f54ee1977fb591b792 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 20 Sep 2019 12:05:43 +0200 Subject: [PATCH 125/159] Add PHP 7.4 to Travis configuration (#19) --- .travis.yml | 16 ++++++---------- composer.json | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7724115..9278f2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,7 @@ language: php sudo: false env: - - COMPOSER_OPTIONS=" - -php: - - 7.1 + - COMPOSER_OPTIONS="" matrix: fast_finish: true @@ -14,22 +11,21 @@ matrix: - php: 7.1 env: - COMPOSER_OPTIONS="--prefer-lowest" + script: vendor/bin/phpunit - php: 7.1 env: - COMPOSER_OPTIONS="--prefer-stable" - php: 7.2 + script: vendor/bin/phpunit - php: 7.3 - - php: nightly - allow_failures: - - php: nightly + script: vendor/bin/phpunit + - php: 7.4snapshot + script: vendor/bin/phpunit cache: directories: - $HOME/.composer/cache/files -before_install: - - composer self-update - install: - composer update -n "$COMPOSER_OPTIONS" diff --git a/composer.json b/composer.json index a325047..2e5251c 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ ] }, "require": { - "php": "^7.1", + "php": ">=7.1", "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0", "symfony/property-access": "^2.7 | ^3.0 | ^4.0" }, From 91f804d676eb51a8d495248ebcdfdf4eff45cbef Mon Sep 17 00:00:00 2001 From: "punit.k" Date: Fri, 20 Sep 2019 18:32:45 +0530 Subject: [PATCH 126/159] add .idea to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a4ecb6f..6b329f6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /vendor-bin/**/vendor /.php_cs.cache /src/compiled.php +.idea From d83613b9efd5db7d2bf4897184ca02e1b4c16019 Mon Sep 17 00:00:00 2001 From: "punit.k" Date: Fri, 20 Sep 2019 23:17:15 +0530 Subject: [PATCH 127/159] added get function --- src/Collection/get.php | 66 ++++++++++++++++++++++++++++++++++++ tests/Collection/GetTest.php | 51 ++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/Collection/get.php create mode 100644 tests/Collection/GetTest.php diff --git a/src/Collection/get.php b/src/Collection/get.php new file mode 100644 index 0000000..a90b51c --- /dev/null +++ b/src/Collection/get.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2017 + */ + +namespace _; + +/** + * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place. + * + * @category Collection + * + * @param array|object $object The associative array or object to fetch value from + * @param array|string $path Dot separated or array of string + * @param mixed $defaultValue The value to be returned when data + * @param bool $defaultOnEmpty To check whether value is empty or isset + * + * @return array Returns the composed aggregate object. + * @example + * + * get(, 'floor'); + * // => ['6' => 2, '4' => 1] + * + * // The `property` iteratee shorthand. + * countBy(['one', 'two', 'three'], 'strlen'); + * // => ['3' => 2, '5' => 1] + * + */ +function get($object, $path, $defaultValue, bool $defaultOnEmpty = false) { + if (is_string($path)) { + $paths = explode(".", $path); + } else { + $paths = $path; + } + $temp = $object; + + + foreach ($paths as $tempPath) { + if (is_array($temp)) { + $valuePresent = $defaultOnEmpty ? !empty($temp[$tempPath]) : isset($temp[$tempPath]); + if ($valuePresent) { + $temp = $temp[$tempPath]; + } else { + return $defaultValue; + } + }elseif(is_object($temp)){ + $valuePresentObject = $defaultOnEmpty ? !empty($temp->{$tempPath}):isset($temp->{$tempPath}) ; + if ($valuePresentObject) { + $temp = $temp->{$tempPath}; + } else { + return $defaultValue; + } + }else{ + return $defaultValue; + } + } + + + return $temp; +} \ No newline at end of file diff --git a/tests/Collection/GetTest.php b/tests/Collection/GetTest.php new file mode 100644 index 0000000..244d200 --- /dev/null +++ b/tests/Collection/GetTest.php @@ -0,0 +1,51 @@ + ["key2" => ["key3" => $actualValue1, "key4" => ""]]]; + $defaultValue = "default"; + $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", "default"),"Default To method 1 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue),"Default To method 2 failed"); + $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue),"Default To method 3 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method 4 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method 5 failed"); + $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue),"Default To method 6 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key4", $defaultValue, true),"Default To method 7 failed"); + $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue),"Default To method 8 failed"); + + $this->assertSame($sampleArray["key1"]["key2"], _::get($sampleArray, "key1.key2", $defaultValue),"Default To method 9 failed"); + $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue),"Default To method 10 failed"); + } + + public function testDefaultToObject(){ + $actualValue1 = "data"; + $sampleArray = (object)["key1" => (object)["key2" => (object)["key3" => $actualValue1, "key4" => ""]]]; + $defaultValue = "default"; + $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", $defaultValue),"Default To method object 1 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue),"Default To method object 2 failed"); + $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue),"Default To method object 3 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method object 4 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method object 5 failed"); + $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue),"Default To method object 6 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key4", $defaultValue, true),"Default To method object 7 failed"); + $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue),"Default To method object 8 failed"); + + $this->assertSame($sampleArray->key1->key2, _::get($sampleArray, "key1.key2", $defaultValue),"Default To method object 9 failed"); + $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue),"Default To method 10 failed"); + } + +} \ No newline at end of file From 2a49f84d5d5190dc5bbffda437c7d561cf86c3cf Mon Sep 17 00:00:00 2001 From: "punit.k" Date: Sat, 21 Sep 2019 18:48:52 +0530 Subject: [PATCH 128/159] added defaultTo function --- README.md | 77 ++++++++++++++++++++++++ src/Collection/get.php | 66 -------------------- src/Object/get.php | 45 ++++++++++++++ src/Util/defaultTo.php | 43 +++++++++++++ src/Util/property.php | 8 ++- src/internal/baseGet.php | 4 +- tests/{Collection => Object}/GetTest.php | 62 +++++++++---------- tests/Util/DefaultToTest.php | 26 ++++++++ 8 files changed, 230 insertions(+), 101 deletions(-) delete mode 100644 src/Collection/get.php create mode 100644 src/Object/get.php create mode 100644 src/Util/defaultTo.php rename tests/{Collection => Object}/GetTest.php (50%) create mode 100644 tests/Util/DefaultToTest.php diff --git a/README.md b/README.md index 59136db..5c45a00 100644 --- a/README.md +++ b/README.md @@ -3707,6 +3707,45 @@ random(1.2, 5.2) ``` ## Object +### get + +Gets the value at path of object. If the resolved value is null the defaultValue is returned in its place. + + + + + + +**Arguments:** + +@param mixed $object The associative array or object to fetch value from + +@param (array | string) $path Dot separated or array of string + +@param mixed $defaultValue (optional)The value returned for unresolved or null values. + + + +**Return:** + +@return mixed Returns the resolved value. + +Example: +```php + ["key2" => ["key3" => "val1", "key4" => ""]]]; +get($sampleArray, 'key1.key2.key3'); +// => "val1" + +get($sampleArray, 'key1.key2.key5', "default"); +// => "default" + +get($sampleArray, 'key1.key2.key4', "default"); +// => "" + +``` ### pick Creates an object composed of the picked `object` properties. @@ -4885,6 +4924,44 @@ if (isError($elements)) { $elements = []; } +``` +### defaultTo + +Checks value to determine whether a default value should be returned in its place. +The defaultValue is returned if value is NaN or null. + + + + + + +**Arguments:** + +@param mixed $value Any value. + +@param mixed $defaultValue Value to return when $value is null or NAN + + + +**Return:** + +@return mixed Returns `value`. + +Example: +```php + "default" + +$a = "x"; + +defaultTo($a, "default"); +// => "x" + ``` ### identity diff --git a/src/Collection/get.php b/src/Collection/get.php deleted file mode 100644 index a90b51c..0000000 --- a/src/Collection/get.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Copyright (c) 2017 - */ - -namespace _; - -/** - * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place. - * - * @category Collection - * - * @param array|object $object The associative array or object to fetch value from - * @param array|string $path Dot separated or array of string - * @param mixed $defaultValue The value to be returned when data - * @param bool $defaultOnEmpty To check whether value is empty or isset - * - * @return array Returns the composed aggregate object. - * @example - * - * get(, 'floor'); - * // => ['6' => 2, '4' => 1] - * - * // The `property` iteratee shorthand. - * countBy(['one', 'two', 'three'], 'strlen'); - * // => ['3' => 2, '5' => 1] - * - */ -function get($object, $path, $defaultValue, bool $defaultOnEmpty = false) { - if (is_string($path)) { - $paths = explode(".", $path); - } else { - $paths = $path; - } - $temp = $object; - - - foreach ($paths as $tempPath) { - if (is_array($temp)) { - $valuePresent = $defaultOnEmpty ? !empty($temp[$tempPath]) : isset($temp[$tempPath]); - if ($valuePresent) { - $temp = $temp[$tempPath]; - } else { - return $defaultValue; - } - }elseif(is_object($temp)){ - $valuePresentObject = $defaultOnEmpty ? !empty($temp->{$tempPath}):isset($temp->{$tempPath}) ; - if ($valuePresentObject) { - $temp = $temp->{$tempPath}; - } else { - return $defaultValue; - } - }else{ - return $defaultValue; - } - } - - - return $temp; -} \ No newline at end of file diff --git a/src/Object/get.php b/src/Object/get.php new file mode 100644 index 0000000..84e8268 --- /dev/null +++ b/src/Object/get.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2019 + */ + +namespace _; + +use function _\internal\baseGet; + +/** + * Gets the value at path of object. If the resolved value is null the defaultValue is returned in its place. + * + * @category Object + * + * @param mixed $object The associative array or object to fetch value from + * @param array|string $path Dot separated or array of string + * @param mixed $defaultValue (optional)The value returned for unresolved or null values. + * + * @return mixed Returns the resolved value. + * + * @author punit-kulal + * + * @example + * + * $sampleArray = ["key1" => ["key2" => ["key3" => "val1", "key4" => ""]]]; + * get($sampleArray, 'key1.key2.key3'); + * // => "val1" + * + * get($sampleArray, 'key1.key2.key5', "default"); + * // => "default" + * + * get($sampleArray, 'key1.key2.key4', "default"); + * // => "" + * + */ +function get($object, $path, $defaultValue = null) +{ + return ($object !== null ? baseGet($object, $path) : null) ?? $defaultValue; +} diff --git a/src/Util/defaultTo.php b/src/Util/defaultTo.php new file mode 100644 index 0000000..79b8baf --- /dev/null +++ b/src/Util/defaultTo.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) 2019 + */ + +namespace _; + +/** + * Checks value to determine whether a default value should be returned in its place. + * The defaultValue is returned if value is NaN or null. + * + * @category Util + * + * @param mixed $value Any value. + * @param mixed $defaultValue Value to return when $value is null or NAN + * + * @return mixed Returns `value`. + * + * @author punit-kulal + * + * @example + * + * $a = null; + * + * defaultTo($a, "default"); + * // => "default" + * + * $a = "x"; + * + * defaultTo($a, "default"); + * // => "x" + * + */ +function defaultTo($value, $defaultValue) +{ + return (null !== $value && (is_object($value) || !\is_nan(\floatval($value)))) ? $value : $defaultValue; +} diff --git a/src/Util/property.php b/src/Util/property.php index 1bc0f40..17f75f0 100644 --- a/src/Util/property.php +++ b/src/Util/property.php @@ -11,6 +11,8 @@ namespace _; +use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException; +use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; use Symfony\Component\PropertyAccess\PropertyAccess; /** @@ -60,6 +62,10 @@ function property($path): callable } } - return $propertyAccess->getValue($value, $path); + try { + return $propertyAccess->getValue($value, $path); + } catch (NoSuchPropertyException | NoSuchIndexException $e) { + return null; + } }; } diff --git a/src/internal/baseGet.php b/src/internal/baseGet.php index c91a3d6..a9ff96a 100644 --- a/src/internal/baseGet.php +++ b/src/internal/baseGet.php @@ -20,9 +20,9 @@ function baseGet($object, $path) $index = 0; $length = \count($path); - while ($object !== null && $index < $length) { + while ($object !== null && !is_scalar($object) && $index < $length) { $object = property(toKey($path[$index++]))($object); } - return ($index > 0 && $index === $length) ? $object : null; + return ($index > 0 && $index === $length) ? $object : null; } diff --git a/tests/Collection/GetTest.php b/tests/Object/GetTest.php similarity index 50% rename from tests/Collection/GetTest.php rename to tests/Object/GetTest.php index 244d200..4fb02bb 100644 --- a/tests/Collection/GetTest.php +++ b/tests/Object/GetTest.php @@ -2,50 +2,48 @@ declare(strict_types=1); /* -* This file is part of the SolidWorx Lodash-PHP project. -* -* @author punit-kulal -* @copyright Copyright (c) 2017 -*/ + * This file is part of the SolidWorx Lodash-PHP project. + * + * @author Pierre du Plessis + * @copyright Copyright (c) 2019 + */ use function _\get; use PHPUnit\Framework\TestCase; class GetTest extends TestCase { - - public function testGetArray(){ + public function testGetArray() + { $actualValue1 = "data"; $sampleArray = ["key1" => ["key2" => ["key3" => $actualValue1, "key4" => ""]]]; $defaultValue = "default"; - $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", "default"),"Default To method 1 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue),"Default To method 2 failed"); - $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue),"Default To method 3 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method 4 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method 5 failed"); - $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue),"Default To method 6 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key4", $defaultValue, true),"Default To method 7 failed"); - $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue),"Default To method 8 failed"); - - $this->assertSame($sampleArray["key1"]["key2"], _::get($sampleArray, "key1.key2", $defaultValue),"Default To method 9 failed"); - $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue),"Default To method 10 failed"); + $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", "default"), "Default To method 1 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue), "Default To method 2 failed"); + $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue), "Default To method 3 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue), "Default To method 4 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue), "Default To method 5 failed"); + $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue), "Default To method 6 failed"); + $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue), "Default To method 8 failed"); + + $this->assertSame($sampleArray["key1"]["key2"], _::get($sampleArray, "key1.key2", $defaultValue), "Default To method 9 failed"); + $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue), "Default To method 10 failed"); } - public function testDefaultToObject(){ + public function testDefaultToObject() + { $actualValue1 = "data"; $sampleArray = (object)["key1" => (object)["key2" => (object)["key3" => $actualValue1, "key4" => ""]]]; $defaultValue = "default"; - $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", $defaultValue),"Default To method object 1 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue),"Default To method object 2 failed"); - $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue),"Default To method object 3 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method object 4 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue),"Default To method object 5 failed"); - $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue),"Default To method object 6 failed"); - $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key4", $defaultValue, true),"Default To method object 7 failed"); - $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue),"Default To method object 8 failed"); - - $this->assertSame($sampleArray->key1->key2, _::get($sampleArray, "key1.key2", $defaultValue),"Default To method object 9 failed"); - $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue),"Default To method 10 failed"); + $this->assertSame($actualValue1, get($sampleArray, "key1.key2.key3", $defaultValue), "Default To method object 1 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key2.key2.key3", $defaultValue), "Default To method object 2 failed"); + $this->assertSame($actualValue1, get($sampleArray, ["key1","key2","key3"], $defaultValue), "Default To method object 3 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue), "Default To method object 4 failed"); + $this->assertSame($defaultValue, get($sampleArray, "key1.key2.key3.key4", $defaultValue), "Default To method object 5 failed"); + $this->assertSame($defaultValue, get($sampleArray, ["key1","key2","key3","key4"], $defaultValue), "Default To method object 6 failed"); + $this->assertSame("", get($sampleArray, "key1.key2.key4", $defaultValue), "Default To method object 8 failed"); + + $this->assertSame($sampleArray->key1->key2, _::get($sampleArray, "key1.key2", $defaultValue), "Default To method object 9 failed"); + $this->assertSame($defaultValue, _::get($sampleArray, "key1.key3", $defaultValue), "Default To method 10 failed"); } - -} \ No newline at end of file +} diff --git a/tests/Util/DefaultToTest.php b/tests/Util/DefaultToTest.php new file mode 100644 index 0000000..f428473 --- /dev/null +++ b/tests/Util/DefaultToTest.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) 2019 + */ + +use function _\defaultTo; +use PHPUnit\Framework\TestCase; + +class DefaultToTest extends TestCase +{ + public function testDefaultTo() + { + $null = null; + $default = "defaultValue"; + $realValue = "string"; + $this->assertSame($default, defaultTo($null, $default), "DefaultTo 1 failed"); + $this->assertSame($default, defaultTo(NAN, $default), "DefaultTo 2 failed"); + $this->assertSame($realValue, defaultTo($realValue, $default), "DefaultTo 3 failed"); + $this->assertSame("", defaultTo("", $default), "DefaultTo 4 failed"); + } +} From 3108696babb79ab9d119a485745cd6700c851f3d Mon Sep 17 00:00:00 2001 From: wizu Date: Wed, 26 Aug 2020 10:37:02 +0200 Subject: [PATCH 129/159] Add Symfony 5 support (#25) Co-authored-by: mwitek --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 2e5251c..c363e26 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ }, "require": { "php": ">=7.1", - "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0", - "symfony/property-access": "^2.7 | ^3.0 | ^4.0" + "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0", + "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0" }, "require-dev": { "phpdocumentor/reflection-docblock": "^4.2", From 9083fdc398db5594b3d6909338d8b824e661955b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Mon, 21 Sep 2020 13:54:55 +0200 Subject: [PATCH 130/159] Always include unicode constants first Fixes #26 --- src/bootstrap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap.php b/src/bootstrap.php index 1e9b200..8bc7456 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -13,6 +13,7 @@ require_once $file; } else { require_once __DIR__.'/internal/Traits/CacheDataTrait.php'; + require_once __DIR__.'/internal/unicode.php'; require_once __DIR__.'/CacheInterface.php'; foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS)) as $file) { From fb7d6d76c1e0703830b8879c2cfb4b1c2e0caed3 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Thu, 20 Jan 2022 22:16:24 +0200 Subject: [PATCH 131/159] Migrate from Travis to GH Actions (#29) * Migrate from Travis to GH Actions * Add bamarni/composer-bin-plugin to composer allowed plugins * Ensure composer scripts are run in CI * Fix unit tests yaml file * Remove incompatible PHP versions form CI --- .github/workflows/cs.yml | 37 + .github/workflows/static-analysis.yml | 37 + .github/workflows/tests.yml | 87 ++ .travis.yml | 35 - composer.json | 5 + vendor-bin/php-cs-fixer/composer.lock | 1949 +++++++++++++++++++------ vendor-bin/phpstan/composer.json | 5 + vendor-bin/phpstan/composer.lock | 1102 ++++++++++---- vendor-bin/phpunit/composer.lock | 713 ++++++--- 9 files changed, 2978 insertions(+), 992 deletions(-) create mode 100644 .github/workflows/cs.yml create mode 100644 .github/workflows/static-analysis.yml create mode 100644 .github/workflows/tests.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/cs.yml b/.github/workflows/cs.yml new file mode 100644 index 0000000..a269994 --- /dev/null +++ b/.github/workflows/cs.yml @@ -0,0 +1,37 @@ +on: + pull_request: + +name: Coding Standards + +jobs: + phpstan: + name: PHP CS + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + tools: composer + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist + + - name: PHP-CS-Fixer + run: vendor/bin/php-cs-fixer fix --dry-run -v diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..d554eb4 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,37 @@ +on: + pull_request: + +name: Static Analysis + +jobs: + phpstan: + name: PHPStan + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + tools: composer + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist + + - name: PHPStan + run: vendor/bin/phpstan analyse ./src -c phpstan.neon --level=6 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..fa4d5ce --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,87 @@ +name: Unit Tests + +on: + push: + branches: + - master + pull_request: ~ + +jobs: + unit-test: + name: Unit ( PHP ${{ matrix.php }} ) + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - php: 7.1 + - php: 7.2 + - php: 7.3 + - php: 7.4 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: opcache + tools: composer + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json composer.lock') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php }}-composer- + + - name: Install dependencies + run: composer update + + - name: Run unit tests + run: vendor/bin/phpunit + + lowest: + name: Unit ( PHP ${{ matrix.php }} + Lowest ) + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - php: 7.1 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: :xdebug + tools: composer + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json composer.lock') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php }}-composer- + + - name: Install dependencies + run: composer update --prefer-lowest --prefer-stable + + - name: Run unit tests + run: vendor/bin/phpunit diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9278f2b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: php - -sudo: false - -env: - - COMPOSER_OPTIONS="" - -matrix: - fast_finish: true - include: - - php: 7.1 - env: - - COMPOSER_OPTIONS="--prefer-lowest" - script: vendor/bin/phpunit - - php: 7.1 - env: - - COMPOSER_OPTIONS="--prefer-stable" - - php: 7.2 - script: vendor/bin/phpunit - - php: 7.3 - script: vendor/bin/phpunit - - php: 7.4snapshot - script: vendor/bin/phpunit - -cache: - directories: - - $HOME/.composer/cache/files - -install: - - composer update -n "$COMPOSER_OPTIONS" - -script: - - vendor/bin/php-cs-fixer fix --dry-run -v - - vendor/bin/phpunit - - vendor/bin/phpstan analyse ./src -c phpstan.neon --level=6 diff --git a/composer.json b/composer.json index c363e26..d778be9 100644 --- a/composer.json +++ b/composer.json @@ -35,5 +35,10 @@ "scripts": { "post-install-cmd": ["@composer bin all install --ansi"], "post-update-cmd": ["@composer bin all update --ansi"] + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + } } } diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock index 0145aaa..c5f5ebc 100644 --- a/vendor-bin/php-cs-fixer/composer.lock +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -6,31 +6,102 @@ ], "content-hash": "6164bfe4091cb1fe1c219656f116f002", "packages": [ + { + "name": "composer/pcre", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-12-06T15:17:27+00:00" + }, { "name": "composer/semver", - "version": "1.4.2", + "version": "3.2.7", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + "reference": "deac27056b57e46faf136fae7b449eeaa71661ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "url": "https://api.github.com/repos/composer/semver/zipball/deac27056b57e46faf136fae7b449eeaa71661ee", + "reference": "deac27056b57e46faf136fae7b449eeaa71661ee", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + "phpstan/phpstan": "^0.12.54", + "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -66,28 +137,50 @@ "validation", "versioning" ], - "time": "2016-08-30T16:08:34+00:00" + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.7" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-04T09:57:54+00:00" }, { "name": "composer/xdebug-handler", - "version": "1.3.1", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "dc523135366eb68f22268d069ea7749486458562" + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", - "reference": "dc523135366eb68f22268d069ea7749486458562", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0", - "psr/log": "^1.0" + "composer/pcre": "^1", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" }, "type": "library", "autoload": { @@ -95,7 +188,7 @@ "Composer\\XdebugHandler\\": "src" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -105,41 +198,60 @@ "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Restarts a process without xdebug.", + "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], - "time": "2018-11-29T10:59:02+00:00" + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/2.0.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-04T17:06:45+00:00" }, { "name": "doctrine/annotations", - "version": "v1.6.0", + "version": "1.13.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + "reference": "5b668aef16090008790395c02c893b1ba13f7e08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08", "shasum": "" }, "require": { "doctrine/lexer": "1.*", - "php": "^7.1" + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^6.4" + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" @@ -150,6 +262,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -158,10 +274,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -172,40 +284,45 @@ } ], "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", "keywords": [ "annotations", "docblock", "parser" ], - "time": "2017-12-06T07:11:42+00:00" + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.2" + }, + "time": "2021-08-05T19:00:23+00:00" }, { "name": "doctrine/lexer", - "version": "v1.0.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", + "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^7.1 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" }, + "type": "library", "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } }, "notification-url": "https://packagist.org/downloads/", @@ -213,77 +330,99 @@ "MIT" ], "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", "keywords": [ + "annotations", + "docblock", "lexer", - "parser" + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } ], - "time": "2014-09-09T13:34:57+00:00" + "time": "2022-01-12T08:27:12+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.13.1", + "version": "v2.19.3", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "54814c62d5beef3ba55297b9b3186ed8b8a1b161" + "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/54814c62d5beef3ba55297b9b3186ed8b8a1b161", - "reference": "54814c62d5beef3ba55297b9b3186ed8b8a1b161", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/75ac86f33fab4714ea5a39a396784d83ae3b5ed8", + "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8", "shasum": "" }, "require": { - "composer/semver": "^1.4", - "composer/xdebug-handler": "^1.2", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^1.2 || ^2.0", "doctrine/annotations": "^1.2", "ext-json": "*", "ext-tokenizer": "*", - "php": "^5.6 || >=7.0 <7.3", + "php": "^5.6 || ^7.0 || ^8.0", "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.17 || ^4.1.6", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", + "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^3.0 || ^4.0 || ^5.0", + "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", "symfony/polyfill-php70": "^1.0", "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" - }, - "conflict": { - "hhvm": "*" + "symfony/process": "^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { - "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.1", + "keradus/cli-executor": "^1.4", "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.1", + "php-coveralls/php-coveralls": "^2.4.2", "php-cs-fixer/accessible-object": "^1.0", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.0.1", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.0.1", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", - "phpunitgoodpractices/traits": "^1.5.1", - "symfony/phpunit-bridge": "^4.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy-phpunit": "^1.1 || ^2.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5", + "phpunitgoodpractices/polyfill": "^1.5", + "phpunitgoodpractices/traits": "^1.9.1", + "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1", + "symfony/phpunit-bridge": "^5.2.1", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" }, "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters.", "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." @@ -292,6 +431,11 @@ "php-cs-fixer" ], "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.19-dev" + } + }, "autoload": { "psr-4": { "PhpCsFixer\\": "src/" @@ -305,90 +449,57 @@ "tests/Test/IntegrationCaseFactory.php", "tests/Test/IntegrationCaseFactoryInterface.php", "tests/Test/InternalIntegrationCaseFactory.php", + "tests/Test/IsIdenticalConstraint.php", + "tests/Test/TokensWithObservedTransformers.php", "tests/TestCase.php" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" } ], "description": "A tool to automatically fix PHP code style", - "time": "2018-10-21T00:32:10+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.99", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "shasum": "" - }, - "require": { - "php": "^7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.19.3" }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" + "url": "https://github.com/keradus", + "type": "github" } ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "time": "2018-07-02T15:55:56+00:00" + "time": "2021-11-15T17:17:55+00:00" }, { "name": "php-cs-fixer/diff", - "version": "v1.3.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", - "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/dbd31aeb251639ac0b9e7e29405c1441907f5759", + "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^5.6 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", "symfony/process": "^3.3" }, "type": "library", @@ -402,14 +513,14 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, { "name": "SpacePossum" } @@ -419,20 +530,24 @@ "keywords": [ "diff" ], - "time": "2018-02-15T16:58:55+00:00" + "support": { + "issues": "https://github.com/PHP-CS-Fixer/diff/issues", + "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1" + }, + "time": "2020-10-14T08:39:05+00:00" }, { - "name": "psr/log", - "version": "1.1.0", + "name": "psr/cache", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", "shasum": "" }, "require": { @@ -446,10 +561,10 @@ }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Cache\\": "src/" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -459,240 +574,516 @@ "homepage": "http://www.php-fig.org/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Common interface for caching libraries", "keywords": [ - "log", + "cache", "psr", - "psr-3" + "psr-6" ], - "time": "2018-11-20T15:27:04+00:00" + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" }, { - "name": "symfony/console", - "version": "v4.2.1", + "name": "psr/container", + "version": "1.1.2", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", - "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0" - }, - "suggest": { - "psr/log-implementation": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "php": ">=7.4.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Psr\\Container\\": "src/" + } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2018-11-27T07:40:44+00:00" + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { - "name": "symfony/contracts", - "version": "v1.0.2", + "name": "psr/event-dispatcher", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/contracts.git", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": "^7.1.3" - }, - "require-dev": { - "psr/cache": "^1.0", - "psr/container": "^1.0" - }, - "suggest": { - "psr/cache": "When using the Cache contracts", - "psr/container": "When using the Service contracts", - "symfony/cache-contracts-implementation": "", - "symfony/service-contracts-implementation": "", - "symfony/translation-contracts-implementation": "" + "php": ">=7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { - "Symfony\\Contracts\\": "" - }, - "exclude-from-classmap": [ - "**/Tests/" - ] + "Psr\\EventDispatcher\\": "src/" + } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "A set of abstractions extracted out of the Symfony components", - "homepage": "https://symfony.com", + "description": "Standard interfaces for event handling.", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "events", + "psr", + "psr-14" ], - "time": "2018-12-05T08:06:11+00:00" + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v4.2.1", + "name": "psr/log", + "version": "1.1.4", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "921f49c3158a276d27c0d770a5a347a3b718b328" + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/921f49c3158a276d27c0d770a5a347a3b718b328", - "reference": "921f49c3158a276d27c0d770a5a347a3b718b328", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Psr\\Log\\": "Psr/Log/" + } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2018-12-01T08:52:38+00:00" + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" }, { - "name": "symfony/filesystem", - "version": "v4.2.1", + "name": "symfony/console", + "version": "v5.4.2", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710" + "url": "https://github.com/symfony/console.git", + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-12-20T16:11:12+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-12T14:48:14+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/27d39ae126352b9fa3be5e196ccf4617897be3eb", + "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T10:19:22+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/2f4c8b999b3b7cadb2a69390b01af70886753710", - "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-ctype": "~1.8" + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } + ], + "time": "2021-07-12T14:48:14+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -701,224 +1092,773 @@ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-28T13:39:27+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "e77046c252be48c48a40816187ed527703c8f76c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/e77046c252be48c48a40816187ed527703c8f76c", + "reference": "e77046c252be48c48a40816187ed527703c8f76c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-12-15T11:06:13+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "b0fb78576487af19c500aaddb269fd36701d4847" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b0fb78576487af19c500aaddb269fd36701d4847", + "reference": "b0fb78576487af19c500aaddb269fd36701d4847", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T10:19:22+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", - "time": "2018-11-11T19:52:12+00:00" + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-30T18:21:41+00:00" }, { - "name": "symfony/finder", - "version": "v4.2.1", + "name": "symfony/polyfill-php70", + "version": "v1.20.0", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", - "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1" }, - "type": "library", + "type": "metapackage", "extra": { "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" + "dev-main": "1.20-dev" }, - "exclude-from-classmap": [ - "/Tests/" - ] + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", "homepage": "https://symfony.com", - "time": "2018-11-11T19:52:12+00:00" + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" }, { - "name": "symfony/options-resolver", - "version": "v4.2.1", + "name": "symfony/polyfill-php72", + "version": "v1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba" + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", - "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" + "Symfony\\Polyfill\\Php72\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony OptionsResolver Component", + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ - "config", - "configuration", - "options" + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-11-11T19:52:12+00:00" + "time": "2021-05-27T09:17:38+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "name": "symfony/polyfill-php73", + "version": "v1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "Symfony\\Polyfill\\Php73\\": "" }, "files": [ "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "ctype", "polyfill", - "portable" + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2021-06-05T21:20:04+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "name": "symfony/polyfill-php80", + "version": "v1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "Symfony\\Polyfill\\Php80\\": "" }, "files": [ "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -928,108 +1868,136 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", "polyfill", "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:33+00:00" }, { - "name": "symfony/polyfill-php70", - "version": "v1.10.0", + "name": "symfony/process", + "version": "v5.4.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" + "url": "https://github.com/symfony/process.git", + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", + "url": "https://api.github.com/repos/symfony/process/zipball/2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", "shasum": "" }, "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" + "Symfony\\Component\\Process\\": "" }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-09-21T06:26:08+00:00" + "time": "2021-12-27T21:01:00+00:00" }, { - "name": "symfony/polyfill-php72", - "version": "v1.10.0", + "name": "symfony/service-contracts", + "version": "v2.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] + "Symfony\\Contracts\\Service\\": "" + } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -1043,48 +2011,63 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { - "name": "symfony/process", - "version": "v4.2.1", + "name": "symfony/stopwatch", + "version": "v5.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2b341009ccec76837a7f46f59641b431e4d4c2b0", - "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/208ef96122bfed82a8f3a61458a07113a08bdcfe", + "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "symfony/service-contracts": "^1|^2|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { - "Symfony\\Component\\Process\\": "" + "Symfony\\Component\\Stopwatch\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -1098,59 +2081,112 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "time": "2018-11-20T16:22:05+00:00" + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T10:19:22+00:00" }, { - "name": "symfony/stopwatch", - "version": "v4.2.1", + "name": "symfony/string", + "version": "v5.4.2", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "ec076716412274e51f8a7ea675d9515e5c311123" + "url": "https://github.com/symfony/string.git", + "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/ec076716412274e51f8a7ea675d9515e5c311123", - "reference": "ec076716412274e51f8a7ea675d9515e5c311123", + "url": "https://api.github.com/repos/symfony/string/zipball/e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", + "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0" + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, + "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\String\\": "" }, + "files": [ + "Resources/functions.php" + ], "exclude-from-classmap": [ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", - "time": "2018-11-11T19:52:12+00:00" + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-12-16T21:52:00+00:00" } ], "packages-dev": [], @@ -1160,5 +2196,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json index d7c0420..49ec786 100644 --- a/vendor-bin/phpstan/composer.json +++ b/vendor-bin/phpstan/composer.json @@ -1,5 +1,10 @@ { "require": { "phpstan/phpstan": "^0.10.3" + }, + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true + } } } diff --git a/vendor-bin/phpstan/composer.lock b/vendor-bin/phpstan/composer.lock index 0ff13a3..08d207d 100644 --- a/vendor-bin/phpstan/composer.lock +++ b/vendor-bin/phpstan/composer.lock @@ -6,26 +6,100 @@ ], "content-hash": "885b295492a97a537399d0d309928b59", "packages": [ + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.5", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-17T14:14:24+00:00" + }, { "name": "composer/xdebug-handler", - "version": "1.3.1", + "version": "1.4.6", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "dc523135366eb68f22268d069ea7749486458562" + "reference": "f27e06cd9675801df441b3656569b328e04aa37c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", - "reference": "dc523135366eb68f22268d069ea7749486458562", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c", + "reference": "f27e06cd9675801df441b3656569b328e04aa37c", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0", + "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "autoload": { @@ -33,7 +107,7 @@ "Composer\\XdebugHandler\\": "src" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -43,33 +117,52 @@ "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Restarts a process without xdebug.", + "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], - "time": "2018-11-29T10:59:02+00:00" + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.6" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-03-25T17:01:18+00:00" }, { "name": "jean85/pretty-package-versions", - "version": "1.2", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + "reference": "1e0104b46f045868f11942aea058cd7186d6c303" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", - "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", + "reference": "1e0104b46f045868f11942aea058cd7186d6c303", "shasum": "" }, "require": { - "ocramius/package-versions": "^1.2.0", - "php": "^7.0" + "composer/package-versions-deprecated": "^1.8.0", + "php": "^7.0|^8.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^6.0|^8.5|^9.2" }, "type": "library", "extra": { @@ -99,43 +192,48 @@ "release", "versions" ], - "time": "2018-06-13T13:22:40+00:00" + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" + }, + "time": "2021-02-04T16:20:16+00:00" }, { "name": "nette/bootstrap", - "version": "v2.4.6", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/nette/bootstrap.git", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + "reference": "3ab4912a08af0c16d541c3709935c3478b5ee090" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/3ab4912a08af0c16d541c3709935c3478b5ee090", + "reference": "3ab4912a08af0c16d541c3709935c3478b5ee090", "shasum": "" }, "require": { - "nette/di": "~2.4.7", - "nette/utils": "~2.4", - "php": ">=5.6.0" + "nette/di": "^3.0.5", + "nette/utils": "^3.2.1", + "php": ">=7.2 <8.2" }, "conflict": { - "nette/nette": "<2.2" + "tracy/tracy": "<2.6" }, "require-dev": { - "latte/latte": "~2.2", - "nette/application": "~2.3", - "nette/caching": "~2.3", - "nette/database": "~2.3", - "nette/forms": "~2.3", - "nette/http": "~2.4.0", - "nette/mail": "~2.3", - "nette/robot-loader": "^2.4.2 || ^3.0", - "nette/safe-stream": "~2.2", - "nette/security": "~2.3", - "nette/tester": "~2.0", - "tracy/tracy": "^2.4.1" + "latte/latte": "^2.8", + "nette/application": "^3.1", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0", + "nette/robot-loader": "^3.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.0", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.6" }, "suggest": { "nette/robot-loader": "to use Configurator::createRobotLoader()", @@ -144,7 +242,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -155,8 +253,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -168,48 +266,54 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", "homepage": "https://nette.org", "keywords": [ "bootstrapping", "configurator", "nette" ], - "time": "2018-05-17T12:52:20+00:00" + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.1.2" + }, + "time": "2021-11-24T16:51:46+00:00" }, { "name": "nette/di", - "version": "v2.4.14", + "version": "v3.0.12", "source": { "type": "git", "url": "https://github.com/nette/di.git", - "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a" + "reference": "11c236b9f7bbfc5a95e7b24742ad8847936feeb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/923da3e2c0aa53162ef455472c0ac7787b096c5a", - "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a", + "url": "https://api.github.com/repos/nette/di/zipball/11c236b9f7bbfc5a95e7b24742ad8847936feeb5", + "reference": "11c236b9f7bbfc5a95e7b24742ad8847936feeb5", "shasum": "" }, "require": { "ext-tokenizer": "*", - "nette/neon": "^2.3.3 || ~3.0.0", - "nette/php-generator": "^2.6.1 || ~3.0.0", - "nette/utils": "^2.4.3 || ~3.0.0", - "php": ">=5.6.0" + "nette/neon": "^3.3", + "nette/php-generator": "^3.5.4", + "nette/robot-loader": "^3.2", + "nette/schema": "^1.1", + "nette/utils": "^3.1.6", + "php": ">=7.1 <8.2" }, "conflict": { - "nette/bootstrap": "<2.4", - "nette/nette": "<2.2" + "nette/bootstrap": "<3.0" }, "require-dev": { - "nette/tester": "^2.0", + "nette/tester": "^2.2", + "phpstan/phpstan": "^0.12", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -217,11 +321,11 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -233,7 +337,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", "homepage": "https://nette.org", "keywords": [ "compiled", @@ -244,37 +348,42 @@ "nette", "static" ], - "time": "2018-09-17T15:47:40+00:00" + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.0.12" + }, + "time": "2021-12-15T21:05:11+00:00" }, { "name": "nette/finder", - "version": "v2.4.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/nette/finder.git", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" + "reference": "64dc25b7929b731e72a1bc84a9e57727f5d5d3e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", + "url": "https://api.github.com/repos/nette/finder/zipball/64dc25b7929b731e72a1bc84a9e57727f5d5d3e8", + "reference": "64dc25b7929b731e72a1bc84a9e57727f5d5d3e8", "shasum": "" }, "require": { - "nette/utils": "~2.4", - "php": ">=5.6.0" + "nette/utils": "^2.4 || ^3.0", + "php": ">=7.1" }, "conflict": { "nette/nette": "<2.2" }, "require-dev": { - "nette/tester": "~2.0", + "nette/tester": "^2.0", + "phpstan/phpstan": "^0.12", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "2.5-dev" } }, "autoload": { @@ -285,8 +394,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -306,35 +415,42 @@ "iterator", "nette" ], - "time": "2018-06-28T11:49:23+00:00" + "support": { + "issues": "https://github.com/nette/finder/issues", + "source": "https://github.com/nette/finder/tree/v2.5.3" + }, + "time": "2021-12-12T17:43:24+00:00" }, { "name": "nette/neon", - "version": "v2.4.3", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/nette/neon.git", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398" + "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "url": "https://api.github.com/repos/nette/neon/zipball/54b287d8c2cdbe577b02e28ca1713e275b05ece2", + "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2", "shasum": "" }, "require": { - "ext-iconv": "*", "ext-json": "*", - "php": ">=5.6.0" + "php": ">=7.1" }, "require-dev": { - "nette/tester": "~2.0", - "tracy/tracy": "^2.3" + "nette/tester": "^2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.7" }, + "bin": [ + "bin/neon-lint" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "3.3-dev" } }, "autoload": { @@ -345,8 +461,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -359,7 +475,7 @@ } ], "description": "🍸 Nette NEON: encodes and decodes NEON file format.", - "homepage": "http://ne-on.org", + "homepage": "https://ne-on.org", "keywords": [ "export", "import", @@ -367,37 +483,43 @@ "nette", "yaml" ], - "time": "2018-03-21T12:12:21+00:00" + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.3.2" + }, + "time": "2021-11-25T15:57:41+00:00" }, { "name": "nette/php-generator", - "version": "v3.0.5", + "version": "v3.6.5", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff" + "reference": "9370403f9d9c25b51c4596ded1fbfe70347f7c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/ea90209c2e8a7cd087b2742ca553c047a8df5eff", - "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff", + "url": "https://api.github.com/repos/nette/php-generator/zipball/9370403f9d9c25b51c4596ded1fbfe70347f7c82", + "reference": "9370403f9d9c25b51c4596ded1fbfe70347f7c82", "shasum": "" }, "require": { - "nette/utils": "^2.4.2 || ~3.0.0", - "php": ">=7.0" - }, - "conflict": { - "nette/nette": "<2.2" + "nette/utils": "^3.1.2", + "php": ">=7.2 <8.2" }, "require-dev": { - "nette/tester": "^2.0", - "tracy/tracy": "^2.3" + "nette/tester": "^2.4", + "nikic/php-parser": "^4.13", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::withBodiesFrom() & GlobalFunction::withBodyFrom()" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.6-dev" } }, "autoload": { @@ -408,8 +530,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -421,7 +543,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.1 features.", "homepage": "https://nette.org", "keywords": [ "code", @@ -429,39 +551,41 @@ "php", "scaffolding" ], - "time": "2018-08-09T14:32:27+00:00" + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v3.6.5" + }, + "time": "2021-11-24T16:23:44+00:00" }, { "name": "nette/robot-loader", - "version": "v3.1.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", - "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4" + "reference": "e2adc334cb958164c050f485d99c44c430f51fe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4", - "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/e2adc334cb958164c050f485d99c44c430f51fe2", + "reference": "e2adc334cb958164c050f485d99c44c430f51fe2", "shasum": "" }, "require": { "ext-tokenizer": "*", - "nette/finder": "^2.3 || ^3.0", - "nette/utils": "^2.4 || ^3.0", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" + "nette/finder": "^2.5 || ^3.0", + "nette/utils": "^3.0", + "php": ">=7.1" }, "require-dev": { "nette/tester": "^2.0", + "phpstan/phpstan": "^0.12", "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -469,11 +593,11 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -494,59 +618,124 @@ "nette", "trait" ], - "time": "2018-08-13T14:19:06+00:00" + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v3.4.1" + }, + "time": "2021-08-25T15:53:54+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" }, { "name": "nette/utils", - "version": "v2.5.3", + "version": "v3.2.6", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" + "reference": "2f261e55bd6a12057442045bf2c249806abc1d02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", - "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", + "url": "https://api.github.com/repos/nette/utils/zipball/2f261e55bd6a12057442045bf2c249806abc1d02", + "reference": "2f261e55bd6a12057442045bf2c249806abc1d02", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=7.2 <8.2" }, "conflict": { - "nette/nette": "<2.2" + "nette/di": "<3.0.6" }, "require-dev": { "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.3" }, "suggest": { "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize() and toAscii()", - "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", "ext-xml": "to use Strings::length() etc. when mbstring is not available" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "3.2-dev" } }, "autoload": { "classmap": [ "src/" - ], - "files": [ - "src/loader.php" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -558,7 +747,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", "homepage": "https://nette.org", "keywords": [ "array", @@ -576,20 +765,24 @@ "utility", "validation" ], - "time": "2018-09-18T10:22:16+00:00" + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.6" + }, + "time": "2021-11-24T15:47:23+00:00" }, { "name": "nikic/php-parser", - "version": "v4.1.0", + "version": "v4.2.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "d0230c5c77a7e3cfa69446febf340978540958c0" + "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/d0230c5c77a7e3cfa69446febf340978540958c0", - "reference": "d0230c5c77a7e3cfa69446febf340978540958c0", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", + "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", "shasum": "" }, "require": { @@ -597,7 +790,8 @@ "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.0" + "ircmaxell/php-yacc": "0.0.4", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" }, "bin": [ "bin/php-parse" @@ -605,7 +799,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -613,7 +807,7 @@ "PhpParser\\": "lib/PhpParser" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -627,81 +821,37 @@ "parser", "php" ], - "time": "2018-10-10T09:24:14+00:00" - }, - { - "name": "ocramius/package-versions", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0.0", - "php": "^7.1.0" - }, - "require-dev": { - "composer/composer": "^1.6.3", - "ext-zip": "*", - "infection/infection": "^0.7.1", - "phpunit/phpunit": "^7.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/master" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-02-05T13:05:30+00:00" + "time": "2019-10-25T18:33:07+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "0.3", + "version": "0.3.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "ed3223362174b8067729930439e139794e9e514a" + "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ed3223362174b8067729930439e139794e9e514a", - "reference": "ed3223362174b8067729930439e139794e9e514a", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/8c4ef2aefd9788238897b678a985e1d5c8df6db4", + "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4", "shasum": "" }, "require": { "php": "~7.1" }, "require-dev": { - "consistence/coding-standard": "^2.0.0", + "consistence/coding-standard": "^3.5", "jakub-onderka/php-parallel-lint": "^0.9.2", "phing/phing": "^2.16.0", - "phpstan/phpstan": "^0.10@dev", + "phpstan/phpstan": "^0.10", "phpunit/phpunit": "^6.3", - "slevomat/coding-standard": "^3.3.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2", "symfony/process": "^3.4 || ^4.0" }, "type": "library", @@ -722,20 +872,24 @@ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", - "time": "2018-06-20T17:48:01+00:00" + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/master" + }, + "time": "2019-06-07T19:13:52+00:00" }, { "name": "phpstan/phpstan", - "version": "0.10.6", + "version": "0.10.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "f0252a5ab6b4a293fb25f218d9c64386f272280f" + "reference": "61840df60f50e186683ba35ece82efb66bd0ab2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f0252a5ab6b4a293fb25f218d9c64386f272280f", - "reference": "f0252a5ab6b4a293fb25f218d9c64386f272280f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/61840df60f50e186683ba35ece82efb66bd0ab2c", + "reference": "61840df60f50e186683ba35ece82efb66bd0ab2c", "shasum": "" }, "require": { @@ -745,7 +899,7 @@ "nette/di": "^2.4.7 || ^3.0", "nette/robot-loader": "^3.0.1", "nette/utils": "^2.4.5 || ^3.0", - "nikic/php-parser": "^4.0.2", + "nikic/php-parser": "4.0.2 - 4.2.5", "php": "~7.1", "phpstan/phpdoc-parser": "^0.3", "symfony/console": "~3.2 || ~4.0", @@ -790,25 +944,91 @@ ] } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2018-12-04T07:28:04+00:00" + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/0.10.9" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2020-01-07T15:26:30+00:00" + }, + { + "name": "psr/container", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/log", - "version": "1.1.0", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -817,7 +1037,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -825,14 +1045,14 @@ "Psr\\Log\\": "Psr/Log/" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -842,51 +1062,58 @@ "psr", "psr-3" ], - "time": "2018-11-20T15:27:04+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" }, { "name": "symfony/console", - "version": "v4.2.1", + "version": "v4.4.36", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" + "reference": "621379b62bb19af213b569b60013200b11dd576f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", - "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "url": "https://api.github.com/repos/symfony/console/zipball/621379b62bb19af213b569b60013200b11dd576f", + "reference": "621379b62bb19af213b569b60013200b11dd576f", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", "symfony/process": "<3.3" }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0" + "psr/log": "^1|^2", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -895,7 +1122,7 @@ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -909,53 +1136,60 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", - "time": "2018-11-27T07:40:44+00:00" + "support": { + "source": "https://github.com/symfony/console/tree/v4.4.36" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-12-15T10:33:10+00:00" }, { - "name": "symfony/contracts", - "version": "v1.0.2", + "name": "symfony/deprecation-contracts", + "version": "v2.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/contracts.git", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", - "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { - "php": "^7.1.3" - }, - "require-dev": { - "psr/cache": "^1.0", - "psr/container": "^1.0" - }, - "suggest": { - "psr/cache": "When using the Cache contracts", - "psr/container": "When using the Service contracts", - "symfony/cache-contracts-implementation": "", - "symfony/service-contracts-implementation": "", - "symfony/translation-contracts-implementation": "" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "psr-4": { - "Symfony\\Contracts\\": "" - }, - "exclude-from-classmap": [ - "**/Tests/" + "files": [ + "function.php" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -969,41 +1203,46 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A set of abstractions extracted out of the Symfony components", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2018-12-05T08:06:11+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/finder", - "version": "v4.2.1", + "version": "v4.4.36", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" + "reference": "1fef05633cd61b629e963e5d8200fb6b67ecf42c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", - "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "url": "https://api.github.com/repos/symfony/finder/zipball/1fef05633cd61b629e963e5d8200fb6b67ecf42c", + "reference": "1fef05633cd61b629e963e5d8200fb6b67ecf42c", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.1.3", + "symfony/polyfill-php80": "^1.16" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" @@ -1012,7 +1251,7 @@ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -1026,26 +1265,46 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", - "time": "2018-11-11T19:52:12+00:00" + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.36" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-12-15T10:33:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" }, "suggest": { "ext-mbstring": "For best performance" @@ -1053,7 +1312,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -1064,7 +1327,7 @@ "bootstrap.php" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -1087,7 +1350,269 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-06-05T21:20:04+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:33+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-04T16:48:04+00:00" } ], "packages-dev": [], @@ -1097,5 +1622,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock index 1fbb7f0..40afbaf 100644 --- a/vendor-bin/phpunit/composer.lock +++ b/vendor-bin/phpunit/composer.lock @@ -8,34 +8,31 @@ "packages": [ { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -49,36 +46,51 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.8.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/collections": "^1.0", @@ -106,7 +118,17 @@ "object", "object graph" ], - "time": "2018-06-11T23:09:50+00:00" + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" }, { "name": "phar-io/manifest", @@ -161,6 +183,10 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, "time": "2018-07-08T19:23:20+00:00" }, { @@ -208,39 +234,38 @@ } ], "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/master" + }, "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -262,44 +287,46 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -310,44 +337,50 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -360,42 +393,47 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + }, + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phpspec/prophecy", - "version": "1.8.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -423,7 +461,11 @@ "spy", "stub" ], - "time": "2018-08-05T17:53:17+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpunit/php-code-coverage", @@ -468,7 +510,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -486,27 +528,31 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + }, "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -519,7 +565,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -536,7 +582,17 @@ "filesystem", "iterator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:42:26+00:00" }, { "name": "phpunit/php-text-template", @@ -577,32 +633,36 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "2.0.0", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -626,25 +686,35 @@ "keywords": [ "timer" ], - "time": "2018-02-01T13:07:23+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.0.1", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" @@ -652,7 +722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -660,7 +730,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -675,20 +745,31 @@ "keywords": [ "tokenizer" ], - "time": "2018-10-30T05:52:18+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2021-07-26T12:15:06+00:00" }, { "name": "phpunit/phpunit", - "version": "7.5.0", + "version": "7.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352" + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/520723129e2b3fc1dc4c0953e43c9d40e1ecb352", - "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", "shasum": "" }, "require": { @@ -706,7 +787,7 @@ "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", + "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^4.0", @@ -741,7 +822,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -759,27 +840,31 @@ "testing", "xunit" ], - "time": "2018-12-07T07:08:12+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + }, + "time": "2020-01-08T08:45:45+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -804,29 +889,39 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", "shasum": "" }, "require": { - "php": "^7.1", + "php": ">=7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -844,6 +939,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -855,10 +954,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -868,27 +963,37 @@ "compare", "equality" ], - "time": "2018-07-12T15:12:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:04:30+00:00" }, { "name": "sebastian/diff", - "version": "3.0.1", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "366541b989927187c4ca70490a35615d3fef2dce" + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", - "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0", + "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", @@ -907,13 +1012,13 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", @@ -924,32 +1029,45 @@ "unidiff", "unified diff" ], - "time": "2018-06-10T07:54:39+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:59:04+00:00" }, { "name": "sebastian/environment", - "version": "4.0.1", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f" + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/febd209a219cea7b56ad799b30ebbea34b71eb8f", - "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.4" + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -957,7 +1075,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -974,29 +1092,39 @@ "environment", "hhvm" ], - "time": "2018-11-25T09:31:21+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", + "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { @@ -1014,6 +1142,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1022,17 +1154,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -1041,7 +1169,17 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T13:51:24+00:00" }, { "name": "sebastian/global-state", @@ -1092,24 +1230,28 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + }, "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, @@ -1139,24 +1281,34 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -1184,24 +1336,34 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" @@ -1222,14 +1384,14 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, { "name": "Adam Harvey", "email": "aharvey@php.net" @@ -1237,24 +1399,34 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.1" }, "type": "library", "extra": { @@ -1267,7 +1439,7 @@ "src/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -1279,7 +1451,17 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" }, { "name": "sebastian/version", @@ -1322,27 +1504,113 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1362,33 +1630,47 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.3.0", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^8.5.13" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.10-dev" } }, "autoload": { @@ -1412,7 +1694,11 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" } ], "packages-dev": [], @@ -1422,5 +1708,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.2.0" } From 92cb03679f5aee883100f972161b4d5d145ecd84 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:23:50 +0100 Subject: [PATCH 132/159] Fix for "PHP Deprecated: Using ${var} in strings is deprecated, use {$var} instead" --- src/String/template.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/String/template.php b/src/String/template.php index a035e74..559e2b4 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -120,17 +120,17 @@ function template(string $string, array $options = []): callable if ($escapeValue) { $escapeValue = \trim($escapeValue); - $source .= ""; + $source .= ""; } if ($evaluateValue) { - $source .= ""; + $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); - $source .= ""; + $source .= ""; } return $source; From 8cc5fa15cfc872e3ac01ca76173c9eeb9630e2ec Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:24:39 +0100 Subject: [PATCH 133/159] Use of `is_iterable` instead of `is_array($source) || $source instanceof Traversable` --- src/internal/baseMatches.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/baseMatches.php b/src/internal/baseMatches.php index d7c919b..3f39f4f 100644 --- a/src/internal/baseMatches.php +++ b/src/internal/baseMatches.php @@ -21,7 +21,7 @@ function baseMatches($source): callable return true; } - if (\is_array($source) || $source instanceof \Traversable) { + if (\is_iterable($source)) { foreach ($source as $k => $v) { if (!isEqual(property($k)($value, $index, $collection), $v)) { return false; From 2294511a7685957147e16542c409e25aa732a4df Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:25:27 +0100 Subject: [PATCH 134/159] Use of null coalesce operator, that comes with PHP7.1 --- src/String/truncate.php | 2 +- src/internal/castSlice.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/String/truncate.php b/src/String/truncate.php index cdca582..7fc4601 100644 --- a/src/String/truncate.php +++ b/src/String/truncate.php @@ -101,7 +101,7 @@ function truncate($string, array $options = []) $newEnd = \end($match[0])[1]; } - $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); + $result = \substr($result, 0, $newEnd ?? $end); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); diff --git a/src/internal/castSlice.php b/src/internal/castSlice.php index fcb027c..6d50495 100644 --- a/src/internal/castSlice.php +++ b/src/internal/castSlice.php @@ -25,7 +25,7 @@ function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); - $end = null === $end ? $length : $end; + $end = $end ?? $length; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } From bbc8fc469f70e450d5788d149be49494928784d9 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:26:05 +0100 Subject: [PATCH 135/159] The rand() function has been replaced with the random_int() function. This change provides more reliable randomness and mitigates potential security vulnerabilities associated with the previous function. --- src/Number/random.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Number/random.php b/src/Number/random.php index 7da25a7..7a72b97 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -74,5 +74,5 @@ function random($lower = null, $upper = null, $floating = null) return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } - return \rand((int) $lower, (int) $upper); + return random_int((int) $lower, (int) $upper); } From 822764e64df62939aa4f7447ea7a63e63691d289 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 11:46:44 +0200 Subject: [PATCH 136/159] Use root namespace for function call --- src/Number/random.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Number/random.php b/src/Number/random.php index 7a72b97..8d322af 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -74,5 +74,5 @@ function random($lower = null, $upper = null, $floating = null) return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } - return random_int((int) $lower, (int) $upper); + return \random_int((int) $lower, (int) $upper); } From 534a89f1b4ef86ba76fcc9af7934d19974a6d2b7 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:23:50 +0100 Subject: [PATCH 137/159] Fix for "PHP Deprecated: Using ${var} in strings is deprecated, use {$var} instead" --- src/String/template.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/String/template.php b/src/String/template.php index a035e74..559e2b4 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -120,17 +120,17 @@ function template(string $string, array $options = []): callable if ($escapeValue) { $escapeValue = \trim($escapeValue); - $source .= ""; + $source .= ""; } if ($evaluateValue) { - $source .= ""; + $source .= ""; } if ($interpolateValue) { $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); - $source .= ""; + $source .= ""; } return $source; From b557e47a82f2f3f9dbb0596dfad7cf2718bac195 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:24:39 +0100 Subject: [PATCH 138/159] Use of `is_iterable` instead of `is_array($source) || $source instanceof Traversable` --- src/internal/baseMatches.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/baseMatches.php b/src/internal/baseMatches.php index d7c919b..3f39f4f 100644 --- a/src/internal/baseMatches.php +++ b/src/internal/baseMatches.php @@ -21,7 +21,7 @@ function baseMatches($source): callable return true; } - if (\is_array($source) || $source instanceof \Traversable) { + if (\is_iterable($source)) { foreach ($source as $k => $v) { if (!isEqual(property($k)($value, $index, $collection), $v)) { return false; From 38197b5baa2e35643bff80ffa2567e5dea658d77 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:25:27 +0100 Subject: [PATCH 139/159] Use of null coalesce operator, that comes with PHP7.1 --- src/String/truncate.php | 2 +- src/internal/castSlice.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/String/truncate.php b/src/String/truncate.php index cdca582..7fc4601 100644 --- a/src/String/truncate.php +++ b/src/String/truncate.php @@ -101,7 +101,7 @@ function truncate($string, array $options = []) $newEnd = \end($match[0])[1]; } - $result = \substr($result, 0, null === $newEnd ? $end : $newEnd); + $result = \substr($result, 0, $newEnd ?? $end); } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); diff --git a/src/internal/castSlice.php b/src/internal/castSlice.php index fcb027c..6d50495 100644 --- a/src/internal/castSlice.php +++ b/src/internal/castSlice.php @@ -25,7 +25,7 @@ function castSlice(array $array, int $start, ?int $end = null): array { $length = \count($array); - $end = null === $end ? $length : $end; + $end = $end ?? $length; return (!$start && $end >= $length) ? $array : \array_slice($array, $start, $end); } From fc6005b1537f5c1933eea3e281fb28eb95b74985 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 10:26:05 +0100 Subject: [PATCH 140/159] The rand() function has been replaced with the random_int() function. This change provides more reliable randomness and mitigates potential security vulnerabilities associated with the previous function. --- src/Number/random.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Number/random.php b/src/Number/random.php index 7da25a7..7a72b97 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -74,5 +74,5 @@ function random($lower = null, $upper = null, $floating = null) return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } - return \rand((int) $lower, (int) $upper); + return random_int((int) $lower, (int) $upper); } From fece3181803f3c1a9d8dc1234bb732027188f15b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 11:46:44 +0200 Subject: [PATCH 141/159] Use root namespace for function call --- src/Number/random.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Number/random.php b/src/Number/random.php index 7a72b97..8d322af 100644 --- a/src/Number/random.php +++ b/src/Number/random.php @@ -74,5 +74,5 @@ function random($lower = null, $upper = null, $floating = null) return $lower + \abs($upper - $lower) * \mt_rand(0, $randMax) / $randMax; } - return random_int((int) $lower, (int) $upper); + return \random_int((int) $lower, (int) $upper); } From 706f23d299824a1a083c7030baa7cb3666107bbc Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 11:06:08 +0100 Subject: [PATCH 142/159] The `dropWhile` predicate in Array has been updated to use the current array value instead of directly referencing by index. --- src/Array/dropWhile.php | 4 +++- tests/Array/DropWhileTest.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Array/dropWhile.php b/src/Array/dropWhile.php index ce62b5f..fea0fe8 100644 --- a/src/Array/dropWhile.php +++ b/src/Array/dropWhile.php @@ -40,11 +40,13 @@ function dropWhile(array $array, callable $predicate): array $count = \count($array); $length = 0; $index = \key($array); - while ($length <= $count && $predicate($array[$index], $index, $array)) { + $value = \current($array); + while ($length <= $count && $predicate($value, $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); + $value = \current($array); } return $array; diff --git a/tests/Array/DropWhileTest.php b/tests/Array/DropWhileTest.php index 997f761..cf5a2e8 100644 --- a/tests/Array/DropWhileTest.php +++ b/tests/Array/DropWhileTest.php @@ -26,4 +26,23 @@ public function testDropWhile() return $user['active']; })); } + + public function testDropWhile2() + { + $lines = [ + 'Processing report:', + 'Processed: 1', + 'Successful: 1', + '', + '', + ]; + + $lines = dropWhile($lines, static function ($x) { return trim((string) $x) !== ''; }); + + self::assertEquals(['', ''], $lines); + + $lines = dropWhile($lines, static function ($x) { return trim((string) $x) === ''; }); + + self::assertEmpty($lines); + } } From 2888581c0e92499e3cbc8917246fd3fbae225a34 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 11:09:03 +0100 Subject: [PATCH 143/159] Fixed tabs -> spaces --- tests/Array/DropWhileTest.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/Array/DropWhileTest.php b/tests/Array/DropWhileTest.php index cf5a2e8..437813e 100644 --- a/tests/Array/DropWhileTest.php +++ b/tests/Array/DropWhileTest.php @@ -26,23 +26,23 @@ public function testDropWhile() return $user['active']; })); } - + public function testDropWhile2() { $lines = [ - 'Processing report:', - 'Processed: 1', - 'Successful: 1', - '', - '', + 'Processing report:', + 'Processed: 1', + 'Successful: 1', + '', + '', ]; - - $lines = dropWhile($lines, static function ($x) { return trim((string) $x) !== ''; }); - - self::assertEquals(['', ''], $lines); - - $lines = dropWhile($lines, static function ($x) { return trim((string) $x) === ''; }); - - self::assertEmpty($lines); + + $lines = dropWhile($lines, static function ($x) { return trim((string) $x) !== ''; }); + + self::assertEquals(['', ''], $lines); + + $lines = dropWhile($lines, static function ($x) { return trim((string) $x) === ''; }); + + self::assertEmpty($lines); } } From 0b131683b667cc7e24595da4d859774b0c0003a1 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 11:10:43 +0100 Subject: [PATCH 144/159] Fixed tabs -> spaces --- src/Array/dropWhile.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Array/dropWhile.php b/src/Array/dropWhile.php index fea0fe8..36020df 100644 --- a/src/Array/dropWhile.php +++ b/src/Array/dropWhile.php @@ -40,13 +40,13 @@ function dropWhile(array $array, callable $predicate): array $count = \count($array); $length = 0; $index = \key($array); - $value = \current($array); + $value = \current($array); while ($length <= $count && $predicate($value, $index, $array)) { array_shift($array); \reset($array); $length++; $index = \key($array); - $value = \current($array); + $value = \current($array); } return $array; From 894cd2aeb44bef10418bfb6599505d2a9c2d27d5 Mon Sep 17 00:00:00 2001 From: rkr Date: Tue, 12 Dec 2023 11:20:08 +0100 Subject: [PATCH 145/159] Fixed code style --- tests/Array/DropWhileTest.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/Array/DropWhileTest.php b/tests/Array/DropWhileTest.php index 437813e..5efeadf 100644 --- a/tests/Array/DropWhileTest.php +++ b/tests/Array/DropWhileTest.php @@ -26,7 +26,7 @@ public function testDropWhile() return $user['active']; })); } - + public function testDropWhile2() { $lines = [ @@ -36,13 +36,17 @@ public function testDropWhile2() '', '', ]; - - $lines = dropWhile($lines, static function ($x) { return trim((string) $x) !== ''; }); - + + $lines = dropWhile($lines, static function ($x) { + return trim((string) $x) !== ''; + }); + self::assertEquals(['', ''], $lines); - - $lines = dropWhile($lines, static function ($x) { return trim((string) $x) === ''; }); - + + $lines = dropWhile($lines, static function ($x) { + return trim((string) $x) === ''; + }); + self::assertEmpty($lines); } } From adcade45b922482f2bd1968139a8481c137d9065 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:32:56 +0200 Subject: [PATCH 146/159] Combine tests --- tests/Array/DropWhileTest.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/Array/DropWhileTest.php b/tests/Array/DropWhileTest.php index 5efeadf..50bef5a 100644 --- a/tests/Array/DropWhileTest.php +++ b/tests/Array/DropWhileTest.php @@ -25,10 +25,7 @@ public function testDropWhile() $this->assertSame([['user' => 'pebbles', 'active' => false]], dropWhile($users, function ($user) { return $user['active']; })); - } - - public function testDropWhile2() - { + $lines = [ 'Processing report:', 'Processed: 1', From 3a4cb7b8546f31654080f7f27e00d544f835fef2 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:43:13 +0200 Subject: [PATCH 147/159] Remove vendor-bin and replace with proper dependencies --- .gitattributes | 1 - .php-version | 1 + composer.json | 15 +- vendor-bin/php-cs-fixer/composer.json | 5 - vendor-bin/php-cs-fixer/composer.lock | 2201 ------------------------- vendor-bin/phpstan/composer.json | 10 - vendor-bin/phpstan/composer.lock | 1627 ------------------ vendor-bin/phpunit/composer.json | 5 - vendor-bin/phpunit/composer.lock | 1713 ------------------- 9 files changed, 5 insertions(+), 5573 deletions(-) delete mode 100644 .gitattributes create mode 100644 .php-version delete mode 100644 vendor-bin/php-cs-fixer/composer.json delete mode 100644 vendor-bin/php-cs-fixer/composer.lock delete mode 100644 vendor-bin/phpstan/composer.json delete mode 100644 vendor-bin/phpstan/composer.lock delete mode 100644 vendor-bin/phpunit/composer.json delete mode 100644 vendor-bin/phpunit/composer.lock diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 011ba22..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -vendor-bin/**/composer.lock binary diff --git a/.php-version b/.php-version new file mode 100644 index 0000000..37722eb --- /dev/null +++ b/.php-version @@ -0,0 +1 @@ +7.4 diff --git a/composer.json b/composer.json index d778be9..f92e27c 100644 --- a/composer.json +++ b/composer.json @@ -29,16 +29,9 @@ }, "require-dev": { "phpdocumentor/reflection-docblock": "^4.2", - "bamarni/composer-bin-plugin": "^1.2", - "phpstan/phpdoc-parser": "^0.3.0" - }, - "scripts": { - "post-install-cmd": ["@composer bin all install --ansi"], - "post-update-cmd": ["@composer bin all update --ansi"] - }, - "config": { - "allow-plugins": { - "bamarni/composer-bin-plugin": true - } + "phpstan/phpdoc-parser": "^0.3.0", + "phpunit/phpunit": "^7.3", + "phpstan/phpstan": "^0.12", + "friendsofphp/php-cs-fixer": "^2.12" } } diff --git a/vendor-bin/php-cs-fixer/composer.json b/vendor-bin/php-cs-fixer/composer.json deleted file mode 100644 index 4741827..0000000 --- a/vendor-bin/php-cs-fixer/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "friendsofphp/php-cs-fixer": "^2.12" - } -} diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock deleted file mode 100644 index c5f5ebc..0000000 --- a/vendor-bin/php-cs-fixer/composer.lock +++ /dev/null @@ -1,2201 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "6164bfe4091cb1fe1c219656f116f002", - "packages": [ - { - "name": "composer/pcre", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-12-06T15:17:27+00:00" - }, - { - "name": "composer/semver", - "version": "3.2.7", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "deac27056b57e46faf136fae7b449eeaa71661ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/deac27056b57e46faf136fae7b449eeaa71661ee", - "reference": "deac27056b57e46faf136fae7b449eeaa71661ee", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.54", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.7" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-04T09:57:54+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", - "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", - "shasum": "" - }, - "require": { - "composer/pcre": "^1", - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.4" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-04T17:06:45+00:00" - }, - { - "name": "doctrine/annotations", - "version": "1.13.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.2" - }, - "time": "2021-08-05T19:00:23+00:00" - }, - { - "name": "doctrine/lexer", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.11" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.2" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-01-12T08:27:12+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.19.3", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/75ac86f33fab4714ea5a39a396784d83ae3b5ed8", - "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.2 || ^2.0", - "doctrine/annotations": "^1.2", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^5.6 || ^7.0 || ^8.0", - "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", - "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", - "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", - "symfony/finder": "^3.0 || ^4.0 || ^5.0", - "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0 || ^5.0", - "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" - }, - "require-dev": { - "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.4", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.4.2", - "php-cs-fixer/accessible-object": "^1.0", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1", - "symfony/phpunit-bridge": "^5.2.1", - "symfony/yaml": "^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters.", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "extra": { - "branch-alias": { - "dev-master": "2.19-dev" - } - }, - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - }, - "classmap": [ - "tests/Test/AbstractFixerTestCase.php", - "tests/Test/AbstractIntegrationCaseFactory.php", - "tests/Test/AbstractIntegrationTestCase.php", - "tests/Test/Assert/AssertTokensTrait.php", - "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php", - "tests/Test/IntegrationCaseFactoryInterface.php", - "tests/Test/InternalIntegrationCaseFactory.php", - "tests/Test/IsIdenticalConstraint.php", - "tests/Test/TokensWithObservedTransformers.php", - "tests/TestCase.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.19.3" - }, - "funding": [ - { - "url": "https://github.com/keradus", - "type": "github" - } - ], - "time": "2021-11-15T17:17:55+00:00" - }, - { - "name": "php-cs-fixer/diff", - "version": "v1.3.1", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/dbd31aeb251639ac0b9e7e29405c1441907f5759", - "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "SpacePossum" - } - ], - "description": "sebastian/diff v2 backport support for PHP5.6", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/diff/issues", - "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1" - }, - "time": "2020-10-14T08:39:05+00:00" - }, - { - "name": "psr/cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, - "time": "2016-08-06T20:24:11+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" - }, - "time": "2021-05-03T11:20:27+00:00" - }, - { - "name": "symfony/console", - "version": "v5.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" - }, - "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v5.4.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-20T16:11:12+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-07-12T14:48:14+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/27d39ae126352b9fa3be5e196ccf4617897be3eb", - "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "symfony/dependency-injection": "<4.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^4.4|^5.0|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-23T10:19:22+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/event-dispatcher": "^1" - }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-07-12T14:48:14+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", - "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-10-28T13:39:27+00:00" - }, - { - "name": "symfony/finder", - "version": "v5.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "e77046c252be48c48a40816187ed527703c8f76c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e77046c252be48c48a40816187ed527703c8f76c", - "reference": "e77046c252be48c48a40816187ed527703c8f76c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-15T11:06:13+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "b0fb78576487af19c500aaddb269fd36701d4847" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b0fb78576487af19c500aaddb269fd36701d4847", - "reference": "b0fb78576487af19c500aaddb269fd36701d4847", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-23T10:19:22+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-10-20T20:35:02+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-23T21:10:46+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-02-19T12:13:01+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-05-27T09:17:38+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-06-05T21:20:04+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-09-13T13:58:33+00:00" - }, - { - "name": "symfony/process", - "version": "v5.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", - "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v5.4.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-27T21:01:00+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-04T16:48:04+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/208ef96122bfed82a8f3a61458a07113a08bdcfe", - "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/service-contracts": "^1|^2|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides a way to profile code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-23T10:19:22+00:00" - }, - { - "name": "symfony/string", - "version": "v5.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" - }, - "conflict": { - "symfony/translation-contracts": ">=3.0" - }, - "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "files": [ - "Resources/functions.php" - ], - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v5.4.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-16T21:52:00+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" -} diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json deleted file mode 100644 index 49ec786..0000000 --- a/vendor-bin/phpstan/composer.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "require": { - "phpstan/phpstan": "^0.10.3" - }, - "config": { - "allow-plugins": { - "composer/package-versions-deprecated": true - } - } -} diff --git a/vendor-bin/phpstan/composer.lock b/vendor-bin/phpstan/composer.lock deleted file mode 100644 index 08d207d..0000000 --- a/vendor-bin/phpstan/composer.lock +++ /dev/null @@ -1,1627 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "885b295492a97a537399d0d309928b59", - "packages": [ - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "1.4.6", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.55", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/1.4.6" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-03-25T17:01:18+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.8.0", - "php": "^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0|^8.5|^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" - }, - "time": "2021-02-04T16:20:16+00:00" - }, - { - "name": "nette/bootstrap", - "version": "v3.1.2", - "source": { - "type": "git", - "url": "https://github.com/nette/bootstrap.git", - "reference": "3ab4912a08af0c16d541c3709935c3478b5ee090" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/bootstrap/zipball/3ab4912a08af0c16d541c3709935c3478b5ee090", - "reference": "3ab4912a08af0c16d541c3709935c3478b5ee090", - "shasum": "" - }, - "require": { - "nette/di": "^3.0.5", - "nette/utils": "^3.2.1", - "php": ">=7.2 <8.2" - }, - "conflict": { - "tracy/tracy": "<2.6" - }, - "require-dev": { - "latte/latte": "^2.8", - "nette/application": "^3.1", - "nette/caching": "^3.0", - "nette/database": "^3.0", - "nette/forms": "^3.0", - "nette/http": "^3.0", - "nette/mail": "^3.0", - "nette/robot-loader": "^3.0", - "nette/safe-stream": "^2.2", - "nette/security": "^3.0", - "nette/tester": "^2.0", - "phpstan/phpstan-nette": "^0.12", - "tracy/tracy": "^2.6" - }, - "suggest": { - "nette/robot-loader": "to use Configurator::createRobotLoader()", - "tracy/tracy": "to use Configurator::enableTracy()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", - "homepage": "https://nette.org", - "keywords": [ - "bootstrapping", - "configurator", - "nette" - ], - "support": { - "issues": "https://github.com/nette/bootstrap/issues", - "source": "https://github.com/nette/bootstrap/tree/v3.1.2" - }, - "time": "2021-11-24T16:51:46+00:00" - }, - { - "name": "nette/di", - "version": "v3.0.12", - "source": { - "type": "git", - "url": "https://github.com/nette/di.git", - "reference": "11c236b9f7bbfc5a95e7b24742ad8847936feeb5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/11c236b9f7bbfc5a95e7b24742ad8847936feeb5", - "reference": "11c236b9f7bbfc5a95e7b24742ad8847936feeb5", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "nette/neon": "^3.3", - "nette/php-generator": "^3.5.4", - "nette/robot-loader": "^3.2", - "nette/schema": "^1.1", - "nette/utils": "^3.1.6", - "php": ">=7.1 <8.2" - }, - "conflict": { - "nette/bootstrap": "<3.0" - }, - "require-dev": { - "nette/tester": "^2.2", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", - "homepage": "https://nette.org", - "keywords": [ - "compiled", - "di", - "dic", - "factory", - "ioc", - "nette", - "static" - ], - "support": { - "issues": "https://github.com/nette/di/issues", - "source": "https://github.com/nette/di/tree/v3.0.12" - }, - "time": "2021-12-15T21:05:11+00:00" - }, - { - "name": "nette/finder", - "version": "v2.5.3", - "source": { - "type": "git", - "url": "https://github.com/nette/finder.git", - "reference": "64dc25b7929b731e72a1bc84a9e57727f5d5d3e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/finder/zipball/64dc25b7929b731e72a1bc84a9e57727f5d5d3e8", - "reference": "64dc25b7929b731e72a1bc84a9e57727f5d5d3e8", - "shasum": "" - }, - "require": { - "nette/utils": "^2.4 || ^3.0", - "php": ">=7.1" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "^2.0", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🔍 Nette Finder: find files and directories with an intuitive API.", - "homepage": "https://nette.org", - "keywords": [ - "filesystem", - "glob", - "iterator", - "nette" - ], - "support": { - "issues": "https://github.com/nette/finder/issues", - "source": "https://github.com/nette/finder/tree/v2.5.3" - }, - "time": "2021-12-12T17:43:24+00:00" - }, - { - "name": "nette/neon", - "version": "v3.3.2", - "source": { - "type": "git", - "url": "https://github.com/nette/neon.git", - "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/neon/zipball/54b287d8c2cdbe577b02e28ca1713e275b05ece2", - "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=7.1" - }, - "require-dev": { - "nette/tester": "^2.0", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.7" - }, - "bin": [ - "bin/neon-lint" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🍸 Nette NEON: encodes and decodes NEON file format.", - "homepage": "https://ne-on.org", - "keywords": [ - "export", - "import", - "neon", - "nette", - "yaml" - ], - "support": { - "issues": "https://github.com/nette/neon/issues", - "source": "https://github.com/nette/neon/tree/v3.3.2" - }, - "time": "2021-11-25T15:57:41+00:00" - }, - { - "name": "nette/php-generator", - "version": "v3.6.5", - "source": { - "type": "git", - "url": "https://github.com/nette/php-generator.git", - "reference": "9370403f9d9c25b51c4596ded1fbfe70347f7c82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/9370403f9d9c25b51c4596ded1fbfe70347f7c82", - "reference": "9370403f9d9c25b51c4596ded1fbfe70347f7c82", - "shasum": "" - }, - "require": { - "nette/utils": "^3.1.2", - "php": ">=7.2 <8.2" - }, - "require-dev": { - "nette/tester": "^2.4", - "nikic/php-parser": "^4.13", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.8" - }, - "suggest": { - "nikic/php-parser": "to use ClassType::withBodiesFrom() & GlobalFunction::withBodyFrom()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.1 features.", - "homepage": "https://nette.org", - "keywords": [ - "code", - "nette", - "php", - "scaffolding" - ], - "support": { - "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v3.6.5" - }, - "time": "2021-11-24T16:23:44+00:00" - }, - { - "name": "nette/robot-loader", - "version": "v3.4.1", - "source": { - "type": "git", - "url": "https://github.com/nette/robot-loader.git", - "reference": "e2adc334cb958164c050f485d99c44c430f51fe2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/e2adc334cb958164c050f485d99c44c430f51fe2", - "reference": "e2adc334cb958164c050f485d99c44c430f51fe2", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "nette/finder": "^2.5 || ^3.0", - "nette/utils": "^3.0", - "php": ">=7.1" - }, - "require-dev": { - "nette/tester": "^2.0", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", - "homepage": "https://nette.org", - "keywords": [ - "autoload", - "class", - "interface", - "nette", - "trait" - ], - "support": { - "issues": "https://github.com/nette/robot-loader/issues", - "source": "https://github.com/nette/robot-loader/tree/v3.4.1" - }, - "time": "2021-08-25T15:53:54+00:00" - }, - { - "name": "nette/schema", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", - "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", - "shasum": "" - }, - "require": { - "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", - "php": ">=7.1 <8.2" - }, - "require-dev": { - "nette/tester": "^2.3 || ^2.4", - "phpstan/phpstan-nette": "^0.12", - "tracy/tracy": "^2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "📐 Nette Schema: validating data structures against a given Schema.", - "homepage": "https://nette.org", - "keywords": [ - "config", - "nette" - ], - "support": { - "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.2.2" - }, - "time": "2021-10-15T11:40:02+00:00" - }, - { - "name": "nette/utils", - "version": "v3.2.6", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "2f261e55bd6a12057442045bf2c249806abc1d02" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/2f261e55bd6a12057442045bf2c249806abc1d02", - "reference": "2f261e55bd6a12057442045bf2c249806abc1d02", - "shasum": "" - }, - "require": { - "php": ">=7.2 <8.2" - }, - "conflict": { - "nette/di": "<3.0.6" - }, - "require-dev": { - "nette/tester": "~2.0", - "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.3" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", - "ext-xml": "to use Strings::length() etc. when mbstring is not available" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.6" - }, - "time": "2021-11-24T15:47:23+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.2.5", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", - "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "0.0.4", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/master" - }, - "time": "2019-10-25T18:33:07+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "0.3.5", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/8c4ef2aefd9788238897b678a985e1d5c8df6db4", - "reference": "8c4ef2aefd9788238897b678a985e1d5c8df6db4", - "shasum": "" - }, - "require": { - "php": "~7.1" - }, - "require-dev": { - "consistence/coding-standard": "^3.5", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phing/phing": "^2.16.0", - "phpstan/phpstan": "^0.10", - "phpunit/phpunit": "^6.3", - "slevomat/coding-standard": "^4.7.2", - "squizlabs/php_codesniffer": "^3.3.2", - "symfony/process": "^3.4 || ^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3-dev" - } - }, - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/master" - }, - "time": "2019-06-07T19:13:52+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "0.10.9", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "61840df60f50e186683ba35ece82efb66bd0ab2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/61840df60f50e186683ba35ece82efb66bd0ab2c", - "reference": "61840df60f50e186683ba35ece82efb66bd0ab2c", - "shasum": "" - }, - "require": { - "composer/xdebug-handler": "^1.3.0", - "jean85/pretty-package-versions": "^1.0.3", - "nette/bootstrap": "^2.4 || ^3.0", - "nette/di": "^2.4.7 || ^3.0", - "nette/robot-loader": "^3.0.1", - "nette/utils": "^2.4.5 || ^3.0", - "nikic/php-parser": "4.0.2 - 4.2.5", - "php": "~7.1", - "phpstan/phpdoc-parser": "^0.3", - "symfony/console": "~3.2 || ~4.0", - "symfony/finder": "~3.2 || ~4.0" - }, - "conflict": { - "symfony/console": "3.4.16 || 4.1.5" - }, - "require-dev": { - "brianium/paratest": "^2.0", - "consistence/coding-standard": "^3.5", - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", - "ext-gd": "*", - "ext-intl": "*", - "ext-mysqli": "*", - "ext-zip": "*", - "jakub-onderka/php-parallel-lint": "^1.0", - "localheinz/composer-normalize": "~0.9.0", - "phing/phing": "^2.16.0", - "phpstan/phpstan-deprecation-rules": "^0.10.2", - "phpstan/phpstan-php-parser": "^0.10", - "phpstan/phpstan-phpunit": "^0.10", - "phpstan/phpstan-strict-rules": "^0.10", - "phpunit/phpunit": "^7.0", - "slevomat/coding-standard": "^4.7.2", - "squizlabs/php_codesniffer": "^3.3.2" - }, - "bin": [ - "bin/phpstan" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.10-dev" - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": [ - "src/", - "build/PHPStan" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "support": { - "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.10.9" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" - } - ], - "time": "2020-01-07T15:26:30+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" - }, - "time": "2021-05-03T11:20:27+00:00" - }, - { - "name": "symfony/console", - "version": "v4.4.36", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "621379b62bb19af213b569b60013200b11dd576f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/621379b62bb19af213b569b60013200b11dd576f", - "reference": "621379b62bb19af213b569b60013200b11dd576f", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2" - }, - "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/console/tree/v4.4.36" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-15T10:33:10+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-07-12T14:48:14+00:00" - }, - { - "name": "symfony/finder", - "version": "v4.4.36", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "1fef05633cd61b629e963e5d8200fb6b67ecf42c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/1fef05633cd61b629e963e5d8200fb6b67ecf42c", - "reference": "1fef05633cd61b629e963e5d8200fb6b67ecf42c", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v4.4.36" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-12-15T10:33:10+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-06-05T21:20:04+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-09-13T13:58:33+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-04T16:48:04+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" -} diff --git a/vendor-bin/phpunit/composer.json b/vendor-bin/phpunit/composer.json deleted file mode 100644 index 1d41d8f..0000000 --- a/vendor-bin/phpunit/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "phpunit/phpunit": "^7.3" - } -} diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock deleted file mode 100644 index 40afbaf..0000000 --- a/vendor-bin/phpunit/composer.lock +++ /dev/null @@ -1,1713 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "c53e40477ad5fd9b453ca1e5ff4a2b95", - "packages": [ - { - "name": "doctrine/instantiator", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-11-10T18:47:58+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.10.2", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2020-11-13T09:40:50+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" - }, - "time": "2018-07-08T19:23:20+00:00" - }, - { - "name": "phar-io/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/master" - }, - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" - }, - "time": "2022-01-04T19:58:01+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "6.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-xdebug": "^2.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" - }, - "time": "2018-10-31T16:06:48+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:42:26+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:20:02+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "abandoned": true, - "time": "2021-07-26T12:15:06+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "7.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" - }, - "time": "2020-01-08T08:45:45+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:15:22+00:00" - }, - { - "name": "sebastian/comparator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:04:30+00:00" - }, - { - "name": "sebastian/diff", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:59:04+00:00" - }, - { - "name": "sebastian/environment", - "version": "4.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:53:42+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-11-11T13:51:24+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" - }, - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:40:27+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:37:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:34:24+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:30:19+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/master" - }, - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-10-20T20:35:02+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" -} From af01041ef654ecbd33d1d8be3e78e3046d09ffd3 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:47:50 +0200 Subject: [PATCH 148/159] Update path for PHPStan files --- phpstan.neon | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 54855d3..9e6b36b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,9 +1,9 @@ parameters: - bootstrap: %rootDir%/../../../../../src/bootstrap.php + bootstrap: %rootDir%/../../../src/bootstrap.php excludes_analyse: - - %rootDir%/../../../../../src/compiled.php - - %rootDir%/../../../../../src/Lodash.php - - %rootDir%/../../../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage + - %rootDir%/../../../src/compiled.php + - %rootDir%/../../../src/Lodash.php + - %rootDir%/../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" From a2c428c8f1c82363c73dbc23b9fbc825dd24d184 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:50:24 +0200 Subject: [PATCH 149/159] Update PHPStan level to 5 --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index 9e6b36b..e5de5a8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,6 @@ parameters: bootstrap: %rootDir%/../../../src/bootstrap.php + level: 5 excludes_analyse: - %rootDir%/../../../src/compiled.php - %rootDir%/../../../src/Lodash.php From 4fe2b3f71436086d13c5e5290295c2793f3417e1 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:56:08 +0200 Subject: [PATCH 150/159] Add PHPStan baseline --- phpstan-baseline.neon | 82 +++++++++++++++++++++++++++++++++++++++++++ phpstan.neon | 14 ++++---- 2 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..233035a --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,82 @@ +parameters: + ignoreErrors: + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" + count: 1 + path: src/Array/differenceBy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" + count: 1 + path: src/Array/differenceWith.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" + count: 1 + path: src/Array/intersectionBy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" + count: 1 + path: src/Array/intersectionWith.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" + count: 1 + path: src/Array/unionBy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" + count: 1 + path: src/Array/unionWith.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" + count: 1 + path: src/Array/zipWith.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Collection/size.php + + - + message: "#^Right side of \\|\\| is always false\\.$#" + count: 2 + path: src/Number/random.php + + - + message: "#^Call to function is_array\\(\\) with null will always evaluate to false\\.$#" + count: 1 + path: src/String/replace.php + + - + message: "#^Comparison operation \"\\>\\=\" between int\\<0, max\\> and 0 is always true\\.$#" + count: 1 + path: src/String/startsWith.php + + - + message: "#^Comparison operation \"\\>\" between int\\<0, max\\> and \\-1 is always true\\.$#" + count: 1 + path: src/String/truncate.php + + - + message: "#^Call to function is_array\\(\\) with object will always evaluate to false\\.$#" + count: 1 + path: src/internal/isIterateeCall.php + + - + message: "#^Result of \\|\\| is always true\\.$#" + count: 1 + path: src/internal/isIterateeCall.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/internal/isIterateeCall.php + + - + message: "#^Regex pattern is invalid\\: Delimiter must not be alphanumeric or backslash in pattern\\: \\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\(\\?\\=\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\|\\(\\?\\:\\[\\^\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\?\\|\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\(\\?\\:\\\\x\\{e83c\\}\\[\\\\x\\{ede6\\}\\-\\\\x\\{edff\\}\\]\\)\\{2\\}\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{ebff\\}\\]\\[\\\\x\\{ec00\\}\\-\\\\x\\{efff\\}\\]\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\)\\[\\\\x\\{fe0e\\}\\\\x\\{fe0f\\}\\]\\?\\(\\?\\:\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\?\\(\\?\\:\\\\x\\{200d\\}\\(\\?\\:\\[\\^\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\|\\(\\?\\:\\\\x\\{e83c\\}\\[\\\\x\\{ede6\\}\\-\\\\x\\{edff\\}\\]\\)\\{2\\}\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{ebff\\}\\]\\[\\\\x\\{ec00\\}\\-\\\\x\\{efff\\}\\]\\)\\[\\\\x\\{fe0e\\}\\\\x\\{fe0f\\}\\]\\?\\(\\?\\:\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\?\\)\\*$#" + count: 1 + path: src/internal/unicodeSize.php + diff --git a/phpstan.neon b/phpstan.neon index e5de5a8..ae2cc00 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,12 +1,14 @@ +includes: + - phpstan-baseline.neon + parameters: + paths: + - src bootstrap: %rootDir%/../../../src/bootstrap.php level: 5 excludes_analyse: - - %rootDir%/../../../src/compiled.php - - %rootDir%/../../../src/Lodash.php - - %rootDir%/../../../src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage + - src/compiled.php + - src/Lodash.php + - src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - - '#PHPDoc tag \@param references unknown parameter \$(comparator|iteratee)#' - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" - - "#Parameter \\#\\d+ \\$callable of static method Closure::fromCallable\\(\\) expects callable, array\\(object, string\\) given.#" - - "#Parameter \\#1 \\$name of class ReflectionFunction constructor expects Closure\\|string, callable given#" From 340ffb416e4de62962bb78202d30c709746962b7 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 15:58:56 +0200 Subject: [PATCH 151/159] Remove inline options for PHPStan --- .github/workflows/static-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index d554eb4..31f3146 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -34,4 +34,4 @@ jobs: run: composer install --prefer-dist - name: PHPStan - run: vendor/bin/phpstan analyse ./src -c phpstan.neon --level=6 + run: vendor/bin/phpstan From 77ffc3c5b028a19167183094342534a1607d3951 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 16:06:56 +0200 Subject: [PATCH 152/159] Add PHP 8+ to test matrix --- .github/workflows/tests.yml | 6 +++++- .gitignore | 1 + composer.json | 6 +++--- tests/Collection/SizeTest.php | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fa4d5ce..40b87c2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,10 +19,14 @@ jobs: - php: 7.2 - php: 7.3 - php: 7.4 + - php: 8.0 + - php: 8.1 + - php: 8.2 + - php: 8.3 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.gitignore b/.gitignore index 6b329f6..ff6836c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /.php_cs.cache /src/compiled.php .idea +.phpunit.result.cache diff --git a/composer.json b/composer.json index f92e27c..3fb0d3a 100644 --- a/composer.json +++ b/composer.json @@ -28,9 +28,9 @@ "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0" }, "require-dev": { - "phpdocumentor/reflection-docblock": "^4.2", - "phpstan/phpdoc-parser": "^0.3.0", - "phpunit/phpunit": "^7.3", + "phpdocumentor/reflection-docblock": "*", + "phpstan/phpdoc-parser": "*", + "phpunit/phpunit": "^7.3 || ^8.4", "phpstan/phpstan": "^0.12", "friendsofphp/php-cs-fixer": "^2.12" } diff --git a/tests/Collection/SizeTest.php b/tests/Collection/SizeTest.php index 490bf89..b750e29 100644 --- a/tests/Collection/SizeTest.php +++ b/tests/Collection/SizeTest.php @@ -26,6 +26,7 @@ public function testSize() })); $this->assertSame(12, size(new class implements \Countable { + #[\ReturnTypeWillChange] public function count() { return 12; From 7b5ae90b3a631f3a9772f15cf16fc2fecdcf7f2b Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 12 Dec 2023 16:16:47 +0200 Subject: [PATCH 153/159] Fix compile script --- bin/compile | 2 -- src/Object/get.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/compile b/bin/compile index 2422749..1018030 100755 --- a/bin/compile +++ b/bin/compile @@ -5,8 +5,6 @@ declare(strict_types=1); -require_once dirname(__DIR__).'/vendor/autoload.php'; - function getCode(SplFileInfo $file): string { $code = php_strip_whitespace($file->getRealPath()); diff --git a/src/Object/get.php b/src/Object/get.php index 84e8268..3a0c66d 100644 --- a/src/Object/get.php +++ b/src/Object/get.php @@ -1,6 +1,6 @@ Date: Sun, 17 Dec 2023 18:11:51 +0200 Subject: [PATCH 154/159] Bump minimum PHP requirement to 7.2 --- .github/workflows/tests.yml | 3 +-- .php-version | 2 +- README.md | 4 ++++ composer.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 40b87c2..1e78057 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,6 @@ jobs: fail-fast: false matrix: include: - - php: 7.1 - php: 7.2 - php: 7.3 - php: 7.4 @@ -60,7 +59,7 @@ jobs: fail-fast: false matrix: include: - - php: 7.1 + - php: 7.2 steps: - name: Checkout diff --git a/.php-version b/.php-version index 37722eb..5904f7a 100644 --- a/.php-version +++ b/.php-version @@ -1 +1 @@ -7.4 +7.2 diff --git a/README.md b/README.md index 5c45a00..3d9cc8a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ Lodash-PHP is a port of the [Lodash JS library](https://lodash.com/) to PHP. It Lodash-PHP tries to mimick lodash.js as close as possible +# Requirements + +Lodash-PHP requires minimum PHP 7.2+, but the latest version of PHP is always recommended. + # Installation Install Lodash-PHP through composer: diff --git a/composer.json b/composer.json index 3fb0d3a..97b84ee 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ ] }, "require": { - "php": ">=7.1", + "php": "^7.2 || ^8.0", "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0", "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0" }, From 3e48ec2829cb1142eda17e36cb4d404187ff2435 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 17 Dec 2023 09:08:27 +0200 Subject: [PATCH 155/159] Update PHPStan to 1.10 --- composer.json | 2 +- phpstan-baseline.neon | 54 ++------------------------------- phpstan.neon | 6 ++-- src/String/split.php | 2 +- src/String/template.php | 12 ++++++-- src/String/truncate.php | 2 +- src/internal/isIterateeCall.php | 2 +- 7 files changed, 19 insertions(+), 61 deletions(-) diff --git a/composer.json b/composer.json index 97b84ee..bc7d4ed 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "phpdocumentor/reflection-docblock": "*", "phpstan/phpdoc-parser": "*", "phpunit/phpunit": "^7.3 || ^8.4", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^1.10", "friendsofphp/php-cs-fixer": "^2.12" } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 233035a..b806197 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,40 +1,5 @@ parameters: ignoreErrors: - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" - count: 1 - path: src/Array/differenceBy.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" - count: 1 - path: src/Array/differenceWith.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" - count: 1 - path: src/Array/intersectionBy.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" - count: 1 - path: src/Array/intersectionWith.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" - count: 1 - path: src/Array/unionBy.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$comparator$#" - count: 1 - path: src/Array/unionWith.php - - - - message: "#^PHPDoc tag @param references unknown parameter\\: \\$iteratee$#" - count: 1 - path: src/Array/zipWith.php - - message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 @@ -56,27 +21,12 @@ parameters: path: src/String/startsWith.php - - message: "#^Comparison operation \"\\>\" between int\\<0, max\\> and \\-1 is always true\\.$#" - count: 1 - path: src/String/truncate.php - - - - message: "#^Call to function is_array\\(\\) with object will always evaluate to false\\.$#" + message: "#^Offset mixed on \\*NEVER\\* in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: src/internal/isIterateeCall.php - - - - message: "#^Result of \\|\\| is always true\\.$#" - count: 1 - path: src/internal/isIterateeCall.php + path: src/internal/baseIntersection.php - message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 path: src/internal/isIterateeCall.php - - - message: "#^Regex pattern is invalid\\: Delimiter must not be alphanumeric or backslash in pattern\\: \\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\(\\?\\=\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\|\\(\\?\\:\\[\\^\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\?\\|\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\(\\?\\:\\\\x\\{e83c\\}\\[\\\\x\\{ede6\\}\\-\\\\x\\{edff\\}\\]\\)\\{2\\}\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{ebff\\}\\]\\[\\\\x\\{ec00\\}\\-\\\\x\\{efff\\}\\]\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\)\\[\\\\x\\{fe0e\\}\\\\x\\{fe0f\\}\\]\\?\\(\\?\\:\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\?\\(\\?\\:\\\\x\\{200d\\}\\(\\?\\:\\[\\^\\\\x\\{e800\\}\\-\\\\x\\{efff\\}\\]\\|\\(\\?\\:\\\\x\\{e83c\\}\\[\\\\x\\{ede6\\}\\-\\\\x\\{edff\\}\\]\\)\\{2\\}\\|\\[\\\\x\\{e800\\}\\-\\\\x\\{ebff\\}\\]\\[\\\\x\\{ec00\\}\\-\\\\x\\{efff\\}\\]\\)\\[\\\\x\\{fe0e\\}\\\\x\\{fe0f\\}\\]\\?\\(\\?\\:\\[\\\\x\\{0300\\}\\-\\\\x\\{036f\\}\\\\x\\{fe20\\}\\-\\\\x\\{fe2f\\}\\\\x\\{20d0\\}\\-\\\\x\\{20ff\\}\\]\\|\\\\x\\{e83c\\}\\[\\\\x\\{effb\\}\\-\\\\x\\{efff\\}\\]\\)\\?\\)\\*$#" - count: 1 - path: src/internal/unicodeSize.php - diff --git a/phpstan.neon b/phpstan.neon index ae2cc00..f537171 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,11 +4,13 @@ includes: parameters: paths: - src - bootstrap: %rootDir%/../../../src/bootstrap.php + bootstrapFiles: + - src/bootstrap.php level: 5 - excludes_analyse: + excludePaths: - src/compiled.php - src/Lodash.php - src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" + - "#^PHPDoc tag \\@param references unknown parameter\\: \\$[a-zA-Z]+$#" diff --git a/src/String/split.php b/src/String/split.php index 2ec929f..73916c3 100644 --- a/src/String/split.php +++ b/src/String/split.php @@ -33,7 +33,7 @@ function split(string $string, string $separator, int $limit = 0): array { if (\preg_match(reRegExpChar, $separator)) { - return \preg_split($separator, $string, $limit ?? -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; + return \preg_split($separator, $string, $limit ?: -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; } /** @var array $result */ diff --git a/src/String/template.php b/src/String/template.php index 559e2b4..8b76ef0 100644 --- a/src/String/template.php +++ b/src/String/template.php @@ -107,12 +107,12 @@ function template(string $string, array $options = []): callable ]); $string = \preg_replace_callback('#'.$reDelimiters.'#u', function ($matches) { - list(, + [, $escapeValue, $interpolateValue, $esTemplateValue, $evaluateValue, - ) = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); + ] = \array_merge($matches, \array_fill(\count($matches), 5 - \count($matches), null)); $interpolateValue = $interpolateValue ?: $esTemplateValue; @@ -128,7 +128,7 @@ function template(string $string, array $options = []): callable } if ($interpolateValue) { - $interpolateValue = \trim($interpolateValue ?? $esTemplateValue); + $interpolateValue = \trim($interpolateValue); $interpolateValue = \preg_replace('#^([\p{L}\p{N}_]+)$#u', '$$1', $interpolateValue); $source .= ""; } @@ -145,8 +145,14 @@ function template(string $string, array $options = []): callable return new class($string, $imports) { public $source; + /** + * @var array + */ private $imports; + /** + * @param array $imports + */ public function __construct(string $source, array $imports) { $this->source = $source; diff --git a/src/String/truncate.php b/src/String/truncate.php index 7fc4601..381c0df 100644 --- a/src/String/truncate.php +++ b/src/String/truncate.php @@ -105,7 +105,7 @@ function truncate($string, array $options = []) } } elseif (\strpos($string, $separator) !== $end) { $index = \strrpos($result, $separator); - if (false !== $index && $index > -1) { + if (false !== $index) { $result = \substr($result, 0, $index); } } diff --git a/src/internal/isIterateeCall.php b/src/internal/isIterateeCall.php index 08b13b2..b9c3169 100644 --- a/src/internal/isIterateeCall.php +++ b/src/internal/isIterateeCall.php @@ -24,7 +24,7 @@ */ function isIterateeCall($value, $index = null, $object = null) { - if (!\is_object($object) || !\is_array($object)) { + if (!\is_object($object) && !\is_array($object)) { return false; } From 799bec715e36626e3d2f62dfa08a179f9190e558 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Mon, 29 Jan 2024 09:49:41 -0500 Subject: [PATCH 156/159] Add 6.x to property access because it blocks install in updated projects --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bc7d4ed..8696e2a 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "require": { "php": "^7.2 || ^8.0", "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0", - "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0" + "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0 | ^6.0" }, "require-dev": { "phpdocumentor/reflection-docblock": "*", From e3e02ac496f049e37159b99b266d77ae7f829880 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Tue, 30 Jan 2024 10:44:40 -0500 Subject: [PATCH 157/159] Add 5.x to sebastian comparator because it blocks install in updated projects --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8696e2a..539cfd9 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ }, "require": { "php": "^7.2 || ^8.0", - "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0", + "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0 | ^5.0", "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0 | ^6.0" }, "require-dev": { From 068dc28a9581367c34093c61e4bbb01ca9dc1a1b Mon Sep 17 00:00:00 2001 From: Andrew Ivchenkov Date: Sun, 18 Aug 2024 02:31:46 +0300 Subject: [PATCH 158/159] Add 6.x to sebastian comparator because it blocks install in updated projects --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 539cfd9..35d299e 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ }, "require": { "php": "^7.2 || ^8.0", - "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0 | ^5.0", + "sebastian/comparator": "^1.2 | ^2.0 | ^2.1 | ^3.0 | ^4.0 | ^5.0 | ^6.0", "symfony/property-access": "^2.7 | ^3.0 | ^4.0 | ^5.0 | ^6.0" }, "require-dev": { From e723bd76894e0504b1c0f3ccbdb3331e1b2919cc Mon Sep 17 00:00:00 2001 From: Andrei Ivchenkov Date: Sun, 18 Aug 2024 13:52:23 +0300 Subject: [PATCH 159/159] updated phpstan.neon --- phpstan.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index f537171..08970a1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,5 +12,4 @@ parameters: - src/Lodash.php - src/internal/memoizeCapped.php # Exclude internal function due to dynamic class usage ignoreErrors: - - "#Callable '.*internal.*' invoked with \\d+ parameters, [\\d-]+ required.#" - "#^PHPDoc tag \\@param references unknown parameter\\: \\$[a-zA-Z]+$#" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy