Passed
Push — master ( cd10c0...d3372a )
by Aimeos
01:55
created

FosUser::__construct()   C

Complexity

Conditions 14
Paths 1

Size

Total Lines 52
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 29
c 5
b 0
f 0
dl 0
loc 52
rs 6.2666
cc 14
nc 1
nop 1

How to fix   Long Method    Complexity   

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, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2018
6
 * @package MShop
7
 * @subpackage Customer
8
 */
9
10
11
namespace Aimeos\MShop\Customer\Manager;
12
13
14
/**
15
 * Customer class implementation for Friends of Symfony user bundle.
16
 *
17
 * @package MShop
18
 * @subpackage Customer
19
 */
20
class FosUser
21
	extends \Aimeos\MShop\Customer\Manager\Standard
22
{
23
	private $searchConfig = array(
24
		// customer.siteid is only for informational purpuse, not for filtering
25
		'customer.id' => array(
26
			'label' => 'Customer ID',
27
			'code' => 'customer.id',
28
			'internalcode' => 'fos."id"',
29
			'type' => 'integer',
30
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
31
			'public' => false,
32
		),
33
		'customer.code' => array(
34
			'label' => 'Customer username',
35
			'code' => 'customer.code',
36
			'internalcode' => 'fos."username"',
37
			'type' => 'string',
38
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
39
		),
40
		'customer.label' => array(
41
			'label' => 'Customer label',
42
			'code' => 'customer.label',
43
			'internalcode' => 'fos."username_canonical"',
44
			'type' => 'string',
45
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
46
		),
47
		'customer.salutation' => array(
48
			'label' => 'Customer salutation',
49
			'code' => 'customer.salutation',
50
			'internalcode' => 'fos."salutation"',
51
			'type' => 'string',
52
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
53
		),
54
		'customer.company'=> array(
55
			'label' => 'Customer company',
56
			'code' => 'customer.company',
57
			'internalcode' => 'fos."company"',
58
			'type' => 'string',
59
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
60
		),
61
		'customer.vatid'=> array(
62
			'label' => 'Customer VAT ID',
63
			'code' => 'customer.vatid',
64
			'internalcode' => 'fos."vatid"',
65
			'type' => 'string',
66
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
67
		),
68
		'customer.title' => array(
69
			'label' => 'Customer title',
70
			'code' => 'customer.title',
71
			'internalcode' => 'fos."title"',
72
			'type' => 'string',
73
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
74
		),
75
		'customer.firstname' => array(
76
			'label' => 'Customer firstname',
77
			'code' => 'customer.firstname',
78
			'internalcode' => 'fos."firstname"',
79
			'type' => 'string',
80
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
81
		),
82
		'customer.lastname' => array(
83
			'label' => 'Customer lastname',
84
			'code' => 'customer.lastname',
85
			'internalcode' => 'fos."lastname"',
86
			'type' => 'string',
87
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
88
		),
89
		'customer.address1' => array(
90
			'label' => 'Customer address part one',
91
			'code' => 'customer.address1',
92
			'internalcode' => 'fos."address1"',
93
			'type' => 'string',
94
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
95
		),
96
		'customer.address2' => array(
97
			'label' => 'Customer address part two',
98
			'code' => 'customer.address2',
99
			'internalcode' => 'fos."address2"',
100
			'type' => 'string',
101
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
102
		),
103
		'customer.address3' => array(
104
			'label' => 'Customer address part three',
105
			'code' => 'customer.address3',
106
			'internalcode' => 'fos."address3"',
107
			'type' => 'string',
108
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
109
		),
110
		'customer.postal' => array(
111
			'label' => 'Customer postal',
112
			'code' => 'customer.postal',
113
			'internalcode' => 'fos."postal"',
114
			'type' => 'string',
115
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
116
		),
117
		'customer.city' => array(
118
			'label' => 'Customer city',
119
			'code' => 'customer.city',
120
			'internalcode' => 'fos."city"',
121
			'type' => 'string',
122
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
123
		),
124
		'customer.state' => array(
125
			'label' => 'Customer state',
126
			'code' => 'customer.state',
127
			'internalcode' => 'fos."state"',
128
			'type' => 'string',
129
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
130
		),
131
		'customer.languageid' => array(
132
			'label' => 'Customer language',
133
			'code' => 'customer.languageid',
134
			'internalcode' => 'fos."langid"',
135
			'type' => 'string',
136
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
137
		),
138
		'customer.countryid' => array(
139
			'label' => 'Customer country',
140
			'code' => 'customer.countryid',
141
			'internalcode' => 'fos."countryid"',
142
			'type' => 'string',
143
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
144
		),
145
		'customer.telephone' => array(
146
			'label' => 'Customer telephone',
147
			'code' => 'customer.telephone',
148
			'internalcode' => 'fos."telephone"',
149
			'type' => 'string',
150
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
151
		),
152
		'customer.email' => array(
153
			'label' => 'Customer email',
154
			'code' => 'customer.email',
155
			'internalcode' => 'fos."email"',
156
			'type' => 'string',
157
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
158
		),
159
		'customer.telefax' => array(
160
			'label' => 'Customer telefax',
161
			'code' => 'customer.telefax',
162
			'internalcode' => 'fos."telefax"',
163
			'type' => 'string',
164
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
165
		),
166
		'customer.website' => array(
167
			'label' => 'Customer website',
168
			'code' => 'customer.website',
169
			'internalcode' => 'fos."website"',
170
			'type' => 'string',
171
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
172
		),
173
		'customer.longitude' => array(
174
			'label' => 'Customer longitude',
175
			'code' => 'customer.longitude',
176
			'internalcode' => 'fos."longitude"',
177
			'type' => 'float',
178
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT,
179
		),
180
		'customer.latitude' => array(
181
			'label' => 'Customer latitude',
182
			'code' => 'customer.latitude',
183
			'internalcode' => 'fos."latitude"',
184
			'type' => 'float',
185
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT,
186
		),
187
		'customer.birthday' => array(
188
			'label' => 'Customer birthday',
189
			'code' => 'customer.birthday',
190
			'internalcode' => 'fos."birthday"',
191
			'type' => 'string',
192
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
193
		),
194
		'customer.password'=> array(
195
			'label' => 'Customer password',
196
			'code' => 'customer.password',
197
			'internalcode' => 'fos."password"',
198
			'type' => 'string',
199
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
200
		),
201
		'customer.status'=> array(
202
			'label' => 'Customer status',
203
			'code' => 'customer.status',
204
			'internalcode' => 'fos."enabled"',
205
			'type' => 'integer',
206
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_BOOL,
207
		),
208
		'customer.dateverified'=> array(
209
			'label' => 'Customer verification date',
210
			'code' => 'customer.dateverified',
211
			'internalcode' => 'fos."vdate"',
212
			'type' => 'date',
213
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
214
		),
215
		'customer.ctime'=> array(
216
			'label' => 'Customer creation time',
217
			'code' => 'customer.ctime',
218
			'internalcode' => 'fos."ctime"',
219
			'type' => 'datetime',
220
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
221
		),
222
		'customer.mtime'=> array(
223
			'label' => 'Customer modification time',
224
			'code' => 'customer.mtime',
225
			'internalcode' => 'fos."mtime"',
226
			'type' => 'datetime',
227
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
228
		),
229
		'customer.editor'=> array(
230
			'label'=>'Customer editor',
231
			'code'=>'customer.editor',
232
			'internalcode' => 'fos."editor"',
233
			'type'=> 'string',
234
			'internaltype'=> \Aimeos\MW\DB\Statement\Base::PARAM_STR,
235
		),
236
		'customer:has' => array(
237
			'code' => 'customer:has()',
238
			'internalcode' => ':site :key AND fosli."id"',
239
			'internaldeps' => ['LEFT JOIN "fos_user_list" AS fosli ON ( fosli."parentid" = fos."id" )'],
240
			'label' => 'Customer has list item, parameter(<domain>[,<list type>[,<reference ID>)]]',
241
			'type' => 'null',
242
			'internaltype' => 'null',
243
			'public' => false,
244
		),
245
		'customer:prop' => array(
246
			'code' => 'customer:prop()',
247
			'internalcode' => ':site :key AND fospr."id"',
248
			'internaldeps' => ['LEFT JOIN "fos_user_property" AS fospr ON ( fospr."parentid" = fos."id" )'],
249
			'label' => 'Customer has property item, parameter(<property type>[,<language code>[,<property value>]])',
250
			'type' => 'null',
251
			'internaltype' => 'null',
252
			'public' => false,
253
		),
254
	);
255
256
257
	/**
258
	 * Initializes the object.
259
	 *
260
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
261
	 */
262
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
263
	{
264
		parent::__construct( $context );
265
266
		$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
267
		$level = $context->getConfig()->get( 'mshop/customer/manager/sitemode', $level );
268
269
		$siteIds = $this->getSiteIds( $level );
270
		$self = $this;
271
272
273
		$this->searchConfig['customer:has']['function'] = function( &$source, array $params ) use ( $self, $siteIds ) {
274
275
			array_walk_recursive( $params, function( &$v ) {
276
				$v = trim( $v, '\'' );
277
			} );
278
279
			$keys = [];
280
			$params[1] = isset( $params[1] ) ? $params[1] : '';
281
			$params[2] = isset( $params[2] ) ? $params[2] : '';
282
283
			foreach( (array) $params[2] as $id ) {
284
				$keys[] = $params[0] . '|' . ( $params[1] ? $params[1] . '|' : '' ) . $id;
285
			}
286
287
			$sitestr = $siteIds ? $self->toExpression( 'fosli."siteid"', $siteIds ) . ' AND' : '';
288
			$keystr = $self->toExpression( 'fosli."key"', $keys, $params[2] !== '' ? '==' : '=~' );
289
			$source = str_replace( [':site', ':key'], [$sitestr, $keystr], $source );
290
291
			return $params;
292
		};
293
294
295
		$this->searchConfig['customer:prop']['function'] = function( &$source, array $params ) use ( $self, $siteIds ) {
296
297
			array_walk_recursive( $params, function( &$v ) {
298
				$v = trim( $v, '\'' );
299
			} );
300
301
			$keys = [];
302
			$params[1] = array_key_exists( 1, $params ) ? $params[1] : '';
303
			$params[2] = isset( $params[2] ) ? $params[2] : '';
304
305
			foreach( (array) $params[2] as $id ) {
306
				$keys[] = $params[0] . '|' . ( $params[1] ? $params[1] . '|' : '' ) .( $id !== '' ?  md5( $id ) : '' );
307
			}
308
309
			$sitestr = $siteIds ? $self->toExpression( 'fospr."siteid"', $siteIds ) . ' AND' : '';
310
			$keystr = $self->toExpression( 'fospr."key"', $keys, $params[2] !== '' ? '==' : '=~' );
311
			$source = str_replace( [':site', ':key'], [$sitestr, $keystr], $source );
312
313
			return $params;
314
		};
315
	}
316
317
318
	/**
319
	 * Removes old entries from the storage.
320
	 *
321
	 * @param array $siteids List of IDs for sites whose entries should be deleted
322
	 */
323
	public function clear( array $siteids )
324
	{
325
		$path = 'mshop/customer/manager/submanagers';
326
		$default = ['address', 'lists', 'property'];
327
328
		foreach( $this->getContext()->getConfig()->get( $path, $default ) as $domain ) {
329
			$this->getObject()->getSubManager( $domain )->clear( $siteids );
330
		}
331
	}
332
333
334
	/**
335
	 * Removes multiple items.
336
	 *
337
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
338
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
339
	 */
340
	public function deleteItems( array $itemIds )
341
	{
342
		$path = 'mshop/customer/manager/fosuser/delete';
343
		return $this->deleteItemsBase( $itemIds, $path, false )->deleteRefItems( $itemIds );
344
	}
345
346
347
	/**
348
	 * Returns the list attributes that can be used for searching.
349
	 *
350
	 * @param boolean $withsub Return also attributes of sub-managers if true
351
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
352
	 */
353
	public function getSearchAttributes( $withsub = true )
354
	{
355
		$path = 'mshop/customer/manager/submanagers';
356
		return $this->getSearchAttributesBase( $this->searchConfig, $path, ['address'], $withsub );
357
	}
358
359
360
	/**
361
	 * Saves a customer item object.
362
	 *
363
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item object
364
	 * @param boolean $fetch True if the new ID should be returned in the item
365
	 * @return \Aimeos\MShop\Customer\Item\Iface $item Updated item including the generated ID
366
	 */
367
	public function saveItem( \Aimeos\MShop\Customer\Item\Iface $item, $fetch = true )
368
	{
369
		$item = $this->addGroups( $item );
370
371
		if( !$item->isModified() )
372
		{
373
			$item = $this->savePropertyItems( $item, 'customer' );
374
			$item = $this->saveAddressItems( $item, 'customer' );
375
			return $this->saveListItems( $item, 'customer' );
376
		}
377
378
		$context = $this->getContext();
379
		$dbm = $context->getDatabaseManager();
380
		$dbname = $this->getResourceName();
381
		$conn = $dbm->acquire( $dbname );
382
383
		try
384
		{
385
			$id = $item->getId();
386
			$date = date( 'Y-m-d H:i:s' );
387
			$billingAddress = $item->getPaymentAddress();
388
			$columns = $this->getObject()->getSaveAttributes();
389
390
			if( $id === null )
391
			{
392
				/** mshop/customer/manager/fosuser/insert
393
				 * Inserts a new customer record into the database table
394
				 *
395
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
396
				 * the database and the newly created ID retrieved afterwards
397
				 * using the "newid" SQL statement.
398
				 *
399
				 * The SQL statement must be a string suitable for being used as
400
				 * prepared statement. It must include question marks for binding
401
				 * the values from the customer item to the statement before they are
402
				 * sent to the database server. The number of question marks must
403
				 * be the same as the number of columns listed in the INSERT
404
				 * statement. The order of the columns must correspond to the
405
				 * order in the saveItems() method, so the correct values are
406
				 * bound to the columns.
407
				 *
408
				 * The SQL statement should conform to the ANSI standard to be
409
				 * compatible with most relational database systems. This also
410
				 * includes using double quotes for table and column names.
411
				 *
412
				 * @param string SQL statement for inserting records
413
				 * @since 2015.01
414
				 * @category Developer
415
				 * @see mshop/customer/manager/fosuser/update
416
				 * @see mshop/customer/manager/fosuser/newid
417
				 * @see mshop/customer/manager/fosuser/delete
418
				 * @see mshop/customer/manager/fosuser/search
419
				 * @see mshop/customer/manager/fosuser/count
420
				 */
421
				$path = 'mshop/customer/manager/fosuser/insert';
422
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ) );
423
			}
424
			else
425
			{
426
				/** mshop/customer/manager/fosuser/update
427
				 * Updates an existing customer record in the database
428
				 *
429
				 * Items which already have an ID (i.e. the ID is not NULL) will
430
				 * be updated in the database.
431
				 *
432
				 * The SQL statement must be a string suitable for being used as
433
				 * prepared statement. It must include question marks for binding
434
				 * the values from the customer item to the statement before they are
435
				 * sent to the database server. The order of the columns must
436
				 * correspond to the order in the saveItems() method, so the
437
				 * correct values are bound to the columns.
438
				 *
439
				 * The SQL statement should conform to the ANSI standard to be
440
				 * compatible with most relational database systems. This also
441
				 * includes using double quotes for table and column names.
442
				 *
443
				 * @param string SQL statement for updating records
444
				 * @since 2015.01
445
				 * @category Developer
446
				 * @see mshop/customer/manager/fosuser/insert
447
				 * @see mshop/customer/manager/fosuser/newid
448
				 * @see mshop/customer/manager/fosuser/delete
449
				 * @see mshop/customer/manager/fosuser/search
450
				 * @see mshop/customer/manager/fosuser/count
451
				 */
452
				$path = 'mshop/customer/manager/fosuser/update';
453
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );
454
			}
