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

AbstractProductSubject::hasBeenProcessed()   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 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Subjects\AbstractProductSubject
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\Subjects;
22
23
use TechDivision\Import\Utils\RegistryKeys;
24
use TechDivision\Import\Subjects\AbstractSubject;
25
use TechDivision\Import\Product\Utils\MemberNames;
26
use TechDivision\Import\Product\Services\ProductProcessorInterface;
27
28
/**
29
 * The abstract product subject implementation that provides basic product
30
 * handling business logic.
31
 *
32
 * @author    Tim Wagner <[email protected]>
33
 * @copyright 2016 TechDivision GmbH <[email protected]>
34
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
35
 * @link      https://github.com/techdivision/import-product
36
 * @link      http://www.techdivision.com
37
 */
38
abstract class AbstractProductSubject extends AbstractSubject
39
{
40
41
    /**
42
     * The processor to read/write the necessary product data.
43
     *
44
     * @var \TechDivision\Import\Product\Services\ProductProcessorInterface
45
     */
46
    protected $productProcessor;
47
48
    /**
49
     * The available EAV attribute sets.
50
     *
51
     * @var array
52
     */
53
    protected $attributeSets = array();
54
55
    /**
56
     * The available stores.
57
     *
58
     * @var array
59
     */
60
    protected $stores = array();
61
62
    /**
63
     * The available store websites.
64
     *
65
     * @var array
66
     */
67
    protected $storeWebsites = array();
68
69
    /**
70
     * The available EAV attributes, grouped by their attribute set and the attribute set name as keys.
71
     *
72
     * @var array
73
     */
74
    protected $attributes = array();
75
76
    /**
77
     * The available tax classes.
78
     *
79
     * @var array
80
     */
81
    protected $taxClasses = array();
82
83
    /**
84
     * The available categories.
85
     *
86
     * @var array
87
     */
88
    protected $categories = array();
89
90
    /**
91
     * The available root categories.
92
     *
93
     * @var array
94
     */
95
    protected $rootCategories = array();
96
97
    /**
98
     * The ID of the product that has been created recently.
99
     *
100
     * @var string
101
     */
102
    protected $lastEntityId;
103
104
    /**
105
     * The SKU of the product that has been created recently.
106
     *
107
     * @var string
108
     */
109
    protected $lastSku;
110
111
    /**
112
     * The store view code the create the product/attributes for.
113
     *
114
     * @var string
115
     */
116
    protected $storeViewCode;
117
118
    /**
119
     * The default store.
120
     *
121
     * @var array
122
     */
123
    protected $defaultStore;
124
125
    /**
126
     * The Magento 2 configuration.
127
     *
128
     * @var array
129
     */
130
    protected $coreConfigData;
131
132
    /**
133
     * The mapping for the SKUs to the created entity IDs.
134
     *
135
     * @var array
136
     */
137
    protected $skuEntityIdMapping = array();
138
139
    /**
140
     * The mapping for the SKUs to the store view codes.
141
     *
142
     * @var array
143
     */
144
    protected $skuStoreViewCodeMapping = array();
145
146
    /**
147
     * Set's the product processor instance.
148
     *
149
     * @param \TechDivision\Import\Product\Services\ProductProcessorInterface $productProcessor The product processor instance
150
     *
151
     * @return void
152
     */
153 3
    public function setProductProcessor(ProductProcessorInterface $productProcessor)
154
    {
155 3
        $this->productProcessor = $productProcessor;
156 3
    }
157
158
    /**
159
     * Return's the product processor instance.
160
     *
161
     * @return \TechDivision\Import\Services\ProductProcessorInterface The product processor instance
162
     */
163 3
    public function getProductProcessor()
164
    {
165 3
        return $this->productProcessor;
166
    }
167
168
    /**
169
     * Set's the SKU of the last imported product.
170
     *
171
     * @param string $lastSku The SKU
172
     *
173
     * @return void
174
     */
175
    public function setLastSku($lastSku)
176
    {
177
        $this->lastSku = $lastSku;
178
    }
179
180
    /**
181
     * Return's the SKU of the last imported product.
182
     *
183
     * @return string|null The SKU
184
     */
185
    public function getLastSku()
186
    {
187
        return $this->lastSku;
188
    }
189
190
    /**
191
     * Set's the ID of the product that has been created recently.
192
     *
193
     * @param string $lastEntityId The entity ID
194
     *
195
     * @return void
196
     */
197 1
    public function setLastEntityId($lastEntityId)
198
    {
199 1
        $this->lastEntityId = $lastEntityId;
200 1
    }
201
202
    /**
203
     * Return's the ID of the product that has been created recently.
204
     *
205
     * @return string The entity Id
206
     */
207
    public function getLastEntityId()
208
    {
209
        return $this->lastEntityId;
210
    }
211
212
    /**
213
     * Queries whether or not the SKU has already been processed.
214
     *
215
     * @param string $sku The SKU to check been processed
216
     *
217
     * @return boolean TRUE if the SKU has been processed, else FALSE
218
     */
219
    public function hasBeenProcessed($sku)
220
    {
221
        return isset($this->skuEntityIdMapping[$sku]);
222
    }
223
224
    /**
225
     * Add the passed SKU => entity ID mapping.
226
     *
227
     * @param string $sku The SKU
228
     *
229
     * @return void
230
     * @uses \Import\Csv\Actions\ProductImportBunchAction::getLastEntityId()
231
     */
232
    public function addSkuEntityIdMapping($sku)
233
    {
234
        $this->skuEntityIdMapping[$sku] = $this->getLastEntityId();
235
    }
236
237
    /**
238
     * Add the passed SKU => store view code mapping.
239
     *
240
     * @param string $sku           The SKU
241
     * @param string $storeViewCode The store view code
242
     *
243
     * @return void
244
     */
245
    public function addSkuStoreViewCodeMapping($sku, $storeViewCode)
246
    {
247
        $this->skuStoreViewCodeMapping[$sku] = $storeViewCode;
248
    }
249
250
    /**
251
     * Set's the store view code the create the product/attributes for.
252
     *
253
     * @param string $storeViewCode The store view code
254
     *
255
     * @return void
256
     */
257 3
    public function setStoreViewCode($storeViewCode)
258
    {
259 3
        $this->storeViewCode = $storeViewCode;
260 3
    }
261
262
    /**
263
     * Return's the store view code the create the product/attributes for.
264
     *
265
     * @param string|null $default The default value to return, if the store view code has not been set
266
     *
267
     * @return string The store view code
268
     */
269
    public function getStoreViewCode($default = null)
270
    {
271
272
        // return the store view code, if available
273
        if ($this->storeViewCode != null) {
274
            return $this->storeViewCode;
275
        }
276
277
        // if NOT and a default code is available
278
        if ($default != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $default of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
279
            // return the default value
280
            return $default;
281
        }
282
    }
283
284
    /**
285
     * Return's the default store.
286
     *
287
     * @return array The default store
288
     */
289
    public function getDefaultStore()
290
    {
291
        return $this->defaultStore;
292
    }
293
294
    /**
295
     * Intializes the previously loaded global data for exactly one bunch.
296
     *
297
     * @return void
298
     * @see \Importer\Csv\Actions\ProductImportAction::prepare()
299
     */
300
    public function setUp()
301
    {
302
303
        // load the status of the actual import
304
        $status = $this->getRegistryProcessor()->getAttribute($this->getSerial());
305
306
        // load the global data we've prepared initially
307
        $this->attributeSets = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::ATTRIBUTE_SETS];
308
        $this->storeWebsites =  $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::STORE_WEBSITES];
