Artikelbilder speichern

Hallo!

Auf dem Server werden alle Artikelbilder per FTP hochgeladen. Jetzt möchte ich diese Bilder, den entsprechenden Artikeln zuordnen. Dazu muss ich ja über den fileSaver das Medium persisten und dann über die product repository den Artikel akualisieren.

  public function createImages(){
    $images = glob(PluginSettings::DIR_IMAGES.'/'.$this->product['id'].'/*.{jpg,JPG,jpeg,JPEG,png,PNG,gif,GIF}', GLOB_BRACE);
    foreach($images as $sourcePath){

      $mediaId = UuidMore::randomHex();
      $fileExtension = pathinfo($sourcePath, PATHINFO_EXTENSION);
      $fileSize = filesize($sourcePath);
      $mimeType = mime_content_type($sourcePath);
      $fileName = basename($sourcePath, '.'.$fileExtension);

      $mediaFile = new MediaFile($sourcePath, $mimeType, $fileExtension, $fileSize);

      try {
        $this->fileSaver->persistFileToMedia(
          $mediaFile,
          $this->product['name'].$fileName,
          $mediaId,
          Context::createDefaultContext()
        );
      } catch (DuplicatedMediaFileNameException $e) {
        $this->fileSaver->persistFileToMedia($mediaFile, $fileName . mb_substr(Uuid::randomHex(), 0, 5), $mediaId, Context::createDefaultContext());
      }
    }

Leider bekomme ich beim persistFileToMedia immer diese Fehlermeldung. Was mache ich falsch?

nach jeder menge trial and error habe ich es jetzt so gelöst:

      // get fileinfos
      $fileExtension = pathinfo($sourcePath, PATHINFO_EXTENSION);
      $fileSize = filesize($sourcePath);
      $mimeType = mime_content_type($sourcePath);
      $fileName = basename($sourcePath, '.'.$fileExtension);

      // get blob
      $imagick = new \Imagick($sourcePath);
      $blob = $imagick->getImagesBlob();

      $uploadedFile = $this->fileFetcher->fetchBlob($blob, $fileExtension, $mimeType);

      $mediaId = $this->mediaService->saveFile(
        $blob,
        $fileExtension,
        $mimeType,
        $fileName,
        Context::createDefaultContext(),
        'product',
        false,
        false // not private!
      );

 

1 „Gefällt mir“

Hi Alex,

hatte ein ähnliches Vorhaben mit lokalen Files. Habe mir dafür einen eigenen Service gebastelt der dies wie folgt löst

/**
     * MediaHelper constructor.
     * @param MediaService $mediaService
     * @param FileFetcher $fileFetcher
     * @param FileSaver $fileSaver
     */
    public function __construct(MediaService $mediaService, FileFetcher $fileFetcher, FileSaver $fileSaver)
    {
        $this->mediaService = $mediaService;
        $this->fileFetcher = $fileFetcher;
        $this->fileSaver = $fileSaver;
    }

    /**
     * @param string $file
     * @param null|string $filename
     * @param string $folder
     * @param bool $private
     * @return string
     * @throws \Shopware\Core\Content\Media\Exception\DuplicatedMediaFileNameException
     * @throws \Shopware\Core\Content\Media\Exception\EmptyMediaFilenameException
     * @throws \Shopware\Core\Content\Media\Exception\IllegalFileNameException
     * @throws \Shopware\Core\Content\Media\Exception\MediaNotFoundException
     */
    public function saveMediaFromFile($file, $filename = null, $folder = '', $private = false): string
    {
        $fileInfo = $this->getFileInfo($file);
        $mediaFile = new MediaFile($file, $fileInfo['mimeType'], $fileInfo['extension'], $fileInfo['fileSize']);

        return $this->saveMedia($mediaFile, $filename ?? $fileInfo['filename'], $folder, $private);
    }

/**
     * @param MediaFile $mediaFile
     * @param string $filename
     * @param string $folder
     * @param bool $private
     * @return string
     * @throws \Shopware\Core\Content\Media\Exception\DuplicatedMediaFileNameException
     * @throws \Shopware\Core\Content\Media\Exception\EmptyMediaFilenameException
     * @throws \Shopware\Core\Content\Media\Exception\IllegalFileNameException
     * @throws \Shopware\Core\Content\Media\Exception\MediaNotFoundException
     */
    private function saveMedia(MediaFile $mediaFile, $filename, $folder, $private): string
    {
        $context = Context::createDefaultContext();
        $mediaId = $this->mediaService->createMediaInFolder($folder, $context, $private);
        $this->fileSaver->persistFileToMedia($mediaFile, $filename, $mediaId, $context);

        return $mediaId;
    }


    /**
     * @param $file
     * @return array
     */
    private function getFileInfo($file): array
    {
        $fileArray = explode('/', $file);
        $fileName = array_pop($fileArray);
        $fileNameArray = explode('.', $fileName);
        $extension = array_pop($fileNameArray);
        $fileName = implode('.', $fileNameArray);

        return [
            'extension' => $extension,
            'filename' => $fileName,
            'mimeType' => mime_content_type($file),
            'fileSize' => filesize($file)
        ];
    }

 

1 „Gefällt mir“

Hi Mowlwurf.

Ich muss diesen Post mal ein wenig hijacken.

Ich möchte meine Dateien gerne in einen bestimmten Ordner ablegen, aber die Dateien landen (wenn nicht gerade $folder = „products“) stets im Media-Root. Weder die Übergabe des Verzeichnisnamens noch die der Folder-ID bringen mich weiter, was mich zur Vermutung bringt, dass man bei Angabe eines custom Folders noch irgendetwas mehr veranstalten muss… korrekt?
Wie geht man da am Besten vor?

Hi Rob,

die Funktion findet leider nur Verzeichnisse welche als Standardspeicherort für bestimmte Objekte definiert wurden. Entweder über den Admin, oder direkt in der Datenbank, Tabelle media_default_folder. „Normale“ Verzeichnisse werden leider nicht durchsucht und entsprechend zugewiesen, daher landen die Bilder dann im Hauptverzeichnis.