Skip to content

Commit 5dd36ae

Browse files
committed
Fix normalization with NormalizableInterface
1 parent 96b85f8 commit 5dd36ae

File tree

6 files changed

+122
-10
lines changed

6 files changed

+122
-10
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"config": {
5757
"sort-packages": true,
5858
"allow-plugins": {
59-
"phpstan/extension-installer": true
59+
"phpstan/extension-installer": true,
60+
"php-http/discovery": true
6061
}
6162
},
6263
"scripts": {

src/SearchableEntity.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\ORM\Mapping\ClassMetadata;
88
use Symfony\Component\Config\Definition\Exception\Exception;
99
use Symfony\Component\Serializer\Exception\ExceptionInterface;
10+
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
1011
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
1112

1213
/**
@@ -22,8 +23,7 @@ final class SearchableEntity
2223
/** @var ClassMetadata<object> */
2324
private ClassMetadata $entityMetadata;
2425

25-
/** @var object */
26-
private $normalizer;
26+
private ?NormalizerInterface $normalizer;
2727

2828
private bool $useSerializerGroups;
2929

@@ -34,14 +34,13 @@ final class SearchableEntity
3434
* SearchableEntity constructor.
3535
*
3636
* @param object $entity
37-
* @param object|null $normalizer
3837
* @param ClassMetadata<object> $entityMetadata
3938
*/
4039
public function __construct(
4140
string $indexUid,
4241
$entity,
4342
ClassMetadata $entityMetadata,
44-
$normalizer = null,
43+
?NormalizerInterface $normalizer = null,
4544
array $extra = []
4645
) {
4746
$this->indexUid = $indexUid;
@@ -71,7 +70,11 @@ public function getSearchableArray(): array
7170
$context['groups'] = [Searchable::NORMALIZATION_GROUP];
7271
}
7372

74-
if ($this->normalizer instanceof NormalizerInterface) {
73+
if ($this->entity instanceof NormalizableInterface && null !== $this->normalizer) {
74+
return $this->entity->normalize($this->normalizer, Searchable::NORMALIZATION_FORMAT, $context);
75+
}
76+
77+
if (null !== $this->normalizer) {
7578
return $this->normalizer->normalize($this->entity, Searchable::NORMALIZATION_FORMAT, $context);
7679
}
7780

@@ -86,7 +89,7 @@ private function setId(): void
8689
throw new Exception('Entity has no primary key');
8790
}
8891

89-
if (1 == \count($ids)) {
92+
if (1 === \count($ids)) {
9093
$this->id = reset($ids);
9194
} else {
9295
$objectID = '';

src/Services/MeilisearchService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
use Symfony\Component\Config\Definition\Exception\Exception;
1717
use Symfony\Component\PropertyAccess\PropertyAccess;
1818
use Symfony\Component\PropertyAccess\PropertyAccessor;
19-
use Symfony\Component\Serializer\SerializerInterface;
19+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2020

2121
/**
2222
* Class MeilisearchService.
2323
*/
2424
final class MeilisearchService implements SearchService
2525
{
26-
private SerializerInterface $normalizer;
26+
private NormalizerInterface $normalizer;
2727
private Engine $engine;
2828
private Collection $configuration;
2929
private PropertyAccessor $propertyAccessor;
@@ -33,7 +33,7 @@ final class MeilisearchService implements SearchService
3333
private array $classToSerializerGroupMapping;
3434
private array $indexIfMapping;
3535

36-
public function __construct(SerializerInterface $normalizer, Engine $engine, array $configuration)
36+
public function __construct(NormalizerInterface $normalizer, Engine $engine, array $configuration)
3737
{
3838
$this->normalizer = $normalizer;
3939
$this->engine = $engine;

tests/Entity/SelfNormalizable.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Bundle\Test\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Meilisearch\Bundle\Searchable;
9+
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
10+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
11+
12+
/**
13+
* @ORM\Entity
14+
*/
15+
class SelfNormalizable implements NormalizableInterface
16+
{
17+
/**
18+
* @ORM\Id
19+
*
20+
* @ORM\Column(type="integer")
21+
*/
22+
private int $id;
23+
24+
/**
25+
* @ORM\Column(type="string")
26+
*/
27+
private string $name;
28+
29+
/**
30+
* @ORM\Column(type="datetime_immutable")
31+
*/
32+
private \DateTimeImmutable $createdAt;
33+
34+
public function __construct(int $id, string $name)
35+
{
36+
$this->id = $id;
37+
$this->name = $name;
38+
$this->createdAt = new \DateTimeImmutable();
39+
}
40+
41+
public function getId(): int
42+
{
43+
return $this->id;
44+
}
45+
46+
public function getName(): string
47+
{
48+
return $this->name;
49+
}
50+
51+
public function getCreatedAt(): \DateTimeImmutable
52+
{
53+
return $this->createdAt;
54+
}
55+
56+
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []): array
57+
{
58+
if (Searchable::NORMALIZATION_FORMAT === $format) {
59+
return [
60+
'id' => $this->id,
61+
'name' => 'this test is correct',
62+
'self_normalized' => true,
63+
];
64+
}
65+
66+
return [];
67+
}
68+
}

tests/Integration/CommandsTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Meilisearch\Bundle\Tests\Integration;
66

77
use Meilisearch\Bundle\Tests\BaseKernelTestCase;
8+
use Meilisearch\Bundle\Test\Entity\SelfNormalizable;
89
use Meilisearch\Client;
910
use Meilisearch\Endpoints\Indexes;
1011
use Meilisearch\Exceptions\ApiException;
@@ -330,4 +331,41 @@ public function testCreateExecuteIndexCreation(): void
330331

331332
$this->assertEquals($this->client->getTasks()->getResults()[0]['type'], 'indexCreation');
332333
}
334+
335+
public function testImportsSelfNormalizable(): void
336+
{
337+
for ($i = 1; $i <= 2; ++$i) {
338+
$this->entityManager->persist(new SelfNormalizable($i, "Self normalizabie $i"));
339+
}
340+
341+
$this->entityManager->flush();
342+
343+
$importCommand = $this->application->find('meili:import');
344+
$importCommandTester = new CommandTester($importCommand);
345+
$importCommandTester->execute(['--indices' => 'self_normalizable']);
346+
347+
$importOutput = $importCommandTester->getDisplay();
348+
349+
$this->assertSame(<<<'EOD'
350+
Importing for index Meilisearch\Bundle\Test\Entity\SelfNormalizable
351+
Indexed 2 / 2 Meilisearch\Bundle\Test\Entity\SelfNormalizable entities into sf_phpunit__self_normalizable index
352+
Done!
353+
354+
EOD, $importOutput);
355+
356+
self::assertSame([
357+
[
358+
'objectID' => 1,
359+
'id' => 1,
360+
'name' => 'this test is correct',
361+
'self_normalized' => true,
362+
],
363+
[
364+
'objectID' => 2,
365+
'id' => 2,
366+
'name' => 'this test is correct',
367+
'self_normalized' => true,
368+
],
369+
], $this->client->index('sf_phpunit__self_normalizable')->getDocuments()->getResults());
370+
}
333371
}

tests/config/meilisearch.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ meilisearch:
3434
- name: pages
3535
class: 'Meilisearch\Bundle\Tests\Entity\Page'
3636
enable_serializer_groups: true
37+
- name: self_normalizable
38+
class: 'Meilisearch\Bundle\Test\Entity\SelfNormalizable'

0 commit comments

Comments
 (0)