455
456
			$idx = 1;
457
			$stmt = $this->getCachedStatement( $conn, $path, $sql );
458
459
			foreach( $columns as $name => $entry ) {
460
				$stmt->bind( $idx++, $item->get( $name ), $entry->getInternalType() );
461
			}
462
463
			$stmt->bind( $idx++, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
464
			$stmt->bind( $idx++, $item->getCode() ); // canonical username
465
			$stmt->bind( $idx++, $item->getCode() ); // username
466
			$stmt->bind( $idx++, $billingAddress->getCompany() );
467
			$stmt->bind( $idx++, $billingAddress->getVatID() );
468
			$stmt->bind( $idx++, $billingAddress->getSalutation() );
469
			$stmt->bind( $idx++, $billingAddress->getTitle() );
470
			$stmt->bind( $idx++, $billingAddress->getFirstname() );
471
			$stmt->bind( $idx++, $billingAddress->getLastname() );
472
			$stmt->bind( $idx++, $billingAddress->getAddress1() );
473
			$stmt->bind( $idx++, $billingAddress->getAddress2() );
474
			$stmt->bind( $idx++, $billingAddress->getAddress3() );
475
			$stmt->bind( $idx++, $billingAddress->getPostal() );
476
			$stmt->bind( $idx++, $billingAddress->getCity() );
477
			$stmt->bind( $idx++, $billingAddress->getState() );
478
			$stmt->bind( $idx++, $billingAddress->getCountryId() );
479
			$stmt->bind( $idx++, $billingAddress->getLanguageId() );
480
			$stmt->bind( $idx++, $billingAddress->getTelephone() );
481
			$stmt->bind( $idx++, $billingAddress->getEmail() );
482
			$stmt->bind( $idx++, $billingAddress->getEmail() );
483
			$stmt->bind( $idx++, $billingAddress->getTelefax() );
484
			$stmt->bind( $idx++, $billingAddress->getWebsite() );
485
			$stmt->bind( $idx++, $billingAddress->getLongitude(), \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT );
486
			$stmt->bind( $idx++, $billingAddress->getLatitude(), \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT );
487
			$stmt->bind( $idx++, $item->getBirthday() );
488
			$stmt->bind( $idx++, ( $item->getStatus() > 0 ? true : false ), \Aimeos\MW\DB\Statement\Base::PARAM_BOOL );
489
			$stmt->bind( $idx++, $item->getDateVerified() );
490
			$stmt->bind( $idx++, $item->getPassword() );
491
			$stmt->bind( $idx++, $date ); // Modification time
492
			$stmt->bind( $idx++, $context->getEditor() );
493
			$stmt->bind( $idx++, serialize( $item->getRoles() ) );
494
			$stmt->bind( $idx++, $item->getSalt() );
495
496
			if( $id !== null ) {
497
				$stmt->bind( $idx, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
498
				$item->setId( $id );
499
			} else {
500
				$stmt->bind( $idx, $date ); // Creation time
501
			}
502
503
			$stmt->execute()->finish();
504
505
			if( $id === null && $fetch === true )
506
			{
507
				/** mshop/customer/manager/fosuser/newid
508
				 * Retrieves the ID generated by the database when inserting a new record
509
				 *
510
				 * As soon as a new record is inserted into the database table,
511
				 * the database server generates a new and unique identifier for
512
				 * that record. This ID can be used for retrieving, updating and
513
				 * deleting that specific record from the table again.
514
				 *
515
				 * For MySQL:
516
				 *  SELECT LAST_INSERT_ID()
517
				 * For PostgreSQL:
518
				 *  SELECT currval('seq_mcus_id')
519
				 * For SQL Server:
520
				 *  SELECT SCOPE_IDENTITY()
521
				 * For Oracle:
522
				 *  SELECT "seq_mcus_id".CURRVAL FROM DUAL
523
				 *
524
				 * There's no way to retrive the new ID by a SQL statements that
525
				 * fits for most database servers as they implement their own
526
				 * specific way.
527
				 *
528
				 * @param string SQL statement for retrieving the last inserted record ID
529
				 * @since 2015.01
530
				 * @category Developer
531
				 * @see mshop/customer/manager/fosuser/insert
532
				 * @see mshop/customer/manager/fosuser/update
533
				 * @see mshop/customer/manager/fosuser/delete
534
				 * @see mshop/customer/manager/fosuser/search
535
				 * @see mshop/customer/manager/fosuser/count
536
				 */
537
				$path = 'mshop/customer/manager/fosuser/newid';
538
				$item->setId( $this->newId( $conn, $path ) );
539
			}
540
541
			$dbm->release( $conn, $dbname );
542
		}
543
		catch( \Exception $e )
544
		{
545
			$dbm->release( $conn, $dbname );
546
			throw $e;
547
		}
548
549
		$item = $this->savePropertyItems( $item, 'customer' );
550
		$item = $this->saveAddressItems( $item, 'customer' );
551
		return $this->saveListItems( $item, 'customer' );
552
	}
