Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.00% covered (success)
95.00%
38 / 40
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SolvFetcher
95.00% covered (success)
95.00%
38 / 40
80.00% covered (warning)
80.00%
4 / 5
10
0.00% covered (danger)
0.00%
0 / 1
 fetchEventsCsvForYear
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 fetchYearlyResultsJson
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 fetchEventResultsHtml
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 curlExec
86.67% covered (warning)
86.67%
13 / 15
0.00% covered (danger)
0.00%
0 / 1
3.02
 sleep
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Olz\Fetchers;
4
5class SolvFetcher {
6    private string $base_url = "https://www.o-l.ch/";
7    /** @var non-empty-string */
8    private string $user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36';
9
10    public function fetchEventsCsvForYear(int|string $year): ?string {
11        $this->sleep(3);
12
13        $path = "cgi-bin/fixtures";
14        $query = "?=&year={$year}&kind=-1&csv=1";
15        $url = "{$this->base_url}{$path}{$query}";
16
17        $ch = curl_init();
18        curl_setopt($ch, CURLOPT_URL, $url);
19        $result = $this->curlExec($ch);
20
21        return iconv('ISO-8859-1', 'UTF-8', $result) ?: '';
22    }
23
24    public function fetchYearlyResultsJson(int|string $year): ?string {
25        $this->sleep(3);
26
27        $path = "cgi-bin/fixtures";
28        $query = "?mode=results&year={$year}&json=1";
29        $url = "{$this->base_url}{$path}{$query}";
30
31        $ch = curl_init();
32        curl_setopt($ch, CURLOPT_URL, $url);
33        $result = $this->curlExec($ch);
34
35        return iconv('ISO-8859-1', 'UTF-8', $result) ?: '';
36    }
37
38    public function fetchEventResultsHtml(int|string $rank_id): ?string {
39        $this->sleep(3);
40
41        $path = "cgi-bin/results";
42        $query = "?rl_id={$rank_id}&club=OL+Zimmerberg&zwizt=1";
43        $url = "{$this->base_url}{$path}{$query}";
44
45        $ch = curl_init();
46        curl_setopt($ch, CURLOPT_URL, $url);
47        $result = $this->curlExec($ch);
48
49        return html_entity_decode(iconv('ISO-8859-1', 'UTF-8', $result) ?: '');
50    }
51
52    protected function curlExec(\CurlHandle $ch): string {
53        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
54        curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent);
55        curl_setopt($ch, CURLOPT_REFERER, 'https://www.o-l.ch/cgi-bin/fixtures');
56        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
57        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
58        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
59        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
60        $result = curl_exec($ch);
61        $errno = curl_errno($ch);
62        $error = curl_error($ch);
63        curl_close($ch);
64        if ($errno || !is_string($result)) {
65            $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
66            throw new \Exception("Error fetching {$url}{$error} ({$errno})");
67        }
68        return $result;
69    }
70
71    protected function sleep(int $seconds): void {
72        sleep($seconds);
73    }
74}