Skip to content

Commit c272db4

Browse files
[11.x] Supports laravel/serializable-closure 2 (#53552)
* [11.x] Supports `laravel/serializable-closure` 2 Signed-off-by: Mior Muhammad Zaki <[email protected]> * Apply fixes from StyleCI * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Apply fixes from StyleCI * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Apply fixes from StyleCI * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Apply fixes from StyleCI * Update SerializableClosureV1QueueTest.php * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Apply suggestions from code review * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> --------- Signed-off-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: StyleCI Bot <[email protected]>
1 parent d7345b6 commit c272db4

File tree

6 files changed

+278
-3
lines changed

6 files changed

+278
-3
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"guzzlehttp/guzzle": "^7.8",
3333
"guzzlehttp/uri-template": "^1.0",
3434
"laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
35-
"laravel/serializable-closure": "^1.3",
35+
"laravel/serializable-closure": "^1.3|^2.0",
3636
"league/commonmark": "^2.2.1",
3737
"league/flysystem": "^3.8.0",
3838
"monolog/monolog": "^3.0",
@@ -107,7 +107,7 @@
107107
"league/flysystem-sftp-v3": "^3.0",
108108
"mockery/mockery": "^1.6.10",
109109
"nyholm/psr7": "^1.2",
110-
"orchestra/testbench-core": "^9.5",
110+
"orchestra/testbench-core": "^9.6",
111111
"pda/pheanstalk": "^5.0",
112112
"phpstan/phpstan": "^1.11.5",
113113
"phpunit/phpunit": "^10.5|^11.0",

src/Illuminate/Queue/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"illuminate/filesystem": "^11.0",
2424
"illuminate/pipeline": "^11.0",
2525
"illuminate/support": "^11.0",
26-
"laravel/serializable-closure": "^1.2.2",
26+
"laravel/serializable-closure": "^1.3|^2.0",
2727
"ramsey/uuid": "^4.7",
2828
"symfony/process": "^7.0"
2929
},
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Integration\Queue\Fixtures\Jobs;
4+
5+
use Illuminate\Contracts\Queue\ShouldQueue;
6+
use Illuminate\Foundation\Auth\User;
7+
use Illuminate\Foundation\Queue\Queueable;
8+
9+
class DeleteUser implements ShouldQueue
10+
{
11+
use Queueable;
12+
13+
/**
14+
* Create a new job instance.
15+
*/
16+
public function __construct(
17+
public User $user
18+
) {
19+
log($user);
20+
}
21+
22+
/**
23+
* Execute the job.
24+
*/
25+
public function handle(): void
26+
{
27+
$this->user->delete();
28+
}
29+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Integration\Queue;
4+
5+
use Illuminate\Foundation\Testing\RefreshDatabase;
6+
use Illuminate\Support\Facades\DB;
7+
use Orchestra\Testbench\Attributes\WithMigration;
8+
use Orchestra\Testbench\Factories\UserFactory;
9+
use Orchestra\Testbench\TestCase;
10+
11+
#[WithMigration]
12+
class SerializableClosureV1QueueTest extends TestCase
13+
{
14+
use RefreshDatabase;
15+
16+
/** {@inheritDoc} */
17+
#[\Override]
18+
protected function defineEnvironment($app)
19+
{
20+
$this->markTestSkippedWhen($this->usingInMemoryDatabase(), 'Test does not support using :memory: database connection');
21+
22+
tap($app->make('config'), function ($config) {
23+
$config->set([
24+
'app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF',
25+
'queue.default' => 'database',
26+
]);
27+
});
28+
}
29+
30+
/** {@inheritDoc} */
31+
protected function afterRefreshingDatabase()
32+
{
33+
UserFactory::new()->create([
34+
'id' => 100,
35+
'name' => 'Taylor Otwell',
36+
'email' => '[email protected]',
37+
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
38+
]);
39+
40+
DB::table('jobs')->insert([
41+
'queue' => 'default',
42+
'payload' => "{\"uuid\":\"d7c0856d-733a-4e73-89c8-eca4dea621ff\",\"displayName\":\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\",\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"maxTries\":null,\"maxExceptions\":null,\"failOnTimeout\":false,\"backoff\":null,\"timeout\":null,\"retryUntil\":null,\"data\":{\"commandName\":\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\",\"command\":\"O:59:\\\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\\\":3:{s:4:\\\"user\\\";O:45:\\\"Illuminate\\\\Contracts\\\\Database\\\\ModelIdentifier\\\":5:{s:5:\\\"class\\\";s:31:\\\"Illuminate\\\\Foundation\\\\Auth\\\\User\\\";s:2:\\\"id\\\";i:100;s:9:\\\"relations\\\";a:0:{}s:10:\\\"connection\\\";s:6:\\\"sqlite\\\";s:15:\\\"collectionClass\\\";N;}s:7:\\\"chained\\\";a:1:{i:0;s:571:\\\"O:34:\\\"Illuminate\\\\Queue\\\\CallQueuedClosure\\\":1:{s:7:\\\"closure\\\";O:47:\\\"Laravel\\\\SerializableClosure\\\\SerializableClosure\\\":1:{s:12:\\\"serializable\\\";O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Signed\\\":2:{s:12:\\\"serializable\\\";s:282:\\\"O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\\\":5:{s:3:\\\"use\\\";a:0:{}s:8:\\\"function\\\";s:57:\\\"function () {\\n \\\\info('Hello world');\\n }\\\";s:5:\\\"scope\\\";s:44:\\\"Illuminate\\\\Foundation\\\\Console\\\\ClosureCommand\\\";s:4:\\\"this\\\";N;s:4:\\\"self\\\";s:32:\\\"000000000000021e0000000000000000\\\";}\\\";s:4:\\\"hash\\\";s:44:\\\"VGMlRmFr2\\/U1E8lksExnzODwffyWR8oD01WOcQ2SUjE=\\\";}}}\\\";}s:19:\\\"chainCatchCallbacks\\\";a:1:{i:0;O:47:\\\"Laravel\\\\SerializableClosure\\\\SerializableClosure\\\":1:{s:12:\\\"serializable\\\";O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Signed\\\":2:{s:12:\\\"serializable\\\";s:309:\\\"O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\\\":5:{s:3:\\\"use\\\";a:0:{}s:8:\\\"function\\\";s:84:\\\"function (\\\\Throwable \$e) {\\n \\\\Illuminate\\\\Support\\\\Facades\\\\Log::error(\$e);\\n }\\\";s:5:\\\"scope\\\";s:44:\\\"Illuminate\\\\Foundation\\\\Console\\\\ClosureCommand\\\";s:4:\\\"this\\\";N;s:4:\\\"self\\\";s:32:\\\"00000000000002380000000000000000\\\";}\\\";s:4:\\\"hash\\\";s:44:\\\"RBSD4RFLgmKL9WJEGY66aeZtWDkX\\/aY1J+MJ8LQSYi4=\\\";}}}}\"}}",
43+
'attempts' => 0,
44+
'available_at' => 1731919764,
45+
'created_at' => 1731919764,
46+
]);
47+
}
48+
49+
public function testItCanProcessQueueFromSerializableClosureV1()
50+
{
51+
$this->assertDatabaseHas('users', [
52+
'name' => 'Taylor Otwell',
53+
'email' => '[email protected]',
54+
]);
55+
56+
$this->artisan('queue:work', [
57+
'connection' => 'database',
58+
'--stop-when-empty' => true,
59+
'--memory' => 1024,
60+
])->assertExitCode(0);
61+
62+
$this->assertDatabaseMissing('users', [
63+
'name' => 'Taylor Otwell',
64+
'email' => '[email protected]',
65+
]);
66+
}
67+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Integration\Route;
4+
5+
use Illuminate\Foundation\Testing\RefreshDatabase;
6+
use Orchestra\Testbench\Attributes\WithConfig;
7+
use Orchestra\Testbench\Attributes\WithMigration;
8+
use Orchestra\Testbench\Factories\UserFactory;
9+
use Orchestra\Testbench\TestCase;
10+
use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily;
11+
12+
use function Illuminate\Filesystem\join_paths;
13+
14+
#[RequiresOperatingSystemFamily('Linux|Darwin')]
15+
#[WithConfig('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF')]
16+
#[WithMigration]
17+
class SerializableClosureV1CacheRouteTest extends TestCase
18+
{
19+
use RefreshDatabase;
20+
21+
/** {@inheritDoc} */
22+
#[\Override]
23+
protected function getPackageProviders($app)
24+
{
25+
return [
26+
\Illuminate\Foundation\Support\Providers\RouteServiceProvider::class,
27+
];
28+
}
29+
30+
/** {@inheritDoc} */
31+
#[\Override]
32+
protected function setUp(): void
33+
{
34+
$_ENV['APP_ROUTES_CACHE'] = realpath(join_paths(__DIR__, 'stubs', 'serializable-closure-v1', 'routes-v7.php'));
35+
36+
parent::setUp();
37+
}
38+
39+
/** {@inheritDoc} */
40+
#[\Override]
41+
protected function tearDown(): void
42+
{
43+
unset($_ENV['APP_ROUTES_CACHE']);
44+
45+
parent::tearDown();
46+
}
47+
48+
public function testItCanUseCachedRouteFromSerializableClosureV1()
49+
{
50+
$user = UserFactory::new()->create();
51+
52+
$this->assertTrue($this->app->routesAreCached());
53+
54+
$this->get('/')->assertSee('Laravel');
55+
56+
$this->get("/users/{$user->getKey()}")
57+
->assertJson($user->toArray());
58+
}
59+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
app('router')->setCompiledRoutes(
4+
[
5+
'compiled' => [
6+
0 => false,
7+
1 => [
8+
'/' => [
9+
0 => [
10+
0 => [
11+
'_route' => 'generated::7CFionvE02fEbBNP',
12+
],
13+
1 => null,
14+
2 => [
15+
'GET' => 0,
16+
'HEAD' => 1,
17+
],
18+
3 => null,
19+
4 => false,
20+
5 => false,
21+
6 => null,
22+
],
23+
],
24+
],
25+
2 => [
26+
0 => '{^(?|/users/([^/]++)(*:22))/?$}sDu',
27+
],
28+
3 => [
29+
22 => [
30+
0 => [
31+
0 => [
32+
'_route' => 'generated::YmZUvOCRFrqhC2sO',
33+
],
34+
1 => [
35+
0 => 'user',
36+
],
37+
2 => [
38+
'GET' => 0,
39+
'HEAD' => 1,
40+
],
41+
3 => null,
42+
4 => false,
43+
5 => true,
44+
6 => null,
45+
],
46+
1 => [
47+
0 => null,
48+
1 => null,
49+
2 => null,
50+
3 => null,
51+
4 => false,
52+
5 => false,
53+
6 => 0,
54+
],
55+
],
56+
],
57+
4 => null,
58+
],
59+
'attributes' => [
60+
'generated::7CFionvE02fEbBNP' => [
61+
'methods' => [
62+
0 => 'GET',
63+
1 => 'HEAD',
64+
],
65+
'uri' => '/',
66+
'action' => [
67+
'middleware' => [
68+
0 => 'web',
69+
],
70+
'uses' => 'O:55:"Laravel\\SerializableClosure\\UnsignedSerializableClosure":1:{s:12:"serializable";O:46:"Laravel\\SerializableClosure\\Serializers\\Native":5:{s:3:"use";a:0:{}s:8:"function";s:44:"function () {
71+
return \\view(\'welcome\');
72+
}";s:5:"scope";s:37:"Illuminate\\Routing\\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000002f00000000000000000";}}',
73+
'namespace' => null,
74+
'prefix' => '',
75+
'where' => [
76+
],
77+
'as' => 'generated::7CFionvE02fEbBNP',
78+
],
79+
'fallback' => false,
80+
'defaults' => [
81+
],
82+
'wheres' => [
83+
],
84+
'bindingFields' => [
85+
],
86+
'lockSeconds' => null,
87+
'waitSeconds' => null,
88+
'withTrashed' => false,
89+
],
90+
'generated::YmZUvOCRFrqhC2sO' => [
91+
'methods' => [
92+
0 => 'GET',
93+
1 => 'HEAD',
94+
],
95+
'uri' => 'users/{user}',
96+
'action' => [
97+
'middleware' => [
98+
0 => 'web',
99+
],
100+
'uses' => 'O:55:"Laravel\\SerializableClosure\\UnsignedSerializableClosure":1:{s:12:"serializable";O:46:"Laravel\\SerializableClosure\\Serializers\\Native":5:{s:3:"use";a:0:{}s:8:"function";s:52:"fn (\\Illuminate\\Foundation\\Auth\\User $user) => $user";s:5:"scope";s:37:"Illuminate\\Routing\\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000002f20000000000000000";}}',
101+
'namespace' => null,
102+
'prefix' => '',
103+
'where' => [
104+
],
105+
'as' => 'generated::YmZUvOCRFrqhC2sO',
106+
],
107+
'fallback' => false,
108+
'defaults' => [
109+
],
110+
'wheres' => [
111+
],
112+
'bindingFields' => [
113+
],
114+
'lockSeconds' => null,
115+
'waitSeconds' => null,
116+
'withTrashed' => false,
117+
],
118+
],
119+
]
120+
);

0 commit comments

Comments
 (0)