Bilder Import und Zuordnung zum Artikel über Cronjob

Hallo,

ich versuche über einen Shopware Cronjob Bilder zu Artikeln hinzuzufügen (die Bilder kommen von einem externen Service).

Der erste Teil der Aufgabe funktioniert: das Bild wird in den Medienmanager von Shopware eingestellt:
 

/** @var \Shopware\Components\Api\Resource\Media $mediaResource */
$mediaResource = $media->create( [
    'album' => 2,
    'file' => 'https://mein.dienstleister.de/bild.jpg',
    'description' => 'Meine Bildbeschreibung'
]);

Nun scheitere ich am Zuordnen des neuen Bildes zum Artikel. Ich habe die Funktion createNewArticleImage gefunden, aber irgendwie haut das nicht hin :frowning:

$articleManager = \Shopware\Components\Api\Manager::getResource('Article');
/** @var \Shopware\Components\Api\Resource\Article $articleResource */
$articleResource = $articleManager->getOne($articleID);
$articleManager->createNewArticleImage($articleResource,$mediaResource);

 

Wenn ich den Cronjob nun mit

php bin/console sw:cron:run Shopware_CronJob_MyupdateCronJobUpdate 

aufrufe bekomme ich 

Processing MyUpdate Update
Status: 500 Internal Server Error
X-Powered-By: PHP/7.2.19
Content-type: text/html; charset=UTF-8

Was läuft hier schief? Es würde ja schon sehr helfen, wenn ich mehr Infos zu dem 500er bekäme!

Hat jemand ein funktionierendes Beispiel, wie man ein über den Cronjob hochgeladenes Bild einem Artikel zuordnen kann und/oder weiß wie man mehr Informationen zu dem 500er erhalten kann? 

Vielen Dank schon einmal!

Christian

weiß wie man mehr Informationen zu dem 500er

In der Regel werden 500er Fehler im PHP-Log des Servers geschrieben. Hierzu kann keiner antworten, weil es alles mögliche sein kann. Da musst du leider selber aktiv werden:

Vielen Dank für deine Antwort - ich bin zwar ein Stück weitergekommen - aber letztendlich scheitere ich immer noch an der Zuordnung des neuen Bildes zum Artikel.

Mit Hilfe des Providers konnte ich mir den Fehler ausgeben lassen und das Problem lag daran, das 

getOne()

standardmäßig ein Array zurückliefert, ich aber ein Object benötigt habe.

Mein Code sieht jetzt wie folgt aus und läuft soweit fehlerfrei durch - neu ist die 2 Zeile, damit $articleResource ein Objekt ist:
 

$articleManager = \Shopware\Components\Api\Manager::getResource('Article');
$articleManager->setResultMode(\Shopware\Components\Api\Resource\Resource::HYDRATE_OBJECT);

/** @var \Shopware\Models\Article\Article $articleResource */
$articleResource = $articleManager->getOne($article['articleID']);


/** @var \Shopware\Components\Api\Resource\Media $mediaResource */
$mediaResource = $media->create( [
    'album' => 2,
    'file' => 'h t t p s : / / mein.dienstleister.de/bild.jpg',
    'description' => 'Meine Bildbeschreibung'
]);

$imageResource = $articleManager->createNewArticleImage($articleResource,$mediaResource);

Er legt das Bild dann einwandfrei im Album ab. Aber anscheinend funktioniert die Methode createNewArticleImage so nicht!?
Fehlermeldung erhalte ich keine, das Skript terminiert sauber. Muss ich hier etwas manuell persistieren?

Ist es so ungewöhnlich Bilder zu den Artikeln per Cron hochzuladen/zu aktualisieren? Ich finde nirgends eine Beispiel für die interne API. Wäre es besser auf die REST API zurückzugreifen?

Freue mich über Ideen, Anregungen, Beispiele, … was auch immer ihr habt :wink:

 

Hallo,

der Bilder-Import und die Zuordnung zum Artikel funktioniert bei mir mit der Shopware API. Die Zuordnung und der Import der Bilder erfolgt direkt mit der API-Artikel und nicht über die API-Media.

https://forum.shopware.com/discussion/42915/article-mit-bild-ueber-api-anlegen

 

Hallo @sacrofano‍!

Vielen Dank. Aber welche API Methode verwendest du?
Habe gerade nochmal durch engine/Shopware/Components/Api/Resource/Article.php geschaut. Für mich sinnig wäre eben 

 createNewArticleImage

diese erwartet aber ein Media Objekt:

 /\*\* \* Helper function which creates a new article image with the passed media object. \* \* @param ArticleModel $article \* @param MediaModel $media \* \* @return Image \*/ public function createNewArticleImage(ArticleModel $article, MediaModel $media)

https://developers.shopware.com/developers-guide/rest-api/examples/article/

Die put Methode bei bereits angelegten Artikeln und dann so, wie im oben von mir verlinkten Beitrag. Hier die wichtigsten Fragmente des JSON:

{
 "mainDetail": {
      "number": "abcd-000001"
        },
   "images": [
    {
      "link": "hxxp://localhost:8100/media/image/56/4f/8c/2Z57JM7.jpg"
    }]
}

 

