ObjectMapper   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 16
c 2
b 0
f 1
lcom 1
cbo 3
dl 0
loc 115
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B map() 0 33 4
A ensureIsObject() 0 6 2
A findGetterMethods() 0 6 1
A filterMethodsWithPrefix() 0 14 3
A processPropertyRules() 0 15 3
A processPropertyTransformers() 0 12 2
1
<?php
2
3
namespace DCP\Mapper;
4
5
use DCP\Mapper\Collections\Maps\RuleMap;
6
use DCP\Mapper\Collections\Maps\TransformerMap;
7
use DCP\Mapper\Exception\InvalidArgumentException;
8
9
class ObjectMapper implements MapperInterface
10
{
11
    /**
12
     * @var RuleMap
13
     */
14
    private $ruleMap;
15
16
    /**
17
     * @var TransformerMap
18
     */
19
    private $transformerMap;
20
21
    public function __construct(RuleMap $ruleMap, TransformerMap $transformerMap)
22
    {
23
        $this->ruleMap = $ruleMap;
24
        $this->transformerMap = $transformerMap;
25
    }
26
27
    public function map($source, $target)
28
    {
29
        $this->ensureIsObject('source', $source);
30
        $this->ensureIsObject('target', $target);
31
32
        $sourceClass = new \ReflectionClass($source);
33
        $targetClass = new \ReflectionClass($target);
34
35
        $sourceGetters = $this->findGetterMethods($sourceClass);
36
37
        foreach ($sourceGetters as $getter) {
38
            $getterPropertyName = lcfirst(substr($getter->getName(), 3)); // getLastName -> lastName
0 ignored issues
show
Bug introduced by
Consider using $getter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
39
40
            if (!$this->processPropertyRules($getterPropertyName)) {
41
                continue;
42
            }
43
44
            $setterMethodName = 'set' . ucfirst($getterPropertyName); // lastName -> setLastName
45
46
            if (!$targetClass->hasMethod($setterMethodName)) {
47
                continue;
48
            }
49
50
            $setter = $targetClass->getMethod($setterMethodName);
51
52
            $propertyValue = $getter->invoke($source);
53
            $propertyValue = $this->processPropertyTransformers($getterPropertyName, $propertyValue);
54
55
            $setter->invokeArgs($target, [$propertyValue]);
56
        }
57
58
        return $target;
59
    }
60
61
    private function ensureIsObject($variableName, $object)
62
    {
63
        if (!is_object($object)) {
64
            throw new InvalidArgumentException(sprintf('$%s must be an object', $variableName));
65
        }
66
    }
67
68
    private function findGetterMethods(\ReflectionClass $class)
69
    {
70
        $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
71
72
        return $this->filterMethodsWithPrefix($methods, 'get');
73
    }
74
75
    /**
76
     * @param \ReflectionMethod[] $methods
77
     * @param string $prefix
78
     * @return \ReflectionMethod[]
79
     */
80
    private function filterMethodsWithPrefix($methods, $prefix)
81
    {
82
        $result = [];
83
84
        foreach ($methods as $method) {
85
            $methodName = $method->getName();
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
86
87
            if (strpos($methodName, $prefix) === 0) {
88
                $result[] = $method;
89
            }
90
        }
91
92
        return $result;
93
    }
94
95
    private function processPropertyRules($property)
96
    {
97
        $rules = $this->ruleMap->get($property);
98
99
        $proceed = true;
100
101
        foreach ($rules as $rule) {
102
            if (!$rule->execute()) {
103
                $proceed = false;
104
                break;
105
            }
106
        }
107
108
        return $proceed;
109
    }
110
111
    private function processPropertyTransformers($property, $value)
112
    {
113
        $transformers = $this->transformerMap->get($property);
114
115
        $result = $value;
116
117
        foreach ($transformers as $transformer) {
118
            $result = $transformer->transform($result);
119
        }
120
121
        return $result;
122
    }
123
}
124