Failed Conditions
Pull Request — master (#43)
by Titouan
08:25
created

PuliStrategy   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 83.33%

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 12
c 3
b 2
f 0
lcom 1
cbo 4
dl 0
loc 146
ccs 35
cts 42
cp 0.8333
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A download() 0 21 2
B getCurrentRemoteVersion() 0 25 4
A getCurrentLocalVersion() 0 4 1
A setStability() 0 10 2
A getStability() 0 4 1
A secureFileGetContents() 0 18 2
1
<?php
2
3
/*
4
 * This file is part of the puli/cli package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Cli\Updater;
13
14
use Composer\CaBundle\CaBundle;
15
use Humbug\SelfUpdate\Exception\HttpRequestException;
16
use Humbug\SelfUpdate\Strategy\StrategyInterface;
17
use Humbug\SelfUpdate\Updater;
18
use Humbug\SelfUpdate\VersionParser;
19
use InvalidArgumentException;
20
use Puli\Cli\PuliApplicationConfig;
21
22
class PuliStrategy implements StrategyInterface
23
{
24
    const ANY = 'any';
25
    const STABLE = 'stable';
26
    const UNSTABLE = 'unstable';
27
28
    const MANIFEST = 'https://puli.io/download/versions.json';
29
    const REMOTE_PHAR = 'https://puli.io/download/%s/puli.phar';
30
31
    /**
32
     * @var array
33
     */
34
    private static $stabilities = array(
35
        self::STABLE,
36
        self::UNSTABLE,
37
        self::ANY,
38
    );
39
40
    /**
41
     * @var string
42
     */
43
    private $stability = self::ANY;
44
45
    /**
46
     * Download the remote Phar file.
47
     *
48
     * @param Updater $updater
49
     */
50 1
    public function download(Updater $updater)
51
    {
52
        /* Switch remote request errors to HttpRequestExceptions */
53 1
        set_error_handler(array($updater, 'throwHttpRequestException'));
54
55 1
        $remoteUrl = sprintf(
56 1
            self::REMOTE_PHAR,
57 1
            $this->getCurrentRemoteVersion($updater)
58
        );
59
60 1
        $result = $this->secureFileGetContents($remoteUrl);
61 1
        restore_error_handler();
62
63 1
        if (false === $result) {
64
            throw new HttpRequestException(sprintf(
65
                'Request to URL failed: %s', $remoteUrl
66
            ));
67
        }
68
69 1
        file_put_contents($updater->getTempPharFile(), $result);
70 1
    }
71
72
    /**
73
     * Retrieve the current version available remotely.
74
     *
75
     * @param Updater $updater
76
     *
77
     * @return string
78
     */
79 2
    public function getCurrentRemoteVersion(Updater $updater)
80
    {
81
        /* Switch remote request errors to HttpRequestExceptions */
82 2
        set_error_handler(array($updater, 'throwHttpRequestException'));
83 2
        $versions = json_decode(humbug_get_contents(self::MANIFEST), true);
84 2
        restore_error_handler();
85
86 2
        if (false === $versions) {
87
            throw new HttpRequestException(sprintf(
88
                'Request to URL failed: %s', self::MANIFEST
89
            ));
90
        }
91
92 2
        $versionParser = new VersionParser($versions);
93
94 2
        if ($this->getStability() === self::STABLE) {
95
            return $versionParser->getMostRecentStable();
96
        }
97
98 2
        if ($this->getStability() === self::UNSTABLE) {
99
            return $versionParser->getMostRecentUnstable();
100
        }
101
102 2
        return $versionParser->getMostRecentAll();
103
    }
104
105
    /**
106
     * Retrieve the current version of the local phar file.
107
     *
108
     * @param Updater $updater
109
     *
110
     * @return string
111
     */
112 1
    public function getCurrentLocalVersion(Updater $updater)
113
    {
114 1
        return PuliApplicationConfig::VERSION;
115
    }
116
117
    /**
118
     * Set target stability.
119
     *
120
     * @param string $stability
121
     */
122 6
    public function setStability($stability)
123
    {
124 6
        if (!in_array($stability, self::$stabilities, true)) {
125 1
            throw new InvalidArgumentException(
126 1
                'Invalid stability value. Must be one of "stable", "unstable" or "any".'
127
            );
128
        }
129
130 5
        $this->stability = $stability;
131 5
    }
132
133
    /**
134
     * Get target stability.
135
     *
136
     * @return string
137
     */
138 5
    public function getStability()
139
    {
140 5
        return $this->stability;
141
    }
142
143
    /**
144
     * Get a remote file content securely using composer/ca-bundle to find the local ca-file.
145
     *
146
     * @param string $remoteUrl
147
     * @return string
148
     */
149 1
    private function secureFileGetContents($remoteUrl)
150
    {
151
        $options = array(
152
            'http' => array(
153
                'method' => 'GET'
154
            )
155 1
        );
156
157 1
        $caPath = CaBundle::getSystemCaRootBundlePath();
158
159 1
        if (is_dir($caPath)) {
160
            $options['ssl']['capath'] = $caPath;
161
        } else {
162 1
            $options['ssl']['cafile'] = $caPath;
163
        }
164
165 1
        return file_get_contents($remoteUrl, false, stream_context_create($options));
166
    }
167
}
168