Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion modules/cart/commerce_cart.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ commerce_cart.page:
_title: 'Shopping cart'
requirements:
_permission: 'access cart'

Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?php

/**
* @file
* Test module for Cart.
*/

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityMalformedException;

Expand Down
4 changes: 3 additions & 1 deletion modules/log/src/LogTemplateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
class LogTemplateManager extends DefaultPluginManager implements LogTemplateManagerInterface {

/**
* The commerce_log_category category manager.
* The log category manager.
*
* @var \Drupal\commerce_log\LogCategoryManagerInterface
*/
Expand All @@ -46,6 +46,8 @@ class LogTemplateManager extends DefaultPluginManager implements LogTemplateMana
* The module handler.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* The cache backend.
* @param \Drupal\commerce_log\LogCategoryManagerInterface $category_manager
* The log category manager.
*/
public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LogCategoryManagerInterface $category_manager) {
$this->moduleHandler = $module_handler;
Expand Down
7 changes: 6 additions & 1 deletion modules/log/tests/module/commerce_log_test.module
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?php
use Drupal\commerce_log\Entity\Log;

/**
* @file
* Test module for Log.
*/

use Drupal\Core\Entity\EntityInterface;

/**
Expand Down
20 changes: 20 additions & 0 deletions modules/order/commerce_order.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* @file
* Install, update and uninstall functions for the Order module.
*/

use Drupal\Core\Field\BaseFieldDefinition;

/**
* Add the 'data' field to 'commerce_order_item' entities.
*/
function commerce_order_update_8201() {
$storage_definition = BaseFieldDefinition::create('map')
->setLabel(t('Data'))
->setDescription(t('A serialized array of additional data.'));

$update_manager = \Drupal::entityDefinitionUpdateManager();
$update_manager->installFieldStorageDefinition('data', 'commerce_order_item', 'commerce_order', $storage_definition);
}
5 changes: 3 additions & 2 deletions modules/order/commerce_order.module
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use Drupal\commerce\BundleFieldDefinition;
use Drupal\commerce_order\Entity\OrderTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;

Expand Down Expand Up @@ -87,7 +88,7 @@ function commerce_order_field_widget_form_alter(&$element, FormStateInterface $f
* - elements: An associative array containing rendered fields.
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_commerce_order(&$variables) {
function template_preprocess_commerce_order(array &$variables) {
/** @var Drupal\commerce_order\Entity\OrderInterface $order */
$order = $variables['elements']['#commerce_order'];

Expand Down Expand Up @@ -130,7 +131,7 @@ function commerce_order_theme_suggestions_commerce_order_receipt(array $variable
* @param \Drupal\commerce_order\Entity\OrderTypeInterface $order_type
* The order type.
*/
function commerce_order_add_order_items_field($order_type) {
function commerce_order_add_order_items_field(OrderTypeInterface $order_type) {
$field_definition = BundleFieldDefinition::create('entity_reference')
->setTargetEntityTypeId('commerce_order')
->setTargetBundle($order_type->id())
Expand Down
4 changes: 2 additions & 2 deletions modules/order/src/Entity/OrderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ public function setRefreshState($refresh_state);
* @param mixed $default
* The default value.
*
* @return array
* The order data.
* @return mixed
* The value.
*/
public function getData($key, $default = NULL);

Expand Down
23 changes: 23 additions & 0 deletions modules/order/src/Entity/OrderItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ public function getTotalPrice() {
}
}

/**
* {@inheritdoc}
*/
public function getData($key, $default = NULL) {
$data = [];
if (!$this->get('data')->isEmpty()) {
$data = $this->get('data')->first()->getValue();
}
return isset($data[$key]) ? $data[$key] : $default;
}

/**
* {@inheritdoc}
*/
public function setData($key, $value) {
$this->get('data')->__set($key, $value);
return $this;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -275,6 +294,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', TRUE);

$fields['data'] = BaseFieldDefinition::create('map')
->setLabel(t('Data'))
->setDescription(t('A serialized array of additional data.'));

$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time when the order item was created.'))
Expand Down
27 changes: 27 additions & 0 deletions modules/order/src/Entity/OrderItemInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ public function setUnitPrice(Price $unit_price);
*/
public function getTotalPrice();

/**
* Gets an order item data value with the given key.
*
* Used to store temporary data during order processing (i.e. checkout).
*
* @param string $key
* The key.
* @param mixed $default
* The default value.
*
* @return mixed
* The value.
*/
public function getData($key, $default = NULL);

/**
* Sets an order item data value with the given key.
*
* @param string $key
* The key.
* @param mixed $value
* The value.
*
* @return $this
*/
public function setData($key, $value);

/**
* Gets the order item creation timestamp.
*
Expand Down
2 changes: 1 addition & 1 deletion modules/order/src/Form/OrderAddForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Drupal\commerce_order\Form;

use \Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ protected function getAdministratorPermissions() {
], parent::getAdministratorPermissions());
}

/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}

/**
* Tests the reassign form with a new user.
*/
Expand Down
6 changes: 6 additions & 0 deletions modules/order/tests/src/Kernel/Entity/OrderItemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ protected function setUp() {
* @covers ::removeAdjustment
* @covers ::recalculateTotalPrice
* @covers ::getTotalPrice
* @covers ::getData
* @covers ::setData
* @covers ::getCreatedTime
* @covers ::setCreatedTime
*/
Expand Down Expand Up @@ -106,6 +108,10 @@ public function testOrderItem() {
$order_item->setAdjustments($adjustments);
$this->assertEquals($adjustments, $order_item->getAdjustments());

$this->assertEquals('default', $order_item->getData('test', 'default'));
$order_item->setData('test', 'value');
$this->assertEquals('value', $order_item->getData('test', 'default'));

$order_item->setCreatedTime(635879700);
$this->assertEquals(635879700, $order_item->getCreatedTime());
}
Expand Down
3 changes: 2 additions & 1 deletion modules/payment/src/Form/PaymentAddForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ protected function buildPaymentMethodForm(array $form, FormStateInterface $form_

/** @var \Drupal\commerce_payment\PaymentMethodStorageInterface $payment_method_storage */
$payment_method_storage = $this->entityTypeManager->getStorage('commerce_payment_method');
$payment_methods = $payment_method_storage->loadReusable($this->order->getCustomer(), $selected_payment_gateway);
$billing_countries = $this->order->getStore()->getBillingCountries();
$payment_methods = $payment_method_storage->loadReusable($this->order->getCustomer(), $selected_payment_gateway, $billing_countries);

if (!empty($payment_methods)) {
$selected_payment_method = reset($payment_methods);
Expand Down
81 changes: 79 additions & 2 deletions modules/payment/src/PaymentMethodStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,78 @@
namespace Drupal\commerce_payment;

use Drupal\commerce\CommerceContentEntityStorage;
use Drupal\commerce\TimeInterface;
use Drupal\commerce_payment\Entity\PaymentGatewayInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsStoredPaymentMethodsInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
* Defines the payment method storage.
*/
class PaymentMethodStorage extends CommerceContentEntityStorage implements PaymentMethodStorageInterface {

/**
* The time.
*
* @var \Drupal\commerce\TimeInterface
*/
protected $time;

/**
* Constructs a new PaymentMethodStorage object.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type definition.
* @param \Drupal\Core\Database\Connection $database
* The database connection to be used.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend to be used.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
* @param \Drupal\commerce\TimeInterface $time
* The time.
*/
public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, EventDispatcherInterface $event_dispatcher, TimeInterface $time) {
parent::__construct($entity_type, $database, $entity_manager, $cache, $language_manager, $event_dispatcher);

$this->time = $time;
}

/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
$container->get('database'),
$container->get('entity.manager'),
$container->get('cache.entity'),
$container->get('language_manager'),
$container->get('event_dispatcher'),
$container->get('commerce.time')
);
}

/**
* {@inheritdoc}
*/
public function loadReusable(UserInterface $account, PaymentGatewayInterface $payment_gateway) {
public function loadReusable(UserInterface $account, PaymentGatewayInterface $payment_gateway, array $billing_countries = []) {
// Anonymous users cannot have reusable payment methods.
if ($account->isAnonymous()) {
return [];
}
if (!($payment_gateway->getPlugin() instanceof SupportsStoredPaymentMethodsInterface)) {
return [];
}
Expand All @@ -25,13 +83,32 @@ public function loadReusable(UserInterface $account, PaymentGatewayInterface $pa
->condition('uid', $account->id())
->condition('payment_gateway', $payment_gateway->id())
->condition('reusable', TRUE)
->condition('expires', $this->time->getRequestTime(), '>')
->sort('created', 'DESC');
$result = $query->execute();
if (empty($result)) {
return [];
}

return $this->loadMultiple($result);
/** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface[] $payment_methods */
$payment_methods = $this->loadMultiple($result);
if (!empty($billing_countries)) {
// Filter out payment methods that don't match the billing countries.
// Payment methods without a billing profile should also be filtered out.
// @todo Use a query condition once #2822359 is fixed.
foreach ($payment_methods as $id => $payment_method) {
$country_code = 'ZZ';
if ($billing_profile = $payment_method->getBillingProfile()) {
$country_code = $billing_profile->address->first()->getCountryCode();
}

if (!in_array($country_code, $billing_countries)) {
unset($payment_methods[$id]);
}
}
}

return $payment_methods;
}

/**
Expand Down
6 changes: 5 additions & 1 deletion modules/payment/src/PaymentMethodStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ interface PaymentMethodStorageInterface extends ContentEntityStorageInterface {
* The user account.
* @param \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway
* The payment gateway.
* @param array $billing_countries
* (Optional) A list of billing countries to filter by.
* For example, if ['US', 'FR'] is given, only payment methods
* with billing profiles from those countries will be returned.
*
* @return \Drupal\commerce_payment\Entity\PaymentMethodInterface[]
* The reusable payment methods.
*/
public function loadReusable(UserInterface $account, PaymentGatewayInterface $payment_gateway);
public function loadReusable(UserInterface $account, PaymentGatewayInterface $payment_gateway, array $billing_countries = []);

}
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ protected function attachPaymentMethodForm(EntityPaymentGatewayInterface $paymen
$order_payment_method = $this->order->payment_method->entity;
$customer = $this->order->getCustomer();
if ($customer) {
$payment_methods = $payment_method_storage->loadReusable($customer, $payment_gateway);
$billing_countries = $this->order->getStore()->getBillingCountries();
$payment_methods = $payment_method_storage->loadReusable($customer, $payment_gateway, $billing_countries);
foreach ($payment_methods as $payment_method) {
$options[$payment_method->id()] = $payment_method->label();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ public function buildPaneForm(array $pane_form, FormStateInterface $form_state,

return $pane_form;
}
else {
$this->checkoutFlow->redirectToStep($this->checkoutFlow->getNextStepId());
}
}

/**
Expand Down
Loading