|
3 | 3 | * UserFrosting (http://www.userfrosting.com) |
4 | 4 | * |
5 | 5 | * @link https://github.com/userfrosting/UserFrosting |
6 | | - * @copyright Copyright (c) 2013-2016 Alexander Weissman |
7 | 6 | * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License) |
8 | 7 | */ |
9 | 8 | namespace UserFrosting\Sprinkle\Core\Sprunje; |
@@ -37,11 +36,6 @@ abstract class Sprunje |
37 | 36 | */ |
38 | 37 | protected $name = ''; |
39 | 38 |
|
40 | | - /** |
41 | | - * Separator to use when splitting filter values to treat them as ORs. |
42 | | - */ |
43 | | - protected $orSeparator = '||'; |
44 | | - |
45 | 39 | /** |
46 | 40 | * @var \Illuminate\Database\Eloquent\Builder |
47 | 41 | */ |
@@ -74,6 +68,18 @@ abstract class Sprunje |
74 | 68 | */ |
75 | 69 | protected $sortable = []; |
76 | 70 |
|
| 71 | + /** |
| 72 | + * List of fields to exclude when processing an "_all" filter. |
| 73 | + * |
| 74 | + * @var array[string] |
| 75 | + */ |
| 76 | + protected $excludeForAll = []; |
| 77 | + |
| 78 | + /** |
| 79 | + * Separator to use when splitting filter values to treat them as ORs. |
| 80 | + */ |
| 81 | + protected $orSeparator = '||'; |
| 82 | + |
77 | 83 | /** |
78 | 84 | * Constructor. |
79 | 85 | * |
@@ -261,26 +267,82 @@ protected function applyFilters() |
261 | 267 | $e->addUserMessage('VALIDATE.SPRUNJE.BAD_FILTER', ['name' => $name]); |
262 | 268 | throw $e; |
263 | 269 | } |
| 270 | + // Set orFilter to 'false' to require a match on _all_ fields |
| 271 | + $this->query = $this->buildFilterQuery($this->query, $name, $value, false); |
| 272 | + } |
264 | 273 |
|
265 | | - // Determine if a custom filter method has been defined |
266 | | - $methodName = 'filter'.studly_case($name); |
| 274 | + return $this->query; |
| 275 | + } |
267 | 276 |
|
268 | | - if (method_exists($this, $methodName)) { |
269 | | - $this->query = $this->$methodName($this->query, $value); |
| 277 | + /** |
| 278 | + * Match any filter in `filterable`. |
| 279 | + * |
| 280 | + * @param Builder $query |
| 281 | + * @param mixed $value |
| 282 | + * @return Builder |
| 283 | + */ |
| 284 | + protected function filterAll($query, $value) |
| 285 | + { |
| 286 | + foreach ($this->filterable as $name) { |
| 287 | + if (studly_case($name) != 'all' && !in_array($name, $this->excludeForAll)) { |
| 288 | + $query = $this->buildFilterQuery($query, $name, $value, true); |
| 289 | + } |
| 290 | + } |
| 291 | + |
| 292 | + return $query; |
| 293 | + } |
| 294 | + |
| 295 | + /** |
| 296 | + * Build the filter query for a single field. |
| 297 | + * |
| 298 | + * @param Builder $query |
| 299 | + * @param string $name |
| 300 | + * @param mixed $value |
| 301 | + * @return Builder |
| 302 | + */ |
| 303 | + protected function buildFilterQuery($query, $name, $value, $orFilter = true) |
| 304 | + { |
| 305 | + $methodName = 'filter'.studly_case($name); |
| 306 | + |
| 307 | + // Determine if a custom filter method has been defined |
| 308 | + if (method_exists($this, $methodName)) { |
| 309 | + $query = $this->$methodName($query, $value); |
| 310 | + } else { |
| 311 | + if ($orFilter) { |
| 312 | + // Since we want to match _any_ of the fields, we wrap the field callback in a 'orWhere' callback |
| 313 | + $query = $query->orWhere(function ($fieldQuery) use ($name, $value) { |
| 314 | + return $this->buildFilterDefaultFieldQuery($fieldQuery, $name, $value); |
| 315 | + }); |
270 | 316 | } else { |
271 | | - // Split value on separator for OR queries |
272 | | - $values = explode($this->orSeparator, $value); |
273 | | - |
274 | | - $this->query = $this->query->where(function ($query) use ($name, $values) { |
275 | | - foreach ($values as $value) { |
276 | | - $query = $query->orLike($name, $value); |
277 | | - } |
278 | | - return $query; |
| 317 | + // Since we want to match _all_ of the fields, we wrap the field callback in a 'where' callback |
| 318 | + $query = $query->where(function ($fieldQuery) use ($name, $value) { |
| 319 | + return $this->buildFilterDefaultFieldQuery($fieldQuery, $name, $value); |
279 | 320 | }); |
280 | 321 | } |
281 | 322 | } |
282 | 323 |
|
283 | | - return $this->query; |
| 324 | + return $query; |
| 325 | + } |
| 326 | + |
| 327 | + /** |
| 328 | + * Perform a 'like' query on a single field, separating the value string on the or separator and |
| 329 | + * matching any of the supplied values. |
| 330 | + * |
| 331 | + * @param Builder $query |
| 332 | + * @param string $name |
| 333 | + * @param mixed $value |
| 334 | + * @return Builder |
| 335 | + */ |
| 336 | + protected function buildFilterDefaultFieldQuery($query, $name, $value) |
| 337 | + { |
| 338 | + // Default filter - split value on separator for OR queries |
| 339 | + // and search by column name |
| 340 | + $values = explode($this->orSeparator, $value); |
| 341 | + foreach ($values as $value) { |
| 342 | + $query = $query->orLike($name, $value); |
| 343 | + } |
| 344 | + |
| 345 | + return $query; |
284 | 346 | } |
285 | 347 |
|
286 | 348 | /** |
@@ -367,35 +429,4 @@ protected function countFiltered() |
367 | 429 | { |
368 | 430 | return $this->query->count(); |
369 | 431 | } |
370 | | - |
371 | | - /** |
372 | | - * Match any filter in `filterable`. |
373 | | - * |
374 | | - * @param Builder $query |
375 | | - * @param mixed $value |
376 | | - * @return Builder |
377 | | - */ |
378 | | - protected function filterAll($query, $value) |
379 | | - { |
380 | | - foreach ($this->filterable as $name) { |
381 | | - $methodName = 'filter'.studly_case($name); |
382 | | - if ($methodName != 'filterAll') { |
383 | | - $query = $query->orWhere(function ($likeQuery) use ($name, $methodName, $value) { |
384 | | - |
385 | | - if (method_exists($this, $methodName)) { |
386 | | - $likeQuery = $this->$methodName($likeQuery, $value); |
387 | | - } else { |
388 | | - // Split value on separator for OR queries |
389 | | - $values = explode($this->orSeparator, $value); |
390 | | - foreach ($values as $value) { |
391 | | - $likeQuery = $likeQuery->orLike($name, $value); |
392 | | - } |
393 | | - } |
394 | | - return $likeQuery; |
395 | | - }); |
396 | | - } |
397 | | - } |
398 | | - |
399 | | - return $query; |
400 | | - } |
401 | 432 | } |
0 commit comments