Skip to content

Commit

Permalink
Issue #2980702 by bojanz: Allow conditions to optionally be aware of …
Browse files Browse the repository at this point in the history
…the parent entity
  • Loading branch information
bojanz committed Jun 28, 2018
1 parent 06497cd commit 59230dd
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Drupal\commerce_order\Plugin\Commerce\Condition;

use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase;
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareTrait;
use Drupal\commerce_price\Calculator;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
Expand All @@ -18,9 +20,12 @@
* label = @Translation("Total product quantity"),
* category = @Translation("Order"),
* entity_type = "commerce_order",
* parent_entity_type = "commerce_promotion",
* )
*/
class OrderItemQuantity extends ConditionBase {
class OrderItemQuantity extends ConditionBase implements ParentEntityAwareInterface {

use ParentEntityAwareTrait;

/**
* {@inheritdoc}
Expand Down Expand Up @@ -74,6 +79,9 @@ public function evaluate(EntityInterface $entity) {
$this->assertEntity($entity);
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $entity;
/** @var \Drupal\commerce_promotion\Entity\PromotionInterface $promotion */
$promotion = $this->parentEntity;

$quantity = '0';
foreach ($order->getItems() as $order_item) {
// @todo Filter by offer conditions here, once available.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\Entity\OrderItemInterface;
use Drupal\commerce_order\Plugin\Commerce\Condition\OrderItemQuantity;
use Drupal\commerce_promotion\Entity\PromotionInterface;
use Drupal\Tests\UnitTestCase;

/**
Expand All @@ -19,10 +20,15 @@ class OrderItemQuantityTest extends UnitTestCase {
* @dataProvider quantityProvider
*/
public function testEvaluate($operator, $quantity, $given_quantity, $result) {
$parent_entity = $this->prophesize(PromotionInterface::class);
$parent_entity = $parent_entity->reveal();

$condition = new OrderItemQuantity([
'operator' => $operator,
'quantity' => $quantity,
], 'order_item_quantity', ['entity_type' => 'commerce_order']);
$condition->setParentEntity($parent_entity);

$order_item = $this->prophesize(OrderItemInterface::class);
$order_item->getEntityTypeId()->willReturn('commerce_order_item');
$order_item->getQuantity()->willReturn($given_quantity);
Expand Down
7 changes: 6 additions & 1 deletion modules/payment/src/Entity/PaymentGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Drupal\commerce\CommerceSinglePluginCollection;
use Drupal\commerce\ConditionGroup;
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\Core\Config\Entity\ConfigEntityBase;

Expand Down Expand Up @@ -188,7 +189,11 @@ public function getConditions() {
$plugin_manager = \Drupal::service('plugin.manager.commerce_condition');
$conditions = [];
foreach ($this->conditions as $condition) {
$conditions[] = $plugin_manager->createInstance($condition['plugin'], $condition['configuration']);
$condition = $plugin_manager->createInstance($condition['plugin'], $condition['configuration']);
if ($condition instanceof ParentEntityAwareInterface) {
$condition->setParentEntity($this);
}
$conditions[] = $condition;
}
return $conditions;
}
Expand Down
7 changes: 6 additions & 1 deletion modules/promotion/src/Entity/Promotion.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Drupal\commerce\ConditionGroup;
use Drupal\commerce\Entity\CommerceContentEntityBase;
use Drupal\commerce\Plugin\Commerce\Condition\ConditionInterface;
use Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareInterface;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\OrderItemPromotionOfferInterface;
use Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\PromotionOfferInterface;
Expand Down Expand Up @@ -193,7 +194,11 @@ public function getConditions() {
$conditions = [];
foreach ($this->get('conditions') as $field_item) {
/** @var \Drupal\commerce\Plugin\Field\FieldType\PluginItemInterface $field_item */
$conditions[] = $field_item->getTargetInstance();
$condition = $field_item->getTargetInstance();
if ($condition instanceof ParentEntityAwareInterface) {
$condition->setParentEntity($this);
}
$conditions[] = $condition;
}
return $conditions;
}
Expand Down
12 changes: 12 additions & 0 deletions src/Annotation/CommerceCondition.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ class CommerceCondition extends Plugin {
*/
public $entity_type;

/**
* The parent entity type ID.
*
* This is the entity type ID of the entity that embeds the conditions.
* For example: 'commerce_promotion'.
*
* When specified, a condition will only be available on that entity type.
*
* @var string
*/
public $parent_entity_type;

/**
* The condition weight.
*
Expand Down
19 changes: 15 additions & 4 deletions src/ConditionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,21 @@ public function processDefinition(&$definition, $plugin_id) {
* {@inheritdoc}
*/
public function getFilteredDefinitions($parent_entity_type_id, array $entity_type_ids) {
$definitions = array_filter($this->getDefinitions(), function ($definition) use ($entity_type_ids) {
return in_array($definition['entity_type'], $entity_type_ids);
});
// Certain conditions might be unavailable to the given parent entity type.
$definitions = $this->getDefinitions();
foreach ($definitions as $plugin_id => $definition) {
// Filter by entity type.
if (!in_array($definition['entity_type'], $entity_type_ids)) {
unset($definitions[$plugin_id]);
continue;
}
// Filter by parent_entity_type, if specified by the plugin.
if (!empty($definition['parent_entity_type'])) {
if ($definition['parent_entity_type'] != $parent_entity_type_id) {
unset($definitions[$plugin_id]);
}
}
}
// Allow modules to filter the condition list.
$event = new FilterConditionsEvent($definitions, $parent_entity_type_id);
$this->eventDispatcher->dispatch(CommerceEvents::FILTER_CONDITIONS, $event);
$definitions = $event->getDefinitions();
Expand Down
26 changes: 26 additions & 0 deletions src/Plugin/Commerce/Condition/ParentEntityAwareInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Drupal\commerce\Plugin\Commerce\Condition;

use Drupal\Core\Entity\EntityInterface;

/**
* Defines the interface for conditions that depend on the parent entity.
*
* For example, an order condition needing access to the parent promotion.
*
* @see \Drupal\commerce\Plugin\Commerce\Condition\ParentEntityAwareTrait
*/
interface ParentEntityAwareInterface {

/**
* Sets the parent entity.
*
* @param \Drupal\Core\Entity\EntityInterface $parent_entity
* The parent entity.
*
* @return $this
*/
public function setParentEntity(EntityInterface $parent_entity);

}
27 changes: 27 additions & 0 deletions src/Plugin/Commerce/Condition/ParentEntityAwareTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Drupal\commerce\Plugin\Commerce\Condition;

use Drupal\Core\Entity\EntityInterface;

/**
* Provides a trait for implementing ParentEntityAwareInterface.
*/
trait ParentEntityAwareTrait {

/**
* The parent entity.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
protected $parentEntity;

/**
* {@inheritdoc}
*/
public function setParentEntity(EntityInterface $parent_entity) {
$this->parentEntity = $parent_entity;
return $this;
}

}

0 comments on commit 59230dd

Please sign in to comment.