Completed
Push — master ( 014eb2...0ec7e8 )
by Alejandro
14s queued 12s
created

Visit::jsonSerialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 2
nop 0
crap 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Core\Entity;
5
6
use Cake\Chronos\Chronos;
7
use JsonSerializable;
8
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
9
use Shlinkio\Shlink\Common\Exception\WrongIpException;
10
use Shlinkio\Shlink\Common\Util\IpAddress;
11
use Shlinkio\Shlink\Core\Model\Visitor;
12
use Shlinkio\Shlink\Core\Visit\Model\UnknownVisitLocation;
13
use Shlinkio\Shlink\Core\Visit\Model\VisitLocationInterface;
14
15
class Visit extends AbstractEntity implements JsonSerializable
16
{
17
    /** @var string */
18
    private $referer;
19
    /** @var Chronos */
20
    private $date;
21
    /** @var string|null */
22
    private $remoteAddr;
23
    /** @var string */
24
    private $userAgent;
25
    /** @var ShortUrl */
26
    private $shortUrl;
27
    /** @var VisitLocation */
28
    private $visitLocation;
29
30 22
    public function __construct(ShortUrl $shortUrl, Visitor $visitor, ?Chronos $date = null)
31
    {
32 22
        $this->shortUrl = $shortUrl;
33 22
        $this->date = $date ?? Chronos::now();
34 22
        $this->userAgent = $visitor->getUserAgent();
35 22
        $this->referer = $visitor->getReferer();
36 22
        $this->remoteAddr = $this->obfuscateAddress($visitor->getRemoteAddress());
37
    }
38
39 22
    private function obfuscateAddress(?string $address): ?string
40
    {
41
        // Localhost addresses do not need to be obfuscated
42 22
        if ($address === null || $address === IpAddress::LOCALHOST) {
43 11
            return $address;
44
        }
45
46
        try {
47 11
            return (string) IpAddress::fromString($address)->getObfuscatedCopy();
48 2
        } catch (WrongIpException $e) {
49 2
            return null;
50
        }
51
    }
52
53 7
    public function getRemoteAddr(): ?string
54
    {
55 7
        return $this->remoteAddr;
56
    }
57
58 11
    public function hasRemoteAddr(): bool
59
    {
60 11
        return ! empty($this->remoteAddr);
61
    }
62
63 7
    public function getVisitLocation(): VisitLocationInterface
64
    {
65 7
        return $this->visitLocation ?? new UnknownVisitLocation();
66
    }
67
68 6
    public function isLocatable(): bool
69
    {
70 6
        return $this->hasRemoteAddr() && $this->remoteAddr !== IpAddress::LOCALHOST;
71
    }
72
73 8
    public function locate(VisitLocation $visitLocation): self
74
    {
75 8
        $this->visitLocation = $visitLocation;
76 8
        return $this;
77
    }
78
79
    /**
80
     * Specify data which should be serialized to JSON
81
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
82
     * @return array data which can be serialized by <b>json_encode</b>,
83
     * which is a value of any type other than a resource.
84
     * @since 5.4.0
85
     */
86 3
    public function jsonSerialize(): array
87
    {
88
        return [
89 3
            'referer' => $this->referer,
90 3
            'date' => $this->date !== null ? $this->date->toAtomString() : null,
91 3
            'userAgent' => $this->userAgent,
92 3
            'visitLocation' => $this->visitLocation,
93
94
            // Deprecated
95
            'remoteAddr' => null,
96
        ];
97
    }
98
99
    /**
100
     * @internal
101
     */
102 1
    public function getDate(): Chronos
103
    {
104 1
        return $this->date;
105
    }
106
}
107