Passed
Push — feature/unit-tests ( 632e05...3f6f78 )
by Daniel
06:05
created

RefererUrlHelper::getAbsoluteUrl()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 10
c 1
b 0
f 0
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 9.2222
nc 5
nop 1
cc 6
crap 6
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\Url;
15
16
use Silverback\ApiComponentBundle\Exception\InvalidArgumentException;
17
use Silverback\ApiComponentBundle\Exception\OutOfBoundsException;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
20
/**
21
 * @author Daniel West <[email protected]>
22
 */
23
class RefererUrlHelper
24
{
25
    private RequestStack $requestStack;
26
27 14
    public function __construct(RequestStack $requestStack)
28
    {
29 14
        $this->requestStack = $requestStack;
30 14
    }
31
32 10
    public function getAbsoluteUrl($path): string
33
    {
34 10
        if (false !== strpos($path, '://') || 0 === strpos($path, '//')) {
35 1
            return $path;
36
        }
37
38 9
        $request = $this->requestStack->getMasterRequest();
39 9
        if (!$request) {
40 2
            throw new InvalidArgumentException('To generate an absolute URL to the referrer, there must be a valid master request');
41
        }
42
43 7
        if (null !== ($origin = $request->headers->get('origin', null))) {
0 ignored issues
show
introduced by
The condition null !== $origin = $requ...rs->get('origin', null) is always true.
Loading history...
44 2
            return $this->getAbsoluteUrlUsingOrigin($origin, $path);
45
        }
46 5
        if (null !== ($referer = $request->headers->get('referer', null))) {
47 4
            return $this->getAbsoluteUrlUsingReferer($referer, $path);
48
        }
49
50 1
        throw new OutOfBoundsException('To generate an absolute URL to the referrer, the request must have a `origin` or `referer` header present');
51
    }
52
53 2
    private function getAbsoluteUrlUsingOrigin(string $origin, string $path): string
54
    {
55 2
        return $this->addPathToUrl(rtrim($origin, '/'), $path);
56
    }
57
58 4
    private function getAbsoluteUrlUsingReferer(string $referer, string $path): string
59
    {
60 4
        ['host' => $host, 'scheme' => $scheme, 'port' => $port] = parse_url($referer) + ['port' => null];
61 4
        if (null === $scheme || null === $host) {
62
            throw new OutOfBoundsException('Could not extract either `scheme` of `host` key while parsing the `referer` header');
63
        }
64 4
        $url = $scheme . '://' . $host;
65 4
        if ($port && (('https' === $scheme && 443 !== $port) || ('http' === $scheme && 80 !== $port))) {
66 1
            $url .= ':' . $port;
67
        }
68
69 4
        return $this->addPathToUrl($url, $path);
70
    }
71
72 6
    private function addPathToUrl(string $url, string $path): string
73
    {
74 6
        return $url . '/' . ltrim($path, '/');
75
    }
76
}
77