Skip to content

Commit 18aaf69

Browse files
committed
MAGETWO-62914: [Backport] - [Github] Directive values are not quote-escaped #3860 - for 2.1
1 parent 75a7b9b commit 18aaf69

File tree

6 files changed

+538
-26
lines changed

6 files changed

+538
-26
lines changed

app/code/Magento/CatalogWidget/Block/Product/Widget/Conditions.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public function __construct(
7373
$this->conditions = $conditions;
7474
$this->rule = $rule;
7575
$this->registry = $registry;
76+
7677
parent::__construct($context, $data);
7778
}
7879

@@ -81,12 +82,17 @@ public function __construct(
8182
*/
8283
protected function _construct()
8384
{
85+
$widgetParameters = [];
8486
$widget = $this->registry->registry('current_widget_instance');
87+
8588
if ($widget) {
8689
$widgetParameters = $widget->getWidgetParameters();
87-
if (isset($widgetParameters['conditions'])) {
88-
$this->rule->loadPost($widgetParameters);
89-
}
90+
} elseif (($widgetOptions = $this->getLayout()->getBlock('wysiwyg_widget.options')) != false) {
91+
$widgetParameters = $widgetOptions->getWidgetValues();
92+
}
93+
94+
if (isset($widgetParameters['conditions'])) {
95+
$this->rule->loadPost($widgetParameters);
9096
}
9197
}
9298

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogWidget\Test\Unit\Block\Product\Widget;
7+
8+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
9+
use Magento\CatalogWidget\Block\Product\Widget\Conditions;
10+
use Magento\Framework\Registry;
11+
use Magento\Backend\Block\Template\Context;
12+
use Magento\CatalogWidget\Model\Rule;
13+
use Magento\Framework\View\LayoutInterface;
14+
use Magento\Framework\View\Element\BlockInterface;
15+
16+
/**
17+
* Test class for \Magento\CatalogWidget\Block\Product\Widget\Conditions
18+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
19+
*/
20+
class ConditionsTest extends \PHPUnit_Framework_TestCase
21+
{
22+
/**
23+
* @var ObjectManagerHelper
24+
*/
25+
private $objectManagerHelper;
26+
27+
/**
28+
* @var Registry|\PHPUnit_Framework_MockObject_MockObject
29+
*/
30+
private $registryMock;
31+
32+
/**
33+
* @var Context|\PHPUnit_Framework_MockObject_MockObject
34+
*/
35+
private $contextMock;
36+
37+
/**
38+
* @var Rule|\PHPUnit_Framework_MockObject_MockObject
39+
*/
40+
protected $ruleMock;
41+
42+
/**
43+
* @var LayoutInterface|\PHPUnit_Framework_MockObject_MockObject
44+
*/
45+
private $layoutMock;
46+
47+
/**
48+
* @var BlockInterface|\PHPUnit_Framework_MockObject_MockObject
49+
*/
50+
private $blockMock;
51+
52+
/**
53+
* return void
54+
*/
55+
protected function setUp()
56+
{
57+
$this->objectManagerHelper = new ObjectManagerHelper($this);
58+
$this->ruleMock = $this->getMockBuilder(Rule::class)
59+
->disableOriginalConstructor()
60+
->getMock();
61+
$this->registryMock = $this->getMockBuilder(Registry::class)
62+
->disableOriginalConstructor()
63+
->getMock();
64+
$this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class);
65+
$this->blockMock = $this->getMockBuilder(BlockInterface::class)
66+
->setMethods(['getWidgetValues'])
67+
->getMockForAbstractClass();
68+
$this->contextMock = $this->getMockBuilder(Context::class)
69+
->disableOriginalConstructor()
70+
->getMock();
71+
$this->contextMock->expects($this->once())
72+
->method('getLayout')
73+
->willReturn($this->layoutMock);
74+
}
75+
76+
/**
77+
* @return void
78+
*/
79+
public function testConstructWithEmptyData()
80+
{
81+
$this->registryMock->expects($this->once())
82+
->method('registry')
83+
->with('current_widget_instance')
84+
->willReturn(null);
85+
$this->layoutMock->expects($this->once())
86+
->method('getBlock')
87+
->with('wysiwyg_widget.options')
88+
->willReturn(null);
89+
$this->blockMock->expects($this->never())
90+
->method('getWidgetValues');
91+
$this->ruleMock->expects($this->never())
92+
->method('loadPost');
93+
94+
$this->objectManagerHelper->getObject(
95+
Conditions::class,
96+
[
97+
'context' => $this->contextMock,
98+
'registry' => $this->registryMock,
99+
'rule' => $this->ruleMock,
100+
]
101+
);
102+
}
103+
104+
/**
105+
* @return void
106+
*/
107+
public function testConstructWithWidgetInstance()
108+
{
109+
$widgetParams = ['conditions' => 'some conditions'];
110+
111+
/** @var \Magento\Widget\Model\Widget\Instance|\PHPUnit_Framework_MockObject_MockObject $widgetMock */
112+
$widgetMock = $this->getMockBuilder(\Magento\Widget\Model\Widget\Instance::class)
113+
->disableOriginalConstructor()
114+
->getMock();
115+
$widgetMock->expects($this->once())
116+
->method('getWidgetParameters')
117+
->willReturn($widgetParams);
118+
119+
$this->layoutMock->expects($this->never())
120+
->method('getBlock');
121+
$this->blockMock->expects($this->never())
122+
->method('getWidgetValues');
123+
$this->registryMock->expects($this->once())
124+
->method('registry')
125+
->with('current_widget_instance')
126+
->willReturn($widgetMock);
127+
$this->ruleMock->expects($this->once())
128+
->method('loadPost')
129+
->with($widgetParams)
130+
->willReturnSelf();
131+
132+
$this->objectManagerHelper->getObject(
133+
Conditions::class,
134+
[
135+
'context' => $this->contextMock,
136+
'registry' => $this->registryMock,
137+
'rule' => $this->ruleMock,
138+
]
139+
);
140+
}
141+
142+
/**
143+
* @return void
144+
*/
145+
public function testConstructWithParamsFromBlock()
146+
{
147+
$widgetParams = ['conditions' => 'some conditions'];
148+
149+
$this->registryMock->expects($this->once())
150+
->method('registry')
151+
->with('current_widget_instance')
152+
->willReturn(null);
153+
$this->layoutMock->expects($this->once())
154+
->method('getBlock')
155+
->with('wysiwyg_widget.options')
156+
->willReturn($this->blockMock);
157+
$this->blockMock->expects($this->once())
158+
->method('getWidgetValues')
159+
->willReturn($widgetParams);
160+
$this->ruleMock->expects($this->once())
161+
->method('loadPost')
162+
->with($widgetParams)
163+
->willReturnSelf();
164+
165+
$this->objectManagerHelper->getObject(
166+
Conditions::class,
167+
[
168+
'context' => $this->contextMock,
169+
'registry' => $this->registryMock,
170+
'rule' => $this->ruleMock,
171+
]
172+
);
173+
}
174+
}