Die Lösung aus dem Beitrag zeigt auch, wie man ein bereits importiertes Bild (MediaID vorhanden) mit einem Artikel verknüpft. Das sieht dann halt ein wenig anders aus.

Danke aber das ist ja dann doch die REST API - ich wollte es ja mittels der lokalen API lösen.

Ob das jetzt effektiver ist als die REST API weiß ich auch nicht :wink:

Falle es jemanden interessiert, hier meine Lösung :
 

                $filename = basename($oXML->BILD_B);
                $path_parts = pathinfo($filename);
                $articleManager = \Shopware\Components\Api\Manager::getResource('Article');
                $articleManager->setResultMode(\Shopware\Components\Api\Resource\Resource::HYDRATE_OBJECT);

                /** @var \Shopware\Models\Article\Article $articleResource */
                $articleResource = $articleManager->getOne($article['articleID']);

                $newFileName = $this->slugify($articleResource->getSupplier()->getName() . ' ' . $articleResource->getName()).'.'.$path_parts['extension'];

                $sql = 'SELECT id FROM s_media WHERE path = "media/image/'.$newFileName.'"';
                $mediaid = Shopware()->Db()->fetchOne($sql);



                if ($mediaid > 1) {
                    $mediares = \Shopware\Components\Api\Manager::getResource('Media');
                    $mediares->update($mediaid, [
                        'file' => 'h t t p s : / / drittanbieter.tld'.$oXML->BILD_B
                    ]);


                } else {

                    /** @var \Shopware\Models\Media\Album $album */
                    $album = Shopware()->Models()->find('Shopware\Models\Media\Album', 2);

                    //create a new model and set the properties
                    $media = new \Shopware\Models\Media\Media();
                    $media->setAlbum($album);
                    $media->setDescription('');
                    $media->setCreated(new DateTime());
                    $media->setUserId(0);
                    $path = Shopware()->DocPath() . 'tmp';
                    if (!file_exists($path)) {
                        mkdir($path);
                    }
                    file_put_contents($path.'/'.$newFileName, file_get_contents('h t t p s : / / drittanbieter.tld'.$oXML->BILD_B));
                    $fileObject = new \Symfony\Component\HttpFoundation\File\File($path.'/'.$newFileName);
                    $media->setFile($fileObject);

                    Shopware()->Models()->persist($media);
                    Shopware()->Models()->flush();

                    $builder = Shopware()->Models()->createQueryBuilder();
                    $data = $builder->select(array('media'))
                        ->from('Shopware\Models\Media\Media', 'media')
                        ->where('media.id = ?1')
                        ->setParameter(1, $media->getId())->getQuery()->getArrayResult();

                    if ($media->getType() === \Shopware\Models\Media\Media::TYPE_IMAGE) {
                        $manager = Shopware()->Container()->get('thumbnail_manager');
                        $manager->createMediaThumbnail($media, array(), true);
                    }
                    unlink($path.'/'.$newFileName);



                    $repository = Shopware()->Models()->getRepository('Shopware\Models\Article\Detail');

                    /** @var Detail $articleDetail */
                    $articleDetail = $repository->findOneBy(['articleId' => $article['articleID']]);

                    if ($articleDetail) {


                         $articleobj = $articleDetail->getArticle();

                        /** @var \Shopware\Models\Article\Image $articleImage */
                        $articleImage = new \Shopware\Models\Article\Image();

                        $articleImage->setArticle($articleobj);
                        $articleImage->setPath($media->getName());
                        $articleImage->setExtension($media->getExtension());


                        $detailImage = new \Shopware\Models\Article\Image();
                        $detailImage->setArticleDetail($articleDetail);
                        $detailImage->setParent($articleImage);
                        $detailImage->setPosition(0);
                        $articleImage->setMain(2);
                        $articleImage->setDescription($articleobj->getSupplier()->getName() . ' ' . $articleobj->getName() . ' ' . $articleDetail->getNumber() );

                        $oldImages = $articleobj->getImages();
                        foreach ($oldImages as $tmp) {
                            $tmp->setMain(2);
                        }

                        $articleImage->setMain(1);
                        $articleImage->setPosition(0);


                        $articleImage->setMedia($media);
                        $media->setAlbum($album);


                        Shopware()->Models()->persist($articleImage);

                        Shopware()->Models()->flush();

                        $articleImages = $articleobj->getImages();

                        $articleImages->add($articleImage);
                        $articleobj->setImages($articleImages);


                        Shopware()->Models()->persist($articleobj);
                        Shopware()->Models()->persist($media);
                        Shopware()->Models()->flush();
                    }

                    
                }

 

Ich hole mir vorher alle Artikel und laufe dann Artikel für Artikel durch. Anhand der EAN des Artikels hole ich mir vom Drittanbieter das Bild (ich bekomme die URL über ein XML:

 $oXML-\>BILD\_B

 

Vielleicht hilft es jemanden weiter. Keine Ahnung ob das so der “geschickteste” Weg ist - aber nach ersten Test scheint es so zuverlässig zu funktionieren. Ist das Bild noch nicht da wird es in Shopware “eingefügt” und dem Artikel als erstes Bild zugeordnet. Ist das Bild schon in Shopware wird es lediglich ersetzt…