GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

WebserverSkeleton::processConfigFiles()   C
last analyzed

Complexity

Conditions 8
Paths 21

Size

Total Lines 36
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 36
rs 5.3846
cc 8
eloc 25
nc 21
nop 2
1
<?php
2
namespace Kunstmaan\Skylab\Skeleton;
3
4
use Kunstmaan\Skylab\Exceptions\SkylabException;
5
use Symfony\Component\Finder\Finder;
6
use Symfony\Component\Finder\SplFileInfo;
7
8
/**
9
 * ApacheSkeleton
10
 */
11
class WebserverSkeleton extends AbstractSkeleton
12
{
13
14
    const NAME = "apache";
15
16
    /**
17
     * @param \ArrayObject $project
18
     *
19
     * @return mixed
20
     */
21
    public function create(\ArrayObject $project)
22
    {
23
        $this->handleAliases($project, $aliases);
24
        // nginx
25
        $this->prepareNginxDirectories($project);
26
        $this->fileSystemProvider->renderConfig($this->fileSystemProvider->getNginxConfigTemplateDir(),$this->fileSystemProvider->getNginxConfigTemplateDir(true),$this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/nginx.d/");
27
        // apache
28
        $this->prepareApacheDirectories($project);
29
        $this->fileSystemProvider->renderDistConfig($this->fileSystemProvider->getApacheConfigTemplateDir(),$this->fileSystemProvider->getApacheConfigTemplateDir(true),$this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d/");
30
    }
31
32
    /**
33
     * @return mixed
34
     */
35
    public function preMaintenance()
36
    {
37
        if ($this->isWebserverNginx()) {
38
            $this->processProvider->executeSudoCommand("rm -Rf " . $this->app["config"]["nginx"]["sitesavailable"] . "/*");
39
            $this->processProvider->executeSudoCommand("rm -Rf " . $this->app["config"]["nginx"]["sitesenabled"] . "/*");
40
        } else {
41
            $this->processProvider->executeSudoCommand("rm -Rf " . $this->app["config"]["apache"]["sitesavailable"] . "/*");
42
            $this->processProvider->executeSudoCommand("rm -Rf " . $this->app["config"]["apache"]["sitesenabled"] . "/*");
43
        }
44
    }
45
46
    /**
47
     * @param \ArrayObject $project
48
     *
49
     * @return mixed
50
     */
51
    public function maintenance(\ArrayObject $project)
52
    {
53
        if ($this->app["config"]["develmode"] || !file_exists($this->fileSystemProvider->getProjectDirectory($project["name"]) . "/data/current")) {
54
            if (!is_dir($this->fileSystemProvider->getProjectDirectory($project["name"]) . "/data/current")){
55
                $this->processProvider->executeSudoCommand("rm -f " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/data/current");
56
                $this->processProvider->executeSudoCommand("ln -sf " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/data/" . $project["name"] . "/ " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/data/current");
57
            }
58
        }
59
60 View Code Duplication
        if (PHP_OS == "Darwin") {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
61
            $this->processProvider->executeSudoCommand('find ' . $this->fileSystemProvider->getProjectDirectory($project["name"]) . '/data/current -type d -name .git -exec cd {} "\;" -exec git config core.filemode false "\;"');
62
        } else {
63
            $this->processProvider->executeSudoCommand('find ' . $this->fileSystemProvider->getProjectDirectory($project["name"]) . '/data/current -type d -name .git -exec cd {} \; -exec git config core.filemode false \;');
64
        }
65
66
        $this->dialogProvider->logConfig("Updating aliases webserver config file");
67
        $this->generateBasicAliases($project, $aliases);
68
69
        if ($this->isWebserverNginx()) {
70
            $this->maintenanceNginx($project, $aliases);
71
        } else {
72
            $this->maintenanceApache($project, $aliases);
73
        }
74
    }
75
76
    /**
77
     * @return mixed
78
     */
79
    public function postMaintenance()
80
    {
81
        $this->writeToHostFile();
82
        if ($this->isWebserverNginx()) {
83
            $finder = new Finder();
84
            $finder->files()->in($this->app["config"]["nginx"]["sitesavailable"])->name("*.conf");
85
            /** @var SplFileInfo $config */
86 View Code Duplication
            foreach ($finder as $config) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
87
                $this->processProvider->executeSudoCommand("ln -sf " . $this->app["config"]["nginx"]["sitesavailable"] . "/" . $config->getFilename() . " " . $this->app["config"]["nginx"]["sitesenabled"] . "/" . $config->getFilename());
88
            }
89
        } else {
90
            $this->writeToFirstHostFile();
91
            $finder = new Finder();
92
            $finder->files()->in($this->app["config"]["apache"]["sitesavailable"])->name("*.conf");
93
            /** @var SplFileInfo $config */
94 View Code Duplication
            foreach ($finder as $config) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
95
                $this->processProvider->executeSudoCommand("ln -sf " . $this->app["config"]["apache"]["sitesavailable"] . "/" . $config->getFilename() . " " . $this->app["config"]["apache"]["sitesenabled"] . "/" . $config->getFilename());
96
            }
97
        }
98
    }
99
100
    private function writeToFirstHostFile()
101
    {
102
        $this->fileSystemProvider->render("/apache/000firsthost.conf.twig", $this->app["config"]["apache"]["sitesavailable"] . "/000firsthost.conf", array(
103
            'admin' => $this->app["config"]["apache"]["admin"]
104
        ));
105
    }
106
107
    private function writeToHostFile()
108
    {
109
        $hostlines = array();
110
        $dialogProvider = $this->dialogProvider;
111
        $this->fileSystemProvider->projectsLoop(function ($project) use (&$hostlines, $dialogProvider) {
112
            $hostlines[] = $this->app["config"]["webserver"]["localip"] . " " . $project["name"] . "." . $this->app["config"]["webserver"]["hostmachine"] . " www." . $project["name"] . "." . $this->app["config"]["webserver"]["hostmachine"] . "\n";
113
        });
114
        $this->dialogProvider->logTask("Updating the /etc/hosts file (add lines)");
115
        $hostsfile = file("/etc/hosts");
116
        $resultLines = array();
117
        $foundSection = false;
118
        $inSection = false;
119
        foreach ($hostsfile as $line) {
120
            if (!$inSection) {
121
                if (strpos($line, "#KDEPLOY_start") === 0) {
122
                    $inSection = true;
123
                    $foundSection = true;
124
                    $resultLines[] = $line;
125
                    $resultLines = array_merge($resultLines, $hostlines);
126
                } else {
127
                    $resultLines[] = $line;
128
                }
129
            } else {
130
                if (strpos($line, "#KDEPLOY_end") === 0) {
131
                    $inSection = false;
132
                    $resultLines[] = $line;
133
                }
134
            }
135
        }
136
        if (!$foundSection) {
137
            $resultLines[] = "#KDEPLOY_start autogenerated section. do not edit below this line. do not remove this line.\n";
138
            $resultLines = array_merge($resultLines, $hostlines);
139
            $resultLines[] = "#KDEPLOY_end autogenerated section. do not edit above this line. do not remove this line.\n";
140
        }
141
        $this->fileSystemProvider->writeProtectedFile("/etc/hosts", implode("", $resultLines));
142
    }
143
144
    /**
145
     * @param \ArrayObject $project
146
     */
147
    private function removeFromHostFile(\ArrayObject $project)
148
    {
149
150
        $hostlines[] = $this->app["config"]["webserver"]["localip"] . " " . $project["name"] . "." . $this->app["config"]["webserver"]["hostmachine"] . " www." . $project["name"] . "." . $this->app["config"]["webserver"]["hostmachine"] . "\n";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$hostlines was never initialized. Although not strictly required by PHP, it is generally a good practice to add $hostlines = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
151
152
        $this->dialogProvider->logTask("Updating the /etc/hosts file (remove lines)");
153
        $hostsfile = file("/etc/hosts");
154
        $resultLines = array();
155
156
        foreach ($hostsfile as $line) {
157
            if (!in_array($line, $hostlines)) {
158
                $resultLines[] = $line;
159
            }
160
        }
161
162
        $this->fileSystemProvider->writeProtectedFile("/etc/hosts", implode("", $resultLines));
163
    }
164
165
    /**
166
     * @return string
167
     */
168
    public function getName()
169
    {
170
        return self::NAME;
171
    }
172
173
    /**
174
     * @param \ArrayObject $project
175
     *
176
     * @return mixed
177
     */
178
    public function preBackup(\ArrayObject $project)
179
    {
180
    }
181
182
    /**
183
     * @param \ArrayObject $project
184
     *
185
     * @return mixed
186
     */
187
    public function postBackup(\ArrayObject $project)
188
    {
189
    }
190
191
    /**
192
     * @param \ArrayObject $project
193
     *
194
     * @return mixed
195
     */
196
    public function preRemove(\ArrayObject $project)
197
    {
198
    }
199
200
    /**
201
     * @param \ArrayObject $project
202
     *
203
     * @return mixed
204
     */
205
    public function postRemove(\ArrayObject $project)
206
    {
207
        $this->removeFromHostFile($project);
208
209
        if ($this->isWebserverNginx()) {
210
            $this->processProvider->executeSudoCommand("rm -f ".$this->app["config"]["nginx"]["sitesenabled"] . "/" . $project["name"] . ".conf");
211
            $this->processProvider->executeSudoCommand("rm -f ".$this->app["config"]["nginx"]["sitesavailable"] . "/" . $project["name"] . ".conf");
212
        }
213
        else{
214
            $this->processProvider->executeSudoCommand("rm -f ".$this->app["config"]["apache"]["sitesenabled"] . "/" . $project["name"] . ".conf");
215
            $this->processProvider->executeSudoCommand("rm -f ".$this->app["config"]["apache"]["sitesavailable"] . "/" . $project["name"] . ".conf");
216
        }
217
218
        if (PHP_OS == "Darwin") {
219
            $this->processProvider->executeSudoCommand("apachectl -k restart");
220
        }
221
        else{
222
            if ($this->isWebserverNginx()) {
223
                $this->processProvider->executeSudoCommand("service nginx reload");
224
            } else {
225
                $this->processProvider->executeSudoCommand("service apache2 reload");
226
            }
227
        }
228
229
    }
230
231
    /**
232
     * @param  \ArrayObject      $project
233
     * @param  \SimpleXMLElement $config  The configuration array
234
     * @return \SimpleXMLElement
235
     */
236
    public function writeConfig(\ArrayObject $project, \SimpleXMLElement $config)
237
    {
238
        $config = $this->projectConfigProvider->addVar($config, 'project.url', $project["url"]);
239
        if (isset($project["aliases"])) {
240
            $config = $this->projectConfigProvider->addVarWithItems($config, 'project.aliases', $project["aliases"]);
241
        }
242
243
        return $config;
244
    }
245
246
    /**
247
     * @return string[]
248
     */
249
    public function dependsOn()
250
    {
251
        return array("base");
252
    }
253
254
    /**
255
     * @param \ArrayObject $project
256
     */
257
    private function prepareNginxDirectories(\ArrayObject $project)
258
    {
259
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->app["config"]["nginx"]["sitesavailable"]);
260
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->app["config"]["nginx"]["sitesenabled"]);
261
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/apachelogs");
262
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/nginx.d");
263
    }
