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 |
||
10 | trait MetadataTrait |
||
11 | { |
||
12 | /* |
||
13 | * Array to record mapping between doctrine types and OData types |
||
14 | */ |
||
15 | protected $mapping = [ |
||
16 | 'integer' => EdmPrimitiveType::INT32, |
||
17 | 'string' => EdmPrimitiveType::STRING, |
||
18 | 'datetime' => EdmPrimitiveType::DATETIME, |
||
19 | 'decimal' => EdmPrimitiveType::DECIMAL, |
||
20 | 'text' => EdmPrimitiveType::STRING, |
||
21 | 'boolean' => EdmPrimitiveType::BOOLEAN, |
||
22 | 'blob' => "stream" |
||
23 | ]; |
||
24 | |||
25 | /* |
||
26 | * Retrieve and assemble this model's metadata for OData packaging |
||
27 | */ |
||
28 | 3 | public function metadata() |
|
63 | |||
64 | /* |
||
65 | * Return the set of fields that are permitted to be in metadata |
||
66 | * - following same visible-trumps-hidden guideline as Laravel |
||
67 | */ |
||
68 | 4 | public function metadataMask() |
|
82 | |||
83 | /* |
||
84 | * Assemble this model's OData metadata as xml schema |
||
85 | */ |
||
86 | 1 | public function getXmlSchema($MetaNamespace = "Data") |
|
112 | |||
113 | public function hookUpRelationships($entityTypes, $resourceSets) |
||
147 | |||
148 | protected function getAllAttributes() |
||
166 | |||
167 | 3 | protected function getRelationshipsFromMethods() |
|
168 | { |
||
169 | 3 | $model = $this; |
|
170 | $relationships = array( |
||
171 | 3 | "HasOne" => array(), |
|
172 | 3 | "UnknownPolyMorphSide"=>array(), |
|
173 | 3 | "HasMany"=>array(), |
|
174 | 3 | "KnownPolyMorphSide"=>array() |
|
175 | 3 | ); |
|
176 | 3 | $methods = get_class_methods($model); |
|
177 | 3 | if (!empty($methods)) { |
|
178 | 3 | foreach ($methods as $method) { |
|
179 | 3 | if (!method_exists('Illuminate\Database\Eloquent\Model', $method) |
|
180 | 3 | ) { |
|
181 | //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php |
||
182 | 3 | $reflection = new \ReflectionMethod($model, $method); |
|
183 | |||
184 | 3 | $file = new \SplFileObject($reflection->getFileName()); |
|
185 | 3 | $file->seek($reflection->getStartLine()-1); |
|
186 | 3 | $code = ''; |
|
187 | 3 | while ($file->key() < $reflection->getEndLine()) { |
|
188 | 3 | $code .= $file->current(); |
|
189 | 3 | $file->next(); |
|
190 | 3 | } |
|
191 | 3 | $code = trim(preg_replace('/\s\s+/', '', $code)); |
|
192 | 3 | $begin = strpos($code, 'function('); |
|
193 | 3 | $code = substr($code, $begin, strrpos($code, '}')-$begin+1); |
|
194 | foreach (array( |
||
195 | 3 | 'hasMany', |
|
196 | 3 | 'hasManyThrough', |
|
197 | 3 | 'belongsToMany', |
|
198 | 3 | 'hasOne', |
|
199 | 3 | 'belongsTo', |
|
200 | 3 | 'morphOne', |
|
201 | 3 | 'morphTo', |
|
202 | 3 | 'morphMany', |
|
203 | 'morphToMany' |
||
204 | 3 | ) as $relation) { |
|
205 | 3 | $search = '$this->'.$relation.'('; |
|
206 | 3 | if ($pos = stripos($code, $search)) { |
|
207 | //Resolve the relation's model to a Relation object. |
||
208 | 3 | $relationObj = $model->$method(); |
|
209 | 3 | if ($relationObj instanceof Relation) { |
|
210 | 3 | $relatedModel = '\\'.get_class($relationObj->getRelated()); |
|
211 | 3 | $relations = ['hasManyThrough', 'belongsToMany', 'hasMany', 'morphMany', 'morphToMany']; |
|
212 | 3 | if (in_array($relation, $relations)) { |
|
213 | //Collection or array of models (because Collection is Arrayable) |
||
214 | 1 | $relationships["HasMany"][$method] = $relatedModel; |
|
215 | 3 | } elseif ($relation === "morphTo") { |
|
216 | // Model isn't specified because relation is polymorphic |
||
217 | 1 | $relationships["UnknownPolyMorphSide"][$method] = |
|
218 | '\Illuminate\Database\Eloquent\Model|\Eloquent'; |
||
219 | 1 | } else { |
|
220 | //Single model is returned |
||
221 | 1 | $relationships["HasOne"][$method] = $relatedModel; |
|
222 | } |
||
223 | 3 | if (in_array($relation, ["morphMany", "morphOne"])) { |
|
224 | 2 | $relationships["KnownPolyMorphSide"][$method] = $relatedModel; |
|
225 | 2 | } |
|
226 | 3 | } |
|
227 | 3 | } |
|
228 | 3 | } |
|
229 | 3 | } |
|
230 | 3 | } |
|
231 | 3 | } |
|
232 | 3 | return $relationships; |
|
233 | } |
||
234 | |||
235 | /** |
||
236 | * Get the visible attributes for the model. |
||
237 | * |
||
238 | * @return array |
||
239 | */ |
||
240 | public abstract function getVisible(); |
||
241 | |||
242 | /** |
||
243 | * Get the hidden attributes for the model. |
||
244 | * |
||
245 | * @return array |
||
246 | */ |
||
247 | public abstract function getHidden(); |
||
248 | |||
249 | /** |
||
250 | * Get the primary key for the model. |
||
251 | * |
||
252 | * @return string |
||
253 | */ |
||
254 | public abstract function getKeyName(); |
||
255 | |||
256 | /** |
||
257 | * Get the current connection name for the model. |
||
258 | * |
||
259 | * @return string |
||
260 | */ |
||
261 | public abstract function getConnectionName(); |
||
262 | |||
263 | /** |
||
264 | * Get the database connection for the model. |
||
265 | * |
||
266 | * @return \Illuminate\Database\Connection |
||
267 | */ |
||
268 | public abstract function getConnection(); |
||
269 | |||
270 | /** |
||
271 | * Get all of the current attributes on the model. |
||
272 | * |
||
273 | * @return array |
||
274 | */ |
||
275 | public abstract function getAttributes(); |
||
276 | |||
277 | /** |
||
278 | * Get the table associated with the model. |
||
279 | * |
||
280 | * @return string |
||
281 | */ |
||
282 | public abstract function getTable(); |
||
283 | |||
284 | /** |
||
285 | * Get the fillable attributes for the model. |
||
286 | * |
||
287 | * @return array |
||
288 | */ |
||
289 | public abstract function getFillable(); |
||
290 | } |
||
291 |