public function run() { $query = Category::find(); $query->andWhere([Category::tableName() . '.active' => 1]); if ($this->root_category_id !== null) { $query->andWhere([Category::tableName() . '.parent_id' => $this->root_category_id]); } if ($this->category_group_id !== null) { $query->andWhere([Category::tableName() . '.category_group_id' => $this->category_group_id]); } $query->groupBy(Category::tableName() . ".id"); $query->orderBy($this->sort); if ($this->limit !== null) { $query->limit($this->limit); } $object = Object::getForClass(Category::className()); \app\properties\PropertiesHelper::appendPropertiesFilters($object, $query, $this->values_by_property_id, []); $sql = $query->createCommand()->getRawSql(); $cacheKey = "FilteredCategoriesWidget:" . md5($sql); $result = Yii::$app->cache->get($cacheKey); if ($result === false) { $categories = Category::findBySql($sql)->all(); $result = $this->render($this->viewFile, ['categories' => $categories]); Yii::$app->cache->set($cacheKey, $result, 86400, new \yii\caching\TagDependency(['tags' => ActiveRecordHelper::getCommonTag(Category::tableName())])); } return $result; }
/** * Returns products for special filtration query * Used in ProductsWidget and ProductController * * @param $category_group_id * @param array $values_by_property_id * @param null|integer|string $selected_category_id * @param bool|string $force_sorting If false - use UserPreferences, if string - use supplied orderBy condition * @param null|integer $limit limit query results * @param bool $apply_filterquery Should we apply filter query(filters based on query params ie. price_min/max) * @param bool $force_limit False to use Pagination, true to use $limit and ignore pagination * @param array $additional_filters Array of callables that will apply additional filters to query */ public static function filteredProducts($category_group_id, array $values_by_property_id = [], $selected_category_id = null, $force_sorting = false, $limit = null, $apply_filterquery = true, $force_limit = false, array $additional_filters = []) { Yii::beginProfile("FilteredProducts"); if (null === ($object = Object::getForClass(static::className()))) { throw new \yii\web\ServerErrorHttpException('Object not found.'); } /** @var \app\modules\shop\ShopModule $module */ $module = Yii::$app->getModule('shop'); $onlyParents = $module->filterOnlyByParentProduct; $query = static::find()->with('images'); if (true === $onlyParents) { $query->andWhere([static::tableName() . '.parent_id' => 0, static::tableName() . '.active' => 1]); } else { $query->andWhere(['!=', static::tableName() . '.parent_id', 0]); $query->andWhere([static::tableName() . '.active' => 1]); } if (null !== $selected_category_id) { $query->innerJoin($object->categories_table_name . ' ocats', 'ocats.category_id = :catid AND ocats.object_model_id = ' . static::tableName() . '.id', [':catid' => $selected_category_id]); } else { $query->innerJoin($object->categories_table_name . ' ocats', 'ocats.object_model_id = ' . static::tableName() . '.id'); } $query->innerJoin(Category::tableName() . ' ocatt', 'ocatt.id = ocats.category_id AND ocatt.category_group_id = :gcatid AND ocatt.active = 1', [':gcatid' => $category_group_id]); $query->addGroupBy(static::tableName() . ".id"); $userSelectedSortingId = UserPreferences::preferences()->getAttributes()['productListingSortId']; $allSorts = []; if ($force_sorting === false) { $allSorts = ProductListingSort::enabledSorts(); if (isset($allSorts[$userSelectedSortingId])) { $query->addOrderBy($allSorts[$userSelectedSortingId]['sort_field'] . ' ' . $allSorts[$userSelectedSortingId]['asc_desc']); } else { $query->addOrderBy(static::tableName() . '.sort_order'); } } elseif (empty($force_sorting) === false || is_array($force_sorting) === true) { $query->addOrderBy($force_sorting); } $productsPerPage = $limit === null ? UserPreferences::preferences()->getAttributes()['productsPerPage'] : $limit; \app\properties\PropertiesHelper::appendPropertiesFilters($object, $query, $values_by_property_id, Yii::$app->request->get('p', [])); // apply additional filters $cacheKeyAppend = ""; if ($apply_filterquery) { $query = Yii::$app->filterquery->filter($query, $cacheKeyAppend); } foreach ($additional_filters as $filter) { if (is_callable($filter)) { call_user_func_array($filter, [&$query, &$cacheKeyAppend]); } } $cacheKey = 'ProductsCount:' . implode('_', [md5($query->createCommand()->getRawSql()), $limit ? '1' : '0', $force_limit ? '1' : '0', $productsPerPage]) . $cacheKeyAppend; $pages = null; if ($force_limit === true) { $query->limit($limit); } else { $products_query = clone $query; $products_query->limit(null); if (false === ($pages = Yii::$app->cache->get($cacheKey))) { $pages = new Pagination(['defaultPageSize' => !is_null($query->limit) ? $query->limit : $productsPerPage, 'pageSizeLimit' => [], 'forcePageParam' => false, 'totalCount' => $products_query->count()]); Yii::$app->cache->set($cacheKey, $pages, 86400, new TagDependency(['tags' => [ActiveRecordHelper::getCommonTag(Category::className()), ActiveRecordHelper::getCommonTag(static::className()), ActiveRecordHelper::getCommonTag($module->className())]])); } $query->offset($pages->offset)->limit($pages->limit); } $cacheKey .= '-' . Yii::$app->request->get('page', 1); if (false === ($products = Yii::$app->cache->get($cacheKey))) { $products = $query->all(); Yii::$app->cache->set($cacheKey, $products, 86400, new TagDependency(['tags' => [ActiveRecordHelper::getCommonTag(Category::className()), ActiveRecordHelper::getCommonTag(static::className()), ActiveRecordHelper::getCommonTag($module->className())]])); } Yii::endProfile("FilteredProducts"); return ['products' => $products, 'pages' => $pages, 'allSorts' => $allSorts]; }