Completed
Push — master ( 9bd6a3...c44643 )
by Patrick
03:49
created

FilterClause::odataOpToStd()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 16
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 20
rs 8.2222
1
<?php
2
namespace Data;
3
4
class FilterClause
5
{
6
    public $var1;
7
    public $var2;
8
    public $op;
9
10
    function __construct($string = false)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
11
    {
12
        if($string !== false)
13
        {
14
            $this->process_filter_string($string);
0 ignored issues
show
Documentation introduced by
$string is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
15
        }
16
    }
17
18
    /**
19
     * Find the string inside the other string
20
     *
21
     * @param string $haystack The string to search inside
22
     * @param string $needle The string to search for
23
     *
24
     * @return boolean True if the needle exists in the haystack, false otherwise
25
     */
26
    static function str_startswith($haystack, $needle)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
27
    {
28
        return substr($haystack, 0, strlen($needle)) === $needle;
29
    }
30
31
    protected function filterIsFunction($string)
32
    {
33
        return (self::str_startswith($string, 'substringof') || self::str_startswith($string, 'contains') ||
34
                self::str_startswith($string, 'indexof'));
35
    }
36
37
    protected function odataOpToStd($op)
38
    {
39
        switch($op)
40
        {
41
            case 'ne':
42
                return '!=';
43
            case 'eq':
44
                return '=';
45
            case 'lt':
46
                return '<';
47
            case 'le':
48
                return '<=';
49
            case 'gt':
50
                return '>';
51
            case 'ge':
52
                return '>=';
53
            default:
54
                return $op;
55
        }
56
    }
57
58
    /**
59
     * Convert the string into an OData Filter
60
     *
61
     * @param string $string The string to turn into a filter
62
     */
63
    protected function process_filter_string($string)
64
    {
65
        if($this->filterIsFunction($string))
66
        {
67
            $this->op   = strtok($string, '(');
68
            $this->var1 = strtok(',');
69
            $this->var2 = trim(strtok(')'));
70
            return;
71
        }
72
        $field = strtok($string, ' ');
73
        $op = strtok(' ');
74
        $rest = strtok("\0");
75
        $this->var1  = $field;
76
        $this->op    = $this->odataOpToStd($op);
77
        $this->var2  = $rest;
78
    }
79
80
    public function to_sql_string()
81
    {
82
        switch($this->op)
83
        {
84
            case 'substringof':
85
            case 'contains':
86
                return $this->var1.' LIKE \'%'.trim($this->var2, "'").'%\'';
87
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
88
            default:
89
                return $this->var1.$this->op.$this->var2;
90
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
91
        }
92
    }
93
94
    public function to_ldap_string()
95
    {
96
        $str = '(';
97
        switch($this->op)
98
        {
99
            case 'substringof':
100
            case 'contains':
101
                $str .= $this->var1.$this->op.'*'.trim($this->var2, "'").'*';
102
                break;
103
            case '!=':
104
                $str .= '!('.$this->var1.'='.$this->var2.')';
105
                break;
106
            default:
107
                $str .= $this->var1.$this->op.$this->var2;
108
                break;
109
        }
110
        return $str.')';
111
    }
112
113
    public function to_mongo_filter()
114
    {
115
        $this->var2 = trim($this->var2, "'");
116
        if($this->var1 === '_id')
117
        {
118
            $this->var2 = new \MongoId($this->var2);
119
        }
120
        switch($this->op)
121
        {
122
            case '!=':
123
                return array($this->var1=>array('$ne'=>$this->var2));
124
            case '=':
125
                return array($this->var1=>$this->var2);
126
            case '<';
127
                return array($this->var1=>array('$lt'=>$this->var2));
128
            case '<=':
129
                return array($this->var1=>array('$lte'=>$this->var2));
130
            case '>':
131
                return array($this->var1=>array('$gt'=>$this->var2));
132
            case '>=':
133
                return array($this->var1=>array('$gte'=>$this->var2));
134
            case 'substringof':
135
                return array($this->var1=>array('$regex'=>new MongoRegex('/'.$this->var2.'/i')));
136
            case 'indexof':
137
                $field = $this->var1;
138
                $case  = false;
139
                if(self::str_startswith($this->var1, 'tolower'))
140
                {
141
                    $field = substr($this->var1, strpos($this->var1, '(') + 1);
142
                    $field = substr($field, 0, strpos($field, ')'));
143
                    $case = true;
144
                }
145
                if($case)
146
                {
147
                    return array($field=>array('$regex'=>new \MongoRegex('/'.$this->var2.'/i')));
148
                }
149
                else
150
                {
151
                    return array($field=>$this->var2);
152
                }
153
        }
154
    }
155
156
    function php_compare($value)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
157
    {
158
        switch($this->op)
159
        {
160
            case '!=':
161
                return $value != $this->var2;
162
            case '=':
163
                return $value == $this->var2;
164
            case '<':
165
                return $value < $this->var2;
166
            case '<=':
167
                return $value <= $this->var2;
168
            case '>':
169
                return $value > $this->var2;
170
            case '>=':
171
                return $value >= $this->var2;
172
        }
173
    }
174
}
175