From ddfa3dc41479ac7b96d67f199ec3c0ad54e501ff Mon Sep 17 00:00:00 2001
From: Robin Gustafsson <robin@rgson.se>
Date: Tue, 22 Apr 2025 23:01:59 +0200
Subject: [PATCH] New upstream version 11.44.2+dfsg

---
 CHANGELOG.md                                  | 20 ++++++-
 composer.json                                 |  2 +-
 .../Collections/Traits/EnumeratesValues.php   |  2 +-
 src/Illuminate/Database/Eloquent/Builder.php  |  2 +-
 .../Concerns/QueriesRelationships.php         |  2 +-
 .../Eloquent/Relations/BelongsToMany.php      |  2 +-
 .../Relations/HasOneOrManyThrough.php         |  2 +-
 src/Illuminate/Database/Query/Builder.php     |  2 +-
 src/Illuminate/Database/Seeder.php            | 12 +++--
 src/Illuminate/Foundation/Application.php     |  4 +-
 .../Redis/Connections/PacksPhpRedisValues.php | 12 ++---
 src/Illuminate/Validation/Validator.php       | 45 ++++++++++------
 .../Database/DatabaseEloquentBuilderTest.php  | 12 ++---
 tests/Integration/Cache/DynamoDbStoreTest.php |  2 +-
 tests/Integration/Cookie/CookieTest.php       |  2 +-
 ...terCommitUsingDatabaseTransactionsTest.php |  2 +-
 ...seEmulatePreparesMariaDbConnectionTest.php |  4 +-
 ...baseEmulatePreparesMySqlConnectionTest.php |  4 +-
 .../Postgres/PostgresSchemaBuilderTest.php    |  4 +-
 .../Mail/SendingMarkdownMailTest.php          |  2 +-
 .../Mail/SendingQueuedMailTest.php            |  2 +-
 tests/Integration/Queue/JobEncryptionTest.php |  4 +-
 .../Queue/ModelSerializationTest.php          |  2 +-
 .../Integration/Queue/QueueConnectionTest.php |  9 ++--
 .../Validation/Rules/EmailValidationTest.php  | 49 +++++++++++++++++
 .../Validation/Rules/FileValidationTest.php   | 54 +++++++++++++++++++
 .../Rules/PasswordValidationTest.php          | 49 +++++++++++++++++
 .../View/BladeAnonymousComponentTest.php      |  2 +-
 tests/Integration/View/BladeTest.php          |  2 +-
 .../View/RenderableViewExceptionTest.php      |  2 +-
 tests/Validation/ValidationEmailRuleTest.php  |  3 ++
 31 files changed, 253 insertions(+), 64 deletions(-)
 create mode 100644 tests/Integration/Validation/Rules/EmailValidationTest.php
 create mode 100644 tests/Integration/Validation/Rules/FileValidationTest.php
 create mode 100644 tests/Integration/Validation/Rules/PasswordValidationTest.php

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b6df29a5b..8a4c7a4c7b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,24 @@
 # Release Notes for 11.x
 
