Completed
Push — 15.x ( 7faf3d )
by Tim
03:57
created

ProductSourceItemObserver::createObserver()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 8
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 21
ccs 0
cts 12
cp 0
crap 6
rs 10
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Msi\Observers\ProductSourceItemObserver
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 2019 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-msi
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Msi\Observers;
22
23
use TechDivision\Import\Subjects\SubjectInterface;
24
use TechDivision\Import\Product\Msi\Utils\ColumnKeys;
25
use TechDivision\Import\Product\Msi\Utils\MemberNames;
26
use TechDivision\Import\Observers\ObserverFactoryInterface;
27
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
28
use TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface;
29
30
/**
31
 * Observer that extracts the MSI source item data to a specific CSV file.
32
 *
33
 * @author    Tim Wagner <[email protected]>
34
 * @copyright 2019 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-msi
37
 * @link      http://www.techdivision.com
38
 */
39
class ProductSourceItemObserver extends AbstractProductImportObserver implements ObserverFactoryInterface
40
{
41
42
    /**
43
     * The artefact type.
44
     *
45
     * @var string
46
     */
47
    const ARTEFACT_TYPE = 'inventory-msi';
48
49
    /**
50
     * The bunch processor instance.
51
     *
52
     * @var \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface
53
     */
54
    protected $processor;
55
56
    /**
57
     * The array for the inventory source templates, used if the column with the
58
     * inventory source data is NOT part of the actual file.
59
     *
60
     * @var array
61
     */
62
    protected $templateDefaultValues = array();
63
64
    /**
65
     * Initializes the observer with the bunch processor instance.
66
     *
67
     * @param \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface $processor The bunch processor instance
68
     */
69
    public function __construct(MsiBunchProcessorInterface $processor)
70
    {
71
        $this->processor = $processor;
72
    }
73
74
    /**
75
     * Will be invoked by the observer visitor when a factory has been defined to create the observer instance.
76
     *
77
     * @param \TechDivision\Import\Subjects\SubjectInterface $subject The subject instance
78
     *
79
     * @return \TechDivision\Import\Observers\ObserverInterface The observer instance
80
     */
81
    public function createObserver(SubjectInterface $subject)
82
    {
83
84
        // load the available inventory sources
85
        $inventorySources = $this->getProcessor()->loadInventorySources();
86
87
        // initialize the template for the inventory source
88
        // column, used if the column is NOT part of the file
89
        foreach ($inventorySources as $inventorySource) {
90
            // initialize the default values
91
            $defaultValue = array(
92
                sprintf('%s=%s', ColumnKeys::SOURCE_CODE, $inventorySource[MemberNames::SOURCE_CODE]),
93
                sprintf('%s=1', ColumnKeys::STATUS),
94
                sprintf('%s=%%d', ColumnKeys::QUANTITY)
95
            );
96
            // concatenate them with the multiple field delimiter and add them to the array with the templates
97
            $this->templateDefaultValues[] = implode($subject->getMultipleFieldDelimiter(), $defaultValue);
98
        }
99
100
        // return the instance itself
101
        return $this;
102
    }
103
104
    /**
105
     *  Return the bunch processor instance.
106
     *
107
     * @return \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface The bunch processor instance
108
     */
109
    protected function getProcessor()
110
    {
111
        return $this->processor;
112
    }
113
114
    /**
115
     * Process the observer's business logic.
116
     *
117
     * @return array The processed row
118
     */
119
    protected function process()
120
    {
121
122
        // query whether or not, we've found a new SKU => means we've found a new product
123
        if ($this->hasBeenProcessed($this->getValue(ColumnKeys::SKU))) {
124
            return;
125
        }
126
127
        // initialize the array for the artefacts
128
        // and the default values for the MSI data
129
        $artefacts = array();
130
        $defaultValues = array();
131
132
        // initialize a default value in case the column with the MSI
133
        // data is NOT available, that looks like
134
        //   source_code=default,status=1,quantity=<value-from-column-qty-if-available>
135
        if ($this->hasHeader(ColumnKeys::INVENTORY_SOURCE_ITEMS) === false) {
136
            $defaultValues = $this->loadDefaultValues($this->getValue(ColumnKeys::QTY, 0));
0 ignored issues
show
Bug introduced by
It seems like $this->getValue(TechDivi...ils\ColumnKeys::QTY, 0) can also be of type null; however, parameter $qty of TechDivision\Import\Prod...er::loadDefaultValues() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

136
            $defaultValues = $this->loadDefaultValues(/** @scrutinizer ignore-type */ $this->getValue(ColumnKeys::QTY, 0));
Loading history...
137
        }
138
139
        // unserialize the inventory source item data from the column that looks like
140
        //   source_code=default,quantity=10.0,status=1|source_code=default,quantity=11.0,status=0
141
        $msiInventorySources = $this->getValue(ColumnKeys::INVENTORY_SOURCE_ITEMS, $defaultValues, function ($value) {
142
            return $this->explode($value, '|');
143
        });
144
145
        // iterate over the found inventory source items
146
        foreach ($msiInventorySources as $msiInventorySource) {
147
            // explode the key => values pairs
148
            $extractedColumns = $this->explode($msiInventorySource);
149
            // initialize the array with the column we want to export
150
            $columns = array(ColumnKeys::SKU => $this->getValue(ColumnKeys::SKU));
151
            // append the extracted values to the array
152
            foreach ($extractedColumns as $extractedColumn) {
153
                // extract key => value pair
154
                list ($key, $value) = $this->explode($extractedColumn, '=');
155
                // append the key => value pair
156
                $columns[$key] = $value;
157
            }
158
159
            // create a new artefact with the column information
160
            $artefacts[] = $this->newArtefact($columns, array());
161
        }
162
163
        // append the artefacts that has to be exported to the subject
164
        $this->addArtefacts($artefacts);
165
    }
166
167
    /**
168
     * Process the template and set the passed quantity for each
169
     * configured inventory source and return the default values.
170
     *
171
     * @param integer $qty The quantity to initialze the template with
172
     *
173
     * @return array The initialized array with the default values
174
     */
175
    protected function loadDefaultValues(int $qty) : array
176
    {
177
        return array_map(function ($value) use ($qty) {
178
            return sprintf($value, $qty);
179
        }, $this->templateDefaultValues);
180
    }
181
182
    /**
183
     * Create's and return's a new empty artefact entity.
184
     *
185
     * @param array $columns             The array with the column data
186
     * @param array $originalColumnNames The array with a mapping from the old to the new column names
187
     *
188
     * @return array The new artefact entity
189
     */
190
    protected function newArtefact(array $columns, array $originalColumnNames)
191
    {
192
        return $this->getSubject()->newArtefact($columns, $originalColumnNames);
193
    }
194
195
    /**
196
     * Add the passed product type artefacts to the product with the
197
     * last entity ID.
198
     *
199
     * @param array $artefacts The product type artefacts
200
     *
201
     * @return void
202
     * @uses \TechDivision\Import\Product\Media\Subjects\MediaSubject::getLastEntityId()
203
     */
204
    protected function addArtefacts(array $artefacts)
205
    {
206
        $this->getSubject()->addArtefacts(ProductSourceItemObserver::ARTEFACT_TYPE, $artefacts, false);
207
    }
208
}
209