Completed
Pull Request — master (#76)
by Tim
06:30
created

AbstractProductSubject::setLastSku()   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 3
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\Product\Utils\MemberNames;
24
use TechDivision\Import\Subjects\AbstractEavSubject;
25
use TechDivision\Import\Subjects\EntitySubjectInterface;
26
use TechDivision\Import\Utils\FrontendInputTypes;
27
use TechDivision\Import\Utils\RegistryKeys;
28
29
/**
30
 * The abstract product subject implementation that provides basic product
31
 * handling business logic.
32
 *
33
 * @author    Tim Wagner <[email protected]>
34
 * @copyright 2016 TechDivision GmbH <[email protected]>
35
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link      https://github.com/techdivision/import-product
37
 * @link      http://www.techdivision.com
38
 */
39
abstract class AbstractProductSubject extends AbstractEavSubject implements EntitySubjectInterface
40
{
41
42
    /**
43
     * The available stores.
44
     *
45
     * @var array
46
     */
47
    protected $stores = array();
48
49
    /**
50
     * The available store websites.
51
     *
52
     * @var array
53
     */
54
    protected $storeWebsites = array();
55
56
    /**
57
     * The available EAV attributes, grouped by their attribute set and the attribute set name as keys.
58
     *
59
     * @var array
60
     */
61
    protected $attributes = array();
62
63
    /**
64
     * The available tax classes.
65
     *
66
     * @var array
67
     */
68
    protected $taxClasses = array();
69
70
    /**
71
     * The available categories.
72
     *
73
     * @var array
74
     */
75
    protected $categories = array();
76
77
    /**
78
     * The available link types.
79
     *
80
     * @var array
81
     */
82
    protected $linkTypes = array();
83
84
    /**
85
     * The ID of the product that has been created recently.
86
     *
87
     * @var string
88
     */
89
    protected $lastEntityId;
90
91
    /**
92
     * The SKU of the product that has been created recently.
93
     *
94
     * @var string
95
     */
96
    protected $lastSku;
97
98
    /**
99
     * The Magento 2 configuration.
100
     *
101
     * @var array
102
     */
103
    protected $coreConfigData;
104
105
    /**
106
     * The mapping for the SKUs to the created entity IDs.
107
     *
108
     * @var array
109
     */
110
    protected $skuEntityIdMapping = array();
111
112
    /**
113
     * The mapping for the SKUs to the store view codes.
114
     *
115
     * @var array
116
     */
117
    protected $skuStoreViewCodeMapping = array();
118
119
    /**
120
     * The array with the available image types and their label columns.
121
     *
122
     * @var array
123
     */
124
    protected $imageTypes = array(
125
        'base_image'      => 'base_image_label',
126
        'small_image'     => 'small_image_label',
127
        'swatch_image'    => 'swatch_image_label',
128
        'thumbnail_image' => 'thumbnail_image_label'
129
    );
130
131
    /**
132
     * Mappings for attribute code => CSV column header.
133
     *
134
     * @var array
135
     */
136
    protected $headerMappings = array(
137
        'product_online'       => 'status',
138
        'tax_class_name'       => 'tax_class_id',
139
        'bundle_price_type'    => 'price_type',
140
        'bundle_sku_type'      => 'sku_type',
141
        'bundle_price_view'    => 'price_view',
142
        'bundle_weight_type'   => 'weight_type',
143
        'base_image'           => 'image',
144
        'base_image_label'     => 'image_label',
145
        'thumbnail_image'      => 'thumbnail',
146
        'thumbnail_image_label'=> 'thumbnail_label',
147
        'bundle_shipment_type' => 'shipment_type',
148
        'related_skus'         => 'relation_skus',
149
        'related_position'     => 'relation_position',
150
        'crosssell_skus'       => 'cross_sell_skus',
151
        'crosssell_position'   => 'cross_sell_position',
152
        'upsell_skus'          => 'up_sell_skus',
153
        'upsell_position'      => 'up_sell_position'
154
    );
155
156
    /**
157
     * The default mappings for the user defined attributes, based on the attributes frontend input type.
158
     *
159
     * @var array
160
     */
161
    protected $defaultFrontendInputCallbackMappings = array(
162
        FrontendInputTypes::SELECT      => 'import_product.callback.select',
163
        FrontendInputTypes::MULTISELECT => 'import_product.callback.multiselect',
164
        FrontendInputTypes::BOOLEAN     => 'import_product.callback.boolean'
165
    );
166
167
    /**
168
     * Return's the default callback frontend input mappings for the user defined attributes.
169
     *
170
     * @return array The default frontend input callback mappings
171
     */
172 18
    public function getDefaultFrontendInputCallbackMappings()
173
    {
174 18
        return $this->defaultFrontendInputCallbackMappings;
175
    }
176
177
    /**
178
     * Return's the available link types.
179
     *
180
     * @return array The link types
181
     */
182
    public function getLinkTypes()
183
    {
184
        return $this->linkTypes;
185
    }
186
187
    /**
188
     * Set's the SKU of the last imported product.
189
     *
190
     * @param string $lastSku The SKU
191
     *
192
     * @return void
193
     */
194
    public function setLastSku($lastSku)
195
    {
196
        $this->lastSku = $lastSku;
197
    }
198
199
    /**
200
     * Return's the SKU of the last imported product.
201
     *
202
     * @return string|null The SKU
203
     */
204
    public function getLastSku()
205
    {
206
        return $this->lastSku;
207
    }
208
209
    /**
210
     * Set's the ID of the product that has been created recently.
211
     *
212
     * @param string $lastEntityId The entity ID
213
     *
214
     * @return void
215
     */
216
    public function setLastEntityId($lastEntityId)
217
    {
218
        $this->lastEntityId = $lastEntityId;
219
    }
220
221
    /**
222
     * Return's the ID of the product that has been created recently.
223
     *
224
     * @return string The entity Id
225
     */
226
    public function getLastEntityId()
227
    {
228
        return $this->lastEntityId;
229
    }
230
231
    /**
232
     * Queries whether or not the SKU has already been processed.
233
     *
234
     * @param string $sku The SKU to check been processed
235
     *
236
     * @return boolean TRUE if the SKU has been processed, else FALSE
237
     */
238
    public function hasBeenProcessed($sku)
239
    {
240
        return isset($this->skuEntityIdMapping[$sku]);
241
    }
242
243
    /**
244
     * Add the passed SKU => entity ID mapping.
245
     *
246
     * @param string $sku The SKU
247
     *
248
     * @return void
249
     */
250
    public function addSkuEntityIdMapping($sku)
251
    {
252
        $this->skuEntityIdMapping[$sku] = $this->getLastEntityId();
253
    }
254
255
    /**
256
     * Add the passed SKU => store view code mapping.
257
     *
258
     * @param string $sku           The SKU
259
     * @param string $storeViewCode The store view code
260
     *
261
     * @return void
262
     */
263
    public function addSkuStoreViewCodeMapping($sku, $storeViewCode)
264
    {
265
        $this->skuStoreViewCodeMapping[$sku] = $storeViewCode;
266
    }
267
268
    /**
269
     * Intializes the previously loaded global data for exactly one bunch.
270
     *
271
     * @param string $serial The serial of the actual import
272
     *
273
     * @return void
274
     */
275 18
    public function setUp($serial)
276
    {
277
278
        // load the status of the actual import
279 18
        $status = $this->getRegistryProcessor()->getAttribute($serial);
280
281
        // load the global data we've prepared initially
282 18
        $this->linkTypes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::LINK_TYPES];
283 18
        $this->categories = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::CATEGORIES];
284 18
        $this->taxClasses = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::TAX_CLASSES];
