CliHttpCache   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 42.86%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 66
ccs 6
cts 14
cp 0.4286
rs 10
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A transfer() 0 3 1
A __construct() 0 3 1
A getServer() 0 11 2
A getEtag() 0 16 6
A getServerKey() 0 3 1
A isNotModified() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\QueryRepository;
6
7
use BEAR\Sunday\Extension\Transfer\HttpCacheInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, BEAR\QueryRepository\HttpCacheInterface. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
9
use function assert;
10
use function is_string;
11
use function parse_str;
12
use function sprintf;
13
use function str_replace;
14 2
use function strtoupper;
15
16 2
use const PHP_EOL;
17 2
18
final class CliHttpCache implements HttpCacheInterface
19
{
20
    public function __construct(
21
        private readonly ResourceStorageInterface $storage,
22 2
    ) {
23
    }
24 2
25
    /**
26
     * {@inheritDoc}
27
     */
28 2
    public function isNotModified(array $server): bool
29
    {
30
        $etag = $this->getEtag($server);
31
        if ($etag === null) {
32
            return false;
33
        }
34 1
35
        return $this->storage->hasEtag($etag);
36 1
    }
37 1
38
    /**
39
     * {@inheritDoc}
40
     *
41
     * @return void
42
     */
43
    public function transfer()
44
    {
45
        echo '304 Not Modified' . PHP_EOL . PHP_EOL;
46
    }
47
48
    /** @return array<string, string> */
49
    private function getServer(string $query): array
50
    {
51
        parse_str($query, $headers);
52
        $server = [];
53
        foreach ($headers as $key => $header) {
54
            assert(is_string($header));
55
            assert(is_string($key));
56
            $server[$this->getServerKey($key)] = $header;
57
        }
58
59
        return $server;
60
    }
61
62
    private function getServerKey(string $key): string
63
    {
64
        return sprintf('HTTP_%s', strtoupper(str_replace('-', '_', $key)));
65
    }
66
67
    /** @param array<string, mixed> $server */
68
    private function getEtag(array $server): string|null
69
    {
70
        /** @psalm-suppress MixedAssignment */
71
        $arg3 = $server['argv'][3] ?? ''; /* @phpstan-ignore-line */
72
        assert(is_string($arg3));
73
        $hasRequestHeaderInCli = isset($server['argc']) && $server['argc'] === 4 && $arg3;
74
        if ($hasRequestHeaderInCli) {
75
            /** @psalm-suppress MixedArrayAccess */
76
            $server = $this->getServer($arg3);
77
        }
78
79
        if (isset($server[Header::HTTP_IF_NONE_MATCH]) && is_string($server[Header::HTTP_IF_NONE_MATCH])) {
80
            return $server[Header::HTTP_IF_NONE_MATCH];
81
        }
82
83
        return null;
84
    }
85
}
86