Skip to content

Commit ebeefd9

Browse files
author
rliukshyn
committed
MAGETWO-32743: Direct web link on Magento order transactions to backend records
1 parent 2015f5c commit ebeefd9

File tree

14 files changed

+443
-7
lines changed

14 files changed

+443
-7
lines changed

app/code/Magento/Sales/Block/Adminhtml/Order/Comments/View.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,26 @@ class View extends \Magento\Backend\Block\Template
1919
*/
2020
protected $_salesData = null;
2121

22+
/**
23+
* @var \Magento\Sales\Helper\Admin
24+
*/
25+
private $adminHelper;
26+
2227
/**
2328
* @param \Magento\Backend\Block\Template\Context $context
2429
* @param \Magento\Sales\Helper\Data $salesData
30+
* @param \Magento\Sales\Helper\Admin $adminHelper
2531
* @param array $data
2632
*/
2733
public function __construct(
2834
\Magento\Backend\Block\Template\Context $context,
2935
\Magento\Sales\Helper\Data $salesData,
36+
\Magento\Sales\Helper\Admin $adminHelper,
3037
array $data = []
3138
) {
3239
$this->_salesData = $salesData;
3340
parent::__construct($context, $data);
41+
$this->adminHelper = $adminHelper;
3442
}
3543

3644
/**
@@ -96,4 +104,16 @@ public function canSendCommentEmail()
96104
}
97105
return true;
98106
}
107+
108+
/**
109+
* Replace links in string
110+
*
111+
* @param array|string $data
112+
* @param null|array $allowedTags
113+
* @return string
114+
*/
115+
public function escapeHtml($data, $allowedTags = null)
116+
{
117+
return $this->adminHelper->escapeHtmlWithLinks($data, $allowedTags);
118+
}
99119
}

app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,29 @@ class History extends \Magento\Backend\Block\Template
2626
*/
2727
protected $_salesData = null;
2828

29+
/**
30+
* @var \Magento\Sales\Helper\Admin
31+
*/
32+
private $adminHelper;
33+
2934
/**
3035
* @param \Magento\Backend\Block\Template\Context $context
3136
* @param \Magento\Sales\Helper\Data $salesData
3237
* @param \Magento\Framework\Registry $registry
38+
* @param \Magento\Sales\Helper\Admin $adminHelper
3339
* @param array $data
3440
*/
3541
public function __construct(
3642
\Magento\Backend\Block\Template\Context $context,
3743
\Magento\Sales\Helper\Data $salesData,
3844
\Magento\Framework\Registry $registry,
45+
\Magento\Sales\Helper\Admin $adminHelper,
3946
array $data = []
4047
) {
4148
$this->_coreRegistry = $registry;
4249
$this->_salesData = $salesData;
4350
parent::__construct($context, $data);
51+
$this->adminHelper = $adminHelper;
4452
}
4553

4654
/**
@@ -122,4 +130,16 @@ public function isCustomerNotificationNotApplicable(\Magento\Sales\Model\Order\S
122130
{
123131
return $history->isCustomerNotificationNotApplicable();
124132
}
133+
134+
/**
135+
* Replace links in string
136+
*
137+
* @param array|string $data
138+
* @param null|array $allowedTags
139+
* @return string
140+
*/
141+
public function escapeHtml($data, $allowedTags = null)
142+
{
143+
return $this->adminHelper->escapeHtmlWithLinks($data, $allowedTags);
144+
}
125145
}

app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,26 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen
2626
*/
2727
protected $_coreRegistry = null;
2828

29+
/**
30+
* @var \Magento\Sales\Helper\Admin
31+
*/
32+
private $adminHelper;
33+
2934
/**
3035
* @param \Magento\Backend\Block\Template\Context $context
3136
* @param \Magento\Framework\Registry $registry
37+
* @param \Magento\Sales\Helper\Admin $adminHelper
3238
* @param array $data
3339
*/
3440
public function __construct(
3541
\Magento\Backend\Block\Template\Context $context,
3642
\Magento\Framework\Registry $registry,
43+
\Magento\Sales\Helper\Admin $adminHelper,
3744
array $data = []
3845
) {
3946
$this->_coreRegistry = $registry;
4047
parent::__construct($context, $data);
48+
$this->adminHelper = $adminHelper;
4149
}
4250

