Completed
Push — master ( 9505fd...415908 )
by Aimeos
02:02
created

Standard::checkLimit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 57
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 57
rs 9.6818
c 0
b 0
f 0
cc 2
eloc 16
nc 2
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017
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
		$context = $this->getContext();
34
		$config = $context->getConfig();
35
36
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer' );
37
		$values = $this->addItemDefaults( $values );
38
39
		try
40
		{
41
			$item = $manager->findItem( $values['customer.code'] );
42
		}
43
		catch( \Aimeos\MShop\Exception $e )
44
		{
45
			$this->checkLimit( $values );
46
47
			$item = $manager->createItem();
48
			$item->fromArray( $values );
49
			$item->setId( null );
50
51
			/** controller/frontend/customer/groupids
52
			 * List of groups new customers should be assigned to
53
			 *
54
			 * Newly created customers will be assigned automatically to the groups
55
			 * given by their IDs. This is especially useful if those groups limit
56
			 * functionality for those users.
57
			 *
58
			 * @param array List of group IDs
59
			 * @since 2017.07
60
			 * @category User
61
			 * @category Developer
62
			 */
63
			$gids = $config->get( 'client/html/checkout/standard/order/account/standard/groupids', [] ); // @deprecated
64
			$item->setGroups( (array) $config->get( 'controller/frontend/customer/groupids', $gids ) );
65
66
			$item = $manager->saveItem( $item );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $item is correct as $manager->saveItem($item) (which targets Aimeos\MShop\Common\Manager\Iface::saveItem()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
67
68
			$msg = $item->toArray();
0 ignored issues
show
Bug introduced by
The method toArray cannot be called on $item (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
69
			$msg['customer.password'] = $values['customer.password'];
70
			$context->getMessageQueue( 'mq-email', 'customer/email/account' )->add( json_encode( $msg ) );
71
		}
72
73
		return $item;
74
	}
75
76
77
	/**
78
	 * Creates a new customer item object pre-filled with the given values but not yet stored
79
	 *
80
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item
81
	 */
82
	public function createItem( array $values = [] )
83
	{
84
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' );
85
86
		$item = $manager->createItem();
87
		$item->fromArray( $values );
88
		$item->setId( null );
89
		$item->setStatus( 1 );
90
91
		return $item;
92
	}
93
94
95
	/**
96
	 * Deletes a customer item that belongs to the current authenticated user
97
	 *
98
	 * @param string $id Unique customer ID
99
	 * @since 2017.04
100
	 */
101
	public function deleteItem( $id )
102
	{
103
		$this->checkUser( $id );
104
105
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' );
106
		$manager->deleteItem( $id );
107
	}
108
109
110
	/**
111
	 * Updates the customer item identified by its ID
112
	 *
113
	 * @param string $id Unique customer ID
114
	 * @param array $values Values added to the customer item like "customer.birthday" or "customer.city"
115
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item
116
	 * @since 2017.04
117
	 */
118
	public function editItem( $id, array $values )
119
	{
120
		$this->checkUser( $id );
121
122
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' );
123
		$item = $manager->getItem( $id, [], true );
124
125
		unset( $values['customer.id'] );
126
		$item->fromArray( $values );
127
128
		return $manager->saveItem( $item );
129
	}
130
131
132
	/**
133
	 * Returns the customer item for the given customer ID
134
	 *
135
	 * @param string|null $id Unique customer ID or null for current customer item
136
	 * @param string[] $domains Domain names of items that are associated with the customers and that should be fetched too
137
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item including the referenced domains items
138
	 * @since 2017.04
139
	 */
140
	public function getItem( $id = null, array $domains = [] )
141
	{
142
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' );
143
144
		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...
145
			return $manager->getItem( $this->getContext()->getUserId(), $domains, true );
146
		}
147
148
		$this->checkUser( $id );
149
150
		return $manager->getItem( $id, $domains, true );
151
	}
152
153
154
	/**
155
	 * Returns the customer item for the given customer code (usually e-mail address)
156
	 *
157
	 * This method doesn't check if the customer item belongs to the logged in user!
158
	 *
159
	 * @param string $code Unique customer code
160
	 * @param string[] $domains Domain names of items that are associated with the customers and that should be fetched too
161
	 * @return \Aimeos\MShop\Customer\Item\Iface Customer item including the referenced domains items
162
	 * @since 2017.04
163
	 */
