Completed
Push — master ( ac1114...7bd2bc )
by Wojciech
13s queued 11s
created

FlexEntity   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 46
c 2
b 1
f 0
dl 0
loc 134
ccs 57
cts 57
cp 1
rs 10
wmc 24

12 Methods

Rating   Name   Duplication   Size   Complexity  
A make() 0 8 2
A toJson() 0 3 1
A toArray() 0 3 1
A __toString() 0 3 1
A set() 0 5 1
A __call() 0 15 4
A add() 0 13 3
A get() 0 7 2
A addArrayField() 0 11 2
A __clone() 0 3 1
A cloneArray() 0 13 4
A fetchValue() 0 9 2
1
<?php
2
/*
3
 * This file is part of the Bushido\Foundation package.
4
 *
5
 * (c) Wojciech Nowicki <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE.md
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Bushido\Foundation\SmartEntity;
12
13
use Bushido\Foundation\Contracts\Makeable;
14
use Bushido\Foundation\Exceptions\InvalidArgumentException;
15
use Bushido\Foundation\Helpers\ArrayableHelper;
16
use Bushido\Foundation\Helpers\ChangeCase;
17
18
class FlexEntity implements Entity
19
{
20
    private $data = [];
21
22
    /**
23
     * @param array $components
24
     * @return static
25
     */
26 54
    public static function make(array $components): Makeable
27
    {
28 54
        $entity = new static();
29
30 54
        foreach ($components as $k => $v) {
31 24
            $entity->{'set' . ChangeCase::snakeToCamel($k)}($v);
32
        }
33 54
        return $entity;
34
    }
35
36 15
    public function toArray(): array
37
    {
38 15
        return ArrayableHelper::processArray($this->data);
39
    }
40
41 6
    public function toJson(int $options = 0): string
42
    {
43 6
        return (string) json_encode($this->toArray(), $options);
44
    }
45
46 3
    public function __toString(): string
47
    {
48 3
        return $this->toJson();
49
    }
50
51 72
    public function __call(string $name, array $arguments)
52
    {
53 72
        $action = substr($name, 0, 3);
54 72
        $property = ChangeCase::camelToSnake(substr($name, 3));
55
56 48
        switch ($action) {
57 72
            case 'set':
58 51
                return $this->set($property, $arguments);
59 45
            case 'get':
60 33
                return $this->get($property);
61 21
            case 'add':
62 18
                return $this->add($property, $arguments);
63
        }
64
65 3
        throw new \RuntimeException('Call to undefined method '.__CLASS__.'::'.$name.'()');
66
    }
67
68
    /**
69
     * @param string $property
70
     * @param array $arguments
71
     * @return $this
72
     */
73 39
    protected function set(string $property, array $arguments)
74
    {
75 39
        $this->data[$property] = $this->fetchValue($arguments, $property);
76
77 36
        return $this;
78
    }
79
80 33
    private function get(string $property)
81
    {
82 33
        if (array_key_exists($property, $this->data)) {
83 30
            return $this->data[$property];
84
        }
85
86 3
        return null;
87
    }
88
89
    /**
90
     * @param string $name
91
     * @param array $arguments
92
     * @return $this
93
     * @throws InvalidArgumentException
94
     */
95 12
    protected function add(string $name, array $arguments)
96
    {
97 12
        if (!isset($this->data[$name])) {
98 9
            $this->data[$name] = [];
99
        }
100
101 12
        if (is_array($this->data[$name])) {
102 9
            $this->addArrayField($this->data[$name], $arguments[0], $arguments);
103
104 9
            return $this;
105
        }
106
107 3
        throw new InvalidArgumentException('Cannot add to [' . $name . '] property as it is not an array.');
108
    }
109
110 9
    protected function addArrayField(&$array, $value, array $arguments)
111
    {
112 9
        if (isset($arguments[1])) {
113 6
            $array[(string) $arguments[1]] = $value;
114
115 6
            return $array;
116
        }
117
118 3
        $array[] = $value;
119
120 3
        return $array;
121
    }
122
123 60
    protected function fetchValue(array $arguments, string $propertyName)
124
    {
125 60
        if (empty($arguments)) {
126 3
            throw new \RuntimeException(
127 3
                'Missing argument on ' . __CLASS__ . '::set' . ChangeCase::snakeToCamel($propertyName, true) . '() call'
128
            );
129
        }
130
131 57
        return $arguments[0];
132
    }
133
134 6
    public function __clone()
135
    {
136 6
        $this->data = $this->cloneArray($this->data);
137 6
    }
138
139 6
    protected function cloneArray(array $data)
140
    {
141 6
        foreach ($data as $k => $v) {
142 6
            if (is_object($v)) {
143 6
                $data[$k] = clone $v;
144
            }
145
146 6
            if (is_array($v)) {
147 4
                $data[$k] = $this->cloneArray($v);
148
            }
149
        }
150
151 6
        return $data;
152
    }
153
}
154