-## [Unreleased](https://github.com/laravel/framework/compare/v11.43.2...11.x)
+## [Unreleased](https://github.com/laravel/framework/compare/v11.44.1...11.x)
+
+## [v11.44.1](https://github.com/laravel/framework/compare/v11.44.0...v11.44.1) - 2025-03-05
+
+* [11.x] Add valid values to ensure method by [@lancepioch](https://github.com/lancepioch) in https://github.com/laravel/framework/pull/54840
+* Fix attribute name used on `Validator` instance within certain rule classes by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54845
+* [11.x] Fix `Application::interBasePath()` fails to resolve application when project name is "vendor" by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54871
+* [11.x] Test improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54879
+
+## [v11.44.0](https://github.com/laravel/framework/compare/v11.43.2...v11.44.0) - 2025-02-24
+
+* [11.x] Fix parsing `PHP_CLI_SERVER_WORKERS` as `string` instead of `int` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54724
+* [11.x] Rename Redis parse connection for cluster test method to follow naming conventions by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54721
+* [11.x] Allow `readAt` method to use in database channel by [@utsavsomaiya](https://github.com/utsavsomaiya) in https://github.com/laravel/framework/pull/54729
+* [11.x] Fix: Custom Exceptions with Multiple Arguments does not properly rein… by [@pandiselvamm](https://github.com/pandiselvamm) in https://github.com/laravel/framework/pull/54705
+* [11.x] Update ConcurrencyTest exception reference to use namespace by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54732
+* [11.x] Deprecate `Factory::$modelNameResolver` by [@samlev](https://github.com/samlev) in https://github.com/laravel/framework/pull/54736
+* [11x.] Improved typehints for `InteractsWithDatabase` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54748
+* [11.x] Improved typehints for `InteractsWithExceptionHandling` && `ExceptionHandlerFake` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54747
 
 ## [v11.43.2](https://github.com/laravel/framework/compare/v11.43.1...v11.43.2) - 2025-02-19
 
diff --git a/composer.json b/composer.json
index cf2c2589ce..282d9ff0aa 100644
--- a/composer.json
+++ b/composer.json
@@ -111,7 +111,7 @@
         "league/flysystem-read-only": "^3.25.1",
         "league/flysystem-sftp-v3": "^3.25.1",
         "mockery/mockery": "^1.6.10",
-        "orchestra/testbench-core": "^9.9.4",
+        "orchestra/testbench-core": "^9.11.2",
         "pda/pheanstalk": "^5.0.6",
         "php-http/discovery": "^1.15",
         "phpstan/phpstan": "^2.0",
diff --git a/src/Illuminate/Collections/Traits/EnumeratesValues.php b/src/Illuminate/Collections/Traits/EnumeratesValues.php
index ce3c302038..55c7110942 100644
--- a/src/Illuminate/Collections/Traits/EnumeratesValues.php
+++ b/src/Illuminate/Collections/Traits/EnumeratesValues.php
@@ -342,7 +342,7 @@ trait EnumeratesValues
      *
      * @template TEnsureOfType
      *
-     * @param  class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>  $type
+     * @param  class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>|'string'|'int'|'float'|'bool'|'array'|'null'  $type
      * @return static<TKey, TEnsureOfType>
      *
      * @throws \UnexpectedValueException
diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php
index 1c27bb2ff7..57baa3a680 100755
--- a/src/Illuminate/Database/Eloquent/Builder.php
+++ b/src/Illuminate/Database/Eloquent/Builder.php
@@ -1018,7 +1018,7 @@ class Builder implements BuilderContract
      * @param  string  $pageName
      * @param  int|null  $page
      * @param  \Closure|int|null  $total
-     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     * @return \Illuminate\Pagination\LengthAwarePaginator
      *
      * @throws \InvalidArgumentException
      */
diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php
index c6162d7656..a9acf90fb6 100644
--- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php
+++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php
@@ -674,7 +674,7 @@ trait QueriesRelationships
             $models->groupBy(fn ($model) => $model->getMorphClass())->each(function ($models) use ($query, $relation) {
                 $query->orWhere(function ($query) use ($relation, $models) {
                     $query->where($relation->qualifyColumn($relation->getMorphType()), '<=>', $models->first()->getMorphClass())
-                        ->whereNotIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey());
+                        ->whereIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey());
                 });
             });
         }, null, null, $boolean);
diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
index 7019cf49c0..5618f0190f 100755
--- a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
+++ b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
@@ -938,7 +938,7 @@ class BelongsToMany extends Relation
      * @param  array  $columns
      * @param  string  $pageName
      * @param  int|null  $page
