0

I want to upload images using graphql using file not base64, can anyone tell me how can I implement this?

Thanks in advance!!

1

3 Answers 3

0

First convert your image into base64 then use that base64 string in to graphql input.

<?php

namespace Vendor\Module\Model\Upload;

use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Driver\File;

class UploadImage implements ResolverInterface
{
    public function __construct(
        Filesystem $fileSystem,
        File $fileDriver
    ) {
        $this->fileSystem = $fileSystem;
        $this->fileDriver = $fileDriver;
    }
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        $this->uploadFile($fileData);
    }

    public function uploadFile($fileData)
    {
        $uploadedFileName = "";
        $fileName = '';
        if (isset($fileData['name'])) {
            $fileName = $fileData['name'];
        } else {
            $fileName = rand() . time();
        }
        if (isset($fileData['filecontent'])) {
            $mediaPath = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath();
            $originalPath = 'ModuleName/Attachments/';
            $mediaFullPath = $mediaPath . $originalPath;
            if (!file_exists($mediaFullPath)) {
                mkdir($mediaFullPath, 0775, true);
            }
            /* Check File is exist or not */
            $fullFilepath = $mediaFullPath . $fileName;
            if ($this->fileDriver->isExists($fullFilepath)) {
                $fileName = rand() . time() . $fileName;
            }
            $fileContent = base64_decode($fileData['filecontent']);
            $savedFile = fopen($mediaFullPath . $fileName, "wb");
            fwrite($savedFile, $fileContent);
            fclose($savedFile);
            $uploadedFileName = "/" . $fileName ;
        }
        return $uploadedFileName;
    }
}

And the VAR is :

$fileData is array 
$fileData['filecontent'] = base64 string of file.
$fileData['name'] = file name.
4
  • I want upload image using file upload not base64. Commented Jul 5, 2022 at 7:01
  • Can you please check this link github.com/huykon/magento-graphql-uploader Commented Jul 5, 2022 at 7:05
  • I have already tried. In this use base64. I need to implement using file upload. Commented Jul 5, 2022 at 7:10
  • you must send with base 64 and convert it on upload/save process. Commented Jul 5, 2022 at 7:15
0

Using base64 is the best solution.

Other solution: You can also get file data using file_get_contents() PHP function. And store in new file using file_put_contents() PHP function. This function creates an issue when data is large. When we use in graphql query then it returns only file data as a response.

Reference link :

https://www.w3schools.com/php/func_filesystem_file_get_contents.asp

https://www.w3schools.com/php/func_filesystem_file_put_contents.asp

https://www.php.net/manual/en/function.file-put-contents.php

https://www.faqcode4u.com/faq/411274/php-image-file-upload-and-convert-to-base64-without-saving-image

I suggest going with base64 implementation

0

Step 1: Create the directory structure for your module: app/code/XTeam/ImageUpload

Step 2: Create the file app/code/XTeam/ImageUpload/etc/schema.graphqls with the following content:

type Mutation {
    xtUploadFiles(input: [ImageUploads!]): XTUploadOutput @resolver(class: "XTeam\\ImageUpload\\Model\\Resolver\\ImgUploadFiles") @doc(description:"Upload files to the pub/media static folder")
}

input ImageUploads {
    image_url: String @doc(description: "Base64 encoded image string")
    store_id: String @doc(description: "Store ID associated with the slider")
    status: String @doc(description: "Status of the slider")
}

type XTUploadOutput {
    items: [XTUploadedReturn]
}

type XTUploadedReturn {
    order_path: String @doc(description: "File Order path")
    message: String @doc(description: "Upload message")
}

Step 3: Create the file app/code/XTeam/ImageUpload/Model/Resolver/ImgUploadFiles.php with the following content:

<?php
declare(strict_types=1);

namespace XTeam\ImageUpload\Model\Resolver;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Filesystem;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use XTeam\Slider\Model\DataexampleFactory;

class ImgUploadFiles implements ResolverInterface
{
    private $_storeManager;
    private $fileSystem;
    private $dataExampleFactory;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        Filesystem $fileSystem,
        DataexampleFactory $dataExampleFactory
    ) {
        $this->_storeManager = $storeManager;
        $this->fileSystem = $fileSystem;
        $this->dataExampleFactory = $dataExampleFactory;
    }

    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        if (empty($args['input']) || !is_array($args['input'])) {
            throw new GraphQlInputException(__('You must specify your input.'));
        }

        try {
            $mediaUrl = $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
            $mediaPath = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath();
            $uploadPath = 'xteam/uploads/';
            $mediaFullPath = $mediaPath . $uploadPath;

            if (!file_exists($mediaFullPath)) {
                mkdir($mediaFullPath, 0775, true);
            }

            $response = ['items' => []];
            foreach ($args['input'] as $input) {
                $base64Data = explode(',', $input['image_url']);
                $fileContent = base64_decode(end($base64Data));

                if ($fileContent === false) {
                    throw new GraphQlInputException(__('Invalid base64 encoded image.'));
                }

                $fileName = uniqid() . '.jpg';
                $filePath = $mediaFullPath . $fileName;
                file_put_contents($filePath, $fileContent);

                $dataModel = $this->dataExampleFactory->create();
                $dataModel->setData([
                    'image_url' => $mediaUrl . $uploadPath . $fileName,
                    'store_id' => $input['store_id'],
                    'status' => $input['status']
                ])->save();

                $response['items'][] = [
                    'order_path' => $uploadPath . $fileName,
                    'message' => 'Image uploaded successfully.'
                ];
            }

            return $response;
        } catch (InputException $e) {
            throw new GraphQlInputException(__($e->getMessage()));
        }
    }
}

Step 4: Use the following GraphQL mutation:

mutation {
  xtUploadFiles(
    input: [
      {
        image_url: "data:image/jpeg;base64,[BASE64_ENCODED_IMAGE]",
        store_id: "1",
        status: "true"
      }
    ]
  ) {
    items {
      order_path
      message
    }
  }
}

Gives output like this:

{
  "data": {
    "xtUploadFiles": {
      "items": [
        {
          "order_path": "xteam/uploads/unique_file_name.jpg",
          "message": "Image uploaded successfully."
        }
      ]
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.