Completed
Push — master ( 8d486f...f6c714 )
by Aimeos
01:43
created

Standard::addItemDefaults()   B

Complexity

Conditions 11
Paths 36

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 7.3166
c 0
b 0
f 0
cc 11
nc 36
nop 1

How to fix   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), 2017-2018
6
 * @package Controller
7
 * @subpackage Frontend
8
 */
9
10
11
namespace Aimeos\Controller\Frontend\Customer;
12
13
14
/**
15
 * Default implementation of the customer frontend controller
16
 *
17
 * @package Controller
18
 * @subpackage Frontend
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Frontend\Base
22
	implements Iface, \Aimeos\Controller\Frontend\Common\Iface
23
{
24
	/**
25
	 * Adds and returns a new customer item object
26
	 *
27
	 * @param array $values Values added to the newly created customer item like "customer.birthday"
28
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item
29
	 * @since 2017.04
30
	 */
31
	public function addItem( array $values )
32
	{
33
		$list = [];
34
		$context = $this->getContext();
35
		$config = $context->getConfig();
36
37
		foreach( $values as $key => $val ) {
38
			$list[str_replace( 'order.base.address', 'customer', $key )] = $val;
39
		}
40
41
		$manager = \Aimeos\MShop::create( $context, 'customer' );
42
		$list = $this->addItemDefaults( $list );
43
		$passwd = $list['customer.password'];
44
45
		try
46
		{
47
			$item = $manager->findItem( $list['customer.code'], [], true );
48
		}
49
		catch( \Aimeos\MShop\Exception $e )
50
		{
51
			$this->checkLimit( $list );
52
53
			$item = $manager->createItem()->fromArray( $list )->setId( null );
54
55
			/** controller/frontend/customer/groupids
56
			 * List of groups new customers should be assigned to
57
			 *
58
			 * Newly created customers will be assigned automatically to the groups
59
			 * given by their IDs. This is especially useful if those groups limit
60
			 * functionality for those users.
61
			 *
62
			 * @param array List of group IDs
63
			 * @since 2017.07
64
			 * @category User
65
			 * @category Developer
66
			 */
67
			$item->setGroups( (array) $config->get( 'controller/frontend/customer/groupids', [] ) );
68
69
			$item = $manager->saveItem( $item );
70
71
			$msg = $item->toArray();
72
			// Show only generated passwords in account creation e-mails
73
			$msg['customer.password'] = ( isset( $values['customer.password'] ) ? null : $passwd );
74
			$context->getMessageQueue( 'mq-email', 'customer/email/account' )->add( json_encode( $msg ) );
75
		}
76
77
		return $item;
78
	}
79
80
81
	/**
82
	 * Creates a new customer item object pre-filled with the given values but not yet stored
83
	 *
84
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item
85
	 */
86
	public function createItem( array $values = [] )
87
	{
88
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer' );
89
		return $manager->createItem()->fromArray( $values )->setId( null );
90
	}
91
92
93
	/**
94
	 * Deletes a customer item that belongs to the current authenticated user
95
	 *
96
	 * @param string $id Unique customer ID
97
	 * @since 2017.04
98
	 */
99
	public function deleteItem( $id )
100
	{
101
		$this->checkUser( $id );
102
103
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer' );
104
		$manager->deleteItem( $id );
105
	}
106
107
108
	/**
109
	 * Updates the customer item identified by its ID
110
	 *
111
	 * @param string $id Unique customer ID
112
	 * @param array $values Values added to the customer item like "customer.birthday" or "customer.city"
113
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item
114
	 * @since 2017.04
115
	 */
116
	public function editItem( $id, array $values )
117
	{
118
		$this->checkUser( $id );
119
		unset( $values['customer.id'] );
120
121
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer' );
122
		$item = $manager->getItem( $id, ['customer/group'], true )->fromArray( $values );
123
124
		return $manager->saveItem( $item );
125
	}
126
127
128
	/**
129
	 * Returns the customer item for the given customer ID
130
	 *
131
	 * @param string|null $id Unique customer ID or null for current customer item
132
	 * @param string[] $domains Domain names of items that are associated with the customers and that should be fetched too
133
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item including the referenced domains items
134
	 * @since 2017.04
135
	 */
