Completed
Push — master ( 1d357f...a1b155 )
by Peter
03:30
created

PayloadTrait   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 1
dl 0
loc 113
ccs 37
cts 37
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A payload() 0 4 1
A setPayload() 0 14 3
A lostProperties() 0 4 2
A setProperty() 0 10 4
A analyze() 0 8 3
A getProperties() 0 10 2
A getMethods() 0 10 2
1
<?php
2
3
/**
4
 * GpsLab component.
5
 *
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2011, Peter Gribanov
8
 * @license   http://opensource.org/licenses/MIT
9
 */
10
11
namespace GpsLab\Component\Payload;
12
13
use GpsLab\Component\Payload\Exception\PropertyException;
14
15
trait PayloadTrait
16
{
17
    /**
18
     * @var array
19
     */
20
    private $payload = [];
21
22
    /**
23
     * @var string[]
24
     */
25
    private $properties = [];
26
27
    /**
28
     * @var string[]
29
     */
30
    private $methods = [];
31
32
    /**
33
     * @return array
34
     */
35 3
    final public function payload()
36
    {
37 3
        return $this->payload;
38
    }
39
40
    /**
41
     * @param array    $payload
42
     * @param string[] $required
43
     *
44
     * @throws PropertyException
45
     */
46 12
    final protected function setPayload(array $payload, array $required = [])
47
    {
48 12
        if ($lost = $this->lostProperties($payload, $required)) {
49 2
            throw PropertyException::noRequiredProperties($lost, $this);
50
        }
51
52 10
        $this->analyze();
53
54 10
        foreach ($payload as $name => $value) {
55 10
            $this->setProperty($name, $value);
56
        }
57
58 4
        $this->payload = $payload;
59 4
    }
60
61
    /**
62
     * @param array    $payload
63
     * @param string[] $required
64
     *
65
     * @return string[]
66
     */
67 12
    private function lostProperties(array $payload, array $required = [])
68
    {
69 12
        return !empty($required) ? array_diff($required, array_keys($payload)) : [];
70
    }
71
72
    /**
73
     * @param string $name
74
     * @param mixed  $value
75
     */
76 10
    private function setProperty($name, $value)
77
    {
78 10
        if (in_array($name, $this->properties)) {
79 3
            $this->$name = $value;
80 7
        } elseif (($method = 'set'.ucfirst($name)) && in_array($method, $this->methods)) {
81 1
            $this->{$method}($value);
82
        } else {
83 6
            throw PropertyException::undefinedProperty($name, $this);
84
        }
85 4
    }
86
87 10
    private function analyze()
88
    {
89 10
        if (!$this->properties && !$this->methods) {
90 10
            $ref = new \ReflectionClass($this);
91 10
            $this->properties = $this->getProperties($ref);
92 10
            $this->methods = $this->getMethods($ref);
93
        }
94 10
    }
95
96
    /**
97
     * @param \ReflectionClass $ref
98
     *
99
     * @return string[]
100
     */
101 10
    private function getProperties(\ReflectionClass $ref)
102
    {
103 10
        $names = [];
104 10
        $properties = $ref->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);
105 10
        foreach ($properties as $property) {
106 9
            $names[] = $property->name;
107
        }
108
109 10
        return $names;
110
    }
111
112
    /**
113
     * @param \ReflectionClass $ref
114
     *
115
     * @return string[]
116
     */
117 10
    private function getMethods(\ReflectionClass $ref)
118
    {
119 10
        $names = [];
120 10
        $methods = $ref->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED);
121 10
        foreach ($methods as $method) {
122 10
            $names[] = $method->name;
123
        }
124
125 10
        return $names;
126
    }
127
}
128