285 18
        $this->storeWebsites =  $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::STORE_WEBSITES];
286
287
        // merge the image types with the values found in the configuration
288 18
        $this->imageTypes = array_merge($this->imageTypes, $this->getConfiguration()->getImageTypes());
289
290
        // invoke the parent method
291 18
        parent::setUp($serial);
292 18
    }
293
294
    /**
295
     * Clean up the global data after importing the bunch.
296
     *
297
     * @param string $serial The serial of the actual import
298
     *
299
     * @return void
300
     */
301
    public function tearDown($serial)
302
    {
303
304
        // invoke the parent method
305
        parent::tearDown($serial);
306
307
        // load the registry processor
308
        $registryProcessor = $this->getRegistryProcessor();
309
310
        // update the status
311
        $registryProcessor->mergeAttributesRecursive(
312
            $serial,
313
            array(
314
                RegistryKeys::FILES => array($this->getFilename() => array(RegistryKeys::STATUS => 1)),
315
                RegistryKeys::SKU_ENTITY_ID_MAPPING => $this->skuEntityIdMapping,
316
                RegistryKeys::SKU_STORE_VIEW_CODE_MAPPING => $this->skuStoreViewCodeMapping
317
            )
318
        );
319
    }
320
321
    /**
322
     * Return's the available image types.
323
     *
324
     * @return array The array with the available image types
325
     */
326
    public function getImageTypes()
327
    {
328
        return $this->imageTypes;
329
    }
330
331
    /**
332
     * Return's the store ID of the actual row, or of the default store
333
     * if no store view code is set in the CSV file.
334
     *
335
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
336
     *
337
     * @return integer The ID of the actual store
338
     * @throws \Exception Is thrown, if the store with the actual code is not available
339
     */