309
        $this->attributes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::EAV_ATTRIBUTES];
310
        $this->stores = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::STORES];
311
        $this->taxClasses = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::TAX_CLASSES];
312
        $this->categories = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::CATEGORIES];
313
        $this->rootCategories = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::ROOT_CATEGORIES];
314
        $this->defaultStore = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::DEFAULT_STORE];
315
        $this->coreConfigData = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::CORE_CONFIG_DATA];
316
317
        // prepare the callbacks
318
        parent::setUp();
319
    }
320
321
    /**
322
     * Clean up the global data after importing the bunch.
323
     *
324
     * @return void
325
     */
326
    public function tearDown()
327
    {
328
329
        // invoke the parent method
330
        parent::tearDown();
331
332
        // load the registry processor
333
        $registryProcessor = $this->getRegistryProcessor();
334
335
        // update the status with the SKU => entity ID mapping
336
        $registryProcessor->mergeAttributesRecursive(
337
            $this->getSerial(),
338
            array()
339
        );
340
341
        // update the status
342
        $registryProcessor->mergeAttributesRecursive(
343
            $this->getSerial(),
344
            array(
345
                RegistryKeys::FILES => array($this->getFilename() => array(RegistryKeys::STATUS => 1)),
346
                RegistryKeys::SKU_ENTITY_ID_MAPPING => $this->skuEntityIdMapping,
347
                RegistryKeys::SKU_STORE_VIEW_CODE_MAPPING => $this->skuStoreViewCodeMapping
348
            )
349
        );
350
    }
