diff --git a/vendor/adldap2/adldap2-laravel/composer.json b/vendor/adldap2/adldap2-laravel/composer.json index 27c2bd15..1b8a158d 100644 --- a/vendor/adldap2/adldap2-laravel/composer.json +++ b/vendor/adldap2/adldap2-laravel/composer.json @@ -1,21 +1,28 @@ { "name": "adldap2/adldap2-laravel", "description": "LDAP Authentication & Management for Laravel.", - "keywords": ["adldap", "adldap2", "ldap", "laravel"], + "keywords": [ + "adldap", + "adldap2", + "ldap", + "laravel" + ], "license": "MIT", "type": "project", "require": { "php": ">=7.1", "adldap2/adldap2": "^10.1", - "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0" + "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0|^10.0" }, "require-dev": { "mockery/mockery": "~1.0", - "phpunit/phpunit": "~7.0|~8.0", - "orchestra/testbench": "~3.7|~4.0" + "phpunit/phpunit": "~7.0|~8.0|^9.5.10", + "orchestra/testbench": "~3.7|~4.0|^8.0" }, "archive": { - "exclude": ["/tests"] + "exclude": [ + "/tests" + ] }, "autoload": { "psr-4": { diff --git a/vendor/adldap2/adldap2/.github/workflows/tests.yaml b/vendor/adldap2/adldap2/.github/workflows/tests.yaml index 05ed56c8..2d8b675d 100644 --- a/vendor/adldap2/adldap2/.github/workflows/tests.yaml +++ b/vendor/adldap2/adldap2/.github/workflows/tests.yaml @@ -32,6 +32,7 @@ jobs: - "7.4" - "8.0" - "8.1" + - "8.2" name: PHP ${{ matrix.php-version }} tests diff --git a/vendor/adldap2/adldap2/composer.json b/vendor/adldap2/adldap2/composer.json index 52c1635e..71a5f0b5 100644 --- a/vendor/adldap2/adldap2/composer.json +++ b/vendor/adldap2/adldap2/composer.json @@ -29,14 +29,14 @@ "php": ">=7.0", "ext-ldap": "*", "ext-json": "*", - "psr/log": "~1.0|~2.0|~3.0", - "psr/simple-cache": "~1.0|~2.0", - "tightenco/collect": "~5.0|~6.0|~7.0|~8.0", - "illuminate/contracts": "~5.0|~6.0|~7.0|~8.0|~9.0" + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "tightenco/collect": "^5.0|^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0" }, "require-dev": { - "symfony/phpunit-bridge": "~5.2|~6.0", - "mockery/mockery": "~1.0" + "symfony/phpunit-bridge": "^5.2|^6.0", + "mockery/mockery": "^1.0" }, "suggest": { "ext-fileinfo": "fileinfo is required when retrieving user encoded thumbnails" diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index c8f64033..9b130804 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2981,6 +2981,7 @@ return array( 'Illuminate\\Cache\\Events\\CacheMissed' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Events/CacheMissed.php', 'Illuminate\\Cache\\Events\\KeyForgotten' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Events/KeyForgotten.php', 'Illuminate\\Cache\\Events\\KeyWritten' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Events/KeyWritten.php', + 'Illuminate\\Cache\\FileLock' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/FileLock.php', 'Illuminate\\Cache\\FileStore' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/FileStore.php', 'Illuminate\\Cache\\HasCacheLock' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/HasCacheLock.php', 'Illuminate\\Cache\\Lock' => $vendorDir . '/laravel/framework/src/Illuminate/Cache/Lock.php', @@ -3368,6 +3369,7 @@ return array( 'Illuminate\\Database\\Query\\Grammars\\PostgresGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php', 'Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php', 'Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php', + 'Illuminate\\Database\\Query\\IndexHint' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/IndexHint.php', 'Illuminate\\Database\\Query\\JoinClause' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/JoinClause.php', 'Illuminate\\Database\\Query\\Processors\\MySqlProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/MySqlProcessor.php', 'Illuminate\\Database\\Query\\Processors\\PostgresProcessor' => $vendorDir . '/laravel/framework/src/Illuminate/Database/Query/Processors/PostgresProcessor.php', @@ -3637,6 +3639,7 @@ return array( 'Illuminate\\Mail\\Transport\\ArrayTransport' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Transport/ArrayTransport.php', 'Illuminate\\Mail\\Transport\\LogTransport' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Transport/LogTransport.php', 'Illuminate\\Mail\\Transport\\SesTransport' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php', + 'Illuminate\\Mail\\Transport\\SesV2Transport' => $vendorDir . '/laravel/framework/src/Illuminate/Mail/Transport/SesV2Transport.php', 'Illuminate\\Notifications\\Action' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Action.php', 'Illuminate\\Notifications\\AnonymousNotifiable' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/AnonymousNotifiable.php', 'Illuminate\\Notifications\\ChannelManager' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/ChannelManager.php', @@ -6466,6 +6469,9 @@ return array( 'Spipu\\Html2Pdf\\Tag\\Svg\\Polyline' => $vendorDir . '/spipu/html2pdf/src/Tag/Svg/Polyline.php', 'Spipu\\Html2Pdf\\Tag\\Svg\\Rect' => $vendorDir . '/spipu/html2pdf/src/Tag/Svg/Rect.php', 'Spipu\\Html2Pdf\\Tag\\TagInterface' => $vendorDir . '/spipu/html2pdf/src/Tag/TagInterface.php', + 'Spiral\\Core\\Attribute\\Finalize' => $vendorDir . '/spiral/core/src/Attribute/Finalize.php', + 'Spiral\\Core\\Attribute\\Scope' => $vendorDir . '/spiral/core/src/Attribute/Scope.php', + 'Spiral\\Core\\Attribute\\Singleton' => $vendorDir . '/spiral/core/src/Attribute/Singleton.php', 'Spiral\\Core\\BinderInterface' => $vendorDir . '/spiral/core/src/BinderInterface.php', 'Spiral\\Core\\Config' => $vendorDir . '/spiral/core/src/Config.php', 'Spiral\\Core\\ConfigsInterface' => $vendorDir . '/spiral/core/src/ConfigsInterface.php', @@ -6495,20 +6501,29 @@ return array( 'Spiral\\Core\\Exception\\Resolver\\WrongTypeException' => $vendorDir . '/spiral/core/src/Exception/Resolver/WrongTypeException.php', 'Spiral\\Core\\Exception\\RuntimeException' => $vendorDir . '/spiral/core/src/Exception/RuntimeException.php', 'Spiral\\Core\\Exception\\ScopeException' => $vendorDir . '/spiral/core/src/Exception/ScopeException.php', + 'Spiral\\Core\\Exception\\Scope\\BadScopeException' => $vendorDir . '/spiral/core/src/Exception/Scope/BadScopeException.php', + 'Spiral\\Core\\Exception\\Scope\\FinalizersException' => $vendorDir . '/spiral/core/src/Exception/Scope/FinalizersException.php', + 'Spiral\\Core\\Exception\\Scope\\NamedScopeDuplicationException' => $vendorDir . '/spiral/core/src/Exception/Scope/NamedScopeDuplicationException.php', + 'Spiral\\Core\\Exception\\Scope\\ScopeContainerLeakedException' => $vendorDir . '/spiral/core/src/Exception/Scope/ScopeContainerLeakedException.php', + 'Spiral\\Core\\Exception\\Scope\\ScopeException' => $vendorDir . '/spiral/core/src/Exception/Scope/ScopeException.php', 'Spiral\\Core\\Exception\\Traits\\ClosureRendererTrait' => $vendorDir . '/spiral/core/src/Exception/Traits/ClosureRendererTrait.php', 'Spiral\\Core\\FactoryInterface' => $vendorDir . '/spiral/core/src/FactoryInterface.php', 'Spiral\\Core\\InjectableConfig' => $vendorDir . '/spiral/core/src/InjectableConfig.php', 'Spiral\\Core\\Internal\\Binder' => $vendorDir . '/spiral/core/src/Internal/Binder.php', + 'Spiral\\Core\\Internal\\Common\\DestructorTrait' => $vendorDir . '/spiral/core/src/Internal/Common/DestructorTrait.php', + 'Spiral\\Core\\Internal\\Common\\Registry' => $vendorDir . '/spiral/core/src/Internal/Common/Registry.php', + 'Spiral\\Core\\Internal\\Config\\StateBinder' => $vendorDir . '/spiral/core/src/Internal/Config/StateBinder.php', + 'Spiral\\Core\\Internal\\Config\\StateStorage' => $vendorDir . '/spiral/core/src/Internal/Config/StateStorage.php', 'Spiral\\Core\\Internal\\Container' => $vendorDir . '/spiral/core/src/Internal/Container.php', - 'Spiral\\Core\\Internal\\DestructorTrait' => $vendorDir . '/spiral/core/src/Internal/DestructorTrait.php', 'Spiral\\Core\\Internal\\Factory' => $vendorDir . '/spiral/core/src/Internal/Factory.php', + 'Spiral\\Core\\Internal\\Factory\\Ctx' => $vendorDir . '/spiral/core/src/Internal/Factory/Ctx.php', 'Spiral\\Core\\Internal\\Invoker' => $vendorDir . '/spiral/core/src/Internal/Invoker.php', - 'Spiral\\Core\\Internal\\Registry' => $vendorDir . '/spiral/core/src/Internal/Registry.php', 'Spiral\\Core\\Internal\\Resolver' => $vendorDir . '/spiral/core/src/Internal/Resolver.php', - 'Spiral\\Core\\Internal\\ResolvingState' => $vendorDir . '/spiral/core/src/Internal/ResolvingState.php', + 'Spiral\\Core\\Internal\\Resolver\\ResolvingState' => $vendorDir . '/spiral/core/src/Internal/Resolver/ResolvingState.php', + 'Spiral\\Core\\Internal\\Scope' => $vendorDir . '/spiral/core/src/Internal/Scope.php', 'Spiral\\Core\\Internal\\State' => $vendorDir . '/spiral/core/src/Internal/State.php', - 'Spiral\\Core\\Internal\\Trace' => $vendorDir . '/spiral/core/src/Internal/Trace.php', 'Spiral\\Core\\Internal\\Tracer' => $vendorDir . '/spiral/core/src/Internal/Tracer.php', + 'Spiral\\Core\\Internal\\Tracer\\Trace' => $vendorDir . '/spiral/core/src/Internal/Tracer/Trace.php', 'Spiral\\Core\\InvokerInterface' => $vendorDir . '/spiral/core/src/InvokerInterface.php', 'Spiral\\Core\\ResolverInterface' => $vendorDir . '/spiral/core/src/ResolverInterface.php', 'Spiral\\Core\\ScopeInterface' => $vendorDir . '/spiral/core/src/ScopeInterface.php', @@ -6630,6 +6645,9 @@ return array( 'Spiral\\RoadRunner\\WorkerAwareInterface' => $vendorDir . '/spiral/roadrunner-worker/src/WorkerAwareInterface.php', 'Spiral\\RoadRunner\\WorkerInterface' => $vendorDir . '/spiral/roadrunner-worker/src/WorkerInterface.php', 'Spiral\\Tokenizer\\AbstractLocator' => $vendorDir . '/spiral/tokenizer/src/AbstractLocator.php', + 'Spiral\\Tokenizer\\Attribute\\AbstractTarget' => $vendorDir . '/spiral/tokenizer/src/Attribute/AbstractTarget.php', + 'Spiral\\Tokenizer\\Attribute\\TargetAttribute' => $vendorDir . '/spiral/tokenizer/src/Attribute/TargetAttribute.php', + 'Spiral\\Tokenizer\\Attribute\\TargetClass' => $vendorDir . '/spiral/tokenizer/src/Attribute/TargetClass.php', 'Spiral\\Tokenizer\\Bootloader\\TokenizerBootloader' => $vendorDir . '/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php', 'Spiral\\Tokenizer\\Bootloader\\TokenizerListenerBootloader' => $vendorDir . '/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php', 'Spiral\\Tokenizer\\ClassLocator' => $vendorDir . '/spiral/tokenizer/src/ClassLocator.php', @@ -6642,6 +6660,10 @@ return array( 'Spiral\\Tokenizer\\InvocationLocator' => $vendorDir . '/spiral/tokenizer/src/InvocationLocator.php', 'Spiral\\Tokenizer\\InvocationLocatorInjector' => $vendorDir . '/spiral/tokenizer/src/InvocationLocatorInjector.php', 'Spiral\\Tokenizer\\InvocationsInterface' => $vendorDir . '/spiral/tokenizer/src/InvocationsInterface.php', + 'Spiral\\Tokenizer\\Listener\\CachedClassesLoader' => $vendorDir . '/spiral/tokenizer/src/Listener/CachedClassesLoader.php', + 'Spiral\\Tokenizer\\Listener\\ClassLocatorByTarget' => $vendorDir . '/spiral/tokenizer/src/Listener/ClassLocatorByTarget.php', + 'Spiral\\Tokenizer\\Listener\\ClassesLoaderInterface' => $vendorDir . '/spiral/tokenizer/src/Listener/ClassesLoaderInterface.php', + 'Spiral\\Tokenizer\\Listener\\ListenerInvoker' => $vendorDir . '/spiral/tokenizer/src/Listener/ListenerInvoker.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionArgument' => $vendorDir . '/spiral/tokenizer/src/Reflection/ReflectionArgument.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionFile' => $vendorDir . '/spiral/tokenizer/src/Reflection/ReflectionFile.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionInvocation' => $vendorDir . '/spiral/tokenizer/src/Reflection/ReflectionInvocation.php', @@ -7704,6 +7726,7 @@ return array( 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', + 'Tightenco\\Collect\\Conditionable\\HigherOrderWhenProxy' => $vendorDir . '/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php', 'Tightenco\\Collect\\Contracts\\Support\\Arrayable' => $vendorDir . '/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php', 'Tightenco\\Collect\\Contracts\\Support\\CanBeEscapedWhenCastToString' => $vendorDir . '/tightenco/collect/src/Collect/Contracts/Support/CanBeEscapedWhenCastToString.php', 'Tightenco\\Collect\\Contracts\\Support\\Htmlable' => $vendorDir . '/tightenco/collect/src/Collect/Contracts/Support/Htmlable.php', @@ -7712,8 +7735,9 @@ return array( 'Tightenco\\Collect\\Support\\Collection' => $vendorDir . '/tightenco/collect/src/Collect/Support/Collection.php', 'Tightenco\\Collect\\Support\\Enumerable' => $vendorDir . '/tightenco/collect/src/Collect/Support/Enumerable.php', 'Tightenco\\Collect\\Support\\HigherOrderCollectionProxy' => $vendorDir . '/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php', - 'Tightenco\\Collect\\Support\\HigherOrderWhenProxy' => $vendorDir . '/tightenco/collect/src/Collect/Support/HigherOrderWhenProxy.php', 'Tightenco\\Collect\\Support\\LazyCollection' => $vendorDir . '/tightenco/collect/src/Collect/Support/LazyCollection.php', + 'Tightenco\\Collect\\Support\\Str' => $vendorDir . '/tightenco/collect/src/Collect/Support/Str.php', + 'Tightenco\\Collect\\Support\\Traits\\Conditionable' => $vendorDir . '/tightenco/collect/src/Collect/Support/Traits/Conditionable.php', 'Tightenco\\Collect\\Support\\Traits\\EnumeratesValues' => $vendorDir . '/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php', 'Tightenco\\Collect\\Support\\Traits\\Macroable' => $vendorDir . '/tightenco/collect/src/Collect/Support/Traits/Macroable.php', 'Tightenco\\Collect\\Support\\Traits\\Tappable' => $vendorDir . '/tightenco/collect/src/Collect/Support/Traits/Tappable.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 097f653c..571666a3 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -3755,6 +3755,7 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Illuminate\\Cache\\Events\\CacheMissed' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/Events/CacheMissed.php', 'Illuminate\\Cache\\Events\\KeyForgotten' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/Events/KeyForgotten.php', 'Illuminate\\Cache\\Events\\KeyWritten' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/Events/KeyWritten.php', + 'Illuminate\\Cache\\FileLock' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/FileLock.php', 'Illuminate\\Cache\\FileStore' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/FileStore.php', 'Illuminate\\Cache\\HasCacheLock' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/HasCacheLock.php', 'Illuminate\\Cache\\Lock' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Cache/Lock.php', @@ -4142,6 +4143,7 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Illuminate\\Database\\Query\\Grammars\\PostgresGrammar' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php', 'Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php', 'Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php', + 'Illuminate\\Database\\Query\\IndexHint' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/IndexHint.php', 'Illuminate\\Database\\Query\\JoinClause' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/JoinClause.php', 'Illuminate\\Database\\Query\\Processors\\MySqlProcessor' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/Processors/MySqlProcessor.php', 'Illuminate\\Database\\Query\\Processors\\PostgresProcessor' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Database/Query/Processors/PostgresProcessor.php', @@ -4411,6 +4413,7 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Illuminate\\Mail\\Transport\\ArrayTransport' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Mail/Transport/ArrayTransport.php', 'Illuminate\\Mail\\Transport\\LogTransport' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Mail/Transport/LogTransport.php', 'Illuminate\\Mail\\Transport\\SesTransport' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php', + 'Illuminate\\Mail\\Transport\\SesV2Transport' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Mail/Transport/SesV2Transport.php', 'Illuminate\\Notifications\\Action' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Action.php', 'Illuminate\\Notifications\\AnonymousNotifiable' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/AnonymousNotifiable.php', 'Illuminate\\Notifications\\ChannelManager' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/ChannelManager.php', @@ -7240,6 +7243,9 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Spipu\\Html2Pdf\\Tag\\Svg\\Polyline' => __DIR__ . '/..' . '/spipu/html2pdf/src/Tag/Svg/Polyline.php', 'Spipu\\Html2Pdf\\Tag\\Svg\\Rect' => __DIR__ . '/..' . '/spipu/html2pdf/src/Tag/Svg/Rect.php', 'Spipu\\Html2Pdf\\Tag\\TagInterface' => __DIR__ . '/..' . '/spipu/html2pdf/src/Tag/TagInterface.php', + 'Spiral\\Core\\Attribute\\Finalize' => __DIR__ . '/..' . '/spiral/core/src/Attribute/Finalize.php', + 'Spiral\\Core\\Attribute\\Scope' => __DIR__ . '/..' . '/spiral/core/src/Attribute/Scope.php', + 'Spiral\\Core\\Attribute\\Singleton' => __DIR__ . '/..' . '/spiral/core/src/Attribute/Singleton.php', 'Spiral\\Core\\BinderInterface' => __DIR__ . '/..' . '/spiral/core/src/BinderInterface.php', 'Spiral\\Core\\Config' => __DIR__ . '/..' . '/spiral/core/src/Config.php', 'Spiral\\Core\\ConfigsInterface' => __DIR__ . '/..' . '/spiral/core/src/ConfigsInterface.php', @@ -7269,20 +7275,29 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Spiral\\Core\\Exception\\Resolver\\WrongTypeException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Resolver/WrongTypeException.php', 'Spiral\\Core\\Exception\\RuntimeException' => __DIR__ . '/..' . '/spiral/core/src/Exception/RuntimeException.php', 'Spiral\\Core\\Exception\\ScopeException' => __DIR__ . '/..' . '/spiral/core/src/Exception/ScopeException.php', + 'Spiral\\Core\\Exception\\Scope\\BadScopeException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Scope/BadScopeException.php', + 'Spiral\\Core\\Exception\\Scope\\FinalizersException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Scope/FinalizersException.php', + 'Spiral\\Core\\Exception\\Scope\\NamedScopeDuplicationException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Scope/NamedScopeDuplicationException.php', + 'Spiral\\Core\\Exception\\Scope\\ScopeContainerLeakedException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Scope/ScopeContainerLeakedException.php', + 'Spiral\\Core\\Exception\\Scope\\ScopeException' => __DIR__ . '/..' . '/spiral/core/src/Exception/Scope/ScopeException.php', 'Spiral\\Core\\Exception\\Traits\\ClosureRendererTrait' => __DIR__ . '/..' . '/spiral/core/src/Exception/Traits/ClosureRendererTrait.php', 'Spiral\\Core\\FactoryInterface' => __DIR__ . '/..' . '/spiral/core/src/FactoryInterface.php', 'Spiral\\Core\\InjectableConfig' => __DIR__ . '/..' . '/spiral/core/src/InjectableConfig.php', 'Spiral\\Core\\Internal\\Binder' => __DIR__ . '/..' . '/spiral/core/src/Internal/Binder.php', + 'Spiral\\Core\\Internal\\Common\\DestructorTrait' => __DIR__ . '/..' . '/spiral/core/src/Internal/Common/DestructorTrait.php', + 'Spiral\\Core\\Internal\\Common\\Registry' => __DIR__ . '/..' . '/spiral/core/src/Internal/Common/Registry.php', + 'Spiral\\Core\\Internal\\Config\\StateBinder' => __DIR__ . '/..' . '/spiral/core/src/Internal/Config/StateBinder.php', + 'Spiral\\Core\\Internal\\Config\\StateStorage' => __DIR__ . '/..' . '/spiral/core/src/Internal/Config/StateStorage.php', 'Spiral\\Core\\Internal\\Container' => __DIR__ . '/..' . '/spiral/core/src/Internal/Container.php', - 'Spiral\\Core\\Internal\\DestructorTrait' => __DIR__ . '/..' . '/spiral/core/src/Internal/DestructorTrait.php', 'Spiral\\Core\\Internal\\Factory' => __DIR__ . '/..' . '/spiral/core/src/Internal/Factory.php', + 'Spiral\\Core\\Internal\\Factory\\Ctx' => __DIR__ . '/..' . '/spiral/core/src/Internal/Factory/Ctx.php', 'Spiral\\Core\\Internal\\Invoker' => __DIR__ . '/..' . '/spiral/core/src/Internal/Invoker.php', - 'Spiral\\Core\\Internal\\Registry' => __DIR__ . '/..' . '/spiral/core/src/Internal/Registry.php', 'Spiral\\Core\\Internal\\Resolver' => __DIR__ . '/..' . '/spiral/core/src/Internal/Resolver.php', - 'Spiral\\Core\\Internal\\ResolvingState' => __DIR__ . '/..' . '/spiral/core/src/Internal/ResolvingState.php', + 'Spiral\\Core\\Internal\\Resolver\\ResolvingState' => __DIR__ . '/..' . '/spiral/core/src/Internal/Resolver/ResolvingState.php', + 'Spiral\\Core\\Internal\\Scope' => __DIR__ . '/..' . '/spiral/core/src/Internal/Scope.php', 'Spiral\\Core\\Internal\\State' => __DIR__ . '/..' . '/spiral/core/src/Internal/State.php', - 'Spiral\\Core\\Internal\\Trace' => __DIR__ . '/..' . '/spiral/core/src/Internal/Trace.php', 'Spiral\\Core\\Internal\\Tracer' => __DIR__ . '/..' . '/spiral/core/src/Internal/Tracer.php', + 'Spiral\\Core\\Internal\\Tracer\\Trace' => __DIR__ . '/..' . '/spiral/core/src/Internal/Tracer/Trace.php', 'Spiral\\Core\\InvokerInterface' => __DIR__ . '/..' . '/spiral/core/src/InvokerInterface.php', 'Spiral\\Core\\ResolverInterface' => __DIR__ . '/..' . '/spiral/core/src/ResolverInterface.php', 'Spiral\\Core\\ScopeInterface' => __DIR__ . '/..' . '/spiral/core/src/ScopeInterface.php', @@ -7404,6 +7419,9 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Spiral\\RoadRunner\\WorkerAwareInterface' => __DIR__ . '/..' . '/spiral/roadrunner-worker/src/WorkerAwareInterface.php', 'Spiral\\RoadRunner\\WorkerInterface' => __DIR__ . '/..' . '/spiral/roadrunner-worker/src/WorkerInterface.php', 'Spiral\\Tokenizer\\AbstractLocator' => __DIR__ . '/..' . '/spiral/tokenizer/src/AbstractLocator.php', + 'Spiral\\Tokenizer\\Attribute\\AbstractTarget' => __DIR__ . '/..' . '/spiral/tokenizer/src/Attribute/AbstractTarget.php', + 'Spiral\\Tokenizer\\Attribute\\TargetAttribute' => __DIR__ . '/..' . '/spiral/tokenizer/src/Attribute/TargetAttribute.php', + 'Spiral\\Tokenizer\\Attribute\\TargetClass' => __DIR__ . '/..' . '/spiral/tokenizer/src/Attribute/TargetClass.php', 'Spiral\\Tokenizer\\Bootloader\\TokenizerBootloader' => __DIR__ . '/..' . '/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php', 'Spiral\\Tokenizer\\Bootloader\\TokenizerListenerBootloader' => __DIR__ . '/..' . '/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php', 'Spiral\\Tokenizer\\ClassLocator' => __DIR__ . '/..' . '/spiral/tokenizer/src/ClassLocator.php', @@ -7416,6 +7434,10 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Spiral\\Tokenizer\\InvocationLocator' => __DIR__ . '/..' . '/spiral/tokenizer/src/InvocationLocator.php', 'Spiral\\Tokenizer\\InvocationLocatorInjector' => __DIR__ . '/..' . '/spiral/tokenizer/src/InvocationLocatorInjector.php', 'Spiral\\Tokenizer\\InvocationsInterface' => __DIR__ . '/..' . '/spiral/tokenizer/src/InvocationsInterface.php', + 'Spiral\\Tokenizer\\Listener\\CachedClassesLoader' => __DIR__ . '/..' . '/spiral/tokenizer/src/Listener/CachedClassesLoader.php', + 'Spiral\\Tokenizer\\Listener\\ClassLocatorByTarget' => __DIR__ . '/..' . '/spiral/tokenizer/src/Listener/ClassLocatorByTarget.php', + 'Spiral\\Tokenizer\\Listener\\ClassesLoaderInterface' => __DIR__ . '/..' . '/spiral/tokenizer/src/Listener/ClassesLoaderInterface.php', + 'Spiral\\Tokenizer\\Listener\\ListenerInvoker' => __DIR__ . '/..' . '/spiral/tokenizer/src/Listener/ListenerInvoker.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionArgument' => __DIR__ . '/..' . '/spiral/tokenizer/src/Reflection/ReflectionArgument.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionFile' => __DIR__ . '/..' . '/spiral/tokenizer/src/Reflection/ReflectionFile.php', 'Spiral\\Tokenizer\\Reflection\\ReflectionInvocation' => __DIR__ . '/..' . '/spiral/tokenizer/src/Reflection/ReflectionInvocation.php', @@ -8478,6 +8500,7 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', + 'Tightenco\\Collect\\Conditionable\\HigherOrderWhenProxy' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php', 'Tightenco\\Collect\\Contracts\\Support\\Arrayable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php', 'Tightenco\\Collect\\Contracts\\Support\\CanBeEscapedWhenCastToString' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Contracts/Support/CanBeEscapedWhenCastToString.php', 'Tightenco\\Collect\\Contracts\\Support\\Htmlable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Contracts/Support/Htmlable.php', @@ -8486,8 +8509,9 @@ class ComposerStaticInite758755b0ce068cedf69837a0c438f81 'Tightenco\\Collect\\Support\\Collection' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Collection.php', 'Tightenco\\Collect\\Support\\Enumerable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Enumerable.php', 'Tightenco\\Collect\\Support\\HigherOrderCollectionProxy' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php', - 'Tightenco\\Collect\\Support\\HigherOrderWhenProxy' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/HigherOrderWhenProxy.php', 'Tightenco\\Collect\\Support\\LazyCollection' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/LazyCollection.php', + 'Tightenco\\Collect\\Support\\Str' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Str.php', + 'Tightenco\\Collect\\Support\\Traits\\Conditionable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Traits/Conditionable.php', 'Tightenco\\Collect\\Support\\Traits\\EnumeratesValues' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php', 'Tightenco\\Collect\\Support\\Traits\\Macroable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Traits/Macroable.php', 'Tightenco\\Collect\\Support\\Traits\\Tappable' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/Traits/Tappable.php', diff --git a/vendor/composer/composer/CHANGELOG.md b/vendor/composer/composer/CHANGELOG.md index 0e04f80d..5405513a 100644 --- a/vendor/composer/composer/CHANGELOG.md +++ b/vendor/composer/composer/CHANGELOG.md @@ -1,3 +1,7 @@ +### [2.5.4] 2023-02-15 + + * Fixed extra.plugin-optional support in PluginInstaller when doing pre-install checks (#11318) + ### [2.5.3] 2023-02-10 * Added extra.plugin-optional support for allow auto-disabling unknown plugins which are not critical when running non-interactive (#11315) @@ -1695,6 +1699,7 @@ * Initial release +[2.5.4]: https://github.com/composer/composer/compare/2.5.3...2.5.4 [2.5.3]: https://github.com/composer/composer/compare/2.5.2...2.5.3 [2.5.2]: https://github.com/composer/composer/compare/2.5.1...2.5.2 [2.5.1]: https://github.com/composer/composer/compare/2.5.0...2.5.1 diff --git a/vendor/composer/composer/src/Composer/Composer.php b/vendor/composer/composer/src/Composer/Composer.php index 6dd019db..3790513f 100644 --- a/vendor/composer/composer/src/Composer/Composer.php +++ b/vendor/composer/composer/src/Composer/Composer.php @@ -51,9 +51,9 @@ class Composer extends PartialComposer * * @see getVersion() */ - public const VERSION = '2.5.3'; + public const VERSION = '2.5.4'; public const BRANCH_ALIAS_VERSION = ''; - public const RELEASE_DATE = '2023-02-10 13:23:52'; + public const RELEASE_DATE = '2023-02-15 13:10:06'; public const SOURCE_VERSION = ''; /** diff --git a/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php b/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php index 68326462..3a982f13 100644 --- a/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php +++ b/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php @@ -50,7 +50,7 @@ class PluginInstaller extends LibraryInstaller { // fail install process early if it is going to fail due to a plugin not being allowed if (($type === 'install' || $type === 'update') && !$this->getPluginManager()->arePluginsDisabled('local')) { - $this->getPluginManager()->isPluginAllowed($package->getName(), false); + $this->getPluginManager()->isPluginAllowed($package->getName(), false, true === ($package->getExtra()['plugin-optional'] ?? false)); } return parent::prepare($type, $package, $prevPackage); diff --git a/vendor/composer/composer/src/Composer/Plugin/PluginManager.php b/vendor/composer/composer/src/Composer/Plugin/PluginManager.php index 74c33221..14eb4021 100644 --- a/vendor/composer/composer/src/Composer/Plugin/PluginManager.php +++ b/vendor/composer/composer/src/Composer/Plugin/PluginManager.php @@ -187,7 +187,7 @@ class PluginManager } } - if (!$this->isPluginAllowed($package->getName(), $isGlobalPlugin, $package->getExtra()['plugin-optional'] ?? false)) { + if (!$this->isPluginAllowed($package->getName(), $isGlobalPlugin, true === ($package->getExtra()['plugin-optional'] ?? false))) { $this->io->writeError('Skipped loading "'.$package->getName() . '" '.($isGlobalPlugin || $this->runningInGlobalDir ? '(installed globally) ' : '').'as it is not in config.allow-plugins', true, IOInterface::DEBUG); return; @@ -370,7 +370,7 @@ class PluginManager if ($sourcePackage === null) { trigger_error('Calling PluginManager::addPlugin without $sourcePackage is deprecated, if you are using this please get in touch with us to explain the use case', E_USER_DEPRECATED); - } elseif (!$this->isPluginAllowed($sourcePackage->getName(), $isGlobalPlugin, $sourcePackage->getExtra()['plugin-optional'] ?? false)) { + } elseif (!$this->isPluginAllowed($sourcePackage->getName(), $isGlobalPlugin, true === ($sourcePackage->getExtra()['plugin-optional'] ?? false))) { $this->io->writeError('Skipped loading "'.get_class($plugin).' from '.$sourcePackage->getName() . '" '.($isGlobalPlugin || $this->runningInGlobalDir ? '(installed globally) ' : '').' as it is not in config.allow-plugins', true, IOInterface::DEBUG); return; diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index eb3b6a80..65135f2b 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,36 +2,36 @@ "packages": [ { "name": "adldap2/adldap2", - "version": "v10.4.3", - "version_normalized": "10.4.3.0", + "version": "v10.5.0", + "version_normalized": "10.5.0.0", "source": { "type": "git", "url": "https://github.com/Adldap2/Adldap2.git", - "reference": "a55e2c5285b9e101ed555894bd7b97b20c0c293e" + "reference": "e400eecb7bd7de8ee79aae320b54ad70d37f86b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/a55e2c5285b9e101ed555894bd7b97b20c0c293e", - "reference": "a55e2c5285b9e101ed555894bd7b97b20c0c293e", + "url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/e400eecb7bd7de8ee79aae320b54ad70d37f86b1", + "reference": "e400eecb7bd7de8ee79aae320b54ad70d37f86b1", "shasum": "" }, "require": { "ext-json": "*", "ext-ldap": "*", - "illuminate/contracts": "~5.0|~6.0|~7.0|~8.0|~9.0", + "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", "php": ">=7.0", - "psr/log": "~1.0|~2.0|~3.0", - "psr/simple-cache": "~1.0|~2.0", - "tightenco/collect": "~5.0|~6.0|~7.0|~8.0" + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "tightenco/collect": "^5.0|^6.0|^7.0|^8.0|^9.0" }, "require-dev": { - "mockery/mockery": "~1.0", - "symfony/phpunit-bridge": "~5.2|~6.0" + "mockery/mockery": "^1.0", + "symfony/phpunit-bridge": "^5.2|^6.0" }, "suggest": { "ext-fileinfo": "fileinfo is required when retrieving user encoded thumbnails" }, - "time": "2022-10-18T13:33:00+00:00", + "time": "2023-02-23T15:00:03+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -70,30 +70,30 @@ }, { "name": "adldap2/adldap2-laravel", - "version": "v6.1.6", - "version_normalized": "6.1.6.0", + "version": "v6.1.7", + "version_normalized": "6.1.7.0", "source": { "type": "git", "url": "https://github.com/Adldap2/Adldap2-Laravel.git", - "reference": "e67f845db08389acdf7326fd596fda10b3560d25" + "reference": "d587c4dea4ffefbbbea7601958c125216ea43452" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Adldap2/Adldap2-Laravel/zipball/e67f845db08389acdf7326fd596fda10b3560d25", - "reference": "e67f845db08389acdf7326fd596fda10b3560d25", + "url": "https://api.github.com/repos/Adldap2/Adldap2-Laravel/zipball/d587c4dea4ffefbbbea7601958c125216ea43452", + "reference": "d587c4dea4ffefbbbea7601958c125216ea43452", "shasum": "" }, "require": { "adldap2/adldap2": "^10.1", - "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0", + "illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0|^10.0", "php": ">=7.1" }, "require-dev": { "mockery/mockery": "~1.0", - "orchestra/testbench": "~3.7|~4.0", - "phpunit/phpunit": "~7.0|~8.0" + "orchestra/testbench": "~3.7|~4.0|^8.0", + "phpunit/phpunit": "~7.0|~8.0|^9.5.10" }, - "time": "2022-02-09T13:04:53+00:00", + "time": "2023-02-15T14:51:44+00:00", "type": "project", "extra": { "laravel": { @@ -125,7 +125,7 @@ ], "support": { "issues": "https://github.com/Adldap2/Adldap2-Laravel/issues", - "source": "https://github.com/Adldap2/Adldap2-Laravel/tree/v6.1.6" + "source": "https://github.com/Adldap2/Adldap2-Laravel/tree/v6.1.7" }, "install-path": "../adldap2/adldap2-laravel" }, @@ -520,17 +520,17 @@ }, { "name": "composer/composer", - "version": "2.5.3", - "version_normalized": "2.5.3.0", + "version": "2.5.4", + "version_normalized": "2.5.4.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab" + "reference": "6b67eeea4d72051c369ccdbfb2423a56e2ab51a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab", - "reference": "607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab", + "url": "https://api.github.com/repos/composer/composer/zipball/6b67eeea4d72051c369ccdbfb2423a56e2ab51a9", + "reference": "6b67eeea4d72051c369ccdbfb2423a56e2ab51a9", "shasum": "" }, "require": { @@ -569,7 +569,7 @@ "ext-zip": "Enabling the zip extension allows you to unzip archives", "ext-zlib": "Allow gzip compression of HTTP requests" }, - "time": "2023-02-10T12:23:52+00:00", + "time": "2023-02-15T12:10:06+00:00", "bin": [ "bin/composer" ], @@ -616,7 +616,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.5.3" + "source": "https://github.com/composer/composer/tree/2.5.4" }, "funding": [ { @@ -2422,27 +2422,27 @@ }, { "name": "graham-campbell/result-type", - "version": "v1.1.0", - "version_normalized": "1.1.0.0", + "version": "v1.1.1", + "version_normalized": "1.1.1.0", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9" + "phpoption/phpoption": "^1.9.1" }, "require-dev": { - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, - "time": "2022-07-30T15:56:11+00:00", + "time": "2023-02-25T20:23:15+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2471,7 +2471,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" }, "funding": [ { @@ -3041,17 +3041,17 @@ }, { "name": "laravel/framework", - "version": "v9.51.0", - "version_normalized": "9.51.0.0", + "version": "v9.52.4", + "version_normalized": "9.52.4.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "b81123134349a013a738a9f7f715c6ce99d5a414" + "reference": "9239128cfb4d22afefb64060dfecf53e82987267" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/b81123134349a013a738a9f7f715c6ce99d5a414", - "reference": "b81123134349a013a738a9f7f715c6ce99d5a414", + "url": "https://api.github.com/repos/laravel/framework/zipball/9239128cfb4d22afefb64060dfecf53e82987267", + "reference": "9239128cfb4d22afefb64060dfecf53e82987267", "shasum": "" }, "require": { @@ -3194,7 +3194,7 @@ "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." }, - "time": "2023-02-07T15:37:18+00:00", + "time": "2023-02-22T14:38:06+00:00", "type": "library", "extra": { "branch-alias": { @@ -3305,17 +3305,17 @@ }, { "name": "laravel/tinker", - "version": "v2.8.0", - "version_normalized": "2.8.0.0", + "version": "v2.8.1", + "version_normalized": "2.8.1.0", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "74d0b287cc4ae65d15c368dd697aae71d62a73ad" + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/74d0b287cc4ae65d15c368dd697aae71d62a73ad", - "reference": "74d0b287cc4ae65d15c368dd697aae71d62a73ad", + "url": "https://api.github.com/repos/laravel/tinker/zipball/04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", "shasum": "" }, "require": { @@ -3333,7 +3333,7 @@ "suggest": { "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)." }, - "time": "2023-01-10T18:03:30+00:00", + "time": "2023-02-15T16:40:09+00:00", "type": "library", "extra": { "branch-alias": { @@ -3370,7 +3370,7 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.8.0" + "source": "https://github.com/laravel/tinker/tree/v2.8.1" }, "install-path": "../laravel/tinker" }, @@ -3520,17 +3520,17 @@ }, { "name": "league/commonmark", - "version": "2.3.8", - "version_normalized": "2.3.8.0", + "version": "2.3.9", + "version_normalized": "2.3.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "c493585c130544c4e91d2e0e131e6d35cb0cbc47" + "reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c493585c130544c4e91d2e0e131e6d35cb0cbc47", - "reference": "c493585c130544c4e91d2e0e131e6d35cb0cbc47", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c1e114f74e518daca2729ea8c4bf1167038fa4b5", + "reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5", "shasum": "" }, "require": { @@ -3563,7 +3563,7 @@ "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, - "time": "2022-12-10T16:02:17+00:00", + "time": "2023-02-15T14:07:24+00:00", "type": "library", "extra": { "branch-alias": { @@ -3714,17 +3714,17 @@ }, { "name": "league/flysystem", - "version": "3.12.2", - "version_normalized": "3.12.2.0", + "version": "3.12.3", + "version_normalized": "3.12.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "f6377c709d2275ed6feaf63e44be7a7162b0e77f" + "reference": "81e87e74dd5213795c7846d65089712d2dda90ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f6377c709d2275ed6feaf63e44be7a7162b0e77f", - "reference": "f6377c709d2275ed6feaf63e44be7a7162b0e77f", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/81e87e74dd5213795c7846d65089712d2dda90ce", + "reference": "81e87e74dd5213795c7846d65089712d2dda90ce", "shasum": "" }, "require": { @@ -3754,7 +3754,7 @@ "phpunit/phpunit": "^9.5.11", "sabre/dav": "^4.3.1" }, - "time": "2023-01-19T12:02:19+00:00", + "time": "2023-02-18T15:32:41+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3788,7 +3788,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.12.2" + "source": "https://github.com/thephpleague/flysystem/tree/3.12.3" }, "funding": [ { @@ -5157,27 +5157,27 @@ }, { "name": "phpoption/phpoption", - "version": "1.9.0", - "version_normalized": "1.9.0.0", + "version": "1.9.1", + "version_normalized": "1.9.1.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8", - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, - "time": "2022-07-30T15:51:26+00:00", + "time": "2023-02-25T19:38:58+00:00", "type": "library", "extra": { "bamarni-bin": { @@ -5219,7 +5219,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" }, "funding": [ { @@ -5302,24 +5302,24 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.24", - "version_normalized": "9.2.24.0", + "version": "9.2.25", + "version_normalized": "9.2.25.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" + "reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", - "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e2b40518197a8c0d4b08bc34dfff1c99c508954", + "reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -5337,7 +5337,7 @@ "ext-pcov": "*", "ext-xdebug": "*" }, - "time": "2023-01-26T08:26:55+00:00", + "time": "2023-02-25T05:32:00+00:00", "type": "library", "extra": { "branch-alias": { @@ -5370,7 +5370,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.25" }, "funding": [ { @@ -5635,17 +5635,17 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.3", - "version_normalized": "9.6.3.0", + "version": "9.6.4", + "version_normalized": "9.6.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555" + "reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7b1615e3e887d6c719121c6d4a44b0ab9645555", - "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9125ee085b6d95e78277dc07aa1f46f9e0607b8d", + "reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d", "shasum": "" }, "require": { @@ -5681,7 +5681,7 @@ "ext-soap": "*", "ext-xdebug": "*" }, - "time": "2023-02-04T13:37:15+00:00", + "time": "2023-02-27T13:06:37+00:00", "bin": [ "phpunit" ], @@ -5720,7 +5720,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.3" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.4" }, "funding": [ { @@ -6174,27 +6174,27 @@ }, { "name": "psr/simple-cache", - "version": "2.0.0", - "version_normalized": "2.0.0.0", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a" + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/8707bf3cea6f710bf6ef05491234e3ab06f6432a", - "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { "php": ">=8.0.0" }, - "time": "2021-10-29T13:22:09+00:00", + "time": "2021-10-29T13:26:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "installation-source": "dist", @@ -6222,7 +6222,7 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/2.0.0" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, "install-path": "../psr/simple-cache" }, @@ -7815,17 +7815,17 @@ }, { "name": "spatie/backtrace", - "version": "1.2.1", - "version_normalized": "1.2.1.0", + "version": "1.2.2", + "version_normalized": "1.2.2.0", "source": { "type": "git", "url": "https://github.com/spatie/backtrace.git", - "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b" + "reference": "7b34fee6c1ad45f8ee0498d17cd8ea9a076402c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", - "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/7b34fee6c1ad45f8ee0498d17cd8ea9a076402c1", + "reference": "7b34fee6c1ad45f8ee0498d17cd8ea9a076402c1", "shasum": "" }, "require": { @@ -7836,7 +7836,7 @@ "phpunit/phpunit": "^9.3", "symfony/var-dumper": "^5.1" }, - "time": "2021-11-09T10:57:15+00:00", + "time": "2023-02-21T08:29:12+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -7863,8 +7863,7 @@ "spatie" ], "support": { - "issues": "https://github.com/spatie/backtrace/issues", - "source": "https://github.com/spatie/backtrace/tree/1.2.1" + "source": "https://github.com/spatie/backtrace/tree/1.2.2" }, "funding": [ { @@ -8322,17 +8321,17 @@ }, { "name": "spiral/core", - "version": "3.5.0", - "version_normalized": "3.5.0.0", + "version": "3.6.1", + "version_normalized": "3.6.1.0", "source": { "type": "git", "url": "https://github.com/spiral/core.git", - "reference": "4745ec855e74b2d52d49232349d4b11dc19fa7e4" + "reference": "dffbc4e7b326004376545aac39161dcfddb57281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/core/zipball/4745ec855e74b2d52d49232349d4b11dc19fa7e4", - "reference": "4745ec855e74b2d52d49232349d4b11dc19fa7e4", + "url": "https://api.github.com/repos/spiral/core/zipball/dffbc4e7b326004376545aac39161dcfddb57281", + "reference": "dffbc4e7b326004376545aac39161dcfddb57281", "shasum": "" }, "require": { @@ -8342,13 +8341,13 @@ "require-dev": { "mockery/mockery": "^1.5", "phpunit/phpunit": "^9.5.20", - "vimeo/psalm": "^4.27" + "vimeo/psalm": "^5.6" }, - "time": "2022-12-23T13:32:05+00:00", + "time": "2023-02-19T07:31:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "installation-source": "dist", @@ -8454,34 +8453,34 @@ }, { "name": "spiral/logger", - "version": "3.5.0", - "version_normalized": "3.5.0.0", + "version": "3.6.1", + "version_normalized": "3.6.1.0", "source": { "type": "git", "url": "https://github.com/spiral/logger.git", - "reference": "1f00e1b57a31af5339a351ecd420df3f76667ecc" + "reference": "9fca2309638c9eb90888b1f7ddf2298d90769dd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/logger/zipball/1f00e1b57a31af5339a351ecd420df3f76667ecc", - "reference": "1f00e1b57a31af5339a351ecd420df3f76667ecc", + "url": "https://api.github.com/repos/spiral/logger/zipball/9fca2309638c9eb90888b1f7ddf2298d90769dd1", + "reference": "9fca2309638c9eb90888b1f7ddf2298d90769dd1", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "1 - 3", - "spiral/core": "^3.5" + "spiral/core": "^3.6.1" }, "require-dev": { "mockery/mockery": "^1.5", "phpunit/phpunit": "^9.5.20", "vimeo/psalm": "^4.27" }, - "time": "2022-12-23T13:35:08+00:00", + "time": "2023-02-20T15:47:39+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "installation-source": "dist", @@ -8522,17 +8521,17 @@ }, { "name": "spiral/roadrunner", - "version": "v2.12.2", - "version_normalized": "2.12.2.0", + "version": "v2.12.3", + "version_normalized": "2.12.3.0", "source": { "type": "git", "url": "https://github.com/roadrunner-server/roadrunner.git", - "reference": "c794a7ab2ae828af8068776b9dfcdcce5299d855" + "reference": "18f526ad9eef19b57bdf1ad4b0252683f514c718" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/roadrunner-server/roadrunner/zipball/c794a7ab2ae828af8068776b9dfcdcce5299d855", - "reference": "c794a7ab2ae828af8068776b9dfcdcce5299d855", + "url": "https://api.github.com/repos/roadrunner-server/roadrunner/zipball/18f526ad9eef19b57bdf1ad4b0252683f514c718", + "reference": "18f526ad9eef19b57bdf1ad4b0252683f514c718", "shasum": "" }, "require": { @@ -8540,7 +8539,7 @@ "spiral/roadrunner-http": "^2.0", "spiral/roadrunner-worker": "^2.0" }, - "time": "2023-01-12T11:55:21+00:00", + "time": "2023-02-16T13:00:26+00:00", "type": "metapackage", "notification-url": "https://packagist.org/downloads/", "license": [ @@ -8551,16 +8550,30 @@ "name": "Anton Titov / Wolfy-J", "email": "wolfy.jd@gmail.com" }, + { + "name": "Valery Piashchynski", + "homepage": "https://github.com/rustatian" + }, { "name": "RoadRunner Community", "homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors" } ], "description": "RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins", + "homepage": "https://roadrunner.dev/", "support": { + "chat": "https://discord.gg/V6EK4he", + "docs": "https://roadrunner.dev/docs", + "forum": "https://forum.roadrunner.dev/", "issues": "https://github.com/roadrunner-server/roadrunner/issues", - "source": "https://github.com/roadrunner-server/roadrunner/tree/v2.12.2" + "source": "https://github.com/roadrunner-server/roadrunner/tree/v2.12.3" }, + "funding": [ + { + "url": "https://github.com/sponsors/roadrunner-server", + "type": "github" + } + ], "install-path": null }, { @@ -8766,36 +8779,38 @@ }, { "name": "spiral/tokenizer", - "version": "3.5.0", - "version_normalized": "3.5.0.0", + "version": "3.6.1", + "version_normalized": "3.6.1.0", "source": { "type": "git", "url": "https://github.com/spiral/tokenizer.git", - "reference": "a11f4f1c5f0a5daad6d02ca4effe42ad45b68ff4" + "reference": "1920f0a9d0d78de3dee8c8b9ef6a68b0724c830e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/tokenizer/zipball/a11f4f1c5f0a5daad6d02ca4effe42ad45b68ff4", - "reference": "a11f4f1c5f0a5daad6d02ca4effe42ad45b68ff4", + "url": "https://api.github.com/repos/spiral/tokenizer/zipball/1920f0a9d0d78de3dee8c8b9ef6a68b0724c830e", + "reference": "1920f0a9d0d78de3dee8c8b9ef6a68b0724c830e", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=8.1", - "spiral/core": "^3.5", - "spiral/logger": "^3.5", + "spiral/core": "^3.6.1", + "spiral/logger": "^3.6.1", "symfony/finder": "^5.3.7|^6.0" }, "require-dev": { "phpunit/phpunit": "^9.5.20", - "spiral/boot": "^3.5", + "spiral/attributes": "^2.8|^3.0", + "spiral/boot": "^3.6.1", + "spiral/files": "^3.6.1", "vimeo/psalm": "^4.27" }, - "time": "2022-12-23T13:37:56+00:00", + "time": "2023-02-20T15:49:04+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "installation-source": "dist", @@ -11789,21 +11804,21 @@ }, { "name": "tightenco/collect", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v9.52.0", + "version_normalized": "9.52.0.0", "source": { "type": "git", "url": "https://github.com/tighten/collect.git", - "reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6" + "reference": "d4772fe52bbc823d1d2e3d289d3f1ca8c0f3323b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6", - "reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6", + "url": "https://api.github.com/repos/tighten/collect/zipball/d4772fe52bbc823d1d2e3d289d3f1ca8c0f3323b", + "reference": "d4772fe52bbc823d1d2e3d289d3f1ca8c0f3323b", "shasum": "" }, "require": { - "php": "^7.3|^8.0", + "php": "^8.0", "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { @@ -11811,7 +11826,7 @@ "nesbot/carbon": "^2.23.0", "phpunit/phpunit": "^8.3" }, - "time": "2023-01-13T18:05:42+00:00", + "time": "2023-02-17T21:37:36+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -11840,7 +11855,7 @@ ], "support": { "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v8.83.27" + "source": "https://github.com/tighten/collect/tree/v9.52.0" }, "install-path": "../tightenco/collect" }, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d49b2de3..b9ee602c 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'celaraze/chemex', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => '6c06b8eb13bc10a4afcb415a0159a4f55a98d32c', + 'reference' => '9e81dd15a9d64f3e43112b1c1e1a25443f9a13bc', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,18 +11,18 @@ ), 'versions' => array( 'adldap2/adldap2' => array( - 'pretty_version' => 'v10.4.3', - 'version' => '10.4.3.0', - 'reference' => 'a55e2c5285b9e101ed555894bd7b97b20c0c293e', + 'pretty_version' => 'v10.5.0', + 'version' => '10.5.0.0', + 'reference' => 'e400eecb7bd7de8ee79aae320b54ad70d37f86b1', 'type' => 'library', 'install_path' => __DIR__ . '/../adldap2/adldap2', 'aliases' => array(), 'dev_requirement' => false, ), 'adldap2/adldap2-laravel' => array( - 'pretty_version' => 'v6.1.6', - 'version' => '6.1.6.0', - 'reference' => 'e67f845db08389acdf7326fd596fda10b3560d25', + 'pretty_version' => 'v6.1.7', + 'version' => '6.1.7.0', + 'reference' => 'd587c4dea4ffefbbbea7601958c125216ea43452', 'type' => 'project', 'install_path' => __DIR__ . '/../adldap2/adldap2-laravel', 'aliases' => array(), @@ -58,7 +58,7 @@ 'celaraze/chemex' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => '6c06b8eb13bc10a4afcb415a0159a4f55a98d32c', + 'reference' => '9e81dd15a9d64f3e43112b1c1e1a25443f9a13bc', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -94,9 +94,9 @@ 'dev_requirement' => false, ), 'composer/composer' => array( - 'pretty_version' => '2.5.3', - 'version' => '2.5.3.0', - 'reference' => '607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab', + 'pretty_version' => '2.5.4', + 'version' => '2.5.4.0', + 'reference' => '6b67eeea4d72051c369ccdbfb2423a56e2ab51a9', 'type' => 'library', 'install_path' => __DIR__ . '/./composer', 'aliases' => array(), @@ -322,9 +322,9 @@ 'dev_requirement' => false, ), 'graham-campbell/result-type' => array( - 'pretty_version' => 'v1.1.0', - 'version' => '1.1.0.0', - 'reference' => 'a878d45c1914464426dc94da61c9e1d36ae262a8', + 'pretty_version' => 'v1.1.1', + 'version' => '1.1.1.0', + 'reference' => '672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831', 'type' => 'library', 'install_path' => __DIR__ . '/../graham-campbell/result-type', 'aliases' => array(), @@ -378,193 +378,193 @@ 'illuminate/auth' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/broadcasting' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/bus' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/cache' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/collections' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/conditionable' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/config' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/console' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/container' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/contracts' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/cookie' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/database' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/encryption' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/events' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/filesystem' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/hashing' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/http' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/log' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/macroable' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/mail' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/notifications' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/pagination' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/pipeline' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/queue' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/redis' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/routing' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/session' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/support' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/testing' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/translation' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/validation' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'illuminate/view' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v9.51.0', + 0 => 'v9.52.4', ), ), 'justinrainbow/json-schema' => array( @@ -583,9 +583,9 @@ ), ), 'laravel/framework' => array( - 'pretty_version' => 'v9.51.0', - 'version' => '9.51.0.0', - 'reference' => 'b81123134349a013a738a9f7f715c6ce99d5a414', + 'pretty_version' => 'v9.52.4', + 'version' => '9.52.4.0', + 'reference' => '9239128cfb4d22afefb64060dfecf53e82987267', 'type' => 'library', 'install_path' => __DIR__ . '/../laravel/framework', 'aliases' => array(), @@ -601,9 +601,9 @@ 'dev_requirement' => false, ), 'laravel/tinker' => array( - 'pretty_version' => 'v2.8.0', - 'version' => '2.8.0.0', - 'reference' => '74d0b287cc4ae65d15c368dd697aae71d62a73ad', + 'pretty_version' => 'v2.8.1', + 'version' => '2.8.1.0', + 'reference' => '04a2d3bd0d650c0764f70bf49d1ee39393e4eb10', 'type' => 'library', 'install_path' => __DIR__ . '/../laravel/tinker', 'aliases' => array(), @@ -628,9 +628,9 @@ 'dev_requirement' => false, ), 'league/commonmark' => array( - 'pretty_version' => '2.3.8', - 'version' => '2.3.8.0', - 'reference' => 'c493585c130544c4e91d2e0e131e6d35cb0cbc47', + 'pretty_version' => '2.3.9', + 'version' => '2.3.9.0', + 'reference' => 'c1e114f74e518daca2729ea8c4bf1167038fa4b5', 'type' => 'library', 'install_path' => __DIR__ . '/../league/commonmark', 'aliases' => array(), @@ -646,9 +646,9 @@ 'dev_requirement' => false, ), 'league/flysystem' => array( - 'pretty_version' => '3.12.2', - 'version' => '3.12.2.0', - 'reference' => 'f6377c709d2275ed6feaf63e44be7a7162b0e77f', + 'pretty_version' => '3.12.3', + 'version' => '3.12.3.0', + 'reference' => '81e87e74dd5213795c7846d65089712d2dda90ce', 'type' => 'library', 'install_path' => __DIR__ . '/../league/flysystem', 'aliases' => array(), @@ -835,9 +835,9 @@ ), ), 'phpoption/phpoption' => array( - 'pretty_version' => '1.9.0', - 'version' => '1.9.0.0', - 'reference' => 'dc5ff11e274a90cc1c743f66c9ad700ce50db9ab', + 'pretty_version' => '1.9.1', + 'version' => '1.9.1.0', + 'reference' => 'dd3a383e599f49777d8b628dadbb90cae435b87e', 'type' => 'library', 'install_path' => __DIR__ . '/../phpoption/phpoption', 'aliases' => array(), @@ -853,9 +853,9 @@ 'dev_requirement' => false, ), 'phpunit/php-code-coverage' => array( - 'pretty_version' => '9.2.24', - 'version' => '9.2.24.0', - 'reference' => '2cf940ebc6355a9d430462811b5aaa308b174bed', + 'pretty_version' => '9.2.25', + 'version' => '9.2.25.0', + 'reference' => '0e2b40518197a8c0d4b08bc34dfff1c99c508954', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-code-coverage', 'aliases' => array(), @@ -898,9 +898,9 @@ 'dev_requirement' => true, ), 'phpunit/phpunit' => array( - 'pretty_version' => '9.6.3', - 'version' => '9.6.3.0', - 'reference' => 'e7b1615e3e887d6c719121c6d4a44b0ab9645555', + 'pretty_version' => '9.6.4', + 'version' => '9.6.4.0', + 'reference' => '9125ee085b6d95e78277dc07aa1f46f9e0607b8d', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/phpunit', 'aliases' => array(), @@ -1017,14 +1017,14 @@ 'psr/log-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '1.0|2.0|3.0', - 1 => '1.0.0 || 2.0.0 || 3.0.0', + 0 => '1.0.0 || 2.0.0 || 3.0.0', + 1 => '1.0|2.0|3.0', ), ), 'psr/simple-cache' => array( - 'pretty_version' => '2.0.0', - 'version' => '2.0.0.0', - 'reference' => '8707bf3cea6f710bf6ef05491234e3ab06f6432a', + 'pretty_version' => '3.0.0', + 'version' => '3.0.0.0', + 'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), @@ -1259,9 +1259,9 @@ 'dev_requirement' => false, ), 'spatie/backtrace' => array( - 'pretty_version' => '1.2.1', - 'version' => '1.2.1.0', - 'reference' => '4ee7d41aa5268107906ea8a4d9ceccde136dbd5b', + 'pretty_version' => '1.2.2', + 'version' => '1.2.2.0', + 'reference' => '7b34fee6c1ad45f8ee0498d17cd8ea9a076402c1', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/backtrace', 'aliases' => array(), @@ -1322,9 +1322,9 @@ 'dev_requirement' => false, ), 'spiral/core' => array( - 'pretty_version' => '3.5.0', - 'version' => '3.5.0.0', - 'reference' => '4745ec855e74b2d52d49232349d4b11dc19fa7e4', + 'pretty_version' => '3.6.1', + 'version' => '3.6.1.0', + 'reference' => 'dffbc4e7b326004376545aac39161dcfddb57281', 'type' => 'library', 'install_path' => __DIR__ . '/../spiral/core', 'aliases' => array(), @@ -1340,18 +1340,18 @@ 'dev_requirement' => false, ), 'spiral/logger' => array( - 'pretty_version' => '3.5.0', - 'version' => '3.5.0.0', - 'reference' => '1f00e1b57a31af5339a351ecd420df3f76667ecc', + 'pretty_version' => '3.6.1', + 'version' => '3.6.1.0', + 'reference' => '9fca2309638c9eb90888b1f7ddf2298d90769dd1', 'type' => 'library', 'install_path' => __DIR__ . '/../spiral/logger', 'aliases' => array(), 'dev_requirement' => false, ), 'spiral/roadrunner' => array( - 'pretty_version' => 'v2.12.2', - 'version' => '2.12.2.0', - 'reference' => 'c794a7ab2ae828af8068776b9dfcdcce5299d855', + 'pretty_version' => 'v2.12.3', + 'version' => '2.12.3.0', + 'reference' => '18f526ad9eef19b57bdf1ad4b0252683f514c718', 'type' => 'metapackage', 'install_path' => NULL, 'aliases' => array(), @@ -1385,9 +1385,9 @@ 'dev_requirement' => false, ), 'spiral/tokenizer' => array( - 'pretty_version' => '3.5.0', - 'version' => '3.5.0.0', - 'reference' => 'a11f4f1c5f0a5daad6d02ca4effe42ad45b68ff4', + 'pretty_version' => '3.6.1', + 'version' => '3.6.1.0', + 'reference' => '1920f0a9d0d78de3dee8c8b9ef6a68b0724c830e', 'type' => 'library', 'install_path' => __DIR__ . '/../spiral/tokenizer', 'aliases' => array(), @@ -1736,9 +1736,9 @@ 'dev_requirement' => true, ), 'tightenco/collect' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6', + 'pretty_version' => 'v9.52.0', + 'version' => '9.52.0.0', + 'reference' => 'd4772fe52bbc823d1d2e3d289d3f1ca8c0f3323b', 'type' => 'library', 'install_path' => __DIR__ . '/../tightenco/collect', 'aliases' => array(), diff --git a/vendor/graham-campbell/result-type/LICENSE b/vendor/graham-campbell/result-type/LICENSE index 9a8accb9..bbd75d13 100644 --- a/vendor/graham-campbell/result-type/LICENSE +++ b/vendor/graham-campbell/result-type/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020-2022 Graham Campbell +Copyright (c) 2020-2023 Graham Campbell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/graham-campbell/result-type/composer.json b/vendor/graham-campbell/result-type/composer.json index f85e1d13..c7292a08 100644 --- a/vendor/graham-campbell/result-type/composer.json +++ b/vendor/graham-campbell/result-type/composer.json @@ -12,10 +12,10 @@ ], "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9" + "phpoption/phpoption": "^1.9.1" }, "require-dev": { - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "autoload": { "psr-4": { diff --git a/vendor/laravel/framework/CHANGELOG.md b/vendor/laravel/framework/CHANGELOG.md index 421b576d..b6ae0bec 100644 --- a/vendor/laravel/framework/CHANGELOG.md +++ b/vendor/laravel/framework/CHANGELOG.md @@ -1,6 +1,97 @@ # Release Notes for 9.x -## [Unreleased](https://github.com/laravel/framework/compare/v9.49.0...9.x) +## [Unreleased](https://github.com/laravel/framework/compare/v9.52.2...9.x) + + +## [v9.52.2](https://github.com/laravel/framework/compare/v9.52.1...v9.52.2) - 2023-02-21 + +### Fixed +- Fixed `Illuminate/Collections/Arr::shuffle()` with empty array ([0c6cae0](https://github.com/laravel/framework/commit/0c6cae0ef647158b9554cad05ff39db7e7ad0d33)) + + +## [v9.52.1](https://github.com/laravel/framework/compare/v9.52.0...v9.52.1) - 2023-02-21 + +### Changed +- Use secure randomness in Arr:random and Arr:shuffle ([#46105](https://github.com/laravel/framework/pull/46105)) + + +## [v9.52.0](https://github.com/laravel/framework/compare/v9.51.0...v9.52.0) - 2023-02-14 + +### Added +- Added methods to Enumerable contract ([#46021](https://github.com/laravel/framework/pull/46021)) +- Added new mailer transport for AWS SES V2 API ([#45977](https://github.com/laravel/framework/pull/45977)) +- Add S3 temporaryUploadUrl method to AwsS3V3Adapter ([#45753](https://github.com/laravel/framework/pull/45753)) +- Add index hinting support to query builder ([#46063](https://github.com/laravel/framework/pull/46063)) +- Add mailer name to data for SentMessage and MessageSending events ([#46079](https://github.com/laravel/framework/pull/46079)) +- Added --pending option to migrate:status ([#46089](https://github.com/laravel/framework/pull/46089)) + +### Fixed +- Fixed pdo exception when rollbacking without active transaction ([#46017](https://github.com/laravel/framework/pull/46017)) +- Fix duplicated columns on select ([#46049](https://github.com/laravel/framework/pull/46049)) +- Fixes memory leak on anonymous migrations ([â„–46073](https://github.com/laravel/framework/pull/46073)) +- Fixed race condition in locks issued by the file cache driver ([#46011](https://github.com/laravel/framework/pull/46011)) + +### Changed +- Allow choosing tables to truncate in `Illuminate/Foundation/Testing/DatabaseTruncation::truncateTablesForConnection()` ([#46025](https://github.com/laravel/framework/pull/46025)) +- Update afterPromptingForMissingArguments method ([#46052](https://github.com/laravel/framework/pull/46052)) +- Accept closure in bus assertion helpers ([#46075](https://github.com/laravel/framework/pull/46075)) +- Avoid mutating the $expectedLitener between loops on Event::assertListening ([#46095](https://github.com/laravel/framework/pull/46095)) + + +## [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 diff --git a/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php b/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php index ee98e8ac..21094bf8 100644 --- a/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php +++ b/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php @@ -13,7 +13,7 @@ trait GuardHelpers /** * The currently authenticated user. * - * @var \Illuminate\Contracts\Auth\Authenticatable + * @var \Illuminate\Contracts\Auth\Authenticatable|null */ protected $user; diff --git a/vendor/laravel/framework/src/Illuminate/Cache/FileLock.php b/vendor/laravel/framework/src/Illuminate/Cache/FileLock.php new file mode 100644 index 00000000..a5638b68 --- /dev/null +++ b/vendor/laravel/framework/src/Illuminate/Cache/FileLock.php @@ -0,0 +1,16 @@ +store->add($this->name, $this->owner, $this->seconds); + } +} diff --git a/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php b/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php index 42292295..6a6feb8a 100755 --- a/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php +++ b/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Collections/Arr.php b/vendor/laravel/framework/src/Illuminate/Collections/Arr.php index 1b38fc52..69220d51 100644 --- a/vendor/laravel/framework/src/Illuminate/Collections/Arr.php +++ b/vendor/laravel/framework/src/Illuminate/Collections/Arr.php @@ -838,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)); } /** diff --git a/vendor/laravel/framework/src/Illuminate/Collections/Collection.php b/vendor/laravel/framework/src/Illuminate/Collections/Collection.php index 37aada72..e5e82bf0 100644 --- a/vendor/laravel/framework/src/Illuminate/Collections/Collection.php +++ b/vendor/laravel/framework/src/Illuminate/Collections/Collection.php @@ -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; } /** @@ -1633,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)); } diff --git a/vendor/laravel/framework/src/Illuminate/Collections/LazyCollection.php b/vendor/laravel/framework/src/Illuminate/Collections/LazyCollection.php index e5aa7978..8119b3af 100644 --- a/vendor/laravel/framework/src/Illuminate/Collections/LazyCollection.php +++ b/vendor/laravel/framework/src/Illuminate/Collections/LazyCollection.php @@ -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) { @@ -1500,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)); } /** diff --git a/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php b/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php index 7b1ca1de..0ff10188 100644 --- a/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php +++ b/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php @@ -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 */ diff --git a/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/QueueingFactory.php b/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/QueueingFactory.php index b73f3bec..2d5f51ac 100644 --- a/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/QueueingFactory.php +++ b/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/QueueingFactory.php @@ -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); diff --git a/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php b/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php index 2f316a39..14661cc7 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php @@ -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)) diff --git a/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php b/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php index 60ad9dc1..aa01f078 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php @@ -65,9 +65,13 @@ class StatusCommand extends BaseCommand $this->components->twoColumnDetail('Migration name', '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'], ]; } diff --git a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php index 65489814..4a416b86 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php @@ -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) diff --git a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Sequence.php b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Sequence.php index 7a4688bf..e523fb3e 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Sequence.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Sequence.php @@ -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) diff --git a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php index 01eaa943..ae460d37 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php index 17ec20a3..01f0c1e5 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php @@ -364,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. * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php b/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php index 66c38780..307fc2ff 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php @@ -66,6 +66,13 @@ class Migrator */ protected $paths = []; + /** + * The paths that have already been required. + * + * @var array + */ + protected static $requiredPathCache = []; + /** * The output interface implementation. * @@ -511,9 +518,15 @@ 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 method_exists($migration, '__construct') + ? $this->files->getRequire($path) + : clone $migration; + } + + return new $class; } /** diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php b/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php index ea3926ef..6f98a8ce 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php index 5540c865..e15c5564 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php @@ -36,6 +36,7 @@ class Grammar extends BaseGrammar 'aggregate', 'columns', 'from', + 'indexHint', 'joins', 'wheres', 'groups', diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php index f9733492..131f8afb 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php index 81b890b8..8bf7d39f 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php index 222a2f12..baebb93b 100755 --- a/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php @@ -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} * diff --git a/vendor/laravel/framework/src/Illuminate/Database/Query/IndexHint.php b/vendor/laravel/framework/src/Illuminate/Database/Query/IndexHint.php new file mode 100755 index 00000000..2a720a2d --- /dev/null +++ b/vendor/laravel/framework/src/Illuminate/Database/Query/IndexHint.php @@ -0,0 +1,33 @@ +type = $type; + $this->index = $index; + } +} diff --git a/vendor/laravel/framework/src/Illuminate/Database/Schema/SchemaState.php b/vendor/laravel/framework/src/Illuminate/Database/Schema/SchemaState.php index 8f998ca2..58d9c3a4 100644 --- a/vendor/laravel/framework/src/Illuminate/Database/Schema/SchemaState.php +++ b/vendor/laravel/framework/src/Illuminate/Database/Schema/SchemaState.php @@ -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) diff --git a/vendor/laravel/framework/src/Illuminate/Filesystem/AwsS3V3Adapter.php b/vendor/laravel/framework/src/Illuminate/Filesystem/AwsS3V3Adapter.php index 9c210c8f..8e908e81 100644 --- a/vendor/laravel/framework/src/Illuminate/Filesystem/AwsS3V3Adapter.php +++ b/vendor/laravel/framework/src/Illuminate/Filesystem/AwsS3V3Adapter.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php b/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php index 87606c97..55d8be1e 100644 --- a/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php +++ b/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php @@ -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. * diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Application.php b/vendor/laravel/framework/src/Illuminate/Foundation/Application.php index 5caee889..2fcc1041 100755 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Application.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Application.php @@ -38,7 +38,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '9.51.0'; + const VERSION = '9.52.4'; /** * The base path for the Laravel installation. diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeCommand.php b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeCommand.php index 94d0b668..62e82ccd 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeCommand.php @@ -137,7 +137,7 @@ class ListenerMakeCommand extends GeneratorCommand */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { - if ($this->didReceiveOptions($input)) { + if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php index 3bec9f77..dbc32855 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php @@ -245,7 +245,7 @@ class ModelMakeCommand extends GeneratorCommand */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { - if ($this->didReceiveOptions($input)) { + if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ObserverMakeCommand.php b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ObserverMakeCommand.php index 6d53265b..039cb4e2 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Console/ObserverMakeCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Console/ObserverMakeCommand.php @@ -162,7 +162,7 @@ class ObserverMakeCommand extends GeneratorCommand */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { - if ($this->didReceiveOptions($input)) { + if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php b/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php index 92bb68f8..7bc95b0e 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php @@ -221,7 +221,7 @@ class PolicyMakeCommand extends GeneratorCommand */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { - if ($this->didReceiveOptions($input)) { + if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php b/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php index 5ddccb33..f3dd30a0 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php @@ -132,7 +132,7 @@ class TestMakeCommand extends GeneratorCommand */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { - if ($this->didReceiveOptions($input)) { + if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } diff --git a/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php b/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php index 16141c0a..b3f1a14f 100644 --- a/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php +++ b/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTruncation.php @@ -80,7 +80,11 @@ trait DatabaseTruncation $connection->unsetEventDispatcher(); collect(static::$allTables[$name] ??= $connection->getDoctrineSchemaManager()->listTableNames()) - ->diff($this->exceptTables($name)) + ->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()); diff --git a/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php b/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php index 779c84c7..daa5a032 100644 --- a/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php +++ b/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php @@ -3,12 +3,14 @@ namespace Illuminate\Mail; use Aws\Ses\SesClient; +use Aws\SesV2\SesV2Client; use Closure; use Illuminate\Contracts\Mail\Factory as FactoryContract; use Illuminate\Log\LogManager; use Illuminate\Mail\Transport\ArrayTransport; use Illuminate\Mail\Transport\LogTransport; use Illuminate\Mail\Transport\SesTransport; +use Illuminate\Mail\Transport\SesV2Transport; use Illuminate\Support\Arr; use Illuminate\Support\Str; use InvalidArgumentException; @@ -154,7 +156,8 @@ class MailManager implements FactoryContract return call_user_func($this->customCreators[$transport], $config); } - if (trim($transport ?? '') === '' || ! method_exists($this, $method = 'create'.ucfirst($transport).'Transport')) { + if (trim($transport ?? '') === '' || + ! method_exists($this, $method = 'create'.ucfirst(Str::camel($transport)).'Transport')) { throw new InvalidArgumentException("Unsupported mail transport [{$transport}]."); } @@ -250,6 +253,28 @@ class MailManager implements FactoryContract ); } + /** + * Create an instance of the Symfony Amazon SES V2 Transport driver. + * + * @param array $config + * @return \Illuminate\Mail\Transport\Se2VwTransport + */ + protected function createSesV2Transport(array $config) + { + $config = array_merge( + $this->app['config']->get('services.ses', []), + ['version' => 'latest'], + $config + ); + + $config = Arr::except($config, ['transport']); + + return new SesV2Transport( + new SesV2Client($this->addSesCredentials($config)), + $config['options'] ?? [] + ); + } + /** * Add the SES credentials to the configuration array. * diff --git a/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php b/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php index 4a253cf2..bfb188c7 100755 --- a/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php +++ b/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php @@ -253,6 +253,8 @@ class Mailer implements MailerContract, MailQueueContract return $this->sendMailable($view); } + $data['mailer'] = $this->name; + // First we need to parse the view, which could either be a string or an array // containing both an HTML and plain text versions of the view which should // be used when sending an e-mail. We will extract both of them out here. diff --git a/vendor/laravel/framework/src/Illuminate/Mail/Message.php b/vendor/laravel/framework/src/Illuminate/Mail/Message.php index 88e83eee..a0420b5a 100755 --- a/vendor/laravel/framework/src/Illuminate/Mail/Message.php +++ b/vendor/laravel/framework/src/Illuminate/Mail/Message.php @@ -315,7 +315,7 @@ class Message /** * Attach in-memory data as an attachment. * - * @param string $data + * @param string|resource $data * @param string $name * @param array $options * @return $this @@ -366,7 +366,7 @@ class Message /** * Embed in-memory data in the message and get the CID. * - * @param string $data + * @param string|resource $data * @param string $name * @param string|null $contentType * @return string diff --git a/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php b/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php index d6a64da8..9db7734c 100644 --- a/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php +++ b/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesTransport.php @@ -88,16 +88,6 @@ class SesTransport extends AbstractTransport $message->getOriginalMessage()->getHeaders()->addHeader('X-SES-Message-ID', $messageId); } - /** - * Get the string representation of the transport. - * - * @return string - */ - public function __toString(): string - { - return 'ses'; - } - /** * Get the Amazon SES client for the SesTransport instance. * @@ -128,4 +118,14 @@ class SesTransport extends AbstractTransport { return $this->options = $options; } + + /** + * Get the string representation of the transport. + * + * @return string + */ + public function __toString(): string + { + return 'ses'; + } } diff --git a/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesV2Transport.php b/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesV2Transport.php new file mode 100644 index 00000000..4157570e --- /dev/null +++ b/vendor/laravel/framework/src/Illuminate/Mail/Transport/SesV2Transport.php @@ -0,0 +1,135 @@ +ses = $ses; + $this->options = $options; + + parent::__construct(); + } + + /** + * {@inheritDoc} + */ + protected function doSend(SentMessage $message): void + { + $options = $this->options; + + if ($message->getOriginalMessage() instanceof Message) { + foreach ($message->getOriginalMessage()->getHeaders()->all() as $header) { + if ($header instanceof MetadataHeader) { + $options['Tags'][] = ['Name' => $header->getKey(), 'Value' => $header->getValue()]; + } + } + } + + try { + $result = $this->ses->sendEmail( + array_merge( + $options, [ + 'ReplyToAddresses' => [$message->getEnvelope()->getSender()->toString()], + 'Destination' => [ + 'ToAddresses' => collect($message->getEnvelope()->getRecipients()) + ->map + ->toString() + ->values() + ->all(), + ], + 'Content' => [ + 'Raw' => [ + 'Data' => $message->toString(), + ], + ], + ] + ) + ); + } catch (AwsException $e) { + $reason = $e->getAwsErrorMessage() ?? $e->getMessage(); + + throw new Exception( + sprintf('Request to AWS SES V2 API failed. Reason: %s.', $reason), + is_int($e->getCode()) ? $e->getCode() : 0, + $e + ); + } + + $messageId = $result->get('MessageId'); + + $message->getOriginalMessage()->getHeaders()->addHeader('X-Message-ID', $messageId); + $message->getOriginalMessage()->getHeaders()->addHeader('X-SES-Message-ID', $messageId); + } + + /** + * Get the Amazon SES V2 client for the SesV2Transport instance. + * + * @return \Aws\SesV2\SesV2Client + */ + public function ses() + { + return $this->ses; + } + + /** + * Get the transmission options being used by the transport. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Set the transmission options being used by the transport. + * + * @param array $options + * @return array + */ + public function setOptions(array $options) + { + return $this->options = $options; + } + + /** + * Get the string representation of the transport. + * + * @return string + */ + public function __toString(): string + { + return 'ses-v2'; + } +} diff --git a/vendor/laravel/framework/src/Illuminate/Routing/ViewController.php b/vendor/laravel/framework/src/Illuminate/Routing/ViewController.php index bd03c5f1..f5b5525d 100644 --- a/vendor/laravel/framework/src/Illuminate/Routing/ViewController.php +++ b/vendor/laravel/framework/src/Illuminate/Routing/ViewController.php @@ -27,7 +27,7 @@ class ViewController extends Controller /** * Invoke the controller method. * - * @param array ...$args + * @param mixed ...$args * @return \Illuminate\Http\Response */ public function __invoke(...$args) diff --git a/vendor/laravel/framework/src/Illuminate/Support/Facades/Blade.php b/vendor/laravel/framework/src/Illuminate/Support/Facades/Blade.php index a58b2142..ff537e4d 100755 --- a/vendor/laravel/framework/src/Illuminate/Support/Facades/Blade.php +++ b/vendor/laravel/framework/src/Illuminate/Support/Facades/Blade.php @@ -13,7 +13,7 @@ namespace Illuminate\Support\Facades; * @method static void extend(callable $compiler) * @method static array getExtensions() * @method static void if(string $name, callable $callback) - * @method static bool check(string $name, array ...$parameters) + * @method static bool check(string $name, mixed ...$parameters) * @method static void component(string $class, string|null $alias = null, string $prefix = '') * @method static void components(array $components, string $prefix = '') * @method static array getClassComponentAliases() diff --git a/vendor/laravel/framework/src/Illuminate/Support/Facades/Bus.php b/vendor/laravel/framework/src/Illuminate/Support/Facades/Bus.php index 986784c5..62ac0588 100644 --- a/vendor/laravel/framework/src/Illuminate/Support/Facades/Bus.php +++ b/vendor/laravel/framework/src/Illuminate/Support/Facades/Bus.php @@ -22,14 +22,14 @@ use Illuminate\Support\Testing\Fakes\BusFake; * @method static \Illuminate\Bus\Dispatcher map(array $map) * @method static void except(array|string $jobsToDispatch) * @method static void assertDispatched(string|\Closure $command, callable|int|null $callback = null) - * @method static void assertDispatchedTimes(string $command, int $times = 1) + * @method static void assertDispatchedTimes(string|\Closure $command, int $times = 1) * @method static void assertNotDispatched(string|\Closure $command, callable|null $callback = null) * @method static void assertNothingDispatched() * @method static void assertDispatchedSync(string|\Closure $command, callable|int|null $callback = null) - * @method static void assertDispatchedSyncTimes(string $command, int $times = 1) + * @method static void assertDispatchedSyncTimes(string|\Closure $command, int $times = 1) * @method static void assertNotDispatchedSync(string|\Closure $command, callable|null $callback = null) * @method static void assertDispatchedAfterResponse(string|\Closure $command, callable|int|null $callback = null) - * @method static void assertDispatchedAfterResponseTimes(string $command, int $times = 1) + * @method static void assertDispatchedAfterResponseTimes(string|\Closure $command, int $times = 1) * @method static void assertNotDispatchedAfterResponse(string|\Closure $command, callable|null $callback = null) * @method static void assertChained(array $expectedChain) * @method static void assertDispatchedWithoutChain(string|\Closure $command, callable|null $callback = null) diff --git a/vendor/laravel/framework/src/Illuminate/Support/Facades/Storage.php b/vendor/laravel/framework/src/Illuminate/Support/Facades/Storage.php index 0d13bb50..f8fcddd2 100644 --- a/vendor/laravel/framework/src/Illuminate/Support/Facades/Storage.php +++ b/vendor/laravel/framework/src/Illuminate/Support/Facades/Storage.php @@ -59,6 +59,7 @@ use Illuminate\Filesystem\Filesystem; * @method static string url(string $path) * @method static bool providesTemporaryUrls() * @method static string temporaryUrl(string $path, \DateTimeInterface $expiration, array $options = []) + * @method static array temporaryUploadUrl(string $path, \DateTimeInterface $expiration, array $options = []) * @method static \League\Flysystem\FilesystemOperator getDriver() * @method static \League\Flysystem\FilesystemAdapter getAdapter() * @method static array getConfig() diff --git a/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/BusFake.php b/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/BusFake.php index 21bd822d..9da1fac7 100644 --- a/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/BusFake.php +++ b/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/BusFake.php @@ -127,15 +127,21 @@ class BusFake implements QueueingDispatcher /** * Assert if a job was pushed a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedTimes($command, $times = 1) { - $count = $this->dispatched($command)->count() + - $this->dispatchedAfterResponse($command)->count() + - $this->dispatchedSync($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatched($command, $callback)->count() + + $this->dispatchedAfterResponse($command, $callback)->count() + + $this->dispatchedSync($command, $callback)->count(); PHPUnit::assertSame( $times, $count, @@ -200,13 +206,19 @@ class BusFake implements QueueingDispatcher /** * Assert if a job was pushed synchronously a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedSyncTimes($command, $times = 1) { - $count = $this->dispatchedSync($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatchedSync($command, $callback)->count(); PHPUnit::assertSame( $times, $count, @@ -259,13 +271,19 @@ class BusFake implements QueueingDispatcher /** * Assert if a job was pushed after the response was sent a number of times. * - * @param string $command + * @param string|\Closure $command * @param int $times * @return void */ public function assertDispatchedAfterResponseTimes($command, $times = 1) { - $count = $this->dispatchedAfterResponse($command)->count(); + $callback = null; + + if ($command instanceof Closure) { + [$command, $callback] = [$this->firstClosureParameterType($command), $command]; + } + + $count = $this->dispatchedAfterResponse($command, $callback)->count(); PHPUnit::assertSame( $times, $count, diff --git a/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/EventFake.php b/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/EventFake.php index 2a102afb..f1e46551 100644 --- a/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/EventFake.php +++ b/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/EventFake.php @@ -85,21 +85,23 @@ class EventFake implements Dispatcher $actualListener = (new ReflectionFunction($listenerClosure)) ->getStaticVariables()['listener']; + $normalizedListener = $expectedListener; + if (is_string($actualListener) && Str::contains($actualListener, '@')) { $actualListener = Str::parseCallback($actualListener); if (is_string($expectedListener)) { if (Str::contains($expectedListener, '@')) { - $expectedListener = Str::parseCallback($expectedListener); + $normalizedListener = Str::parseCallback($expectedListener); } else { - $expectedListener = [$expectedListener, 'handle']; + $normalizedListener = [$expectedListener, 'handle']; } } } - if ($actualListener === $expectedListener || + if ($actualListener === $normalizedListener || ($actualListener instanceof Closure && - $expectedListener === Closure::class)) { + $normalizedListener === Closure::class)) { PHPUnit::assertTrue(true); return; diff --git a/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php b/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php index 630fbb87..3fa40418 100644 --- a/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php +++ b/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php @@ -1682,7 +1682,7 @@ class TestResponse implements ArrayAccess * Proxy isset() checks to the underlying base response. * * @param string $key - * @return mixed + * @return bool */ public function __isset($key) { diff --git a/vendor/laravel/framework/src/Illuminate/Translation/MessageSelector.php b/vendor/laravel/framework/src/Illuminate/Translation/MessageSelector.php index 37c9b31f..9f6b74db 100755 --- a/vendor/laravel/framework/src/Illuminate/Translation/MessageSelector.php +++ b/vendor/laravel/framework/src/Illuminate/Translation/MessageSelector.php @@ -89,9 +89,9 @@ class MessageSelector */ private function stripConditions($segments) { - return collect($segments)->map(function ($part) { - return preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part); - })->all(); + return collect($segments) + ->map(fn ($part) => preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part)) + ->all(); } /** diff --git a/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php b/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php index bf4f43d7..9edbc5ce 100644 --- a/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php +++ b/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php @@ -721,7 +721,7 @@ class BladeCompiler extends Compiler implements CompilerInterface * Check the result of a condition. * * @param string $name - * @param array ...$parameters + * @param mixed ...$parameters * @return bool */ public function check($name, ...$parameters) diff --git a/vendor/laravel/tinker/src/Console/TinkerCommand.php b/vendor/laravel/tinker/src/Console/TinkerCommand.php index 9c12158b..07ad30da 100644 --- a/vendor/laravel/tinker/src/Console/TinkerCommand.php +++ b/vendor/laravel/tinker/src/Console/TinkerCommand.php @@ -131,6 +131,10 @@ class TinkerCommand extends Command $casters['Illuminate\Database\Eloquent\Model'] = 'Laravel\Tinker\TinkerCaster::castModel'; } + if (class_exists('Illuminate\Process\ProcessResult')) { + $casters['Illuminate\Process\ProcessResult'] = 'Laravel\Tinker\TinkerCaster::castProcessResult'; + } + if (class_exists('Illuminate\Foundation\Application')) { $casters['Illuminate\Foundation\Application'] = 'Laravel\Tinker\TinkerCaster::castApplication'; } diff --git a/vendor/laravel/tinker/src/TinkerCaster.php b/vendor/laravel/tinker/src/TinkerCaster.php index a5c04dee..8b08aa04 100644 --- a/vendor/laravel/tinker/src/TinkerCaster.php +++ b/vendor/laravel/tinker/src/TinkerCaster.php @@ -94,6 +94,22 @@ class TinkerCaster ]; } + /** + * Get an array representing the properties of a process result. + * + * @param \Illuminate\Process\ProcessResult $result + * @return array + */ + public static function castProcessResult($result) + { + return [ + Caster::PREFIX_VIRTUAL.'output' => $result->output(), + Caster::PREFIX_VIRTUAL.'errorOutput' => $result->errorOutput(), + Caster::PREFIX_VIRTUAL.'exitCode' => $result->exitCode(), + Caster::PREFIX_VIRTUAL.'successful' => $result->successful(), + ]; + } + /** * Get an array representing the properties of a model. * diff --git a/vendor/league/commonmark/CHANGELOG.md b/vendor/league/commonmark/CHANGELOG.md index 1a246b01..cd2d341c 100644 --- a/vendor/league/commonmark/CHANGELOG.md +++ b/vendor/league/commonmark/CHANGELOG.md @@ -6,6 +6,12 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi ## [Unreleased][unreleased] +## [2.3.9] - 2023-02-15 + +### Fixed + +- Fixed autolink extension not detecting some URIs with underscores (#956) + ## [2.3.8] - 2022-12-10 ### Fixed @@ -512,7 +518,8 @@ No changes were introduced since the previous release. - Alternative 1: Use `CommonMarkConverter` or `GithubFlavoredMarkdownConverter` if you don't need to customize the environment - Alternative 2: Instantiate a new `Environment` and add the necessary extensions yourself -[unreleased]: https://github.com/thephpleague/commonmark/compare/2.3.8...main +[unreleased]: https://github.com/thephpleague/commonmark/compare/2.3.9...main +[2.3.9]: https://github.com/thephpleague/commonmark/compare/2.3.8...2.3.9 [2.3.8]: https://github.com/thephpleague/commonmark/compare/2.3.7...2.3.8 [2.3.7]: https://github.com/thephpleague/commonmark/compare/2.3.6...2.3.7 [2.3.6]: https://github.com/thephpleague/commonmark/compare/2.3.5...2.3.6 diff --git a/vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php b/vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php index f2a140a8..de5c111e 100644 --- a/vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php +++ b/vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php @@ -72,6 +72,7 @@ final class AttributesHelper continue; } + /** @psalm-suppress PossiblyUndefinedArrayOffset */ [$name, $value] = \explode('=', $attribute, 2); $first = $value[0]; diff --git a/vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php b/vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php index 7fad7f55..6b4290a9 100644 --- a/vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php +++ b/vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php @@ -22,16 +22,22 @@ final class UrlAutolinkParser implements InlineParserInterface { private const ALLOWED_AFTER = [null, ' ', "\t", "\n", "\x0b", "\x0c", "\x0d", '*', '_', '~', '(']; - // RegEx adapted from https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Validator/Constraints/UrlValidator.php + // RegEx adapted from https://github.com/symfony/symfony/blob/6.3/src/Symfony/Component/Validator/Constraints/UrlValidator.php private const REGEX = '~ ( # Must start with a supported scheme + auth, or "www" (?: - (?:%s):// # protocol - (?:([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth + (?:%s):// # protocol + (?:(?:(?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+)@)? # basic auth |www\.) (?: - (?:[\pL\pN\pS\-\.])+(?:\.?(?:[\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name + (?: + (?:xn--[a-z0-9-]++\.)*+xn--[a-z0-9-]++ # a domain name using punycode + | + (?:[\pL\pN\pS\pM\-\_]++\.)+[\pL\pN\pM]++ # a multi-level domain name + | + [a-z0-9\-\_]++ # a single-level domain name + )\.? | # or \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address | # or @@ -40,9 +46,9 @@ final class UrlAutolinkParser implements InlineParserInterface \] # an IPv6 address ) (?::[0-9]+)? # a port (optional) - (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path - (?:\? (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional) - (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional) + (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path + (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional) + (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional) )~ixu'; /** diff --git a/vendor/league/commonmark/src/Node/Query/AndExpr.php b/vendor/league/commonmark/src/Node/Query/AndExpr.php index ceb441a4..d2cd6153 100644 --- a/vendor/league/commonmark/src/Node/Query/AndExpr.php +++ b/vendor/league/commonmark/src/Node/Query/AndExpr.php @@ -31,7 +31,7 @@ final class AndExpr implements ExpressionInterface */ public function __construct(callable ...$expressions) { - $this->conditions = $expressions; + $this->conditions = \array_values($expressions); } /** diff --git a/vendor/league/commonmark/src/Node/Query/OrExpr.php b/vendor/league/commonmark/src/Node/Query/OrExpr.php index df2adef7..b0baad8c 100644 --- a/vendor/league/commonmark/src/Node/Query/OrExpr.php +++ b/vendor/league/commonmark/src/Node/Query/OrExpr.php @@ -31,7 +31,7 @@ final class OrExpr implements ExpressionInterface */ public function __construct(callable ...$expressions) { - $this->conditions = $expressions; + $this->conditions = \array_values($expressions); } /** diff --git a/vendor/phpoption/phpoption/composer.json b/vendor/phpoption/phpoption/composer.json index 0106c977..82a83005 100644 --- a/vendor/phpoption/phpoption/composer.json +++ b/vendor/phpoption/phpoption/composer.json @@ -19,8 +19,8 @@ "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8", - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "autoload": { "psr-4": { diff --git a/vendor/phpunit/php-code-coverage/ChangeLog.md b/vendor/phpunit/php-code-coverage/ChangeLog.md index cdf28e0a..35ef8119 100644 --- a/vendor/phpunit/php-code-coverage/ChangeLog.md +++ b/vendor/phpunit/php-code-coverage/ChangeLog.md @@ -2,6 +2,12 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. +## [9.2.25] - 2023-02-25 + +### Fixed + +* [#981](https://github.com/sebastianbergmann/php-code-coverage/issues/981): `CodeUnitFindingVisitor` does not support DNF types + ## [9.2.24] - 2023-01-26 ### Changed @@ -464,6 +470,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt * This component is no longer supported on PHP 7.1 +[9.2.25]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.24...9.2.25 [9.2.24]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.23...9.2.24 [9.2.23]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.22...9.2.23 [9.2.22]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.21...9.2.22 diff --git a/vendor/phpunit/php-code-coverage/composer.json b/vendor/phpunit/php-code-coverage/composer.json index b09bd647..6db6936f 100644 --- a/vendor/phpunit/php-code-coverage/composer.json +++ b/vendor/phpunit/php-code-coverage/composer.json @@ -32,7 +32,7 @@ "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", "sebastian/code-unit-reverse-lookup": "^2.0.2", diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php index 6672a6ea..b44870b5 100644 --- a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php @@ -117,7 +117,7 @@ final class Dashboard extends Renderer private function coverageDistribution(array $classes): array { $result = [ - 'class' => [ + 'class' => [ '0%' => 0, '0-10%' => 0, '10-20%' => 0, diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php index 69fd8b1d..101a9ada 100644 --- a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php @@ -284,19 +284,19 @@ final class File extends Renderer $buffer .= $this->renderItemTemplate( $template, [ - 'name' => $this->abbreviateClassName($name), - 'numClasses' => $numClasses, - 'numTestedClasses' => $numTestedClasses, - 'numMethods' => $numMethods, - 'numTestedMethods' => $numTestedMethods, - 'linesExecutedPercent' => Percentage::fromFractionAndTotal( + 'name' => $this->abbreviateClassName($name), + 'numClasses' => $numClasses, + 'numTestedClasses' => $numTestedClasses, + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => Percentage::fromFractionAndTotal( $item['executedLines'], $item['executableLines'], )->asFloat(), - 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, - 'numExecutedLines' => $item['executedLines'], - 'numExecutableLines' => $item['executableLines'], - 'branchesExecutedPercent' => Percentage::fromFractionAndTotal( + 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'branchesExecutedPercent' => Percentage::fromFractionAndTotal( $item['executedBranches'], $item['executableBranches'], )->asFloat(), @@ -307,14 +307,14 @@ final class File extends Renderer $item['executedPaths'], $item['executablePaths'] )->asFloat(), - 'pathsExecutedPercentAsString' => $pathsExecutedPercentAsString, - 'numExecutedPaths' => $item['executedPaths'], - 'numExecutablePaths' => $item['executablePaths'], - 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), - 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), - 'testedClassesPercent' => $testedClassesPercentage->asFloat(), - 'testedClassesPercentAsString' => $testedClassesPercentage->asString(), - 'crap' => $item['crap'], + 'pathsExecutedPercentAsString' => $pathsExecutedPercentAsString, + 'numExecutedPaths' => $item['executedPaths'], + 'numExecutablePaths' => $item['executablePaths'], + 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), + 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), + 'testedClassesPercent' => $testedClassesPercentage->asFloat(), + 'testedClassesPercentAsString' => $testedClassesPercentage->asString(), + 'crap' => $item['crap'], ] ); @@ -384,7 +384,7 @@ final class File extends Renderer return $this->renderItemTemplate( $template, [ - 'name' => sprintf( + 'name' => sprintf( '%s%s', $indent, $item['startLine'], diff --git a/vendor/phpunit/php-code-coverage/src/StaticAnalysis/CodeUnitFindingVisitor.php b/vendor/phpunit/php-code-coverage/src/StaticAnalysis/CodeUnitFindingVisitor.php index 8a2003fa..cb85cd61 100644 --- a/vendor/phpunit/php-code-coverage/src/StaticAnalysis/CodeUnitFindingVisitor.php +++ b/vendor/phpunit/php-code-coverage/src/StaticAnalysis/CodeUnitFindingVisitor.php @@ -26,6 +26,7 @@ use PhpParser\Node\Stmt\Function_; use PhpParser\Node\Stmt\Interface_; use PhpParser\Node\Stmt\Trait_; use PhpParser\Node\UnionType; +use PhpParser\NodeAbstract; use PhpParser\NodeTraverser; use PhpParser\NodeVisitorAbstract; use SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor; @@ -180,8 +181,12 @@ final class CodeUnitFindingVisitor extends NodeVisitorAbstract return '?' . $type->type; } - if ($type instanceof UnionType || $type instanceof IntersectionType) { - return $this->unionOrIntersectionAsString($type); + if ($type instanceof UnionType) { + return $this->unionTypeAsString($type); + } + + if ($type instanceof IntersectionType) { + return $this->intersectionTypeAsString($type); } return $type->toString(); @@ -298,29 +303,43 @@ final class CodeUnitFindingVisitor extends NodeVisitorAbstract return trim(rtrim($namespacedName, $name), '\\'); } - /** - * @psalm-param UnionType|IntersectionType $type - */ - private function unionOrIntersectionAsString(ComplexType $type): string + private function unionTypeAsString(UnionType $node): string { - if ($type instanceof UnionType) { - $separator = '|'; - } else { - $separator = '&'; - } - $types = []; - foreach ($type->types as $_type) { - if ($_type instanceof Name) { - $types[] = $_type->toCodeString(); - } else { - assert($_type instanceof Identifier); + foreach ($node->types as $type) { + if ($type instanceof IntersectionType) { + $types[] = '(' . $this->intersectionTypeAsString($type) . ')'; - $types[] = $_type->toString(); + continue; } + + $types[] = $this->typeAsString($type); } - return implode($separator, $types); + return implode('|', $types); + } + + private function intersectionTypeAsString(IntersectionType $node): string + { + $types = []; + + foreach ($node->types as $type) { + $types[] = $this->typeAsString($type); + } + + return implode('&', $types); + } + + /** + * @psalm-param Identifier|Name $node $node + */ + private function typeAsString(NodeAbstract $node): string + { + if ($node instanceof Name) { + return $node->toCodeString(); + } + + return $node->toString(); } } diff --git a/vendor/phpunit/php-code-coverage/src/Version.php b/vendor/phpunit/php-code-coverage/src/Version.php index 8d45b6c6..7feb0a9c 100644 --- a/vendor/phpunit/php-code-coverage/src/Version.php +++ b/vendor/phpunit/php-code-coverage/src/Version.php @@ -22,7 +22,7 @@ final class Version public static function id(): string { if (self::$version === null) { - self::$version = (new VersionId('9.2.24', dirname(__DIR__)))->getVersion(); + self::$version = (new VersionId('9.2.25', dirname(__DIR__)))->getVersion(); } return self::$version; diff --git a/vendor/phpunit/phpunit/ChangeLog-8.5.md b/vendor/phpunit/phpunit/ChangeLog-8.5.md index 6485b8e5..a65e6a61 100644 --- a/vendor/phpunit/phpunit/ChangeLog-8.5.md +++ b/vendor/phpunit/phpunit/ChangeLog-8.5.md @@ -2,6 +2,12 @@ All notable changes of the PHPUnit 8.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. +## [8.5.33] - 2023-02-27 + +### Fixed + +* [#5186](https://github.com/sebastianbergmann/phpunit/issues/5186): SBOM does not validate + ## [8.5.32] - 2023-01-26 ### Fixed @@ -262,6 +268,7 @@ All notable changes of the PHPUnit 8.5 release series are documented in this fil * [#3967](https://github.com/sebastianbergmann/phpunit/issues/3967): Cannot double interface that extends interface that extends `\Throwable` * [#3968](https://github.com/sebastianbergmann/phpunit/pull/3968): Test class run in a separate PHP process are passing when `exit` called inside +[8.5.33]: https://github.com/sebastianbergmann/phpunit/compare/8.5.32...8.5.33 [8.5.32]: https://github.com/sebastianbergmann/phpunit/compare/8.5.31...8.5.32 [8.5.31]: https://github.com/sebastianbergmann/phpunit/compare/8.5.30...8.5.31 [8.5.30]: https://github.com/sebastianbergmann/phpunit/compare/8.5.29...8.5.30 diff --git a/vendor/phpunit/phpunit/ChangeLog-9.6.md b/vendor/phpunit/phpunit/ChangeLog-9.6.md index 2491e303..df27bce7 100644 --- a/vendor/phpunit/phpunit/ChangeLog-9.6.md +++ b/vendor/phpunit/phpunit/ChangeLog-9.6.md @@ -2,6 +2,12 @@ All notable changes of the PHPUnit 9.6 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. +## [9.6.4] - 2023-02-27 + +### Fixed + +* [#5186](https://github.com/sebastianbergmann/phpunit/issues/5186): SBOM does not validate + ## [9.6.3] - 2023-02-04 ### Fixed @@ -19,7 +25,7 @@ All notable changes of the PHPUnit 9.6 release series are documented in this fil ### Fixed * [#5073](https://github.com/sebastianbergmann/phpunit/issues/5073): `--no-extensions` CLI option only prevents extension PHARs from being loaded -* [#5160](https://github.com/sebastianbergmann/phpunit/issues/5160): PHPUnit 9.6 misses deprecations for assertions and constraints removed in PHPUnit 10 +* [#5160](https://github.com/sebastianbergmann/phpunit/issues/5160): Deprecate `assertClassHasAttribute()`, `assertClassNotHasAttribute()`, `assertClassHasStaticAttribute()`, `assertClassNotHasStaticAttribute()`, `assertObjectHasAttribute()`, `assertObjectNotHasAttribute()`, `classHasAttribute()`, `classHasStaticAttribute()`, and `objectHasAttribute()` ## [9.6.0] - 2023-02-03 @@ -30,6 +36,7 @@ All notable changes of the PHPUnit 9.6 release series are documented in this fil * [#5064](https://github.com/sebastianbergmann/phpunit/issues/5064): Deprecate `PHPUnit\Framework\TestCase::getMockClass()` * [#5132](https://github.com/sebastianbergmann/phpunit/issues/5132): Deprecate `Test` suffix for abstract test case classes +[9.6.4]: https://github.com/sebastianbergmann/phpunit/compare/9.6.3...9.6.4 [9.6.3]: https://github.com/sebastianbergmann/phpunit/compare/9.6.2...9.6.3 [9.6.2]: https://github.com/sebastianbergmann/phpunit/compare/9.6.1...9.6.2 [9.6.1]: https://github.com/sebastianbergmann/phpunit/compare/9.6.0...9.6.1 diff --git a/vendor/phpunit/phpunit/SECURITY.md b/vendor/phpunit/phpunit/SECURITY.md index dcc15385..965e5ed2 100644 --- a/vendor/phpunit/phpunit/SECURITY.md +++ b/vendor/phpunit/phpunit/SECURITY.md @@ -1,11 +1,33 @@ # Security Policy -PHPUnit is a framework for writing as well as a commandline tool for running tests. Writing and running tests is a development-time activity. There is no reason why PHPUnit should be installed on a webserver. +If you believe you have found a security vulnerability in PHPUnit, please report it to us through coordinated disclosure. + +**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.** + +Instead, please email `sebastian@phpunit.de`. + +Please include as much of the information listed below as you can to help us better understand and resolve the issue: + +* The type of issue +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +## Web Context + +PHPUnit is a framework for writing as well as a command-line tool for running tests. Writing and running tests is a development-time activity. There is no reason why PHPUnit should be installed on a webserver and/or in a production environment. **If you upload PHPUnit to a webserver then your deployment process is broken. On a more general note, if your `vendor` directory is publicly accessible on your webserver then your deployment process is also broken.** Please note that if you upload PHPUnit to a webserver "bad things" may happen. [You have been warned.](https://thephp.cc/articles/phpunit-a-security-risk) -## Security Contact Information +PHPUnit is developed with a focus on development environments and the command-line. No specific testing or hardening with regard to using PHPUnit in an HTTP or web context or with untrusted input data is performed. PHPUnit might also contain functionality that intentionally exposes internal application data for debugging purposes. -After the above, if you still would like to report a security vulnerability, please email `sebastian@phpunit.de`. +If PHPUnit is used in a web application, the application developer is responsible for filtering inputs or escaping outputs as necessary and for verifying that the used functionality is safe for use within the intended context. + +Vulnerabilities specific to the use outside a development context will be fixed as applicable, provided that the fix does not have an averse effect on the primary use case for development purposes. diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php index 70de3024..7fda90ba 100644 --- a/vendor/phpunit/phpunit/src/Runner/Version.php +++ b/vendor/phpunit/phpunit/src/Runner/Version.php @@ -41,7 +41,7 @@ final class Version } if (self::$version === '') { - self::$version = (new VersionId('9.6.3', dirname(__DIR__, 2)))->getVersion(); + self::$version = (new VersionId('9.6.4', dirname(__DIR__, 2)))->getVersion(); } return self::$version; diff --git a/vendor/psr/simple-cache/composer.json b/vendor/psr/simple-cache/composer.json index a520e7d5..f307a845 100644 --- a/vendor/psr/simple-cache/composer.json +++ b/vendor/psr/simple-cache/composer.json @@ -19,7 +19,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } } } diff --git a/vendor/psr/simple-cache/src/CacheInterface.php b/vendor/psr/simple-cache/src/CacheInterface.php index cb05d2f1..671e340c 100644 --- a/vendor/psr/simple-cache/src/CacheInterface.php +++ b/vendor/psr/simple-cache/src/CacheInterface.php @@ -15,7 +15,7 @@ interface CacheInterface * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function get(string $key, mixed $default = null); + public function get(string $key, mixed $default = null): mixed; /** * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time. @@ -31,7 +31,7 @@ interface CacheInterface * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null); + public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool; /** * Delete an item from the cache by its unique key. @@ -43,14 +43,14 @@ interface CacheInterface * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function delete(string $key); + public function delete(string $key): bool; /** * Wipes clean the entire cache's keys. * * @return bool True on success and false on failure. */ - public function clear(); + public function clear(): bool; /** * Obtains multiple cache items by their unique keys. @@ -64,7 +64,7 @@ interface CacheInterface * MUST be thrown if $keys is neither an array nor a Traversable, * or if any of the $keys are not a legal value. */ - public function getMultiple(iterable $keys, mixed $default = null); + public function getMultiple(iterable $keys, mixed $default = null): iterable; /** * Persists a set of key => value pairs in the cache, with an optional TTL. @@ -80,7 +80,7 @@ interface CacheInterface * MUST be thrown if $values is neither an array nor a Traversable, * or if any of the $values are not a legal value. */ - public function setMultiple(iterable $values, null|int|\DateInterval $ttl = null); + public function setMultiple(iterable $values, null|int|\DateInterval $ttl = null): bool; /** * Deletes multiple cache items in a single operation. @@ -93,7 +93,7 @@ interface CacheInterface * MUST be thrown if $keys is neither an array nor a Traversable, * or if any of the $keys are not a legal value. */ - public function deleteMultiple(iterable $keys); + public function deleteMultiple(iterable $keys): bool; /** * Determines whether an item is present in the cache. @@ -110,5 +110,5 @@ interface CacheInterface * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function has(string $key); + public function has(string $key): bool; } diff --git a/vendor/spatie/backtrace/.php-cs-fixer.dist.php b/vendor/spatie/backtrace/.php-cs-fixer.dist.php deleted file mode 100644 index 3de28fd4..00000000 --- a/vendor/spatie/backtrace/.php-cs-fixer.dist.php +++ /dev/null @@ -1,40 +0,0 @@ -in([ - __DIR__ . '/src', - __DIR__ . '/tests', - ]) - ->name('*.php') - ->notName('*.blade.php') - ->ignoreDotFiles(true) - ->ignoreVCS(true); - -return (new PhpCsFixer\Config()) - ->setRules([ - '@PSR2' => true, - 'array_syntax' => ['syntax' => 'short'], - 'ordered_imports' => ['sort_algorithm' => 'alpha'], - 'no_unused_imports' => true, - 'not_operator_with_successor_space' => true, - 'trailing_comma_in_multiline' => true, - 'phpdoc_scalar' => true, - 'unary_operator_spaces' => true, - 'binary_operator_spaces' => true, - 'blank_line_before_statement' => [ - 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], - ], - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_var_without_name' => true, - 'class_attributes_separation' => [ - 'elements' => [ - 'method' => 'one', - ], - ], - 'method_argument_space' => [ - 'on_multiline' => 'ensure_fully_multiline', - 'keep_multiple_spaces_after_comma' => true, - ], - 'single_trait_insert_per_statement' => true, - ]) - ->setFinder($finder); diff --git a/vendor/spatie/backtrace/CHANGELOG.md b/vendor/spatie/backtrace/CHANGELOG.md deleted file mode 100644 index 7f5c9dc5..00000000 --- a/vendor/spatie/backtrace/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -All notable changes to `backtrace` will be documented in this file - -## 1.2.1 - 2021-11-09 - -- Add a return typehint (#4) - -## 1.2.0 - 2021-05-19 - -- add `firstApplicationFrameIndex` - -## 1.1.0 - 2021-01-29 - -- add `snippetProperties` - -## 1.0.1 - 2021-01-27 - -- add support for PHP 7.3 - -## 1.0.0 - 2020-11-24 - -- initial release diff --git a/vendor/spatie/backtrace/README.md b/vendor/spatie/backtrace/README.md index 9df948e0..6caae216 100644 --- a/vendor/spatie/backtrace/README.md +++ b/vendor/spatie/backtrace/README.md @@ -1,3 +1,6 @@ + +[](https://supportukrainenow.org) + # A better PHP backtrace [![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/backtrace.svg?style=flat-square)](https://packagist.org/packages/spatie/backtrace) @@ -101,7 +104,7 @@ $frames = Backtrace::create() With this code, all frames before the frame that concerns `MyClass` will have been filtered out. -Alternatively, you can use the `offSet` method, which will skip the given number of frames. In this example the first 2 frames will not end up in `$frames`. +Alternatively, you can use the `offset` method, which will skip the given number of frames. In this example the first 2 frames will not end up in `$frames`. ```php $frames = Spatie\Backtrace\Backtrace::create() @@ -141,7 +144,7 @@ Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed re ## Contributing -Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. +Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. ## Security Vulnerabilities diff --git a/vendor/spatie/backtrace/src/Backtrace.php b/vendor/spatie/backtrace/src/Backtrace.php index c9007316..b5e3ca62 100644 --- a/vendor/spatie/backtrace/src/Backtrace.php +++ b/vendor/spatie/backtrace/src/Backtrace.php @@ -61,7 +61,7 @@ class Backtrace public function applicationPath(string $applicationPath): self { - $this->applicationPath = $applicationPath; + $this->applicationPath = rtrim($applicationPath, '/'); return $this; } diff --git a/vendor/spiral/core/composer.json b/vendor/spiral/core/composer.json index 723f9fb4..2a6671c7 100644 --- a/vendor/spiral/core/composer.json +++ b/vendor/spiral/core/composer.json @@ -31,9 +31,9 @@ "psr/container": "^1.1|^2.0" }, "require-dev": { - "phpunit/phpunit": "^9.5.20", "mockery/mockery": "^1.5", - "vimeo/psalm": "^4.27" + "phpunit/phpunit": "^9.5.20", + "vimeo/psalm": "^5.6" }, "autoload": { "psr-4": { @@ -47,7 +47,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "config": { diff --git a/vendor/spiral/core/psalm.xml b/vendor/spiral/core/psalm.xml index cf0ee1b6..fc709a15 100644 --- a/vendor/spiral/core/psalm.xml +++ b/vendor/spiral/core/psalm.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" - errorLevel="4" hoistConstants="true" resolveFromConfigFile="true" @@ -11,6 +10,8 @@ findUnusedVariablesAndParams="true" ensureArrayStringOffsetsExist="true" addParamDefaultToDocblockType="true" + findUnusedBaselineEntry="true" + findUnusedCode="false" > diff --git a/vendor/spiral/core/src/Attribute/Finalize.php b/vendor/spiral/core/src/Attribute/Finalize.php new file mode 100644 index 00000000..40b09a81 --- /dev/null +++ b/vendor/spiral/core/src/Attribute/Finalize.php @@ -0,0 +1,19 @@ + $class * @param class-string> $injector */ public function bindInjector(string $class, string $injector): void; + /** + * @param class-string $class + */ public function removeInjector(string $class): void; /** * Check if class points to injector. + * + * @param class-string $class */ public function hasInjector(string $class): bool; } diff --git a/vendor/spiral/core/src/Config.php b/vendor/spiral/core/src/Config.php index 81306daa..61f7ac94 100644 --- a/vendor/spiral/core/src/Config.php +++ b/vendor/spiral/core/src/Config.php @@ -7,22 +7,32 @@ namespace Spiral\Core; use IteratorAggregate; use Psr\Container\ContainerInterface; use Spiral\Core\Internal\Binder; +use Spiral\Core\Internal\Container; use Spiral\Core\Internal\Factory; use Spiral\Core\Internal\Invoker; use Spiral\Core\Internal\Resolver; +use Spiral\Core\Internal\Scope; use Spiral\Core\Internal\State; -use Spiral\Core\Internal\Container; use Spiral\Core\Internal\Tracer; use Traversable; /** + * Container configuration that will be used not only in the root container but also in all child containers. + * The {@see self::$scopedBindings} property is internal and common for all containers. + * By the reason you can access to bindings for any scope from any container. + * * @implements IteratorAggregate< * non-empty-string, - * class-string|class-string|class-string|class-string|class-string|class-string|class-string + * class-string|class-string|class-string|class-string|class-string|class-string|class-string|class-string * > */ class Config implements IteratorAggregate { + /** @var class-string */ + public readonly string $scope; + public readonly Internal\Config\StateStorage $scopedBindings; + private bool $rootLocked = true; + /** * @param class-string $state * @param class-string $resolver @@ -41,6 +51,8 @@ class Config implements IteratorAggregate public readonly string $invoker = Invoker::class, public readonly string $tracer = Tracer::class, ) { + $this->scope = Scope::class; + $this->scopedBindings = new Internal\Config\StateStorage(); } public function getIterator(): Traversable @@ -52,5 +64,20 @@ class Config implements IteratorAggregate yield 'binder' => $this->binder; yield 'invoker' => $this->invoker; yield 'tracer' => $this->tracer; + yield 'scope' => $this->scope; + } + + /** + * Mutex lock for root container. + * First run of the method will return {@see true}, all subsequent calls will return {@see false}. + * The parent container must call the method once and before any child container. + */ + public function lockRoot(): bool + { + try { + return $this->rootLocked; + } finally { + $this->rootLocked = false; + } } } diff --git a/vendor/spiral/core/src/ConfigsInterface.php b/vendor/spiral/core/src/ConfigsInterface.php index 5a449ca5..4c9d4c61 100644 --- a/vendor/spiral/core/src/ConfigsInterface.php +++ b/vendor/spiral/core/src/ConfigsInterface.php @@ -10,6 +10,9 @@ use Spiral\Core\Exception\ConfiguratorException; /** * Provides array based configuration for specified config section. In addition configurator * interface is responsible for contextual config injections. + * + * @template TClass of object + * @extends InjectorInterface */ interface ConfigsInterface extends InjectorInterface { diff --git a/vendor/spiral/core/src/Container.php b/vendor/spiral/core/src/Container.php index fdcd807a..9bf4a290 100644 --- a/vendor/spiral/core/src/Container.php +++ b/vendor/spiral/core/src/Container.php @@ -11,7 +11,10 @@ use Spiral\Core\Container\InjectableInterface; use Spiral\Core\Container\SingletonInterface; use Spiral\Core\Exception\Container\ContainerException; use Spiral\Core\Exception\LogicException; -use Spiral\Core\Internal\DestructorTrait; +use Spiral\Core\Exception\Scope\FinalizersException; +use Spiral\Core\Exception\Scope\ScopeContainerLeakedException; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Config\StateBinder; /** * Auto-wiring container: declarative singletons, contextual injections, parent container @@ -24,8 +27,6 @@ use Spiral\Core\Internal\DestructorTrait; * * You can use injectors to delegate class resolution to external container. * - * @see \Spiral\Core\Container::registerInstance() to add your own behaviours. - * * @see InjectableInterface * @see SingletonInterface * @@ -43,29 +44,28 @@ final class Container implements { use DestructorTrait; + public const DEFAULT_ROOT_SCOPE_NAME = 'root'; + private Internal\State $state; private ResolverInterface|Internal\Resolver $resolver; private FactoryInterface|Internal\Factory $factory; private ContainerInterface|Internal\Container $container; private BinderInterface|Internal\Binder $binder; private InvokerInterface|Internal\Invoker $invoker; + private Internal\Scope $scope; /** * Container constructor. */ - public function __construct(Config $config = new Config()) - { - $constructor = new Internal\Registry($config, [ - 'state' => new Internal\State(), - ]); - foreach ($config as $property => $class) { - if (\property_exists($this, $property)) { - $this->$property = $constructor->get($property, $class); - } - } + public function __construct( + private Config $config = new Config(), + ?string $scopeName = self::DEFAULT_ROOT_SCOPE_NAME, + ) { + $this->initServices($this, $scopeName); + // Bind himself /** @psalm-suppress PossiblyNullPropertyAssignment */ - $this->state->bindings = [ + $this->state->bindings = \array_merge($this->state->bindings, [ self::class => \WeakReference::create($this), ContainerInterface::class => self::class, BinderInterface::class => self::class, @@ -73,12 +73,12 @@ final class Container implements ScopeInterface::class => self::class, ResolverInterface::class => self::class, InvokerInterface::class => self::class, - ]; + ]); } public function __destruct() { - $this->destruct(); + $this->closeScope(); } /** @@ -123,13 +123,12 @@ final class Container implements * @param class-string|string|Autowire $id * @param string|null $context Call context. * - * @return T - * @psalm-return ($id is class-string ? T : mixed) + * @return ($id is class-string ? T : mixed) * * @throws ContainerException * @throws \Throwable * - * @psalm-suppress PossiblyInvalidArgument, PossiblyInvalidCast + * @psalm-suppress InvalidArgument, InvalidCast */ public function get(string|Autowire $id, string $context = null): mixed { @@ -141,6 +140,20 @@ final class Container implements return $this->container->has($id); } + /** + * Make a Binder proxy to configure default bindings for a specific scope. + * Default bindings won't affect already created Container instances except the case with the root one. + * + * @internal We are testing this feature, it may be changed in the future. + */ + public function getBinder(string $scope): BinderInterface + { + return new StateBinder($this->config->scopedBindings->getState($scope)); + } + + /** + * @deprecated use {@see scope()} instead. + */ public function runScope(array $bindings, callable $scope): mixed { $binds = &$this->state->bindings; @@ -170,6 +183,56 @@ final class Container implements } } + /** + * @template TReturn + * + * @param callable(mixed ...$params): TReturn $closure + * @param array $bindings Custom bindings for the new scope. + * @param null|string $name Scope name. Named scopes can have individual bindings and constrains. + * @param bool $autowire If {@see false}, closure will be invoked with just only the passed Container as an + * argument. Otherwise, {@see InvokerInterface::invoke()} will be used to invoke the closure. + * + * @return TReturn + * @throws \Throwable + * + * @internal We are testing this feature, it may be changed in the future. + */ + public function scope(callable $closure, array $bindings = [], ?string $name = null, bool $autowire = true): mixed + { + // Open scope + $container = new self($this->config, $name); + + try { + // Configure scope + $container->scope->setParent($this, $this->scope); + + // Add specific bindings + foreach ($bindings as $alias => $resolver) { + $container->binder->bind($alias, $resolver); + } + + return ContainerScope::runScope( + $container, + static function (self $container) use ($autowire, $closure): mixed { + try { + return $autowire + ? $container->invoke($closure) + : $closure($container); + } finally { + $container->closeScope(); + } + } + ); + } finally { + // Check the container has not been leaked + $link = \WeakReference::create($container); + unset($container); + if ($link->get() !== null) { + throw new ScopeContainerLeakedException($name, $this->scope->getParentScopeNames()); + } + } + } + /** * Bind value resolver to container alias. Resolver can be class name (will be constructed * for each method call), function array or Closure (executed every call). Only object resolvers @@ -214,6 +277,9 @@ final class Container implements /** * Bind class or class interface to the injector source (InjectorInterface). + * + * Todo: remove suppression after {@link https://github.com/vimeo/psalm/issues/8298} fixing. + * @psalm-suppress InvalidArgument,InvalidCast */ public function bindInjector(string $class, string $injector): void { @@ -229,4 +295,68 @@ final class Container implements { return $this->binder->hasInjector($class); } + + /** + * Init internal container services. + */ + private function initServices( + self $container, + ?string $scopeName, + ): void { + $isRoot = $container->config->lockRoot(); + + // Get named scope or create anonymous one + $state = match (true) { + $scopeName === null => new Internal\State(), + // Only root container can make default bindings directly + $isRoot => $container->config->scopedBindings->getState($scopeName), + default => clone $container->config->scopedBindings->getState($scopeName), + }; + + $constructor = new Internal\Common\Registry($container->config, [ + 'state' => $state, + 'scope' => new Internal\Scope($scopeName), + ]); + + // Create container services + foreach ($container->config as $property => $class) { + if (\property_exists($container, $property)) { + $container->$property = $constructor->get($property, $class); + } + } + } + + /** + * Execute finalizers and destruct the container. + * + * @throws FinalizersException + */ + private function closeScope(): void + { + /** @psalm-suppress RedundantPropertyInitializationCheck */ + if (!isset($this->scope)) { + $this->destruct(); + return; + } + + $scopeName = $this->scope->getScopeName(); + + // Run finalizers + $errors = []; + foreach ($this->state->finalizers as $finalizer) { + try { + $this->invoker->invoke($finalizer); + } catch (\Throwable $e) { + $errors[] = $e; + } + } + + // Destroy the container + $this->destruct(); + + // Throw collected errors + if ($errors !== []) { + throw new FinalizersException($scopeName, $errors); + } + } } diff --git a/vendor/spiral/core/src/Container/InjectableInterface.php b/vendor/spiral/core/src/Container/InjectableInterface.php index e6a35064..9aa520de 100644 --- a/vendor/spiral/core/src/Container/InjectableInterface.php +++ b/vendor/spiral/core/src/Container/InjectableInterface.php @@ -8,7 +8,7 @@ namespace Spiral\Core\Container; * Must define constant INJECTOR pointing to associated injector class or binding. * * Attention, this abstraction is currently under re-thinking process in order to replace it with - * binded context-specific factory (non breaking change). + * bound context-specific factory (non breaking change). */ interface InjectableInterface { diff --git a/vendor/spiral/core/src/ContainerScope.php b/vendor/spiral/core/src/ContainerScope.php index 2b9cda6b..f4ff85cb 100644 --- a/vendor/spiral/core/src/ContainerScope.php +++ b/vendor/spiral/core/src/ContainerScope.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Spiral\Core; +use Fiber; use Psr\Container\ContainerInterface; use Throwable; @@ -34,7 +35,20 @@ final class ContainerScope [$previous, self::$container] = [self::$container, $container]; try { - return $scope(self::$container); + if (Fiber::getCurrent() === null) { + return $scope(self::$container); + } + + // Wrap scope into fiber + $fiber = new Fiber(static fn () => $scope(self::$container)); + $value = $fiber->start(); + while (!$fiber->isTerminated()) { + self::$container = $previous; + $resume = Fiber::suspend($value); + self::$container = $container; + $value = $fiber->resume($resume); + } + return $fiber->getReturn(); } finally { self::$container = $previous; } diff --git a/vendor/spiral/core/src/Exception/Scope/BadScopeException.php b/vendor/spiral/core/src/Exception/Scope/BadScopeException.php new file mode 100644 index 00000000..65df1063 --- /dev/null +++ b/vendor/spiral/core/src/Exception/Scope/BadScopeException.php @@ -0,0 +1,21 @@ + \sprintf( + "# %s\n%s", + $e::class, + $e->getMessage(), + ), + $exceptions, + )), + ), + ); + } + + /** + * @return Throwable[] + */ + public function getExceptions(): array + { + return $this->exceptions; + } +} diff --git a/vendor/spiral/core/src/Exception/Scope/NamedScopeDuplicationException.php b/vendor/spiral/core/src/Exception/Scope/NamedScopeDuplicationException.php new file mode 100644 index 00000000..06f1610e --- /dev/null +++ b/vendor/spiral/core/src/Exception/Scope/NamedScopeDuplicationException.php @@ -0,0 +1,20 @@ +, string|null> $parents + */ + public function __construct( + ?string $scope, + array $parents, + ) { + $scopes = \implode('->', \array_map( + static fn (?string $scope): string => $scope === null ? 'null' : "\"$scope\"", + [...\array_reverse($parents), $scope], + )); + parent::__construct( + $scope, + \sprintf('Scoped container has been leaked. Scope: %s.', $scopes), + ); + } +} diff --git a/vendor/spiral/core/src/Exception/Scope/ScopeException.php b/vendor/spiral/core/src/Exception/Scope/ScopeException.php new file mode 100644 index 00000000..ecfdf7d3 --- /dev/null +++ b/vendor/spiral/core/src/Exception/Scope/ScopeException.php @@ -0,0 +1,31 @@ +scope; + } +} diff --git a/vendor/spiral/core/src/InjectableConfig.php b/vendor/spiral/core/src/InjectableConfig.php index 83207ffa..357b7931 100644 --- a/vendor/spiral/core/src/InjectableConfig.php +++ b/vendor/spiral/core/src/InjectableConfig.php @@ -9,11 +9,14 @@ use Spiral\Core\Exception\ConfigException; /** * Generic implementation of array based configuration. + * + * @implements \IteratorAggregate + * @implements \ArrayAccess */ abstract class InjectableConfig implements InjectableInterface, \IteratorAggregate, \ArrayAccess { /** - * @var class-string<\Spiral\Core\ConfigsInterface> + * @var class-string */ public const INJECTOR = ConfigsInterface::class; diff --git a/vendor/spiral/core/src/Internal/Binder.php b/vendor/spiral/core/src/Internal/Binder.php index ea94ffb6..01342376 100644 --- a/vendor/spiral/core/src/Internal/Binder.php +++ b/vendor/spiral/core/src/Internal/Binder.php @@ -5,152 +5,37 @@ declare(strict_types=1); namespace Spiral\Core\Internal; use Psr\Container\ContainerInterface; -use Spiral\Core\BinderInterface; -use Spiral\Core\Container\Autowire; -use Spiral\Core\Container\InjectableInterface; -use Spiral\Core\Container\InjectorInterface; -use Spiral\Core\Exception\Container\ContainerException; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Common\Registry; +use Spiral\Core\Internal\Config\StateBinder; /** - * @psalm-type TResolver = class-string|non-empty-string|callable|array{class-string, non-empty-string} - * * @internal */ -final class Binder implements BinderInterface +final class Binder extends StateBinder { use DestructorTrait; - private State $state; private ContainerInterface $container; public function __construct(Registry $constructor) { $constructor->set('binder', $this); - $this->state = $constructor->get('state', State::class); $this->container = $constructor->get('container', ContainerInterface::class); + parent::__construct($constructor->get('state', State::class)); } - /** - * Bind value resolver to container alias. Resolver can be class name (will be constructed - * for each method call), function array or Closure (executed every call). Only object resolvers - * supported by this method. - * - * @psalm-param TResolver|object $resolver - */ - public function bind(string $alias, string|array|callable|object $resolver): void - { - if (\is_array($resolver) || $resolver instanceof \Closure || $resolver instanceof Autowire) { - // array means = execute me, false = not singleton - $this->state->bindings[$alias] = [$resolver, false]; - - return; - } - - $this->state->bindings[$alias] = $resolver; - } - - /** - * Bind value resolver to container alias to be executed as cached. Resolver can be class name - * (will be constructed only once), function array or Closure (executed only once call). - * - * @psalm-param TResolver|object $resolver - */ - public function bindSingleton(string $alias, string|array|callable|object $resolver): void - { - if (\is_object($resolver) && !$resolver instanceof \Closure && !$resolver instanceof Autowire) { - // direct binding to an instance - $this->state->bindings[$alias] = $resolver; - - return; - } - - $this->state->bindings[$alias] = [$resolver, true]; - } - - /** - * Check if alias points to constructed instance (singleton). - */ public function hasInstance(string $alias): bool { if (!$this->container->has($alias)) { return false; } - $bindings = &$this->state->bindings; - - while (isset($bindings[$alias]) && \is_string($bindings[$alias])) { - //Checking alias tree - $alias = $bindings[$alias]; - } - - return isset($bindings[$alias]) && \is_object($bindings[$alias]); + return parent::hasInstance($alias); } - public function removeBinding(string $alias): void + public function destruct(): void { - unset($this->state->bindings[$alias]); - } - - /** - * Bind class or class interface to the injector source (InjectorInterface). - * - * @template TClass - * - * @param class-string $class - * @param class-string> $injector - */ - public function bindInjector(string $class, string $injector): void - { - $this->state->injectors[$class] = $injector; - } - - public function removeInjector(string $class): void - { - unset($this->state->injectors[$class]); - } - - public function hasInjector(string $class): bool - { - try { - $reflection = new \ReflectionClass($class); - } catch (\ReflectionException $e) { - throw new ContainerException($e->getMessage(), $e->getCode(), $e); - } - - if (\array_key_exists($class, $this->state->injectors)) { - return $this->state->injectors[$class] !== null; - } - - if ( - $reflection->implementsInterface(InjectableInterface::class) - && $reflection->hasConstant('INJECTOR') - ) { - $this->state->injectors[$class] = $reflection->getConstant('INJECTOR'); - - return true; - } - - // check interfaces - foreach ($this->state->injectors as $target => $injector) { - if ( - \class_exists($target, true) - && $reflection->isSubclassOf($target) - ) { - $this->state->injectors[$class] = $injector; - - return true; - } - - if ( - \interface_exists($target, true) - && $reflection->implementsInterface($target) - ) { - $this->state->injectors[$class] = $injector; - - return true; - } - } - - return false; + unset($this->container); } } diff --git a/vendor/spiral/core/src/Internal/DestructorTrait.php b/vendor/spiral/core/src/Internal/Common/DestructorTrait.php similarity index 93% rename from vendor/spiral/core/src/Internal/DestructorTrait.php rename to vendor/spiral/core/src/Internal/Common/DestructorTrait.php index 4da2c083..3c009c17 100644 --- a/vendor/spiral/core/src/Internal/DestructorTrait.php +++ b/vendor/spiral/core/src/Internal/Common/DestructorTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Spiral\Core\Internal; +namespace Spiral\Core\Internal\Common; /** * @internal diff --git a/vendor/spiral/core/src/Internal/Registry.php b/vendor/spiral/core/src/Internal/Common/Registry.php similarity index 95% rename from vendor/spiral/core/src/Internal/Registry.php rename to vendor/spiral/core/src/Internal/Common/Registry.php index 8720e116..4cdba50d 100644 --- a/vendor/spiral/core/src/Internal/Registry.php +++ b/vendor/spiral/core/src/Internal/Common/Registry.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Spiral\Core\Internal; +namespace Spiral\Core\Internal\Common; use Spiral\Core\Config; diff --git a/vendor/spiral/core/src/Internal/Config/StateBinder.php b/vendor/spiral/core/src/Internal/Config/StateBinder.php new file mode 100644 index 00000000..8d9eb463 --- /dev/null +++ b/vendor/spiral/core/src/Internal/Config/StateBinder.php @@ -0,0 +1,125 @@ +state->bindings[$alias] = [$resolver, false]; + + return; + } + + $this->state->bindings[$alias] = $resolver; + } + + /** + * @param TResolver|object $resolver + */ + public function bindSingleton(string $alias, string|array|callable|object $resolver): void + { + if (\is_object($resolver) && !$resolver instanceof \Closure && !$resolver instanceof Autowire) { + // direct binding to an instance + $this->state->bindings[$alias] = $resolver; + + return; + } + + $this->state->bindings[$alias] = [$resolver, true]; + } + + public function hasInstance(string $alias): bool + { + $bindings = &$this->state->bindings; + + while (\is_string($bindings[$alias] ?? null)) { + //Checking alias tree + $alias = $bindings[$alias]; + } + + return isset($bindings[$alias]) && \is_object($bindings[$alias]); + } + + public function removeBinding(string $alias): void + { + unset($this->state->bindings[$alias]); + } + + public function bindInjector(string $class, string $injector): void + { + $this->state->injectors[$class] = $injector; + } + + public function removeInjector(string $class): void + { + unset($this->state->injectors[$class]); + } + + public function hasInjector(string $class): bool + { + try { + $reflection = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + throw new ContainerException($e->getMessage(), $e->getCode(), $e); + } + + if (\array_key_exists($class, $this->state->injectors)) { + return $this->state->injectors[$class] !== null; + } + + if ( + $reflection->implementsInterface(InjectableInterface::class) + && $reflection->hasConstant('INJECTOR') + ) { + $this->state->injectors[$class] = $reflection->getConstant('INJECTOR'); + + return true; + } + + // check interfaces + foreach ($this->state->injectors as $target => $injector) { + if ( + \class_exists($target, true) + && $reflection->isSubclassOf($target) + ) { + $this->state->injectors[$class] = $injector; + + return true; + } + + if ( + \interface_exists($target, true) + && $reflection->implementsInterface($target) + ) { + $this->state->injectors[$class] = $injector; + + return true; + } + } + + return false; + } +} diff --git a/vendor/spiral/core/src/Internal/Config/StateStorage.php b/vendor/spiral/core/src/Internal/Config/StateStorage.php new file mode 100644 index 00000000..e9065a22 --- /dev/null +++ b/vendor/spiral/core/src/Internal/Config/StateStorage.php @@ -0,0 +1,21 @@ + */ + private array $states = []; + + /** + * Get bindings for the given scope. + */ + public function getState(string $scope): State + { + return $this->states[$scope] ??= new State(); + } +} diff --git a/vendor/spiral/core/src/Internal/Container.php b/vendor/spiral/core/src/Internal/Container.php index 27af50c9..c906607d 100644 --- a/vendor/spiral/core/src/Internal/Container.php +++ b/vendor/spiral/core/src/Internal/Container.php @@ -8,6 +8,8 @@ use Psr\Container\ContainerInterface; use Spiral\Core\Container\Autowire; use Spiral\Core\Exception\Container\ContainerException; use Spiral\Core\FactoryInterface; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Common\Registry; /** * @internal @@ -40,8 +42,7 @@ final class Container implements ContainerInterface * @param class-string|string|Autowire $id * @param string|null $context Call context. * - * @return T - * @psalm-return ($id is class-string ? T : mixed) + * @return ($id is class-string ? T : mixed) * * @throws ContainerException * @throws \Throwable diff --git a/vendor/spiral/core/src/Internal/Factory.php b/vendor/spiral/core/src/Internal/Factory.php index 663c6e5c..d45e4bbe 100644 --- a/vendor/spiral/core/src/Internal/Factory.php +++ b/vendor/spiral/core/src/Internal/Factory.php @@ -4,7 +4,11 @@ declare(strict_types=1); namespace Spiral\Core\Internal; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Spiral\Core\Attribute\Finalize; +use Spiral\Core\Attribute\Scope as ScopeAttribute; +use Spiral\Core\Attribute\Singleton; use Spiral\Core\BinderInterface; use Spiral\Core\Container\Autowire; use Spiral\Core\Container\InjectorInterface; @@ -16,7 +20,11 @@ use Spiral\Core\Exception\Container\NotCallableException; use Spiral\Core\Exception\Container\NotFoundException; use Spiral\Core\Exception\Resolver\ValidationException; use Spiral\Core\Exception\Resolver\WrongTypeException; +use Spiral\Core\Exception\Scope\BadScopeException; use Spiral\Core\FactoryInterface; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Common\Registry; +use Spiral\Core\Internal\Factory\Ctx; use Spiral\Core\InvokerInterface; use Spiral\Core\ResolverInterface; use WeakReference; @@ -34,6 +42,7 @@ final class Factory implements FactoryInterface private ContainerInterface $container; private ResolverInterface $resolver; private Tracer $tracer; + private Scope $scope; public function __construct(Registry $constructor) { @@ -45,6 +54,7 @@ final class Factory implements FactoryInterface $this->container = $constructor->get('container', ContainerInterface::class); $this->resolver = $constructor->get('resolver', ResolverInterface::class); $this->tracer = $constructor->get('tracer', Tracer::class); + $this->scope = $constructor->get('scope', Scope::class); } /** @@ -55,134 +65,224 @@ final class Factory implements FactoryInterface public function make(string $alias, array $parameters = [], string $context = null): mixed { if (!isset($this->state->bindings[$alias])) { - $this->tracer->push(false, action: 'autowire', alias: $alias, context: $context); - try { - //No direct instructions how to construct class, make is automatically - return $this->autowire($alias, $parameters, $context); - } finally { - $this->tracer->pop(false); - } + return $this->resolveWithoutBinding($alias, $parameters, $context); } + $avoidCache = $parameters !== []; $binding = $this->state->bindings[$alias]; try { - $this->tracer->push(false, action: 'resolve from binding', alias: $alias, context: $context, binding: $binding); + $this->tracer->push( + false, + action: 'resolve from binding', + alias: $alias, + scope: $this->scope->getScopeName(), + context: $context, + binding: $binding, + ); $this->tracer->push(true); if (\is_object($binding)) { if ($binding::class === WeakReference::class) { - if ($binding->get() === null && \class_exists($alias)) { - try { - $this->tracer->push(false, alias: $alias, source: WeakReference::class, context: $context); - $object = $this->createInstance($alias, $parameters, $context); - $binding = $this->state->bindings[$alias] = WeakReference::create($object); - } catch (\Throwable) { - throw new ContainerException($this->tracer->combineTraceMessage(\sprintf( - 'Can\'t resolve `%s`: can\'t instantiate `%s` from WeakReference binding.', - $this->tracer->getRootAlias(), - $alias, - ))); - } finally { - $this->tracer->pop(); - } - } - return $binding->get(); + return $this->resolveWeakReference($binding, $alias, $context, $parameters); } - //When binding is instance, assuming singleton - return $binding; + + // When binding is instance, assuming singleton + return $avoidCache + ? $this->createInstance( + new Ctx(alias: $alias, class: $binding::class, parameter: $context), + $parameters, + ) + : $binding; } + $ctx = new Ctx(alias: $alias, class: $alias, parameter: $context); if (\is_string($binding)) { - //Binding is pointing to something else - return $this->make($binding, $parameters, $context); + $ctx->class = $binding; + return $binding === $alias + ? $this->autowire($ctx, $parameters) + //Binding is pointing to something else + : $this->make($binding, $parameters, $context); } + if ($binding[1] === true) { + $ctx->singleton = true; + } unset($this->state->bindings[$alias]); try { - $instance = $binding[0] === $alias - ? $this->autowire($alias, $parameters, $context) - : $this->evaluateBinding($alias, $binding[0], $parameters, $context); + return $binding[0] === $alias + ? $this->autowire($ctx, $parameters) + : $this->evaluateBinding($ctx, $binding[0], $parameters); } finally { - /** @psalm-var class-string $alias */ - $this->state->bindings[$alias] = $binding; + $this->state->bindings[$alias] ??= $binding; } } finally { $this->tracer->pop(true); $this->tracer->pop(false); } + } - if ($binding[1]) { - // Indicates singleton - /** @psalm-var class-string $alias */ - $this->state->bindings[$alias] = $instance; + private function resolveWeakReference( + WeakReference $binding, + string $alias, + ?string $context, + array $parameters + ): ?object { + $avoidCache = $parameters !== []; + + if (($avoidCache || $binding->get() === null) && \class_exists($alias)) { + try { + $this->tracer->push(false, alias: $alias, source: WeakReference::class, context: $context); + /** @psalm-suppress NoValue */ + $object = $this->createInstance( + new Ctx(alias: $alias, class: $alias, parameter: $context), + $parameters, + ); + if ($avoidCache) { + return $object; + } + $binding = $this->state->bindings[$alias] = WeakReference::create($object); + } catch (\Throwable) { + throw new ContainerException( + $this->tracer->combineTraceMessage( + \sprintf( + 'Can\'t resolve `%s`: can\'t instantiate `%s` from WeakReference binding.', + $this->tracer->getRootAlias(), + $alias, + ) + ) + ); + } finally { + $this->tracer->pop(); + } } - return $instance; + return $binding->get(); + } + + private function resolveWithoutBinding(string $alias, array $parameters = [], string $context = null): mixed + { + $parent = $this->scope->getParent(); + + if ($parent !== null) { + try { + $this->tracer->push(false, ...[ + 'current scope' => $this->scope->getScopeName(), + 'jump to parent scope' => $this->scope->getParentScope()->getScopeName(), + ]); + return $parent->make($alias, $parameters, $context); + } catch (BadScopeException $e) { + if ($this->scope->getScopeName() !== $e->getScope()) { + throw $e; + } + } catch (ContainerExceptionInterface $e) { + $className = match (true) { + $e instanceof NotFoundException => NotFoundException::class, + default => ContainerException::class, + }; + throw new $className($this->tracer->combineTraceMessage(\sprintf( + 'Can\'t resolve `%s`.', + $alias, + )), previous: $e); + } finally { + $this->tracer->pop(false); + } + } + + $this->tracer->push(false, action: 'autowire', alias: $alias, context: $context); + try { + //No direct instructions how to construct class, make is automatically + return $this->autowire( + new Ctx(alias: $alias, class: $alias, parameter: $context), + $parameters, + ); + } finally { + $this->tracer->pop(false); + } } /** * Automatically create class. + * Object will be cached if the $arguments list is empty. * - * @param class-string $class + * @psalm-assert class-string $class * * @throws AutowireException * @throws \Throwable */ - private function autowire(string $class, array $parameters, string $context = null): object + private function autowire(Ctx $ctx, array $arguments): object { - if (!\class_exists($class) && !isset($this->state->injectors[$class])) { + if (!(\class_exists($ctx->class) || ( + \interface_exists($ctx->class) + && + (isset($this->state->injectors[$ctx->class]) || $this->binder->hasInjector($ctx->class)) + )) + ) { throw new NotFoundException($this->tracer->combineTraceMessage(\sprintf( 'Can\'t resolve `%s`: undefined class or binding `%s`.', $this->tracer->getRootAlias(), - $class + $ctx->class, ))); } // automatically create instance - $instance = $this->createInstance($class, $parameters, $context); + $instance = $this->createInstance($ctx, $arguments); // apply registration functions to created instance - return $this->registerInstance($instance, $parameters); + return $arguments === [] + ? $this->registerInstance($ctx, $instance) + : $instance; } /** - * @param mixed $target Value binded by user. + * @param mixed $target Value that was bound by user. * * @throws ContainerException * @throws \Throwable */ private function evaluateBinding( - string $alias, + Ctx $ctx, mixed $target, - array $parameters, - string $context = null + array $arguments, ): mixed { if (\is_string($target)) { // Reference - return $this->make($target, $parameters, $context); + $instance = $this->make($target, $arguments, $ctx->parameter); + } else { + if ($target instanceof Autowire) { + $instance = $target->resolve($this, $arguments); + } else { + try { + $instance = $this->invoker->invoke($target, $arguments); + } catch (NotCallableException $e) { + throw new ContainerException( + $this->tracer->combineTraceMessage(\sprintf('Invalid binding for `%s`.', $ctx->alias)), + $e->getCode(), + $e, + ); + } + } + + // Check scope name + if (\is_object($instance)) { + $ctx->reflection = new \ReflectionClass($instance); + $scopeName = ($ctx->reflection->getAttributes(ScopeAttribute::class)[0] ?? null)?->newInstance()->name; + if ($scopeName !== null && $scopeName !== $this->scope->getScopeName()) { + throw new BadScopeException($scopeName, $instance::class); + } + } } - if ($target instanceof Autowire) { - return $target->resolve($this, $parameters); - } - - try { - return $this->invoker->invoke($target, $parameters); - } catch (NotCallableException $e) { - throw new ContainerException( - $this->tracer->combineTraceMessage(\sprintf('Invalid binding for `%s`.', $alias)), - $e->getCode(), - $e, - ); - } + return \is_object($instance) && $arguments === [] + ? $this->registerInstance($ctx, $instance) + : $instance; } /** * Create instance of desired class. * - * @template TObject + * @template TObject of object * - * @param class-string $class + * @param Ctx $ctx * @param array $parameters Constructor parameters. * * @return TObject @@ -190,14 +290,23 @@ final class Factory implements FactoryInterface * @throws ContainerException * @throws \Throwable */ - private function createInstance(string $class, array $parameters, string $context = null): object - { + private function createInstance( + Ctx $ctx, + array $parameters, + ): object { + $class = $ctx->class; try { - $reflection = new \ReflectionClass($class); + $ctx->reflection = $reflection = new \ReflectionClass($class); } catch (\ReflectionException $e) { throw new ContainerException($e->getMessage(), $e->getCode(), $e); } + // Check scope name + $scope = ($reflection->getAttributes(ScopeAttribute::class)[0] ?? null)?->newInstance()->name; + if ($scope !== null && $scope !== $this->scope->getScopeName()) { + throw new BadScopeException($scope, $class); + } + //We have to construct class using external injector when we know exact context if ($parameters === [] && $this->binder->hasInjector($class)) { $injector = $this->state->injectors[$reflection->getName()]; @@ -215,8 +324,11 @@ final class Factory implements FactoryInterface ); } - /** @var InjectorInterface $injectorInstance */ - $instance = $injectorInstance->createInjection($reflection, $context); + /** + * @var InjectorInterface $injectorInstance + * @psalm-suppress RedundantCondition + */ + $instance = $injectorInstance->createInjection($reflection, $ctx->parameter); if (!$reflection->isInstance($instance)) { throw new InjectionException( \sprintf( @@ -285,22 +397,60 @@ final class Factory implements FactoryInterface /** * Register instance in container, might perform methods like auto-singletons, log populations - * and etc. Can be extended. + * and etc. * - * @param object $instance Created object. - * @param array $parameters Parameters which been passed with created instance. + * @template TObject of object + * + * @param TObject $instance Created object. + * @param \ReflectionClass $reflection + * + * @return TObject */ - private function registerInstance(object $instance, array $parameters): object + private function registerInstance(Ctx $ctx, object $instance): object { - //Declarative singletons (only when class received via direct get) - if ($parameters === [] && $instance instanceof SingletonInterface) { - $alias = $instance::class; - if (!isset($this->state->bindings[$alias])) { - $this->state->bindings[$alias] = $instance; - } + $ctx->reflection ??= new \ReflectionClass($instance); + + //Declarative singletons + if ($this->isSingleton($ctx)) { + $this->state->bindings[$ctx->alias] = $instance; + } + + // Register finalizer + $finalizer = $this->getFinalizer($ctx, $instance); + if ($finalizer !== null) { + $this->state->finalizers[] = $finalizer; } - // Your code can go here (for example LoggerAwareInterface, custom hydration and etc) return $instance; } + + /** + * Check the class was configured as a singleton. + */ + private function isSingleton(Ctx $ctx): bool + { + if ($ctx->singleton === true) { + return true; + } + + if ($ctx->reflection->implementsInterface(SingletonInterface::class)) { + return true; + } + + return $ctx->reflection->getAttributes(Singleton::class) !== []; + } + + private function getFinalizer(Ctx $ctx, object $instance): ?callable + { + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var Finalize|null $attribute + */ + $attribute = ($ctx->reflection->getAttributes(Finalize::class)[0] ?? null)?->newInstance(); + if ($attribute === null) { + return null; + } + + return [$instance, $attribute->method]; + } } diff --git a/vendor/spiral/core/src/Internal/Factory/Ctx.php b/vendor/spiral/core/src/Internal/Factory/Ctx.php new file mode 100644 index 00000000..f3130daf --- /dev/null +++ b/vendor/spiral/core/src/Internal/Factory/Ctx.php @@ -0,0 +1,24 @@ + $class + * @param null|\ReflectionClass $reflection + */ + public function __construct( + public readonly string $alias, + public string $class, + public ?string $parameter = null, + public ?bool $singleton = null, + public ?\ReflectionClass $reflection = null, + ) { + } +} diff --git a/vendor/spiral/core/src/Internal/Invoker.php b/vendor/spiral/core/src/Internal/Invoker.php index 004a40b5..9a484886 100644 --- a/vendor/spiral/core/src/Internal/Invoker.php +++ b/vendor/spiral/core/src/Internal/Invoker.php @@ -7,6 +7,8 @@ namespace Spiral\Core\Internal; use Psr\Container\ContainerInterface; use Spiral\Core\Exception\Container\ContainerException; use Spiral\Core\Exception\Container\NotCallableException; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Common\Registry; use Spiral\Core\InvokerInterface; use Spiral\Core\ResolverInterface; @@ -53,7 +55,7 @@ final class Invoker implements InvokerInterface // Invoking factory method with resolved arguments return $method->invokeArgs( $resolver, - $this->resolver->resolveArguments($method, $parameters) + $this->resolver->resolveArguments($method, $parameters), ); } diff --git a/vendor/spiral/core/src/Internal/Resolver.php b/vendor/spiral/core/src/Internal/Resolver.php index 5a21b398..9dc3e89d 100644 --- a/vendor/spiral/core/src/Internal/Resolver.php +++ b/vendor/spiral/core/src/Internal/Resolver.php @@ -21,6 +21,9 @@ use Spiral\Core\Exception\Resolver\ResolvingException; use Spiral\Core\Exception\Resolver\UnknownParameterException; use Spiral\Core\Exception\Resolver\UnsupportedTypeException; use Spiral\Core\FactoryInterface; +use Spiral\Core\Internal\Common\DestructorTrait; +use Spiral\Core\Internal\Common\Registry; +use Spiral\Core\Internal\Resolver\ResolvingState; use Spiral\Core\ResolverInterface; use Throwable; @@ -91,6 +94,7 @@ final class Resolver implements ResolverInterface $name = $parameter->getName(); if (($positional || $variadic) && $key !== null) { + /** @psalm-suppress ReferenceReusedFromConfusingScope */ $value = \array_shift($arguments); } elseif ($key === null || !\array_key_exists($name, $arguments)) { if ($parameter->isOptional()) { diff --git a/vendor/spiral/core/src/Internal/ResolvingState.php b/vendor/spiral/core/src/Internal/Resolver/ResolvingState.php similarity index 98% rename from vendor/spiral/core/src/Internal/ResolvingState.php rename to vendor/spiral/core/src/Internal/Resolver/ResolvingState.php index fc358a40..ac0a881e 100644 --- a/vendor/spiral/core/src/Internal/ResolvingState.php +++ b/vendor/spiral/core/src/Internal/Resolver/ResolvingState.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Spiral\Core\Internal; +namespace Spiral\Core\Internal\Resolver; use ReflectionFunctionAbstract; use ReflectionParameter; diff --git a/vendor/spiral/core/src/Internal/Scope.php b/vendor/spiral/core/src/Internal/Scope.php new file mode 100644 index 00000000..53e46278 --- /dev/null +++ b/vendor/spiral/core/src/Internal/Scope.php @@ -0,0 +1,81 @@ +scopeName; + } + + /** + * Link the current scope with its parent scope and container. + * + * @throws NamedScopeDuplicationException + */ + public function setParent(\Spiral\Core\Container $parent, self $parentScope): void + { + $this->parent = $parent; + $this->parentScope = $parentScope; + + // Check a scope with the same name is not already registered + if ($this->scopeName !== null) { + $tmp = $this; + while ($tmp->parentScope !== null) { + $tmp = $tmp->parentScope; + $tmp->scopeName !== $this->scopeName ?: throw new NamedScopeDuplicationException($this->scopeName); + } + } + } + + public function getParent(): ?\Spiral\Core\Container + { + return $this->parent; + } + + /** + * Return list of parent scope names. + * The first element is the current scope name, and the next is the closest parent scope name... + * + * @return array, string|null> + */ + public function getParentScopeNames(): array + { + $result = [$this->scopeName]; + + $parent = $this; + while ($parent->parentScope !== null) { + $parent = $parent->parentScope; + $result[] = $parent->scopeName; + } + + return $result; + } + + public function getParentScope(): ?self + { + return $this->parentScope; + } + + public function destruct(): void + { + $this->parent = null; + $this->parentScope = null; + } +} diff --git a/vendor/spiral/core/src/Internal/State.php b/vendor/spiral/core/src/Internal/State.php index c9d4abd5..c3b02a33 100644 --- a/vendor/spiral/core/src/Internal/State.php +++ b/vendor/spiral/core/src/Internal/State.php @@ -2,15 +2,17 @@ namespace Spiral\Core\Internal; +use Spiral\Core\Container\Autowire; + /** - * @psalm-type TResolver = class-string|non-empty-string|callable|array{class-string, non-empty-string} + * @psalm-type TResolver = class-string|non-empty-string|callable|array{class-string, non-empty-string}|Autowire * * @internal */ final class State { /** - * @var array + * @var array */ public array $bindings = []; @@ -20,9 +22,16 @@ final class State */ public array $injectors = []; + /** + * List of finalizers to be called on container scope destruction. + * @var callable[] + */ + public array $finalizers = []; + public function destruct(): void { $this->injectors = []; $this->bindings = []; + $this->finalizers = []; } } diff --git a/vendor/spiral/core/src/Internal/Tracer.php b/vendor/spiral/core/src/Internal/Tracer.php index 69756c6c..42163160 100644 --- a/vendor/spiral/core/src/Internal/Tracer.php +++ b/vendor/spiral/core/src/Internal/Tracer.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Spiral\Core\Internal; +use Spiral\Core\Internal\Tracer\Trace; + /** * @internal */ @@ -23,10 +25,8 @@ final class Tracer implements \Stringable /** * @param string $header Message before stack list - * @param bool $lastBlock Generate trace list only for last block - * @param bool $clear Remove touched trace list */ - public function combineTraceMessage(string $header, bool $lastBlock = false, bool $clear = false): string + public function combineTraceMessage(string $header): string { return "$header\n$this"; } diff --git a/vendor/spiral/core/src/Internal/Trace.php b/vendor/spiral/core/src/Internal/Tracer/Trace.php similarity index 95% rename from vendor/spiral/core/src/Internal/Trace.php rename to vendor/spiral/core/src/Internal/Tracer/Trace.php index d0aa273b..03eb639a 100644 --- a/vendor/spiral/core/src/Internal/Trace.php +++ b/vendor/spiral/core/src/Internal/Tracer/Trace.php @@ -2,9 +2,8 @@ declare(strict_types=1); -namespace Spiral\Core\Internal; +namespace Spiral\Core\Internal\Tracer; -use ReflectionFunction; use Spiral\Core\Exception\Traits\ClosureRendererTrait; /** @@ -43,7 +42,7 @@ final class Trace implements \Stringable $item instanceof \UnitEnum => $item::class . "::$item->name", \is_object($item) => 'instance of ' . $item::class, \is_array($item) => $this->renderArray($item), - default => \gettype($item), + default => \get_debug_type($item), }; } diff --git a/vendor/spiral/core/src/ScopeInterface.php b/vendor/spiral/core/src/ScopeInterface.php index f98590dc..5f0a28d4 100644 --- a/vendor/spiral/core/src/ScopeInterface.php +++ b/vendor/spiral/core/src/ScopeInterface.php @@ -6,6 +6,8 @@ namespace Spiral\Core; /** * Provides ability to run code withing isolated IoC scope. + * + * @deprecated */ interface ScopeInterface { diff --git a/vendor/spiral/logger/composer.json b/vendor/spiral/logger/composer.json index 76c9bf1b..fa129626 100644 --- a/vendor/spiral/logger/composer.json +++ b/vendor/spiral/logger/composer.json @@ -29,7 +29,7 @@ "require": { "php": ">=8.1", "psr/log": "1 - 3", - "spiral/core": "^3.5" + "spiral/core": "^3.6.1" }, "require-dev": { "phpunit/phpunit": "^9.5.20", @@ -48,7 +48,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "config": { diff --git a/vendor/spiral/tokenizer/composer.json b/vendor/spiral/tokenizer/composer.json index 0b99abcd..2a5793e1 100644 --- a/vendor/spiral/tokenizer/composer.json +++ b/vendor/spiral/tokenizer/composer.json @@ -29,12 +29,14 @@ "require": { "php": ">=8.1", "ext-tokenizer": "*", - "spiral/core": "^3.5", - "spiral/logger": "^3.5", + "spiral/core": "^3.6.1", + "spiral/logger": "^3.6.1", "symfony/finder": "^5.3.7|^6.0" }, "require-dev": { - "spiral/boot": "^3.5", + "spiral/attributes": "^2.8|^3.0", + "spiral/boot": "^3.6.1", + "spiral/files": "^3.6.1", "phpunit/phpunit": "^9.5.20", "vimeo/psalm": "^4.27" }, @@ -50,7 +52,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "3.7.x-dev" } }, "config": { diff --git a/vendor/spiral/tokenizer/src/AbstractLocator.php b/vendor/spiral/tokenizer/src/AbstractLocator.php index 5f3b1ab3..233de8ca 100644 --- a/vendor/spiral/tokenizer/src/AbstractLocator.php +++ b/vendor/spiral/tokenizer/src/AbstractLocator.php @@ -24,7 +24,7 @@ abstract class AbstractLocator implements InjectableInterface, LoggerAwareInterf public function __construct( protected Finder $finder, - protected readonly bool $debug = false + protected readonly bool $debug = false, ) { } diff --git a/vendor/spiral/tokenizer/src/Attribute/AbstractTarget.php b/vendor/spiral/tokenizer/src/Attribute/AbstractTarget.php new file mode 100644 index 00000000..0863ff5b --- /dev/null +++ b/vendor/spiral/tokenizer/src/Attribute/AbstractTarget.php @@ -0,0 +1,41 @@ + + */ + abstract public function filter(array $classes): \Iterator; + + /** + * Get scope for class locator. If scope is not set, all classes will be listened. + * @return non-empty-string|null + */ + public function getScope(): ?string + { + return $this->scope; + } +} diff --git a/vendor/spiral/tokenizer/src/Attribute/TargetAttribute.php b/vendor/spiral/tokenizer/src/Attribute/TargetAttribute.php new file mode 100644 index 00000000..441d04a3 --- /dev/null +++ b/vendor/spiral/tokenizer/src/Attribute/TargetAttribute.php @@ -0,0 +1,107 @@ +attribute); + $attribute = $target->getAttributes(\Attribute::class)[0] ?? null; + + // If annotations are used, we need to use the annotation reader also + // It will slow down the process a bit, but it will allow us to use annotations + $reader = $this->useAnnotations + ? (new Factory())->create() + : new AttributeReader(); + + if ($attribute === null) { + return; + } + + $attribute = $attribute->newInstance(); + + foreach ($classes as $class) { + // If attribute is defined on class level and class has target attribute + // then we can add it to the list of classes + if (($attribute->flags & \Attribute::TARGET_CLASS) + && $reader->firstClassMetadata($class, $target->getName()) + ) { + yield $class->getName(); + continue; + } + + // If attribute is defined on method level and class methods has target attribute + // then we can add it to the list of classes + if ($attribute->flags & \Attribute::TARGET_METHOD) { + foreach ($class->getMethods() as $method) { + if ($reader->firstFunctionMetadata($method, $target->getName())) { + yield $class->getName(); + continue 2; + } + } + } + + // If attribute is defined on property level and class properties has target attribute + // then we can add it to the list of classes + if ($attribute->flags & \Attribute::TARGET_PROPERTY) { + foreach ($class->getProperties() as $property) { + if ($reader->firstPropertyMetadata($property, $target->getName())) { + yield $class->getName(); + continue 2; + } + } + } + + + // If attribute is defined on constant level and class constants has target attribute + // then we can add it to the list of classes + if ($attribute->flags & \Attribute::TARGET_CLASS_CONSTANT) { + foreach ($class->getReflectionConstants() as $constant) { + if ($reader->firstConstantMetadata($constant, $target->getName())) { + yield $class->getName(); + continue 2; + } + } + } + + + // If attribute is defined on method parameters level and class method parameter has target attribute + // then we can add it to the list of classes + if ($attribute->flags & \Attribute::TARGET_PARAMETER) { + foreach ($class->getMethods() as $method) { + foreach ($method->getParameters() as $parameter) { + if ($reader->firstParameterMetadata($parameter, $target->getName())) { + yield $class->getName(); + continue 3; + } + } + } + } + } + } +} diff --git a/vendor/spiral/tokenizer/src/Attribute/TargetClass.php b/vendor/spiral/tokenizer/src/Attribute/TargetClass.php new file mode 100644 index 00000000..4126d17c --- /dev/null +++ b/vendor/spiral/tokenizer/src/Attribute/TargetClass.php @@ -0,0 +1,50 @@ +class); + + foreach ($classes as $class) { + if (!$target->isTrait()) { + if ($class->isSubclassOf($target) || $class->getName() === $target->getName()) { + yield $class->getName(); + } + + continue; + } + + // Checking using traits + if (\in_array($target->getName(), $this->fetchTraits($class->getName()), true)) { + yield $class->getName(); + } + } + } +} diff --git a/vendor/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php b/vendor/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php index f612199d..cf43bf8a 100644 --- a/vendor/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php +++ b/vendor/spiral/tokenizer/src/Bootloader/TokenizerBootloader.php @@ -29,7 +29,7 @@ final class TokenizerBootloader extends Bootloader implements SingletonInterface ]; public function __construct( - private readonly ConfiguratorInterface $config + private readonly ConfiguratorInterface $config, ) { } diff --git a/vendor/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php b/vendor/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php index 5f424127..220c9b58 100644 --- a/vendor/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php +++ b/vendor/spiral/tokenizer/src/Bootloader/TokenizerListenerBootloader.php @@ -6,21 +6,39 @@ namespace Spiral\Tokenizer\Bootloader; use Spiral\Boot\AbstractKernel; use Spiral\Boot\Bootloader\Bootloader; +use Spiral\Boot\DirectoriesInterface; +use Spiral\Boot\EnvironmentInterface; +use Spiral\Boot\Memory; +use Spiral\Boot\NullMemory; +use Spiral\Bootloader\Attributes\AttributesBootloader; use Spiral\Core\Container\SingletonInterface; +use Spiral\Core\FactoryInterface; use Spiral\Tokenizer\ClassesInterface; +use Spiral\Tokenizer\Config\TokenizerConfig; +use Spiral\Tokenizer\Listener\CachedClassesLoader; +use Spiral\Tokenizer\Listener\ClassesLoaderInterface; +use Spiral\Tokenizer\Listener\ListenerInvoker; use Spiral\Tokenizer\TokenizationListenerInterface; use Spiral\Tokenizer\TokenizerListenerRegistryInterface; +/** + * The bootloader is responsible for speeding up the static analysis of the application. + * First of all, it allows use static analysis only ones and use listeners to analyze found classes. + * Secondly, it allows to cache the result of the analysis for each listener and use it in the future. + * If you want to have better performance during the application boot, you should use this bootloader. + */ final class TokenizerListenerBootloader extends Bootloader implements SingletonInterface, TokenizerListenerRegistryInterface { protected const DEPENDENCIES = [ + AttributesBootloader::class, TokenizerBootloader::class, ]; protected const SINGLETONS = [ TokenizerListenerRegistryInterface::class => self::class, + ClassesLoaderInterface::class => [self::class, 'initCachedClassesLoader'], ]; /** @var TokenizationListenerInterface[] */ @@ -33,28 +51,52 @@ final class TokenizerListenerBootloader extends Bootloader implements public function boot(AbstractKernel $kernel): void { - $kernel->booted(function (ClassesInterface $classes): void { - foreach ($classes->getClasses() as $class) { - $this->invokeListeners($class); + $kernel->booted(function ( + ClassesInterface $classes, + ClassesLoaderInterface $loader, + ListenerInvoker $invoker, + ): void { + // First, we check if the listener has been cached. If it has, we will load the classes + // from the cache. + foreach ($this->listeners as $i => $listener) { + if ($loader->loadClasses($listener)) { + unset($this->listeners[$i]); + } } - $this->finalize(); + // If there are no listeners left, we don't need to use static analysis at all and save + // valuable time. + if ($this->listeners === []) { + return; + } + + // If there are listeners left, we will use static analysis to find the classes. + // Please note that this is a very expensive operation and should be avoided if possible. + // Use #[TargetClass] or #[TargetAttribute] attributes in your listeners to cache the classes. + $classes = $classes->getClasses(); + foreach ($this->listeners as $listener) { + $invoker->invoke($listener, $classes); + } + + // We don't need the listeners anymore, so we will clear them from memory. + $this->listeners = []; }); } - private function invokeListeners(\ReflectionClass $class): void - { - foreach ($this->listeners as $listener) { - $listener->listen($class); - } - } - - private function finalize(): void - { - foreach ($this->listeners as $listener) { - $listener->finalize(); - } - - $this->listeners = []; + public function initCachedClassesLoader( + FactoryInterface $factory, + DirectoriesInterface $dirs, + EnvironmentInterface $env, + TokenizerConfig $config, + ): ClassesLoaderInterface { + // We will use a file memory to cache the classes. Because it's available in the runtime. + // If you want to disable the read cache, you can use the TOKENIZER_CACHE_TARGETS environment variable. + // In this case the classes will be stored in a cache on every bootstrap, but not read from there. + return $factory->make(CachedClassesLoader::class, [ + 'memory' => $factory->make(Memory::class, [ + 'directory' => $config->getCacheDirectory() ?? $dirs->get('runtime') . 'cache/listeners', + ]), + 'readCache' => $env->get('TOKENIZER_CACHE_TARGETS', $config->isCacheEnabled()), + ]); } } diff --git a/vendor/spiral/tokenizer/src/Config/TokenizerConfig.php b/vendor/spiral/tokenizer/src/Config/TokenizerConfig.php index 69d9c069..3564effe 100644 --- a/vendor/spiral/tokenizer/src/Config/TokenizerConfig.php +++ b/vendor/spiral/tokenizer/src/Config/TokenizerConfig.php @@ -22,6 +22,7 @@ final class TokenizerConfig extends InjectableConfig /** * @psalm-var array{ + * "cache": array{"directory": null, "enabled": bool}, * "directories": TDirectories, * "exclude": TDirectories, * "scopes": array @@ -29,6 +30,10 @@ final class TokenizerConfig extends InjectableConfig * @var array */ protected array $config = [ + 'cache' => [ + 'directory' => null, + 'enabled' => false, + ], 'debug' => false, 'directories' => [], 'exclude' => [], @@ -37,7 +42,7 @@ final class TokenizerConfig extends InjectableConfig public function isDebug(): bool { - return (bool) ($this->config['debug'] ?? false); + return (bool)($this->config['debug'] ?? false); } /** @@ -45,7 +50,7 @@ final class TokenizerConfig extends InjectableConfig */ public function getDirectories(): array { - return $this->config['directories'] ?? [(string) \getcwd()]; + return $this->config['directories'] ?? [(string)\getcwd()]; } /** @@ -69,4 +74,23 @@ final class TokenizerConfig extends InjectableConfig 'exclude' => $excludes, ]; } + + /** + * Check if tokenizer listeners cache is enabled. + */ + public function isCacheEnabled(): bool + { + return (bool)($this->config['cache']['enabled'] ?? false); + } + + /** + * Get tokenizer listeners cache directory. + */ + public function getCacheDirectory(): ?string + { + $dir = $this->config['cache']['directory'] ?? null; + \assert(\is_string($dir) || $dir === null, 'Invalid cache directory.'); + + return $dir; + } } diff --git a/vendor/spiral/tokenizer/src/Listener/CachedClassesLoader.php b/vendor/spiral/tokenizer/src/Listener/CachedClassesLoader.php new file mode 100644 index 00000000..beb6ce48 --- /dev/null +++ b/vendor/spiral/tokenizer/src/Listener/CachedClassesLoader.php @@ -0,0 +1,69 @@ +parseAttributes($listener)); + + // If there are no targets, then listener can't be cached. + if ($targets === []) { + return false; + } + + $listenerClasses = []; + + // We decided to load classes for each target separately. + // It allows us to cache classes for each target separately and if we reuse the + // same target in multiple listeners, we will not have to load classes for the same target. + foreach ($targets as $target) { + $cacheKey = (string)$target; + + $classes = $this->readCache ? $this->memory->loadData($cacheKey) : null; + if ($classes === null) { + $this->memory->saveData( + $cacheKey, + $classes = $this->locator->getClasses($target), + ); + } + + $listenerClasses = \array_merge($listenerClasses, $classes); + } + + $this->invoker->invoke( + $listener, + \array_map(static fn (string $class) => new \ReflectionClass($class), \array_unique($listenerClasses)), + ); + + return true; + } + + private function parseAttributes(TokenizationListenerInterface $listener): \Generator + { + $listener = new \ReflectionClass($listener); + + foreach ($this->reader->getClassMetadata($listener) as $attribute) { + if ($attribute instanceof AbstractTarget) { + yield $attribute; + } + } + } +} diff --git a/vendor/spiral/tokenizer/src/Listener/ClassLocatorByTarget.php b/vendor/spiral/tokenizer/src/Listener/ClassLocatorByTarget.php new file mode 100644 index 00000000..95542000 --- /dev/null +++ b/vendor/spiral/tokenizer/src/Listener/ClassLocatorByTarget.php @@ -0,0 +1,49 @@ +filter( + $this->findClasses($target), + ), + ); + } + + /** + * @return \ReflectionClass[] + */ + private function findClasses(AbstractTarget $target): array + { + $scope = $target->getScope(); + + // If scope for listener attribute is defined, we should use scoped class locator + return $scope !== null + ? $this->scopedClasses->getScopedClasses($scope) + : $this->classes->getClasses(); + } +} diff --git a/vendor/spiral/tokenizer/src/Listener/ClassesLoaderInterface.php b/vendor/spiral/tokenizer/src/Listener/ClassesLoaderInterface.php new file mode 100644 index 00000000..200d7d01 --- /dev/null +++ b/vendor/spiral/tokenizer/src/Listener/ClassesLoaderInterface.php @@ -0,0 +1,17 @@ + $classes + */ + public function invoke(TokenizationListenerInterface $listener, iterable $classes): void + { + foreach ($classes as $class) { + $listener->listen($class); + } + + $listener->finalize(); + } +} diff --git a/vendor/spiral/tokenizer/src/TokenizationListenerInterface.php b/vendor/spiral/tokenizer/src/TokenizationListenerInterface.php index 9c2528de..f2814f5d 100644 --- a/vendor/spiral/tokenizer/src/TokenizationListenerInterface.php +++ b/vendor/spiral/tokenizer/src/TokenizationListenerInterface.php @@ -4,15 +4,23 @@ declare(strict_types=1); namespace Spiral\Tokenizer; +/** + * Listeners are used to process classes found by Tokenizer and to perform some actions with them. + * For example, you can use listeners to look for classes with specific attributes or classes that + * implement specific interfaces and register them in your application during application bootstrap. + * Listeners allow application to be more flexible and increase performance. + * With listeners, you can also use TargetClass and TargetAttribute attributes to increase performance + * by filtering classes that are not needed for the listener and caching the result. + */ interface TokenizationListenerInterface { /** - * The method will be fired for every found class by a class locator. + * The method will be fired for each class that was found by Tokenizer. */ public function listen(\ReflectionClass $class): void; /** - * The method will be fired after a class locator will finish iterating of found classes. + * The method will be fired after all classes were processed by listen method. */ public function finalize(): void; } diff --git a/vendor/tightenco/collect/.github/workflows/run-tests.yml b/vendor/tightenco/collect/.github/workflows/run-tests.yml index 2a0d42f9..406c4004 100644 --- a/vendor/tightenco/collect/.github/workflows/run-tests.yml +++ b/vendor/tightenco/collect/.github/workflows/run-tests.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [Ubuntu, macOS] - php: [7.3, 7.4, 8.0, 8.1] + php: [8.0, 8.1, 8.2] include: - os: Ubuntu diff --git a/vendor/tightenco/collect/composer.json b/vendor/tightenco/collect/composer.json index 88ebb77a..949635dc 100644 --- a/vendor/tightenco/collect/composer.json +++ b/vendor/tightenco/collect/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^7.3|^8.0", + "php": "^8.0", "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { @@ -33,7 +33,6 @@ "tests/files/Support/HtmlString.php", "tests/files/Support/HigherOrderTapProxy.php", "tests/files/Support/Str.php", - "tests/files/Support/Traits/Conditionable.php", "tests/files/Support/Stringable.php", "tests/files/Support/ItemNotFoundException.php", "tests/files/Support/MultipleItemsFoundException.php", diff --git a/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php b/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php new file mode 100644 index 00000000..eaf24812 --- /dev/null +++ b/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php @@ -0,0 +1,109 @@ +target = $target; + } + + /** + * Set the condition on the proxy. + * + * @param bool $condition + * @return $this + */ + public function condition($condition) + { + [$this->condition, $this->hasCondition] = [$condition, true]; + + return $this; + } + + /** + * Indicate that the condition should be negated. + * + * @return $this + */ + public function negateConditionOnCapture() + { + $this->negateConditionOnCapture = true; + + return $this; + } + + /** + * Proxy accessing an attribute onto the target. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + if (! $this->hasCondition) { + $condition = $this->target->{$key}; + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$key} + : $this->target; + } + + /** + * Proxy a method call on the target. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (! $this->hasCondition) { + $condition = $this->target->{$method}(...$parameters); + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$method}(...$parameters) + : $this->target; + } +} diff --git a/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php b/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php index a2058040..190bb9bc 100755 --- a/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php +++ b/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php @@ -2,12 +2,16 @@ namespace Tightenco\Collect\Contracts\Support; +/** + * @template TKey of array-key + * @template TValue + */ interface Arrayable { /** * Get the instance as an array. * - * @return array + * @return array */ public function toArray(); } diff --git a/vendor/tightenco/collect/src/Collect/Support/Arr.php b/vendor/tightenco/collect/src/Collect/Support/Arr.php index ea047251..f3a4b042 100644 --- a/vendor/tightenco/collect/src/Collect/Support/Arr.php +++ b/vendor/tightenco/collect/src/Collect/Support/Arr.php @@ -2,6 +2,7 @@ namespace Tightenco\Collect\Support; +use ArgumentCountError; use ArrayAccess; use Tightenco\Collect\Support\Traits\Macroable; use InvalidArgumentException; @@ -25,7 +26,7 @@ class Arr * Add an element to an array using "dot" notation if it doesn't exist. * * @param array $array - * @param string $key + * @param string|int|float $key * @param mixed $value * @return array */ @@ -142,7 +143,7 @@ class Arr * Get all of the given array except for a specified array of keys. * * @param array $array - * @param array|string $keys + * @param array|string|int|float $keys * @return array */ public static function except($array, $keys) @@ -169,6 +170,10 @@ class Arr return $array->offsetExists($key); } + if (is_float($key)) { + $key = (string) $key; + } + return array_key_exists($key, $array); } @@ -252,7 +257,7 @@ class Arr * Remove one or many array items from a given array using "dot" notation. * * @param array $array - * @param array|string $keys + * @param array|string|int|float $keys * @return void */ public static function forget(&$array, $keys) @@ -281,7 +286,7 @@ class Arr while (count($parts) > 1) { $part = array_shift($parts); - if (isset($array[$part]) && is_array($array[$part])) { + if (isset($array[$part]) && static::accessible($array[$part])) { $array = &$array[$part]; } else { continue 2; @@ -314,7 +319,7 @@ class Arr return $array[$key]; } - if (strpos($key, '.') === false) { + if (! str_contains($key, '.')) { return $array[$key] ?? value($default); } @@ -423,6 +428,59 @@ class Arr return ! self::isAssoc($array); } + /** + * Join all items using a string. The final items can use a separate glue string. + * + * @param array $array + * @param string $glue + * @param string $finalGlue + * @return string + */ + public static function join($array, $glue, $finalGlue = '') + { + if ($finalGlue === '') { + return implode($glue, $array); + } + + if (count($array) === 0) { + return ''; + } + + if (count($array) === 1) { + return end($array); + } + + $finalItem = array_pop($array); + + return implode($glue, $array).$finalGlue.$finalItem; + } + + /** + * Key an associative array by a field or using a callback. + * + * @param array $array + * @param callable|array|string $keyBy + * @return array + */ + public static function keyBy($array, $keyBy) + { + return Collection::make($array)->keyBy($keyBy)->all(); + } + + /** + * Prepend the key names of an associative array. + * + * @param array $array + * @param string $prependWith + * @return array + */ + public static function prependKeysWith($array, $prependWith) + { + return Collection::make($array)->mapWithKeys(function ($item, $key) use ($prependWith) { + return [$prependWith.$key => $item]; + })->all(); + } + /** * Get a subset of the items from the given array. * @@ -487,6 +545,26 @@ class Arr return [$value, $key]; } + /** + * Run a map over each of the items in the array. + * + * @param array $array + * @param callable $callback + * @return array + */ + public static function map(array $array, callable $callback) + { + $keys = array_keys($array); + + try { + $items = array_map($callback, $array, $keys); + } catch (ArgumentCountError) { + $items = array_map($callback, $array); + } + + return array_combine($keys, $items); + } + /** * Push an item onto the beginning of an array. * @@ -539,7 +617,7 @@ class Arr * * @param array $array * @param int|null $number - * @param bool|false $preserveKeys + * @param bool $preserveKeys * @return mixed * * @throws \InvalidArgumentException @@ -587,7 +665,7 @@ class Arr * If no key is given to the method, the entire array will be replaced. * * @param array $array - * @param string|null $key + * @param string|int|null $key * @param mixed $value * @return array */ @@ -653,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. * @@ -705,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. * @@ -725,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)); } /** diff --git a/vendor/tightenco/collect/src/Collect/Support/Collection.php b/vendor/tightenco/collect/src/Collect/Support/Collection.php index 0dc73239..e705ee0d 100644 --- a/vendor/tightenco/collect/src/Collect/Support/Collection.php +++ b/vendor/tightenco/collect/src/Collect/Support/Collection.php @@ -8,22 +8,33 @@ use Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString; use Tightenco\Collect\Support\Traits\EnumeratesValues; use Tightenco\Collect\Support\Traits\Macroable; use stdClass; +use Traversable; +/** + * @template TKey of array-key + * @template TValue + * + * @implements \ArrayAccess + * @implements \Tightenco\Collect\Support\Enumerable + */ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Tightenco\Collect\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The items contained in the collection. * - * @var array + * @var array */ protected $items = []; /** * Create a new collection. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items * @return void */ public function __construct($items = []) @@ -36,7 +47,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -46,7 +57,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get all of the items in the collection. * - * @return array + * @return array */ public function all() { @@ -56,7 +67,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get a lazy collection for the items in this collection. * - * @return \Tightenco\Collect\Support\LazyCollection + * @return \Tightenco\Collect\Support\LazyCollection */ public function lazy() { @@ -66,18 +77,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { $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; @@ -87,15 +96,14 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { $values = (isset($key) ? $this->pluck($key) : $this) - ->filter(function ($item) { - return ! is_null($item); - })->sort()->values(); + ->filter(fn ($item) => ! is_null($item)) + ->sort()->values(); $count = $values->count(); @@ -117,8 +125,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -130,23 +138,20 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl $counts = new static; - $collection->each(function ($value) use ($counts) { - $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1; - }); + $collection->each(fn ($value) => $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1); $sorted = $counts->sort(); $highestValue = $sorted->last(); - return $sorted->filter(function ($value) use ($highestValue) { - return $value == $highestValue; - })->sort()->keys()->all(); + return $sorted->filter(fn ($value) => $value == $highestValue) + ->sort()->keys()->all(); } /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -156,7 +161,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Determine if an item exists in the collection. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,6 +181,26 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + return in_array($key, $this->items, true); + } + /** * Determine if an item is not contained in the collection. * @@ -192,8 +217,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists) { @@ -205,7 +233,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection that are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -216,8 +244,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -228,7 +256,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -239,8 +267,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -251,7 +279,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -262,8 +290,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -274,7 +302,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Retrieve duplicate items from the collection. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -302,7 +330,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Retrieve duplicate items from the collection using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -314,25 +342,21 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Get the comparison function to detect duplicates. * * @param bool $strict - * @return \Closure + * @return callable(TValue, TValue): bool */ 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; } /** * Get all items except for those with the specified keys. * - * @param \Tightenco\Collect\Support\Collection|mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -349,7 +373,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ public function filter(callable $callback = null) @@ -364,9 +388,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the first item from the collection passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -377,7 +403,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Get a flattened array of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -387,7 +413,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -397,7 +423,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Remove an item from the collection by key. * - * @param string|int|array $keys + * @param TKey|array $keys * @return $this */ public function forget($keys) @@ -412,9 +438,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -446,9 +474,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -470,7 +498,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl } foreach ($groupKeys as $groupKey) { - $groupKey = is_bool($groupKey) ? (int) $groupKey : $groupKey; + $groupKey = match (true) { + is_bool($groupKey) => (int) $groupKey, + $groupKey instanceof \Stringable => (string) $groupKey, + default => $groupKey, + }; if (! array_key_exists($groupKey, $results)) { $results[$groupKey] = new static; @@ -492,8 +524,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -517,7 +549,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key) @@ -559,12 +591,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ public function implode($value, $glue = null) { + if ($this->useAsCallable($value)) { + return implode($glue ?? '', $this->map($value)->all()); + } + $first = $this->first(); if (is_array($first) || (is_object($first) && ! $first instanceof \Illuminate\Support\Stringable)) { @@ -577,7 +613,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -585,10 +621,45 @@ 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 \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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 \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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 \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -651,7 +722,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -661,9 +732,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -673,9 +746,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the values of a given key. * - * @param string|array|int|null $value + * @param string|int|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -685,16 +758,14 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { - $keys = array_keys($this->items); - - $items = array_map($callback, $this->items, $keys); - - return new static(array_combine($keys, $items)); + return new static(Arr::map($this->items, $callback)); } /** @@ -702,8 +773,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -731,8 +805,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { @@ -752,7 +829,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -763,8 +840,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -774,8 +853,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values) { @@ -785,7 +866,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Union the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -820,7 +901,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array|string|null $keys * @return static */ public function only($keys) @@ -842,7 +923,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Get and remove the last N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function pop($count = 1) { @@ -868,8 +949,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Push an item onto the beginning of the collection. * - * @param mixed $value - * @param mixed $key + * @param TValue $value + * @param TKey $key * @return $this */ public function prepend($value, $key = null) @@ -882,7 +963,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Push one or more items onto the end of the collection. * - * @param mixed $values + * @param TValue ...$values * @return $this */ public function push(...$values) @@ -897,7 +978,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source) @@ -914,9 +995,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get and remove an item from the collection. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TPullDefault + * + * @param TKey $key + * @param TPullDefault|(\Closure(): TPullDefault) $default + * @return TValue|TPullDefault */ public function pull($key, $default = null) { @@ -926,8 +1009,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Put an item in the collection by key. * - * @param mixed $key - * @param mixed $value + * @param TKey $key + * @param TValue $value * @return $this */ public function put($key, $value) @@ -940,8 +1023,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get one or a specified number of items randomly from the collection. * - * @param int|null $number - * @return static|mixed + * @param (callable(self): int)|int|null $number + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -951,13 +1034,17 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl return Arr::random($this->items); } + if (is_callable($number)) { + return new static(Arr::random($this->items, $number($this))); + } + return new static(Arr::random($this->items, $number)); } /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -968,7 +1055,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -989,9 +1076,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false) { @@ -1012,7 +1099,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Get and remove the first N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function shift($count = 1) { @@ -1051,7 +1138,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { @@ -1076,7 +1163,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1087,7 +1174,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1111,7 +1198,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1148,7 +1235,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1158,10 +1245,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Tightenco\Collect\Support\ItemNotFoundException * @throws \Tightenco\Collect\Support\MultipleItemsFoundException @@ -1172,14 +1259,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl ? $this->operatorForWhere(...func_get_args()) : $key; - $items = $this->when($filter)->filter($filter); + $items = $this->unless($filter == null)->filter($filter); - if ($items->isEmpty()) { + $count = $items->count(); + + if ($count === 0) { throw new ItemNotFoundException; } - if ($items->count() > 1) { - throw new MultipleItemsFoundException; + if ($count > 1) { + throw new MultipleItemsFoundException($count); } return $items->first(); @@ -1188,10 +1277,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Tightenco\Collect\Support\ItemNotFoundException */ @@ -1216,7 +1305,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1236,8 +1325,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1249,7 +1338,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Sort through each item with a callback. * - * @param callable|int|null $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1281,7 +1370,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Sort the collection using the given callback. * - * @param callable|array|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1319,14 +1408,14 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Sort the collection using multiple comparisons. * - * @param array $comparisons + * @param array $comparisons * @return static */ protected function sortByMany(array $comparisons = []) { $items = $this->items; - usort($items, function ($a, $b) use ($comparisons) { + uasort($items, function ($a, $b) use ($comparisons) { foreach ($comparisons as $comparison) { $comparison = Arr::wrap($comparison); @@ -1335,8 +1424,6 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl $ascending = Arr::get($comparison, 1, true) === true || Arr::get($comparison, 1, true) === 'asc'; - $result = 0; - if (! is_string($prop) && is_callable($prop)) { $result = $prop($a, $b); } else { @@ -1363,7 +1450,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -1402,7 +1489,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1419,7 +1506,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @param int $offset * @param int|null $length - * @param mixed $replacement + * @param array $replacement * @return static */ public function splice($offset, $length = null, $replacement = []) @@ -1449,7 +1536,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) @@ -1460,7 +1547,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) @@ -1471,7 +1558,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Transform each item in the collection using a callback. * - * @param callable $callback + * @param callable(TValue, TKey): TValue $callback * @return $this */ public function transform(callable $callback) @@ -1494,7 +1581,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1520,7 +1607,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1533,18 +1620,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ 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)); } @@ -1552,9 +1637,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1564,10 +1651,9 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get an iterator for the items. * - * @return \ArrayIterator + * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->items); } @@ -1577,8 +1663,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->items); } @@ -1586,8 +1671,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -1597,7 +1682,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Add an item to the collection. * - * @param mixed $item + * @param TValue $item * @return $this */ public function add($item) @@ -1610,7 +1695,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get a base Support collection instance from this collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Tightenco\Collect\Support\Collection */ public function toBase() { @@ -1620,11 +1705,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Determine if an item exists at an offset. * - * @param mixed $key + * @param TKey $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return isset($this->items[$key]); } @@ -1632,11 +1716,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get an item at a given offset. * - * @param mixed $key - * @return mixed + * @param TKey $key + * @return TValue */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items[$key]; } @@ -1644,12 +1727,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Set the item at a given offset. * - * @param mixed $key - * @param mixed $value + * @param TKey|null $key + * @param TValue $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { if (is_null($key)) { $this->items[] = $value; @@ -1661,11 +1743,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Unset the item at a given offset. * - * @param mixed $key + * @param TKey $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { unset($this->items[$key]); } diff --git a/vendor/tightenco/collect/src/Collect/Support/Enumerable.php b/vendor/tightenco/collect/src/Collect/Support/Enumerable.php index 60af386c..1f0db03a 100644 --- a/vendor/tightenco/collect/src/Collect/Support/Enumerable.php +++ b/vendor/tightenco/collect/src/Collect/Support/Enumerable.php @@ -2,19 +2,31 @@ namespace Tightenco\Collect\Support; +use CachingIterator; use Countable; use Tightenco\Collect\Contracts\Support\Arrayable; use Tightenco\Collect\Contracts\Support\Jsonable; use IteratorAggregate; use JsonSerializable; +use Traversable; +/** + * @template TKey of array-key + * @template TValue + * + * @extends \Tightenco\Collect\Contracts\Support\Arrayable + * @extends \IteratorAggregate + */ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable { /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []); @@ -39,16 +51,21 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value); /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value); @@ -69,38 +86,38 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null); /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null); /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null); /** * Collapse the items into a single enumerable. * - * @return static + * @return static */ public function collapse(); /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -110,8 +127,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Determine if an item exists, using strict comparison. * - * @param mixed $key - * @param mixed $value + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value * @return bool */ public function containsStrict($key, $value = null); @@ -119,26 +136,39 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null); /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool */ public function contains($key, $operator = null, $value = null); + /** + * Determine if an item is not contained in the collection. + * + * @param mixed $key + * @param mixed $operator + * @param mixed $value + * @return bool + */ + public function doesntContain($key, $operator = null, $value = null); + /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists); @@ -146,7 +176,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Dump the collection and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args); @@ -160,7 +190,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items); @@ -168,8 +198,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback); @@ -177,7 +207,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items); @@ -185,8 +215,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback); @@ -194,7 +224,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items); @@ -202,8 +232,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback); @@ -211,7 +241,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -220,7 +250,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null); @@ -228,7 +258,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback); @@ -244,7 +274,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -254,7 +284,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array $keys * @return static */ public function except($keys); @@ -262,64 +292,76 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue): bool)|null $callback * @return static */ public function filter(callable $callback = null); /** - * Apply the callback if the value is truthy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TWhenReturnType as null * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TWhenReturnType)|null $callback + * @param (callable($this): TWhenReturnType)|null $default + * @return $this|TWhenReturnType */ - public function when($value, callable $callback, callable $default = null); + public function when($value, callable $callback = null, callable $default = null); /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null); /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null); /** - * Apply the callback if the value is falsy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TUnlessReturnType * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TUnlessReturnType) $callback + * @param (callable($this): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType */ public function unless($value, callable $callback, callable $default = null); /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null); /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null); @@ -362,7 +404,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -372,7 +414,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values); @@ -381,7 +423,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values); @@ -390,7 +432,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values); @@ -399,7 +441,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -409,7 +451,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values); @@ -417,17 +459,21 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type); /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue,TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null); @@ -437,7 +483,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null); @@ -452,44 +498,54 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Flip the values with their keys. * - * @return static + * @return static */ public function flip(); /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null); /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false); /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy); /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key); + /** + * Determine if any of the keys exist in the collection. + * + * @param mixed $key + * @return bool + */ + public function hasAny($key); + /** * Concatenate values of a given key as a string. * @@ -502,7 +558,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items); @@ -510,7 +566,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items); @@ -529,6 +585,13 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, */ public function isNotEmpty(); + /** + * Determine if the collection contains a single item. + * + * @return bool + */ + public function containsOneItem(); + /** * Join all items from the collection using a string. The final items can use a separate glue string. * @@ -541,24 +604,28 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys(); /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null); /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback); @@ -575,8 +642,11 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback); @@ -585,8 +655,11 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback); @@ -595,31 +668,39 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback); /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Tightenco\Collect\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback); /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class); /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items); @@ -627,23 +708,27 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items); /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values); /** * Union the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items); @@ -651,7 +736,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null); @@ -659,7 +744,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null); @@ -676,7 +761,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array|string $keys * @return static */ public function only($keys); @@ -693,17 +778,17 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value - * @return static + * @return static, static> */ public function partition($key, $operator = null, $value = null); /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source); @@ -712,7 +797,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -721,16 +806,30 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null); + /** + * Reduce the collection to multiple aggregate values. + * + * @param callable $callback + * @param mixed ...$initial + * @return array + * + * @throws \UnexpectedValueException + */ + public function reduceSpread(callable $callback, ...$initial); + /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items); @@ -738,7 +837,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items); @@ -753,9 +852,9 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false); @@ -767,6 +866,15 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, */ public function shuffle($seed = null); + /** + * Create chunks representing a "sliding window" view of the items in the collection. + * + * @param int $size + * @param int $step + * @return static + */ + public function sliding($size = 2, $step = 1); + /** * Skip the first {$count} items. * @@ -778,7 +886,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value); @@ -786,7 +894,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value); @@ -804,30 +912,63 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups); + /** + * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Tightenco\Collect\Support\ItemNotFoundException + * @throws \Tightenco\Collect\Support\MultipleItemsFoundException + */ + public function sole($key = null, $operator = null, $value = null); + + /** + * Get the first item in the collection but throw an exception if no matching items exist. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Tightenco\Collect\Support\ItemNotFoundException + */ + public function firstOrFail($key = null, $operator = null, $value = null); + /** * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size); /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback); + /** + * Split a collection into a certain number of groups, and fill the first groups completely. + * + * @param int $numberOfGroups + * @return static + */ + public function splitIn($numberOfGroups); + /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null); @@ -843,7 +984,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -853,7 +994,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -876,10 +1017,18 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, */ public function sortKeysDesc($options = SORT_REGULAR); + /** + * Sort the collection keys using a callback. + * + * @param callable(TKey, TKey): int $callback + * @return static + */ + public function sortKeysUsing(callable $callback); + /** * Get the sum of the given values. * - * @param callable|string|null $callback + * @param (callable(TValue): mixed)|string|null $callback * @return mixed */ public function sum($callback = null); @@ -895,7 +1044,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value); @@ -903,7 +1052,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value); @@ -911,7 +1060,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Pass the collection to the given callback and then return it. * - * @param callable $callback + * @param callable(TValue): mixed $callback * @return $this */ public function tap(callable $callback); @@ -919,32 +1068,57 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Pass the enumerable to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback); + /** + * Pass the collection into a new class. + * + * @param class-string $class + * @return mixed + */ + public function pipeInto($class); + + /** + * Pass the collection through a series of callable pipes and return the result. + * + * @param array $pipes + * @return mixed + */ + public function pipeThrough($pipes); + /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null); /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true); + /** + * Convert a flatten "dot" notation array into an expanded array. + * + * @return static + */ + public function undot(); + /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -953,7 +1127,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null); @@ -961,26 +1135,42 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values(); /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value); /** - * Count the number of items in the collection using a given truth test. + * Get the values iterator. * - * @param callable|null $callback - * @return static + * @return \Traversable */ - public function countBy($callback = null); + public function getIterator(): Traversable; + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count(): int; + + /** + * Count the number of items in the collection by a field or using a callback. + * + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static + */ + public function countBy($countBy = null); /** * Zip the collection together with one or more arrays. @@ -988,18 +1178,50 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items); /** * Collect the values into a collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Tightenco\Collect\Support\Collection */ public function collect(); + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function toArray(); + + /** + * Convert the object into something JSON serializable. + * + * @return mixed + */ + public function jsonSerialize(): mixed; + + /** + * Get the collection of items as JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0); + + /** + * Get a CachingIterator instance. + * + * @param int $flags + * @return \CachingIterator + */ + public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING); + /** * Convert the collection to its string representation. * @@ -1007,6 +1229,14 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, */ public function __toString(); + /** + * Indicate that the model's string representation should be escaped when __toString is invoked. + * + * @param bool $escape + * @return $this + */ + public function escapeWhenCastingToString($escape = true); + /** * Add a method to the list of proxied methods. * diff --git a/vendor/tightenco/collect/src/Collect/Support/HigherOrderWhenProxy.php b/vendor/tightenco/collect/src/Collect/Support/HigherOrderWhenProxy.php deleted file mode 100644 index ea48c7c5..00000000 --- a/vendor/tightenco/collect/src/Collect/Support/HigherOrderWhenProxy.php +++ /dev/null @@ -1,63 +0,0 @@ -condition = $condition; - $this->collection = $collection; - } - - /** - * Proxy accessing an attribute onto the collection. - * - * @param string $key - * @return mixed - */ - public function __get($key) - { - return $this->condition - ? $this->collection->{$key} - : $this->collection; - } - - /** - * Proxy a method call onto the collection. - * - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call($method, $parameters) - { - return $this->condition - ? $this->collection->{$method}(...$parameters) - : $this->collection; - } -} diff --git a/vendor/tightenco/collect/src/Collect/Support/LazyCollection.php b/vendor/tightenco/collect/src/Collect/Support/LazyCollection.php index a54787d7..07327cb1 100644 --- a/vendor/tightenco/collect/src/Collect/Support/LazyCollection.php +++ b/vendor/tightenco/collect/src/Collect/Support/LazyCollection.php @@ -5,27 +5,39 @@ namespace Tightenco\Collect\Support; use ArrayIterator; use Closure; use DateTimeInterface; +use Generator; use Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString; use Tightenco\Collect\Support\Traits\EnumeratesValues; use Tightenco\Collect\Support\Traits\Macroable; +use InvalidArgumentException; use IteratorAggregate; use stdClass; +use Traversable; +/** + * @template TKey of array-key + * @template TValue + * + * @implements \Tightenco\Collect\Support\Enumerable + */ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Tightenco\Collect\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The source from which to generate items. * - * @var callable|static + * @var (Closure(): \Generator)|static|array */ public $source; /** * Create a new lazy collection instance. * - * @param mixed $source + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source * @return void */ public function __construct($source = null) @@ -34,17 +46,35 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable $this->source = $source; } elseif (is_null($source)) { $this->source = static::empty(); + } elseif ($source instanceof Generator) { + throw new InvalidArgumentException( + 'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.' + ); } else { $this->source = $this->getArrayableItems($source); } } + /** + * Create a new collection instance if the value isn't one already. + * + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items + * @return static + */ + public static function make($items = []) + { + return new static($items); + } + /** * Create a collection with the given range. * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -64,7 +94,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get all items in the enumerable. * - * @return array + * @return array */ public function all() { @@ -126,8 +156,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { @@ -137,8 +167,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { @@ -148,8 +178,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -159,7 +189,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -177,7 +207,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -187,6 +217,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable if (func_num_args() === 1 && $this->useAsCallable($key)) { $placeholder = new stdClass; + /** @var callable $key */ return $this->first($key, $placeholder) !== $placeholder; } @@ -205,6 +236,32 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + foreach ($this as $item) { + if ($item === $key) { + return true; + } + } + + return false; + } + /** * Determine if an item is not contained in the enumerable. * @@ -221,8 +278,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Cross join the given iterables, returning all possible permutations. * - * @param array ...$arrays - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$arrays + * @return static> */ public function crossJoin(...$arrays) { @@ -232,8 +292,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -261,7 +321,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -272,8 +332,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -284,7 +344,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -295,8 +355,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -307,7 +367,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -318,8 +378,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -330,7 +390,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -342,7 +402,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -353,7 +413,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -364,15 +424,13 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ 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) { @@ -387,9 +445,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -416,7 +476,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Get a flattened list of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -438,7 +498,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -452,9 +512,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get an item by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey|null $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -474,9 +536,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -486,8 +548,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -548,7 +610,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ @@ -560,7 +622,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -568,10 +630,45 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable return $this->passthru('intersect', func_get_args()); } + /** + * Intersect the collection with the given items, using the callback. + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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 \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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 \Tightenco\Collect\Contracts\Support\Arrayable|iterable $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. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -614,7 +711,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -628,9 +725,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -648,9 +747,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -678,8 +777,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { @@ -695,8 +796,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -708,8 +812,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { @@ -723,7 +830,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -734,8 +841,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -745,8 +854,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $values + * @return static */ public function combine($values) { @@ -776,7 +887,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Union the collection with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -809,7 +920,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Tightenco\Collect\Support\Enumerable|array|string $keys * @return static */ public function only($keys) @@ -844,7 +955,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Push all of the given items onto the collection. * - * @param iterable $source + * @param iterable $source * @return static */ public function concat($source) @@ -859,7 +970,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -873,7 +984,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -900,7 +1011,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -921,12 +1032,13 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false) { + /** @var (callable(TValue,TKey): bool) $predicate */ $predicate = $this->useAsCallable($value) ? $value : function ($item) use ($value, $strict) { @@ -958,7 +1070,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { @@ -971,7 +1083,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable $chunk[$iterator->key()] = $iterator->current(); if (count($chunk) == $size) { - yield tap(new static($chunk), function () use (&$chunk, $step) { + yield (new static($chunk))->tap(function () use (&$chunk, $step) { $chunk = array_slice($chunk, $step, null, true); }); @@ -1018,7 +1130,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1031,7 +1143,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1075,7 +1187,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1085,10 +1197,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Tightenco\Collect\Support\ItemNotFoundException * @throws \Tightenco\Collect\Support\MultipleItemsFoundException @@ -1100,7 +1212,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(2) ->collect() @@ -1110,10 +1222,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Tightenco\Collect\Support\ItemNotFoundException */ @@ -1124,7 +1236,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(1) ->collect() @@ -1135,7 +1247,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1174,7 +1286,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1184,8 +1296,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, Collection): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1221,7 +1333,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1243,7 +1355,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1256,7 +1368,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -1291,7 +1403,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1331,11 +1443,12 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) { + /** @var callable(TValue, TKey): bool $callback */ $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return new static(function () use ($callback) { @@ -1359,30 +1472,39 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable { $timeout = $timeout->getTimestamp(); - return $this->takeWhile(function () use ($timeout) { - return $this->now() < $timeout; + return new static(function () use ($timeout) { + if ($this->now() >= $timeout) { + return; + } + + foreach ($this as $key => $value) { + yield $key => $value; + + if ($this->now() >= $timeout) { + break; + } + } }); } /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) { + /** @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)); } /** * Pass each item in the collection to the given callback, lazily. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return static */ public function tapEach(callable $callback) @@ -1409,7 +1531,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1433,7 +1555,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1450,8 +1572,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items) { @@ -1473,9 +1597,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1501,10 +1627,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the values iterator. * - * @return \Traversable + * @return \Traversable */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->makeIterator($this->source); } @@ -1514,8 +1639,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { if (is_array($this->source)) { return count($this->source); @@ -1527,8 +1651,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Make an iterator from the given source. * - * @param mixed $source - * @return \Traversable + * @template TIteratorKey of array-key + * @template TIteratorValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $source + * @return \Traversable */ protected function makeIterator($source) { @@ -1540,15 +1667,23 @@ 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); } /** * Explode the "value" and "key" arguments passed to "pluck". * - * @param string|array $value - * @param string|array|null $key - * @return array + * @param string|string[] $value + * @param string|string[]|null $key + * @return array{string[],string[]|null} */ protected function explodePluckParameters($value, $key) { @@ -1563,7 +1698,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * Pass this lazy collection through a method on the collection class. * * @param string $method - * @param array $params + * @param array $params * @return static */ protected function passthru($method, array $params) diff --git a/vendor/tightenco/collect/src/Collect/Support/Str.php b/vendor/tightenco/collect/src/Collect/Support/Str.php new file mode 100644 index 00000000..ea109830 --- /dev/null +++ b/vendor/tightenco/collect/src/Collect/Support/Str.php @@ -0,0 +1,1367 @@ + $needles + * @param bool $ignoreCase + * @return bool + */ + public static function contains($haystack, $needles, $ignoreCase = false) + { + if ($ignoreCase) { + $haystack = mb_strtolower($haystack); + } + + if (! is_iterable($needles)) { + $needles = (array) $needles; + } + + foreach ($needles as $needle) { + if ($ignoreCase) { + $needle = mb_strtolower($needle); + } + + if ($needle !== '' && str_contains($haystack, $needle)) { + return true; + } + } + + return false; + } + + /** + * Determine if a given string contains all array values. + * + * @param string $haystack + * @param iterable $needles + * @param bool $ignoreCase + * @return bool + */ + public static function containsAll($haystack, $needles, $ignoreCase = false) + { + foreach ($needles as $needle) { + if (! static::contains($haystack, $needle, $ignoreCase)) { + return false; + } + } + + return true; + } + + /** + * Determine if a given string ends with a given substring. + * + * @param string $haystack + * @param string|iterable $needles + * @return bool + */ + public static function endsWith($haystack, $needles) + { + if (! is_iterable($needles)) { + $needles = (array) $needles; + } + + foreach ($needles as $needle) { + if ((string) $needle !== '' && str_ends_with($haystack, $needle)) { + return true; + } + } + + return false; + } + + /** + * Extracts an excerpt from text that matches the first instance of a phrase. + * + * @param string $text + * @param string $phrase + * @param array $options + * @return string|null + */ + public static function excerpt($text, $phrase = '', $options = []) + { + $radius = $options['radius'] ?? 100; + $omission = $options['omission'] ?? '...'; + + preg_match('/^(.*?)('.preg_quote((string) $phrase).')(.*)$/iu', (string) $text, $matches); + + if (empty($matches)) { + return null; + } + + $start = ltrim($matches[1]); + + $start = str(mb_substr($start, max(mb_strlen($start, 'UTF-8') - $radius, 0), $radius, 'UTF-8'))->ltrim()->unless( + fn ($startWithRadius) => $startWithRadius->exactly($start), + fn ($startWithRadius) => $startWithRadius->prepend($omission), + ); + + $end = rtrim($matches[3]); + + $end = str(mb_substr($end, 0, $radius, 'UTF-8'))->rtrim()->unless( + fn ($endWithRadius) => $endWithRadius->exactly($end), + fn ($endWithRadius) => $endWithRadius->append($omission), + ); + + return $start->append($matches[2], $end)->toString(); + } + + /** + * Cap a string with a single instance of a given value. + * + * @param string $value + * @param string $cap + * @return string + */ + public static function finish($value, $cap) + { + $quoted = preg_quote($cap, '/'); + + return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap; + } + + /** + * Wrap the string with the given strings. + * + * @param string $value + * @param string $before + * @param string|null $after + * @return string + */ + public static function wrap($value, $before, $after = null) + { + return $before.$value.($after ??= $before); + } + + /** + * Determine if a given string matches a given pattern. + * + * @param string|iterable $pattern + * @param string $value + * @return bool + */ + public static function is($pattern, $value) + { + $value = (string) $value; + + if (! is_iterable($pattern)) { + $pattern = [$pattern]; + } + + foreach ($pattern as $pattern) { + $pattern = (string) $pattern; + + // If the given value is an exact match we can of course return true right + // from the beginning. Otherwise, we will translate asterisks and do an + // actual pattern match against the two strings to see if they match. + if ($pattern === $value) { + return true; + } + + $pattern = preg_quote($pattern, '#'); + + // Asterisks are translated into zero-or-more regular expression wildcards + // to make it convenient to check if the strings starts with the given + // pattern such as "library/*", making any string check convenient. + $pattern = str_replace('\*', '.*', $pattern); + + if (preg_match('#^'.$pattern.'\z#u', $value) === 1) { + return true; + } + } + + return false; + } + + /** + * Determine if a given string is 7 bit ASCII. + * + * @param string $value + * @return bool + */ + public static function isAscii($value) + { + return ASCII::is_ascii((string) $value); + } + + /** + * Determine if a given string is valid JSON. + * + * @param string $value + * @return bool + */ + public static function isJson($value) + { + if (! is_string($value)) { + return false; + } + + try { + json_decode($value, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException) { + return false; + } + + return true; + } + + /** + * Determine if a given string is a valid UUID. + * + * @param string $value + * @return bool + */ + public static function isUuid($value) + { + if (! is_string($value)) { + return false; + } + + return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; + } + + /** + * Determine if a given string is a valid ULID. + * + * @param string $value + * @return bool + */ + public static function isUlid($value) + { + if (! is_string($value)) { + return false; + } + + return Ulid::isValid($value); + } + + /** + * Convert a string to kebab case. + * + * @param string $value + * @return string + */ + public static function kebab($value) + { + return static::snake($value, '-'); + } + + /** + * Return the length of the given string. + * + * @param string $value + * @param string|null $encoding + * @return int + */ + public static function length($value, $encoding = null) + { + if ($encoding) { + return mb_strlen($value, $encoding); + } + + return mb_strlen($value); + } + + /** + * Limit the number of characters in a string. + * + * @param string $value + * @param int $limit + * @param string $end + * @return string + */ + public static function limit($value, $limit = 100, $end = '...') + { + if (mb_strwidth($value, 'UTF-8') <= $limit) { + return $value; + } + + return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end; + } + + /** + * Convert the given string to lower-case. + * + * @param string $value + * @return string + */ + public static function lower($value) + { + return mb_strtolower($value, 'UTF-8'); + } + + /** + * Limit the number of words in a string. + * + * @param string $value + * @param int $words + * @param string $end + * @return string + */ + public static function words($value, $words = 100, $end = '...') + { + preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches); + + if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) { + return $value; + } + + return rtrim($matches[0]).$end; + } + + /** + * Converts GitHub flavored Markdown into HTML. + * + * @param string $string + * @param array $options + * @return string + */ + public static function markdown($string, array $options = []) + { + $converter = new GithubFlavoredMarkdownConverter($options); + + return (string) $converter->convert($string); + } + + /** + * Converts inline Markdown into HTML. + * + * @param string $string + * @param array $options + * @return string + */ + public static function inlineMarkdown($string, array $options = []) + { + $environment = new Environment($options); + + $environment->addExtension(new GithubFlavoredMarkdownExtension()); + $environment->addExtension(new InlinesOnlyExtension()); + + $converter = new MarkdownConverter($environment); + + return (string) $converter->convert($string); + } + + /** + * Masks a portion of a string with a repeated character. + * + * @param string $string + * @param string $character + * @param int $index + * @param int|null $length + * @param string $encoding + * @return string + */ + public static function mask($string, $character, $index, $length = null, $encoding = 'UTF-8') + { + if ($character === '') { + return $string; + } + + $segment = mb_substr($string, $index, $length, $encoding); + + if ($segment === '') { + return $string; + } + + $strlen = mb_strlen($string, $encoding); + $startIndex = $index; + + if ($index < 0) { + $startIndex = $index < -$strlen ? 0 : $strlen + $index; + } + + $start = mb_substr($string, 0, $startIndex, $encoding); + $segmentLen = mb_strlen($segment, $encoding); + $end = mb_substr($string, $startIndex + $segmentLen); + + return $start.str_repeat(mb_substr($character, 0, 1, $encoding), $segmentLen).$end; + } + + /** + * Get the string matching the given pattern. + * + * @param string $pattern + * @param string $subject + * @return string + */ + public static function match($pattern, $subject) + { + preg_match($pattern, $subject, $matches); + + if (! $matches) { + return ''; + } + + return $matches[1] ?? $matches[0]; + } + + /** + * Get the string matching the given pattern. + * + * @param string $pattern + * @param string $subject + * @return \Tightenco\Collect\Support\Collection + */ + public static function matchAll($pattern, $subject) + { + preg_match_all($pattern, $subject, $matches); + + if (empty($matches[0])) { + return collect(); + } + + return collect($matches[1] ?? $matches[0]); + } + + /** + * Pad both sides of a string with another. + * + * @param string $value + * @param int $length + * @param string $pad + * @return string + */ + public static function padBoth($value, $length, $pad = ' ') + { + $short = max(0, $length - mb_strlen($value)); + $shortLeft = floor($short / 2); + $shortRight = ceil($short / 2); + + return mb_substr(str_repeat($pad, $shortLeft), 0, $shortLeft). + $value. + mb_substr(str_repeat($pad, $shortRight), 0, $shortRight); + } + + /** + * Pad the left side of a string with another. + * + * @param string $value + * @param int $length + * @param string $pad + * @return string + */ + public static function padLeft($value, $length, $pad = ' ') + { + $short = max(0, $length - mb_strlen($value)); + + return mb_substr(str_repeat($pad, $short), 0, $short).$value; + } + + /** + * Pad the right side of a string with another. + * + * @param string $value + * @param int $length + * @param string $pad + * @return string + */ + public static function padRight($value, $length, $pad = ' ') + { + $short = max(0, $length - mb_strlen($value)); + + return $value.mb_substr(str_repeat($pad, $short), 0, $short); + } + + /** + * Parse a Class[@]method style callback into class and method. + * + * @param string $callback + * @param string|null $default + * @return array + */ + public static function parseCallback($callback, $default = null) + { + return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default]; + } + + /** + * Get the plural form of an English word. + * + * @param string $value + * @param int|array|\Countable $count + * @return string + */ + public static function plural($value, $count = 2) + { + return Pluralizer::plural($value, $count); + } + + /** + * Pluralize the last word of an English, studly caps case string. + * + * @param string $value + * @param int|array|\Countable $count + * @return string + */ + public static function pluralStudly($value, $count = 2) + { + $parts = preg_split('/(.)(?=[A-Z])/u', $value, -1, PREG_SPLIT_DELIM_CAPTURE); + + $lastWord = array_pop($parts); + + return implode('', $parts).self::plural($lastWord, $count); + } + + /** + * Generate a more truly "random" alpha-numeric string. + * + * @param int $length + * @return string + */ + public static function random($length = 16) + { + return (static::$randomStringFactory ?? function ($length) { + $string = ''; + + while (($len = strlen($string)) < $length) { + $size = $length - $len; + + $bytesSize = (int) ceil(($size) / 3) * 3; + + $bytes = random_bytes($bytesSize); + + $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); + } + + return $string; + })($length); + } + + /** + * Set the callable that will be used to generate random strings. + * + * @param callable|null $factory + * @return void + */ + public static function createRandomStringsUsing(callable $factory = null) + { + static::$randomStringFactory = $factory; + } + + /** + * Set the sequence that will be used to generate random strings. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function createRandomStringsUsingSequence(array $sequence, $whenMissing = null) + { + $next = 0; + + $whenMissing ??= function ($length) use (&$next) { + $factoryCache = static::$randomStringFactory; + + static::$randomStringFactory = null; + + $randomString = static::random($length); + + static::$randomStringFactory = $factoryCache; + + $next++; + + return $randomString; + }; + + static::createRandomStringsUsing(function ($length) use (&$next, $sequence, $whenMissing) { + if (array_key_exists($next, $sequence)) { + return $sequence[$next++]; + } + + return $whenMissing($length); + }); + } + + /** + * Indicate that random strings should be created normally and not using a custom factory. + * + * @return void + */ + public static function createRandomStringsNormally() + { + static::$randomStringFactory = null; + } + + /** + * Repeat the given string. + * + * @param string $string + * @param int $times + * @return string + */ + public static function repeat(string $string, int $times) + { + return str_repeat($string, $times); + } + + /** + * Replace a given value in the string sequentially with an array. + * + * @param string $search + * @param iterable $replace + * @param string $subject + * @return string + */ + public static function replaceArray($search, $replace, $subject) + { + if ($replace instanceof Traversable) { + $replace = collect($replace)->all(); + } + + $segments = explode($search, $subject); + + $result = array_shift($segments); + + foreach ($segments as $segment) { + $result .= (array_shift($replace) ?? $search).$segment; + } + + return $result; + } + + /** + * Replace the given value in the given string. + * + * @param string|iterable $search + * @param string|iterable $replace + * @param string|iterable $subject + * @return string + */ + public static function replace($search, $replace, $subject) + { + if ($search instanceof Traversable) { + $search = collect($search)->all(); + } + + if ($replace instanceof Traversable) { + $replace = collect($replace)->all(); + } + + if ($subject instanceof Traversable) { + $subject = collect($subject)->all(); + } + + return str_replace($search, $replace, $subject); + } + + /** + * Replace the first occurrence of a given value in the string. + * + * @param string $search + * @param string $replace + * @param string $subject + * @return string + */ + public static function replaceFirst($search, $replace, $subject) + { + $search = (string) $search; + + if ($search === '') { + return $subject; + } + + $position = strpos($subject, $search); + + if ($position !== false) { + return substr_replace($subject, $replace, $position, strlen($search)); + } + + return $subject; + } + + /** + * Replace the last occurrence of a given value in the string. + * + * @param string $search + * @param string $replace + * @param string $subject + * @return string + */ + public static function replaceLast($search, $replace, $subject) + { + if ($search === '') { + return $subject; + } + + $position = strrpos($subject, $search); + + if ($position !== false) { + return substr_replace($subject, $replace, $position, strlen($search)); + } + + return $subject; + } + + /** + * Remove any occurrence of the given string in the subject. + * + * @param string|iterable $search + * @param string $subject + * @param bool $caseSensitive + * @return string + */ + public static function remove($search, $subject, $caseSensitive = true) + { + if ($search instanceof Traversable) { + $search = collect($search)->all(); + } + + $subject = $caseSensitive + ? str_replace($search, '', $subject) + : str_ireplace($search, '', $subject); + + return $subject; + } + + /** + * Reverse the given string. + * + * @param string $value + * @return string + */ + public static function reverse(string $value) + { + return implode(array_reverse(mb_str_split($value))); + } + + /** + * Begin a string with a single instance of a given value. + * + * @param string $value + * @param string $prefix + * @return string + */ + public static function start($value, $prefix) + { + $quoted = preg_quote($prefix, '/'); + + return $prefix.preg_replace('/^(?:'.$quoted.')+/u', '', $value); + } + + /** + * Convert the given string to upper-case. + * + * @param string $value + * @return string + */ + public static function upper($value) + { + return mb_strtoupper($value, 'UTF-8'); + } + + /** + * Convert the given string to title case. + * + * @param string $value + * @return string + */ + public static function title($value) + { + return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8'); + } + + /** + * Convert the given string to title case for each word. + * + * @param string $value + * @return string + */ + public static function headline($value) + { + $parts = explode(' ', $value); + + $parts = count($parts) > 1 + ? array_map([static::class, 'title'], $parts) + : array_map([static::class, 'title'], static::ucsplit(implode('_', $parts))); + + $collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts)); + + return implode(' ', array_filter(explode('_', $collapsed))); + } + + /** + * Get the singular form of an English word. + * + * @param string $value + * @return string + */ + public static function singular($value) + { + return Pluralizer::singular($value); + } + + /** + * Generate a URL friendly "slug" from a given string. + * + * @param string $title + * @param string $separator + * @param string|null $language + * @param array $dictionary + * @return string + */ + public static function slug($title, $separator = '-', $language = 'en', $dictionary = ['@' => 'at']) + { + $title = $language ? static::ascii($title, $language) : $title; + + // Convert all dashes/underscores into separator + $flip = $separator === '-' ? '_' : '-'; + + $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title); + + // Replace dictionary words + foreach ($dictionary as $key => $value) { + $dictionary[$key] = $separator.$value.$separator; + } + + $title = str_replace(array_keys($dictionary), array_values($dictionary), $title); + + // Remove all characters that are not the separator, letters, numbers, or whitespace + $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', static::lower($title)); + + // Replace all separator characters and whitespace by a single separator + $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title); + + return trim($title, $separator); + } + + /** + * Convert a string to snake case. + * + * @param string $value + * @param string $delimiter + * @return string + */ + public static function snake($value, $delimiter = '_') + { + $key = $value; + + if (isset(static::$snakeCache[$key][$delimiter])) { + return static::$snakeCache[$key][$delimiter]; + } + + if (! ctype_lower($value)) { + $value = preg_replace('/\s+/u', '', ucwords($value)); + + $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value)); + } + + return static::$snakeCache[$key][$delimiter] = $value; + } + + /** + * Remove all "extra" blank space from the given string. + * + * @param string $value + * @return string + */ + public static function squish($value) + { + return preg_replace('~(\s|\x{3164})+~u', ' ', preg_replace('~^[\s\x{FEFF}]+|[\s\x{FEFF}]+$~u', '', $value)); + } + + /** + * Determine if a given string starts with a given substring. + * + * @param string $haystack + * @param string|iterable $needles + * @return bool + */ + public static function startsWith($haystack, $needles) + { + if (! is_iterable($needles)) { + $needles = [$needles]; + } + + foreach ($needles as $needle) { + if ((string) $needle !== '' && str_starts_with($haystack, $needle)) { + return true; + } + } + + return false; + } + + /** + * Convert a value to studly caps case. + * + * @param string $value + * @return string + */ + public static function studly($value) + { + $key = $value; + + if (isset(static::$studlyCache[$key])) { + return static::$studlyCache[$key]; + } + + $words = explode(' ', static::replace(['-', '_'], ' ', $value)); + + $studlyWords = array_map(fn ($word) => static::ucfirst($word), $words); + + return static::$studlyCache[$key] = implode($studlyWords); + } + + /** + * Returns the portion of the string specified by the start and length parameters. + * + * @param string $string + * @param int $start + * @param int|null $length + * @param string $encoding + * @return string + */ + public static function substr($string, $start, $length = null, $encoding = 'UTF-8') + { + return mb_substr($string, $start, $length, $encoding); + } + + /** + * Returns the number of substring occurrences. + * + * @param string $haystack + * @param string $needle + * @param int $offset + * @param int|null $length + * @return int + */ + public static function substrCount($haystack, $needle, $offset = 0, $length = null) + { + if (! is_null($length)) { + return substr_count($haystack, $needle, $offset, $length); + } + + return substr_count($haystack, $needle, $offset); + } + + /** + * Replace text within a portion of a string. + * + * @param string|string[] $string + * @param string|string[] $replace + * @param int|int[] $offset + * @param int|int[]|null $length + * @return string|string[] + */ + public static function substrReplace($string, $replace, $offset = 0, $length = null) + { + if ($length === null) { + $length = strlen($string); + } + + return substr_replace($string, $replace, $offset, $length); + } + + /** + * Swap multiple keywords in a string with other keywords. + * + * @param array $map + * @param string $subject + * @return string + */ + public static function swap(array $map, $subject) + { + return strtr($subject, $map); + } + + /** + * Make a string's first character lowercase. + * + * @param string $string + * @return string + */ + public static function lcfirst($string) + { + return static::lower(static::substr($string, 0, 1)).static::substr($string, 1); + } + + /** + * Make a string's first character uppercase. + * + * @param string $string + * @return string + */ + public static function ucfirst($string) + { + return static::upper(static::substr($string, 0, 1)).static::substr($string, 1); + } + + /** + * Split a string into pieces by uppercase characters. + * + * @param string $string + * @return string[] + */ + public static function ucsplit($string) + { + return preg_split('/(?=\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY); + } + + /** + * Get the number of words a string contains. + * + * @param string $string + * @param string|null $characters + * @return int + */ + public static function wordCount($string, $characters = null) + { + return str_word_count($string, 0, $characters); + } + + /** + * Generate a UUID (version 4). + * + * @return \Ramsey\Uuid\UuidInterface + */ + public static function uuid() + { + return static::$uuidFactory + ? call_user_func(static::$uuidFactory) + : Uuid::uuid4(); + } + + /** + * Generate a time-ordered UUID (version 4). + * + * @return \Ramsey\Uuid\UuidInterface + */ + public static function orderedUuid() + { + if (static::$uuidFactory) { + return call_user_func(static::$uuidFactory); + } + + $factory = new UuidFactory; + + $factory->setRandomGenerator(new CombGenerator( + $factory->getRandomGenerator(), + $factory->getNumberConverter() + )); + + $factory->setCodec(new TimestampFirstCombCodec( + $factory->getUuidBuilder() + )); + + return $factory->uuid4(); + } + + /** + * Set the callable that will be used to generate UUIDs. + * + * @param callable|null $factory + * @return void + */ + public static function createUuidsUsing(callable $factory = null) + { + static::$uuidFactory = $factory; + } + + /** + * Set the sequence that will be used to generate UUIDs. + * + * @param array $sequence + * @param callable|null $whenMissing + * @return void + */ + public static function createUuidsUsingSequence(array $sequence, $whenMissing = null) + { + $next = 0; + + $whenMissing ??= function () use (&$next) { + $factoryCache = static::$uuidFactory; + + static::$uuidFactory = null; + + $uuid = static::uuid(); + + static::$uuidFactory = $factoryCache; + + $next++; + + return $uuid; + }; + + static::createUuidsUsing(function () use (&$next, $sequence, $whenMissing) { + if (array_key_exists($next, $sequence)) { + return $sequence[$next++]; + } + + return $whenMissing(); + }); + } + + /** + * Always return the same UUID when generating new UUIDs. + * + * @param \Closure|null $callback + * @return \Ramsey\Uuid\UuidInterface + */ + public static function freezeUuids(Closure $callback = null) + { + $uuid = Str::uuid(); + + Str::createUuidsUsing(fn () => $uuid); + + if ($callback !== null) { + try { + $callback($uuid); + } finally { + Str::createUuidsNormally(); + } + } + + return $uuid; + } + + /** + * Indicate that UUIDs should be created normally and not using a custom factory. + * + * @return void + */ + public static function createUuidsNormally() + { + static::$uuidFactory = null; + } + + /** + * Generate a ULID. + * + * @return \Symfony\Component\Uid\Ulid + */ + public static function ulid() + { + return new Ulid(); + } + + /** + * Remove all strings from the casing caches. + * + * @return void + */ + public static function flushCache() + { + static::$snakeCache = []; + static::$camelCache = []; + static::$studlyCache = []; + } +} diff --git a/vendor/tightenco/collect/src/Collect/Support/Traits/Conditionable.php b/vendor/tightenco/collect/src/Collect/Support/Traits/Conditionable.php new file mode 100644 index 00000000..f5249923 --- /dev/null +++ b/vendor/tightenco/collect/src/Collect/Support/Traits/Conditionable.php @@ -0,0 +1,73 @@ +condition($value); + } + + if ($value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } + + /** + * Apply the callback if the given "value" is (or resolves to) falsy. + * + * @template TUnlessParameter + * @template TUnlessReturnType + * + * @param (\Closure($this): TUnlessParameter)|TUnlessParameter|null $value + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $callback + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType + */ + public function unless($value = null, callable $callback = null, callable $default = null) + { + $value = $value instanceof Closure ? $value($this) : $value; + + if (func_num_args() === 0) { + return (new HigherOrderWhenProxy($this))->negateConditionOnCapture(); + } + + if (func_num_args() === 1) { + return (new HigherOrderWhenProxy($this))->condition(! $value); + } + + if (! $value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } +} diff --git a/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php b/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php index 2f1187f0..25cde221 100644 --- a/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php +++ b/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php @@ -11,7 +11,6 @@ use Tightenco\Collect\Support\Arr; use Tightenco\Collect\Support\Collection; use Tightenco\Collect\Support\Enumerable; use Tightenco\Collect\Support\HigherOrderCollectionProxy; -use Tightenco\Collect\Support\HigherOrderWhenProxy; use JsonSerializable; use Symfony\Component\VarDumper\VarDumper; use Traversable; @@ -19,6 +18,9 @@ use UnexpectedValueException; use UnitEnum; /** + * @template TKey of array-key + * @template TValue + * * @property-read HigherOrderCollectionProxy $average * @property-read HigherOrderCollectionProxy $avg * @property-read HigherOrderCollectionProxy $contains @@ -35,19 +37,23 @@ use UnitEnum; * @property-read HigherOrderCollectionProxy $min * @property-read HigherOrderCollectionProxy $partition * @property-read HigherOrderCollectionProxy $reject + * @property-read HigherOrderCollectionProxy $skipUntil + * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $some * @property-read HigherOrderCollectionProxy $sortBy * @property-read HigherOrderCollectionProxy $sortByDesc - * @property-read HigherOrderCollectionProxy $skipUntil - * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $takeUntil * @property-read HigherOrderCollectionProxy $takeWhile * @property-read HigherOrderCollectionProxy $unique + * @property-read HigherOrderCollectionProxy $unless * @property-read HigherOrderCollectionProxy $until + * @property-read HigherOrderCollectionProxy $when */ trait EnumeratesValues { + use Conditionable; + /** * Indicates that the object's string representation should be escaped when __toString is invoked. * @@ -58,7 +64,7 @@ trait EnumeratesValues /** * The methods that can be proxied. * - * @var string[] + * @var array */ protected static $proxies = [ 'average', @@ -86,14 +92,19 @@ trait EnumeratesValues 'takeUntil', 'takeWhile', 'unique', + 'unless', 'until', + 'when', ]; /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []) { @@ -103,8 +114,10 @@ trait EnumeratesValues /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value) { @@ -116,8 +129,11 @@ trait EnumeratesValues /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value) { @@ -137,9 +153,11 @@ trait EnumeratesValues /** * Create a new collection by invoking the callback a given amount of times. * + * @template TTimesValue + * * @param int $number - * @param callable|null $callback - * @return static + * @param (callable(int): TTimesValue)|null $callback + * @return static */ public static function times($number, callable $callback = null) { @@ -148,15 +166,15 @@ trait EnumeratesValues } return static::range(1, $number) - ->when($callback) + ->unless($callback == null) ->map($callback); } /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null) { @@ -166,7 +184,7 @@ trait EnumeratesValues /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,39 +194,11 @@ trait EnumeratesValues return $this->contains(...func_get_args()); } - /** - * Determine if an item exists, using strict comparison. - * - * @param mixed $key - * @param mixed $value - * @return bool - */ - public function containsStrict($key, $value = null) - { - if (func_num_args() === 2) { - return $this->contains(function ($item) use ($key, $value) { - return data_get($item, $key) === $value; - }); - } - - if ($this->useAsCallable($key)) { - return ! is_null($this->first($key)); - } - - foreach ($this as $item) { - if ($item === $key) { - return true; - } - } - - return false; - } - /** * Dump the items and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args) { @@ -236,7 +226,7 @@ trait EnumeratesValues /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback) @@ -253,7 +243,7 @@ trait EnumeratesValues /** * Execute a callback over each nested chunk of items. * - * @param callable $callback + * @param callable(...mixed): mixed $callback * @return static */ public function eachSpread(callable $callback) @@ -268,7 +258,7 @@ trait EnumeratesValues /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -293,16 +283,32 @@ trait EnumeratesValues /** * Get the first item by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null) { return $this->first($this->operatorForWhere(...func_get_args())); } + /** + * Get a single key's value from the first matching item in the collection. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function value($key, $default = null) + { + if ($value = $this->firstWhere($key)) { + return data_get($value, $key, $default); + } + + return value($default); + } + /** * Determine if the collection is not empty. * @@ -316,8 +322,10 @@ trait EnumeratesValues /** * Run a map over each nested chunk of items. * - * @param callable $callback - * @return static + * @template TMapSpreadValue + * + * @param callable(mixed): TMapSpreadValue $callback + * @return static */ public function mapSpread(callable $callback) { @@ -333,8 +341,11 @@ trait EnumeratesValues * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback) { @@ -346,8 +357,11 @@ trait EnumeratesValues /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Tightenco\Collect\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback) { @@ -357,48 +371,42 @@ trait EnumeratesValues /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class) { - return $this->map(function ($value, $key) use ($class) { - return new $class($value, $key); - }); + return $this->map(fn ($value, $key) => new $class($value, $key)); } /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null) { $callback = $this->valueRetriever($callback); - return $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $value) { - return is_null($result) || $value < $result ? $value : $result; - }); + return $this->map(fn ($value) => $callback($value)) + ->filter(fn ($value) => ! is_null($value)) + ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result); } /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null) { $callback = $this->valueRetriever($callback); - return $this->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $item) use ($callback) { + return $this->filter(fn ($value) => ! is_null($value))->reduce(function ($result, $item) use ($callback) { $value = $callback($item); return is_null($result) || $value > $result ? $value : $result; @@ -422,10 +430,10 @@ trait EnumeratesValues /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key - * @param mixed $operator - * @param mixed $value - * @return static + * @param (callable(TValue, TKey): bool)|TValue|string $key + * @param TValue|string|null $operator + * @param TValue|null $value + * @return static, static> */ public function partition($key, $operator = null, $value = null) { @@ -450,7 +458,7 @@ trait EnumeratesValues /** * Get the sum of the given values. * - * @param callable|string|null $callback + * @param (callable(TValue): mixed)|string|null $callback * @return mixed */ public function sum($callback = null) @@ -459,40 +467,17 @@ trait EnumeratesValues ? $this->identity() : $this->valueRetriever($callback); - return $this->reduce(function ($result, $item) use ($callback) { - return $result + $callback($item); - }, 0); - } - - /** - * Apply the callback if the value is truthy. - * - * @param bool|mixed $value - * @param callable|null $callback - * @param callable|null $default - * @return static|mixed - */ - public function when($value, callable $callback = null, callable $default = null) - { - if (! $callback) { - return new HigherOrderWhenProxy($this, $value); - } - - if ($value) { - return $callback($this, $value); - } elseif ($default) { - return $default($this, $value); - } - - return $this; + return $this->reduce(fn ($result, $item) => $result + $callback($item), 0); } /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null) { @@ -502,34 +487,25 @@ trait EnumeratesValues /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } - /** - * Apply the callback if the value is falsy. - * - * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed - */ - public function unless($value, callable $callback, callable $default = null) - { - return $this->when(! $value, $callback, $default); - } - /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null) { @@ -539,9 +515,11 @@ trait EnumeratesValues /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null) { @@ -551,7 +529,7 @@ trait EnumeratesValues /** * Filter items by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value * @return static @@ -599,7 +577,7 @@ trait EnumeratesValues * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -607,16 +585,14 @@ trait EnumeratesValues { $values = $this->getArrayableItems($values); - return $this->filter(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values) @@ -628,7 +604,7 @@ trait EnumeratesValues * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values) @@ -640,21 +616,21 @@ trait EnumeratesValues * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values) { - return $this->filter(function ($item) use ($key, $values) { - return data_get($item, $key) < reset($values) || data_get($item, $key) > end($values); - }); + return $this->filter( + fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values) + ); } /** * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -662,16 +638,14 @@ trait EnumeratesValues { $values = $this->getArrayableItems($values); - return $this->reject(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values) @@ -682,8 +656,10 @@ trait EnumeratesValues /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type) { @@ -705,8 +681,10 @@ trait EnumeratesValues /** * Pass the collection to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback) { @@ -716,7 +694,7 @@ trait EnumeratesValues /** * Pass the collection into a new class. * - * @param string $class + * @param class-string $class * @return mixed */ public function pipeInto($class) @@ -727,38 +705,26 @@ trait EnumeratesValues /** * Pass the collection through a series of callable pipes and return the result. * - * @param array $pipes + * @param array $callbacks * @return mixed */ - public function pipeThrough($pipes) + public function pipeThrough($callbacks) { - return static::make($pipes)->reduce( - function ($carry, $pipe) { - return $pipe($carry); - }, + return Collection::make($callbacks)->reduce( + fn ($carry, $callback) => $callback($carry), $this, ); } - /** - * Pass the collection to the given callback and then return it. - * - * @param callable $callback - * @return $this - */ - public function tap(callable $callback) - { - $callback(clone $this); - - return $this; - } - /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null) { @@ -771,22 +737,6 @@ trait EnumeratesValues return $result; } - /** - * Reduce the collection to multiple aggregate values. - * - * @param callable $callback - * @param mixed ...$initial - * @return array - * - * @deprecated Use "reduceSpread" instead - * - * @throws \UnexpectedValueException - */ - public function reduceMany(callable $callback, ...$initial) - { - return $this->reduceSpread($callback, ...$initial); - } - /** * Reduce the collection to multiple aggregate values. * @@ -805,7 +755,7 @@ trait EnumeratesValues if (! is_array($result)) { throw new UnexpectedValueException(sprintf( - "%s::reduceMany expects reducer to return an array, but got a '%s' instead.", + "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.", class_basename(static::class), gettype($result) )); } @@ -814,22 +764,10 @@ trait EnumeratesValues return $result; } - /** - * Reduce an associative collection to a single value. - * - * @param callable $callback - * @param mixed $initial - * @return mixed - */ - public function reduceWithKeys(callable $callback, $initial = null) - { - return $this->reduce($callback, $initial); - } - /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true) @@ -843,10 +781,45 @@ trait EnumeratesValues }); } + /** + * Pass the collection to the given callback and then return it. + * + * @param callable($this): mixed $callback + * @return $this + */ + public function tap(callable $callback) + { + $callback($this); + + return $this; + } + + /** + * Return only unique items from the collection array. + * + * @param (callable(TValue, TKey): mixed)|string|null $key + * @param bool $strict + * @return static + */ + public function unique($key = null, $strict = false) + { + $callback = $this->valueRetriever($key); + + $exists = []; + + return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { + if (in_array($id = $callback($item, $key), $exists, $strict)) { + return true; + } + + $exists[] = $id; + }); + } + /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null) @@ -857,7 +830,7 @@ trait EnumeratesValues /** * Collect the values into a collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Tightenco\Collect\Support\Collection */ public function collect() { @@ -867,22 +840,19 @@ trait EnumeratesValues /** * Get the collection of items as a plain array. * - * @return array + * @return array */ public function toArray() { - return $this->map(function ($value) { - return $value instanceof Arrayable ? $value->toArray() : $value; - })->all(); + return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all(); } /** * Convert the object into something JSON serializable. * - * @return array + * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return array_map(function ($value) { if ($value instanceof JsonSerializable) { @@ -976,7 +946,7 @@ trait EnumeratesValues * Results array of items from Collection or Arrayable. * * @param mixed $items - * @return array + * @return array */ protected function getArrayableItems($items) { @@ -986,12 +956,12 @@ trait EnumeratesValues return $items->all(); } elseif ($items instanceof Arrayable) { return $items->toArray(); + } elseif ($items instanceof Traversable) { + return iterator_to_array($items); } elseif ($items instanceof Jsonable) { return json_decode($items->toJson(), true); } elseif ($items instanceof JsonSerializable) { return (array) $items->jsonSerialize(); - } elseif ($items instanceof Traversable) { - return iterator_to_array($items); } elseif ($items instanceof UnitEnum) { return [$items]; } @@ -1002,13 +972,17 @@ trait EnumeratesValues /** * Get an operator checker callback. * - * @param string $key + * @param callable|string $key * @param string|null $operator * @param mixed $value * @return \Closure */ protected function operatorForWhere($key, $operator = null, $value = null) { + if ($this->useAsCallable($key)) { + return $key; + } + if (func_num_args() === 1) { $value = true; @@ -1044,6 +1018,7 @@ trait EnumeratesValues case '>=': return $retrieved >= $value; case '===': return $retrieved === $value; case '!==': return $retrieved !== $value; + case '<=>': return $retrieved <=> $value; } }; } @@ -1071,22 +1046,18 @@ trait EnumeratesValues return $value; } - return function ($item) use ($value) { - return data_get($item, $value); - }; + return fn ($item) => data_get($item, $value); } /** * Make a function to check an item's equality. * * @param mixed $value - * @return \Closure + * @return \Closure(mixed): bool */ protected function equality($value) { - return function ($item) use ($value) { - return $item === $value; - }; + return fn ($item) => $item === $value; } /** @@ -1097,20 +1068,16 @@ trait EnumeratesValues */ protected function negate(Closure $callback) { - return function (...$params) use ($callback) { - return ! $callback(...$params); - }; + return fn (...$params) => ! $callback(...$params); } /** * Make a function that returns what's passed to it. * - * @return \Closure + * @return \Closure(TValue): TValue */ protected function identity() { - return function ($value) { - return $value; - }; + return fn ($value) => $value; } } diff --git a/vendor/tightenco/collect/src/Collect/Support/alias.php b/vendor/tightenco/collect/src/Collect/Support/alias.php index a9c04063..d2184d20 100644 --- a/vendor/tightenco/collect/src/Collect/Support/alias.php +++ b/vendor/tightenco/collect/src/Collect/Support/alias.php @@ -9,7 +9,6 @@ $aliases = [ Tightenco\Collect\Support\Collection::class => Illuminate\Support\Collection::class, Tightenco\Collect\Support\Enumerable::class => Illuminate\Support\Enumerable::class, Tightenco\Collect\Support\HigherOrderCollectionProxy::class => Illuminate\Support\HigherOrderCollectionProxy::class, - Tightenco\Collect\Support\HigherOrderWhenProxy::class => Illuminate\Support\HigherOrderWhenProxy::class, Tightenco\Collect\Support\LazyCollection::class => Illuminate\Support\LazyCollection::class, Tightenco\Collect\Support\Traits\EnumeratesValues::class => Illuminate\Support\Traits\EnumeratesValues::class, ];