1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SpeckCatalog\Service; |
4
|
|
|
|
5
|
|
|
class Product extends AbstractService |
6
|
|
|
{ |
7
|
|
|
protected $entityMapper = 'speckcatalog_product_mapper'; |
8
|
|
|
protected $optionService; |
9
|
|
|
protected $productUomService; |
10
|
|
|
protected $imageService; |
11
|
|
|
protected $documentService; |
12
|
|
|
protected $specService; |
13
|
|
|
protected $companyService; |
14
|
|
|
protected $builderService; |
15
|
|
|
protected $categoryService; |
16
|
|
|
protected $choiceService; |
17
|
|
|
|
18
|
|
|
public function getAllProductsInCategories() |
19
|
|
|
{ |
20
|
|
|
return $this->getEntityMapper()->getAllProductsInCategories(); |
21
|
|
|
} |
22
|
|
|
|
23
|
2 |
|
public function update($data, array $where = null) |
24
|
|
|
{ |
25
|
2 |
|
if (null === $where && is_array($data)) { |
26
|
1 |
|
$where['product_id'] = $data['product_id']; |
27
|
1 |
|
} |
28
|
2 |
|
if (null === $where && $data instanceof \SpeckCatalog\Model\Product) { |
29
|
1 |
|
$where['product_id'] = $data->getProductId(); |
30
|
1 |
|
} |
31
|
|
|
|
32
|
|
|
$vars = array( |
33
|
2 |
|
'data' => $data, |
34
|
2 |
|
'where' => $where, |
35
|
2 |
|
); |
36
|
2 |
|
$this->getEventManager()->trigger('update.pre', $this, $vars); |
37
|
|
|
|
38
|
2 |
|
$result = parent::update($data, $where); |
39
|
2 |
|
$vars['result'] = $result; |
40
|
|
|
|
41
|
2 |
|
$this->getEventManager()->trigger('update.post', $this, $vars); |
42
|
|
|
|
43
|
2 |
|
return $result; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
public function getCrumbs($product) |
47
|
|
|
{ |
48
|
|
|
$crumbs = array($product); |
49
|
|
|
$categoryService = $this->getCategoryService(); |
50
|
|
|
$parent = $categoryService->getByProductId($product->getProductId()); |
51
|
|
|
if ($parent) { |
52
|
|
|
return $categoryService->getCrumbs($parent, $crumbs); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
return $crumbs; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function getParentCategory($productId) |
59
|
|
|
{ |
60
|
|
|
return $this->getEntityMapper()->getParentCategory($productId); |
61
|
|
|
} |
62
|
|
|
|
63
|
1 |
|
public function getFullProduct($productId) |
64
|
|
|
{ |
65
|
1 |
|
$product = $this->find(array('product_id' => $productId), true, true); |
66
|
1 |
|
if (!$product) { |
67
|
|
|
return false; |
68
|
|
|
} |
69
|
1 |
|
$this->populate($product, true); |
70
|
1 |
|
return $product; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
public function getFullProductFromItemNumber($itemNumber) |
74
|
|
|
{ |
75
|
|
|
$product = $this->find(array('item_number' => $itemNumber), true, true); |
76
|
|
|
|
77
|
|
|
if (!$product) { |
78
|
|
|
return false; |
79
|
|
|
} |
80
|
|
|
$this->populate($product, true); |
81
|
|
|
return $product; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
public function populate($product, $recursive = false, $children = true) |
85
|
|
|
{ |
86
|
|
|
$productId = $product->getProductId(); |
87
|
|
|
|
88
|
|
|
$allChildren = ($children === true) ? true : false; |
89
|
|
|
$children = (is_array($children)) ? $children : array(); |
90
|
|
|
|
91
|
|
|
if ($allChildren || in_array('options', $children)) { |
92
|
|
|
$options = $this->getOptionService()->getByProductId($productId, true, $recursive); |
93
|
|
|
$product->setOptions($options); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
if ($allChildren || in_array('images', $children)) { |
97
|
|
|
$images = $this->getImageService()->getImages('product', $productId); |
98
|
|
|
$product->setImages($images); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
if ($allChildren || in_array('documents', $children)) { |
102
|
|
|
$documents = $this->getDocumentService()->getDocuments($productId); |
103
|
|
|
$product->setDocuments($documents); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if ($allChildren || in_array('uoms', $children)) { |
107
|
|
|
$uoms = $this->getProductUomService()->getByProductId($productId, true, $recursive); |
108
|
|
|
$product->setUoms($uoms); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if ($allChildren || in_array('specs', $children)) { |
112
|
|
|
$specs = $this->getSpecService()->getByProductId($productId); |
113
|
|
|
$product->setSpecs($specs); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
if ($allChildren || in_array('manufacturer', $children)) { |
117
|
|
|
$manufacturer = $this->getCompanyService()->findById($product->getManufacturerId()); |
118
|
|
|
$product->setManufacturer($manufacturer); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
if ($product->getProductTypeId() == 1 && ($allChildren || in_array('builders', $children))) { |
122
|
|
|
$builders = $this->getBuilderService()->getBuildersByParentProductId($productId); |
123
|
|
|
$product->setBuilders($builders); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
if ($product->has('builders') && ($allChildren || (in_array('options', $children)))) { |
127
|
|
|
$this->singleOptionBuilderSingleUom($product); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
//check if the product is has a single builder option, |
132
|
|
|
//and if all builder products share a common uom |
133
|
|
|
//set "add price" (used for display) on choices, and return true |
|
|
|
|
134
|
|
|
public function singleOptionBuilderSingleUom($product) |
135
|
|
|
{ |
136
|
|
|
if (!$product->has('options')) { |
137
|
|
|
return false; |
138
|
|
|
} |
139
|
|
|
if (!$product->has('builders')) { |
140
|
|
|
return false; |
141
|
|
|
} |
142
|
|
|
$builderOptionCount = 0; |
143
|
|
|
$choices = array(); |
144
|
|
|
foreach ($product->getOptions() as $option) { |
145
|
|
|
if ($option->getBuilder() == true) { |
146
|
|
|
$builderOptionCount++; |
147
|
|
|
//add the choices to a flat array |
148
|
|
|
foreach ($option->getChoices() as $choice) { |
149
|
|
|
$choices[$choice->getChoiceId()] = $choice; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
if ($builderOptionCount > 1) { |
153
|
|
|
return false; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
$allUoms = array(); |
157
|
|
|
foreach ($product->getBuilders() as $builder) { |
158
|
|
|
$uoms = $builder->getProduct()->getUoms(); |
159
|
|
|
if (count($uoms) > 1) { |
160
|
|
|
return false; |
161
|
|
|
} |
162
|
|
|
foreach ($uoms as $uom) { |
163
|
|
|
$str = $uom->getUomCode() . $uom->getQuantity(); |
164
|
|
|
$allUoms[$str] = $str; |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
if (count($allUoms) > 1) { |
168
|
|
|
return false; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
//test is true, set the add price on the choices |
172
|
|
|
foreach ($product->getBuilders() as $builder) { |
173
|
|
|
foreach ($builder->getSelected() as $optionId => $choiceId) { |
174
|
|
|
$addPrice = $builder->getProduct()->getPrice() - $product->getPrice(); |
175
|
|
|
$choices[$choiceId]->setAddPrice($addPrice); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
return true; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
public function getProductsById(array $productIds = array()) |
182
|
|
|
{ |
183
|
|
|
return $this->getEntityMapper()->getProductsById($productIds); |
184
|
|
|
} |
185
|
|
|
|
186
|
2 |
|
public function addOption($productOrId, $optionOrId) |
187
|
|
|
{ |
188
|
2 |
|
$productId = ( is_int($productOrId) ? $productOrId : $productOrId->getProductId() ); |
189
|
2 |
|
$optionId = ( is_int($optionOrId) ? $optionOrId : $optionOrId->getOptionId() ); |
190
|
|
|
|
191
|
2 |
|
$this->getEntityMapper()->addOption($productId, $optionId); |
192
|
|
|
|
193
|
2 |
|
return $this->getOptionService()->find(array('option_id' => $optionId)); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* store new sort order for product options |
198
|
|
|
* $order is array of position => optionId |
199
|
|
|
*/ |
200
|
1 |
|
public function sortOptions($productId, array $order) |
201
|
|
|
{ |
202
|
1 |
|
return $this->getEntityMapper()->sortOptions($productId, $order); |
203
|
|
|
} |
204
|
|
|
|
205
|
1 |
|
public function removeOption(array $product, array $option) |
206
|
|
|
{ |
207
|
1 |
|
$productId = $product['product_id']; |
208
|
1 |
|
$optionId = $option['option_id']; |
209
|
|
|
|
210
|
1 |
|
return $this->removeOptionById($productId, $optionId); |
211
|
|
|
} |
212
|
|
|
|
213
|
1 |
|
public function removeOptionById($productId, $optionId) |
214
|
|
|
{ |
215
|
1 |
|
return $this->getEntityMapper()->removeOption($productId, $optionId); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
public function removeBuilder(array $product, array $builder) |
219
|
|
|
{ |
220
|
|
|
$productId = $product['product_id']; |
221
|
|
|
$builderProductId = $builder['product_id']; |
222
|
|
|
|
223
|
|
|
return $this->removeBuilderById($productId, $builderProductId); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
public function removeBuilderById($productId, $builderProductId) |
227
|
|
|
{ |
228
|
|
|
return $this->getEntityMapper()->removeBuilder($productId, $builderProductId); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
public function removeSpec(array $product, array $spec) |
232
|
|
|
{ |
233
|
|
|
$productId = $product['product_id']; |
234
|
|
|
$specId = $spec['spec_id']; |
235
|
|
|
|
236
|
|
|
return $this->removeSpecById($productId, $specId); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
public function removeSpecById($productId, $specId) |
240
|
|
|
{ |
241
|
|
|
return $this->getEntityMapper()->removeSpec($productId, $specId); |
242
|
|
|
} |
243
|
|
|
|
244
|
1 |
|
public function insert($dataOrModel) |
245
|
|
|
{ |
246
|
|
|
$vars = array( |
247
|
|
|
'data' => $dataOrModel |
248
|
1 |
|
); |
249
|
|
|
|
250
|
1 |
|
$this->getEventManager()->trigger('insert.pre', $this, $vars); |
251
|
|
|
|
252
|
1 |
|
$id = parent::insert($dataOrModel); |
253
|
1 |
|
$vars['result'] = $id; |
254
|
|
|
|
255
|
1 |
|
$this->getEventManager()->trigger('insert.post', $this, $vars); |
256
|
|
|
|
257
|
1 |
|
return $this->find(array('product_id' => $id)); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
public function populateForPricing($product) |
|
|
|
|
261
|
|
|
{ |
262
|
|
|
//recursive options (only whats needed for pricing) |
263
|
|
|
//productUoms, Availabilities |
264
|
|
|
// |
265
|
|
|
} |
266
|
|
|
|
267
|
1 |
|
public function getByCategoryId($categoryId) |
268
|
|
|
{ |
269
|
1 |
|
return $this->getEntityMapper()->getByCategoryId($categoryId); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* @return optionService |
274
|
|
|
*/ |
275
|
4 |
|
public function getOptionService() |
276
|
|
|
{ |
277
|
4 |
|
if (null === $this->optionService) { |
278
|
1 |
|
$this->optionService = $this->getServiceLocator()->get('speckcatalog_option_service'); |
279
|
1 |
|
} |
280
|
4 |
|
return $this->optionService; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @param $optionService |
285
|
|
|
* @return self |
286
|
|
|
*/ |
287
|
3 |
|
public function setOptionService($optionService) |
288
|
|
|
{ |
289
|
3 |
|
$this->optionService = $optionService; |
290
|
3 |
|
return $this; |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* @return productUomService |
295
|
|
|
*/ |
296
|
2 |
|
public function getProductUomService() |
297
|
|
|
{ |
298
|
2 |
|
if (null === $this->productUomService) { |
299
|
1 |
|
$this->productUomService = $this->getServiceLocator()->get('speckcatalog_product_uom_service'); |
300
|
1 |
|
} |
301
|
|
|
|
302
|
2 |
|
return $this->productUomService->setEnabledOnly($this->enabledOnly()); |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* @param $productUomService |
307
|
|
|
* @return self |
308
|
|
|
*/ |
309
|
1 |
|
public function setProductUomService($productUomService) |
310
|
|
|
{ |
311
|
1 |
|
$this->productUomService = $productUomService; |
312
|
1 |
|
return $this; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* @return imageService |
317
|
|
|
*/ |
318
|
2 |
|
public function getImageService() |
319
|
|
|
{ |
320
|
2 |
|
if (null === $this->imageService) { |
321
|
1 |
|
$this->imageService = $this->getServiceLocator()->get('speckcatalog_product_image_service'); |
322
|
1 |
|
} |
323
|
2 |
|
return $this->imageService; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @param $imageService |
328
|
|
|
* @return self |
329
|
|
|
*/ |
330
|
1 |
|
public function setImageService($imageService) |
331
|
|
|
{ |
332
|
1 |
|
$this->imageService = $imageService; |
333
|
1 |
|
return $this; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* @return documentService |
338
|
|
|
*/ |
339
|
2 |
|
public function getDocumentService() |
340
|
|
|
{ |
341
|
2 |
|
if (null === $this->documentService) { |
342
|
1 |
|
$this->documentService = $this->getServiceLocator()->get('speckcatalog_document_service'); |
343
|
1 |
|
} |
344
|
2 |
|
return $this->documentService; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* @param $documentService |
349
|
|
|
* @return self |
350
|
|
|
*/ |
351
|
1 |
|
public function setDocumentService($documentService) |
352
|
|
|
{ |
353
|
1 |
|
$this->documentService = $documentService; |
354
|
1 |
|
return $this; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* @return specService |
359
|
|
|
*/ |
360
|
2 |
|
public function getSpecService() |
361
|
|
|
{ |
362
|
2 |
|
if (null === $this->specService) { |
363
|
1 |
|
$this->specService = $this->getServiceLocator()->get('speckcatalog_spec_service'); |
364
|
1 |
|
} |
365
|
2 |
|
return $this->specService; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
/** |
369
|
|
|
* @param $specService |
370
|
|
|
* @return self |
371
|
|
|
*/ |
372
|
1 |
|
public function setSpecService($specService) |
373
|
|
|
{ |
374
|
1 |
|
$this->specService = $specService; |
375
|
1 |
|
return $this; |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
/** |
379
|
|
|
* @return companyService |
380
|
|
|
*/ |
381
|
2 |
|
public function getCompanyService() |
382
|
|
|
{ |
383
|
2 |
|
if (null === $this->companyService) { |
384
|
1 |
|
$this->companyService = $this->getServiceLocator()->get('speckcatalog_company_service'); |
385
|
1 |
|
} |
386
|
2 |
|
return $this->companyService; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* @param $companyService |
391
|
|
|
* @return self |
392
|
|
|
*/ |
393
|
1 |
|
public function setCompanyService($companyService) |
394
|
|
|
{ |
395
|
1 |
|
$this->companyService = $companyService; |
396
|
1 |
|
return $this; |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @return builderService |
401
|
|
|
*/ |
402
|
|
|
public function getBuilderService() |
403
|
|
|
{ |
404
|
|
|
if (null === $this->builderService) { |
405
|
|
|
$this->builderService = $this->getServiceLocator()->get('speckcatalog_builder_product_service'); |
406
|
|
|
} |
407
|
|
|
return $this->builderService; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
/** |
411
|
|
|
* @param $builderService |
412
|
|
|
* @return self |
413
|
|
|
*/ |
414
|
|
|
public function setBuilderService($builderService) |
415
|
|
|
{ |
416
|
|
|
$this->builderService = $builderService; |
417
|
|
|
return $this; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* @return categoryService |
422
|
|
|
*/ |
423
|
|
|
public function getCategoryService() |
424
|
|
|
{ |
425
|
|
|
if (null === $this->categoryService) { |
426
|
|
|
$this->categoryService = $this->getServiceLocator()->get('speckcatalog_category_service'); |
427
|
|
|
} |
428
|
|
|
return $this->categoryService; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* @param $categoryService |
433
|
|
|
* @return self |
434
|
|
|
*/ |
435
|
|
|
public function setCategoryService($categoryService) |
436
|
|
|
{ |
437
|
|
|
$this->categoryService = $categoryService; |
438
|
|
|
return $this; |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* @return choiceService |
443
|
|
|
*/ |
444
|
|
|
public function getChoiceService() |
445
|
|
|
{ |
446
|
|
|
if (null === $this->choiceService) { |
447
|
|
|
$this->choiceService = $this->getServiceLocator()->get('speckcatalog_choice_service'); |
448
|
|
|
} |
449
|
|
|
return $this->choiceService; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* @param $choiceService |
454
|
|
|
* @return self |
455
|
|
|
*/ |
456
|
|
|
public function setChoiceService($choiceService) |
457
|
|
|
{ |
458
|
|
|
$this->choiceService = $choiceService; |
459
|
|
|
return $this; |
460
|
|
|
} |
461
|
|
|
} |
462
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.