Completed
Pull Request — master (#30)
by Tim
03:14
created

AbstractProductImportObserver   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 398
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 65.43%

Importance

Changes 0
Metric Value
wmc 39
lcom 1
cbo 1
dl 0
loc 398
ccs 53
cts 81
cp 0.6543
rs 8.2857
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A setRow() 0 4 1
A getRow() 0 4 1
A handle() 0 12 1
A process() 0 3 1
A hasBeenProcessed() 0 4 1
A addSkuEntityIdMapping() 0 4 1
A addSkuStoreViewCodeMapping() 0 4 1
A getMultipleFieldDelimiter() 0 4 1
A setHeaders() 0 4 1
A getHeaders() 0 4 1
A hasHeader() 0 4 1
A getHeader() 0 4 1
A addHeader() 0 4 1
A isLastSku() 0 4 1
A getLastEntityId() 0 4 1
A getSourceDateFormat() 0 4 1
A castValueByBackendType() 0 4 1
A setStoreViewCode() 0 4 1
A getStoreViewCode() 0 4 1
A prepareStoreViewCode() 0 11 2
A formatDate() 0 11 2
A explode() 0 11 2
A hasValue() 0 15 3
A setValue() 0 4 1
C getValue() 0 29 8
A initializeEntity() 0 4 1
A mergeEntity() 0 4 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Observers\AbstractProductImportObserver
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\EntityStatus;
24
use TechDivision\Import\Product\Utils\ColumnKeys;
25
use TechDivision\Import\Observers\AbstractObserver;
26
27
/**
28
 * A SLSB that handles the process to import product bunches.
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
abstract class AbstractProductImportObserver extends AbstractObserver implements ProductImportObserverInterface
37
{
38
39
    /**
40
     * The actual row, that has to be processed.
41
     *
42
     * @var array
43
     */
44
    protected $row = array();
45
46
    /**
47
     * Set's the actual row, that has to be processed.
48
     *
49
     * @param array $row The row
50
     *
51
     * @return void
52
     */
53 8
    protected function setRow(array $row)
54
    {
55 8
        $this->row = $row;
56 8
    }
57
58
    /**
59
     * Return's the actual row, that has to be processed.
60
     *
61
     * @return array The row
62
     */
63 8
    protected function getRow()
64
    {
65 8
        return $this->row;
66
    }
67
68
    /**
69
     * Will be invoked by the action on the events the listener has been registered for.
70
     *
71
     * @param array $row The row to handle
72
     *
73
     * @return array The modified row
74
     * @see \TechDivision\Import\Product\Observers\ImportObserverInterface::handle()
75
     */
76 8
    public function handle(array $row)
77
    {
78
79
        // initialize the row
80 8
        $this->setRow($row);
81
82
        // process the functionality and return the row
83 8
        $this->process();
84
85
        // return the processed row
86 8
        return $this->getRow();
87
    }
88
89
    /**
90
     * Process the observer's business logic.
91
     *
92
     * @return void
93
     */
94
    protected function process()
95
    {
96
    }
97
98
    /**
99
     * Queries whether or not the SKU has already been processed.
100
     *
101
     * @param string $sku The SKU to check been processed
102
     *
103
     * @return boolean TRUE if the SKU has been processed, else FALSE
104
     */
105 7
    protected function hasBeenProcessed($sku)
106
    {
107 7
        return $this->getSubject()->hasBeenProcessed($sku);
108
    }
109
110
    /**
111
     * Add the passed SKU => entity ID mapping.
112
     *
113
     * @param string $sku The SKU
114
     *
115
     * @return void
116
     */
117
    protected function addSkuEntityIdMapping($sku)
118
    {
119
        $this->getSubject()->addSkuEntityIdMapping($sku);
120
    }
121
122
    /**
123
     * Add the passed SKU => store view code mapping.
124
     *
125
     * @param string $sku           The SKU
126
     * @param string $storeViewCode The store view code
127
     *
128
     * @return void
129
     */
130
    protected function addSkuStoreViewCodeMapping($sku, $storeViewCode)
131
    {
132
        $this->getSubject()->addSkuStoreViewCodeMapping($sku, $storeViewCode);
133
    }
134
135
    /**
136
     * Return's the multiple field delimiter character to use, default value is comma (,).
137
     *
138
     * @return string The multiple field delimiter character
139
     */
140
    protected function getMultipleFieldDelimiter()
141
    {
142
        return $this->getSubject()->getMultipleFieldDelimiter();
143
    }
144
145
    /**
146
     * Set's the array containing header row.
147
     *
148
     * @param array $headers The array with the header row
149
     *
150
     * @return void
151
     */
152
    public function setHeaders(array $headers)
153
    {
154
        $this->getSubject()->setHeaders($headers);
155
    }
156
157
    /**
158
     * Return's the array containing header row.
159
     *
160
     * @return array The array with the header row
161
     */
162
    protected function getHeaders()
163
    {
164
        return $this->getSubject()->getHeaders();
165
    }
166
167
    /**
168
     * Queries whether or not the header with the passed name is available.
169
     *
170
     * @param string $name The header name to query
171
     *
172
     * @return boolean TRUE if the header is available, else FALSE
173
     */
174 8
    protected function hasHeader($name)
175
    {
176 8
        return $this->getSubject()->hasHeader($name);
177
    }
178
179
    /**
180
     * Return's the header value for the passed name.
181
     *
182
     * @param string $name The name of the header to return the value for
183
     *
184
     * @return mixed The header value
185
     * \InvalidArgumentException Is thrown, if the header with the passed name is NOT available
186
     */
187 8
    protected function getHeader($name)
188
    {
189 8
        return $this->getSubject()->getHeader($name);
190
    }
191
192
    /**
193
     * Add's the header with the passed name and position, if not NULL.
194
     *
195
     * @param string $name The header name to add
196
     *
197
     * @return integer The new headers position
198
     */
199
    protected function addHeader($name)
200
    {
201
        return $this->getSubject()->addHeader($name);
202
    }
203
204
    /**
205
     * Return's TRUE if the passed SKU is the actual one.
206
     *
207
     * @param string $sku The SKU to check
208
     *
209
     * @return boolean TRUE if the passed SKU is the actual one
210
     */
211 1
    protected function isLastSku($sku)
212
    {
213 1
        return $this->getSubject()->getLastSku() === $sku;
214
    }
215
216
    /**
217
     * Return's the ID of the product that has been created recently.
218
     *
219
     * @return string The entity Id
220
     */
221 4
    protected function getLastEntityId()
222
    {
223 4
        return $this->getSubject()->getLastEntityId();
224
    }
225
226
    /**
227
     * Return's the source date format to use.
228
     *
229
     * @return string The source date format
230
     */
231 1
    protected function getSourceDateFormat()
232
    {
233 1
        return $this->getSubject()->getSourceDateFormat();
234
    }
235
236
    /**
237
     * Cast's the passed value based on the backend type information.
238
     *
239
     * @param string $backendType The backend type to cast to
240
     * @param mixed  $value       The value to be casted
241
     *
242
     * @return mixed The casted value
243
     */
244 1
    protected function castValueByBackendType($backendType, $value)
245
    {
246 1
        return $this->getSubject()->castValueByBackendType($backendType, $value);
247
    }
248
249
    /**
250
     * Set's the store view code the create the product/attributes for.
251
     *
252
     * @param string $storeViewCode The store view code
253
     *
254
     * @return void
255
     */
256 3
    protected function setStoreViewCode($storeViewCode)
257
    {
258 3
        $this->getSubject()->setStoreViewCode($storeViewCode);
259 3
    }
260
261
    /**
262
     * Return's the store view code the create the product/attributes for.
263
     *
264
     * @param string|null $default The default value to return, if the store view code has not been set
265
     *
266
     * @return string The store view code
267
     */
268
    protected function getStoreViewCode($default = null)
269
    {
270
        return $this->getSubject()->getStoreViewCode($default);
271
    }
272
273
    /**
274
     * Prepare's the store view code in the subject.
275
     *
276
     * @return void
277
     */
278 3
    protected function prepareStoreViewCode()
279
    {
280
281
        // re-set the store view code
282 3
        $this->setStoreViewCode(null);
283
284
        // initialize the store view code
285 3
        if ($storeViewCode = $this->getValue(ColumnKeys::STORE_VIEW_CODE)) {
286 2
            $this->setStoreViewCode($storeViewCode);
287
        }
288 3
    }
289
290
    /**
291
     * Tries to format the passed value to a valid date with format 'Y-m-d H:i:s'.
292
     * If the passed value is NOT a valid date, NULL will be returned.
293
     *
294
     * @param string|null $value The value to format
295
     *
296
     * @return string The formatted date
297
     */
298 1
    protected function formatDate($value)
299
    {
300
301
        // create a DateTime instance from the passed value
302 1
        if ($dateTime = \DateTime::createFromFormat($this->getSourceDateFormat(), $value)) {
303 1
            return $dateTime->format('Y-m-d H:i:s');
304
        }
305
306
        // return NULL, if the passed value is NOT a valid date
307
        return null;
308
    }
309
310
    /**
311
     * Extracts the elements of the passed value by exploding them
312
     * with the also passed delimiter.
313
     *
314
     * @param string      $value     The value to extract
315
     * @param string|null $delimiter The delimiter used to extrace the elements
316
     *
317
     * @return array The exploded values
318
     */
319
    protected function explode($value, $delimiter = null)
320
    {
321
322
        // load the default multiple field delimiter
323
        if ($delimiter === null) {
324
            $delimiter = $this->getMultipleFieldDelimiter();
325
        }
326
327
        // explode and return the array with the values, by using the delimiter
328
        return explode($delimiter, $value);
329
    }
330
331
    /**
332
     * Query whether or not a value for the column with the passed name exists.
333
     *
334
     * @param string $name The column name to query for a valid value
335
     *
336
     * @return boolean TRUE if the value is set, else FALSE
337
     */
338 1
    protected function hasValue($name)
339
    {
340
341
        // query whether or not the header is available
342 1
        if ($this->hasHeader($name)) {
343
            // load the key for the row
344 1
            $headerValue = $this->getHeader($name);
345
346
            // query whether the rows column has a vaild value
347 1
            return (isset($this->row[$headerValue]) && $this->row[$headerValue] != '');
348
        }
349
350
        // return FALSE if not
351
        return false;
352
    }
353
354
    /**
355
     * Set the value in the passed column name.
356
     *
357
     * @param string $name  The column name to set the value for
358
     * @param mixed  $value The value to set
359
     *
360
     * @return void
361
     */
362
    protected function setValue($name, $value)
363
    {
364
        $this->row[$this->getHeader($name)] = $value;
365
    }
366
367
    /**
368
     * Resolve's the value with the passed colum name from the actual row. If a callback will
369
     * be passed, the callback will be invoked with the found value as parameter. If
370
     * the value is NULL or empty, the default value will be returned.
371
     *
372
     * @param string        $name     The name of the column to return the value for
373
     * @param mixed|null    $default  The default value, that has to be returned, if the row's value is empty
374
     * @param callable|null $callback The callback that has to be invoked on the value, e. g. to format it
375
     *
376
     * @return mixed|null The, almost formatted, value
377
     */
378 8
    protected function getValue($name, $default = null, callable $callback = null)
379
    {
380
381
        // initialize the value
382 8
        $value = null;
383
384
        // query whether or not the header is available
385 8
        if ($this->hasHeader($name)) {
386
            // load the header value
387 8
            $headerValue = $this->getHeader($name);
388
            // query wheter or not, the value with the requested key is available
389 8
            if ((isset($this->row[$headerValue]) && $this->row[$headerValue] != '')) {
390 8
                $value = $this->row[$headerValue];
391
            }
392
        }
393
394
        // query whether or not, a callback has been passed
395 8
        if ($value != null && is_callable($callback)) {
396 1
            $value = call_user_func($callback, $value);
397
        }
398
399
        // query whether or not
400 8
        if ($value == null && $default !== null) {
401 1
            $value = $default;
402
        }
403
404
        // return the value
405 8
        return $value;
406
    }
407
408
    /**
409
     * Initialize's and return's a new entity with the status 'create'.
410
     *
411
     * @param array $attr The attributes to merge into the new entity
412
     *
413
     * @return array The initialized entity
414
     */
415 5
    protected function initializeEntity(array $attr = array())
416
    {
417 5
        return array_merge(array(EntityStatus::MEMBER_NAME => EntityStatus::STATUS_CREATE), $attr);
418
    }
419
420
    /**
421
     * Merge's and return's the entity with the passed attributes and set's the
422
     * status to 'update'.
423
     *
424
     * @param array $entity The entity to merge the attributes into
425
     * @param array $attr   The attributes to be merged
426
     *
427
     * @return array The merged entity
428
     */
429 2
    protected function mergeEntity(array $entity, array $attr)
430
    {
431 2
        return array_merge($entity, $attr, array(EntityStatus::MEMBER_NAME => EntityStatus::STATUS_UPDATE));
432
    }
433
}
434