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;
 }
예제 #2
0
 /**
  * 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];
 }