4

I am trying to create product attribute of image type. I am already created one custom attribute group and some other attribute in it but image type attribute doesn't look good.

enter image description here

InstallData.php

$eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'my_attribute_image',
            [
                'type' => 'varchar',
                'backend' => 'My\Test5\Model\Attribute\Product\Image',
                'frontend' => '',
                'label' => 'My Attribute Image7',
                'input' => 'image',
                'class' => '',
                'source' => '',
                'group' =>'My custom group',
                'visible' => true,
                'required' => false,
                'user_defined' => false,
                'default' => 0,
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => true,
                'used_in_product_listing' => true,
                'unique' => false,
                'apply_to' => ''
            ]
        );

My\Test5\Model\Attribute\Product\Image.php

class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
{

    protected $_uploaderFactory;
    protected $_filesystem;
    protected $_fileUploaderFactory;
    protected $_logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory
    ) {
        $this->_filesystem = $filesystem;
        $this->_fileUploaderFactory = $fileUploaderFactory;
        $this->_logger = $logger;
    }

    public function afterSave($object)
    {
        $value = $object->getData($this->getAttribute()->getName() . '_additional_data');

        if (empty($value) && empty($_FILES)) {
            return $this;
        }

        if (is_array($value) && !empty($value['delete'])) {
            $object->setData($this->getAttribute()->getName(), '');
            $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
            return $this;
        }

        $path = $this->_filesystem->getDirectoryRead(
            DirectoryList::MEDIA
        )->getAbsolutePath(
            'catalog/product/'
        );

        try {

            $uploader = $this->_fileUploaderFactory->create(['fileId' => $this->getAttribute()->getName()]);
            $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
            $uploader->setAllowRenameFiles(true);
            $result = $uploader->save($path);

            $object->setData($this->getAttribute()->getName(), $result['file']);
            $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
        } catch (\Exception $e) {
            if ($e->getCode() != \Magento\MediaStorage\Model\File\Uploader::TMP_NAME_EMPTY) {
                $this->_logger->critical($e);
            }
        }
        return $this;
    }
}

It's save image perfectly at front at

Magento_Root/pub/catalog/product

But cann't display/delete at admin in product tab.because It's find image at {base_url}/catalog/product/my_image.jpg

So it's look like miss "pub" in url. Anyone wants to suggest another way or correction in my code. Any kind of help will be appreciated. Thank you.

1
  • I am getting 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'catalog_product_entity_file'. How do we add table catalog_product_entity_file?
    – konika
    Aug 25, 2016 at 12:19

1 Answer 1

4

Potential Bug in Magento2

I found a few problems in Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image.php with the function called _getUrl. Override that function by performing the following steps:

Step1: di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image" type="<Vendor>\<Module>\Block\Product" />    
</config>

Step2: Vendor/Module/Block/Product.php

<?php
namespace <Vendor>\<Module>\Block;

class Product extends \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image
{
    protected function _getUrl()
    {
        $url = false;
        if ($this->getValue()) {
            $url = $this->_urlBuilder->getBaseUrl(['_type' => 
                \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
            ]) . 'catalog/product/' . $this->getValue();
        }
        return $url;
    }

    protected function _toHtml()
        {
            $this->setModuleName($this->extractModuleName('Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Image'));
            return parent::_toHtml();
        }

}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.