Completed
Push — master ( 59386c...dd9198 )
by Sven
17s queued 12s
created

ImageImport::getDetailIdsNeedingImageImport()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 1
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
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\CustomModels\Connect\Attribute;
12
use Shopware\Models\Article\Article;
13
use Shopware\Models\Article\Detail;
14
use Shopware\Models\Article\Image;
15
use Shopware\Models\Media\Media;
16
use Shopware\Models\Attribute\Media as MediaAttribute;
17
use Shopware\Models\Attribute\ArticleImage as ImageAttribute;
18
use Symfony\Component\HttpFoundation\File\File;
19
use Shopware\Models\Article\Supplier;
20
use Shopware\Components\Thumbnail\Manager as ThumbnailManager;
21
22
class ImageImport
23
{
24
    /** @var \Shopware\Components\Model\ModelManager */
25
    protected $manager;
26
27
    /** @var Helper */
28
    protected $helper;
29
30
    /**
31
     * @var ThumbnailManager
32
     */
33
    protected $thumbnailManager;
34
35
    /** @var \ShopwarePlugins\Connect\Components\Logger */
36
    protected $logger;
37
38
    public function __construct(
39
        ModelManager $manager,
40
        Helper $helper,
41
        ThumbnailManager $thumbnailManager,
42
        Logger $logger
43
    ) {
44
        $this->manager = $manager;
45
        $this->helper = $helper;
46
        $this->thumbnailManager = $thumbnailManager;
47
        $this->logger = $logger;
48
    }
49
50
    /**
51
     * Helper to determine, if there is a main image for a given articleId
52
     *
53
     * @param $articleId
54
     * @return bool
55
     */
56
    public function hasArticleMainImage($articleId)
57
    {
58
        $builder = $this->manager->createQueryBuilder();
59
        $builder->select(['images'])
60
            ->from('Shopware\Models\Article\Image', 'images')
61
            ->where('images.articleId = :articleId')
62
            ->andWhere('images.parentId IS NULL')
63
            ->andWhere('images.main = :main')
64
            ->setParameter('main', 1)
65
            ->setParameter('articleId', $articleId)
66
            ->setFirstResult(0)
67
            ->setMaxResults(1);
68
69
        $result = $builder->getQuery()->getResult();
70
71
        return !empty($result);
72
    }
73
74
    /**
75
     * Get ids of details that needs an image import
76
     * @param null $limit
77
     * @return array        Ids of products needing an image import
78
     */
79
    public function getDetailIdsNeedingImageImport($limit=null)
80
    {
81
        $updateFlags = $this->helper->getUpdateFlags();
82
        $updateFlagsByName = array_flip($updateFlags);
83
84
        $initialImportFlag = $updateFlagsByName['imageInitialImport'];
85
86
        $builder = $this->manager->createQueryBuilder();
87
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'at');
88
        $builder->select('at.articleDetailId');
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
        $detailRepository = $this->manager->getRepository('Shopware\Models\Article\Detail');
111
112
        $flags = $this->helper->getUpdateFlags();
113
        $flagsByName = array_flip($flags);
114
115
        $ids = $this->getDetailIdsNeedingImageImport($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\...IdsNeedingImageImport() 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\Detail $detail */
119
            $detail = $detailRepository->find($id);
120
            $connectAttribute = $this->helper->getConnectAttributeByModel($detail);
121
122
            $this->manager->getConnection()->beginTransaction();
123
            try {
124
                $lastUpdate = json_decode($connectAttribute->getLastUpdate(), true);
125
                $this->importArticleImagesWhenMainDetail($detail, $lastUpdate);
126
                $this->importImagesForDetail($lastUpdate['variantImages'], $detail);
127
                $connectAttribute->flipLastUpdateFlag($flagsByName['imageInitialImport']);
128
                $this->manager->flush();
129
                $this->manager->getConnection()->commit();
130
            } catch (\PDOException $e) {
131
                // possible lock with ImageImport from ToShop channel
132
                // is thrown before flipping of last update flag
133
                // so we should process the detail again in next cron run
134
                $this->manager->getConnection()->rollback();
135
            }
136
        }
137
    }
138
139
    /**
140
     * Handles the image import of a product. This will:
141
     * - delete all images imported from connect before and not in the current import list
142
     * - create new images which have not already been imported
143
     * - set the main image, if there is no main image, yet
144
     *
145
     * Images are identified via the URL of the connect image. So we don't need to md5 the
146
     * actual image content every time.
147
     *
148
     * @param array $images
149
     * @param $article \Shopware\Models\Article\Article
150
     */
