Passed
Push — master ( 1ba3e3...448aab )
by Kacper
03:26
created

Rules::add()   B

Complexity

Conditions 6
Paths 24

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 24
nop 2
dl 0
loc 27
ccs 18
cts 18
cp 1
crap 6
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2016, Some right reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp: [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Highlighter\Parser;
17
18
19
use Kadet\Highlighter\Exceptions\NameConflictException;
20
use Kadet\Highlighter\Exceptions\NoSuchElementException;
21
use Kadet\Highlighter\Language\Language;
22
use Kadet\Highlighter\Parser\Validator\Validator;
23
24
class Rules extends \ArrayObject
25
{
26
    /** @var Language Default language assigned to added rules. */
27
    private $_language;
28
29
    /** @var Validator Default validator used in added rules. */
30
    public $validator;
31
32 25
    private function _getName($name, $prefix)
33
    {
34 25
        if (is_int($name)) {
35 6
            return $prefix;
36
        } else {
37 25
            return $prefix ? "$prefix.$name" : $name;
38
        }
39
    }
40
41
    /**
42
     * Rules constructor.
43
     *
44
     * @param Language $language
45
     */
46 38
    public function __construct($language)
47
    {
48 38
        $this->_language = $language;
49
50 38
        $this->validator = new Validator();
51 38
    }
52
53
    /**
54
     * Adds array of rules
55
     *
56
     * @param array       $rules
57
     * @param string|null $prefix
58
     *
59
     * @throws \LogicException
60
     */
61 40
    public function addMany(array $rules, $prefix = null)
62
    {
63 40
        foreach ($rules as $type => $rule) {
64 25
            $type = $this->_getName($type, $prefix);
65
66 25
            if ($rule instanceof Rule) {
67 24
                $this->add($type, $rule);
68 25
            } elseif (is_array($rule)) {
69 6
                $this->addMany($rule, $type);
70 6
            } else {
71 1
                throw new \LogicException('Array values has to be either arrays of rules or rules.');
72
            }
73 39
        }
74 39
    }
75
76
    /**
77
     * Adds one rule
78
     *
79
     * @param string $type
80
     * @param Rule   $rule
81
     *
82
     * @throws NameConflictException When there is already defined rule with given name.
83
     */
84 28
    public function add($type, Rule $rule)
85
    {
86 28
        if (!isset($this[$type])) {
87 26
            $this[$type] = [];
88 26
        }
89
90 28
        if ($rule->language === false) {
91 19
            $rule->language = $this->_language;
92 19
        }
93
94 28
        if ($rule->validator === false) {
95 19
            $rule->validator = $this->validator;
96 19
        }
97
98 28
        $rule->factory->setBase($type);
99
100 28
        if ($rule->name !== null) {
101 2
            if (isset($this[$type][$rule->name])) {
102 1
                throw new NameConflictException("Rule with '{$rule->name}' is already defined, name has to be unique!");
103
            }
104
105 2
            $this[$type][$rule->name] = $rule;
106 2
            return;
107
        }
108
109 26
        $this[$type][] = $rule;
110 26
    }
111
112
    /**
113
     * Return reference to rule of given type and index.
114
     *
115
     * @param string $type
116
     * @param mixed  $index
117
     *
118
     * @return \Kadet\Highlighter\Parser\Rule
119
     */
120 3
    public function &rule($type, $index = 0)
121
    {
122 3
        return $this[$type][$index];
123
    }
124
125
    /**
126
     * Retrieves all rules of given type.
127
     *
128
     * @param $type
129
     *
130
     * @return Rule[]
131
     * @throws NoSuchElementException
132
     */
133 2
    public function rules($type)
134
    {
135 2
        if (!isset($this[$type])) {
136 1
            throw new NoSuchElementException("There isn't any rule of '$type' type.");
137
        }
138
139 1
        return $this[$type];
140
    }
141
142
    /**
143
     * Replaces rule of given type and index with provided one.
144
     *
145
     * @param Rule $replacement
146
     * @param      $type
147
     * @param int  $index
148
     */
149 1
    public function replace(Rule $replacement, $type, $index = 0)
150
    {
151 1
        $current = $this->rule($type, $index);
152 1
        if ($current->name !== null) {
153
            $replacement->name = $current->name;
154
        }
155
156 1
        $this[$type][$index] = $replacement;
157 1
    }
158
159
    /**
160
     * Removes rule of given type and index.
161
     *
162
     * @param string $type
163
     * @param mixed  $index
164
     *
165
     * @throws NoSuchElementException
166
     */
167 2
    public function remove($type, $index = null)
168
    {
169 2
        if ($index === null) {
170 1
            unset($this[$type]);
171 1
            return;
172
        }
173
174 2
        if(!isset($this[$type][$index])) {
175 1
            throw new NoSuchElementException("There is no rule '$type' type indexed by '$index'.");
176
        }
177
178 1
        unset($this[$type][$index]);
179 1
    }
180
181
    /**
182
     * Retrieves all rule set.
183
     *
184
     * @return Rule[]
185
     */
186 22
    public function all()
187
    {
188 22
        $items = $this->getArrayCopy();
189 22
        if(empty($items)) return [];
190
191 22
        return call_user_func_array('array_merge', $items);
192
    }
193
194
    /**
195
     * @return Language
196
     */
197 1
    public function getLanguage()
198
    {
199 1
        return $this->_language;
200
    }
201
202
    /**
203
     * @param Language $language
204
     */
205 1
    public function setLanguage(Language $language = null)
206
    {
207 1
        $this->_language = $language;
208 1
    }
209
}
210