Completed
Push — master ( 5e52c5...291fe2 )
by Peter
03:20
created

ScriptHandler::getConsoleDir()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 18
ccs 0
cts 9
cp 0
rs 9.2
cc 4
eloc 9
nc 4
nop 2
crap 20
1
<?php
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2017, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Bundle\GeoIP2Bundle\Composer;
11
12
use Composer\Script\Event;
13
use Symfony\Component\Process\PhpExecutableFinder;
14
use Symfony\Component\Process\Process;
15
16
class ScriptHandler
17
{
18
    /**
19
     * Composer variables are declared static so that an event could update
20
     * a composer.json and set new options, making them immediately available
21
     * to forthcoming listeners.
22
     */
23
    private static $options = [
24
        'symfony-app-dir' => 'app',
25
    ];
26
27
    /**
28
     * @param Event $event
29
     */
30
    public static function updateDatabase(Event $event)
31
    {
32
        $options = static::getOptions($event);
33
        $console_dir = static::getConsoleDir($event, 'clear the cache');
34
35
        if (null === $console_dir) {
36
            return;
37
        }
38
39
        self::executeCommand($event, $console_dir, 'geoip2:update --no-debug', $options['process-timeout']);
40
    }
41
42
    /**
43
     * @param Event $event
44
     * @param string $console_dir
45
     * @param string $cmd
46
     * @param int $timeout
47
     */
48
    protected static function executeCommand(Event $event, $console_dir, $cmd, $timeout = 300)
49
    {
50
        $php = escapeshellarg(static::getPhp(false));
0 ignored issues
show
Bug introduced by
Since getPhp() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getPhp() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
51
        $php_args = implode(' ', array_map('escapeshellarg', static::getPhpArguments()));
0 ignored issues
show
Bug introduced by
Since getPhpArguments() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getPhpArguments() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
52
        $console = escapeshellarg($console_dir.'/console');
53
        if ($event->getIO()->isDecorated()) {
54
            $console .= ' --ansi';
55
        }
56
        $process = new Process($php.($php_args ? ' '.$php_args : '').' '.$console.' '.$cmd, null, null, null, $timeout);
57
        $process->run(function ($type, $buffer) use ($event) {
58
            $event->getIO()->write($buffer, false);
59
        });
60
61
        if (!$process->isSuccessful()) {
62
            throw new \RuntimeException(sprintf(
63
                "An error occurred when executing the \"%s\" command:\n\n%s\n\n%s.",
64
                escapeshellarg($cmd),
65
                $process->getOutput(),
66
                $process->getErrorOutput()
67
            ));
68
        }
69
    }
70
71
    /**
72
     * @param Event $event
73
     *
74
     * @return array
75
     */
76
    protected static function getOptions(Event $event)
77
    {
78
        $options = array_merge(static::$options, $event->getComposer()->getPackage()->getExtra());
0 ignored issues
show
Bug introduced by
Since $options is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $options to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
79
80
        $options['process-timeout'] = $event->getComposer()->getConfig()->get('process-timeout');
81
82
        return $options;
83
    }
84
85
    /**
86
     * Returns a relative path to the directory that contains the `console` command or null if not found.
87
     *
88
     * @param Event  $event       The command event
89
     * @param string $action_name The name of the action
90
     *
91
     * @return string|null
92
     */
93
    protected static function getConsoleDir(Event $event, $action_name)
94
    {
95
        $options = static::getOptions($event);
96
97
        if (static::useNewDirectoryStructure($options)) {
0 ignored issues
show
Bug introduced by
Since useNewDirectoryStructure() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of useNewDirectoryStructure() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
98
            if (!static::hasDirectory($event, 'symfony-bin-dir', $options['symfony-bin-dir'], $action_name)) {
0 ignored issues
show
Bug introduced by
Since hasDirectory() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of hasDirectory() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
99
                return;
100
            }
101
102
            return $options['symfony-bin-dir'];
103
        }
104
105
        if (!static::hasDirectory($event, 'symfony-app-dir', $options['symfony-app-dir'], 'execute command')) {
0 ignored issues
show
Bug introduced by
Since hasDirectory() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of hasDirectory() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
106
            return;
107
        }
108
109
        return $options['symfony-app-dir'];
110
    }
111
112
    /**
113
     * @param Event  $event
114
     * @param string $config_name
115
     * @param string $path
116
     * @param string $action_name
117
     *
118
     * @return bool
119
     */
120
    private static function hasDirectory(Event $event, $config_name, $path, $action_name)
121
    {
122
        if (!is_dir($path)) {
123
            $event->getIO()->write(sprintf(
124
                'The %s (%s) specified in composer.json was not found in %s, can not %s.',
125
                $config_name,
126
                $path,
127
                getcwd(),
128
                $action_name
129
            ));
130
131
            return false;
132
        }
133
134
        return true;
135
    }
136
137
    /**
138
     * Returns true if the new directory structure is used.
139
     *
140
     * @param array $options Composer options
141
     *
142
     * @return bool
143
     */
144
    private static function useNewDirectoryStructure(array $options)
145
    {
146
        return isset($options['symfony-var-dir']) && is_dir($options['symfony-var-dir']);
147
    }
148
149
    /**
150
     * Get path to php executable.
151
     *
152
     * @param bool $include_args
153
     *
154
     * @throws \RuntimeException
155
     *
156
     * @return string
157
     */
158
    private static function getPhp($include_args = true)
159
    {
160
        $phpFinder = new PhpExecutableFinder();
161
        if (!$phpPath = $phpFinder->find($include_args)) {
162
            throw new \RuntimeException('The php executable could not be found, add it to your PATH environment variable and try again');
163
        }
164
165
        return $phpPath;
166
    }
167
168
    /**
169
     * @return array
170
     */
171
    private static function getPhpArguments()
172
    {
173
        $ini = null;
0 ignored issues
show
Unused Code introduced by
$ini is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
174
        $arguments = [];
175
        $php_finder = new PhpExecutableFinder();
176
        if (method_exists($php_finder, 'findArguments')) {
177
            $arguments = $php_finder->findArguments();
178
        }
179
180
        if ($env = strval(getenv('COMPOSER_ORIGINAL_INIS'))) {
181
            $paths = explode(PATH_SEPARATOR, $env);
182
            $ini = array_shift($paths);
183
        } else {
184
            $ini = php_ini_loaded_file();
185
        }
186
187
        if ($ini) {
188
            $arguments[] = '--php-ini='.$ini;
189
        }
190
191
        return $arguments;
192
    }
193
}
194