Passed
Push — master ( 60b6ca...163cac )
by Kylian
06:19
created

MultiQuery::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
1
<?php
2
3
namespace KriKrixs\functions;
4
5
use KriKrixs\object\beatmap\BeatMap;
6
use KriKrixs\object\response\ResponseDownload;
7
8
class MultiQuery {
9
    private string $apiUrl;
10
    private string $userAgent;
11
12
    /**
13
     * MultiQuery Constructor
14
     * @param string $apiUrl
15
     * @param string $userAgent
16
     */
17
    public function __construct(string $apiUrl, string $userAgent)
18
    {
19
        $this->apiUrl       = $apiUrl;
20
        $this->userAgent    = $userAgent;
21
    }
22
23
    /**
24
     * @param $p_URLs
25
     * @return array
26
     */
27
    public function DoMultiQuery($p_URLs, bool $isHash): array
28
    {
29
        $l_Multi    = curl_multi_init();
30
        $apiUrlExt  = $isHash ? "/maps/hash/" : "/maps/id/";
31
        $l_Handles  = [];
32
        foreach ($p_URLs as $l_URL)
33
        {
34
            $l_CURL = curl_init($this->apiUrl.$apiUrlExt.$l_URL);
35
            curl_setopt($l_CURL, CURLOPT_USERAGENT, $this->userAgent);
36
            curl_setopt($l_CURL, CURLOPT_RETURNTRANSFER, true);
37
38
            $l_Handles[] = $l_CURL;
39
        }
40
41
        foreach ($l_Handles as $l_Current)
42
            curl_multi_add_handle($l_Multi, $l_Current);
0 ignored issues
show
Bug introduced by
It seems like $l_Multi can also be of type true; however, parameter $multi_handle of curl_multi_add_handle() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
            curl_multi_add_handle(/** @scrutinizer ignore-type */ $l_Multi, $l_Current);
Loading history...
43
44
        $l_RunningHandles = null;
45
46
        do
47
        {
48
            curl_multi_exec($l_Multi, $l_RunningHandles);
0 ignored issues
show
Bug introduced by
It seems like $l_Multi can also be of type true; however, parameter $multi_handle of curl_multi_exec() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

48
            curl_multi_exec(/** @scrutinizer ignore-type */ $l_Multi, $l_RunningHandles);
Loading history...
49
            curl_multi_select($l_Multi);
0 ignored issues
show
Bug introduced by
It seems like $l_Multi can also be of type true; however, parameter $multi_handle of curl_multi_select() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
            curl_multi_select(/** @scrutinizer ignore-type */ $l_Multi);
Loading history...
50
        } while ($l_RunningHandles > 0);
51
52
        $l_Result = [];
53
        foreach ($l_Handles as $l_Current)
54
        {
55
            $l_Error = curl_error($l_Current);
56
57
            if (!empty($l_Error) || curl_getinfo($l_Current, CURLINFO_HTTP_CODE) !== 200)
58
                $l_Result[] = false;
59
            else
60
                $l_Result[] = new BeatMap(json_decode(curl_multi_getcontent($l_Current)));
61
62
            curl_multi_remove_handle($l_Multi, $l_Current);
0 ignored issues
show
Bug introduced by
It seems like $l_Multi can also be of type true; however, parameter $multi_handle of curl_multi_remove_handle() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
            curl_multi_remove_handle(/** @scrutinizer ignore-type */ $l_Multi, $l_Current);
Loading history...
63
        }
64
65
        curl_multi_close($l_Multi);
0 ignored issues
show
Bug introduced by
It seems like $l_Multi can also be of type true; however, parameter $multi_handle of curl_multi_close() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
        curl_multi_close(/** @scrutinizer ignore-type */ $l_Multi);
Loading history...
66
        return $l_Result;
67
    }
68
69
    public function downloadMapZipAndCover(array $p_URLs, string $targetDir): ResponseDownload
70
    {
71
        $response = new ResponseDownload();
72
73
        $anyError = [];
74
        $allFailed = null;
75
76
        foreach ($p_URLs as $hash => $l_URLs) {
77
            echo $hash . ": ";
78
79
            $error = false;
80
81
            foreach ($l_URLs as $type => $l_URL) {
82
                echo $type . ": ";
83
84
                $extension = $type === "map" ? '.zip' : '.jpg';
85
86
                if (!file_exists($targetDir)) {
87
                    mkdir($targetDir, 0777, true);
88
                }
89
90
                if(substr($targetDir, -1) !== "/")
91
                    $targetDir .= "/";
92
93
                //The path & filename to save to.
94
                $saveTo = $targetDir . $hash . $extension;
95
96
                $ch = curl_init($l_URL);
97
                curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
98
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
99
                curl_setopt($ch, CURLOPT_ENCODING, "");
100
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
101
102
                $result = curl_exec($ch);
103
104
                if(curl_errno($ch) === 0) {
105
                    $allFailed = false;
106
                    echo "Ok ";
107
                } else {
108
                    $anyError[] = $hash;
109
                    $error = true;
110
                    if(is_null($allFailed)) $allFailed = true;
111
                    echo "Error ";
112
                }
113
114
                file_put_contents($saveTo, $result);
115
116
                curl_close($ch);
117
            }
118
119
            echo "save: " . ($error ? "No" : "Yes") . "\n";
120
        }
121
122
        $status = "";
123
124
        if($allFailed) {
0 ignored issues
show
introduced by
$allFailed is of type false|null, thus it always evaluated to false.
Loading history...
125
            $status = "All failed";
126
            $response->setErrorStatus(true)->setErrorMessage("Can't download all/some maps");
127
        } else {
128
            if(count($anyError) !== 0) {
129
                $response->setErrorStatus(true)->setErrorMessage("Can't download all/some maps");
130
131
                foreach ($anyError as $hash) {
132
                    $status .= $hash . ", ";
133
                }
134
135
                $status .= "Failed";
136
            }
137
        }
138
139
        $response->setDownloadStatus($status);
140
141
        return $response;
142
    }
143
144
    public function buildDownloadArray($items, $isHash): array
145
    {
146
        $downloadLinks = [];
147
148
        /** @var BeatMap $beatmap */
149
        foreach ($this->DoMultiQuery($items, $isHash) as $beatmap) {
150
            $downloadLinks[$beatmap->getVersions()[0]->getHash()]["map"] = $beatmap->getVersions()[0]->getDownloadURL();
151
            $downloadLinks[$beatmap->getVersions()[0]->getHash()]["cover"] = $beatmap->getVersions()[0]->getCoverURL();
152
        }
153
154
        return $downloadLinks;
155
    }
156
157
}