This is my fieldset from the uicomponent form:
<fieldset name="image_form_fieldset">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Form</item>
</item>
</argument>
<field name="file">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">File</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="formElement" xsi:type="string">fileUploader</item>
<item name="source" xsi:type="string">file</item>
<item name="sortOrder" xsi:type="string">15</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="regenerate/image/file"/>
</item>
</item>
</argument>
</field>
</fieldset>
This is my controller for the regenerate/image/file part:
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\UrlInterface;
use Magento\Backend\App\Action;
class File extends Action {
/**
* @var UploaderFactory
*/
protected $uploaderFactory;
/**
* @var Filesystem\Directory\WriteInterface
*/
protected $mediaDirectory;
/**
* @var StoreManagerInterface
*/
protected $storeManager;
public function __construct(
Context $context,
UploaderFactory $uploaderFactory,
Filesystem $filesystem,
StoreManagerInterface $storeManager
)
{
parent::__construct($context);
$this->uploaderFactory = $uploaderFactory;
$this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
$this->storeManager = $storeManager;
}
public function execute()
{
$jsonResult = $this->resultFactory->create(ResultFactory::TYPE_JSON);
try {
$fileUploader = $this->uploaderFactory->create(['fileId' => 'file']);
$fileUploader->setAllowedExtensions(['csv']);
$fileUploader->setAllowRenameFiles(true);
$fileUploader->setAllowCreateFolders(true);
$fileUploader->setFilesDispersion(false);
$fileUploader->validateFile();
$result = $fileUploader->save($this->mediaDirectory->getAbsolutePath('tmp/imageUploader/images'));
$result['url'] = $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) . 'regenerate_images/';
return $jsonResult->setData($result);
} catch (LocalizedException $e) {
return $jsonResult->setData(['errorcode' => 0, 'error' => $e->getMessage()]);
} catch (\Exception $e) {
error_log($e->getMessage());
error_log($e->getTraceAsString());
return $jsonResult->setData(['errorcode' => 0, 'error' => __('An error occurred, please try again later.'. $e->getMessage())]);
}
}
}
My code is failing at this part: $fileUploader = $this->uploaderFactory->create(['fileId' => 'file']);. Getting this error message:
An error occurred, please try again later.Notice: Trying to access array offset on value of type null in ../vendor/magento/framework/File/Uploader.php on line 226
Any idea why ? and how can I fix this. I just want to upload a csv file in the media folder.
Thanks
1 Answer 1
My problem mainly was because of this part:
['fileId' => 'file']
It didn't match with my input value name defined in the UI Component. I will leave here all of the code, maybe it will help someone in the future:
From: app/code/Vendor/Products/view/adminhtml/layout/regenerate_image_index.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Regenerate Image Cache</title>
</head>
<body>
<referenceContainer name="content">
<uiComponent name="fileupload_form"/>
</referenceContainer>
</body>
</page>
From: app/code/Vendor/Products/view/adminhtml/ui_component/fileupload_form.xml:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Ui/etc/ui_configuration.xsd">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">fileupload_form.fileupload_form_data_source</item>
<item name="deps" xsi:type="string">fileupload_form.fileupload_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Form</item>
<item name="layout" xsi:type="array">
<item name="type" xsi:type="string">tabs</item>
</item>
<item name="buttons" xsi:type="array">
<item name="save" xsi:type="array">
<item name="name" xsi:type="string">save</item>
<item name="label" xsi:type="string" translate="true">Upload CSV file</item>
<item name="class" xsi:type="string">save primary</item>
</item>
</item>
</argument>
<dataSource name="fileupload_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Vendor\Products\Model\DataProvider</argument>
<argument name="name" xsi:type="string">fileupload_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
</item>
</argument>
</dataSource>
<fieldset name="fileupload_form">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Form</item>
</item>
</argument>
<field name="file">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">File</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="formElement" xsi:type="string">fileUploader</item>
<item name="source" xsi:type="string">file</item>
<item name="sortOrder" xsi:type="string">15</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="regenerate/image/file"/>
</item>
</item>
</argument>
</field>
</fieldset>
</form>
From my controller: app/code/Vendor/Products/Controller/Adminhtml/Image/File.php :
<?php
namespace Vendor\Products\Controller\Adminhtml\Image;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Backend\App\Action;
use Magento\Framework\App\Filesystem\DirectoryList;
use Exception;
class File extends Action {
/**
* @var Filesystem
*/
protected $fileSystem;
/**
* @var UploaderFactory
*/
protected $uploaderFactory;
/**
* @var Filesystem\Directory\WriteInterface
*/
protected $mediaDirectory;
/**
* @var StoreManagerInterface
*/
protected $storeManager;
public function __construct(
Context $context,
UploaderFactory $uploaderFactory,
Filesystem $filesystem,
StoreManagerInterface $storeManager,
Filesystem $fileSystem
) {
parent::__construct($context);
$this->uploaderFactory = $uploaderFactory;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->storeManager = $storeManager;
$this->fileSystem = $fileSystem;
}
public function execute()
{
$jsonResult = $this->resultFactory->create(ResultFactory::TYPE_JSON);
try {
$fileUploader = $this->uploaderFactory->create([
'fileId' => 'fileupload_form[file]'
]);
$fileUploader->setAllowedExtensions(['csv']);
$fileUploader->setAllowRenameFiles(true);
$fileUploader->setAllowCreateFolders(true);
$fileUploader->setFilesDispersion(false);
$data = $fileUploader->save($this->mediaDirectory->getAbsolutePath('regenerate_images'));
return $jsonResult->setData($data);
} catch (LocalizedException|Exception $error) {
return $jsonResult->setData(['errorcode' => 0, 'error' => $error->getMessage()]);
}
}
}
Good luck!
\Magento\MediaStorage\Model\File\Uploader. Based on line$fileUploader->validate();you have a some customization forUploader. Exceptvalidate- provided code should work with original uploader.