44
55namespace Setono \SyliusMeilisearchPlugin \Document \Metadata ;
66
7- use Setono \SyliusMeilisearchPlugin \Document \Attribute \Facetable as FacetableAttribute ;
8- use Setono \SyliusMeilisearchPlugin \Document \Attribute \Filterable as FilterableAttribute ;
9- use Setono \SyliusMeilisearchPlugin \Document \Attribute \Image as ImageAttribute ;
10- use Setono \SyliusMeilisearchPlugin \Document \Attribute \MapProductAttribute ;
11- use Setono \SyliusMeilisearchPlugin \Document \Attribute \MapProductOption ;
12- use Setono \SyliusMeilisearchPlugin \Document \Attribute \Searchable as SearchableAttribute ;
13- use Setono \SyliusMeilisearchPlugin \Document \Attribute \Sortable as SortableAttribute ;
147use Setono \SyliusMeilisearchPlugin \Document \Document ;
15- use Webmozart \Assert \Assert ;
168
17- // TODO: Do we need an interface, why not just have public readonly properties?
18- final class Metadata implements MetadataInterface
9+ final class Metadata
1910{
2011 /** @var class-string<Document> */
21- private readonly string $ document ;
12+ public readonly string $ document ;
2213
23- /** @var array<string, Filterable> */
24- private array $ filterableAttributes = [];
14+ /**
15+ * Filterable attributes indexed by the name
16+ *
17+ * @var array<string, Filterable>
18+ */
19+ public array $ filterableAttributes = [];
2520
26- /** @var array<string, Facet> */
27- private array $ facetableAttributes = [];
21+ /**
22+ * Facetable attributes indexed by the name
23+ *
24+ * @var array<string, Facet>
25+ */
26+ public array $ facetableAttributes = [];
2827
29- /** @var array<string, Searchable> */
30- private array $ searchableAttributes = [];
28+ /**
29+ * Searchable attributes indexed by the name
30+ *
31+ * @var array<string, Searchable>
32+ */
33+ public array $ searchableAttributes = [];
3134
32- /** @var array<string, Sortable> */
33- private array $ sortableAttributes = [];
35+ /**
36+ * Sortable attributes indexed by the name
37+ *
38+ * @var array<string, Sortable>
39+ */
40+ public array $ sortableAttributes = [];
3441
35- /** @var array<string, list<string>> */
36- private array $ mappedProductOptions = [];
42+ /**
43+ * Return product options codes mapped by document property
44+ *
45+ * @var array<string, list<string>>
46+ */
47+ public array $ mappedProductOptions = [];
3748
3849 /** @var list<MappedProductAttribute> */
39- private array $ mappedProductAttributes = [];
50+ public array $ mappedProductAttributes = [];
4051
4152 /** @var array<string, Image> */
42- private array $ imageAttributes = [];
53+ public array $ imageAttributes = [];
4354
4455 /**
4556 * @param class-string<Document>|Document $document
@@ -51,108 +62,33 @@ public function __construct(string|Document $document)
5162 }
5263
5364 $ this ->document = $ document ;
54-
55- $ this ->load ();
56- }
57-
58- private function load (): void
59- {
60- $ documentReflection = new \ReflectionClass ($ this ->document );
61- foreach ($ documentReflection ->getProperties (\ReflectionProperty::IS_PUBLIC ) as $ reflectionProperty ) {
62- $ this ->loadAttributes ($ reflectionProperty );
63- }
64-
65- foreach ($ documentReflection ->getMethods (\ReflectionMethod::IS_PUBLIC ) as $ reflectionMethod ) {
66- if (!self ::isGetter ($ reflectionMethod )) {
67- continue ;
68- }
69-
70- $ this ->loadAttributes ($ reflectionMethod );
71- }
72- }
73-
74- private function loadAttributes (\ReflectionProperty |\ReflectionMethod $ attributesAware ): void
75- {
76- $ name = self ::resolveName ($ attributesAware );
77- if (null === $ name ) {
78- return ;
79- }
80-
81- foreach ($ attributesAware ->getAttributes () as $ reflectionAttribute ) {
82- $ attribute = $ reflectionAttribute ->newInstance ();
83-
84- if ($ attribute instanceof FilterableAttribute) {
85- $ this ->filterableAttributes [$ name ] = new Filterable ($ name );
86- }
87-
88- if ($ attribute instanceof FacetableAttribute) {
89- $ this ->facetableAttributes [$ name ] = new Facet (
90- $ name ,
91- self ::getFacetType ($ attributesAware ),
92- $ attribute ->position ,
93- $ attribute ->sorter ?? null ,
94- );
95- }
96-
97- if ($ attribute instanceof SearchableAttribute) {
98- $ this ->searchableAttributes [$ name ] = new Searchable ($ name , $ attribute ->priority );
99- }
100-
101- if ($ attribute instanceof SortableAttribute) {
102- $ this ->sortableAttributes [$ name ] = new Sortable ($ name , $ attribute ->direction );
103- }
104-
105- if ($ attribute instanceof MapProductOption) {
106- Assert::isInstanceOf ($ attributesAware , \ReflectionProperty::class);
107- // todo are we sure this needs to be an array?
108- Assert::same ('array ' , (string ) $ attributesAware ->getType ());
109- $ this ->mappedProductOptions [$ name ] = $ attribute ->codes ;
110- }
111-
112- if ($ attribute instanceof MapProductAttribute) {
113- Assert::isInstanceOf ($ attributesAware , \ReflectionProperty::class);
114- $ this ->mappedProductAttributes [] = new MappedProductAttribute ($ name , (string ) $ attributesAware ->getType (), $ attribute ->codes );
115- }
116-
117- if ($ attribute instanceof ImageAttribute) {
118- $ this ->imageAttributes [$ name ] = new Image ($ name , $ attribute ->filterSet , $ attribute ->type );
119- }
120- }
12165 }
12266
12367 /**
124- * @return class-string<Document>
68+ * Returns the names of the filterable attributes
69+ *
70+ * @return list<string>
12571 */
126- public function getDocument (): string
127- {
128- return $ this ->document ;
129- }
130-
131- public function getFilterableAttributes (): array
132- {
133- return $ this ->filterableAttributes ;
134- }
135-
13672 public function getFilterableAttributeNames (): array
13773 {
13874 return array_keys ($ this ->filterableAttributes );
13975 }
14076
141- public function getFacetableAttributes (): array
142- {
143- return $ this -> facetableAttributes ;
144- }
145-
77+ /**
78+ * Returns the names of the facetable attributes
79+ *
80+ * @return list<string>
81+ */
14682 public function getFacetableAttributeNames (): array
14783 {
14884 return array_keys ($ this ->facetableAttributes );
14985 }
15086
151- public function getSearchableAttributes (): array
152- {
153- return $ this -> searchableAttributes ;
154- }
155-
87+ /**
88+ * Returns the names of the searchable attributes (sorted by priority)
89+ *
90+ * @return list<string>
91+ */
15692 public function getSearchableAttributeNames (): array
15793 {
15894 $ searchableAttributes = $ this ->searchableAttributes ;
@@ -161,69 +97,13 @@ public function getSearchableAttributeNames(): array
16197 return array_map (static fn (Searchable $ searchableAttribute ) => $ searchableAttribute ->name , $ searchableAttributes );
16298 }
16399
164- public function getSortableAttributes (): array
165- {
166- return $ this -> sortableAttributes ;
167- }
168-
100+ /**
101+ * Returns the names of the sortable attributes
102+ *
103+ * @return list<string>
104+ */
169105 public function getSortableAttributeNames (): array
170106 {
171107 return array_keys ($ this ->sortableAttributes );
172108 }
173-
174- public function getMappedProductOptions (): array
175- {
176- return $ this ->mappedProductOptions ;
177- }
178-
179- public function getMappedProductAttributes (): array
180- {
181- return $ this ->mappedProductAttributes ;
182- }
183-
184- public function getImageAttributes (): array
185- {
186- return $ this ->imageAttributes ;
187- }
188-
189- private static function isGetter (\ReflectionMethod $ reflection ): bool
190- {
191- if ($ reflection ->getNumberOfParameters () > 0 ) {
192- return false ;
193- }
194-
195- $ name = $ reflection ->getName ();
196-
197- return str_starts_with ($ name , 'get ' ) || str_starts_with ($ name , 'is ' ) || str_starts_with ($ name , 'has ' );
198- }
199-
200- private static function resolveName (\ReflectionProperty |\ReflectionMethod $ reflection ): ?string
201- {
202- if ($ reflection instanceof \ReflectionProperty) {
203- return $ reflection ->getName ();
204- }
205-
206- if ($ reflection ->getNumberOfParameters () > 0 ) {
207- return null ;
208- }
209-
210- $ name = $ reflection ->getName ();
211-
212- foreach (['get ' , 'is ' , 'has ' ] as $ prefix ) {
213- if (str_starts_with ($ name , $ prefix )) {
214- return lcfirst (substr ($ name , strlen ($ prefix )));
215- }
216- }
217-
218- return null ;
219- }
220-
221- private static function getFacetType (\ReflectionProperty |\ReflectionMethod $ attributesAware ): string
222- {
223- if ($ attributesAware instanceof \ReflectionProperty) {
224- return str_replace ('? ' , '' , (string ) $ attributesAware ->getType ());
225- }
226-
227- return str_replace ('? ' , '' , (string ) $ attributesAware ->getReturnType ());
228- }
229109}
0 commit comments