Passed
Push — master ( bcc204...64e7d7 )
by Aimeos
04:52
created

Standard::search()   A

Complexity

Conditions 3
Paths 7

Size

Total Lines 184
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
c 0
b 0
f 0
dl 0
loc 184
rs 9.424
cc 3
nc 7
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2024
6
 * @package MShop
7
 * @subpackage Order
8
 */
9
10
11
namespace Aimeos\MShop\Order\Manager;
12
13
14
/**
15
 * Default order manager implementation.
16
 *
17
 * @package MShop
18
 * @subpackage Order
19
 */
20
class Standard extends Base
21
	implements \Aimeos\MShop\Order\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
22
{
23
	use Session;
24
	use Update;
25
26
27
	private array $searchConfig = [
28
		'order.invoiceno' => [
29
			'label' => 'Invoice number',
30
			'internalcode' => 'invoiceno',
31
		],
32
		'order.relatedid' => [
33
			'label' => 'Related invoice ID',
34
			'internalcode' => 'relatedid',
35
		],
36
		'order.channel' => [
37
			'label' => 'Order channel',
38
			'internalcode' => 'channel',
39
		],
40
		'order.datepayment' => [
41
			'label' => 'Purchase date',
42
			'internalcode' => 'datepayment',
43
			'type' => 'datetime',
44
		],
45
		'order.datedelivery' => [
46
			'label' => 'Delivery date',
47
			'internalcode' => 'datedelivery',
48
			'type' => 'datetime',
49
		],
50
		'order.statusdelivery' => [
51
			'label' => 'Delivery status',
52
			'internalcode' => 'statusdelivery',
53
			'type' => 'int',
54
		],
55
		'order.statuspayment' => [
56
			'label' => 'Payment status',
57
			'internalcode' => 'statuspayment',
58
			'type' => 'int',
59
		],
60
		'order.customerid' => [
61
			'label' => 'Order customer ID',
62
			'internalcode' => 'customerid',
63
		],
64
		'order.customerref' => [
65
			'label' => 'Order customer reference',
66
			'internalcode' => 'customerref',
67
		],
68
		'order.comment' => [
69
			'label' => 'Order comment',
70
			'internalcode' => 'comment',
71
		],
72
	];
73
74
75
	/**
76
	 * Counts the number items that are available for the values of the given key.
77
	 *
78
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria
79
	 * @param array|string $key Search key or list of key to aggregate items for
80
	 * @param string|null $value Search key for aggregating the value column
81
	 * @param string|null $type Type of the aggregation, empty string for count or "sum" or "avg" (average)
82
	 * @return \Aimeos\Map List of the search keys as key and the number of counted items as value
83
	 */
84
	public function aggregate( \Aimeos\Base\Criteria\Iface $search, $key, string $value = null, string $type = null ) : \Aimeos\Map
85
	{
86
		/** mshop/order/manager/aggregate/mysql
87
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
88
		 *
89
		 * @see mshop/order/manager/aggregate/ansi
90
		 */
91
92
		/** mshop/order/manager/aggregate/ansi
93
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
94
		 *
95
		 * Groups all records by the values in the key column and counts their
96
		 * occurence. The matched records can be limited by the given criteria
97
		 * from the order database. The records must be from one of the sites
98
		 * that are configured via the context item. If the current site is part
99
		 * of a tree of sites, the statement can count all records from the
100
		 * current site and the complete sub-tree of sites.
101
		 *
102
		 * As the records can normally be limited by criteria from sub-managers,
103
		 * their tables must be joined in the SQL context. This is done by
104
		 * using the "internaldeps" property from the definition of the ID
105
		 * column of the sub-managers. These internal dependencies specify
106
		 * the JOIN between the tables and the used columns for joining. The
107
		 * ":joins" placeholder is then replaced by the JOIN strings from
108
		 * the sub-managers.
109
		 *
110
		 * To limit the records matched, conditions can be added to the given
111
		 * criteria object. It can contain comparisons like column names that
112
		 * must match specific values which can be combined by AND, OR or NOT
113
		 * operators. The resulting string of SQL conditions replaces the
114
		 * ":cond" placeholder before the statement is sent to the database
115
		 * server.
116
		 *
117
		 * This statement doesn't return any records. Instead, it returns pairs
118
		 * of the different values found in the key column together with the
119
		 * number of records that have been found for that key values.
120
		 *
121
		 * The SQL statement should conform to the ANSI standard to be
122
		 * compatible with most relational database systems. This also
123
		 * includes using double quotes for table and column names.
124
		 *
125
		 * @param string SQL statement for aggregating order items
126
		 * @since 2014.09
127
		 * @see mshop/order/manager/insert/ansi
128
		 * @see mshop/order/manager/update/ansi
129
		 * @see mshop/order/manager/newid/ansi
130
		 * @see mshop/order/manager/delete/ansi
131
		 * @see mshop/order/manager/search/ansi
132
		 * @see mshop/order/manager/count/ansi
133
		 */
134
135
		/** mshop/order/manager/aggregateavg/mysql
136
		 * Computes the average of all values grouped by the key column and matched by the given criteria
137
		 *
138
		 * @param string SQL statement for aggregating the order items and computing the average value
139
		 * @since 2017.10
140
		 * @see mshop/order/manager/aggregateavg/ansi
141
		 * @see mshop/order/manager/aggregate/mysql
142
		 */
143
144
		/** mshop/order/manager/aggregateavg/ansi
145
		 * Computes the average of all values grouped by the key column and matched by the given criteria
146
		 *
147
		 * @param string SQL statement for aggregating the order items and computing the average value
148
		 * @since 2017.10
149
		 * @see mshop/order/manager/aggregate/ansi
150
		 */
151
152
		/** mshop/order/manager/aggregatesum/mysql
153
		 * Computes the sum of all values grouped by the key column and matched by the given criteria
154
		 *
155
		 * @param string SQL statement for aggregating the order items and computing the sum
156
		 * @since 2017.10
157
		 * @see mshop/order/manager/aggregatesum/ansi
158
		 * @see mshop/order/manager/aggregate/mysql
159
		 */
160
161
		/** mshop/order/manager/aggregatesum/ansi
162
		 * Computes the sum of all values grouped by the key column and matched by the given criteria
163
		 *
164
		 * @param string SQL statement for aggregating the order items and computing the sum
165
		 * @since 2017.10
166
		 * @see mshop/order/manager/aggregate/ansi
167
		 */
168
169
		$cfgkey = 'mshop/order/manager/aggregate';
170
		return $this->aggregateBase( $search, $key, $cfgkey, ['order'], $value, $type );
171
	}
172
173
174
	/**
175
	 * Creates a new empty item instance
176
	 *
177
	 * @param array $values Values the item should be initialized with
178
	 * @return \Aimeos\MShop\Order\Item\Iface New order item object
179
	 */
180
	public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
181
	{
182
		$context = $this->context();
183
		$locale = $context->locale();
184
185
		$values['.locale'] = $values['.locale'] ?? $locale;
186
		$values['.price'] = $values['.price'] ?? \Aimeos\MShop::create( $context, 'price' )->create();
187
		$values['order.siteid'] = $values['order.siteid'] ?? $locale->getSiteId();
188
189
		$item = new \Aimeos\MShop\Order\Item\Standard( 'order.', $values );
190
		\Aimeos\MShop::create( $context, 'plugin' )->register( $item, 'order' );
191
192
		return $item;
193
	}
194
195
196
	/**
197
	 * Creates a search critera object
198
	 *
199
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
200
	 * @param bool $site TRUE to add site criteria to show orders with available products only
201
	 * @return \Aimeos\Base\Criteria\Iface New search criteria object
202
	 */
203
	public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
204
	{
205
		$search = parent::filter( $default );
206
207
		if( $default !== false ) {
208
			$search->add( ['order.customerid' => $this->context()->user()] );
209
		}
210
211
		if( $site === true )
212
		{
213
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_SUBTREE;
214
			$search->add( $this->siteCondition( 'order.product.siteid', $level ) );
215
		}
216
217
		return $search;
218
	}
219
220
221
	/**
222
	 * Returns the additional column/search definitions
223
	 *
224
	 * @return array Associative list of column names as keys and items implementing \Aimeos\Base\Criteria\Attribute\Iface
225
	 */
226
	public function getSaveAttributes() : array
227
	{
228
		return $this->createAttributes( $this->searchConfig );
229
	}
230
231
232
	/**
233
	 * Returns the attributes that can be used for searching.
234
	 *
235
	 * @param bool $withsub Return also attributes of sub-managers if true
236
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
237
	 */
238
	public function getSearchAttributes( bool $withsub = true ) : array
239
	{
240
		$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
241
		$level = $this->context()->config()->get( 'mshop/order/manager/sitemode', $level );
242
243
		$name = 'order:status';
0 ignored issues
show
Unused Code introduced by
The assignment to $name is dead and can be removed.
Loading history...
244
		$expr = $this->siteString( 'mordst_cs."siteid"', $level );
245
246
		return array_replace( parent::getSearchAttributes( $withsub ), $this->createAttributes( [
247
			'order.sitecode' => [
248
				'label' => 'Order site code',
249
				'internalcode' => 'sitecode',
250
				'public' => false,
251
			],
252
			'order.languageid' => [
253
				'label' => 'Order language code',
254
				'internalcode' => 'langid',
255
			],
256
			'order.currencyid' => [
257
				'label' => 'Order currencyid code',
258
				'internalcode' => 'currencyid',
259
			],
260
			'order.price' => [
261
				'label' => 'Order price amount',
262
				'internalcode' => 'price',
263
			],
264
			'order.costs' => [
265
				'label' => 'Order shipping amount',
266
				'internalcode' => 'costs',
267
			],
268
			'order.rebate' => [
269
				'label' => 'Order rebate amount',
270
				'internalcode' => 'rebate',
271
			],
272
			'order.taxvalue' => [
273
				'label' => 'Order tax amount',
274
				'internalcode' => 'tax',
275
			],
276
			'order.taxflag' => [
277
				'label' => 'Order tax flag (0=net, 1=gross)',
278
				'internalcode' => 'taxflag',
279
			],
280
			'order.cdate' => [
281
				'label' => 'Create date',
282
				'internalcode' => 'cdate',
283
			],
284
			'order.cmonth' => [
285
				'label' => 'Create month',
286
				'internalcode' => 'cmonth',
287
			],
288
			'order.cweek' => [
289
				'label' => 'Create week',
290
				'internalcode' => 'cweek',
291
			],
292
			'order.cwday' => [
293
				'label' => 'Create weekday',
294
				'internalcode' => 'cwday',
295
			],
296
			'order.chour' => [
297
				'label' => 'Create hour',
298
				'internalcode' => 'chour',
299
			],
300
			'order:status' => [
301
				'code' => 'order:status()',
302
				'internalcode' => '( SELECT COUNT(mordst_cs."parentid")
303
					FROM "mshop_order_status" AS mordst_cs
304
					WHERE mord."id" = mordst_cs."parentid" AND ' . $expr . '
305
					AND mordst_cs."type" = $1 AND mordst_cs."value" IN ( $2 ) )',
306
				'label' => 'Number of order status items, parameter(<type>,<value>)',
307
				'type' => 'int',
308
				'public' => false,
309
			],
310
		] ) );
311
	}
