Test Failed
Pull Request — master (#85)
by Gabriel
02:58
created

ChangeWindows::fetchVersions()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.6845
c 0
b 0
f 0
cc 4
eloc 18
nc 4
nop 0
1
<?php
2
3
/**
4
 * Fetch versions from changewindows.org
5
 * © 2014-present CHANGEWINDOWS
6
 *
7
 * Disclaimer
8
 * All trademarks mentioned are the property of their respective owners. The content generated by this script
9
 * comes from changewindows.org and may not be accurate.
10
 */
11
class ChangeWindows
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
{
13
    private static $errors = array(
14
        'could_not_fetch_version' => 'Could not fetch current version from ChangeWindows',
15
        'invalid_version' => 'Windows version is invalid',
16
        'could_not_fetch_page' => 'Could not fetch page from ChangeWindows'
17
    );
18
19
    public static function fetchVersions()
20
    {
21
        $windowsVersions = json_decode(file_get_contents(__DIR__ . '/windowsVersions.json'), true);
22
        if (!count($windowsVersions)) {
23
            $currentVersion = explode('.', self::fetchCurrentVersion(), 2);
24
            if (!isset($currentVersion[0])) throw new Exception(self::$errors['invalid_version']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
25
            $windowsVersions = self::fetchVersion($windowsVersions, $currentVersion[0]);
26
            self::writeWindowsVersions($windowsVersions);
27
        } else {
28
            reset($windowsVersions);
29
            $firstVersion = key($windowsVersions);
30
            end($windowsVersions);
31
            $lastVersion = key($windowsVersions);
32
33
            try {
34
                $result = self::fetchVersion($windowsVersions, $firstVersion);
35
                $windowsVersions = $result;
36
            } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
37
            }
38
39
            $windowsVersions = self::fetchVersion($windowsVersions, $lastVersion);
40
            self::writeWindowsVersions($windowsVersions);
41
        }
42
    }
43
44
    private static function fetchVersion($windowsVersions, $version)
45
    {
46
        $siblingVersions = self::fetchPage($version);
47
        $windowsVersions[$version] = true;
48
        self::writeWindowsVersions($windowsVersions);
49
50 View Code Duplication
        if (isset($siblingVersions[0]) && !isset($windowsVersions[$siblingVersions[0]])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
            $windowsVersions = self::fetchVersion($windowsVersions, $siblingVersions[0]);
52
        }
53
54 View Code Duplication
        if (isset($siblingVersions[1]) && !isset($windowsVersions[$siblingVersions[1]])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
            $windowsVersions = self::fetchVersion($windowsVersions, $siblingVersions[1]);
56
        }
57
58
        return $windowsVersions;
59
    }
60
61
    private static function writeWindowsVersions($windowsVersions)
62
    {
63
        ksort($windowsVersions);
64
        file_put_contents(__DIR__ . '/windowsVersions.json', json_encode($windowsVersions, JSON_PRETTY_PRINT));
65
    }
66
67
    private static function fetchCurrentVersion()
68
    {
69
        $content = file_get_contents('https://changewindows.org/filter/pc/all/current/month/true');
70
        if (!$content) throw new Exception(self::$errors['could_not_fetch_version']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
71
        $content = explode('class="timeline"', $content, 2);
72
        if (!isset($content[1])) throw new Exception(self::$errors['could_not_fetch_version']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
73
        $content = explode('build"', $content[1], 2);
74
        if (!isset($content[1])) throw new Exception(self::$errors['could_not_fetch_version']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
75
        preg_match("/(\d*\.\d*)<\/div>/", $content[1], $matches);
76
        if (!isset($matches[1])) throw new Exception(self::$errors['could_not_fetch_version']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
77
        return $matches[1];
78
    }
79
80
    private static function fetchPage($version)
81
    {
82
        $url = "https://changewindows.org/build/{$version}/pc";
83
        $content = file_get_contents($url);
84
        $siblingVersions = self::fetchSiblingVersions($content);
85
        self::fetchEdgeVersion($content);
86
        return $siblingVersions;
87
    }
88
89
    private static function fetchEdgeVersion($content)
90
    {
91
        preg_match('/<h4[^>]*> *Edge ([\d\.]*) *<\/h4>/', $content, $edge);
92
        preg_match('/<h4[^>]*>EdgeHTML ([\d\.]*)<\/h4>/', $content, $edgeHtml);
93
94
        if (isset($edge[1]) && isset($edgeHtml[1])) {
95
            self::writeEdgeVersion($edgeHtml[1], $edge[1]);
96
        }
97
        return null;
98
    }
99
100 View Code Duplication
    private static function writeEdgeVersion($edgeHtml, $edge)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
    {
102
        $file = __DIR__ . '/../../src/edgeVersionMap.php';
103
        $currentVersions = require $file;
104
        if (!isset($currentVersions[$edgeHtml])) {
105
            $currentVersions[$edgeHtml] = $edge;
106
            ksort($currentVersions);
107
            $content = '';
108
            foreach ($currentVersions as $edgeHtml => $edge) {
109
                $content .= "    '{$edgeHtml}' => '{$edge}'," . PHP_EOL;
110
            }
111
            $data = <<<PHP
112
<?php
113
114
return array(
115
    %s
116
);
117
118
PHP;
119
            file_put_contents($file, sprintf($data, trim($content)));
120
        }
121
    }
122
123
    private static function fetchSiblingVersions($content)
124
    {
125
        if (!$content) throw new Exception(self::$errors['could_not_fetch_page']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
126
        $content = explode('build-sidebar', $content, 2);
127
        if (!isset($content[1])) throw new Exception(self::$errors['could_not_fetch_page']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
128
        $content = explode('fa-angle-left', $content[1]);
129
        if (!isset($content[1])) throw new Exception(self::$errors['could_not_fetch_page']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
130
        $content = explode('fa-angle-right', $content[1]);
131
        if (!isset($content[0])) throw new Exception(self::$errors['could_not_fetch_page']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
132
        preg_match_all("/> *(\d+) *</", $content[0], $matches);
133
        if (!isset($matches[1])) throw new Exception(self::$errors['could_not_fetch_page']);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
134
        return $matches[1];
135
    }
136
}
137