1 <?php
2
3 4 5 6 7 8
9
10 11 12 13 14 15
16 class AfRangeFilter extends AfBaseFilter
17 {
18 19 20
21 public $betweenPrefix = '';
22
23 24 25
26 public $betweenInfix = ' to ';
27
28 29 30
31 public $betweenSuffix = '';
32
33 34 35
36 public $lessThanPrefix = '<';
37
38 39 40
41 public $lessThanSuffix = '';
42
43
44 45 46
47 public $lessThanEqualPrefix = '<=';
48
49 50 51
52 public $lessThanEqualSuffix = '';
53
54
55 56 57
58 public $greaterThanPrefix = '>';
59
60 61 62
63 public $greaterThanSuffix = '';
64
65
66 67 68
69 public $greaterThanEqualPrefix = '>=';
70
71 72 73
74 public $greaterThanEqualSuffix = '';
75
76
77 78 79
80 public $equalPrefix = '=';
81
82 83 84
85 public $equalSuffix = '';
86
87 88 89 90
91 public $numberPattern = '-?\\d*\\.?\\d+';
92
93 94 95 96 97 98
99 public $conversionNumDigits = 20;
100
101 102 103 104 105 106
107 public $conversionDecimalPlaces = 4;
108
109 110 111 112 113
114 public $treatNonNumericValuesAsZero = false;
115
116 private $startOfRange;
117 private $endOfRange;
118 private $rangeIsInclusive = true;
119
120 121 122 123 124 125 126 127
128 protected function getColumnExpression()
129 {
130 $columnExpression = parent::getColumnExpression();
131
132 $nonNumericResultValue = $this->treatNonNumericValuesAsZero ? 0 : null;
133
134 return $this->getDbHelper()->convertExpressionToDecimal(
135 $columnExpression, $this->conversionNumDigits,
136 $this->conversionDecimalPlaces, $nonNumericResultValue);
137 }
138
139 140 141 142 143 144
145 public function acceptsFilterExpression()
146 {
147 return $this->parseExpression();
148 }
149
150 151 152 153 154
155 public function getCriteria()
156 {
157 $this->parseExpression();
158
159 $criteria = new CDbCriteria;
160
161 $column = $this->columnExpression;
162
163 $hash = md5($this->filterExpression . $this->columnExpression);
164 $startParam = ':rangeStart' . $hash;
165 $endParam = ':rangeEnd' . $hash;
166
167 if ($this->startOfRange !== null)
168 {
169 $operator = $this->rangeIsInclusive
170 ? ($this->invertLogic ? '<' : '>=')
171 : ($this->invertLogic ? '<=' : '>');
172
173 $criteria->addCondition("$column $operator $startParam");
174 $criteria->params[$startParam] = $this->startOfRange;
175 }
176
177 if ($this->endOfRange !== null)
178 {
179 $operator = $this->rangeIsInclusive
180 ? ($this->invertLogic ? '>' : '<=')
181 : ($this->invertLogic ? '>=' : '<');
182
183
184 $mergeType = $this->invertLogic ? 'OR' : 'AND';
185
186 $criteria->addCondition("$column $operator $endParam",
187 $mergeType);
188 $criteria->params[$endParam] = $this->endOfRange;
189 }
190
191 return $criteria;
192 }
193
194 private $_expressionAccepted;
195 private function parseExpression()
196 {
197
198 if ($this->_expressionAccepted !== null)
199 return $this->_expressionAccepted;
200
201 $this->_expressionAccepted = true;
202
203 $expression = $this->filterExpression;
204
205
206 $betweenMatches = array();
207
208 if (preg_match($this->getBetweenPattern(), $expression,
209 $betweenMatches))
210 {
211 $this->startOfRange = $betweenMatches[1];
212 $this->endOfRange = $betweenMatches[2];
213 return $this->_expressionAccepted;
214 }
215
216
217 $matches = array();
218
219 if (preg_match($this->getLessThanPattern(), $expression, $matches))
220 {
221 $this->endOfRange = $matches[1];
222 $this->rangeIsInclusive = false;
223 }
224 else if (preg_match($this->getLessThanEqualPattern(), $expression,
225 $matches))
226 {
227 $this->endOfRange = $matches[1];
228 }
229 else if (preg_match($this->getGreaterThanPattern(), $expression,
230 $matches))
231 {
232 $this->startOfRange = $matches[1];
233 $this->rangeIsInclusive = false;
234 }
235 else if (preg_match($this->getGreaterThanEqualPattern(), $expression,
236 $matches))
237 {
238 $this->startOfRange = $matches[1];
239 }
240 else if (preg_match($this->getEqualPattern(), $expression, $matches))
241 {
242 $this->startOfRange = $matches[1];
243 $this->endOfRange = $matches[1];
244 }
245 else
246 {
247 $this->_expressionAccepted = false;
248 }
249
250 return $this->_expressionAccepted;
251 }
252
253 private function getBetweenPattern()
254 {
255 return '/^'
256 . preg_quote($this->betweenPrefix, '/')
257 . '\\s*(' . $this->numberPattern . ')\\s*'
258 . preg_quote($this->betweenInfix, '/')
259 . '\\s*(' . $this->numberPattern . ')\\s*'
260 . preg_quote($this->betweenSuffix, '/')
261 . '$/i';
262 }
263
264 private function getLessThanPattern()
265 {
266 return '/^'
267 . preg_quote($this->lessThanPrefix, '/')
268 . '\\s*(' . $this->numberPattern . ')\\s*'
269 . preg_quote($this->lessThanSuffix, '/')
270 . '$/i';
271 }
272
273 private function getLessThanEqualPattern()
274 {
275 return '/^'
276 . preg_quote($this->lessThanEqualPrefix, '/')
277 . '\\s*(' . $this->numberPattern . ')\\s*'
278 . preg_quote($this->lessThanEqualSuffix, '/')
279 . '$/i';
280 }
281
282 private function getGreaterThanPattern()
283 {
284 return '/^'
285 . preg_quote($this->greaterThanPrefix, '/')
286 . '\\s*(' . $this->numberPattern . ')\\s*'
287 . preg_quote($this->greaterThanSuffix, '/')
288 . '$/i';
289 }
290
291 private function getGreaterThanEqualPattern()
292 {
293 return '/^'
294 . preg_quote($this->greaterThanEqualPrefix, '/')
295 . '\\s*(' . $this->numberPattern . ')\\s*'
296 . preg_quote($this->greaterThanEqualSuffix, '/')
297 . '$/i';
298 }
299
300 private function getEqualPattern()
301 {
302 return '/^'
303 . preg_quote($this->equalPrefix, '/')
304 . '\\s*(' . $this->numberPattern . ')\\s*'
305 . preg_quote($this->equalSuffix, '/')
306 . '$/i';
307 }
308 }
309