Skip to content

Commit 398b915

Browse files
MAGETWO-60351: Unnecessary disabled payment methods on checkout page #4868
1 parent ab7a89d commit 398b915

File tree

6 files changed

+466
-0
lines changed

6 files changed

+466
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Payment\Plugin;
7+
8+
/**
9+
* Class PaymentConfigurationProcess
10+
*
11+
* Removes inactive payment methods and group from checkout configuration.
12+
*/
13+
class PaymentConfigurationProcess
14+
{
15+
/**
16+
* @var \Magento\Payment\Api\PaymentMethodListInterface
17+
*/
18+
private $paymentMethodList;
19+
20+
/**
21+
* @var \Magento\Store\Model\StoreManagerInterface
22+
*/
23+
private $storeManager;
24+
25+
/**
26+
* @param \Magento\Payment\Api\PaymentMethodListInterface $paymentMethodList
27+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
28+
*/
29+
public function __construct(
30+
\Magento\Payment\Api\PaymentMethodListInterface $paymentMethodList,
31+
\Magento\Store\Model\StoreManagerInterface $storeManager
32+
) {
33+
$this->paymentMethodList = $paymentMethodList;
34+
$this->storeManager = $storeManager;
35+
}
36+
37+
/**
38+
* Checkout LayoutProcessor before process plugin.
39+
*
40+
* @param \Magento\Checkout\Block\Checkout\LayoutProcessor $processor
41+
* @param array $jsLayout
42+
* @return array
43+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
44+
*/
45+
public function beforeProcess(\Magento\Checkout\Block\Checkout\LayoutProcessor $processor, $jsLayout)
46+
{
47+
$configuration = &$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']
48+
['children']['payment']['children']['renders']['children'];
49+
50+
if (!isset($configuration)) {
51+
return [$jsLayout];
52+
}
53+
54+
$storeId = $this->storeManager->getStore()->getId();
55+
$activePaymentMethodList = $this->paymentMethodList->getActiveList($storeId);
56+
$getCodeFunc = function($method) {
57+
return $method->getCode();
58+
};
59+
$activePaymentMethodCodes = array_map($getCodeFunc, $activePaymentMethodList);
60+
61+
foreach ($configuration as $paymentGroup => $groupConfig) {
62+
foreach (array_keys($groupConfig['methods']) as $paymentCode) {
63+
if (!in_array($paymentCode, $activePaymentMethodCodes)) {
64+
unset($configuration[$paymentGroup]['methods'][$paymentCode]);
65+
}
66+
}
67+
if (empty($configuration[$paymentGroup]['methods'])) {
68+
unset($configuration[$paymentGroup]);
69+
}
70+
}
71+
72+
return [$jsLayout];
73+
}
74+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Payment\Test\Unit\Plugin;
7+
8+
/**
9+
* Class PaymentConfigurationProcessTest.
10+
*/
11+
class PaymentConfigurationProcessTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
15+
*/
16+
private $storeManager;
17+
18+
/**
19+
* @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject
20+
*/
21+
private $store;
22+
23+
/**
24+
* @var \Magento\Payment\Api\PaymentMethodListInterface|\PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $paymentMethodList;
27+
28+
/**
29+
* @var \Magento\Checkout\Block\Checkout\LayoutProcessor|\PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $layoutProcessor;
32+
33+
/**
34+
* @var \Magento\Payment\Plugin\PaymentConfigurationProcess
35+
*/
36+
private $plugin;
37+
38+
/**
39+
* Set up
40+
*/
41+
protected function setUp()
42+
{
43+
$this->storeManager = $this
44+
->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
45+
->disableOriginalConstructor()
46+
->setMethods(['getStore'])
47+
->getMockForAbstractClass();
48+
$this->store = $this
49+
->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
50+
->disableOriginalConstructor()
51+
->setMethods(['getId'])
52+
->getMockForAbstractClass();
53+
$this->paymentMethodList = $this
54+
->getMockBuilder(\Magento\Payment\Api\PaymentMethodListInterface::class)
55+
->disableOriginalConstructor()
56+
->setMethods(['getActiveList'])
57+
->getMockForAbstractClass();
58+
$this->layoutProcessor = $this
59+
->getMockBuilder(\Magento\Checkout\Block\Checkout\LayoutProcessor::class)
60+
->disableOriginalConstructor()
61+
->setMethods(['process'])
62+
->getMockForAbstractClass();
63+
64+
$objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
65+
$this->plugin = $objectManagerHelper->getObject(
66+
\Magento\Payment\Plugin\PaymentConfigurationProcess::class,
67+
[
68+
'paymentMethodList' => $this->paymentMethodList,
69+
'storeManager' => $this->storeManager
70+
]
71+
);
72+
}
73+
74+
/**
75+
* @param array $jsLayout
76+
* @param array $activePaymentList
77+
* @param array $expectedResult
78+
* @dataProvider beforeProcessDataProvider
79+
*/
80+
public function testBeforeProcess($jsLayout, $activePaymentList, $expectedResult)
81+
{
82+
$this->store->expects($this->once())->method('getId')->willReturn(1);
83+
$this->storeManager->expects($this->once())->method('getStore')->willReturn($this->store);
84+
$this->paymentMethodList->expects($this->once())
85+
->method('getActiveList')
86+
->with(1)
87+
->willReturn($activePaymentList);
88+
89+
$result = $this->plugin->beforeProcess($this->layoutProcessor, $jsLayout);
90+
$this->assertEquals($result[0], $expectedResult);
91+
}
92+
93+
/**
94+
* Data provider for BeforeProcess.
95+
*
96+
* @return array
97+
*/
98+
public function beforeProcessDataProvider()
99+
{
100+
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']
101+
['children']['payment']['children']['renders']['children'] = [
102+
'braintree' => [
103+
'methods' => [
104+
'braintree' => [],
105+
'braintree_paypal' => []
106+
]
107+
]
108+
];
109+
$result['components']['checkout']['children']['steps']['children']['billing-step']
110+
['children']['payment']['children']['renders']['children'] = [];
111+
112+
$braintreePaymentMethod = $this
113+
->getMockBuilder(\Magento\Payment\Api\Data\PaymentMethodInterface::class)
114+
->disableOriginalConstructor()
115+
->setMethods(['getCode'])
116+
->getMockForAbstractClass();
117+
$braintreePaypalPaymentMethod = $this
118+
->getMockBuilder(\Magento\Payment\Api\Data\PaymentMethodInterface::class)
119+
->disableOriginalConstructor()
120+
->setMethods(['getCode'])
121+
->getMockForAbstractClass();
122+
123+
$braintreePaymentMethod->expects($this->any())->method('getCode')->willReturn('braintree');
124+
$braintreePaypalPaymentMethod->expects($this->any())->method('getCode')->willReturn('braintree_paypal');
125+
126+
return [
127+
[$jsLayout, [], $result],
128+
[$jsLayout, [$braintreePaymentMethod, $braintreePaypalPaymentMethod], $jsLayout]
129+
];
130+
}
131+
}

