fixes
This commit is contained in:
126
vendor/laravel/framework/CHANGELOG.md
vendored
126
vendor/laravel/framework/CHANGELOG.md
vendored
@@ -1,6 +1,130 @@
|
||||
# Release Notes for 9.x
|
||||
|
||||
## [Unreleased](https://github.com/laravel/framework/compare/v9.47.0...9.x)
|
||||
## [Unreleased](https://github.com/laravel/framework/compare/v9.51.0...9.x)
|
||||
|
||||
|
||||
## [v9.51.0](https://github.com/laravel/framework/compare/v9.50.2...v9.51.0) - 2023-02-07
|
||||
|
||||
### Added
|
||||
- Added `Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase::expectsDatabaseQueryCount()` ([#45932](https://github.com/laravel/framework/pull/45932))
|
||||
- Added pending has-many-through and has-one-through builder ([#45894](https://github.com/laravel/framework/pull/45894))
|
||||
- Added `Illuminate/Http/Client/PendingRequest::withUrlParameters()` ([#45982](https://github.com/laravel/framework/pull/45982))
|
||||
|
||||
### Fixed
|
||||
- Fix: prevent duplicated content-type on HTTP client ([#45960](https://github.com/laravel/framework/pull/45960))
|
||||
- Add missing php extensions in composer ([#45941](https://github.com/laravel/framework/pull/45941))
|
||||
|
||||
### Changed
|
||||
- Command schedule:work minor features: schedule:run output file & environment specific verbosity ([#45949](https://github.com/laravel/framework/pull/45949))
|
||||
- Added missing self reserved word to reservedNames array in `Illuminate/Console/GeneratorCommand.php` ([#46001](https://github.com/laravel/framework/pull/46001))
|
||||
- pass value along to ttl callback in `Illuminate/Cache/Repository::remember()` ([#46006](https://github.com/laravel/framework/pull/46006))
|
||||
- Make sure the lock_connection is used for schedule's withoutOverlapping() ([#45963](https://github.com/laravel/framework/pull/45963))
|
||||
|
||||
|
||||
## [v9.50.2](https://github.com/laravel/framework/compare/v9.50.1...v9.50.2) - 2023-02-02
|
||||
|
||||
### Fixed
|
||||
- Fixed missing_with and missing_with_all validation ([#45913](https://github.com/laravel/framework/pull/45913))
|
||||
- Fixes blade escaped tags issue ([#45928](https://github.com/laravel/framework/pull/45928))
|
||||
|
||||
### Changed
|
||||
- Trims numeric validation values / parameters ([#45912](https://github.com/laravel/framework/pull/45912))
|
||||
- Random function doesn't generate evenly distributed random chars ([#45916](https://github.com/laravel/framework/pull/45916))
|
||||
|
||||
|
||||
## [v9.50.1](https://github.com/laravel/framework/compare/v9.50.0...v9.50.1) - 2023-02-01
|
||||
|
||||
### Reverted
|
||||
- Reverted ["Optimize destroy method"](https://github.com/laravel/framework/pull/45709) ([#45903](https://github.com/laravel/framework/pull/45903))
|
||||
|
||||
### Changed
|
||||
- Allow scheme to be specified in `Illuminate/Mail/MailManager::createSmtpTransport()` ([68a8bfc](https://github.com/laravel/framework/commit/68a8bfc3ab758962c8f050160ec32833dc12e467))
|
||||
- Accept optional mode in `Illuminate/Filesystem/Filesystem::replace()` ([2664e7f](https://github.com/laravel/framework/commit/2664e7fcdfe3a290462ae8e326ba79a17c747c1e))
|
||||
|
||||
|
||||
## [v9.50.0](https://github.com/laravel/framework/compare/v9.49.0...v9.50.0) - 2023-02-01
|
||||
|
||||
### Added
|
||||
- Added `Illuminate/Translation/Translator::stringable()` ([#45874](https://github.com/laravel/framework/pull/45874))
|
||||
- Added `Illuminate/Foundation/Testing/DatabaseTruncation` ([#45726](https://github.com/laravel/framework/pull/45726))
|
||||
- Added @style Blade directive ([#45887](https://github.com/laravel/framework/pull/45887))
|
||||
|
||||
### Reverted
|
||||
- Reverted: ["Fix Illuminate Filesystem replace() leaves file executable"](https://github.com/laravel/framework/pull/45856) ([5ea388d](https://github.com/laravel/framework/commit/5ea388d7fe6f786b6dbcb34e0b52341c0b38ad7e))
|
||||
|
||||
### Fixed
|
||||
- Fixed LazyCollection::makeIterator() to accept non Generator Function ([#45881](https://github.com/laravel/framework/pull/45881))
|
||||
|
||||
### Changed
|
||||
- Solve data to be dumped for separate schemes ([#45805](https://github.com/laravel/framework/pull/45805))
|
||||
|
||||
|
||||
## [v9.49.0](https://github.com/laravel/framework/compare/v9.48.0...v9.49.0) - 2023-01-31
|
||||
|
||||
### Added
|
||||
- Added `Illuminate/Database/Schema/ForeignKeyDefinition::noActionOnDelete()` ([#45712](https://github.com/laravel/framework/pull/45712))
|
||||
- Added new throw helper methods to the HTTP Client ([#45704](https://github.com/laravel/framework/pull/45704))
|
||||
- Added configurable timezone support for WorkCommand output timestamps ([#45722](https://github.com/laravel/framework/pull/45722))
|
||||
- Added support for casting arrays containing enums ([#45621](https://github.com/laravel/framework/pull/45621))
|
||||
- Added "missing" validation rules ([#45717](https://github.com/laravel/framework/pull/45717))
|
||||
- Added `/Illuminate/Database/Eloquent/SoftDeletes::forceDeleteQuietly()` ([#45737](https://github.com/laravel/framework/pull/45737))
|
||||
- Added `Illuminate/Collections/Arr::sortDesc()` ([#45761](https://github.com/laravel/framework/pull/45761))
|
||||
- Added CLI Prompts ([#45629](https://github.com/laravel/framework/pull/45629), [#45864](https://github.com/laravel/framework/pull/45864))
|
||||
- Adds assertJsonIsArray and assertJsonIsObject for TestResponse ([#45731](https://github.com/laravel/framework/pull/45731))
|
||||
- Added `Illuminate/Database/Eloquent/Relations/HasOneOrMany::createQuietly()` ([#45783](https://github.com/laravel/framework/pull/45783))
|
||||
- Add validation rules: ascii_alpha, ascii_alpha_num, ascii_alpha_dash ([#45769](https://github.com/laravel/framework/pull/45769))
|
||||
- Extract status methods to traits ([#45789](https://github.com/laravel/framework/pull/45789))
|
||||
- Add "addRestoreOrCreate" extension to SoftDeletingScope ([#45754](https://github.com/laravel/framework/pull/45754))
|
||||
- Added connection established event ([f850d99](https://github.com/laravel/framework/commit/f850d99c50d173189ece2bb37b6c7ddcb456f1f9))
|
||||
- Add forceDeleting event to models ([#45836](https://github.com/laravel/framework/pull/45836))
|
||||
- Add title tag in mail template ([#45859](https://github.com/laravel/framework/pull/45859))
|
||||
- Added new methods to Collection ([#45839](https://github.com/laravel/framework/pull/45839))
|
||||
- Add skip cancelled middleware ([#45869](https://github.com/laravel/framework/pull/45869))
|
||||
|
||||
### Fixed
|
||||
- Fix flushdb on cluster for `PredisClusterConnection.php` ([#45544](https://github.com/laravel/framework/pull/45544))
|
||||
- Fix blade tag issue with nested calls ([#45764](https://github.com/laravel/framework/pull/45764))
|
||||
- Fix infinite loop in blade compiler ([#45780](https://github.com/laravel/framework/pull/45780))
|
||||
- Fix ValidationValidator not to accept terminating newline ([#45790](https://github.com/laravel/framework/pull/45790))
|
||||
- Fix stubs publish command generating incorrect controller stubs ([#45812](https://github.com/laravel/framework/pull/45812))
|
||||
- fix: normalize route pipeline exception ([#45817](https://github.com/laravel/framework/pull/45817))
|
||||
- Fix Illuminate Filesystem replace() leaves file executable ([#45856](https://github.com/laravel/framework/pull/45856))
|
||||
|
||||
### Changed
|
||||
- Ensures channel name matches from start of string ([#45692](https://github.com/laravel/framework/pull/45692))
|
||||
- Replace raw invisible characters in regex expressions with counterpart Unicode regex notations ([#45680](https://github.com/laravel/framework/pull/45680))
|
||||
- Optimize destroy method ([#45709](https://github.com/laravel/framework/pull/45709))
|
||||
- Unify prohibits behavior around prohibits_if ([#45723](https://github.com/laravel/framework/pull/45723))
|
||||
- Removes dependency on bcmath ([#45729](https://github.com/laravel/framework/pull/45729))
|
||||
- Allow brick/math 0.11 also ([#45762](https://github.com/laravel/framework/pull/45762))
|
||||
- Optimize findMany of BelongsToMany ([#45745](https://github.com/laravel/framework/pull/45745))
|
||||
- Ensure decimal rule handles large values ([#45693](https://github.com/laravel/framework/pull/45693))
|
||||
- Backed enum support for @js ([#45862](https://github.com/laravel/framework/pull/45862))
|
||||
- Restart syscalls for SIGALRM when worker times out a job ([#45871](https://github.com/laravel/framework/pull/45871))
|
||||
- Ensure subsiquent calls to Mailable->to() overwrite previous entries ([#45885](https://github.com/laravel/framework/pull/45885))
|
||||
|
||||
|
||||
## [v9.48.0](https://github.com/laravel/framework/compare/v9.47.0...v9.48.0) - 2023-01-17
|
||||
|
||||
### Added
|
||||
- Added `Illuminate/Database/Schema/Builder::withoutForeignKeyConstraints()` ([#45601](https://github.com/laravel/framework/pull/45601))
|
||||
- Added `fragments()` \ `fragmentIf()` \ `fragmentsIf()` methods to `Illuminate/View/View.php` class ([#45656](https://github.com/laravel/framework/pull/45656), [#45669](https://github.com/laravel/framework/pull/45669))
|
||||
- Added `incrementEach()` and `decrementEach()` to `Illuminate/Database/Query/Builder` ([#45577](https://github.com/laravel/framework/pull/45577))
|
||||
- Added ability to drop an index when modifying a column ([#45513](https://github.com/laravel/framework/pull/45513))
|
||||
- Allow to set HTTP client for mailers ([#45684](https://github.com/laravel/framework/pull/45684))
|
||||
- Added 402 exception view ([#45682](https://github.com/laravel/framework/pull/45682))
|
||||
- Added `notFound()` helper to Http Client response ([#45681](https://github.com/laravel/framework/pull/45681))
|
||||
|
||||
### Fixed
|
||||
- Fixed decimal cast ([#45602](https://github.com/laravel/framework/pull/45602))
|
||||
|
||||
### Changed
|
||||
- Ignore whitespaces/newlines when finding relations in model:show command ([#45608](https://github.com/laravel/framework/pull/45608))
|
||||
- Fail queued job with a string messag ([#45625](https://github.com/laravel/framework/pull/45625))
|
||||
- Allow fake() helper in unit tests ([#45624](https://github.com/laravel/framework/pull/45624))
|
||||
- allow egulias/email-validator v4 ([#45649](https://github.com/laravel/framework/pull/45649))
|
||||
- Force countBy method in EloquentCollection to return base collection ([#45663](https://github.com/laravel/framework/pull/45663))
|
||||
- Allow for the collection of stubs to be published ([#45653](https://github.com/laravel/framework/pull/45653))
|
||||
|
||||
|
||||
## [v9.47.0](https://github.com/laravel/framework/compare/v9.46.0...v9.47.0) - 2023-01-10
|
||||
|
17
vendor/laravel/framework/composer.json
vendored
17
vendor/laravel/framework/composer.json
vendored
@@ -16,13 +16,19 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-filter": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"brick/math": "^0.10.2",
|
||||
"doctrine/inflector": "^2.0",
|
||||
"ext-session": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"brick/math": "^0.9.3|^0.10.2|^0.11",
|
||||
"doctrine/inflector": "^2.0.5",
|
||||
"dragonmantank/cron-expression": "^3.3.2",
|
||||
"egulias/email-validator": "^3.2.1|^4.0",
|
||||
"fruitcake/php-cors": "^1.2",
|
||||
"guzzlehttp/uri-template": "^1.0",
|
||||
"laravel/serializable-closure": "^1.2.2",
|
||||
"league/commonmark": "^2.2.1",
|
||||
"league/flysystem": "^3.8.0",
|
||||
@@ -83,6 +89,7 @@
|
||||
"illuminate/view": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gmp": "*",
|
||||
"ably/ably-php": "^1.0",
|
||||
"aws/aws-sdk-php": "^3.235.5",
|
||||
"doctrine/dbal": "^2.13.3|^3.1.4",
|
||||
@@ -140,11 +147,13 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Required to use the multiple_of validation rule.",
|
||||
"ext-apcu": "Required to use the APC cache driver.",
|
||||
"ext-fileinfo": "Required to use the Filesystem class.",
|
||||
"ext-ftp": "Required to use the Flysystem FTP driver.",
|
||||
"ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().",
|
||||
"ext-memcached": "Required to use the memcache cache driver.",
|
||||
"ext-pcntl": "Required to use all features of the queue worker.",
|
||||
"ext-pcntl": "Required to use all features of the queue worker and console signal trapping.",
|
||||
"ext-pdo": "Required to use all database features.",
|
||||
"ext-posix": "Required to use all features of the queue worker.",
|
||||
"ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).",
|
||||
"ably/ably-php": "Required to use the Ably broadcast driver (^1.0).",
|
||||
|
@@ -15,6 +15,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-hash": "*",
|
||||
"illuminate/collections": "^9.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
"illuminate/http": "^9.0",
|
||||
|
@@ -371,6 +371,6 @@ abstract class Broadcaster implements BroadcasterContract
|
||||
*/
|
||||
protected function channelNameMatchesPattern($channel, $pattern)
|
||||
{
|
||||
return preg_match('/'.preg_replace('/\{(.*?)\}/', '([^\.]+)', $pattern).'$/', $channel);
|
||||
return preg_match('/^'.preg_replace('/\{(.*?)\}/', '([^\.]+)', $pattern).'$/', $channel);
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,6 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-json": "*",
|
||||
"psr/log": "^1.0|^2.0|^3.0",
|
||||
"illuminate/bus": "^9.0",
|
||||
"illuminate/collections": "^9.0",
|
||||
@@ -35,6 +34,7 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-hash": "Required to use the Ably and Pusher broadcast drivers.",
|
||||
"ably/ably-php": "Required to use the Ably broadcast driver (^1.0).",
|
||||
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0)."
|
||||
},
|
||||
|
16
vendor/laravel/framework/src/Illuminate/Cache/FileLock.php
vendored
Normal file
16
vendor/laravel/framework/src/Illuminate/Cache/FileLock.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
class FileLock extends CacheLock
|
||||
{
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
return $this->store->add($this->name, $this->owner, $this->seconds);
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@ use Illuminate\Support\InteractsWithTime;
|
||||
|
||||
class FileStore implements Store, LockProvider
|
||||
{
|
||||
use InteractsWithTime, HasCacheLock, RetrievesMultipleKeys;
|
||||
use InteractsWithTime, RetrievesMultipleKeys;
|
||||
|
||||
/**
|
||||
* The Illuminate Filesystem instance.
|
||||
@@ -200,6 +200,31 @@ class FileStore implements Store, LockProvider
|
||||
return $this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @param string|null $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0, $owner = null)
|
||||
{
|
||||
return new FileLock($this, $name, $seconds, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a lock instance using the owner identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function restoreLock($name, $owner)
|
||||
{
|
||||
return $this->lock($name, 0, $owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
|
@@ -394,7 +394,9 @@ class Repository implements ArrayAccess, CacheContract
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->put($key, $value = $callback(), value($ttl));
|
||||
$value = $callback();
|
||||
|
||||
$this->put($key, $value, value($ttl, $value));
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
@@ -34,6 +34,8 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-apcu": "Required to use the APC cache driver.",
|
||||
"ext-filter": "Required to use the DynamoDb cache driver.",
|
||||
"ext-memcached": "Required to use the memcache cache driver.",
|
||||
"illuminate/database": "Required to use the database cache driver (^9.0).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (^9.0).",
|
||||
|
@@ -731,6 +731,18 @@ class Arr
|
||||
return Collection::make($array)->sortBy($callback)->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the array in descending order using the given callback or "dot" notation.
|
||||
*
|
||||
* @param array $array
|
||||
* @param callable|array|string|null $callback
|
||||
* @return array
|
||||
*/
|
||||
public static function sortDesc($array, $callback = null)
|
||||
{
|
||||
return Collection::make($array)->sortByDesc($callback)->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively sort an array by keys and values.
|
||||
*
|
||||
@@ -783,6 +795,29 @@ class Arr
|
||||
return implode(' ', $classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally compile styles from an array into a style list.
|
||||
*
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
public static function toCssStyles($array)
|
||||
{
|
||||
$styleList = static::wrap($array);
|
||||
|
||||
$styles = [];
|
||||
|
||||
foreach ($styleList as $class => $constraint) {
|
||||
if (is_numeric($class)) {
|
||||
$styles[] = Str::finish($constraint, ';');
|
||||
} elseif ($constraint) {
|
||||
$styles[] = Str::finish($class, ';');
|
||||
}
|
||||
}
|
||||
|
||||
return implode(' ', $styles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the array using the given callback.
|
||||
*
|
||||
@@ -803,9 +838,7 @@ class Arr
|
||||
*/
|
||||
public static function whereNotNull($array)
|
||||
{
|
||||
return static::where($array, function ($value) {
|
||||
return ! is_null($value);
|
||||
});
|
||||
return static::where($array, fn ($value) => ! is_null($value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -84,11 +84,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
|
||||
{
|
||||
$callback = $this->valueRetriever($callback);
|
||||
|
||||
$items = $this->map(function ($value) use ($callback) {
|
||||
return $callback($value);
|
||||
})->filter(function ($value) {
|
||||
return ! is_null($value);
|
||||
});
|
||||
$items = $this
|
||||
->map(fn ($value) => $callback($value))
|
||||
->filter(fn ($value) => ! is_null($value));
|
||||
|
||||
if ($count = $items->count()) {
|
||||
return $items->sum() / $count;
|
||||
@@ -349,14 +347,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
|
||||
protected function duplicateComparator($strict)
|
||||
{
|
||||
if ($strict) {
|
||||
return function ($a, $b) {
|
||||
return $a === $b;
|
||||
};
|
||||
return fn ($a, $b) => $a === $b;
|
||||
}
|
||||
|
||||
return function ($a, $b) {
|
||||
return $a == $b;
|
||||
};
|
||||
return fn ($a, $b) => $a == $b;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -627,6 +621,41 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
|
||||
return new static(array_intersect($this->items, $this->getArrayableItems($items)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items, using the callback.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
|
||||
* @param callable(TValue, TValue): int $callback
|
||||
* @return static
|
||||
*/
|
||||
public function intersectUsing($items, callable $callback)
|
||||
{
|
||||
return new static(array_uintersect($this->items, $this->getArrayableItems($items), $callback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items with additional index check.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
|
||||
* @return static
|
||||
*/
|
||||
public function intersectAssoc($items)
|
||||
{
|
||||
return new static(array_intersect_assoc($this->items, $this->getArrayableItems($items)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items with additional index check, using the callback.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
|
||||
* @param callable(TValue, TValue): int $callback
|
||||
* @return static
|
||||
*/
|
||||
public function intersectAssocUsing($items, callable $callback)
|
||||
{
|
||||
return new static(array_intersect_uassoc($this->items, $this->getArrayableItems($items), $callback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items by key.
|
||||
*
|
||||
@@ -872,7 +901,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
|
||||
/**
|
||||
* Get the items with the specified keys.
|
||||
*
|
||||
* @param \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string $keys
|
||||
* @param \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string|null $keys
|
||||
* @return static
|
||||
*/
|
||||
public function only($keys)
|
||||
@@ -1598,13 +1627,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
|
||||
*/
|
||||
public function zip($items)
|
||||
{
|
||||
$arrayableItems = array_map(function ($items) {
|
||||
return $this->getArrayableItems($items);
|
||||
}, func_get_args());
|
||||
$arrayableItems = array_map(fn ($items) => $this->getArrayableItems($items), func_get_args());
|
||||
|
||||
$params = array_merge([function () {
|
||||
return new static(func_get_args());
|
||||
}, $this->items], $arrayableItems);
|
||||
$params = array_merge([fn () => new static(func_get_args()), $this->items], $arrayableItems);
|
||||
|
||||
return new static(array_map(...$params));
|
||||
}
|
||||
|
@@ -51,11 +51,10 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
|
||||
/**
|
||||
* Wrap the given value in a collection if applicable.
|
||||
*
|
||||
* @template TWrapKey of array-key
|
||||
* @template TWrapValue
|
||||
*
|
||||
* @param iterable<TWrapKey, TWrapValue> $value
|
||||
* @return static<TWrapKey, TWrapValue>
|
||||
* @param iterable<array-key, TWrapValue>|TWrapValue $value
|
||||
* @return static<array-key, TWrapValue>
|
||||
*/
|
||||
public static function wrap($value);
|
||||
|
||||
|
@@ -430,9 +430,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
|
||||
public function filter(callable $callback = null)
|
||||
{
|
||||
if (is_null($callback)) {
|
||||
$callback = function ($value) {
|
||||
return (bool) $value;
|
||||
};
|
||||
$callback = fn ($value) => (bool) $value;
|
||||
}
|
||||
|
||||
return new static(function () use ($callback) {
|
||||
@@ -632,6 +630,41 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
|
||||
return $this->passthru('intersect', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items, using the callback.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
|
||||
* @param callable(TValue, TValue): int $callback
|
||||
* @return static
|
||||
*/
|
||||
public function intersectUsing()
|
||||
{
|
||||
return $this->passthru('intersectUsing', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items with additional index check.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
|
||||
* @return static
|
||||
*/
|
||||
public function intersectAssoc($items)
|
||||
{
|
||||
return $this->passthru('intersectAssoc', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items with additional index check, using the callback.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
|
||||
* @param callable(TValue, TValue): int $callback
|
||||
* @return static
|
||||
*/
|
||||
public function intersectAssocUsing($items, callable $callback)
|
||||
{
|
||||
return $this->passthru('intersectAssocUsing', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items by key.
|
||||
*
|
||||
@@ -1465,9 +1498,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
|
||||
/** @var callable(TValue, TKey): bool $callback */
|
||||
$callback = $this->useAsCallable($value) ? $value : $this->equality($value);
|
||||
|
||||
return $this->takeUntil(function ($item, $key) use ($callback) {
|
||||
return ! $callback($item, $key);
|
||||
});
|
||||
return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1636,7 +1667,15 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
|
||||
return new ArrayIterator($source);
|
||||
}
|
||||
|
||||
return $source();
|
||||
if (is_callable($source)) {
|
||||
$maybeTraversable = $source();
|
||||
|
||||
return $maybeTraversable instanceof Traversable
|
||||
? $maybeTraversable
|
||||
: new ArrayIterator(Arr::wrap($maybeTraversable));
|
||||
}
|
||||
|
||||
return new ArrayIterator((array) $source);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -114,11 +114,10 @@ trait EnumeratesValues
|
||||
/**
|
||||
* Wrap the given value in a collection if applicable.
|
||||
*
|
||||
* @template TWrapKey of array-key
|
||||
* @template TWrapValue
|
||||
*
|
||||
* @param iterable<TWrapKey, TWrapValue> $value
|
||||
* @return static<TWrapKey, TWrapValue>
|
||||
* @param iterable<array-key, TWrapValue>|TWrapValue $value
|
||||
* @return static<array-key, TWrapValue>
|
||||
*/
|
||||
public static function wrap($value)
|
||||
{
|
||||
|
@@ -180,7 +180,7 @@ if (! function_exists('value')) {
|
||||
* Return the default value of the given value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $args
|
||||
* @param mixed ...$args
|
||||
* @return mixed
|
||||
*/
|
||||
function value($value, ...$args)
|
||||
|
@@ -13,7 +13,7 @@ trait Conditionable
|
||||
* @template TWhenParameter
|
||||
* @template TWhenReturnType
|
||||
*
|
||||
* @param (\Closure($this): TWhenParameter)|TWhenParameter|null $value
|
||||
* @param (\Closure($this): TWhenParameter)|TWhenParameter|null $value
|
||||
* @param (callable($this, TWhenParameter): TWhenReturnType)|null $callback
|
||||
* @param (callable($this, TWhenParameter): TWhenReturnType)|null $default
|
||||
* @return $this|TWhenReturnType
|
||||
|
@@ -16,6 +16,7 @@ class Command extends SymfonyCommand
|
||||
Concerns\HasParameters,
|
||||
Concerns\InteractsWithIO,
|
||||
Concerns\InteractsWithSignals,
|
||||
Concerns\PromptsForMissingInput,
|
||||
Macroable;
|
||||
|
||||
/**
|
||||
|
108
vendor/laravel/framework/src/Illuminate/Console/Concerns/PromptsForMissingInput.php
vendored
Normal file
108
vendor/laravel/framework/src/Illuminate/Console/Concerns/PromptsForMissingInput.php
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput as PromptsForMissingInputContract;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
trait PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* Interact with the user before validating the input.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
parent::interact($input, $output);
|
||||
|
||||
if ($this instanceof PromptsForMissingInputContract) {
|
||||
$this->promptForMissingArguments($input, $output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for any missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function promptForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$prompted = collect($this->getDefinition()->getArguments())
|
||||
->filter(fn ($argument) => $argument->isRequired() && is_null($input->getArgument($argument->getName())))
|
||||
->filter(fn ($argument) => $argument->getName() !== 'command')
|
||||
->each(fn ($argument) => $input->setArgument(
|
||||
$argument->getName(),
|
||||
$this->askPersistently(
|
||||
$this->promptForMissingArgumentsUsing()[$argument->getName()] ??
|
||||
'What is '.lcfirst($argument->getDescription()).'?'
|
||||
)
|
||||
))
|
||||
->isNotEmpty();
|
||||
|
||||
if ($prompted) {
|
||||
$this->afterPromptingForMissingArguments($input, $output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions after the user was prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the input contains any options that differ from the default values.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @return bool
|
||||
*/
|
||||
protected function didReceiveOptions(InputInterface $input)
|
||||
{
|
||||
return collect($this->getDefinition()->getOptions())
|
||||
->reject(fn ($option) => $input->getOption($option->getName()) === $option->getDefault())
|
||||
->isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue asking a question until an answer is provided.
|
||||
*
|
||||
* @param string $question
|
||||
* @return string
|
||||
*/
|
||||
private function askPersistently($question)
|
||||
{
|
||||
$answer = null;
|
||||
|
||||
while ($answer === null) {
|
||||
$answer = $this->components->ask($question);
|
||||
|
||||
if ($answer === null) {
|
||||
$this->components->error('The answer is required.');
|
||||
}
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
}
|
@@ -3,11 +3,13 @@
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Console\Concerns\CreatesMatchingTest;
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
abstract class GeneratorCommand extends Command
|
||||
abstract class GeneratorCommand extends Command implements PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
@@ -90,6 +92,7 @@ abstract class GeneratorCommand extends Command
|
||||
'require',
|
||||
'require_once',
|
||||
'return',
|
||||
'self',
|
||||
'static',
|
||||
'switch',
|
||||
'throw',
|
||||
@@ -233,6 +236,40 @@ abstract class GeneratorCommand extends Command
|
||||
: $rootNamespace.$model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of possible model names.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
protected function possibleModels()
|
||||
{
|
||||
$modelPath = is_dir(app_path('Models')) ? app_path('Models') : app_path();
|
||||
|
||||
return collect((new Finder)->files()->depth(0)->in($modelPath))
|
||||
->map(fn ($file) => $file->getBasename('.php'))
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of possible event names.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
protected function possibleEvents()
|
||||
{
|
||||
$eventPath = app_path('Events');
|
||||
|
||||
if (! is_dir($eventPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect((new Finder)->files()->depth(0)->in($eventPath))
|
||||
->map(fn ($file) => $file->getBasename('.php'))
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
@@ -436,7 +473,19 @@ abstract class GeneratorCommand extends Command
|
||||
protected function getArguments()
|
||||
{
|
||||
return [
|
||||
['name', InputArgument::REQUIRED, 'The name of the class'],
|
||||
['name', InputArgument::REQUIRED, 'The name of the '.strtolower($this->type)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'name' => 'What should the '.strtolower($this->type).' be named?',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,11 @@ class QuestionHelper extends SymfonyQuestionHelper
|
||||
$choices = $question->getChoices();
|
||||
$text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($choices[$default] ?? $default));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($default));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
|
||||
class CacheEventMutex implements EventMutex, CacheAware
|
||||
{
|
||||
@@ -39,6 +40,12 @@ class CacheEventMutex implements EventMutex, CacheAware
|
||||
*/
|
||||
public function create(Event $event)
|
||||
{
|
||||
if ($this->cache->store($this->store)->getStore() instanceof LockProvider) {
|
||||
return $this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->acquire();
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->add(
|
||||
$event->mutexName(), true, $event->expiresAt * 60
|
||||
);
|
||||
@@ -52,6 +59,12 @@ class CacheEventMutex implements EventMutex, CacheAware
|
||||
*/
|
||||
public function exists(Event $event)
|
||||
{
|
||||
if ($this->cache->store($this->store)->getStore() instanceof LockProvider) {
|
||||
return ! $this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->get(fn () => true);
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->has($event->mutexName());
|
||||
}
|
||||
|
||||
@@ -63,6 +76,14 @@ class CacheEventMutex implements EventMutex, CacheAware
|
||||
*/
|
||||
public function forget(Event $event)
|
||||
{
|
||||
if ($this->cache->store($this->store)->getStore() instanceof LockProvider) {
|
||||
$this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->forceRelease();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache->store($this->store)->forget($event->mutexName());
|
||||
}
|
||||
|
||||
|
@@ -129,6 +129,8 @@ class CallbackEvent extends Event
|
||||
/**
|
||||
* Do not allow the event to overlap each other.
|
||||
*
|
||||
* The expiration time of the underlying cache lock may be specified in minutes.
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*
|
||||
|
@@ -80,7 +80,7 @@ class Event
|
||||
public $onOneServer = false;
|
||||
|
||||
/**
|
||||
* The amount of time the mutex should be valid.
|
||||
* The number of minutes the mutex should be valid.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
@@ -659,6 +659,8 @@ class Event
|
||||
/**
|
||||
* Do not allow the event to overlap each other.
|
||||
*
|
||||
* The expiration time of the underlying cache lock may be specified in minutes.
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*/
|
||||
|
@@ -4,18 +4,20 @@ namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
#[AsCommand(name: 'schedule:work')]
|
||||
class ScheduleWorkCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'schedule:work';
|
||||
protected $signature = 'schedule:work {--run-output-file= : The file to direct <info>schedule:run</info> output to}';
|
||||
|
||||
/**
|
||||
* The name of the console command.
|
||||
@@ -42,20 +44,29 @@ class ScheduleWorkCommand extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->components->info('Running schedule tasks every minute.');
|
||||
$this->components->info(
|
||||
'Running scheduled tasks every minute.',
|
||||
$this->getLaravel()->isLocal() ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE
|
||||
);
|
||||
|
||||
[$lastExecutionStartedAt, $executions] = [null, []];
|
||||
|
||||
$command = implode(' ', array_map(fn ($arg) => ProcessUtils::escapeArgument($arg), [
|
||||
PHP_BINARY,
|
||||
defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan',
|
||||
'schedule:run',
|
||||
]));
|
||||
|
||||
if ($this->option('run-output-file')) {
|
||||
$command .= ' >> '.ProcessUtils::escapeArgument($this->option('run-output-file')).' 2>&1';
|
||||
}
|
||||
|
||||
while (true) {
|
||||
usleep(100 * 1000);
|
||||
|
||||
if (Carbon::now()->second === 0 &&
|
||||
! Carbon::now()->startOfMinute()->equalTo($lastExecutionStartedAt)) {
|
||||
$executions[] = $execution = new Process([
|
||||
PHP_BINARY,
|
||||
defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan',
|
||||
'schedule:run',
|
||||
]);
|
||||
$executions[] = $execution = Process::fromShellCommandline($command);
|
||||
|
||||
$execution->start();
|
||||
|
||||
@@ -64,7 +75,7 @@ class ScheduleWorkCommand extends Command
|
||||
|
||||
foreach ($executions as $key => $execution) {
|
||||
$output = $execution->getIncrementalOutput().
|
||||
$execution->getIncrementalErrorOutput();
|
||||
$execution->getIncrementalErrorOutput();
|
||||
|
||||
$this->output->write(ltrim($output, "\n"));
|
||||
|
||||
|
18
vendor/laravel/framework/src/Illuminate/Console/View/Components/Ask.php
vendored
Normal file
18
vendor/laravel/framework/src/Illuminate/Console/View/Components/Ask.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
class Ask extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $default = null)
|
||||
{
|
||||
return $this->usingQuestionHelper(fn () => $this->output->ask($question, $default));
|
||||
}
|
||||
}
|
29
vendor/laravel/framework/src/Illuminate/Console/View/Components/AskWithCompletion.php
vendored
Normal file
29
vendor/laravel/framework/src/Illuminate/Console/View/Components/AskWithCompletion.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class AskWithCompletion extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $choices, $default = null)
|
||||
{
|
||||
$question = new Question($question, $default);
|
||||
|
||||
is_callable($choices)
|
||||
? $question->setAutocompleterCallback($choices)
|
||||
: $question->setAutocompleterValues($choices);
|
||||
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->askQuestion($question)
|
||||
);
|
||||
}
|
||||
}
|
@@ -12,13 +12,17 @@ class Choice extends Component
|
||||
* @param string $question
|
||||
* @param array<array-key, string> $choices
|
||||
* @param mixed $default
|
||||
* @param int $attempts
|
||||
* @param bool $multiple
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $choices, $default = null)
|
||||
public function render($question, $choices, $default = null, $attempts = null, $multiple = false)
|
||||
{
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->askQuestion(
|
||||
new ChoiceQuestion($question, $choices, $default)
|
||||
(new ChoiceQuestion($question, $choices, $default))
|
||||
->setMaxAttempts($attempts)
|
||||
->setMultiselect($multiple)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@@ -6,8 +6,10 @@ use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @method void alert(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method mixed ask(string $question, string $default = null)
|
||||
* @method mixed askWithCompletion(string $question, array|callable $choices, string $default = null)
|
||||
* @method void bulletList(array $elements, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method mixed choice(string $question, array $choices, $default = null)
|
||||
* @method mixed choice(string $question, array $choices, $default = null, int $attempts = null, bool $multiple = false)
|
||||
* @method bool confirm(string $question, bool $default = false)
|
||||
* @method void error(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void info(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
|
@@ -15,6 +15,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-mbstring": "*",
|
||||
"illuminate/collections": "^9.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
"illuminate/macroable": "^9.0",
|
||||
@@ -35,6 +36,7 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl": "Required to use signal trapping.",
|
||||
"dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).",
|
||||
"guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.5).",
|
||||
"illuminate/bus": "Required to use the scheduled job dispatcher (^9.0).",
|
||||
|
@@ -631,9 +631,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
*/
|
||||
public function wrap(Closure $callback, array $parameters = [])
|
||||
{
|
||||
return function () use ($callback, $parameters) {
|
||||
return $this->call($callback, $parameters);
|
||||
};
|
||||
return fn () => $this->call($callback, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -677,9 +675,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
*/
|
||||
public function factory($abstract)
|
||||
{
|
||||
return function () use ($abstract) {
|
||||
return $this->make($abstract);
|
||||
};
|
||||
return fn () => $this->make($abstract);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1083,9 +1079,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
return $this->make($className);
|
||||
}
|
||||
|
||||
return array_map(function ($abstract) {
|
||||
return $this->resolve($abstract);
|
||||
}, $concrete);
|
||||
return array_map(fn ($abstract) => $this->resolve($abstract), $concrete);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1446,9 +1440,7 @@ class Container implements ArrayAccess, ContainerContract
|
||||
*/
|
||||
public function offsetSet($key, $value): void
|
||||
{
|
||||
$this->bind($key, $value instanceof Closure ? $value : function () use ($value) {
|
||||
return $value;
|
||||
});
|
||||
$this->bind($key, $value instanceof Closure ? $value : fn () => $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
8
vendor/laravel/framework/src/Illuminate/Contracts/Console/PromptsForMissingInput.php
vendored
Normal file
8
vendor/laravel/framework/src/Illuminate/Contracts/Console/PromptsForMissingInput.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Contracts\Console;
|
||||
|
||||
interface PromptsForMissingInput
|
||||
{
|
||||
//
|
||||
}
|
@@ -7,7 +7,7 @@ interface QueueingFactory extends Factory
|
||||
/**
|
||||
* Queue a cookie to send with the next response.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param mixed ...$parameters
|
||||
* @return void
|
||||
*/
|
||||
public function queue(...$parameters);
|
||||
|
@@ -8,8 +8,7 @@ interface Castable
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return string
|
||||
* @return string|\Illuminate\Contracts\Database\Eloquent\CastsAttributes|\Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes
|
||||
* @return class-string<CastsAttributes|CastsInboundAttributes>|CastsAttributes|CastsInboundAttributes
|
||||
*/
|
||||
public static function castUsing(array $arguments);
|
||||
}
|
||||
|
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Illuminate\Contracts\Database\Eloquent;
|
||||
|
||||
/**
|
||||
* @template TGet
|
||||
* @template TSet
|
||||
*/
|
||||
interface CastsAttributes
|
||||
{
|
||||
/**
|
||||
@@ -11,7 +15,7 @@ interface CastsAttributes
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
* @return TGet|null
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes);
|
||||
|
||||
@@ -20,7 +24,7 @@ interface CastsAttributes
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param TSet|null $value
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
|
@@ -64,7 +64,7 @@ interface Application extends Container
|
||||
/**
|
||||
* Get or check the current application environment.
|
||||
*
|
||||
* @param string|array $environments
|
||||
* @param string|array ...$environments
|
||||
* @return string|bool
|
||||
*/
|
||||
public function environment(...$environments);
|
||||
|
@@ -22,7 +22,7 @@ class EncryptCookies
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
|
||||
|
@@ -15,6 +15,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-hash": "*",
|
||||
"illuminate/collections": "^9.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
"illuminate/macroable": "^9.0",
|
||||
|
@@ -290,7 +290,11 @@ trait ManagesTransactions
|
||||
protected function performRollBack($toLevel)
|
||||
{
|
||||
if ($toLevel == 0) {
|
||||
$this->getPdo()->rollBack();
|
||||
$pdo = $this->getPdo();
|
||||
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
} elseif ($this->queryGrammar->supportsSavepoints()) {
|
||||
$this->getPdo()->exec(
|
||||
$this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1))
|
||||
|
@@ -94,7 +94,7 @@ class DumpCommand extends Command
|
||||
*/
|
||||
protected function path(Connection $connection)
|
||||
{
|
||||
return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.dump'), function ($path) {
|
||||
return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.sql'), function ($path) {
|
||||
(new Filesystem)->ensureDirectoryExists(dirname($path));
|
||||
});
|
||||
}
|
||||
|
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace Illuminate\Database\Console\Migrations;
|
||||
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
||||
use Illuminate\Database\Migrations\MigrationCreator;
|
||||
use Illuminate\Support\Composer;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MigrateMakeCommand extends BaseCommand
|
||||
class MigrateMakeCommand extends BaseCommand implements PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* The console command signature.
|
||||
@@ -128,4 +129,16 @@ class MigrateMakeCommand extends BaseCommand
|
||||
|
||||
return parent::getMigrationPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'name' => 'What should the migration be named?',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -65,9 +65,13 @@ class StatusCommand extends BaseCommand
|
||||
|
||||
$this->components->twoColumnDetail('<fg=gray>Migration name</>', '<fg=gray>Batch / Status</>');
|
||||
|
||||
$migrations->each(
|
||||
fn ($migration) => $this->components->twoColumnDetail($migration[0], $migration[1])
|
||||
);
|
||||
$migrations
|
||||
->when($this->option('pending'), fn ($collection) => $collection->filter(function ($migration) {
|
||||
return str($migration[1])->contains('Pending');
|
||||
}))
|
||||
->each(
|
||||
fn ($migration) => $this->components->twoColumnDetail($migration[0], $migration[1])
|
||||
);
|
||||
|
||||
$this->newLine();
|
||||
} else {
|
||||
@@ -120,9 +124,8 @@ class StatusCommand extends BaseCommand
|
||||
{
|
||||
return [
|
||||
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
|
||||
|
||||
['pending', null, InputOption::VALUE_NONE, 'Only list pending migrations'],
|
||||
['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to use'],
|
||||
|
||||
['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
|
||||
];
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ namespace Illuminate\Database;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Illuminate\Database\Connectors\ConnectionFactory;
|
||||
use Illuminate\Database\Events\ConnectionEstablished;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\ConfigurationUrlParser;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -99,6 +100,12 @@ class DatabaseManager implements ConnectionResolverInterface
|
||||
$this->connections[$name] = $this->configure(
|
||||
$this->makeConnection($database), $type
|
||||
);
|
||||
|
||||
if ($this->app->bound('events')) {
|
||||
$this->app['events']->dispatch(
|
||||
new ConnectionEstablished($this->connections[$name])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->connections[$name];
|
||||
|
@@ -849,7 +849,7 @@ class Builder implements BuilderContract
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array with the values of a given column.
|
||||
* Get a collection with the values of a given column.
|
||||
*
|
||||
* @param string|\Illuminate\Database\Query\Expression $column
|
||||
* @param string|null $key
|
||||
|
@@ -6,6 +6,11 @@ use ArrayObject as BaseArrayObject;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* @template TKey of array-key
|
||||
* @template TItem
|
||||
* @extends \ArrayObject<TKey, TItem>
|
||||
*/
|
||||
class ArrayObject extends BaseArrayObject implements Arrayable, JsonSerializable
|
||||
{
|
||||
/**
|
||||
|
@@ -11,7 +11,7 @@ class AsArrayObject implements Castable
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return object|string
|
||||
* @return CastsAttributes<ArrayObject<array-key, mixed>, iterable>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ class AsCollection implements Castable
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return object|string
|
||||
* @return CastsAttributes<\Illuminate\Support\Collection<array-key, mixed>, iterable>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ class AsEncryptedArrayObject implements Castable
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return object|string
|
||||
* @return CastsAttributes<ArrayObject<array-key, mixed>, iterable>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
|
@@ -13,7 +13,7 @@ class AsEncryptedCollection implements Castable
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return object|string
|
||||
* @return CastsAttributes<\Illuminate\Support\Collection<array-key, mixed>, iterable>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
|
84
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Casts/AsEnumArrayObject.php
vendored
Normal file
84
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Casts/AsEnumArrayObject.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Eloquent\Casts;
|
||||
|
||||
use BackedEnum;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class AsEnumArrayObject implements Castable
|
||||
{
|
||||
/**
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @template TEnum
|
||||
*
|
||||
* @param array{class-string<TEnum>} $arguments
|
||||
* @return CastsAttributes<ArrayObject<array-key, TEnum>, iterable<TEnum>>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
return new class($arguments) implements CastsAttributes
|
||||
{
|
||||
protected $arguments;
|
||||
|
||||
public function __construct(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function get($model, $key, $value, $attributes)
|
||||
{
|
||||
if (! isset($attributes[$key]) || is_null($attributes[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($attributes[$key], true);
|
||||
|
||||
if (! is_array($data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enumClass = $this->arguments[0];
|
||||
|
||||
return new ArrayObject((new Collection($data))->map(function ($value) use ($enumClass) {
|
||||
return is_subclass_of($enumClass, BackedEnum::class)
|
||||
? $enumClass::from($value)
|
||||
: constant($enumClass.'::'.$value);
|
||||
})->toArray());
|
||||
}
|
||||
|
||||
public function set($model, $key, $value, $attributes)
|
||||
{
|
||||
if ($value === null) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
$storable = [];
|
||||
|
||||
foreach ($value as $enum) {
|
||||
$storable[] = $this->getStorableEnumValue($enum);
|
||||
}
|
||||
|
||||
return [$key => json_encode($storable)];
|
||||
}
|
||||
|
||||
public function serialize($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return (new Collection($value->getArrayCopy()))->map(function ($enum) {
|
||||
return $this->getStorableEnumValue($enum);
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
protected function getStorableEnumValue($enum)
|
||||
{
|
||||
if (is_string($enum) || is_int($enum)) {
|
||||
return $enum;
|
||||
}
|
||||
|
||||
return $enum instanceof BackedEnum ? $enum->value : $enum->name;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
80
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Casts/AsEnumCollection.php
vendored
Normal file
80
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Casts/AsEnumCollection.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Eloquent\Casts;
|
||||
|
||||
use BackedEnum;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class AsEnumCollection implements Castable
|
||||
{
|
||||
/**
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @template TEnum of \UnitEnum|\BackedEnum
|
||||
*
|
||||
* @param array{class-string<TEnum>} $arguments
|
||||
* @return CastsAttributes<Collection<array-key, TEnum>, iterable<TEnum>>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
return new class($arguments) implements CastsAttributes
|
||||
{
|
||||
protected $arguments;
|
||||
|
||||
public function __construct(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function get($model, $key, $value, $attributes)
|
||||
{
|
||||
if (! isset($attributes[$key]) || is_null($attributes[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($attributes[$key], true);
|
||||
|
||||
if (! is_array($data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enumClass = $this->arguments[0];
|
||||
|
||||
return (new Collection($data))->map(function ($value) use ($enumClass) {
|
||||
return is_subclass_of($enumClass, BackedEnum::class)
|
||||
? $enumClass::from($value)
|
||||
: constant($enumClass.'::'.$value);
|
||||
});
|
||||
}
|
||||
|
||||
public function set($model, $key, $value, $attributes)
|
||||
{
|
||||
$value = $value !== null
|
||||
? (new Collection($value))->map(function ($enum) {
|
||||
return $this->getStorableEnumValue($enum);
|
||||
})->toJson()
|
||||
: null;
|
||||
|
||||
return [$key => $value];
|
||||
}
|
||||
|
||||
public function serialize($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return (new Collection($value))->map(function ($enum) {
|
||||
return $this->getStorableEnumValue($enum);
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
protected function getStorableEnumValue($enum)
|
||||
{
|
||||
if (is_string($enum) || is_int($enum)) {
|
||||
return $enum;
|
||||
}
|
||||
|
||||
return $enum instanceof BackedEnum ? $enum->value : $enum->name;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@ class AsStringable implements Castable
|
||||
* Get the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return object|string
|
||||
* @return CastsAttributes<\Illuminate\Support\Stringable, string|\Stringable>
|
||||
*/
|
||||
public static function castUsing(array $arguments)
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param TFindDefault $default
|
||||
* @return static<TKey|TModel>|TModel|TFindDefault
|
||||
* @return static<TKey, TModel>|TModel|TFindDefault
|
||||
*/
|
||||
public function find($key, $default = null)
|
||||
{
|
||||
@@ -44,9 +44,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
return $this->whereIn($this->first()->getKeyName(), $key);
|
||||
}
|
||||
|
||||
return Arr::first($this->items, function ($model) use ($key) {
|
||||
return $model->getKey() == $key;
|
||||
}, $default);
|
||||
return Arr::first($this->items, fn ($model) => $model->getKey() == $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,9 +231,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
$relation = reset($relation);
|
||||
}
|
||||
|
||||
$models->filter(function ($model) use ($name) {
|
||||
return ! is_null($model) && ! $model->relationLoaded($name);
|
||||
})->load($relation);
|
||||
$models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation);
|
||||
|
||||
if (empty($path)) {
|
||||
return;
|
||||
@@ -261,12 +257,8 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
{
|
||||
$this->pluck($relation)
|
||||
->filter()
|
||||
->groupBy(function ($model) {
|
||||
return get_class($model);
|
||||
})
|
||||
->each(function ($models, $className) use ($relations) {
|
||||
static::make($models)->load($relations[$className] ?? []);
|
||||
});
|
||||
->groupBy(fn ($model) => get_class($model))
|
||||
->each(fn ($models, $className) => static::make($models)->load($relations[$className] ?? []));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -282,12 +274,8 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
{
|
||||
$this->pluck($relation)
|
||||
->filter()
|
||||
->groupBy(function ($model) {
|
||||
return get_class($model);
|
||||
})
|
||||
->each(function ($models, $className) use ($relations) {
|
||||
static::make($models)->loadCount($relations[$className] ?? []);
|
||||
});
|
||||
->groupBy(fn ($model) => get_class($model))
|
||||
->each(fn ($models, $className) => static::make($models)->loadCount($relations[$className] ?? []));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -307,14 +295,10 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
}
|
||||
|
||||
if ($key instanceof Model) {
|
||||
return parent::contains(function ($model) use ($key) {
|
||||
return $model->is($key);
|
||||
});
|
||||
return parent::contains(fn ($model) => $model->is($key));
|
||||
}
|
||||
|
||||
return parent::contains(function ($model) use ($key) {
|
||||
return $model->getKey() == $key;
|
||||
});
|
||||
return parent::contains(fn ($model) => $model->getKey() == $key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,9 +308,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
*/
|
||||
public function modelKeys()
|
||||
{
|
||||
return array_map(function ($model) {
|
||||
return $model->getKey();
|
||||
}, $this->items);
|
||||
return array_map(fn ($model) => $model->getKey(), $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,9 +340,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
{
|
||||
$result = parent::map($callback);
|
||||
|
||||
return $result->contains(function ($item) {
|
||||
return ! $item instanceof Model;
|
||||
}) ? $result->toBase() : $result;
|
||||
return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,9 +358,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
{
|
||||
$result = parent::mapWithKeys($callback);
|
||||
|
||||
return $result->contains(function ($item) {
|
||||
return ! $item instanceof Model;
|
||||
}) ? $result->toBase() : $result;
|
||||
return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,12 +381,8 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
->get()
|
||||
->getDictionary();
|
||||
|
||||
return $this->filter(function ($model) use ($freshModels) {
|
||||
return $model->exists && isset($freshModels[$model->getKey()]);
|
||||
})
|
||||
->map(function ($model) use ($freshModels) {
|
||||
return $freshModels[$model->getKey()];
|
||||
});
|
||||
return $this->filter(fn ($model) => $model->exists && isset($freshModels[$model->getKey()]))
|
||||
->map(fn ($model) => $freshModels[$model->getKey()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,7 +558,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
/**
|
||||
* Count the number of items in the collection by a field or using a callback.
|
||||
*
|
||||
* @param (callable(TValue, TKey): array-key)|string|null $countBy
|
||||
* @param (callable(TModel, TKey): array-key)|string|null $countBy
|
||||
* @return \Illuminate\Support\Collection<array-key, int>
|
||||
*/
|
||||
public function countBy($countBy = null)
|
||||
@@ -676,13 +650,11 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
* Get the comparison function to detect duplicates.
|
||||
*
|
||||
* @param bool $strict
|
||||
* @return callable(TValue, TValue): bool
|
||||
* @return callable(TModel, TModel): bool
|
||||
*/
|
||||
protected function duplicateComparator($strict)
|
||||
{
|
||||
return function ($a, $b) {
|
||||
return $a->is($b);
|
||||
};
|
||||
return fn ($a, $b) => $a->is($b);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -801,9 +773,7 @@ class Collection extends BaseCollection implements QueueableCollection
|
||||
|
||||
$class = get_class($model);
|
||||
|
||||
if ($this->filter(function ($model) use ($class) {
|
||||
return ! $model instanceof $class;
|
||||
})->isNotEmpty()) {
|
||||
if ($this->filter(fn ($model) => ! $model instanceof $class)->isNotEmpty()) {
|
||||
throw new LogicException('Unable to create query for collection with mixed types.');
|
||||
}
|
||||
|
||||
|
@@ -98,7 +98,7 @@ trait HasEvents
|
||||
[
|
||||
'retrieved', 'creating', 'created', 'updating', 'updated',
|
||||
'saving', 'saved', 'restoring', 'restored', 'replicating',
|
||||
'deleting', 'deleted', 'forceDeleted',
|
||||
'deleting', 'deleted', 'forceDeleting', 'forceDeleted',
|
||||
],
|
||||
$this->observables
|
||||
);
|
||||
|
@@ -7,6 +7,7 @@ use Illuminate\Database\ClassMorphViolationException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\PendingHasThroughRelationship;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@@ -359,6 +360,21 @@ trait HasRelationships
|
||||
return $caller['function'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pending has-many-through or has-one-through relationship.
|
||||
*
|
||||
* @param string|\Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne $relationship
|
||||
* @return \Illuminate\Database\Eloquent\PendingHasThroughRelationship
|
||||
*/
|
||||
public function through($relationship)
|
||||
{
|
||||
if (is_string($relationship)) {
|
||||
$relationship = $this->{$relationship}();
|
||||
}
|
||||
|
||||
return new PendingHasThroughRelationship($this, $relationship);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a one-to-many relationship.
|
||||
*
|
||||
|
@@ -9,7 +9,7 @@ class CrossJoinSequence extends Sequence
|
||||
/**
|
||||
* Create a new cross join sequence instance.
|
||||
*
|
||||
* @param array $sequences
|
||||
* @param array ...$sequences
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(...$sequences)
|
||||
|
@@ -525,7 +525,7 @@ abstract class Factory
|
||||
/**
|
||||
* Add a new sequenced state transformation to the model definition.
|
||||
*
|
||||
* @param array $sequence
|
||||
* @param mixed ...$sequence
|
||||
* @return static
|
||||
*/
|
||||
public function sequence(...$sequence)
|
||||
@@ -536,7 +536,7 @@ abstract class Factory
|
||||
/**
|
||||
* Add a new sequenced state transformation to the model definition and update the pending creation count to the size of the sequence.
|
||||
*
|
||||
* @param array $sequence
|
||||
* @param array ...$sequence
|
||||
* @return static
|
||||
*/
|
||||
public function forEachSequence(...$sequence)
|
||||
@@ -547,7 +547,7 @@ abstract class Factory
|
||||
/**
|
||||
* Add a new cross joined sequenced state transformation to the model definition.
|
||||
*
|
||||
* @param array $sequence
|
||||
* @param array ...$sequence
|
||||
* @return static
|
||||
*/
|
||||
public function crossJoinSequence(...$sequence)
|
||||
|
@@ -30,7 +30,7 @@ class Sequence implements Countable
|
||||
/**
|
||||
* Create a new sequence instance.
|
||||
*
|
||||
* @param array $sequence
|
||||
* @param mixed ...$sequence
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(...$sequence)
|
||||
|
@@ -1083,6 +1083,16 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the model and all of its relationships without raising any events to the parent model.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function pushQuietly()
|
||||
{
|
||||
return static::withoutEvents(fn () => $this->push());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the model to the database without raising any events.
|
||||
*
|
||||
@@ -2312,6 +2322,11 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt
|
||||
return $resolver($this);
|
||||
}
|
||||
|
||||
if (Str::startsWith($method, 'through') &&
|
||||
method_exists($this, $relationMethod = Str::of($method)->after('through')->lcfirst()->toString())) {
|
||||
return $this->through($relationMethod);
|
||||
}
|
||||
|
||||
return $this->forwardCallTo($this->newQuery(), $method, $parameters);
|
||||
}
|
||||
|
||||
|
90
vendor/laravel/framework/src/Illuminate/Database/Eloquent/PendingHasThroughRelationship.php
vendored
Normal file
90
vendor/laravel/framework/src/Illuminate/Database/Eloquent/PendingHasThroughRelationship.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Eloquent;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PendingHasThroughRelationship
|
||||
{
|
||||
/**
|
||||
* The root model that the relationship exists on.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $rootModel;
|
||||
|
||||
/**
|
||||
* The local relationship.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
protected $localRelationship;
|
||||
|
||||
/**
|
||||
* Create a pending has-many-through or has-one-through relationship.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $rootModel
|
||||
* @param \Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne $localRelationship
|
||||
*/
|
||||
public function __construct($rootModel, $localRelationship)
|
||||
{
|
||||
$this->rootModel = $rootModel;
|
||||
|
||||
$this->localRelationship = $localRelationship;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the distant relationship that this model has.
|
||||
*
|
||||
* @param string|(callable(\Illuminate\Database\Eloquent\Model): (\Illuminate\Database\Eloquent\Relations\HasOne|\Illuminate\Database\Eloquent\Relations\HasMany)) $callback
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough|\Illuminate\Database\Eloquent\Relations\HasOneThrough
|
||||
*/
|
||||
public function has($callback)
|
||||
{
|
||||
if (is_string($callback)) {
|
||||
$callback = fn () => $this->localRelationship->getRelated()->{$callback}();
|
||||
}
|
||||
|
||||
$distantRelation = $callback($this->localRelationship->getRelated());
|
||||
|
||||
if ($distantRelation instanceof HasMany) {
|
||||
return $this->rootModel->hasManyThrough(
|
||||
$distantRelation->getRelated()::class,
|
||||
$this->localRelationship->getRelated()::class,
|
||||
$this->localRelationship->getForeignKeyName(),
|
||||
$distantRelation->getForeignKeyName(),
|
||||
$this->localRelationship->getLocalKeyName(),
|
||||
$distantRelation->getLocalKeyName(),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->rootModel->hasOneThrough(
|
||||
$distantRelation->getRelated()::class,
|
||||
$this->localRelationship->getRelated()::class,
|
||||
$this->localRelationship->getForeignKeyName(),
|
||||
$distantRelation->getForeignKeyName(),
|
||||
$this->localRelationship->getLocalKeyName(),
|
||||
$distantRelation->getLocalKeyName(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic method calls into the model.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (Str::startsWith($method, 'has')) {
|
||||
return $this->has(Str::of($method)->after('has')->lcfirst()->toString());
|
||||
}
|
||||
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Call to undefined method %s::%s()', static::class, $method
|
||||
));
|
||||
}
|
||||
}
|
@@ -688,8 +688,8 @@ class BelongsToMany extends Relation
|
||||
return $this->getRelated()->newCollection();
|
||||
}
|
||||
|
||||
return $this->whereIn(
|
||||
$this->getRelated()->getQualifiedKeyName(), $this->parseIds($ids)
|
||||
return $this->whereKey(
|
||||
$this->parseIds($ids)
|
||||
)->get($columns);
|
||||
}
|
||||
|
||||
@@ -1153,8 +1153,6 @@ class BelongsToMany extends Relation
|
||||
*/
|
||||
public function touch()
|
||||
{
|
||||
$key = $this->getRelated()->getKeyName();
|
||||
|
||||
$columns = [
|
||||
$this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(),
|
||||
];
|
||||
@@ -1163,7 +1161,7 @@ class BelongsToMany extends Relation
|
||||
// the related model's timestamps, to make sure these all reflect the changes
|
||||
// to the parent models. This will help us keep any caching synced up here.
|
||||
if (count($ids = $this->allRelatedIds()) > 0) {
|
||||
$this->getRelated()->newQueryWithoutRelationships()->whereIn($key, $ids)->update($columns);
|
||||
$this->getRelated()->newQueryWithoutRelationships()->whereKey($ids)->update($columns);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -323,6 +323,17 @@ abstract class HasOneOrMany extends Relation
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the related model without raising any events to the parent model.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function createQuietly(array $attributes = [])
|
||||
{
|
||||
return Model::withoutEvents(fn () => $this->create($attributes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the related model. Allow mass-assignment.
|
||||
*
|
||||
@@ -353,6 +364,17 @@ abstract class HasOneOrMany extends Relation
|
||||
return $instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Collection of new instances of the related model without raising any events to the parent model.
|
||||
*
|
||||
* @param iterable $records
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function createManyQuietly(iterable $records)
|
||||
{
|
||||
return Model::withoutEvents(fn () => $this->createMany($records));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the foreign ID for creating a related model.
|
||||
*
|
||||
|
@@ -45,6 +45,10 @@ trait SoftDeletes
|
||||
*/
|
||||
public function forceDelete()
|
||||
{
|
||||
if ($this->fireModelEvent('forceDeleting') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->forceDeleting = true;
|
||||
|
||||
return tap($this->delete(), function ($deleted) {
|
||||
@@ -56,6 +60,16 @@ trait SoftDeletes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a hard delete on a soft deleted model without raising any events.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function forceDeleteQuietly()
|
||||
{
|
||||
return static::withoutEvents(fn () => $this->forceDelete());
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the actual delete query on this model instance.
|
||||
*
|
||||
@@ -181,6 +195,17 @@ trait SoftDeletes
|
||||
static::registerModelEvent('restored', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a "forceDeleting" model event callback with the dispatcher.
|
||||
*
|
||||
* @param \Closure|string $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function forceDeleting($callback)
|
||||
{
|
||||
static::registerModelEvent('forceDeleting', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a "forceDeleted" model event callback with the dispatcher.
|
||||
*
|
||||
|
@@ -9,7 +9,7 @@ class SoftDeletingScope implements Scope
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $extensions = ['Restore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
|
||||
protected $extensions = ['Restore', 'RestoreOrCreate', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
|
||||
|
||||
/**
|
||||
* Apply the scope to a given Eloquent query builder.
|
||||
@@ -74,6 +74,23 @@ class SoftDeletingScope implements Scope
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the restore-or-create extension to the builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||
* @return void
|
||||
*/
|
||||
protected function addRestoreOrCreate(Builder $builder)
|
||||
{
|
||||
$builder->macro('restoreOrCreate', function (Builder $builder, array $attributes = [], array $values = []) {
|
||||
$builder->withTrashed();
|
||||
|
||||
return tap($builder->firstOrCreate($attributes, $values), function ($instance) {
|
||||
$instance->restore();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the with-trashed extension to the builder.
|
||||
*
|
||||
|
8
vendor/laravel/framework/src/Illuminate/Database/Events/ConnectionEstablished.php
vendored
Normal file
8
vendor/laravel/framework/src/Illuminate/Database/Events/ConnectionEstablished.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Events;
|
||||
|
||||
class ConnectionEstablished extends ConnectionEvent
|
||||
{
|
||||
//
|
||||
}
|
@@ -66,6 +66,13 @@ class Migrator
|
||||
*/
|
||||
protected $paths = [];
|
||||
|
||||
/**
|
||||
* The paths that have already been required.
|
||||
*
|
||||
* @var array<string, \Illuminate\Database\Migrations\Migration|null>
|
||||
*/
|
||||
protected static $requiredPathCache = [];
|
||||
|
||||
/**
|
||||
* The output interface implementation.
|
||||
*
|
||||
@@ -511,9 +518,13 @@ class Migrator
|
||||
return new $class;
|
||||
}
|
||||
|
||||
$migration = $this->files->getRequire($path);
|
||||
$migration = static::$requiredPathCache[$path] ??= $this->files->getRequire($path);
|
||||
|
||||
return is_object($migration) ? $migration : new $class;
|
||||
if (is_object($migration)) {
|
||||
return clone $migration;
|
||||
}
|
||||
|
||||
return new $class;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,7 +740,7 @@ class Migrator
|
||||
* Write to the console's output.
|
||||
*
|
||||
* @param string $component
|
||||
* @param array<int, string>|string $arguments
|
||||
* @param array<int, string>|string ...$arguments
|
||||
* @return void
|
||||
*/
|
||||
protected function write($component, ...$arguments)
|
||||
|
@@ -100,6 +100,13 @@ class Builder implements BuilderContract
|
||||
*/
|
||||
public $from;
|
||||
|
||||
/**
|
||||
* The index hint for the query.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\IndexHint
|
||||
*/
|
||||
public $indexHint;
|
||||
|
||||
/**
|
||||
* The table joins for the query.
|
||||
*
|
||||
@@ -411,6 +418,10 @@ class Builder implements BuilderContract
|
||||
|
||||
$this->selectSub($column, $as);
|
||||
} else {
|
||||
if (is_array($this->columns) && in_array($column, $this->columns, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->columns[] = $column;
|
||||
}
|
||||
}
|
||||
@@ -454,6 +465,45 @@ class Builder implements BuilderContract
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index hint to suggest a query index.
|
||||
*
|
||||
* @param string $index
|
||||
* @return $this
|
||||
*/
|
||||
public function useIndex($index)
|
||||
{
|
||||
$this->indexHint = new IndexHint('hint', $index);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index hint to force a query index.
|
||||
*
|
||||
* @param string $index
|
||||
* @return $this
|
||||
*/
|
||||
public function forceIndex($index)
|
||||
{
|
||||
$this->indexHint = new IndexHint('force', $index);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index hint to ignore a query index.
|
||||
*
|
||||
* @param string $index
|
||||
* @return $this
|
||||
*/
|
||||
public function ignoreIndex($index)
|
||||
{
|
||||
$this->indexHint = new IndexHint('ignore', $index);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a join clause to the query.
|
||||
*
|
||||
@@ -2498,7 +2548,7 @@ class Builder implements BuilderContract
|
||||
/**
|
||||
* Lock the selected rows in the table for updating.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
* @return $this
|
||||
*/
|
||||
public function lockForUpdate()
|
||||
{
|
||||
@@ -2508,7 +2558,7 @@ class Builder implements BuilderContract
|
||||
/**
|
||||
* Share lock the selected rows in the table.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
* @return $this
|
||||
*/
|
||||
public function sharedLock()
|
||||
{
|
||||
|
@@ -36,6 +36,7 @@ class Grammar extends BaseGrammar
|
||||
'aggregate',
|
||||
'columns',
|
||||
'from',
|
||||
'indexHint',
|
||||
'joins',
|
||||
'wheres',
|
||||
'groups',
|
||||
|
@@ -74,6 +74,22 @@ class MySqlGrammar extends Grammar
|
||||
return "match ({$columns}) against (".$value."{$mode}{$expanded})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the index hints for the query.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query
|
||||
* @param \Illuminate\Database\Query\IndexHint $indexHint
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIndexHint(Builder $query, $indexHint)
|
||||
{
|
||||
return match ($indexHint->type) {
|
||||
'hint' => "use index ({$indexHint->index})",
|
||||
'force' => "force index ({$indexHint->index})",
|
||||
default => "ignore index ({$indexHint->index})",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an insert ignore statement into SQL.
|
||||
*
|
||||
|
@@ -117,6 +117,20 @@ class SQLiteGrammar extends Grammar
|
||||
return "strftime('{$type}', {$this->wrap($where['column'])}) {$where['operator']} cast({$value} as text)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the index hints for the query.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query
|
||||
* @param \Illuminate\Database\Query\IndexHint $indexHint
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIndexHint(Builder $query, $indexHint)
|
||||
{
|
||||
return $indexHint->type === 'force'
|
||||
? "indexed by {$indexHint->index}"
|
||||
: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a "JSON length" statement into SQL.
|
||||
*
|
||||
|
@@ -96,6 +96,20 @@ class SqlServerGrammar extends Grammar
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the index hints for the query.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query
|
||||
* @param \Illuminate\Database\Query\IndexHint $indexHint
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIndexHint(Builder $query, $indexHint)
|
||||
{
|
||||
return $indexHint->type === 'force'
|
||||
? "with (index({$indexHint->index}))"
|
||||
: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
33
vendor/laravel/framework/src/Illuminate/Database/Query/IndexHint.php
vendored
Executable file
33
vendor/laravel/framework/src/Illuminate/Database/Query/IndexHint.php
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Query;
|
||||
|
||||
class IndexHint
|
||||
{
|
||||
/**
|
||||
* The type of query hint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* The name of the index.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $index;
|
||||
|
||||
/**
|
||||
* Create a new index hint instance.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $index
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($type, $index)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->index = $index;
|
||||
}
|
||||
}
|
@@ -63,4 +63,14 @@ class ForeignKeyDefinition extends Fluent
|
||||
{
|
||||
return $this->onDelete('set null');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that deletes should have "no action".
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noActionOnDelete()
|
||||
{
|
||||
return $this->onDelete('no action');
|
||||
}
|
||||
}
|
||||
|
@@ -15,19 +15,16 @@ class PostgresSchemaState extends SchemaState
|
||||
*/
|
||||
public function dump(Connection $connection, $path)
|
||||
{
|
||||
$excludedTables = collect($connection->getSchemaBuilder()->getAllTables())
|
||||
->map->tablename
|
||||
->reject(function ($table) {
|
||||
return $table === $this->migrationTable;
|
||||
})->map(function ($table) {
|
||||
return '--exclude-table-data="*.'.$table.'"';
|
||||
})->implode(' ');
|
||||
$commands = collect([
|
||||
$this->baseDumpCommand().' --schema-only > '.$path,
|
||||
$this->baseDumpCommand().' -t '.$this->migrationTable.' --data-only >> '.$path,
|
||||
]);
|
||||
|
||||
$this->makeProcess(
|
||||
$this->baseDumpCommand().' --file="${:LARAVEL_LOAD_PATH}" '.$excludedTables
|
||||
)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
$commands->map(function ($command, $path) {
|
||||
$this->makeProcess($command)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +55,7 @@ class PostgresSchemaState extends SchemaState
|
||||
*/
|
||||
protected function baseDumpCommand()
|
||||
{
|
||||
return 'pg_dump --no-owner --no-acl -Fc --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
|
||||
return 'pg_dump --no-owner --no-acl --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -86,7 +86,7 @@ abstract class SchemaState
|
||||
/**
|
||||
* Create a new process instance.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param mixed ...$arguments
|
||||
* @return \Symfony\Component\Process\Process
|
||||
*/
|
||||
public function makeProcess(...$arguments)
|
||||
|
@@ -16,7 +16,8 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"brick/math": "^0.9.3|^0.10.2|^0.11",
|
||||
"illuminate/collections": "^9.0",
|
||||
"illuminate/container": "^9.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
@@ -35,6 +36,7 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-filter": "Required to use the Postgres database driver.",
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).",
|
||||
"fakerphp/faker": "Required to use the eloquent factory builder (^1.21).",
|
||||
"illuminate/console": "Required to use the database commands (^9.0).",
|
||||
|
@@ -112,7 +112,7 @@ class Encrypter implements EncrypterContract, StringEncrypter
|
||||
$tag = base64_encode($tag ?? '');
|
||||
|
||||
$mac = self::$supportedCiphers[strtolower($this->cipher)]['aead']
|
||||
? '' // For AEAD-algoritms, the tag / MAC is returned by openssl_encrypt...
|
||||
? '' // For AEAD-algorithms, the tag / MAC is returned by openssl_encrypt...
|
||||
: $this->hash($iv, $value);
|
||||
|
||||
$json = json_encode(compact('iv', 'value', 'mac', 'tag'), JSON_UNESCAPED_SLASHES);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2",
|
||||
"ext-json": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"illuminate/contracts": "^9.0",
|
||||
|
@@ -95,6 +95,40 @@ class AwsS3V3Adapter extends FilesystemAdapter
|
||||
return (string) $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a temporary upload URL for the file at the given path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param \DateTimeInterface $expiration
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
public function temporaryUploadUrl($path, $expiration, array $options = [])
|
||||
{
|
||||
$command = $this->client->getCommand('PutObject', array_merge([
|
||||
'Bucket' => $this->config['bucket'],
|
||||
'Key' => $this->prefixer->prefixPath($path),
|
||||
], $options));
|
||||
|
||||
$signedRequest = $this->client->createPresignedRequest(
|
||||
$command, $expiration, $options
|
||||
);
|
||||
|
||||
$uri = $signedRequest->getUri();
|
||||
|
||||
// If an explicit base URL has been set on the disk configuration then we will use
|
||||
// it as the base URL instead of the default path. This allows the developer to
|
||||
// have full control over the base path for this filesystem's generated URLs.
|
||||
if (isset($this->config['temporary_url'])) {
|
||||
$uri = $this->replaceBaseUrl($uri, $this->config['temporary_url']);
|
||||
}
|
||||
|
||||
return [
|
||||
'url' => (string) $uri,
|
||||
'headers' => $signedRequest->getHeaders(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying S3 client.
|
||||
*
|
||||
|
@@ -195,9 +195,10 @@ class Filesystem
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $content
|
||||
* @param int|null $mode
|
||||
* @return void
|
||||
*/
|
||||
public function replace($path, $content)
|
||||
public function replace($path, $content, $mode = null)
|
||||
{
|
||||
// If the path already exists and is a symlink, get the real path...
|
||||
clearstatcache(true, $path);
|
||||
@@ -207,7 +208,11 @@ class Filesystem
|
||||
$tempPath = tempnam(dirname($path), basename($path));
|
||||
|
||||
// Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...
|
||||
chmod($tempPath, 0777 - umask());
|
||||
if (! is_null($mode)) {
|
||||
chmod($tempPath, $mode);
|
||||
} else {
|
||||
chmod($tempPath, 0777 - umask());
|
||||
}
|
||||
|
||||
file_put_contents($tempPath, $content);
|
||||
|
||||
|
@@ -733,6 +733,25 @@ class FilesystemAdapter implements CloudFilesystemContract
|
||||
throw new RuntimeException('This driver does not support creating temporary URLs.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a temporary upload URL for the file at the given path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param \DateTimeInterface $expiration
|
||||
* @param array $options
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function temporaryUploadUrl($path, $expiration, array $options = [])
|
||||
{
|
||||
if (method_exists($this->adapter, 'temporaryUploadUrl')) {
|
||||
return $this->adapter->temporaryUploadUrl($path, $expiration, $options);
|
||||
}
|
||||
|
||||
throw new RuntimeException('This driver does not support creating temporary upload URLs.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate a path to a URL.
|
||||
*
|
||||
|
@@ -32,7 +32,9 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "Required to use the Filesystem class.",
|
||||
"ext-ftp": "Required to use the Flysystem FTP driver.",
|
||||
"ext-hash": "Required to use the Filesystem class.",
|
||||
"illuminate/http": "Required for handling uploaded files (^7.0).",
|
||||
"league/flysystem": "Required to use the Flysystem local driver (^3.0.16).",
|
||||
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).",
|
||||
|
@@ -38,7 +38,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '9.48.0';
|
||||
const VERSION = '9.52.0';
|
||||
|
||||
/**
|
||||
* The base path for the Laravel installation.
|
||||
@@ -567,7 +567,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
|
||||
/**
|
||||
* Get or check the current application environment.
|
||||
*
|
||||
* @param string|array $environments
|
||||
* @param string|array ...$environments
|
||||
* @return string|bool
|
||||
*/
|
||||
public function environment(...$environments)
|
||||
@@ -656,9 +656,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
|
||||
public function registerConfiguredProviders()
|
||||
{
|
||||
$providers = Collection::make($this->make('config')->get('app.providers'))
|
||||
->partition(function ($provider) {
|
||||
return str_starts_with($provider, 'Illuminate\\');
|
||||
});
|
||||
->partition(fn ($provider) => str_starts_with($provider, 'Illuminate\\'));
|
||||
|
||||
$providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);
|
||||
|
||||
@@ -738,9 +736,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
|
||||
{
|
||||
$name = is_string($provider) ? $provider : get_class($provider);
|
||||
|
||||
return Arr::where($this->serviceProviders, function ($value) use ($name) {
|
||||
return $value instanceof $name;
|
||||
});
|
||||
return Arr::where($this->serviceProviders, fn ($value) => $value instanceof $name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,6 +11,7 @@ trait Dispatchable
|
||||
/**
|
||||
* Dispatch the job with the given arguments.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
* @return \Illuminate\Foundation\Bus\PendingDispatch
|
||||
*/
|
||||
public static function dispatch(...$arguments)
|
||||
@@ -67,6 +68,7 @@ trait Dispatchable
|
||||
*
|
||||
* Queueable jobs will be dispatched to the "sync" queue.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dispatchSync(...$arguments)
|
||||
@@ -89,6 +91,7 @@ trait Dispatchable
|
||||
/**
|
||||
* Dispatch a command to its appropriate handler after the current process.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public static function dispatchAfterResponse(...$arguments)
|
||||
|
@@ -185,7 +185,7 @@ class Kernel implements KernelContract
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when the command lifecyle duration exceeds a given amount of time.
|
||||
* Register a callback to be invoked when the command lifecycle duration exceeds a given amount of time.
|
||||
*
|
||||
* @param \DateTimeInterface|\Carbon\CarbonInterval|float|int $threshold
|
||||
* @param callable $handler
|
||||
|
@@ -6,7 +6,9 @@ use Illuminate\Console\Concerns\CreatesMatchingTest;
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'make:listener')]
|
||||
class ListenerMakeCommand extends GeneratorCommand
|
||||
@@ -125,4 +127,28 @@ class ListenerMakeCommand extends GeneratorCommand
|
||||
['queued', null, InputOption::VALUE_NONE, 'Indicates the event listener should be queued'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interact further with the user if they were prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event = $this->components->askWithCompletion(
|
||||
'What event should be listened for?',
|
||||
$this->possibleEvents(),
|
||||
'none'
|
||||
);
|
||||
|
||||
if ($event && $event !== 'none') {
|
||||
$input->setOption('event', $event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ class MailMakeCommand extends GeneratorCommand
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'Mail';
|
||||
protected $type = 'Mailable';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
|
@@ -6,7 +6,9 @@ use Illuminate\Console\Concerns\CreatesMatchingTest;
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'make:model')]
|
||||
class ModelMakeCommand extends GeneratorCommand
|
||||
@@ -233,4 +235,36 @@ class ModelMakeCommand extends GeneratorCommand
|
||||
['requests', 'R', InputOption::VALUE_NONE, 'Create new form request classes and use them in the resource controller'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interact further with the user if they were prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
collect($this->components->choice('Would you like any of the following?', [
|
||||
'none',
|
||||
'all',
|
||||
'factory',
|
||||
'form requests',
|
||||
'migration',
|
||||
'policy',
|
||||
'resource controller',
|
||||
'seed',
|
||||
], default: 0, multiple: true))
|
||||
->reject('none')
|
||||
->map(fn ($option) => match ($option) {
|
||||
'resource controller' => 'resource',
|
||||
'form requests' => 'requests',
|
||||
default => $option,
|
||||
})
|
||||
->each(fn ($option) => $input->setOption($option, true));
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,9 @@ namespace Illuminate\Foundation\Console;
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'make:observer')]
|
||||
class ObserverMakeCommand extends GeneratorCommand
|
||||
@@ -150,4 +152,28 @@ class ObserverMakeCommand extends GeneratorCommand
|
||||
['model', 'm', InputOption::VALUE_OPTIONAL, 'The model that the observer applies to'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interact further with the user if they were prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$model = $this->components->askWithCompletion(
|
||||
'What model should this observer apply to?',
|
||||
$this->possibleModels(),
|
||||
'none'
|
||||
);
|
||||
|
||||
if ($model && $model !== 'none') {
|
||||
$input->setOption('model', $model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,9 @@ use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use LogicException;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'make:policy')]
|
||||
class PolicyMakeCommand extends GeneratorCommand
|
||||
@@ -209,4 +211,28 @@ class PolicyMakeCommand extends GeneratorCommand
|
||||
['guard', 'g', InputOption::VALUE_OPTIONAL, 'The guard that the policy relies on'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interact further with the user if they were prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$model = $this->components->askWithCompletion(
|
||||
'What model should this policy apply to?',
|
||||
$this->possibleModels(),
|
||||
'none'
|
||||
);
|
||||
|
||||
if ($model && $model !== 'none') {
|
||||
$input->setOption('model', $model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -84,12 +84,12 @@ class StubPublishCommand extends Command
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.model.api.stub') => 'controller.model.api.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.model.stub') => 'controller.model.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.api.stub') => 'controller.nested.api.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.api.stub') => 'controller.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.stub') => 'controller.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.api.stub') => 'controller.nested.singleton.api.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.stub') => 'controller.nested.singleton.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.stub') => 'controller.nested.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.plain.stub') => 'controller.plain.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.api.stub') => 'controller.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.stub') => 'controller.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.api.stub') => 'controller.singleton.api.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.stub') => 'controller.singleton.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/controller.stub') => 'controller.stub',
|
||||
realpath(__DIR__.'/../../Routing/Console/stubs/middleware.stub') => 'middleware.stub',
|
||||
];
|
||||
|
@@ -5,7 +5,9 @@ namespace Illuminate\Foundation\Console;
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'make:test')]
|
||||
class TestMakeCommand extends GeneratorCommand
|
||||
@@ -120,4 +122,32 @@ class TestMakeCommand extends GeneratorCommand
|
||||
['pest', 'p', InputOption::VALUE_NONE, 'Create a Pest test'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interact further with the user if they were prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$type = $this->components->choice('Which type of test would you like', [
|
||||
'feature',
|
||||
'unit',
|
||||
'pest feature',
|
||||
'pest unit',
|
||||
], default: 0);
|
||||
|
||||
match ($type) {
|
||||
'feature' => null,
|
||||
'unit' => $input->setOption('unit', true),
|
||||
'pest feature' => $input->setOption('pest', true),
|
||||
'pest unit' => tap($input)->setOption('pest', true)->setOption('unit', true),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -51,21 +51,21 @@ class Kernel implements KernelContract
|
||||
/**
|
||||
* The application's middleware stack.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [];
|
||||
|
||||
@@ -245,7 +245,7 @@ class Kernel implements KernelContract
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when the requests lifecyle duration exceeds a given amount of time.
|
||||
* Register a callback to be invoked when the requests lifecycle duration exceeds a given amount of time.
|
||||
*
|
||||
* @param \DateTimeInterface|\Carbon\CarbonInterval|float|int $threshold
|
||||
* @param callable $handler
|
||||
|
@@ -19,7 +19,7 @@ class PreventRequestsDuringMaintenance
|
||||
/**
|
||||
* The URIs that should be accessible while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
|
||||
|
@@ -16,7 +16,7 @@ class TrimStrings extends TransformsRequest
|
||||
/**
|
||||
* The attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
@@ -53,7 +53,7 @@ class TrimStrings extends TransformsRequest
|
||||
return $value;
|
||||
}
|
||||
|
||||
return preg_replace('~^[\s]+|[\s]+$~u', '', $value) ?? trim($value);
|
||||
return preg_replace('~^[\s\x{FEFF}\x{200B}]+|[\s\x{FEFF}\x{200B}]+$~u', '', $value) ?? trim($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -34,7 +34,7 @@ class VerifyCsrfToken
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
|
||||
|
@@ -122,9 +122,7 @@ class ProviderRepository
|
||||
return;
|
||||
}
|
||||
|
||||
$this->app->make('events')->listen($events, function () use ($provider) {
|
||||
$this->app->register($provider);
|
||||
});
|
||||
$this->app->make('events')->listen($events, fn () => $this->app->register($provider));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,7 +11,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* The event handler mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
protected $listen = [];
|
||||
|
||||
|
@@ -168,6 +168,30 @@ trait InteractsWithDatabase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the number of database queries that should occur throughout the test.
|
||||
*
|
||||
* @param int $expected
|
||||
* @param string|null $connection
|
||||
* @return $this
|
||||
*/
|
||||
public function expectsDatabaseQueryCount($expected, $connection = null)
|
||||
{
|
||||
with($this->getConnection($connection), function ($connection) use ($expected) {
|
||||
$actual = 0;
|
||||
|
||||
$connection->listen(function () use (&$actual) {
|
||||
$actual++;
|
||||
});
|
||||
|
||||
$this->beforeApplicationDestroyed(function () use (&$actual, $expected, $connection) {
|
||||
$this->assertSame($actual, $expected, "Expected {$expected} database queries on the [{$connection->getName()}] connection. {$actual} occurred.");
|
||||
});
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the argument is a soft deletable model.
|
||||
*
|
||||
|
122
vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php
vendored
Normal file
122
vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Foundation\Testing;
|
||||
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Foundation\Testing\Traits\CanConfigureMigrationCommands;
|
||||
|
||||
trait DatabaseTruncation
|
||||
{
|
||||
use CanConfigureMigrationCommands;
|
||||
|
||||
/**
|
||||
* The cached names of the database tables for each connection.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static array $allTables;
|
||||
|
||||
/**
|
||||
* Truncate the database tables for all configured connections.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function truncateDatabaseTables(): void
|
||||
{
|
||||
// Migrate and seed the database on first run...
|
||||
if (! RefreshDatabaseState::$migrated) {
|
||||
$this->artisan('migrate:fresh', $this->migrateFreshUsing());
|
||||
|
||||
$this->app[Kernel::class]->setArtisan(null);
|
||||
|
||||
RefreshDatabaseState::$migrated = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Always clear any test data on subsequent runs...
|
||||
$this->truncateTablesForAllConnections();
|
||||
|
||||
if ($seeder = $this->seeder()) {
|
||||
// Use a specific seeder class...
|
||||
$this->artisan('db:seed', ['--class' => $seeder]);
|
||||
} elseif ($this->shouldSeed()) {
|
||||
// Use the default seeder class...
|
||||
$this->artisan('db:seed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the database tables for all configured connections.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function truncateTablesForAllConnections(): void
|
||||
{
|
||||
$database = $this->app->make('db');
|
||||
|
||||
collect($this->connectionsToTruncate())
|
||||
->each(function ($name) use ($database) {
|
||||
$connection = $database->connection($name);
|
||||
|
||||
$connection->getSchemaBuilder()->withoutForeignKeyConstraints(
|
||||
fn () => $this->truncateTablesForConnection($connection, $name)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the database tables for the given database connection.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param string|null $name
|
||||
* @return void
|
||||
*/
|
||||
protected function truncateTablesForConnection(ConnectionInterface $connection, ?string $name): void
|
||||
{
|
||||
$dispatcher = $connection->getEventDispatcher();
|
||||
|
||||
$connection->unsetEventDispatcher();
|
||||
|
||||
collect(static::$allTables[$name] ??= $connection->getDoctrineSchemaManager()->listTableNames())
|
||||
->when(
|
||||
property_exists($this, 'tablesToTruncate'),
|
||||
fn ($tables) => $tables->intersect($this->tablesToTruncate),
|
||||
fn ($tables) => $tables->diff($this->exceptTables($name))
|
||||
)
|
||||
->filter(fn ($table) => $connection->table($table)->exists())
|
||||
->each(fn ($table) => $connection->table($table)->truncate());
|
||||
|
||||
$connection->setEventDispatcher($dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* The database connections that should have their tables truncated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function connectionsToTruncate(): array
|
||||
{
|
||||
return property_exists($this, 'connectionsToTruncate')
|
||||
? $this->connectionsToTruncate : [null];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tables that should not be truncated.
|
||||
*
|
||||
* @param string|null $connectionName
|
||||
* @return array
|
||||
*/
|
||||
protected function exceptTables(?string $connectionName): array
|
||||
{
|
||||
if (property_exists($this, 'exceptTables')) {
|
||||
return array_merge(
|
||||
$this->exceptTables[$connectionName] ?? [],
|
||||
[$this->app['config']->get('database.migrations')]
|
||||
);
|
||||
}
|
||||
|
||||
return [$this->app['config']->get('database.migrations')];
|
||||
}
|
||||
}
|
@@ -131,6 +131,10 @@ abstract class TestCase extends BaseTestCase
|
||||
$this->runDatabaseMigrations();
|
||||
}
|
||||
|
||||
if (isset($uses[DatabaseTruncation::class])) {
|
||||
$this->truncateDatabaseTables();
|
||||
}
|
||||
|
||||
if (isset($uses[DatabaseTransactions::class])) {
|
||||
$this->beginDatabaseTransaction();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user