3

I am trying to add an image field in my module. I know its been asked before, I tried many provided solutions but can't get it to work. Here's the error I am getting:

While editing old entity:

/pub/static/adminhtml/Magento/backend/en_US/Magento_Ui/js/form/element/file-uploader.js:69 Uncaught TypeError: value.map is not a function

While creating new entity, after selecting the uploadable file, I get this on console:

admin/namespace_module/entity_image/upload/key/dce7aaf794cabba38bc88c52a3317988b859ee4987303d9954ab92c91f9f9049?isAjax=true 500 (Internal Server Error)

On checking the url above:

Exception #0 (BadMethodCallException): Missing required argument $baseTmpPath of Magento\Catalog\Model\ImageUploader.

My form.xml

<field name="image">
    <argument name="class" xsi:type="string">Namespace\Module\Model\Entity\DataProvider</argument>
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">string</item>
            <item name="source" xsi:type="string">Entity</item>
            <item name="label" xsi:type="string" translate="true">Image</item>
            <item name="visible" xsi:type="boolean">true</item>
            <item name="formElement" xsi:type="string">fileUploader</item>
            <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
            <item name="previewTmpl" xsi:type="string">Namespace_Module/image-preview</item>
            <item name="required" xsi:type="boolean">false</item>
            <item name="uploaderConfig" xsi:type="array">
                <item name="url" xsi:type="url" path="namespace_module/entity_image/upload"/>
            </item>
        </item>
    </argument>
</field>

My Upload Class:

namespace [Namespace]\[Module]\Controller\Adminhtml\[Entity]\Image;

use Magento\Framework\Controller\ResultFactory;

/**
 * Class Upload
 */
class Upload extends \Magento\Backend\App\Action
{
    /**
     * Image uploader
     *
     * @var \[Namespace]\[Module]\Model\ImageUploader
     */
    protected $imageUploader;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Catalog\Model\ImageUploader $imageUploader
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Catalog\Model\ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }

    /**
     * Check admin permissions for this controller
     *
     * @return boolean
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('[Namespace]_[Module]::[entity]');
    }

    /**
     * Upload file controller action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('image');

            $result['cookie'] = [
                'name' => $this->_getSession()->getName(),
                'value' => $this->_getSession()->getSessionId(),
                'lifetime' => $this->_getSession()->getCookieLifetime(),
                'path' => $this->_getSession()->getCookiePath(),
                'domain' => $this->_getSession()->getCookieDomain(),
            ];
        } catch (\Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }
        return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
    }
}

Is there something I am missing? Do I need to add/update anyother files?

  • how does your [Namespace]\[Module]\Model\ImageUploader class look like? and why do you get the error in the catalog model image upload? – Marius Jun 22 '17 at 6:28
  • I am sorry that is supposed to be \Magento\Catalog\Model\ImageUploader, I have updated the question to reflect it. – Prateek Jun 22 '17 at 6:36
6

The Catalog model image uploader is a bit abstract. It can be used to upload images/files basically anywhere. It does not have a path and a tmp path set for image uploading.
You can create a virtual type based on it and use that one.
You can do that by adding this in the di.xml file of your module.

<virtualType name="[entity]ImageUploader" type="Magento\Catalog\Model\ImageUploader"><!-- replace [entity] with your entity name -->
    <arguments>
        <argument name="baseTmpPath" xsi:type="string">path/to/upload/tmp</argument>
        <argument name="basePath" xsi:type="string">path/to/upload</argument>
        <argument name="allowedExtensions" xsi:type="array"><!-- you can add here file extension restrictions -->
            <item name="jpg" xsi:type="string">jpg</item>
            <item name="jpeg" xsi:type="string">jpeg</item>
            <item name="gif" xsi:type="string">gif</item>
            <item name="png" xsi:type="string">png</item>
        </argument>
    </arguments>
</virtualType>

and then you need to tell magento that your image upload controller uses this virtual type to upload the file. This virtual type instance is basically an instance of the catalog image uploader but with baseTmpPath, basePath and allowedExtensions set to certain values.

Add this also to the di.xml of your module

<type name="[Namespace]\[Module]\Controller\Adminhtml\[Entity]\Image\Upload">
    <arguments>
        <argument name="imageUploader" xsi:type="object">[entity]ImageUploader</argument><!-- again, replace [entity] with the name of your entity. Make sure it matches the name of the virtual type above. -->
    </arguments>
</type>
  • I had to change the type above to <type name="[Namespace][Module]\Controller\Adminhtml[Entity]\Image\Upload">. And it worked. Cheers. – Prateek Jun 22 '17 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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