151
    public function importImagesForArticle($images, Article $article)
152
    {
153
        $localImagesFromConnect = $this->getImportedImages($article);
154
        $remoteImagesFromConnect = array_flip($images);
155
156
        // Build up arrays of images to delete and images to create
157
        $imagesToDelete = array_diff_key($localImagesFromConnect, $remoteImagesFromConnect);
158
        $imagesToCreate = array_diff_key($remoteImagesFromConnect, $localImagesFromConnect);
159
160
        // Delete old connect images and media objects
161
        foreach ($imagesToDelete as $hash => $data) {
162
            /** @var \Shopware\Models\Article\Image $image */
163
            $image = $data['image'];
164
            // if the image has mapping, it's variant image and shouldn't be deleted
165
            if (count($image->getMappings()) > 0) {
166
                continue;
167
            }
168
            $this->manager->remove($data['media']);
169
            $this->manager->remove($image);
170
        }
171
        $this->manager->flush();
172
173
        try {
174
            $this->importImages($imagesToCreate, $article);
175
        } catch (\Exception $e) {
176
            // log exception message if for some reason
177
            // image import fails
178
            $this->logger->write(true, 'Import images', $e->getMessage());
179
        }
180
181
        $this->manager->flush();
182
    }
183
184
    /**
185
     * Handles the image import of a product. This will:
186
     * - delete all images imported from connect before and not in the current import list
187
     * - create new images which have not already been imported
188
     * - set the main image, if there is no main image, yet
189
     *
190
     * Images are identified via the URL of the connect image. So we don't need to md5 the
191
     * actual image content every time.
192
     *
193
     * @param array $variantImages
194
     * @param $detail \Shopware\Models\Article\Detail
195
     */
196
    public function importImagesForDetail(array $variantImages, Detail $detail)
