Passed
Push — master ( 6aab01...0294bc )
by Aimeos
09:44
created

Standard::saveItem()   B

Complexity

Conditions 7
Paths 17

Size

Total Lines 180
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 55
dl 0
loc 180
rs 8.0484
c 0
b 0
f 0
cc 7
nc 17
nop 2

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 Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 * @package MShop
8
 * @subpackage Order
9
 */
10
11
12
namespace Aimeos\MShop\Order\Manager\Base\Address;
13
14
15
/**
16
 * Default order address manager implementation.
17
 *
18
 * @package MShop
19
 * @subpackage Order
20
 */
21
class Standard
22
	extends \Aimeos\MShop\Common\Manager\Base
23
	implements \Aimeos\MShop\Order\Manager\Base\Address\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	private $searchConfig = array(
26
		'order.base.address.id' => array(
27
			'code' => 'order.base.address.id',
28
			'internalcode' => 'mordbaad."id"',
29
			'internaldeps' => array( 'LEFT JOIN "mshop_order_base_address" AS mordbaad ON ( mordba."id" = mordbaad."baseid" )' ),
30
			'label' => 'Address ID',
31
			'type' => 'integer',
32
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
33
			'public' => false,
34
		),
35
		'order.base.address.baseid' => array(
36
			'code' => 'order.base.address.baseid',
37
			'internalcode' => 'mordbaad."baseid"',
38
			'label' => 'Order ID',
39
			'type' => 'integer',
40
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
41
			'public' => false,
42
		),
43
		'order.base.address.siteid' => array(
44
			'code' => 'order.base.address.siteid',
45
			'internalcode' => 'mordbaad."siteid"',
46
			'label' => 'Address site ID',
47
			'type' => 'string',
48
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
49
			'public' => false,
50
		),
51
		'order.base.address.addressid' => array(
52
			'code' => 'order.base.address.addressid',
53
			'internalcode' => 'mordbaad."addrid"',
54
			'label' => 'Customer address ID',
55
			'type' => 'string',
56
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
57
			'public' => false,
58
		),
59
		'order.base.address.type' => array(
60
			'code' => 'order.base.address.type',
61
			'internalcode' => 'mordbaad."type"',
62
			'label' => 'Address type',
63
			'type' => 'string',
64
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
65
		),
66
		'order.base.address.company' => array(
67
			'code' => 'order.base.address.company',
68
			'internalcode' => 'mordbaad."company"',
69
			'label' => 'Address company',
70
			'type' => 'string',
71
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
72
		),
73
		'order.base.address.vatid' => array(
74
			'code' => 'order.base.address.vatid',
75
			'internalcode' => 'mordbaad."vatid"',
76
			'label' => 'Address Vat ID',
77
			'type' => 'string',
78
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
79
		),
80
		'order.base.address.salutation' => array(
81
			'code' => 'order.base.address.salutation',
82
			'internalcode' => 'mordbaad."salutation"',
83
			'label' => 'Address salutation',
84
			'type' => 'string',
85
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
86
		),
87
		'order.base.address.title' => array(
88
			'code' => 'order.base.address.title',
89
			'internalcode' => 'mordbaad."title"',
90
			'label' => 'Address title',
91
			'type' => 'string',
92
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
93
		),
94
		'order.base.address.firstname' => array(
95
			'code' => 'order.base.address.firstname',
96
			'internalcode' => 'mordbaad."firstname"',
97
			'label' => 'Address firstname',
98
			'type' => 'string',
99
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
100
		),
101
		'order.base.address.lastname' => array(
102
			'code' => 'order.base.address.lastname',
103
			'internalcode' => 'mordbaad."lastname"',
104
			'label' => 'Address lastname',
105
			'type' => 'string',
106
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
107
		),
108
		'order.base.address.address1' => array(
109
			'code' => 'order.base.address.address1',
110
			'internalcode' => 'mordbaad."address1"',
111
			'label' => 'Address part one',
112
			'type' => 'string',
113
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
114
		),
115
		'order.base.address.address2' => array(
116
			'code' => 'order.base.address.address2',
117
			'internalcode' => 'mordbaad."address2"',
118
			'label' => 'Address part two',
119
			'type' => 'string',
120
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
121
		),
122
		'order.base.address.address3' => array(
123
			'code' => 'order.base.address.address3',
124
			'internalcode' => 'mordbaad."address3"',
125
			'label' => 'Address part three',
126
			'type' => 'string',
127
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
128
		),
129
		'order.base.address.postal' => array(
130
			'code' => 'order.base.address.postal',
131
			'internalcode' => 'mordbaad."postal"',
132
			'label' => 'Address postal',
133
			'type' => 'string',
134
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
135
		),
136
		'order.base.address.city' => array(
137
			'code' => 'order.base.address.city',
138
			'internalcode' => 'mordbaad."city"',
139
			'label' => 'Address city',
140
			'type' => 'string',
141
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
142
		),
143
		'order.base.address.state' => array(
144
			'code' => 'order.base.address.state',
145
			'internalcode' => 'mordbaad."state"',
146
			'label' => 'Address state',
147
			'type' => 'string',
148
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
149
		),
150
		'order.base.address.countryid' => array(
151
			'code' => 'order.base.address.countryid',
152
			'internalcode' => 'mordbaad."countryid"',
153
			'label' => 'Address country ID',
154
			'type' => 'string',
155
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
156
		),
157
		'order.base.address.languageid' => array(
158
			'code' => 'order.base.address.languageid',
159
			'internalcode' => 'mordbaad."langid"',
160
			'label' => 'Address language ID',
161
			'type' => 'string',
162
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
163
		),
164
		'order.base.address.telephone' => array(
165
			'code' => 'order.base.address.telephone',
166
			'internalcode' => 'mordbaad."telephone"',
167
			'label' => 'Address telephone',
168
			'type' => 'string',
169
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
170
		),
171
		'order.base.address.email' => array(
172
			'code' => 'order.base.address.email',
173
			'internalcode' => 'mordbaad."email"',
174
			'label' => 'Address email',
175
			'type' => 'string',
176
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
177
		),
178
		'order.base.address.telefax' => array(
179
			'code' => 'order.base.address.telefax',
180
			'internalcode' => 'mordbaad."telefax"',
181
			'label' => 'Address telefax',
182
			'type' => 'string',
183
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
184
		),
185
		'order.base.address.website' => array(
186
			'code' => 'order.base.address.website',
187
			'internalcode' => 'mordbaad."website"',
188
			'label' => 'Address website',
189
			'type' => 'string',
190
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
191
		),
192
		'order.base.address.longitude' => array(
193
			'code' => 'order.base.address.longitude',
194
			'internalcode' => 'mordbaad."longitude"',
195
			'label' => 'Address longitude',
196
			'type' => 'string',
197
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
198
			'public' => false,
199
		),
200
		'order.base.address.latitude' => array(
201
			'code' => 'order.base.address.latitude',
202
			'internalcode' => 'mordbaad."latitude"',
203
			'label' => 'Address latitude',
204
			'type' => 'string',
205
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
206
			'public' => false,
207
		),
208
		'order.base.address.position' => array(
209
			'code' => 'order.base.address.position',
210
			'internalcode' => 'mordbaad."pos"',
211
			'label' => 'Address position',
212
			'type' => 'integer',
213
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
214
			'public' => false,
215
		),
216
		'order.base.address.birthday' => array(
217
			'code' => 'order.base.address.birthday',
218
			'internalcode' => 'mordbaad."birthday"',
219
			'label' => 'Address birthday',
220
			'type' => 'date',
221
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
222
			'public' => false,
223
		),
224
		'order.base.address.ctime' => array(
225
			'code' => 'order.base.address.ctime',
226
			'internalcode' => 'mordbaad."ctime"',
227
			'label' => 'Address create date/time',
228
			'type' => 'datetime',
229
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
230
			'public' => false,
231
		),
232
		'order.base.address.mtime' => array(
233
			'code' => 'order.base.address.mtime',
234
			'internalcode' => 'mordbaad."mtime"',
235
			'label' => 'Address modify date/time',
236
			'type' => 'string',
237
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
238
			'public' => false,
239
		),
240
		'order.base.address.editor' => array(
241
			'code' => 'order.base.address.editor',
242
			'internalcode' => 'mordbaad."editor"',
243
			'label' => 'Address editor',
244
			'type' => 'string',
245
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
246
			'public' => false,
247
		),
248
	);
