Completed
Push — master ( 221982...3ea98f )
by Iqbal
02:19
created

MessageMapperFactory::normalizeValue()   C

Complexity

Conditions 10
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 22
rs 6.1368
cc 10
eloc 11
nc 6
nop 2

How to fix   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
 * This file is part of the Borobudur-Bus package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\Bus\Message;
12
13
use Borobudur\Bus\Exception\InvalidArgumentException;
14
use ReflectionClass;
15
use ReflectionParameter;
16
17
/**
18
 * @author      Iqbal Maulana <[email protected]>
19
 * @created     10/12/15
20
 */
21
class MessageMapperFactory
22
{
23
    /**
24
     * Factory create object.
25
     *
26
     * @param string $class
27
     * @param array  $data
28
     *
29
     * @return object
30
     */
31
    public static function create($class, array $data)
32
    {
33
        $reflection = new ReflectionClass($class);
34
        $parameters = $reflection->getConstructor()->getParameters();
35
36
        return $reflection->newInstanceArgs(self::normalizeParameters($parameters, $data));
37
    }
38
39
    /**
40
     * Call factory method on class.
41
     *
42
     * @param string $class
43
     * @param string $method
44
     * @param array  $data
45
     *
46
     * @return object
47
     */
48
    public static function call($class, $method, array $data)
49
    {
50
        $reflection = new ReflectionClass($class);
51
        if (!$reflection->hasMethod($method)) {
52
            throw new InvalidArgumentException(sprintf(
53
                'Undefined method "%s" in class "%s".',
54
                $method,
55
                $class
56
            ));
57
        }
58
59
        $method = $reflection->getMethod($method);
60
        $parameters = $method->getParameters();
61
62
        return $method->invokeArgs(null, self::normalizeParameters($parameters, $data));
63
    }
64
65
    /**
66
     * Normalize parameters.
67
     *
68
     * @param ReflectionParameter[] $parameters
69
     * @param array                 $data
70
     *
71
     * @return array
72
     */
73
    public static function normalizeParameters(array $parameters, array $data)
74
    {
75
        $arguments = array();
76
        foreach ($parameters as $param) {
77
            if (!$param instanceof ReflectionParameter) {
78
                throw new InvalidArgumentException(sprintf(
79
                    'Param "%s" not instance of ReflectionParameter',
80
                    (string) $param
81
                ));
82
            }
83
84
            $name = $param->getName();
85
            $value = isset($data[$name]) ? $data[$name] : null;
86
87
            $arguments[$name] = self::normalizeValue($param, $value);
88
        }
89
90
        return $arguments;
91
    }
92
93
    /**
94
     * Normalize value.
95
     *
96
     * @param ReflectionParameter $param
97
     * @param mixed               $value
98
     *
99
     * @return mixed
100
     */
101
    private static function normalizeValue(ReflectionParameter $param, $value)
102
    {
103
        if (null === $value) {
104
            return $value;
105
        }
106
        
107
        if (null !== ($class = $param->getClass()) && false === is_object($value)) {
108
            if (is_scalar($value) && $class->hasMethod('fromString')) {
109
                return $class->getMethod('fromString')->invoke(null, $value);
110
            }
111
112
            if ((is_array($value) || is_object($value)) && $class->hasMethod('deserialize')) {
113
                return $class->getMethod('deserialize')->invoke(null, $value);
114
            }
115
116
            if ($class->isInstantiable()) {
117
                return $class->newInstance($value);
118
            }
119
        }
120
121
        return $value;
122
    }
123
}
124