136
	public function getItem( $id = null, array $domains = [] )
137
	{
138
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer' );
139
140
		if( $id == null ) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $id of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
141
			return $manager->getItem( $this->getContext()->getUserId(), $domains, true );
142
		}
143
144
		$this->checkUser( $id );
145
146
		return $manager->getItem( $id, $domains, true );
147
	}
148
149
150
	/**
151
	 * Returns the customer item for the given customer code (usually e-mail address)
152
	 *
153
	 * This method doesn't check if the customer item belongs to the logged in user!
154
	 *
155
	 * @param string $code Unique customer code
156
	 * @param string[] $domains Domain names of items that are associated with the customers and that should be fetched too
157
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item including the referenced domains items
158
	 * @since 2017.04
159
	 */
160
	public function findItem( $code, array $domains = [] )
161
	{
162
		return \Aimeos\MShop::create( $this->getContext(), 'customer' )->findItem( $code, $domains, true );
163
	}
164
165
166
	/**
167
	 * Stores a modified customer item
168
	 *
169
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item
170
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item including the generated ID
171
	 */
172
	public function saveItem( \Aimeos\MShop\Customer\Item\Iface $item )
173
	{
174
		return \Aimeos\MShop::create( $this->getContext(), 'customer' )->saveItem( $item );
175
	}
176
177
178
	/**
179
	 * Creates and returns a new item object
180
	 *
181
	 * @param array $values Values added to the newly created customer item like "customer.birthday"
182
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
183
	 * @since 2017.04
184
	 */
185
	public function addAddressItem( array $values )
186
	{
187
		$context = $this->getContext();
188
		$manager = \Aimeos\MShop::create( $context, 'customer/address' );
189
190
		$item = $manager->createItem()->fromArray( $values )->setId( null )->setParentId( $context->getUserId() );
191
		return $manager->saveItem( $item );
192
	}
193
194
195
	/**
196
	 * Creates a new customer address item object pre-filled with the given values but not yet stored
197
	 *
198
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
199
	 */
200
	public function createAddressItem( array $values = [] )
201
	{
202
		$context = $this->getContext();
203
		$manager = \Aimeos\MShop::create( $context, 'customer/address' );
204
205
		return $manager->createItem()->fromArray( $values )->setId( null )->setParentId( $context->getUserId() );
206
	}
207
208
209
	/**
210
	 * Deletes a customer item that belongs to the current authenticated user
211
	 *
212
	 * @param string $id Unique customer address ID
213
	 * @since 2017.04
214
	 */
215
	public function deleteAddressItem( $id )
216
	{
217
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/address' );
218
219
		$this->checkUser( $manager->getItem( $id, [], true )->getParentId() );
220
221
		$manager->deleteItem( $id );
222
	}
223
224
225
	/**
226
	 * Saves a modified customer item object
227
	 *
228
	 * @param string $id Unique customer address ID
229
	 * @param array $values Values added to the customer item like "customer.address.city"
230
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
231
	 * @since 2017.04
232
	 */
233
	public function editAddressItem( $id, array $values )
234
	{
235
		unset( $values['customer.address.id'] );
236
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/address' );
237
238
		$item = $manager->getItem( $id, [], true );
239
		$this->checkUser( $item->getParentId() );
240
241
		return $manager->saveItem( $item->fromArray( $values ) );
242
	}
243
244
245
	/**
246
	 * Returns the customer item for the given customer ID
247
	 *
248
	 * @param string $id Unique customer address ID
249
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
250
	 * @since 2017.04
251
	 */
252
	public function getAddressItem( $id )
253
	{
254
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/address' );
255
256
		$item = $manager->getItem( $id );
257
		$this->checkUser( $item->getParentId() );
258
259
		return $item;
260
	}
261
262
263
	/**
264
	 * Stores a modified customer address item
265
	 *
266
	 * @param \Aimeos\MShop\Customer\Item\Address\Iface $item Customer address item
267
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item including the generated ID
268
	 */
269
	public function saveAddressItem( \Aimeos\MShop\Customer\Item\Address\Iface $item )
270
	{
271
		return \Aimeos\MShop::create( $this->getContext(), 'customer/address' )->saveItem( $item );
272
	}
