silverstripe-framework/src/ORM/Filters/PartialMatchFilter.php

129 lines
3.5 KiB
PHP
Raw Normal View History

<?php
namespace SilverStripe\ORM\Filters;
use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\DB;
use InvalidArgumentException;
/**
* Matches textual content with a LIKE '%keyword%' construct.
*/
2016-11-29 00:31:16 +01:00
class PartialMatchFilter extends SearchFilter
{
2016-11-29 00:31:16 +01:00
public function getSupportedModifiers()
{
return ['not', 'nocase', 'case'];
}
2014-08-15 08:53:05 +02:00
2016-11-29 00:31:16 +01:00
/**
* Apply the match filter to the given variable value
*
* @param string $value The raw value
* @return string
*/
protected function getMatchPattern($value)
{
return "%$value%";
}
2014-08-15 08:53:05 +02:00
2017-02-02 21:03:19 +01:00
/**
* Apply filter criteria to a SQL query.
*
* @param DataQuery $query
* @return DataQuery
*/
public function apply(DataQuery $query)
{
if ($this->aggregate) {
throw new InvalidArgumentException(sprintf(
'Aggregate functions can only be used with comparison filters. See %s',
$this->fullName
));
}
return parent::apply($query);
}
2016-11-29 00:31:16 +01:00
protected function applyOne(DataQuery $query)
{
$this->model = $query->applyRelation($this->relation);
$comparisonClause = DB::get_conn()->comparisonClause(
$this->getDbName(),
null,
false, // exact?
false, // negate?
$this->getCaseSensitive(),
true
);
2017-02-02 21:03:19 +01:00
$clause = [$comparisonClause => $this->getMatchPattern($this->getValue())];
2017-02-02 21:03:19 +01:00
return $this->aggregate ?
$this->applyAggregate($query, $clause) :
$query->where($clause);
2016-11-29 00:31:16 +01:00
}
2016-11-29 00:31:16 +01:00
protected function applyMany(DataQuery $query)
{
$this->model = $query->applyRelation($this->relation);
$whereClause = [];
2016-11-29 00:31:16 +01:00
$comparisonClause = DB::get_conn()->comparisonClause(
$this->getDbName(),
null,
false, // exact?
false, // negate?
$this->getCaseSensitive(),
true
);
foreach ($this->getValue() as $value) {
$whereClause[] = [$comparisonClause => $this->getMatchPattern($value)];
2016-11-29 00:31:16 +01:00
}
return $query->whereAny($whereClause);
}
2016-11-29 00:31:16 +01:00
protected function excludeOne(DataQuery $query)
{
$this->model = $query->applyRelation($this->relation);
$comparisonClause = DB::get_conn()->comparisonClause(
$this->getDbName(),
null,
false, // exact?
true, // negate?
$this->getCaseSensitive(),
true
);
return $query->where([
2016-11-29 00:31:16 +01:00
$comparisonClause => $this->getMatchPattern($this->getValue())
]);
2016-11-29 00:31:16 +01:00
}
2016-11-29 00:31:16 +01:00
protected function excludeMany(DataQuery $query)
{
$this->model = $query->applyRelation($this->relation);
$values = $this->getValue();
$comparisonClause = DB::get_conn()->comparisonClause(
$this->getDbName(),
null,
false, // exact?
true, // negate?
$this->getCaseSensitive(),
true
);
$parameters = [];
2016-11-29 00:31:16 +01:00
foreach ($values as $value) {
$parameters[] = $this->getMatchPattern($value);
}
// Since query connective is ambiguous, use AND explicitly here
2022-04-14 03:12:59 +02:00
$count = count($values ?? []);
$predicate = implode(' AND ', array_fill(0, $count ?? 0, $comparisonClause));
return $query->where([$predicate => $parameters]);
2016-11-29 00:31:16 +01:00
}
2014-08-15 08:53:05 +02:00
2016-11-29 00:31:16 +01:00
public function isEmpty()
{
return $this->getValue() === [] || $this->getValue() === null || $this->getValue() === '';
2016-11-29 00:31:16 +01:00
}
}