ArgumentMapper::mapToObject()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 22
rs 8.6737
cc 5
eloc 12
nc 4
nop 2
1
<?php
2
3
namespace Tonic\Component\ApiLayer\JsonRpc\Method\ArgumentMapper;
4
5
use Tonic\Component\ApiLayer\JsonRpc\Method\ArgumentMapper\Normalizer\NormalizerInterface;
6
use Tonic\Component\ApiLayer\JsonRpc\Method\Exception\InvalidCallableArgumentsException;
7
use Tonic\Component\ApiLayer\JsonRpc\Method\Exception\InvalidMethodParametersException;
8
use Tonic\Component\Reflection\ReflectionFunctionFactory;
9
10
/**
11
 * Maps arguments to request object.
12
 */
13
class ArgumentMapper implements ArgumentMapperInterface
14
{
15
    /**
16
     * @var NormalizerInterface
17
     */
18
    private $normalizer;
19
20
    /**
21
     * Constructor.
22
     *
23
     * @param NormalizerInterface $normalizer
24
     */
25
    public function __construct(NormalizerInterface $normalizer)
26
    {
27
        $this->normalizer = $normalizer;
28
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function mapToObject(callable $callable, array $arguments)
34
    {
35
        if ((count($arguments) > 0) && $this->isIndexedArray($arguments)) {
36
            throw new InvalidCallableArgumentsException('Can not map indexed arrays');
37
        }
38
39
        $reflectionFunction = ReflectionFunctionFactory::createFromCallable($callable);
40
        if ($reflectionFunction->getNumberOfRequiredParameters() > 1) {
41
            throw new InvalidMethodParametersException('Could not map to more than one parameter');
42
        }
43
44
        $reflectionParameters = $reflectionFunction->getParameters();
45
        /** @var \ReflectionParameter $targetReflectionParameter */
46
        $targetReflectionParameter = reset($reflectionParameters);
47
        if (null === $targetReflectionParameter->getClass()) {
48
            throw new InvalidMethodParametersException('Method parameter should have type definition');
49
        }
50
51
        $mapped = $this->normalizer->denormalize($targetReflectionParameter->getClass()->name, $arguments);
52
53
        return $mapped;
54
    }
55
56
    /**
57
     * @param array $array
58
     *
59
     * @return bool
60
     */
61
    private function isIndexedArray(array $array)
62
    {
63
        return array_values($array) == $array;
64
    }
65
}
66