PagerDenormalizer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Paysera\Bundle\ApiBundle\Normalizer\Pagination;
5
6
use Paysera\Pagination\Entity\OrderingPair;
7
use Paysera\Pagination\Entity\Pager;
8
use Paysera\Component\Normalization\DenormalizationContext;
9
use Paysera\Component\Normalization\Exception\InvalidDataException;
10
use Paysera\Component\Normalization\ObjectDenormalizerInterface;
11
use Paysera\Component\Normalization\TypeAwareInterface;
12
use Paysera\Component\ObjectWrapper\Exception\InvalidItemException;
13
use Paysera\Component\ObjectWrapper\ObjectWrapper;
14
15
class PagerDenormalizer implements ObjectDenormalizerInterface, TypeAwareInterface
16
{
17
    private $defaultLimit;
18
    private $maxLimit;
19
20 121
    public function __construct(int $defaultLimit, int $maxLimit)
21
    {
22 121
        $this->defaultLimit = $defaultLimit;
23 121
        $this->maxLimit = $maxLimit;
24 121
    }
25
26 41
    public function denormalize(ObjectWrapper $input, DenormalizationContext $context)
27
    {
28 41
        $limit = isset($input['limit']) ? $this->getPositiveInt($input, 'limit') : $this->defaultLimit;
29 38
        if ($limit > $this->maxLimit) {
30 2
            throw new InvalidItemException(
31 2
                'limit',
32 2
                sprintf('limit cannot exceed %s', $this->maxLimit)
33
            );
34
        }
35
36 36
        $offset = isset($input['offset']) ? $this->getPositiveInt($input, 'offset') : null;
37 33
        $after = $input->getString('after');
38 32
        $before = $input->getString('before');
39
40
        if (
41 31
            ($before !== null && $after !== null)
42 29
            || ($before !== null && $offset !== null)
43 31
            || ($after !== null && $offset !== null)
44
        ) {
45 4
            throw new InvalidDataException('Only one of offset, before and after can be specified');
46
        }
47
48 27
        $orderingPairs = isset($input['sort']) ? $this->parseOrderingPairs($input->getString('sort')) : [];
49
50 26
        return (new Pager())
51 26
            ->setOrderingPairs($orderingPairs)
52 26
            ->setOffset($offset)
53 26
            ->setLimit($limit)
54 26
            ->setBefore($before)
55 26
            ->setAfter($after)
56
        ;
57
    }
58
59 6
    private function parseOrderingPairs(string $ordering): array
60
    {
61 6
        $orderingPairs = [];
62 6
        $orderingFields = explode(',', $ordering);
63 6
        foreach ($orderingFields as $field) {
64 6
            $orderAsc = true;
65 6
            if (mb_substr($field, 0, 1) === '-') {
66 2
                $field = mb_substr($field, 1);
67 2
                $orderAsc = false;
68
            }
69
70 6
            $orderingPairs[] = new OrderingPair($field, $orderAsc);
71
        }
72
73 6
        return $orderingPairs;
74
    }
75
76 27
    private function getPositiveInt(ObjectWrapper $input, string $key): int
77
    {
78 27
        $filtered = filter_var($input->getRequiredString($key), FILTER_VALIDATE_INT, ['options' => [
79
            'min_range' => 0,
80
        ]]);
81
82 25
        if ($filtered === false) {
83 4
            throw new InvalidItemException($key, sprintf('%s must be positive integer', $key));
84
        }
85
86 21
        return $filtered;
87
    }
88
89 96
    public function getType(): string
90
    {
91 96
        return Pager::class;
92
    }
93
}
94