We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
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:
Complex classes like CrudTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use CrudTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | trait CrudTrait |
||
9 | { |
||
10 | /* |
||
11 | |-------------------------------------------------------------------------- |
||
12 | | Methods for ENUM and SELECT crud fields. |
||
13 | |-------------------------------------------------------------------------- |
||
14 | */ |
||
15 | |||
16 | public static function getPossibleEnumValues($field_name) |
||
28 | |||
29 | public static function isColumnNullable($column_name) |
||
36 | |||
37 | /* |
||
38 | |-------------------------------------------------------------------------- |
||
39 | | Methods for Fake Fields functionality (used in PageManager). |
||
40 | |-------------------------------------------------------------------------- |
||
41 | */ |
||
42 | |||
43 | /** |
||
44 | * Add fake fields as regular attributes, even though they are stored as JSON. |
||
45 | * |
||
46 | * @param array $columns - the database columns that contain the JSONs |
||
47 | */ |
||
48 | public function addFakes($columns = ['extras']) |
||
64 | |||
65 | /** |
||
66 | * Return the entity with fake fields as attributes. |
||
67 | * |
||
68 | * @param array $columns - the database columns that contain the JSONs |
||
69 | * |
||
70 | * @return Model |
||
71 | */ |
||
72 | public function withFakes($columns = []) |
||
84 | |||
85 | /* |
||
86 | |-------------------------------------------------------------------------- |
||
87 | | Methods for storing uploaded files (used in CRUD). |
||
88 | |-------------------------------------------------------------------------- |
||
89 | */ |
||
90 | |||
91 | /** |
||
92 | * Handle file upload and DB storage for a file: |
||
93 | * - on CREATE |
||
94 | * - stores the file at the destination path |
||
95 | * - generates a name |
||
96 | * - stores the full path in the DB; |
||
97 | * - on UPDATE |
||
98 | * - if the value is null, deletes the file and sets null in the DB |
||
99 | * - if the value is different, stores the different file and updates DB value. |
||
100 | * |
||
101 | * @param [type] $value Value for that column sent from the input. |
||
102 | * @param [type] $attribute_name Model attribute name (and column in the db). |
||
103 | * @param [type] $disk Filesystem disk used to store files. |
||
104 | * @param [type] $destination_path Path in disk where to store the files. |
||
105 | */ |
||
106 | public function uploadFileToDisk($value, $attribute_name, $disk, $destination_path) |
||
138 | |||
139 | /** |
||
140 | * Handle multiple file upload and DB storage: |
||
141 | * - if files are sent |
||
142 | * - stores the files at the destination path |
||
143 | * - generates random names |
||
144 | * - stores the full path in the DB, as JSON array; |
||
145 | * - if a hidden input is sent to clear one or more files |
||
146 | * - deletes the file |
||
147 | * - removes that file from the DB. |
||
148 | * |
||
149 | * @param [type] $value Value for that column sent from the input. |
||
150 | * @param [type] $attribute_name Model attribute name (and column in the db). |
||
151 | * @param [type] $disk Filesystem disk used to store files. |
||
152 | * @param [type] $destination_path Path in disk where to store the files. |
||
153 | */ |
||
154 | public function uploadMultipleFilesToDisk($value, $attribute_name, $disk, $destination_path) |
||
190 | |||
191 | /** |
||
192 | * Handle image upload and DB storage for a image: |
||
193 | * - on CREATE |
||
194 | * - stores the image at the destination path |
||
195 | * - generates a name |
||
196 | * - creates image variations |
||
197 | * - stores json object into database with variations and paths |
||
198 | * - on UPDATE |
||
199 | * - if the value is null, deletes the file and sets null in the DB |
||
200 | * - if the value is different, stores the different file and updates DB value. |
||
201 | * |
||
202 | * @param [type] $value Value for that column sent from the input. |
||
203 | * @param [type] $attribute_name Model attribute name (and column in the db). |
||
204 | * @param [type] $disk Filesystem disk used to store files. |
||
205 | * @param [type] $destination_path Path in disk where to store the files. |
||
206 | * @param [type] $variations Array of variations and their dimensions |
||
207 | */ |
||
208 | public function uploadImageToDisk($value, $attribute_name, $disk, $destination_path, $variations = null) |
||
209 | { |
||
210 | if (! $variations || ! is_array($variations)) { |
||
211 | $variations = ['original' => null, 'thumb' => [150, 150]]; |
||
212 | } |
||
213 | |||
214 | //Needed for the original image |
||
215 | if (! array_key_exists('original', $variations)) { |
||
216 | $variations['original'] = null; |
||
217 | } |
||
218 | |||
219 | //Needed for admin thumbnails |
||
220 | if (! array_key_exists('thumb', $variations)) { |
||
221 | $variations['thumb'] = [150, 150]; |
||
222 | } |
||
223 | |||
224 | $request = \Request::instance(); |
||
225 | |||
226 | //We need to setup the disk paths as they're handled differently |
||
227 | //depending if you need a public path or internal storage |
||
228 | $disk_config = config('filesystems.disks.'.$disk); |
||
229 | $disk_root = $disk_config['root']; |
||
230 | |||
231 | //if the disk is public, we need to know the public path |
||
232 | View Code Duplication | if ($disk_config['visibility'] == 'public') { |
|
233 | $public_path = str_replace(public_path(), '', $disk_root); |
||
234 | } else { |
||
235 | $public_path = $disk_root; |
||
236 | } |
||
237 | |||
238 | // if a new file is uploaded, delete the file from the disk |
||
239 | if (($request->hasFile($attribute_name) || starts_with($value, 'data:image')) && $this->{$attribute_name}) { |
||
240 | View Code Duplication | foreach ($variations as $variant => $dimensions) { |
|
241 | $variant_name = str_replace('-original', '-'.$variant, $this->{$attribute_name}); |
||
242 | \Storage::disk($disk)->delete($variant_name); |
||
243 | } |
||
244 | $this->attributes[$attribute_name] = null; |
||
245 | } |
||
246 | |||
247 | // if the file input is empty, delete the file from the disk |
||
248 | if (empty($value)) { |
||
249 | View Code Duplication | foreach ($variations as $variant => $dimensions) { |
|
250 | $variant_name = str_replace('-original', '-'.$variant, $this->{$attribute_name}); |
||
251 | \Storage::disk($disk)->delete($variant_name); |
||
252 | } |
||
253 | |||
254 | return $this->attributes[$attribute_name] = null; |
||
255 | } |
||
256 | |||
257 | // if a new file is uploaded, store it on disk and its filename in the database |
||
258 | if ($request->hasFile($attribute_name) && $request->file($attribute_name)->isValid()) { |
||
259 | |||
260 | // 1. Generate a new file name |
||
261 | $file = $request->file($attribute_name); |
||
262 | $new_file_name = md5($file->getClientOriginalName().time()); |
||
263 | $new_file = $new_file_name.'.'.$file->getClientOriginalExtension(); |
||
264 | |||
265 | // 2. Move the new file to the correct path |
||
266 | $file_path = $file->storeAs($destination_path, $new_file, $disk); |
||
267 | $image_variations = []; |
||
268 | |||
269 | // 3. but only if they have the ability to crop/handle images |
||
270 | if (class_exists('\Intervention\Image\ImageManagerStatic')) { |
||
271 | $img = \Intervention\Image\ImageManagerStatic::make($file); |
||
272 | foreach ($variations as $variant => $dimensions) { |
||
273 | $variant_name = $new_file_name.'-'.$variant.'.'.$file->getClientOriginalExtension(); |
||
274 | $variant_file = $destination_path.'/'.$variant_name; |
||
275 | |||
276 | View Code Duplication | if ($dimensions) { |
|
277 | $width = $dimensions[0]; |
||
278 | $height = $dimensions[1]; |
||
279 | |||
280 | if ($img->width() > $width || $img->height() > $height) { |
||
281 | $img->resize($width, $height, function ($constraint) { |
||
282 | $constraint->aspectRatio(); |
||
283 | }) |
||
284 | ->save($disk_root.'/'.$variant_file); |
||
285 | } else { |
||
286 | $img->save($disk_root.'/'.$variant_file); |
||
287 | } |
||
288 | |||
289 | $image_variations[$variant] = $public_path.'/'.$variant_file; |
||
290 | } else { |
||
291 | $image_variations['original'] = $public_path.'/'.$file_path; |
||
292 | } |
||
293 | } |
||
294 | } else { |
||
295 | $image_variations['original'] = $public_path.'/'.$file_path; |
||
296 | $image_variations['thumb'] = $public_path.'/'.$file_path; |
||
297 | } |
||
298 | |||
299 | // 3. Save the complete path to the database |
||
300 | $this->attributes[$attribute_name] = $image_variations['original']; |
||
301 | } elseif (starts_with($value, 'data:image')) { |
||
302 | $img = \Intervention\Image\ImageManagerStatic::make($value); |
||
303 | $new_file_name = md5($value.time()); |
||
304 | |||
305 | if (! \Illuminate\Support\Facades\File::exists($disk_root.'/'.trim($destination_path, '/'))) { |
||
306 | \Illuminate\Support\Facades\File::makeDirectory($disk_root.'/'.trim($destination_path, '/'), 0775, true); |
||
307 | } |
||
308 | |||
309 | foreach ($variations as $variant => $dimensions) { |
||
310 | switch ($img->mime()) { |
||
311 | case 'image/bmp': |
||
312 | case 'image/ief': |
||
313 | case 'image/jpeg': |
||
314 | case 'image/pipeg': |
||
315 | case 'image/tiff': |
||
316 | case 'image/x-jps': |
||
317 | $extension = '.jpg'; |
||
318 | break; |
||
319 | case 'image/gif': |
||
320 | $extension = '.gif'; |
||
321 | break; |
||
322 | case 'image/x-icon': |
||
323 | case 'image/png': |
||
324 | $extension = '.png'; |
||
325 | break; |
||
326 | default: |
||
327 | $extension = '.jpg'; |
||
328 | break; |
||
329 | } |
||
330 | |||
331 | $variant_name = $new_file_name.'-'.$variant.$extension; |
||
332 | $variant_file = $destination_path.'/'.$variant_name; |
||
333 | |||
334 | View Code Duplication | if ($dimensions) { |
|
335 | $width = $dimensions[0]; |
||
336 | $height = $dimensions[1]; |
||
337 | |||
338 | if ($img->width() > $width || $img->height() > $height) { |
||
339 | $img->resize($width, $height, function ($constraint) { |
||
340 | $constraint->aspectRatio(); |
||
341 | }) |
||
342 | ->save($disk_root.'/'.$variant_file); |
||
343 | } else { |
||
344 | $img->save($disk_root.'/'.$variant_file); |
||
345 | } |
||
346 | |||
347 | $image_variations[$variant] = $public_path.'/'.$variant_file; |
||
348 | } else { |
||
349 | $img->save($disk_root.'/'.$variant_file); |
||
350 | $image_variations['original'] = $variant_file; |
||
351 | } |
||
352 | } |
||
353 | |||
354 | $this->attributes[$attribute_name] = $image_variations['original']; |
||
355 | } |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Handles the retrieval of an image by variant:. |
||
360 | * |
||
361 | * @param [type] $attribute Name of the attribute within the model that contains the json |
||
362 | * @param [type] $variant Name of the variant you want to extract |
||
363 | * @param [type] $disk Filesystem disk used to store files. |
||
364 | */ |
||
365 | public function getUploadedImageFromDisk($attribute, $variant = 'original', $disk = null) |
||
399 | } |
||
400 |
This check marks parameter names that have not been written in camelCase.
In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes
databaseConnectionString
.