249
250
251
	/**
252
	 * Initializes the object.
253
	 *
254
	 * @param \Aimeos\MShop\ContextIface $context Context object
255
	 */
256
	public function __construct( \Aimeos\MShop\ContextIface $context )
257
	{
258
		parent::__construct( $context );
259
		$this->setResourceName( 'db-order' );
260
	}
261
262
263
	/**
264
	 * Counts the number items that are available for the values of the given key.
265
	 *
266
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria
267
	 * @param array|string $key Search key or list of keys to aggregate items for
268
	 * @param string|null $value Search key for aggregating the value column
269
	 * @param string|null $type Type of the aggregation, empty string for count or "sum" or "avg" (average)
270
	 * @return \Aimeos\Map List of the search keys as key and the number of counted items as value
271
	 */
272
	public function aggregate( \Aimeos\Base\Criteria\Iface $search, $key, string $value = null, string $type = null ) : \Aimeos\Map
273
	{
274
		/** mshop/order/manager/base/address/aggregate/mysql
275
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
276
		 *
277
		 * @see mshop/order/manager/base/address/aggregate/ansi
278
		 */
279
280
		/** mshop/order/manager/base/address/aggregate/ansi
281
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
282
		 *
283
		 * Groups all records by the values in the key column and counts their
284
		 * occurence. The matched records can be limited by the given criteria
285
		 * from the order database. The records must be from one of the sites
286
		 * that are configured via the context item. If the current site is part
287
		 * of a tree of sites, the statement can count all records from the
288
		 * current site and the complete sub-tree of sites.
289
		 *
290
		 * As the records can normally be limited by criteria from sub-managers,
291
		 * their tables must be joined in the SQL context. This is done by
292
		 * using the "internaldeps" property from the definition of the ID
293
		 * column of the sub-managers. These internal dependencies specify
294
		 * the JOIN between the tables and the used columns for joining. The
295
		 * ":joins" placeholder is then replaced by the JOIN strings from
296
		 * the sub-managers.
297
		 *
298
		 * To limit the records matched, conditions can be added to the given
299
		 * criteria object. It can contain comparisons like column names that
300
		 * must match specific values which can be combined by AND, OR or NOT
301
		 * operators. The resulting string of SQL conditions replaces the
302
		 * ":cond" placeholder before the statement is sent to the database
303
		 * server.
304
		 *
305
		 * This statement doesn't return any records. Instead, it returns pairs
306
		 * of the different values found in the key column together with the
307
		 * number of records that have been found for that key values.
308
		 *
309
		 * The SQL statement should conform to the ANSI standard to be
310
		 * compatible with most relational database systems. This also
311
		 * includes using double quotes for table and column names.
312
		 *
313
		 * @param string SQL statement for aggregating order items
314
		 * @since 2014.09
315
		 * @category Developer
316
		 * @see mshop/order/manager/base/address/insert/ansi
317
		 * @see mshop/order/manager/base/address/update/ansi
318
		 * @see mshop/order/manager/base/address/newid/ansi
319
		 * @see mshop/order/manager/base/address/delete/ansi
320
		 * @see mshop/order/manager/base/address/search/ansi
321
		 * @see mshop/order/manager/base/address/count/ansi
322
		 */
323
		$cfgkey = 'mshop/order/manager/base/address/aggregate';
324
		return $this->aggregateBase( $search, $key, $cfgkey, ['order.base.address'], $value, $type );
325
	}
