Completed
Pull Request — master (#422)
by Jonas
05:22
created

ImageImport::importImagesForArticle()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 17
nc 6
nop 2
1
<?php
2
/**
3
 * (c) shopware AG <[email protected]>
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace ShopwarePlugins\Connect\Components;
9
10
use Shopware\Components\Model\ModelManager;
11
use Shopware\Models\Article\Article;
12
use Shopware\Models\Article\Detail;
13
use Shopware\Models\Article\Image;
14
use Shopware\Models\Media\Media;
15
use Shopware\Models\Attribute\Media as MediaAttribute;
16
use Shopware\Models\Attribute\ArticleImage as ImageAttribute;
17
use Symfony\Component\HttpFoundation\File\File;
18
use Shopware\Models\Article\Supplier;
19
use Shopware\Components\Thumbnail\Manager as ThumbnailManager;
20
21
class ImageImport
22
{
23
    /** @var \Shopware\Components\Model\ModelManager */
24
    protected $manager;
25
26
    /** @var Helper */
27
    protected $helper;
28
29
    /**
30
     * @var ThumbnailManager
31
     */
32
    protected $thumbnailManager;
33
34
    /** @var \ShopwarePlugins\Connect\Components\Logger */
35
    protected $logger;
36
37
    public function __construct(
38
        ModelManager $manager,
39
        Helper $helper,
40
        ThumbnailManager $thumbnailManager,
41
        Logger $logger
42
    ) {
43
        $this->manager = $manager;
44
        $this->helper = $helper;
45
        $this->thumbnailManager = $thumbnailManager;
46
        $this->logger = $logger;
47
    }
48
49
    /**
50
     * Helper to determine, if there is a main image for a given articleId
51
     *
52
     * @param $articleId
53
     * @return bool
54
     */
55
    public function hasArticleMainImage($articleId)
56
    {
57
        $builder = $this->manager->createQueryBuilder();
58
        $builder->select(['images'])
59
            ->from('Shopware\Models\Article\Image', 'images')
60
            ->where('images.articleId = :articleId')
61
            ->andWhere('images.parentId IS NULL')
62
            ->andWhere('images.main = :main')
63
            ->setParameter('main', 1)
64
            ->setParameter('articleId', $articleId)
65
            ->setFirstResult(0)
66
            ->setMaxResults(1);
67
68
        $result = $builder->getQuery()->getResult();
69
70
        return !empty($result);
71
    }
72
73
    /**
74
     * Get ids of products that needs an image import
75
     * @param null $limit
76
     * @return array        Ids of products needing an image import
77
     */
78
    public function getProductsNeedingImageImport($limit=null)
79
    {
80
        $updateFlags = $this->helper->getUpdateFlags();
81
        $updateFlagsByName = array_flip($updateFlags);
82
83
        $initialImportFlag = $updateFlagsByName['imageInitialImport'];
84
85
        $builder = $this->manager->createQueryBuilder();
86
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'at');
87
        $builder->innerJoin('at.articleDetail', 'detail');
88
        $builder->select('at.articleId');
89
        $builder->andWhere('at.shopId IS NOT NULL')
90
            ->andWHere('at.lastUpdateFlag IS NOT NULL')
91
            ->andWHere('BIT_AND(at.lastUpdateFlag, :initialImportFlag) > 0')
92
            ->setParameter('initialImportFlag', $initialImportFlag);
93
94
        if ($limit) {
95
            $builder->setMaxResults($limit);
96
        }
97
98
        $ids = $builder->getQuery()->getArrayResult();
99
100
        return array_map('array_pop', $ids);
101
    }
102
103
    /**
104
     * Batch import images for new products without images
105
     *
106
     * @param int|null $limit
107
     */
108
    public function import($limit = null)
