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 |
||
21 | class Renamer extends Command |
||
22 | { |
||
23 | /** |
||
24 | * {@inheritdoc} |
||
25 | */ |
||
26 | protected $signature = 'app:rename {name? : The new name}'; |
||
27 | |||
28 | /** |
||
29 | * {@inheritdoc} |
||
30 | */ |
||
31 | protected $description = 'Perform an application rename'; |
||
32 | |||
33 | /** |
||
34 | * {@inheritdoc} |
||
35 | */ |
||
36 | 1 | public function handle(): void |
|
42 | |||
43 | /** |
||
44 | * Updates the binary name and the application |
||
45 | * name on the composer.json. |
||
46 | * |
||
47 | * @return $this |
||
48 | */ |
||
49 | 1 | protected function rename(): Renamer |
|
61 | |||
62 | /** |
||
63 | * Asks for the application name. |
||
64 | * |
||
65 | * If there is no interaction, we take the folder basename. |
||
66 | * |
||
67 | * @return string |
||
68 | */ |
||
69 | 1 | protected function asksForApplicationName(): string |
|
81 | |||
82 | /** |
||
83 | * Update composer json with related information. |
||
84 | * |
||
85 | * @param string $name |
||
86 | * |
||
87 | * @return $this |
||
88 | */ |
||
89 | 1 | protected function updateComposer(string $name): Renamer |
|
90 | { |
||
91 | 1 | $this->task( |
|
|
|||
92 | 1 | 'Updating config/app.php "name" property', |
|
93 | View Code Duplication | function () use ($name) { |
|
94 | 1 | $neededLine = "'name' => '".Str::ucfirst($this->getCurrentBinaryName())."'"; |
|
95 | |||
96 | 1 | if (Str::contains($contents = $this->getConfig(), $neededLine)) { |
|
97 | 1 | File::put( |
|
98 | 1 | config_path('app.php'), |
|
99 | 1 | Str::replaceFirst( |
|
100 | 1 | $neededLine, |
|
101 | 1 | "'name' => '".Str::ucfirst($name)."'", |
|
102 | 1 | $contents |
|
103 | ) |
||
104 | ); |
||
105 | |||
106 | 1 | return true; |
|
107 | } |
||
108 | |||
109 | return false; |
||
110 | 1 | } |
|
111 | ); |
||
112 | |||
113 | 1 | $this->task( |
|
114 | 1 | 'Updating composer "bin"', |
|
115 | View Code Duplication | function () use ($name) { |
|
116 | 1 | $neededLine = '"bin": ["'.$this->getCurrentBinaryName().'"]'; |
|
117 | |||
118 | 1 | if (Str::contains($contents = $this->getComposer(), $neededLine)) { |
|
119 | 1 | File::put( |
|
120 | 1 | base_path('composer.json'), |
|
121 | 1 | Str::replaceFirst( |
|
122 | 1 | $neededLine, |
|
123 | 1 | '"bin": ["'.$name.'"]', |
|
124 | 1 | $contents |
|
125 | ) |
||
126 | ); |
||
127 | |||
128 | 1 | return true; |
|
129 | } |
||
130 | |||
131 | return false; |
||
132 | 1 | } |
|
133 | ); |
||
134 | |||
135 | 1 | return $this; |
|
136 | } |
||
137 | |||
138 | /** |
||
139 | * Renames the application binary. |
||
140 | * |
||
141 | * @param string $name |
||
142 | * |
||
143 | * @return $this |
||
144 | */ |
||
145 | 1 | protected function renameBinary(string $name): Renamer |
|
146 | { |
||
147 | 1 | $this->task( |
|
148 | 1 | sprintf('Renaming application to "%s"', $name), |
|
149 | function () use ($name) { |
||
150 | 1 | return File::move($this->app->basePath($this->getCurrentBinaryName()), $this->app->basePath($name)); |
|
151 | 1 | } |
|
152 | ); |
||
153 | |||
154 | 1 | return $this; |
|
155 | } |
||
156 | |||
157 | /** |
||
158 | * Returns the current binary name. |
||
159 | * |
||
160 | * @return string |
||
161 | */ |
||
162 | 1 | protected function getCurrentBinaryName(): string |
|
168 | |||
169 | /** |
||
170 | * Get composer file. |
||
171 | * |
||
172 | * @return string |
||
173 | */ |
||
174 | 1 | protected function getComposer(): string |
|
184 | |||
185 | /** |
||
186 | * Get config file. |
||
187 | * |
||
188 | * @return string |
||
189 | */ |
||
190 | 1 | protected function getConfig(): string |
|
200 | } |
||
201 |
If you implement
__call
and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.This is often the case, when
__call
is implemented by a parent class and only the child class knows which methods exist: