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 namespace Wn\Generators\Commands; |
||
| 4 | class ModelCommand extends BaseCommand { |
||
| 5 | |||
| 6 | protected $signature = 'wn:model |
||
| 7 | {name : Name of the model.} |
||
| 8 | {--fillable= : the fillable fields.} |
||
| 9 | {--guarded= : the guarded fields.} |
||
| 10 | {--dates= : date fields.} |
||
| 11 | {--has-many= : hasMany relationships.} |
||
| 12 | {--has-one= : hasOne relationships.} |
||
| 13 | {--belongs-to= : belongsTo relationships.} |
||
| 14 | {--belongs-to-many= : belongsToMany relationships.} |
||
| 15 | {--images= : images to be associated with model} |
||
| 16 | {--rules= : fields validation rules.} |
||
| 17 | {--path=app : where to store the model php file.} |
||
| 18 | {--soft-deletes= : adds SoftDeletes trait to the model.} |
||
| 19 | {--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options} |
||
| 20 | {--force= : override the existing files} |
||
| 21 | '; |
||
| 22 | |||
| 23 | protected $description = 'Generates a model class for a RESTfull resource'; |
||
| 24 | |||
| 25 | public function handle() |
||
| 26 | { |
||
| 27 | $name = $this->argument('name'); |
||
| 28 | $path = $this->option('path'); |
||
|
|
|||
| 29 | |||
| 30 | $content = $this->getTemplate('model') |
||
| 31 | ->with([ |
||
| 32 | 'name' => $name, |
||
| 33 | 'namespace' => $this->getNamespace(), |
||
| 34 | 'fillable' => $this->getAsArrayFields('fillable'), |
||
| 35 | 'guarded' => $this->getAsArrayFields('guarded'), |
||
| 36 | 'dates' => $this->getAsArrayFields('dates'), |
||
| 37 | 'relations' => $this->getRelations(), |
||
| 38 | 'images' => $this->getImages('images'), |
||
| 39 | 'appends' => $this->getAsArrayFields('images'), |
||
| 40 | 'rules' => $this->getRules(), |
||
| 41 | 'uses' => $this->getUses() |
||
| 42 | ]) |
||
| 43 | ->get(); |
||
| 44 | |||
| 45 | $this->save($content, "./App/Models/{$name}.php", "{$name} model"); |
||
| 46 | } |
||
| 47 | |||
| 48 | protected function getAsArrayFields($arg, $isOption = true) |
||
| 49 | { |
||
| 50 | $arg = ($isOption) ? $this->option($arg) : $this->argument($arg); |
||
| 51 | if(is_string($arg)){ |
||
| 52 | $arg = explode(',', $arg); |
||
| 53 | } else if(! is_array($arg)) { |
||
| 54 | $arg = []; |
||
| 55 | } |
||
| 56 | return implode(', ', array_map(function($item){ |
||
| 57 | return '"' . $item . '"'; |
||
| 58 | }, $arg)); |
||
| 59 | } |
||
| 60 | |||
| 61 | protected function getNamespace() |
||
| 62 | { |
||
| 63 | return str_replace(' ', '\\', ucwords(str_replace('/', ' ', $this->option('path')))); |
||
| 64 | } |
||
| 65 | |||
| 66 | protected function getRelations() |
||
| 67 | { |
||
| 68 | $relations = array_merge([], |
||
| 69 | $this->getRelationsByType('hasOne', 'has-one'), |
||
| 70 | $this->getRelationsByType('hasMany', 'has-many'), |
||
| 71 | $this->getRelationsByType('belongsTo', 'belongs-to'), |
||
| 72 | $this->getRelationsByType('belongsToMany', 'belongs-to-many', true) |
||
| 73 | ); |
||
| 74 | |||
| 75 | if(empty($relations)){ |
||
| 76 | return " // Relationships"; |
||
| 77 | } |
||
| 78 | |||
| 79 | return implode(PHP_EOL, $relations); |
||
| 80 | } |
||
| 81 | |||
| 82 | protected function getImages($option) |
||
| 83 | { |
||
| 84 | $images = []; |
||
| 85 | $option = $this->option($option); |
||
| 86 | if($option){ |
||
| 87 | |||
| 88 | $items = $this->getArgumentParser('images')->parse($option); |
||
| 89 | |||
| 90 | $template = 'model/image'; |
||
| 91 | $template = $this->getTemplate($template); |
||
| 92 | foreach ($items as $item) { |
||
| 93 | if(! $item['image']){ |
||
| 94 | $item['image'] = "get" . str_replace(' ', '', ucwords(str_replace('_', ' ', $item['name']))) . "Attribute"; |
||
| 95 | } |
||
| 96 | $images[] = $template->with($item)->get(); |
||
| 97 | } |
||
| 98 | } |
||
| 99 | |||
| 100 | $media = array_merge([], $images); |
||
| 101 | |||
| 102 | if(empty($media)){ |
||
| 103 | return " // Media methods"; |
||
| 104 | } |
||
| 105 | |||
| 106 | return implode(PHP_EOL, $media); |
||
| 107 | } |
||
| 108 | |||
| 109 | protected function getRelationsByType($type, $option, $withTimestamps = false) |
||
| 110 | { |
||
| 111 | $relations = []; |
||
| 112 | $option = $this->option($option); |
||
| 113 | if($option){ |
||
| 114 | |||
| 115 | $items = $this->getArgumentParser('relations')->parse($option); |
||
| 116 | |||
| 117 | $template = ($withTimestamps) ? 'model/relation-with-timestamps' : 'model/relation'; |
||
| 118 | $template = $this->getTemplate($template); |
||
| 119 | foreach ($items as $item) { |
||
| 120 | $item['type'] = $type; |
||
| 121 | if(! $item['model']){ |
||
| 122 | $item['model'] = $this->getNamespace() . '\\' . ucwords(\Illuminate\Support\Str::singular($item['name'])); |
||
| 123 | } else if(strpos($item['model'], '\\') === false ){ |
||
| 124 | $item['model'] = $this->getNamespace() . '\\' . $item['model']; |
||
| 125 | } |
||
| 126 | $relations[] = $template->with($item)->get(); |
||
| 127 | } |
||
| 128 | } |
||
| 129 | return $relations; |
||
| 130 | } |
||
| 131 | |||
| 132 | View Code Duplication | protected function getRules() |
|
| 133 | { |
||
| 134 | $rules = $this->option('rules'); |
||
| 135 | if(! $rules){ |
||
| 136 | return " // Validation rules"; |
||
| 137 | } |
||
| 138 | $items = $rules; |
||
| 139 | if(! $this->option('parsed')){ |
||
| 140 | $items = $this->getArgumentParser('rules')->parse($rules); |
||
| 141 | } |
||
| 142 | $rules = []; |
||
| 143 | $template = $this->getTemplate('model/rule'); |
||
| 144 | foreach ($items as $item) { |
||
| 145 | $rules[] = $template->with($item)->get(); |
||
| 146 | } |
||
| 147 | |||
| 148 | return implode(PHP_EOL, $rules); |
||
| 149 | } |
||
| 150 | |||
| 151 | protected function getUses() |
||
| 157 | |||
| 158 | } |
||
| 159 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.