Skip to content

Commit 50fffdd

Browse files
committed
Added support for 'enumType' property option on entities having an enum
value.
1 parent 399224d commit 50fffdd

File tree

9 files changed

+124
-59
lines changed

9 files changed

+124
-59
lines changed

src/Annotation/Property.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ final class Property implements PropertyAnnotationInterface, DumperInterface
2727
*/
2828
public string $type;
2929

30+
public ?string $enumType = null;
31+
3032
public bool $multilanguage = false;
3133

3234
/**
@@ -37,7 +39,7 @@ final class Property implements PropertyAnnotationInterface, DumperInterface
3739
/**
3840
* The object name must be defined, if type is 'object' or 'nested'
3941
*/
40-
public string $objectName;
42+
public ?string $objectName = null;
4143

4244
/**
4345
* Defines if related object will have one or multiple values.

src/Mapping/DocumentParser.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,12 @@ public function getPropertiesMetadata(\ReflectionClass $documentReflection): arr
103103
switch ($propertyAnnotation::class) {
104104
case Property::class:
105105
$propertyMetadata[$propertyAnnotation->name] = [
106-
'propertyName' => $propertyName,
107-
'type' => $propertyAnnotation->type,
108-
'multilanguage' => $propertyAnnotation->multilanguage,
106+
'propertyName' => $propertyName,
107+
'type' => $propertyAnnotation->type,
109108
];
109+
if ($propertyAnnotation->multilanguage) {
110+
$propertyMetadata[$propertyAnnotation->name]['multilanguage'] = true;
111+
}
110112

111113
// If property is a (nested) object
112114
if (\in_array($propertyAnnotation->type, ['object', 'nested'])) {
@@ -122,6 +124,10 @@ public function getPropertiesMetadata(\ReflectionClass $documentReflection): arr
122124
'className' => $child->getName(),
123125
]
124126
);
127+
} else {
128+
if (null !== $propertyAnnotation->enumType) {
129+
$propertyMetadata[$propertyAnnotation->name]['enumType'] = $propertyAnnotation->enumType;
130+
}
125131
}
126132
break;
127133

src/Result/DocumentConverter.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ public function assignArrayToObject(array $array, ObjectInterface $object, array
8585
continue;
8686
}
8787

88-
if (\in_array($propertyMetadata['type'], ['string', 'keyword', 'text']) && !empty($propertyMetadata['multilanguage'])) {
88+
if (!empty($propertyMetadata['enumType'])) {
89+
$objectValue = $propertyMetadata['enumType']::from($array[$esField]);
90+
} elseif (\in_array($propertyMetadata['type'], ['string', 'keyword', 'text']) && !empty($propertyMetadata['multilanguage'])) {
8991
$objectValue = null;
9092
foreach ($array as $fieldName => $value) {
9193
$prefixLength = \strlen($esField.$this->languageSeparator);

tests/App/fixture/Acme/FooBundle/Document/Customer.php

+12-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Sineflow\ElasticsearchBundle\Annotation as ES;
66
use Sineflow\ElasticsearchBundle\Document\AbstractDocument;
77
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Document\Provider\CustomerProvider;
8+
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum\CustomerTypeEnum;
89

910
/**
1011
* @ES\Document(
@@ -16,15 +17,22 @@ class Customer extends AbstractDocument
1617
/**
1718
* Test adding raw mapping.
1819
*
19-
* @var string
20-
*
2120
* @ES\Property(name="name", type="keyword")
2221
*/
23-
public $name;
22+
public string $name;
2423