109
    {
110
        $articleRepository = $this->manager->getRepository('Shopware\Models\Article\Article');
111
112
        $flags = $this->helper->getUpdateFlags();
113
        $flagsByName = array_flip($flags);
114
115
        $ids = $this->getProductsNeedingImageImport($limit);
0 ignored issues
show
Bug introduced by
It seems like $limit defined by parameter $limit on line 108 can also be of type integer; however, ShopwarePlugins\Connect\...ctsNeedingImageImport() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
116
117
        foreach ($ids as $id) {
118
            /** @var \Shopware\Models\Article\Article $article */
119
            $article = $articleRepository->find($id);
120
            $connectAttributes = $this->helper->getConnectAttributesByArticle($article);
121
122
            /** @var \Shopware\CustomModels\Connect\Attribute $connectAttribute */
123
            foreach ($connectAttributes as $connectAttribute) {
124
                $lastUpdate = json_decode($connectAttribute->getLastUpdate(), true);
125
                // update mainImage can be set to true because this just runs on initial import
126
                $this->importImagesForArticle(array_diff($lastUpdate['image'], $lastUpdate['variantImages']), $article);
127
                $this->importImagesForDetail($lastUpdate['variantImages'], $connectAttribute->getArticleDetail());
128
                $connectAttribute->flipLastUpdateFlag($flagsByName['imageInitialImport']);
129
            }
130
131
            $this->manager->flush();
132
        }
133
    }
134
135
    /**
136
     * Handles the image import of a product. This will:
137
     * - delete all images imported from connect before and not in the current import list
138
     * - create new images which have not already been imported
139
     * - set the main image, if there is no main image, yet
140
     *
141
     * Images are identified via the URL of the connect image. So we don't need to md5 the
142
     * actual image content every time.
143
     *
144
     * @param array $images
145
     * @param $article \Shopware\Models\Article\Article
146
     */
147
    public function importImagesForArticle($images, Article $article)
148
    {
149
        $localImagesFromConnect = $this->getImportedImages($article);
150
        $remoteImagesFromConnect = array_flip($images);
151
152
        // Build up arrays of images to delete and images to create
153
        $imagesToDelete = array_diff_key($localImagesFromConnect, $remoteImagesFromConnect);
154
        $imagesToCreate = array_diff_key($remoteImagesFromConnect, $localImagesFromConnect);
155
156
        // Delete old connect images and media objects
157
        foreach ($imagesToDelete as $hash => $data) {
158
            /** @var \Shopware\Models\Article\Image $image */
159
            $image = $data['image'];
160
            // if the image has mapping, it's variant image and shouldn't be deleted
161
            if (count($image->getMappings()) > 0) {
162
                continue;
163
            }
164
            $this->manager->remove($image);
165
            $this->manager->remove($data['media']);
166
        }
167
        $this->manager->flush();
168
169
        try {
170
            $this->importImages($imagesToCreate, $article);
171
        } catch (\Exception $e) {
172
            // log exception message if for some reason
173
            // image import fails
174
            $this->logger->write(true, 'Import images', $e->getMessage());
175
        }
176
177
        $this->manager->flush();
178
    }
179
180
    /**
181
     * Handles the image import of a product. This will:
182
     * - delete all images imported from connect before and not in the current import list
183
     * - create new images which have not already been imported
184
     * - set the main image, if there is no main image, yet
185
     *
186
     * Images are identified via the URL of the connect image. So we don't need to md5 the
187
     * actual image content every time.
188
     *
189
     * @param array $variantImages
190
     * @param $detail \Shopware\Models\Article\Detail
191
     */
192
    public function importImagesForDetail(array $variantImages, Detail $detail)
