Skip to content

Commit fdc1b92

Browse files
committed
Merge branch '9.x'
# Conflicts: # CHANGELOG.md # composer.json # src/Illuminate/Foundation/Application.php # src/Illuminate/Support/composer.json # tests/Support/SupportTestingQueueFakeTest.php
2 parents ed34853 + 92bd07b commit fdc1b92

File tree

89 files changed

+2411
-243
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+2411
-243
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Laravel is accessible, yet powerful, providing tools needed for large, robust ap
2626

2727
Laravel has the most extensive and thorough documentation and video tutorial library of any modern web application framework. The [Laravel documentation](https://laravel.com/docs) is in-depth and complete, making it a breeze to get started learning the framework.
2828

29+
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
30+
2931
If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 1100 video tutorials covering a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.
3032

3133
## Contributing

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"symfony/mime": "^6.2",
4242
"symfony/process": "^6.2",
4343
"symfony/routing": "^6.2",
44+
"symfony/uid": "^6.2",
4445
"symfony/var-dumper": "^6.2",
4546
"tijsverkoyen/css-to-inline-styles": "^2.2.2",
4647
"vlucas/phpdotenv": "^5.4.1",
@@ -88,6 +89,7 @@
8889
"guzzlehttp/guzzle": "^7.2",
8990
"league/flysystem-aws-s3-v3": "^3.0",
9091
"league/flysystem-ftp": "^3.0",
92+
"league/flysystem-path-prefixing": "^3.3",
9193
"league/flysystem-read-only": "^3.3",
9294
"league/flysystem-sftp-v3": "^3.0",
9395
"mockery/mockery": "^1.4.4",
@@ -152,6 +154,7 @@
152154
"laravel/tinker": "Required to use the tinker console command (^2.0).",
153155
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).",
154156
"league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).",
157+
"league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).",
155158
"league/flysystem-read-only": "Required to use read-only disks (^3.3)",
156159
"league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).",
157160
"mockery/mockery": "Required to use mocking (^1.4.4).",

src/Illuminate/Bus/Batchable.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace Illuminate\Bus;
44

5+
use Carbon\CarbonImmutable;
56
use Illuminate\Container\Container;
7+
use Illuminate\Support\Str;
8+
use Illuminate\Support\Testing\Fakes\BatchFake;
69

710
trait Batchable
811
{
@@ -13,13 +16,24 @@ trait Batchable
1316
*/
1417
public $batchId;
1518

19+
/**
20+
* The fake batch, if applicable.
21+
*
22+
* @var \Illuminate\Support\Testing\BatchFake
23+
*/
24+
private $fakeBatch;
25+
1626
/**
1727
* Get the batch instance for the job, if applicable.
1828
*
1929
* @return \Illuminate\Bus\Batch|null
2030
*/
2131
public function batch()
2232
{
33+
if ($this->fakeBatch) {
34+
return $this->fakeBatch;
35+
}
36+
2337
if ($this->batchId) {
2438
return Container::getInstance()->make(BatchRepository::class)->find($this->batchId);
2539
}
@@ -49,4 +63,43 @@ public function withBatchId(string $batchId)
4963

5064
return $this;
5165
}
66+
67+
/**
68+
* Indicate that the job should use a fake batch.
69+
*
70+
* @param string $id
71+
* @param string $name
72+
* @param int $totalJobs
73+
* @param int $pendingJobs
74+
* @param int $failedJobs
75+
* @param array $failedJobIds
76+
* @param array $options
77+
* @return array{0: $this, 1: \Illuminate\Support\Testing\BatchFake}
78+
*/
79+
public function withFakeBatch(string $id = '',
80+
string $name = '',
81+
int $totalJobs = 0,
82+
int $pendingJobs = 0,
83+
int $failedJobs = 0,
84+
array $failedJobIds = [],
85+
array $options = [],
86+
CarbonImmutable $createdAt = null,
87+
?CarbonImmutable $cancelledAt = null,
88+
?CarbonImmutable $finishedAt = null)
89+
{
90+
$this->fakeBatch = new BatchFake(
91+
empty($id) ? (string) Str::uuid() : $id,
92+
$name,
93+
$totalJobs,
94+
$pendingJobs,
95+
$failedJobs,
96+
$failedJobIds,
97+
$options,
98+
$createdAt ?? CarbonImmutable::now(),
99+
$cancelledAt,
100+
$finishedAt,
101+
);
102+
103+
return [$this, $this->fakeBatch];
104+
}
52105
}

