Magento 2: यूआई फाइलअप लोडर को लागू करें


22

मैंने हाल ही में Magento 2.1.7 पर अपने फॉर्म में FileUploader Ui Component को लागू किया है ।

इसके लिए कोड यहाँ है ( ऐप / कोड / विक्रेता / ब्लॉग / दृश्य / adminhtml / ui_component / seller_blog_form.xml ):

<field name="featured_images">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" translate="true" xsi:type="string">Hervorgehobene Bilder:</item>
                    <item name="formElement" xsi:type="string">fileUploader</item>
                    <item name="componentType" xsi:type="string">fileUploader</item>
                    <item name="previewTmpl" xsi:type="string">Magento_Catalog/image-preview</item>
                    <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
                    <item name="allowedExtensions" xsi:type="string">jpg jpeg gif png</item>
                    <item name="notice" xsi:type="string" translate="true">Erlaubte Dateitypen: png, gif, jpg, jpeg.</item>
                    <item name="maxFileSize" xsi:type="number">2097152</item>
                    <item name="source" xsi:type="string">blog</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                    <item name="dataScope" xsi:type="string">featured_images</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">false</item>
                    </item>
                    <item name="uploaderConfig" xsi:type="array">
                        <item name="url" xsi:type="url" path="vendor_blog/blog/upload"/>
                    </item>
                </item>
            </argument>
        </field>

इसके लिए मेरा कंट्रोलर यह है ( ऐप / कोड / वेंडर / ब्लॉग / कंट्रोलर / एडमिनिस्ट्रेटर / ब्लॉग / अपलोड / एफपीपी ):

<?php

namespace Vendor\Blog\Controller\Adminhtml\Blog;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Backend\App\Action;  

class Upload extends \Vendor\Blog\Controller\Adminhtml\Blog
{

    protected $_fileUploaderFactory;
    protected $_directory_list;
    protected $_logger;

    public function __construct(
        Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory,
        \Magento\Framework\App\Filesystem\DirectoryList $directory_list,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->_fileUploaderFactory = $fileUploaderFactory;
        $this->_directory_list = $directory_list;
        $this->_logger = $logger;
        parent::__construct($context, $coreRegistry);
    }

    public function execute(){
        $uploader = $this->_fileUploaderFactory->create(['fileId' => 'featured_images']);
        $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
        $uploader->setAllowRenameFiles(false);
        $uploader->setFilesDispersion(false);
        $path = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath('blog');
        //$path = $this->_directory_list->getPath('media') . '/blog';
        $this->_logger->debug('Uploader.php: '.$path);
        $uploader->save($path);
    }
}

हालांकि, जब मैं एक छवि अपलोड करता हूं और क्रोम के कंसोल में कॉल का निरीक्षण करता हूं, तो मुझे अपवाद के साथ एक त्रुटि 500 ​​मिलती है: $ _FILES सरणी खाली है

मैं दो दिनों से संघर्ष कर रहा हूं, लेकिन मैं इसे सही तरीके से काम नहीं कर सकता। जब मैं वैकल्पिक $pathवैरिएबल लाइन को अनसुना कर देता हूं , तो अपलोड सफल हो जाता है लेकिन मुझे पूर्वावलोकन नहीं मिलता है।

मैंने पढ़ा कि यह enctypeउस समस्या का कारण बनने वाले फ़ॉर्म का हो सकता है , लेकिन मुझे UI घटक के लिए इसे कैसे जांचना है, इस बारे में कोई जानकारी नहीं मिली।

यदि आपको संपूर्ण अपवाद कोड की आवश्यकता है, तो कृपया मुझे बताएं।

मैं हर संभव मदद की सराहना करता हूं। धन्यवाद!


अपलोड करने का दूसरा तरीका क्यों न आज़माएं? उदाहरण के लिए। webkul.com/blog/…
पल्लवी

अफसोस की बात है कि मैं केवल इस विस्तार के लिए एक्सएमएल घोषणा के साथ शुद्ध यूआई घटकों का उपयोग करने के लिए सीमित हूं। लेकिन यह एक अच्छा विकल्प होगा।
हॉलरेलन

जवाबों:


35

