Passed
Push — master ( 29d5f6...586595 )
by Aimeos
04:48
created

mshoplib/src/MShop/Customer/Manager/Standard.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package MShop
8
 * @subpackage Customer
9
 */
10
11
12
namespace Aimeos\MShop\Customer\Manager;
13
14
15
/**
16
 * Default implementation of the customer class.
17
 *
18
 * @package MShop
19
 * @subpackage Customer
20
 */
21
class Standard
22
	extends \Aimeos\MShop\Customer\Manager\Base
23
	implements \Aimeos\MShop\Customer\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	use \Aimeos\MShop\Common\Manager\AddressRef\Traits;
26
	use \Aimeos\MShop\Common\Manager\PropertyRef\Traits;
27
28
29
	private $searchConfig = array(
30
		// no siteid
31
		'customer.id' => array(
32
			'label' => 'ID',
33
			'code' => 'customer.id',
34
			'internalcode' => 'mcus."id"',
35
			'type' => 'integer',
36
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
37
			'public' => false,
38
		),
39
		'customer.code' => array(
40
			'label' => 'Username',
41
			'code' => 'customer.code',
42
			'internalcode' => 'mcus."code"',
43
			'type' => 'string',
44
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
45
		),
46
		'customer.label' => array(
47
			'label' => 'Label',
48
			'code' => 'customer.label',
49
			'internalcode' => 'mcus."label"',
50
			'type' => 'string',
51
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
52
		),
53
		'customer.salutation' => array(
54
			'label' => 'Salutation',
55
			'code' => 'customer.salutation',
56
			'internalcode' => 'mcus."salutation"',
57
			'type' => 'string',
58
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
59
		),
60
		'customer.company' => array(
61
			'label' => 'Company',
62
			'code' => 'customer.company',
63
			'internalcode' => 'mcus."company"',
64
			'type' => 'string',
65
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
66
		),
67
		'customer.vatid' => array(
68
			'label' => 'Vat ID',
69
			'code' => 'customer.vatid',
70
			'internalcode' => 'mcus."vatid"',
71
			'type' => 'string',
72
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
73
		),
74
		'customer.title' => array(
75
			'label' => 'Title',
76
			'code' => 'customer.title',
77
			'internalcode' => 'mcus."title"',
78
			'type' => 'string',
79
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
80
		),
81
		'customer.firstname' => array(
82
			'label' => 'Firstname',
83
			'code' => 'customer.firstname',
84
			'internalcode' => 'mcus."firstname"',
85
			'type' => 'string',
86
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
87
		),
88
		'customer.lastname' => array(
89
			'label' => 'Lastname',
90
			'code' => 'customer.lastname',
91
			'internalcode' => 'mcus."lastname"',
92
			'type' => 'string',
93
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
94
		),
95
		'customer.address1' => array(
96
			'label' => 'Address part one',
97
			'code' => 'customer.address1',
98
			'internalcode' => 'mcus."address1"',
99
			'type' => 'string',
100
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
101
		),
102
		'customer.address2' => array(
103
			'label' => 'Address part two',
104
			'code' => 'customer.address2',
105
			'internalcode' => 'mcus."address2"',
106
			'type' => 'string',
107
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
108
		),
109
		'customer.address3' => array(
110
			'label' => 'Address part three',
111
			'code' => 'customer.address3',
112
			'internalcode' => 'mcus."address3"',
113
			'type' => 'string',
114
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
115
		),
116
		'customer.postal' => array(
117
			'label' => 'Postal',
118
			'code' => 'customer.postal',
119
			'internalcode' => 'mcus."postal"',
120
			'type' => 'string',
121
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
122
		),
123
		'customer.city' => array(
124
			'label' => 'City',
125
			'code' => 'customer.city',
126
			'internalcode' => 'mcus."city"',
127
			'type' => 'string',
128
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
129
		),
130
		'customer.state' => array(
131
			'label' => 'State',
132
			'code' => 'customer.state',
133
			'internalcode' => 'mcus."state"',
134
			'type' => 'string',
135
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
136
		),
137
		'customer.languageid' => array(
138
			'label' => 'Language',
139
			'code' => 'customer.languageid',
140
			'internalcode' => 'mcus."langid"',
141
			'type' => 'string',
142
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
143
		),
144
		'customer.countryid' => array(
145
			'label' => 'Country',
146
			'code' => 'customer.countryid',
147
			'internalcode' => 'mcus."countryid"',
148
			'type' => 'string',
149
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
150
		),
151
		'customer.telephone' => array(
152
			'label' => 'Telephone',
153
			'code' => 'customer.telephone',
154
			'internalcode' => 'mcus."telephone"',
155
			'type' => 'string',
156
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
157
		),
158
		'customer.email' => array(
159
			'label' => 'E-mail',
160
			'code' => 'customer.email',
161
			'internalcode' => 'mcus."email"',
162
			'type' => 'string',
163
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
164
		),
165
		'customer.telefax' => array(
166
			'label' => 'Facsimile',
167
			'code' => 'customer.telefax',
168
			'internalcode' => 'mcus."telefax"',
169
			'type' => 'string',
170
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
171
		),
172
		'customer.website' => array(
173
			'label' => 'Web site',
174
			'code' => 'customer.website',
175
			'internalcode' => 'mcus."website"',
176
			'type' => 'string',
177
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
178
		),
179
		'customer.longitude' => array(
180
			'label' => 'Longitude',
181
			'code' => 'customer.longitude',
182
			'internalcode' => 'mcus."longitude"',
183
			'type' => 'string',
184
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
185
			'public' => false,
186
		),
187
		'customer.latitude' => array(
188
			'label' => 'Latitude',
189
			'code' => 'customer.latitude',
190
			'internalcode' => 'mcus."latitude"',
191
			'type' => 'string',
192
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
193
			'public' => false,
194
		),
195
		'customer.birthday' => array(
196
			'label' => 'Birthday',
197
			'code' => 'customer.birthday',
198
			'internalcode' => 'mcus."birthday"',
199
			'type' => 'string',
200
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
201
		),
202
		'customer.status' => array(
203
			'label' => 'Status',
204
			'code' => 'customer.status',
205
			'internalcode' => 'mcus."status"',
206
			'type' => 'integer',
207
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
208
		),
209
		'customer.dateverified' => array(
210
			'label' => 'Verification date',
211
			'code' => 'customer.dateverified',
212
			'internalcode' => 'mcus."vdate"',
213
			'type' => 'date',
214
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
215
			'public' => false,
216
		),
217
		'customer.password' => array(
218
			'label' => 'Password',
219
			'code' => 'customer.password',
220
			'internalcode' => 'mcus."password"',
221
			'type' => 'string',
222
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
223
			'public' => false,
224
		),
225
		'customer.ctime' => array(
226
			'label' => 'Create date/time',
227
			'code' => 'customer.ctime',
228
			'internalcode' => 'mcus."ctime"',
229
			'type' => 'datetime',
230
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
231
			'public' => false,
232
		),
233
		'customer.mtime' => array(
234
			'label' => 'Modify date/time',
235
			'code' => 'customer.mtime',
236
			'internalcode' => 'mcus."mtime"',
237
			'type' => 'datetime',
238
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
239
			'public' => false,
240
		),
241
		'customer.editor' => array(
242
			'label' => 'Editor',
243
			'code' => 'customer.editor',
244
			'internalcode' => 'mcus."editor"',
245
			'type' => 'string',
246
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
247
			'public' => false,
248
		),
249
	);