app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
<?php
22
/**
3-
*
43
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
54
* See COPYING.txt for license details.
65
*/
76
namespace Magento\Widget\Controller\Adminhtml\Widget;
87

8+
use Magento\Framework\App\ObjectManager;
9+
910
class LoadOptions extends \Magento\Backend\App\Action
1011
{
12+
/**
13+
* @var \Magento\Widget\Helper\Conditions
14+
*/
15+
private $conditionsHelper;
16+
1117
/**
1218
* Ajax responder for loading plugin options form
1319
*
@@ -18,13 +24,19 @@ public function execute()
1824
try {
1925
$this->_view->loadLayout();
2026
if ($paramsJson = $this->getRequest()->getParam('widget')) {
21-
$request = $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonDecode($paramsJson);
27+
$request = $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)
28+
->jsonDecode($paramsJson);
2229
if (is_array($request)) {
2330
$optionsBlock = $this->_view->getLayout()->getBlock('wysiwyg_widget.options');
2431
if (isset($request['widget_type'])) {
2532
$optionsBlock->setWidgetType($request['widget_type']);
2633
}
2734
if (isset($request['values'])) {
35+
$request['values'] = array_map('htmlspecialchars_decode', $request['values']);
36+
if (isset($request['values']['conditions_encoded'])) {
37+
$request['values']['conditions'] =
38+
$this->getConditionsHelper()->decode($request['values']['conditions_encoded']);
39+
}
2840
$optionsBlock->setWidgetValues($request['values']);
2941
}
3042
}
@@ -33,8 +45,21 @@ public function execute()
3345
} catch (\Magento\Framework\Exception\LocalizedException $e) {
3446
$result = ['error' => true, 'message' => $e->getMessage()];
3547
$this->getResponse()->representJson(
36-
$this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
48+
$this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result)
3749
);
3850
}
3951
}
52+
53+
/**
54+
* @return \Magento\Widget\Helper\Conditions
55+
* @deprecated
56+
*/
57+
private function getConditionsHelper()
58+
{
59+
if (!$this->conditionsHelper) {
60+
$this->conditionsHelper = ObjectManager::getInstance()->get(\Magento\Widget\Helper\Conditions::class);
61+
}
62+
63+
return $this->conditionsHelper;
64+
}
4065
}

app/code/Magento/Widget/Model/Widget.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private function getMathRandom()
8989
{
9090
if ($this->mathRandom === null) {
9191
$this->mathRandom = \Magento\Framework\App\ObjectManager::getInstance()
92-
->get('\Magento\Framework\Math\Random');
92+
->get(\Magento\Framework\Math\Random::class);
9393
}
9494
return $this->mathRandom;
9595
}
@@ -314,12 +314,11 @@ public function getWidgetDeclaration($type, $params = [], $asIs = true)
314314
}
315315
}
316316
if ($value) {
317-
$directive .= sprintf(' %s="%s"', $name, $value);
317+
$directive .= sprintf(' %s="%s"', $name, $this->escaper->escapeQuote($value));
318318
}
319319
}
320320

321321
$directive .= $this->getWidgetPageVarName($params);
322-
323322
$directive .= '}}';
324323

325324
if ($asIs) {

0 commit comments

Comments
 (0)