PagerComponentFactory::createComponent()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 28
rs 9.472
c 0
b 0
f 0
1
<?php
2
3
namespace BenTools\OpenCubes\Component\Pager;
4
5
use BenTools\OpenCubes\Component\ComponentFactoryInterface;
6
use BenTools\OpenCubes\Component\ComponentInterface;
7
use BenTools\OpenCubes\Component\Pager\Model\PageSize;
8
use BenTools\OpenCubes\OptionsTrait;
9
use Psr\Http\Message\UriInterface;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
use function BenTools\OpenCubes\contains_only_integers;
12
13
final class PagerComponentFactory implements ComponentFactoryInterface
14
{
15
    use OptionsTrait;
16
17
    public const OPT_DEFAULT_PAGESIZE = 'default_size';
18
    public const OPT_AVAILABLE_PAGESIZES = 'available_sizes';
19
    public const OPT_ENABLED = 'enabled';
20
    public const OPT_TOTAL_ITEMS = 'total_items';
21
    public const OPT_DELTA = 'delta';
22
23
    /**
24
     * @var PagerUriManagerInterface
25
     */
26
    private $uriManager;
27
28
    /**
29
     * PagerComponentFactory constructor.
30
     * @param array                $options
31
     * @param PagerUriManagerInterface|null $uriManager
32
     */
33
    public function __construct(array $options = [], PagerUriManagerInterface $uriManager = null)
34
    {
35
        $this->options = $this->resolveOptions($options);
36
        $this->uriManager = $uriManager ?? new PagerUriManager();
37
    }
38
39
    /**
40
     * @param array $options
41
     * @return array
42
     * @throws \Symfony\Component\OptionsResolver\Exception\AccessException
43
     * @throws \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
44
     * @throws \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
45
     * @throws \Symfony\Component\OptionsResolver\Exception\NoSuchOptionException
46
     * @throws \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException
47
     * @throws \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
48
     */
49
    protected function resolveOptions(array $options): array
50
    {
51
        $resolver = new OptionsResolver();
52
        $resolver->setDefaults([
53
            self::OPT_TOTAL_ITEMS         => 0,
54
            self::OPT_DEFAULT_PAGESIZE    => 50,
55
            self::OPT_AVAILABLE_PAGESIZES => [],
56
            self::OPT_ENABLED             => true,
57
            self::OPT_DELTA               => null,
58
        ]);
59
60
        $resolver->setAllowedTypes(self::OPT_TOTAL_ITEMS, ['int']);
61
        $resolver->setAllowedTypes(self::OPT_AVAILABLE_PAGESIZES, 'array');
62
        $resolver->setAllowedValues(self::OPT_AVAILABLE_PAGESIZES, function ($value) {
63
            return is_array($value) && contains_only_integers($value);
0 ignored issues
show
Documentation introduced by
$value is of type array, but the function expects a object<BenTools\OpenCubes\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
64
        });
65
        $resolver->setAllowedTypes(self::OPT_DEFAULT_PAGESIZE, ['int']);
66
        $resolver->setAllowedTypes(self::OPT_ENABLED, 'bool');
67
        $resolver->setAllowedTypes(self::OPT_DELTA, ['null', 'int']);
68
        $resolver->setRequired(self::OPT_ENABLED);
69
70
        return $resolver->resolve($options);
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76
    public function supports(string $name): bool
77
    {
78
        return PagerComponent::getName() === $name;
79
    }
80
81
    /**
82
     * @inheritDoc
83
     * @return PagerComponent
84
     */
85
    public function createComponent(UriInterface $uri, array $options = []): ComponentInterface
86
    {
87
        $options = $this->resolveOptions($this->getMergedOptions($options));
88
89
        $currentSize = $this->uriManager->getCurrentPageSize($uri) ?? $this->getOption(self::OPT_DEFAULT_PAGESIZE, $options);
90
        $currentPageNumber = $this->uriManager->getCurrentPageNumber($uri) ?? 1;
91
        $availableSizes = $this->getOption(self::OPT_AVAILABLE_PAGESIZES, $options);
92
        $totalItems = $this->getOption(self::OPT_TOTAL_ITEMS, $options);
93
        $delta = $this->getOption(self::OPT_DELTA, $options);
94
95
        if (false === $this->getOption(self::OPT_ENABLED, $options)) {
96
            $currentSize = null;
97
            $currentPageNumber = 1;
98
        }
99
100
        // Create PageSize objects
101
        $pageSizes = $this->createPageSizes($uri, $currentSize, $availableSizes);
102
        
103
        return new PagerComponent(
104
            $uri,
105
            $totalItems,
106
            $currentSize,
107
            $currentPageNumber,
108
            $delta,
109
            $pageSizes,
110
            $this->uriManager
111
        );
112
    }
113
114
    /**
115
     * @param UriInterface $uri
116
     * @param int|null     $currentSize
117
     * @param array        $sizes
118
     * @return PageSize[]
119
     */
120
    private function createPageSizes(UriInterface $uri, ?int $currentSize, array $sizes): array
121
    {
122
        if (null !== $currentSize && !in_array($currentSize, $sizes)) {
123
            $sizes[] = $currentSize;
124
        }
125
126
        sort($sizes, SORT_NUMERIC);
127
128
        // Create PageSize objects
129
        return array_map(function (int $size) use ($uri, $currentSize) {
130
            return new PageSize($size, $size === $currentSize, $this->uriManager->buildSizeUri($uri, $size === $currentSize ? null : $size));
131
        }, $sizes);
132
    }
133
}
134