Completed
Pull Request — master (#402)
by Alejandro
05:51
created

GeolocationDbUpdater::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Util;
5
6
use Cake\Chronos\Chronos;
7
use GeoIp2\Database\Reader;
8
use InvalidArgumentException;
9
use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException;
10
use Shlinkio\Shlink\Common\Exception\RuntimeException;
11
use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
12
13
class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
14
{
15
    /** @var DbUpdaterInterface */
16
    private $dbUpdater;
17
    /** @var Reader */
18
    private $geoLiteDbReader;
19
20 40
    public function __construct(DbUpdaterInterface $dbUpdater, Reader $geoLiteDbReader)
21
    {
22 40
        $this->dbUpdater = $dbUpdater;
23 40
        $this->geoLiteDbReader = $geoLiteDbReader;
24
    }
25
26
    /**
27
     * @throws GeolocationDbUpdateFailedException
28
     */
29 40
    public function checkDbUpdate(callable $mustBeUpdated = null, callable $handleProgress = null): void
30
    {
31
        try {
32 40
            $meta = $this->geoLiteDbReader->metadata();
33 39
            if ($this->buildIsTooOld($meta->__get('buildEpoch'))) {
34 39
                $this->downloadNewDb(true, $mustBeUpdated, $handleProgress);
35
            }
36 5
        } catch (InvalidArgumentException $e) {
37
            // This is the exception thrown by the reader when the database file does not exist
38 1
            $this->downloadNewDb(false, $mustBeUpdated, $handleProgress);
39
        }
40
    }
41
42 39
    private function buildIsTooOld(int $buildTimestamp): bool
43
    {
44 39
        $buildDate = Chronos::createFromTimestamp($buildTimestamp);
45 39
        $now = Chronos::now();
46 39
        return $now->gt($buildDate->addDays(35));
47
    }
48
49
    /**
50
     * @throws GeolocationDbUpdateFailedException
51
     */
52 5
    private function downloadNewDb(
53
        bool $olderDbExists,
54
        callable $mustBeUpdated = null,
55
        callable $handleProgress = null
56
    ): void {
57 5
        if ($mustBeUpdated !== null) {
58 1
            $mustBeUpdated($olderDbExists);
59
        }
60
61
        try {
62 5
            $this->dbUpdater->downloadFreshCopy($handleProgress);
63 5
        } catch (RuntimeException $e) {
64 5
            throw GeolocationDbUpdateFailedException::create($olderDbExists, $e);
65
        }
66
    }
67
}
68