197
    {
198
        $article = $detail->getArticle();
199
        $articleImages = $article->getImages();
200
201
        $localImagesFromConnect = $this->getImportedImages($detail);
202
        $localArticleImagesFromConnect = $this->getImportedImages($article);
203
204
        $remoteImagesFromConnect = array_flip($variantImages);
205
206
        // Build up arrays of images to delete and images to create
207
        $imagesToDelete = array_diff_key($localImagesFromConnect, $remoteImagesFromConnect);
208
        $imagesToCreate = array_diff_key($remoteImagesFromConnect, $localImagesFromConnect);
209
210
        $mappingRepository = $this->manager->getRepository('Shopware\Models\Article\Image\Mapping');
211
        // Delete old connect images and media objects
212
        foreach ($imagesToDelete as $hash => $data) {
213
            /** @var \Shopware\Models\Article\Image $image */
214
            $image = $data['image'];
215
            /** @var \Shopware\Models\Article\Image $child */
216
            foreach ($image->getChildren() as $child) {
217
                if ($detail->getId() == $child->getArticleDetail()->getId()) {
218
                    $childAttribute = $child->getAttribute();
219
                    if (!$childAttribute) {
220
                        break;
221
                    }
222
223
                    $mapping = $mappingRepository->find($childAttribute->getConnectDetailMappingId());
224
                    if (!$mapping) {
225
                        break;
226
                    }
227
228
                    $this->manager->remove($mapping);
229
                    $this->manager->remove($child);
230
                    break;
231
                }
232
            }
233
234
            if (count($image->getChildren()) == 1) {
235
                $this->manager->remove($image);
236
                $this->manager->remove($data['media']);
237
            }
238
        }
239
        $this->manager->flush();
240
241
        try {
242
            $positions = [];
243
            foreach ($article->getImages() as $image) {
244
                $positions[] = $image->getPosition();
245
            }
246
            $maxPosition = count($positions) > 0 ? max($positions) : 0;
247
248
            /** @var \Shopware\Models\Media\Album $album */
249
            $album = $this->manager->find('Shopware\Models\Media\Album', -1);
250
            foreach ($imagesToCreate as $imageUrl => $key) {
251
                // check if image already exists in article images
252
                // 1) if it exists skip import and it's global image
253
                if (array_key_exists($imageUrl, $localArticleImagesFromConnect)
254
                    && empty($localArticleImagesFromConnect[$imageUrl]['image']->getMappings())) {
255
                    // if image doesn't have mappings
256
                    // it's global for all details
257
                    // do nothing, just continue
258
                    continue;
259
                }
260
261
                // 2) if it has mapping, add new one for current detail
262
                if (array_key_exists($imageUrl, $localArticleImagesFromConnect)) {
263
                    /** @var \Shopware\Models\Article\Image $articleImage */
264
                    $articleImage = $localArticleImagesFromConnect[$imageUrl]['image'];
265
                    $articleMedia = $localArticleImagesFromConnect[$imageUrl]['media'];
266
267
                    // add new mapping
268
                    $mapping = new Image\Mapping();
269
                    $mapping->setImage($articleImage);
270
                    foreach ($detail->getConfiguratorOptions() as $option) {
271
                        $rule = new Image\Rule();
272
                        $rule->setMapping($mapping);
273
                        $rule->setOption($option);
274
                        $mapping->getRules()->add($rule);
275
                    }
276
                    $this->manager->persist($mapping);
277
                    // mapping should have id, because it should be stored as child image attribute
278
                    $this->manager->flush($mapping);
279
                    $articleImage->getMappings()->add($mapping);
280
281
                    // add child image
282
                    $childImage = new Image();
283
                    $childImage->setMain(2);
284
                    $childImage->setPosition($maxPosition + $key + 1);
285
                    $childImage->setParent($articleImage);
286
                    $childImage->setArticleDetail($detail);
287
                    $childImage->setExtension($articleMedia->getExtension());
288
                    $childImageAttribute = $childImage->getAttribute() ?: new ImageAttribute();
289
                    $childImageAttribute->setArticleImage($childImage);
290
                    $childImageAttribute->setConnectDetailMappingId($mapping->getId());
291
292
                    $detail->getImages()->add($childImage);
293
                    $articleImage->getChildren()->add($childImage);
294
295
                    $this->manager->persist($childImage);
296
                    $this->manager->persist($childImageAttribute);
297
                    $this->manager->persist($articleImage);
298
299
                    continue;
300
                }
301
302
                // 3) if it doesn't exist, import it
303
                $importedImages = $this->importImages([$imageUrl => $key], $article, $maxPosition);
304
                $image = reset($importedImages);
305
                $media = $image->getMedia();
306
307
                // add new mapping
308
                $mapping = new Image\Mapping();
309
                $mapping->setImage($image);
310
                foreach ($detail->getConfiguratorOptions() as $option) {
311
                    $rule = new Image\Rule();
312
                    $rule->setMapping($mapping);
313
                    $rule->setOption($option);
314
                    $rules = $mapping->getRules();
315
                    $rules->add($rule);
316
                    $mapping->setRules($rules);
317
                    $this->manager->persist($rule);
318
                }
319
                $this->manager->persist($mapping);
320
                // mapping should have id, because it should be stored as child image attribute
321
                $this->manager->flush($mapping);
322
323
                $mappings = $image->getMappings();
324
                $mappings->add($mapping);
325
                $image->setMappings($mappings);
326
327
                // add child image
328
                $childImage = new Image();
329
                $childImage->setMain(2);
330
                $childImage->setPosition($maxPosition + $key + 1);
331
                $childImage->setParent($image);
332
                $childImage->setArticleDetail($detail);
333
                $childImage->setExtension($media->getExtension());
334
                $childImageAttribute = $childImage->getAttribute() ?: new ImageAttribute();
335
                $childImageAttribute->setArticleImage($childImage);
336
                $childImageAttribute->setConnectDetailMappingId($mapping->getId());
337
                $detail->getImages()->add($childImage);
338
339
                $image->getChildren()->add($childImage);
340
341
                $this->manager->persist($childImage);
342
                $this->manager->persist($childImageAttribute);
343
                $this->manager->persist($image);
344
345
                $this->thumbnailManager->createMediaThumbnail(
346
                    $media,
347
                    $this->getThumbnailSize($album),
348
                    true
349
                );
350
            }
351
        } catch (\Exception $e) {
352
            // log exception message if for some reason
353
            // image import fails
354
            $this->logger->write(true, 'Import images', $e->getMessage());
355
        }
356
357
        $article->setImages($articleImages);
358
        $this->manager->persist($article);
359
        $this->manager->flush();
360
    }
361
362
    /**
363
     * Helper: Read images for a given detail
364
     *
365
     * @param int $articleDetailId
366
     * @return array
367
     */
368
    public function getImagesForDetail($articleDetailId)
369
    {
370
        $builder = $this->manager->createQueryBuilder();
371
        $builder->select('media.path')
372
            ->from('Shopware\Models\Article\Image', 'images')
373
            ->join('images.media', 'media')
374
            ->where('images.articleDetailId = :articleDetailId')
375
            ->andWhere('images.parentId IS NULL')
376
            ->setParameter('articleDetailId', $articleDetailId)
377
            ->orderBy('images.main', 'ASC')
378
            ->addOrderBy('images.position', 'ASC');
379
380
        return array_map(
381
            function ($image) {
382
                return $image['path'];
383
            },
384
            $builder->getQuery()->getArrayResult()
385
        );
386
    }