326
327
328
	/**
329
	 * Removes old entries from the storage.
330
	 *
331
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
332
	 * @return \Aimeos\MShop\Order\Manager\Base\Address\Iface Manager object for chaining method calls
333
	 */
334
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
335
	{
336
		$path = 'mshop/order/manager/base/address/submanagers';
337
		foreach( $this->context()->config()->get( $path, [] ) as $domain ) {
338
			$this->object()->getSubManager( $domain )->clear( $siteids );
339
		}
340
341
		return $this->clearBase( $siteids, 'mshop/order/manager/base/address/delete' );
342
	}
343
344
345
	/**
346
	 * Creates a new empty item instance
347
	 *
348
	 * @param array $values Values the item should be initialized with
349
	 * @return \Aimeos\MShop\Order\Item\Base\Address\Iface New order address item object
350
	 */
351
	public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
352
	{
353
		$values['order.base.address.siteid'] = $this->context()->locale()->getSiteId();
354
		return $this->createItemBase( $values );
355
	}
356
357
358
	/**
359
	 * Creates a filter object.
360
	 *
361
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
362
	 * @param bool $site TRUE for adding site criteria to limit items by the site of related items
363
	 * @return \Aimeos\Base\Criteria\Iface Returns the filter object
364
	 */
365
	public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
366
	{
367
		$search = parent::filter( $default );
368
		$search->setSortations( [$search->sort( '+', 'order.base.address.id' )] );
369
370
		return $search;
371
	}
372
373
374
	/**
375
	 * Removes multiple items.
376
	 *
377
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
378
	 * @return \Aimeos\MShop\Order\Manager\Base\Address\Iface Manager object for chaining method calls
379
	 */
