Menu Close
    Searching for an experienced eCommerce & Marketplace Development Company ?

    How to upload an image at a storefront in Shopware 6

    In this blog, you are going to learn “How to upload an image in Shopware 6 at the storefront.”
    I hope you know the directory structure of Shopware 6 plugin, if you don’t know, see here- https://docs.shopware.com/en/shopware-platform-dev-en/internals/directory-structure.

    Firstly, you have to create an form in html.twig file. In my case, file name is test.html.twig .

    test.html.twig

    {% block test_from %}
     <form 
     action="{{ path('frontend.test.upload') }}"
     method="post"
     data-form-csrf-handler="true"
     data-form-validation="true">
        {% block test_upload_form_csrf %}
           {{ sw_csrf('frontend.test.upload') }}
        {% endblock %}
        <input type="file" id="upload-file" name="upload_file"  />
        <button type="submit" class="btn btn-primary">
          upload                     
        </button>
     </form>
    {% endblock %}

    In the above code, {{ path('frontend.test.upload') }} is a route name of the function in the controller, it sends the request to that function, data-form-csrf-handler="true" is a handler of csrf token. If it set to true then it is able to handle the csrf token.

    {{ sw_csrf('frontend.test.upload') }} is a csrf token function which generates a token for the form. Parameters of the csrf function should be the same as the route name of the controller

    Now, lets create the controller for uploading an image.

    TestController.php

    <?php declare(strict_types=1);
    
    use Shopware\Storefront\Controller\StorefrontController;
    use Shopware\Core\Framework\Context;
    use Shopware\Core\Framework\Routing\Annotation\RouteScope;
    use Shopware\Core\Framework\Uuid\Uuid;
    use Shopware\Core\Content\Media\File\FileSaver;
    use Shopware\Core\Content\Media\File\MediaFile;
    use Shopware\Core\Content\Media\File\FileNameProvider;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    use Shopware\Core\Framework\Util\Random;
    
    /**
     * @RouteScope(scopes={"storefront"})
     */
    class TestController extends StorefrontController 
    {
       private $mediaUpdater;
       private $fileNameProvider;
       private $systemConfigService;
    
       public function __construct(
           FileSaver $mediaUpdater,
           FileNameProvider $fileNameProvider      
        ) {
           $this->mediaUpdater = $mediaUpdater;
           $this->fileNameProvider = $fileNameProvider;     
        }
        
         /**
         * @Route("/upload/image", name="frontend.test.upload", defaults={"csrf_protected"=false})
         */
        public function uploadMedia(Request $request)
        {
            $data = $request->files;
            $testSupportedExtension = array('gif', 'png', 'jpg', 'jpeg', 'pdf');
            
            $context = Context::createDefaultContext();
            $mediaRepository = $this->container->get('media.repository');
            
            foreach ($data as $file) {
                $fileName = $file->getClientOriginalName();
                $ext = pathinfo($fileName, PATHINFO_EXTENSION);
                if (!in_array($ext,$testSupportedExtension) ) {
                    $error = true;
                    $message = 'Invalid Extension';
                } else {
                    $fileName = $fileName . Random::getInteger(100, 1000);
                    
                    $mediaId = Uuid::randomHex();
                    $media = [
                        [
                            'id' => $mediaId,
                            'name' => $fileName,
                            'fileName' => $fileName,
                            'mimeType' => $file->getClientMimeType(),
                            'fileExtension' => $file->guessExtension(),
                         ]
                     ];
                        
                    $mediaId = $mediaRepository->create($media, Context::createDefaultContext())- 
                    >getEvents()->getElements()[1]->getIds()[0];
                    if (is_array($mediaId)) {
                        $mediaId = $mediaId['mediaId'];
                    }
                    try {
                        $this->upload($file, $fileName, $mediaId, $context);                
                    } catch (\Exception $exception) {
                        $fileName = $fileName . Random::getInteger(100, 1000);
                        $this->upload($file, $fileName, $mediaId, $context);
                    }
                }
            }
        } 
    
        public function upload($file, $fileName, $mediaId, $context)
        {   
            return $this->mediaUpdater->persistFileToMedia(
                new MediaFile(
                    $file->getRealPath(),
                    $file->getMimeType(),
                    $file->guessExtension(),
                    $file->getSize()
                ),
                $this->fileNameProvider->provide(
                    $fileName,
                    $file->getExtension(),
                    $mediaId,
                    $context
                ),
                $mediaId,
                $context
            );  
        }
    }

    To upload an image, you need to import some files are FileSaver, MediaFile, FileNameProvider which helps to upload an image in Shopware 6. These files are also included in the service file.
    In the above code, you can add your own validation for the image. You have to use a media Repository for saving media data to the media table.

    Uuid::randomHex() it generates a unique id for the media table. id , fileName, name, mimeType, fileExtension these are important fields for the media Repository. Now you have to save the mediaId. You can use this mediaId to get detail of an image, you also find the URL of an image.

    I hope it will help you. Thanks for reading. Happy Coding 🙂
    Thank You.

    . . .
    Discuss on Helpdesk

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top