Passed
Push — master ( bada6f...d61b94 )
by Aimeos
04:42
created

MShopAddDataAbstract::getAttributeItem()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
nc 4
nop 3
dl 0
loc 13
c 0
b 0
f 0
cc 4
rs 10
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2014
6
 * @copyright Aimeos (aimeos.org), 2015-2021
7
 */
8
9
10
namespace Aimeos\Upscheme\Task;
11
12
13
/**
14
 * Adds records to tables.
15
 */
16
class MShopAddDataAbstract extends Base
17
{
18
	private $attributes;
19
20
21
	/**
22
	 * Returns the list of task names which this task depends on.
23
	 *
24
	 * @return string[] List of task names
25
	 */
26
	public function after() : array
27
	{
28
		return ['Attribute', 'Media', 'Price', 'Product', 'Text'];
29
	}
30
31
32
	public function up()
33
	{
34
	}
35
36
37
	/**
38
	 * Adds the attributes to the given parent in the database.
39
	 *
40
	 * @param string $parentid ID of the parent item where the media should be associated to
41
	 * @param array $data Two dimensional associative list of attribute data
42
	 * @param string $domain Domain name the texts should be added to, e.g. 'catalog'
43
	 */
44
	protected function addAttributes( $parentid, array $data, $domain )
45
	{
46
		$context = $this->context();
0 ignored issues
show
Bug introduced by
The method context() does not exist on Aimeos\Upscheme\Task\MShopAddDataAbstract. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

46
		/** @scrutinizer ignore-call */ 
47
  $context = $this->context();
Loading history...
47
		$attrManager = \Aimeos\MShop::create( $context, 'attribute' );
48
		$listManager = \Aimeos\MShop::create( $context, $domain . '/lists' );
49
50
51
		$item = $attrManager->create();
52
		$item->setDomain( $domain );
53
54
		$listItem = $listManager->create();
55
		$listItem->setParentId( $parentid );
56
		$listItem->setDomain( 'attribute' );
57
58
59
		foreach( $data as $entry )
60
		{
61
			if( ( $attrItem = $this->getAttributeItem( $domain, $entry['type'], $entry['code'] ) ) === null )
62
			{
63
				$item->setId( null );
64
				$item->setType( $entry['type'] );
65
				$item->setCode( $entry['code'] );
66
				$item->setLabel( $entry['label'] );
67
				$item->setPosition( $entry['position'] );
68
				$item->setStatus( $entry['status'] );
69
70
				$attrManager->save( $item );
71
				$id = $item->getId();
72
			}
73
			else
74
			{
75
				$id = $attrItem->getId();
76
			}
77
78
			$listItem->setId( null );
79
			$listItem->setType( $entry['list-type'] );
80
			$listItem->setDateStart( $entry['list-start'] );
81
			$listItem->setDateEnd( $entry['list-end'] );
82
			$listItem->setConfig( $entry['list-config'] );
83
			$listItem->setPosition( $entry['list-position'] );
84
			$listItem->setStatus( $entry['list-status'] );
85
			$listItem->setRefId( $id );
86
87
			$listManager->save( $listItem, false );
88
89
90
			if( isset( $entry['attribute'] ) ) {
91
				$this->addAttributes( $id, $entry['attribute'], 'attribute' );
92
			}
93
94
			if( isset( $entry['media'] ) ) {
95
				$this->addMedia( $id, $entry['media'], 'attribute' );
96
			}
97
98
			if( isset( $entry['price'] ) ) {
99
				$this->addPrices( $id, $entry['price'], 'attribute' );
100
			}
101
102
			if( isset( $entry['text'] ) ) {
103
				$this->addTexts( $id, $entry['text'], 'attribute' );
104
			}
105
		}
106
	}
107
108
109
	/**
110
	 * Adds the media to the given parent in the database.
111
	 *
112
	 * @param string $parentid ID of the parent item where the media should be associated to
113
	 * @param array $data Two dimensional associative list of media data
114
	 * @param string $domain Domain name the texts should be added to, e.g. 'catalog'
115
	 */
116
	protected function addMedia( $parentid, array $data, $domain )
117
	{
118
		$context = $this->context();
119
		$mediaManager = \Aimeos\MShop::create( $context, 'media' );
120
		$listManager = \Aimeos\MShop::create( $context, $domain . '/lists' );
121
122
123
		$item = $mediaManager->create();
124
		$item->setDomain( $domain );
125
126
		$listItem = $listManager->create();
127
		$listItem->setParentId( $parentid );
128
		$listItem->setDomain( 'media' );
129
130
131
		foreach( $data as $entry )
132
		{
133
			$item->setId( null );
134
			$item->setType( $entry['type'] );
135
			$item->setLanguageId( $entry['languageid'] );
136
			$item->setMimetype( $entry['mimetype'] );
137
			$item->setPreviews( (array) $entry['preview'] );
138
			$item->setUrl( $entry['url'] );
139
			$item->setLabel( $entry['label'] );
140
			$item->setStatus( $entry['status'] );
141
142
			$mediaManager->save( $item );
143
144
			$listItem->setId( null );
145
			$listItem->setType( $entry['list-type'] );
146
			$listItem->setDateStart( $entry['list-start'] );
147
			$listItem->setDateEnd( $entry['list-end'] );
148
			$listItem->setConfig( $entry['list-config'] );
149
			$listItem->setPosition( $entry['list-position'] );
150
			$listItem->setStatus( $entry['list-status'] );
151
			$listItem->setRefId( $item->getId() );
152
153
			$listManager->save( $listItem, false );
154
155
156
			if( isset( $entry['attribute'] ) ) {
157
				$this->addAttributes( $item->getId(), $entry['attribute'], 'media' );
158
			}
159
160
			if( isset( $entry['media'] ) ) {
161
				$this->addMedia( $item->getId(), $entry['media'], 'media' );
162
			}
163
164
			if( isset( $entry['price'] ) ) {
165
				$this->addPrices( $item->getId(), $entry['price'], 'media' );
166
			}
167
168
			if( isset( $entry['text'] ) ) {
169
				$this->addTexts( $item->getId(), $entry['text'], 'media' );
170
			}
171
		}
172
	}
173
174
175
	/**
176
	 * Adds the prices to the given parent in the database.
177
	 *
178
	 * @param string $parentid ID of the parent item where the media should be associated to
179
	 * @param array $data Two dimensional associative list of price data
180
	 * @param string $domain Domain name the texts should be added to, e.g. 'catalog'
181
	 */
182
	protected function addPrices( $parentid, array $data, $domain )
183
	{
184
		$context = $this->context();
185
		$mediaManager = \Aimeos\MShop::create( $context, 'price' );
186
		$listManager = \Aimeos\MShop::create( $context, $domain . '/lists' );
187
188
189
		$item = $mediaManager->create();
190
		$item->setDomain( $domain );
191
192
		$listItem = $listManager->create();
193
		$listItem->setParentId( $parentid );
194
		$listItem->setDomain( 'price' );
195
196
197
		foreach( $data as $entry )
198
		{
199
			$item->setId( null );
200
			$item->setLabel( $entry['label'] );
201
			$item->setType( $entry['type'] );
202
			$item->setCurrencyId( $entry['currencyid'] );
203
			$item->setQuantity( $entry['quantity'] );
204
			$item->setValue( $entry['value'] );
205
			$item->setCosts( $entry['costs'] );
206
			$item->setRebate( $entry['rebate'] );
207
			$item->setTaxRate( $entry['taxrate'] );
208
			$item->setStatus( $entry['status'] );
209
210
			$mediaManager->save( $item );
211
212
			$listItem->setId( null );
213
			$listItem->setType( $entry['list-type'] );
214
			$listItem->setDateStart( $entry['list-start'] );
215
			$listItem->setDateEnd( $entry['list-end'] );
216
			$listItem->setConfig( $entry['list-config'] );
217
			$listItem->setPosition( $entry['list-position'] );
218
			$listItem->setStatus( $entry['list-status'] );
219
			$listItem->setRefId( $item->getId() );
220
221
			$listManager->save( $listItem, false );
222
223
224
			if( isset( $entry['attribute'] ) ) {
225
				$this->addAttributes( $item->getId(), $entry['attribute'], 'price' );
226
			}
227
228
			if( isset( $entry['media'] ) ) {
229
				$this->addMedia( $item->getId(), $entry['media'], 'price' );
230
			}
231
232
			if( isset( $entry['price'] ) ) {
233
				$this->addPrices( $item->getId(), $entry['price'], 'price' );
234
			}
235
236
			if( isset( $entry['text'] ) ) {
237
				$this->addTexts( $item->getId(), $entry['text'], 'price' );
238
			}
239
		}
240
	}
241
242
243
	/**
244
	 * Adds the texts to the given parent in the database.
245
	 *
246
	 * @param string $parentid ID of the parent item where the media should be associated to
247
	 * @param array $data Two dimensional associative list text data
248
	 * @param string $domain Domain name the texts should be added to, e.g. 'catalog'
249
	 */
250
	protected function addTexts( $parentid, array $data, $domain )
251
	{
252
		$context = $this->context();
253
		$textManager = \Aimeos\MShop::create( $context, 'text' );
254
		$listManager = \Aimeos\MShop::create( $context, $domain . '/lists' );
255
256
257
		$item = $textManager->create();
258
		$item->setDomain( $domain );
259
260
		$listItem = $listManager->create();
261
		$listItem->setParentId( $parentid );
262
		$listItem->setDomain( 'text' );
263
264
265
		foreach( $data as $entry )
266
		{
267
			$item->setId( null );
268
			$item->setType( $entry['type'] );
269
			$item->setLanguageId( $entry['languageid'] );
270
			$item->setContent( $entry['content'] );
271
			$item->setLabel( $entry['label'] );
272
			$item->setStatus( $entry['status'] );
273
274
			$textManager->save( $item );
275
276
			$listItem->setId( null );
277
			$listItem->setType( $entry['list-type'] );
278
			$listItem->setDateStart( $entry['list-start'] );
279
			$listItem->setDateEnd( $entry['list-end'] );
280
			$listItem->setConfig( $entry['list-config'] );
281
			$listItem->setPosition( $entry['list-position'] );
282
			$listItem->setStatus( $entry['list-status'] );
283
			$listItem->setRefId( $item->getId() );
284
285
			$listManager->save( $listItem, false );
286
287
288
			if( isset( $entry['attribute'] ) ) {
289
				$this->addAttributes( $item->getId(), $entry['attribute'], 'text' );
290
			}
291
292
			if( isset( $entry['media'] ) ) {
293
				$this->addMedia( $item->getId(), $entry['media'], 'text' );
294
			}
295
296
			if( isset( $entry['price'] ) ) {
297
				$this->addPrices( $item->getId(), $entry['price'], 'text' );
298
			}
299
300
			if( isset( $entry['text'] ) ) {
301
				$this->addTexts( $item->getId(), $entry['text'], 'text' );
302
			}
303
		}
304
	}
305
306
307
	/**
308
	 * Adds the products to the given parent in the database.
309
	 *
310
	 * @param string $parentid ID of the parent item where the products should be associated to
311
	 * @param array $data Two dimensional associative list of product data
312
	 * @param string $domain Domain name the products should be added to, e.g. 'catalog'
313
	 */
314
	protected function addProducts( $parentid, array $data, $domain )
315
	{
316
		$context = $this->context();
317
		$productManager = \Aimeos\MShop::create( $context, 'product' );
318
		$listManager = \Aimeos\MShop::create( $context, $domain . '/lists' );
319
320
321
		$listItem = $listManager->create();
322
		$listItem->setParentId( $parentid );
323
		$listItem->setDomain( 'product' );
324
325
326
		$codes = [];
327
328
		foreach( $data as $entry ) {
329
			$codes[$entry['code']] = null;
330
		}
331
332
		$search = $productManager->filter();
333
		$search->setConditions( $search->compare( '==', 'product.code', array_keys( $codes ) ) );
334
		$products = $productManager->search( $search );
335
336
		foreach( $products as $product ) {
337
			$codes[$product->getCode()] = $product->getId();
338
		}
339
340
341
		foreach( $data as $entry )
342
		{
343
			if( !isset( $codes[$entry['code']] ) ) {
344
				throw new \RuntimeException( sprintf( 'No product for code "%1$s" found', $entry['code'] ) );
345
			}
346
347
			$listItem->setId( null );
348
			$listItem->setType( $entry['list-type'] );
349
			$listItem->setDateStart( $entry['list-start'] );
350
			$listItem->setDateEnd( $entry['list-end'] );
351
			$listItem->setConfig( $entry['list-config'] );
352
			$listItem->setPosition( $entry['list-position'] );
353
			$listItem->setStatus( $entry['list-status'] );
354
			$listItem->setRefId( $codes[$entry['code']] );
355
356
			$listManager->save( $listItem, false );
357
		}
358
	}
359
360
361
	/**
362
	 * Adds stock levels to the given product in the database.
363
	 *
364
	 * @param string $productId ID of the product item where the stock levels should be associated to
365
	 * @param array $data Two dimensional associative list of product stock data
366
	 */
367
	protected function addProductStock( string $productId, array $data )
368
	{
369
		$manager = \Aimeos\MShop::create( $this->context(), 'stock/type' );
370
371
		$types = [];
372
		foreach( $manager->search( $manager->filter() ) as $id => $item ) {
373
			$types[$item->getCode()] = $id;
374
		}
375
376
		$manager = \Aimeos\MShop::create( $this->context(), 'stock' );
377
378
		$item = $manager->create();
379
		$item->setProductId( $productId );
380
381
		foreach( $data as $entry )
382
		{
383
			$item->setId( null );
384
			$item->setDateBack( $entry['dateback'] );
385
			$item->setStockLevel( $entry['stocklevel'] );
386
			$item->setType( $entry['type'] );
387
388
			$manager->save( $item, false );
389
		}
390
	}
391
392
393
	/**
394
	 * Returns the attribute for the given code, type and domain
395
	 *
396
	 * @param string $domain Domain the attribute belongs to
397
	 * @param string $type Attribute type
398
	 * @param string $code Attribute code
399
	 * @return \Aimeos\MShop\Attribute\Item\Iface|null Found attribute item or null if not available
400
	 */
401
	protected function getAttributeItem( $domain, $type, $code )
402
	{
403
		if( $this->attributes === null )
404
		{
405
			$manager = \Aimeos\MShop::create( $this->context(), 'attribute' );
406
407
			foreach( $manager->search( $manager->filter() ) as $item ) {
408
				$this->attributes[$item->getDomain()][$item->getType()][$item->getCode()] = $item;
409
			}
410
		}
411
412
		if( isset( $this->attributes[$domain][$type][$code] ) ) {
413
			return $this->attributes[$domain][$type][$code];
414
		}
415
	}
416
417
418
	/**
419
	 * Deletes the demo items from the given parent ID in the database.
420
	 *
421
	 * @param string $parentid ID of the parent item where the associated items should be removed from
422
	 * @param string $name Name of the list manager, e.g. 'catalog/lists'
423
	 * @param string $domain Name of the domain the items are associated to, e.g. 'catalog'
424
	 * @param string $refdomain Name of the domain to remove the items from, e.g. 'text'
425
	 */
426
	protected function removeItems( $parentid, $name, $domain, $refdomain )
427
	{
428
		$context = $this->context();
429
		$key = str_replace( '/', '.', $name );
430
431
		$manager = \Aimeos\MShop::create( $context, $refdomain );
432
		$listManager = \Aimeos\MShop::create( $context, $name );
433
434
435
		$search = $manager->filter();
436
		$expr = array(
437
			$search->compare( '==', $refdomain . '.domain', $domain ),
438
			$search->compare( '=~', $refdomain . '.label', 'Demo' ),
439
		);
440
		$search->setConditions( $search->and( $expr ) );
441
442
		$ids = $manager->search( $search )->keys()->toArray();
443
		$manager->delete( $ids );
444
445
446
		$search = $listManager->filter();
447
		$expr = array(
448
			$search->compare( '==', $key . '.parentid', $parentid ),
449
			$search->compare( '==', $key . '.domain', $refdomain ),
450
			$search->compare( '==', $key . '.refid', $ids ),
451
		);
452
		$search->setConditions( $search->and( $expr ) );
453
454
		$listManager->delete( $listManager->search( $search )->toArray() );
455
	}
456
457
458
	/**
459
	 * Deletes the references to non-existent or demo items in the database.
460
	 *
461
	 * @param string $parentid ID of the parent item where the associated items should be removed from
462
	 * @param string $name Name of the list manager, e.g. 'catalog/lists'
463
	 * @param string $refdomain Name of the domain to remove the items from, e.g. 'product'
464
	 */
465
	protected function removeListItems( $parentid, $name, $refdomain )
466
	{
467
		$start = 0;
468
		$context = $this->context();
469
		$key = str_replace( '/', '.', $name );
470
471
		$manager = \Aimeos\MShop::create( $context, $refdomain );
472
		$listManager = \Aimeos\MShop::create( $context, $name );
473
474
475
		$search = $listManager->filter();
476
		$expr = array(
477
			$search->compare( '==', $key . '.parentid', $parentid ),
478
			$search->compare( '==', $key . '.domain', $refdomain ),
479
		);
480
		$search->setConditions( $search->and( $expr ) );
481
482
		do
483
		{
484
			$refIds = $listIds = $map = [];
485
			$result = $listManager->search( $search );
486
487
			foreach( $result as $id => $listItem )
488
			{
489
				$refIds[] = $listItem->getRefId();
490
				$map[$listItem->getRefId()][] = $id;
491
			}
492
493
494
			$search = $manager->filter();
495
			$search->setConditions( $search->compare( '==', $refdomain . '.id', $refIds ) );
496
			$ids = $manager->search( $search )->keys()->toArray();
497
498
			foreach( array_diff( $refIds, $ids ) as $refId ) {
499
				$listIds = array_merge( $listIds, $map[$refId] );
500
			}
501
502
			$listManager->delete( $listIds );
503
504
505
			$count = count( $result );
506
			$start += $count;
507
			$search->slice( $start );
508
		}
509
		while( $count == $search->getLimit() );
510
511
512
		$search = $manager->filter();
513
		$search->setConditions( $search->compare( '=~', $refdomain . '.label', 'Demo' ) );
514
		$ids = $manager->search( $search )->keys()->toArray();
515
516
		$search = $listManager->filter();
517
		$expr = array(
518
			$search->compare( '==', $key . '.parentid', $parentid ),
519
			$search->compare( '==', $key . '.refid', $ids ),
520
			$search->compare( '==', $key . '.domain', $refdomain ),
521
		);
522
		$search->setConditions( $search->and( $expr ) );
523
524
		$listManager->delete( $listManager->search( $search )->toArray() );
525
	}
526
527
528
	/**
529
	 * Starts a new transation
530
	 */
531
	protected function txBegin()
532
	{
533
		$dbm = $this->context()->getDatabaseManager();
534
535
		$conn = $dbm->acquire();
536
		$conn->begin();
537
		$dbm->release( $conn );
538
	}
539
540
541
	/**
542
	 * Commits an existing transaction
543
	 */
544
	protected function txCommit()
545
	{
546
		$dbm = $this->context()->getDatabaseManager();
547
548
		$conn = $dbm->acquire();
549
		$conn->commit();
550
		$dbm->release( $conn );
551
	}
552
}
553