src/Illuminate/Collections/Traits/EnumeratesValues.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,7 @@ protected function operatorForWhere($key, $operator = null, $value = null)
10571057
case '>=': return $retrieved >= $value;
10581058
case '===': return $retrieved === $value;
10591059
case '!==': return $retrieved !== $value;
1060+
case '<=>': return $retrieved <=> $value;
10601061
}
10611062
};
10621063
}

src/Illuminate/Console/Scheduling/ManagesFrequencies.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ public function timezone($timezone)
546546
*/
547547
protected function spliceIntoPosition($position, $value)
548548
{
549-
$segments = explode(' ', $this->expression);
549+
$segments = preg_split("/\s+/", $this->expression);
550550

551551
$segments[$position - 1] = $value;
552552

src/Illuminate/Console/Scheduling/ScheduleListCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public function handle(Schedule $schedule)
134134
*/
135135
private function getCronExpressionSpacing($events)
136136
{
137-
$rows = $events->map(fn ($event) => array_map('mb_strlen', explode(' ', $event->expression)));
137+
$rows = $events->map(fn ($event) => array_map('mb_strlen', preg_split("/\s+/", $event->expression)));
138138

139139
return collect($rows[0] ?? [])->keys()->map(fn ($key) => $rows->max($key));
140140
}
@@ -148,7 +148,7 @@ private function getCronExpressionSpacing($events)
148148
*/
149149
private function formatCronExpression($expression, $spacing)
150150
{
151-
$expressions = explode(' ', $expression);
151+
$expressions = preg_split("/\s+/", $expression);
152152

153153
return collect($spacing)
154154
->map(fn ($length, $index) => str_pad($expressions[$index], $length))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Illuminate\Contracts\View;
4+
5+
use Exception;
6+
7+
class ViewCompilationException extends Exception
8+
{
9+
//
10+
}

src/Illuminate/Database/Connection.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,15 +1134,15 @@ public function getDoctrineConnection()
11341134
/**
11351135
* Register a custom Doctrine mapping type.
11361136
*
1137-
* @param string $class
1137+
* @param Type|class-string<Type> $class
11381138
* @param string $name
11391139
* @param string $type
11401140
* @return void
11411141
*
11421142
* @throws \Doctrine\DBAL\DBALException
11431143
* @throws \RuntimeException
11441144
*/
1145-
public function registerDoctrineType(string $class, string $name, string $type): void
1145+
public function registerDoctrineType(Type|string $class, string $name, string $type): void
11461146
{
11471147
if (! $this->isDoctrineAvailable()) {
11481148
throw new RuntimeException(
@@ -1151,7 +1151,8 @@ public function registerDoctrineType(string $class, string $name, string $type):
11511151
}
11521152

11531153
if (! Type::hasType($name)) {
1154-
Type::addType($name, $class);
1154+
Type::getTypeRegistry()
1155+
->register($name, is_string($class) ? new $class() : $class);
11551156
}
11561157

11571158
$this->doctrineTypeMappings[$name] = $type;

src/Illuminate/Database/Console/Migrations/MigrateCommand.php

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Illuminate\Database\Migrations\Migrator;
1010
use Illuminate\Database\SQLiteDatabaseDoesNotExistException;
1111
use Illuminate\Database\SqlServerConnection;
12+
use PDOException;
13+
use Throwable;
1214

1315
class MigrateCommand extends BaseCommand
1416
{
@@ -134,26 +136,88 @@ protected function prepareDatabase()
134136
protected function repositoryExists()
135137
{
136138
return retry(2, fn () => $this->migrator->repositoryExists(), 0, function ($e) {
137-
if (! $e->getPrevious() instanceof SQLiteDatabaseDoesNotExistException) {
138-
return false;
139-
}
139+
try {
140+
if ($e->getPrevious() instanceof SQLiteDatabaseDoesNotExistException) {
141+
return $this->createMissingSqliteDatbase($e->getPrevious()->path);
142+
}
140143

141-
if ($this->option('force')) {
142-
return touch($e->getPrevious()->path);
143-
}
144+
$connection = $this->migrator->resolveConnection($this->option('database'));
144145

145-
if ($this->option('no-interaction')) {
146+
if (
147+
$e->getPrevious() instanceof PDOException &&
148+
$e->getPrevious()->getCode() === 1049 &&
149+
$connection->getDriverName() === 'mysql') {
150+
return $this->createMissingMysqlDatabase($connection);
151+
}
152+
153+
return false;
154+
} catch (Throwable) {
146155
return false;
147156
}
157+
});
158+
}
148159

149-
$this->components->warn('The SQLite database does not exist: '.$e->getPrevious()->path);
160+
/**
161+
* Create a missing SQLite database.
162+
*
163+
* @param string $path
164+
* @return bool
165+
*/
166+
protected function createMissingSqliteDatbase($path)
167+
{
168+
if ($this->option('force')) {
169+
return touch($path);
170+
}
171+
172+
if ($this->option('no-interaction')) {
173+
return false;
174+
}
175+
176+
$this->components->warn('The SQLite database does not exist: '.$path);
177+
178+
if (! $this->components->confirm('Would you like to create it?')) {
179+
return false;
180+
}
181+
182+
return touch($path);
183+
}
184+
185+
/**
186+
* Create a missing MySQL database.
187+
*
188+
* @return bool
189+
*/
190+
protected function createMissingMysqlDatabase($connection)
191+
{
192+
if ($this->laravel['config']->get("database.connections.{$connection->getName()}.database") !== $connection->getDatabaseName()) {
193+
return false;
194+
}
195+
196+
if (! $this->option('force') && $this->option('no-interaction')) {
197+
return false;
198+
}
199+
200+
if (! $this->option('force') && ! $this->option('no-interaction')) {
201+
$this->components->warn("The database '{$connection->getDatabaseName()}' does not exist on the '{$connection->getName()}' connection.");
150202

151203
if (! $this->components->confirm('Would you like to create it?')) {
152204
return false;
153205
}
206+
}
154207

155-
return touch($e->getPrevious()->path);
156-
});
208+
try {
209+
$this->laravel['config']->set("database.connections.{$connection->getName()}.database", null);
210+
211+
$this->laravel['db']->purge();
212+
213+
$freshConnection = $this->migrator->resolveConnection($this->option('database'));
214+
215+
return tap($freshConnection->unprepared("CREATE DATABASE IF NOT EXISTS {$connection->getDatabaseName()}"), function () {
216+
$this->laravel['db']->purge();
217+
});
218+
} finally {
219+
$this->laravel['config']->set("database.connections.{$connection->getName()}.database", $connection->getDatabaseName());
220+
}
157221
}
158222

159223
/**

src/Illuminate/Database/DetectsLostConnections.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ protected function causedByLostConnection(Throwable $e)
6060
'TCP Provider: Error code 0x274C',
6161
'SQLSTATE[HY000] [2002] No such file or directory',
6262
'SSL: Operation timed out',
63+
'Reason: Server is in script upgrade mode. Only administrator can connect at this time.',
6364
]);
6465
}
6566
}

0 commit comments

Comments
 (0)