Skip to content

Commit 680bc15

Browse files
committed
Remove task array access
1 parent 6a2bef7 commit 680bc15

File tree

5 files changed

+87
-152
lines changed

5 files changed

+87
-152
lines changed

src/Contracts/Task.php

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
use Meilisearch\Contracts\TaskDetails\TaskCancelationDetails;
1717
use Meilisearch\Contracts\TaskDetails\TaskDeletionDetails;
1818

19-
final class Task implements \ArrayAccess
19+
final class Task
2020
{
2121
/**
2222
* @param non-negative-int $taskUid
2323
* @param non-empty-string|null $indexUid
24-
* @param array<mixed> $data Raw data
2524
*/
2625
public function __construct(
2726
private readonly int $taskUid,
@@ -36,7 +35,6 @@ public function __construct(
3635
private readonly ?int $batchUid = null,
3736
private readonly ?TaskDetails $details = null,
3837
private readonly ?TaskError $error = null,
39-
private readonly array $data = [],
4038
) {
4139
}
4240

@@ -106,38 +104,6 @@ public function getError(): ?TaskError
106104
return $this->error;
107105
}
108106

109-
/**
110-
* @return array<mixed>
111-
*/
112-
public function getData(): array
113-
{
114-
return $this->data;
115-
}
116-
117-
// @todo: deprecate
118-
public function offsetExists(mixed $offset): bool
119-
{
120-
return \array_key_exists($offset, $this->data);
121-
}
122-
123-
// @todo: deprecate
124-
public function offsetGet(mixed $offset): mixed
125-
{
126-
return $this->data[$offset] ?? null;
127-
}
128-
129-
// @todo: deprecate
130-
public function offsetSet(mixed $offset, mixed $value): void
131-
{
132-
throw new \LogicException(\sprintf('Setting data on "%s::%s" is not supported.', get_debug_type($this), $offset));
133-
}
134-
135-
// @todo: deprecate
136-
public function offsetUnset(mixed $offset): void
137-
{
138-
throw new \LogicException(\sprintf('Unsetting data on "%s::%s" is not supported.', get_debug_type($this), $offset));
139-
}
140-
141107
public function isFinished(): bool
142108
{
143109
return TaskStatus::Enqueued !== $this->status && TaskStatus::Processing !== $this->status;
@@ -151,47 +117,47 @@ public function isFinished(): bool
151117
* status: non-empty-string,
152118
* type: non-empty-string,
153119
* enqueuedAt: non-empty-string,
154-
* startedAt?: non-empty-string,
155-
* finishedAt?: non-empty-string,
156-
* duration?: non-empty-string,
120+
* startedAt?: non-empty-string|null,
121+
* finishedAt?: non-empty-string|null,
122+
* duration?: non-empty-string|null,
157123
* canceledBy?: int,
158124
* batchUid?: int,
159125
* details?: array<mixed>|null,
160-
* error?: array<mixed>|null,
161-
* data: array<mixed>
126+
* error?: array<mixed>|null
162127
* } $data
163128
*/
164129
public static function fromArray(array $data): Task
165130
{
131+
$details = $data['details'] ?? null;
132+
166133
return new self(
167134
$data['taskUid'] ?? $data['uid'],
168135
$data['indexUid'] ?? null,
169136
TaskStatus::from($data['status']),
170137
$type = TaskType::from($data['type']),
171138
new \DateTimeImmutable($data['enqueuedAt']),
172-
isset($data['startedAt']) ? new \DateTimeImmutable($data['startedAt']) : null,
173-
isset($data['finishedAt']) ? new \DateTimeImmutable($data['finishedAt']) : null,
139+
\array_key_exists('startedAt', $data) && null !== $data['startedAt'] ? new \DateTimeImmutable($data['startedAt']) : null,
140+
\array_key_exists('finishedAt', $data) && null !== $data['finishedAt'] ? new \DateTimeImmutable($data['finishedAt']) : null,
174141
$data['duration'] ?? null,
175142
$data['canceledBy'] ?? null,
176143
$data['batchUid'] ?? null,
177144
match ($type) {
178-
TaskType::IndexCreation => null !== $data['details'] ? IndexCreationDetails::fromArray($data['details']) : null,
179-
TaskType::IndexUpdate => null !== $data['details'] ? IndexUpdateDetails::fromArray($data['details']) : null,
180-
TaskType::IndexDeletion => null !== $data['details'] ? IndexDeletionDetails::fromArray($data['details']) : null,
181-
TaskType::IndexSwap => null !== $data['details'] ? IndexSwapDetails::fromArray($data['details']) : null,
182-
TaskType::DocumentAdditionOrUpdate => null !== $data['details'] ? DocumentAdditionOrUpdateDetails::fromArray($data['details']) : null,
183-
TaskType::DocumentDeletion => null !== $data['details'] ? DocumentDeletionDetails::fromArray($data['details']) : null,
184-
TaskType::DocumentEdition => null !== $data['details'] ? DocumentEditionDetails::fromArray($data['details']) : null,
185-
TaskType::SettingsUpdate => null !== $data['details'] ? SettingsUpdateDetails::fromArray($data['details']) : null,
186-
TaskType::DumpCreation => null !== $data['details'] ? DumpCreationDetails::fromArray($data['details']) : null,
187-
TaskType::TaskCancelation => null !== $data['details'] ? TaskCancelationDetails::fromArray($data['details']) : null,
188-
TaskType::TaskDeletion => null !== $data['details'] ? TaskDeletionDetails::fromArray($data['details']) : null,
145+
TaskType::IndexCreation => null !== $details ? IndexCreationDetails::fromArray($details) : null,
146+
TaskType::IndexUpdate => null !== $details ? IndexUpdateDetails::fromArray($details) : null,
147+
TaskType::IndexDeletion => null !== $details ? IndexDeletionDetails::fromArray($details) : null,
148+
TaskType::IndexSwap => null !== $details ? IndexSwapDetails::fromArray($details) : null,
149+
TaskType::DocumentAdditionOrUpdate => null !== $details ? DocumentAdditionOrUpdateDetails::fromArray($details) : null,
150+
TaskType::DocumentDeletion => null !== $details ? DocumentDeletionDetails::fromArray($details) : null,
151+
TaskType::DocumentEdition => null !== $details ? DocumentEditionDetails::fromArray($details) : null,
152+
TaskType::SettingsUpdate => null !== $details ? SettingsUpdateDetails::fromArray($details) : null,
153+
TaskType::DumpCreation => null !== $details ? DumpCreationDetails::fromArray($details) : null,
154+
TaskType::TaskCancelation => null !== $details ? TaskCancelationDetails::fromArray($details) : null,
155+
TaskType::TaskDeletion => null !== $details ? TaskDeletionDetails::fromArray($details) : null,
189156
// It’s intentional that SnapshotCreation tasks don’t have a details object
190157
// (no SnapshotCreationDetails exists and tests don’t exercise any details)
191158
TaskType::SnapshotCreation => null,
192159
},
193-
null !== $data['error'] ? TaskError::fromArray($data['error']) : null,
194-
$data,
160+
\array_key_exists('error', $data) && null !== $data['error'] ? TaskError::fromArray($data['error']) : null,
195161
);
196162
}
197163
}