340
    public function getRowStoreId($default = null)
341
    {
342
343
        // initialize the default store view code, if not passed
344
        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...
345
            $defaultStore = $this->getDefaultStore();
346
            $default = $defaultStore[MemberNames::CODE];
347
        }
348
349
        // load the store view code the create the product/attributes for
350
        $storeViewCode = $this->getStoreViewCode($default);
351
352
        // query whether or not, the requested store is available
353
        if (isset($this->stores[$storeViewCode])) {
354
            return (integer) $this->stores[$storeViewCode][MemberNames::STORE_ID];
355
        }
356
357
        // throw an exception, if not
358
        throw new \Exception(
359
            $this->appendExceptionSuffix(
360
                sprintf('Found invalid store view code %s', $storeViewCode)
361
            )
362
        );
363
    }
364
365
    /**
366
     * Return's the tax class ID for the passed tax class name.
367
     *
368
     * @param string $taxClassName The tax class name to return the ID for
369
     *
370
     * @return integer The tax class ID
371
     * @throws \Exception Is thrown, if the tax class with the requested name is not available
372
     */
373 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...
374
    {
375
376
        // query whether or not, the requested tax class is available
377
        if (isset($this->taxClasses[$taxClassName])) {
378
            return (integer) $this->taxClasses[$taxClassName][MemberNames::CLASS_ID];
379
        }
380
381
        // throw an exception, if not
382
        throw new \Exception(
383
            $this->appendExceptionSuffix(
384
                sprintf('Found invalid tax class name %s', $taxClassName)
385
            )
386
        );
387
    }
388
389
    /**
390
     * Return's the store website for the passed code.
391
     *
392
     * @param string $code The code of the store website to return the ID for
393
     *
394
     * @return integer The store website ID
395
     * @throws \Exception Is thrown, if the store website with the requested code is not available
396
     */
397 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...
398
    {
399
400
        // query whether or not, the requested store website is available
401
        if (isset($this->storeWebsites[$code])) {
402
            return (integer) $this->storeWebsites[$code][MemberNames::WEBSITE_ID];
403
        }
404
405
        // throw an exception, if not
406
        throw new \Exception(
407
            $this->appendExceptionSuffix(
408
                sprintf('Found invalid website code %s', $code)
409
            )
410
        );
411
    }
412
413
    /**
414
     * Return's the category with the passed path.
415
     *
416
     * @param string $path The path of the category to return
417
     *
418
     * @return array The category
419
     * @throws \Exception Is thrown, if the requested category is not available
420
     */
421
    public function getCategoryByPath($path)
422
    {
423
424
        // query whether or not the category with the passed path exists
425
        if (isset($this->categories[$path])) {
426
            return $this->categories[$path];
427
        }
428
429
        // throw an exception, if not
430
        throw new \Exception(
431
            $this->appendExceptionSuffix(
432
                sprintf('Can\'t find category with path %s', $path)
433
            )
434
        );
435
    }
436
437
    /**
438
     * Return's the category with the passed ID.
439
     *
440
     * @param integer $categoryId The ID of the category to return
441
     *
442
     * @return array The category data
443
     * @throws \Exception Is thrown, if the category is not available
444
     */
445
    public function getCategory($categoryId)
446
    {
447
448
        // try to load the category with the passed ID
449
        foreach ($this->categories as $category) {
450
            if ($category[MemberNames::ENTITY_ID] == $categoryId) {
451
                return $category;
452
            }
453
        }
454
455
        // throw an exception if the category is NOT available
456
        throw new \Exception(
457
            $this->appendExceptionSuffix(
458
                sprintf('Can\'t load category with ID %d', $categoryId)
459
            )
460
        );
461
    }
462
463
    /**
464
     * Return's the root category for the actual view store.
465
     *
466
     * @return array The store's root category
467
     * @throws \Exception Is thrown if the root category for the passed store code is NOT available
468
     */
469
    public function getRootCategory()
470
    {
471
472
        // load the default store
473
        $defaultStore = $this->getDefaultStore();
474
475
        // load the actual store view code
476
        $storeViewCode = $this->getStoreViewCode($defaultStore[MemberNames::CODE]);
477
478
        // query weather or not we've a root category or not
479
        if (isset($this->rootCategories[$storeViewCode])) {
480
            return $this->rootCategories[$storeViewCode];
481
        }
482
483
        // throw an exception if the root category is NOT available
484
        throw new \Exception(
485
            $this->appendExceptionSuffix(
486
                sprintf('Root category for %s is not available', $storeViewCode)
487
            )
488
        );
489
    }
490
}
491