264
265
    /**
266
     * @param \ArrayObject $project
267
     */
268
    public function prepareApacheDirectories(\ArrayObject $project)
269
    {
270
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->app["config"]["apache"]["vhostdir"]);
271
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/apachelogs");
272
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d");
273
        $this->processProvider->executeSudoCommand("mkdir -p " . $this->fileSystemProvider->getProjectDirectory($project["name"]) . "/stats");
274
        $this->processProvider->executeSudoCommand("chmod -R 777 " . $this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d/");
275
    }
276
277
    /**
278
     * @param \ArrayObject $project
279
     * @param $aliases
280
     */
281
    private function handleAliases(\ArrayObject &$project, &$aliases)
282
    {
283
        // url
284
        $defaultUrl = $project["name"] . ".be";
285
        $project["url"] = $this->dialogProvider->askFor("Enter the base url", null, $defaultUrl);
286
        // url aliases
287
        $this->generateBasicAliases($project, $aliases);
288
        $aliases = array();
289
        if ($this->noInteraction) {
290
            $this->dialogProvider->logNotice("--no-iteraction selected, using www." . $project["url"]);
291
            $aliases[] = "www." . $project["url"];
292
        } else {
293
            while (1 == 1) {
294
                $alias = $this->dialogProvider->askFor("Add an url alias (leave empty to stop adding):");
295
                if (empty($alias)) {
296
                    break;
297
                } else {
298
                    $aliases[] = $alias;
299
                }
300
            }
301
        }
302
        $project["aliases"] = $aliases;
303
    }
