Completed
Pull Request — master (#26)
by
unknown
66:17 queued 59:06
created

ProductBundleExampleFactory   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 3
dl 0
loc 88
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A configureOptions() 0 8 1
B create() 0 27 3
A createSlotOptions() 0 14 3
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * Created by solutionDrive GmbH
6
 *
7
 * @copyright 2018 solutionDrive GmbH
8
 */
9
10
namespace solutionDrive\SyliusProductBundlesPlugin\Fixture\Factory;
11
12
use solutionDrive\SyliusProductBundlesPlugin\Entity\ProductBundleInterface;
13
use solutionDrive\SyliusProductBundlesPlugin\Service\Options\ProductBundleSlotOptions;
14
use solutionDrive\SyliusProductBundlesPlugin\Service\Options\ProductBundleSlotOptionsInterface;
15
use solutionDrive\SyliusProductBundlesPlugin\Service\ProductBundleCreatorInterface;
16
use Sylius\Bundle\CoreBundle\Fixture\Factory\AbstractExampleFactory;
17
use Sylius\Component\Core\Model\ProductInterface;
18
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
19
use Symfony\Component\OptionsResolver\OptionsResolver;
20
use Webmozart\Assert\Assert;
21
22
class ProductBundleExampleFactory extends AbstractExampleFactory
23
{
24
    /**
25
     * @var ProductBundleCreatorInterface
26
     */
27
    private $productBundleCreator;
28
29
    /**
30
     * @var ProductRepositoryInterface
31
     */
32
    private $productRepository;
33
34
    /**
35
     * @var OptionsResolver
36
     */
37
    private $optionsResolver;
38
39
    public function __construct(
40
        ProductBundleCreatorInterface $productBundleCreator,
41
        ProductRepositoryInterface $productRepository
42
    ) {
43
        $this->productBundleCreator = $productBundleCreator;
44
        $this->productRepository = $productRepository;
45
        $this->optionsResolver = new OptionsResolver();
46
        $this->configureOptions($this->optionsResolver);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    protected function configureOptions(OptionsResolver $resolver): void
53
    {
54
        $resolver
55
            ->setDefined('productCode')
56
            ->setAllowedTypes('productCode', 'string')
57
            ->setDefined('slots')
58
            ->setAllowedTypes('slots', 'array');
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function create(array $options = []): ProductBundleInterface
65
    {
66
        $options = $this->optionsResolver->resolve($options);
67
68
        /** @var ProductInterface $product */
69
        $product = $this->productRepository->findOneByCode($options['productCode']);
70
71
        Assert::notNull($product, sprintf('Bundle product %s could not be found', $options['productCode']));
72
        $productBundleCreator = $this->productBundleCreator->createProductBundle($product->getName(), $product);
73
74
        foreach ($options['slots'] as $slot) {
75
            $slotProducts = [];
76
            foreach ($slot['productCodes'] as $productCode) {
77
                $slotProduct =  $this->productRepository->findOneByCode($productCode);
78
                Assert::notNull($slotProduct, sprintf('Slot product %s could not be found', $productCode));
79
                $slotProducts[] = $slotProduct;
80
            }
81
            $slotOptions = $this->createSlotOptions($slot['options']);
82
            $productBundleCreator->addSlot($slot['name'], $slotOptions, $slotProducts);
83
        }
84
85
        /** @var ProductBundleInterface $productBundle */
86
        $productBundle = $productBundleCreator->getProductBundle();
87
        $productBundle->setCode($product->getCode());
88
89
        return $productBundle;
90
    }
91
92
    /**
93
     * @param string[] $rawSlotOptions
94
     */
95
    private function createSlotOptions(array $rawSlotOptions= []): ProductBundleSlotOptionsInterface
96
    {
97
        $slotOptions = new ProductBundleSlotOptions();
98
        foreach ($rawSlotOptions as $optionName => $optionValue) {
99
            $setter = 'set' . ucfirst($optionName);
100
101
            Assert::methodExists($slotOptions, $setter, sprintf('Setter %s for ProductBundleSlotOptions is not defined', $setter));
102
103
            if (method_exists($slotOptions, $setter = 'set' . ucfirst($optionName))) {
104
                $slotOptions->$setter($optionValue);
105
            }
106
        }
107
        return $slotOptions;
108
    }
109
}
110