Completed
Push — master ( fb9075...7e65e5 )
by Tim
9s
created

ProductAttributeObserver::handle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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