351
352
    /**
353
     * Return's the attributes for the attribute set of the product that has to be created.
354
     *
355
     * @return array The attributes
356
     * @throws \Exception Is thrown if the attributes for the actual attribute set are not available
357
     */
358
    public function getAttributes()
359
    {
360
361
        // load the attribute set of the product that has to be created.
362
        $attributeSet = $this->getAttributeSet();
0 ignored issues
show
Bug introduced by
The method getAttributeSet() does not exist on TechDivision\Import\Prod...\AbstractProductSubject. Did you maybe mean getAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
363
364
        // query whether or not, the requested EAV attributes are available
365
        if (isset($this->attributes[$attributeSetName = $attributeSet[MemberNames::ATTRIBUTE_SET_NAME]])) {
366
            return $this->attributes[$attributeSetName];
367
        }
368
369
        // throw an exception, if not
370
        throw new \Exception(
371
            sprintf(
372
                'Found invalid attribute set name %s in file %s on line %d',
373
                $attributeSetName,
374
                $this->getFilename(),
375
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
376
            )
377
        );
378
    }
379
380
    /**
381
     * Return's the store ID of the actual row, or of the default store
382
     * if no store view code is set in the CSV file.
383
     *
384
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
385
     *
386
     * @return integer The ID of the actual store
387
     * @throws \Exception Is thrown, if the store with the actual code is not available
388
     */
389
    public function getRowStoreId($default = null)
390
    {
391
392
        // initialize the default store view code, if not passed
393
        if ($default == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $default of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
394
            $defaultStore = $this->getDefaultStore();
395
            $default = $defaultStore[MemberNames::CODE];
396
        }
397
398
        // load the store view code the create the product/attributes for
399
        $storeViewCode = $this->getStoreViewCode($default);
400
401
        // query whether or not, the requested store is available
402
        if (isset($this->stores[$storeViewCode])) {
403
            return (integer) $this->stores[$storeViewCode][MemberNames::STORE_ID];
404
        }
405
406
        // throw an exception, if not
407
        throw new \Exception(
408
            sprintf(
409
                'Found invalid store view code %s in file %s on line %d',
410
                $storeViewCode,
411
                $this->getFilename(),
412
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
413
            )
414
        );
415
    }
416
417
    /**
418
     * Return's the tax class ID for the passed tax class name.
419
     *
420
     * @param string $taxClassName The tax class name to return the ID for
421
     *
422
     * @return integer The tax class ID
423
     * @throws \Exception Is thrown, if the tax class with the requested name is not available
424
     */
