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 |
||
12 | class FileSystemProvider extends AbstractProvider |
||
13 | { |
||
14 | |||
15 | /** |
||
16 | * Registers services on the given app. |
||
17 | * |
||
18 | * @param Application $app An Application instance |
||
19 | */ |
||
20 | public function register(Application $app) |
||
21 | { |
||
22 | $app['filesystem'] = $this; |
||
23 | $this->app = $app; |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * @return SplFileInfo[] |
||
28 | */ |
||
29 | public function getProjects() |
||
30 | { |
||
31 | $finder = new Finder(); |
||
32 | $finder |
||
33 | ->directories() |
||
34 | ->sortByName() |
||
35 | ->in($this->app["config"]["projects"]["path"]) |
||
36 | ->depth('== 0') |
||
37 | ->filter(function (\SplFileInfo $file) { |
||
38 | return file_exists($file->getRealPath() . "/conf/config.xml"); |
||
39 | }); |
||
40 | |||
41 | return iterator_to_array($finder); |
||
42 | } |
||
43 | |||
44 | /** |
||
45 | * @param string $path |
||
46 | * @return SplFileInfo[] |
||
47 | */ |
||
48 | public function getDotDFiles($path) |
||
49 | { |
||
50 | $finder = new Finder(); |
||
51 | $finder->files()->sortByName()->in($path)->depth('== 0'); |
||
52 | |||
53 | return iterator_to_array($finder); |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * @param string $projectname |
||
58 | * @return bool |
||
59 | */ |
||
60 | public function projectExists($projectname) |
||
61 | { |
||
62 | $finder = new Finder(); |
||
63 | $finder->directories()->sortByName()->in($this->app["config"]["projects"]["path"])->depth('== 0')->name($projectname); |
||
64 | |||
65 | return $finder->count() != 0; |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * @param string $projectname |
||
70 | * |
||
71 | * @return string |
||
72 | */ |
||
73 | public function getProjectConfigDirectory($projectname) |
||
74 | { |
||
75 | return $this->getProjectDirectory($projectname) . "/conf"; |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * @param string $projectname |
||
80 | * |
||
81 | * @return string |
||
82 | */ |
||
83 | public function getProjectDirectory($projectname) |
||
84 | { |
||
85 | return $this->app["config"]["projects"]["path"] . '/' . $projectname; |
||
86 | } |
||
87 | |||
88 | /** |
||
89 | * @param string $projectname The project name |
||
90 | */ |
||
91 | public function createProjectDirectory($projectname) |
||
92 | { |
||
93 | $projectDirectory = $this->getProjectDirectory($projectname); |
||
94 | $this->processProvider->executeSudoCommand('mkdir -p ' . $projectDirectory); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @param \ArrayObject $project The project |
||
99 | * @param string $path The relative path in the project folder |
||
100 | */ |
||
101 | public function createDirectory(\ArrayObject $project, $path) |
||
102 | { |
||
103 | $projectDirectory = $this->getProjectDirectory($project["name"]); |
||
104 | $this->processProvider->executeSudoCommand('mkdir -p ' . $projectDirectory . '/' . $path); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * @param \ArrayObject $project The project |
||
109 | * @param string $path The relative path in the project folder |
||
110 | * |
||
111 | * @return string |
||
112 | */ |
||
113 | public function getDirectory(\ArrayObject $project, $path) |
||
114 | { |
||
115 | $projectDirectory = $this->getProjectDirectory($project["name"]); |
||
116 | |||
117 | return $projectDirectory . '/' . $path; |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * @param \ArrayObject $project The project |
||
122 | */ |
||
123 | public function runTar(\ArrayObject $project) |
||
124 | { |
||
125 | $this->processProvider->executeSudoCommand('mkdir -p ' . $this->app["config"]["projects"]["backuppath"]); |
||
126 | $projectDirectory = $this->getProjectDirectory($project["name"]); |
||
127 | $excluded = ''; |
||
128 | foreach ($project["backupexcludes"] as $backupexclude) { |
||
129 | $excluded = $excluded . " --exclude='" . $backupexclude . "'"; |
||
130 | } |
||
131 | $this->processProvider->executeSudoCommand('nice -n 19 tar --create --absolute-names ' . $excluded . ' --file ' . $this->app["config"]["projects"]["backuppath"] . '/' . $project["name"] . '.tar.gz --totals --gzip ' . $projectDirectory . '/ 2>&1'); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * @param \ArrayObject $project The project |
||
136 | */ |
||
137 | public function removeProjectDirectory(\ArrayObject $project) |
||
138 | { |
||
139 | if (empty($project["dir"])) { |
||
140 | throw new RuntimeException("The project has no name"); |
||
141 | } |
||
142 | $projectDirectory = $this->getProjectDirectory($project["name"]); |
||
143 | $this->processProvider->executeSudoCommand("rm -Rf " . $projectDirectory); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * @return string |
||
148 | */ |
||
149 | public function getApacheConfigTemplateDir($clean = false) |
||
150 | { |
||
151 | return $this->getConfigTemplateDir("apache", $clean); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @return string |
||
156 | */ |
||
157 | public function getConfigTemplateDir($skeletonName, $clean = false) |
||
158 | { |
||
159 | return ($clean ? "/" . $skeletonName . "/apache.d/" : BASE_DIR . "/templates/" . $skeletonName . "/apache.d/"); |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * @return string |
||
164 | */ |
||
165 | public function getCustomConfigTemplateDir($skeletonName, $clean = false) |
||
166 | { |
||
167 | return ($clean ? "/" . $skeletonName . "/custom.d/" : BASE_DIR . "/templates/" . $skeletonName . "/custom.d/"); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @return string |
||
172 | */ |
||
173 | public function getNginxConfigTemplateDir($clean = false) |
||
174 | { |
||
175 | return ($clean ? "/nginx/nginx.d/" : BASE_DIR . "/templates/nginx/nginx.d/"); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * @param \Closure $callback |
||
180 | */ |
||
181 | public function projectsLoop($callback) |
||
182 | { |
||
183 | $projects = $this->getProjects(); |
||
184 | foreach ($projects as $projectFile) { |
||
185 | /** @var $projectFile SplFileInfo */ |
||
186 | $projectname = $projectFile->getFilename(); |
||
187 | $project = $this->projectConfigProvider->loadProjectConfig($projectname); |
||
188 | $callback($project); |
||
189 | } |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * @param \ArrayObject $project |
||
194 | * @return array |
||
195 | */ |
||
196 | View Code Duplication | public function getProjectApacheConfigs(\ArrayObject $project) |
|
|
|||
197 | { |
||
198 | $finder = new Finder(); |
||
199 | $finder->files() |
||
200 | ->sortByName() |
||
201 | ->in($this->getProjectConfigDirectory($project["name"]) . "/apache.d/") |
||
202 | ->ignoreVCS(true) |
||
203 | ->ignoreDotFiles(true) |
||
204 | ->notName("*~") |
||
205 | ->notName("*.swp") |
||
206 | ->notName("*.bak") |
||
207 | ->notName("*-") |
||
208 | ->depth('== 0'); |
||
209 | |||
210 | return iterator_to_array($finder); |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * @param \ArrayObject $project |
||
215 | * @return array |
||
216 | */ |
||
217 | View Code Duplication | public function getProjectNginxConfigs(\ArrayObject $project) |
|
218 | { |
||
219 | $finder = new Finder(); |
||
220 | $finder->files() |
||
221 | ->sortByName() |
||
222 | ->in($this->getProjectConfigDirectory($project["name"]) . "/nginx.d/") |
||
223 | ->ignoreVCS(true) |
||
224 | ->ignoreDotFiles(true) |
||
225 | ->notName("*~") |
||
226 | ->notName("*.swp") |
||
227 | ->notName("*.bak") |
||
228 | ->notName("*-") |
||
229 | ->depth('== 0'); |
||
230 | |||
231 | return iterator_to_array($finder); |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * @param $path |
||
236 | * @param $content |
||
237 | */ |
||
238 | public function writeProtectedFile($path, $content, $append=false) |
||
245 | |||
246 | /** |
||
247 | * @param string $sourcePath |
||
248 | * @param string $destinationPath |
||
249 | * @param string[] $variables |
||
250 | */ |
||
251 | public function render($sourcePath, $destinationPath, $variables = array()) |
||
252 | { |
||
253 | $this->dialogProvider->logConfig("Rendering " . $sourcePath . " to " . $destinationPath); |
||
254 | $this->processProvider->executeSudoCommand('mkdir -p ' . dirname($destinationPath)); |
||
255 | $content = $this->renderString(file_get_contents(BASE_DIR . "/templates" . $sourcePath), $variables); |
||
256 | $this->writeProtectedFile($destinationPath, $content); |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * @param string $sourcePath |
||
261 | * @param string $destinationPath |
||
262 | * @param string[] $variables |
||
263 | */ |
||
264 | public function renderDist($sourcePath, $destinationPath) |
||
270 | |||
271 | /** |
||
272 | * @param $content |
||
273 | * @param $variables |
||
274 | * @return string |
||
275 | */ |
||
276 | public function renderString($content, $variables) |
||
280 | |||
281 | /** |
||
282 | * @param $cleanedLocation |
||
283 | * @param $target |
||
284 | * @param SplFileInfo $config |
||
285 | */ |
||
286 | public function renderSingleConfig($cleanedLocation, $target, $config) |
||
293 | |||
294 | /** |
||
295 | * @param $cleanedLocation |
||
296 | * @param $target |
||
297 | * @param SplFileInfo $config |
||
298 | */ |
||
299 | public function renderSingleDistConfig($cleanedLocation, $target, $config) |
||
306 | |||
307 | /** |
||
308 | * @param $location |
||
309 | * @param $cleanedLocation |
||
310 | * @param $target |
||
311 | */ |
||
312 | View Code Duplication | public function renderConfig($location, $cleanedLocation, $target) |
|
321 | |||
322 | /** |
||
323 | * @param $location |
||
324 | * @param $cleanedLocation |
||
325 | * @param $target |
||
326 | */ |
||
327 | View Code Duplication | public function renderDistConfig($location, $cleanedLocation, $target) |
|
336 | } |
||
337 |
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.