553
554
555
	/**
556
	 * Returns the item objects matched by the given search criteria.
557
	 *
558
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
559
	 * @param integer &$total Number of items that are available in total
560
	 * @return array List of items implementing \Aimeos\MShop\Customer\Item\Iface
561
	 * @throws \Aimeos\MShop\Customer\Exception If creating items failed
562
	 */
563
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
564
	{
565
		$dbm = $this->getContext()->getDatabaseManager();
566
		$dbname = $this->getResourceName();
567
		$conn = $dbm->acquire( $dbname );
568
		$map = [];
569
570
		try
571
		{
572
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
573
			$cfgPathSearch = 'mshop/customer/manager/fosuser/search';
574
			$cfgPathCount = 'mshop/customer/manager/fosuser/count';
575
			$ref[] = 'customer/group';
576
			$required = ['customer'];
577
578
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
579
			while( ( $row = $results->fetch() ) !== false ) {
580
				$map[(string) $row['customer.id']] = $row;
581
			}
582
583
			$dbm->release( $conn, $dbname );
584
		}
585
		catch( \Exception $e )
586
		{
587
			$dbm->release( $conn, $dbname );
588
			throw $e;
589
		}
590
591
		$addrItems = [];
592
		if( in_array( 'customer/address', $ref, true ) ) {
593
			$addrItems = $this->getAddressItems( array_keys( $map ), 'customer' );
594
		}
595
596
		$propItems = []; $name = 'customer/property';
597
		if( isset( $ref[$name] ) || in_array( $name, $ref, true ) )
598
		{
599
			$propTypes = isset( $ref[$name] ) && is_array( $ref[$name] ) ? $ref[$name] : null;
600
			$propItems = $this->getPropertyItems( array_keys( $map ), 'customer', $propTypes );
601
		}
602
603
		return $this->buildItems( $map, $ref, 'customer', $addrItems, $propItems );
604
	}