380
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
381
	{
382
		/** mshop/order/manager/base/address/delete/mysql
383
		 * Deletes the items matched by the given IDs from the database
384
		 *
385
		 * @see mshop/order/manager/base/address/delete/ansi
386
		 */
387
388
		/** mshop/order/manager/base/address/delete/ansi
389
		 * Deletes the items matched by the given IDs from the database
390
		 *
391
		 * Removes the records specified by the given IDs from the order database.
392
		 * The records must be from the site that is configured via the
393
		 * context item.
394
		 *
395
		 * The ":cond" placeholder is replaced by the name of the ID column and
396
		 * the given ID or list of IDs while the site ID is bound to the question
397
		 * mark.
398
		 *
399
		 * The SQL statement should conform to the ANSI standard to be
400
		 * compatible with most relational database systems. This also
401
		 * includes using double quotes for table and column names.
402
		 *
403
		 * @param string SQL statement for deleting items
404
		 * @since 2014.03
405
		 * @category Developer
406
		 * @see mshop/order/manager/base/address/insert/ansi
407
		 * @see mshop/order/manager/base/address/update/ansi
408
		 * @see mshop/order/manager/base/address/newid/ansi
409
		 * @see mshop/order/manager/base/address/search/ansi
410
		 * @see mshop/order/manager/base/address/count/ansi
411
		 */
412
		$path = 'mshop/order/manager/base/address/delete';
413
414
		return $this->deleteItemsBase( $itemIds, $path );
415
	}
416
417
418
	/**
419
	 * Creates a order base address item object for the given item id.
420
	 *
421
	 * @param string $id Id of the order base address item
422
	 * @param string[] $ref List of domains to fetch list items and referenced items for
423
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
424
	 * @return \Aimeos\MShop\Order\Item\Base\Address\Iface Returns order base address item of the given id
425
	 * @throws \Aimeos\MShop\Exception If item couldn't be found
426
	 */
