From 714f74f18f66b2d01d422dad0f0f916ee3dfa9bc Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 21 Nov 2024 15:10:06 +0000 Subject: [PATCH 1/6] Bump Craft requirement --- composer.json | 2 +- composer.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index b3b4d39ca0..871b90968a 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "prefer-stable": true, "require": { "php": "^8.2", - "craftcms/cms": "^5.2.0", + "craftcms/cms": "^5.5.0", "dompdf/dompdf": "^2.0.2", "ibericode/vat": "^1.2.2", "iio/libmergepdf": "^4.0", diff --git a/composer.lock b/composer.lock index 44fc587fcd..a56e134c3b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2f3ba664672e378629a5fd88f697019c", + "content-hash": "733b4b868ad8dbf52e6ea739a7a83494", "packages": [ { "name": "bacon/bacon-qr-code", @@ -331,16 +331,16 @@ }, { "name": "craftcms/cms", - "version": "5.5.0.1", + "version": "5.5.1.1", "source": { "type": "git", "url": "https://github.com/craftcms/cms.git", - "reference": "5e24a0bf74ea29ea2f5c04d4c9dcc325dcbb41ba" + "reference": "2233b27fd7e80cccc3aab927ad073f5916167dba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/craftcms/cms/zipball/5e24a0bf74ea29ea2f5c04d4c9dcc325dcbb41ba", - "reference": "5e24a0bf74ea29ea2f5c04d4c9dcc325dcbb41ba", + "url": "https://api.github.com/repos/craftcms/cms/zipball/2233b27fd7e80cccc3aab927ad073f5916167dba", + "reference": "2233b27fd7e80cccc3aab927ad073f5916167dba", "shasum": "" }, "require": { @@ -454,7 +454,7 @@ "rss": "https://github.com/craftcms/cms/releases.atom", "source": "https://github.com/craftcms/cms" }, - "time": "2024-11-13T14:36:24+00:00" + "time": "2024-11-19T02:11:31+00:00" }, { "name": "craftcms/plugin-installer", @@ -9423,16 +9423,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.10", + "version": "1.12.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "fc463b5d0fe906dcf19689be692c65c50406a071" + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/fc463b5d0fe906dcf19689be692c65c50406a071", - "reference": "fc463b5d0fe906dcf19689be692c65c50406a071", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", "shasum": "" }, "require": { @@ -9477,7 +9477,7 @@ "type": "github" } ], - "time": "2024-11-11T15:37:09+00:00" + "time": "2024-11-17T14:08:01+00:00" }, { "name": "phpunit/php-code-coverage", From 242086009513fefcf0193aa6fb22534fb735f044 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 21 Nov 2024 15:10:29 +0000 Subject: [PATCH 2/6] WIP Card layout designer --- src/elements/Product.php | 28 +++++++++++++++++++ src/services/LineItems.php | 1 + .../settings/producttypes/_edit.twig | 2 ++ 3 files changed, 31 insertions(+) diff --git a/src/elements/Product.php b/src/elements/Product.php index 20526d32c8..ee853418b6 100644 --- a/src/elements/Product.php +++ b/src/elements/Product.php @@ -565,6 +565,34 @@ protected static function defineDefaultTableAttributes(string $source): array return $attributes; } + /** + * @inheritdoc + */ + protected static function defineCardAttributes(): array + { + return array_merge(parent::defineCardAttributes(), [ + 'defaultPrice' => [ + 'label' => Craft::t('commerce', 'Price'), + 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'defaultSku' => [ + 'label' => Craft::t('commerce', 'SKU'), + 'placeholder' => Html::tag('code', 'SKU123'), + ], + ]); + } + + /** + * @inheritdoc + */ + protected static function defineDefaultCardAttributes(): array + { + return array_merge(parent::defineDefaultCardAttributes(), [ + 'defaultSku', + 'defaultPrice', + ]); + } + /** * @inheritdoc */ diff --git a/src/services/LineItems.php b/src/services/LineItems.php index e7627fde24..812c1994cd 100644 --- a/src/services/LineItems.php +++ b/src/services/LineItems.php @@ -444,6 +444,7 @@ public function create(Order $order, array $params = [], LineItemType $type = Li } $params['class'] = LineItem::class; + /** @var LineItem $lineItem */ $lineItem = Craft::createObject($params); if ($lineItem->type === LineItemType::Purchasable) { diff --git a/src/templates/settings/producttypes/_edit.twig b/src/templates/settings/producttypes/_edit.twig index a290e42450..d607cb77d1 100644 --- a/src/templates/settings/producttypes/_edit.twig +++ b/src/templates/settings/producttypes/_edit.twig @@ -408,6 +408,7 @@ {{ forms.fieldLayoutDesignerField({ fieldLayout: productType.getProductFieldLayout(), + withCardViewDesigner: true, }) }} @@ -417,6 +418,7 @@ {% namespace "variant-layout" %} {{ forms.fieldLayoutDesignerField({ fieldLayout: productType.getVariantFieldLayout(), + withCardViewDesigner: true, }) }} {% endnamespace %} From 7ca145f376c732ce03981baf7f4c7dcafadb855a Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 21 Nov 2024 15:11:06 +0000 Subject: [PATCH 3/6] Changelog --- CHANGELOG-WIP.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index de991b6ce5..7608192b6f 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -1,5 +1,7 @@ # Release Notes for Craft Commerce (WIP) -## Administration +### Administration +- Added a new "Payment Gateway" order condition rule. ([#3722](https://github.com/craftcms/commerce/discussions/3722)) -- Added a new "Payment Gateway" order condition rule. ([#3722](https://github.com/craftcms/commerce/discussions/3722)) \ No newline at end of file +### System +- Craft Commerce now requires Craft CMS 5.5 or later. \ No newline at end of file From 92fc28fbd3b0350de7e34a11350bb96db1de089e Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Thu, 28 Nov 2024 17:21:05 +0000 Subject: [PATCH 4/6] WIP variant card attributes --- src/elements/Product.php | 11 ++++++ src/elements/Variant.php | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/src/elements/Product.php b/src/elements/Product.php index ee853418b6..74dc8174e6 100644 --- a/src/elements/Product.php +++ b/src/elements/Product.php @@ -565,6 +565,17 @@ protected static function defineDefaultTableAttributes(string $source): array return $attributes; } + /** + * @inheritdoc + */ + public static function attributePreviewHtml(array $attribute): mixed + { + return match($attribute['value']) { + 'defaultSku' => $attribute['placeholder'], + default => parent::attributePreviewHtml($attribute) + }; + } + /** * @inheritdoc */ diff --git a/src/elements/Variant.php b/src/elements/Variant.php index f0ddc22b28..065f60015a 100755 --- a/src/elements/Variant.php +++ b/src/elements/Variant.php @@ -1329,6 +1329,73 @@ protected static function defineActions(string $source): array ]]; } + /** + * @inheritdoc + */ + public static function attributePreviewHtml(array $attribute): mixed + { + return match($attribute['value']) { + 'sku', 'priceView' => $attribute['placeholder'], + 'availableForPurchase', 'promotable' => Html::tag('span', '', [ + 'class' => 'checkbox-icon', + 'role' => 'img', + 'title' => $attribute['label'], + 'aria' => [ + 'label' => $attribute['label'], + ], + ]) . + Html::tag('span', $attribute['label'], [ + 'class' => 'checkbox-preview-label', + ]), + default => parent::attributePreviewHtml($attribute) + }; + } + + /** + * @inheritdoc + */ + protected static function defineCardAttributes(): array + { + return array_merge(parent::defineCardAttributes(), [ + 'basePromotionalPrice' => [ + 'label' => Craft::t('commerce', 'Base Promotional Price'), + 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'basePrice' => [ + 'label' => Craft::t('commerce', 'Base Price'), + 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'product' => [ + 'label' => Craft::t('commerce', 'Product'), + ], + 'promotable' => [ + 'label' => Craft::t('commerce', 'Promotable'), + ], + 'availableForPurchase' => [ + 'label' => Craft::t('commerce', 'Available for purchase'), + ], + 'priceView' => [ + 'label' => Craft::t('commerce', 'Price'), + 'placeholder' => Html::tag('del','¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(199.99), ['style' => 'opacity: .5']) . ' ¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'sku' => [ + 'label' => Craft::t('commerce', 'SKU'), + 'placeholder' => Html::tag('code', 'SKU123'), + ], + ]); + } + + /** + * @inheritdoc + */ + protected static function defineDefaultCardAttributes(): array + { + return array_merge(parent::defineDefaultCardAttributes(), [ + 'sku', + 'priceView', + ]); + } + /** * @inheritdoc */ @@ -1377,6 +1444,15 @@ protected function attributeHtml(string $attribute): string return sprintf(' %s', $product->getStatus(), Html::encode($product->title)); } + if ($attribute === 'priceView') { + $price = $this->basePriceAsCurrency; + if ($this->getBasePromotionalPrice() && $this->getBasePromotionalPrice() < $this->getBasePrice()) { + $price = Html::tag('del', $price, ['style' => 'opacity: .5']) . ' ' . $this->basePromotionalPriceAsCurrency; + } + + return $price; + } + return parent::attributeHtml($attribute); } } From 0d7ec5ffd7ab0584a2c48c73627f13571a86b96a Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 10 Dec 2024 12:40:02 +0000 Subject: [PATCH 5/6] Move card attributes to purchasable class --- src/base/Purchasable.php | 95 ++++++++++++++++++++++++++++++++++++++++ src/elements/Variant.php | 88 +++++-------------------------------- 2 files changed, 107 insertions(+), 76 deletions(-) diff --git a/src/base/Purchasable.php b/src/base/Purchasable.php index 764fbc4eb4..2a95d0fd36 100644 --- a/src/base/Purchasable.php +++ b/src/base/Purchasable.php @@ -1276,6 +1276,24 @@ protected function attributeHtml(string $attribute): string } } + $dimensions = []; + if ($attribute === 'dimensions') { + $dimensions = array_filter([ + $this->length, + $this->width, + $this->height + ]); + } + + if ($attribute === 'priceView') { + $price = $this->basePriceAsCurrency; + if ($this->getBasePromotionalPrice() && $this->getBasePromotionalPrice() < $this->getBasePrice()) { + $price = Html::tag('del', $price, ['style' => 'opacity: .5']) . ' ' . $this->basePromotionalPriceAsCurrency; + } + + return $price; + } + return match ($attribute) { 'sku' => (string)Html::encode($this->getSkuAsText()), 'price' => $this->basePriceAsCurrency, @@ -1287,6 +1305,7 @@ protected function attributeHtml(string $attribute): string 'minQty' => (string)$this->minQty, 'maxQty' => (string)$this->maxQty, 'stock' => $stock, + 'dimensions' => !empty($dimensions) ? implode(' x ', $dimensions) . ' ' . Plugin::getInstance()->getSettings()->dimensionUnits : '', default => parent::attributeHtml($attribute), }; } @@ -1324,6 +1343,82 @@ protected static function defineDefaultTableAttributes(string $source): array ]; } + /** + * @inheritdoc + */ + public static function attributePreviewHtml(array $attribute): mixed + { + return match($attribute['value']) { + 'sku', 'priceView', 'dimensions', 'weight' => $attribute['placeholder'], + 'availableForPurchase', 'promotable' => Html::tag('span', '', [ + 'class' => 'checkbox-icon', + 'role' => 'img', + 'title' => $attribute['label'], + 'aria' => [ + 'label' => $attribute['label'], + ], + ]) . + Html::tag('span', $attribute['label'], [ + 'class' => 'checkbox-preview-label', + ]), + default => parent::attributePreviewHtml($attribute) + }; + } + + /** + * @inheritdoc + */ + protected static function defineDefaultCardAttributes(): array + { + return array_merge(parent::defineDefaultCardAttributes(), [ + 'sku', + 'priceView', + ]); + } + + /** + * @inheritdoc + */ + protected static function defineCardAttributes(): array + { + return array_merge(Element::defineCardAttributes(), [ + 'availableForPurchase' => [ + 'label' => Craft::t('commerce', 'Available for purchase'), + ], + 'basePrice' => [ + 'label' => Craft::t('commerce', 'Base Price'), + 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'basePromotionalPrice' => [ + 'label' => Craft::t('commerce', 'Base Promotional Price'), + 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'dimensions' => [ + 'label' => Craft::t('commerce', 'Dimensions'), + 'placeholder' => '1 x 2 x 3 ' . Plugin::getInstance()->getSettings()->dimensionUnits, + ], + 'priceView' => [ + 'label' => Craft::t('commerce', 'Price'), + 'placeholder' => Html::tag('del', '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(199.99), ['style' => 'opacity: .5']) . ' ¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), + ], + 'promotable' => [ + 'label' => Craft::t('commerce', 'Promotable'), + ], + 'sku' => [ + 'label' => Craft::t('commerce', 'SKU'), + 'placeholder' => Html::tag('code', 'SKU123'), + ], + 'stock' => [ + 'label' => Craft::t('commerce', 'Stock'), + 'placeholder' => 10, + ], + 'weight' => [ + 'label' => Craft::t('commerce', 'Weight'), + 'placeholder' => 123 . Plugin::getInstance()->getSettings()->weightUnits, + ] + ]); + } + /** * @inheritdoc */ diff --git a/src/elements/Variant.php b/src/elements/Variant.php index 6204d5307d..7ef4f42117 100755 --- a/src/elements/Variant.php +++ b/src/elements/Variant.php @@ -1338,73 +1338,6 @@ protected static function defineActions(string $source): array ]]; } - /** - * @inheritdoc - */ - public static function attributePreviewHtml(array $attribute): mixed - { - return match($attribute['value']) { - 'sku', 'priceView' => $attribute['placeholder'], - 'availableForPurchase', 'promotable' => Html::tag('span', '', [ - 'class' => 'checkbox-icon', - 'role' => 'img', - 'title' => $attribute['label'], - 'aria' => [ - 'label' => $attribute['label'], - ], - ]) . - Html::tag('span', $attribute['label'], [ - 'class' => 'checkbox-preview-label', - ]), - default => parent::attributePreviewHtml($attribute) - }; - } - - /** - * @inheritdoc - */ - protected static function defineCardAttributes(): array - { - return array_merge(parent::defineCardAttributes(), [ - 'basePromotionalPrice' => [ - 'label' => Craft::t('commerce', 'Base Promotional Price'), - 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), - ], - 'basePrice' => [ - 'label' => Craft::t('commerce', 'Base Price'), - 'placeholder' => '¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), - ], - 'product' => [ - 'label' => Craft::t('commerce', 'Product'), - ], - 'promotable' => [ - 'label' => Craft::t('commerce', 'Promotable'), - ], - 'availableForPurchase' => [ - 'label' => Craft::t('commerce', 'Available for purchase'), - ], - 'priceView' => [ - 'label' => Craft::t('commerce', 'Price'), - 'placeholder' => Html::tag('del','¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(199.99), ['style' => 'opacity: .5']) . ' ¤' . Craft::$app->getFormattingLocale()->getFormatter()->asDecimal(123.99), - ], - 'sku' => [ - 'label' => Craft::t('commerce', 'SKU'), - 'placeholder' => Html::tag('code', 'SKU123'), - ], - ]); - } - - /** - * @inheritdoc - */ - protected static function defineDefaultCardAttributes(): array - { - return array_merge(parent::defineDefaultCardAttributes(), [ - 'sku', - 'priceView', - ]); - } - /** * @inheritdoc */ @@ -1439,6 +1372,18 @@ protected static function defineSearchableAttributes(): array return [...parent::defineSearchableAttributes(), ...['productTitle']]; } + /** + * @inheritdoc + */ + protected static function defineCardAttributes(): array + { + return array_merge(parent::defineCardAttributes(), [ + 'product' => [ + 'label' => Craft::t('commerce', 'Product'), + ], + ]); + } + /** * @inheritdoc */ @@ -1453,15 +1398,6 @@ protected function attributeHtml(string $attribute): string return sprintf(' %s', $product->getStatus(), Html::encode($product->title)); } - if ($attribute === 'priceView') { - $price = $this->basePriceAsCurrency; - if ($this->getBasePromotionalPrice() && $this->getBasePromotionalPrice() < $this->getBasePrice()) { - $price = Html::tag('del', $price, ['style' => 'opacity: .5']) . ' ' . $this->basePromotionalPriceAsCurrency; - } - - return $price; - } - return parent::attributeHtml($attribute); } } From ae5601c4658de09d1b10d12c38421714b13110b9 Mon Sep 17 00:00:00 2001 From: Nathaniel Hammond Date: Tue, 10 Dec 2024 12:43:02 +0000 Subject: [PATCH 6/6] fix cs --- src/base/Purchasable.php | 8 ++++---- src/elements/Product.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/base/Purchasable.php b/src/base/Purchasable.php index 2a95d0fd36..d3fc8d55c3 100644 --- a/src/base/Purchasable.php +++ b/src/base/Purchasable.php @@ -1281,7 +1281,7 @@ protected function attributeHtml(string $attribute): string $dimensions = array_filter([ $this->length, $this->width, - $this->height + $this->height, ]); } @@ -1348,9 +1348,9 @@ protected static function defineDefaultTableAttributes(string $source): array */ public static function attributePreviewHtml(array $attribute): mixed { - return match($attribute['value']) { + return match ($attribute['value']) { 'sku', 'priceView', 'dimensions', 'weight' => $attribute['placeholder'], - 'availableForPurchase', 'promotable' => Html::tag('span', '', [ + 'availableForPurchase', 'promotable' => Html::tag('span', '', [ 'class' => 'checkbox-icon', 'role' => 'img', 'title' => $attribute['label'], @@ -1415,7 +1415,7 @@ protected static function defineCardAttributes(): array 'weight' => [ 'label' => Craft::t('commerce', 'Weight'), 'placeholder' => 123 . Plugin::getInstance()->getSettings()->weightUnits, - ] + ], ]); } diff --git a/src/elements/Product.php b/src/elements/Product.php index 895920d15a..8261a18620 100644 --- a/src/elements/Product.php +++ b/src/elements/Product.php @@ -570,7 +570,7 @@ protected static function defineDefaultTableAttributes(string $source): array */ public static function attributePreviewHtml(array $attribute): mixed { - return match($attribute['value']) { + return match ($attribute['value']) { 'defaultSku' => $attribute['placeholder'], default => parent::attributePreviewHtml($attribute) };