Skip to content

Commit c33b1af

Browse files
Merge pull request #3663 from magento-qwerty/2.2.8-bugfixes-300119
Fixed issues: - MAGETWO-97043: Template Callbacks - MAGETWO-97081: Fixed incorrect behaviour of sync actions
2 parents 949a961 + c222823 commit c33b1af

File tree

4 files changed

+76
-35
lines changed

4 files changed

+76
-35
lines changed

app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ private function getProductIdsByActions(array $actions)
138138
$productIds = [];
139139

140140
foreach ($actions as $action) {
141-
$productIds[] = $action['product_id'];
141+
if (isset($action['product_id']) && is_int($action['product_id'])) {
142+
$productIds[] = $action['product_id'];
143+
}
142144
}
143145

144146
return $productIds;
@@ -159,33 +161,37 @@ public function syncActions(array $productsData, $typeId)
159161
$customerId = $this->session->getCustomerId();
160162
$visitorId = $this->visitor->getId();
161163
$collection = $this->getActionsByType($typeId);
162-
$collection->addFieldToFilter('product_id', $this->getProductIdsByActions($productsData));
163-
164-
/**
165-
* Note that collection is also filtered by visitor id and customer id
166-
* This collection shouldnt be flushed when visitor has products and then login
167-
* It can remove only products for visitor, or only products for customer
168-
*
169-
* ['product_id' => 'added_at']
170-
* @var ProductFrontendActionInterface $item
171-
*/
172-
foreach ($collection as $item) {
173-
$this->entityManager->delete($item);
174-
}
175-
176-
foreach ($productsData as $productId => $productData) {
177-
/** @var ProductFrontendActionInterface $action */
178-
$action = $this->productFrontendActionFactory->create([
179-
'data' => [
180-
'visitor_id' => $customerId ? null : $visitorId,
181-
'customer_id' => $this->session->getCustomerId(),
182-
'added_at' => $productData['added_at'],
183-
'product_id' => $productId,
184-
'type_id' => $typeId
185-
]
186-
]);
187-
188-
$this->entityManager->save($action);
164+
$productIds = $this->getProductIdsByActions($productsData);
165+
166+
if ($productIds) {
167+
$collection->addFieldToFilter('product_id', $productIds);
168+
169+
/**
170+
* Note that collection is also filtered by visitor id and customer id
171+
* This collection shouldnt be flushed when visitor has products and then login
172+
* It can remove only products for visitor, or only products for customer
173+
*
174+
* ['product_id' => 'added_at']
175+
* @var ProductFrontendActionInterface $item
176+
*/
177+
foreach ($collection as $item) {
178+
$this->entityManager->delete($item);
179+
}
180+
181+
foreach ($productsData as $productId => $productData) {
182+
/** @var ProductFrontendActionInterface $action */
183+
$action = $this->productFrontendActionFactory->create([
184+
'data' => [
185+
'visitor_id' => $customerId ? null : $visitorId,
186+
'customer_id' => $this->session->getCustomerId(),
187+
'added_at' => $productData['added_at'],
188+
'product_id' => $productId,
189+
'type_id' => $typeId
190+
]
191+
]);
192+
193+
$this->entityManager->save($action);
194+
}
189195
}
190196
}
191197

lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2904,7 +2904,7 @@ public function prepareSqlCondition($fieldName, $condition)
29042904
if (isset($condition['to'])) {
29052905
$query .= empty($query) ? '' : ' AND ';
29062906
$to = $this->_prepareSqlDateCondition($condition, 'to');
2907-
$query = $this->_prepareQuotedSqlCondition($query . $conditionKeyMap['to'], $to, $fieldName);
2907+
$query = $query . $this->_prepareQuotedSqlCondition($conditionKeyMap['to'], $to, $fieldName);
29082908
}
29092909
} elseif (array_key_exists($key, $conditionKeyMap)) {
29102910
$value = $condition[$key];

lib/internal/Magento/Framework/Filter/Template.php

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ class Template implements \Zend_Filter_Interface
5252
*/
5353
protected $string;
5454

55+
/**
56+
* @var string[]
57+
*/
58+
private $restrictedMethods = ['addafterfiltercallback'];
59+
5560
/**
5661
* @param \Magento\Framework\Stdlib\StringUtils $string
5762
* @param array $variables
@@ -297,6 +302,25 @@ protected function getParameters($value)
297302
return $params;
298303
}
299304

305+
/**
306+
* Validate method call initiated in a template.
307+
*
308+
* Deny calls for methods that may disrupt template processing.
309+
*
310+
* @param object $object
311+
* @param string $method
312+
* @return void
313+
* @throws \InvalidArgumentException
314+
*/
315+
private function validateVariableMethodCall($object, string $method)
316+
{
317+
if ($object === $this) {
318+
if (in_array(mb_strtolower($method), $this->restrictedMethods)) {
319+
throw new \InvalidArgumentException("Method $method cannot be called from template.");
320+
}
321+
}
322+
}
323+
300324
/**
301325
* Return variable value for var construction
302326
*
@@ -345,12 +369,12 @@ protected function getVariable($value, $default = '{no_value_defined}')
345369
$last = $i;
346370
} elseif (isset($stackVars[$i - 1]['variable']) && $stackVars[$i]['type'] == 'method') {
347371
// Calling object methods
348-
if (method_exists($stackVars[$i - 1]['variable'], $stackVars[$i]['name'])) {
349-
$stackVars[$i]['args'] = $this->getStackArgs($stackVars[$i]['args']);
350-
$stackVars[$i]['variable'] = call_user_func_array(
351-
[$stackVars[$i - 1]['variable'], $stackVars[$i]['name']],
352-
$stackVars[$i]['args']
353-
);
372+
$object = $stackVars[$i - 1]['variable'];
373+
$method = $stackVars[$i]['name'];
374+
if (method_exists($object, $method)) {
375+
$args = $this->getStackArgs($stackVars[$i]['args']);
376+
$this->validateVariableMethodCall($object, $method);
377+
$stackVars[$i]['variable'] = call_user_func_array([$object, $method], $args);
354378
}
355379
$last = $i;
356380
}

lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,15 @@ public function varDirectiveDataProvider()
205205
],
206206
];
207207
}
208+
209+
/**
210+
* Test adding callbacks when already filtering.
211+
*
212+
* @expectedException \InvalidArgumentException
213+
*/
214+
public function testInappropriateCallbacks()
215+
{
216+
$this->templateFilter->setVariables(['filter' => $this->templateFilter]);
217+
$this->templateFilter->filter('Test {{var filter.addAfterFilterCallback(\'mb_strtolower\')}}');
218+
}
208219
}

0 commit comments

Comments
 (0)