427
	public function get( string $id, array $ref = [], ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
428
	{
429
		return $this->getItemBase( 'order.base.address.id', $id, $ref, $default );
430
	}
431
432
433
	/**
434
	 * Returns the available manager types
435
	 *
436
	 * @param bool $withsub Return also the resource type of sub-managers if true
437
	 * @return string[] Type of the manager and submanagers, subtypes are separated by slashes
438
	 */
439
	public function getResourceType( bool $withsub = true ) : array
440
	{
441
		$path = 'mshop/order/manager/base/address/submanagers';
442
		return $this->getResourceTypeBase( 'order/base/address', $path, [], $withsub );
443
	}
444
445
446
	/**
447
	 * Returns the attributes that can be used for searching.
448
	 *
449
	 * @param bool $withsub Return also attributes of sub-managers if true
450
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
451
	 */
452
	public function getSearchAttributes( bool $withsub = true ) : array
453
	{
454
		/** mshop/order/manager/base/address/submanagers
455
		 * List of manager names that can be instantiated by the order base address manager
456
		 *
457
		 * Managers provide a generic interface to the underlying storage.
458
		 * Each manager has or can have sub-managers caring about particular
459
		 * aspects. Each of these sub-managers can be instantiated by its
460
		 * parent manager using the getSubManager() method.
461
		 *
462
		 * The search keys from sub-managers can be normally used in the
463
		 * manager as well. It allows you to search for items of the manager
464
		 * using the search keys of the sub-managers to further limit the
465
		 * retrieved list of items.
466
		 *
467
		 * @param array List of sub-manager names
468
		 * @since 2014.03
469
		 * @category Developer
470
		 */
471
		$path = 'mshop/order/manager/base/address/submanagers';
472
473
		return $this->getSearchAttributesBase( $this->searchConfig, $path, [], $withsub );
474
	}
475
476
477
	/**
478
	 * Creates a new manager for order
479
	 *
480
	 * @param string $manager Name of the sub manager type in lower case
481
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
482
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions
483
	 * @throws \Aimeos\MShop\Order\Exception If creating manager failed
484
	 */
485
486
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
487
	{
488
		/** mshop/order/manager/base/address/name
489
		 * Class name of the used order base address manager implementation
490
		 *
491
		 * Each default order base address manager can be replaced by an alternative imlementation.
492
		 * To use this implementation, you have to set the last part of the class
493
		 * name as configuration value so the manager factory knows which class it
494
		 * has to instantiate.
495
		 *
496
		 * For example, if the name of the default class is
497
		 *
498
		 *  \Aimeos\MShop\Order\Manager\Base\Address\Standard
499
		 *
500
		 * and you want to replace it with your own version named
501
		 *
502
		 *  \Aimeos\MShop\Order\Manager\Base\Address\Myaddress
503
		 *
504
		 * then you have to set the this configuration option:
505
		 *
506
		 *  mshop/order/manager/base/address/name = Myaddress
507
		 *
508
		 * The value is the last part of your own class name and it's case sensitive,
509
		 * so take care that the configuration value is exactly named like the last
510
		 * part of the class name.
511
		 *
512
		 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
513
		 * characters are possible! You should always start the last part of the class
514
		 * name with an upper case character and continue only with lower case characters
515
		 * or numbers. Avoid chamel case names like "MyAddress"!
516
		 *
517
		 * @param string Last part of the class name
518
		 * @since 2014.03
519
		 * @category Developer
520
		 */
521
522
		/** mshop/order/manager/base/address/decorators/excludes
523
		 * Excludes decorators added by the "common" option from the order base address manager
524
		 *
525
		 * Decorators extend the functionality of a class by adding new aspects
526
		 * (e.g. log what is currently done), executing the methods of the underlying
527
		 * class only in certain conditions (e.g. only for logged in users) or
528
		 * modify what is returned to the caller.
529
		 *
530
		 * This option allows you to remove a decorator added via
531
		 * "mshop/common/manager/decorators/default" before they are wrapped
532
		 * around the order base address manager.
533
		 *
534
		 *  mshop/order/manager/base/address/decorators/excludes = array( 'decorator1' )
535
		 *
536
		 * This would remove the decorator named "decorator1" from the list of
537
		 * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
538
		 * "mshop/common/manager/decorators/default" for the order base address manager.
539
		 *
540
		 * @param array List of decorator names
541
		 * @since 2014.03
542
		 * @category Developer
543
		 * @see mshop/common/manager/decorators/default
544
		 * @see mshop/order/manager/base/address/decorators/global
545
		 * @see mshop/order/manager/base/address/decorators/local
546
		 */
547
548
		/** mshop/order/manager/base/address/decorators/global
549
		 * Adds a list of globally available decorators only to the order base address manager
550
		 *
551
		 * Decorators extend the functionality of a class by adding new aspects
552
		 * (e.g. log what is currently done), executing the methods of the underlying
553
		 * class only in certain conditions (e.g. only for logged in users) or
554
		 * modify what is returned to the caller.
555
		 *
556
		 * This option allows you to wrap global decorators
557
		 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the order base
558
		 * address manager.
559
		 *
560
		 *  mshop/order/manager/base/address/decorators/global = array( 'decorator1' )
561
		 *
562
		 * This would add the decorator named "decorator1" defined by
563
		 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the order base
564
		 * address manager.
565
		 *
566
		 * @param array List of decorator names
567
		 * @since 2014.03
568
		 * @category Developer
569
		 * @see mshop/common/manager/decorators/default
570
		 * @see mshop/order/manager/base/address/decorators/excludes
571
		 * @see mshop/order/manager/base/address/decorators/local
572
		 */
573
574
		/** mshop/order/manager/base/address/decorators/local
575
		 * Adds a list of local decorators only to the order base address manager
576
		 *
577
		 * Decorators extend the functionality of a class by adding new aspects
578
		 * (e.g. log what is currently done), executing the methods of the underlying
579
		 * class only in certain conditions (e.g. only for logged in users) or
580
		 * modify what is returned to the caller.
581
		 *
582
		 * This option allows you to wrap local decorators
583
		 * ("\Aimeos\MShop\Order\Manager\Base\Address\Decorator\*") around the
584
		 * order base address manager.
585
		 *
586
		 *  mshop/order/manager/base/address/decorators/local = array( 'decorator2' )
587
		 *
588
		 * This would add the decorator named "decorator2" defined by
589
		 * "\Aimeos\MShop\Order\Manager\Base\Address\Decorator\Decorator2" only
590
		 * to the order base address manager.
591
		 *
592
		 * @param array List of decorator names
593
		 * @since 2014.03
594
		 * @category Developer
595
		 * @see mshop/common/manager/decorators/default
596
		 * @see mshop/order/manager/base/address/decorators/excludes
597
		 * @see mshop/order/manager/base/address/decorators/global
598
		 */
599
600
		return $this->getSubManagerBase( 'order', 'base/address/' . $manager, $name );
601
	}
602
603
604
	/**
605
	 * Inserts the new order base address items
606
	 *
607
	 * @param \Aimeos\MShop\Order\Item\Base\Address\Iface $item order address item which should be saved
608
	 * @param bool $fetch True if the new ID should be returned in the item
609
	 * @return \Aimeos\MShop\Order\Item\Base\Address\Iface $item Updated item including the generated ID
610
	 */
611
	public function saveItem( \Aimeos\MShop\Order\Item\Base\Address\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Order\Item\Base\Address\Iface
612
	{
613
		if( !$item->isModified() ) {
614
			return $item;
615
		}
616
617
		$context = $this->context();
618
		$conn = $context->db( $this->getResourceName() );
619
620
			$id = $item->getId();
621
			$date = date( 'Y-m-d H:i:s' );
622
			$columns = $this->object()->getSaveAttributes();
623
624
			if( $id === null )
625
			{
626
				/** mshop/order/manager/base/address/insert/mysql
627
				 * Inserts a new order record into the database table
628
				 *
629
				 * @see mshop/order/manager/base/address/insert/ansi
630
				 */
631
632
				/** mshop/order/manager/base/address/insert/ansi
633
				 * Inserts a new order record into the database table
634
				 *
635
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
636
				 * the database and the newly created ID retrieved afterwards
637
				 * using the "newid" SQL statement.
638
				 *
639
				 * The SQL statement must be a string suitable for being used as
640
				 * prepared statement. It must include question marks for binding
641
				 * the values from the order item to the statement before they are
642
				 * sent to the database server. The number of question marks must
643
				 * be the same as the number of columns listed in the INSERT
644
				 * statement. The order of the columns must correspond to the
645
				 * order in the save() method, so the correct values are
646
				 * bound to the columns.
647
				 *
648
				 * The SQL statement should conform to the ANSI standard to be
649
				 * compatible with most relational database systems. This also
650
				 * includes using double quotes for table and column names.
651
				 *
652
				 * @param string SQL statement for inserting records
653
				 * @since 2014.03
654
				 * @category Developer
655
				 * @see mshop/order/manager/base/address/update/ansi
656
				 * @see mshop/order/manager/base/address/newid/ansi
657
				 * @see mshop/order/manager/base/address/delete/ansi
658
				 * @see mshop/order/manager/base/address/search/ansi
659
				 * @see mshop/order/manager/base/address/count/ansi
660
				 */
661
				$path = 'mshop/order/manager/base/address/insert';
662
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getSqlConfig($path) can also be of type array; however, parameter $sql of Aimeos\MShop\Common\Manager\Base::addSqlColumns() does only seem to accept string, 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

662
				$sql = $this->addSqlColumns( array_keys( $columns ), /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ) );
Loading history...
663
			}
664
			else
665
			{
666
				/** mshop/order/manager/base/address/update/mysql
667
				 * Updates an existing order record in the database
668
				 *
669
				 * @see mshop/order/manager/base/address/update/ansi
670
				 */
671
672
				/** mshop/order/manager/base/address/update/ansi
673
				 * Updates an existing order record in the database
674
				 *
675
				 * Items which already have an ID (i.e. the ID is not NULL) will
676
				 * be updated in the database.
677
				 *
678
				 * The SQL statement must be a string suitable for being used as
679
				 * prepared statement. It must include question marks for binding
680
				 * the values from the order item to the statement before they are
681
				 * sent to the database server. The order of the columns must
682
				 * correspond to the order in the save() method, so the
683
				 * correct values are bound to the columns.
684
				 *
685
				 * The SQL statement should conform to the ANSI standard to be
686
				 * compatible with most relational database systems. This also
687
				 * includes using double quotes for table and column names.
688
				 *
689
				 * @param string SQL statement for updating records
690
				 * @since 2014.03
691
				 * @category Developer
692
				 * @see mshop/order/manager/base/address/insert/ansi
693
				 * @see mshop/order/manager/base/address/newid/ansi
694
				 * @see mshop/order/manager/base/address/delete/ansi
695
				 * @see mshop/order/manager/base/address/search/ansi
696
				 * @see mshop/order/manager/base/address/count/ansi
697
				 */
698
				$path = 'mshop/order/manager/base/address/update';
699
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );
700
			}
701
702
			$idx = 1;
703
			$stmt = $this->getCachedStatement( $conn, $path, $sql );
704
705
			foreach( $columns as $name => $entry ) {
706
				$stmt->bind( $idx++, $item->get( $name ), $entry->getInternalType() );
707
			}
708
709
			$stmt->bind( $idx++, $item->getBaseId(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
710
			$stmt->bind( $idx++, $item->getAddressId() );
711
			$stmt->bind( $idx++, $item->getType() );
712
			$stmt->bind( $idx++, $item->getCompany() );
713
			$stmt->bind( $idx++, $item->getVatID() );
714
			$stmt->bind( $idx++, $item->getSalutation() );
715
			$stmt->bind( $idx++, $item->getTitle() );
716
			$stmt->bind( $idx++, $item->getFirstname() );
717
			$stmt->bind( $idx++, $item->getLastname() );
718
			$stmt->bind( $idx++, $item->getAddress1() );
719
			$stmt->bind( $idx++, $item->getAddress2() );
720
			$stmt->bind( $idx++, $item->getAddress3() );
721
			$stmt->bind( $idx++, $item->getPostal() );
722
			$stmt->bind( $idx++, $item->getCity() );
723
			$stmt->bind( $idx++, $item->getState() );
724
			$stmt->bind( $idx++, $item->getCountryId() );
725
			$stmt->bind( $idx++, $item->getLanguageId() );
726
			$stmt->bind( $idx++, $item->getTelephone() );
727
			$stmt->bind( $idx++, $item->getEmail() );
728
			$stmt->bind( $idx++, $item->getTelefax() );
729
			$stmt->bind( $idx++, $item->getWebsite() );
730
			$stmt->bind( $idx++, $item->getLongitude() );
731
			$stmt->bind( $idx++, $item->getLatitude() );
732
			$stmt->bind( $idx++, (int) $item->getPosition(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
733
			$stmt->bind( $idx++, $item->getBirthday() );
734
			$stmt->bind( $idx++, $date );
735
			$stmt->bind( $idx++, $context->editor() );
736
			$stmt->bind( $idx++, $context->locale()->getSiteId() );
737
738
			if( $id !== null ) {
739
				$stmt->bind( $idx++, $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
740
			} else {
741
				$stmt->bind( $idx++, $date ); // ctime
742
			}
743
744
			$stmt->execute()->finish();
745
746
			if( $id === null && $fetch === true )
747
			{
748
				/** mshop/order/manager/base/address/newid/mysql
749
				 * Retrieves the ID generated by the database when inserting a new record
750
				 *
751
				 * @see mshop/order/manager/base/address/newid/ansi
752
				 */
753
754
				/** mshop/order/manager/base/address/newid/ansi
755
				 * Retrieves the ID generated by the database when inserting a new record
756
				 *
757
				 * As soon as a new record is inserted into the database table,
758
				 * the database server generates a new and unique identifier for
759
				 * that record. This ID can be used for retrieving, updating and
760
				 * deleting that specific record from the table again.
761
				 *
762
				 * For MySQL:
763
				 *  SELECT LAST_INSERT_ID()
764
				 * For PostgreSQL:
765
				 *  SELECT currval('seq_mord_id')
766
				 * For SQL Server:
767
				 *  SELECT SCOPE_IDENTITY()
768
				 * For Oracle:
769
				 *  SELECT "seq_mord_id".CURRVAL FROM DUAL
770
				 *
771
				 * There's no way to retrive the new ID by a SQL statements that
772
				 * fits for most database servers as they implement their own
773
				 * specific way.
774
				 *
775
				 * @param string SQL statement for retrieving the last inserted record ID
776
				 * @since 2014.03
777
				 * @category Developer
778
				 * @see mshop/order/manager/base/address/insert/ansi
779
				 * @see mshop/order/manager/base/address/update/ansi
780
				 * @see mshop/order/manager/base/address/delete/ansi
781
				 * @see mshop/order/manager/base/address/search/ansi
782
				 * @see mshop/order/manager/base/address/count/ansi
783
				 */
784
				$path = 'mshop/order/manager/base/address/newid';
785
				$id = $this->newId( $conn, $path );
786
			}
787
788
			$item->setId( $id );
789
790
		return $item;
791
	}
792
793
794
	/**
795
	 * Search for order base address items based on the given critera.
796
	 *
797
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria object
798
	 * @param string[] $ref List of domains to fetch list items and referenced items for
799
	 * @param int|null &$total Number of items that are available in total
800
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Order\Item\Base\Address\Iface with ids as keys
801
	 */
802
	public function search( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map
803
	{
804
		$context = $this->context();
805
		$conn = $context->db( $this->getResourceName() );
806
		$items = [];
807
808
			$required = array( 'order.base.address' );
809
810
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
811
			$level = $context->config()->get( 'mshop/order/manager/sitemode', $level );
812
813
			/** mshop/order/manager/base/address/search/mysql
814
			 * Retrieves the records matched by the given criteria in the database
815
			 *
816
			 * @see mshop/order/manager/base/address/search/ansi
817
			 */
818
819
			/** mshop/order/manager/base/address/search/ansi
820
			 * Retrieves the records matched by the given criteria in the database
821
			 *
822
			 * Fetches the records matched by the given criteria from the order
823
			 * database. The records must be from one of the sites that are
824
			 * configured via the context item. If the current site is part of
825
			 * a tree of sites, the SELECT statement can retrieve all records
826
			 * from the current site and the complete sub-tree of sites.
827
			 *
828
			 * As the records can normally be limited by criteria from sub-managers,
829
			 * their tables must be joined in the SQL context. This is done by
830
			 * using the "internaldeps" property from the definition of the ID
831
			 * column of the sub-managers. These internal dependencies specify
832
			 * the JOIN between the tables and the used columns for joining. The
833
			 * ":joins" placeholder is then replaced by the JOIN strings from
834
			 * the sub-managers.
835
			 *
836
			 * To limit the records matched, conditions can be added to the given
837
			 * criteria object. It can contain comparisons like column names that
838
			 * must match specific values which can be combined by AND, OR or NOT
839
			 * operators. The resulting string of SQL conditions replaces the
840
			 * ":cond" placeholder before the statement is sent to the database
841
			 * server.
842
			 *
843
			 * If the records that are retrieved should be ordered by one or more
844
			 * columns, the generated string of column / sort direction pairs
845
			 * replaces the ":order" placeholder. In case no ordering is required,
846
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
847
			 * markers is removed to speed up retrieving the records. Columns of
848
			 * sub-managers can also be used for ordering the result set but then
849
			 * no index can be used.
850
			 *
851
			 * The number of returned records can be limited and can start at any
852
			 * number between the begining and the end of the result set. For that
853
			 * the ":size" and ":start" placeholders are replaced by the
854
			 * corresponding values from the criteria object. The default values
855
			 * are 0 for the start and 100 for the size value.
856
			 *
857
			 * The SQL statement should conform to the ANSI standard to be
858
			 * compatible with most relational database systems. This also
859
			 * includes using double quotes for table and column names.
860
			 *
861
			 * @param string SQL statement for searching items
862
			 * @since 2014.03
863
			 * @category Developer
864
			 * @see mshop/order/manager/base/address/insert/ansi
865
			 * @see mshop/order/manager/base/address/update/ansi
866
			 * @see mshop/order/manager/base/address/newid/ansi
867
			 * @see mshop/order/manager/base/address/delete/ansi
868
			 * @see mshop/order/manager/base/address/count/ansi
869
			 */
870
			$cfgPathSearch = 'mshop/order/manager/base/address/search';
871
872
			/** mshop/order/manager/base/address/count/mysql
873
			 * Counts the number of records matched by the given criteria in the database
874
			 *
875
			 * @see mshop/order/manager/base/address/count/ansi
876
			 */
877
878
			/** mshop/order/manager/base/address/count/ansi
879
			 * Counts the number of records matched by the given criteria in the database
880
			 *
881
			 * Counts all records matched by the given criteria from the order
882
			 * database. The records must be from one of the sites that are
883
			 * configured via the context item. If the current site is part of
884
			 * a tree of sites, the statement can count all records from the
885
			 * current site and the complete sub-tree of sites.
886
			 *
887
			 * As the records can normally be limited by criteria from sub-managers,
888
			 * their tables must be joined in the SQL context. This is done by
889
			 * using the "internaldeps" property from the definition of the ID
890
			 * column of the sub-managers. These internal dependencies specify
891
			 * the JOIN between the tables and the used columns for joining. The
892
			 * ":joins" placeholder is then replaced by the JOIN strings from
893
			 * the sub-managers.
894
			 *
895
			 * To limit the records matched, conditions can be added to the given
896
			 * criteria object. It can contain comparisons like column names that
897
			 * must match specific values which can be combined by AND, OR or NOT
898
			 * operators. The resulting string of SQL conditions replaces the
899
			 * ":cond" placeholder before the statement is sent to the database
900
			 * server.
901
			 *
902
			 * Both, the strings for ":joins" and for ":cond" are the same as for
903
			 * the "search" SQL statement.
904
			 *
905
			 * Contrary to the "search" statement, it doesn't return any records
906
			 * but instead the number of records that have been found. As counting
907
			 * thousands of records can be a long running task, the maximum number
908
			 * of counted records is limited for performance reasons.
909
			 *
910
			 * The SQL statement should conform to the ANSI standard to be
911
			 * compatible with most relational database systems. This also
912
			 * includes using double quotes for table and column names.
913
			 *
914
			 * @param string SQL statement for counting items
915
			 * @since 2014.03
916
			 * @category Developer
917
			 * @see mshop/order/manager/base/address/insert/ansi
918
			 * @see mshop/order/manager/base/address/update/ansi
919
			 * @see mshop/order/manager/base/address/newid/ansi
920
			 * @see mshop/order/manager/base/address/delete/ansi
921
			 * @see mshop/order/manager/base/address/search/ansi
922
			 */
923
			$cfgPathCount = 'mshop/order/manager/base/address/count';
924
925
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount,
926
				$required, $total, $level );
927
928
			try
929
			{
930
				while( ( $row = $results->fetch() ) !== null )
931
				{
932
					if( $item = $this->applyFilter( $this->createItemBase( $row ) ) ) {
933
						$items[$row['order.base.address.id']] = $item;
934
					}
935
				}
936
			}
937
			catch( \Exception $e )
938
			{
939
				$results->finish();
940
				throw $e;
941
			}
942
943
		return map( $items );
944
	}
945
946
947
	/**
948
	 * Creates new order base address item object.
949
	 *
950
	 * @param array $values Possible optional array keys can be given: id, type, firstname, lastname
951
	 * @return \Aimeos\MShop\Order\Item\Base\Address\Iface New order base address item object
952
	 */
953
	protected function createItemBase( array $values = [] ) : \Aimeos\MShop\Order\Item\Base\Address\Iface
954
	{
955
		return new \Aimeos\MShop\Order\Item\Base\Address\Standard( $values );
956
	}
957
}
958