From 72a1aa2da789ddf3685e2633b4e0e4b4f91d8fe3 Mon Sep 17 00:00:00 2001 From: yarik Date: Mon, 14 Nov 2016 18:25:59 +0200 Subject: [PATCH] Catalog optimize --- models/Category.php | 2 +- models/Product.php | 4 ++-- models/ProductFrontendSearch.php | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------- 3 files changed, 167 insertions(+), 137 deletions(-) diff --git a/models/Category.php b/models/Category.php index b1e4208..0057f7c 100755 --- a/models/Category.php +++ b/models/Category.php @@ -149,7 +149,7 @@ public function getProducts() { return $this->hasMany(Product::className(), [ 'id' => 'product_id' ]) - ->viaTable('product_category', [ 'category_id' => 'id' ]); + ->viaTable('product_category', [ 'category_id' => 'id' ])->inverseOf('categories'); } /** diff --git a/models/Product.php b/models/Product.php index fccbe3d..8096f49 100755 --- a/models/Product.php +++ b/models/Product.php @@ -121,7 +121,7 @@ 'product_id' => 'id', ], 'conditions' => [ - 'product_variant_id' => null, + 'product_image.product_variant_id' => null, ], 'model' => ProductImage::className(), 'config' => [ @@ -365,7 +365,7 @@ public function getCategories() { return $this->hasMany(Category::className(), [ 'id' => 'category_id' ]) - ->viaTable('product_category', [ 'product_id' => 'id' ]); + ->viaTable('product_category', [ 'product_id' => 'id' ])->inverseOf('products'); } /** diff --git a/models/ProductFrontendSearch.php b/models/ProductFrontendSearch.php index 3e0f5d5..0f0258e 100644 --- a/models/ProductFrontendSearch.php +++ b/models/ProductFrontendSearch.php @@ -1,145 +1,175 @@ $this->getSearchQuery($category, $params, $in_stock)->with([ - 'images', - 'variant', - 'variant.image', - 'comments', -// 'averageRating', - ])->all(), - 'pagination' => [ - 'pageSize' => 15, - ], - 'sort' => [ - 'attributes' => [ - 'name_asc' => [ - 'asc' => ['name' => SORT_ASC], - 'desc' => ['name' => SORT_ASC], - 'default' => SORT_ASC, - 'label' => 'имени от А до Я', - ], - 'name_desc' => [ - 'asc' => ['name' => SORT_DESC], - 'desc' => ['name' => SORT_DESC], - 'default' => SORT_DESC, - 'label' => 'имени от Я до А', - ], - 'price' => [ - 'asc' => ['price' => SORT_ASC], - 'desc' => ['price' => SORT_DESC], - 'default' => SORT_DESC, - 'label' => 'по цене', + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ + 'price_interval', + 'brands', ], + 'safe', ], - ] - ]); + ]; + } + + /** + * @inheritdoc + */ + public function scenarios() + { + // bypass scenarios() implementation in the parent class + return Model::scenarios(); + } - - return $dataProvider; - } - - public function getSearchQuery($category = null, $params = [], $in_stock = true) { - - if (!empty($category)) { - /** @var ActiveQuery $query */ - /**@var Category $category **/ - $query = $category->getProducts(); - - } else { - $query = Product::find(); + /** + * Creates data provider instance with search query applied for frontend + * + * @param array $params + * + * @return ArrayDataProvider + */ + public function search($category = null, $params = [], $in_stock = true) + { + + $dataProvider = new ArrayDataProvider( + [ + 'allModels' => $this->getSearchQuery($category, $params, $in_stock) + ->all(), + 'pagination' => [ + 'pageSize' => 10, + ], + 'sort' => [ + 'attributes' => [ + 'name_asc' => [ + 'asc' => [ 'name' => SORT_ASC ], + 'desc' => [ 'name' => SORT_ASC ], + 'default' => SORT_ASC, + 'label' => 'имени от А до Я', + ], + 'name_desc' => [ + 'asc' => [ 'name' => SORT_DESC ], + 'desc' => [ 'name' => SORT_DESC ], + 'default' => SORT_DESC, + 'label' => 'имени от Я до А', + ], + 'price' => [ + 'asc' => [ 'price' => SORT_ASC ], + 'desc' => [ 'price' => SORT_DESC ], + 'default' => SORT_DESC, + 'label' => 'по цене', + ], + ], + ], + ] + ); + + return $dataProvider; } - - $query->select(['product.*']); - $query->joinWith(['enabledVariants.lang','brand','options', 'category']); - - $query->groupBy(['product.id', 'product_variant.price']); - - FilterHelper::setQueryParams($query, $params); - if($in_stock){ - $query->andWhere(['>=', ProductVariant::tableName() .'.stock', 1]); + + public function getSearchQuery($category = null, $params = [], $in_stock = true) + { + + if (!empty( $category )) { + /** @var ActiveQuery $query */ + /**@var Category $category * */ + $query = $category->getProducts(); + + } else { + $query = Product::find(); + } + + $query->select([ 'product.*' ]); + $query->joinWith( + [ + 'lang', + 'brand.lang', + 'options', + ] + ) + ->innerJoinWith( + [ + 'enabledVariants' => function ($query) { + /** + * @var ActiveQuery $query + */ + $query->joinWith('lang') + ->with('images'); + }, + ] + ); + + $query->groupBy( + [ + 'product.id', + 'product_variant.price', + ] + ); + + FilterHelper::setQueryParams($query, $params); + if ($in_stock) { + $query->andWhere( + [ + '>=', + ProductVariant::tableName() . '.stock', + 1, + ] + ); + } + + return $query; } - - - return $query; - } - - - /** - * @param Category|null $category - * @return array - */ - - public function priceLimits($category = null) { - if (!empty($category)) { - /** @var ActiveQuery $query */ - $query = $category->getProducts(); - } else { - $query = Product::find(); + + /** + * @param Category|null $category + * + * @return array + */ + + public function priceLimits($category = null) + { + if (!empty( $category )) { + /** @var ActiveQuery $query */ + $query = $category->getProducts(); + } else { + $query = Product::find(); + } + $query->joinWith('variant'); + + return [ + 'min' => $query->min(ProductVariant::tableName() . '.price'), + 'max' => $query->max(ProductVariant::tableName() . '.price'), + ]; } - $query->joinWith('variant'); - - return [ - 'min' => $query->min(ProductVariant::tableName() .'.price'), - 'max' => $query->max(ProductVariant::tableName() .'.price'), - ]; - } -} \ No newline at end of file + } \ No newline at end of file -- libgit2 0.21.4