1: <?php
2:
3: namespace Charcoal\Source;
4:
5: use \InvalidArgumentException;
6:
7:
8: use \Charcoal\Source\FilterInterface;
9:
10: 11: 12:
13: class Filter implements FilterInterface
14: {
15: const DEFAULT_OPERATOR = '=';
16: const DEFAULT_FUNC = '';
17: const DEFAULT_OPERAND = 'AND';
18: const DEFAULT_TABLE_NAME = 'objTable';
19:
20: 21: 22:
23: protected $property;
24: 25: 26:
27: protected $val;
28:
29: 30: 31:
32: protected $operator = self::DEFAULT_OPERATOR;
33: 34: 35:
36: protected $func = self::DEFAULT_FUNC;
37: 38: 39:
40: protected $operand = self::DEFAULT_OPERAND;
41:
42: 43: 44:
45: protected $tableName = self::DEFAULT_TABLE_NAME;
46:
47: 48: 49: 50: 51:
52: protected $string;
53:
54: 55: 56: 57:
58: protected $active;
59:
60: 61: 62: 63:
64: public function setData(array $data)
65: {
66: if (isset($data['property'])) {
67: $this->setProperty($data['property']);
68: }
69:
70: if (isset($data['val'])) {
71: $this->setVal($data['val']);
72: }
73:
74: if (isset($data['operator'])) {
75: $this->setOperator($data['operator']);
76: }
77:
78: if (isset($data['func'])) {
79: $this->setFunc($data['func']);
80: }
81:
82: if (isset($data['operand'])) {
83: $this->setOperand($data['operand']);
84: }
85:
86: if (isset($data['table_name'])) {
87: $this->setTableName($data['table_name']);
88: }
89:
90: if (isset($data['string'])) {
91: $this->setString($data['string']);
92: }
93:
94: if (isset($data['active'])) {
95: $this->setActive($data['active']);
96: }
97:
98: return $this;
99: }
100:
101: 102: 103: 104: 105:
106: public function setProperty($property)
107: {
108: if (!is_string($property)) {
109: throw new InvalidArgumentException(
110: 'Property must be a string.'
111: );
112: }
113: if ($property == '') {
114: throw new InvalidArgumentException(
115: 'Property can not be empty.'
116: );
117: }
118:
119: $this->property = $property;
120: return $this;
121: }
122:
123: 124: 125:
126: public function property()
127: {
128: return $this->property;
129: }
130:
131: 132: 133: 134:
135: public function setVal($val)
136: {
137: $this->val = $this->parseVal($val);
138:
139: return $this;
140: }
141:
142: 143: 144:
145: public function val()
146: {
147: return $this->val;
148: }
149:
150: 151: 152: 153: 154: 155:
156: public function parseVal($val)
157: {
158: if ($val instanceof \DateTimeInterface) {
159: $val = $val->format('Y-m-d H:i:s');
160: } elseif ($val instanceof \Charcoal\Property\DateTimeProperty) {
161: $val = $val->storageVal($this->val());
162: } elseif (is_string($val)) {
163: if ($val === 'true') {
164: $val = true;
165: } elseif ($val === 'false') {
166: $val = false;
167: }
168: }
169:
170: return $val;
171: }
172:
173: 174: 175: 176: 177:
178: public function setOperator($operator)
179: {
180: if (!is_string($operator)) {
181: throw new InvalidArgumentException(
182: 'Operator should be a string.'
183: );
184: }
185:
186: $operator = strtoupper($operator);
187: if (!in_array($operator, $this->validOperators())) {
188: throw new InvalidArgumentException(
189: 'This is not a valid operator.'
190: );
191: }
192:
193: $this->operator = $operator;
194: return $this;
195: }
196:
197: 198: 199:
200: public function operator()
201: {
202: return strtoupper($this->operator);
203: }
204:
205: 206: 207: 208: 209:
210: public function setFunc($func)
211: {
212: if (!is_string($func)) {
213: throw new InvalidArgumentException(
214: 'Func should be astring.'
215: );
216: }
217:
218: $func = strtoupper($func);
219: if (!in_array($func, $this->validFunc())) {
220: throw new InvalidArgumentException(
221: 'This is not a valid function.'
222: );
223: }
224: $this->func = $func;
225: return $this;
226: }
227:
228: 229: 230:
231: public function func()
232: {
233: return $this->func;
234: }
235:
236: 237: 238: 239: 240:
241: public function setOperand($operand)
242: {
243: if (!is_string($operand)) {
244: throw new InvalidArgumentException(
245: 'Operand should be a string.'
246: );
247: }
248:
249: $operand = strtoupper($operand);
250: if (!in_array($operand, $this->validOperands())) {
251: throw new InvalidArgumentException(
252: 'This is not a valid operand.'
253: );
254: }
255:
256: $this->operand = $operand;
257: return $this;
258: }
259:
260: 261: 262:
263: public function operand()
264: {
265: return strtoupper($this->operand);
266: }
267:
268: 269: 270: 271: 272:
273: public function setTableName($tableName)
274: {
275: if (!is_string($tableName)) {
276: throw new InvalidArgumentException(
277: 'TableName should be a string.'
278: );
279: }
280:
281: $this->tableName = $tableName;
282: return $this;
283: }
284:
285: 286: 287:
288: public function tableName()
289: {
290: return $this->tableName;
291: }
292:
293: 294: 295: 296: 297:
298: public function setString($sql)
299: {
300: if (!is_string($sql)) {
301: throw new InvalidArgumentException(
302: 'Custom SQL clause should be a string.'
303: );
304: }
305:
306: $this->string = $sql;
307:
308: return $this;
309: }
310:
311: 312: 313:
314: public function string()
315: {
316: return $this->string;
317: }
318:
319: 320: 321: 322:
323: public function setActive($active)
324: {
325: $this->active = !!$active;
326: return $this;
327: }
328:
329: 330: 331:
332: public function active()
333: {
334: return $this->active;
335: }
336:
337:
338:
339: 340: 341: 342: 343:
344: protected function validOperators()
345: {
346: $validOperators = [
347: '=', 'IS', '!=', 'IS NOT',
348: 'LIKE', 'NOT LIKE',
349: 'FIND_IN_SET',
350: '>', '>=', '<', '<=',
351: 'IS NULL', 'IS NOT NULL',
352: '%', 'MOD',
353: 'IN','NOT IN',
354: 'REGEXP', 'NOT REGEXP'
355: ];
356:
357: return $validOperators;
358: }
359:
360: 361: 362: 363: 364:
365: protected function validOperands()
366: {
367: $validOperands = [
368: 'AND', '&&',
369: 'OR', '||',
370: 'XOR'
371: ];
372:
373: return $validOperands;
374: }
375:
376: 377: 378: 379:
380: protected function validFunc()
381: {
382: $validFunctions = [
383: 'ABS',
384: 'ACOS', 'ASIN', 'ATAN',
385: 'COS', 'COT', 'SIN', 'TAN',
386: 'CEIL', 'CEILING', 'FLOOR', 'ROUND',
387: 'CHAR_LENGTH', 'CHARACTER_LENGTH', 'LENGTH', 'OCTET_LENGTH',
388: 'CRC32', 'MD5', 'SHA1',
389: 'DATE',
390: 'DAY', 'DAYNAME', 'DAYOFMONTH', 'DAYOFWEEK', 'DAYOFYEAR', 'LAST_DAY',
391: 'MONTH', 'MONTHNAME',
392: 'WEEK', 'WEEKDAY', 'WEEKOFYEAR', 'YEARWEEK',
393: 'YEAR',
394: 'QUARTER',
395: 'FROM_UNIXTIME',
396: 'HOUR', 'MICROSECOND', 'MINUTE', 'SECOND', 'TIME',
397: 'TIMESTAMP', 'UNIX_TIMESTAMP',
398: 'DEGREES', 'RADIANS',
399: 'EXP', 'LOG', 'LOG10', 'LN',
400: 'HEX',
401: 'LCASE', 'LOWER', 'UCASE', 'UPPER',
402: 'LTRIM', 'RTRIM', 'TRIM',
403: 'REVERSE',
404: 'SIGN',
405: 'SQRT'
406: ];
407:
408: return $validFunctions;
409: }
410: }
411: