Skip to content

Commit 7d00d28

Browse files
author
Oleksii Korshenko
authored
Merge pull request #1844 from magento-engcom/2.2-develop-prs
Merge pull request #1014 from magento-engcom/2.2-develop-prs [EngCom] Public Pull Requests - 2.2-develop Public Pull Requests - #1012 10814: Attribute repository resets sourceModel for new attributes. by @nmalevanec - #1006 #12285: The option false for mobile device don't work in product - view page gallery by @p-bystritsky - #983 #12259: Save and Duplicated product not working by @p-bystritsky - #1000 8204: catalog:images:resize = getimagesize(): Read error! by @RomaKis #12633 Magento Connect no longer exist by @miguelbalparda Fixed Public Issues - #10814 Attribute repository resets sourceModel for new attributes - #12285 The option false for mobile device don't work in product view page gallery - #12490 I can't disable full screen gallery on mobile on magento 2.2.1 - #12259 Save and Duplicated product not working - #8204 catalog:images:resize = getimagesize(): Read error! in vendor/magento/module-catalog/Model/Product/Image.php on line 410 if an image is 0 bytes - #12632 Magento Connect no longer exist
2 parents 506d500 + 407884c commit 7d00d28

File tree

14 files changed

+408
-44
lines changed

14 files changed

+408
-44
lines changed

app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Catalog\Console\Command;
77

8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
811
class ImagesResizeCommand extends \Symfony\Component\Console\Command\Command
912
{
1013
/**
@@ -58,10 +61,8 @@ protected function configure()
5861
/**
5962
* {@inheritdoc}
6063
*/
61-
protected function execute(
62-
\Symfony\Component\Console\Input\InputInterface $input,
63-
\Symfony\Component\Console\Output\OutputInterface $output
64-
) {
64+
protected function execute(InputInterface $input, OutputInterface $output)
65+
{
6566
$this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
6667

6768
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
@@ -73,6 +74,7 @@ protected function execute(
7374
return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
7475
}
7576

77+
$errorMessage = '';
7678
try {
7779
foreach ($productIds as $productId) {
7880
try {
@@ -82,9 +84,13 @@ protected function execute(
8284
continue;
8385
}
8486

85-
/** @var \Magento\Catalog\Model\Product\Image\Cache $imageCache */
86-
$imageCache = $this->imageCacheFactory->create();
87-
$imageCache->generate($product);
87+
try {
88+
/** @var \Magento\Catalog\Model\Product\Image\Cache $imageCache */
89+
$imageCache = $this->imageCacheFactory->create();
90+
$imageCache->generate($product);
91+
} catch (\Magento\Framework\Exception\RuntimeException $e) {
92+
$errorMessage = $e->getMessage();
93+
}
8894

8995
$output->write(".");
9096
}
@@ -95,6 +101,12 @@ protected function execute(
95101
}
96102

97103
$output->write("\n");
98-
$output->writeln("<info>Product images resized successfully</info>");
104+
$output->writeln("<info>Product images resized successfully.</info>");
105+
106+
if ($errorMessage !== '') {
107+
$output->writeln("<comment>{$errorMessage}</comment>");
108+
}
109+
110+
return 0;
99111
}
100112
}

app/code/Magento/Catalog/Model/Product/Attribute/Repository.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib
118118
$attribute->setAttributeId($existingModel->getAttributeId());
119119
$attribute->setIsUserDefined($existingModel->getIsUserDefined());
120120
$attribute->setFrontendInput($existingModel->getFrontendInput());
121+
if ($attribute->getIsUserDefined()) {
122+
$this->processAttributeData($attribute);
123+
}
121124

122125
if (is_array($attribute->getFrontendLabels())) {
123126
$defaultFrontendLabel = $attribute->getDefaultFrontendLabel();
@@ -156,15 +159,7 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib
156159
$this->validateCode($attribute->getAttributeCode());
157160
$this->validateFrontendInput($attribute->getFrontendInput());
158161

159-
$attribute->setBackendType(
160-
$attribute->getBackendTypeByInput($attribute->getFrontendInput())
161-
);
162-
$attribute->setSourceModel(
163-
$this->productHelper->getAttributeSourceModelByInputType($attribute->getFrontendInput())
164-
);
165-
$attribute->setBackendModel(
166-
$this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput())
167-
);
162+
$this->processAttributeData($attribute);
168163
$attribute->setEntityTypeId(
169164
$this->eavConfig
170165
->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE)
@@ -275,4 +270,23 @@ protected function validateFrontendInput($frontendInput)
275270
throw InputException::invalidFieldValue('frontend_input', $frontendInput);
276271
}
277272
}
273+
274+
/**
275+
* Process attribute data based on attribute frontend input type.
276+
*
277+
* @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute
278+
* @return void
279+
*/
280+
private function processAttributeData(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute)
281+
{
282+
$attribute->setBackendType(
283+
$attribute->getBackendTypeByInput($attribute->getFrontendInput())
284+
);
285+
$attribute->setSourceModel(
286+
$this->productHelper->getAttributeSourceModelByInputType($attribute->getFrontendInput())
287+
);
288+
$attribute->setBackendModel(
289+
$this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput())
290+
);
291+
}
278292
}

