Parser   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 113
ccs 41
cts 41
cp 1
rs 10
c 0
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 0 10 1
A extractParams() 0 22 3
A applyTypesToParams() 0 21 4
A normalizeParam() 0 16 2
1
<?php
2
3
/**
4
 * Linna Filter
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2018, Sebastian Rapetti
8
 * @license http://opensource.org/licenses/MIT MIT License
9
 */
10
declare(strict_types=1);
11
12
namespace Linna\Filter;
13
14
use Linna\Filter\Rules\Number;
15
use OutOfBoundsException;
16
17
/**
18
 * Parser.
19
 *
20
 */
21
class Parser
22
{
23
    /**
24
     * @var array Filters rules.
25
     */
26
    private $rules = [];
27
28
    /**
29
     * @var array Rule aliases.
30
     */
31
    private $alias = [];
32
33
    /**
34
     * Parse user defined rules.
35
     *
36
     * @param array $tokens Tokens from lexer
37
     * @param array $rules  Rule properties
38
     * @param array $alias  Alises for a rule
39
     *
40
     * @return array
41
     */
42 90
    public function parse(array $tokens, array $rules, array $alias): array
43
    {
44 90
        $this->rules = $rules;
45 90
        $this->alias = $alias;
46
47 90
        $this->extractParams($tokens);
48 83
        $this->applyTypesToParams($tokens);
49 83
        $this->normalizeParam($tokens);
50
51 83
        return $tokens;
52
    }
53
54
    /**
55
     * Separate keywords from parameters.
56
     *
57
     * @param array $words
58
     */
59 90
    private function extractParams(array &$words): void
60
    {
61 90
        $array = [];
62 90
        $field = \array_shift($words);
63
64 90
        while (\count($words)) {
65 90
            $word = \strtolower($words[0]);
66
67 90
            if (isset($this->alias[$word])) {
68
                //replace the alias fo fix missing class error
69
                //when call applyTypesToParams
70 86
                $word = $words[0] = $this->alias[$word];
71 86
                $args = $this->rules[$word]['args_count'];
72
73 86
                $array[$field][] = \array_splice($words, 0, (int) ++$args);
74 86
                continue;
75
            }
76
77 7
            throw new OutOfBoundsException("Unknown filter provided for field ({$field})");
78
        }
79
80 83
        $words = $array;
81 83
    }
82
83
    /**
84
     * Apply types to rules parameters.
85
     *
86
     * @param array $words
87
     */
88 83
    private function applyTypesToParams(array &$words): void
89
    {
90 83
        $rules = $this->rules;
91 83
        $field = &$words[\key($words)];
92
93
        //needed
94 83
        $number = new Number();
95
96
        //word variable need reference for point to value
97 83
        foreach ($field as &$word) {
98 83
            $types = $rules[$word[0]]['args_type'];
99
100 83
            foreach ($types as $key => $type) {
101 58
                $param = &$word[$key + 1];
102
103 58
                if ($type === 'number') {
104 58
                    $number->sanitize($param);
105 58
                    continue;
106
                }
107
108 83
                \settype($param, $type);
109
            }
110
        }
111 83
    }
112
113
    /**
114
     * Organize rules' array.
115
     *
116
     * @param array $words
117
     */
118 83
    private function normalizeParam(array &$words): void
119
    {
120 83
        $field = \array_keys($words)[0];
121 83
        $temp = [];
122
123 83
        foreach ($words[$field] as $word) {
124 83
            $rule = $word[0];
125
126
            //remove the first element from the array
127
            //it's the name of the rule
128 83
            \array_shift($word);
129
130 83
            $temp[] = [$field, $rule, $word];
131
        }
132
133 83
        $words = $temp;
134 83
    }
135
}
136