diff --git a/src/elements/CommerceProduct.php b/src/elements/CommerceProduct.php index c28b3019..dd58176c 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,70 @@ 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 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->getType()->propagationMethod !== \craft\enums\PropagationMethod::Custom) { + return $existingElement; + } + + // 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 product, and swap it with the propagated copy + $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; + } + /** * @inheritDoc */ @@ -180,6 +254,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'))) {