DBWhere   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Test Coverage

Coverage 98.18%

Importance

Changes 3
Bugs 1 Features 2
Metric Value
eloc 73
c 3
b 1
f 2
dl 0
loc 202
ccs 54
cts 55
cp 0.9818
rs 10
wmc 28

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __get() 0 11 2
A __set() 0 13 2
A __construct() 0 15 1
F __toString() 0 59 23
1
<?php
2
namespace Godsgood33\Php_Db;
3
4
use InvalidArgumentException;
5
6
/**
7
 * Class to create a where clause
8
 *
9
 * @property int $index Index of the current object
10
 * @property string $field Name of the field to put in the clause
11
 * @property mixed $value Value of the field
12
 * @property float $low Low value to put in a BETWEEN clause
13
 * @property float $high High value to put in a BETWEEN clause
14
 * @property bool $escape Decide if you want to escape the value
15
 * @property string $sqlOperator What operation do you want to compare the field value to (=, !=, <, etc)
16
 * @property bool $backticks Do you want to put backticks around the field name
17
 * @property bool $openParen Do you want this clause to start with an open paren
18
 * @property bool $closeParen Do you want this clause to end with a close paren
19
 * @property bool $caseInsensitive Is this clause supposed to be case insensitive
20
 *
21
 * @author Ryan Prather <[email protected]>
22
 */