387
388
    /**
389
     * Download, import and assign images to article
390
     *
391
     * @param array $imagesToCreate
392
     * @param Article|Detail $model
393
     * @param null|int $maxPosition
394
     * @throws \Doctrine\ORM\ORMException
395
     * @throws \Doctrine\ORM\OptimisticLockException
396
     * @throws \Doctrine\ORM\TransactionRequiredException
397
     * @throws \Exception
398
     * @return \Shopware\Models\Article\Image
399
     */
400
    private function importImages(array $imagesToCreate, $model, $maxPosition = null)
401
    {
402
        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...
403
            $positions = [];
404
            foreach ($model->getImages() as $image) {
405
                $positions[] = $image->getPosition();
406
            }
407
            $maxPosition = count($positions) > 0 ? max($positions) : 0;
408
        }
409
410
        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...
411
            $article = $model->getArticle();
412
        } 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...
413
            $article = $model;
414
        } else {
415
            throw new \RuntimeException('Model must be instance of Article or Detail!');
416
        }
417
418
        // If there is no main image set first image as main image
419
        $hasMainImage = $this->hasArticleMainImage($article->getId());
420
        $importedImages = [];
421
        /** @var \Shopware\Models\Media\Album $album */
422
        $album = $this->manager->find('Shopware\Models\Media\Album', -1);
423
        $tempDir = Shopware()->DocPath('media_temp');
424
        foreach ($imagesToCreate as $imageUrl => $key) {
425
            $tempFile = tempnam($tempDir, 'image');
426
            copy($imageUrl, $tempFile);
427
            $file = new File($tempFile);
428
429
            // Create the media object
430
            $media = new Media();
431
            $media->setAlbum($album);
432
            $media->setDescription('');
433
            $media->setCreated(new \DateTime());
434
            $media->setUserId(0);
435
            $media->setFile($file);
436
437
            $mediaAttribute = $media->getAttribute() ?: new MediaAttribute();
438
            $mediaAttribute->setConnectHash($imageUrl);
439
            $mediaAttribute->setMedia($media);
440
            $media->setAttribute($mediaAttribute);
441
            $this->manager->persist($media);
442
            $this->manager->persist($mediaAttribute);
443
444
            // Create the associated image object
445
            $image = new Image();
446
            $image->setMain((!$hasMainImage && $key == 0) ? 1 : 2);
447
            $image->setMedia($media);
448
            $image->setPosition($maxPosition + $key + 1);
449
            $image->setArticle($article);
450
            $image->setPath($media->getName());
451
            $image->setExtension($media->getExtension());
452
453
            $article->getImages()->add($image);
454
455
            $this->manager->persist($image);
456
457
            $this->thumbnailManager->createMediaThumbnail(
458
                $media,
459
                $this->getThumbnailSize($album),
460
                true
461
            );
462
463
            $importedImages[] = $image;
464
        }
465
466
        return $importedImages;
467
    }
468
469
    /**
470
     * Returns a list with already imported images from Connect
471
     * by given Article or Detail
472
     *
473
     * @param Article|Detail $model
474
     * @return array
475
     */
476
    private function getImportedImages($model)
477
    {
478
        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...
479
            throw new \RuntimeException('Model must be instance of Article or Detail!');
480
        }
481
482
        $localArticleImagesFromConnect = [];
483
484
        /** @var \Shopware\Models\Article\Image $image */
485
        foreach ($model->getImages() as $image) {
486
            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...
487
                $image = $image->getParent();
488
            }
489
            $media = $image->getMedia();
490
491
            try {
492
                if (!$media || !$media->getAttribute()) {
493
                    continue;
494
                }
495
                $attribute = $media->getAttribute();
496
            } 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...
497
                //is thrown if media was deleted -> simply continue
498
                continue;
499
            }
500
501
            // If the image was not imported from connect, skip it
502
            $connectHash = $attribute->getConnectHash();
503
            if (!$connectHash) {
504
                continue;
505
            }
506
            $localArticleImagesFromConnect[$connectHash] = ['image' => $image, 'media' => $media];
507
        }
508
509
        return $localArticleImagesFromConnect;
510
    }
511
512
    /**
513
     * @param $imageUrl
514
     * @param Supplier $supplier
515
     */
516
    public function importImageForSupplier($imageUrl, Supplier $supplier)