src/Contracts/TaskDetails/DocumentAdditionOrUpdateDetails.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
final class DocumentAdditionOrUpdateDetails implements TaskDetails
1616
{
1717
/**
18-
* @param non-negative-int $receivedDocuments Number of documents received
18+
* @param non-negative-int $receivedDocuments Number of documents received.
1919
* @param non-negative-int|null $indexedDocuments Number of documents indexed. `null` while the task status is enqueued or processing.
2020
*/
2121
public function __construct(

tests/Contracts/TaskTest.php

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use Meilisearch\Contracts\TaskStatus;
1111
use Meilisearch\Contracts\TaskType;
1212
use PHPUnit\Framework\TestCase;
13-
use Tests\MockTask;
1413

1514
final class TaskTest extends TestCase
1615
{
@@ -34,13 +33,6 @@ public function testCreate(): void
3433
'invalid_request',
3534
'https://docs.meilisearch.com/errors#index_not_found',
3635
),
37-
data: [
38-
'taskUid' => 1,
39-
'indexUid' => 'documents',
40-
'status' => 'failed',
41-
'type' => 'index_creation',
42-
'enqueuedAt' => '2025-04-09T10:28:12.236789123Z',
43-
],
4436
);
4537

4638
self::assertSame(1, $task->getTaskUid());
@@ -60,20 +52,6 @@ public function testCreate(): void
6052
'invalid_request',
6153
'https://docs.meilisearch.com/errors#index_not_found',
6254
), $task->getError());
63-
self::assertSame([
64-
'taskUid' => 1,
65-
'indexUid' => 'documents',
66-
'status' => 'failed',
67-
'type' => 'index_creation',
68-
'enqueuedAt' => '2025-04-09T10:28:12.236789123Z',
69-
], $task->getData());
70-
71-
// Ensure the class supports array access retrocompatibility
72-
self::assertSame(1, $task->getTaskUid());
73-
self::assertSame('documents', $task['indexUid']);
74-
self::assertSame('failed', $task['status']);
75-
self::assertSame('index_creation', $task['type']);
76-
self::assertSame('2025-04-09T10:28:12.236789123Z', $task['enqueuedAt']);
7755
}
7856

