Skip to content

Commit

Permalink
Merge branch 'release/4.5.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
nfourtythree committed Apr 2, 2024
2 parents 504896a + 18611d9 commit 77a3164
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 44 deletions.
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/BUG-REPORT-V3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ name: Bug Report – Commerce 3
description: Report an issue or unexpected behavior pertaining to Commerce 3
title: '[3.x]: '
labels:
- 🐞 bug
- commerce3
- Craft Commerce # Linear
- bug # Linear
body:
- type: markdown
attributes:
Expand Down
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ name: Bug Report – Commerce 4
description: Report an issue or unexpected behavior pertaining to Commerce 4
title: '[4.x]: '
labels:
- 🐞 bug
- commerce4
- Craft Commerce # Linear
- bug # Linear
body:
- type: markdown
attributes:
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Release Notes for Craft Commerce

## 4.5.3 - 2024-04-02

- The “Postcode Condition Formula” condition rule now allows multi-line input. ([#3147](https://github.com/craftcms/commerce/issues/3147)
- Fixed a bug where order adjustments could be duplicated. ([#3438](https://github.com/craftcms/commerce/issues/3438))
- Fixed a bug where successful refunds could show a failure notice.

## 4.5.2 - 2024-03-06

- Fixed a bug where order status sources weren’t showing count badges on the Orders index page. ([#3397](https://github.com/craftcms/commerce/issues/3397))
- Fixed a bug where discounts weren’t listing more than 128 related purchasables or categories. ([#3379](https://github.com/craftcms/commerce/issues/3379))

## 4.5.1.1 - 2024-03-01

- Fixed a bug where the “Share cart” order index action wasn’t working.
Expand Down
2 changes: 1 addition & 1 deletion src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public static function editions(): array
/**
* @inheritDoc
*/
public string $schemaVersion = '4.5.0';
public string $schemaVersion = '4.5.1';

/**
* @inheritdoc
Expand Down
45 changes: 45 additions & 0 deletions src/controllers/CartController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Throwable;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\mutex\Mutex;
use yii\web\BadRequestHttpException;
use yii\web\HttpException;
use yii\web\NotFoundHttpException;
Expand Down Expand Up @@ -52,6 +53,16 @@ class CartController extends BaseFrontEndController
*/
protected ?User $_currentUser = null;

/**
* @var Mutex|null
*/
private ?Mutex $_mutex = null;

/**
* @var string|null
*/
private ?string $_mutexLockName = null;

/**
* @throws InvalidConfigException
*/
Expand Down Expand Up @@ -92,10 +103,36 @@ public function actionUpdateCart(): ?Response
{
$this->requirePostRequest();
$isSiteRequest = $this->request->getIsSiteRequest();
$isConsoleRequest = $this->request->getIsConsoleRequest();
$currentUser = Craft::$app->getUser()->getIdentity();
/** @var Plugin $plugin */
$plugin = Plugin::getInstance();

$useMutex = (!$isConsoleRequest && Craft::$app->getRequest()->getBodyParam('number')) || (!$isConsoleRequest && $plugin->getCarts()->getHasSessionCartNumber());

if ($useMutex) {
$lockOrderNumber = null;
if ($bodyNumber = Craft::$app->getRequest()->getBodyParam('number')) {
$lockOrderNumber = $bodyNumber;
} elseif (!$isConsoleRequest) {
$request = Craft::$app->getRequest();
$requestCookies = $request->getCookies();
$cookieNumber = $requestCookies->getValue($plugin->getCarts()->cartCookie['name']);

if ($cookieNumber) {
$lockOrderNumber = $cookieNumber;
}
}

if ($lockOrderNumber) {
$this->_mutexLockName = "order:$lockOrderNumber";
$this->_mutex = Craft::$app->getMutex();
if (!$this->_mutex->acquire($this->_mutexLockName, 5)) {
throw new Exception('Unable to acquire a lock for saving of Order: ' . $lockOrderNumber);
}
}
}

// Get the cart from the request or from the session.
// When we are about to update the cart, we consider it a real cart at this point, and want to actually create it in the DB.
$this->_cart = $this->_getCart(true);
Expand Down Expand Up @@ -489,6 +526,10 @@ private function _returnCart(): ?Response
$error = Craft::t('commerce', 'Unable to update cart.');
$message = $this->request->getValidatedBodyParam('failMessage') ?? $error;

if ($this->_mutex && $this->_mutexLockName) {
$this->_mutex->release($this->_mutexLockName);
}

return $this->asModelFailure(
$this->_cart,
$message,
Expand All @@ -509,6 +550,10 @@ private function _returnCart(): ?Response
$this->_cartVariable => $this->_cart,
]);

if ($this->_mutex && $this->_mutexLockName) {
$this->_mutex->release($this->_mutexLockName);
}

return $this->asModelSuccess(
$this->_cart,
$message,
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/OrdersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ public function actionTransactionRefund(): Response

$message = $child->message ? ' (' . $child->message . ')' : '';

if ($child->status == TransactionRecord::STATUS_SUCCESS) {
if ($child->status == TransactionRecord::STATUS_SUCCESS || $child->status == TransactionRecord::STATUS_PROCESSING) {
$child->order->updateOrderPaidInformation();
$this->setSuccessFlash(Craft::t('commerce', 'Transaction refunded successfully: {message}', [
'message' => $message,
Expand Down Expand Up @@ -1210,7 +1210,7 @@ private function _registerJavascript(array $variables): void

$shippingCategories = Plugin::getInstance()->getShippingCategories()->getAllShippingCategoriesAsList();
Craft::$app->getView()->registerJs('window.orderEdit.shippingCategories = ' . Json::encode(ArrayHelper::toArray($shippingCategories)) . ';', View::POS_BEGIN);

$currentUser = Craft::$app->getUser()->getIdentity();
$permissions = [
'commerce-manageOrders' => $currentUser->can('commerce-manageOrders'),
Expand Down
34 changes: 34 additions & 0 deletions src/controllers/PaymentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,32 @@ public function actionPay(): ?Response

$number = $this->request->getParam('number');

$useMutex = $number || (!$isCpRequest && $plugin->getCarts()->getHasSessionCartNumber());

if ($useMutex) {
$lockOrderNumber = null;
if ($number) {
$lockOrderNumber = $number;
} elseif (!$isCpRequest) {
$request = Craft::$app->getRequest();
$requestCookies = $request->getCookies();
$cookieNumber = $requestCookies->getValue($plugin->getCarts()->cartCookie['name']);

if ($cookieNumber) {
$lockOrderNumber = $cookieNumber;
}
}

if ($lockOrderNumber) {
$lockName = "order:$lockOrderNumber";
$mutex = Craft::$app->getMutex();
if (!$mutex->acquire($lockName, 5)) {
throw new Exception('Unable to acquire a lock for saving of Order: ' . $lockOrderNumber);
}
}
}


if ($number !== null) {
$order = $plugin->getOrders()->getOrderByNumber($number);

Expand Down Expand Up @@ -375,6 +401,10 @@ public function actionPay(): ?Response

$error = Craft::t('commerce', 'Something changed with the order before payment, please review your order and submit payment again.');

if ($useMutex && isset($mutex, $lockName)) {
$mutex->release($lockName);
}

return $this->asModelFailure(
$paymentForm,
$error,
Expand All @@ -390,6 +420,10 @@ public function actionPay(): ?Response
}
}

if ($useMutex && isset($mutex, $lockName)) {
$mutex->release($lockName);
}

$redirect = '';
$redirectData = [];
$transaction = null;
Expand Down
6 changes: 6 additions & 0 deletions src/elements/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -3399,6 +3399,12 @@ private function _saveAdjustments(): void
$previousAdjustment->delete();
}
}

// Make sure all other adjustments have been cleaned up.
Db::delete(
Table::ORDERADJUSTMENTS,
['and', ['orderId' => $this->id], ['not', ['id' => $newAdjustmentIds]]]
);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@
*/
class PostalCodeFormulaConditionRule extends BaseTextConditionRule implements ElementConditionRuleInterface
{
/**
* @inheritdoc
*/
public function getLabel(): string
{
return Craft::t('commerce', 'Postal Code Formula');
}

/**
* @inheritdoc
*/
public function getExclusiveQueryParams(): array
{
return [];
Expand Down Expand Up @@ -70,14 +76,14 @@ public function operators(): array
public function inputHtml(): string
{
return Html::hiddenLabel($this->getLabel(), 'value') .
Cp::textHtml([
'type' => $this->inputType(),
'id' => 'value',
'name' => 'value',
'code' => 'value',
'value' => $this->value,
'autocomplete' => false,
'class' => 'fullwidth code',
]);
Cp::textareaHtml([
'type' => $this->inputType(),
'id' => 'value',
'name' => 'value',
'code' => 'value',
'value' => $this->value,
'autocomplete' => false,
'class' => 'fullwidth code',
]);
}
}
2 changes: 0 additions & 2 deletions src/elements/traits/OrderElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ protected static function defineSources(string $context = null): array
'label' => Craft::t('commerce', 'All Orders'),
'criteria' => ['isCompleted' => true],
'defaultSort' => ['dateOrdered', 'desc'],
'badgeCount' => 0,
'data' => [
'date-attr' => 'dateOrdered',
],
Expand All @@ -320,7 +319,6 @@ protected static function defineSources(string $context = null): array
'label' => Craft::t('site', $orderStatus->name),
'criteria' => $criteriaStatus,
'defaultSort' => ['dateOrdered', 'desc'],
'badgeCount' => 0,
'data' => [
'handle' => $orderStatus->handle,
'date-attr' => 'dateOrdered',
Expand Down
2 changes: 2 additions & 0 deletions src/migrations/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ public function createTables(): void
'hasFreeShippingForMatchingItems' => $this->boolean()->notNull()->defaultValue(false),
'hasFreeShippingForOrder' => $this->boolean()->notNull()->defaultValue(false),
'allPurchasables' => $this->boolean()->notNull()->defaultValue(false),
'purchasableIds' => $this->text(),
'allCategories' => $this->boolean()->notNull()->defaultValue(false),
'categoryIds' => $this->text(),
'appliedTo' => $this->enum('appliedTo', ['matchingLineItems', 'allLineItems'])->notNull()->defaultValue('matchingLineItems'),
'categoryRelationshipType' => $this->enum('categoryRelationshipType', ['element', 'sourceElement', 'targetElement'])->notNull()->defaultValue('element'),
'orderConditionFormula' => $this->text(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace craft\commerce\migrations;

use craft\db\Migration;
use craft\db\Query as Query;
use craft\helpers\Json;

/**
* m240306_091057_move_element_ids_on_discount_to_columns migration.
*/
class m240306_091057_move_element_ids_on_discount_to_columns extends Migration
{
/**
* @inheritdoc
*/
public function safeUp(): bool
{
$discountCategoriesTable = '{{%commerce_discount_categories}}';
$discountPurchasablesTables = '{{%commerce_discount_purchasables}}';
$discountsTable = '{{%commerce_discounts}}';

$this->addColumn($discountsTable, 'purchasableIds', $this->text()->after('allPurchasables'));
$this->addColumn($discountsTable, 'categoryIds', $this->text()->after('allCategories'));

$purchasableIdsByDiscountId = (new Query())
->select(['discountId', 'purchasableId'])
->from([$discountPurchasablesTables])
->collect();

$purchasableIdsByDiscountId = $purchasableIdsByDiscountId->groupBy('discountId')->map(function($row) {
return array_column($row->toArray(), 'purchasableId');
});

$categoryIdsByDiscountId = (new Query())
->select(['discountId', 'categoryId'])
->from([$discountCategoriesTable])
->collect();

$categoryIdsByDiscountId = $categoryIdsByDiscountId->groupBy('discountId')->map(function($row) {
return array_column($row->toArray(), 'categoryId');
});

foreach ($purchasableIdsByDiscountId as $discountId => $purchasableIds) {
$this->update($discountsTable, ['purchasableIds' => Json::encode($purchasableIds)], ['id' => $discountId]);
}

foreach ($categoryIdsByDiscountId as $discountId => $categoryIds) {
$this->update($discountsTable, ['categoryIds' => Json::encode($categoryIds)], ['id' => $discountId]);
}

return true;
}

/**
* @inheritdoc
*/
public function safeDown(): bool
{
echo "m240306_091057_move_element_ids_on_discount_to_columns cannot be reverted.\n";
return false;
}
}
2 changes: 2 additions & 0 deletions src/records/Discount.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
* Discount record.
*
* @property bool $allCategories
* @property ?array $categoryIds
* @property bool $allPurchasables
* @property ?array $purchasableIds
* @property float $baseDiscount
* @property float $purchaseTotal
* @property string $baseDiscountType
Expand Down
Loading

0 comments on commit 77a3164

Please sign in to comment.