4351
/**
@@ -192,8 +200,9 @@ public function isItemNotified(array $item, $isSimpleCheck = true)
192200
*/
193201
public function getItemComment(array $item)
194202
{
195-
$allowedTags = ['b', 'br', 'strong', 'i', 'u'];
196-
return isset($item['comment']) ? $this->escapeHtml($item['comment'], $allowedTags) : '';
203+
$allowedTags = ['b', 'br', 'strong', 'i', 'u', 'a'];
204+
return isset($item['comment'])
205+
? $this->adminHelper->escapeHtmlWithLinks($item['comment'], $allowedTags) : '';
197206
}
198207

199208
/**

app/code/Magento/Sales/Block/Adminhtml/Transactions/Detail.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,25 @@ class Detail extends \Magento\Backend\Block\Widget\Container
2626
*/
2727
protected $_coreRegistry = null;
2828

29+
/**
30+
* @var \Magento\Sales\Helper\Admin
31+
*/
32+
private $adminHelper;
33+
2934
/**
3035
* @param \Magento\Backend\Block\Widget\Context $context
3136
* @param \Magento\Framework\Registry $registry
37+
* @param \Magento\Sales\Helper\Admin $adminHelper
3238
* @param array $data
3339
*/
3440
public function __construct(
3541
\Magento\Backend\Block\Widget\Context $context,
3642
\Magento\Framework\Registry $registry,
43+
\Magento\Sales\Helper\Admin $adminHelper,
3744
array $data = []
3845
) {
3946
$this->_coreRegistry = $registry;
47+
$this->adminHelper = $adminHelper;
4048
parent::__construct($context, $data);
4149
}
4250

@@ -97,7 +105,10 @@ public function getHeaderText()
97105
*/
98106
protected function _toHtml()
99107
{
100-
$this->setTxnIdHtml($this->escapeHtml($this->_txn->getTxnId()));
108+
$this->setTxnIdHtml($this->adminHelper->escapeHtmlWithLinks(
109+
$this->_txn->getHtmlTxnId(),
110+
['a']
111+
));
101112

102113
$this->setParentTxnIdUrlHtml(
103114
$this->escapeHtml($this->getUrl('sales/transactions/view', ['txn_id' => $this->_txn->getParentId()]))

app/code/Magento/Sales/Helper/Admin.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,29 @@ class Admin extends \Magento\Framework\App\Helper\AbstractHelper
2222
*/
2323
protected $priceCurrency;
2424

25+
/**
26+
* @var \Magento\Framework\Escaper
27+
*/
28+
protected $escaper;
29+
2530
/**
2631
* @param \Magento\Framework\App\Helper\Context $context
2732
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
2833
* @param \Magento\Sales\Model\Config $salesConfig
2934
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
35+
* @param \Magento\Framework\Escaper $escaper
3036
*/
3137
public function __construct(
3238
\Magento\Framework\App\Helper\Context $context,
3339
\Magento\Store\Model\StoreManagerInterface $storeManager,
3440
\Magento\Sales\Model\Config $salesConfig,
35-
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
41+
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
42+
\Magento\Framework\Escaper $escaper
3643
) {
3744
$this->priceCurrency = $priceCurrency;
3845
$this->_storeManager = $storeManager;
3946
$this->_salesConfig = $salesConfig;
47+
$this->escaper = $escaper;
4048
parent::__construct($context);
4149
}
4250

@@ -127,4 +135,29 @@ public function applySalableProductTypesFilter($collection)
127135
}
128136
return $collection;
129137
}
138+
139+
/**
140+
* Escape string preserving links
141+
*
142+
* @param string $data
143+
* @param null|array $allowedTags
144+
* @return string
145+
*/
146+
public function escapeHtmlWithLinks($data, $allowedTags = null)
147+
{
148+
if (!empty($data) && is_array($allowedTags) && in_array('a', $allowedTags)) {
149+
$links = [];
150+
$i = 1;
151+
$data = str_replace('%', '%%', $data);
152+
$regexp = '@(<a[^>]*>(?:[^<]|<[^/]|</[^a]|</a[^>])*</a>)@';
153+
while (preg_match($regexp, $data, $matches)) {
154+
$links[] = $matches[1];
155+
$data = str_replace($matches[1], '%' . $i . '$s', $data);
156+
++$i;
157+
}
158+
$data = $this->escaper->escapeHtml($data, $allowedTags);
159+
return vsprintf($data, $links);
160+
}
161+
return $this->escaper->escapeHtml($data, $allowedTags);
162+
}
130163
}

