Completed
Pull Request — master (#33)
by Tim
04:03
created

ProductAttributeObserver::getAttributeId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\ColumnKeys;
25
use TechDivision\Import\Product\Utils\MemberNames;
26
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
27
28
/**
29
 * Observer that creates/updates the product's attributes.
30
 *
31
 * @author    Tim Wagner <[email protected]>
32
 * @copyright 2016 TechDivision GmbH <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      https://github.com/techdivision/import-product
35
 * @link      http://www.techdivision.com
36
 */
37
class ProductAttributeObserver extends AbstractProductImportObserver
38
{
39
40
    /**
41
     * The ID of the attribute to create the values for.
42
     *
43
     * @var integer
44
     */
45
    protected $attributeId;
46
47
    /**
48
     * The attribute code of the attribute to create the values for.
49
     *
50
     * @var string
51
     */
52
    protected $attributeCode;
53
54
    /**
55
     * The backend type of the attribute to create the values for.
56
     *
57
     * @var string
58
     */
59
    protected $backendType;
60
61
    /**
62
     * The attribute value to process.
63
     *
64
     * @var mixed
65
     */
66
    protected $attributeValue;
67
68
    /**
69
     * Process the observer's business logic.
70
     *
71
     * @return void
72
     */
73
    protected function process()
74
    {
75
76
        // initialize the store view code
77
        $this->prepareStoreViewCode();
78
79
        // load the attributes by the found attribute set and the backend types
80
        $attributes = $this->getAttributes();
81
        $backendTypes = $this->getBackendTypes();
82
83
        // remove all the empty values from the row
84
        $row = array_filter(
85
            $this->row,
86
            function ($value, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
                return ($value !== null && $value !== '');
88
            },
89
            ARRAY_FILTER_USE_BOTH
90
        );
91
92
        // load the header keys
93
        $headers = array_flip($this->getHeaders());
94
95
        // iterate over the attributes and append them to the row
96
        foreach ($row as $key => $attributeValue) {
97
            // query whether or not we've a attribute value found
98
            if ($attributeValue === null) {
99
                continue;
100
            }
101
102
            // query whether or not attribute with the found code exists
103
            if (!isset($attributes[$attributeCode = $headers[$key]])) {
104
                continue;
105
            }
106
107
            // if yes, load the attribute by its code
108
            $attribute = $attributes[$attributeCode];
109
110
            // load the backend type => to find the apropriate entity
111
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
112
            if ($backendType == null) {
113
                $this->getSystemLogger()->warning(sprintf('Found EMTPY backend type for attribute %s', $attributeCode));
114
                continue;
115
            }
116
117
            // do nothing on static backend type
118
            if ($backendType === 'static') {
119
                continue;
120
            }
121
122
            // query whether or not we've found a supported backend type
123
            if (isset($backendTypes[$backendType])) {
124
                // initialize attribute ID/code and backend type
125
                $this->attributeId = $attribute[MemberNames::ATTRIBUTE_ID];
126
                $this->attributeCode = $attributeCode;
127
                $this->backendType = $backendType;
128
129
                // initialize the persist method for the found backend type
130
                list ($persistMethod, ) = $backendTypes[$backendType];
131
132
                // set the attribute value
133
                $this->attributeValue = $attributeValue;
134
135
                // load the prepared values
136
                $entity = $this->initializeAttribute($this->prepareAttributes());
137
138
                // persist the attribute and continue
139
                $this->$persistMethod($entity);
140
                continue;
141
            }
142
143
            // log the debug message
144
            $this->getSystemLogger()->debug(
145
                sprintf(
146
                    'Found invalid backend type %s for attribute %s in file %s on line %s',
147
                    $this->backendType,
148
                    $this->attributeCode,
149
                    $this->getFilename(),
150
                    $this->getLineNumber()
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
    protected function prepareAttributes()
162
    {
163
164
        // laod the callbacks for the actual attribute code
165
        $callbacks = $this->getCallbacksByType($this->attributeCode);
166
167
        // invoke the pre-cast callbacks
168
        foreach ($callbacks as $callback) {
169
            $this->attributeValue = $callback->handle($this->attributeValue);
170
        }
171
172
        // load the ID of the product that has been created recently
173
        $lastEntityId = $this->getPrimaryKey();
174
175
        // load the store ID
176
        $storeId = $this->getRowStoreId(StoreViewCodes::ADMIN);
177
178
        // cast the value based on the backend type
179
        $castedValue = $this->castValueByBackendType($this->backendType, $this->attributeValue);
180
181
        // prepare the attribute values
182
        return $this->initializeEntity(
183
            array(
184
                MemberNames::ENTITY_ID    => $lastEntityId,
185
                MemberNames::ATTRIBUTE_ID => $this->attributeId,
186
                MemberNames::STORE_ID     => $storeId,
187
                MemberNames::VALUE        => $castedValue
188
            )
189
        );
190
    }
191
192
    /**
193
     * Initialize the category product with the passed attributes and returns an instance.
194
     *
195
     * @param array $attr The category product attributes
196
     *
197
     * @return array The initialized category product
198
     */
199
    protected function initializeAttribute(array $attr)
200
    {
201
        return $attr;
202
    }
203
204
    /**
205
     * Return's the PK to create the product => attribute relation.
206
     *
207
     * @return integer The PK to create the relation with
208
     */
209
    protected function getPrimaryKey()
210
    {
211
        return $this->getLastEntityId();
212
    }
213
214
    /**
215
     * Map the passed attribute code, if a header mapping exists and return the
216
     * mapped mapping.
217
     *
218
     * @param string $attributeCode The attribute code to map
219
     *
220
     * @return string The mapped attribute code, or the original one
221
     */
222
    protected function mapAttributeCodeByHeaderMapping($attributeCode)
223
    {
224
        return $this->getSubject()->mapAttributeCodeByHeaderMapping($attributeCode);
225
    }
226
227
    /**
228
     * Return's the array with callbacks for the passed type.
229
     *
230
     * @param string $type The type of the callbacks to return
231
     *
232
     * @return array The callbacks
233
     */
234
    protected function getCallbacksByType($type)
235
    {
236
        return $this->getSubject()->getCallbacksByType($type);
237
    }
238
239
    /**
240
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
241
     *
242
     * @return array The mapping for the supported backend types
243
     */
244
    protected function getBackendTypes()
245
    {
246
        return $this->getSubject()->getBackendTypes();
247
    }
248
249
    /**
250
     * Return's the attributes for the attribute set of the product that has to be created.
251
     *
252
     * @return array The attributes
253
     * @throws \Exception
254
     */
255
    protected function getAttributes()
256
    {
257
        return $this->getSubject()->getAttributes();
258
    }
259
260
    /**
261
     * Return's the store ID of the actual row, or of the default store
262
     * if no store view code is set in the CSV file.
263
     *
264
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
265
     *
266
     * @return integer The ID of the actual store
267
     * @throws \Exception Is thrown, if the store with the actual code is not available
268
     */
269
    protected function getRowStoreId($default = null)
270
    {
271
        return $this->getSubject()->getRowStoreId($default);
272
    }
273
274
    /**
275
     * Persist's the passed product varchar attribute.
276
     *
277
     * @param array $attribute The attribute to persist
278
     *
279
     * @return void
280
     */
281
    protected function persistProductVarcharAttribute($attribute)
282
    {
283
        $this->getSubject()->persistProductVarcharAttribute($attribute);
284
    }
285
286
    /**
287
     * Persist's the passed product integer attribute.
288
     *
289
     * @param array $attribute The attribute to persist
290
     *
291
     * @return void
292
     */
293
    protected function persistProductIntAttribute($attribute)
294
    {
295
        $this->getSubject()->persistProductIntAttribute($attribute);
296
    }
297
298
    /**
299
     * Persist's the passed product decimal attribute.
300
     *
301
     * @param array $attribute The attribute to persist
302
     *
303
     * @return void
304
     */
305
    protected function persistProductDecimalAttribute($attribute)
306
    {
307
        $this->getSubject()->persistProductDecimalAttribute($attribute);
308
    }
309
310
    /**
311
     * Persist's the passed product datetime attribute.
312
     *
313
     * @param array $attribute The attribute to persist
314
     *
315
     * @return void
316
     */
317
    protected function persistProductDatetimeAttribute($attribute)
318
    {
319
        $this->getSubject()->persistProductDatetimeAttribute($attribute);
320
    }
321
322
    /**
323
     * Persist's the passed product text attribute.
324
     *
325
     * @param array $attribute The attribute to persist
326
     *
327
     * @return void
328
     */
329
    protected function persistProductTextAttribute($attribute)
330
    {
331
        $this->getSubject()->persistProductTextAttribute($attribute);
332
    }
333
}
334