Completed
Push — 16.x ( 3844cc...bd15cd )
by
unknown
11:39 queued 09:54
created

AdditionalAttributeCsvSerializer   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 316
Duplicated Lines 12.97 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 96.83%

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 5
dl 41
loc 316
ccs 61
cts 63
cp 0.9683
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A getConfiguration() 0 4 1
A getValueCsvSerializerFactory() 0 4 1
A setValueCsvSerializer() 0 4 1
A getValueCsvSerializer() 0 4 1
A getImportProcessor() 0 4 1
A getEntityTypeId() 0 4 1
A getMultipleValueDelimiter() 0 4 1
A getMultipleFieldDelimiter() 0 4 1
A loadAttributeByAttributeCode() 0 4 1
A pack() 20 20 4
A unpack() 20 20 3
A init() 0 9 1
A unserialize() 0 21 4
A serialize() 0 16 4
A explode() 0 4 2
A implode() 0 4 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * TechDivision\Import\Serializers\AdditionalAttributeCsvSerializer
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2018 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Serializers;
22
23
use TechDivision\Import\Configuration\CsvConfigurationInterface;
24
use TechDivision\Import\Utils\FrontendInputTypes;
25
use TechDivision\Import\Utils\MemberNames;
26
use TechDivision\Import\Configuration\ConfigurationInterface;
27
use TechDivision\Import\Services\ImportProcessorInterface;
28
29
/**
30
 * Serializer implementation that un-/serializes the additional product attribues found in the CSV file
31
 * in the row 'additional_attributes'.
32
 *
33
 * @author     Tim Wagner <[email protected]>
34
 * @copyright  2021 TechDivision GmbH <[email protected]>
35
 * @license    http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link       https://github.com/techdivision/import
37
 * @link       http://www.techdivision.com
38
 * @deprecated Since 16.8.3
39
 * @see        \TechDivision\Import\Serializer\AdditionalAttributeCsvSerializer
40
 */
