[Web] Update composer libs
- Removing symfony/deprecation-contracts (v2.4.0) - Upgrading ddeboer/imap (1.12.1 => 1.13.1) - Upgrading directorytree/ldaprecord (v2.6.3 => v2.10.1) - Upgrading illuminate/contracts (v8.53.1 => v9.3.0) - Upgrading nesbot/carbon (2.51.1 => 2.57.0) - Upgrading phpmailer/phpmailer (v6.5.0 => v6.6.0) - Upgrading psr/container (1.1.1 => 2.0.2) - Upgrading psr/log (1.1.4 => 3.0.0) - Upgrading psr/simple-cache (1.0.1 => 2.0.0) - Upgrading robthree/twofactorauth (1.8.0 => 1.8.1) - Upgrading symfony/polyfill-ctype (v1.23.0 => v1.24.0) - Upgrading symfony/polyfill-mbstring (v1.23.1 => v1.24.0) - Upgrading symfony/polyfill-php80 (v1.23.1 => v1.24.0) - Upgrading symfony/translation (v5.3.4 => v6.0.5) - Upgrading symfony/translation-contracts (v2.4.0 => v3.0.0) - Upgrading symfony/var-dumper (v5.3.6 => v6.0.5) - Upgrading tightenco/collect (v8.34.0 => v8.83.2) - Upgrading twig/twig (v3.3.2 => v3.3.8)
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
name: Run tests
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches: [laravel-9-ongoing, laravel-8-ongoing]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [Ubuntu, macOS]
|
||||
php: [7.2, 7.3, 7.4, 8.0]
|
||||
php: [7.3, 7.4, 8.0, 8.1]
|
||||
|
||||
include:
|
||||
- os: Ubuntu
|
||||
|
67
data/web/inc/lib/vendor/tightenco/collect/branch-commit-push.sh
vendored
Executable file
67
data/web/inc/lib/vendor/tightenco/collect/branch-commit-push.sh
vendored
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
WHITE='\033[0;37m'
|
||||
RESET='\033[0m'
|
||||
|
||||
function validateVersion()
|
||||
{
|
||||
echo ""
|
||||
passedVersion=$1
|
||||
echo -e "${WHITE}-- Validating tag '$passedVersion'...${RESET}"
|
||||
|
||||
# Todo: validate the version here using a regex; if fail, just exit
|
||||
# ... expect 8.75.0, with no v in front of it
|
||||
|
||||
if [[ $passedVersion == '' ]]; then
|
||||
echo -e "\n-- Invalid tag. Tags should be structured without v; e.g. 8.57.0"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo -e "${WHITE}-- Tag valid.${RESET}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Exit script if any command fails (e.g. phpunit)
|
||||
set -e
|
||||
|
||||
|
||||
# Require confirmation it's set up corrctly
|
||||
echo
|
||||
echo -e "${WHITE}-- This script is meant to be run after running upgrade.sh, BEFORE committing to Git.${RESET}"
|
||||
|
||||
while true; do
|
||||
echo -e "${GREEN}-- Is that the current state of your local project?${RESET}"
|
||||
read -p "-- (y/n) " yn
|
||||
case $yn in
|
||||
[Yy]* ) break;;
|
||||
[Nn]* ) exit;;
|
||||
* ) echo "Please answer y or n.";;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get the version and exit if not valid
|
||||
validateVersion $1
|
||||
|
||||
# Create official v prefaced version
|
||||
version="v$1"
|
||||
|
||||
# Run tests (and bail if they fail)
|
||||
phpunit
|
||||
echo -e "\n${WHITE}-- Tests succeeded.${RESET}"
|
||||
|
||||
# Branch
|
||||
echo -e "\n${WHITE}-- Creating a Git branch '$version-changes'...${RESET}\n"
|
||||
git checkout -b $version-changes
|
||||
|
||||
# Add and commit, with "v8.57.0 changes" as the commit name
|
||||
git add -A
|
||||
git commit -m "$version changes"
|
||||
|
||||
echo
|
||||
echo -e "${WHITE}-- Git committed.${RESET}"
|
||||
|
||||
# Push
|
||||
git push -u origin $version-changes
|
@@ -10,8 +10,8 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2|^8.0",
|
||||
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0"
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
@@ -33,7 +33,11 @@
|
||||
"tests/files/Support/HtmlString.php",
|
||||
"tests/files/Support/HigherOrderTapProxy.php",
|
||||
"tests/files/Support/Str.php",
|
||||
"tests/files/Support/Stringable.php"
|
||||
"tests/files/Support/Traits/Conditionable.php",
|
||||
"tests/files/Support/Stringable.php",
|
||||
"tests/files/Support/ItemNotFoundException.php",
|
||||
"tests/files/Support/MultipleItemsFoundException.php",
|
||||
"tests/Support/Concerns/CountsEnumerations.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
|
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tightenco\Collect\Contracts\Support;
|
||||
|
||||
interface CanBeEscapedWhenCastToString
|
||||
{
|
||||
/**
|
||||
* Indicate that the object's string representation should be escaped when __toString is invoked.
|
||||
*
|
||||
* @param bool $escape
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeWhenCastingToString($escape = true);
|
||||
}
|
@@ -121,6 +121,23 @@ class Arr
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a flatten "dot" notation array into an expanded array.
|
||||
*
|
||||
* @param iterable $array
|
||||
* @return array
|
||||
*/
|
||||
public static function undot($array)
|
||||
{
|
||||
$results = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
static::set($results, $key, $value);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the given array except for a specified array of keys.
|
||||
*
|
||||
@@ -393,6 +410,19 @@ class Arr
|
||||
return array_keys($keys) !== $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an array is a list.
|
||||
*
|
||||
* An array is a "list" if all array keys are sequential integers starting from 0 with no gaps in between.
|
||||
*
|
||||
* @param array $array
|
||||
* @return bool
|
||||
*/
|
||||
public static function isList($array)
|
||||
{
|
||||
return ! self::isAssoc($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subset of the items from the given array.
|
||||
*
|
||||
@@ -493,6 +523,17 @@ class Arr
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the array into a query string.
|
||||
*
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
public static function query($array)
|
||||
{
|
||||
return http_build_query($array, '', '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get one or a specified number of random values from an array.
|
||||
*
|
||||
@@ -642,14 +683,26 @@ class Arr
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the array into a query string.
|
||||
* Conditionally compile classes from an array into a CSS class list.
|
||||
*
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
public static function query($array)
|
||||
public static function toCssClasses($array)
|
||||
{
|
||||
return http_build_query($array, '', '&', PHP_QUERY_RFC3986);
|
||||
$classList = static::wrap($array);
|
||||
|
||||
$classes = [];
|
||||
|
||||
foreach ($classList as $class => $constraint) {
|
||||
if (is_numeric($class)) {
|
||||
$classes[] = $constraint;
|
||||
} elseif ($constraint) {
|
||||
$classes[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
return implode(' ', $classes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -664,6 +717,19 @@ class Arr
|
||||
return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter items where the value is not null.
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
public static function whereNotNull($array)
|
||||
{
|
||||
return static::where($array, function ($value) {
|
||||
return ! is_null($value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given value is not an array and not null, wrap it in one.
|
||||
*
|
||||
|
@@ -4,11 +4,12 @@ namespace Tightenco\Collect\Support;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString;
|
||||
use Tightenco\Collect\Support\Traits\EnumeratesValues;
|
||||
use Tightenco\Collect\Support\Traits\Macroable;
|
||||
use stdClass;
|
||||
|
||||
class Collection implements ArrayAccess, Enumerable
|
||||
class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable
|
||||
{
|
||||
use EnumeratesValues, Macroable;
|
||||
|
||||
@@ -175,6 +176,19 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return $this->contains($this->operatorForWhere(...func_get_args()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an item is not contained in the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function doesntContain($key, $operator = null, $value = null)
|
||||
{
|
||||
return ! $this->contains(...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross join with the given lists, returning all possible permutations.
|
||||
*
|
||||
@@ -260,7 +274,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
/**
|
||||
* Retrieve duplicate items from the collection.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
@@ -288,7 +302,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
/**
|
||||
* Retrieve duplicate items from the collection using strict comparison.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @return static
|
||||
*/
|
||||
public function duplicatesStrict($callback = null)
|
||||
@@ -383,7 +397,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
/**
|
||||
* Remove an item from the collection by key.
|
||||
*
|
||||
* @param string|array $keys
|
||||
* @param string|int|array $keys
|
||||
* @return $this
|
||||
*/
|
||||
public function forget($keys)
|
||||
@@ -411,6 +425,24 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return value($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the collection by key or add it to collection if it does not exist.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOrPut($key, $value)
|
||||
{
|
||||
if (array_key_exists($key, $this->items)) {
|
||||
return $this->items[$key];
|
||||
}
|
||||
|
||||
$this->offsetSet($key, $value = value($value));
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group an associative array by a field or using a callback.
|
||||
*
|
||||
@@ -501,6 +533,29 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if any of the keys exist in the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAny($key)
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$keys = is_array($key) ? $key : func_get_args();
|
||||
|
||||
foreach ($keys as $value) {
|
||||
if ($this->has($value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate values of a given key as a string.
|
||||
*
|
||||
@@ -513,10 +568,10 @@ class Collection implements ArrayAccess, Enumerable
|
||||
$first = $this->first();
|
||||
|
||||
if (is_array($first) || (is_object($first) && ! $first instanceof \Illuminate\Support\Stringable)) {
|
||||
return implode($glue, $this->pluck($value)->all());
|
||||
return implode($glue ?? '', $this->pluck($value)->all());
|
||||
}
|
||||
|
||||
return implode($value, $this->items);
|
||||
return implode($value ?? '', $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -784,13 +839,30 @@ class Collection implements ArrayAccess, Enumerable
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and remove the last item from the collection.
|
||||
* Get and remove the last N items from the collection.
|
||||
*
|
||||
* @param int $count
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop()
|
||||
public function pop($count = 1)
|
||||
{
|
||||
return array_pop($this->items);
|
||||
if ($count === 1) {
|
||||
return array_pop($this->items);
|
||||
}
|
||||
|
||||
if ($this->isEmpty()) {
|
||||
return new static;
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
||||
$collectionCount = $this->count();
|
||||
|
||||
foreach (range(1, min($count, $collectionCount)) as $item) {
|
||||
array_push($results, array_pop($this->items));
|
||||
}
|
||||
|
||||
return new static($results);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -810,7 +882,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
/**
|
||||
* Push one or more items onto the end of the collection.
|
||||
*
|
||||
* @param mixed $values [optional]
|
||||
* @param mixed $values
|
||||
* @return $this
|
||||
*/
|
||||
public function push(...$values)
|
||||
@@ -937,13 +1009,30 @@ class Collection implements ArrayAccess, Enumerable
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and remove the first item from the collection.
|
||||
* Get and remove the first N items from the collection.
|
||||
*
|
||||
* @param int $count
|
||||
* @return mixed
|
||||
*/
|
||||
public function shift()
|
||||
public function shift($count = 1)
|
||||
{
|
||||
return array_shift($this->items);
|
||||
if ($count === 1) {
|
||||
return array_shift($this->items);
|
||||
}
|
||||
|
||||
if ($this->isEmpty()) {
|
||||
return new static;
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
||||
$collectionCount = $this->count();
|
||||
|
||||
foreach (range(1, min($count, $collectionCount)) as $item) {
|
||||
array_push($results, array_shift($this->items));
|
||||
}
|
||||
|
||||
return new static($results);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -957,6 +1046,22 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return new static(Arr::shuffle($this->items, $seed));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create chunks representing a "sliding window" view of the items in the collection.
|
||||
*
|
||||
* @param int $size
|
||||
* @param int $step
|
||||
* @return static
|
||||
*/
|
||||
public function sliding($size = 2, $step = 1)
|
||||
{
|
||||
$chunks = floor(($this->count() - $size) / $step) + 1;
|
||||
|
||||
return static::times($chunks, function ($number) use ($size, $step) {
|
||||
return $this->slice(($number - 1) * $step, $size);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the first {$count} items.
|
||||
*
|
||||
@@ -1050,6 +1155,63 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return $this->chunk(ceil($this->count() / $numberOfGroups));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Tightenco\Collect\Support\ItemNotFoundException
|
||||
* @throws \Tightenco\Collect\Support\MultipleItemsFoundException
|
||||
*/
|
||||
public function sole($key = null, $operator = null, $value = null)
|
||||
{
|
||||
$filter = func_num_args() > 1
|
||||
? $this->operatorForWhere(...func_get_args())
|
||||
: $key;
|
||||
|
||||
$items = $this->when($filter)->filter($filter);
|
||||
|
||||
if ($items->isEmpty()) {
|
||||
throw new ItemNotFoundException;
|
||||
}
|
||||
|
||||
if ($items->count() > 1) {
|
||||
throw new MultipleItemsFoundException;
|
||||
}
|
||||
|
||||
return $items->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item in the collection but throw an exception if no matching items exist.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Tightenco\Collect\Support\ItemNotFoundException
|
||||
*/
|
||||
public function firstOrFail($key = null, $operator = null, $value = null)
|
||||
{
|
||||
$filter = func_num_args() > 1
|
||||
? $this->operatorForWhere(...func_get_args())
|
||||
: $key;
|
||||
|
||||
$placeholder = new stdClass();
|
||||
|
||||
$item = $this->first($filter, $placeholder);
|
||||
|
||||
if ($item === $placeholder) {
|
||||
throw new ItemNotFoundException;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk the collection into chunks of the given size.
|
||||
*
|
||||
@@ -1136,7 +1298,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
|
||||
// First we will loop through the items and get the comparator from a callback
|
||||
// function which we were given. Then, we will sort the returned values and
|
||||
// and grab the corresponding values for the sorted keys from this array.
|
||||
// grab all the corresponding values for the sorted keys from this array.
|
||||
foreach ($this->items as $key => $value) {
|
||||
$results[$key] = $callback($value, $key);
|
||||
}
|
||||
@@ -1175,7 +1337,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
|
||||
$result = 0;
|
||||
|
||||
if (is_callable($prop)) {
|
||||
if (! is_string($prop) && is_callable($prop)) {
|
||||
$result = $prop($a, $b);
|
||||
} else {
|
||||
$values = [data_get($a, $prop), data_get($b, $prop)];
|
||||
@@ -1237,6 +1399,21 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return $this->sortKeys($options, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the collection keys using a callback.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return static
|
||||
*/
|
||||
public function sortKeysUsing(callable $callback)
|
||||
{
|
||||
$items = $this->items;
|
||||
|
||||
uksort($items, $callback);
|
||||
|
||||
return new static($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splice a portion of the underlying collection array.
|
||||
*
|
||||
@@ -1251,7 +1428,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return new static(array_splice($this->items, $offset));
|
||||
}
|
||||
|
||||
return new static(array_splice($this->items, $offset, $length, $replacement));
|
||||
return new static(array_splice($this->items, $offset, $length, $this->getArrayableItems($replacement)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1304,6 +1481,42 @@ class Collection implements ArrayAccess, Enumerable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a flatten "dot" notation array into an expanded array.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function undot()
|
||||
{
|
||||
return new static(Arr::undot($this->all()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only unique items from the collection array.
|
||||
*
|
||||
* @param string|callable|null $key
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
public function unique($key = null, $strict = false)
|
||||
{
|
||||
if (is_null($key) && $strict === false) {
|
||||
return new static(array_unique($this->items, SORT_REGULAR));
|
||||
}
|
||||
|
||||
$callback = $this->valueRetriever($key);
|
||||
|
||||
$exists = [];
|
||||
|
||||
return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
|
||||
if (in_array($id = $callback($item, $key), $exists, $strict)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$exists[] = $id;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the keys on the underlying array.
|
||||
*
|
||||
@@ -1353,6 +1566,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->items);
|
||||
@@ -1363,6 +1577,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->items);
|
||||
@@ -1408,6 +1623,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return isset($this->items[$key]);
|
||||
@@ -1419,6 +1635,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->items[$key];
|
||||
@@ -1431,6 +1648,7 @@ class Collection implements ArrayAccess, Enumerable
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
@@ -1443,9 +1661,10 @@ class Collection implements ArrayAccess, Enumerable
|
||||
/**
|
||||
* Unset the item at a given offset.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $key
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
unset($this->items[$key]);
|
||||
|
@@ -211,7 +211,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
|
||||
/**
|
||||
* Retrieve duplicate items.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
@@ -220,7 +220,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
|
||||
/**
|
||||
* Retrieve duplicate items using strict comparison.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @return static
|
||||
*/
|
||||
public function duplicatesStrict($callback = null);
|
||||
|
@@ -5,12 +5,13 @@ namespace Tightenco\Collect\Support;
|
||||
use ArrayIterator;
|
||||
use Closure;
|
||||
use DateTimeInterface;
|
||||
use Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString;
|
||||
use Tightenco\Collect\Support\Traits\EnumeratesValues;
|
||||
use Tightenco\Collect\Support\Traits\Macroable;
|
||||
use IteratorAggregate;
|
||||
use stdClass;
|
||||
|
||||
class LazyCollection implements Enumerable
|
||||
class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
|
||||
{
|
||||
use EnumeratesValues, Macroable;
|
||||
|
||||
@@ -204,6 +205,19 @@ class LazyCollection implements Enumerable
|
||||
return $this->contains($this->operatorForWhere(...func_get_args()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an item is not contained in the enumerable.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function doesntContain($key, $operator = null, $value = null)
|
||||
{
|
||||
return ! $this->contains(...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross join the given iterables, returning all possible permutations.
|
||||
*
|
||||
@@ -316,7 +330,7 @@ class LazyCollection implements Enumerable
|
||||
/**
|
||||
* Retrieve duplicate items.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
@@ -328,7 +342,7 @@ class LazyCollection implements Enumerable
|
||||
/**
|
||||
* Retrieve duplicate items using strict comparison.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param callable|string|null $callback
|
||||
* @return static
|
||||
*/
|
||||
public function duplicatesStrict($callback = null)
|
||||
@@ -512,6 +526,25 @@ class LazyCollection implements Enumerable
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if any of the keys exist in the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAny($key)
|
||||
{
|
||||
$keys = array_flip(is_array($key) ? $key : func_get_args());
|
||||
|
||||
foreach ($this as $key => $value) {
|
||||
if (array_key_exists($key, $keys)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate values of a given key as a string.
|
||||
*
|
||||
@@ -920,6 +953,45 @@ class LazyCollection implements Enumerable
|
||||
return $this->passthru('shuffle', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create chunks representing a "sliding window" view of the items in the collection.
|
||||
*
|
||||
* @param int $size
|
||||
* @param int $step
|
||||
* @return static
|
||||
*/
|
||||
public function sliding($size = 2, $step = 1)
|
||||
{
|
||||
return new static(function () use ($size, $step) {
|
||||
$iterator = $this->getIterator();
|
||||
|
||||
$chunk = [];
|
||||
|
||||
while ($iterator->valid()) {
|
||||
$chunk[$iterator->key()] = $iterator->current();
|
||||
|
||||
if (count($chunk) == $size) {
|
||||
yield tap(new static($chunk), function () use (&$chunk, $step) {
|
||||
$chunk = array_slice($chunk, $step, null, true);
|
||||
});
|
||||
|
||||
// If the $step between chunks is bigger than each chunk's $size
|
||||
// we will skip the extra items (which should never be in any
|
||||
// chunk) before we continue to the next chunk in the loop.
|
||||
if ($step > $size) {
|
||||
$skip = $step - $size;
|
||||
|
||||
for ($i = 0; $i < $skip && $iterator->valid(); $i++) {
|
||||
$iterator->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$iterator->next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the first {$count} items.
|
||||
*
|
||||
@@ -1010,6 +1082,55 @@ class LazyCollection implements Enumerable
|
||||
return $this->passthru('split', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Tightenco\Collect\Support\ItemNotFoundException
|
||||
* @throws \Tightenco\Collect\Support\MultipleItemsFoundException
|
||||
*/
|
||||
public function sole($key = null, $operator = null, $value = null)
|
||||
{
|
||||
$filter = func_num_args() > 1
|
||||
? $this->operatorForWhere(...func_get_args())
|
||||
: $key;
|
||||
|
||||
return $this
|
||||
->when($filter)
|
||||
->filter($filter)
|
||||
->take(2)
|
||||
->collect()
|
||||
->sole();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item in the collection but throw an exception if no matching items exist.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $operator
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Tightenco\Collect\Support\ItemNotFoundException
|
||||
*/
|
||||
public function firstOrFail($key = null, $operator = null, $value = null)
|
||||
{
|
||||
$filter = func_num_args() > 1
|
||||
? $this->operatorForWhere(...func_get_args())
|
||||
: $key;
|
||||
|
||||
return $this
|
||||
->when($filter)
|
||||
->filter($filter)
|
||||
->take(1)
|
||||
->collect()
|
||||
->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk the collection into chunks of the given size.
|
||||
*
|
||||
@@ -1167,6 +1288,17 @@ class LazyCollection implements Enumerable
|
||||
return $this->passthru('sortKeysDesc', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the collection keys using a callback.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return static
|
||||
*/
|
||||
public function sortKeysUsing(callable $callback)
|
||||
{
|
||||
return $this->passthru('sortKeysUsing', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the first or last {$limit} items.
|
||||
*
|
||||
@@ -1264,6 +1396,40 @@ class LazyCollection implements Enumerable
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a flatten "dot" notation array into an expanded array.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function undot()
|
||||
{
|
||||
return $this->passthru('undot', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only unique items from the collection array.
|
||||
*
|
||||
* @param string|callable|null $key
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
public function unique($key = null, $strict = false)
|
||||
{
|
||||
$callback = $this->valueRetriever($key);
|
||||
|
||||
return new static(function () use ($callback, $strict) {
|
||||
$exists = [];
|
||||
|
||||
foreach ($this as $key => $item) {
|
||||
if (! in_array($id = $callback($item, $key), $exists, $strict)) {
|
||||
yield $key => $item;
|
||||
|
||||
$exists[] = $id;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the keys on the underlying array.
|
||||
*
|
||||
@@ -1337,6 +1503,7 @@ class LazyCollection implements Enumerable
|
||||
*
|
||||
* @return \Traversable
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->makeIterator($this->source);
|
||||
@@ -1347,6 +1514,7 @@ class LazyCollection implements Enumerable
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
if (is_array($this->source)) {
|
||||
|
@@ -15,11 +15,13 @@ use Tightenco\Collect\Support\HigherOrderWhenProxy;
|
||||
use JsonSerializable;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
use Traversable;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @property-read HigherOrderCollectionProxy $average
|
||||
* @property-read HigherOrderCollectionProxy $avg
|
||||
* @property-read HigherOrderCollectionProxy $contains
|
||||
* @property-read HigherOrderCollectionProxy $doesntContain
|
||||
* @property-read HigherOrderCollectionProxy $each
|
||||
* @property-read HigherOrderCollectionProxy $every
|
||||
* @property-read HigherOrderCollectionProxy $filter
|
||||
@@ -45,6 +47,13 @@ use Traversable;
|
||||
*/
|
||||
trait EnumeratesValues
|
||||
{
|
||||
/**
|
||||
* Indicates that the object's string representation should be escaped when __toString is invoked.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeWhenCastingToString = false;
|
||||
|
||||
/**
|
||||
* The methods that can be proxied.
|
||||
*
|
||||
@@ -54,6 +63,7 @@ trait EnumeratesValues
|
||||
'average',
|
||||
'avg',
|
||||
'contains',
|
||||
'doesntContain',
|
||||
'each',
|
||||
'every',
|
||||
'filter',
|
||||
@@ -713,6 +723,22 @@ trait EnumeratesValues
|
||||
return new $class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the collection through a series of callable pipes and return the result.
|
||||
*
|
||||
* @param array<callable> $pipes
|
||||
* @return mixed
|
||||
*/
|
||||
public function pipeThrough($pipes)
|
||||
{
|
||||
return static::make($pipes)->reduce(
|
||||
function ($carry, $pipe) {
|
||||
return $pipe($carry);
|
||||
},
|
||||
$this,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the collection to the given callback and then return it.
|
||||
*
|
||||
@@ -730,7 +756,7 @@ trait EnumeratesValues
|
||||
* Reduce the collection to a single value.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param mixed $initial
|
||||
* @param mixed $initial
|
||||
* @return mixed
|
||||
*/
|
||||
public function reduce(callable $callback, $initial = null)
|
||||
@@ -745,23 +771,60 @@ trait EnumeratesValues
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce an associative collection to a single value.
|
||||
* Reduce the collection to multiple aggregate values.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param mixed $initial
|
||||
* @return mixed
|
||||
* @param mixed ...$initial
|
||||
* @return array
|
||||
*
|
||||
* @deprecated Use "reduceSpread" instead
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public function reduceWithKeys(callable $callback, $initial = null)
|
||||
public function reduceMany(callable $callback, ...$initial)
|
||||
{
|
||||
return $this->reduceSpread($callback, ...$initial);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the collection to multiple aggregate values.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param mixed ...$initial
|
||||
* @return array
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public function reduceSpread(callable $callback, ...$initial)
|
||||
{
|
||||
$result = $initial;
|
||||
|
||||
foreach ($this as $key => $value) {
|
||||
$result = $callback($result, $value, $key);
|
||||
$result = call_user_func_array($callback, array_merge($result, [$value, $key]));
|
||||
|
||||
if (! is_array($result)) {
|
||||
throw new UnexpectedValueException(sprintf(
|
||||
"%s::reduceMany expects reducer to return an array, but got a '%s' instead.",
|
||||
class_basename(static::class), gettype($result)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce an associative collection to a single value.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param mixed $initial
|
||||
* @return mixed
|
||||
*/
|
||||
public function reduceWithKeys(callable $callback, $initial = null)
|
||||
{
|
||||
return $this->reduce($callback, $initial);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a collection of all elements that do not pass a given truth test.
|
||||
*
|
||||
@@ -779,28 +842,6 @@ trait EnumeratesValues
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only unique items from the collection array.
|
||||
*
|
||||
* @param string|callable|null $key
|
||||
* @param bool $strict
|
||||
* @return static
|
||||
*/
|
||||
public function unique($key = null, $strict = false)
|
||||
{
|
||||
$callback = $this->valueRetriever($key);
|
||||
|
||||
$exists = [];
|
||||
|
||||
return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
|
||||
if (in_array($id = $callback($item, $key), $exists, $strict)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$exists[] = $id;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only unique items from the collection array using strict comparison.
|
||||
*
|
||||
@@ -839,6 +880,7 @@ trait EnumeratesValues
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return array_map(function ($value) {
|
||||
@@ -883,7 +925,22 @@ trait EnumeratesValues
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toJson();
|
||||
return $this->escapeWhenCastingToString
|
||||
? e($this->toJson())
|
||||
: $this->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the model's string representation should be escaped when __toString is invoked.
|
||||
*
|
||||
* @param bool $escape
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeWhenCastingToString($escape = true)
|
||||
{
|
||||
$this->escapeWhenCastingToString = $escape;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -62,6 +62,16 @@ trait Macroable
|
||||
return isset(static::$macros[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the existing macros.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function flushMacros()
|
||||
{
|
||||
static::$macros = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls to the class.
|
||||
*
|
||||
|
@@ -8,7 +8,7 @@ trait Tappable
|
||||
* Call the given Closure with this instance then return the instance.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @return mixed
|
||||
* @return $this|\Tightenco\Collect\Support\HigherOrderTapProxy
|
||||
*/
|
||||
public function tap($callback = null)
|
||||
{
|
||||
|
@@ -4,6 +4,7 @@ $aliases = [
|
||||
Tightenco\Collect\Contracts\Support\Arrayable::class => Illuminate\Contracts\Support\Arrayable::class,
|
||||
Tightenco\Collect\Contracts\Support\Jsonable::class => Illuminate\Contracts\Support\Jsonable::class,
|
||||
Tightenco\Collect\Contracts\Support\Htmlable::class => Illuminate\Contracts\Support\Htmlable::class,
|
||||
Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString::class => Illuminate\Contracts\Support\CanBeEscapedWhenCastToString::class,
|
||||
Tightenco\Collect\Support\Arr::class => Illuminate\Support\Arr::class,
|
||||
Tightenco\Collect\Support\Collection::class => Illuminate\Support\Collection::class,
|
||||
Tightenco\Collect\Support\Enumerable::class => Illuminate\Support\Enumerable::class,
|
||||
@@ -13,8 +14,11 @@ $aliases = [
|
||||
Tightenco\Collect\Support\Traits\EnumeratesValues::class => Illuminate\Support\Traits\EnumeratesValues::class,
|
||||
];
|
||||
|
||||
# echo "\n\n-- Aliasing....\n---------------------------------------------\n\n";
|
||||
|
||||
foreach ($aliases as $tighten => $illuminate) {
|
||||
if (! class_exists($illuminate) && ! interface_exists($illuminate) && ! trait_exists($illuminate)) {
|
||||
# echo "Aliasing {$tighten} to {$illuminate}.\n";
|
||||
class_alias($tighten, $illuminate);
|
||||
}
|
||||
}
|
||||
|
@@ -6,19 +6,6 @@ use Tightenco\Collect\Support\HigherOrderTapProxy;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
|
||||
if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
if (! function_exists('array_wrap')) {
|
||||
/**
|
||||
* If the given value is not an array, wrap it in one.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return array
|
||||
*/
|
||||
function array_wrap($value)
|
||||
{
|
||||
return ! is_array($value) ? [$value] : $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('collect')) {
|
||||
/**
|
||||
* Create a collection from the given value.
|
||||
@@ -39,9 +26,9 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
function value($value)
|
||||
function value($value, ...$args)
|
||||
{
|
||||
return $value instanceof Closure ? $value() : $value;
|
||||
return $value instanceof Closure ? $value(...$args) : $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +36,9 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
/**
|
||||
* Get an item from an array or object using "dot" notation.
|
||||
*
|
||||
* @param mixed $target
|
||||
* @param string|array $key
|
||||
* @param mixed $default
|
||||
* @param mixed $target
|
||||
* @param string|array|int|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
function data_get($target, $key, $default = null)
|
||||
@@ -62,7 +49,13 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
|
||||
$key = is_array($key) ? $key : explode('.', $key);
|
||||
|
||||
while (($segment = array_shift($key)) !== null) {
|
||||
foreach ($key as $i => $segment) {
|
||||
unset($key[$i]);
|
||||
|
||||
if (is_null($segment)) {
|
||||
return $target;
|
||||
}
|
||||
|
||||
if ($segment === '*') {
|
||||
if ($target instanceof Collection) {
|
||||
$target = $target->all();
|
||||
@@ -70,7 +63,11 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
return value($default);
|
||||
}
|
||||
|
||||
$result = Arr::pluck($target, $key);
|
||||
$result = [];
|
||||
|
||||
foreach ($target as $item) {
|
||||
$result[] = data_get($item, $key);
|
||||
}
|
||||
|
||||
return in_array('*', $key) ? Arr::collapse($result) : $result;
|
||||
}
|
||||
@@ -108,32 +105,18 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('with')) {
|
||||
if (! function_exists('class_basename')) {
|
||||
/**
|
||||
* Return the given object. Useful for chaining.
|
||||
* Get the class "basename" of the given object / class.
|
||||
*
|
||||
* @param mixed $object
|
||||
* @return mixed
|
||||
* @param string|object $class
|
||||
* @return string
|
||||
*/
|
||||
function with($object)
|
||||
function class_basename($class)
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
$class = is_object($class) ? get_class($class) : $class;
|
||||
|
||||
if (! function_exists('dd')) {
|
||||
/**
|
||||
* Dump the passed variables and end the script.
|
||||
*
|
||||
* @param mixed
|
||||
* @return void
|
||||
*/
|
||||
function dd(...$args)
|
||||
{
|
||||
foreach ($args as $x) {
|
||||
VarDumper::dump($x);
|
||||
}
|
||||
die(1);
|
||||
return basename(str_replace('\\', '/', $class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user