193
    {
194
        $article = $detail->getArticle();
195
        $articleImages = $article->getImages();
196
197
        $localImagesFromConnect = $this->getImportedImages($detail);
198
        $localArticleImagesFromConnect = $this->getImportedImages($article);
199
200
        $remoteImagesFromConnect = array_flip($variantImages);
201
202
        // Build up arrays of images to delete and images to create
203
        $imagesToDelete = array_diff_key($localImagesFromConnect, $remoteImagesFromConnect);
204
        $imagesToCreate = array_diff_key($remoteImagesFromConnect, $localImagesFromConnect);
205
206
        $mappingRepository = $this->manager->getRepository('Shopware\Models\Article\Image\Mapping');
207
        // Delete old connect images and media objects
208
        foreach ($imagesToDelete as $hash => $data) {
209
            /** @var \Shopware\Models\Article\Image $image */
210
            $image = $data['image'];
211
            /** @var \Shopware\Models\Article\Image $child */
212
            foreach ($image->getChildren() as $child) {
213
                if ($detail->getId() == $child->getArticleDetail()->getId()) {
214
                    $childAttribute = $child->getAttribute();
215
                    if (!$childAttribute) {
216
                        break;
217
                    }
218
219
                    $mapping = $mappingRepository->find($childAttribute->getConnectDetailMappingId());
220
                    if (!$mapping) {
221
                        break;
222
                    }
223
224
                    $this->manager->remove($mapping);
225
                    $this->manager->remove($child);
226
                    break;
227
                }
228
            }
229
230
            if (count($image->getChildren()) == 1) {
231
                $this->manager->remove($image);
232
                $this->manager->remove($data['media']);
233
            }
234
        }
235
        $this->manager->flush();
236
237
        try {
238
            $positions = [];
239
            foreach ($article->getImages() as $image) {
240
                $positions[] = $image->getPosition();
241
            }
242
            $maxPosition = count($positions) > 0 ? max($positions) : 0;
243
244
            /** @var \Shopware\Models\Media\Album $album */
245
            $album = $this->manager->find('Shopware\Models\Media\Album', -1);
246
            foreach ($imagesToCreate as $imageUrl => $key) {
247
                // check if image already exists in article images
248
                // 1) if it exists skip import and it's global image
249
                if (array_key_exists($imageUrl, $localArticleImagesFromConnect)
250
                    && empty($localArticleImagesFromConnect[$imageUrl]['image']->getMappings())) {
251
                    // if image doesn't have mappings
252
                    // it's global for all details
253
                    // do nothing, just continue
254
                    continue;
255
                }
256
257
                // 2) if it has mapping, add new one for current detail
258
                if (array_key_exists($imageUrl, $localArticleImagesFromConnect)) {
259
                    /** @var \Shopware\Models\Article\Image $articleImage */
260
                    $articleImage = $localArticleImagesFromConnect[$imageUrl]['image'];
261
                    $articleMedia = $localArticleImagesFromConnect[$imageUrl]['media'];
262
263
                    // add new mapping
264
                    $mapping = new Image\Mapping();
265
                    $mapping->setImage($articleImage);
266
                    foreach ($detail->getConfiguratorOptions() as $option) {
267
                        $rule = new Image\Rule();
268
                        $rule->setMapping($mapping);
269
                        $rule->setOption($option);
270
                        $mapping->getRules()->add($rule);
271
                    }
272
                    $this->manager->persist($mapping);
273
                    // mapping should have id, because it should be stored as child image attribute
274
                    $this->manager->flush($mapping);
275
                    $articleImage->getMappings()->add($mapping);
276
277
                    // add child image
278
                    $childImage = new Image();
279
                    $childImage->setMain(2);
280
                    $childImage->setPosition($maxPosition + $key + 1);
281
                    $childImage->setParent($articleImage);
282
                    $childImage->setArticleDetail($detail);
283
                    $childImage->setExtension($articleMedia->getExtension());
284
                    $childImageAttribute = $childImage->getAttribute() ?: new ImageAttribute();
285
                    $childImageAttribute->setArticleImage($childImage);
286
                    $childImageAttribute->setConnectDetailMappingId($mapping->getId());
287
288
                    $detail->getImages()->add($childImage);
289
                    $articleImage->getChildren()->add($childImage);
290
291
                    $this->manager->persist($childImage);
292
                    $this->manager->persist($childImageAttribute);
293
                    $this->manager->persist($articleImage);
294
295
                    continue;
296
                }
297
298
                // 3) if it doesn't exist, import it
299
                $importedImages = $this->importImages([$imageUrl => $key], $article, $maxPosition);
300
                $image = reset($importedImages);
301
                $media = $image->getMedia();
302
303
                // add new mapping
304
                $mapping = new Image\Mapping();
305
                $mapping->setImage($image);
306
                foreach ($detail->getConfiguratorOptions() as $option) {
307
                    $rule = new Image\Rule();
308
                    $rule->setMapping($mapping);
309
                    $rule->setOption($option);
310
                    $rules = $mapping->getRules();
311
                    $rules->add($rule);
312
                    $mapping->setRules($rules);
313
                    $this->manager->persist($rule);
314
                }
315
                $this->manager->persist($mapping);
316
                // mapping should have id, because it should be stored as child image attribute
317
                $this->manager->flush($mapping);
318
319
                $mappings = $image->getMappings();
320
                $mappings->add($mapping);
321
                $image->setMappings($mappings);
322
323
                // add child image
324
                $childImage = new Image();
325
                $childImage->setMain(2);
326
                $childImage->setPosition($maxPosition + $key + 1);
327
                $childImage->setParent($image);
328
                $childImage->setArticleDetail($detail);
329
                $childImage->setExtension($media->getExtension());
330
                $childImageAttribute = $childImage->getAttribute() ?: new ImageAttribute();
331
                $childImageAttribute->setArticleImage($childImage);
332
                $childImageAttribute->setConnectDetailMappingId($mapping->getId());
333
                $detail->getImages()->add($childImage);
334
335
                $image->getChildren()->add($childImage);
336
337
                $this->manager->persist($childImage);
338
                $this->manager->persist($childImageAttribute);
339
                $this->manager->persist($image);
340
341
                $this->thumbnailManager->createMediaThumbnail(
342
                    $media,
343
                    $this->getThumbnailSize($album),
344
                    true
345
                );
346
            }
347
        } catch (\Exception $e) {
348
            // log exception message if for some reason
349
            // image import fails
350
            $this->logger->write(true, 'Import images', $e->getMessage());
351
        }
352
353
        $article->setImages($articleImages);
354
        $this->manager->persist($article);
355
        $this->manager->flush();
356
    }