164
	public function findItem( $code, array $domains = [] )
165
	{
166
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' )->findItem( $code, $domains );
167
	}
168
169
170
	/**
171
	 * Stores a modified customer item
172
	 *
173
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item
174
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item including the generated ID
175
	 */
176
	public function saveItem( \Aimeos\MShop\Customer\Item\Iface $item )
177
	{
178
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer' )->saveItem( $item );
179
	}
180
181
182
	/**
183
	 * Creates and returns a new item object
184
	 *
185
	 * @param array $values Values added to the newly created customer item like "customer.birthday"
186
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
187
	 * @since 2017.04
188
	 */
189
	public function addAddressItem( array $values )
190
	{
191
		$context = $this->getContext();
192
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer/address' );
193
194
		$item = $manager->createItem();
195
		$item->fromArray( $values );
196
		$item->setId( null );
197
		$item->setParentId( $context->getUserId() );
198
199
		return $manager->saveItem( $item );
200
	}
201
202
203
	/**
204
	 * Creates a new customer address item object pre-filled with the given values but not yet stored
205
	 *
206
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
207
	 */
208
	public function createAddressItem( array $values = [] )
209
	{
210
		$context = $this->getContext();
211
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer/address' );
212
213
		$item = $manager->createItem();
214
		$item->fromArray( $values );
215
		$item->setId( null );
216
217
		$item->setParentId( $context->getUserId() );
218
219
		return $item;
220
	}
221
222
223
	/**
224
	 * Deletes a customer item that belongs to the current authenticated user
225
	 *
226
	 * @param string $id Unique customer address ID
227
	 * @since 2017.04
228
	 */
229
	public function deleteAddressItem( $id )
230
	{
231
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/address' );
232
233
		$this->checkUser( $manager->getItem( $id, [], true )->getParentId() );
234
235
		$manager->deleteItem( $id );
236
	}
237
238
239
	/**
240
	 * Saves a modified customer item object
241
	 *
242
	 * @param string $id Unique customer address ID
243
	 * @param array $values Values added to the customer item like "customer.address.city"
244
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
245
	 * @since 2017.04
246
	 */
247
	public function editAddressItem( $id, array $values )
248
	{
249
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/address' );
250
251
		$item = $manager->getItem( $id, [], true );
252
		$this->checkUser( $item->getParentId() );
253
254
		unset( $values['customer.address.id'] );
255
		$item->fromArray( $values );
256
257
		return $manager->saveItem( $item );
258
	}
259
260
261
	/**
262
	 * Returns the customer item for the given customer ID
263
	 *
264
	 * @param string $id Unique customer address ID
265
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
266
	 * @since 2017.04
267
	 */
268
	public function getAddressItem( $id )
269
	{
270
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/address' );
271
272
		$item = $manager->getItem( $id );
273
		$this->checkUser( $item->getParentId() );
274
275
		return $item;
276
	}
277
278
279
	/**
280
	 * Stores a modified customer address item
281
	 *
282
	 * @param \Aimeos\MShop\Customer\Item\Address\Iface $item Customer address item
283
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item including the generated ID
284
	 */
285
	public function saveAddressItem( \Aimeos\MShop\Customer\Item\Address\Iface $item )
286
	{
287
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/address' )->saveItem( $item );
288
	}
289
290
291
	/**
292
	 * Creates and returns a new list item object
293
	 *
294
	 * @param array $values Values added to the newly created customer item like "customer.lists.refid"
295
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface Customer lists item
296
	 * @since 2017.06
297
	 */
298
	public function addListItem( array $values )
299
	{
300
		$context = $this->getContext();
301
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer/lists' );
302
303
		if( !isset( $values['customer.lists.typeid'] ) )
304
		{
305
			if( !isset( $values['customer.lists.type'] ) ) {
306
				throw new \Aimeos\Controller\Frontend\Customer\Exception( sprintf( 'No customer lists type code' ) );
307
			}
308
309
			if( !isset( $values['customer.lists.domain'] ) ) {
310
				throw new \Aimeos\Controller\Frontend\Customer\Exception( sprintf( 'No customer lists domain' ) );
311
			}
312
313
			$typeManager = \Aimeos\MShop\Factory::createManager( $context, 'customer/lists/type' );
314
			$typeItem = $typeManager->findItem( $values['customer.lists.type'], [], $values['customer.lists.domain'] );
315
			$values['customer.lists.typeid'] = $typeItem->getId();
316
		}
317
318
		$item = $manager->createItem();
319
		$item->fromArray( $values );
320
		$item->setId( null );
321
		$item->setParentId( $context->getUserId() );
322
323
		return $manager->saveItem( $item );
324
	}
