Answer the question
In order to leave comments, you need to log in
Yii2 filter select only having a set of options?
Good afternoon, when implementing an object filter, I encountered such a problem.
I took yii2-filter
as a basis.
The essence of the problem: There is a filter / option type checkbox
$filtered = FilterValue::find()->select('item_id')->groupBy('item_id')->andHaving("COUNT(DISTINCT `filter_id`) = $variantCount")->andFilterWhere($condition);
SELECT `item_id` FROM `filter_value` WHERE (`filter_id`=2) AND (`variant_id` IN ('8', '12')) GROUP BY `item_id` HAVING COUNT(DISTINCT `filter_id`) = 1
SELECT *, GROUP_CONCAT(variant_id) AS variant_ids FROM filter_value GROUP BY item_id HAVING LOCATE('8', variant_ids) AND LOCATE('12', variant_ids)
public function filtered($filterIds = false, $mode = 0)
{
if(!$filterIds) {
$filterIds = Yii::$app->request->get($this->fieldName);
}
if(empty($filterIds)) {
return $this->owner;
}
$condition = ['OR'];
$variantCount = 0;
$filterCount = count($filterIds);
foreach($filterIds as $filterId => $value) {
$filter = Filter::findOne($filterId);
if($filter->type == 'range' && is_string($value)) {
$value = explode(';', $value);
if($value[0] != $value[1]) {
$variants = FilterVariant::find()->where('filter_id = :filterId AND (numeric_value >= :min AND numeric_value <= :max)', [':filterId' => $filterId, ':min' => $value[0], ':max' => $value[1]])->select('id')->all();
} else {
$variants = FilterVariant::find()->where('filter_id = :filterId AND numeric_value = :value', [':filterId' => $filterId, ':value' => $value[0]])->select('id')->all();
}
$variantIds = ArrayHelper::map($variants, 'id', 'id');
} else {
$variantIds = $value;
}
$condition[] = ['filter_id' => $filterId, 'variant_id' => $variantIds];
if($mode == 1) {
$variantCount += count($variantIds);
} else {
$variantCount++;
}
}
$filtered = FilterValue::find()->select('item_id')->groupBy('item_id')->andHaving("COUNT(DISTINCT `filter_id`) = $variantCount")->andFilterWhere($condition);
$modelClass = $this->owner->modelClass;
$tableName = $modelClass::tableName();
if ($filtered->count() > 0) {
$this->owner->andWhere([$tableName . '.id' => $filtered]);
} else {
$this->owner->andWhere([$tableName . '.id' => 0]);
}
return $this->owner;
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question