357
358
    /**
359
     * Helper: Read images for a given detail
360
     *
361
     * @param int $articleDetailId
362
     * @return array
363
     */
364
    public function getImagesForDetail($articleDetailId)
365
    {
366
        $builder = $this->manager->createQueryBuilder();
367
        $builder->select('media.path')
368
            ->from('Shopware\Models\Article\Image', 'images')
369
            ->join('images.media', 'media')
370
            ->where('images.articleDetailId = :articleDetailId')
371
            ->andWhere('images.parentId IS NULL')
372
            ->setParameter('articleDetailId', $articleDetailId)
373
            ->orderBy('images.main', 'ASC')
374
            ->addOrderBy('images.position', 'ASC');
375
376
        return array_map(function ($image) {
377
            return $image['path'];
378
        },
379
            $builder->getQuery()->getArrayResult()
380
        );
381
    }
382
383
    /**
384
     * Download, import and assign images to article
385
     *
386
     * @param array $imagesToCreate
387
     * @param Article|Detail $model
388
     * @param null|int $maxPosition
389
     * @throws \Doctrine\ORM\ORMException
390
     * @throws \Doctrine\ORM\OptimisticLockException
391
     * @throws \Doctrine\ORM\TransactionRequiredException
392
     * @throws \Exception
393
     * @return \Shopware\Models\Article\Image
394
     */
395
    private function importImages(array $imagesToCreate, $model, $maxPosition = null)
396
    {
397
        if (!$maxPosition) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $maxPosition of type null|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
398
            $positions = [];
399
            foreach ($model->getImages() as $image) {
400
                $positions[] = $image->getPosition();
401
            }
402
            $maxPosition = count($positions) > 0 ? max($positions) : 0;
403
        }
404
405
        if ($model instanceof Detail) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