-     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     * @return \Illuminate\Pagination\LengthAwarePaginator
      */
     public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
     {
diff --git a/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php b/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php
index 6e74acf746..72a65b0c1f 100644
--- a/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php
+++ b/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php
@@ -468,7 +468,7 @@ abstract class HasOneOrManyThrough extends Relation
      * @param  array  $columns
      * @param  string  $pageName
      * @param  int  $page
-     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     * @return \Illuminate\Pagination\LengthAwarePaginator
      */
     public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
     {
diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php
index 538994fe4b..d6d9fd07b4 100755
--- a/src/Illuminate/Database/Query/Builder.php
+++ b/src/Illuminate/Database/Query/Builder.php
@@ -3142,7 +3142,7 @@ class Builder implements BuilderContract
      * @param  string  $pageName
      * @param  int|null  $page
      * @param  \Closure|int|null  $total
-     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     * @return \Illuminate\Pagination\LengthAwarePaginator
      */
     public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null, $total = null)
     {
diff --git a/src/Illuminate/Database/Seeder.php b/src/Illuminate/Database/Seeder.php
index bfb48aedf3..08e57b2d78 100755
--- a/src/Illuminate/Database/Seeder.php
+++ b/src/Illuminate/Database/Seeder.php
@@ -110,11 +110,15 @@ abstract class Seeder
      */
     public function callOnce($class, $silent = false, array $parameters = [])
     {
-        if (in_array($class, static::$called)) {
-            return;
-        }
+        $classes = Arr::wrap($class);
+
+        foreach ($classes as $class) {
+            if (in_array($class, static::$called)) {
+                continue;
+            }
 
-        $this->call($class, $silent, $parameters);
+            $this->call($class, $silent, $parameters);
+        }
     }
 
     /**
diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php
index cc9783289b..be7345c8ef 100755
--- a/src/Illuminate/Foundation/Application.php
+++ b/src/Illuminate/Foundation/Application.php
@@ -45,7 +45,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
      *
      * @var string
      */
-    const VERSION = '11.44.0';
+    const VERSION = '11.44.2';
 
     /**
      * The base path for the Laravel installation.
@@ -257,7 +257,7 @@ class Application extends Container implements ApplicationContract, CachesConfig
             isset($_ENV['APP_BASE_PATH']) => $_ENV['APP_BASE_PATH'],
             default => dirname(array_values(array_filter(
                 array_keys(ClassLoader::getRegisteredLoaders()),
-                fn ($path) => ! str_contains($path, '/vendor/'),
+                fn ($path) => ! str_starts_with($path, 'phar://'),
             ))[0]),
         };
     }
diff --git a/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php b/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php
index 526a764ede..1a81720b07 100644
--- a/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php
+++ b/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php
@@ -95,26 +95,26 @@ trait PacksPhpRedisValues
         $oldSerializer = null;
 
         if ($this->serialized()) {
-            $oldSerializer = $client->getOption($client::OPT_SERIALIZER);
-            $client->setOption($client::OPT_SERIALIZER, $client::SERIALIZER_NONE);
+            $oldSerializer = $client->getOption(Redis::OPT_SERIALIZER);
+            $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
         }
 
         $oldCompressor = null;
 
         if ($this->compressed()) {
-            $oldCompressor = $client->getOption($client::OPT_COMPRESSION);
-            $client->setOption($client::OPT_COMPRESSION, $client::COMPRESSION_NONE);
+            $oldCompressor = $client->getOption(Redis::OPT_COMPRESSION);
+            $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_NONE);
         }
 
         try {
             return $callback();
         } finally {
             if ($oldSerializer !== null) {
-                $client->setOption($client::OPT_SERIALIZER, $oldSerializer);
+                $client->setOption(Redis::OPT_SERIALIZER, $oldSerializer);
             }
 
             if ($oldCompressor !== null) {
-                $client->setOption($client::OPT_COMPRESSION, $oldCompressor);
+                $client->setOption(Redis::OPT_COMPRESSION, $oldCompressor);
             }
         }
     }
diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php
index 557ab19f57..21cb2e7273 100755
--- a/src/Illuminate/Validation/Validator.php
+++ b/src/Illuminate/Validation/Validator.php
@@ -307,11 +307,11 @@ class Validator implements ValidatorContract
     protected $defaultNumericRules = ['Numeric', 'Integer', 'Decimal'];
 
     /**
-     * The current placeholder for dots in rule keys.
+     * The current random hash for the validator.
      *
      * @var string
      */
-    protected $dotPlaceholder;
+    protected static $placeholderHash;
 
     /**
      * The exception to throw upon failure.
@@ -344,7 +344,9 @@ class Validator implements ValidatorContract
         array $messages = [],
         array $attributes = [],
     ) {
-        $this->dotPlaceholder = Str::random();
+        if (! isset(static::$placeholderHash)) {
+            static::$placeholderHash = Str::random();
+        }
 
         $this->initialRules = $rules;
         $this->translator = $translator;
@@ -372,7 +374,7 @@ class Validator implements ValidatorContract
 
             $key = str_replace(
                 ['.', '*'],
-                [$this->dotPlaceholder, '__asterisk__'],
+                ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash],
                 $key
             );
 
@@ -410,7 +412,7 @@ class Validator implements ValidatorContract
     protected function replacePlaceholderInString(string $value)
     {
         return str_replace(
-            [$this->dotPlaceholder, '__asterisk__'],
+            ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash],
             ['.', '*'],
             $value
         );
@@ -419,13 +421,13 @@ class Validator implements ValidatorContract
     /**
      * Replace each field parameter dot placeholder with dot.
      *
-     * @param  string  $value
-     * @return string
+     * @param  array  $parameters
+     * @return array
      */
     protected function replaceDotPlaceholderInParameters(array $parameters)
     {
         return array_map(function ($field) {
-            return str_replace($this->dotPlaceholder, '.', $field);
+            return str_replace('__dot__'.static::$placeholderHash, '.', $field);
         }, $parameters);
     }
 
@@ -746,7 +748,7 @@ class Validator implements ValidatorContract
     protected function replaceDotInParameters(array $parameters)
     {
         return array_map(function ($field) {
-            return str_replace('\.', $this->dotPlaceholder, $field);
+            return str_replace('\.', '__dot__'.static::$placeholderHash, $field);
         }, $parameters);
     }
 
@@ -872,11 +874,24 @@ class Validator implements ValidatorContract
      */
     protected function validateUsingCustomRule($attribute, $value, $rule)
     {
-        $attribute = $this->replacePlaceholderInString($attribute);
+        $originalAttribute = $this->replacePlaceholderInString($attribute);
+
+        $attribute = match (true) {
+            $rule instanceof Rules\Email => $attribute,
+            $rule instanceof Rules\File => $attribute,
+            $rule instanceof Rules\Password => $attribute,
+            default => $originalAttribute,
+        };
 
         $value = is_array($value) ? $this->replacePlaceholders($value) : $value;
 
         if ($rule instanceof ValidatorAwareRule) {
+            if ($attribute !== $originalAttribute) {
+                $this->addCustomAttributes([
+                    $attribute => $this->customAttributes[$originalAttribute] ?? $originalAttribute,
+                ]);
+            }
+
             $rule->setValidator($this);
         }
 
@@ -889,14 +904,14 @@ class Validator implements ValidatorContract
                 get_class($rule->invokable()) :
                 get_class($rule);
 
-            $this->failedRules[$attribute][$ruleClass] = [];
+            $this->failedRules[$originalAttribute][$ruleClass] = [];
 
-            $messages = $this->getFromLocalArray($attribute, $ruleClass) ?? $rule->message();
+            $messages = $this->getFromLocalArray($originalAttribute, $ruleClass) ?? $rule->message();
 
             $messages = $messages ? (array) $messages : [$ruleClass];
 
             foreach ($messages as $key => $message) {
-                $key = is_string($key) ? $key : $attribute;
+                $key = is_string($key) ? $key : $originalAttribute;
 
                 $this->messages->add($key, $this->makeReplacements(
                     $message, $key, $ruleClass, []
@@ -1189,7 +1204,7 @@ class Validator implements ValidatorContract
     {
         return (new Collection($this->rules))
             ->mapWithKeys(fn ($value, $key) => [
-                str_replace($this->dotPlaceholder, '\\.', $key) => $value,
+                str_replace('__dot__'.static::$placeholderHash, '\\.', $key) => $value,
             ])
             ->all();
     }
@@ -1203,7 +1218,7 @@ class Validator implements ValidatorContract
     public function setRules(array $rules)
     {
         $rules = (new Collection($rules))->mapWithKeys(function ($value, $key) {
-            return [str_replace('\.', $this->dotPlaceholder, $key) => $value];
+            return [str_replace('\.', '__dot__'.static::$placeholderHash, $key) => $value];
         })->toArray();
 
         $this->initialRules = $rules;
diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php
index 60daa61f0b..ad0c86122a 100755
--- a/tests/Database/DatabaseEloquentBuilderTest.php
+++ b/tests/Database/DatabaseEloquentBuilderTest.php
@@ -1837,7 +1837,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->whereNotMorphedTo('morph', $relatedModel);
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql());
         $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());
     }
 
@@ -1854,7 +1854,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->whereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)))', $builder->toSql());
         $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());
     }
 
