Completed
Push — master ( 7f402b...a6068b )
by Aimeos
10:08
created

Standard::getPropertyItems()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 2
nop 1
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
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-2017
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
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
23
	implements \Aimeos\MShop\Customer\Manager\Iface
24
{
25
	use \Aimeos\MShop\Common\Manager\PropertyRef\Traits;
26
27
28
	private $searchConfig = array(
29
		// no siteid
30
		'customer.id' => array(
31
			'label' => 'ID',
32
			'code' => 'customer.id',
33
			'internalcode' => 'mcus."id"',
34
			'type' => 'integer',
35
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
36
			'public' => false,
37
		),
38
		'customer.code' => array(
39
			'label' => 'Username',
40
			'code' => 'customer.code',
41
			'internalcode' => 'mcus."code"',
42
			'type' => 'string',
43
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
44
		),
45
		'customer.label' => array(
46
			'label' => 'Label',
47
			'code' => 'customer.label',
48
			'internalcode' => 'mcus."label"',
49
			'type' => 'string',
50
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
51
		),
52
		'customer.salutation' => array(
53
			'label' => 'Salutation',
54
			'code' => 'customer.salutation',
55
			'internalcode' => 'mcus."salutation"',
56
			'type' => 'string',
57
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
58
		),
59
		'customer.company' => array(
60
			'label' => 'Company',
61
			'code' => 'customer.company',
62
			'internalcode' => 'mcus."company"',
63
			'type' => 'string',
64
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
65
		),
66
		'customer.vatid' => array(
67
			'label' => 'Vat ID',
68
			'code' => 'customer.vatid',
69
			'internalcode' => 'mcus."vatid"',
70
			'type' => 'string',
71
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
72
		),
73
		'customer.title' => array(
74
			'label' => 'Title',
75
			'code' => 'customer.title',
76
			'internalcode' => 'mcus."title"',
77
			'type' => 'string',
78
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
79
		),
80
		'customer.firstname' => array(
81
			'label' => 'Firstname',
82
			'code' => 'customer.firstname',
83
			'internalcode' => 'mcus."firstname"',
84
			'type' => 'string',
85
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
86
		),
87
		'customer.lastname' => array(
88
			'label' => 'Lastname',
89
			'code' => 'customer.lastname',
90
			'internalcode' => 'mcus."lastname"',
91
			'type' => 'string',
92
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
93
		),
94
		'customer.address1' => array(
95
			'label' => 'Address part one',
96
			'code' => 'customer.address1',
97
			'internalcode' => 'mcus."address1"',
98
			'type' => 'string',
99
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
100
		),
101
		'customer.address2' => array(
102
			'label' => 'Address part two',
103
			'code' => 'customer.address2',
104
			'internalcode' => 'mcus."address2"',
105
			'type' => 'string',
106
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
107
		),
108
		'customer.address3' => array(
109
			'label' => 'Address part three',
110
			'code' => 'customer.address3',
111
			'internalcode' => 'mcus."address3"',
112
			'type' => 'string',
113
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
114
		),
115
		'customer.postal' => array(
116
			'label' => 'Postal',
117
			'code' => 'customer.postal',
118
			'internalcode' => 'mcus."postal"',
119
			'type' => 'string',
120
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
121
		),
122
		'customer.city' => array(
123
			'label' => 'City',
124
			'code' => 'customer.city',
125
			'internalcode' => 'mcus."city"',
126
			'type' => 'string',
127
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
128
		),
129
		'customer.state' => array(
130
			'label' => 'State',
131
			'code' => 'customer.state',
132
			'internalcode' => 'mcus."state"',
133
			'type' => 'string',
134
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
135
		),
136
		'customer.languageid' => array(
137
			'label' => 'Language',
138
			'code' => 'customer.languageid',
139
			'internalcode' => 'mcus."langid"',
140
			'type' => 'string',
141
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
142
		),
143
		'customer.countryid' => array(
144
			'label' => 'Country',
145
			'code' => 'customer.countryid',
146
			'internalcode' => 'mcus."countryid"',
147
			'type' => 'string',
148
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
149
		),
150
		'customer.telephone' => array(
151
			'label' => 'Telephone',
152
			'code' => 'customer.telephone',
153
			'internalcode' => 'mcus."telephone"',
154
			'type' => 'string',
155
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
156
		),
157
		'customer.email' => array(
158
			'label' => 'E-mail',
159
			'code' => 'customer.email',
160
			'internalcode' => 'mcus."email"',
161
			'type' => 'string',
162
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
163
		),
164
		'customer.telefax' => array(
165
			'label' => 'Facsimile',
166
			'code' => 'customer.telefax',
167
			'internalcode' => 'mcus."telefax"',
168
			'type' => 'string',
169
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
170
		),
171
		'customer.website' => array(
172
			'label' => 'Web site',
173
			'code' => 'customer.website',
174
			'internalcode' => 'mcus."website"',
175
			'type' => 'string',
176
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
177
		),
178
		'customer.longitude' => array(
179
			'label' => 'Longitude',
180
			'code' => 'customer.longitude',
181
			'internalcode' => 'mcus."longitude"',
182
			'type' => 'string',
183
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
184
			'public' => false,
185
		),
186
		'customer.latitude' => array(
187
			'label' => 'Latitude',
188
			'code' => 'customer.latitude',
189
			'internalcode' => 'mcus."latitude"',
190
			'type' => 'string',
191
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
192
			'public' => false,
193
		),
194
		'customer.birthday' => array(
195
			'label' => 'Birthday',
196
			'code' => 'customer.birthday',
197
			'internalcode' => 'mcus."birthday"',
198
			'type' => 'string',
199
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
200
		),
201
		'customer.status' => array(
202
			'label' => 'Status',
203
			'code' => 'customer.status',
204
			'internalcode' => 'mcus."status"',
205
			'type' => 'integer',
206
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
207
		),
208
		'customer.dateverified' => array(
209
			'label' => 'Verification date',
210
			'code' => 'customer.dateverified',
211
			'internalcode' => 'mcus."vdate"',
212
			'type' => 'date',
213
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
214
			'public' => false,
215
		),
216
		'customer.password' => array(
217
			'label' => 'Password',
218
			'code' => 'customer.password',
219
			'internalcode' => 'mcus."password"',
220
			'type' => 'string',
221
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
222
			'public' => false,
223
		),
224
		'customer.ctime' => array(
225
			'label' => 'Create date/time',
226
			'code' => 'customer.ctime',
227
			'internalcode' => 'mcus."ctime"',
228
			'type' => 'datetime',
229
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
230
			'public' => false,
231
		),
232
		'customer.mtime' => array(
233
			'label' => 'Modify date/time',
234
			'code' => 'customer.mtime',
235
			'internalcode' => 'mcus."mtime"',
236
			'type' => 'datetime',
237
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
238
			'public' => false,
239
		),
240
		'customer.editor' => array(
241
			'label' => 'Editor',
242
			'code' => 'customer.editor',
243
			'internalcode' => 'mcus."editor"',
244
			'type' => 'string',
245
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
246
			'public' => false,
247
		),
248
	);
249
250
251
	/**
252
	 * Removes old entries from the storage.
253
	 *
254
	 * @param integer[] $siteids List of IDs for sites whose entries should be deleted
255
	 */
256
	public function cleanup( array $siteids )
257
	{
258
		$path = 'mshop/customer/manager/submanagers';
259
		foreach( $this->getContext()->getConfig()->get( $path, array( 'address', 'lists', 'group' ) ) as $domain ) {
260
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
261
		}
262
263
		$this->cleanupBase( $siteids, 'mshop/customer/manager/standard/delete' );
264
	}
265
266
267
	/**
268
	 * Instantiates a new customer item object.
269
	 *
270
	 * @return \Aimeos\MShop\Customer\Item\Iface
271
	 */
272
	public function createItem()
273
	{
274
		$values = array( 'customer.siteid' => $this->getContext()->getLocale()->getSiteId() );
275
276
		return $this->createItemBase( $values );
277
	}
278
279
280
	/**
281
	 * Returns the available manager types
282
	 *
283
	 * @param boolean $withsub Return also the resource type of sub-managers if true
284
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
285
	 */
286
	public function getResourceType( $withsub = true )
287
	{
288
		$path = 'mshop/customer/manager/submanagers';
289
290
		return $this->getResourceTypeBase( 'customer', $path, array( 'address', 'group', 'lists' ), $withsub );
291
	}
292
293
294
	/**
295
	 * Returns the attributes that can be used for searching.
296
	 *
297
	 * @param boolean $withsub Return also attributes of sub-managers if true
298
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
299
	 */
300
	public function getSearchAttributes( $withsub = true )
301
	{
302
		/** mshop/customer/manager/submanagers
303
		 * List of manager names that can be instantiated by the customer manager
304
		 *
305
		 * Managers provide a generic interface to the underlying storage.
306
		 * Each manager has or can have sub-managers caring about particular
307
		 * aspects. Each of these sub-managers can be instantiated by its
308
		 * parent manager using the getSubManager() method.
309
		 *
310
		 * The search keys from sub-managers can be normally used in the
311
		 * manager as well. It allows you to search for items of the manager
312
		 * using the search keys of the sub-managers to further limit the
313
		 * retrieved list of items.
314
		 *
315
		 * @param array List of sub-manager names
316
		 * @since 2014.03
317
		 * @category Developer
318
		 */
319
		$path = 'mshop/customer/manager/submanagers';
320
321
		return $this->getSearchAttributesBase( $this->searchConfig, $path, array( 'address', 'lists' ), $withsub );
322
	}
323
324
325
	/**
326
	 * Removes multiple items specified by ids in the array.
327
	 *
328
	 * @param array $ids List of IDs
329
	 */
330
	public function deleteItems( array $ids )
331
	{
332
		/** mshop/customer/manager/standard/delete/mysql
333
		 * Deletes the items matched by the given IDs from the database
334
		 *
335
		 * @see mshop/customer/manager/standard/delete/ansi
336
		 */
337
338
		/** mshop/customer/manager/standard/delete/ansi
339
		 * Deletes the items matched by the given IDs from the database
340
		 *
341
		 * Removes the records specified by the given IDs from the customer database.
342
		 * The records must be from the site that is configured via the
343
		 * context item.
344
		 *
345
		 * The ":cond" placeholder is replaced by the name of the ID column and
346
		 * the given ID or list of IDs while the site ID is bound to the question
347
		 * mark.
348
		 *
349
		 * The SQL statement should conform to the ANSI standard to be
350
		 * compatible with most relational database systems. This also
351
		 * includes using double quotes for table and column names.
352
		 *
353
		 * @param string SQL statement for deleting items
354
		 * @since 2014.03
355
		 * @category Developer
356
		 * @see mshop/customer/manager/standard/insert/ansi
357
		 * @see mshop/customer/manager/standard/update/ansi
358
		 * @see mshop/customer/manager/standard/newid/ansi
359
		 * @see mshop/customer/manager/standard/search/ansi
360
		 * @see mshop/customer/manager/standard/count/ansi
361
		 */
362
		$path = 'mshop/customer/manager/standard/delete';
363
		$this->deleteItemsBase( $ids, $path );
364
	}
365
366
367
	/**
368
	 * Saves a customer item object.
369
	 *
370
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item object
371
	 * @param boolean $fetch True if the new ID should be returned in the item
372
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
0 ignored issues
show
Documentation introduced by
Should the return type not be \Aimeos\MShop\Common\Item\ListRef\Iface?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
373
	 */
374
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
375
	{
376
		$iface = '\\Aimeos\\MShop\\Customer\\Item\\Iface';
377
		if( !( $item instanceof $iface ) ) {
378
			throw new \Aimeos\MShop\Customer\Exception( sprintf( 'Object is not of required type "%1$s"', $iface ) );
379
		}
380
381
		if( !$item->isModified() )
382
		{
383
			$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\Iface>, but the function expects a object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
384
			return $this->saveRefItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\ListRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
385
		}
386
387
		$context = $this->getContext();
388
389
		$dbm = $context->getDatabaseManager();
390
		$dbname = $this->getResourceName();
391
		$conn = $dbm->acquire( $dbname );
392
393
		try
394
		{
395
			$id = $item->getId();
396
			$date = date( 'Y-m-d H:i:s' );
397
			$billingAddress = $item->getPaymentAddress();
398
399
			if( $id === null )
400
			{
401
				/** mshop/customer/manager/standard/insert/mysql
402
				 * Inserts a new customer record into the database table
403
				 *
404
				 * @see mshop/customer/manager/standard/insert/ansi
405
				 */
406
407
				/** mshop/customer/manager/standard/insert/ansi
408
				 * Inserts a new customer record into the database table
409
				 *
410
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
411
				 * the database and the newly created ID retrieved afterwards
412
				 * using the "newid" SQL statement.
413
				 *
414
				 * The SQL statement must be a string suitable for being used as
415
				 * prepared statement. It must include question marks for binding
416
				 * the values from the customer item to the statement before they are
417
				 * sent to the database server. The number of question marks must
418
				 * be the same as the number of columns listed in the INSERT
419
				 * statement. The order of the columns must correspond to the
420
				 * order in the saveItems() method, so the correct values are
421
				 * bound to the columns.
422
				 *
423
				 * The SQL statement should conform to the ANSI standard to be
424
				 * compatible with most relational database systems. This also
425
				 * includes using double quotes for table and column names.
426
				 *
427
				 * @param string SQL statement for inserting records
428
				 * @since 2014.03
429
				 * @category Developer
430
				 * @see mshop/customer/manager/standard/update/ansi
431
				 * @see mshop/customer/manager/standard/newid/ansi
432
				 * @see mshop/customer/manager/standard/delete/ansi
433
				 * @see mshop/customer/manager/standard/search/ansi
434
				 * @see mshop/customer/manager/standard/count/ansi
435
				 */
436
				$path = 'mshop/customer/manager/standard/insert';
437
			}
438
			else
439
			{
440
				/** mshop/customer/manager/standard/update/mysql
441
				 * Updates an existing customer record in the database
442
				 *
443
				 * @see mshop/customer/manager/standard/update/ansi
444
				 */
445
446
				/** mshop/customer/manager/standard/update/ansi
447
				 * Updates an existing customer record in the database
448
				 *
449
				 * Items which already have an ID (i.e. the ID is not NULL) will
450
				 * be updated in the database.
451
				 *
452
				 * The SQL statement must be a string suitable for being used as
453
				 * prepared statement. It must include question marks for binding
454
				 * the values from the customer item to the statement before they are
455
				 * sent to the database server. The order of the columns must
456
				 * correspond to the order in the saveItems() method, so the
457
				 * correct values are bound to the columns.
458
				 *
459
				 * The SQL statement should conform to the ANSI standard to be
460
				 * compatible with most relational database systems. This also
461
				 * includes using double quotes for table and column names.
462
				 *
463
				 * @param string SQL statement for updating records
464
				 * @since 2014.03
465
				 * @category Developer
466
				 * @see mshop/customer/manager/standard/insert/ansi
467
				 * @see mshop/customer/manager/standard/newid/ansi
468
				 * @see mshop/customer/manager/standard/delete/ansi
469
				 * @see mshop/customer/manager/standard/search/ansi
470
				 * @see mshop/customer/manager/standard/count/ansi
471
				 */
472
				$path = 'mshop/customer/manager/standard/update';
473
			}
474
475
			$stmt = $this->getCachedStatement( $conn, $path );
476
477
			$stmt->bind( 1, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
478
			$stmt->bind( 2, $item->getLabel() );
479
			$stmt->bind( 3, $item->getCode() );
480
			$stmt->bind( 4, $billingAddress->getCompany() );
481
			$stmt->bind( 5, $billingAddress->getVatID() );
482
			$stmt->bind( 6, $billingAddress->getSalutation() );
483
			$stmt->bind( 7, $billingAddress->getTitle() );
484
			$stmt->bind( 8, $billingAddress->getFirstname() );
485
			$stmt->bind( 9, $billingAddress->getLastname() );
486
			$stmt->bind( 10, $billingAddress->getAddress1() );
487
			$stmt->bind( 11, $billingAddress->getAddress2() );
488
			$stmt->bind( 12, $billingAddress->getAddress3() );
489
			$stmt->bind( 13, $billingAddress->getPostal() );
490
			$stmt->bind( 14, $billingAddress->getCity() );
491
			$stmt->bind( 15, $billingAddress->getState() );
492
			$stmt->bind( 16, $billingAddress->getCountryId() );
493
			$stmt->bind( 17, $billingAddress->getLanguageId() );
494
			$stmt->bind( 18, $billingAddress->getTelephone() );
495
			$stmt->bind( 19, $billingAddress->getEmail() );
496
			$stmt->bind( 20, $billingAddress->getTelefax() );
497
			$stmt->bind( 21, $billingAddress->getWebsite() );
498
			$stmt->bind( 22, $billingAddress->getLongitude() );
499
			$stmt->bind( 23, $billingAddress->getLatitude() );
500
			$stmt->bind( 24, $item->getBirthday() );
501
			$stmt->bind( 25, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
502
			$stmt->bind( 26, $item->getDateVerified() );
503
			$stmt->bind( 27, $item->getPassword() );
504
			$stmt->bind( 28, $date ); // Modification time
505
			$stmt->bind( 29, $context->getEditor() );
506
507
			if( $id !== null ) {
508
				$stmt->bind( 30, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
509
				$billingAddress->setId( $id ); // enforce ID to be present
510
				$item->setId( $id );
511
			} else {
512
				$stmt->bind( 30, $date ); // Creation time
513
			}
514
515
			$stmt->execute()->finish();
516
517
			if( $id === null && $fetch === true )
518
			{
519
				/** mshop/customer/manager/standard/newid/mysql
520
				 * Retrieves the ID generated by the database when inserting a new record
521
				 *
522
				 * @see mshop/customer/manager/standard/newid/ansi
523
				 */
524
525
				/** mshop/customer/manager/standard/newid/ansi
526
				 * Retrieves the ID generated by the database when inserting a new record
527
				 *
528
				 * As soon as a new record is inserted into the database table,
529
				 * the database server generates a new and unique identifier for
530
				 * that record. This ID can be used for retrieving, updating and
531
				 * deleting that specific record from the table again.
532
				 *
533
				 * For MySQL:
534
				 *  SELECT LAST_INSERT_ID()
535
				 * For PostgreSQL:
536
				 *  SELECT currval('seq_mcus_id')
537
				 * For SQL Server:
538
				 *  SELECT SCOPE_IDENTITY()
539
				 * For Oracle:
540
				 *  SELECT "seq_mcus_id".CURRVAL FROM DUAL
541
				 *
542
				 * There's no way to retrive the new ID by a SQL statements that
543
				 * fits for most database servers as they implement their own
544
				 * specific way.
545
				 *
546
				 * @param string SQL statement for retrieving the last inserted record ID
547
				 * @since 2014.03
548
				 * @category Developer
549
				 * @see mshop/customer/manager/standard/insert/ansi
550
				 * @see mshop/customer/manager/standard/update/ansi
551
				 * @see mshop/customer/manager/standard/delete/ansi
552
				 * @see mshop/customer/manager/standard/search/ansi
553
				 * @see mshop/customer/manager/standard/count/ansi
554
				 */
555
				$path = 'mshop/customer/manager/standard/newid';
556
				$item->setId( $this->newId( $conn, $path ) );
557
			}
558
559
			$dbm->release( $conn, $dbname );
560
		}
561
		catch( \Exception $e )
562
		{
563
			$dbm->release( $conn, $dbname );
564
			throw $e;
565
		}
566
567
		$this->addGroups( $item );
568
569
		$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\Iface>, but the function expects a object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
570
		return $this->saveRefItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\ListRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
571
	}
572
573
574
	/**
575
	 * Returns the item objects matched by the given search criteria.
576
	 *
577
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
578
	 * @param string[] $ref List of domains to fetch list items and referenced items for
579
	 * @param integer|null &$total Number of items that are available in total
580
	 * @return array Associative list of IDs as keys and items implementing \Aimeos\MShop\Customer\Item\Iface as values
581
	 */
582
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
583
	{
584
		$map = [];
585
		$context = $this->getContext();
586
587
		$dbm = $context->getDatabaseManager();
588
		$dbname = $this->getResourceName();
589
		$conn = $dbm->acquire( $dbname );
590
591
		try
592
		{
593
			$required = array( 'customer' );
594
595
			/** mshop/customer/manager/sitemode
596
			 * Mode how items from levels below or above in the site tree are handled
597
			 *
598
			 * By default, only items from the current site are fetched from the
599
			 * storage. If the ai-sites extension is installed, you can create a
600
			 * tree of sites. Then, this setting allows you to define for the
601
			 * whole customer domain if items from parent sites are inherited,
602
			 * sites from child sites are aggregated or both.
603
			 *
604
			 * Available constants for the site mode are:
605
			 * * 0 = only items from the current site
606
			 * * 1 = inherit items from parent sites
607
			 * * 2 = aggregate items from child sites
608
			 * * 3 = inherit and aggregate items at the same time
609
			 *
610
			 * You also need to set the mode in the locale manager
611
			 * (mshop/locale/manager/standard/sitelevel) to one of the constants.
612
			 * If you set it to the same value, it will work as described but you
613
			 * can also use different modes. For example, if inheritance and
614
			 * aggregation is configured the locale manager but only inheritance
615
			 * in the domain manager because aggregating items makes no sense in
616
			 * this domain, then items wil be only inherited. Thus, you have full
617
			 * control over inheritance and aggregation in each domain.
618
			 *
619
			 * @param integer Constant from Aimeos\MShop\Locale\Manager\Base class
620
			 * @category Developer
621
			 * @since 2018.01
622
			 * @see mshop/locale/manager/standard/sitelevel
623
			 */
624
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
625
			$level = $context->getConfig()->get( 'mshop/customer/manager/sitemode', $level );
626
627
			/** mshop/customer/manager/standard/search/mysql
628
			 * Retrieves the records matched by the given criteria in the database
629
			 *
630
			 * @see mshop/customer/manager/standard/search/ansi
631
			 */
632
633
			/** mshop/customer/manager/standard/search/ansi
634
			 * Retrieves the records matched by the given criteria in the database
635
			 *
636
			 * Fetches the records matched by the given criteria from the customer
637
			 * database. The records must be from one of the sites that are
638
			 * configured via the context item. If the current site is part of
639
			 * a tree of sites, the SELECT statement can retrieve all records
640
			 * from the current site and the complete sub-tree of sites.
641
			 *
642
			 * As the records can normally be limited by criteria from sub-managers,
643
			 * their tables must be joined in the SQL context. This is done by
644
			 * using the "internaldeps" property from the definition of the ID
645
			 * column of the sub-managers. These internal dependencies specify
646
			 * the JOIN between the tables and the used columns for joining. The
647
			 * ":joins" placeholder is then replaced by the JOIN strings from
648
			 * the sub-managers.
649
			 *
650
			 * To limit the records matched, conditions can be added to the given
651
			 * criteria object. It can contain comparisons like column names that
652
			 * must match specific values which can be combined by AND, OR or NOT
653
			 * operators. The resulting string of SQL conditions replaces the
654
			 * ":cond" placeholder before the statement is sent to the database
655
			 * server.
656
			 *
657
			 * If the records that are retrieved should be ordered by one or more
658
			 * columns, the generated string of column / sort direction pairs
659
			 * replaces the ":order" placeholder. In case no ordering is required,
660
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
661
			 * markers is removed to speed up retrieving the records. Columns of
662
			 * sub-managers can also be used for ordering the result set but then
663
			 * no index can be used.
664
			 *
665
			 * The number of returned records can be limited and can start at any
666
			 * number between the begining and the end of the result set. For that
667
			 * the ":size" and ":start" placeholders are replaced by the
668
			 * corresponding values from the criteria object. The default values
669
			 * are 0 for the start and 100 for the size value.
670
			 *
671
			 * The SQL statement should conform to the ANSI standard to be
672
			 * compatible with most relational database systems. This also
673
			 * includes using double quotes for table and column names.
674
			 *
675
			 * @param string SQL statement for searching items
676
			 * @since 2014.03
677
			 * @category Developer
678
			 * @see mshop/customer/manager/standard/insert/ansi
679
			 * @see mshop/customer/manager/standard/update/ansi
680
			 * @see mshop/customer/manager/standard/newid/ansi
681
			 * @see mshop/customer/manager/standard/delete/ansi
682
			 * @see mshop/customer/manager/standard/count/ansi
683
			 */
684
			$cfgPathSearch = 'mshop/customer/manager/standard/search';
685
686
			/** mshop/customer/manager/standard/count/mysql
687
			 * Counts the number of records matched by the given criteria in the database
688
			 *
689
			 * @see mshop/customer/manager/standard/count/ansi
690
			 */
691
692
			/** mshop/customer/manager/standard/count/ansi
693
			 * Counts the number of records matched by the given criteria in the database
694
			 *
695
			 * Counts all records matched by the given criteria from the customer
696
			 * database. The records must be from one of the sites that are
697
			 * configured via the context item. If the current site is part of
698
			 * a tree of sites, the statement can count all records from the
699
			 * current site and the complete sub-tree of sites.
700
			 *
701
			 * As the records can normally be limited by criteria from sub-managers,
702
			 * their tables must be joined in the SQL context. This is done by
703
			 * using the "internaldeps" property from the definition of the ID
704
			 * column of the sub-managers. These internal dependencies specify
705
			 * the JOIN between the tables and the used columns for joining. The
706
			 * ":joins" placeholder is then replaced by the JOIN strings from
707
			 * the sub-managers.
708
			 *
709
			 * To limit the records matched, conditions can be added to the given
710
			 * criteria object. It can contain comparisons like column names that
711
			 * must match specific values which can be combined by AND, OR or NOT
712
			 * operators. The resulting string of SQL conditions replaces the
713
			 * ":cond" placeholder before the statement is sent to the database
714
			 * server.
715
			 *
716
			 * Both, the strings for ":joins" and for ":cond" are the same as for
717
			 * the "search" SQL statement.
718
			 *
719
			 * Contrary to the "search" statement, it doesn't return any records
720
			 * but instead the number of records that have been found. As counting
721
			 * thousands of records can be a long running task, the maximum number
722
			 * of counted records is limited for performance reasons.
723
			 *
724
			 * The SQL statement should conform to the ANSI standard to be
725
			 * compatible with most relational database systems. This also
726
			 * includes using double quotes for table and column names.
727
			 *
728
			 * @param string SQL statement for counting items
729
			 * @since 2014.03
730
			 * @category Developer
731
			 * @see mshop/customer/manager/standard/insert/ansi
732
			 * @see mshop/customer/manager/standard/update/ansi
733
			 * @see mshop/customer/manager/standard/newid/ansi
734
			 * @see mshop/customer/manager/standard/delete/ansi
735
			 * @see mshop/customer/manager/standard/search/ansi
736
			 */
737
			$cfgPathCount = 'mshop/customer/manager/standard/count';
738
739
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
740
			while( ( $row = $results->fetch() ) !== false ) {
741
				$map[$row['customer.id']] = $row;
742
			}
743
744
			$dbm->release( $conn, $dbname );
745
		}
746
		catch( \Exception $e )
747
		{
748
			$dbm->release( $conn, $dbname );
749
			throw $e;
750
		}
751
752
		$addrItems = [];
753
		if( in_array( 'customer/address', $ref, true ) ) {
754
			$addrItems = $this->getAddressItems( array_keys( $map ) );
755
		}
756
757
		$propItems = [];
758
		if( in_array( 'customer/property', $ref, true ) ) {
759
			$propItems = $this->getPropertyItems( array_keys( $map ), 'customer' );
760
		}
761
762
		return $this->buildItems( $map, $ref, 'customer', $addrItems, $propItems );
763
	}
764
765
766
	/**
767
	 * Returns a new manager for customer extensions.
768
	 *
769
	 * @param string $manager Name of the sub manager type in lower case
770
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
771
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
772
	 */
773
	public function getSubManager( $manager, $name = null )
774
	{
775
		return $this->getSubManagerBase( 'customer', $manager, $name );
776
	}
777
}
778