Completed
Push — master ( aca90e...8ef0e7 )
by Alejandro
10s
created

VisitsTracker::__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 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 2
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Core\Service;
5
6
use Doctrine\ORM;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Shlinkio\Shlink\Common\Util\DateRange;
9
use Shlinkio\Shlink\Core\Entity\ShortUrl;
10
use Shlinkio\Shlink\Core\Entity\Visit;
11
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
12
use Shlinkio\Shlink\Core\Repository\VisitRepository;
13
14
class VisitsTracker implements VisitsTrackerInterface
15
{
16
    /**
17
     * @var ORM\EntityManagerInterface
18
     */
19
    private $em;
20
21 3
    public function __construct(ORM\EntityManagerInterface $em)
22
    {
23 3
        $this->em = $em;
24 3
    }
25
26
    /**
27
     * Tracks a new visit to provided short code, using an array of data to look up information
28
     *
29
     * @param string $shortCode
30
     * @param ServerRequestInterface $request
31
     * @throws ORM\ORMInvalidArgumentException
32
     * @throws ORM\OptimisticLockException
33
     */
34 2
    public function track($shortCode, ServerRequestInterface $request)
35
    {
36
        /** @var ShortUrl $shortUrl */
37 2
        $shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
38 2
            'shortCode' => $shortCode,
39
        ]);
40
41 2
        $visit = new Visit();
42 2
        $visit->setShortUrl($shortUrl)
43 2
              ->setUserAgent($request->getHeaderLine('User-Agent'))
44 2
              ->setReferer($request->getHeaderLine('Referer'))
45 2
              ->setRemoteAddr($this->findOutRemoteAddr($request));
46
47
        /** @var ORM\EntityManager $em */
48 2
        $em = $this->em;
49 2
        $em->persist($visit);
50 2
        $em->flush($visit);
51 2
    }
52
53
    /**
54
     * @param ServerRequestInterface $request
55
     * @return string|null
56
     */
57 2
    private function findOutRemoteAddr(ServerRequestInterface $request)
58
    {
59 2
        $forwardedFor = $request->getHeaderLine('X-Forwarded-For');
60 2
        if (empty($forwardedFor)) {
61 1
            $serverParams = $request->getServerParams();
62 1
            return $serverParams['REMOTE_ADDR'] ?? null;
63
        }
64
65 1
        $ips = explode(',', $forwardedFor);
66 1
        return $ips[0] ?? null;
67
    }
68
69
    /**
70
     * Returns the visits on certain short code
71
     *
72
     * @param string $shortCode
73
     * @param DateRange $dateRange
74
     * @return Visit[]
75
     * @throws InvalidArgumentException
76
     */
77 1
    public function info(string $shortCode, DateRange $dateRange = null): array
78
    {
79
        /** @var ShortUrl|null $shortUrl */
80 1
        $shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
81 1
            'shortCode' => $shortCode,
82
        ]);
83 1
        if ($shortUrl === null) {
84
            throw new InvalidArgumentException(sprintf('Short code "%s" not found', $shortCode));
85
        }
86
87
        /** @var VisitRepository $repo */
88 1
        $repo = $this->em->getRepository(Visit::class);
89 1
        return $repo->findVisitsByShortUrl($shortUrl, $dateRange);
90
    }
91
}
92