Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit ad2d79d

Browse files
author
Joan He
committed
Merge remote-tracking branch 'upstream/2.3-develop' into BugFixPR
2 parents 9bd3260 + 0c9d6d1 commit ad2d79d

File tree

60 files changed

+1652
-231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1652
-231
lines changed

app/code/Magento/Backend/etc/module.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9-
<module name="Magento_Backend" >
9+
<module name="Magento_Backend">
1010
<sequence>
1111
<module name="Magento_Directory"/>
1212
</sequence>

app/code/Magento/Catalog/Block/Product/View/Gallery.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
use Magento\Framework\Stdlib\ArrayUtils;
2424

2525
/**
26+
* Product gallery block
27+
*
2628
* @api
2729
* @since 100.0.2
2830
*/
@@ -139,7 +141,7 @@ public function getGalleryImagesJson()
139141
'thumb' => $image->getData('small_image_url'),
140142
'img' => $image->getData('medium_image_url'),
141143
'full' => $image->getData('large_image_url'),
142-
'caption' => $image->getData('label'),
144+
'caption' => ($image->getLabel() ?: $this->getProduct()->getName()),
143145
'position' => $image->getData('position'),
144146
'isMain' => $this->isMainImage($image),
145147
'type' => str_replace('external-', '', $image->getMediaType()),
@@ -196,6 +198,8 @@ public function isMainImage($image)
196198
}
197199

198200
/**
201+
* Returns image attribute
202+
*
199203
* @param string $imageId
200204
* @param string $attributeName
201205
* @param string $default
@@ -222,6 +226,8 @@ private function getConfigView()
222226
}
223227

224228
/**
229+
* Returns image gallery config object
230+
*
225231
* @return Collection
226232
*/
227233
private function getGalleryImagesConfig()

app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public function __construct(
102102
}
103103

104104
/**
105+
* Execute create handler
106+
*
105107
* @param object $product
106108
* @param array $arguments
107109
* @return object
@@ -167,23 +169,19 @@ public function execute($product, $arguments = [])
167169
if (empty($attrData) && empty($clearImages) && empty($newImages) && empty($existImages)) {
168170
continue;
169171
}
170-
if (in_array($attrData, $clearImages)) {
171-
$product->setData($mediaAttrCode, 'no_selection');
172-
}
173-
174-
if (in_array($attrData, array_keys($newImages))) {
175-
$product->setData($mediaAttrCode, $newImages[$attrData]['new_file']);
176-
$product->setData($mediaAttrCode . '_label', $newImages[$attrData]['label']);
177-
}
178-
179-
if (in_array($attrData, array_keys($existImages)) && isset($existImages[$attrData]['label'])) {
180-
$product->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
181-
}
182-
if (!empty($product->getData($mediaAttrCode))) {
183-
$product->addAttributeUpdate(
172+
$this->processMediaAttribute(
173+
$product,
174+
$mediaAttrCode,
175+
$clearImages,
176+
$newImages
177+
);
178+
if (in_array($mediaAttrCode, ['image', 'small_image', 'thumbnail'])) {
179+
$this->processMediaAttributeLabel(
180+
$product,
184181
$mediaAttrCode,
185-
$product->getData($mediaAttrCode),
186-
$product->getStoreId()
182+
$clearImages,
183+
$newImages,
184+
$existImages
187185
);
188186
}
189187
}
@@ -208,6 +206,8 @@ public function execute($product, $arguments = [])
208206
}
209207

210208
/**
209+
* Returns media gallery atribute instance
210+
*
211211
* @return \Magento\Catalog\Api\Data\ProductAttributeInterface
212212
* @since 101.0.0
213213
*/
@@ -223,6 +223,8 @@ public function getAttribute()
223223
}
224224