250
251
252
	/**
253
	 * Removes old entries from the storage.
254
	 *
255
	 * @param integer[] $siteids List of IDs for sites whose entries should be deleted
256
	 */
257
	public function cleanup( array $siteids )
258
	{
259
		$path = 'mshop/customer/manager/submanagers';
260
		$default = ['address', 'group', 'lists', 'property'];
261
262
		foreach( $this->getContext()->getConfig()->get( $path, $default ) as $domain ) {
263
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
264
		}
265
266
		$this->cleanupBase( $siteids, 'mshop/customer/manager/standard/delete' );
267
	}
268
269
270
	/**
271
	 * Creates a new empty item instance
272
	 *
273
	 * @param string|null Type the item should be created with
274
	 * @param string|null Domain of the type the item should be created with
275
	 * @param array $values Values the item should be initialized with
276
	 * @return \Aimeos\MShop\Customer\Item\Iface New customer item object
277
	 */
278
	public function createItem( $type = null, $domain = null, array $values = [] )
279
	{
280
		$values['customer.siteid'] = $this->getContext()->getLocale()->getSiteId();
281
		return $this->createItemBase( $values );
282
	}
283
284
285
	/**
286
	 * Returns the available manager types
287
	 *
288
	 * @param boolean $withsub Return also the resource type of sub-managers if true
289
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
290
	 */
