Completed
Push — master ( 629593...731a14 )
by Patrick
02:15
created

Filter::contains()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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