23
class DBWhere
24
{
25
26
    /**
27
     * Global to represent an IN statement (e.g.
28
     * WHERE field IN (1,2))
29
     *
30
     * @var string
31
     */
32
    public const IN = 'IN';
33
34
    /**
35
     * Global to represent a NOT IN statement (e.g.
36
     * WHERE field NOT IN (1,2))
37
     *
38
     * @var string
39
     */
40
    public const NOT_IN = 'NOT IN';
41
42
    /**
43
     * Global to represent a BETWEEN statement (e.g.
44
     * WHERE field BETWEEN 1 and 2)
45
     *
46
     * @var string
47
     */
48
    public const BETWEEN = 'BETWEEN';
49
50
    /**
51
     * Global to represent a LIKE statement (e.g.
52
     * WHERE field LIKE '%value%')
53
     *
54
     * @var string
55
     */
56
    public const LIKE = 'LIKE';
57
58
    /**
59
     * Global to represent a NOT LIKE statement (e.g.
60
     * WHERE field NOT LIKE '%value%')
61
     *
62
     * @var string
63
     */
64
    public const NOT_LIKE = 'NOT LIKE';
65
66
    /**
67
     * Global to represent an IS statement (e.g.
68
     * WHERE field IS NULL)
69
     *
70
     * @var string
71
     */
72
    public const IS = 'IS';
73
74
    /**
75
     * Global to represent an IS NOT statement (e.g.
76
     * WHERE field IS NOT NULL)
77
     *
78
     * @var string
79
     */
80
    public const IS_NOT = 'IS NOT';
81
82
    /**
83
     * Array to store the necessary class variables
84
     *
85
     * @var array
86
     */
87
    protected $data = [];
88
89
    /**
90
     * Constructor
91
     *
92
     * @param string $field
93
     * @param mixed $value
94
     * @param string $operator
95
     */
96 37
    public function __construct($field = null, $value = null, $operator = '=')
97
    {
98 37
        $this->data = [
99 37
            'index' => 0,
100 37
            'field' => $field,
101 37
            'value' => $value,
102
            'low' => null,
103
            'high' => null,
104
            'escape' => true,
105 37
            'operator' => $operator,
106 37
            'sqlOperator' => 'AND',
107
            'backticks' => true,
108
            'openParen' => false,
109
            'closeParen' => false,
110
            'caseInsensitive' => false
111
        ];
112 37
    }
113
114
    /**
115
     * Method to return the variables
116
     *
117
     * @param string $var
118
     *
119
     * @return mixed
120
     *
121
     * @throws InvalidArgumentException
122
     */
123 19
    public function __get($var)
124
    {
125 19
        if(!in_array($var, [
126 19
            'index', 'field', 'value', 'low', 'high', 'operator', 'backticks',
127
            'sqlOperator', 'escape', 'openParen', 'closeParen', 'caseInsensitive'
128
        ])) {
129 1
            $trace = \debug_backtrace();
130 1
            throw new InvalidArgumentException("Property not allowed via __get():  $var in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_WARNING);
131
        }
132
133 18
        return $this->data[$var];
134
    }
135
136
    /**
137
     * Method to set a variable
138
     *
139
     * @param string $name
140
     * @param mixed $value
141
     *
142
     * @throws InvalidArgumentException
143
     *
144
     * @return DBWhere
145
     */
146 23
    public function __set($name, $value)
147
    {
148 23
        if(!in_array($name, [
149 23
            'index', 'field', 'value', 'low', 'high', 'operator', 'backticks',
150
            'sqlOperator', 'escape', 'openParen', 'closeParen', 'caseInsensitive'
151
        ])) {
152 1
            $trace = \debug_backtrace();
153 1
            throw new InvalidArgumentException("Property not allowed via __set():  $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_WARNING);
154
        }
155
156 22
        $this->data[$name] = $value;
157
158 22
        return $this;
159
    }
160
161
    /**
162
     * Method to parse where clauses and convert class to string
163
     *
164
     * @return string
165
     */
166 33
    public function __toString(): string
167
    {
168 33
        $ret = '';
169
170 33
        if (is_null($this->data['field']) && isset($this->data['closeParen']) && $this->data['closeParen']) {
171 1
            $ret .= ")";
172 1
            return $ret;
173
        }
174
175 32
        switch ($this->data['operator']) {
176 32
            case self::BETWEEN:
177 2
                if (! isset($this->data['field']) || ! isset($this->data['low']) || ! isset($this->data['high'])) {
178 1
                    return '';
179
                }
180 1
                break;
181
            default:
182 30
                if (! $this->data['field']) {
183 1
                    return '';
184
                }
185
        }
186
187 30
        if ($this->data['openParen']) {
188 1
            $ret .= " (";
189
        }
190
191 30
        if (! $this->data['backticks']) {
192 1
            $field = $this->data['field'];
193
        } else {
194 29
            $field = "`{$this->data['field']}`";
195
        }
196
197 30
        if ($this->data['operator'] == self::IN || $this->data['operator'] == self::NOT_IN) {
198 4
            if (is_string($this->data['value'])) {
199 2
                $ret .= " {$field} {$this->data['operator']} " . (strpos($this->data['value'], '(') !== false ? $this->data['value'] : "({$this->data['value']})");
200 2
            } elseif (is_array($this->data['value'])) {
201 2
                $ret .= " {$field} {$this->data['operator']} (" . implode(",", $this->data['value']) . ")";
202
            } else {
203
                return '';
204
            }
205 26
        } elseif ($this->data['operator'] == self::BETWEEN) {
206 1
            $low = (is_string($this->data['low']) ? "'{$this->data['low']}'" : $this->data['low']);
207 1
            $high = (is_string($this->data['high']) ? "'{$this->data['high']}'" : $this->data['high']);
208
209 1
            $ret .= " {$field} BETWEEN {$low} AND {$high}";
210
        } else {
211 25
            $value = (is_null($this->data['value']) ? "NULL" : $this->data['value']);
212
213 25
            if ($this->data['caseInsensitive']) {
214 1
                $ret .= " LOWER({$field}) {$this->data['operator']} LOWER({$value})";
215
            } else {
216 24
                $ret .= " {$field} {$this->data['operator']} {$value}";
217
            }
218
        }
219
220 30
        if (isset($this->data['closeParen']) && $this->data['closeParen']) {
221 1
            $ret .= ")";
222
        }
223
224 30
        return $ret;
225
    }
226
}