Skip to content

Commit 59230dd

Browse files
committed
Issue #2980702 by bojanz: Allow conditions to optionally be aware of the parent entity
1 parent 06497cd commit 59230dd

File tree

8 files changed

+107
-7
lines changed

8 files changed

+107
-7
lines changed

modules/order/src/Plugin/Commerce/Condition/OrderItemQuantity.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Drupal\commerce_order\Plugin\Commerce\Condition;
44

55
use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase;
6+
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
7+
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareTrait;
68
use Drupal\commerce_price\Calculator;
79
use Drupal\Core\Entity\EntityInterface;
810
use Drupal\Core\Form\FormStateInterface;
@@ -18,9 +20,12 @@
1820
* label = @Translation("Total product quantity"),
1921
* category = @Translation("Order"),
2022
* entity_type = "commerce_order",
23+
* parent_entity_type = "commerce_promotion",
2124
* )
2225
*/
23-
class OrderItemQuantity extends ConditionBase {
26+
class OrderItemQuantity extends ConditionBase implements ParentEntityAwareInterface {
27+
28+
use ParentEntityAwareTrait;
2429

2530
/**
2631
* {@inheritdoc}
@@ -74,6 +79,9 @@ public function evaluate(EntityInterface $entity) {
7479
$this->assertEntity($entity);
7580
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
7681
$order = $entity;
82+
/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
83+
$promotion = $this->parentEntity;
84+
7785
$quantity = '0';
7886
foreach ($order->getItems() as $order_item) {
7987
// @todo Filter by offer conditions here, once available.

modules/order/tests/src/Unit/Plugin/Commerce/Condition/OrderItemQuantityTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Drupal\commerce_order\Entity\OrderInterface;
66
use Drupal\commerce_order\Entity\OrderItemInterface;
77
use Drupal\commerce_order\Plugin\Commerce\Condition\OrderItemQuantity;
8+
use Drupal\commerce_promotion\Entity\PromotionInterface;
89
use Drupal\Tests\UnitTestCase;
910

1011
/**
@@ -19,10 +20,15 @@ class OrderItemQuantityTest extends UnitTestCase {
1920
* @dataProvider quantityProvider
2021
*/
2122
public function testEvaluate($operator, $quantity, $given_quantity, $result) {
23+
$parent_entity = $this->prophesize(PromotionInterface::class);
24+
$parent_entity = $parent_entity->reveal();
25+
2226
$condition = new OrderItemQuantity([
2327
'operator' => $operator,
2428
'quantity' => $quantity,
2529
], 'order_item_quantity', ['entity_type' => 'commerce_order']);
30+
$condition->setParentEntity($parent_entity);
31+
2632
$order_item = $this->prophesize(OrderItemInterface::class);
2733
$order_item->getEntityTypeId()->willReturn('commerce_order_item');
2834
$order_item->getQuantity()->willReturn($given_quantity);

modules/payment/src/Entity/PaymentGateway.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Drupal\commerce\CommerceSinglePluginCollection;
66
use Drupal\commerce\ConditionGroup;
7+
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
78
use Drupal\commerce_order\Entity\OrderInterface;
89
use Drupal\Core\Config\Entity\ConfigEntityBase;
910

@@ -188,7 +189,11 @@ public function getConditions() {
188189
$plugin_manager = \Drupal::service('plugin.manager.commerce_condition');
189190
$conditions = [];
190191
foreach ($this->conditions as $condition) {
191-
$conditions[] = $plugin_manager->createInstance($condition['plugin'], $condition['configuration']);
192+
$condition = $plugin_manager->createInstance($condition['plugin'], $condition['configuration']);
193+
if ($condition instanceof ParentEntityAwareInterface) {
194+
$condition->setParentEntity($this);
195+
}
196+
$conditions[] = $condition;
192197
}
193198
return $conditions;
194199
}

modules/promotion/src/Entity/Promotion.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Drupal\commerce\ConditionGroup;
66
use Drupal\commerce\Entity\CommerceContentEntityBase;
77
use Drupal\commerce\Plugin\Commerce\Condition\ConditionInterface;
8+
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
89
use Drupal\commerce_order\Entity\OrderInterface;
910
use Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\OrderItemPromotionOfferInterface;
1011
use Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\PromotionOfferInterface;
@@ -193,7 +194,11 @@ public function getConditions() {
193194
$conditions = [];
194195
foreach ($this->get('conditions') as $field_item) {
195196
/** @var \Drupal\commerce\Plugin\Field\FieldType\PluginItemInterface $field_item */
196-
$conditions[] = $field_item->getTargetInstance();
197+
$condition = $field_item->getTargetInstance();
198+
if ($condition instanceof ParentEntityAwareInterface) {
199+
$condition->setParentEntity($this);
200+
}
201+
$conditions[] = $condition;
197202
}
198203
return $conditions;
199204
}

src/Annotation/CommerceCondition.php

+12
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ class CommerceCondition extends Plugin {
6060
*/
6161
public $entity_type;
6262

63+
/**
64+
* The parent entity type ID.
65+
*
66+
* This is the entity type ID of the entity that embeds the conditions.
67+
* For example: 'commerce_promotion'.
68+
*
69+
* When specified, a condition will only be available on that entity type.
70+
*
71+
* @var string
72+
*/
73+
public $parent_entity_type;
74+
6375
/**
6476
* The condition weight.
6577
*

src/ConditionManager.php

+15-4
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,21 @@ public function processDefinition(&$definition, $plugin_id) {
8282
* {@inheritdoc}
8383
*/
8484
public function getFilteredDefinitions($parent_entity_type_id, array $entity_type_ids) {
85-
$definitions = array_filter($this->getDefinitions(), function ($definition) use ($entity_type_ids) {
86-
return in_array($definition['entity_type'], $entity_type_ids);
87-
});
88-
// Certain conditions might be unavailable to the given parent entity type.
85+
$definitions = $this->getDefinitions();
86+
foreach ($definitions as $plugin_id => $definition) {
87+
// Filter by entity type.
88+
if (!in_array($definition['entity_type'], $entity_type_ids)) {
89+
unset($definitions[$plugin_id]);
90+
continue;
91+
}
92+
// Filter by parent_entity_type, if specified by the plugin.
93+
if (!empty($definition['parent_entity_type'])) {
94+
if ($definition['parent_entity_type'] != $parent_entity_type_id) {
95+
unset($definitions[$plugin_id]);
96+
}
97+
}
98+
}
99+
// Allow modules to filter the condition list.
89100
$event = new FilterConditionsEvent($definitions, $parent_entity_type_id);
90101
$this->eventDispatcher->dispatch(CommerceEvents::FILTER_CONDITIONS, $event);
91102
$definitions = $event->getDefinitions();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Drupal\commerce\Plugin\Commerce\Condition;
4+
5+
use Drupal\Core\Entity\EntityInterface;
6+
7+
/**
8+
* Defines the interface for conditions that depend on the parent entity.
9+
*
10+
* For example, an order condition needing access to the parent promotion.
11+
*
12+
* @see \Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareTrait
13+
*/
14+
interface ParentEntityAwareInterface {
15+
16+
/**
17+
* Sets the parent entity.
18+
*
19+
* @param \Drupal\Core\Entity\EntityInterface $parent_entity
20+
* The parent entity.
21+
*
22+
* @return $this
23+
*/
24+
public function setParentEntity(EntityInterface $parent_entity);
25+
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Drupal\commerce\Plugin\Commerce\Condition;
4+
5+
use Drupal\Core\Entity\EntityInterface;
6+
7+
/**
8+
* Provides a trait for implementing ParentEntityAwareInterface.
9+
*/
10+
trait ParentEntityAwareTrait {
11+
12+
/**
13+
* The parent entity.
14+
*
15+
* @var \Drupal\Core\Entity\EntityInterface
16+
*/
17+
protected $parentEntity;
18+
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function setParentEntity(EntityInterface $parent_entity) {
23+
$this->parentEntity = $parent_entity;
24+
return $this;
25+
}
26+
27+
}

0 commit comments

Comments
 (0)