Completed
Push — master ( 7bba9a...df8d00 )
by Tim
9s
created

ProductAttributeObserver::process()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 76
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 0
loc 76
ccs 0
cts 45
cp 0
rs 6.5808
c 0
b 0
f 0
cc 7
eloc 35
nc 7
nop 0
crap 56

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Observers\ProductAttributeObserver
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 2016 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-product
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Observers;
22
23
use TechDivision\Import\Utils\StoreViewCodes;
24
use TechDivision\Import\Product\Utils\MemberNames;
25
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
26
27
/**
28
 * Observer that creates/updates the product's attributes.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2016 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import-product
34
 * @link      http://www.techdivision.com
35
 */
36
class ProductAttributeObserver extends AbstractProductImportObserver
37
{
38
39
    /**
40
     * The ID of the attribute to create the values for.
41
     *
42
     * @var integer
43
     */
44
    protected $attributeId;
45
46
    /**
47
     * The attribute code of the attribute to create the values for.
48
     *
49
     * @var string
50
     */
51
    protected $attributeCode;
52
53
    /**
54
     * The backend type of the attribute to create the values for.
55
     *
56
     * @var string
57
     */
58
    protected $backendType;
59
60
    /**
61
     * The attribute value to process.
62
     *
63
     * @var mixed
64
     */
65
    protected $attributeValue;
66
67
    /**
68
     * Process the observer's business logic.
69
     *
70
     * @return void
71
     */
72
    protected function process()
73
    {
74
75
        // initialize the store view code
76
        $this->prepareStoreViewCode();
77
78
        // load the attributes by the found attribute set
79
        $attributes = $this->getAttributes();
80
81
        // iterate over the attribute related by the found attribute set
82
        foreach ($attributes as $attribute) {
83
            // load the attribute code/ID
84
            $attributeCode = $attribute[MemberNames::ATTRIBUTE_CODE];
85
            $attributeId = (integer) $attribute[MemberNames::ATTRIBUTE_ID];
86
87
            // query weather or not we've a mapping, if yes, map the attribute code
88
            $attributeCode = $this->mapAttributeCodeByHeaderMapping($attributeCode);
89
90
            if (!$this->hasHeader($attributeCode)) {
91
                continue;
92
            }
93
94
            // query whether or not we've a attribute value found
95
            $attributeValue = $this->getValue($attributeCode);
96
            if ($attributeValue == null) {
97
                continue;
98
            }
99
100
            // load the backend type => to find the apropriate entity
101
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
102
            if ($backendType == null) {
103
                $this->getSystemLogger()->warning(sprintf('Found EMTPY backend type for attribute %s', $attributeCode));
104
                continue;
105
            }
106
107
            // load the supported backend types
108
            $backendTypes = $this->getBackendTypes();
109
110
            // do nothing on static backend type
111
            if ($backendType === 'static') {
112
                continue;
113
            }
114
115
            // query whether or not we've found a supported backend type
116
            if (isset($backendTypes[$backendType])) {
117
                // initialize attribute ID/code and backend type
118
                $this->setAttributeId($attributeId);
119
                $this->setAttributeCode($attributeCode);
120
                $this->setBackendType($backendType);
121
122
                // initialize the persist method for the found backend type
123
                list ($persistMethod, ) = $backendTypes[$backendType];
124
125
                // set the attribute value
126
                $this->setAttributeValue($attributeValue);
127
128
                // load the prepared values
129
                $entity = $this->initializeAttribute($this->prepareAttributes());
130
131
                // persist the attribute and continue
132
                $this->$persistMethod($entity);
133
                continue;
134
            }
135
136
            // log the debug message
137
            $this->getSystemLogger()->debug(
138
                sprintf(
139
                    'Found invalid backend type %s for attribute %s in file %s on line %s',
140
                    $backendType,
141
                    $attributeCode,
142
                    $this->getFilename(),
0 ignored issues
show
Bug introduced by
The method getFilename() does not seem to exist on object<TechDivision\Impo...oductAttributeObserver>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
143
                    $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...oductAttributeObserver>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
                )
145
            );
146
        }
147
    }
148
149
    /**
150
     * Prepare the attributes of the entity that has to be persisted.
151
     *
152
     * @return array The prepared attributes
153
     */
154
    protected function prepareAttributes()
155
    {
156
157
        // load the attribute value
158
        $attributeValue = $this->getAttributeValue();
159
160
        // laod the callbacks for the actual attribute code
161
        $callbacks = $this->getCallbacksByType($this->getAttributeCode());
162
163
        // invoke the pre-cast callbacks
164
        foreach ($callbacks as $callback) {
165
            $attributeValue = $callback->handle($attributeValue);
166
        }
167
168
        // load the ID of the product that has been created recently
169
        $lastEntityId = $this->getPrimaryKey();
170
171
        // load the ID of the attribute to create the values for
172
        $attributeId = $this->getAttributeId();
173
174
        // load the store ID
175
        $storeId = $this->getRowStoreId(StoreViewCodes::ADMIN);
176
177
        // load the backend type of the actual attribute
178
        $backendType = $this->getBackendType();
179
180
        // cast the value based on the backend type
181
        $castedValue = $this->castValueByBackendType($backendType, $attributeValue);
182
183
        // prepare the attribute values
184
        return $this->initializeEntity(
185
            array(
186
                MemberNames::ENTITY_ID    => $lastEntityId,
187
                MemberNames::ATTRIBUTE_ID => $attributeId,
188
                MemberNames::STORE_ID     => $storeId,
189
                MemberNames::VALUE        => $castedValue
190
            )
191
        );
192
    }
193
194
    /**
195
     * Initialize the category product with the passed attributes and returns an instance.
196
     *
197
     * @param array $attr The category product attributes
198
     *
199
     * @return array The initialized category product
200
     */
201
    protected function initializeAttribute(array $attr)
202
    {
203
        return $attr;
204
    }
205
206
    /**
207
     * Return's the PK to create the product => attribute relation.
208
     *
209
     * @return integer The PK to create the relation with
210
     */
211
    protected function getPrimaryKey()
212
    {
213
        return $this->getLastEntityId();
214
    }
215
216
    /**
217
     * Set's the attribute value to process.
218
     *
219
     * @param mixed $attributeValue The attribute value
220
     *
221
     * @return void
222
     */
223
    protected function setAttributeValue($attributeValue)
224
    {
225
        $this->attributeValue = $attributeValue;
226
    }
227
228
    /**
229
     * Return's the attribute value to process.
230
     *
231
     * @return mixed The attribute value
232
     */
233
    protected function getAttributeValue()
234
    {
235
        return $this->attributeValue;
236
    }
237
238
    /**
239
     * Set's the backend type of the attribute to create the values for.
240
     *
241
     * @param string $backendType The backend type
242
     *
243
     * @return void
244
     */
245
    protected function setBackendType($backendType)
246
    {
247
        $this->backendType = $backendType;
248
    }
249
250
    /**
251
     * Return's the backend type of the attribute to create the values for.
252
     *
253
     * @return string The backend type
254
     */
255
    protected function getBackendType()
256
    {
257
        return $this->backendType;
258
    }
259
260
    /**
261
     * Set's the attribute code of the attribute to create the values for.
262
     *
263
     * @param string $attributeCode The attribute code
264
     *
265
     * @return void
266
     */
267
    protected function setAttributeCode($attributeCode)
268
    {
269
        $this->attributeCode = $attributeCode;
270
    }
271
272
    /**
273
     * Return's the attribute code of the attribute to create the values for.
274
     *
275
     * @return string The attribute code
276
     */
277
    protected function getAttributeCode()
278
    {
279
        return $this->attributeCode;
280
    }
281
282
    /**
283
     * Set's the ID of the attribute to create the values for.
284
     *
285
     * @param integer $attributeId The attribute ID
286
     *
287
     * @return void
288
     */
289
    protected function setAttributeId($attributeId)
290
    {
291
        $this->attributeId = $attributeId;
292
    }
293
294
    /**
295
     * Return's the ID of the attribute to create the values for.
296
     *
297
     * @return integer The attribute ID
298
     */
299
    protected function getAttributeId()
300
    {
301
        return $this->attributeId;
302
    }
303
304
    /**
305
     * Map the passed attribute code, if a header mapping exists and return the
306
     * mapped mapping.
307
     *
308
     * @param string $attributeCode The attribute code to map
309
     *
310
     * @return string The mapped attribute code, or the original one
311
     */
312
    protected function mapAttributeCodeByHeaderMapping($attributeCode)
313
    {
314
        return $this->getSubject()->mapAttributeCodeByHeaderMapping($attributeCode);
315
    }
316
317
    /**
318
     * Return's the array with callbacks for the passed type.
319
     *
320
     * @param string $type The type of the callbacks to return
321
     *
322
     * @return array The callbacks
323
     */
324
    protected function getCallbacksByType($type)
325
    {
326
        return $this->getSubject()->getCallbacksByType($type);
327
    }
328
329
    /**
330
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
331
     *
332
     * @return array The mapping for the supported backend types
333
     */
334
    protected function getBackendTypes()
335
    {
336
        return $this->getSubject()->getBackendTypes();
337
    }
338
339
    /**
340
     * Return's the attributes for the attribute set of the product that has to be created.
341
     *
342
     * @return array The attributes
343
     * @throws \Exception
344
     */
345
    protected function getAttributes()
346
    {
347
        return $this->getSubject()->getAttributes();
348
    }
349
350
    /**
351
     * Return's the store ID of the actual row, or of the default store
352
     * if no store view code is set in the CSV file.
353
     *
354
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
355
     *
356
     * @return integer The ID of the actual store
357
     * @throws \Exception Is thrown, if the store with the actual code is not available
358
     */
359
    protected function getRowStoreId($default = null)
360
    {
361
        return $this->getSubject()->getRowStoreId($default);
362
    }
363
364
    /**
365
     * Persist's the passed product varchar attribute.
366
     *
367
     * @param array $attribute The attribute to persist
368
     *
369
     * @return void
370
     */
371
    protected function persistProductVarcharAttribute($attribute)
372
    {
373
        $this->getSubject()->persistProductVarcharAttribute($attribute);
374
    }
375
376
    /**
377
     * Persist's the passed product integer attribute.
378
     *
379
     * @param array $attribute The attribute to persist
380
     *
381
     * @return void
382
     */
383
    protected function persistProductIntAttribute($attribute)
384
    {
385
        $this->getSubject()->persistProductIntAttribute($attribute);
386
    }
387
388
    /**
389
     * Persist's the passed product decimal attribute.
390
     *
391
     * @param array $attribute The attribute to persist
392
     *
393
     * @return void
394
     */
395
    protected function persistProductDecimalAttribute($attribute)
396
    {
397
        $this->getSubject()->persistProductDecimalAttribute($attribute);
398
    }
399
400
    /**
401
     * Persist's the passed product datetime attribute.
402
     *
403
     * @param array $attribute The attribute to persist
404
     *
405
     * @return void
406
     */
407
    protected function persistProductDatetimeAttribute($attribute)
408
    {
409
        $this->getSubject()->persistProductDatetimeAttribute($attribute);
410
    }
411
412
    /**
413
     * Persist's the passed product text attribute.
414
     *
415
     * @param array $attribute The attribute to persist
416
     *
417
     * @return void
418
     */
419
    protected function persistProductTextAttribute($attribute)
420
    {
421
        $this->getSubject()->persistProductTextAttribute($attribute);
422
    }
423
}
424