325
326
327
	/**
328
	 * Returns a new customer lists filter criteria object
329
	 *
330
	 * @return \Aimeos\MW\Criteria\Iface New filter object
331
	 * @since 2017.06
332
	 */
333
	public function createListsFilter()
334
	{
335
		$context = $this->getContext();
336
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer/lists' );
337
338
		$filter = $manager->createSearch();
339
		$filter->setConditions( $filter->compare( '==', 'customer.lists.parentid', $context->getUserId() ) );
340
341
		return $filter;
342
	}
343
344
345
	/**
346
	 * Deletes a customer item that belongs to the current authenticated user
347
	 *
348
	 * @param string $id Unique customer address ID
349
	 * @since 2017.06
350
	 */
351
	public function deleteListItem( $id )
352
	{
353
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/lists' );
354
355
		$this->checkUser( $manager->getItem( $id )->getParentId() );
356
357
		$manager->deleteItem( $id );
358
	}
359
360
361
	/**
362
	 * Saves a modified customer lists item object
363
	 *
364
	 * @param string $id Unique customer lists ID
365
	 * @param array $values Values added to the customer lists item like "customer.lists.refid"
366
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface Customer lists item
367
	 * @since 2017.06
368
	 */
369
	public function editListItem( $id, array $values )
370
	{
371
		$context = $this->getContext();
372
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer/lists' );
373
374
		$item = $manager->getItem( $id, [], true );
375
		$this->checkUser( $item->getParentId() );
376
377
		if( !isset( $values['customer.lists.typeid'] ) )
378
		{
379
			if( !isset( $values['customer.lists.type'] ) ) {
380
				throw new \Aimeos\Controller\Frontend\Customer\Exception( sprintf( 'No customer lists type code' ) );
381
			}
382
383
			if( !isset( $values['customer.lists.domain'] ) ) {
384
				throw new \Aimeos\Controller\Frontend\Customer\Exception( sprintf( 'No customer lists domain' ) );
385
			}
386
387
			$typeManager = \Aimeos\MShop\Factory::createManager( $context, 'customer/lists/type' );
388
			$typeItem = $typeManager->findItem( $values['customer.lists.type'], [], $values['customer.lists.domain'] );
389
			$values['customer.lists.typeid'] = $typeItem->getId();
390
		}
391
392
		unset( $values['customer.lists.id'] );
393
		$item->fromArray( $values );
394
395
		return $manager->saveItem( $item );
396
	}
397
398
399
	/**
400
	 * Returns the customer item for the given customer ID
401
	 *
402
	 * @param string $id Unique customer address ID
403
	 * @return \Aimeos\MShop\Customer\Item\Address\Iface Customer address item
404
	 * @since 2017.06
405
	 */
406
	public function getListItem( $id )
407
	{
408
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/lists' );
409
		$item = $manager->getItem( $id );
410
411
		$this->checkUser( $item->getParentId() );
412
413
		return $item;
414
	}
415
416
417
	/**
418
	 * Returns the customer lists items filtered by the given criteria
419
	 *
420
	 * @param \Aimeos\MW\Criteria\Iface $filter Criteria object which contains the filter conditions
421
	 * @param integer &$total Parameter where the total number of found attributes will be stored in
422
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface[] Customer list items
423
	 * @since 2017.06
424
	 */
425
	public function searchListItems( \Aimeos\MW\Criteria\Iface $filter, &$total = null )
426
	{
427
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'customer/lists' );
428
429
		return $manager->searchItems( $filter, [], $total );
430
	}
431
432
433
	/**
434
	 * Adds the default values for customer items if not yet available
435
	 *
436
	 * @param string[] $values Associative list of customer keys (e.g. "customer.label") and their values
437
	 * @return string[] Associative list of customer key/value pairs with default values set
438
	 */
439
	protected function addItemDefaults( array $values )