@@ -1874,7 +1874,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->whereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql());
         $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());
     }
 
@@ -1950,7 +1950,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', $relatedModel);
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql());
         $this->assertEquals(['baz', $relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());
     }
 
@@ -1967,7 +1967,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)))', $builder->toSql());
         $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());
     }
 
@@ -1987,7 +1987,7 @@ class DatabaseEloquentBuilderTest extends TestCase
 
         $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);
 
-        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql());
+        $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql());
         $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());
     }
 
diff --git a/tests/Integration/Cache/DynamoDbStoreTest.php b/tests/Integration/Cache/DynamoDbStoreTest.php
index b465cc61ea..7abe70d278 100644
--- a/tests/Integration/Cache/DynamoDbStoreTest.php
+++ b/tests/Integration/Cache/DynamoDbStoreTest.php
@@ -65,7 +65,7 @@ class DynamoDbStoreTest extends TestCase
      * @param  \Illuminate\Foundation\Application  $app
      * @return void
      */
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         if (! env('DYNAMODB_CACHE_TABLE')) {
             $this->markTestSkipped('DynamoDB not configured.');
diff --git a/tests/Integration/Cookie/CookieTest.php b/tests/Integration/Cookie/CookieTest.php
index bc52526303..ed5223022a 100644
--- a/tests/Integration/Cookie/CookieTest.php
+++ b/tests/Integration/Cookie/CookieTest.php
@@ -42,7 +42,7 @@ class CookieTest extends TestCase
         $this->assertEquals(Carbon::now()->getTimestamp() + 60, $response->headers->getCookies()[1]->getExpiresTime());
     }
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app->instance(
             ExceptionHandler::class,
diff --git a/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php b/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php
index 25a8b27a72..620df3d0b9 100644
--- a/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php
+++ b/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php
@@ -32,7 +32,7 @@ class EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest extends Te
         }
     }
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $connection = $app->make('config')->get('database.default');
 