app/code/Magento/Payment/etc/frontend/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@
1919
</argument>
2020
</arguments>
2121
</type>
22+
<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
23+
<plugin name="ProcessPaymentConfiguration" type="Magento\Payment\Plugin\PaymentConfigurationProcess"/>
24+
</type>
2225
</config>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Vault\Plugin;
7+
8+
/**
9+
* Class PaymentVaultConfigurationProcess
10+
*
11+
* Checks if vault group have active vaults.
12+
*/
13+
class PaymentVaultConfigurationProcess
14+
{
15+
/**
16+
* @var \Magento\Vault\Api\PaymentMethodListInterface
17+
*/
18+
private $vaultPaymentList;
19+
20+
/**
21+
* @var \Magento\Vault\Api\PaymentMethodListInterface
22+
*/
23+
private $paymentMethodList;
24+
25+
/**
26+
* @var \Magento\Store\Model\StoreManagerInterface
27+
*/
28+
private $storeManager;
29+
30+
/**
31+
* @param \Magento\Vault\Api\PaymentMethodListInterface $vaultPaymentList
32+
* @param \Magento\Payment\Api\PaymentMethodListInterface $paymentMethodList
33+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
34+
*/
35+
public function __construct(
36+
\Magento\Vault\Api\PaymentMethodListInterface $vaultPaymentList,
37+
\Magento\Payment\Api\PaymentMethodListInterface $paymentMethodList,
38+
\Magento\Store\Model\StoreManagerInterface $storeManager
39+
) {
40+
$this->vaultPaymentList = $vaultPaymentList;
41+
$this->paymentMethodList = $paymentMethodList;
42+
$this->storeManager = $storeManager;
43+
}
44+
45+
/**
46+
* Checkout LayoutProcessor before process plugin.
47+
*
48+
* @param \Magento\Checkout\Block\Checkout\LayoutProcessor $processor
49+
* @param array $jsLayout
50+
* @return array
51+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
52+
*/
53+
public function beforeProcess(\Magento\Checkout\Block\Checkout\LayoutProcessor $processor, $jsLayout)
54+
{
55+
$configuration = &$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']
56+
['children']['payment']['children']['renders']['children'];
57+
58+
if (!isset($configuration)) {
59+
return [$jsLayout];
60+
}
61+
62+
$storeId = $this->storeManager->getStore()->getId();
63+
$activePaymentMethodList = $this->paymentMethodList->getActiveList($storeId);
64+
$activeVaultList = $this->vaultPaymentList->getActiveList($storeId);
65+
$getCodeFunc = function($method) {
66+
return $method->getCode();
67+
};
68+
$getProviderCodeFunc = function($method) {
69+
return $method->getProviderCode();
70+
};
71+
$activePaymentMethodCodes = array_map($getCodeFunc, $activePaymentMethodList);
72+
$activeVaultCodes = array_map($getCodeFunc, $activeVaultList);
73+
$activeVaultProviderCodes = array_map($getProviderCodeFunc, $activeVaultList);
74+
$activePaymentMethodCodes = array_merge($activePaymentMethodCodes, $activeVaultCodes, $activeVaultProviderCodes);
75+
76+
foreach ($configuration as $paymentGroup => $groupConfig) {
77+
foreach (array_keys($groupConfig['methods']) as $paymentCode) {
78+
if (!in_array($paymentCode, $activePaymentMethodCodes)) {
79+
unset($configuration[$paymentGroup]['methods'][$paymentCode]);
80+
}
81+
}
82+
if ($paymentGroup === 'vault' && !empty($activeVaultCodes)) {
83+
continue;
84+
}
85+
if (empty($configuration[$paymentGroup]['methods'])) {
86+
unset($configuration[$paymentGroup]);
87+
}
88+
}
89+
90+
return [$jsLayout];
91+
}
92+
}

0 commit comments

Comments
 (0)