OperatorPool   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 46
dl 0
loc 86
rs 10
c 3
b 0
f 1
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getOperator() 0 9 2
A retrieveDefaultOperators() 0 7 1
A addOperator() 0 11 3
A __construct() 0 7 3
1
<?php
2
/**
3
 * Copyright © Thomas Klein, All rights reserved.
4
 * See LICENSE bundled with this library for license details.
5
 */
6
declare(strict_types=1);
7
8
namespace LogicTree\Operator;
9
10
use LogicException;
11
use LogicTree\Operator\Comparator\EmptyOperator;
12
use LogicTree\Operator\Comparator\EqOperator;
13
use LogicTree\Operator\Comparator\GteqOperator;
14
use LogicTree\Operator\Comparator\GtOperator;
15
use LogicTree\Operator\Comparator\IdenOperator;
16
use LogicTree\Operator\Comparator\InIdenOperator;
17
use LogicTree\Operator\Comparator\InOperator;
18
use LogicTree\Operator\Comparator\LteqOperator;
19
use LogicTree\Operator\Comparator\LtOperator;
20
use LogicTree\Operator\Comparator\NeqOperator;
21
use LogicTree\Operator\Comparator\NidenOperator;
22
use LogicTree\Operator\Comparator\NinIdenOperator;
23
use LogicTree\Operator\Comparator\NinOperator;
24
use LogicTree\Operator\Comparator\NotNullOperator;
25
use LogicTree\Operator\Comparator\NullOperator;
26
use LogicTree\Operator\Comparator\RegexpOperator;
27
use LogicTree\Operator\Logical\AndOperator;
28
use LogicTree\Operator\Logical\NandOperator;
29
use LogicTree\Operator\Logical\NorOperator;
30
use LogicTree\Operator\Logical\OrOperator;
31
use LogicTree\Operator\Logical\XnorOperator;
32
use LogicTree\Operator\Logical\XorOperator;
33
use function array_map;
34
use function array_merge_recursive;
35
use function sprintf;
36
37
/**
38
 * @api
39
 */
40
final class OperatorPool
41
{
42
    public const TYPE_LOGICAL = 'logical';
43
    public const TYPE_COMPARATOR = 'comparator';
44
45
    /**
46
     * Default operators code and class name listed by types
47
     *
48
     * @var array
49
     */
50
    private const DEFAULT_OPERATORS = [
51
        OperatorPool::TYPE_COMPARATOR => [
52
            EmptyOperator::CODE => EmptyOperator::class,
53
            EqOperator::CODE => EqOperator::class,
54
            GteqOperator::CODE => GteqOperator::class,
55
            GtOperator::CODE => GtOperator::class,
56
            IdenOperator::CODE => IdenOperator::class,
57
            InIdenOperator::CODE => InIdenOperator::class,
58
            InOperator::CODE => InOperator::class,
59
            LteqOperator::CODE => LteqOperator::class,
60
            LtOperator::CODE => LtOperator::class,
61
            NeqOperator::CODE => NeqOperator::class,
62
            NidenOperator::CODE => NidenOperator::class,
63
            NinIdenOperator::CODE => NinIdenOperator::class,
64
            NinOperator::CODE => NinOperator::class,
65
            NotNullOperator::CODE => NotNullOperator::class,
66
            NullOperator::CODE => NullOperator::class,
67
            RegexpOperator::CODE => RegexpOperator::class,
68
        ],
69
        OperatorPool::TYPE_LOGICAL => [
70
            AndOperator::CODE => AndOperator::class,
71
            OrOperator::CODE => OrOperator::class,
72
            XorOperator::CODE => XorOperator::class,
73
            NandOperator::CODE => NandOperator::class,
74
            NorOperator::CODE => NorOperator::class,
75
            XnorOperator::CODE => XnorOperator::class,
76
        ],
77
    ];
78
79
    /**
80
     * @var array[\LogicTree\Operator\OperatorInterface[]]
0 ignored issues
show
Documentation Bug introduced by
The doc comment array[\LogicTree\Operator\OperatorInterface[]] at position 1 could not be parsed: Expected ']' at position 1, but found '['.
Loading history...
81
     */
82
    private $operators = [];
83
84
    public function __construct(array $operators = [])
85
    {
86
        $typeOperators = array_merge_recursive($this->retrieveDefaultOperators(), $operators);
87
88
        foreach ($typeOperators as $type => $operatorList) {
89
            foreach ($operatorList as $operatorCode => $operator) {
90
                $this->addOperator($type, $operatorCode, $operator);
91
            }
92
        }
93
    }
94
95
    public function getOperator(string $type, string $operatorCode): OperatorInterface
96
    {
97
        if (!isset($this->operators[$type][$operatorCode])) {
98
            throw new LogicException(
99
                sprintf('No registered operator for the type "%s" and code "%s".', $type, $operatorCode)
100
            );
101
        }
102
103
        return $this->operators[$type][$operatorCode];
104
    }
105
106
    public function addOperator(string $type, string $operatorCode, OperatorInterface $operator): OperatorPool
107
    {
108
        if (!isset($this->operators[$type][$operatorCode])) {
109
            if (!isset($this->operators[$type])) {
110
                $this->operators[$type] = [];
111
            }
112
113
            $this->operators[$type][$operatorCode] = $operator;
114
        }
115
116
        return $this;
117
    }
118
119
    private function retrieveDefaultOperators(): array
120
    {
121
        return array_map(static function ($operators) {
122
            return array_map(static function ($operator) {
123
                return new $operator();
124
            }, $operators);
125
        }, self::DEFAULT_OPERATORS);
126
    }
127
}
128