Passed
Push — master ( 54a649...9d29dd )
by
unknown
10:22 queued 04:44
created

PageFixtureFactory::resolveProducts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file was created by developers working at BitBag
5
 * Do you need more information about us and what we do? Visit our https://bitbag.io website!
6
 * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
7
*/
8
9
declare(strict_types=1);
10
11
namespace BitBag\SyliusCmsPlugin\Fixture\Factory;
12
13
use BitBag\SyliusCmsPlugin\Assigner\ChannelsAssignerInterface;
14
use BitBag\SyliusCmsPlugin\Assigner\ProductsAssignerInterface;
15
use BitBag\SyliusCmsPlugin\Assigner\SectionsAssignerInterface;
16
use BitBag\SyliusCmsPlugin\Entity\Media;
17
use BitBag\SyliusCmsPlugin\Entity\MediaInterface;
18
use BitBag\SyliusCmsPlugin\Entity\PageInterface;
19
use BitBag\SyliusCmsPlugin\Entity\PageTranslationInterface;
20
use BitBag\SyliusCmsPlugin\Repository\PageRepositoryInterface;
21
use BitBag\SyliusCmsPlugin\Resolver\MediaProviderResolverInterface;
22
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
23
use Sylius\Component\Core\Model\ChannelInterface;
24
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
25
use Sylius\Component\Locale\Context\LocaleContextInterface;
26
use Sylius\Component\Resource\Factory\FactoryInterface;
27
use Symfony\Component\HttpFoundation\File\UploadedFile;
28
use Webmozart\Assert\Assert;
29
30
final class PageFixtureFactory implements FixtureFactoryInterface
31
{
32
    public const CHANNEL_WITH_CODE_NOT_FOUND_MESSAGE = 'Channel with code "%s" not found';
33
34
    /** @var FactoryInterface */
35
    private $pageFactory;
36
37
    /** @var FactoryInterface */
38
    private $pageTranslationFactory;
39
40
    /** @var PageRepositoryInterface */
41
    private $pageRepository;
42
43
    /** @var MediaProviderResolverInterface */
44
    private $mediaProviderResolver;
45
46
    /** @var ProductRepositoryInterface */
47
    private $productRepository;
48
49
    /** @var LocaleContextInterface */
50
    private $localeContext;
51
52
    /** @var ProductsAssignerInterface */
53
    private $productsAssigner;
54
55
    /** @var SectionsAssignerInterface */
56
    private $sectionsAssigner;
57
58
    /** @var ChannelsAssignerInterface */
59
    private $channelAssigner;
60
61
    /** @var ChannelRepositoryInterface */
62
    private $channelRepository;
63
64
    public function __construct(
65
        FactoryInterface $pageFactory,
66
        FactoryInterface $pageTranslationFactory,
67
        PageRepositoryInterface $pageRepository,
68
        MediaProviderResolverInterface $mediaProviderResolver,
69
        ProductsAssignerInterface $productsAssigner,
70
        SectionsAssignerInterface $sectionsAssigner,
71
        ChannelsAssignerInterface $channelAssigner,
72
        ProductRepositoryInterface $productRepository,
73
        LocaleContextInterface $localeContext,
74
        ChannelRepositoryInterface $channelRepository
75
    ) {
76
        $this->pageFactory = $pageFactory;
77
        $this->pageTranslationFactory = $pageTranslationFactory;
78
        $this->pageRepository = $pageRepository;
79
        $this->mediaProviderResolver = $mediaProviderResolver;
80
        $this->productsAssigner = $productsAssigner;
81
        $this->sectionsAssigner = $sectionsAssigner;
82
        $this->channelAssigner = $channelAssigner;
83
        $this->productRepository = $productRepository;
84
        $this->localeContext = $localeContext;
85
        $this->channelRepository = $channelRepository;
86
    }
87
88
    public function load(array $data): void
89
    {
90
        foreach ($data as $code => $fields) {
91
            if (
92
                true === $fields['remove_existing'] &&
93
                null !== $page = $this->pageRepository->findOneBy(['code' => $code])
94
            ) {
95
                $this->pageRepository->remove($page);
96
            }
97
98
            if (null !== $fields['number']) {
99
                for ($i = 0; $i < $fields['number']; ++$i) {
100
                    $this->createPage(md5(uniqid()), $fields, true);
101
                }
102
            } else {
103
                $this->createPage($code, $fields);
104
            }
105
        }
106
    }
107
108
    private function createPage(
109
        string $code,
110
        array $pageData,
111
        bool $generateSlug = false
112
    ): void {
113
        /** @var PageInterface $page */
114
        $page = $this->pageFactory->createNew();
115
        $products = $pageData['products'];
116
        $channelsCodes = $pageData['channels'];
117
        if (null !== $products) {
118
            $this->resolveProductsForChannels($page, $products, $channelsCodes);
119
        }
120
121
        $this->sectionsAssigner->assign($page, $pageData['sections']);
122
        $this->productsAssigner->assign($page, $pageData['productCodes']);
123
        $this->channelAssigner->assign($page, $channelsCodes);
124
125
        $page->setCode($code);
126
        $page->setEnabled($pageData['enabled']);
127
128
        foreach ($pageData['translations'] as $localeCode => $translation) {
129
            /** @var PageTranslationInterface $pageTranslation */
130
            $pageTranslation = $this->pageTranslationFactory->createNew();
131
            $slug = true === $generateSlug ? md5(uniqid()) : $translation['slug'];
132
133
            $pageTranslation->setLocale($localeCode);
134
            $pageTranslation->setSlug($slug);
135
            $pageTranslation->setName($translation['name']);
136
            $pageTranslation->setNameWhenLinked($translation['name_when_linked']);
137
            $pageTranslation->setDescriptionWhenLinked($translation['description_when_linked']);
138
            $pageTranslation->setMetaKeywords($translation['meta_keywords']);
139
            $pageTranslation->setMetaDescription($translation['meta_description']);
140
            $pageTranslation->setContent($translation['content']);
141
142
            if ($translation['image_path']) {
143
                $image = new Media();
144
                $path = $translation['image_path'];
145
                $uploadedImage = new UploadedFile($path, md5($path) . '.jpg');
146
147
                $image->setFile($uploadedImage);
148
                $image->setCode(md5(uniqid()));
149
                $image->setType(MediaInterface::IMAGE_TYPE);
150
                $pageTranslation->setImage($image);
151
152
                $this->mediaProviderResolver->resolveProvider($image)->upload($image);
153
            }
154
155
            $page->addTranslation($pageTranslation);
156
        }
157
158
        $this->pageRepository->add($page);
159
    }
160
161
    private function resolveProductsForChannels(
162
        PageInterface $page,
163
        int $limit,
164
        array $channelCodes
165
    ): void {
166
        foreach ($channelCodes as $channelCode) {
167
            /** @var ChannelInterface|null $channel */
168
            $channel = $this->channelRepository->findOneByCode($channelCode);
169
            Assert::notNull($channel, sprintf(self::CHANNEL_WITH_CODE_NOT_FOUND_MESSAGE, $channelCode));
170
171
            $this->resolveProductsForChannel($page, $limit, $channel);
172
        }
173
    }
174
175
    private function resolveProductsForChannel(
176
        PageInterface $page,
177
        int $limit,
178
        ChannelInterface $channel
179
    ): void {
180
        $products = $this->productRepository->findLatestByChannel(
181
            $channel,
182
            $this->localeContext->getLocaleCode(),
183
            $limit
184
        );
185
186
        foreach ($products as $product) {
187
            $page->addProduct($product);
188
        }
189
    }
190
}
191