406
            $article = $model->getArticle();
407
        } elseif ($model instanceof Article) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Article does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
408
            $article = $model;
409
        } else {
410
            throw new \RuntimeException('Model must be instance of Article or Detail!');
411
        }
412
413
        // If there is no main image set first image as main image
414
        $hasMainImage = $this->hasArticleMainImage($article->getId());
415
        $importedImages = [];
416
        /** @var \Shopware\Models\Media\Album $album */
417
        $album = $this->manager->find('Shopware\Models\Media\Album', -1);
418
        $tempDir = Shopware()->DocPath('media_temp');
419
        foreach ($imagesToCreate as $imageUrl => $key) {
420
            $tempFile = tempnam($tempDir, 'image');
421
            copy($imageUrl, $tempFile);
422
            $file = new File($tempFile);
423
424
            // Create the media object
425
            $media = new Media();
426
            $media->setAlbum($album);
427
            $media->setDescription('');
428
            $media->setCreated(new \DateTime());
429
            $media->setUserId(0);
430
            $media->setFile($file);
431
432
            $mediaAttribute = $media->getAttribute() ?: new MediaAttribute();
433
            $mediaAttribute->setConnectHash($imageUrl);
434
            $mediaAttribute->setMedia($media);
435
            $media->setAttribute($mediaAttribute);
436
            $this->manager->persist($media);
437
            $this->manager->persist($mediaAttribute);
438
439
            // Create the associated image object
440
            $image = new Image();
441
            $image->setMain((!$hasMainImage && $key == 0) ? 1 : 2);
442
            $image->setMedia($media);
443
            $image->setPosition($maxPosition + $key + 1);
444
            $image->setArticle($article);
445
            $image->setPath($media->getName());
446
            $image->setExtension($media->getExtension());
447
448
            $article->getImages()->add($image);
449
450
            $this->manager->persist($image);
451
452
            $this->thumbnailManager->createMediaThumbnail(
453
                $media,
454
                $this->getThumbnailSize($album),
455
                true
456
            );
457
458
            $importedImages[] = $image;
459
        }
460
461
        return $importedImages;
462
    }
463
464
    /**
465
     * Returns a list with already imported images from Connect
466
     * by given Article or Detail
467
     *
468
     * @param Article|Detail $model
469
     * @return array
470
     */
471
    private function getImportedImages($model)
472
    {
473
        if (!$model instanceof Article && !$model instanceof Detail) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Article does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
474
            throw new \RuntimeException('Model must be instance of Article or Detail!');
475
        }
476
477
        $localArticleImagesFromConnect = [];
478
479
        /** @var \Shopware\Models\Article\Image $image */
480
        foreach ($model->getImages() as $image) {
481
            if ($model instanceof Detail && $model->getId() == $image->getArticleDetail()->getId()) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
482
                $image = $image->getParent();
483
            }
484
            $media = $image->getMedia();
485
486
            try {
487
                if (!$media || !$media->getAttribute()) {
488
                    continue;
489
                }
490
                $attribute = $media->getAttribute();
491
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine\ORM\EntityNotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
492
                //is thrown if media was deleted -> simply continue
493
                continue;
494
            }
495
496
            // If the image was not imported from connect, skip it
497
            $connectHash = $attribute->getConnectHash();
498
            if (!$connectHash) {
499
                continue;
500
            }
501
            $localArticleImagesFromConnect[$connectHash] = ['image' => $image, 'media' => $media];
502
        }
503
504
        return $localArticleImagesFromConnect;
505
    }
506
507
    /**
508
     * @param $imageUrl
509
     * @param Supplier $supplier
510
     */
511
    public function importImageForSupplier($imageUrl, Supplier $supplier)