225225
/**
226+
* Process delete images
227+
*
226228
* @param \Magento\Catalog\Model\Product $product
227229
* @param array $images
228230
* @return void
@@ -234,6 +236,8 @@ protected function processDeletedImages($product, array &$images)
234236
}
235237

236238
/**
239+
* Process images
240+
*
237241
* @param \Magento\Catalog\Model\Product $product
238242
* @param array $images
239243
* @return void
@@ -296,6 +300,8 @@ protected function processNewImage($product, array &$image)
296300
}
297301

298302
/**
303+
* Duplicate attribute
304+
*
299305
* @param \Magento\Catalog\Model\Product $product
300306
* @return $this
301307
* @since 101.0.0
@@ -364,6 +370,8 @@ private function getSafeFilename($file)
364370
}
365371

366372
/**
373+
* Returns file name according to tmp name
374+
*
367375
* @param string $file
368376
* @return string
369377
* @since 101.0.0
@@ -449,4 +457,81 @@ private function getMediaAttributeCodes()
449457
}
450458
return $this->mediaAttributeCodes;
451459
}
460+
461+
/**
462+
* Process media attribute
463+
*
464+
* @param \Magento\Catalog\Model\Product $product
465+
* @param string $mediaAttrCode
466+
* @param array $clearImages
467+
* @param array $newImages
468+
*/
469+
private function processMediaAttribute(
470+
\Magento\Catalog\Model\Product $product,
471+
$mediaAttrCode,
472+
array $clearImages,
473+
array $newImages
474+
) {
475+
$attrData = $product->getData($mediaAttrCode);
476+
if (in_array($attrData, $clearImages)) {
477+
$product->setData($mediaAttrCode, 'no_selection');
478+
}
479+
480+
if (in_array($attrData, array_keys($newImages))) {
481+
$product->setData($mediaAttrCode, $newImages[$attrData]['new_file']);
482+
}
483+
if (!empty($product->getData($mediaAttrCode))) {
484+
$product->addAttributeUpdate(
485+
$mediaAttrCode,
486+
$product->getData($mediaAttrCode),
487+
$product->getStoreId()
488+
);
489+
}
490+
}
491+
492+
/**
493+
* Process media attribute label
494+
*
495+
* @param \Magento\Catalog\Model\Product $product
496+
* @param string $mediaAttrCode
497+
* @param array $clearImages
498+
* @param array $newImages
499+
* @param array $existImages
500+
*/
501+
private function processMediaAttributeLabel(
502+
\Magento\Catalog\Model\Product $product,
503+
$mediaAttrCode,
504+
array $clearImages,
505+
array $newImages,
506+
array $existImages
507+
) {
508+
$resetLabel = false;
509+
$attrData = $product->getData($mediaAttrCode);
510+
if (in_array($attrData, $clearImages)) {
511+
$product->setData($mediaAttrCode . '_label', null);
512+
$resetLabel = true;
513+
}
514+
515+
if (in_array($attrData, array_keys($newImages))) {
516+
$product->setData($mediaAttrCode . '_label', $newImages[$attrData]['label']);
517+
}
518+
519+
if (in_array($attrData, array_keys($existImages)) && isset($existImages[$attrData]['label'])) {
520+
$product->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
521+
}
522+
523+
if ($attrData === 'no_selection' && !empty($product->getData($mediaAttrCode . '_label'))) {
524+
$product->setData($mediaAttrCode . '_label', null);
525+
$resetLabel = true;
526+
}
527+
if (!empty($product->getData($mediaAttrCode . '_label'))
528+
|| $resetLabel === true
529+
) {
530+
$product->addAttributeUpdate(
531+
$mediaAttrCode . '_label',
532+
$product->getData($mediaAttrCode . '_label'),
533+
$product->getStoreId()
534+
);
535+
}
536+
}
452537
}

app/code/Magento/Catalog/Plugin/Model/Attribute/Backend/AttributeValidation.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,21 @@
77

88
use Magento\Store\Model\Store;
99

10+
/**
11+
* Attribute validation
12+
*/
1013
class AttributeValidation
1114
{
1215
/**
1316
* @var \Magento\Store\Model\StoreManagerInterface
1417
*/
1518
private $storeManager;
1619

20+
/**
21+
* @var array
22+
*/
23+
private $allowedEntityTypes;
24+
1725
/**
1826
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
1927
* @param array $allowedEntityTypes
@@ -27,9 +35,12 @@ public function __construct(
2735
}
2836

2937
/**
38+
* Around validate
39+
*
3040
* @param \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend $subject
3141
* @param \Closure $proceed
3242
* @param \Magento\Framework\DataObject $entity
43+
* @throws \Magento\Framework\Exception\NoSuchEntityException
3344
* @return bool
3445
*/
3546
public function aroundValidate(
@@ -41,7 +52,7 @@ public function aroundValidate(
4152
return $entity instanceof $allowedEntity;
4253
}, $this->allowedEntityTypes)));
4354

44-
if ($isAllowedType && $this->storeManager->getStore()->getId() !== Store::DEFAULT_STORE_ID) {
55+
if ($isAllowedType && (int) $this->storeManager->getStore()->getId() !== Store::DEFAULT_STORE_ID) {
4556
$attrCode = $subject->getAttribute()->getAttributeCode();
4657
// Null is meaning "no value" which should be overridden by value from default scope
4758
if (array_key_exists($attrCode, $entity->getData()) && $entity->getData($attrCode) === null) {

app/code/Magento/Catalog/Test/Unit/Block/Product/View/GalleryTest.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,94 @@ protected function setUp()
9191
]);
9292
}
9393

