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?
Best Answer
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.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
andallowedExtensions
set to certain values.Add this also to the
di.xml
of your module