eZ Platform Discussions

Upload and add an image to new content struct

I’m trying to make a script wish curl an external link and then upload the image to the local storage and finally attach the image to a new content.

I started by uploading the image, I don’t know whether there’s some existing service which do the job for me.
To manage a content we need to set the field Value to my content:
$contentCreateStruct->setField( 'image_field_identifier', ...); with an instance of \eZ\Publish\Core\FieldType\Image\Value.
Anyway, I created an image service to handle the upload and return our Image\Value instance ?

class ImageService
{
    protected $dfsDir;
    protected $ioUrlPrefix;

    public function __construct(
        $dfsDir, $ioUrlPrefix
    ) {
        $this->dfsDir = $dfsDir;
        $this->ioUrlPrefix = $ioUrlPrefix;
    }

    public function createImageValue(string $fileUrl)
    {
        $content = $this->getFileContentFromExternalUrl($fileUrl);
        if (false === $content) {
            throw new InvalidImportFieldException(
                'L\'url du fichier n\'existe pas : ' . $fileUrl
            );
        }

        $newFilename = \substr($fileUrl, \strrpos($fileUrl, '/'));
        $path = $this->ioUrlPrefix . '/images/' . \basename($newFilename);
        $basePath = $this->dfsDir . '/' . $path;
        if (false === @\file_put_contents($basePath, $content)) {
            throw new \RuntimeException('Unable to write file ' . $basePath);
        }
        \file_put_contents($basePath, $content);


        return new \eZ\Publish\Core\FieldType\Image\Value(
            [
                'path' => $path,
                'fileSize' => filesize($basePath),
                'fileName' => \basename($newFilename),
                'alternativeText' => \basename($newFilename),
            ]
        );

    }

    private function getFileContentFromExternalUrl($URL)
    {
        $ch = \curl_init();
        \curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        \curl_setopt($ch, CURLOPT_URL, $URL);
        $data = \curl_exec($ch);

        \curl_close($ch);

        return $data;
    }

AppBundle\Service\ImageService:
    lazy:  true
    arguments:
        $dfsDir:  '%dfs_nfs_path%'
        $ioUrlPrefix:  "$var_dir$/$storage_dir$"

The image is well uploaded under the "%dfs_nfs_path%$var_dir$/$storage_dir$" directory. But I don’t know how to handle image version and language. Because normally The final image path should look like this:

/var/www/html/project/dfsdata/var/site/storage/images/1/7/5/0/571-5-fre-FR/my_image.png
But I got this as a path:
/var/www/html/project/dfsdata/var/site/storage/images/my_image.png
My question: how to add the missing 1/7/5/0/571-5-fre-FR to my path:

This is my dfs storage configuration:

# define the flysystem handler
oneup_flysystem:
    adapters:
        nfs_adapter:
            local:
                directory: "/%dfs_nfs_path%/$var_dir$/$storage_dir$"

# define the ez handlers
ez_io:
    binarydata_handlers:
        nfs:
            flysystem:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: doctrine.dbal.dfs_connection

# set the application handlers
ezpublish:
    system:
        default:
            io:
                metadata_handler: dfs
                binarydata_handler: nfs

This is my parameters.yml

    env(DFS_NFS_PATH): /var/www/html/project/dfsdata
    dfs_nfs_path: env(DFS_NFS_PATH)

Hi,
I think you are missing this part to create new content version, right?

I didn’t miss that part, as you see i already prepared my contentCreateStruct but i didn’t post the hole code. You can take a look to the doc https://doc.ezplatform.com/en/latest/api/public_php_api_creating_content/#creating-an-image
The problem that my image is external.

You should not have to worry about this. When creating the content you do not have to place the image in the correct storage path. eZ will take whatever you pass to path and copy it into the correct storage location when the content is saved. Once saved you can remove/delete your image you grabbed by curl.

After that the ez_image_alias will return the correct image path for the translation/variation.