Completed
Push — 22.x ( 064ead...4f6cd8 )
by Tim
01:47
created

BunchSubject::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 7
cp 0
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Subjects\BunchSubject
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 Doctrine\Common\Collections\Collection;
24
use League\Event\EmitterInterface;
25
use TechDivision\Import\Loaders\LoaderInterface;
26
use TechDivision\Import\Services\RegistryProcessorInterface;
27
use TechDivision\Import\Utils\Generators\GeneratorInterface;
28
use TechDivision\Import\Utils\StoreViewCodes;
29
use TechDivision\Import\Product\Utils\MemberNames;
30
use TechDivision\Import\Product\Utils\RegistryKeys;
31
use TechDivision\Import\Product\Utils\VisibilityKeys;
32
use TechDivision\Import\Product\Utils\ConfigurationKeys;
33
use TechDivision\Import\Subjects\ExportableTrait;
34
use TechDivision\Import\Subjects\FileUploadTrait;
35
use TechDivision\Import\Subjects\ExportableSubjectInterface;
36
use TechDivision\Import\Subjects\FileUploadSubjectInterface;
37
use TechDivision\Import\Subjects\UrlKeyAwareSubjectInterface;
38
use TechDivision\Import\Subjects\CleanUpColumnsSubjectInterface;
39
40
/**
41
 * The subject implementation that handles the business logic to persist products.
42
 *
43
 * @author    Tim Wagner <[email protected]>
44
 * @copyright 2016 TechDivision GmbH <[email protected]>
45
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
46
 * @link      https://github.com/techdivision/import-product
47
 * @link      http://www.techdivision.com
48
 */
