Skip to content

Commit dc97dd2

Browse files
authored
Merge pull request #4 from kettasoft/feature/invoker
Add Serializable support to Invoker
2 parents 8a742ac + ca78f7b commit dc97dd2

File tree

4 files changed

+156
-4
lines changed

4 files changed

+156
-4
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"require": {
3434
"php": "^8.0",
3535
"illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0",
36-
"illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0"
36+
"illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0",
37+
"opis/closure": "^4.3"
3738
},
3839
"require-dev": {
3940
"mockery/mockery": "^1.3.2",

composer.lock

Lines changed: 65 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Foundation/Invoker.php

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@
33
namespace Kettasoft\Filterable\Foundation;
44

55
use Closure;
6+
use Serializable;
7+
use Illuminate\Support\Facades\DB;
8+
use Illuminate\Support\Facades\App;
9+
use Illuminate\Database\Query\Builder;
610
use Illuminate\Support\Traits\ForwardsCalls;
711
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
812
use Kettasoft\Filterable\Foundation\Traits\HandleFluentReturn;
913
use Kettasoft\Filterable\Foundation\Contracts\QueryBuilderInterface;
1014

15+
use function Opis\Closure\{serialize, unserialize};
16+
1117
/**
1218
* Class Invoker
1319
*
@@ -17,7 +23,7 @@
1723
*
1824
* @link https://kettasoft.github.io/filterable/execution/invoker
1925
*/
20-
class Invoker implements QueryBuilderInterface
26+
class Invoker implements QueryBuilderInterface, Serializable
2127
{
2228
use ForwardsCalls,
2329
HandleFluentReturn;
@@ -48,7 +54,7 @@ class Invoker implements QueryBuilderInterface
4854
*
4955
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|QueryBuilderInterface $builder
5056
*/
51-
public function __construct(protected EloquentBuilder|QueryBuilderInterface $builder) {}
57+
public function __construct(protected EloquentBuilder|Builder|QueryBuilderInterface $builder) {}
5258

5359
/**
5460
* Instantiate a new Invoker object using a builder.
@@ -133,6 +139,16 @@ public function onError(Closure $callback)
133139
return $this;
134140
}
135141

142+
/**
143+
* Get the underlying query builder instance.
144+
*
145+
* @return Builder|EloquentBuilder|QueryBuilderInterface
146+
*/
147+
public function getBuilder(): EloquentBuilder|Builder|QueryBuilderInterface
148+
{
149+
return $this->builder;
150+
}
151+
136152
/**
137153
* Dispatch the query execution as a Laravel job.
138154
*
@@ -161,6 +177,42 @@ public function asJob(string $jobClass, array $jobData = [], string|null $queue
161177
return dispatch($job);
162178
}
163179

180+
/**
181+
* Serialize the Invoker instance.
182+
*
183+
* @return string
184+
*/
185+
public function serialize(): string
186+
{
187+
return serialize([
188+
'builder_sql' => $this->builder->toSql(),
189+
'builder_bindings' => $this->builder->getBindings(),
190+
'beforeCallback' => $this->beforeCallback ? serialize($this->beforeCallback) : null,
191+
'afterCallback' => $this->afterCallback ? serialize($this->afterCallback) : null,
192+
'errorCallback' => $this->errorCallback ? serialize($this->errorCallback) : null
193+
]);
194+
}
195+
196+
/**
197+
* Unserialize the Invoker instance.
198+
*
199+
* @param string $data
200+
* @return void
201+
*/
202+
public function unserialize($data): void
203+
{
204+
$unserialized = unserialize($data);
205+
$connection = App::make('db')->connection();
206+
207+
$this->builder = $connection->table(DB::raw("({$unserialized['builder_sql']}) as t"));
208+
209+
$this->builder->setBindings($unserialized['builder_bindings']);
210+
211+
$this->beforeCallback = $unserialized['beforeCallback'];
212+
$this->afterCallback = $unserialized['afterCallback'];
213+
$this->errorCallback = $unserialized['errorCallback'];
214+
}
215+
164216
/**
165217
* Handles dynamic calls to the builder, and tracks execution time
166218
* for terminal methods only.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Kettasoft\Filterable\Tests\Feature\Invoker;
4+
5+
use Kettasoft\Filterable\Tests\Models\Post;
6+
use Kettasoft\Filterable\Tests\TestCase;
7+
8+
class InvokerSerializationTest extends TestCase
9+
{
10+
public function test_it_can_be_serialized_and_unserialized()
11+
{
12+
$builder = Post::query();
13+
$invoker = new \Kettasoft\Filterable\Foundation\Invoker($builder);
14+
15+
// Set some callbacks
16+
$invoker->beforeExecute(function () {
17+
return 'before';
18+
});
19+
$invoker->afterExecute(function () {
20+
return 'after';
21+
});
22+
$invoker->onError(function () {
23+
return 'error';
24+
});
25+
26+
// Serialize the invoker
27+
$serialized = serialize($invoker);
28+
29+
// Unserialize the invoker
30+
$unserializedInvoker = unserialize($serialized);
31+
32+
// Assert that the unserialized object is an instance of Invoker
33+
$this->assertInstanceOf(\Kettasoft\Filterable\Foundation\Invoker::class, $unserializedInvoker);
34+
}
35+
}

0 commit comments

Comments
 (0)