291
	public function getResourceType( $withsub = true )
292
	{
293
		$path = 'mshop/customer/manager/submanagers';
294
		$default = ['address', 'group', 'lists', 'property'];
295
296
		return $this->getResourceTypeBase( 'customer', $path, $default, $withsub );
297
	}
298
299
300
	/**
301
	 * Returns the attributes that can be used for searching.
302
	 *
303
	 * @param boolean $withsub Return also attributes of sub-managers if true
304
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
305
	 */
306
	public function getSearchAttributes( $withsub = true )
307
	{
308
		/** mshop/customer/manager/submanagers
309
		 * List of manager names that can be instantiated by the customer manager
310
		 *
311
		 * Managers provide a generic interface to the underlying storage.
312
		 * Each manager has or can have sub-managers caring about particular
313
		 * aspects. Each of these sub-managers can be instantiated by its
314
		 * parent manager using the getSubManager() method.
315
		 *
316
		 * The search keys from sub-managers can be normally used in the
317
		 * manager as well. It allows you to search for items of the manager
318
		 * using the search keys of the sub-managers to further limit the
319
		 * retrieved list of items.
320
		 *
321
		 * @param array List of sub-manager names
322
		 * @since 2014.03
323
		 * @category Developer
324
		 */
325
		$path = 'mshop/customer/manager/submanagers';
326
		$default = ['address', 'group', 'lists', 'property'];
327
328
		return $this->getSearchAttributesBase( $this->searchConfig, $path, $default, $withsub );
329
	}
330
331
332
	/**
333
	 * Removes multiple items specified by ids in the array.
334
	 *
335
	 * @param array $ids List of IDs
336
	 */
337
	public function deleteItems( array $ids )
338
	{
339
		/** mshop/customer/manager/standard/delete/mysql
340
		 * Deletes the items matched by the given IDs from the database
341
		 *
342
		 * @see mshop/customer/manager/standard/delete/ansi
343
		 */
344
345
		/** mshop/customer/manager/standard/delete/ansi
346
		 * Deletes the items matched by the given IDs from the database
347
		 *
348
		 * Removes the records specified by the given IDs from the customer database.
349
		 * The records must be from the site that is configured via the
350
		 * context item.
351
		 *
352
		 * The ":cond" placeholder is replaced by the name of the ID column and
353
		 * the given ID or list of IDs while the site ID is bound to the question
354
		 * mark.
355
		 *
356
		 * The SQL statement should conform to the ANSI standard to be
357
		 * compatible with most relational database systems. This also
358
		 * includes using double quotes for table and column names.
359
		 *
360
		 * @param string SQL statement for deleting items
361
		 * @since 2014.03
362
		 * @category Developer
363
		 * @see mshop/customer/manager/standard/insert/ansi
364
		 * @see mshop/customer/manager/standard/update/ansi
365
		 * @see mshop/customer/manager/standard/newid/ansi
366
		 * @see mshop/customer/manager/standard/search/ansi
367
		 * @see mshop/customer/manager/standard/count/ansi
368
		 */
369
		$path = 'mshop/customer/manager/standard/delete';
370
		$this->deleteItemsBase( $ids, $path );
371
	}
372
373
374
	/**
375
	 * Saves a customer item object.
376
	 *
377
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item object
378
	 * @param boolean $fetch True if the new ID should be returned in the item
379
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
380
	 */