49
class BunchSubject extends AbstractProductSubject implements ExportableSubjectInterface, FileUploadSubjectInterface, UrlKeyAwareSubjectInterface, CleanUpColumnsSubjectInterface
50
{
51
52
    /**
53
     * The trait that implements the export functionality.
54
     *
55
     * @var \TechDivision\Import\Subjects\ExportableTrait
56
     */
57
    use ExportableTrait;
58
59
    /**
60
     * The trait that provides file upload functionality.
61
     *
62
     * @var \TechDivision\Import\Subjects\FileUploadTrait
63
     */
64
    use FileUploadTrait;
65
66
    /**
67
     * The array with the pre-loaded entity IDs.
68
     *
69
     * @var array
70
     */
71
    protected $preLoadedEntityIds = array();
72
73
    /**
74
     * Mappings for the table column => CSV column header.
75
     *
76
     * @var array
77
     */
78
    protected $headerStockMappings = array(
79
        'qty'                         => array('qty', 'float'),
80
        'min_qty'                     => array('out_of_stock_qty', 'float'),
81
        'use_config_min_qty'          => array('use_config_min_qty', 'int'),
82
        'is_qty_decimal'              => array('is_qty_decimal', 'int'),
83
        'backorders'                  => array('allow_backorders', 'int'),
84
        'use_config_backorders'       => array('use_config_backorders', 'int'),
85
        'min_sale_qty'                => array('min_cart_qty', 'float'),
86
        'use_config_min_sale_qty'     => array('use_config_min_sale_qty', 'int'),
87
        'max_sale_qty'                => array('max_cart_qty', 'float'),
88
        'use_config_max_sale_qty'     => array('use_config_max_sale_qty', 'int'),
89
        'is_in_stock'                 => array('is_in_stock', 'int'),
90
        'notify_stock_qty'            => array('notify_on_stock_below', 'float'),
91
        'use_config_notify_stock_qty' => array('use_config_notify_stock_qty', 'int'),
92
        'manage_stock'                => array('manage_stock', 'int'),
93
        'use_config_manage_stock'     => array('use_config_manage_stock', 'int'),
94
        'use_config_qty_increments'   => array('use_config_qty_increments', 'int'),
95
        'qty_increments'              => array('qty_increments', 'float'),
96
        'use_config_enable_qty_inc'   => array('use_config_enable_qty_inc', 'int'),
97
        'enable_qty_increments'       => array('enable_qty_increments', 'int'),
98
        'is_decimal_divided'          => array('is_decimal_divided', 'int'),
99
    );
100
101
    /**
102
     * The array with the available visibility keys.
103
     *
104
     * @var array
105
     */
106
    protected $availableVisibilities = array(
107
        'Not Visible Individually' => VisibilityKeys::VISIBILITY_NOT_VISIBLE,
108
        'Catalog'                  => VisibilityKeys::VISIBILITY_IN_CATALOG,
109
        'Search'                   => VisibilityKeys::VISIBILITY_IN_SEARCH,
110
        'Catalog, Search'          => VisibilityKeys::VISIBILITY_BOTH
111
    );
112
113
    /**
114
     * The default callback mappings for the Magento standard product attributes.
115
     *
116
     * @var array
117
     */
118
    protected $defaultCallbackMappings = array(
119
        'visibility'           => array('import_product.callback.visibility'),
120
        'tax_class_id'         => array('import_product.callback.tax.class'),
121
        'bundle_price_type'    => array('import_product_bundle.callback.bundle.type'),
122
        'bundle_sku_type'      => array('import_product_bundle.callback.bundle.type'),
123
        'bundle_weight_type'   => array('import_product_bundle.callback.bundle.type'),
124
        'bundle_price_view'    => array('import_product_bundle.callback.bundle.price.view'),
125
        'bundle_shipment_type' => array('import_product_bundle.callback.bundle.shipment.type')
126
    );
127
128
    /**
129
     * The available entity types.
130
     *
131
     * @var array
132
     */
133
    protected $entityTypes = array();
134
135
    /**
136
     * The media roles loader instance.
137
     *
138
     * @var \TechDivision\Import\Loaders\LoaderInterface
139
     */
140
    protected $mediaRolesLoader;
141
142
    /**
143
     * BunchSubject constructor
144
     *
145
     * @param RegistryProcessorInterface $registryProcessor          The registry processor instance
146
     * @param GeneratorInterface         $coreConfigDataUidGenerator The generator instance
147
     * @param Collection                 $systemLoggers              The system logger collection
148
     * @param EmitterInterface           $emitter                    The emitter instance
149
     * @param LoaderInterface            $loader                     The media type loader instance
150
     */
151 18
    public function __construct(
152
        RegistryProcessorInterface $registryProcessor,
153
        GeneratorInterface $coreConfigDataUidGenerator,
154
        Collection $systemLoggers,
155
        EmitterInterface $emitter,
156
        LoaderInterface $loader
157
    ) {
158
159
        // set the loader for the media roles
160 18
        $this->mediaRolesLoader = $loader;
161
162
        // pass the other instances to the parent constructor
163 18
        parent::__construct($registryProcessor, $coreConfigDataUidGenerator, $systemLoggers, $emitter);
164 18
    }
165
166
    /**
167
     * Intializes the previously loaded global data for exactly one bunch.
168
     *
169
     * @param string $serial The serial of the actual import
170
     *
171
     * @return void
172
     */
173 18
    public function setUp($serial)
174
    {
175
176
        // load the status of the actual import
177 18
        $status = $this->getRegistryProcessor()->getAttribute(RegistryKeys::STATUS);
178
179
        // load the global data we've prepared initially
180 18
        $this->entityTypes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::ENTITY_TYPES];
181
182
        // initialize the flag whether to copy images or not
183 18
        if ($this->getConfiguration()->hasParam(ConfigurationKeys::COPY_IMAGES)) {
184
            $this->setCopyImages($this->getConfiguration()->getParam(ConfigurationKeys::COPY_IMAGES));
185
        }
186
187
        // initialize the flag whether to override images or not
188
        // @todo https://github.com/techdivision/import/issues/181
189
        //       Create new constant ConfigurationKeys::OVERRIDE_IMAGES for future release
190 18
        if ($this->getConfiguration()->hasParam('override-images')) {
191
            $this->setOverrideImages($this->getConfiguration()->getParam('override-images'));
192
        }
193
194
        // initialize media directory => can be absolute or relative
195 18 View Code Duplication
        if ($this->getConfiguration()->hasParam(ConfigurationKeys::MEDIA_DIRECTORY)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
196
            try {
197
                $this->setMediaDir($this->resolvePath($this->getConfiguration()->getParam(ConfigurationKeys::MEDIA_DIRECTORY)));
198
            } catch (\InvalidArgumentException $iae) {
199
                $this->getSystemLogger()->warning($iae);
200
            }
201
        }
202
203
        // initialize images directory => can be absolute or relative
204 18 View Code Duplication
        if ($this->getConfiguration()->hasParam(ConfigurationKeys::IMAGES_FILE_DIRECTORY)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
205
            try {
206
                $this->setImagesFileDir($this->resolvePath($this->getConfiguration()->getParam(ConfigurationKeys::IMAGES_FILE_DIRECTORY)));
207
            } catch (\InvalidArgumentException $iae) {
208
                $this->getSystemLogger()->warning($iae);
209
            }
210
        }
211
212
        // invoke the parent method
213 18
        parent::setUp($serial);
214 18
    }
215
216
    /**
217
     * Clean up the global data after importing the bunch.
218
     *
219
     * @param string $serial The serial of the actual import
220
     *
221
     * @return void
222
     */
223
    public function tearDown($serial)
