Skip to content

Commit acca7cb

Browse files
committed
MAGETWO-58918: Unable to create custom image attribute in category - for 2.1.x
1 parent 7ea39cd commit acca7cb

File tree

13 files changed

+1026
-165
lines changed

13 files changed

+1026
-165
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Category/Image/Upload.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@ protected function _isAllowed()
4444
}
4545

4646
/**
47-
* Upload file controller action
47+
* Upload file controller action.
4848
*
4949
* @return \Magento\Framework\Controller\ResultInterface
5050
*/
5151
public function execute()
5252
{
53+
$imageId = $this->_request->getParam('param_name', 'image');
5354
try {
54-
$result = $this->imageUploader->saveFileToTmpDir('image');
55+
$result = $this->imageUploader->saveFileToTmpDir($imageId);
5556

5657
$result['cookie'] = [
5758
'name' => $this->_getSession()->getName(),

app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Catalog\Controller\Adminhtml\Category;
77

88
use Magento\Store\Model\StoreManagerInterface;
9+
use Magento\Catalog\Api\Data\CategoryAttributeInterface;
910

1011
/**
1112
* Class Save
@@ -48,6 +49,13 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category
4849
*/
4950
private $storeManager;
5051

52+
/**
53+
* Config instance holder.
54+
*
55+
* @var \Magento\Eav\Model\Config
56+
*/
57+
private $eavConfig;
58+
5159
/**
5260
* Constructor
5361
*
@@ -72,8 +80,9 @@ public function __construct(
7280
}
7381

7482
/**
75-
* Filter category data
83+
* Filter category data.
7684
*
85+
* @deprecated
7786
* @param array $rawData
7887
* @return array
7988
*/
@@ -126,7 +135,7 @@ public function execute()
126135
$this->storeManager->setCurrentStore($store->getCode());
127136
$parentId = isset($categoryPostData['parent']) ? $categoryPostData['parent'] : null;
128137
if ($categoryPostData) {
129-
$category->addData($this->_filterCategoryPostData($categoryPostData));
138+
$category->addData($categoryPostData);
130139
if ($isNewCategory) {
131140
$parentCategory = $this->getParentCategory($parentId, $storeId);
132141
$category->setPath($parentCategory->getPath());
@@ -248,21 +257,47 @@ public function execute()
248257
}
249258

250259
/**
251-
* Image data preprocessing
260+
* Sets image attribute data to false, if image was removed.
252261
*
253262
* @param array $data
254263
*
255264
* @return array
256265
*/
257-
public function imagePreprocessing($data)
266+
public function imagePreprocessing(array $data)
258267
{
259-
if (empty($data['image'])) {
260-
unset($data['image']);
261-
$data['image']['delete'] = true;
268+
$emptyImageAttributes = $this->getEmptyImageAttributes($data);
269+
foreach ($emptyImageAttributes as $attributeCode => $attributeModel) {
270+
$data[$attributeCode] = false;
262271
}
272+
263273
return $data;
264274
}
265275

276+
/**
277+
* Get image attributes without value.
278+
*
279+
* @param array $data
280+
* @return array
281+
*/
282+
private function getEmptyImageAttributes(array $data)
283+
{
284+
$result = [];
285+
$entityType = $this->getConfig()->getEntityType(CategoryAttributeInterface::ENTITY_TYPE_CODE);
286+
foreach ($entityType->getAttributeCollection() as $attribute) {
287+
$attributeCode = $attribute->getAttributeCode();
288+
$backendModel = $attribute->getBackend();
289+
if (isset($data[$attributeCode])) {
290+
continue;
291+
}
292+
if (!$backendModel instanceof \Magento\Catalog\Model\Category\Attribute\Backend\Image) {
293+
continue;
294+
}
295+
$result[$attributeCode] = $attribute;
296+
}
297+
298+
return $result;
299+
}
300+
266301
/**
267302
* Converting inputs from string to boolean
268303
*
@@ -346,4 +381,20 @@ protected function getRedirectParams($isNewCategory, $hasError, $categoryId, $pa
346381
}
347382
return ['path' => $path, 'params' => $params];
348383
}
384+
385+
/**
386+
* Get Config instance.
387+
*
388+
* @return \Magento\Eav\Model\Config
389+
*/
390+
private function getConfig()
391+
{
392+
if (null === $this->eavConfig) {
393+
$this->eavConfig = \Magento\Framework\App\ObjectManager::getInstance()->get(
394+
\Magento\Eav\Model\Config::class
395+
);
396+
}
397+
398+
return $this->eavConfig;
399+
}
349400
}

app/code/Magento/Catalog/Model/Category.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,14 +652,16 @@ public function formatUrlKey($str)
652652
}
653653

654654
/**
655-
* Retrieve image URL
655+
* Get image url by attribute code.
656656
*
657+
* @param string $attributeCode
657658
* @return string
659+
* @throws \Magento\Framework\Exception\LocalizedException
658660
*/
659-
public function getImageUrl()
661+
public function getImageUrl($attributeCode = 'image')
660662
{
661663
$url = false;
662-
$image = $this->getImage();
664+
$image = $this->getData($attributeCode);
663665
if ($image) {
664666
if (is_string($image)) {
665667
$url = $this->_storeManager->getStore()->getBaseUrl(
@@ -671,6 +673,7 @@ public function getImageUrl()
671673
);
672674
}
673675
}
676+
674677
return $url;
675678
}
676679

app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,45 @@ public function __construct(
7070
}
7171

7272
/**
73-
* Get image uploader
73+
* Avoiding saving potential upload data to DB.
74+
* Will set empty image attribute value if image was not uploaded.
75+
*
76+
* @param \Magento\Framework\DataObject $object
77+
* @return $this
78+
*/
79+
public function beforeSave($object)
80+
{
81+
$attributeName = $this->getAttribute()->getName();
82+
$value = $object->getData($attributeName);
83+
$imageName = $this->getUploadedImageName($value);
84+
85+
if ($imageName) {
86+
$object->setData($attributeName, $imageName);
87+
} else if (!is_string($value)) {
88+
$object->setData($attributeName, '');
89+
}
90+
91+
return parent::beforeSave($object);
92+
}
93+
94+
/**
95+
* Gets image name from $value array.
96+
* Will return empty string in case $value is not an array.
97+
*
98+
* @param array $value Attribute value
99+
* @return string
100+
*/
101+
private function getUploadedImageName($value)
102+
{
103+
if (is_array($value) && isset($value[0]['name'])) {
104+
return $value[0]['name'];
105+
}
106+
107+
return '';
108+
}
109+
110+
/**
111+
* Get image uploader.
74112
*
75113
* @return \Magento\Catalog\Model\ImageUploader
76114
*
@@ -79,26 +117,25 @@ public function __construct(
79117
private function getImageUploader()
80118
{
81119
if ($this->imageUploader === null) {
82-
$this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance()->get(
83-
'Magento\Catalog\CategoryImageUpload'
84-
);
120+
$this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance()
121+
->get(\Magento\Catalog\CategoryImageUpload::class);
85122
}
123+
86124
return $this->imageUploader;
87125
}
88126

89127
/**
90-
* Save uploaded file and set its name to category
128+
* Save uploaded file and set its name to category.
91129
*
92130
* @param \Magento\Framework\DataObject $object
93131
* @return \Magento\Catalog\Model\Category\Attribute\Backend\Image
94132
*/
95133
public function afterSave($object)
96134
{
97-
$image = $object->getData($this->getAttribute()->getName(), null);
98-
99-
if ($image !== null) {
135+
$imageName = $object->getData($this->getAttribute()->getName(), null);
136+
if ($imageName) {
100137
try {
101-
$this->getImageUploader()->moveFileFromTmp($image);
138+
$this->getImageUploader()->moveFileFromTmp($imageName);
102139
} catch (\Exception $e) {
103140
$this->_logger->critical($e);
104141
}

app/code/Magento/Catalog/Model/Category/DataProvider.php

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Magento\Ui\DataProvider\EavValidationRules;
1818
use Magento\Catalog\Model\CategoryFactory;
1919
use Magento\Framework\Exception\NoSuchEntityException;
20+
use Magento\Catalog\Model\Category\Attribute\Backend\Image as ImageBackendModel;
2021

2122
/**
2223
* Class DataProvider
@@ -206,16 +207,54 @@ public function getData()
206207
$categoryData = $this->addUseDefaultSettings($category, $categoryData);
207208
$categoryData = $this->addUseConfigSettings($categoryData);
208209
$categoryData = $this->filterFields($categoryData);
209-
if (isset($categoryData['image'])) {
210-
unset($categoryData['image']);
211-
$categoryData['image'][0]['name'] = $category->getData('image');
212-
$categoryData['image'][0]['url'] = $category->getImageUrl();
213-
}
210+
$categoryData = $this->convertValues($category, $categoryData);
211+
214212
$this->loadedData[$category->getId()] = $categoryData;
215213
}
216214
return $this->loadedData;
217215
}
218216

217+
/**
218+
* Converts category image data to acceptable format for rendering.
219+
*
220+
* @param \Magento\Catalog\Model\Category $category
221+
* @param array $categoryData
222+
* @return array
223+
*/
224+
private function convertValues(Category $category, array $categoryData)
225+
{
226+
$imageAttributes = $this->getImageAttributes($category, $categoryData);
227+
foreach ($imageAttributes as $attributeCode => $attribute) {
228+
unset($categoryData[$attributeCode]);
229+
$categoryData[$attributeCode][0]['name'] = $category->getData($attributeCode);
230+
$categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode);
231+
}
232+
233+
return $categoryData;
234+
}
235+
236+
/**
237+
* Get all category image attributes.
238+
*
239+
* @param \Magento\Catalog\Model\Category $category
240+
* @param array $categoryData
241+
* @return array
242+
*/
243+
private function getImageAttributes(Category $category, array $categoryData)
244+
{
245+
$imageAttributes = [];
246+
foreach ($category->getAttributes() as $attributeCode => $attribute) {
247+
if (!isset($categoryData[$attributeCode])) {
248+
continue;
249+
}
250+
if ($attribute->getBackend() instanceof ImageBackendModel) {
251+
$imageAttributes[$attributeCode] = $attribute;
252+
}
253+
}
254+
255+
return $imageAttributes;
256+
}
257+
219258
/**
220259
* Get attributes meta
221260
*

0 commit comments

Comments
 (0)