Passed
Push — master ( a64949...af41cd )
by Gerrit
01:55
created

resolveStringArgumentConfiguration()   F

Complexity

Conditions 21
Paths 23

Size

Total Lines 214

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 75
CRAP Score 42.3389

Importance

Changes 0
Metric Value
dl 0
loc 214
ccs 75
cts 118
cp 0.6356
rs 3.3333
c 0
b 0
f 0
cc 21
nc 23
nop 3
crap 42.3389

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright (C) 2018 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 *
8
 * @license GPL-3.0
9
 *
10
 * @author Gerrit Addiks <[email protected]>
11
 */
12
13
namespace Addiks\SymfonyGenerics\Services;
14
15
use Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
16
use Psr\Container\ContainerInterface;
17
use ReflectionParameter;
18
use ReflectionType;
19
use ReflectionMethod;
20
use Symfony\Component\HttpFoundation\Request;
21
use Webmozart\Assert\Assert;
22
use ReflectionClass;
23
use ReflectionFunctionAbstract;
24
use InvalidArgumentException;
25
use ReflectionException;
26
use Doctrine\ORM\EntityManagerInterface;
27
use ValueObjects\ValueObjectInterface;
28
use Symfony\Component\HttpFoundation\FileBag;
29
use Symfony\Component\HttpFoundation\File\UploadedFile;
30
31
final class ArgumentCompiler implements ArgumentCompilerInterface
32
{
33
34
    /**
35
     * @var ContainerInterface
36
     */
37
    private $container;
38
39
    /**
40
     * @var EntityManagerInterface
41
     */
42
    private $entityManager;
43
44 12
    public function __construct(
45
        ContainerInterface $container,
46
        EntityManagerInterface $entityManager
47
    ) {
48 12
        $this->container = $container;
49 12
        $this->entityManager = $entityManager;
50 12
    }
51
52 9
    public function buildArguments(
53
        array $argumentsConfiguration,
54
        Request $request,
55
        array $additionalData = array()
56
    ): array {
57
        /** @var array<int, mixed> $routeArguments */
58 9
        $routeArguments = array();
59
60 9
        foreach ($argumentsConfiguration as $key => $argumentConfiguration) {
61
            /** @var array|string $argumentConfiguration */
62
63
            /** @var string|null $parameterTypeName */
64 9
            $parameterTypeName = null;
65
66 9
            if (isset($argumentConfiguration['entity-class'])) {
67
                $parameterTypeName = $argumentConfiguration['entity-class'];
68
            }
69
70
            /** @var mixed $argumentValue */
71 9
            $argumentValue = $this->resolveArgumentConfiguration(
72 9
                $argumentConfiguration,
73 9
                $request,
74 9
                $parameterTypeName,
75 9
                $additionalData
76
            );
77
78 6
            $routeArguments[$key] = $argumentValue;
79
        }
80
81 5
        return $routeArguments;
82
    }
83
84 4
    public function buildCallArguments(
85
        ReflectionFunctionAbstract $routineReflection,
86
        array $argumentsConfiguration,
87
        Request $request,
88
        array $predefinedArguments = array(),
89
        array $additionalData = array()
90
    ): array {
91
        /** @var array<int, mixed> $callArguments */
92 4
        $callArguments = array();
93
94 4
        foreach ($routineReflection->getParameters() as $index => $parameterReflection) {
95
            /** @var ReflectionParameter $parameterReflection */
96
97 3
            if (isset($predefinedArguments[$index])) {
98
                $callArguments[] = $predefinedArguments[$index];
99
                continue;
100
            }
101
102
            /** @var string $parameterName */
103 3
            $parameterName = $parameterReflection->getName();
0 ignored issues
show
Bug introduced by
Consider using $parameterReflection->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
104
105
            /** @var mixed $requestValue */
106 3
            $requestValue = $request->get($parameterName);
107
108
            /** @var string|null $parameterTypeName */
109 3
            $parameterTypeName = null;
110
111 3
            if ($parameterReflection->hasType()) {
112
                /** @var ReflectionType|null $parameterType */
113 2
                $parameterType = $parameterReflection->getType();
114
115 2
                if ($parameterType instanceof ReflectionType) {
0 ignored issues
show
Bug introduced by
The class ReflectionType does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
116 2
                    $parameterTypeName = $parameterType->__toString();
117
                }
118
            }
119
120 3
            if (isset($argumentsConfiguration[$parameterName])) {
121
                /** @var array|string $argumentConfiguration */
122 3
                $argumentConfiguration = $argumentsConfiguration[$parameterName];
123
124
                /** @var mixed $argumentValue */
125 3
                $argumentValue = $argumentConfiguration;
126
127 3
                if (is_string($argumentConfiguration) || is_array($argumentConfiguration)) {
128 3
                    $argumentValue = $this->resolveArgumentConfiguration(
129 3
                        $argumentConfiguration,
130 3
                        $request,
131 3
                        $parameterTypeName,
132 3
                        $additionalData
133
                    );
134
                }
135
136 1
                $callArguments[$index] = $argumentValue;
137
138 2
            } elseif (isset($argumentsConfiguration[$index])) {
139
                /** @var array|string $argumentConfiguration */
140
                $argumentConfiguration = $argumentsConfiguration[$index];
141
142
                /** @var mixed $argumentValue */
143
                $argumentValue = $argumentConfiguration;
144
145
                if (is_string($argumentConfiguration) || is_array($argumentConfiguration)) {
146
                    $argumentValue = $this->resolveArgumentConfiguration(
147
                        $argumentConfiguration,
148
                        $request,
149
                        $parameterTypeName,
150
                        $additionalData
151
                    );
152
                }
153
154
                $callArguments[$index] = $argumentValue;
155
156 2
            } elseif (!is_null($requestValue)) {
157 1
                if (!is_null($parameterTypeName)) {
158
                    /** @psalm-suppress UndefinedClass ValueObjects\ValueObjectInterface does not exist */
159
                    if (is_subclass_of($parameterTypeName, ValueObjectInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \ValueObjects\ValueObjectInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
160
                        $argumentValue = $parameterTypeName::fromNative($requestValue);
161
162
                        $callArguments[$index] = $argumentValue;
163
                    }
164
165
                } else {
166 1
                    $callArguments[$index] = $requestValue;
167
                }
168
169 1
            } elseif ($parameterTypeName === Request::class) {
170
                $callArguments[$index] = $request;
171
172
            } else {
173
                try {
174 1
                    $callArguments[$index] = $parameterReflection->getDefaultValue();
175
176 1
                } catch (ReflectionException $exception) {
177 1
                    throw new InvalidArgumentException(sprintf(
178 1
                        "Missing argument '%s' for the call to '%s'!",
179 1
                        $parameterName,
180 2
                        $routineReflection->getName()
181
                    ));
182
                }
183
            }
184
        }
185
186 2
        return $callArguments;
187
    }
188
189
    /**
190
     * @param array|string $argumentConfiguration
191
     *
192
     * @return mixed
193
     */
194 12
    public function resolveArgumentConfiguration(
195
        $argumentConfiguration,
196
        Request $request,
197
        ?string $parameterTypeName,
198
        array $additionalData = array()
199
    ) {
200
        /** @var mixed $argumentValue */
201 12
        $argumentValue = null;
202
203 12
        if (is_array($argumentConfiguration)) {
204 3
            if (isset($argumentConfiguration['entity-class'])) {
205
                $parameterTypeName = $argumentConfiguration['entity-class'];
206
            }
207
208 3
            if (isset($argumentConfiguration['service-id'])) {
209 3
                $argumentValue = $this->container->get($argumentConfiguration['service-id']);
210
211 3
                Assert::object($argumentValue, sprintf(
212 3
                    "Did not find service '%s'!",
213 3
                    $argumentConfiguration['service-id']
214
                ));
215
216
            } elseif (isset($argumentConfiguration['entity-id'])) {
217
                $argumentValue = $this->resolveStringArgumentConfiguration(
218
                    $argumentConfiguration['entity-id'],
219
                    $request
220
                );
221
222
            } elseif (class_exists($parameterTypeName)) {
223
                $argumentValue = $this->resolveStringArgumentConfiguration(
224
                    $parameterTypeName,
225
                    $request
226
                );
227
            }
228
229 2
            if (isset($argumentConfiguration['method'])) {
230 2
                $methodReflection = new ReflectionMethod($argumentValue, $argumentConfiguration['method']);
231
232 2
                if (!isset($argumentConfiguration['arguments'])) {
233 1
                    $argumentConfiguration['arguments'] = [];
234
                }
235
236
                /** @var array $callArguments */
237 2
                $callArguments = $this->buildCallArguments(
238 2
                    $methodReflection,
239 2
                    $argumentConfiguration['arguments'],
240 2
                    $request
241
                );
242
243 1
                $argumentValue = $methodReflection->invokeArgs($argumentValue, $callArguments);
244
            }
245
246
        } else {
247 10
            $argumentValue = $this->resolveStringArgumentConfiguration(
248 10
                $argumentConfiguration,
249 10
                $request,
250 10
                $additionalData
251
            );
252
        }
253
254 7
        if (!empty($parameterTypeName) && !is_object($argumentValue)) {
255 1
            if (class_exists($parameterTypeName)) {
256
                /** @psalm-suppress UndefinedClass ValueObjects\ValueObjectInterface does not exist */
257 1
                if (is_subclass_of($parameterTypeName, ValueObjectInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \ValueObjects\ValueObjectInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
258
                    $argumentValue = call_user_func("{$parameterTypeName}::fromNative", $argumentValue);
259
260
                } else {
261 1
                    $argumentValue = $this->entityManager->find($parameterTypeName, $argumentValue);
262
                }
263
            }
264
        }
265
266 7
        return $argumentValue;
267
    }
268
269
    /**
270
     * @return mixed
271
     */
272 10
    private function resolveStringArgumentConfiguration(
273
        string $argumentConfiguration,
274
        Request $request,
275
        array $additionalData = array()
276
    ) {
277
        /** @var mixed $argumentValue */
278 10
        $argumentValue = null;
279
280 10
        $argumentConfiguration = trim($argumentConfiguration);
281
282 10
        if (empty($argumentConfiguration)) {
283
            $argumentValue = "";
284
285 10
        } elseif (is_int(strpos($argumentConfiguration, '::'))) {
286 2
            [$factoryClass, $factoryMethod] = explode('::', $argumentConfiguration);
0 ignored issues
show
Bug introduced by
The variable $factoryClass does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $factoryMethod seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
287
288
            /** @var array<string> $callArgumentConfigurations */
289 2
            $callArgumentConfigurations = array();
290
291 2
            if (is_int(strpos($factoryMethod, '('))) {
0 ignored issues
show
Bug introduced by
The variable $factoryMethod seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
292
                $factoryMethod = str_replace(')', '', $factoryMethod);
0 ignored issues
show
Bug introduced by
The variable $factoryMethod seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
293
                [$factoryMethod, $rawArguments] = explode('(', $factoryMethod, 2);
0 ignored issues
show
Bug introduced by
The variable $rawArguments does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
294
295
                foreach (explode(",", $rawArguments) as $rawArgument) {
296
                    /** @var string $rawArgument */
297
298
                    $callArgumentConfigurations[] = trim($rawArgument);
299
                }
300
            }
301
302 2
            if (!empty($factoryClass)) {
303 2
                if ($factoryClass[0] == '@') {
304
                    /** @var string $factoryServiceId */
305 2
                    $factoryServiceId = substr($factoryClass, 1);
306
307
                    /** @var object $factoryObject */
308 2
                    $factoryObject = $this->container->get($factoryServiceId);
309
310 2
                    Assert::object($factoryObject, sprintf(
311 2
                        "Could not find service with id '%s'!",
312 2
                        $factoryServiceId
313
                    ));
314
315 2
                    Assert::methodExists($factoryObject, $factoryMethod, sprintf(
0 ignored issues
show
Bug introduced by
The variable $factoryMethod does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
316 2
                        "Method '%s' does not exist on service '%s'! (Class '%s')",
317 2
                        $factoryMethod,
318 2
                        $factoryServiceId,
319 2
                        get_class($factoryObject)
320
                    ));
321
322
                    /** @var array<int, mixed> $callArguments */
323 1
                    $callArguments = $this->buildCallArguments(
324 1
                        new ReflectionMethod($factoryObject, $factoryMethod),
325 1
                        $callArgumentConfigurations,
326 1
                        $request
327
                    );
328
329 1
                    $argumentValue = $this->callOnObject(
330 1
                        $factoryObject,
331 1
                        $factoryMethod,
332 1
                        $callArguments,
333 1
                        $request,
334 1
                        sprintf(
335 1
                            "Did not find service with id '%s' that has a method '%s'!",
336 1
                            $factoryServiceId,
337 1
                            $factoryMethod
338
                        )
339
                    );
340
341
                } elseif (is_int(strpos($factoryClass, '#'))) {
342
                    # Create by call on entity
343
                    [$entityClass, $idRaw] = explode('#', $factoryClass);
0 ignored issues
show
Bug introduced by
The variable $entityClass does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $idRaw does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
344
345
                    $id = $this->resolveStringArgumentConfiguration($idRaw, $request, $additionalData);
346
347
                    /** @var object $entity */
348
                    $entity = $this->entityManager->find($entityClass, $id);
349
350
                    Assert::object($entity, sprintf(
351
                        "Could not find entity '%s' with id '%s'!",
352
                        $entityClass,
353
                        $id
354
                    ));
355
356
                    /** @var array<int, mixed> $callArguments */
357
                    $callArguments = $this->buildCallArguments(
358
                        new ReflectionMethod($entity, $factoryMethod),
359
                        $callArgumentConfigurations,
360
                        $request
361
                    );
362
363
                    $argumentValue = $this->callOnObject(
364
                        $entity,
365
                        $factoryMethod,
366
                        $callArguments,
367
                        $request,
368
                        sprintf(
369
                            "Entity '%s' does not have method '%s'!",
370
                            $entityClass,
371
                            $factoryMethod
372
                        )
373
                    );
374
375
                } else {
376
                    $callArguments = array();
377
378
                    if (is_int(strpos($argumentConfiguration, '('))) {
379
                        $argumentConfiguration = str_replace(")", "", $argumentConfiguration);
380
                        [$argumentConfiguration, $callArgumentsRaw] = explode('(', $argumentConfiguration);
0 ignored issues
show
Bug introduced by
The variable $callArgumentsRaw does not exist. Did you mean $callArguments?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
381
382
                        if (!empty($callArgumentsRaw)) {
0 ignored issues
show
Bug introduced by
The variable $callArgumentsRaw does not exist. Did you mean $callArguments?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
383
                            foreach (explode(',', $callArgumentsRaw) as $callArgumentRaw) {
384
                                $callArguments[] = $this->resolveStringArgumentConfiguration(
385
                                    $callArgumentRaw,
386
                                    $request,
387
                                    $additionalData
388
                                );
389
                            }
390
                        }
391
                    }
392
393
                    # Create by static factory-method of other class
394 1
                    $argumentValue = call_user_func_array($argumentConfiguration, $callArguments);
395
                }
396
397 1
            } else {
398
                # TODO: What to do here? What could "::Something" be? A template?
399
            }
400
401 10
        } elseif ($argumentConfiguration[0] == "'" && $argumentConfiguration[strlen($argumentConfiguration) - 1] == "'") {
402 1
            $argumentValue = substr($argumentConfiguration, 1, strlen($argumentConfiguration) - 2);
403
404 9
        } elseif ($argumentConfiguration == '$') {
405 1
            $argumentValue = $request->getContent(false);
406
407 8
        } elseif (substr($argumentConfiguration, 0, 7) === '$files.') {
408
            /** @var FileBag $files */
409 2
            $files = $request->files;
410
411 2
            [, $filesKey, $fileArgument] = explode(".", $argumentConfiguration);
0 ignored issues
show
Bug introduced by
The variable $filesKey does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $fileArgument does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
412
413
            /** @var UploadedFile $file */
414 2
            $file = $files->get($filesKey);
415
416 2
            Assert::isInstanceOf($file, UploadedFile::class, sprintf(
417 2
                "Missing request-argument '%s' as uploaded file!",
418 2
                $filesKey
419
            ));
420
421
            $argumentValue = [
422 1
                'object' => $file,
423 1
                'originalname' => $file->getClientOriginalName(),
424 1
                'filename' => $file->getFilename(),
425 1
                'content' => file_get_contents($file->getPathname()),
426 1
                'mimetype' => $file->getMimeType(),
427 1
            ][$fileArgument];
428
429 6
        } elseif ($argumentConfiguration[0] == '$') {
430 3
            $argumentValue = $request->get(substr($argumentConfiguration, 1));
431
432 3
            if (is_string($argumentValue)) {
433 3
                $argumentValue = trim($argumentValue);
434
            }
435
436 4
        } elseif ($argumentConfiguration[0] == '@') {
437 1
            $argumentValue = $this->container->get(substr($argumentConfiguration, 1));
438
439 3
        } elseif ($argumentConfiguration[0] == '%') {
440
            /** @var string $key */
441 3
            $key = substr($argumentConfiguration, 1);
442
443 3
            if (is_int(strpos($key, '.'))) {
444 1
                [$key, $methodName] = explode('.', $key);
0 ignored issues
show
Bug introduced by
The variable $methodName does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
445
446 1
                Assert::keyExists($additionalData, $key, sprintf(
447 1
                    'Missing additional-data key "%s"',
448 1
                    $key
449
                ));
450
451 1
                $argumentValue = $additionalData[$key];
452
453 1
                Assert::methodExists($argumentValue, $methodName, sprintf(
454 1
                    "Missing method '%s' on '%s'!",
455 1
                    $methodName,
456 1
                    $argumentConfiguration
457
                ));
458
459
                $argumentValue = call_user_func([$argumentValue, $methodName]);
460
461
            } else {
462 2
                Assert::keyExists($additionalData, $key, sprintf(
463 2
                    'Missing additional-data key "%s"',
464 2
                    $key
465
                ));
466
467 1
                $argumentValue = $additionalData[$key];
468
            }
469
470
        } elseif (is_int(strpos($argumentConfiguration, '#'))) {
471
            # Create as entity
472
            [$entityClass, $idRaw] = explode('#', $argumentConfiguration);
473
474
            $id = $this->resolveStringArgumentConfiguration($idRaw, $request);
475
476
            $argumentValue = $this->entityManager->find($entityClass, $id);
477
478
            Assert::object($argumentValue, sprintf("Did not find entity %s with id '%s'!", $entityClass, $id));
479
480
        } else {
481
            $argumentValue = $argumentConfiguration;
482
        }
483
484 7
        return $argumentValue;
485
    }
486
487
    /**
488
     * @param object $object
489
     *
490
     * @return mixed
491
     */
492 1
    private function callOnObject(
493
        $object,
494
        string $method,
495
        array $callArguments,
496
        Request $request,
497
        string $methodNotExistMessage
498
    ) {
499 1
        Assert::methodExists($object, $method, $methodNotExistMessage);
500
501 1
        $objectReflection = new ReflectionClass($object);
502
503
        /** @var ReflectionMethod $methodReflection */
504 1
        $methodReflection = $objectReflection->getMethod($method);
505
506 1
        $callArguments = $this->buildCallArguments(
507 1
            $methodReflection,
508 1
            [], # TODO
509 1
            $request,
510 1
            $callArguments
511
        );
512
513 1
        return call_user_func_array([$object, $method], $callArguments);
514
    }
515
516
}
517