Skip to content
Closed
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
87 changes: 87 additions & 0 deletions modules/payment/commerce_payment.post_update.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/**
* @file
* Post update functions for Payment.
*/

/**
* Update user Remote ID field data using payments gateways instead of module.
*
* @see https://www.drupal.org/node/2861181
*/
function commerce_payment_post_update_1(&$sandbox) {
// Use the sandbox to store the information needed to track progression.
if (!isset($sandbox['current'])) {
// First check is any user has this field set.
if ($count = \Drupal::entityQuery('user')->exists('commerce_remote_id')->count()->execute()) {
// The count of entities visited so far.
$sandbox['current'] = 0;
// Total entities that must be visited.
$sandbox['max'] = $count;

// Get the first payment gateway for every payment module.
$payment_gateways_by_module = [];
/** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
$payment_gateway_storage = \Drupal::entityTypeManager()->getStorage('commerce_payment_gateway');
$payment_gateways = $payment_gateway_storage->loadMultiple();
uasort($payment_gateways, [$payment_gateway_storage->getEntityType()->getClass(), 'sort']);
foreach ($payment_gateways as $payment_gateway) {
$payment_gateway_data = $payment_gateway->toArray();
$module = reset($payment_gateway_data['dependencies']['module']);
if (!isset($payment_gateways_by_module[$module])) {
$payment_gateways_by_module[$module] = $payment_gateway;
}
}
$sandbox['payment_gateways'] = $payment_gateways;
$sandbox['payment_gateways_by_module'] = $payment_gateways_by_module;
$sandbox['user_storage'] = \Drupal::entityTypeManager()->getStorage('user');
}
else {
return t('No user Remote ID field data to update.');
}
}

// Process entities by groups of 20.
$limit = 20;
// Get the user ids that have 'commerce_remote_id' field not empty.
$result = \Drupal::entityQuery('user')
->exists('commerce_remote_id')
->range($sandbox['current'], $limit)
->execute();

foreach ($result as $uid) {
$user = $sandbox['user_storage']->load($uid);

$save = FALSE;
/** @var \Drupal\commerce\Plugin\Field\FieldType\RemoteIdFieldItemListInterface $remote_ids */
$remote_ids = $user->commerce_remote_id;
/** @var \Drupal\commerce\Plugin\Field\FieldType\RemoteIdItem $item */
foreach ($remote_ids as $index => $item) {
$current_provider = $item->getValue()['provider'];
if (in_array($current_provider, array_keys($sandbox['payment_gateways_by_module']))) {
$payment_gateway = $sandbox['payment_gateways_by_module'][$current_provider];
$item->set('provider', $payment_gateway->id() . '-' . $payment_gateway->getPlugin()->getMode());
$save = TRUE;
}
elseif (!in_array($current_provider, array_keys($sandbox['payment_gateways']))) {
// Delete "orphaned" Remote Ids.
$remote_ids->removeItem($index);
$save = TRUE;
}
}
if ($save) {
$user->save();
}

// Update our progress information.
$sandbox['current']++;
}

$sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']);

if ($sandbox['#finished'] >= 1) {
return t('The user Remote ID field data for payments updated.');
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Plugin\PluginWithFormsTrait;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
Expand Down Expand Up @@ -319,4 +320,25 @@ public function buildPaymentOperations(PaymentInterface $payment) {
return $operations;
}

/**
* {@inheritdoc}
*/
public function getOwnerRemoteId(UserInterface $user) {
$remote_id = NULL;
if ($user->isAuthenticated()) {
$remote_id = $user->commerce_remote_id->getByProvider($this->entityId . '-' . $this->getMode());
}
return $remote_id;
}

/**
* {@inheritdoc}
*/
public function setOwnerRemoteId(UserInterface $user, $remote_id) {
if ($user->isAuthenticated()) {
$user->commerce_remote_id->setByProvider($this->entityId . '-' . $this->getMode(), $remote_id);
$user->save();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Drupal\Component\Plugin\DerivativeInspectionInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\user\UserInterface;

/**
* Defines the base interface for payment gateways.
Expand Down Expand Up @@ -112,4 +113,25 @@ public function getCreditCardTypes();
*/
public function buildPaymentOperations(PaymentInterface $payment);

/**
* Gets the user remote ID for the payment gateway if any.
*
* @param \Drupal\user\UserInterface $user
* The user.
*
* @return string|null
* The user remote ID for the payment gateway or NULL.
*/
public function getOwnerRemoteId(UserInterface $user);

/**
* Sets the user remote ID for the payment gateway.
*
* @param \Drupal\user\UserInterface $user
* The user.
* @param string $remote_id
* The remote ID.
*/
public function setOwnerRemoteId(UserInterface $user, $remote_id);

}
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,14 @@ public function testCheckoutWithExistingPaymentMethod() {
$this->assertSession()->pageTextContains('Your order number is 1. You can view your order on your account page when logged in.');

$order = Order::load(1);
$this->assertEquals('onsite', $order->get('payment_gateway')->target_id);
$this->assertEquals('1', $order->get('payment_method')->target_id);
/** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */
$payment_method = $order->get('payment_method')->entity;
$this->assertEquals('1', $payment_method->id());
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
$payment_gateway = $order->get('payment_gateway')->entity;
$this->assertEquals('onsite', $payment_gateway->id());
$payment_gateway_plugin = $payment_gateway->getPlugin();
$this->assertNull($payment_gateway_plugin->getOwnerRemoteId($payment_method->getOwner()));

// Verify that a payment was created.
$payment = Payment::load(1);
Expand Down Expand Up @@ -283,6 +289,11 @@ public function testCheckoutWithNewPaymentMethod() {
$payment_method = $order->get('payment_method')->entity;
$this->assertEquals('1881', $payment_method->get('card_number')->value);
$this->assertEquals('123 New York Drive', $payment_method->getBillingProfile()->get('address')->address_line1);
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
$payment_gateway = $order->get('payment_gateway')->entity;
$payment_gateway_plugin = $payment_gateway->getPlugin();
$owner = $payment_method->getOwner();
$this->assertEquals($owner->id(), $payment_gateway_plugin->getOwnerRemoteId($owner));

// Verify that a payment was created.
$payment = Payment::load(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ public function createPaymentMethod(PaymentMethodInterface $payment_method, arra
}
}

// Payment method remote owner id.
$owner = $payment_method->getOwner();
if (!$this->getOwnerRemoteId($owner)) {
$this->setOwnerRemoteId($owner, $owner->id());
}

// Perform the create request here, throw an exception if it fails.
// See \Drupal\commerce_payment\Exception for the available exceptions.
// You might need to do different API requests based on whether the
Expand Down