Completed
Push — issues ( f063a7 )
by Arnaud
04:03
created

Serve::processCommand()   B

Complexity

Conditions 9
Paths 121

Size

Total Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 63
rs 7.1117
c 0
b 0
f 0
cc 9
nc 121
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of the PHPoole package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace PHPoole\Command;
12
13
use PHPoole\Util\Plateform;
14
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
15
use Symfony\Component\Filesystem\Filesystem;
16
use Symfony\Component\Finder\Finder;
17
use Symfony\Component\Process\Exception\ProcessFailedException;
18
use Symfony\Component\Process\Process;
19
use Yosymfony\ResourceWatcher\Crc32ContentHash;
20
use Yosymfony\ResourceWatcher\ResourceCacheMemory;
21
use Yosymfony\ResourceWatcher\ResourceWatcher;
22
23
class Serve extends AbstractCommand
24
{
25
    /**
26
     * @var bool
27
     */
28
    protected $watch;
29
    /**
30
     * @var bool
31
     */
32
    protected $browser;
33
    /**
34
     * @var Filesystem
35
     */
36
    protected $fileSystem;
37
38
    public function processCommand()
39
    {
40
        $this->watch = $this->getRoute()->getMatchedParam('watch', false);
41
        $this->browser = $this->getRoute()->getMatchedParam('browser', false);
42
        $this->fileSystem = new Filesystem();
43
44
        $this->setUpServer();
45
        $command = sprintf(
46
            'php -S %s:%d -t %s %s',
47
            'localhost',
48
            '8000',
49
            $this->getPath().'/'.$this->getPHPoole()->getConfig()->get('output.dir'),
50
            sprintf('%s/.phpoole/router.php', $this->getPath())
51
        );
52
53
        $this->wlAnnonce(sprintf('Starting server (http://%s:%d)...', 'localhost', '8000'));
54
        $process = new Process($command);
55
        if (!$process->isStarted()) {
56
            // write changes cache
57
            if ($this->watch) {
58
                $finder = new Finder();
59
                $finder->files()
60
                    ->name('*.md')
61
                    ->name('*.twig')
62
                    ->in([
63
                        $this->getPath().'/'.$this->getPHPoole()->getConfig()->get('content.dir'),
64
                        $this->getPath().'/'.$this->getPHPoole()->getConfig()->get('layouts.dir'),
65
                    ]);
66
                if (is_dir($this->getPath().'/'.$this->getPHPoole()->getConfig()->get('themes.dir'))) {
67
                    $finder->in($this->getPath().'/'.$this->getPHPoole()->getConfig()->get('themes.dir'));
68
                }
69
                $hashContent = new Crc32ContentHash();
70
                $resourceCache = new ResourceCacheMemory();
71
                $resourceWatcher = new ResourceWatcher($resourceCache, $finder, $hashContent);
72
                $resourceWatcher->initialize();
73
                $this->fileSystem->dumpFile($this->getPath().'/.phpoole/watch.flag', '');
74
            }
75
            // start server
76
            try {
77
                $process->start();
78
                if ($this->browser) {
79
                    Plateform::openBrowser('http://localhost:8000');
80
                }
81
                while ($process->isRunning()) {
82
                    // watch changes?
83
                    if ($this->watch) {
84
                        $result = $resourceWatcher->findChanges();
0 ignored issues
show
Bug introduced by
The variable $resourceWatcher does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
85
                        if ($result->hasChanges()) {
86
                            // re-generate
87
                            $this->wlAlert('Changes detected!');
88
                            $callable = new Build($this->getRoute(), $this->getConsole());
0 ignored issues
show
Unused Code introduced by
The call to Build::__construct() has too many arguments starting with $this->getRoute().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
89
                            $callable($this->getRoute(), $this->getConsole());
90
                        }
91
                    }
92
                    usleep(1000000); // 1 s
93
                }
94
            } catch (ProcessFailedException $e) {
95
                $this->tearDownServer();
96
                echo $e->getMessage();
97
                exit(2);
98
            }
99
        }
100
    }
101
102
    public function setUpServer()
103
    {
104
        try {
105
            $root = __DIR__.'/../../';
106
            if (Plateform::isPhar()) {
107
                $root = Plateform::getPharPath().'/';
108
            }
109
            $this->fileSystem->copy($root.'res/router.php', $this->getPath().'/.phpoole/router.php', true);
110
            $this->fileSystem->copy($root.'res/livereload.js', $this->getPath().'/.phpoole/livereload.js', true);
111
            $this->fileSystem->dumpFile($this->getPath().'/.phpoole/baseurl', $this->getPHPoole()->getConfig()->get('site.baseurl'));
112
        } catch (IOExceptionInterface $e) {
113
            echo 'An error occurred while copying file at '.$e->getPath().PHP_EOL;
114
            echo $e->getMessage().PHP_EOL;
115
            exit(2);
116
        }
117
        if (!is_file(sprintf('%s/.phpoole/router.php', $this->getPath()))) {
118
            $this->wlError('Router not found');
119
            exit(2);
120
        }
121
    }
122
123
    public function tearDownServer()
124
    {
125
        try {
126
            $this->fileSystem->remove([
0 ignored issues
show
Documentation introduced by
array($this->getPath() .... . '/.phpoole/baseurl') is of type array<integer,string,{"0..."string","2":"string"}>, but the function expects a string|object<Symfony\Co...nt\Filesystem\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
127
                $this->getPath().'/.phpoole/router.php',
128
                $this->getPath().'/.phpoole/livereload.js',
129
                $this->getPath().'/.phpoole/baseurl',
130
            ]);
131
        } catch (IOExceptionInterface $e) {
132
            echo $e->getMessage().PHP_EOL;
133
        }
134
    }
135
}
136