Completed
Pull Request — master (#17)
by Tim
03:38
created

ProductAttributeObserver::processAttribute()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 33
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 0
cts 15
cp 0
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 1
crap 6
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
     * Will be invoked by the action on the events the listener has been registered for.
69
     *
70
     * @param array $row The row to handle
71
     *
72
     * @return array The modified row
73
     * @see \TechDivision\Import\Product\Observers\ImportObserverInterface::handle()
74
     */
75
    public function handle(array $row)
76
    {
77
78
        // initialize the row
79
        $this->setRow($row);
80
81
        // process the functionality and return the row
82
        $this->process();
83
84
        // return the processed row
85
        return $this->getRow();
86
    }
87
88
    /**
89
     * Process the observer's business logic.
90
     *
91
     * @return void
92
     */
93
    public function process()
94
    {
95
96
        // initialize the store view code
97
        $this->prepareStoreViewCode();
98
99
        // load the attributes by the found attribute set
100
        $attributes = $this->getAttributes();
101
102
        // iterate over the attribute related by the found attribute set
103
        foreach ($attributes as $attribute) {
104
            // load the attribute code/ID
105
            $attributeCode = $attribute[MemberNames::ATTRIBUTE_CODE];
106
            $attributeId = (integer) $attribute[MemberNames::ATTRIBUTE_ID];
107
108
            // query weather or not we've a mapping, if yes, map the attribute code
109
            $attributeCode = $this->mapAttributeCodeByHeaderMapping($attributeCode);
110
111
            // query whether or not we've a attribute value found
112
            $attributeValue = $this->getValue($attributeCode);
113
            if ($attributeValue == null) {
114
                continue;
115
            }
116
117
            // load the backend type => to find the apropriate entity
118
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
119
            if ($backendType == null) {
120
                $this->getSystemLogger()
121
                     ->warning(sprintf('Found EMTPY backend type for attribute %s', $attributeCode));
122
                continue;
123
            }
124
125
            // load the supported backend types
126
            $backendTypes = $this->getBackendTypes();
127
128
            // query whether or not we've found a supported backend type
129
            if (isset($backendTypes[$backendType])) {
130
                // initialize attribute ID/code and backend type
131
                $this->setAttributeId($attributeId);
132
                $this->setAttributeCode($attributeCode);
133
                $this->setBackendType($backendType);
134
135
                // initialize the persist method for the found backend type
136
                list ($persistMethod, ) = $backendTypes[$backendType];
137
138
                // set the attribute value
139
                $this->setAttributeValue($attributeValue);
140
141
                // load the prepared values
142
                $entity = $this->initializeAttribute($this->prepareAttributes());
143
144
                // persist the attribute
145
                $this->$persistMethod($entity);
146
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
147
            } else {
148
                // log the debug message
149
                $this->getSystemLogger()->debug(
150
                    sprintf('Found invalid backend type %s for attribute %s', $backendType, $attributeCode)
151
                );
152
            }
153
        }
154
    }
155
156
    /**
157
     * Prepare the attributes of the entity that has to be persisted.
158
     *
159
     * @return array The prepared attributes
160
     */
161
    public function prepareAttributes()
162
    {
163
164
        // load the attribute value
165
        $attributeValue = $this->getAttributeValue();
166
167
        // laod the callbacks for the actual attribute code
168
        $callbacks = $this->getCallbacksByType($this->getAttributeCode());
169
170
        // invoke the pre-cast callbacks
171
        foreach ($callbacks as $callback) {
172
            $attributeValue = $callback->handle($attributeValue);
173
        }
174
175
        // load the ID of the product that has been created recently
176
        $lastEntityId = $this->getPrimaryKey();
177
178
        // load the ID of the attribute to create the values for
179
        $attributeId = $this->getAttributeId();
180
181
        // load the store ID
182
        $storeId = $this->getRowStoreId(StoreViewCodes::ADMIN);
183
184
        // load the backend type of the actual attribute
185
        $backendType = $this->getBackendType();
186
187
        // cast the value based on the backend type
188
        $castedValue = $this->castValueByBackendType($backendType, $attributeValue);
189
190
        // prepare the attribute values
191
        return $this->initializeEntity(
192
            array(
193
                MemberNames::ENTITY_ID    => $lastEntityId,
194
                MemberNames::ATTRIBUTE_ID => $attributeId,
195
                MemberNames::STORE_ID     => $storeId,
196
                MemberNames::VALUE        => $castedValue
197
            )
198
        );
199
    }
200
201
    /**
202
     * Initialize the category product with the passed attributes and returns an instance.
203
     *
204
     * @param array $attr The category product attributes
205
     *
206
     * @return array The initialized category product
207
     */
208
    public function initializeAttribute(array $attr)
209
    {
210
        return $attr;
211
    }
212
213
    /**
214
     * Return's the PK to create the product => attribute relation.
215
     *
216
     * @return integer The PK to create the relation with
217
     */
218
    public function getPrimaryKey()
219
    {
220
        return $this->getLastEntityId();
221
    }
222
223
    /**
224
     * Set's the attribute value to process.
225
     *
226
     * @param mixed $attributeValue The attribute value
227
     *
228
     * @return void
229
     */
230
    public function setAttributeValue($attributeValue)
231
    {
232
        $this->attributeValue = $attributeValue;
233
    }
234
235
    /**
236
     * Return's the attribute value to process.
237
     *
238
     * @return mixed The attribute value
239
     */
240
    public function getAttributeValue()
241
    {
242
        return $this->attributeValue;
243
    }
244
245
    /**
246
     * Set's the backend type of the attribute to create the values for.
247
     *
248
     * @param string $backendType The backend type
249
     *
250
     * @return void
251
     */
252
    public function setBackendType($backendType)
253
    {
254
        $this->backendType = $backendType;
255
    }
256
257
    /**
258
     * Return's the backend type of the attribute to create the values for.
259
     *
260
     * @return string The backend type
261
     */
262
    public function getBackendType()
263
    {
264
        return $this->backendType;
265
    }
266
267
    /**
268
     * Set's the attribute code of the attribute to create the values for.
269
     *
270
     * @param string $attributeCode The attribute code
271
     *
272
     * @return void
273
     */
274
    public function setAttributeCode($attributeCode)
275
    {
276
        $this->attributeCode = $attributeCode;
277
    }
278
279
    /**
280
     * Return's the attribute code of the attribute to create the values for.
281
     *
282
     * @return string The attribute code
283
     */
284
    public function getAttributeCode()
285
    {
286
        return $this->attributeCode;
287
    }
288
289
    /**
290
     * Set's the ID of the attribute to create the values for.
291
     *
292
     * @param integer $attributeId The attribute ID
293
     *
294
     * @return void
295
     */
296
    public function setAttributeId($attributeId)
297
    {
298
        $this->attributeId = $attributeId;
299
    }
300
301
    /**
302
     * Return's the ID of the attribute to create the values for.
303
     *
304
     * @return integer The attribute ID
305
     */
306
    public function getAttributeId()
307
    {
308
        return $this->attributeId;
309
    }
310
311
    /**
312
     * Map the passed attribute code, if a header mapping exists and return the
313
     * mapped mapping.
314
     *
315
     * @param string $attributeCode The attribute code to map
316
     *
317
     * @return string The mapped attribute code, or the original one
318
     */
319
    public function mapAttributeCodeByHeaderMapping($attributeCode)
320
    {
321
        return $this->getSubject()->mapAttributeCodeByHeaderMapping($attributeCode);
322
    }
323
324
    /**
325
     * Return's the array with callbacks for the passed type.
326
     *
327
     * @param string $type The type of the callbacks to return
328
     *
329
     * @return array The callbacks
330
     */
331
    public function getCallbacksByType($type)
332
    {
333
        return $this->getSubject()->getCallbacksByType($type);
334
    }
335
336
    /**
337
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
338
     *
339
     * @return array The mapping for the supported backend types
340
     */
341
    public function getBackendTypes()
342
    {
343
        return $this->getSubject()->getBackendTypes();
344
    }
345
346
    /**
347
     * Return's the attributes for the attribute set of the product that has to be created.
348
     *
349
     * @return array The attributes
350
     * @throws \Exception
351
     */
352
    public function getAttributes()
353
    {
354
        return $this->getSubject()->getAttributes();
355
    }
356
357
    /**
358
     * Return's the store ID of the actual row, or of the default store
359
     * if no store view code is set in the CSV file.
360
     *
361
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
362
     *
363
     * @return integer The ID of the actual store
364
     * @throws \Exception Is thrown, if the store with the actual code is not available
365
     */
366
    public function getRowStoreId($default = null)
367
    {
368
        return $this->getSubject()->getRowStoreId($default);
369
    }
370
371
    /**
372
     * Persist's the passed product varchar attribute.
373
     *
374
     * @param array $attribute The attribute to persist
375
     *
376
     * @return void
377
     */
378
    public function persistProductVarcharAttribute($attribute)
379
    {
380
        $this->getSubject()->persistProductVarcharAttribute($attribute);
381
    }
382
383
    /**
384
     * Persist's the passed product integer attribute.
385
     *
386
     * @param array $attribute The attribute to persist
387
     *
388
     * @return void
389
     */
390
    public function persistProductIntAttribute($attribute)
391
    {
392
        $this->getSubject()->persistProductIntAttribute($attribute);
393
    }
394
395
    /**
396
     * Persist's the passed product decimal attribute.
397
     *
398
     * @param array $attribute The attribute to persist
399
     *
400
     * @return void
401
     */
402
    public function persistProductDecimalAttribute($attribute)
403
    {
404
        $this->getSubject()->persistProductDecimalAttribute($attribute);
405
    }
406
407
    /**
408
     * Persist's the passed product datetime attribute.
409
     *
410
     * @param array $attribute The attribute to persist
411
     *
412
     * @return void
413
     */
414
    public function persistProductDatetimeAttribute($attribute)
415
    {
416
        $this->getSubject()->persistProductDatetimeAttribute($attribute);
417
    }
418
419
    /**
420
     * Persist's the passed product text attribute.
421
     *
422
     * @param array $attribute The attribute to persist
423
     *
424
     * @return void
425
     */
426
    public function persistProductTextAttribute($attribute)
427
    {
428
        $this->getSubject()->persistProductTextAttribute($attribute);
429
    }
430
}
431