Completed
Push — master ( df6bb2...227d1b )
by Saulius
8s
created

ConverterCollection::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the sauls/helpers package.
4
 *
5
 * @author    Saulius Vaičeliūnas <[email protected]>
6
 * @link      http://saulius.vaiceliunas.lt
7
 * @copyright 2018
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Sauls\Component\Helper\Operation\TypeOperation\Collection;
14
15
use Sauls\Component\Helper\Exception\InvalidTypeConverterException;
16
use Sauls\Component\Helper\Operation\TypeOperation\Converter\ConverterInterface;
17
18
class ConverterCollection implements ConverterCollectionInterface
19
{
20
    private $converters = [];
21
22
    private static $typeAliases = [
23
        'boolean' => 'bool',
24
        'integer' => 'int',
25
        'long' => 'int',
26
        'double' => 'float',
27
        'real' => 'float',
28
        '[]' => 'array',
29
    ];
30
31 1
    public function __construct($converters = [])
32
    {
33 1
        if ($converters instanceof \Traversable) {
34 1
            $converters = iterator_to_array($converters);
35
        }
36
37 1
        $this->add($converters);
38 1
    }
39
40 5
    public function add(array $converters): void
41
    {
42 5
        foreach ($converters as $ensurer) {
43 4
            $this->set($ensurer);
44
        }
45 5
    }
46
47 4
    public function set(ConverterInterface $converter): void
48
    {
49 4
        $type = $this->resolveType($converter->getType());
50 4
        $this->converters[$type][] = $converter;
51 4
        $this->removeDuplicateConverters($type);
52 4
        $this->sort($type);
53 4
    }
54
55 4
    private function removeDuplicateConverters($type): void
56
    {
57 4
        $this->converters[$type] = array_unique($this->converters[$type], SORT_REGULAR);
58 4
    }
59
60 4
    private function sort(string $type): void
61
    {
62 4
        uasort(
63 4
            $this->converters[$this->resolveType($type)],
64 4
            function (ConverterInterface $ensurer1, ConverterInterface $ensurer2) {
65
66 4
                $priority1 = $ensurer1->getPriority();
67 4
                $priority2 = $ensurer2->getPriority();
68
69 4
                if ($priority1 === $priority2) {
70 3
                    return 0;
71
                }
72
73 1
                return ($priority1 > $priority2) ? -1 : 1;
74 4
            }
75
        );
76 4
    }
77
78
    /**
79
     * @return array|ConverterInterface[]
80
     *
81
     * @throws \Sauls\Component\Helper\Exception\InvalidTypeConverterException
82
     */
83 5
    public function get(string $type): array
84
    {
85
        try {
86 5
            return $this->converters[$this->resolveType($type)];
87 1
        } catch (\Throwable $t) {
88 1
            throw new InvalidTypeConverterException(
89 1
                sprintf('Invalid converter type `%s`.', $type)
90
            );
91
        }
92
    }
93
94
    /**
95
     * @param string $type
96
     *
97
     * @return mixed
98
     */
99 5
    private function resolveType(string $type)
100
    {
101 5
        return \strtr($type, self::$typeAliases);
102
    }
103
}
104