304
305
    /**
306
     * @param \ArrayObject $project
307
     * @param $aliases
308
     */
309
    private function generateBasicAliases(\ArrayObject &$project, &$aliases)
310
    {
311
        $hostmachine = $this->app["config"]["webserver"]["hostmachine"];
312
        $aliases = (isset($project["aliases"])) ? $project["aliases"] : array();
313
        $aliases[] = $project["url"];
314
        $aliases[] = $project["name"] . "." . $hostmachine;
315
        $aliases[] = "*." . $project["name"] . "." . $hostmachine;
316
        if ($this->app["config"]["develmode"]) {
317
            $aliases[] = $project["name"] . ".*.xip.io";
318
            $aliases[] = "*." . $project["name"] . ".*.xip.io";
319
        }
320
    }
321
322
    /**
323
     * @param \ArrayObject $project
324
     * @return string
325
     */
326
    private function processConfigFiles(\ArrayObject $project, $configs)
327
    {
328
        $ignoreList = array();
329
        foreach ($configs as $config) {
330
            /** @var SplFileInfo $config */
331
            if ($config->getExtension() == "local") {
332
                $ignoreList[] = $config->getBasename('.' . $config->getExtension());
333
            }
334
        }
335
336
        $configcontent = '';
337
        foreach ($configs as $config) {
338
            /** @var SplFileInfo $config */
339
            if ($config->getExtension() == "dist" ){
340
                $realPathArray = explode("\n", file_get_contents($config->getRealPath()));
341
                $realPath = $realPathArray[0];
342
                $path = BASE_DIR . "/templates" . $realPath;
343
                if (!file_exists($path)){
344
                    $this->dialogProvider->logError("There is Apache config in a .dist file, or you mistyped the template path, check " . $config);
345
                }
346
                $content = $this->fileSystemProvider->renderString(file_get_contents($path), array());
347
            } else {
348
                $realPath = $config->getRealPath();
349
                $content = file_get_contents($realPath);
350
            }
351
            if ($config->getExtension() != "local" && in_array($config->getBasename('.'. $config->getExtension()),$ignoreList)){
352
                $configcontent .= "\n#SKIPPED " . $realPath . " because there was a .local file\n\n";
353
            } else {
354
                $configcontent .= "\n#BEGIN " . $realPath . "\n\n";
355
                $configcontent .= $this->projectConfigProvider->searchReplacer($content, $project) . "\n";
356
                $configcontent .= "\n#END " . $realPath . "\n\n";
357
            }
358
            $this->checkObviousErrors($project, $config, $configcontent);
359
        }
360
        return $configcontent;
361
    }