7957
public function testCreateEnqueuedTask(): void
@@ -99,24 +77,4 @@ public function testCreateEnqueuedTask(): void
9977
self::assertNull($task->getDetails());
10078
self::assertNull($task->getError());
10179
}
102-
103-
public function testArraySetThrows(): void
104-
{
105-
$task = MockTask::create(TaskType::IndexCreation);
106-
107-
$this->expectException(\LogicException::class);
108-
$this->expectExceptionMessage('Setting data on "Meilisearch\Contracts\Task::type" is not supported.');
109-
110-
$task['type'] = TaskType::IndexDeletion;
111-
}
112-
113-
public function testArrayUnsetThrows(): void
114-
{
115-
$task = MockTask::create(TaskType::IndexCreation);
116-
117-
$this->expectException(\LogicException::class);
118-
$this->expectExceptionMessage('Unsetting data on "Meilisearch\Contracts\Task::type" is not supported.');
119-
120-
unset($task['type']);
121-
}
12280
}

tests/Endpoints/DocumentsTest.php

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use Meilisearch\Contracts\DocumentsQuery;
88
use Meilisearch\Contracts\Http;
99
use Meilisearch\Contracts\Task;
10+
use Meilisearch\Contracts\TaskDetails\DocumentAdditionOrUpdateDetails;
11+
use Meilisearch\Contracts\TaskStatus;
1012
use Meilisearch\Contracts\TaskType;
1113
use Meilisearch\Endpoints\Indexes;
1214
use Meilisearch\Exceptions\ApiException;
@@ -75,11 +77,11 @@ public function testAddDocumentsCsv(): void
7577
fclose($fileCsv);
7678

7779
$task = $index->addDocumentsCsv($documentCsv);
80+
$completedTask = $index->waitForTask($task->getTaskUid());
7881

79-
$update = $index->waitForTask($task->getTaskUid());
80-
81-
self::assertSame('succeeded', $update['status']);
82-
self::assertNotSame(0, $update['details']['receivedDocuments']);
82+
self::assertSame(TaskStatus::Succeeded, $completedTask->getStatus());
83+
self::assertInstanceOf(DocumentAdditionOrUpdateDetails::class, $details = $completedTask->getDetails());
84+
self::assertNotSame(0, $details->receivedDocuments);
8385

8486
$response = $index->getDocuments();
8587
self::assertCount(20, $response);
@@ -92,11 +94,11 @@ public function testAddDocumentsCsvWithCustomSeparator(): void
9294
$csv = file_get_contents('./tests/datasets/songs-custom-separator.csv', true);
9395

9496
$task = $index->addDocumentsCsv($csv, null, '|');
97+
$completedTask = $index->waitForTask($task->getTaskUid());
9598

96-
$update = $index->waitForTask($task->getTaskUid());
97-
98-
self::assertSame('succeeded', $update['status']);
99-
self::assertSame(6, $update['details']['receivedDocuments']);
99+
self::assertSame(TaskStatus::Succeeded, $completedTask->getStatus());
100+
self::assertInstanceOf(DocumentAdditionOrUpdateDetails::class, $details = $completedTask->getDetails());
101+
self::assertSame(6, $details->receivedDocuments);
100102

101103
$documents = $index->getDocuments()->getResults();
102104
self::assertSame('Teenage Neon Jungle', $documents[4]['album']);
@@ -112,11 +114,11 @@ public function testAddDocumentsJson(): void
112114
fclose($fileJson);
113115

114116
$task = $index->addDocumentsJson($documentJson);
117+
$completedTask = $index->waitForTask($task->getTaskUid());
115118

