1616use Doctrine \Common \Cache \Cache ;
1717use ONGR \ElasticsearchBundle \Annotation \AbstractAnnotation ;
1818use ONGR \ElasticsearchBundle \Annotation \Embedded ;
19+ use ONGR \ElasticsearchBundle \Annotation \Id ;
1920use ONGR \ElasticsearchBundle \Annotation \Index ;
2021use ONGR \ElasticsearchBundle \Annotation \NestedType ;
2122use ONGR \ElasticsearchBundle \Annotation \ObjectType ;
@@ -150,6 +151,9 @@ private function getClassMetadata(\ReflectionClass $class): array
150151
151152 if ($ annotation instanceof Property) {
152153 $ fieldMapping ['type ' ] = $ annotation ->type ;
154+ if ($ annotation ->fields ) {
155+ $ fieldMapping ['fields ' ] = $ annotation ->fields ;
156+ }
153157 $ fieldMapping ['analyzer ' ] = $ annotation ->analyzer ;
154158 $ fieldMapping ['search_analyzer ' ] = $ annotation ->searchAnalyzer ;
155159 $ fieldMapping ['search_quote_analyzer ' ] = $ annotation ->searchQuoteAnalyzer ;
@@ -186,6 +190,70 @@ private function getClassMetadata(\ReflectionClass $class): array
186190 return $ mapping ;
187191 }
188192
193+ public function getPropertyMetadata (\ReflectionClass $ class , bool $ subClass = false ): array
194+ {
195+ if ($ class ->isTrait () || (!$ this ->reader ->getClassAnnotation ($ class , Index::class) && !$ subClass )) {
196+ return [];
197+ }
198+
199+ $ metadata = [];
200+
201+ /** @var \ReflectionProperty $property */
202+ foreach ($ this ->getDocumentPropertiesReflection ($ class ) as $ name => $ property ) {
203+ /** @var AbstractAnnotation $annotation */
204+ foreach ($ this ->reader ->getPropertyAnnotations ($ property ) as $ annotation ) {
205+ if (!$ annotation instanceof PropertiesAwareInterface) {
206+ continue ;
207+ }
208+
209+ $ propertyMetadata = [
210+ 'identifier ' => false ,
211+ 'class ' => null ,
212+ 'embeded ' => false ,
213+ 'type ' => null ,
214+ 'public ' => $ property ->isPublic (),
215+ 'getter ' => null ,
216+ 'setter ' => null ,
217+ 'sub_properties ' => []
218+ ];
219+
220+ $ name = $ property ->getName ();
221+ $ propertyMetadata ['name ' ] = $ name ;
222+
223+ if (!$ propertyMetadata ['public ' ]) {
224+ $ propertyMetadata ['getter ' ] = $ this ->guessGetter ($ class , $ name );
225+ }
226+
227+ if ($ annotation instanceof Id) {
228+ $ propertyMetadata ['identifier ' ] = true ;
229+ } else {
230+ if (!$ propertyMetadata ['public ' ]) {
231+ $ propertyMetadata ['setter ' ] = $ this ->guessSetter ($ class , $ name );
232+ }
233+ }
234+
235+ if ($ annotation instanceof Property) {
236+ // we need the type (and possibly settings?) in Converter::denormalize()
237+ $ propertyMetadata ['type ' ] = $ annotation ->type ;
238+ $ propertyMetadata ['settings ' ] = $ annotation ->settings ;
239+ }
240+
241+ if ($ annotation instanceof Embedded) {
242+ $ propertyMetadata ['embeded ' ] = true ;
243+ $ propertyMetadata ['class ' ] = $ annotation ->class ;
244+ $ propertyMetadata ['sub_properties ' ] = $ this ->getPropertyMetadata (
245+ new \ReflectionClass ($ annotation ->class ),
246+ true
247+ );
248+ }
249+
250+ $ metadata [$ annotation ->getName () ?? Caser::snake ($ name )] = $ propertyMetadata ;
251+ }
252+ }
253+
254+ return $ metadata ;
255+ }
256+
189257 public function getAnalysisConfig (\ReflectionClass $ class ): array
190258 {
191259 $ config = [];
@@ -202,7 +270,14 @@ public function getAnalysisConfig(\ReflectionClass $class): array
202270 }
203271 }
204272
205- foreach (['tokenizer ' , 'filter ' , 'normalizer ' , 'char_filter ' ] as $ type ) {
273+ $ normalizers = $ this ->getListFromArrayByKey ('normalizer ' , $ mapping );
274+ foreach ($ normalizers as $ normalizer ) {
275+ if (isset ($ this ->analysisConfig ['normalizer ' ][$ normalizer ])) {
276+ $ config ['normalizer ' ][$ normalizer ] = $ this ->analysisConfig ['normalizer ' ][$ normalizer ];
277+ }
278+ }
279+
280+ foreach (['tokenizer ' , 'filter ' , 'char_filter ' ] as $ type ) {
206281 $ list = $ this ->getListFromArrayByKey ($ type , $ config );
207282
208283 foreach ($ list as $ listItem ) {
@@ -215,6 +290,51 @@ public function getAnalysisConfig(\ReflectionClass $class): array
215290 return $ config ;
216291 }
217292
293+ protected function guessGetter (\ReflectionClass $ class , $ name ): string
294+ {
295+ if ($ class ->hasMethod ($ name )) {
296+ return $ name ;
297+ }
298+
299+ if ($ class ->hasMethod ('get ' . ucfirst ($ name ))) {
300+ return 'get ' . ucfirst ($ name );
301+ }
302+
303+ if ($ class ->hasMethod ('is ' . ucfirst ($ name ))) {
304+ return 'is ' . ucfirst ($ name );
305+ }
306+
307+ // if there are underscores in the name convert them to CamelCase
308+ if (strpos ($ name , '_ ' )) {
309+ $ name = Caser::camel ($ name );
310+ if ($ class ->hasMethod ('get ' . ucfirst ($ name ))) {
311+ return 'get ' . $ name ;
312+ }
313+ if ($ class ->hasMethod ('is ' . ucfirst ($ name ))) {
314+ return 'is ' . $ name ;
315+ }
316+ }
317+
318+ throw new \Exception ("Could not determine a getter for ` $ name` of class ` {$ class ->getNamespaceName ()}` " );
319+ }
320+
321+ protected function guessSetter (\ReflectionClass $ class , $ name ): string
322+ {
323+ if ($ class ->hasMethod ('set ' . ucfirst ($ name ))) {
324+ return 'set ' . ucfirst ($ name );
325+ }
326+
327+ // if there are underscores in the name convert them to CamelCase
328+ if (strpos ($ name , '_ ' )) {
329+ $ name = Caser::camel ($ name );
330+ if ($ class ->hasMethod ('set ' . ucfirst ($ name ))) {
331+ return 'set ' . $ name ;
332+ }
333+ }
334+
335+ throw new \Exception ("Could not determine a setter for ` $ name` of class ` {$ class ->getNamespaceName ()}` " );
336+ }
337+
218338 private function getListFromArrayByKey (string $ searchKey , array $ array ): array
219339 {
220340 $ list = [];
0 commit comments