Completed
Push — master ( 20d667...bbf4c7 )
by Lukas Kahwe
9s
created

SymfonyVersion::getLatestVersion()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 35
rs 9.0488
c 1
b 0
f 0
cc 5
nc 2
nop 1
1
<?php
2
3
namespace Liip\MonitorBundle\Check;
4
5
use Symfony\Component\HttpKernel\Kernel;
6
use ZendDiagnostics\Check\CheckInterface;
7
use ZendDiagnostics\Result\Failure;
8
use ZendDiagnostics\Result\Success;
9
use ZendDiagnostics\Result\Warning;
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 = 'http://symfony.com/roadmap.json?version=%s';
21
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public function check()
26
    {
27
        $currentBranch = Kernel::MAJOR_VERSION.'.'.Kernel::MINOR_VERSION;
28
29
        // use symfony.com version checker to see if current branch is still maintained
30
        $response = $this->getResponseAndDecode(sprintf(self::VERSION_CHECK_URL, $currentBranch));
31
32
        if (!isset($response['eol']) || !isset($response['is_eoled'])) {
33
            throw new \Exception('Invalid response from Symfony version checker.');
34
        }
35
36
        $endOfLife = \DateTime::createFromFormat('m/Y', $response['eol'])->format('F, Y');
37
38
        if (true === $response['is_eoled']) {
39
            return new Failure(sprintf('Symfony branch "%s" reached it\'s end of life in %s.', $currentBranch, $endOfLife));
40
        }
41
42
        $currentVersion = Kernel::VERSION;
43
        $latestRelease = $this->getLatestVersion($currentBranch); // eg. 2.0.12
44
45
        if (version_compare($currentVersion, $latestRelease) < 0) {
46
            return new Warning(sprintf('There is a new release - update to %s from %s.', $latestRelease, $currentVersion));
47
        }
48
49
        return new Success(sprintf('Your current Symfony branch reaches it\'s end of life in %s.', $endOfLife));
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function getLabel()
56
    {
57
        return 'Symfony version';
58
    }
59
60
    /**
61
     * @param string $branch
62
     *
63
     * @return string
64
     *
65
     * @throws \Exception
66
     */
67
    private function getLatestVersion($branch)
68
    {
69
        $response = $this->getResponseAndDecode(self::PACKAGIST_URL);
70
71
        if (!isset($response['package']['versions'])) {
72
            throw new \Exception('Invalid response from packagist.');
73
        }
74
75
        $branch = 'v'.$branch;
76
77
        // filter out branches and versions without current minor version
78
        $versions = array_filter(
79
            $response['package']['versions'],
80
            function ($value) use ($branch) {
81
                $value = $value['version'];
82
83
                if (stripos($value, 'PR') || stripos($value, 'RC') && stripos($value, 'BETA')) {
84
                    return false;
85
                }
86
87
                return 0 === strpos($value, $branch);
88
            }
89
        );
90
91
        // just get versions
92
        $versions = array_keys($versions);
93
94
        // sort tags
95
        usort($versions, 'version_compare');
96
97
        // reverse to ensure latest is first
98
        $versions = array_reverse($versions);
99
100
        return str_replace('v', '', $versions[0]);
101
    }
102
103
    /**
104
     * @param $url
105
     *
106
     * @return array
107
     *
108
     * @throws \Exception
109
     */
110
    private function getResponseAndDecode($url)
111
    {
112
        $opts = array(
113
            'http' => array(
114
                'method' => 'GET',
115
                'header' => "User-Agent: LiipMonitorBundle\r\n",
116
            ),
117
        );
118
119
        $array = json_decode(file_get_contents($url, false, stream_context_create($opts)), true);
120
121
        if (empty($array)) {
122
            throw new \Exception(sprintf('Invalid response from "%s".', $url));
123
        }
124
125
        return $array;
126
    }
127
}
128