OptionBuilder   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Test Coverage

Coverage 79.69%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 61
c 1
b 0
f 0
dl 0
loc 195
ccs 51
cts 64
cp 0.7969
rs 10
wmc 11

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __clone() 0 3 1
A withLabel() 0 8 1
A withIsDefault() 0 6 1
A withStoreId() 0 6 1
A __construct() 0 10 1
A withSortOrder() 0 6 1
A getOptionId() 0 21 3
A build() 0 15 1
A anOptionFor() 0 25 1
1
<?php
2
declare(strict_types=1);
3
4
namespace TddWizard\Fixtures\Catalog;
5
6
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
7
use Magento\Catalog\Model\Product;
8
use Magento\Eav\Api\AttributeOptionManagementInterface;
9
use Magento\Eav\Api\Data\AttributeOptionLabelInterface;
10
use Magento\Eav\Model\Entity\Attribute\Option as AttributeOption;
11
use Magento\TestFramework\Helper\Bootstrap;
0 ignored issues
show
Bug introduced by
The type Magento\TestFramework\Helper\Bootstrap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
13
/**
14
 * Create a source-model option for an attribute.
15
 *
16
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
17
 */
18
class OptionBuilder
19
{
20
21
    /**
22
     * @var AttributeOptionManagementInterface
23
     */
24
    private $optionManagement;
25
26
    /**
27
     * @var AttributeOption
28
     */
29
    private $option;
30
31
    /**
32
     * @var AttributeOptionLabelInterface
33
     */
34
    private $optionLabel;
35
36
    /**
37
     * @var string
38
     */
39
    private $attributeCode;
40
41
    /**
42
     * OptionBuilder constructor.
43
     *
44
     * @param AttributeOptionManagementInterface $optionManagement
45
     * @param AttributeOption $option
46
     * @param AttributeOptionLabelInterface $optionLabel
47
     * @param string $attributeCode
48
     */
49 6
    public function __construct(
50
        AttributeOptionManagementInterface $optionManagement,
51
        AttributeOption $option,
52
        AttributeOptionLabelInterface $optionLabel,
53
        string $attributeCode
54
    ) {
55 6
        $this->optionManagement = $optionManagement;
56 6
        $this->option = $option;
57 6
        $this->optionLabel = $optionLabel;
58 6
        $this->attributeCode = $attributeCode;
59 6
    }
60
61
    /**
62
     * Clone the builder.
63
     */
64 6
    public function __clone()
65
    {
66 6
        $this->option = clone $this->option;
67 6
    }
68
69
    /**
70
     * Create an option.
71
     *
72
     * @param string $attributeCode
73
     * @return OptionBuilder
74
     * @throws \Magento\Framework\Exception\InputException
75
     * @throws \Magento\Framework\Exception\StateException
76
     */
77 6
    public static function anOptionFor(string $attributeCode): OptionBuilder
78
    {
79 6
        $objectManager = Bootstrap::getObjectManager();
80
        /** @var AttributeOptionManagementInterface $optionManagement */
81 6
        $optionManagement = $objectManager->create(AttributeOptionManagementInterface::class);
82 6
        $items = $optionManagement->getItems(Product::ENTITY, $attributeCode);
0 ignored issues
show
Bug introduced by
Magento\Catalog\Model\Product::ENTITY of type string is incompatible with the type integer expected by parameter $entityType of Magento\Eav\Api\Attribut...ntInterface::getItems(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

82
        $items = $optionManagement->getItems(/** @scrutinizer ignore-type */ Product::ENTITY, $attributeCode);
Loading history...
83
84
        /** @var AttributeOptionLabelInterface $optionLabel */
85 6
        $optionLabel = $objectManager->create(AttributeOptionLabelInterface::class);
86 6
        $label = uniqid('Name ', true);
87 6
        $optionLabel->setStoreId(0);
88 6
        $optionLabel->setLabel($label);
89
90
        /** @var AttributeOption $option */
91 6
        $option = $objectManager->create(AttributeOption::class);
92 6
        $option->setLabel($label);
93 6
        $option->setStoreLabels([$optionLabel]);
94 6
        $option->setSortOrder(count($items) + 1);
95 6
        $option->setIsDefault(false);
96
97 6
        return new static(
98 6
            $optionManagement,
99
            $option,
100
            $optionLabel,
101
            $attributeCode
102
        );
103
    }
104
105
    /**
106
     * Set label.
107
     *
108
     * @param string $label
109
     * @return OptionBuilder
110
     */
111 3
    public function withLabel(string $label): OptionBuilder
112
    {
113 3
        $builder = clone $this;
114 3
        $builder->optionLabel->setLabel($label);
115 3
        $builder->option->setStoreLabels([$builder->optionLabel]);
116 3
        $builder->option->setLabel($label);
117
118 3
        return $builder;
119
    }
120
121
    /**
122
     * Set sort order.
123
     *
124
     * @param int $sortOrder
125
     * @return OptionBuilder
126
     */
127
    public function withSortOrder(int $sortOrder): OptionBuilder
128
    {
129
        $builder = clone $this;
130
        $builder->option->setSortOrder($sortOrder);
131
132
        return $builder;
133
    }
134
135
    /**
136
     * Set default.
137
     *
138
     * @param bool $isDefault
139
     * @return OptionBuilder
140
     */
141
    public function withIsDefault(bool $isDefault): OptionBuilder
142
    {
143
        $builder = clone $this;
144
        $builder->option->setIsDefault($isDefault);
145
146
        return $builder;
147
    }
148
149
    /**
150
     * Set store ID.
151
     *
152
     * @param int $storeId
153
     * @return OptionBuilder
154
     */
155
    public function withStoreId(int $storeId): OptionBuilder
156
    {
157
        $builder = clone $this;
158
        $builder->optionLabel->setStoreId($storeId);
159
160
        return $builder;
161
    }
162
163
    /**
164
     * Build the option and apply it to the attribute.
165
     *
166
     * @return AttributeOption
167
     * @throws \Magento\Framework\Exception\InputException
168
     * @throws \Magento\Framework\Exception\StateException
169
     */
170 6
    public function build(): AttributeOption
171
    {
172 6
        $builder = clone $this;
173
174
        // add the option
175 6
        $this->optionManagement->add(
176 6
            \Magento\Catalog\Model\Product::ENTITY,
0 ignored issues
show
Bug introduced by
Magento\Catalog\Model\Product::ENTITY of type string is incompatible with the type integer expected by parameter $entityType of Magento\Eav\Api\Attribut...agementInterface::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

176
            /** @scrutinizer ignore-type */ \Magento\Catalog\Model\Product::ENTITY,
Loading history...
177 6
            $builder->attributeCode,
178 6
            $builder->option
179
        );
180
181 6
        $optionId = $this->getOptionId();
182 6
        $builder->option->setId($optionId);
183
184 6
        return $builder->option;
185
    }
186
187
    /**
188
     * Get the option ID.
189
     *
190
     * @return int
191
     */
192 6
    private function getOptionId(): int
193
    {
194 6
        $objectManager = Bootstrap::getObjectManager();
195
        // the add option above does not return the option, so we need to retrieve it
196 6
        $attributeRepository = $objectManager->get(ProductAttributeRepositoryInterface::class);
197 6
        $attribute = $attributeRepository->get($this->attributeCode);
198 6
        $attributeValues[$attribute->getAttributeId()] = [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$attributeValues was never initialized. Although not strictly required by PHP, it is generally a good practice to add $attributeValues = array(); before regardless.
Loading history...
199
200
        // We have to generate a new sourceModel instance each time through to prevent it from
201
        // referencing its _options cache. No other way to get it to pick up newly-added values.
202 6
        $tableFactory = $objectManager->get(\Magento\Eav\Model\Entity\Attribute\Source\TableFactory::class);
0 ignored issues
show
Bug introduced by
The type Magento\Eav\Model\Entity...ute\Source\TableFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
203 6
        $sourceModel = $tableFactory->create();
204 6
        $sourceModel->setAttribute($attribute);
205 6
        foreach ($sourceModel->getAllOptions() as $option) {
206 6
            $attributeValues[$attribute->getAttributeId()][$option['label']] = $option['value'];
207
        }
208 6
        if (isset($attributeValues[$attribute->getAttributeId()][$this->optionLabel->getLabel()])) {
209 6
            return (int)$attributeValues[$attribute->getAttributeId()][$this->optionLabel->getLabel()];
210
        }
211
212
        throw new \RuntimeException('Error building option');
213
    }
214
}
215