From 05f65bfe363fd826b215f381abde249fa7a31fe6 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Mon, 23 Sep 2024 14:33:50 +0100 Subject: [PATCH 1/2] Fixed variants propagating to incorrect sites --- CHANGELOG.md | 1 + src/Plugin.php | 2 +- src/elements/Variant.php | 14 +++++ ..._132625_remove_orphaned_variants_sites.php | 63 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/migrations/m240923_132625_remove_orphaned_variants_sites.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 80228bd9e3..df50606ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Fixed a bug where variants weren’t respecting their owner’s propagation method. - Fixed a PHP error that could occur when creating a new product. ## 5.1.2 - 2024-09-19 diff --git a/src/Plugin.php b/src/Plugin.php index 1894ce421d..eacc59985a 100755 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -254,7 +254,7 @@ public static function editions(): array /** * @inheritDoc */ - public string $schemaVersion = '5.1.0.2'; + public string $schemaVersion = '5.1.0.3'; /** * @inheritdoc diff --git a/src/elements/Variant.php b/src/elements/Variant.php index d95cd21d7b..dac4279940 100755 --- a/src/elements/Variant.php +++ b/src/elements/Variant.php @@ -886,6 +886,20 @@ public static function gqlScopesByContext(mixed $context): array return ['productTypes.' . $context->uid]; } + /** + * @inheritdoc + */ + public function getSupportedSites(): array + { + $owner = $this->getOwner(); + + if (!$owner) { + return [Craft::$app->getSites()->getPrimarySite()->id]; + } + + return $this->getOwner()->getSupportedSites(); + } + /** * @inheritdoc * @throws Exception diff --git a/src/migrations/m240923_132625_remove_orphaned_variants_sites.php b/src/migrations/m240923_132625_remove_orphaned_variants_sites.php new file mode 100644 index 0000000000..0cf191af74 --- /dev/null +++ b/src/migrations/m240923_132625_remove_orphaned_variants_sites.php @@ -0,0 +1,63 @@ +select(['elementId', 'siteId']) + ->from('{{%elements_sites}}' . ' es') + ->innerJoin('{{%commerce_products}}' . ' p', '[[es.elementId]] = [[p.id]]') + ->collect(); + + // Group them by product ID + $siteIdsByProductId = $allProductsSites->groupBy('elementId')->map(function($row) { + return collect($row)->pluck('siteId')->toArray(); + } + ); + + // Find all existing combinations of variant and site IDs + $allVariantsSites = (new Query) + ->select(['es.id', 'elementId', 'siteId', 'primaryOwnerId']) + ->from('{{%elements_sites}}' . ' es') + ->innerJoin('{{%commerce_variants}}' . ' v', '[[es.elementId]] = [[v.id]]') + ->collect(); + + // Find all variants that are not associated with any of their product's sites + $orphanedVariantsSites = array_values($allVariantsSites->filter(function($row) use ($siteIdsByProductId) { + return !in_array($row['siteId'], $siteIdsByProductId[$row['primaryOwnerId']]); + })->map(fn($row) => $row['id'])->toArray()); + + if (empty($orphanedVariantsSites)) { + return true; + } + + // Bulk delete the orphaned variants' site rows (if any) 1000 at a time + foreach (array_chunk($orphanedVariantsSites, 1000) as $chunk) { + $this->delete('{{%elements_sites}}', ['id' => $chunk]); + } + + return true; + } + + /** + * @inheritdoc + */ + public function safeDown(): bool + { + echo "m240923_132625_remove_orphaned_variants_sites cannot be reverted.\n"; + return false; + } +} From fd703f568dd95d9bc59e2648aa0b782f6b0909e5 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Mon, 23 Sep 2024 14:34:30 +0100 Subject: [PATCH 2/2] fix cs --- .../m240923_132625_remove_orphaned_variants_sites.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/migrations/m240923_132625_remove_orphaned_variants_sites.php b/src/migrations/m240923_132625_remove_orphaned_variants_sites.php index 0cf191af74..ce7bac534d 100644 --- a/src/migrations/m240923_132625_remove_orphaned_variants_sites.php +++ b/src/migrations/m240923_132625_remove_orphaned_variants_sites.php @@ -29,7 +29,7 @@ public function safeUp(): bool ); // Find all existing combinations of variant and site IDs - $allVariantsSites = (new Query) + $allVariantsSites = (new Query()) ->select(['es.id', 'elementId', 'siteId', 'primaryOwnerId']) ->from('{{%elements_sites}}' . ' es') ->innerJoin('{{%commerce_variants}}' . ' v', '[[es.elementId]] = [[v.id]]')