Completed
Push — master ( 50866c...ab1dfc )
by Viacheslav
01:54
created

Uploader::findBinFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace slavkluev\Ip2Location;
6
7
use GuzzleHttp\Client;
8
use GuzzleHttp\Exception\GuzzleException;
9
use ZipArchive;
10
11
class Uploader
12
{
13
    const BASE_URI = 'https://www.ip2location.com/download/';
14
15
    /**
16
     * Stores the HTTP Client.
17
     * @var Client
18
     */
19
    private $httpClient;
20
21
    /**
22
     * Uploader constructor.
23
     * @param Client|null $client
24
     */
25 15
    public function __construct(?Client $client = null)
26
    {
27 15
        if ($client) {
28 15
            $this->httpClient = $client;
29
        } else {
30
            $this->httpClient = new Client([
31
                'base_uri' => self::BASE_URI,
32
            ]);
33
        }
34 15
    }
35
36
    /**
37
     * @param string $token
38
     * @param string $code
39
     * @param string $filePath
40
     * @throws GuzzleException
41
     * @throws \Exception
42
     */
43 15
    public function update(string $token, string $code, string $filePath)
44
    {
45 15
        $tmpFile = $this->uploadUrl($token, $code);
46 15
        $this->extractBinFile((string)$tmpFile, $filePath);
47 6
    }
48
49
    /**
50
     * @param string $filename
51
     * @param string $filePath
52
     * @throws \Exception
53
     */
54 15
    protected function extractBinFile(string $filename, string $filePath)
55
    {
56 15
        $zip = new ZipArchive();
57 15
        $zip->open($filename);
58 15
        $binFilename = $this->findBinFile($zip);
59 12
        $file = $zip->getFromName($binFilename);
60
61 12
        if (false === @file_put_contents($filePath, $file)) {
62 6
            throw new \Exception('Failure while storing: ' . error_get_last()['message']);
63
        }
64
65 6
        $zip->close();
66 6
    }
67
68
    /**
69
     * @param ZipArchive $archive
70
     * @return string
71
     * @throws \Exception
72
     */
73 15
    protected function findBinFile(ZipArchive $archive): string
74
    {
75 15
        for ($i = 0; $i < $archive->numFiles; $i++) {
76 15
            $filename = $archive->getNameIndex($i);
77 15
            if (substr(strtolower($filename), -4, 4) == '.bin') {
78 12
                return $filename;
79
            }
80
        }
81
82 3
        throw new \Exception("bin file has not found");
83
    }
84
85
    /**
86
     * @param string $token
87
     * @param string $code
88
     * @return TmpFile
89
     * @throws \GuzzleHttp\Exception\GuzzleException
90
     */
91 15
    protected function uploadUrl(string $token, string $code): TmpFile
92
    {
93 15
        $tmpFile = new TmpFile();
94 15
        $resource = fopen((string)$tmpFile, 'w');
95 15
        $this->httpClient->request(
96 15
            'GET',
97 15
            '/',
98
            [
99
                'query' => [
100 15
                    'token' => $token,
101 15
                    'file' => $code,
102
                ],
103 15
                'sink' => $resource,
104
            ]
105
        );
106 15
        fclose($resource);
0 ignored issues
show
Bug introduced by
It seems like $resource can also be of type false; however, parameter $handle of fclose() does only seem to accept 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

106
        fclose(/** @scrutinizer ignore-type */ $resource);
Loading history...
107
108 15
        return $tmpFile;
109
    }
110
}
111