273
274
275
	/**
276
	 * Creates and returns a new list item object
277
	 *
278
	 * @param array $values Values added to the newly created customer item like "customer.lists.refid"
279
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface Customer lists item
280
	 * @since 2017.06
281
	 */
282
	public function addListItem( array $values )
283
	{
284
		$context = $this->getContext();
285
		$manager = \Aimeos\MShop::create( $context, 'customer/lists' );
286
287
		$item = $manager->createItem()->fromArray( $values )->setId( null )->setParentId( $context->getUserId() );
288
		return $manager->saveItem( $item );
289
	}
290
291
292
	/**
293
	 * Returns a new customer lists filter criteria object
294
	 *
295
	 * @return \Aimeos\MW\Criteria\Iface New filter object
296
	 * @since 2017.06
297
	 */
298
	public function createListsFilter()
299
	{
300
		$context = $this->getContext();
301
		$manager = \Aimeos\MShop::create( $context, 'customer/lists' );
302
303
		$filter = $manager->createSearch();
304
		$filter->setConditions( $filter->compare( '==', 'customer.lists.parentid', $context->getUserId() ) );
305
306
		return $filter;
307
	}
308
309
310
	/**
311
	 * Deletes a customer item that belongs to the current authenticated user
312
	 *
313
	 * @param string $id Unique customer address ID
314
	 * @since 2017.06
315
	 */
316
	public function deleteListItem( $id )
317
	{
318
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/lists' );
319
320
		$this->checkUser( $manager->getItem( $id )->getParentId() );
321
322
		$manager->deleteItem( $id );
323
	}
324
325
326
	/**
327
	 * Saves a modified customer lists item object
328
	 *
329
	 * @param string $id Unique customer lists ID
330
	 * @param array $values Values added to the customer lists item like "customer.lists.refid"
331
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface Customer lists item
332
	 * @since 2017.06
333
	 */
334
	public function editListItem( $id, array $values )
335
	{
336
		$context = $this->getContext();
337
		$manager = \Aimeos\MShop::create( $context, 'customer/lists' );
338
339
		$item = $manager->getItem( $id, [], true );
340
		$this->checkUser( $item->getParentId() );
341
		unset( $values['customer.lists.id'] );
342
343
		return $manager->saveItem( $item->fromArray( $values ) );
344
	}
345
346
347
	/**
348
	 * Returns the customer item for the given customer ID
349
	 *
350
	 * @param string $id Unique customer address ID
351
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
352
	 * @since 2017.06
353
	 */
354
	public function getListItem( $id )
355
	{
356
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/lists' );
357
		$item = $manager->getItem( $id );
358
359
		$this->checkUser( $item->getParentId() );
360
361
		return $item;
362
	}
363
364
365
	/**
366
	 * Returns the customer lists items filtered by the given criteria
367
	 *
368
	 * @param \Aimeos\MW\Criteria\Iface $filter Criteria object which contains the filter conditions
369
	 * @param integer &$total Parameter where the total number of found attributes will be stored in
370
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface[] Customer list items
371
	 * @since 2017.06
372
	 */
373
	public function searchListItems( \Aimeos\MW\Criteria\Iface $filter, &$total = null )
374
	{
375
		$manager = \Aimeos\MShop::create( $this->getContext(), 'customer/lists' );
376
377
		return $manager->searchItems( $filter, [], $total );
378
	}
379
380
381
	/**
382
	 * Adds the default values for customer items if not yet available
383
	 *
384
	 * @param string[] $values Associative list of customer keys (e.g. "customer.label") and their values
385
	 * @return string[] Associative list of customer key/value pairs with default values set
386
	 */
387
	protected function addItemDefaults( array $values )
