Completed
Pull Request — master (#236)
by
unknown
06:11
created

SymfonyVersion::getResponseAndDecode()   B

Complexity

Conditions 7
Paths 20

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 0
cts 14
cp 0
rs 8.5386
c 0
b 0
f 0
cc 7
nc 20
nop 1
crap 56
1
<?php
2
3
namespace Liip\MonitorBundle\Check;
4
5
use Laminas\Diagnostics\Check\CheckInterface;
6
use Laminas\Diagnostics\Result\Failure;
7
use Laminas\Diagnostics\Result\Success;
8
use Laminas\Diagnostics\Result\Warning;
9
use Symfony\Component\HttpKernel\Kernel;
10
11
/**
12
 * Checks the version of this app against the latest stable release.
13
 *
14
 * @author Roderik van der Veer <[email protected]>
15
 * @author Kevin Bond <[email protected]>
16
 */
17
class SymfonyVersion implements CheckInterface
18
{
19
    const PACKAGIST_URL = 'https://packagist.org/packages/symfony/symfony.json';
20
    const VERSION_CHECK_URL = 'https://symfony.com/releases/%s.json';
21
22
    public function check()
23
    {
24
        $currentBranch = Kernel::MAJOR_VERSION.'.'.Kernel::MINOR_VERSION;
25
26
        // use symfony.com version checker to see if current branch is still maintained
27
        $response = $this->getResponseAndDecode(sprintf(self::VERSION_CHECK_URL, $currentBranch));
28
29
        if (!isset($response['eol']) || !isset($response['is_eoled'])) {
30
            throw new \Exception('Invalid response from Symfony version checker.');
31
        }
32
33
        $endOfLife = \DateTime::createFromFormat('m/Y', $response['eol'])->format('F, Y');
34
35
        if (true === $response['is_eoled']) {
36
            return new Failure(sprintf('Symfony branch "%s" reached it\'s end of life in %s.', $currentBranch, $endOfLife));
37
        }
38
39
        $currentVersion = Kernel::VERSION;
40
        $latestRelease = $this->getLatestVersion($currentBranch); // eg. 2.0.12
41
42
        if (version_compare($currentVersion, $latestRelease) < 0) {
43
            return new Warning(sprintf('There is a new release - update to %s from %s.', $latestRelease, $currentVersion));
44
        }
45
46
        return new Success(sprintf('Your current Symfony branch reaches it\'s end of life in %s.', $endOfLife));
47
    }
48
49
    public function getLabel()
50
    {
51
        return 'Symfony version';
52
    }
53
54
    /**
55
     * @param string $branch
56
     *
57
     * @return string
58
     *
59
     * @throws \Exception
60
     */
61
    private function getLatestVersion($branch)
62
    {
63
        $response = $this->getResponseAndDecode(self::PACKAGIST_URL);
64
65
        if (!isset($response['package']['versions'])) {
66
            throw new \Exception('Invalid response from packagist.');
67
        }
68
69
        $branch = 'v'.$branch;
70
71
        // filter out branches and versions without current minor version
72
        $versions = array_filter(
73
            $response['package']['versions'],
74
            function ($value) use ($branch) {
75
                $value = $value['version'];
76
77
                if (stripos($value, 'PR') || stripos($value, 'RC') && stripos($value, 'BETA')) {
78
                    return false;
79
                }
80
81
                return 0 === strpos($value, $branch);
82
            }
83
        );
84
85
        // just get versions
86
        $versions = array_keys($versions);
87
88
        // sort tags
89
        usort($versions, 'version_compare');
90
91
        // reverse to ensure latest is first
92
        $versions = array_reverse($versions);
93
94
        return str_replace('v', '', $versions[0]);
95
    }
96
97
    /**
98
     * @param $url
99
     *
100
     * @return array
101
     *
102
     * @throws \Exception
103
     */
104
    private function getResponseAndDecode($url)
105
    {
106
        if (class_exists(\Symfony\Component\HttpClient\HttpClient::class)) {
107
            $client = \Symfony\Component\HttpClient\HttpClient::create();
108
            try {
109
                $content = $client->request('GET', $url)->getContent();
110
                $array = json_decode($content, true);
111
            } catch (ClientExceptionInterface $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Liip\MonitorBundle\Check\ClientExceptionInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
112
            } catch (RedirectionExceptionInterface $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Liip\MonitorBundle\Check...ctionExceptionInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
113
            } catch (ServerExceptionInterface $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Liip\MonitorBundle\Check\ServerExceptionInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
114
            } catch (TransportExceptionInterface $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Liip\MonitorBundle\Check...sportExceptionInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
115
            }
116
        } else {
117
            $opts = [
118
                'http' => [
119
                    'method' => 'GET',
120
                    'header' => "User-Agent: LiipMonitorBundle\r\n",
121
                ],
122
            ];
123
            $array = json_decode(file_get_contents($url, false, stream_context_create($opts)), true);
124
        }
125
126
        if (empty($array)) {
127
            throw new \Exception(sprintf('Invalid response from "%s".', $url));
128
        }
129
130
        return $array;
131
    }
132
}
133