Completed
Pull Request — develop (#111)
by Patrick
02:28
created

Filter::filterElement()   B

Complexity

Conditions 10
Paths 15

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 15
nop 1
dl 0
loc 40
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Data;
3
4
class Filter
5
{
6
    protected $children = array();
7
    protected $string;
8
    protected $sqlAppend = '';
9
10
    /**
11
     * Creates a new filter object
12
     *
13
     * @param false|string $string The string to create the filter from or false for an empty filter
14
     */
15
    public function __construct($string = false)
16
    {
17
        if($string !== false)
18
        {
19
            $this->string = $string;
20
            $this->children = self::process_string($this->string);
21
        }
22
    }
23
24
    static public function process_string($string)
25
    {
26
        $parens = false;
27
        //First check for parenthesis...
28
        if($string[0] === '(' && substr($string, -1) === ')')
29
        {
30
            $string = substr($string, 1, strlen($string) - 2);
31
            $parens = true;
32
        }
33
        if(preg_match('/(.+?)( and | or )(.+)/', $string, $clauses) === 0)
34
        {
35
            return array(new FilterClause($string));
36
        }
37
        $children = array();
38
        if($parens)
39
        {
40
            array_push($children, '(');
41
        }
42
        $children = array_merge($children, self::process_string($clauses[1]));
43
        array_push($children, trim($clauses[2]));
44
        $children = array_merge($children, self::process_string($clauses[3]));
45
        if($parens)
46
        {
47
            array_push($children, ')');
48
        }
49
        return $children;
50
    }
51
52
    public function to_sql_string()
53
    {
54
        $ret = '';
55
        $count = count($this->children);
56
        for($i = 0; $i < $count; $i++)
57
        {
58
            if($this->children[$i] === '(' || $this->children[$i] === ')')
59
            {
60
                $ret .= $this->children[$i];
61
            }
62
            else if($this->children[$i] === 'and')
63
            {
64
                $ret .= ' AND ';
65
            }
66
            else if($this->children[$i] === 'or')
67
            {
68
                $ret .= ' OR ';
69
            }
70
            else
71
            {
72
                $ret .= $this->children[$i]->to_sql_string();
73
            }
74
        }
75
        return $ret.$this->sqlAppend;
76
    }
77
78
    public function to_ldap_string()
79
    {
80
        $ret = '';
81
        $count = count($this->children);
82
        $prefix = '';
83
        for($i = 0; $i < $count; $i++)
84
        {
85
            if($this->children[$i] === 'and')
86
            {
87
                if($prefix == '|')
88
                {
89
                    throw new \Exception('Do not support both and or');
90
                }
91
                $prefix = '&';
92
            }
93
            else if($this->children[$i] === 'or')
94
            {
95
                if($prefix == '&')
96
                {
97
                    throw new \Exception('Do not support both and or');
98
                }
99
                $prefix = '|';
100
            }
101
            else
102
            {
103
                $ret .= $this->children[$i]->to_ldap_string();
104
            }
105
        }
106
        if($count === 1 && $prefix === '')
107
        {
108
            return $ret;
109
        }
110
        return '('.$prefix.$ret.')';
111
    }
112
113
    public function to_mongo_filter()
114
    {
115
        $ret = array();
116
        $count = count($this->children);
117
        for($i = 0; $i < $count; $i++)
118
        {
119
            if($this->children[$i] === 'and')
120
            {
121
                $old = array_pop($ret);
122
                array_push($ret, array('$and'=>array($old, $this->children[++$i]->toMongoFilter())));
123
            }
124
            else if($this->children[$i] === 'or')
125
            {
126
                $old = array_pop($ret);
127
                array_push($ret, array('$or'=>array($old, $this->children[++$i]->toMongoFilter())));
128
            }
129
            else
130
            {
131
                array_push($ret, $this->children[$i]->toMongoFilter());
132
            }
133
        }
134
        if(count($ret) == 1 && is_array($ret[0]))
135
        {
136
            return $ret[0];
137
        }
138
        return $ret;
139
    }
140
141
    public function filterElement($element)
142
    {
143
        $res = array();
144
        $count = count($this->children);
145
	for($i = 0; $i < $count; $i++)
146
	{
147
            if($this->children[$i] === 'and' || $this->children[$i] === 'or')
148
	    {
149
                array_push($res, $this->children[$i]);
150
	    }
151
	    else
152
	    {
153
                $tmp = $this->children[$i]->php_compare($element);
154
		array_push($res, $tmp);
155
	    }
156
	}
157
	if($count === 1)
158
	{
159
            return $res[0];
160
	}
161
	while($count >= 3)
162
	{
163
	    if($res[1] === 'and')
164
            {
165
                $var1 = array_shift($res);
166
                array_shift($res);
167
                $var2 = array_shift($res);
168
	        $res = array_merge(array($var1 && $var2), $res);
169
            }
170
	    else if($res[1] === 'or')
171
            {
172
                $var1 = array_shift($res);
173
                array_shift($res);
174
                $var2 = array_shift($res);
175
                $res = array_merge(array($var1 || $var2), $res);
176
	    }
177
	    $count = count($res);
178
	}
179
        return $res[0];
180
    }
181
182
    public function filter_array(&$array)
183
    {
184
        if(is_array($array))
185
	{
186
            return array_filter($array, array($this, 'filterElement'));
187
        }
188
        return array();
189
    }
190
191
    public function contains($substr)
192
    {
193
        return strstr($this->string, $substr) !== false;
194
    }
195
196
    public function getClause($substr)
197
    {
198
        $count = count($this->children);
199
        for($i = 0; $i < $count; $i++)
200
        {
201
            if(!is_object($this->children[$i]))
202
            {
203
                continue;
204
            }
205
            if(strstr($this->children[$i]->var1, $substr) !== false ||
206
               strstr($this->children[$i]->var2, $substr) !== false)
207
            {
208
                return $this->children[$i];
209
            }
210
        }
211
    }
212
213
    public function addToSQLString($string)
214
    {
215
        $this->sqlAppend .= $string;
216
    }
217
218
    public function appendChild($child)
219
    {
220
        if($child === 'and' || $child === 'or')
221
        {
222
            array_push($this->children, $child);
223
            return;
224
        }
225
        else if(is_a($child, '\Data\Filter'))
226
        {
227
            $this->children = array_merge($this->children, $child->children);
228
        }
229
        else
230
        {
231
            $this->children = array_merge($this->children, self::process_string($child));
232
        }
233
    }
234
235
    public function getChildren()
236
    {
237
        return $this->children;
238
    }
239
}
240