1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* TechDivision\Import\Product\Observers\ProductInventoryObserver |
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\Observers\StateDetectorInterface; |
24
|
|
|
use TechDivision\Import\Observers\AttributeLoaderInterface; |
25
|
|
|
use TechDivision\Import\Observers\DynamicAttributeObserverInterface; |
26
|
|
|
use TechDivision\Import\Product\Utils\ColumnKeys; |
27
|
|
|
use TechDivision\Import\Product\Utils\MemberNames; |
28
|
|
|
use TechDivision\Import\Product\Services\ProductBunchProcessorInterface; |
29
|
|
|
use TechDivision\Import\Subjects\SubjectInterface; |
30
|
|
|
use TechDivision\Import\Observers\ObserverFactoryInterface; |
31
|
|
|
use TechDivision\Import\Observers\StateDetectorAwareObserverInterface; |
32
|
|
|
use TechDivision\Import\Utils\EntityStatus; |
33
|
|
|
use TechDivision\Import\Observers\EntityMergers\EntityMergerInterface; |
34
|
|
|
use TechDivision\Import\Product\Utils\EntityTypeCodes; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Observer that creates/updates the product's inventory. |
38
|
|
|
* |
39
|
|
|
* @author Tim Wagner <[email protected]> |
40
|
|
|
* @copyright 2016 TechDivision GmbH <[email protected]> |
41
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
42
|
|
|
* @link https://github.com/techdivision/import-product |
43
|
|
|
* @link http://www.techdivision.com |
44
|
|
|
*/ |
45
|
|
|
class ProductInventoryObserver extends AbstractProductImportObserver implements DynamicAttributeObserverInterface, StateDetectorAwareObserverInterface, ObserverFactoryInterface |
46
|
|
|
{ |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* The product bunch processor instance. |
50
|
|
|
* |
51
|
|
|
* @var \TechDivision\Import\Product\Services\ProductBunchProcessorInterface |
52
|
|
|
*/ |
53
|
|
|
protected $productBunchProcessor; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* The attribute loader instance. |
57
|
|
|
* |
58
|
|
|
* @var \TechDivision\Import\Observers\AttributeLoaderInterface |
59
|
|
|
*/ |
60
|
|
|
protected $attributeLoader; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* The entity merger instance. |
64
|
|
|
* |
65
|
|
|
* @var \TechDivision\Import\Observers\EntityMergers\EntityMergerInterface |
66
|
|
|
*/ |
67
|
|
|
protected $entityMerger; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* The array with the column mappings that has to be computed. |
71
|
|
|
* |
72
|
|
|
* @var array |
73
|
|
|
*/ |
74
|
|
|
protected $columns = array(); |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Initialize the observer with the passed product bunch processor instance. |
78
|
|
|
* |
79
|
|
|
* @param \TechDivision\Import\Product\Services\ProductBunchProcessorInterface $productBunchProcessor The product bunch processor instance |
80
|
|
|
* @param \TechDivision\Import\Observers\AttributeLoaderInterface $attributeLoader The attribute loader instance |
81
|
|
|
* @param \TechDivision\Import\Observers\EntityMergers\EntityMergerInterface|null $entityMerger The entity merger instance |
82
|
|
|
* @param \TechDivision\Import\Observers\StateDetectorInterface|null $stateDetector The state detector instance to use |
83
|
|
|
*/ |
84
|
2 |
View Code Duplication |
public function __construct( |
|
|
|
|
85
|
|
|
ProductBunchProcessorInterface $productBunchProcessor, |
86
|
|
|
AttributeLoaderInterface $attributeLoader, |
87
|
|
|
EntityMergerInterface $entityMerger = null, |
88
|
|
|
StateDetectorInterface $stateDetector = null |
89
|
|
|
) { |
90
|
|
|
|
91
|
|
|
// initialize the bunch processor and the attribute loader instance |
92
|
2 |
|
$this->productBunchProcessor = $productBunchProcessor; |
93
|
2 |
|
$this->attributeLoader = $attributeLoader; |
94
|
2 |
|
$this->entityMerger = $entityMerger; |
95
|
|
|
|
96
|
|
|
// pass the state detector to the parent method |
97
|
2 |
|
parent::__construct($stateDetector); |
98
|
2 |
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Will be invoked by the observer visitor when a factory has been defined to create the observer instance. |
102
|
|
|
* |
103
|
|
|
* @param \TechDivision\Import\Subjects\SubjectInterface $subject The subject instance |
104
|
|
|
* |
105
|
|
|
* @return \TechDivision\Import\Observers\ObserverInterface The observer instance |
106
|
|
|
*/ |
107
|
|
|
public function createObserver(SubjectInterface $subject) |
108
|
|
|
{ |
109
|
|
|
|
110
|
|
|
// load the header stock mappings from the subject |
111
|
|
|
$headerStockMappings = $subject->getHeaderStockMappings(); |
|
|
|
|
112
|
|
|
|
113
|
|
|
// prepare the array with column name => type mapping |
114
|
|
|
foreach ($headerStockMappings as $columnName => $mappings) { |
115
|
|
|
// explode the mapping details |
116
|
|
|
list (, $type) = $mappings; |
117
|
|
|
// add the column name => type mapping |
118
|
|
|
$this->columns[$columnName] = $type; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
// return the instance itself |
122
|
|
|
return $this; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Returns an array of the columns with their types to detect state. |
127
|
|
|
* |
128
|
|
|
* @return array The array with the column names as key and their type as value |
129
|
|
|
*/ |
130
|
|
|
public function getColumns() |
131
|
|
|
{ |
132
|
|
|
return array_intersect_key($this->columns, $this->getHeaders()); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Return's the product bunch processor instance. |
137
|
|
|
* |
138
|
|
|
* @return \TechDivision\Import\Product\Services\ProductBunchProcessorInterface The product bunch processor instance |
139
|
|
|
*/ |
140
|
1 |
|
protected function getProductBunchProcessor() |
141
|
|
|
{ |
142
|
1 |
|
return $this->productBunchProcessor; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Process the observer's business logic. |
147
|
|
|
* |
148
|
|
|
* @return array The processed row |
149
|
|
|
*/ |
150
|
2 |
|
protected function process() |
151
|
|
|
{ |
152
|
|
|
|
153
|
|
|
// query whether or not, we've found a new SKU => means we've found a new product |
154
|
2 |
|
if ($this->hasBeenProcessed($this->getValue(ColumnKeys::SKU))) { |
155
|
1 |
|
return; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
// prepare, initialize and persist the stock status/item |
159
|
1 |
|
if ($this->hasChanges($entity = $this->initializeStockItem($this->prepareStockItemAttributes()))) { |
160
|
1 |
|
$this->persistStockItem($entity); |
161
|
|
|
} |
162
|
1 |
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Prepare the basic attributes of the stock status/item entity that has to be persisted. |
166
|
|
|
* |
167
|
|
|
* @return array The prepared stock status/item attributes |
168
|
|
|
*/ |
169
|
1 |
|
protected function prepareAttributes() |
170
|
|
|
{ |
171
|
|
|
|
172
|
|
|
// load the ID of the product that has been created recently |
173
|
1 |
|
$lastEntityId = $this->getSubject()->getLastEntityId(); |
|
|
|
|
174
|
|
|
|
175
|
|
|
// initialize the stock status data |
176
|
1 |
|
$websiteId = $this->getValue(ColumnKeys::WEBSITE_ID, 0); |
177
|
|
|
|
178
|
|
|
// return the prepared stock status |
179
|
1 |
|
return $this->initializeEntity( |
180
|
1 |
|
$this->loadRawEntity( |
181
|
|
|
array( |
182
|
1 |
|
MemberNames::PRODUCT_ID => $lastEntityId, |
183
|
1 |
|
MemberNames::WEBSITE_ID => $websiteId, |
184
|
1 |
|
MemberNames::STOCK_ID => 1 |
185
|
|
|
) |
186
|
|
|
) |
187
|
|
|
); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Merge's and return's the entity with the passed attributes and set's the |
192
|
|
|
* passed status. |
193
|
|
|
* |
194
|
|
|
* @param array $entity The entity to merge the attributes into |
195
|
|
|
* @param array $attr The attributes to be merged |
196
|
|
|
* @param string|null $changeSetName The change set name to use |
197
|
|
|
* |
198
|
|
|
* @return array The merged entity |
199
|
|
|
* @todo https://github.com/techdivision/import/issues/179 |
200
|
|
|
*/ |
201
|
|
View Code Duplication |
protected function mergeEntity(array $entity, array $attr, $changeSetName = null) |
|
|
|
|
202
|
|
|
{ |
203
|
|
|
return array_merge( |
204
|
|
|
$entity, |
205
|
|
|
$this->entityMerger ? $this->entityMerger->merge($this, $entity, $attr) : $attr, |
206
|
|
|
array(EntityStatus::MEMBER_NAME => $this->detectState($entity, $attr, $changeSetName)) |
207
|
|
|
); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Prepare the stock item attributes of the entity that has to be persisted. |
212
|
|
|
* |
213
|
|
|
* @return array The prepared stock status item |
214
|
|
|
*/ |
215
|
1 |
|
protected function prepareStockItemAttributes() |
216
|
|
|
{ |
217
|
1 |
|
return array_merge($this->prepareAttributes(), $this->attributeLoader->load($this, $this->getHeaderStockMappings())); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Load's and return's a raw customer entity without primary key but the mandatory members only and nulled values. |
222
|
|
|
* |
223
|
|
|
* @param array $data An array with data that will be used to initialize the raw entity with |
224
|
|
|
* |
225
|
|
|
* @return array The initialized entity |
226
|
|
|
*/ |
227
|
1 |
|
protected function loadRawEntity(array $data = array()) |
228
|
|
|
{ |
229
|
1 |
|
return $this->getProductBunchProcessor()->loadRawEntity(EntityTypeCodes::CATALOGINVENTORY_STOCK_ITEM, $data); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
/** |
233
|
|
|
* Initialize the stock item with the passed attributes and returns an instance. |
234
|
|
|
* |
235
|
|
|
* @param array $attr The stock item attributes |
236
|
|
|
* |
237
|
|
|
* @return array The initialized stock item |
238
|
|
|
*/ |
239
|
1 |
|
protected function initializeStockItem(array $attr) |
240
|
|
|
{ |
241
|
1 |
|
return $attr; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Return's the appings for the table column => CSV column header. |
246
|
|
|
* |
247
|
|
|
* @return array The header stock mappings |
248
|
|
|
*/ |
249
|
1 |
|
protected function getHeaderStockMappings() |
250
|
|
|
{ |
251
|
1 |
|
return $this->getSubject()->getHeaderStockMappings(); |
|
|
|
|
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Persist's the passed stock item data and return's the ID. |
256
|
|
|
* |
257
|
|
|
* @param array $stockItem The stock item data to persist |
258
|
|
|
* |
259
|
|
|
* @return void |
260
|
|
|
*/ |
261
|
1 |
|
protected function persistStockItem($stockItem) |
262
|
|
|
{ |
263
|
1 |
|
$this->getProductBunchProcessor()->persistStockItem($stockItem); |
264
|
1 |
|
} |
265
|
|
|
} |
266
|
|
|
|
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.