94+
public function testGetGalleryImagesJsonWithLabel()
95+
{
96+
$this->prepareGetGalleryImagesJsonMocks();
97+
$json = $this->model->getGalleryImagesJson();
98+
$decodedJson = json_decode($json, true);
99+
$this->assertEquals('product_page_image_small_url', $decodedJson[0]['thumb']);
100+
$this->assertEquals('product_page_image_medium_url', $decodedJson[0]['img']);
101+
$this->assertEquals('product_page_image_large_url', $decodedJson[0]['full']);
102+
$this->assertEquals('test_label', $decodedJson[0]['caption']);
103+
$this->assertEquals('2', $decodedJson[0]['position']);
104+
$this->assertEquals(false, $decodedJson[0]['isMain']);
105+
$this->assertEquals('test_media_type', $decodedJson[0]['type']);
106+
$this->assertEquals('test_video_url', $decodedJson[0]['videoUrl']);
107+
}
108+
109+
public function testGetGalleryImagesJsonWithoutLabel()
110+
{
111+
$this->prepareGetGalleryImagesJsonMocks(false);
112+
$json = $this->model->getGalleryImagesJson();
113+
$decodedJson = json_decode($json, true);
114+
$this->assertEquals('test_product_name', $decodedJson[0]['caption']);
115+
}
116+
117+
private function prepareGetGalleryImagesJsonMocks($hasLabel = true)
118+
{
119+
$storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
120+
->disableOriginalConstructor()
121+
->getMock();
122+
123+
$productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
124+
->disableOriginalConstructor()
125+
->getMock();
126+
127+
$productTypeMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Type\AbstractType::class)
128+
->disableOriginalConstructor()
129+
->getMock();
130+
$productTypeMock->expects($this->any())
131+
->method('getStoreFilter')
132+
->with($productMock)
133+
->willReturn($storeMock);
134+
135+
$productMock->expects($this->any())
136+
->method('getTypeInstance')
137+
->willReturn($productTypeMock);
138+
$productMock->expects($this->any())
139+
->method('getMediaGalleryImages')
140+
->willReturn($this->getImagesCollectionWithPopulatedDataObject($hasLabel));
141+
$productMock->expects($this->any())
142+
->method('getName')
143+
->willReturn('test_product_name');
144+
145+
$this->registry->expects($this->any())
146+
->method('registry')
147+
->with('product')
148+
->willReturn($productMock);
149+
150+
$this->imageHelper = $this->getMockBuilder(\Magento\Catalog\Helper\Image::class)
151+
->setMethods(['init', 'setImageFile', 'getUrl'])
152+
->disableOriginalConstructor()
153+
->getMock();
154+
155+
$this->imageHelper->expects($this->any())
156+
->method('init')
157+
->willReturnMap([
158+
[$productMock, 'product_page_image_small', [], $this->imageHelper],
159+
[$productMock, 'product_page_image_medium_no_frame', [], $this->imageHelper],
160+
[$productMock, 'product_page_image_large_no_frame', [], $this->imageHelper],
161+
])
162+
->willReturnSelf();
163+
$this->imageHelper->expects($this->any())
164+
->method('setImageFile')
165+
->with('test_file')
166+
->willReturnSelf();
167+
$this->urlBuilder->expects($this->at(0))
168+
->method('getUrl')
169+
->willReturn('product_page_image_small_url');
170+
$this->urlBuilder->expects($this->at(1))
171+
->method('getUrl')
172+
->willReturn('product_page_image_medium_url');
173+
$this->urlBuilder->expects($this->at(2))
174+
->method('getUrl')
175+
->willReturn('product_page_image_large_url');
176+
177+
$this->galleryImagesConfigMock->expects($this->exactly(2))
178+
->method('getItems')
179+
->willReturn($this->getGalleryImagesConfigItems());
180+
}
181+
94182
public function testGetGalleryImages()
95183
{
96184
$productMock = $this->createMock(Product::class);
@@ -163,4 +251,30 @@ private function getGalleryImagesConfigItems()
163251
])
164252
];
165253
}
254+
255+
/**
256+
* @return \Magento\Framework\Data\Collection
257+
*/
258+
private function getImagesCollectionWithPopulatedDataObject($hasLabel)
259+
{
260+
$collectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection::class)
261+
->disableOriginalConstructor()
262+
->getMock();
263+
264+
$items = [
265+
new \Magento\Framework\DataObject([
266+
'file' => 'test_file',
267+
'label' => ($hasLabel ? 'test_label' : ''),
268+
'position' => '2',
269+
'media_type' => 'external-test_media_type',
270+
"video_url" => 'test_video_url'
271+
]),
272+
];
273+
274+
$collectionMock->expects($this->any())
275+
->method('getIterator')
276+
->willReturn(new \ArrayIterator($items));
277+
278+
return $collectionMock;
279+
}
166280
}

0 commit comments

Comments
 (0)