मैं व्यवस्थापक रूप में UI फ़ाइलअप लोडर घटक जोड़ने के लिए इस चरण का पालन करता हूं

मैं अपने FAQ एक्सटेंशन के लिए आइकन अपलोड करने के लिए UI फ़ाइलअप लोडर घटक का उपयोग करता हूं। आप यहाँ से संदर्भ ले सकते हैं: https://github.com/mageprince/magento2-FAQ

1) admin_form.xml(व्यवस्थापक फ़ॉर्म) में फ़ील्ड जोड़ें

<field name="icon">
    <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">FaqGroup</item>
            <item name="label" xsi:type="string" translate="true">Group 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">Vendor_Module/image-preview</item>
            <item name="required" xsi:type="boolean">false</item>
            <item name="sortOrder" xsi:type="number">40</item>
            <item name="uploaderConfig" xsi:type="array">
                <item name="url" xsi:type="url" path="your_router/faqgroup/upload"/>
            </item>
        </item>
    </argument>
</field>

2) अब हमें नियंत्रक बनाने की आवश्यकता है जिसे हम uploaderConfigव्यवस्थापक रूप में परिभाषित करते हैं :<item name="url" xsi:type="url" path="vendor_module/faqgroup/upload"/>

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / नियंत्रक / Adminhtml / FaqGroup / Upload.php

<?php

namespace Vendor\Module\Controller\Adminhtml\FaqGroup;

use Magento\Framework\Controller\ResultFactory;

class Upload extends \Magento\Backend\App\Action
{
    public $imageUploader;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Vendor\Module\Model\ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }

    public function _isAllowed()
    {
        return $this->_authorization->isAllowed('Vendor_Module::Faq');
    }

    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('icon');
            $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);
    }
}

3) बनाएं ImageUploader.php

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / मॉडल / ImageUploader.php

<?php

namespace Prince\Faq\Model;

class ImageUploader
{
    private $coreFileStorageDatabase;
    private $mediaDirectory;
    private $uploaderFactory;
    private $storeManager;
    private $logger;
    public $baseTmpPath;
    public $basePath;
    public $allowedExtensions;

    public function __construct(
        \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->coreFileStorageDatabase = $coreFileStorageDatabase;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
        $this->uploaderFactory = $uploaderFactory;
        $this->storeManager = $storeManager;
        $this->logger = $logger;
        $this->baseTmpPath = "faq/tmp/icon";
        $this->basePath = "faq/icon";
        $this->allowedExtensions= ['jpg', 'jpeg', 'gif', 'png'];
    }

    public function setBaseTmpPath($baseTmpPath)
    {
        $this->baseTmpPath = $baseTmpPath;
    }

    public function setBasePath($basePath)
    {
        $this->basePath = $basePath;
    }

    public function setAllowedExtensions($allowedExtensions)
    {
        $this->allowedExtensions = $allowedExtensions;
    }

    public function getBaseTmpPath()
    {
        return $this->baseTmpPath;
    }

    public function getBasePath()
    {
        return $this->basePath;
    }

    public function getAllowedExtensions()
    {
        return $this->allowedExtensions;
    }

    public function getFilePath($path, $imageName)
    {
        return rtrim($path, '/') . '/' . ltrim($imageName, '/');
    }

    public function moveFileFromTmp($imageName)
    {
        $baseTmpPath = $this->getBaseTmpPath();
        $basePath = $this->getBasePath();
        $baseImagePath = $this->getFilePath($basePath, $imageName);
        $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName);
        try {
            $this->coreFileStorageDatabase->copyFile(
                $baseTmpImagePath,
                $baseImagePath
            );
            $this->mediaDirectory->renameFile(
                $baseTmpImagePath,
                $baseImagePath
            );
        } catch (\Exception $e) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('Something went wrong while saving the file(s).')
            );
        }
        return $imageName;
    }

    public function saveFileToTmpDir($fileId)
    {
        $baseTmpPath = $this->getBaseTmpPath();
        $uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
        $uploader->setAllowedExtensions($this->getAllowedExtensions());
        $uploader->setAllowRenameFiles(true);
        $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath));
        if (!$result) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('File can not be saved to the destination folder.')
            );
        }

        $result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
        $result['path'] = str_replace('\\', '/', $result['path']);
        $result['url'] = $this->storeManager
                ->getStore()
                ->getBaseUrl(
                    \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
                ) . $this->getFilePath($baseTmpPath, $result['file']);
        $result['name'] = $result['file'];
        if (isset($result['file'])) {
            try {
                $relativePath = rtrim($baseTmpPath, '/') . '/' . ltrim($result['file'], '/');
                $this->coreFileStorageDatabase->saveFile($relativePath);
            } catch (\Exception $e) {
                $this->logger->critical($e);
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('Something went wrong while saving the file(s).')
                );
            }
        }
        return $result;
    }
}