116-
$update = $index->waitForTask($task->getTaskUid());
117-
118-
self::assertSame('succeeded', $update['status']);
119-
self::assertNotSame(0, $update['details']['receivedDocuments']);
119+
self::assertSame(TaskStatus::Succeeded, $completedTask->getStatus());
120+
self::assertInstanceOf(DocumentAdditionOrUpdateDetails::class, $details = $completedTask->getDetails());
121+
self::assertNotSame(0, $details->receivedDocuments);
120122

121123
$response = $index->getDocuments();
122124
self::assertCount(20, $response);
@@ -131,11 +133,11 @@ public function testAddDocumentsNdJson(): void
131133
fclose($fileNdJson);
132134

133135
$task = $index->addDocumentsNdjson($documentNdJson);
136+
$completedTask = $index->waitForTask($task->getTaskUid());
134137

135-
$update = $index->waitForTask($task->getTaskUid());
136-
137-
self::assertSame('succeeded', $update['status']);
138-
self::assertNotSame(0, $update['details']['receivedDocuments']);
138+
self::assertSame(TaskStatus::Succeeded, $completedTask->getStatus());
139+
self::assertInstanceOf(DocumentAdditionOrUpdateDetails::class, $details = $completedTask->getDetails());
140+
self::assertNotSame(0, $details->receivedDocuments);
139141

140142
$response = $index->getDocuments();
141143
self::assertCount(20, $response);
@@ -155,8 +157,10 @@ public function testCannotAddDocumentWhenJsonEncodingFails(): void
155157
public function testGetSingleDocumentWithIntegerDocumentId(): void
156158
{
157159
$index = $this->createEmptyIndex($this->safeIndexName('movies'));
160+
158161
$task = $index->addDocuments(self::DOCUMENTS);
159162
$index->waitForTask($task->getTaskUid());
163+
160164
$doc = $this->findDocumentWithId(self::DOCUMENTS, 4);
161165
$response = $index->getDocument($doc['id']);
162166

@@ -167,8 +171,10 @@ public function testGetSingleDocumentWithIntegerDocumentId(): void
167171
public function testGetSingleDocumentWithFields(): void
168172
{
169173
$index = $this->createEmptyIndex($this->safeIndexName('movies'));
174+
170175
$task = $index->addDocuments(self::DOCUMENTS);
171176
$index->waitForTask($task->getTaskUid());
177+
172178
$doc = $this->findDocumentWithId(self::DOCUMENTS, 4);
173179
$response = $index->getDocument($doc['id'], ['title']);
174180

@@ -179,8 +185,10 @@ public function testGetSingleDocumentWithFields(): void
179185
public function testGetSingleDocumentWithStringDocumentId(): void
180186
{
181187
$stringDocumentId = 'myUniqueId';
188+
182189
$index = $this->createEmptyIndex($this->safeIndexName('movies'));
183190
$task = $index->addDocuments([['id' => $stringDocumentId]]);
191+
184192
$index->waitForTask($task->getTaskUid());
185193
$response = $index->getDocument($stringDocumentId);
186194

@@ -190,8 +198,10 @@ public function testGetSingleDocumentWithStringDocumentId(): void
190198
public function testGetMultipleDocumentsByIds(): void
191199
{
192200
$index = $this->createEmptyIndex($this->safeIndexName('movies'));
201+
193202
$task = $index->addDocuments(self::DOCUMENTS);
194203
$index->waitForTask($task->getTaskUid());
204+
195205
$documentIds = [1, 2];
196206
$response = $index->getDocuments((new DocumentsQuery())->setIds($documentIds));
197207

@@ -204,8 +214,10 @@ public function testGetMultipleDocumentsByIds(): void
204214
public function testReplaceDocuments(): void
205215
{
206216
$index = $this->createEmptyIndex($this->safeIndexName('movies'));
217+
207218
$task = $index->addDocuments(self::DOCUMENTS);
208219
$index->waitForTask($task->getTaskUid());
220+
209221
$replacement = [
210222
'id' => 2,
211223
'title' => 'The Red And The Black',
@@ -917,7 +929,7 @@ public function testUpdateDocumentsNdjsonInBatches(): void
917929
self::assertSame('Ailitp', $response['artist']);
918930
}
919931

920-
private function findDocumentWithId($documents, $documentId)
932+
private function findDocumentWithId($documents, $documentId): ?array
921933
{
922934
foreach ($documents as $document) {
923935
if ($document['id'] === $documentId) {

0 commit comments

Comments
 (0)