diff --git a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php
index 8c155518dc..451fd3a1bd 100755
--- a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php
+++ b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php
@@ -10,9 +10,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension;
 #[RequiresPhpExtension('pdo_mysql')]
 class DatabaseEmulatePreparesMariaDbConnectionTest extends DatabaseMariaDbConnectionTest
 {
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
-        parent::getEnvironmentSetUp($app);
+        parent::defineEnvironment($app);
 
         $app['config']->set('database.connections.mariadb.options', [
             PDO::ATTR_EMULATE_PREPARES => true,
diff --git a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php
index 62592a4048..a67d747945 100755
--- a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php
+++ b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php
@@ -10,9 +10,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension;
 #[RequiresPhpExtension('pdo_mysql')]
 class DatabaseEmulatePreparesMySqlConnectionTest extends DatabaseMySqlConnectionTest
 {
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
-        parent::getEnvironmentSetUp($app);
+        parent::defineEnvironment($app);
 
         $app['config']->set('database.connections.mysql.options', [
             PDO::ATTR_EMULATE_PREPARES => true,
diff --git a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php
index 4f64c21fbc..bfcf439d74 100644
--- a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php
+++ b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php
@@ -13,9 +13,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension;
 #[RequiresPhpExtension('pdo_pgsql')]
 class PostgresSchemaBuilderTest extends PostgresTestCase
 {
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
-        parent::getEnvironmentSetUp($app);
+        parent::defineEnvironment($app);
 
         $app['config']->set('database.connections.pgsql.search_path', 'public,private');
     }
diff --git a/tests/Integration/Mail/SendingMarkdownMailTest.php b/tests/Integration/Mail/SendingMarkdownMailTest.php
index 591b7264f6..43ecd15664 100644
--- a/tests/Integration/Mail/SendingMarkdownMailTest.php
+++ b/tests/Integration/Mail/SendingMarkdownMailTest.php
@@ -12,7 +12,7 @@ use Orchestra\Testbench\TestCase;
 
 class SendingMarkdownMailTest extends TestCase
 {
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('mail.driver', 'array');
 
diff --git a/tests/Integration/Mail/SendingQueuedMailTest.php b/tests/Integration/Mail/SendingQueuedMailTest.php
index 6f982043ce..e20a44659c 100644
--- a/tests/Integration/Mail/SendingQueuedMailTest.php
+++ b/tests/Integration/Mail/SendingQueuedMailTest.php
@@ -11,7 +11,7 @@ use Orchestra\Testbench\TestCase;
 
 class SendingQueuedMailTest extends TestCase
 {
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('mail.driver', 'array');
 
diff --git a/tests/Integration/Queue/JobEncryptionTest.php b/tests/Integration/Queue/JobEncryptionTest.php
index 704c080010..85701d5187 100644
--- a/tests/Integration/Queue/JobEncryptionTest.php
+++ b/tests/Integration/Queue/JobEncryptionTest.php
@@ -21,9 +21,9 @@ class JobEncryptionTest extends DatabaseTestCase
 {
     use DatabaseMigrations;
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
-        parent::getEnvironmentSetUp($app);
+        parent::defineEnvironment($app);
 
         $app['config']->set('app.key', Str::random(32));
         $app['config']->set('queue.default', 'database');
diff --git a/tests/Integration/Queue/ModelSerializationTest.php b/tests/Integration/Queue/ModelSerializationTest.php
index 359bbff8fa..bd3b401c65 100644
--- a/tests/Integration/Queue/ModelSerializationTest.php
+++ b/tests/Integration/Queue/ModelSerializationTest.php
@@ -18,7 +18,7 @@ class ModelSerializationTest extends TestCase
 {
     use RefreshDatabase;
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('database.connections.custom', [
             'driver' => 'sqlite',
diff --git a/tests/Integration/Queue/QueueConnectionTest.php b/tests/Integration/Queue/QueueConnectionTest.php
index 1ae5f1ef90..7ad7722499 100644
--- a/tests/Integration/Queue/QueueConnectionTest.php
+++ b/tests/Integration/Queue/QueueConnectionTest.php
@@ -8,17 +8,14 @@ use Illuminate\Database\DatabaseTransactionsManager;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Support\Facades\Bus;
 use Mockery as m;
+use Orchestra\Testbench\Attributes\WithConfig;
 use Orchestra\Testbench\TestCase;
 use Throwable;
 
+#[WithConfig('queue.default', 'sqs')]
+#[WithConfig('queue.connections.sqs.after_commit', true)]
 class QueueConnectionTest extends TestCase
 {
-    protected function getEnvironmentSetUp($app)
-    {
-        $app['config']->set('queue.default', 'sqs');
-        $app['config']->set('queue.connections.sqs.after_commit', true);
-    }
-
     protected function tearDown(): void
     {
         QueueConnectionTestJob::$ran = false;
diff --git a/tests/Integration/Validation/Rules/EmailValidationTest.php b/tests/Integration/Validation/Rules/EmailValidationTest.php
new file mode 100644
index 0000000000..558bef77a9
--- /dev/null
+++ b/tests/Integration/Validation/Rules/EmailValidationTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Illuminate\Tests\Integration\Validation\Rules;
+
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rules\Email;
+use Orchestra\Testbench\TestCase;
+use PHPUnit\Framework\Attributes\TestWith;
+
+class EmailValidationTest extends TestCase
+{
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array(string $attribute)
+    {
+        $validator = Validator::make([
+            'emails' => [
+                $attribute => 'taylor@laravel.com',
+            ],
+        ], [
+            'emails.*' => ['required', Email::default()->rfcCompliant()],
+        ]);
+
+        $this->assertTrue($validator->passes());
+    }
+
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute)
+    {
+        $validator = Validator::make([
+            'emails' => [
+                $attribute => 'taylor[at]laravel.com',
+            ],
+        ], [
+            'emails.*' => ['required', Email::default()->rfcCompliant()],
+        ]);
+
+        $this->assertFalse($validator->passes());
+
+        $this->assertSame([
+            0 => __('validation.email', ['attribute' => sprintf('emails.%s', str_replace('_', ' ', $attribute))]),
+        ], $validator->messages()->all());
+    }
+}
diff --git a/tests/Integration/Validation/Rules/FileValidationTest.php b/tests/Integration/Validation/Rules/FileValidationTest.php
new file mode 100644
index 0000000000..ba0d54920e
--- /dev/null
+++ b/tests/Integration/Validation/Rules/FileValidationTest.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Illuminate\Tests\Integration\Validation\Rules;
+
+use Illuminate\Http\UploadedFile;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rules\File;
+use Orchestra\Testbench\TestCase;
+use PHPUnit\Framework\Attributes\TestWith;
+
+class FileValidationTest extends TestCase
+{
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array(string $attribute)
+    {
+        $file = UploadedFile::fake()->create('laravel.png', 1, 'image/png');
+
+        $validator = Validator::make([
+            'files' => [
+                $attribute => $file,
+            ],
+        ], [
+            'files.*' => ['required', File::types(['image/png', 'image/jpeg'])],
+        ]);
+
+        $this->assertTrue($validator->passes());
+    }
+
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute)
+    {
+        $file = UploadedFile::fake()->create('laravel.php', 1, 'image/php');
+
+        $validator = Validator::make([
+            'files' => [
+                $attribute => $file,
+            ],
+        ], [
+            'files.*' => ['required', File::types($mimes = ['image/png', 'image/jpeg'])],
+        ]);
+
+        $this->assertFalse($validator->passes());
+
+        $this->assertSame([
+            0 => __('validation.mimetypes', ['attribute' => sprintf('files.%s', str_replace('_', ' ', $attribute)), 'values' => implode(', ', $mimes)]),
+        ], $validator->messages()->all());
+    }
+}
diff --git a/tests/Integration/Validation/Rules/PasswordValidationTest.php b/tests/Integration/Validation/Rules/PasswordValidationTest.php
new file mode 100644
index 0000000000..e1f7672ac8
--- /dev/null
+++ b/tests/Integration/Validation/Rules/PasswordValidationTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Illuminate\Tests\Integration\Validation\Rules;
+
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rules\Password;
+use Orchestra\Testbench\TestCase;
+use PHPUnit\Framework\Attributes\TestWith;
+
+class PasswordValidationTest extends TestCase
+{
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array(string $attribute)
+    {
+        $validator = Validator::make([
+            'passwords' => [
+                $attribute => 'secret',
+            ],
+        ], [
+            'passwords.*' => ['required', Password::default()->min(6)],
+        ]);
+
+        $this->assertTrue($validator->passes());
+    }
+
+    #[TestWith(['0'])]
+    #[TestWith(['.'])]
+    #[TestWith(['*'])]
+    #[TestWith(['__asterisk__'])]
+    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute)
+    {
+        $validator = Validator::make([
+            'passwords' => [
+                $attribute => 'secret',
+            ],
+        ], [
+            'passwords.*' => ['required', Password::default()->min(8)],
+        ]);
+
+        $this->assertFalse($validator->passes());
+
+        $this->assertSame([
+            0 => sprintf('The passwords.%s field must be at least 8 characters.', str_replace('_', ' ', $attribute)),
+        ], $validator->messages()->all());
+    }
+}
diff --git a/tests/Integration/View/BladeAnonymousComponentTest.php b/tests/Integration/View/BladeAnonymousComponentTest.php
index eb29765dae..0281de48d8 100644
--- a/tests/Integration/View/BladeAnonymousComponentTest.php
+++ b/tests/Integration/View/BladeAnonymousComponentTest.php
@@ -41,7 +41,7 @@ class BladeAnonymousComponentTest extends TestCase
         $view = View::make('panel')->render();
     }
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('view.paths', [__DIR__.'/anonymous-components-templates']);
     }
diff --git a/tests/Integration/View/BladeTest.php b/tests/Integration/View/BladeTest.php
index 7a08d43fd0..6495175337 100644
--- a/tests/Integration/View/BladeTest.php
+++ b/tests/Integration/View/BladeTest.php
@@ -210,7 +210,7 @@ class BladeTest extends TestCase
         $this->artisan('view:clear');
     }
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('view.paths', [__DIR__.'/templates']);
     }
diff --git a/tests/Integration/View/RenderableViewExceptionTest.php b/tests/Integration/View/RenderableViewExceptionTest.php
index 93c91cb313..f5ed176e26 100644
--- a/tests/Integration/View/RenderableViewExceptionTest.php
+++ b/tests/Integration/View/RenderableViewExceptionTest.php
@@ -21,7 +21,7 @@ class RenderableViewExceptionTest extends TestCase
         $response->assertSee('This is a renderable exception.');
     }
 
-    protected function getEnvironmentSetUp($app)
+    protected function defineEnvironment($app)
     {
         $app['config']->set('view.paths', [__DIR__.'/templates']);
     }
diff --git a/tests/Validation/ValidationEmailRuleTest.php b/tests/Validation/ValidationEmailRuleTest.php
index b6382f508b..c48451db9b 100644
--- a/tests/Validation/ValidationEmailRuleTest.php
+++ b/tests/Validation/ValidationEmailRuleTest.php
@@ -11,6 +11,7 @@ use Illuminate\Validation\Rule;
 use Illuminate\Validation\Rules\Email;
 use Illuminate\Validation\ValidationServiceProvider;
 use Illuminate\Validation\Validator;
+use PHPUnit\Framework\Attributes\RequiresPhpExtension;
 use PHPUnit\Framework\Attributes\TestWith;
 use PHPUnit\Framework\TestCase;
 
@@ -143,6 +144,7 @@ class ValidationEmailRuleTest extends TestCase
         );
     }
 
+    #[RequiresPhpExtension('intl')]
     public function testValidateMxRecord()
     {
         $this->fails(
@@ -674,6 +676,7 @@ class ValidationEmailRuleTest extends TestCase
         );
     }
 
+    #[RequiresPhpExtension('intl')]
     public function testCombiningRules()
     {
         $this->passes(
-- 
GitLab