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

PageFixtureFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
c 0
b 0
f 0
dl 0
loc 22
rs 9.9332
cc 1
nc 1
nop 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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