Skip to content

Commit 0d3defe

Browse files
authored
Merge pull request #5416 from magento-tsg-csl3/2.4-develop-pr15
[TSG-CSL3] For 2.4 (pr15)
2 parents 45b624c + 475c521 commit 0d3defe

File tree

20 files changed

+343
-108
lines changed

20 files changed

+343
-108
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*
2121
* Service which allows to sync product widget information, such as product id with db. In order to reuse this info
2222
* on different devices
23+
*
24+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2325
*/
2426
class Synchronizer
2527
{
@@ -94,6 +96,7 @@ public function __construct(
9496
*
9597
* @param string $namespace
9698
* @return int
99+
* @throws \Magento\Framework\Exception\LocalizedException
97100
*/
98101
private function getLifeTimeByNamespace($namespace)
99102
{
@@ -119,6 +122,7 @@ private function getLifeTimeByNamespace($namespace)
119122
* @param array $productsData (product action data, that came from frontend)
120123
* @param string $typeId namespace (type of action)
121124
* @return array
125+
* @throws \Magento\Framework\Exception\LocalizedException
122126
*/
123127
private function filterNewestActions(array $productsData, $typeId)
124128
{
@@ -166,6 +170,7 @@ private function getProductIdsByActions(array $actions)
166170
* @param array $productsData
167171
* @param string $typeId
168172
* @return void
173+
* @throws \Exception
169174
*/
170175
public function syncActions(array $productsData, $typeId)
171176
{
@@ -189,16 +194,15 @@ public function syncActions(array $productsData, $typeId)
189194
foreach ($collection as $item) {
190195
$this->entityManager->delete($item);
191196
}
192-
193-
foreach ($productsData as $productId => $productData) {
197+
foreach ($productsData as $productData) {
194198
/** @var ProductFrontendActionInterface $action */
195199
$action = $this->productFrontendActionFactory->create(
196200
[
197201
'data' => [
198202
'visitor_id' => $customerId ? null : $visitorId,
199203
'customer_id' => $this->session->getCustomerId(),
200204
'added_at' => $productData['added_at'],
201-
'product_id' => $productId,
205+
'product_id' => $productData['product_id'],
202206
'type_id' => $typeId
203207
]
204208
]

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,7 @@ protected function _productLimitationJoinPrice()
19041904
* @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice()
19051905
* @param bool $joinLeft
19061906
* @return $this
1907+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
19071908
*/
19081909
protected function _productLimitationPrice($joinLeft = false)
19091910
{
@@ -1922,14 +1923,14 @@ protected function _productLimitationPrice($joinLeft = false)
19221923

19231924
$connection = $this->getConnection();
19241925
$select = $this->getSelect();
1925-
$joinCond = join(
1926-
' AND ',
1927-
[
1928-
'price_index.entity_id = e.entity_id',
1929-
$connection->quoteInto('price_index.website_id = ?', $filters['website_id']),
1930-
$connection->quoteInto('price_index.customer_group_id = ?', $filters['customer_group_id'])
1931-
]
1932-
);
1926+
$joinCondArray = [];
1927+
$joinCondArray[] = 'price_index.entity_id = e.entity_id';
1928+
$joinCondArray[] = $connection->quoteInto('price_index.customer_group_id = ?', $filters['customer_group_id']);
1929+
// Add website condition only if it's different from admin scope
1930+
if (((int) $filters['website_id']) !== Store::DEFAULT_STORE_ID) {
1931+
$joinCondArray[] = $connection->quoteInto('price_index.website_id = ?', $filters['website_id']);
1932+
}
1933+
$joinCond = join(' AND ', $joinCondArray);
19331934

19341935
$fromPart = $select->getPart(\Magento\Framework\DB\Select::FROM);
19351936
if (!isset($fromPart['price_index'])) {

app/code/Magento/Catalog/Test/Unit/Model/Product/ProductFrontendAction/SynchronizerTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ public function testFilterProductActions()
8282
{
8383
$typeId = 'recently_compared_product';
8484
$productsData = [
85-
1 => [
85+
'website-1-1' => [
8686
'added_at' => 12,
8787
'product_id' => 1,
8888
],
89-
2 => [
89+
'website-1-2' => [
9090
'added_at' => 13,
9191
'product_id' => '2',
9292
],
93-
3 => [
93+
'website-2-3' => [
9494
'added_at' => 14,
9595
'product_id' => 3,
9696
]

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
307307
// Can't add new translated strings in patch release
308308
'invalidLayoutUpdate' => 'Invalid format.',
309309
'insufficientPermissions' => 'Invalid format.',
310+
ValidatorInterface::ERROR_SKU_MARGINAL_WHITESPACES => 'SKU contains marginal whitespaces'
310311
];
311312
//@codingStandardsIgnoreEnd
312313

app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ interface RowValidatorInterface extends \Magento\Framework\Validator\ValidatorIn
8787

8888
const ERROR_DUPLICATE_MULTISELECT_VALUES = 'duplicatedMultiselectValues';
8989

90+
const ERROR_SKU_MARGINAL_WHITESPACES = 'skuMarginalWhitespaces';
91+
9092
/**
9193
* Value that means all entities (e.g. websites, groups etc.)
9294
*/

app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Magento\Catalog\Model\Product\Attribute\Backend\Sku;
1111

1212
/**
13-
* Class Validator
13+
* Product import model validator
1414
*
1515
* @api
1616
* @since 100.0.2
@@ -72,8 +72,12 @@ protected function textValidation($attrCode, $type)
7272
$val = $this->string->cleanString($this->_rowData[$attrCode]);
7373
if ($type == 'text') {
7474
$valid = $this->string->strlen($val) < Product::DB_MAX_TEXT_LENGTH;
75-
} else if ($attrCode == Product::COL_SKU) {
75+
} elseif ($attrCode == Product::COL_SKU) {
7676
$valid = $this->string->strlen($val) <= SKU::SKU_MAX_LENGTH;
77+
if ($this->string->strlen($val) !== $this->string->strlen(trim($val))) {
78+
$this->_addMessages([RowValidatorInterface::ERROR_SKU_MARGINAL_WHITESPACES]);
79+
return false;
80+
}
7781
} else {
7882
$valid = $this->string->strlen($val) < Product::DB_MAX_VARCHAR_LENGTH;
7983
}
@@ -359,5 +363,7 @@ public function init($context)
359363
foreach ($this->validators as $validator) {
360364
$validator->init($context);
361365
}
366+
367+
return $this;
362368
}
363369
}

app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Magento\Catalog\Api\Data\ProductInterface;
1313
use Magento\Catalog\Model\ProductCategoryList;
14+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
1415
use Magento\Store\Model\Store;
1516

1617
/**
@@ -122,59 +123,47 @@ protected function _addSpecialAttributes(array &$attributes)
122123
/**
123124
* Add condition to collection
124125
*
125-
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
126+
* @param Collection $collection
126127
* @return $this
127128
*/
128129
public function addToCollection($collection)
129130
{
130131
$attribute = $this->getAttributeObject();
132+
$attributeCode = $attribute->getAttributeCode();
133+
if ($attributeCode !== 'price' || !$collection->getLimitationFilters()->isUsingPriceIndex()) {
134+
if ($collection->isEnabledFlat()) {
135+
if ($attribute->isEnabledInFlat()) {
136+
$alias = array_keys($collection->getSelect()->getPart('from'))[0];
137+
$this->joinedAttributes[$attributeCode] = $alias . '.' . $attributeCode;
138+
} else {
139+
$alias = 'at_' . $attributeCode;
140+
if (!in_array($alias, array_keys($collection->getSelect()->getPart('from')))) {
141+
$collection->joinAttribute($attributeCode, "catalog_product/$attributeCode", 'entity_id');
142+
}
131143

132-
if ($collection->isEnabledFlat()) {
133-
if ($attribute->isEnabledInFlat()) {
134-
$alias = array_keys($collection->getSelect()->getPart('from'))[0];
135-
$this->joinedAttributes[$attribute->getAttributeCode()] = $alias . '.' . $attribute->getAttributeCode();
136-
} else {
137-
$alias = 'at_' . $attribute->getAttributeCode();
138-
if (!in_array($alias, array_keys($collection->getSelect()->getPart('from')))) {
139-
$collection->joinAttribute(
140-
$attribute->getAttributeCode(),
141-
'catalog_product/'.$attribute->getAttributeCode(),
142-
'entity_id'
143-
);
144+
$this->joinedAttributes[$attributeCode] = $alias . '.value';
144145
}
145-
146-
$this->joinedAttributes[$attribute->getAttributeCode()] = $alias . '.value';
146+
} elseif ($attributeCode !== 'category_ids' && !$attribute->isStatic()) {
147+
$this->addAttributeToCollection($attribute, $collection);
148+
$attributes = $this->getRule()->getCollectedAttributes();
149+
$attributes[$attributeCode] = true;
150+
$this->getRule()->setCollectedAttributes($attributes);
147151
}
148-
return $this;
149152
}
150153

151-
if ('category_ids' == $attribute->getAttributeCode() || $attribute->isStatic()) {
152-
return $this;
153-
}
154-
155-
if ($attribute->getBackend() && $attribute->isScopeGlobal()) {
156-
$this->addGlobalAttribute($attribute, $collection);
157-
} else {
158-
$this->addNotGlobalAttribute($attribute, $collection);
159-
}
160-
161-
$attributes = $this->getRule()->getCollectedAttributes();
162-
$attributes[$attribute->getAttributeCode()] = true;
163-
$this->getRule()->setCollectedAttributes($attributes);
164-
165154
return $this;
166155
}
167156

168157
/**
169158
* Adds Attributes that belong to Global Scope
170159
*
171160
* @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute
172-
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
161+
* @param Collection $collection
173162
* @return $this
174163
*/
175164
protected function addGlobalAttribute(
176165
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute,
177-
\Magento\Catalog\Model\ResourceModel\Product\Collection $collection
166+
Collection $collection
178167
) {
179168
switch ($attribute->getBackendType()) {
180169
case 'decimal':
@@ -207,12 +196,12 @@ protected function addGlobalAttribute(
207196
* Adds Attributes that don't belong to Global Scope
208197
*
209198
* @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute
210-
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
199+
* @param Collection $collection
211200
* @return $this
212201
*/
213202
protected function addNotGlobalAttribute(
214203
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute,
215-
\Magento\Catalog\Model\ResourceModel\Product\Collection $collection
204+
Collection $collection
216205
) {
217206
$storeId = $this->storeManager->getStore()->getId();
218207
$values = $collection->getAllAttributeValues($attribute);
@@ -255,6 +244,8 @@ public function getMappedSqlField()
255244
$result = parent::getMappedSqlField();
256245
} elseif (isset($this->joinedAttributes[$this->getAttribute()])) {
257246
$result = $this->joinedAttributes[$this->getAttribute()];
247+
} elseif ($this->getAttribute() === 'price') {
248+
$result = 'price_index.min_price';
258249
} elseif ($this->getAttributeObject()->isStatic()) {
259250
$result = $this->getAttributeObject()->getAttributeCode();
260251
} elseif ($this->getValueParsed()) {
@@ -267,11 +258,27 @@ public function getMappedSqlField()
267258
/**
268259
* @inheritdoc
269260
*
270-
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection
261+
* @param Collection $productCollection
271262
* @return $this
272263
*/
273264
public function collectValidatedAttributes($productCollection)
274265
{
275266
return $this->addToCollection($productCollection);
276267
}
268+
269+
/**
270+
* Add attribute to collection based on scope
271+
*
272+
* @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute
273+
* @param Collection $collection
274+
* @return void
275+
*/
276+
private function addAttributeToCollection($attribute, $collection): void
277+
{
278+
if ($attribute->getBackend() && $attribute->isScopeGlobal()) {
279+
$this->addGlobalAttribute($attribute, $collection);
280+
} else {
281+
$this->addNotGlobalAttribute($attribute, $collection);
282+
}
283+
}
277284
}

app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Magento\Framework\Controller\Result\RawFactory;
2222
use Magento\Backend\App\Action\Context;
2323
use Magento\Framework\App\ObjectManager;
24+
use Magento\Framework\Filesystem\Driver\File;
2425

2526
/**
2627
* Process template text for wysiwyg editor.
@@ -67,6 +68,11 @@ class Directive extends Action implements HttpGetActionInterface
6768
*/
6869
private $filter;
6970

71+
/**
72+
* @var File
73+
*/
74+
private $file;
75+
7076
/**
7177
* Constructor
7278
*
@@ -77,6 +83,7 @@ class Directive extends Action implements HttpGetActionInterface
7783
* @param LoggerInterface|null $logger
7884
* @param Config|null $config
7985
* @param Filter|null $filter
86+
* @param File|null $file
8087
*/
8188
public function __construct(
8289
Context $context,
@@ -85,7 +92,8 @@ public function __construct(
8592
AdapterFactory $adapterFactory = null,
8693
LoggerInterface $logger = null,
8794
Config $config = null,
88-
Filter $filter = null
95+
Filter $filter = null,
96+
File $file = null
8997
) {
9098
parent::__construct($context);
9199
$this->urlDecoder = $urlDecoder;
@@ -94,6 +102,7 @@ public function __construct(
94102
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
95103
$this->config = $config ?: ObjectManager::getInstance()->get(Config::class);
96104
$this->filter = $filter ?: ObjectManager::getInstance()->get(Filter::class);
105+
$this->file = $file ?: ObjectManager::getInstance()->get(File::class);
97106
}
98107

99108
/**
@@ -127,6 +136,15 @@ public function execute()
127136
$this->logger->warning($e);
128137
}
129138
}
139+
$mimeType = $image->getMimeType();
140+
unset($image);
141+
// To avoid issues with PNG images with alpha blending we return raw file
142+
// after validation as an image source instead of generating the new PNG image
143+
// with image adapter
144+
$content = $this->file->fileGetContents($imagePath);
145+
$resultRaw->setHeader('Content-Type', $mimeType);
146+
$resultRaw->setContents($content);
147+
130148
return $resultRaw;
131149
}
132150
}

0 commit comments

Comments
 (0)