-
-
Notifications
You must be signed in to change notification settings - Fork 403
/
Copy pathFiltersPartial.php
83 lines (67 loc) · 2.49 KB
/
FiltersPartial.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
namespace Spatie\QueryBuilder\Filters;
use Illuminate\Database\Eloquent\Builder;
/**
* @template TModelClass of \Illuminate\Database\Eloquent\Model
* @template-implements \Spatie\QueryBuilder\Filters\Filter<TModelClass>
*/
class FiltersPartial extends FiltersExact implements Filter
{
/** {@inheritdoc} */
public function __invoke(Builder $query, $value, string $property)
{
if ($this->addRelationConstraint) {
if ($this->isRelationProperty($query, $property)) {
$this->withRelationConstraint($query, $value, $property);
return;
}
}
$wrappedProperty = $query->getQuery()->getGrammar()->wrap($query->qualifyColumn($property));
$databaseDriver = $this->getDatabaseDriver($query);
if (is_array($value)) {
if (count(array_filter($value, fn ($item) => $item != '')) === 0) {
return $query;
}
$query->where(function (Builder $query) use ($value, $wrappedProperty, $databaseDriver) {
foreach (array_filter($value, fn ($item) => $item != '') as $partialValue) {
[$sql, $bindings] = $this->getWhereRawParameters($partialValue, $wrappedProperty, $databaseDriver);
$query->orWhereRaw($sql, $bindings);
}
});
return;
}
[$sql, $bindings] = $this->getWhereRawParameters($value, $wrappedProperty, $databaseDriver);
$query->whereRaw($sql, $bindings);
}
protected function getDatabaseDriver(Builder $query): string
{
return $query->getConnection()->getDriverName(); /** @phpstan-ignore-line */
}
protected function getWhereRawParameters(mixed $value, string $property, string $driver): array
{
$value = mb_strtolower((string) $value, 'UTF8');
return [
"LOWER({$property}) LIKE ?".self::maybeSpecifyEscapeChar($driver),
['%'.self::escapeLike($value).'%'],
];
}
protected static function escapeLike(string $value): string
{
return str_replace(
['\\', '_', '%'],
['\\\\', '\\_', '\\%'],
$value,
);
}
/**
* @param 'sqlite'|'pgsql'|'sqlsrc'|'mysql'|'mariadb' $driver
* @return string
*/
protected static function maybeSpecifyEscapeChar(string $driver): string
{
if (! in_array($driver, ['sqlite','sqlsrv'])) {
return '';
}
return " ESCAPE '\'";
}
}