388
	{
389
		if( !isset( $values['customer.label'] ) || $values['customer.label'] == '' )
390
		{
391
			$label = '';
392
393
			if( isset( $values['customer.lastname'] ) ) {
394
				$label = $values['customer.lastname'];
395
			}
396
397
			if( isset( $values['customer.firstname'] ) && $values['customer.firstname'] != '' ) {
398
				$label = $values['customer.firstname'] . ' ' . $label;
399
			}
400
401
			if( isset( $values['customer.company'] ) && $values['customer.company'] != '' ) {
402
				$label .= ' (' . $values['customer.company'] . ')';
403
			}
404
405
			$values['customer.label'] = $label;
406
		}
407
408
		if( !isset( $values['customer.code'] ) && isset( $values['customer.email'] ) ) {
409
			$values['customer.code'] = $values['customer.email'];
410
		}
411
412
		if( !isset( $values['customer.password'] ) ) {
413
			$values['customer.password'] = substr( md5( microtime( true ) . getmypid() . rand() ), -8 );
414
		}
415
416
		return $values;
417
	}
418
419
420
	/**
421
	 * Checks if the current user is allowed to create more customer accounts
422
	 *
423
	 * @param string[] $values Associative list of customer keys (e.g. "customer.label") and their values
424
	 * @throws \Aimeos\Controller\Frontend\Customer\Exception If access isn't allowed
425
	 */
426
	protected function checkLimit( array $values )
0 ignored issues
show
Unused Code introduced by
The parameter $values is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
427
	{
428
		$total = 0;
429
		$context = $this->getContext();
430
		$config = $context->getConfig();
431
432
		/** controller/frontend/customer/limit-count
433
		 * Maximum number of customers within the time frame
434
		 *
435
		 * Creating new customers is limited to avoid abuse and mitigate denial of
436
		 * service attacks. The number of customer accountss created within the
437
		 * time frame configured by "controller/frontend/customer/limit-seconds"
438
		 * are counted before a new customer account (identified by the IP address)
439
		 * is created. If the number of accounts is higher than the configured value,
440
		 * an error message will be shown to the user instead of creating a new account.
441
		 *
442
		 * @param integer Number of customer accounts allowed within the time frame
443
		 * @since 2017.07
444
		 * @category Developer
445
		 * @see controller/frontend/customer/limit-seconds
446
		 */
447
		$count = $config->get( 'controller/frontend/customer/limit-count', 5 );
448
449
		/** controller/frontend/customer/limit-seconds
450
		 * Customer account limitation time frame in seconds
451
		 *
452
		 * Creating new customer accounts is limited to avoid abuse and mitigate
453
		 * denial of service attacks. Within the configured time frame, only a
454
		 * limited number of customer accounts can be created. All accounts from
455
		 * the same source (identified by the IP address) within the last X
456
		 * seconds are counted. If the total value is higher then the number
457
		 * configured in "controller/frontend/customer/limit-count", an error
458
		 * message will be shown to the user instead of creating a new account.
459
		 *
460
		 * @param integer Number of seconds to check customer accounts within
461
		 * @since 2017.07
462
		 * @category Developer
463
		 * @see controller/frontend/customer/limit-count
464
		 */
465
		$seconds = $config->get( 'controller/frontend/customer/limit-seconds', 300 );
466
467
		$manager = \Aimeos\MShop::create( $context, 'customer' );
468
469
		$search = $manager->createSearch();
470
		$expr = [
471
			$search->compare( '==', 'customer.editor', $context->getEditor() ),
472
			$search->compare( '>=', 'customer.ctime', date( 'Y-m-d H:i:s', time() - $seconds ) ),
473
		];
474
		$search->setConditions( $search->combine( '&&', $expr ) );
475
		$search->setSlice( 0, 0 );
476
477
		$manager->searchItems( $search, [], $total );
478
479
		if( $total > $count ) {
480
			throw new \Aimeos\Controller\Frontend\Basket\Exception( sprintf( 'Temporary limit reached' ) );
481
		}
482
	}
483
484
485
	/**
486
	 * Checks if the current user is allowed to retrieve the customer data for the given ID
487
	 *
488
	 * @param string $id Unique customer ID
489
	 * @throws \Aimeos\Controller\Frontend\Customer\Exception If access isn't allowed
490
	 */
491
	protected function checkUser( $id )
492
	{
493
		if( $id != $this->getContext()->getUserId() )
494
		{
495
			$msg = sprintf( 'Not allowed to access customer data for ID "%1$s"', $id );
496
			throw new \Aimeos\Controller\Frontend\Customer\Exception( $msg );
497
		}
498
	}
499
}
500