605
606
607
	/**
608
	 * Returns a new manager for customer extensions
609
	 *
610
	 * @param string $manager Name of the sub manager type in lower case
611
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
612
	 * @return mixed Manager for different extensions, e.g stock, tags, locations, etc.
613
	 */
614
	public function getSubManager( $manager, $name = null )
615
	{
616
		return $this->getSubManagerBase( 'customer', $manager, ( $name === null ? 'FosUser' : $name ) );
617
	}
618
619
620
	/**
621
	 * Creates a new customer item.
622
	 *
623
	 * @param array $values List of attributes for customer item
624
	 * @param \Aimeos\MShop\Common\Lists\Item\Iface[] $listItems List of list items
625
	 * @param \Aimeos\MShop\Common\Item\Iface[] $refItems List of referenced items
626
	 * @param \Aimeos\MShop\Common\Item\Address\Iface[] $addrItems List of referenced address items
627
	 * @param \Aimeos\MShop\Common\Item\Property\Iface[] $propItems List of property items
628
	 * @return \Aimeos\MShop\Customer\Item\Iface New customer item
629
	 */
630
	protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [],
631
		array $addrItems = [], array $propItems = [] )
632
	{
633
		if( isset( $values['roles'] ) ) {
634
			$values['roles'] = unserialize( $values['roles'] );
635
		}
636
637
		$helper = $this->getPasswordHelper();
638
		$address = new \Aimeos\MShop\Common\Item\Address\Simple( 'customer.', $values );
639
640
		return new \Aimeos\MShop\Customer\Item\FosUser(
641
			$address, $values, $listItems, $refItems, $addrItems, $propItems, $helper
642
		);
643
	}
644
}
645