381
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
382
	{
383
		self::checkClass( '\\Aimeos\\MShop\\Customer\\Item\\Iface', $item );
384
385
		if( !$item->isModified() )
386
		{
387
			$item = $this->savePropertyItems( $item, 'customer', $fetch );
388
			$item = $this->saveAddressItems( $item, 'customer', $fetch );
389
			return $this->saveListItems( $item, 'customer', $fetch );
390
		}
391
392
		$context = $this->getContext();
393
394
		$dbm = $context->getDatabaseManager();
395
		$dbname = $this->getResourceName();
396
		$conn = $dbm->acquire( $dbname );
397
398
		try
399
		{
400
			$id = $item->getId();
401
			$date = date( 'Y-m-d H:i:s' );
402
			$billingAddress = $item->getPaymentAddress();
403
404
			if( $id === null )
405
			{
406
				/** mshop/customer/manager/standard/insert/mysql
407
				 * Inserts a new customer record into the database table
408
				 *
409
				 * @see mshop/customer/manager/standard/insert/ansi
410
				 */
411
412
				/** mshop/customer/manager/standard/insert/ansi
413
				 * Inserts a new customer record into the database table
414
				 *
415
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
416
				 * the database and the newly created ID retrieved afterwards
417
				 * using the "newid" SQL statement.
418
				 *
419
				 * The SQL statement must be a string suitable for being used as
420
				 * prepared statement. It must include question marks for binding
421
				 * the values from the customer item to the statement before they are
422
				 * sent to the database server. The number of question marks must
423
				 * be the same as the number of columns listed in the INSERT
424
				 * statement. The order of the columns must correspond to the
425
				 * order in the saveItems() method, so the correct values are
426
				 * bound to the columns.
427
				 *
428
				 * The SQL statement should conform to the ANSI standard to be
429
				 * compatible with most relational database systems. This also
430
				 * includes using double quotes for table and column names.
431
				 *
432
				 * @param string SQL statement for inserting records
433
				 * @since 2014.03
434
				 * @category Developer
435
				 * @see mshop/customer/manager/standard/update/ansi
436
				 * @see mshop/customer/manager/standard/newid/ansi
437
				 * @see mshop/customer/manager/standard/delete/ansi
438
				 * @see mshop/customer/manager/standard/search/ansi
439
				 * @see mshop/customer/manager/standard/count/ansi
440
				 */
441
				$path = 'mshop/customer/manager/standard/insert';
442
			}
443
			else
444
			{
445
				/** mshop/customer/manager/standard/update/mysql
446
				 * Updates an existing customer record in the database
447
				 *
448
				 * @see mshop/customer/manager/standard/update/ansi
449
				 */
450
451
				/** mshop/customer/manager/standard/update/ansi
452
				 * Updates an existing customer record in the database
453
				 *
454
				 * Items which already have an ID (i.e. the ID is not NULL) will
455
				 * be updated in the database.
456
				 *
457
				 * The SQL statement must be a string suitable for being used as
458
				 * prepared statement. It must include question marks for binding
459
				 * the values from the customer item to the statement before they are
460
				 * sent to the database server. The order of the columns must
461
				 * correspond to the order in the saveItems() method, so the
462
				 * correct values are bound to the columns.
463
				 *
464
				 * The SQL statement should conform to the ANSI standard to be
465
				 * compatible with most relational database systems. This also
466
				 * includes using double quotes for table and column names.
467
				 *
468
				 * @param string SQL statement for updating records
469
				 * @since 2014.03
470
				 * @category Developer
471
				 * @see mshop/customer/manager/standard/insert/ansi
472
				 * @see mshop/customer/manager/standard/newid/ansi
473
				 * @see mshop/customer/manager/standard/delete/ansi
474
				 * @see mshop/customer/manager/standard/search/ansi
475
				 * @see mshop/customer/manager/standard/count/ansi
476
				 */
477
				$path = 'mshop/customer/manager/standard/update';
478
			}
479
480
			$stmt = $this->getCachedStatement( $conn, $path );
481
482
			$stmt->bind( 1, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
483
			$stmt->bind( 2, $item->getLabel() );
1 ignored issue
show
The method getLabel() does not exist on Aimeos\MShop\Common\Item\Iface. It seems like you code against a sub-type of Aimeos\MShop\Common\Item\Iface such as Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Locale\Item\Site\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Customer\Item\Group\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Tag\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Catalog\Item\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Attribute\Item\Standard or Aimeos\MShop\Catalog\Item\Standard or Aimeos\MShop\Customer\Item\Base or Aimeos\MShop\Plugin\Item\Standard or Aimeos\MShop\Tag\Item\Standard or Aimeos\MShop\Customer\Item\Group\Standard or Aimeos\MShop\Media\Item\Standard or Aimeos\MAdmin\Job\Item\Standard or Aimeos\MShop\Common\Item\Type\Standard or Aimeos\MShop\Locale\Item\Site\Standard or Aimeos\MShop\Locale\Item\Currency\Standard or Aimeos\MShop\Text\Item\Standard or Aimeos\MShop\Locale\Item\Language\Standard or Aimeos\MShop\Service\Item\Standard or Aimeos\MShop\Common\Item\ListRef\Base or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Supplier\Item\Standard or Aimeos\MShop\Coupon\Item\Standard or Aimeos\MShop\Product\Item\Standard or Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Common\Item\Tree\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Price\Item\Base. ( Ignorable by Annotation )

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

483
			$stmt->bind( 2, $item->/** @scrutinizer ignore-call */ getLabel() );
Loading history...
484
			$stmt->bind( 3, $item->getCode() );
485
			$stmt->bind( 4, $billingAddress->getCompany() );
486
			$stmt->bind( 5, $billingAddress->getVatID() );
487
			$stmt->bind( 6, $billingAddress->getSalutation() );
488
			$stmt->bind( 7, $billingAddress->getTitle() );
489
			$stmt->bind( 8, $billingAddress->getFirstname() );
490
			$stmt->bind( 9, $billingAddress->getLastname() );
491
			$stmt->bind( 10, $billingAddress->getAddress1() );
492
			$stmt->bind( 11, $billingAddress->getAddress2() );
493
			$stmt->bind( 12, $billingAddress->getAddress3() );
494
			$stmt->bind( 13, $billingAddress->getPostal() );
495
			$stmt->bind( 14, $billingAddress->getCity() );
496
			$stmt->bind( 15, $billingAddress->getState() );
497
			$stmt->bind( 16, $billingAddress->getCountryId() );
498
			$stmt->bind( 17, $billingAddress->getLanguageId() );
499
			$stmt->bind( 18, $billingAddress->getTelephone() );
500
			$stmt->bind( 19, $billingAddress->getEmail() );
501
			$stmt->bind( 20, $billingAddress->getTelefax() );
502
			$stmt->bind( 21, $billingAddress->getWebsite() );
503
			$stmt->bind( 22, $billingAddress->getLongitude() );
504
			$stmt->bind( 23, $billingAddress->getLatitude() );
505
			$stmt->bind( 24, $item->getBirthday() );
506
			$stmt->bind( 25, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
507
			$stmt->bind( 26, $item->getDateVerified() );
508
			$stmt->bind( 27, $item->getPassword() );
509
			$stmt->bind( 28, $date ); // Modification time
510
			$stmt->bind( 29, $context->getEditor() );
511
512
			if( $id !== null ) {
513
				$stmt->bind( 30, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
514
				$billingAddress->setId( $id ); // enforce ID to be present
515
				$item->setId( $id );
516
			} else {
517
				$stmt->bind( 30, $date ); // Creation time
518
			}
519
520
			$stmt->execute()->finish();
521
522
			if( $id === null )
523
			{
524
				/** mshop/customer/manager/standard/newid/mysql
525
				 * Retrieves the ID generated by the database when inserting a new record
526
				 *
527
				 * @see mshop/customer/manager/standard/newid/ansi
528
				 */
529
530
				/** mshop/customer/manager/standard/newid/ansi
531
				 * Retrieves the ID generated by the database when inserting a new record
532
				 *
533
				 * As soon as a new record is inserted into the database table,
534
				 * the database server generates a new and unique identifier for
535
				 * that record. This ID can be used for retrieving, updating and
536
				 * deleting that specific record from the table again.
537
				 *
538
				 * For MySQL:
539
				 *  SELECT LAST_INSERT_ID()
540
				 * For PostgreSQL:
541
				 *  SELECT currval('seq_mcus_id')
542
				 * For SQL Server:
543
				 *  SELECT SCOPE_IDENTITY()
544
				 * For Oracle:
545
				 *  SELECT "seq_mcus_id".CURRVAL FROM DUAL
546
				 *
547
				 * There's no way to retrive the new ID by a SQL statements that
548
				 * fits for most database servers as they implement their own
549
				 * specific way.
550
				 *
551
				 * @param string SQL statement for retrieving the last inserted record ID
552
				 * @since 2014.03
553
				 * @category Developer
554
				 * @see mshop/customer/manager/standard/insert/ansi
555
				 * @see mshop/customer/manager/standard/update/ansi
556
				 * @see mshop/customer/manager/standard/delete/ansi
557
				 * @see mshop/customer/manager/standard/search/ansi
558
				 * @see mshop/customer/manager/standard/count/ansi
559
				 */
560
				$path = 'mshop/customer/manager/standard/newid';
561
				$item->setId( $this->newId( $conn, $path ) );
562
			}
563
564
			$dbm->release( $conn, $dbname );
565
		}
566
		catch( \Exception $e )
567
		{
568
			$dbm->release( $conn, $dbname );
569
			throw $e;
570
		}
571
572
		$this->addGroups( $item );
573
574
		$item = $this->savePropertyItems( $item, 'customer', $fetch );
575
		$item = $this->saveAddressItems( $item, 'customer', $fetch );
576
		return $this->saveListItems( $item, 'customer', $fetch );
577
	}
578
579
580
	/**
581
	 * Returns the item objects matched by the given search criteria.
582
	 *
583
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
584
	 * @param string[] $ref List of domains to fetch list items and referenced items for
585
	 * @param integer|null &$total Number of items that are available in total
586
	 * @return array Associative list of IDs as keys and items implementing \Aimeos\MShop\Customer\Item\Iface as values
587
	 */
588
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
589
	{
590
		$map = [];
591
		$context = $this->getContext();
592
593
		$dbm = $context->getDatabaseManager();
594
		$dbname = $this->getResourceName();
595
		$conn = $dbm->acquire( $dbname );
596
597
		try
598
		{
599
			$required = array( 'customer' );
600
601
			/** mshop/customer/manager/sitemode
602
			 * Mode how items from levels below or above in the site tree are handled
603
			 *
604
			 * By default, only items from the current site are fetched from the
605
			 * storage. If the ai-sites extension is installed, you can create a
606
			 * tree of sites. Then, this setting allows you to define for the
607
			 * whole customer domain if items from parent sites are inherited,
608
			 * sites from child sites are aggregated or both.
609
			 *
610
			 * Available constants for the site mode are:
611
			 * * 0 = only items from the current site
612
			 * * 1 = inherit items from parent sites
613
			 * * 2 = aggregate items from child sites
614
			 * * 3 = inherit and aggregate items at the same time
615
			 *
616
			 * You also need to set the mode in the locale manager
617
			 * (mshop/locale/manager/standard/sitelevel) to one of the constants.
618
			 * If you set it to the same value, it will work as described but you
619
			 * can also use different modes. For example, if inheritance and
620
			 * aggregation is configured the locale manager but only inheritance
621
			 * in the domain manager because aggregating items makes no sense in
622
			 * this domain, then items wil be only inherited. Thus, you have full
623
			 * control over inheritance and aggregation in each domain.
624
			 *
625
			 * @param integer Constant from Aimeos\MShop\Locale\Manager\Base class
626
			 * @category Developer
627
			 * @since 2018.01
628
			 * @see mshop/locale/manager/standard/sitelevel
629
			 */
630
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
631
			$level = $context->getConfig()->get( 'mshop/customer/manager/sitemode', $level );
632
633
			/** mshop/customer/manager/standard/search/mysql
634
			 * Retrieves the records matched by the given criteria in the database
635
			 *
636
			 * @see mshop/customer/manager/standard/search/ansi
637
			 */
638
639
			/** mshop/customer/manager/standard/search/ansi
640
			 * Retrieves the records matched by the given criteria in the database
641
			 *
642
			 * Fetches the records matched by the given criteria from the customer
643
			 * database. The records must be from one of the sites that are
644
			 * configured via the context item. If the current site is part of
645
			 * a tree of sites, the SELECT statement can retrieve all records
646
			 * from the current site and the complete sub-tree of sites.
647
			 *
648
			 * As the records can normally be limited by criteria from sub-managers,
649
			 * their tables must be joined in the SQL context. This is done by
650
			 * using the "internaldeps" property from the definition of the ID
651
			 * column of the sub-managers. These internal dependencies specify
652
			 * the JOIN between the tables and the used columns for joining. The
653
			 * ":joins" placeholder is then replaced by the JOIN strings from
654
			 * the sub-managers.
655
			 *
656
			 * To limit the records matched, conditions can be added to the given
657
			 * criteria object. It can contain comparisons like column names that
658
			 * must match specific values which can be combined by AND, OR or NOT
659
			 * operators. The resulting string of SQL conditions replaces the
660
			 * ":cond" placeholder before the statement is sent to the database
661
			 * server.
662
			 *
663
			 * If the records that are retrieved should be ordered by one or more
664
			 * columns, the generated string of column / sort direction pairs
665
			 * replaces the ":order" placeholder. In case no ordering is required,
666
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
667
			 * markers is removed to speed up retrieving the records. Columns of
668
			 * sub-managers can also be used for ordering the result set but then
669
			 * no index can be used.
670
			 *
671
			 * The number of returned records can be limited and can start at any
672
			 * number between the begining and the end of the result set. For that
673
			 * the ":size" and ":start" placeholders are replaced by the
674
			 * corresponding values from the criteria object. The default values
675
			 * are 0 for the start and 100 for the size value.
676
			 *
677
			 * The SQL statement should conform to the ANSI standard to be
678
			 * compatible with most relational database systems. This also
679
			 * includes using double quotes for table and column names.
680
			 *
681
			 * @param string SQL statement for searching items
682
			 * @since 2014.03
683
			 * @category Developer
684
			 * @see mshop/customer/manager/standard/insert/ansi
685
			 * @see mshop/customer/manager/standard/update/ansi
686
			 * @see mshop/customer/manager/standard/newid/ansi
687
			 * @see mshop/customer/manager/standard/delete/ansi
688
			 * @see mshop/customer/manager/standard/count/ansi
689
			 */
690
			$cfgPathSearch = 'mshop/customer/manager/standard/search';
691
692
			/** mshop/customer/manager/standard/count/mysql
693
			 * Counts the number of records matched by the given criteria in the database
694
			 *
695
			 * @see mshop/customer/manager/standard/count/ansi
696
			 */
697
698
			/** mshop/customer/manager/standard/count/ansi
699
			 * Counts the number of records matched by the given criteria in the database
700
			 *
701
			 * Counts all records matched by the given criteria from the customer
702
			 * database. The records must be from one of the sites that are
703
			 * configured via the context item. If the current site is part of
704
			 * a tree of sites, the statement can count all records from the
705
			 * current site and the complete sub-tree of sites.
706
			 *
707
			 * As the records can normally be limited by criteria from sub-managers,
708
			 * their tables must be joined in the SQL context. This is done by
709
			 * using the "internaldeps" property from the definition of the ID
710
			 * column of the sub-managers. These internal dependencies specify
711
			 * the JOIN between the tables and the used columns for joining. The
712
			 * ":joins" placeholder is then replaced by the JOIN strings from
713
			 * the sub-managers.
714
			 *
715
			 * To limit the records matched, conditions can be added to the given
716
			 * criteria object. It can contain comparisons like column names that
717
			 * must match specific values which can be combined by AND, OR or NOT
718
			 * operators. The resulting string of SQL conditions replaces the
719
			 * ":cond" placeholder before the statement is sent to the database
720
			 * server.
721
			 *
722
			 * Both, the strings for ":joins" and for ":cond" are the same as for
723
			 * the "search" SQL statement.
724
			 *
725
			 * Contrary to the "search" statement, it doesn't return any records
726
			 * but instead the number of records that have been found. As counting
727
			 * thousands of records can be a long running task, the maximum number
728
			 * of counted records is limited for performance reasons.
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 counting items
735
			 * @since 2014.03
736
			 * @category Developer
737
			 * @see mshop/customer/manager/standard/insert/ansi
738
			 * @see mshop/customer/manager/standard/update/ansi
739
			 * @see mshop/customer/manager/standard/newid/ansi
740
			 * @see mshop/customer/manager/standard/delete/ansi
741
			 * @see mshop/customer/manager/standard/search/ansi
742
			 */
743
			$cfgPathCount = 'mshop/customer/manager/standard/count';
744
745
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
746
			while( ( $row = $results->fetch() ) !== false ) {
747
				$map[$row['customer.id']] = $row;
748
			}
749
750
			$dbm->release( $conn, $dbname );
751
		}
752
		catch( \Exception $e )
753
		{
754
			$dbm->release( $conn, $dbname );
755
			throw $e;
756
		}
757
758
		$addrItems = [];
759
		if( in_array( 'customer/address', $ref, true ) ) {
760
			$addrItems = $this->getAddressItems( array_keys( $map ), 'customer' );
761
		}
762
763
		$propItems = [];
764
		if( in_array( 'customer/property', $ref, true ) ) {
765
			$propItems = $this->getPropertyItems( array_keys( $map ), 'customer' );
766
		}
767
768
		return $this->buildItems( $map, $ref, 'customer', $addrItems, $propItems );
769
	}
770
771
772
	/**
773
	 * Returns a new manager for customer extensions.
774
	 *
775
	 * @param string $manager Name of the sub manager type in lower case
776
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
777
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
778
	 */
779
	public function getSubManager( $manager, $name = null )
780
	{
781
		return $this->getSubManagerBase( 'customer', $manager, $name );
782
	}
783
}
784