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
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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.