4) बनाएं image-preview.html

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / देखें / adminhtml / वेब / टेम्पलेट / छवि preview.html

<div class="file-uploader-summary">
    <div class="file-uploader-preview">
        <a attr="href: $parent.getFilePreview($file)" target="_blank">
            <img
                class="preview-image"
                tabindex="0"
                event="load: $parent.onPreviewLoad.bind($parent)"
                attr="
                    src: $parent.getFilePreview($file),
                    alt: $file.name">
        </a>

        <div class="actions">
            <button
                type="button"
                class="action-remove"
                data-role="delete-button"
                attr="title: $t('Delete image')"
                click="$parent.removeFile.bind($parent, $file)">
                <span translate="'Delete image'"/>
            </button>
        </div>
    </div>

    <div class="file-uploader-filename" text="$file.name"/>
    <div class="file-uploader-meta">
        <text args="$file.previewWidth"/>x<text args="$file.previewHeight"/>
    </div>
</div>

5) अब ImageUploader.phpdi.xml में तर्क जोड़ें

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / etc / di.xml

<type name="Vendor\Module\Model\ImageUploader">
    <arguments>
        <!-- Temporary file stored in pub/media/faq/tmp/icon -->
        <argument name="baseTmpPath" xsi:type="string">faq/tmp/icon</argument>
        <argument name="basePath" xsi:type="string">faq/icon</argument>
        <argument name="allowedExtensions" xsi:type="array">
            <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>
</type>

संपादित फ़ॉर्म पर लोड अपलोड की गई छवि के लिए इस फ़ाइल की जाँच करें: DataProvider.php

उत्पादन:

यहां छवि विवरण दर्ज करें

डेटाबेस में छवि को बचाने के लिए

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / नियंत्रक / Adminhtml / Save.php

<?php

namespace Vendor\Module\Controller\Adminhtml;

use Magento\Framework\Exception\LocalizedException;

class Save extends \Magento\Backend\App\Action
{
    protected $dataPersistor;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\App\Request\DataPersistorInterface $dataPersistor
    ) {
        $this->dataPersistor = $dataPersistor;
        parent::__construct($context);
    }

    public function execute()
    {
        ...
        ...
        $data = $this->_filterFoodData($data);
        $model->setData($data);
        $model->save();
        ...
        ...     
    }

    public function _filterFoodData(array $rawData)
    {
        //Replace icon with fileuploader field name
        $data = $rawData;
        if (isset($data['icon'][0]['name'])) {
            $data['icon'] = $data['icon'][0]['name'];
        } else {
            $data['icon'] = null;
        }
        return $data;
    }
}

अपलोड की गई छवि को फॉर्म संपादित पृष्ठ पर दिखाने के लिए:

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / मॉडल / DataProvider.php

<?php

namespace Vendor\Module\Model;

use Magento\Store\Model\StoreManagerInterface;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    ...
    ...

    public function getData()
    {
        ...
        ...
        $items = $this->collection->getItems();

        //Replace icon with fileuploader field name
        foreach ($items as $model) {
            $this->loadedData[$model->getId()] = $model->getData();
            if ($model->getIcon()) {
                $m['icon'][0]['name'] = $model->getIcon();
                $m['icon'][0]['url'] = $this->getMediaUrl().$model->getIcon();
                $fullData = $this->loadedData;
                $this->loadedData[$model->getId()] = array_merge($fullData[$model->getId()], $m);
            }
        }
        ...
        ...

        return $this->loadedData;
    }

    public function getMediaUrl()
    {
        $mediaUrl = $this->storeManager->getStore()
            ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA).'faq/tmp/icon/';
        return $mediaUrl;
    }
}