224
    {
225
226
        // invoke the parent method
227
        parent::tearDown($serial);
228
229
        // load the registry processor
230
        $registryProcessor = $this->getRegistryProcessor();
231
232
        // update the status
233
        $registryProcessor->mergeAttributesRecursive(
234
            RegistryKeys::STATUS,
235
            array(
236
                RegistryKeys::PRE_LOADED_ENTITY_IDS => $this->preLoadedEntityIds,
237
            )
238
        );
239
    }
240
241
    /**
242
     * Return's the default callback mappings.
243
     *
244
     * @return array The default callback mappings
245
     */
246
    public function getDefaultCallbackMappings()
247
    {
248
        return $this->defaultCallbackMappings;
249
    }
250
251
    /**
252
     * Return's the mappings for the table column => CSV column header.
253
     *
254
     * @return array The header stock mappings
255
     */
256 1
    public function getHeaderStockMappings()
257
    {
258 1
        return $this->headerStockMappings;
259
    }
260
261
    /**
262
     * Return's the visibility key for the passed visibility string.
263
     *
264
     * @param string $visibility The visibility string to return the key for
265
     *
266
     * @return integer The requested visibility key
267
     * @throws \Exception Is thrown, if the requested visibility is not available
268
     */
269
    public function getVisibilityIdByValue($visibility)
270
    {
271
272
        // query whether or not, the requested visibility is available
273
        if (isset($this->availableVisibilities[$visibility])) {
274
            // load the visibility ID, add the mapping and return the ID
275
            return $this->availableVisibilities[$visibility];
276
        }
277
278
        // throw an exception, if not
279
        throw new \Exception(
280
            $this->appendExceptionSuffix(
281
                sprintf('Found invalid visibility %s', $visibility)
282
            )
283
        );
284
    }
285
286
    /**
287
     * Pre-load the entity ID for the passed product.
288
     *
289
     * @param array $product The product to be pre-loaded
290
     *
291
     * @return void
292
     */
293
    public function preLoadEntityId(array $product)
294
    {
295
        $this->preLoadedEntityIds[$product[MemberNames::SKU]] = $product[MemberNames::ENTITY_ID];
296
    }
297
298
    /**
299
     * Return's the entity type for the configured entity type code.
300
     *
301
     * @return array The requested entity type
302
     * @throws \Exception Is thrown, if the requested entity type is not available
303
     */
304 1 View Code Duplication
    public function getEntityType()
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...
305
    {
306
307
        // query whether or not the entity type with the passed code is available
308 1
        if (isset($this->entityTypes[$entityTypeCode = $this->getEntityTypeCode()])) {
309 1
            return $this->entityTypes[$entityTypeCode];
310
        }
311
312
        // throw a new exception
313
        throw new \Exception(
314
            $this->appendExceptionSuffix(
315
                sprintf('Requested entity type "%s" is not available', $entityTypeCode)
316
            )
317
        );
318
    }
319
320
    /**
321
     * Return's TRUE, if the passed URL key varchar value IS related with the actual PK.
322
     *
323
     * @param array $productVarcharAttribute The varchar value to check
324
     *
325
     * @return boolean TRUE if the URL key is related, else FALSE
326
     */
327
    public function isUrlKeyOf(array $productVarcharAttribute)
328
    {
329
        return ((integer) $productVarcharAttribute[MemberNames::ENTITY_ID] === (integer) $this->getLastEntityId()) &&
330
               ((integer) $productVarcharAttribute[MemberNames::STORE_ID] === (integer) $this->getRowStoreId(StoreViewCodes::ADMIN));
331
    }
332
333
    /**
334
     * Loads and returns the media roles.
335
     *
336
     * @return array The array with the media roles
337
     */
338
    public function getMediaRoles(): array
339
    {
340
        return $this->mediaRolesLoader->load();
341
    }
342
343
    /**
344
     * Merge the columns from the configuration with all image type columns to define which
345
     * columns should be cleaned-up.
346
     *
347
     * @return array The columns that has to be cleaned-up
348
     */
349
    public function getCleanUpColumns()
350
    {
351
352
        // initialize the array for the columns that has to be cleaned-up
353
        $cleanUpColumns = array();
0 ignored issues
show
Bug Compatibility introduced by
The expression array(); of type array adds the type array to the return on line 361 which is incompatible with the return type of the parent method TechDivision\Import\Prod...ject::getCleanUpColumns of type string.
Loading history...
354
355
        // query whether or not an array has been specified in the configuration
356
        if ($this->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_EMPTY_COLUMNS)) {
357
            $cleanUpColumns = $this->getConfiguration()->getParam(ConfigurationKeys::CLEAN_UP_EMPTY_COLUMNS);
358
        }
359
360
        // return the array with the column names
361
        return $cleanUpColumns;
362
    }
363
}
364