Completed
Push — master ( a3283a...df6bb2 )
by Saulius
27s
created

ConverterCollection   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 84
ccs 36
cts 36
cp 1
rs 10
c 0
b 0
f 0
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A set() 0 6 1
A removeDuplicateConverters() 0 3 1
A resolveType() 0 3 1
A __construct() 0 7 2
A add() 0 4 2
A sort() 0 14 3
A get() 0 7 2
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