app/code/Magento/Catalog/Model/Product/Copier.php

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
<?php
22
/**
3-
* Catalog product copier. Creates product duplicate
4-
*
53
* Copyright © Magento, Inc. All rights reserved.
64
* See COPYING.txt for license details.
75
*/
86
namespace Magento\Catalog\Model\Product;
97

108
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Model\Product;
10+
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\Catalog\Model\ProductFactory;
13+
use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
1114

15+
/**
16+
* Catalog product copier. Creates product duplicate
17+
*/
1218
class Copier
1319
{
1420
/**
15-
* @var Option\Repository
21+
* @var OptionRepository
1622
*/
1723
protected $optionRepository;
1824

@@ -22,22 +28,22 @@ class Copier
2228
protected $copyConstructor;
2329

2430
/**
25-
* @var \Magento\Catalog\Model\ProductFactory
31+
* @var ProductFactory
2632
*/
2733
protected $productFactory;
2834

2935
/**
30-
* @var \Magento\Framework\EntityManager\MetadataPool
36+
* @var MetadataPool
3137
*/
3238
protected $metadataPool;
3339

3440
/**
3541
* @param CopyConstructorInterface $copyConstructor
36-
* @param \Magento\Catalog\Model\ProductFactory $productFactory
42+
* @param ProductFactory $productFactory
3743
*/
3844
public function __construct(
3945
CopyConstructorInterface $copyConstructor,
40-
\Magento\Catalog\Model\ProductFactory $productFactory
46+
ProductFactory $productFactory
4147
) {
4248
$this->productFactory = $productFactory;
4349
$this->copyConstructor = $copyConstructor;
@@ -46,18 +52,16 @@ public function __construct(
4652
/**
4753
* Create product duplicate
4854
*
49-
* @param \Magento\Catalog\Model\Product $product
50-
* @return \Magento\Catalog\Model\Product
55+
* @param Product $product
56+
* @return Product
5157
*/
52-
public function copy(\Magento\Catalog\Model\Product $product)
58+
public function copy(Product $product)
5359
{
5460
$product->getWebsiteIds();
5561
$product->getCategoryIds();
5662

57-
/** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */
5863
$metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
5964

60-
/** @var \Magento\Catalog\Model\Product $duplicate */
6165
$duplicate = $this->productFactory->create();
6266
$productData = $product->getData();
6367
$productData = $this->removeStockItem($productData);
@@ -83,6 +87,7 @@ public function copy(\Magento\Catalog\Model\Product $product)
8387
$duplicate->save();
8488
$isDuplicateSaved = true;
8589
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
90+
} catch (\Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException $e) {
8691
}
8792
} while (!$isDuplicateSaved);
8893
$this->getOptionRepository()->duplicate($product, $duplicate);
@@ -94,27 +99,25 @@ public function copy(\Magento\Catalog\Model\Product $product)
9499
}
95100

96101
/**
97-
* @return Option\Repository
102+
* @return OptionRepository
98103
* @deprecated 101.0.0
99104
*/
100105
private function getOptionRepository()
101106
{
102107
if (null === $this->optionRepository) {
103-
$this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance()
104-
->get(\Magento\Catalog\Model\Product\Option\Repository::class);
108+
$this->optionRepository = ObjectManager::getInstance()->get(OptionRepository::class);
105109
}
106110
return $this->optionRepository;
107111
}
108112

109113
/**
110-
* @return \Magento\Framework\EntityManager\MetadataPool
114+
* @return MetadataPool
111115
* @deprecated 101.0.0
112116
*/
113117
private function getMetadataPool()
114118
{
115119
if (null === $this->metadataPool) {
116-
$this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
117-
->get(\Magento\Framework\EntityManager\MetadataPool::class);
120+
$this->metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
118121
}
119122
return $this->metadataPool;
120123
}

app/code/Magento/Catalog/Model/Product/Image/Cache.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection;
1111
use Magento\Framework\App\Area;
1212
use Magento\Framework\View\ConfigInterface;
13+
use Psr\Log\LoggerInterface;
1314

1415
class Cache
1516
{
@@ -33,19 +34,29 @@ class Cache
3334
*/
3435
protected $data = [];
3536

37+
/**
38+
* Logger.
39+
*
40+
* @var LoggerInterface
41+
*/
42+
private $logger;
43+
3644
/**
3745
* @param ConfigInterface $viewConfig
3846
* @param ThemeCollection $themeCollection
3947
* @param ImageHelper $imageHelper
48+
* @param LoggerInterface $logger
4049
*/
4150
public function __construct(
4251
ConfigInterface $viewConfig,
4352
ThemeCollection $themeCollection,
44-
ImageHelper $imageHelper
53+
ImageHelper $imageHelper,
54+
LoggerInterface $logger = null
4555
) {
4656
$this->viewConfig = $viewConfig;
4757
$this->themeCollection = $themeCollection;
4858
$this->imageHelper = $imageHelper;
59+
$this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class);
4960
}
5061

5162
/**
@@ -74,21 +85,37 @@ protected function getData()
7485
}
7586

7687
/**
77-
* Resize product images and save results to image cache
88+
* Resize product images and save results to image cache.
7889
*
7990
* @param Product $product
91+
*
8092
* @return $this
93+
* @throws \Exception
8194
*/
8295
public function generate(Product $product)
8396
{
97+
$isException = false;
8498
$galleryImages = $product->getMediaGalleryImages();
8599
if ($galleryImages) {
86100
foreach ($galleryImages as $image) {
87101
foreach ($this->getData() as $imageData) {
88-
$this->processImageData($product, $imageData, $image->getFile());
102+
try {
103+
$this->processImageData($product, $imageData, $image->getFile());
104+
} catch (\Exception $e) {
105+
$isException = true;
106+
$this->logger->error($e->getMessage());
107+
$this->logger->error(__('The image could not be resized: ') . $image->getPath());
108+
}
89109
}
90110
}
91111
}
112+
113+
if ($isException === true) {
114+
throw new \Magento\Framework\Exception\RuntimeException(
115+
__('Some images could not be resized. See log file for details.')
116+
);
117+
}
118+
92119
return $this;
93120
}
94121

app/code/Magento/Catalog/Test/Unit/Console/Command/ImagesResizeCommandTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,44 @@ protected function prepareImageCache()
208208
->method('create')
209209
->willReturn($this->imageCache);
210210
}
211+
212+
public function testExecuteWithExceptionInGenerate()
213+
{
214+
$productsIds = [1, 2];
215+
216+
$this->appState->expects($this->once())
217+
->method('setAreaCode')
218+
->with(Area::AREA_GLOBAL)
219+
->willReturnSelf();
220+
221+
$this->productCollection->expects($this->once())
222+
->method('getAllIds')
223+
->willReturn($productsIds);
224+
225+
$productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
226+
->disableOriginalConstructor()
227+
->getMock();
228+
229+
$this->productRepository->expects($this->at(0))
230+
->method('getById')
231+
->with($productsIds[0])
232+
->willReturn($productMock);
233+
$this->productRepository->expects($this->at(1))
234+
->method('getById')
235+
->with($productsIds[1])
236+
->willThrowException(new NoSuchEntityException());
237+
238+
$this->imageCache->expects($this->exactly(count($productsIds) - 1))
239+
->method('generate')
240+
->with($productMock)
241+
->willThrowException(new \Magento\Framework\Exception\RuntimeException(__('Some text is here.')));
242+
243+
$commandTester = new CommandTester($this->command);
244+
$commandTester->execute([]);
245+
246+
$this->assertContains(
247+
'Some text is here.',
248+
$commandTester->getDisplay()
249+
);
250+
}
211251
}

0 commit comments

Comments
 (0)