Skip to content

Commit 64f9d46

Browse files
committed
Merge branch 'release/4.2.11'
2 parents 759a864 + 4655eda commit 64f9d46

File tree

7 files changed

+89
-43
lines changed

7 files changed

+89
-43
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Release Notes for Craft Commerce
22

3+
## 4.2.11 - 2023-06-05
4+
5+
- Fixed a bug where “Send Email” option text wasn’t getting translated. ([#3172](https://github.com/craftcms/commerce/issues/3172))
6+
- Fixed a bug where discounts’ user condition values weren’t getting migrated properly when upgrading to Commerce 4. ([#3176](https://github.com/craftcms/commerce/issues/3176))
7+
38
## 4.2.10 - 2023-05-31
49

510
- An error notification is now displayed when attempting to delete a user with existing orders or subscriptions. ([#3071](https://github.com/craftcms/commerce/pull/3071), [#3070](https://github.com/craftcms/commerce/pull/3070))

src/elements/conditions/customers/DiscountCustomerCondition.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace craft\commerce\elements\conditions\customers;
44

5+
use craft\commerce\elements\conditions\users\DiscountGroupConditionRule;
56
use craft\elements\conditions\users\UserCondition as UserElementCondition;
67

78
/**
@@ -20,6 +21,7 @@ protected function conditionRuleTypes(): array
2021
return array_merge(parent::conditionRuleTypes(), [
2122
HasOrdersConditionRule::class,
2223
SignedInConditionRule::class,
24+
DiscountGroupConditionRule::class,
2325
]);
2426
}
2527
}

src/elements/conditions/users/DiscountGroupConditionRule.php

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,48 @@
44

55
use craft\elements\conditions\users\GroupConditionRule;
66
use craft\elements\db\ElementQueryInterface;
7+
use yii\base\InvalidConfigException;
78
use yii\base\NotSupportedException;
89

910
/**
1011
* Discount user group condition rule.
1112
*
1213
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
1314
* @since 4.0.0
14-
*
15-
* @property-read float|int $orderAttributeValue
1615
*/
1716
class DiscountGroupConditionRule extends GroupConditionRule
1817
{
18+
protected const OPERATOR_IN_ALL = 'inAll';
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
public function getLabel(): string
24+
{
25+
return \Craft::t('app', 'User Groups');
26+
}
27+
28+
/**
29+
* @inheritDoc
30+
*/
31+
protected function operators(): array
32+
{
33+
return array_merge(parent::operators(), [
34+
self::OPERATOR_IN_ALL,
35+
]);
36+
}
37+
38+
/**
39+
* @inheritDoc
40+
*/
41+
protected function operatorLabel(string $operator): string
42+
{
43+
return match ($operator) {
44+
self::OPERATOR_IN_ALL => 'is in all of',
45+
default => parent::operatorLabel($operator)
46+
};
47+
}
48+
1949
/**
2050
* @inheritdoc
2151
*/
@@ -28,4 +58,30 @@ public function getExclusiveQueryParams(): array
2858
{
2959
return [];
3060
}
61+
62+
/**
63+
* Returns whether the condition rule matches the given value.
64+
*
65+
* @param string|string[]|null $value
66+
* @return bool
67+
*/
68+
protected function matchValue(array|string|null $value): bool
69+
{
70+
if (!$this->getValues()) {
71+
return true;
72+
}
73+
74+
if ($value === '' || $value === null) {
75+
$value = [];
76+
} else {
77+
$value = (array)$value;
78+
}
79+
80+
return match ($this->operator) {
81+
self::OPERATOR_IN => !empty(array_intersect($value, $this->getValues())),
82+
self::OPERATOR_NOT_IN => empty(array_intersect($value, $this->getValues())),
83+
self::OPERATOR_IN_ALL => empty(array_diff($this->getValues(), $value)),
84+
default => throw new InvalidConfigException("Invalid operator: $this->operator"),
85+
};
86+
}
3187
}

src/migrations/m220304_094835_discount_conditions.php

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use craft\commerce\elements\conditions\users\DiscountGroupConditionRule;
99
use craft\db\Migration;
1010
use craft\db\Query;
11+
use craft\helpers\Db;
1112
use craft\helpers\Json;
1213

1314
/**
@@ -21,9 +22,7 @@ class m220304_094835_discount_conditions extends Migration
2122
public function safeUp(): bool
2223
{
2324
$orderCondition = new DiscountOrderCondition();
24-
// TODO migrate some discount conditions to the builder
2525
$customerCondition = new DiscountCustomerCondition();
26-
// TODO migrate the user groups condition to the builder
2726
$shippingAddressCondition = new DiscountAddressCondition();
2827
$billingAddressCondition = new DiscountAddressCondition();
2928

@@ -42,41 +41,38 @@ public function safeUp(): bool
4241
'orderCondition' => Json::encode($orderCondition->getConfig()),
4342
], ['id' => $id]);
4443

45-
4644
/**
47-
* User condition
45+
* User/Customer condition
4846
*/
4947
$discountsUserGroupIds = (new Query())->select(['dug.userGroupId'])
5048
->from('{{%commerce_discounts}} discounts')
5149
->leftJoin('{{%commerce_discount_usergroups}} dug', '[[dug.discountId]] = [[discounts.id]]')
5250
->where(['discounts.id' => $id])
5351
->column();
5452

55-
$userGroupUids = $this->_getGroupUids($discountsUserGroupIds);
53+
$userGroupUids = Db::uidsByIds('{{%usergroups}}', $discountsUserGroupIds, $this->db);
5654

57-
$userRules = [];
58-
if ($discount['userGroupsCondition'] == 'userGroupsAnyOrNone') {
59-
// do nothing
60-
} elseif ($discount['userGroupsCondition'] == 'userGroupsIncludeAll') {
61-
foreach ($discountsUserGroupIds as $userGroupId) {
55+
if ($discountsUserGroupIds && $userGroupUids && ($discount['userGroupsCondition'] != 'userGroupsAnyOrNone')) {
56+
$userRules = [];
57+
if ($discount['userGroupsCondition'] == 'userGroupsIncludeAll') {
58+
$conditionRule = new DiscountGroupConditionRule();
59+
$conditionRule->setValues($userGroupUids);
60+
$conditionRule->operator = 'inAll';
61+
$userRules[] = $conditionRule;
62+
} elseif ($discount['userGroupsCondition'] == 'userGroupsIncludeAny') {
6263
$conditionRule = new DiscountGroupConditionRule();
63-
$userGroup = \Craft::$app->getUserGroups()->getGroupById($userGroupId);
64-
$conditionRule->setValues($userGroup->uid);
64+
$conditionRule->setValues($userGroupUids);
6565
$conditionRule->operator = 'in';
6666
$userRules[] = $conditionRule;
67+
} elseif ($discount['userGroupsCondition'] == 'userGroupsExcludeAny') {
68+
$conditionRule = new DiscountGroupConditionRule();
69+
$conditionRule->setValues($userGroupUids);
70+
$conditionRule->operator = 'ni';
71+
$userRules[] = $conditionRule;
6772
}
68-
} elseif ($discount['userGroupsCondition'] == 'userGroupsIncludeAny') {
69-
$conditionRule = new DiscountGroupConditionRule();
70-
$conditionRule->setValues($userGroupUids);
71-
$conditionRule->operator = 'in';
72-
$userRules[] = $conditionRule;
73-
} elseif ($discount['userGroupsCondition'] == 'userGroupsExcludeAny') {
74-
$conditionRule = new DiscountGroupConditionRule();
75-
$conditionRule->setValues($userGroupUids);
76-
$conditionRule->operator = 'ni';
77-
$userRules[] = $conditionRule;
73+
$customerCondition->setConditionRules($userRules);
7874
}
79-
$customerCondition->setConditionRules($userRules);
75+
8076
$this->update('{{%commerce_discounts}}', [
8177
'customerCondition' => Json::encode($customerCondition->getConfig()),
8278
], ['id' => $id]);
@@ -96,9 +92,10 @@ public function safeUp(): bool
9692
], ['id' => $id]);
9793
}
9894

95+
// No longer needed now that we have the condition builder
9996
$this->dropTableIfExists('{{%commerce_discount_usergroups}}');
10097
$this->dropColumn('{{%commerce_discounts}}', 'userGroupsCondition');
101-
98+
10299
return true;
103100
}
104101

@@ -110,17 +107,4 @@ public function safeDown(): bool
110107
echo "m220304_094835_discount_conditions cannot be reverted.\n";
111108
return false;
112109
}
113-
114-
/**
115-
* @param array $ids
116-
* @return array
117-
*/
118-
private function _getGroupUids(array $ids): array
119-
{
120-
return array_map(function($value) {
121-
$userGroup = \Craft::$app->getUserGroups()->getGroupById($value);
122-
123-
return $userGroup->uid;
124-
}, $ids);
125-
}
126110
}

src/web/assets/commerceui/dist/js/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/commerceui/dist/js/app.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/commerceui/src/js/order/apps/OrderSecondaryActions.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
3939
<a
4040
:href="emailTemplate.id"
4141
@click.prevent="sendEmail(emailTemplate.id)"
42-
>Send the “{{ emailTemplate.name }}”
43-
email</a
42+
>{{ emailTemplate.name }}</a
4443
>
4544
</li>
4645
</ul>

0 commit comments

Comments
 (0)