From ce11f5fa336d0a89cda509c3652210b55e590569 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 14 Nov 2024 11:05:36 +0000 Subject: [PATCH 1/3] WIP variant owner instantiation --- src/elements/Product.php | 15 ++++++++++++ src/elements/Variant.php | 51 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/elements/Product.php b/src/elements/Product.php index 98eea0d891..20526d32c8 100644 --- a/src/elements/Product.php +++ b/src/elements/Product.php @@ -1045,6 +1045,21 @@ public function getVariants(bool $includeDisabled = false): VariantCollection } $this->_variants = self::createVariantQuery($this)->status(null)->collect(); + $this->_variants->map(function(Variant $v) { + if (!$this->id) { + return $v; + } + + if ($v->primaryOwnerId === $this->id) { + $v->setPrimaryOwner($this); + } + + if ($v->ownerId === $this->id) { + $v->setOwner($this); + } + + return $v; + }); } return $this->_variants->filter(fn(Variant $variant) => $includeDisabled || ($variant->getStatus() === self::STATUS_ENABLED)); diff --git a/src/elements/Variant.php b/src/elements/Variant.php index f1b8816b92..43feff97cd 100755 --- a/src/elements/Variant.php +++ b/src/elements/Variant.php @@ -60,8 +60,6 @@ * @property-read string $gqlTypeName * @property-read string $skuAsText * @property string $salePriceAsCurrency - * @method Product|null getOwner() - * @method Product|null getPrimaryOwner() * @author Pixel & Tonic, Inc. * @since 2.0 */ @@ -524,6 +522,55 @@ public function setOwner(?ElementInterface $owner): void $this->traitSetOwner($owner); } + /** + * @inheritdoc + */ + public function getPrimaryOwner(): ?ElementInterface + { + if (!isset($this->_primaryOwner)) { + $primaryOwnerId = $this->getPrimaryOwnerId(); + if (!$primaryOwnerId) { + return null; + } + + $this->_primaryOwner = Craft::$app->getElements()->getElementById($primaryOwnerId, Product::class, $this->siteId, [ + 'trashed' => null, + ]) ?? false; + if (!$this->_primaryOwner) { + throw new InvalidConfigException("Invalid owner ID: $primaryOwnerId"); + } + } + + return $this->_primaryOwner ?: null; + } + + /** + * @inheritdoc + */ + public function getOwner(): ?ElementInterface + { + if (!isset($this->_owner)) { + $ownerId = $this->getOwnerId(); + if (!$ownerId) { + return null; + } + + // If ownerId and primaryOwnerId are the same, return the primary owner + if ($ownerId === $this->getPrimaryOwnerId()) { + return $this->getPrimaryOwner(); + } + + $this->_owner = Craft::$app->getElements()->getElementById($ownerId, Product::class, $this->siteId, [ + 'trashed' => null, + ]) ?? false; + if (!$this->_owner) { + throw new InvalidConfigException("Invalid owner ID: $ownerId"); + } + } + + return $this->_owner ?: null; + } + /** * Returns the product associated with this variant. * From 9010336242a80ca112d6ba0a6bdbf7602d1d277f Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 14 Nov 2024 19:19:02 +0000 Subject: [PATCH 2/3] Changelog item --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc36160e01..3203e72bd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Improved the performance of `Product::getVariants()`. ([#3578](https://github.com/craftcms/commerce/issues/3758)) - Fixed a SQL error that could occur when creating a variant. ([#3763](https://github.com/craftcms/commerce/issues/)) ## 5.2.3 - 2024-11-13 From ba07f0a95425a49b1e3b372ddb10634a11eae505 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 14 Nov 2024 19:31:15 +0000 Subject: [PATCH 3/3] Tidy --- src/elements/Variant.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/elements/Variant.php b/src/elements/Variant.php index 43feff97cd..f0ddc22b28 100755 --- a/src/elements/Variant.php +++ b/src/elements/Variant.php @@ -524,8 +524,9 @@ public function setOwner(?ElementInterface $owner): void /** * @inheritdoc + * @TODO remove implementation when `NestedElementTrait::getOwner()` is updated */ - public function getPrimaryOwner(): ?ElementInterface + public function getPrimaryOwner(): ?Product { if (!isset($this->_primaryOwner)) { $primaryOwnerId = $this->getPrimaryOwnerId(); @@ -541,13 +542,15 @@ public function getPrimaryOwner(): ?ElementInterface } } + /** @phpstan-ignore-next-line */ return $this->_primaryOwner ?: null; } /** * @inheritdoc + * @TODO remove implementation when `NestedElementTrait::getOwner()` is updated */ - public function getOwner(): ?ElementInterface + public function getOwner(): ?Product { if (!isset($this->_owner)) { $ownerId = $this->getOwnerId(); @@ -568,6 +571,7 @@ public function getOwner(): ?ElementInterface } } + /** @phpstan-ignore-next-line */ return $this->_owner ?: null; }