312
313
314
	/**
315
	 * Binds additional values to the statement before execution.
316
	 *
317
	 * @param \Aimeos\MShop\Common\Item\Iface $item Item object
318
	 * @param \Aimeos\Base\DB\Statement\Iface $stmt Database statement object
319
	 * @param int $idx Current bind index
320
	 * @return \Aimeos\Base\DB\Statement\Iface Database statement object with bound values
321
	 */
322
	protected function bind( \Aimeos\MShop\Common\Item\Iface $item, \Aimeos\Base\DB\Statement\Iface $stmt, int &$idx ) : \Aimeos\Base\DB\Statement\Iface
323
	{
324
		$price = $item->getPrice();
325
		$context = $this->context();
326
327
		$stmt->bind( $idx++, $context->locale()->getSiteItem()->getCode() );
328
		$stmt->bind( $idx++, $item->locale()->getLanguageId() );
329
		$stmt->bind( $idx++, $price->getCurrencyId() );
330
		$stmt->bind( $idx++, $price->getValue() );
331
		$stmt->bind( $idx++, $price->getCosts() );
332
		$stmt->bind( $idx++, $price->getRebate() );
333
		$stmt->bind( $idx++, $price->getTaxValue() );
334
		$stmt->bind( $idx++, $price->getTaxFlag(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
335
336
		if( $item->getId() === null )
337
		{
338
			$date = date_create_from_format( 'Y-m-d H:i:s', $context->datetime() );
339
			$stmt->bind( $idx++, $date->format( 'Y-m-d' ) ); // cdate
340
			$stmt->bind( $idx++, $date->format( 'Y-m' ) ); // cmonth
341
			$stmt->bind( $idx++, $date->format( 'Y-W' ) ); // cweek
342
			$stmt->bind( $idx++, $date->format( 'w' ) ); // cwday
343
			$stmt->bind( $idx++, $date->format( 'G' ) ); // chour
344
		}
345
346
		return $stmt;
347
	}
348
349
350
	/**
351
	 * Creates a one-time order in the storage from the given invoice object.
352
	 *
353
	 * @param \Aimeos\MShop\Common\Item\Iface $item Order item with necessary values
354
	 * @param bool $fetch True if the new ID should be returned in the item
355
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
356
	 */
357
	protected function saveBase( \Aimeos\MShop\Common\Item\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Common\Item\Iface
358
	{
359
		if( !$item->isModified() )
360
		{
361
			$this->saveAddresses( $item )->saveServices( $item )->saveProducts( $item )->saveCoupons( $item );
362
			return $item;
363
		}
364
365
		if( empty( $item->getInvoiceNumber() ) && $item->getStatusPayment() >= \Aimeos\MShop\Order\Item\Base::PAY_PENDING )
366
		{
367
			try {
368
				$item->setInvoiceNumber( $this->createInvoiceNumber( $item ) );
369
			} catch( \Exception $e ) { // redo on transaction deadlock
370
				$item->setInvoiceNumber( $this->createInvoiceNumber( $item ) );
371
			}
372
		}
373
374
		$item = parent::saveBase( $item, $fetch );
375
376
		$this->saveAddresses( $item )->saveServices( $item )->saveProducts( $item )->saveCoupons( $item );
377
		$this->addStatus( $item );
378
379
		return $item;
380
	}
381
382
383
	/**
384
	 * Fetches the rows from the database statement and returns the list of items.
385
	 *
386
	 * @param \Aimeos\Base\DB\Result\Iface $stmt Database statement object
387
	 * @param array $ref List of domains whose items should be fetched too
388
	 * @param string $prefix Prefix for the property names
389
	 * @param array $attrs List of attributes that should be decoded
390
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Common\Item\Iface
391
	 */
392
	protected function fetch( \Aimeos\Base\DB\Result\Iface $results, array $ref, string $prefix = '', array $attrs = [] ) : \Aimeos\Map
393
	{
394
		$map = [];
395
		$context = $this->context();
396
397
		$priceManager = \Aimeos\MShop::create( $context, 'price' );
398
		$localeManager = \Aimeos\MShop::create( $context, 'locale' );
399
400
		while( $row = $results->fetch() )
401
		{
402
			$row['.price'] = $priceManager->create( [
403
				'price.currencyid' => $row['order.currencyid'],
404
				'price.value' => $row['order.price'],
405
				'price.costs' => $row['order.costs'],
406
				'price.rebate' => $row['order.rebate'],
407
				'price.taxflag' => $row['order.taxflag'],
408
				'price.taxvalue' => $row['order.taxvalue'],
409
				'price.siteid' => $row['order.siteid'],
410
			] );
411
412
			// you may need the site object! take care!
413
			$row['.locale'] = $localeManager->create( [
414
				'locale.currencyid' => $row['order.currencyid'],
415
				'locale.languageid' => $row['order.languageid'],
416
				'locale.siteid' => $row['order.siteid'],
417
			] );
418
419
			$map[$row['order.id']] = $row;
420
		}
421
422
		$ids = array_keys( $map );
423
		$items = $addresses = $customers = $coupons = $products = $services = [];
424
425
		if( $this->hasRef( $ref, 'customer' ) && !( $cids = map( $map )->col( 'order.customerid' )->filter() )->empty() )
426
		{
427
			$manager = \Aimeos\MShop::create( $this->context(), 'customer' );
428
			$search = $manager->filter()->slice( 0, 0x7fffffff )->add( ['customer.id' => $cids] );
429
			$customers = $manager->search( $search, $ref );
430
		}
431
432
		if( $this->hasRef( $ref, 'order/address' ) ) {
433
			$addresses = $this->getAddresses( $ids, $ref );
434
		}
435
436
		if( $this->hasRef( $ref, 'order/product' ) || $this->hasRef( $ref, 'order/coupon' ) ) {
437
			$products = $this->getProducts( $ids, $ref );
438
		}
439
440
		if( $this->hasRef( $ref, 'order/coupon' ) ) {
441
			$coupons = $this->getCoupons( $ids, $ref );
442
		}
443
444
		if( $this->hasRef( $ref, 'order/service' ) ) {
445
			$services = $this->getServices( $ids, $ref );
446
		}
447
448
		foreach( $map as $id => $row )
449
		{
450
			$row['.customer'] = $customers[$row['order.customerid']] ?? null;
451
			$row['.addresses'] = $addresses[$id] ?? [];
452
			$row['.coupons'] = $coupons[$id] ?? [];
453
			$row['.products'] = $products[$id] ?? [];
454
			$row['.services'] = $services[$id] ?? [];
455
456
			if( $item = $this->applyFilter( $item = $this->create( $row ) ) ) {
457
				$items[$id] = $item;
458
			}
459
		}
460
461
		return map( $items );
462
	}
463
464
465
	/**
466
	 * Adds the new payment and delivery values to the order status log.
467
	 *
468
	 * @param \Aimeos\MShop\Order\Item\Iface $item Order item object
469
	 */
470
	protected function addStatus( \Aimeos\MShop\Order\Item\Iface $item )
471
	{
472
		$statusManager = \Aimeos\MShop::create( $this->context(), 'order/status' );
473
474
		$statusItem = $statusManager->create();
475
		$statusItem->setParentId( $item->getId() );
476
477
		if( ( $status = $item->get( '.statuspayment' ) ) !== null && $status != $item->getStatusPayment() )
478
		{
479
			$statusItem->setId( null )->setValue( $item->getStatusPayment() )
480
				->setType( \Aimeos\MShop\Order\Item\Status\Base::STATUS_PAYMENT );
481
482
			$statusManager->save( $statusItem, false );
483
		}
484
485
		if( ( $status = $item->get( '.statusdelivery' ) ) !== null && $status != $item->getStatusDelivery() )
486
		{
487
			$statusItem->setId( null )->setValue( $item->getStatusDelivery() )
488
				->setType( \Aimeos\MShop\Order\Item\Status\Base::STATUS_DELIVERY );
489
490
			$statusManager->save( $statusItem, false );
491
		}
492
	}
493
494
495
	/**
496
	 * Creates a new invoice number for the passed order and site.
497
	 *
498
	 * @param \Aimeos\MShop\Order\Item\Iface $item Order item with necessary values
499
	 * @return string Unique invoice number for the current site
500
	 */
501
	protected function createInvoiceNumber( \Aimeos\MShop\Order\Item\Iface $item ) : string
502
	{
503
		$context = $this->context();
504
		$siteId = $context->locale()->getSiteId();
505
		$conn = $context->db( 'db-locale', true );
506
507
		try
508
		{
509
			$conn->query( 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE' )->finish();
510
			$conn->query( 'START TRANSACTION' )->finish();
511
512
			$result = $conn->query( 'SELECT "invoiceno" FROM "mshop_locale_site" where "siteid" = ?', [$siteId] );
513
			$row = $result->fetch();
514
			$result->finish();
515
516
			$conn->create( 'UPDATE "mshop_locale_site" SET "invoiceno" = "invoiceno" + 1 WHERE "siteid" = ?' )
517
				->bind( 1, $siteId )->execute()->finish();
518
519
			$conn->query( 'COMMIT' )->finish();
520
		}
521
		catch( \Exception $e )
522
		{
523
			$conn->close();
524
			throw $e;
525
		}
526
527
		return $row['invoiceno'] ?? '';
528
	}
529
530
531
	/**
532
	 * Returns the prefix for the item properties and search keys.
533
	 *
534
	 * @return string Prefix for the item properties and search keys
535
	 */
536
	protected function prefix() : string
537
	{
538
		return 'order.';
539
	}
540
541
542
	/** mshop/order/manager/name
543
	 * Class name of the used order manager implementation
544
	 *
545
	 * Each default manager can be replace by an alternative imlementation.
546
	 * To use this implementation, you have to set the last part of the class
547
	 * name as configuration value so the manager factory knows which class it
548
	 * has to instantiate.
549
	 *
550
	 * For example, if the name of the default class is
551
	 *
552
	 *  \Aimeos\MShop\Order\Manager\Standard
553
	 *
554
	 * and you want to replace it with your own version named
555
	 *
556
	 *  \Aimeos\MShop\Order\Manager\Mymanager
557
	 *
558
	 * then you have to set the this configuration option:
559
	 *
560
	 *  mshop/order/manager/name = Mymanager
561
	 *
562
	 * The value is the last part of your own class name and it's case sensitive,
563
	 * so take care that the configuration value is exactly named like the last
564
	 * part of the class name.
565
	 *
566
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
567
	 * characters are possible! You should always start the last part of the class
568
	 * name with an upper case character and continue only with lower case characters
569
	 * or numbers. Avoid chamel case names like "MyManager"!
570
	 *
571
	 * @param string Last part of the class name
572
	 * @since 2015.10
573
	 */
574
575
	/** mshop/order/manager/decorators/excludes
576
	 * Excludes decorators added by the "common" option from the order manager
577
	 *
578
	 * Decorators extend the functionality of a class by adding new aspects
579
	 * (e.g. log what is currently done), executing the methods of the underlying
580
	 * class only in certain conditions (e.g. only for logged in users) or
581
	 * modify what is returned to the caller.
582
	 *
583
	 * This option allows you to remove a decorator added via
584
	 * "mshop/common/manager/decorators/default" before they are wrapped
585
	 * around the order manager.
586
	 *
587
	 *  mshop/order/manager/decorators/excludes = array( 'decorator1' )
588
	 *
589
	 * This would remove the decorator named "decorator1" from the list of
590
	 * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
591
	 * "mshop/common/manager/decorators/default" for the order manager.
592
	 *
593
	 * @param array List of decorator names
594
	 * @since 2015.10
595
	 * @see mshop/common/manager/decorators/default
596
	 * @see mshop/order/manager/decorators/global
597
	 * @see mshop/order/manager/decorators/local
598
	 */
599
600
	/** mshop/order/manager/decorators/global
601
	 * Adds a list of globally available decorators only to the order manager
602
	 *
603
	 * Decorators extend the functionality of a class by adding new aspects
604
	 * (e.g. log what is currently done), executing the methods of the underlying
605
	 * class only in certain conditions (e.g. only for logged in users) or
606
	 * modify what is returned to the caller.
607
	 *
608
	 * This option allows you to wrap global decorators
609
	 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the order manager.
610
	 *
611
	 *  mshop/order/manager/decorators/global = array( 'decorator1' )
612
	 *
613
	 * This would add the decorator named "decorator1" defined by
614
	 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the order
615
	 * manager.
616
	 *
617
	 * @param array List of decorator names
618
	 * @since 2015.10
619
	 * @see mshop/common/manager/decorators/default
620
	 * @see mshop/order/manager/decorators/excludes
621
	 * @see mshop/order/manager/decorators/local
622
	 */
623
624
	/** mshop/order/manager/decorators/local
625
	 * Adds a list of local decorators only to the order manager
626
	 *
627
	 * Decorators extend the functionality of a class by adding new aspects
628
	 * (e.g. log what is currently done), executing the methods of the underlying
629
	 * class only in certain conditions (e.g. only for logged in users) or
630
	 * modify what is returned to the caller.
631
	 *
632
	 * This option allows you to wrap local decorators
633
	 * ("\Aimeos\MShop\Order\Manager\Decorator\*") around the order manager.
634
	 *
635
	 *  mshop/order/manager/decorators/local = array( 'decorator2' )
636
	 *
637
	 * This would add the decorator named "decorator2" defined by
638
	 * "\Aimeos\MShop\Order\Manager\Decorator\Decorator2" only to the order
639
	 * manager.
640
	 *
641
	 * @param array List of decorator names
642
	 * @since 2015.10
643
	 * @see mshop/common/manager/decorators/default
644
	 * @see mshop/order/manager/decorators/excludes
645
	 * @see mshop/order/manager/decorators/global
646
	 */
647
648
	/** mshop/order/manager/resource
649
	 * Name of the database connection resource to use
650
	 *
651
	 * You can configure a different database connection for each data domain
652
	 * and if no such connection name exists, the "db" connection will be used.
653
	 * It's also possible to use the same database connection for different
654
	 * data domains by configuring the same connection name using this setting.
655
	 *
656
	 * @param string Database connection name
657
	 * @since 2023.04
658
	 */
659
660
661
	/** mshop/order/manager/delete/mysql
662
	 * Deletes the items matched by the given IDs from the database
663
	 *
664
	 * @see mshop/order/manager/delete/ansi
665
	 */
666
667
	/** mshop/order/manager/delete/ansi
668
	 * Deletes the items matched by the given IDs from the database
669
	 *
670
	 * Removes the records specified by the given IDs from the order database.
671
	 * The records must be from the site that is configured via the
672
	 * context item.
673
	 *
674
	 * The ":cond" placeholder is replaced by the name of the ID column and
675
	 * the given ID or list of IDs while the site ID is bound to the question
676
	 * mark.
677
	 *
678
	 * The SQL statement should conform to the ANSI standard to be
679
	 * compatible with most relational database systems. This also
680
	 * includes using double quotes for table and column names.
681
	 *
682
	 * @param string SQL statement for deleting items
683
	 * @since 2015.10
684
	 * @see mshop/order/manager/insert/ansi
685
	 * @see mshop/order/manager/update/ansi
686
	 * @see mshop/order/manager/newid/ansi
687
	 * @see mshop/order/manager/search/ansi
688
	 * @see mshop/order/manager/count/ansi
689
	 */
690
691
	/** mshop/order/manager/submanagers
692
	 * List of manager names that can be instantiated by the order manager
693
	 *
694
	 * Managers provide a generic interface to the underlying storage.
695
	 * Each manager has or can have sub-managers caring about particular
696
	 * aspects. Each of these sub-managers can be instantiated by its
697
	 * parent manager using the getSubManager() method.
698
	 *
699
	 * The search keys from sub-managers can be normally used in the
700
	 * manager as well. It allows you to search for items of the manager
701
	 * using the search keys of the sub-managers to further limit the
702
	 * retrieved list of items.
703
	 *
704
	 * @param array List of sub-manager names
705
	 * @since 2015.10
706
	 */
707
708
	/** mshop/order/manager/insert/mysql
709
	 * Inserts a new order record into the database table
710
	 *
711
	 * @see mshop/order/manager/insert/ansi
712
	 */
713
714
	/** mshop/order/manager/insert/ansi
715
	 * Inserts a new order record into the database table
716
	 *
717
	 * Items with no ID yet (i.e. the ID is NULL) will be created in
718
	 * the database and the newly created ID retrieved afterwards
719
	 * using the "newid" SQL statement.
720
	 *
721
	 * The SQL statement must be a string suitable for being used as
722
	 * prepared statement. It must include question marks for binding
723
	 * the values from the order item to the statement before they are
724
	 * sent to the database server. The number of question marks must
725
	 * be the same as the number of columns listed in the INSERT
726
	 * statement. The catalog of the columns must correspond to the
727
	 * catalog in the save() method, so the correct values are
728
	 * bound to the columns.
729
	 *
730
	 * The SQL statement should conform to the ANSI standard to be
731
	 * compatible with most relational database systems. This also
732
	 * includes using double quotes for table and column names.
733
	 *
734
	 * @param string SQL statement for inserting records
735
	 * @since 2015.10
736
	 * @see mshop/order/manager/update/ansi
737
	 * @see mshop/order/manager/newid/ansi
738
	 * @see mshop/order/manager/delete/ansi
739
	 * @see mshop/order/manager/search/ansi
740
	 * @see mshop/order/manager/count/ansi
741
	 */
742
743
	/** mshop/order/manager/update/mysql
744
	 * Updates an existing order record in the database
745
	 *
746
	 * @see mshop/order/manager/update/ansi
747
	 */
748
749
	/** mshop/order/manager/update/ansi
750
	 * Updates an existing order record in the database
751
	 *
752
	 * Items which already have an ID (i.e. the ID is not NULL) will
753
	 * be updated in the database.
754
	 *
755
	 * The SQL statement must be a string suitable for being used as
756
	 * prepared statement. It must include question marks for binding
757
	 * the values from the order item to the statement before they are
758
	 * sent to the database server. The catalog of the columns must
759
	 * correspond to the catalog in the save() method, so the
760
	 * correct values are bound to the columns.
761
	 *
762
	 * The SQL statement should conform to the ANSI standard to be
763
	 * compatible with most relational database systems. This also
764
	 * includes using double quotes for table and column names.
765
	 *
766
	 * @param string SQL statement for updating records
767
	 * @since 2015.10
768
	 * @see mshop/order/manager/insert/ansi
769
	 * @see mshop/order/manager/newid/ansi
770
	 * @see mshop/order/manager/delete/ansi
771
	 * @see mshop/order/manager/search/ansi
772
	 * @see mshop/order/manager/count/ansi
773
	 */
774
775
	/** mshop/order/manager/newid/mysql
776
	 * Retrieves the ID generated by the database when inserting a new record
777
	 *
778
	 * @see mshop/order/manager/newid/ansi
779
	 */
780
781
	/** mshop/order/manager/newid/ansi
782
	 * Retrieves the ID generated by the database when inserting a new record
783
	 *
784
	 * As soon as a new record is inserted into the database table,
785
	 * the database server generates a new and unique identifier for
786
	 * that record. This ID can be used for retrieving, updating and
787
	 * deleting that specific record from the table again.
788
	 *
789
	 * For MySQL:
790
	 *  SELECT LAST_INSERT_ID()
791
	 * For PostgreSQL:
792
	 *  SELECT currval('seq_mrul_id')
793
	 * For SQL Server:
794
	 *  SELECT SCOPE_IDENTITY()
795
	 * For Oracle:
796
	 *  SELECT "seq_mrul_id".CURRVAL FROM DUAL
797
	 *
798
	 * There's no way to retrive the new ID by a SQL statements that
799
	 * fits for most database servers as they implement their own
800
	 * specific way.
801
	 *
802
	 * @param string SQL statement for retrieving the last inserted record ID
803
	 * @since 2015.10
804
	 * @see mshop/order/manager/insert/ansi
805
	 * @see mshop/order/manager/update/ansi
806
	 * @see mshop/order/manager/delete/ansi
807
	 * @see mshop/order/manager/search/ansi
808
	 * @see mshop/order/manager/count/ansi
809
	 */
810
811
	/** mshop/order/manager/sitemode
812
	 * Mode how items from levels below or above in the site tree are handled
813
	 *
814
	 * By default, only items from the current site are fetched from the
815
	 * storage. If the ai-sites extension is installed, you can create a
816
	 * tree of sites. Then, this setting allows you to define for the
817
	 * whole order domain if items from parent sites are inherited,
818
	 * sites from child sites are aggregated or both.
819
	 *
820
	 * Available constants for the site mode are:
821
	 * * 0 = only items from the current site
822
	 * * 1 = inherit items from parent sites
823
	 * * 2 = aggregate items from child sites
824
	 * * 3 = inherit and aggregate items at the same time
825
	 *
826
	 * You also need to set the mode in the locale manager
827
	 * (mshop/locale/manager/sitelevel) to one of the constants.
828
	 * If you set it to the same value, it will work as described but you
829
	 * can also use different modes. For example, if inheritance and
830
	 * aggregation is configured the locale manager but only inheritance
831
	 * in the domain manager because aggregating items makes no sense in
832
	 * this domain, then items wil be only inherited. Thus, you have full
833
	 * control over inheritance and aggregation in each domain.
834
	 *
835
	 * @param int Constant from Aimeos\MShop\Locale\Manager\Base class
836
	 * @since 2018.01
837
	 * @see mshop/locale/manager/sitelevel
838
	 */
839
840
	/** mshop/order/manager/search/mysql
841
	 * Retrieves the records matched by the given criteria in the database
842
	 *
843
	 * @see mshop/order/manager/search/ansi
844
	 */
845
846
	/** mshop/order/manager/search/ansi
847
	 * Retrieves the records matched by the given criteria in the database
848
	 *
849
	 * Fetches the records matched by the given criteria from the order
850
	 * database. The records must be from one of the sites that are
851
	 * configured via the context item. If the current site is part of
852
	 * a tree of sites, the SELECT statement can retrieve all records
853
	 * from the current site and the complete sub-tree of sites.
854
	 *
855
	 * As the records can normally be limited by criteria from sub-managers,
856
	 * their tables must be joined in the SQL context. This is done by
857
	 * using the "internaldeps" property from the definition of the ID
858
	 * column of the sub-managers. These internal dependencies specify
859
	 * the JOIN between the tables and the used columns for joining. The
860
	 * ":joins" placeholder is then replaced by the JOIN strings from
861
	 * the sub-managers.
862
	 *
863
	 * To limit the records matched, conditions can be added to the given
864
	 * criteria object. It can contain comparisons like column names that
865
	 * must match specific values which can be combined by AND, OR or NOT
866
	 * operators. The resulting string of SQL conditions replaces the
867
	 * ":cond" placeholder before the statement is sent to the database
868
	 * server.
869
	 *
870
	 * If the records that are retrieved should be cataloged by one or more
871
	 * columns, the generated string of column / sort direction pairs
872
	 * replaces the ":catalog" placeholder. In case no cataloging is required,
873
	 * the complete ORDER BY part including the "\/*-catalogby*\/...\/*catalogby-*\/"
874
	 * markers is removed to speed up retrieving the records. Columns of
875
	 * sub-managers can also be used for cataloging the result set but then
876
	 * no index can be used.
877
	 *
878
	 * The number of returned records can be limited and can start at any
879
	 * number between the begining and the end of the result set. For that
880
	 * the ":size" and ":start" placeholders are replaced by the
881
	 * corresponding values from the criteria object. The default values
882
	 * are 0 for the start and 100 for the size value.
883
	 *
884
	 * The SQL statement should conform to the ANSI standard to be
885
	 * compatible with most relational database systems. This also
886
	 * includes using double quotes for table and column names.
887
	 *
888
	 * @param string SQL statement for searching items
889
	 * @since 2015.10
890
	 * @see mshop/order/manager/insert/ansi
891
	 * @see mshop/order/manager/update/ansi
892
	 * @see mshop/order/manager/newid/ansi
893
	 * @see mshop/order/manager/delete/ansi
894
	 * @see mshop/order/manager/count/ansi
895
	 */
896
897
	/** mshop/order/manager/count/mysql
898
	 * Counts the number of records matched by the given criteria in the database
899
	 *
900
	 * @see mshop/order/manager/count/ansi
901
	 */
902
903
	/** mshop/order/manager/count/ansi
904
	 * Counts the number of records matched by the given criteria in the database
905
	 *
906
	 * Counts all records matched by the given criteria from the order
907
	 * database. The records must be from one of the sites that are
908
	 * configured via the context item. If the current site is part of
909
	 * a tree of sites, the statement can count all records from the
910
	 * current site and the complete sub-tree of sites.
911
	 *
912
	 * As the records can normally be limited by criteria from sub-managers,
913
	 * their tables must be joined in the SQL context. This is done by
914
	 * using the "internaldeps" property from the definition of the ID
915
	 * column of the sub-managers. These internal dependencies specify
916
	 * the JOIN between the tables and the used columns for joining. The
917
	 * ":joins" placeholder is then replaced by the JOIN strings from
918
	 * the sub-managers.
919
	 *
920
	 * To limit the records matched, conditions can be added to the given
921
	 * criteria object. It can contain comparisons like column names that
922
	 * must match specific values which can be combined by AND, OR or NOT
923
	 * operators. The resulting string of SQL conditions replaces the
924
	 * ":cond" placeholder before the statement is sent to the database
925
	 * server.
926
	 *
927
	 * Both, the strings for ":joins" and for ":cond" are the same as for
928
	 * the "search" SQL statement.
929
	 *
930
	 * Contrary to the "search" statement, it doesn't return any records
931
	 * but instead the number of records that have been found. As counting
932
	 * thousands of records can be a long running task, the maximum number
933
	 * of counted records is limited for performance reasons.
934
	 *
935
	 * The SQL statement should conform to the ANSI standard to be
936
	 * compatible with most relational database systems. This also
937
	 * includes using double quotes for table and column names.
938
	 *
939
	 * @param string SQL statement for counting items
940
	 * @since 2015.10
941
	 * @see mshop/order/manager/insert/ansi
942
	 * @see mshop/order/manager/update/ansi
943
	 * @see mshop/order/manager/newid/ansi
944
	 * @see mshop/order/manager/delete/ansi
945
	 * @see mshop/order/manager/search/ansi
946
	 */
947
}
948