362
363
    /**
364
     * @param \ArrayObject $project
365
     * @param SplFileInfo $config
366
     * @param string $content
367
     */
368
    function checkObviousErrors(\ArrayObject $project, SplFileInfo $config, $content){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
369
        // project was not migrated because the 19php.conf file does not contain "proxy:unix:/var/run/php5-fpm"
370
        if (!$this->app["config"]["develmode"] && strpos($config->getFilename(), "19php") !== FALSE && strpos($content, "proxy:unix:/var/run/php-fpm") === FALSE){
371
            $this->dialogProvider->logWarning("The ".$project["name"]." project was not migrated yet, this will NOT work");
372
        }
373
    }
374
375
    /**
376
     * @param $aliases
377
     * @return string
378
     */
379
    private function generateAliasLine($aliases, $type)
380
    {
381
        $serverName = ($type == 'nginx'?"server_name ":"ServerAlias ");
382
        foreach ($aliases as $alias) {
383
            $serverName .= " " . $alias;
384
        }
385
        $serverName .= ($type == 'nginx'?";\n":"\n");
386
        return $serverName;
387
    }
388
389
    /**
390
     * @param \ArrayObject $project
391
     * @param $aliases
392
     */
393
    public function maintenanceNginx(\ArrayObject $project, $aliases)
394
    {
395
        $this->prepareNginxDirectories($project);
396
        $serverName = $this->generateAliasLine($aliases, $this->app["config"]["webserver"]["engine"]);
397
        $this->processProvider->executeSudoCommand("rm -f " . $this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/nginx.d/05servername*");
398
        $finder = new Finder();
399
        $finder->files()->in($this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/nginx.d/")->name("01-base*");
400
        if ($finder->count() == 0) {
401
            $this->fileSystemProvider->writeProtectedFile($this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/nginx.d/05servername", $serverName);
402
        }
403
        $configcontent = $this->processConfigFiles($project, $this->fileSystemProvider->getProjectNginxConfigs($project));
404
        $this->fileSystemProvider->writeProtectedFile($this->app["config"]["nginx"]["sitesavailable"] . "/" . $project["name"] . ".conf", $configcontent);
405
    }
406
407
    /**
408
     * @param \ArrayObject $project
409
     * @param $aliases
410
     */
411
    private function maintenanceApache(\ArrayObject $project, $aliases)
412
    {
413
        $serverAlias = $this->generateAliasLine($aliases, $this->app["config"]["webserver"]["engine"]);
414
        $this->fileSystemProvider->writeProtectedFile($this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d/05aliases", $serverAlias);
415
        if ($this->app["config"]["develmode"]) {
416
            $this->fileSystemProvider->writeProtectedFile($this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d/06devmode", "SetEnv APP_ENV dev");
417
        } else {
418
            $this->processProvider->executeSudoCommand("rm -f " . $this->fileSystemProvider->getProjectConfigDirectory($project["name"]) . "/apache.d/06devmode");
419
        }
420
        $configcontent = $this->processConfigFiles($project, $this->fileSystemProvider->getProjectApacheConfigs($project));
421
        if ($this->app["config"]["develmode"]) {
422
            $configcontent = str_replace("-Indexes", "+Indexes", $configcontent);
423
        }
424
        $this->fileSystemProvider->writeProtectedFile($this->app["config"]["apache"]["sitesavailable"] . "/" . $project["name"] . ".conf", $configcontent);
425
    }
426
427
    /**
428
     * @return bool
429
     */
430
    private function isWebserverNginx()
431
    {
432
        return $this->app["config"]["webserver"]["engine"] == 'nginx';
433
    }
434
435
}
436