425 View Code Duplication
    public function getTaxClassIdByTaxClassName($taxClassName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
426
    {
427
428
        // query whether or not, the requested tax class is available
429
        if (isset($this->taxClasses[$taxClassName])) {
430
            return (integer) $this->taxClasses[$taxClassName][MemberNames::CLASS_ID];
431
        }
432
433
        // throw an exception, if not
434
        throw new \Exception(
435
            sprintf(
436
                'Found invalid tax class name %s in file %s on line %d',
437
                $taxClassName,
438
                $this->getFilename(),
439
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
440
            )
441
        );
442
    }
443
444
    /**
445
     * Return's the store website for the passed code.
446
     *
447
     * @param string $code The code of the store website to return the ID for
448
     *
449
     * @return integer The store website ID
450
     * @throws \Exception Is thrown, if the store website with the requested code is not available
451
     */
452 View Code Duplication
    public function getStoreWebsiteIdByCode($code)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
453
    {
454
455
        // query whether or not, the requested store website is available
456
        if (isset($this->storeWebsites[$code])) {
457
            return (integer) $this->storeWebsites[$code][MemberNames::WEBSITE_ID];
458
        }
459
460
        // throw an exception, if not
461
        throw new \Exception(
462
            sprintf(
463
                'Found invalid website code %s in file %s on line %d',
464
                $code,
465
                $this->getFilename(),
466
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
467
            )
468
        );
469
    }
470
471
    /**
472
     * Return's the attribute set with the passed attribute set name.
473
     *
474
     * @param string $attributeSetName The name of the requested attribute set
475
     *
476
     * @return array The attribute set data
477
     * @throws \Exception Is thrown, if the attribute set with the passed name is not available
478
     */
479 View Code Duplication
    public function getAttributeSetByAttributeSetName($attributeSetName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
480
    {
481
482
        // query whether or not, the requested attribute set is available
483
        if (isset($this->attributeSets[$attributeSetName])) {
484
            return $this->attributeSets[$attributeSetName];
485
        }
486
487
        // throw an exception, if not
488
        throw new \Exception(
489
            sprintf(
490
                'Found invalid attribute set name %s in file %s on line %d',
491
                $attributeSetName,
492
                $this->getFilename(),
493
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
494
            )
495
        );
496
    }
497
498
    /**
499
     * Return's the category with the passed path.
500
     *
501
     * @param string $path The path of the category to return
502
     *
503
     * @return array The category
504
     * @throws \Exception Is thrown, if the requested category is not available
505
     */
506 View Code Duplication
    public function getCategoryByPath($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
507
    {
508
509
        // query whether or not the category with the passed path exists
510
        if (isset($this->categories[$path])) {
511
            return $this->categories[$path];
512
        }
513
514
        // throw an exception, if not
515
        throw new \Exception(
516
            sprintf(
517
                'Can\'t find category with path %s in file %s on line %d',
518
                $path,
519
                $this->getFilename(),
520
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
521
            )
522
        );
523
    }
524
525
    /**
526
     * Return's the category with the passed ID.
527
     *
528
     * @param integer $categoryId The ID of the category to return
529
     *
530
     * @return array The category data
531
     * @throws \Exception Is thrown, if the category is not available
532
     */
533
    public function getCategory($categoryId)
534
    {
535
536
        // try to load the category with the passed ID
537
        foreach ($this->categories as $category) {
538
            if ($category[MemberNames::ENTITY_ID] == $categoryId) {
539
                return $category;
540
            }
541
        }
542
543
        // throw an exception if the category is NOT available
544
        throw new \Exception(
545
            sprintf(
546
                'Can\'t load category with ID %d in file %s on line %d',
547
                $categoryId,
548
                $this->getFilename(),
549
                $this->getLineNumber()
0 ignored issues
show
Bug introduced by
The method getLineNumber() does not seem to exist on object<TechDivision\Impo...AbstractProductSubject>.

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...
550
            )
551
        );
552
    }
553
554
    /**
555
     * Return's the root category for the actual view store.
556
     *
557
     * @return array The store's root category
558
     * @throws \Exception Is thrown if the root category for the passed store code is NOT available
559
     */
560
    public function getRootCategory()
561
    {
562
563
        // load the default store
564
        $defaultStore = $this->getDefaultStore();
565
566
        // load the actual store view code
567
        $storeViewCode = $this->getStoreViewCode($defaultStore[MemberNames::CODE]);
568
569
        // query weather or not we've a root category or not
570
        if (isset($this->rootCategories[$storeViewCode])) {
571
            return $this->rootCategories[$storeViewCode];
572
        }
573
574
        // throw an exception if the root category is NOT available
575
        throw new \Exception(sprintf('Root category for %s is not available', $storeViewCode));
576
    }
577
}
578