41
class AdditionalAttributeCsvSerializer extends AbstractCsvSerializer
0 ignored issues
show
Deprecated Code introduced by
The class TechDivision\Import\Seri...s\AbstractCsvSerializer has been deprecated with message: Since 16.8.3

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
42
{
43
44
    /**
45
     * The factory instance for the CSV value serializer.
46
     *
47
     * @var \TechDivision\Import\Serializers\ConfigurationAwareSerializerFactoryInterface
48
     */
49
    private $valueCsvSerializerFactory;
50
51
    /**
52
     * The CSV value serializer instance.
53
     *
54
     * @var \TechDivision\Import\Serializers\SerializerInterface
55
     */
56
    private $valueCsvSerializer;
57
58
    /**
59
     * The entity type from the configuration.
60
     *
61
     * @var array
62
     */
63
    private $entityType;
64
65
    /**
66
     *  The configuration instance.
67
     *
68
     * @var \TechDivision\Import\Configuration\ConfigurationInterface
69
     */
70
    private $configuration;
71
72
    /**
73
     * The convert processor instance.
74
     *
75
     * @var \TechDivision\Import\Services\ImportProcessorInterface
76
     */
77
    private $importProcessor;
78
79
    /**
80
     * Initialize the serializer with the passed CSV value serializer factory.
81
     *
82
     * @param \TechDivision\Import\Configuration\ConfigurationInterface                     $configuration             The configuration instance
83
     * @param \TechDivision\Import\Services\ImportProcessorInterface                        $importProcessor           The processor instance
84
     * @param \TechDivision\Import\Serializers\ConfigurationAwareSerializerFactoryInterface $valueCsvSerializerFactory The CSV value serializer factory
85
     */
86 13
    public function __construct(
87
        ConfigurationInterface $configuration,
88
        ImportProcessorInterface $importProcessor,
89
        ConfigurationAwareSerializerFactoryInterface $valueCsvSerializerFactory
90
    ) {
91
92
        // set the passed instances
93 13
        $this->configuration = $configuration;
94 13
        $this->importProcessor = $importProcessor;
95 13
        $this->valueCsvSerializerFactory = $valueCsvSerializerFactory;
96
97
        // load the entity type for the entity type defined in the configuration
98 13
        $this->entityType = $importProcessor->getEavEntityTypeByEntityTypeCode($configuration->getEntityTypeCode());
99 13
    }
100
101
    /**
102
     * Returns the configuration instance.
103
     *
104
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance
105
     */
106 13
    protected function getConfiguration()
107
    {
108 13
        return $this->configuration;
109
    }
110
111
    /**
112
     * Returns the factory instance for the CSV value serializer.
113
     *
114
     * @return \TechDivision\Import\Serializers\ConfigurationAwareSerializerFactoryInterface The CSV value serializer factory instance
115
     */
116 13
    protected function getValueCsvSerializerFactory()
117
    {
118 13
        return $this->valueCsvSerializerFactory;
119
    }
120
121
    /**
122
     * Returns the CSV value serializer instance.
123
     *
124
     * @param \TechDivision\Import\Serializers\SerializerInterface $valueCsvSerializer The CSV value serializer instance
125
     *
126
     * @return void
127
     */
128 13
    protected function setValueCsvSerializer(SerializerInterface $valueCsvSerializer)
129
    {
130 13
        $this->valueCsvSerializer = $valueCsvSerializer;
131 13
    }
132
133
    /**
134
     * Returns the CSV value serializer instance.
135
     *
136
     * @return \TechDivision\Import\Serializers\SerializerInterface The CSV value serializer instance
137
     */
138 13
    protected function getValueCsvSerializer()
139
    {
140 13
        return $this->valueCsvSerializer;
141
    }
142
143
    /**
144
     * Returns the import processor instance.
145
     *
146
     * @return \TechDivision\Import\Services\ImportProcessorInterface The import processor instance
147
     */
148 11
    protected function getImportProcessor()
149
    {
150 11
        return $this->importProcessor;
151
    }
152
153
    /**
154
     * Returns entity type ID mapped from the configuration.
155
     *
156
     * @return integer The mapped entity type ID
157
     */
158 11
    protected function getEntityTypeId()
159
    {
160 11
        return $this->entityType[MemberNames::ENTITY_TYPE_ID];
161
    }
162
163
    /**
164
     * Returns the multiple value delimiter from the configuration.
165
     *
166
     * @return string The multiple value delimiter
167
     */
168 4
    protected function getMultipleValueDelimiter()
169
    {
170 4
        return $this->getConfiguration()->getMultipleValueDelimiter();
171
    }
172
173
    /**
174
     * Returns the multiple field delimiter from the configuration.
175
     *
176
     * @return string The multiple field delimiter
177
     */
178 13
    protected function getMultipleFieldDelimiter()
179
    {
180 13
        return $this->getConfiguration()->getMultipleFieldDelimiter();
181
    }
182
183
    /**
184
     * Loads and returns the attribute with the passed code from the database.
185
     *
186
     * @param string $attributeCode The code of the attribute to return
187
     *
188
     * @return array The attribute
189
     */
190 11
    protected function loadAttributeByAttributeCode($attributeCode)
191
    {
192 11
        return $this->getImportProcessor()->getEavAttributeByEntityTypeIdAndAttributeCode($this->getEntityTypeId(), $attributeCode);
193
    }
194
195
    /**
196
     * Packs the passed value according to the frontend input type of the attribute with the passed code.
197
     *
198
     * @param string $attributeCode The code of the attribute to pack the passed value for
199
     * @param mixed  $value         The value to pack
200
     *
201
     * @return string The packed value
202
     */
203 4 View Code Duplication
    protected function pack($attributeCode, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
    {
205
206
        // load the attibute with the passed code
207 4
        $attribute = $this->loadAttributeByAttributeCode($attributeCode);
208
209
        // pack the value according to the attribute's frontend input type
210 4
        switch ($attribute[MemberNames::FRONTEND_INPUT]) {
211 4
            case FrontendInputTypes::MULTISELECT:
212 1
                return implode($this->getMultipleValueDelimiter(), $value);
213
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
214
215 4
            case FrontendInputTypes::BOOLEAN:
216 1
                return $value === true ? 'true' : 'false';
217
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
218
219
            default:
220 4
                return $value;
221
        }
222
    }
223
224
    /**
225
     * Unpacks the passed value according to the frontend input type of the attribute with the passed code.
226
     *
227
     * @param string $attributeCode The code of the attribute to pack the passed value for
228
     * @param string $value         The value to unpack
229
     *
230
     * @return mixed The unpacked value
231
     */
232 7 View Code Duplication
    protected function unpack($attributeCode, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
    {
234
235
        // load the attibute with the passed code
236 7
        $attribute = $this->loadAttributeByAttributeCode($attributeCode);
237
238
        // unpack the value according to the attribute's frontend input type
239 7
        switch ($attribute[MemberNames::FRONTEND_INPUT]) {
240 7
            case FrontendInputTypes::MULTISELECT:
241 3
                return explode($this->getMultipleValueDelimiter(), $value);
242
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
243
244 7
            case FrontendInputTypes::BOOLEAN:
245 3
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
246
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
247
248
            default:
249 7
                return $value;
250
        }
251
    }
252
253
    /**
254
     * Passes the configuration and initializes the serializer.
255
     *
256
     * @param \TechDivision\Import\Configuration\CsvConfigurationInterface $configuration The CSV configuration
257
     *
258
     * @return void
259
     */
260 13
    public function init(CsvConfigurationInterface $configuration)
261
    {
262
263
        // pass the configuration to the parent instance
264 13
        parent::init($configuration);
265
266
        // create the CSV value serializer instance
267 13
        $this->setValueCsvSerializer($this->getValueCsvSerializerFactory()->createSerializer($configuration));
268 13
    }
269
270
    /**
271
     * Unserializes the elements of the passed string.
272
     *
273
     * @param string|null $serialized The value to unserialize
274
     * @param string|null $delimiter  The delimiter used to unserialize the elements
275
     *
276
     * @return array The unserialized values
277
     * @see \TechDivision\Import\Serializers\SerializerInterface::unserialize()
278
     */
279 8
    public function unserialize($serialized = null, $delimiter = null)
280
    {
281
282
        // initialize the array for the attributes
283 8
        $attrs = array();
284
285
        // explode the additional attributes
286 8
        $additionalAttributes = $this->getValueCsvSerializer()->unserialize($serialized, $delimiter ? $delimiter : $this->getMultipleFieldDelimiter());
287
288
        // iterate over the attributes and append them to the row
289 8
        if (is_array($additionalAttributes)) {
290 7
            foreach ($additionalAttributes as $additionalAttribute) {
291
                // explode attribute code/option value from the attribute
292 7
                list ($attributeCode, $optionValue) = $this->explode($additionalAttribute, '=');
293 7
                $attrs[$attributeCode] = $this->unpack($attributeCode, $optionValue);
294
            }
295
        }
296
297
        // return the extracted array with the additional attributes
298 8
        return $attrs;
299
    }
300
301
    /**
302
     * Serializes the elements of the passed array.
303
     *
304
     * @param array|null  $unserialized The serialized data
305
     * @param string|null $delimiter    The delimiter used to serialize the values
306
     *
307
     * @return string The serialized array
308
     * @see \TechDivision\Import\Serializers\SerializerInterface::serialize()
309
     */
310 5
    public function serialize(array $unserialized = null, $delimiter = null)
311
    {
312
313
        // initialize the array for the attributes
314 5
        $attrs = array();
315
316
        // iterate over the attributes and append them to the row
317 5
        if (is_array($unserialized)) {
318 5
            foreach ($unserialized as $attributeCode => $optionValue) {
319 4
                $attrs[] = sprintf('%s=%s', $attributeCode, $this->pack($attributeCode, $optionValue));
320
            }
321
        }
322
323
        // implode the array with the packed additional attributes and return it
324 5
        return $this->getValueCsvSerializer()->serialize($attrs, $delimiter ? $delimiter : $this->getMultipleFieldDelimiter());
325
    }
326
327
    /**
328
     * Extracts the elements of the passed value by exploding them
329
     * with the also passed delimiter.
330
     *
331
     * @param string|null $value     The value to extract
332
     * @param string|null $delimiter The delimiter used to extrace the elements
333
     *
334
     * @return array|null The exploded values
335
     * @see \TechDivision\Import\Serializers\SerializerInterface::unserialize()
336
     */
337 7
    public function explode($value = null, $delimiter = null)
338
    {
339 7
        return $this->getValueCsvSerializer()->explode($value, $delimiter ? $delimiter : $this->getMultipleFieldDelimiter());
340
    }
341
342
    /**
343
     * Compacts the elements of the passed value by imploding them
344
     * with the also passed delimiter.
345
     *
346
     * @param array|null  $value     The values to compact
347
     * @param string|null $delimiter The delimiter use to implode the values
348
     *
349
     * @return string|null The compatected value
350
     * @see \TechDivision\Import\Serializers\SerializerInterface::serialize()
351
     */
352
    public function implode(array $value = null, $delimiter = null)
353
    {
354
        return $this->getValueCsvSerializer()->implode($value, $delimiter ? $delimiter : $this->getMultipleFieldDelimiter());
355
    }
356
}
357