From 74628bbf1a640b3ab791892568d1a1b28c6599c7 Mon Sep 17 00:00:00 2001 From: Jade Geels Date: Fri, 6 Oct 2023 10:11:31 +0200 Subject: [PATCH 1/7] Implement products relation for categories --- config/rapidez.php | 1 + src/Models/Category.php | 15 +++++++++++++++ src/Models/CategoryProduct.php | 10 ++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/Models/CategoryProduct.php diff --git a/config/rapidez.php b/config/rapidez.php index 8e8120152..fc3e985ce 100644 --- a/config/rapidez.php +++ b/config/rapidez.php @@ -86,6 +86,7 @@ 'attribute' => Rapidez\Core\Models\Attribute::class, 'product' => Rapidez\Core\Models\Product::class, 'category' => Rapidez\Core\Models\Category::class, + 'category_product' => Rapidez\Core\Models\CategoryProduct::class, 'config' => Rapidez\Core\Models\Config::class, 'option_swatch' => Rapidez\Core\Models\OptionSwatch::class, 'option_value' => Rapidez\Core\Models\OptionValue::class, diff --git a/src/Models/Category.php b/src/Models/Category.php index 975ea7a0c..c3f36c6d2 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Rapidez\Core\Models\Scopes\IsActiveScope; use Rapidez\Core\Models\Traits\HasAlternatesThroughRewrites; @@ -65,6 +66,20 @@ public function subcategories() return $this->hasMany(self::class, 'parent_id', 'entity_id'); } + public function products(): HasManyThrough + { + return $this->hasManyThrough( + config('rapidez.models.product'), + config('rapidez.models.category_product'), + 'category_id', + 'entity_id', + 'entity_id', + 'product_id' + ) + ->withoutGlobalScopes() + ->whereIn('visibility', [2, 4]); + } + public function rewrites(): HasMany { return $this diff --git a/src/Models/CategoryProduct.php b/src/Models/CategoryProduct.php new file mode 100644 index 000000000..bf6a1f405 --- /dev/null +++ b/src/Models/CategoryProduct.php @@ -0,0 +1,10 @@ + Date: Fri, 6 Oct 2023 10:11:45 +0200 Subject: [PATCH 2/7] use withCount for products_count in indexer & optimize query --- src/Commands/IndexCategoriesCommand.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Commands/IndexCategoriesCommand.php b/src/Commands/IndexCategoriesCommand.php index 72fba29a6..61f92c365 100644 --- a/src/Commands/IndexCategoriesCommand.php +++ b/src/Commands/IndexCategoriesCommand.php @@ -25,11 +25,12 @@ public function handle(): int public function getCategories() { - return config('rapidez.models.category')::query() - ->select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path', 'children_count'])) + return config('rapidez.models.category') + ::select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path'])) + ->withCount('products') ->whereNotNull('url_key') ->whereNot('url_key', 'default-category') - ->where('children_count', '>', 0) + ->having('products_count', '>', 0) ->get() ?? []; } } From 103d3cb455a00144c3a4dd7d9e2703db5b283aeb Mon Sep 17 00:00:00 2001 From: Jade Geels Date: Fri, 6 Oct 2023 10:34:59 +0200 Subject: [PATCH 3/7] Use catalog_category_product_index_storeX tables --- src/Models/Category.php | 2 +- src/Models/CategoryProduct.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Models/Category.php b/src/Models/Category.php index c3f36c6d2..9aa87de2f 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -77,7 +77,7 @@ public function products(): HasManyThrough 'product_id' ) ->withoutGlobalScopes() - ->whereIn('visibility', [2, 4]); + ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); } public function rewrites(): HasMany diff --git a/src/Models/CategoryProduct.php b/src/Models/CategoryProduct.php index bf6a1f405..780b73a85 100644 --- a/src/Models/CategoryProduct.php +++ b/src/Models/CategoryProduct.php @@ -4,7 +4,10 @@ class CategoryProduct extends Model { - protected $table = 'catalog_category_product'; - protected $primaryKey = 'entity_id'; + + public function getTable() + { + return 'catalog_category_product_index_store' . config('rapidez.store'); + } } From 5dd836848700f9f136cde772b61ad55ddee97f6b Mon Sep 17 00:00:00 2001 From: Jade Geels Date: Fri, 6 Oct 2023 10:39:55 +0200 Subject: [PATCH 4/7] Add indices-only relation to improve performance if all you want is a count --- src/Commands/IndexCategoriesCommand.php | 4 ++-- src/Models/Category.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Commands/IndexCategoriesCommand.php b/src/Commands/IndexCategoriesCommand.php index 61f92c365..8130dc64a 100644 --- a/src/Commands/IndexCategoriesCommand.php +++ b/src/Commands/IndexCategoriesCommand.php @@ -27,10 +27,10 @@ public function getCategories() { return config('rapidez.models.category') ::select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path'])) - ->withCount('products') + ->withCount('productIndices') ->whereNotNull('url_key') ->whereNot('url_key', 'default-category') - ->having('products_count', '>', 0) + ->having('product_indices_count', '>', 0) ->get() ?? []; } } diff --git a/src/Models/Category.php b/src/Models/Category.php index 9aa87de2f..3de0f6eb3 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -66,6 +66,16 @@ public function subcategories() return $this->hasMany(self::class, 'parent_id', 'entity_id'); } + public function productIndices(): HasMany + { + return $this->hasMany( + config('rapidez.models.category_product'), + 'category_id', + 'entity_id' + ) + ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); + } + public function products(): HasManyThrough { return $this->hasManyThrough( From 5a3ac3e78f590b4eb46cc58c238ad2f5406ae2d4 Mon Sep 17 00:00:00 2001 From: Jade-GG Date: Fri, 6 Oct 2023 08:40:27 +0000 Subject: [PATCH 5/7] Apply fixes from Duster --- src/Commands/IndexCategoriesCommand.php | 3 +-- src/Models/Category.php | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Commands/IndexCategoriesCommand.php b/src/Commands/IndexCategoriesCommand.php index 8130dc64a..52425168e 100644 --- a/src/Commands/IndexCategoriesCommand.php +++ b/src/Commands/IndexCategoriesCommand.php @@ -25,8 +25,7 @@ public function handle(): int public function getCategories() { - return config('rapidez.models.category') - ::select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path'])) + return config('rapidez.models.category')::select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path'])) ->withCount('productIndices') ->whereNotNull('url_key') ->whereNot('url_key', 'default-category') diff --git a/src/Models/Category.php b/src/Models/Category.php index 3de0f6eb3..468f012e1 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -69,23 +69,23 @@ public function subcategories() public function productIndices(): HasMany { return $this->hasMany( - config('rapidez.models.category_product'), - 'category_id', - 'entity_id' - ) + config('rapidez.models.category_product'), + 'category_id', + 'entity_id' + ) ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); } public function products(): HasManyThrough { return $this->hasManyThrough( - config('rapidez.models.product'), - config('rapidez.models.category_product'), - 'category_id', - 'entity_id', - 'entity_id', - 'product_id' - ) + config('rapidez.models.product'), + config('rapidez.models.category_product'), + 'category_id', + 'entity_id', + 'entity_id', + 'product_id' + ) ->withoutGlobalScopes() ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); } From ca765457a9420c84b015879958ab20395dd54e97 Mon Sep 17 00:00:00 2001 From: Jade Geels Date: Wed, 11 Oct 2023 07:24:02 +0200 Subject: [PATCH 6/7] Use `has()` for a more efficient query --- src/Commands/IndexCategoriesCommand.php | 3 +-- src/Models/Category.php | 10 ---------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Commands/IndexCategoriesCommand.php b/src/Commands/IndexCategoriesCommand.php index 52425168e..0f35d09a5 100644 --- a/src/Commands/IndexCategoriesCommand.php +++ b/src/Commands/IndexCategoriesCommand.php @@ -26,10 +26,9 @@ public function handle(): int public function getCategories() { return config('rapidez.models.category')::select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path'])) - ->withCount('productIndices') ->whereNotNull('url_key') ->whereNot('url_key', 'default-category') - ->having('product_indices_count', '>', 0) + ->has('products') ->get() ?? []; } } diff --git a/src/Models/Category.php b/src/Models/Category.php index 468f012e1..649b26bd5 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -66,16 +66,6 @@ public function subcategories() return $this->hasMany(self::class, 'parent_id', 'entity_id'); } - public function productIndices(): HasMany - { - return $this->hasMany( - config('rapidez.models.category_product'), - 'category_id', - 'entity_id' - ) - ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); - } - public function products(): HasManyThrough { return $this->hasManyThrough( From 1770b12a241f029fe142463e59e6f0d38c2ccd16 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 11 Oct 2023 10:34:47 +0200 Subject: [PATCH 7/7] Update src/Models/Category.php --- src/Models/Category.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Models/Category.php b/src/Models/Category.php index 649b26bd5..994d7cccc 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -68,14 +68,15 @@ public function subcategories() public function products(): HasManyThrough { - return $this->hasManyThrough( - config('rapidez.models.product'), - config('rapidez.models.category_product'), - 'category_id', - 'entity_id', - 'entity_id', - 'product_id' - ) + return $this + ->hasManyThrough( + config('rapidez.models.product'), + config('rapidez.models.category_product'), + 'category_id', + 'entity_id', + 'entity_id', + 'product_id' + ) ->withoutGlobalScopes() ->whereIn((new(config('rapidez.models.category_product')))->qualifyColumn('visibility'), [2, 4]); }