From 894b56653f8b3daf7380bd0b92596fedcba8d5ce Mon Sep 17 00:00:00 2001 From: Brad Bell Date: Thu, 10 Oct 2024 17:31:23 -0700 Subject: [PATCH 1/4] WIP --- src/elements/CommerceProduct.php | 69 ++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/elements/CommerceProduct.php b/src/elements/CommerceProduct.php index c28b3019..b39a5faf 100644 --- a/src/elements/CommerceProduct.php +++ b/src/elements/CommerceProduct.php @@ -23,6 +23,7 @@ use craft\fields\Matrix; use craft\fields\Table; use craft\helpers\ArrayHelper; +use craft\helpers\ElementHelper; use craft\helpers\Json; use DateTime; use Exception; @@ -144,12 +145,24 @@ public function getGroups(): array */ public function getQuery($settings, array $params = []): mixed { + $targetSiteId = Hash::get($settings, 'siteId') ?: Craft::$app->getSites()->getPrimarySite()->id; + if ($this->element !== null) { + $productType = $this->element->getType(); + } + $query = ProductElement::find() ->status(null) - ->typeId($settings['elementGroup'][ProductElement::class]) - ->siteId(Hash::get($settings, 'siteId') ?: Craft::$app->getSites()->getPrimarySite()->id); - Craft::configure($query, $params); + ->typeId($settings['elementGroup'][ProductElement::class]); + + if (isset($productType) && $productType->propagationMethod === \craft\enums\PropagationMethod::Custom) { + $query->site('*') + ->preferSites([$targetSiteId]) + ->unique(); + } else { + $query->siteId($targetSiteId); + } + Craft::configure($query, $params); return $query; } @@ -167,9 +180,59 @@ public function setModel($settings): ElementInterface $this->element->siteId = $siteId; } + /* @var \craft\commerce\models\ProductType $productType */ + $productType = Commerce::getInstance()->getProductTypes()->getProductTypeById($this->element->typeId); + + // Set the default site status based on the section's settings + $enabledForSite = []; + foreach ($productType->getSiteSettings() as $siteSettings) { + if ( + $productType->propagationMethod !== \craft\enums\PropagationMethod::Custom || + $siteSettings->siteId == $siteId + ) { + $enabledForSite[$siteSettings->siteId] = $siteSettings->enabledByDefault; + } + } + $this->element->setEnabledForSite($enabledForSite); + return $this->element; } + /** + * Checks if $existingElement should be propagated to the target site. + * + * @param $existingElement + * @param array $feed + * @return ElementInterface|null + * @throws \yii\base\Exception + * @throws \craft\errors\SiteNotFoundException + * @throws \craft\errors\UnsupportedSiteException + * @since 5.1.3 + */ + public function checkPropagation($existingElement, array $feed) + { + $targetSiteId = Hash::get($feed, 'siteId') ?: Craft::$app->getSites()->getPrimarySite()->id; + + // Did the entry come back in a different site? + if ($existingElement->siteId != $targetSiteId) { + // Skip it if its product type doesn't use the `custom` propagation method + if ($existingElement->getSection()->propagationMethod !== \craft\enums\PropagationMethod::Custom) { + return $existingElement; + } + + // Give the entry a status for the import's target site + // (This is how the `custom` propagation method knows which sites the entry should support.) + $siteStatuses = ElementHelper::siteStatusesForElement($existingElement); + $siteStatuses[$targetSiteId] = $existingElement->getEnabledForSite(); + $existingElement->setEnabledForSite($siteStatuses); + + // Propagate the entry, and swap $entry with the propagated copy + return Craft::$app->getElements()->propagateElement($existingElement, $targetSiteId); + } + + return $existingElement; + } + /** * @inheritDoc */ From 83378a21bf0759baa4e9e0185261f24fae5aa908 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Tue, 15 Oct 2024 10:05:27 +0100 Subject: [PATCH 2/4] tweak comments & fix how we compare propagation method --- src/elements/CommerceProduct.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/elements/CommerceProduct.php b/src/elements/CommerceProduct.php index b39a5faf..0063b569 100644 --- a/src/elements/CommerceProduct.php +++ b/src/elements/CommerceProduct.php @@ -213,20 +213,20 @@ public function checkPropagation($existingElement, array $feed) { $targetSiteId = Hash::get($feed, 'siteId') ?: Craft::$app->getSites()->getPrimarySite()->id; - // Did the entry come back in a different site? + // Did the product come back in a different site? if ($existingElement->siteId != $targetSiteId) { // Skip it if its product type doesn't use the `custom` propagation method - if ($existingElement->getSection()->propagationMethod !== \craft\enums\PropagationMethod::Custom) { + if ($existingElement->getType()->propagationMethod !== \craft\enums\PropagationMethod::Custom) { return $existingElement; } - // Give the entry a status for the import's target site - // (This is how the `custom` propagation method knows which sites the entry should support.) + // Give the product a status for the import's target site + // (This is how the `custom` propagation method knows which sites the product should support.) $siteStatuses = ElementHelper::siteStatusesForElement($existingElement); $siteStatuses[$targetSiteId] = $existingElement->getEnabledForSite(); $existingElement->setEnabledForSite($siteStatuses); - // Propagate the entry, and swap $entry with the propagated copy + // Propagate the product, and swap it with the propagated copy return Craft::$app->getElements()->propagateElement($existingElement, $targetSiteId); } From 2544dd76cb1a0874202b7e14010e813c4be30ab1 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Tue, 15 Oct 2024 10:05:55 +0100 Subject: [PATCH 3/4] ensure element gets propagated when importing for the first time --- src/elements/CommerceProduct.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/elements/CommerceProduct.php b/src/elements/CommerceProduct.php index 0063b569..4b5c00cb 100644 --- a/src/elements/CommerceProduct.php +++ b/src/elements/CommerceProduct.php @@ -243,6 +243,7 @@ public function save($element, $settings): bool if ($this->element->getIsDraft()) { $this->element->setDirtyAttributes(['variants']); $this->element = Craft::$app->getDrafts()->applyDraft($this->element); + $this->element->propagateAll = true; } if (!Craft::$app->getElements()->saveElement($this->element, true, true, Hash::get($this->feed, 'updateSearchIndexes'))) { From d6b91d41482e10151b76aec4027848fbf8458def Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Tue, 15 Oct 2024 13:32:55 +0100 Subject: [PATCH 4/4] propagate variants too & ensure they get updated with new content --- src/elements/CommerceProduct.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/elements/CommerceProduct.php b/src/elements/CommerceProduct.php index 4b5c00cb..dd58176c 100644 --- a/src/elements/CommerceProduct.php +++ b/src/elements/CommerceProduct.php @@ -227,7 +227,18 @@ public function checkPropagation($existingElement, array $feed) $existingElement->setEnabledForSite($siteStatuses); // Propagate the product, and swap it with the propagated copy - return Craft::$app->getElements()->propagateElement($existingElement, $targetSiteId); + $propagatedElement = Craft::$app->getElements()->propagateElement($existingElement, $targetSiteId); + + // we need this so that the variants get propagated too + $propagatedElement->setVariants($existingElement->getVariants()); + $propagatedElement->newSiteIds = [$targetSiteId]; + $propagatedElement->afterPropagate(false); + + // we're done propagating now + $propagatedElement->propagating = false; + $propagatedElement->propagatingFrom = null; + + return $propagatedElement; } return $existingElement;