इसके लिए आपको बहुत बहुत धन्यवाद, वास्तव में इसकी सराहना करते हैं। हालाँकि जब मैं आपके समाधान को लागू करता हूं और एक छवि अपलोड करता हूं, तो क्रोम के कंसोल में मेरी वापसी की प्रतिक्रिया है: {"त्रुटि": "$ _ FILES सरणी खाली है", "त्रुटि कोड": 0}। फ़ाइल अपलोड नहीं की गई है (मैंने chmod चेक किया है) और निश्चित रूप से पूर्वावलोकन दिखाई नहीं दे सकता है।
हॉलरन जूल

1
दरअसल मुझे आपके कोड की मदद से आखिरकार यह काम कर गया। इसलिए आपको बहुत बहुत धन्यवाद! आप मेरे हीरो हैं! :-)
हॉलरेलन

आपका स्वागत है :)
प्रिंस पटेल

@PrincePatel यह सिर्फ महान है, लेकिन मुझे लगता है कि मेरे पास एक संपादन फ़ॉर्म है, मैं डेटा प्रदाता से गेटडाटा से पढ़ी गई छवि-पूर्वावलोकन टेम्पलेट कैसे बना सकता हूं
येहिया ए.सैलम

1
@PrincePatel मैं Magento 2.3 में काम कर रहा हूं और di.xml से "ImageUploader" कॉल कर रहा हूं और उसी से baseTmpPath, basePath और allowExtensions params भेज रहा हूं। अब मेरा मॉडल "ImageUploader" एक त्रुटि "अपवाद # 0 (BadMethodCallException) फेंकता है: गुम आवश्यक तर्क $ baseTmpPath"। क्या आप कृपया मुझे "ImageUploader" मॉडल के कंस्ट्रक्टर फ़ंक्शन में सेट करने के बजाय di.xml से प्रबंधन करने में मदद कर सकते हैं?
धरा भट्टी

6

Magento 2.2 UI घटक के लिए अनुपूरक

Magento 2.1 के साथ तुलना करें, Magento 2.2 में , यूआई घटक में नीचे की तरह कुछ वैकल्पिक अंतर थे । हम Magento_Catalog/image-previewपूर्वावलोकन टेम्पल के रूप में आधिकारिक का उपयोग कर सकते हैं , और नियंत्रक जैसे बाकी कोड स्वीकृत उत्तर का उल्लेख कर सकते हैं ।

<field name="image" formElement="fileUploader">
    <settings>
        <notice translate="true">Allowed file types: jpg, jpeg, gif, png.</notice>
        <label translate="true">Image</label>
        <componentType>fileUploader</componentType>
    </settings>
    <formElements>
        <fileUploader>
            <settings>
                <allowedExtensions>jpg jpeg gif png</allowedExtensions>
                <maxFileSize>10240000</maxFileSize>
                <placeholderType>image</placeholderType>
                <previewTmpl>Magento_Catalog/image-preview</previewTmpl>
                <uploaderConfig>
                    <param xsi:type="string" name="url">path/to/controller</param>
                </uploaderConfig>
            </settings>
        </fileUploader>
    </formElements>
</field>

1
मुझे त्रुटि मिलती है TypeError: value.map is not a function। मैं इसे कैसे ठीक कर सकता हूं
नीर फंग

@NeroPhung हाय, कृपया इस समाधान का प्रयास करें magento.stackexchange.com/q/138642/44237
कुंजी शांग

मैंने उस पोस्ट को फॉलो करते हुए इस मुद्दे को खुद से किया है। सहायता का शुक्रिया!
नीरो फंग

@KeyShang, आपके कोड में, मैंने कैसे और कहाँ छवि अपोलोडर फ़ील्ड के लिए सत्यापन रखा
Jaisa

@ श्री मैं आपका प्रश्न देखता हूं, मैं आपके प्रश्न का उत्तर दूंगा magento.stackexchange.com/questions/211957/… , मुझे कुछ समय दें।
कुंजी शांग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.