Passed
Push — master ( 8a769b...ec7f33 )
by Patrick
01:56
created

RuleUtils   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 55
c 2
b 0
f 0
dl 0
loc 166
rs 10
wmc 23

7 Methods

Rating   Name   Duplication   Size   Complexity  
B parse_parenthesis() 0 29 8
A get_number() 0 14 3
A get_group() 0 7 1
A eval_getNext() 0 12 4
A get_string() 0 8 1
A get_function() 0 19 4
A check_negate_first() 0 10 2
1
<?php
2
3
/**
4
 * Rule evaluation utilities
5
 *
6
 * @license GPL
7
 * @author Patrick Proy
8
 * @package trapdirector
9
 * @subpackage Processing
10
 *
11
 */
12
trait RuleUtils
13
{
14
    
15
    /** rule eval starting from $token
16
     * @param string $rule
17
     * @param int $item
18
     */
19
    abstract public function evaluation($rule,&$item);
20
21
    /**
22
     * Get full number
23
     * @param string $rule Rule as string
24
     * @param int $item current eval position
25
     * @return array<int,string>
26
     */
27
    private function get_number(string $rule,int &$item)
28
    {
29
        $item2=$item+1;
30
        while (
31
            ($item2!=strlen($rule))
32
            && (preg_match('/[\-0-9\.]/',$rule[$item2])))
33
        {
34
            $item2++ ;
35
        }
36
        $val=substr($rule,$item,$item2-$item);
37
        $item=$item2;
38
        //echo "number ".$val."\n";
39
        
40
        return array(0,$val);
41
    }
42
43
    /**
44
     * Get a string (between ") 
45
     * @param string $rule Rule as string
46
     * @param int $item current eval position
47
     * @return array<int,string>
48
     */
49
    private function get_string(string $rule,int &$item)
50
    {
51
        $item++;
52
        $item2=$this->eval_getNext($rule,$item,'"');
53
        $val=substr($rule,$item,$item2-$item-1);
54
        $item=$item2;
55
        //echo "string : ".$val."\n";
56
        return array(1,$val);
57
        
58
    }
59
    
60
    /**
61
     * Parse elements inside () : jumps over "" and count parenthesis.
62
     * Ex : ( "test" != ")test" & (1==2) ) will return "test" != ")test" & (1==2)
63
     * @param string $rule : the current rule
64
     * @param int $item : actual position in rule
65
     * @throws Exception
66
     * @return string : everything inside parenthesis
67
     */
68
    private function parse_parenthesis(string $rule,int &$item) : string
69
    {
70
        $item++;
71
        $start=$item;
72
        $parenthesisCount=0;
73
        while (($item < strlen($rule)) // Not end of string AND
74
            && ( ($rule[$item] != ')' ) || $parenthesisCount > 0) ) // Closing ')' or embeded ()
75
        {
76
            if ($rule[$item] == '"' )
77
            { // pass through string
78
                $item++;
79
                $item=$this->eval_getNext($rule,$item,'"');
80
                continue;
81
            }
82
            if ($rule[$item] == '(')
83
            {
84
                $parenthesisCount++;
85
            }
86
            if ($rule[$item] == ')')
87
            {
88
                $parenthesisCount--;
89
            }
90
            $item++;
91
        }
92
        
93
        if ($item==strlen($rule)) {throw new Exception("no closing () in ".$rule ." at " .$item);}
0 ignored issues
show
Bug introduced by
Are you sure $item of type array<integer,string>|integer can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
        if ($item==strlen($rule)) {throw new Exception("no closing () in ".$rule ." at " ./** @scrutinizer ignore-type */ $item);}
Loading history...
94
        $val=substr($rule,$start,$item-$start);
95
        $item++;
96
        return $val;
97
    }
98
99
    /**
100
     * Get and eval a grouped condition - ex : (1==1)
101
     * @param string $rule
102
     * @param int $item
103
     * @return array<int,string>
104
     */
105
    private function get_group(string $rule,int &$item) : array
106
    {
107
        // gets eveything inside parenthesis
108
        $val=$this->parse_parenthesis($rule, $item);
109
        // Returns boolean with evaluation of all inside parenthesis
110
        $start=0;
111
        return array(2,$this->evaluation($val,$start));
112
    }
113
    
114
    /**
115
     * @param string $rule
116
     * @param int $item
117
     * @throws Exception
118
     * @return array<int,string>
119
     */
120
    private function get_function(string $rule,int &$item) : array
121
    {
122
        // function is : __function(param1,param2...)
123
        $start=$item;
124
        while (($item < strlen($rule)) && ($rule[$item] != '(' )) // Not end of string AND not opening '('
125
        {
126
            $item++;
127
        }
128
        if ($item==strlen($rule)) {throw new Exception("no opening () for function in ".$rule ." at " .$item);}
129
        
130
        // get parameters between parenthesis
131
        
132
        $this->parse_parenthesis($rule, $item);
133
        
134
        $val=substr($rule,$start,$item-$start);
135
        
136
        $this->logging->log('got function ' . $val,DEBUG);
137
        
138
        return array(2,$this->trapClass->pluginClass->evaluateFunctionString($val));
139
        
140
    }
141
142
    /** Find next token $tok in $rule starting at $item 
143
     * @param string $rule
144
     * @param int $item
145
     * @param string $tok : token to search for
146
     * @throws Exception
147
     * @return array<int,string>
148
     */
149
    protected function eval_getNext(string $rule,int $item,string $tok)
150
    {
151
        while (
152
            ($rule[$item] != $tok )
153
            && ($item < strlen($rule)))
154
        {
155
            $item++;
156
        }
157
        if ($item==strlen($rule)) {
158
            throw new Exception("closing '".$tok."' not found in ".$rule ." at " .$item);
159
        }
160
        return $item+1;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $item + 1 returns the type integer which is incompatible with the documented return type array<integer,string>.
Loading history...
161
    }
162
163
    /** get negate (!) and return true if found - and pass it with item++ - 
164
     * @param string $rule
165
     * @param int $item
166
     * @return boolean
167
     */
168
    private function check_negate_first(string $rule,int &$item)
169
    {
170
        if ( $rule[$item] == '!') // If '!' found, negate next expression.
171
        {
172
            $item++;
173
            return true;
174
        }
175
        else
176
        {
177
            return false;
178
        }
179
    }
180
    
181
}