512
    {
513
        try {
514
            $album = $this->manager->find('Shopware\Models\Media\Album', -12);
515
            $tempDir = Shopware()->DocPath('media_temp');
516
517
            $tempFile = tempnam($tempDir, 'image');
518
            copy($imageUrl, $tempFile);
519
            $file = new File($tempFile);
520
521
            $media = new Media();
522
            $media->setAlbum($album);
523
            $media->setDescription('');
524
            $media->setCreated(new \DateTime());
525
            $media->setUserId(0);
526
            $media->setFile($file);
527
528
            $this->manager->persist($media);
529
530
            $this->thumbnailManager->createMediaThumbnail(
531
                $media,
532
                $this->getThumbnailSize($album),
533
                true
534
            );
535
536
            $supplier->setImage($media->getPath());
537
            $this->manager->persist($supplier);
538
539
            $this->manager->flush();
540
        } catch (\Exception $e) {
541
            $this->logger->write(
542
                true,
543
                'import image for supplier',
544
                $e->getMessage() . 'imageUrl:' . $imageUrl
545
            );
546
        }
547
    }
548
549
    /**
550
     * Returns thumbnails size by album
551
     * @param $album \Shopware\Models\Media\Album
552
     * @return array
553
     */
554
    protected function getThumbnailSize($album)
555
    {
556
        if (!$album->getId()) {
557
            return;
558
        }
559
560
        $thumbnailSizes = $album->getSettings()->getThumbnailSize();
561
        $sizesArray = [];
562
        $requiredSizeExists = false;
563
        foreach ($thumbnailSizes as $size) {
564
            if (strlen($size) == 0) {
565
                continue;
566
            }
567
568
            $sizes = explode('x', $size);
569
            if ($sizes[0] == 140 && $sizes[1] == 140) {
570
                $requiredSizeExists = true;
571
            }
572
            $sizesArray[] = $size;
573
        }
574
575
        if ($requiredSizeExists === false) {
576
            $sizesArray[] = '140x140';
577
        }
578
579
        return $sizesArray;
580
    }
581
582
    /**
583
     * @param $imageUrl string
584
     * @param $articleId int
585
     */
586
    public function importMainImage($imageUrl, $articleId)
587
    {
588
        $oldMainImageId = $this->manager->getConnection()->fetchColumn('SELECT id FROM s_articles_img WHERE articleID = ? AND main = 1 AND parent_id IS NULL',
589
            [$articleId]);
590
591
        $newMainImageId = $this->manager->getConnection()->fetchColumn('
592
            SELECT s_articles_img.id 
593
            FROM s_articles_img 
594
            INNER JOIN s_media ON s_articles_img.media_id = s_media.id
595
            INNER JOIN s_media_attributes ON s_media.id = s_media_attributes.mediaID
596
            WHERE s_articles_img.articleID = ? AND s_articles_img.parent_id IS NULL AND s_media_attributes.connect_hash = ?',
597
            [$articleId, $imageUrl]);
598
599
        if ($newMainImageId && $newMainImageId !== $oldMainImageId) {
600
            $this->manager->getConnection()->executeQuery('
601
            UPDATE s_articles_img SET main = ? WHERE id = ?',
602
            [0, $oldMainImageId]);
603
            $this->manager->getConnection()->executeQuery('
604
            UPDATE s_articles_img SET main = ? WHERE id = ?',
605
             [1, $newMainImageId]);
606
        }
607
    }
608
609
    /**
610
     * @param $imageUrl string
611
     * @param $articleId int
612
     * @return bool
613
     */
614
    public function hasMainImageChanged($imageUrl, $articleId)
615
    {
616
        $result = $this->manager->getConnection()->fetchColumn('
617
            SELECT s_articles_img.id 
618
            FROM s_articles_img 
619
            INNER JOIN s_media ON s_articles_img.media_id = s_media.id
620
            INNER JOIN s_media_attributes ON s_media.id = s_media_attributes.mediaID
621
            WHERE s_articles_img.articleID = ? AND s_articles_img.main = 1 AND s_articles_img.parent_id IS NULL AND s_media_attributes.connect_hash = ?',
622
            [$articleId, $imageUrl]);
623
624
        return !(bool) $result;
625
    }
626
}
627