2524
/**
26-
* @var bool
25+
* Test adding raw mapping.
2726
*
27+
* @ES\Property(
28+
* name="customer_type",
29+
* type="integer",
30+
* enumType=Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum\CustomerTypeEnum::class
31+
* )
32+
*/
33+
public ?CustomerTypeEnum $customerType = null;
34+
35+
/**
2836
* @ES\Property(name="active", type="boolean")
2937
*/
3038
private $active;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Document;
4+
5+
use Sineflow\ElasticsearchBundle\Annotation as ES;
6+
use Sineflow\ElasticsearchBundle\Document\AbstractDocument;
7+
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum\CustomerTypeEnum;
8+
9+
/**
10+
* @ES\Document
11+
*/
12+
class EntityWithInvalidEnum extends AbstractDocument
13+
{
14+
/**
15+
* @ES\Property(
16+
* name="enum_test",
17+
* type="string",
18+
* enumType=nonExistingEnumClass
19+
* )
20+
*/
21+
public ?CustomerTypeEnum $enumTest = null;
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum;
4+
5+
enum CustomerTypeEnum: int
6+
{
7+
case INDIVIDUAL = 1;
8+
case COMPANY = 2;
9+
}

tests/Functional/Finder/FinderTest.php

+44-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Sineflow\ElasticsearchBundle\Tests\AbstractElasticsearchTestCase;
1010
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\BarBundle\Document\Product;
1111
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Document\Customer;
12+
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum\CustomerTypeEnum;
1213

1314
/**
1415
* Class FinderTest
@@ -39,10 +40,17 @@ protected function getDataArray()
3940
],
4041
'customer' => [
4142
[
42-
'_id' => 111,
43-
'name' => 'Jane Doe',
44-
'title' => 'aaa bbb',
45-
'active' => true,
43+
'_id' => 111,
44+
'name' => 'Jane Doe',
45+
'title' => 'aaa bbb',
46+
'active' => true,
47+
'customer_type' => CustomerTypeEnum::COMPANY, // When php-elasticsearch serializes the request, json_encode will convert this to a scalar value
48+
],
49+
[
50+
'_id' => 222,
51+
'name' => 'John Doe',
52+
'title' => 'bbb',
53+
'customer_type' => 1,
4654
],
4755
],
4856
];
@@ -153,22 +161,47 @@ public function testFindInMultipleTypesAndIndices(): void
153161
'title' => 'bbb',
154162
],
155163
],
164+
'sort' => [
165+
'_id' => 'asc',
166+
],
156167
];
157168

158169
$res = $finder->find(['AcmeBarBundle:Product', 'AcmeFooBundle:Customer'], $searchBody, Finder::RESULTS_OBJECT, [], $totalHits);
159170
$this->assertInstanceOf(DocumentIterator::class, $res);
160-
$this->assertCount(2, $res);
161-
$this->assertEquals(2, $totalHits);
171+
$this->assertCount(3, $res);
172+
$this->assertEquals(3, $totalHits);
173+
$resAsArray = iterator_to_array($res);
174+
175+
$this->assertInstanceOf(Customer::class, $resAsArray[0]);
176+
$this->assertInstanceOf(Customer::class, $resAsArray[1]);
177+
$this->assertInstanceOf(Product::class, $resAsArray[2]);
178+
179+
$this->assertEquals(111, $resAsArray[0]->id);
180+
$this->assertSame('Jane Doe', $resAsArray[0]->name);
181+
$this->assertSame(CustomerTypeEnum::COMPANY, $resAsArray[0]->customerType);
182+
183+
$this->assertEquals(222, $resAsArray[1]->id);
184+
$this->assertSame('John Doe', $resAsArray[1]->name);
185+
$this->assertSame(CustomerTypeEnum::INDIVIDUAL, $resAsArray[1]->customerType);
186+
187+
$this->assertSame('doc2', $resAsArray[2]->id);
188+
$this->assertSame('bbb', $resAsArray[2]->title);
162189

163190
$res = $finder->find(['AcmeBarBundle:Product', 'AcmeFooBundle:Customer'], $searchBody, Finder::RESULTS_ARRAY);
164191
$this->assertArraySubset([
165192
'doc2' => [
166193
'title' => 'bbb',
167194
],
168195
111 => [
169-
'name' => 'Jane Doe',
170-
'title' => 'aaa bbb',
171-
'active' => true,
196+
'name' => 'Jane Doe',
197+
'title' => 'aaa bbb',
198+
'active' => true,
199+
'customer_type' => 2,
200+
],
201+
222 => [
202+
'name' => 'John Doe',
203+
'title' => 'bbb',
204+
'customer_type' => 1,
172205
],
173206
], $res);
174207

@@ -214,8 +247,8 @@ public function testCount(): void
214247
],
215248
];
216249

217-
$this->assertEquals(1, $finder->count(['AcmeFooBundle:Customer'], $searchBody));
218-
$this->assertEquals(2, $finder->count(['AcmeBarBundle:Product', 'AcmeFooBundle:Customer'], $searchBody));
250+
$this->assertEquals(2, $finder->count(['AcmeFooBundle:Customer'], $searchBody));
251+
$this->assertEquals(3, $finder->count(['AcmeBarBundle:Product', 'AcmeFooBundle:Customer'], $searchBody));
219252
}
220253

221254
public function testGetTargetIndices(): void

tests/Functional/Mapping/DocumentMetadataCollectorTest.php

+13-22
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\BarBundle\Document\Repository\ProductRepository;
1515
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Document\Customer;
1616
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Document\Provider\CustomerProvider;
17+
use Sineflow\ElasticsearchBundle\Tests\App\Fixture\Acme\FooBundle\Enum\CustomerTypeEnum;
1718
use Symfony\Contracts\Cache\CacheInterface;
1819

1920
/**
@@ -41,21 +42,28 @@ class DocumentMetadataCollectorTest extends AbstractContainerAwareTestCase
4142
'active' => [
4243
'type' => 'boolean',
4344
],
45+
'customer_type' => [
46+
'type' => 'integer',
47+
],
4448
],
4549
'fields' => [
4650
],
4751
'propertiesMetadata' => [
4852
'name' => [
4953
'propertyName' => 'name',
5054
'type' => 'keyword',
51-
'multilanguage' => null,
55+
'propertyAccess' => 1,
56+
],
57+
'customer_type' => [
58+
'propertyName' => 'customerType',
59+
'type' => 'integer',
60+
'enumType' => CustomerTypeEnum::class,
5261
'propertyAccess' => 1,
5362
],
5463
'active' => [
55-
'propertyName' => 'active',
56-
'type' => 'boolean',
57-
'multilanguage' => null,
58-
'methods' => [
64+
'propertyName' => 'active',
65+
'type' => 'boolean',
66+
'methods' => [
5967
'getter' => 'isActive',
6068
'setter' => 'setActive',
6169
],
@@ -190,43 +198,36 @@ class DocumentMetadataCollectorTest extends AbstractContainerAwareTestCase
190198
'title' => [
191199
'propertyName' => 'title',
192200
'type' => 'text',
193-
'multilanguage' => null,
194201
'propertyAccess' => 1,
195202
],
196203
'description' => [
197204
'propertyName' => 'description',
198205
'type' => 'text',
199-
'multilanguage' => null,
200206
'propertyAccess' => 1,
201207
],
202208
'category' => [
203209
'propertyName' => 'category',
204210
'type' => 'object',
205-
'multilanguage' => null,
206211
'multiple' => null,
207212
'propertiesMetadata' => [
208213
'id' => [
209214
'propertyName' => 'id',
210215
'type' => 'integer',
211-
'multilanguage' => null,
212216
'propertyAccess' => 1,
213217
],
214218
'title' => [
215219
'propertyName' => 'title',
216220
'type' => 'keyword',
217-
'multilanguage' => null,
218221
'propertyAccess' => 1,
219222
],
220223
'tags' => [
221224
'propertyName' => 'tags',
222225
'type' => 'object',
223-
'multilanguage' => null,
224226
'multiple' => true,
225227
'propertiesMetadata' => [
226228
'tagname' => [
227229
'propertyName' => 'tagName',
228230
'type' => 'text',
229-
'multilanguage' => null,
230231
'propertyAccess' => 1,
231232
],
232233
],
@@ -240,31 +241,26 @@ class DocumentMetadataCollectorTest extends AbstractContainerAwareTestCase
240241
'related_categories' => [
241242
'propertyName' => 'relatedCategories',
242243
'type' => 'object',
243-
'multilanguage' => null,
244244
'multiple' => true,
245245
'propertiesMetadata' => [
246246
'id' => [
247247
'propertyName' => 'id',
248248
'type' => 'integer',
249-
'multilanguage' => null,
250249
'propertyAccess' => 1,
251250
],
252251
'title' => [
253252
'propertyName' => 'title',
254253
'type' => 'keyword',
255-
'multilanguage' => null,
256254
'propertyAccess' => 1,
257255
],
258256
'tags' => [
259257
'propertyName' => 'tags',
260258
'type' => 'object',
261-
'multilanguage' => null,
262259
'multiple' => true,
263260
'propertiesMetadata' => [
264261
'tagname' => [
265262
'propertyName' => 'tagName',
266263
'type' => 'text',
267-
'multilanguage' => null,
268264
'propertyAccess' => 1,
269265
],
270266
],
@@ -278,25 +274,21 @@ class DocumentMetadataCollectorTest extends AbstractContainerAwareTestCase
278274
'price' => [
279275
'propertyName' => 'price',
280276
'type' => 'float',
281-
'multilanguage' => null,
282277
'propertyAccess' => 1,
283278
],
284279
'location' => [
285280
'propertyName' => 'location',
286281
'type' => 'geo_point',
287-
'multilanguage' => null,
288282
'propertyAccess' => 1,
289283
],
290284
'limited' => [
291285
'propertyName' => 'limited',
292286
'type' => 'boolean',
293-
'multilanguage' => null,
294287
'propertyAccess' => 1,
295288
],
296289
'released' => [
297290
'propertyName' => 'released',
298291
'type' => 'date',
299-
'multilanguage' => null,
300292
'propertyAccess' => 1,
301293
],
302294
'ml_info' => [
@@ -314,7 +306,6 @@ class DocumentMetadataCollectorTest extends AbstractContainerAwareTestCase
314306
'pieces_count' => [
315307
'propertyName' => 'tokenPiecesCount',
316308
'type' => 'text',
317-
'multilanguage' => null,
318309
'propertyAccess' => 1,
319310
],
320311
'_id' => [

0 commit comments

Comments
 (0)