440
	{
441
		if( !isset( $values['customer.label'] ) || $values['customer.label'] == '' )
442
		{
443
			$label = '';
444
445
			if( isset( $values['customer.lastname'] ) ) {
446
				$label = $values['customer.lastname'];
447
			}
448
449
			if( isset( $values['customer.firstname'] ) && $values['customer.firstname'] != '' ) {
450
				$label = $values['customer.firstname'] . ' ' . $label;
451
			}
452
453
			if( isset( $values['customer.company'] ) && $values['customer.company'] != '' ) {
454
				$label .= ' (' . $values['customer.company'] . ')';
455
			}
456
457
			$values['customer.label'] = $label;
458
		}
459
460
		if( !isset( $values['customer.code'] ) ) {
461
			$values['customer.code'] = $values['customer.email'];
462
		}
463
464
		if( !isset( $values['customer.status'] ) ) {
465
			$values['customer.status'] = 1;
466
		}
467
468
		if( !isset( $values['customer.password'] ) ) {
469
			$values['customer.password'] = substr( md5( microtime( true ) . getmypid() . rand() ), -8 );
470
		}
471
472
		return $values;
473
	}
474
475
476
	/**
477
	 * Checks if the current user is allowed to create more customer accounts
478
	 *
479
	 * @param string[] $values Associative list of customer keys (e.g. "customer.label") and their values
480
	 * @throws \Aimeos\Controller\Frontend\Customer\Exception If access isn't allowed
481
	 */
482
	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...
483
	{
484
		$total = 0;
485
		$context = $this->getContext();
486
		$config = $context->getConfig();
487
488
		/** controller/frontend/customer/limit-count
489
		 * Maximum number of customers within the time frame
490
		 *
491
		 * Creating new customers is limited to avoid abuse and mitigate denial of
492
		 * service attacks. The number of customer accountss created within the
493
		 * time frame configured by "controller/frontend/customer/limit-seconds"
494
		 * are counted before a new customer account (identified by the IP address)
495
		 * is created. If the number of accounts is higher than the configured value,
496
		 * an error message will be shown to the user instead of creating a new account.
497
		 *
498
		 * @param integer Number of customer accounts allowed within the time frame
499
		 * @since 2017.07
500
		 * @category Developer
501
		 * @see controller/frontend/customer/limit-seconds
502
		 */
503
		$count = $config->get( 'controller/frontend/customer/limit-count', 5 );
504
505
		/** controller/frontend/customer/limit-seconds
506
		 * Customer account limitation time frame in seconds
507
		 *
508
		 * Creating new customer accounts is limited to avoid abuse and mitigate
509
		 * denial of service attacks. Within the configured time frame, only a
510
		 * limited number of customer accounts can be created. All accounts from
511
		 * the same source (identified by the IP address) within the last X
512
		 * seconds are counted. If the total value is higher then the number
513
		 * configured in "controller/frontend/customer/limit-count", an error
514
		 * message will be shown to the user instead of creating a new account.
515
		 *
516
		 * @param integer Number of seconds to check customer accounts within
517
		 * @since 2017.07
518
		 * @category Developer
519
		 * @see controller/frontend/customer/limit-count
520
		 */
521
		$seconds = $config->get( 'controller/frontend/customer/limit-seconds', 300 );
522
523
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'customer' );
524
525
		$search = $manager->createSearch();
526
		$expr = [
527
			$search->compare( '==', 'customer.editor', $context->getEditor() ),
528
			$search->compare( '>=', 'customer.ctime', date( 'Y-m-d H:i:s', time() - $seconds ) ),
529
		];
530
		$search->setConditions( $search->combine( '&&', $expr ) );
531
		$search->setSlice( 0, 0 );
532
533
		$manager->searchItems( $search, [], $total );
534
535
		if( $total > $count ) {
536
			throw new \Aimeos\Controller\Frontend\Basket\Exception( sprintf( 'Temporary limit reached' ) );
537
		}
538
	}
539
540
541
	/**
542
	 * Checks if the current user is allowed to retrieve the customer data for the given ID
543
	 *
544
	 * @param string $id Unique customer ID
545
	 * @throws \Aimeos\Controller\Frontend\Customer\Exception If access isn't allowed
546
	 */
547
	protected function checkUser( $id )
548
	{
549
		if( $id != $this->getContext()->getUserId() )
550
		{
551
			$msg = sprintf( 'Not allowed to access customer data for ID "%1$s"', $id );
552
			throw new \Aimeos\Controller\Frontend\Customer\Exception( $msg );
553
		}
554
	}
555
}
556