Сделал примерно как
Илья Зябиров описал
interface PropertyQueryOptionsInterface
{
/**
* @param array $attribute
*/
public function fill(array $attribute): void;
/**
* @param QueryBuilder $queryBuilder
*/
public function addWhere(QueryBuilder $queryBuilder): void;
}
class RangePropertyPriceOption implements PropertyQueryOptionsInterface
{
public const TYPE = 'RangePropertyPriceOption';
/**
* @var string
*/
protected $alias;
/**
* @var float
*/
protected $min = null;
/**
* @var float
*/
protected $max = null;
/**
* @param array $attribute
*/
public function fill(array $attribute): void
{
if (isset($attribute['key'])) {
$this->alias = $attribute['key'];
}
if (isset($attribute['value'])) {
if (isset($attribute['value'][0])) {
$this->min = $attribute['value'][0];
}
if (isset($attribute['value'][1]) && $attribute['value'][1] != 0) {
$this->max = $attribute['value'][1];
}
}
}
public function addWhere(QueryBuilder $queryBuilder): void
{
$whereByValue = $this->alias === Property::FILTER_RANGE_PRICE ? 'price' : 'areaPrice';
if (!is_null($this->min)) {
$whereParameter = ':' . 'min_' . $whereByValue;
$queryBuilder
->andWhere(sprintf('p.%s >= %s', $whereByValue, $whereParameter))
->setParameter($whereParameter, $this->min);
}
if (!is_null($this->max) && $this->max != 0) {
$whereParameter = ':' . 'max_' . $whereByValue;
$queryBuilder
->andWhere(sprintf('p.%s <= %s', $whereByValue, $whereParameter))
->setParameter($whereParameter, $this->max);
}
}
}
foreach ($options['propertyQueryOptions'] as $queryOption) {
if ($queryOption instanceof PropertyQueryOptionsInterface) {
$queryOption->addWhere($queryBuilder);
}
}