Skip to content

Commit 8279f54

Browse files
committed
Inject document factory soft delete config
1 parent 7fd1166 commit 8279f54

5 files changed

Lines changed: 66 additions & 17 deletions

File tree

src/Factories/DocumentFactory.php

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,63 @@
1313
*/
1414
class DocumentFactory implements DocumentFactoryInterface
1515
{
16+
/**
17+
* Create a new document factory instance.
18+
*/
19+
public function __construct(
20+
protected bool $softDelete = false,
21+
) {}
22+
1623
/**
1724
* Create OpenSearch documents from the given model collection.
1825
*/
1926
public function makeFromModels(Collection $models): Collection
2027
{
2128
return $models->map(function (Model $model) {
22-
if (
23-
config('scout.soft_delete', false) &&
24-
in_array(SoftDeletes::class, class_uses_recursive($model), true)
25-
) {
29+
if ($this->softDelete && $this->isSoftDeletable($model)) {
2630
$model->pushSoftDeleteMetadata();
2731
}
2832

29-
$documentId = (string) $model->getScoutKey();
30-
$documentContent = array_merge($model->scoutMetadata(), $model->toSearchableArray());
33+
$source = $this->makeDocumentSource($model);
3134

32-
if (array_key_exists('_id', $documentContent)) {
33-
throw new UnexpectedValueException(sprintf(
34-
'_id is not allowed in the document content. Please, make sure the field is not returned by '.
35-
'the %1$s::toSearchableArray or %1$s::scoutMetadata methods.',
36-
class_basename($model)
37-
));
38-
}
35+
$this->assertValidDocumentSource($model, $source);
3936

40-
return new Document($documentId, $documentContent);
37+
return new Document((string) $model->getScoutKey(), $source);
4138
});
4239
}
40+
41+
/**
42+
* Assert that the given document source is valid.
43+
*
44+
* @throws \UnexpectedValueException
45+
*/
46+
protected function assertValidDocumentSource(Model $model, array $source): void
47+
{
48+
if (array_key_exists('_id', $source)) {
49+
throw new UnexpectedValueException(sprintf(
50+
'_id is not allowed in the document source. Please, make sure the field is not returned by '.
51+
'the %1$s::toSearchableArray or %1$s::scoutMetadata methods.',
52+
class_basename($model)
53+
));
54+
}
55+
}
56+
57+
/**
58+
* Create the document source from the given model.
59+
*/
60+
protected function makeDocumentSource(Model $model): array
61+
{
62+
return array_merge(
63+
$model->scoutMetadata(),
64+
$model->toSearchableArray()
65+
);
66+
}
67+
68+
/**
69+
* Determine if the given model uses soft deletes.
70+
*/
71+
protected function isSoftDeletable(Model $model): bool
72+
{
73+
return in_array(SoftDeletes::class, class_uses_recursive($model), true);
74+
}
4375
}

src/OpenSearchScoutServiceProvider.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ public function register(): void
3030
$this->mergeConfigFrom(__DIR__.'/../config/opensearch-scout.php', 'opensearch-scout');
3131

3232
$this->app->bind(ModelFactoryInterface::class, ModelFactory::class);
33-
$this->app->bind(DocumentFactoryInterface::class, DocumentFactory::class);
3433
$this->app->bind(SearchRequestFactoryInterface::class, SearchRequestFactory::class);
3534

35+
$this->app->bind(DocumentFactoryInterface::class, function (Application $app) {
36+
return new DocumentFactory($app['config']->get('scout.soft_delete', false));
37+
});
38+
3639
$this->app->singleton(DocumentManagerInterface::class, function (Application $app) {
3740
return new DocumentManager($app->make(OpenSearchManager::class)->default());
3841
});

src/SearchRequestPayload.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function toArray(): array
9999
'from' => $this->from,
100100
'size' => $this->size,
101101
'aggregations' => $this->aggregations,
102-
], fn (mixed $value) => blank($value) === false);
102+
], fn (mixed $value) => filled($value));
103103
}
104104

105105
/**

tests/Integration/OpenSearchScoutDriverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
it('indexes and filters soft deleted models when scout soft deletes are enabled', function (): void {
8282
config()->set('scout.soft_delete', true);
8383

84-
$engine = app(EngineManager::class)->engine('opensearch');
84+
$engine = app(EngineManager::class)->forgetDrivers()->engine('opensearch');
8585

8686
Client::query()->whereKey(3)->delete();
8787

tests/Unit/Factories/DocumentFactoryTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
->and($documents->first()->source())->toBe(['name' => 'John', 'email' => 'john@example.com']);
2020
});
2121

22+
it('creates documents with soft delete metadata when enabled', function () {
23+
$model = new Client(['id' => 1, 'name' => 'John']);
24+
25+
$model->deleted_at = now();
26+
27+
$document = (new DocumentFactory(softDelete: true))->makeFromModels(new Collection([$model]))->first();
28+
29+
expect($document->source())->toBe([
30+
'__soft_deleted' => 1,
31+
'name' => 'John',
32+
'email' => 'john@example.com',
33+
]);
34+
});
35+
2236
it('rejects restricted document fields', function () {
2337
$model = new class extends Client
2438
{

0 commit comments

Comments
 (0)