if ($this->beginCache('FilterSets:' . json_encode($urlParams) . ':' . (int) $hideEmpty, $cacheParams)) { $_tplHtml = <<<'TPL' <div class="filter-property"> <div class="property-name">%s</div> <ul class="property-values"> %s </ul> </div> TPL; echo array_reduce($filterSets, function ($result, $item) use($urlParams, $_tplHtml) { /** @var \app\modules\shop\models\FilterSets $item */ $property = $item->getProperty(); if (!$property->has_static_values) { return $result; } $selections = \app\models\PropertyStaticValues::getValuesForFilter($property->id, $urlParams['last_category_id'], $urlParams['properties']); if (empty($selections)) { return $result; } $items = array_reduce($selections, function ($r, $i) use($urlParams, $property) { /** @var \app\models\PropertyStaticValues $i */ $urlParams['properties'][$property->id] = [$i['id']]; $r .= '<li>' . Html::checkbox('properties[' . $property->id . '][]', false, ['value' => $i['id'], 'class' => 'filter-check filter-check-property-' . $property->id, 'id' => 'filter-check-' . $i['id'], 'data-property-id' => $property->id]) . Html::a($i['name'], Url::toRoute($urlParams), ['class' => 'filter-link', 'data-selection-id' => $i['id'], 'data-property-id' => $property->id]) . '</li>'; return $r; }, ''); $result .= sprintf($_tplHtml, Html::encode($property->name), $items); return $result; }, ''); $this->endCache(); } ?>
/** * Actual run function for all widget classes extending BaseWidget * * @return mixed */ public function widgetRun() { $categoryId = Yii::$app->request->get('last_category_id'); if ($categoryId === null) { return '<!-- no category_id specified for FilterSet widget in request -->'; } $filterSets = FilterSets::getForCategoryId($categoryId); if (count($filterSets) === 0) { return '<!-- no filter sets for current category -->'; } if ($this->header === '') { $this->header = Yii::t('app', 'Filters'); } // Begin of a new filter sets implementation if ($this->useNewFilter) { $urlParams = ['@category', 'last_category_id' => $categoryId, 'properties' => Yii::$app->request->get('properties', []), 'category_group_id' => Yii::$app->request->get('category_group_id', 0)]; $priceMin = empty(Yii::$app->request->post('price_min')) ? Yii::$app->request->get('price_min') : Yii::$app->request->post('price_min'); $priceMax = empty(Yii::$app->request->post('price_max')) ? Yii::$app->request->get('price_max') : Yii::$app->request->post('price_max'); if (false === empty($priceMin)) { $urlParams['price_min'] = $priceMin; } if (false === empty($priceMax)) { $urlParams['price_max'] = $priceMax; } $urlParams = $this->mergeUrlProperties($urlParams, ['properties' => Yii::$app->request->post('properties', [])]); $urlParams = $this->removeLostDependencies($filterSets, $urlParams); $properties = $urlParams['properties']; $newGet = Yii::$app->request->get(); $newGet['properties'] = $properties; Yii::$app->request->setQueryParams($newGet); ksort($properties); $cacheKey = 'FilterSets:' . $categoryId . ':' . json_encode($urlParams); unset($properties); if (false === ($filtersArray = Yii::$app->cache->get($cacheKey))) { $filtersArray = []; foreach ($filterSets as $filterSet) { /** Если eav и слайдер, то фильтр формируется по особым правилам */ if ($filterSet->is_range_slider && $filterSet->property->is_eav) { $filter = $this->getEavSliderFilter($filterSet->property, $urlParams); if ($filter) { $filtersArray[] = $filter; } continue; } elseif ($filterSet->property->has_static_values === 0) { continue; } if (!empty($filterSet->property->depends_on_property_id) && !empty($filterSet->property->depended_property_values)) { if ($this->getSelectedPropertyIndex($urlParams['properties'], $filterSet->property->depends_on_property_id, $filterSet->property->depended_property_values) === false) { continue; } } $selections = PropertyStaticValues::getValuesForFilter($filterSet->property->id, $urlParams['last_category_id'], $urlParams['properties'], $filterSet->multiple, Yii::$app->getModule('shop')->filterOnlyByParentProduct); if (count($selections) === 0) { continue; } $item = ['id' => $filterSet->property->id, 'name' => $filterSet->property->name, 'sort_order' => $filterSet->property->sort_order, 'isRange' => $filterSet->is_range_slider, 'selections' => [], 'multiple' => $filterSet->multiple]; if ($filterSet->is_range_slider) { $item['max'] = 0; $item['min'] = PHP_INT_MAX; $item['property'] = $filterSet->property; } foreach ($selections as $selection) { if ($filterSet->is_range_slider) { if ((int) $selection['value'] > $item['max']) { $item['max'] = (int) $selection['value']; } if ((int) $selection['value'] < $item['min']) { $item['min'] = (int) $selection['value']; } } else { $selectedPropertyIndex = $this->getSelectedPropertyIndex($urlParams['properties'], $filterSet->property_id, $selection['id']); if ($selectedPropertyIndex !== false) { if (count($urlParams['properties'][$filterSet->property_id]) > 1) { $routeParams = $urlParams; unset($routeParams['properties'][$filterSet->property_id][$selectedPropertyIndex]); } else { $routeParams = $urlParams; unset($routeParams['properties'][$filterSet->property_id]); } if (isset($this->toUnset[$filterSet->property_id])) { foreach ($this->toUnset[$filterSet->property_id] as $id) { unset($routeParams['properties'][$id]); } } } else { $routeParams = $this->mergeUrlProperties($urlParams, ['properties' => [$filterSet->property_id => [$selection['id']]]]); } $item['selections'][] = ['id' => $selection['id'], 'checked' => $selectedPropertyIndex !== false, 'label' => $selection['name'], 'url' => $selection['active'] === true || $selectedPropertyIndex !== false ? Url::toRoute($routeParams) : null, 'active' => $selection['active']]; } } if ($filterSet->is_range_slider) { if ($item['min'] === $item['max']) { continue; } $i = 1; $n = $item['max'] - $item['min']; while ($n >= 10) { $n = $n / 10; $i++; } $item['step'] = $i > 3 ? (int) pow(10, $i - 3) : 1; unset($i, $n); } $filtersArray[] = $item; unset($item); } Yii::$app->cache->set($cacheKey, $filtersArray, 86400, new TagDependency(['tags' => [ActiveRecordHelper::getCommonTag(FilterSets::className()), ActiveRecordHelper::getCommonTag(Product::className()), ActiveRecordHelper::getCommonTag(Property::className())]])); } return $this->render($this->viewFile, ['filtersArray' => $filtersArray, 'id' => 'filter-set-' . $this->id, 'urlParams' => $urlParams, 'usePjax' => $this->usePjax]); } // End of a new filter sets implementation return $this->render($this->viewFile, ['filterSets' => $filterSets, 'id' => 'filter-set-' . $this->id, 'hideEmpty' => $this->hideEmpty]); }