ResolvesPages::toPage()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 1
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 3
rs 10
c 2
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cerbero\LazyJsonPages\Concerns;
6
7
use Cerbero\JsonParser\Concerns\DetectsEndpoints;
8
use Cerbero\LazyJsonPages\Exceptions\InvalidPageInPathException;
9
use GuzzleHttp\Psr7\Uri;
10
use Psr\Http\Message\UriInterface;
11
12
/**
13
 * The trait to resolve pages.
14
 */
15
trait ResolvesPages
16
{
17
    use DetectsEndpoints;
18
19
    /**
20
     * Retrieve the page out of the given value.
21
     *
22
     * @return ($onlyNumerics is true ? int|null : string|int|null)
0 ignored issues
show
Documentation Bug introduced by
The doc comment ($onlyNumerics at position 1 could not be parsed: Unknown type name '$onlyNumerics' at position 1 in ($onlyNumerics.
Loading history...
23
     */
24 42
    protected function toPage(mixed $value, bool $onlyNumerics = true): string|int|null
25
    {
26
        return match (true) {
27 42
            is_numeric($value) => (int) $value,
28 6
            !is_string($value) || $value === '' => null,
29 5
            !$this->isEndpoint($value) => $onlyNumerics ? null : $value,
30 42
            default => $this->pageFromParsedUri(parse_url($value), $onlyNumerics), /** @phpstan-ignore-line */
31
        };
32
    }
33
34
    /**
35
     * Retrieve the page from the given parsed URI.
36
     *
37
     * @param array{path?: string, query?: string} $parsedUri
38
     * @return ($onlyNumerics is true ? int|null : string|int|null)
0 ignored issues
show
Documentation Bug introduced by
The doc comment ($onlyNumerics at position 1 could not be parsed: Unknown type name '$onlyNumerics' at position 1 in ($onlyNumerics.
Loading history...
39
     */
40 4
    protected function pageFromParsedUri(array $parsedUri, bool $onlyNumerics = true): string|int|null
41
    {
42 4
        if ($pattern = $this->config->pageInPath) {
43 1
            preg_match($pattern, $parsedUri['path'] ?? '', $matches);
44
45 1
            return $this->toPage($matches[1] ?? null, $onlyNumerics);
46
        }
47
48 3
        parse_str($parsedUri['query'] ?? '', $parameters);
49
50 3
        return $this->toPage($parameters[$this->config->pageName] ?? null, $onlyNumerics);
51
    }
52
53
    /**
54
     * Retrieve the URI for the given page.
55
     */
56 41
    protected function uriForPage(UriInterface $uri, string $page): UriInterface
57
    {
58 41
        if ($key = $this->config->offsetKey) {
59 4
            $value = (intval($page) - $this->config->firstPage) * $this->itemsPerPage;
60
61 4
            return Uri::withQueryValue($uri, $key, strval($value));
62
        }
63
64 37
        if (!$pattern = $this->config->pageInPath) {
65 33
            return Uri::withQueryValue($uri, $this->config->pageName, $page);
66
        }
67
68 4
        if (!preg_match($pattern, $path = $uri->getPath(), $matches, PREG_OFFSET_CAPTURE)) {
69 1
            throw new InvalidPageInPathException($path, $pattern);
70
        }
71
72 3
        return $uri->withPath(substr_replace($path, $page, (int) $matches[1][1], strlen($matches[1][0])));
0 ignored issues
show
Bug introduced by
It seems like substr_replace($path, $p...strlen($matches[1][0])) can also be of type array; however, parameter $path of Psr\Http\Message\UriInterface::withPath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
        return $uri->withPath(/** @scrutinizer ignore-type */ substr_replace($path, $page, (int) $matches[1][1], strlen($matches[1][0])));
Loading history...
73
    }
74
}
75