517
    {
518
        try {
519
            $album = $this->manager->find('Shopware\Models\Media\Album', -12);
520
            $tempDir = Shopware()->DocPath('media_temp');
521
522
            $tempFile = tempnam($tempDir, 'image');
523
            copy($imageUrl, $tempFile);
524
            $file = new File($tempFile);
525
526
            $media = new Media();
527
            $media->setAlbum($album);
528
            $media->setDescription('');
529
            $media->setCreated(new \DateTime());
530
            $media->setUserId(0);
531
            $media->setFile($file);
532
533
            $this->manager->persist($media);
534
535
            $this->thumbnailManager->createMediaThumbnail(
536
                $media,
537
                $this->getThumbnailSize($album),
538
                true
539
            );
540
541
            $supplier->setImage($media->getPath());
542
            $this->manager->persist($supplier);
543
544
            $this->manager->flush();
545
        } catch (\Exception $e) {
546
            $this->logger->write(
547
                true,
548
                'import image for supplier',
549
                $e->getMessage() . 'imageUrl:' . $imageUrl
550
            );
551
        }
552
    }
553
554
    /**
555
     * Returns thumbnails size by album
556
     * @param $album \Shopware\Models\Media\Album
557
     * @return array
558
     */
559
    protected function getThumbnailSize($album)
560
    {
561
        if (!$album->getId()) {
562
            return;
563
        }
564
565
        $thumbnailSizes = $album->getSettings()->getThumbnailSize();
566
        $sizesArray = [];
567
        $requiredSizeExists = false;
568
        foreach ($thumbnailSizes as $size) {
569
            if (strlen($size) == 0) {
570
                continue;
571
            }
572
573
            $sizes = explode('x', $size);
574
            if ($sizes[0] == 140 && $sizes[1] == 140) {
575
                $requiredSizeExists = true;
576
            }
577
            $sizesArray[] = $size;
578
        }
579
580
        if ($requiredSizeExists === false) {
581
            $sizesArray[] = '140x140';
582
        }
583
584
        return $sizesArray;
585
    }
586
587
    /**
588
     * @param $imageUrl string
589
     * @param $articleId int
590
     */
591
    public function importMainImage($imageUrl, $articleId)
592
    {
593
        $oldMainImageId = $this->manager->getConnection()->fetchColumn(
594
            'SELECT id FROM s_articles_img WHERE articleID = ? AND main = 1 AND parent_id IS NULL',
595
            [$articleId]
596
        );
597
598
        $newMainImageId = $this->manager->getConnection()->fetchColumn(
599
            '
600
            SELECT s_articles_img.id 
601
            FROM s_articles_img 
602
            INNER JOIN s_media ON s_articles_img.media_id = s_media.id
603
            INNER JOIN s_media_attributes ON s_media.id = s_media_attributes.mediaID
604
            WHERE s_articles_img.articleID = ? AND s_articles_img.parent_id IS NULL AND s_media_attributes.connect_hash = ?',
605
            [$articleId, $imageUrl]
606
        );
607
608
        if ($newMainImageId && $newMainImageId !== $oldMainImageId) {
609
            $this->manager->getConnection()->executeQuery(
610
                '
611
            UPDATE s_articles_img SET main = ? WHERE id = ?',
612
            [0, $oldMainImageId]
613
            );
614
            $this->manager->getConnection()->executeQuery(
615
                '
616
            UPDATE s_articles_img SET main = ? WHERE id = ?',
617
             [1, $newMainImageId]
618
            );
619
        }
620
    }
621
622
    /**
623
     * @param $imageUrl string
624
     * @param $articleId int
625
     * @return bool
626
     */
627
    public function hasMainImageChanged($imageUrl, $articleId)
628
    {
629
        $result = $this->manager->getConnection()->fetchColumn(
630
            '
631
            SELECT s_articles_img.id 
632
            FROM s_articles_img 
633
            INNER JOIN s_media ON s_articles_img.media_id = s_media.id
634
            INNER JOIN s_media_attributes ON s_media.id = s_media_attributes.mediaID
635
            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 = ?',
636
            [$articleId, $imageUrl]
637
        );
638
639
        return !(bool) $result;
640
    }
641
642
    /**
643
     * @param Detail $detail
644
     * @param array $lastUpdate
645
     */
646
    private function importArticleImagesWhenMainDetail($detail, array $lastUpdate)
647
    {
648
        if ($detail->getKind() == 1) {
649
            $this->importImagesForArticle(array_diff($lastUpdate['image'], $lastUpdate['variantImages']), $detail->getArticle());
650
        }
651
    }
652
}
653