1
|
|
|
<?php |
2
|
|
|
namespace einfach\representer; |
3
|
|
|
|
4
|
|
|
use einfach\representer\serializer\ArraySerializer; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Trait Representer |
8
|
|
|
* |
9
|
|
|
* @package einfach\representer |
10
|
|
|
*/ |
11
|
|
|
trait Representer |
12
|
|
|
{ |
13
|
|
|
use ArraySerializer; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Object that is being represented |
17
|
|
|
* or a collection handler |
18
|
|
|
*/ |
19
|
|
|
protected $source; |
20
|
|
|
/** |
21
|
|
|
* Class name to be restored |
22
|
|
|
* |
23
|
|
|
* @var string |
24
|
|
|
*/ |
25
|
|
|
protected $targetClassName; |
26
|
|
|
/** |
27
|
|
|
* Strategy indicator |
28
|
|
|
* 1 = one |
29
|
|
|
* 2 = collection |
30
|
|
|
* 3 = restore one |
31
|
|
|
* 4 = restore collection |
32
|
|
|
* |
33
|
|
|
* @var string |
34
|
|
|
*/ |
35
|
|
|
protected $strategy; |
36
|
|
|
|
37
|
8 |
|
public function __construct($source = null, $strategy) |
38
|
|
|
{ |
39
|
8 |
|
if (is_null($strategy)) { |
40
|
|
|
throw new \Exception('Representer can not be initialized without a strategy param'); |
41
|
|
|
} |
42
|
|
|
|
43
|
8 |
|
$this->source = $source; |
44
|
8 |
|
$this->strategy = $strategy; |
45
|
8 |
|
} |
46
|
|
|
|
47
|
|
|
public function rules() |
48
|
|
|
{ |
49
|
|
|
return []; |
50
|
|
|
} |
51
|
|
|
|
52
|
4 |
|
public function setTargetClassName($name) |
53
|
|
|
{ |
54
|
4 |
|
$this->targetClassName = $name; |
55
|
4 |
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @param $name |
59
|
|
|
* @return PropertyRule |
60
|
|
|
*/ |
61
|
8 |
|
public function property($name) |
62
|
|
|
{ |
63
|
8 |
|
return new PropertyRule($this->source, $name); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Represent one instance |
68
|
|
|
* |
69
|
|
|
* @param $source |
70
|
|
|
* @return static |
71
|
|
|
*/ |
72
|
6 |
|
public static function one($source) |
73
|
|
|
{ |
74
|
6 |
|
return new static($source, 1); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Represent collection of instances |
79
|
|
|
* |
80
|
|
|
* @param array $array |
81
|
|
|
* @return static |
82
|
|
|
*/ |
83
|
2 |
|
public static function collection(array $array) |
84
|
|
|
{ |
85
|
2 |
|
return new static($array, 2); |
86
|
|
|
} |
87
|
|
|
|
88
|
2 |
|
protected function getCollectionRepresentation() |
89
|
|
|
{ |
90
|
2 |
|
if (is_array($this->source) && count($this->source) > 0) { |
91
|
|
|
return array_map(function ($object) { |
92
|
2 |
|
return static::one($object)->getOneRepresentation(); |
93
|
2 |
|
}, $this->source); |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
6 |
View Code Duplication |
protected function getOneRepresentation() |
|
|
|
|
98
|
|
|
{ |
99
|
6 |
|
$rules = $this->rules(); |
100
|
6 |
|
$represented = []; |
101
|
|
|
|
102
|
6 |
|
if (!empty($rules)) { |
103
|
6 |
|
foreach ($rules as $rule) { |
104
|
|
|
/** @var $rule PropertyRule */ |
105
|
6 |
|
$resultArray = $rule->compile(); |
106
|
|
|
|
107
|
6 |
|
reset($resultArray); |
108
|
6 |
|
$key = key($resultArray); |
109
|
6 |
|
$value = $resultArray[$key]; |
110
|
|
|
|
111
|
6 |
|
$represented[$key] = $value; |
112
|
6 |
|
} |
113
|
6 |
|
} |
114
|
|
|
|
115
|
6 |
|
return $represented; |
116
|
|
|
} |
117
|
|
|
|
118
|
6 |
|
protected function getRepresentation() |
119
|
|
|
{ |
120
|
6 |
|
switch ($this->strategy) { |
121
|
6 |
|
case 1: |
122
|
4 |
|
return $this->getOneRepresentation(); |
123
|
2 |
|
case 2: |
124
|
2 |
|
return $this->getCollectionRepresentation(); |
125
|
|
|
default: |
126
|
|
|
throw new \Exception('Representation strategy not defined'); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* @param $className |
134
|
|
|
* @return static |
135
|
|
|
*/ |
136
|
4 |
|
public static function restore($className) |
137
|
|
|
{ |
138
|
4 |
|
$instance = new static(null, 3); |
139
|
4 |
|
$instance->setTargetClassName($className); |
140
|
4 |
|
return $instance; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @param string $className |
145
|
|
|
* @return static |
146
|
|
|
*/ |
147
|
1 |
|
public static function restoreCollection($className) |
148
|
|
|
{ |
149
|
1 |
|
$instance = new static(null, 4); |
150
|
1 |
|
$instance->setTargetClassName($className); |
151
|
1 |
|
return $instance; |
152
|
|
|
} |
153
|
|
|
|
154
|
4 |
|
protected function getReverseRepresentation($projection) |
155
|
|
|
{ |
156
|
4 |
|
switch ($this->strategy) { |
157
|
4 |
|
case 3: |
158
|
3 |
|
return $this->getOneReverseRepresentation($projection); |
159
|
1 |
|
case 4: |
160
|
1 |
|
return $this->getCollectionReverseRepresentation($projection); |
161
|
|
|
default: |
162
|
|
|
throw new \Exception('Reverse representation strategy not defined'); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
} |
166
|
|
|
|
167
|
4 |
View Code Duplication |
protected function getOneReverseRepresentation($projection) |
|
|
|
|
168
|
|
|
{ |
169
|
4 |
|
$rules = $this->rules(); |
170
|
4 |
|
$target = new $this->targetClassName(); |
171
|
|
|
|
172
|
4 |
|
if (!empty($rules)) { |
173
|
4 |
|
foreach ($rules as $rule) { |
174
|
|
|
/** @var $rule PropertyRule */ |
175
|
4 |
|
$resultArray = $rule->reverseCompile($projection); |
176
|
|
|
|
177
|
4 |
|
reset($resultArray); |
178
|
4 |
|
$key = key($resultArray); |
179
|
4 |
|
$value = $resultArray[$key]; |
180
|
|
|
|
181
|
4 |
|
$target->$key = $value; |
182
|
4 |
|
} |
183
|
4 |
|
} |
184
|
4 |
|
return $target; |
185
|
|
|
} |
186
|
|
|
|
187
|
1 |
|
protected function getCollectionReverseRepresentation($projectionArray) |
188
|
|
|
{ |
189
|
1 |
|
if (is_array($projectionArray) && count($projectionArray) > 0) { |
190
|
1 |
|
return array_map(function ($projection) { |
191
|
1 |
|
return static::restore($this->targetClassName)->getOneReverseRepresentation($projection); |
192
|
1 |
|
}, $projectionArray); |
193
|
|
|
} |
194
|
|
|
} |
195
|
|
|
} |
196
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.