app/code/Magento/Sales/Model/Order/Payment.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,7 @@ protected function _isTransactionExists($txnId = null)
14211421
protected function _appendTransactionToMessage($transaction, $message)
14221422
{
14231423
if ($transaction) {
1424-
$txnId = is_object($transaction) ? $transaction->getTxnId() : $transaction;
1424+
$txnId = is_object($transaction) ? $transaction->getHtmlTxnId() : $transaction;
14251425
$message .= ' ' . __('Transaction ID: "%1"', $txnId);
14261426
}
14271427
return $message;

app/code/Magento/Sales/Model/Order/Payment/Transaction.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,17 @@ public function getTxnId()
979979
return $this->getData(TransactionInterface::TXN_ID);
980980
}
981981

982+
/**
983+
* Get HTML format for transaction id
984+
*
985+
* @return string
986+
*/
987+
public function getHtmlTxnId()
988+
{
989+
$this->_eventManager->dispatch($this->_eventPrefix . '_html_txn_id', $this->_getEventData());
990+
return isset($this->_data['html_txn_id']) ? $this->_data['html_txn_id'] : $this->getTxnId();
991+
}
992+
982993
/**
983994
* Returns parent_txn_id
984995
*
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Sales\Test\Unit\Block\Adminhtml\Order\Comments;
7+
8+
class ViewTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var \Magento\Sales\Helper\Admin|\PHPUnit_Framework_MockObject_MockObject
12+
*/
13+
protected $adminHelperMock;
14+
15+
/**
16+
* @var \Magento\Sales\Block\Adminhtml\Order\Comments\View
17+
*/
18+
protected $commentsView;
19+
20+
protected function setUp()
21+
{
22+
$this->adminHelperMock = $this->getMockBuilder('Magento\Sales\Helper\Admin')
23+
->disableOriginalConstructor()
24+
->getMock();
25+
26+
$this->commentsView = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
27+
'Magento\Sales\Block\Adminhtml\Order\Comments\View',
28+
[
29+
'adminHelper' => $this->adminHelperMock
30+
]
31+
);
32+
}
33+
34+
/**
35+
* @param string $data
36+
* @param string $expected
37+
* @param null|array $allowedTags
38+
* @dataProvider escapeHtmlDataProvider
39+
*/
40+
public function testEscapeHtml($data, $expected, $allowedTags = null)
41+
{
42+
$this->adminHelperMock
43+
->expects($this->any())
44+
->method('escapeHtmlWithLinks')
45+
->will($this->returnValue($expected));
46+
$actual = $this->commentsView->escapeHtml($data, $allowedTags);
47+
$this->assertEquals($expected, $actual);
48+
}
49+
50+
/**
51+
* @return array
52+
*/
53+
public function escapeHtmlDataProvider()
54+
{
55+
return [
56+
[
57+
'<a>some text in tags</a>',
58+
'&lt;a&gt;some text in tags&lt;/a&gt;',
59+
'allowedTags' => null
60+
],
61+
[
62+
'Transaction ID: "<a target="_blank" href="https://www.paypal.com/?id=XX123XX">XX123XX</a>"',
63+
'Transaction ID: &quot;<a target="_blank" href="https://www.paypal.com/?id=XX123XX">XX123XX</a>&quot;',
64+
'allowedTags' => ['b', 'br', 'strong', 'i', 'u', 'a']
65+
],
66+
[
67+
'<a>some text in tags</a>',
68+
'<a>some text in tags</a>',
69+
'allowedTags' => ['a']
70+
]
71+
];
72+
}
73+
}

0 commit comments

Comments
 (0)