28
28
use Pimcore \Model \DataObject \Fieldcollection \Data \AbstractData ;
29
29
use Pimcore \Model \DataObject \Localizedfield ;
30
30
use Pimcore \Model \DataObject \Objectbrick \Definition ;
31
+ use Pimcore \Model \Factory ;
31
32
32
33
class DataObjectFieldHelper extends AbstractFieldHelper
33
34
{
35
+ protected Factory $ modelFactory ;
36
+
37
+ public function __construct (\Pimcore \Model \Factory $ modelFactory )
38
+ {
39
+ parent ::__construct ();
40
+ $ this ->modelFactory = $ modelFactory ;
41
+ }
42
+
34
43
/**
35
44
* @param array $nodeDef
36
45
* @param ClassDefinition|\Pimcore\Model\DataObject\Fieldcollection\Definition $class
@@ -70,8 +79,8 @@ public function getQueryFieldConfigFromConfig($nodeDef, $class, $container = nul
70
79
'key ' => $ key ,
71
80
'config ' => [
72
81
'name ' => $ key ,
73
- 'type ' => Type::int ()
74
- ]
82
+ 'type ' => Type::int (),
83
+ ],
75
84
];
76
85
case 'filename ' :
77
86
case 'fullpath ' :
@@ -80,16 +89,16 @@ public function getQueryFieldConfigFromConfig($nodeDef, $class, $container = nul
80
89
'key ' => $ key ,
81
90
'config ' => [
82
91
'name ' => $ key ,
83
- 'type ' => Type::string ()
84
- ]
92
+ 'type ' => Type::string (),
93
+ ],
85
94
];
86
95
case 'published ' :
87
96
return [
88
97
'key ' => $ key ,
89
98
'config ' => [
90
99
'name ' => $ key ,
91
100
'type ' => Type::boolean (),
92
- ]
101
+ ],
93
102
];
94
103
default :
95
104
return null ;
@@ -269,7 +278,7 @@ public function getMutationFieldConfigFromConfig($nodeDef, $class)
269
278
'arg ' => ['type ' => Type::string ()],
270
279
'processor ' => function ($ object , $ newValue , $ args ) {
271
280
$ object ->setKey ($ newValue );
272
- }
281
+ },
273
282
274
283
];
275
284
case 'published ' :
@@ -278,7 +287,7 @@ public function getMutationFieldConfigFromConfig($nodeDef, $class)
278
287
'arg ' => ['type ' => Type::boolean ()],
279
288
'processor ' => function ($ object , $ newValue , $ args ) {
280
289
$ object ->setPublished ($ newValue );
281
- }
290
+ },
282
291
];
283
292
default :
284
293
return null ;
@@ -370,10 +379,39 @@ public function doExtractData(FieldNode $ast, &$data, $container, $args, $contex
370
379
$ isLocalizedField = false ;
371
380
$ containerDefinition = null ;
372
381
373
- if ($ container instanceof Concrete) {
374
- $ containerDefinition = $ container ->getClass ();
375
- } elseif ($ container instanceof AbstractData || $ container instanceof \Pimcore \Model \DataObject \Objectbrick \Data \AbstractData) {
376
- $ containerDefinition = $ container ->getDefinition ();
382
+ // This reflection object is used to determine if the getter can be used.
383
+ // $container isn't used directly in order to allow specialized handling
384
+ // of mock objects and other placeholders which act transparently but
385
+ // don't implement the getters themselves.
386
+ $ methodCheckClass = new \ReflectionClass ($ container );
387
+ $ skipMethodCallCheck = false ;
388
+ // Adjust meta data for data handling on type of the data container.
389
+ switch (true ) {
390
+ case $ container instanceof Concrete:
391
+ $ containerDefinition = $ container ->getClass ();
392
+ break ;
393
+
394
+ case $ container instanceof AbstractData:
395
+ case $ container instanceof \Pimcore \Model \DataObject \Objectbrick \Data \AbstractData:
396
+ $ containerDefinition = $ container ->getDefinition ();
397
+ break ;
398
+
399
+ // All default indexers implement o_classId - access it directly to
400
+ // load class definition and with it use the model loader to fetch
401
+ // the actual implementing class for further reflection.
402
+ case $ container instanceof DefaultMockup:
403
+ if (($ mockClassId = $ container ->getParam ('o_classId ' ))) {
404
+ $ containerDefinition = ClassDefinition::getById ($ mockClassId );
405
+ // Unfortunately there's no API for this so we re-implement
406
+ // what \Pimcore\Model\DataObject\AbstractObject::getById()
407
+ // does.
408
+ $ baseClassName = 'Pimcore \\Model \\DataObject \\' . ucfirst ($ containerDefinition ->getName ());
409
+ $ className = $ this ->modelFactory ->getClassNameFor ($ baseClassName );
410
+ $ methodCheckClass = new \ReflectionClass ($ className );
411
+ } else {
412
+ $ skipMethodCallCheck = true ;
413
+ }
414
+ break ;
377
415
}
378
416
379
417
if ($ containerDefinition ) {
@@ -383,7 +421,8 @@ public function doExtractData(FieldNode $ast, &$data, $container, $args, $contex
383
421
$ isLocalizedField = true ;
384
422
}
385
423
}
386
- if (method_exists ($ container , $ getter )) {
424
+
425
+ if (($ methodCheckClass ->hasMethod ($ getter ) && $ methodCheckClass ->getMethod ($ getter )->isPublic ()) || $ skipMethodCallCheck ) {
387
426
if ($ isLocalizedField ) {
388
427
// defer it
389
428
$ data [$ astName ] = function ($ source , $ args , $ context , ResolveInfo $ info ) use (
@@ -395,17 +434,6 @@ public function doExtractData(FieldNode $ast, &$data, $container, $args, $contex
395
434
} else {
396
435
$ data [$ astName ] = $ container ->$ getter ();
397
436
}
398
- } else {
399
- // we could also have a Mockup objects from Elastic which not supports the "method_exists"
400
- // in this case we just try to get the data directly
401
- if ($ container instanceof DefaultMockup) {
402
- try {
403
- // we don't have to take care about localization because this is already handled in elastic
404
- $ data [$ astName ] = $ container ->$ getter ();
405
- } catch (\Exception $ e ) {
406
- Logger::info ('Could not get data from Datahub/DataObjectFieldHelper with message: ' . $ e ->getMessage ());
407
- }
408
- }
409
437
}
410
438
}
411
439
0 commit comments