Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
11 | abstract class AbstractJsonDeserializeObject implements JsonDeserializeInterface, ObjectTreeInterface |
||
12 | { |
||
13 | use ObjectTreeTrait; |
||
14 | |||
15 | const JSON_DESERIALIZE_INTERFACE = 'Commercetools\Core\Model\Common\JsonDeserializeInterface'; |
||
16 | const TYPEABLE_INTERFACE = '\Commercetools\Core\Model\Common\TypeableInterface'; |
||
17 | |||
18 | abstract protected function initialize($field); |
||
19 | |||
20 | protected $rawData = []; |
||
21 | protected $typeData = []; |
||
22 | protected $initialized = []; |
||
23 | |||
24 | /** |
||
25 | * @param array $data |
||
26 | * @param Context|callable $context |
||
27 | */ |
||
28 | 1057 | public function __construct(array $data = [], $context = null) |
|
29 | { |
||
30 | 1057 | $this->setContext($context); |
|
31 | 1057 | if (!is_null($data)) { |
|
32 | 1057 | $this->rawData = $this->typeData = $data; |
|
33 | } |
||
34 | 1057 | } |
|
35 | |||
36 | protected static $primitives = [ |
||
37 | 'bool' => 'is_bool', |
||
38 | 'int' => 'is_int', |
||
39 | 'string' => 'is_string', |
||
40 | 'float' => 'is_float', |
||
41 | 'array' => 'is_array' |
||
42 | ]; |
||
43 | |||
44 | /** |
||
45 | * @var bool[] |
||
46 | */ |
||
47 | protected static $interfaces = []; |
||
48 | |||
49 | public function __sleep() |
||
50 | { |
||
51 | return array_diff(array_keys(get_object_vars($this)), ['context']); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * @param $type |
||
56 | * @param $interfaceName |
||
57 | * @return bool |
||
58 | * @internal |
||
59 | */ |
||
60 | 370 | protected function hasInterface($type, $interfaceName) |
|
61 | { |
||
62 | 370 | $interfaceName = trim($interfaceName, '\\'); |
|
63 | 370 | $cacheKey = $interfaceName . '-' . $type; |
|
64 | 370 | if (!isset(static::$interfaces[$cacheKey])) { |
|
65 | 82 | $interface = false; |
|
66 | 82 | if ($this->isPrimitive($type) === false |
|
67 | 82 | && isset(class_implements($type)[$interfaceName]) |
|
68 | ) { |
||
69 | 74 | $interface = true; |
|
70 | } |
||
71 | 82 | static::$interfaces[$cacheKey] = $interface; |
|
72 | } |
||
73 | 370 | return static::$interfaces[$cacheKey]; |
|
74 | } |
||
75 | |||
76 | /** |
||
77 | * @param $type |
||
78 | * @return string|false |
||
79 | * @internal |
||
80 | */ |
||
81 | 670 | protected function isPrimitive($type) |
|
82 | { |
||
83 | 670 | if (!isset(static::$primitives[$type])) { |
|
84 | 365 | return false; |
|
85 | } |
||
86 | |||
87 | 624 | return static::$primitives[$type]; |
|
88 | } |
||
89 | |||
90 | /** |
||
91 | * @param string|bool $type |
||
92 | * @param mixed $value |
||
93 | * @return bool |
||
94 | */ |
||
95 | 660 | protected function isValidType($type, $value) |
|
96 | { |
||
97 | 660 | return !is_string($type) || is_null($value) || $this->isType($type, $value); |
|
98 | } |
||
99 | |||
100 | /** |
||
101 | * @param string $type |
||
102 | * @param mixed $value |
||
103 | * @return bool |
||
104 | * @internal |
||
105 | */ |
||
106 | 655 | protected function isType($type, $value) |
|
107 | { |
||
108 | 655 | if ($typeFunction = $this->isPrimitive($type)) { |
|
109 | 622 | return $typeFunction($value); |
|
110 | } |
||
111 | 347 | return $value instanceof $type; |
|
112 | } |
||
113 | |||
114 | /** |
||
115 | * @param $value |
||
116 | * @return bool |
||
117 | */ |
||
118 | protected function isDeserializable($value) |
||
119 | { |
||
120 | return (is_object($value) && $this->hasInterface(get_class($value), static::JSON_DESERIALIZE_INTERFACE)); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * @param $type |
||
125 | * @return bool |
||
126 | */ |
||
127 | 371 | View Code Duplication | protected function isDeserializableType($type) |
|
|||
128 | { |
||
129 | 371 | if (!is_string($type) || empty($type)) { |
|
130 | 14 | return false; |
|
131 | } |
||
132 | 370 | return $this->hasInterface($type, static::JSON_DESERIALIZE_INTERFACE); |
|
133 | } |
||
134 | |||
135 | 358 | View Code Duplication | protected function isTypeableType($type) |
136 | { |
||
137 | 358 | if (!is_string($type) || empty($type)) { |
|
138 | 14 | return false; |
|
139 | } |
||
140 | 357 | return $this->hasInterface($type, static::TYPEABLE_INTERFACE); |
|
141 | } |
||
142 | |||
143 | 427 | protected function getTyped($offset) |
|
144 | { |
||
145 | 427 | if (!isset($this->initialized[$offset])) { |
|
146 | 373 | $this->initialize($offset); |
|
147 | } |
||
148 | 427 | if (array_key_exists($offset, $this->typeData)) { |
|
149 | 427 | return $this->typeData[$offset]; |
|
150 | } |
||
151 | return $this->rawData[$offset]; |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @param array $rawData |
||
156 | * @internal |
||
157 | * @return $this |
||
158 | */ |
||
159 | 10 | public function setRawData(array $rawData) |
|
160 | { |
||
161 | 10 | $this->rawData = $this->typeData = $rawData; |
|
162 | |||
163 | 10 | return $this; |
|
164 | } |
||
165 | |||
166 | /** |
||
167 | * @param $field |
||
168 | * @param $default |
||
169 | * @return mixed |
||
170 | */ |
||
171 | 370 | protected function getRaw($field, $default = null) |
|
172 | { |
||
173 | 370 | return isset($this->rawData[$field])? $this->rawData[$field]: $default; |
|
174 | } |
||
175 | |||
176 | /** |
||
177 | * (PHP 5 >= 5.4.0)<br/> |
||
178 | * Specify data which should be serialized to JSON |
||
179 | * @link http://php.net/manual/en/jsonserializable.jsonserialize.php |
||
180 | * @return mixed data which can be serialized by <b>json_encode</b>, |
||
181 | * which is a value of any type other than a resource. |
||
182 | */ |
||
183 | 315 | public function jsonSerialize() |
|
187 | |||
188 | /** |
||
189 | * @return array |
||
190 | */ |
||
191 | 315 | protected function toJson() |
|
199 | |||
200 | /** |
||
201 | * @return array |
||
202 | */ |
||
203 | 5 | public function toArray() |
|
219 | |||
220 | /** |
||
221 | * @param array $data |
||
222 | * @param Context|callable $context |
||
223 | * @return static |
||
224 | */ |
||
225 | 540 | public static function fromArray(array $data, $context = null) |
|
226 | { |
||
227 | 540 | return new static($data, $context); |
|
228 | } |
||
229 | |||
230 | /** |
||
231 | * @param Context|callable $context |
||
232 | * @return static |
||
233 | */ |
||
234 | 807 | final public static function of($context = null) |
|
238 | } |
||
239 |
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.