Passed
Branch master (4f99e3)
by Aimeos
04:48
created

Standard::addData()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 59
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 28
nc 16
nop 3
dl 0
loc 59
rs 9.1608
c 0
b 0
f 0

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 Metaways Infosystems GmbH, 2014
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package Client
8
 * @subpackage Html
9
 */
10
11
12
namespace Aimeos\Client\Html\Account\Watch;
13
14
15
/**
16
 * Default implementation of account watch HTML client.
17
 *
18
 * @package Client
19
 * @subpackage Html
20
 */
21
class Standard
22
	extends \Aimeos\Client\Html\Common\Client\Factory\Base
23
	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
24
{
25
	/** client/html/account/watch/standard/subparts
26
	 * List of HTML sub-clients rendered within the account watch section
27
	 *
28
	 * The output of the frontend is composed of the code generated by the HTML
29
	 * clients. Each HTML client can consist of serveral (or none) sub-clients
30
	 * that are responsible for rendering certain sub-parts of the output. The
31
	 * sub-clients can contain HTML clients themselves and therefore a
32
	 * hierarchical tree of HTML clients is composed. Each HTML client creates
33
	 * the output that is placed inside the container of its parent.
34
	 *
35
	 * At first, always the HTML code generated by the parent is printed, then
36
	 * the HTML code of its sub-clients. The order of the HTML sub-clients
37
	 * determines the order of the output of these sub-clients inside the parent
38
	 * container. If the configured list of clients is
39
	 *
40
	 *  array( "subclient1", "subclient2" )
41
	 *
42
	 * you can easily change the order of the output by reordering the subparts:
43
	 *
44
	 *  client/html/<clients>/subparts = array( "subclient1", "subclient2" )
45
	 *
46
	 * You can also remove one or more parts if they shouldn't be rendered:
47
	 *
48
	 *  client/html/<clients>/subparts = array( "subclient1" )
49
	 *
50
	 * As the clients only generates structural HTML, the layout defined via CSS
51
	 * should support adding, removing or reordering content by a fluid like
52
	 * design.
53
	 *
54
	 * @param array List of sub-client names
55
	 * @since 2014.03
56
	 * @category Developer
57
	 */
58
	private $subPartPath = 'client/html/account/watch/standard/subparts';
59
	private $subPartNames = [];
60
	private $view;
61
62
63
	/**
64
	 * Returns the HTML code for insertion into the body.
65
	 *
66
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
	 * @return string HTML code
68
	 */
69
	public function getBody( $uid = '' )
70
	{
71
		$context = $this->getContext();
72
		$view = $this->getView();
73
74
		try
75
		{
76
			if( !isset( $this->view ) ) {
77
				$view = $this->view = $this->getObject()->addData( $view );
78
			}
79
80
			$html = '';
81
			foreach( $this->getSubClients() as $subclient ) {
82
				$html .= $subclient->setView( $view )->getBody( $uid );
83
			}
84
			$view->watchBody = $html;
85
		}
86
		catch( \Aimeos\Client\Html\Exception $e )
87
		{
88
			$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
89
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
90
		}
91
		catch( \Aimeos\Controller\Frontend\Exception $e )
92
		{
93
			$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
94
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
95
		}
96
		catch( \Aimeos\MShop\Exception $e )
97
		{
98
			$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
99
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
100
		}
101
		catch( \Exception $e )
102
		{
103
			$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
104
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
105
			$this->logException( $e );
106
		}
107
108
		/** client/html/account/watch/standard/template-body
109
		 * Relative path to the HTML body template of the account watch client.
110
		 *
111
		 * The template file contains the HTML code and processing instructions
112
		 * to generate the result shown in the body of the frontend. The
113
		 * configuration string is the path to the template file relative
114
		 * to the templates directory (usually in client/html/templates).
115
		 *
116
		 * You can overwrite the template file configuration in extensions and
117
		 * provide alternative templates. These alternative templates should be
118
		 * named like the default one but with the string "standard" replaced by
119
		 * an unique name. You may use the name of your project for this. If
120
		 * you've implemented an alternative client class as well, "standard"
121
		 * should be replaced by the name of the new class.
122
		 *
123
		 * @param string Relative path to the template creating code for the HTML page body
124
		 * @since 2014.03
125
		 * @category Developer
126
		 * @see client/html/account/watch/standard/template-header
127
		 */
128
		$tplconf = 'client/html/account/watch/standard/template-body';
129
		$default = 'account/watch/body-standard';
130
131
		return $view->render( $view->config( $tplconf, $default ) );
132
	}
133
134
135
	/**
136
	 * Returns the HTML string for insertion into the header.
137
	 *
138
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
139
	 * @return string|null String including HTML tags for the header on error
140
	 */
141
	public function getHeader( $uid = '' )
142
	{
143
		$view = $this->getView();
144
145
		try
146
		{
147
			if( !isset( $this->view ) ) {
148
				$view = $this->view = $this->getObject()->addData( $view );
149
			}
150
151
			$html = '';
152
			foreach( $this->getSubClients() as $subclient ) {
153
				$html .= $subclient->setView( $view )->getHeader( $uid );
154
			}
155
			$view->watchHeader = $html;
156
157
			/** client/html/account/watch/standard/template-header
158
			 * Relative path to the HTML header template of the account watch client.
159
			 *
160
			 * The template file contains the HTML code and processing instructions
161
			 * to generate the HTML code that is inserted into the HTML page header
162
			 * of the rendered page in the frontend. The configuration string is the
163
			 * path to the template file relative to the templates directory (usually
164
			 * in client/html/templates).
165
			 *
166
			 * You can overwrite the template file configuration in extensions and
167
			 * provide alternative templates. These alternative templates should be
168
			 * named like the default one but with the string "standard" replaced by
169
			 * an unique name. You may use the name of your project for this. If
170
			 * you've implemented an alternative client class as well, "standard"
171
			 * should be replaced by the name of the new class.
172
			 *
173
			 * @param string Relative path to the template creating code for the HTML page head
174
			 * @since 2014.03
175
			 * @category Developer
176
			 * @see client/html/account/watch/standard/template-body
177
			 */
178
			$tplconf = 'client/html/account/watch/standard/template-header';
179
			$default = 'account/watch/header-standard';
180
181
			return $view->render( $view->config( $tplconf, $default ) );
182
		}
183
		catch( \Exception $e )
184
		{
185
			$this->logException( $e );
186
		}
187
	}
188
189
190
	/**
191
	 * Returns the sub-client given by its name.
192
	 *
193
	 * @param string $type Name of the client type
194
	 * @param string|null $name Name of the sub-client (Default if null)
195
	 * @return \Aimeos\Client\Html\Iface Sub-client object
196
	 */
197
	public function getSubClient( $type, $name = null )
198
	{
199
		/** client/html/account/watch/decorators/excludes
200
		 * Excludes decorators added by the "common" option from the account watch html client
201
		 *
202
		 * Decorators extend the functionality of a class by adding new aspects
203
		 * (e.g. log what is currently done), executing the methods of the underlying
204
		 * class only in certain conditions (e.g. only for logged in users) or
205
		 * modify what is returned to the caller.
206
		 *
207
		 * This option allows you to remove a decorator added via
208
		 * "client/html/common/decorators/default" before they are wrapped
209
		 * around the html client.
210
		 *
211
		 *  client/html/account/watch/decorators/excludes = array( 'decorator1' )
212
		 *
213
		 * This would remove the decorator named "decorator1" from the list of
214
		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
215
		 * "client/html/common/decorators/default" to the html client.
216
		 *
217
		 * @param array List of decorator names
218
		 * @since 2014.05
219
		 * @category Developer
220
		 * @see client/html/common/decorators/default
221
		 * @see client/html/account/watch/decorators/global
222
		 * @see client/html/account/watch/decorators/local
223
		 */
224
225
		/** client/html/account/watch/decorators/global
226
		 * Adds a list of globally available decorators only to the account watch html client
227
		 *
228
		 * Decorators extend the functionality of a class by adding new aspects
229
		 * (e.g. log what is currently done), executing the methods of the underlying
230
		 * class only in certain conditions (e.g. only for logged in users) or
231
		 * modify what is returned to the caller.
232
		 *
233
		 * This option allows you to wrap global decorators
234
		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
235
		 *
236
		 *  client/html/account/watch/decorators/global = array( 'decorator1' )
237
		 *
238
		 * This would add the decorator named "decorator1" defined by
239
		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
240
		 *
241
		 * @param array List of decorator names
242
		 * @since 2014.05
243
		 * @category Developer
244
		 * @see client/html/common/decorators/default
245
		 * @see client/html/account/watch/decorators/excludes
246
		 * @see client/html/account/watch/decorators/local
247
		 */
248
249
		/** client/html/account/watch/decorators/local
250
		 * Adds a list of local decorators only to the account watch html client
251
		 *
252
		 * Decorators extend the functionality of a class by adding new aspects
253
		 * (e.g. log what is currently done), executing the methods of the underlying
254
		 * class only in certain conditions (e.g. only for logged in users) or
255
		 * modify what is returned to the caller.
256
		 *
257
		 * This option allows you to wrap local decorators
258
		 * ("\Aimeos\Client\Html\Account\Decorator\*") around the html client.
259
		 *
260
		 *  client/html/account/watch/decorators/local = array( 'decorator2' )
261
		 *
262
		 * This would add the decorator named "decorator2" defined by
263
		 * "\Aimeos\Client\Html\Account\Decorator\Decorator2" only to the html client.
264
		 *
265
		 * @param array List of decorator names
266
		 * @since 2014.05
267
		 * @category Developer
268
		 * @see client/html/common/decorators/default
269
		 * @see client/html/account/watch/decorators/excludes
270
		 * @see client/html/account/watch/decorators/global
271
		 */
272
273
		return $this->createSubClient( 'account/watch/' . $type, $name );
274
	}
275
276
277
	/**
278
	 * Processes the input, e.g. store given values.
279
	 * A view must be available and this method doesn't generate any output
280
	 * besides setting view variables.
281
	 */
282
	public function process()
283
	{
284
		$view = $this->getView();
285
		$context = $this->getContext();
286
287
288
		try
289
		{
290
			$userId = $context->getUserId();
291
			$ids = (array) $view->param( 'wat_id', [] );
292
293
			if( $userId != null && !empty( $ids ) )
294
			{
295
				$manager = \Aimeos\MShop::create( $context, 'customer/lists' );
296
				$items = $this->getListItems( $manager, $ids, 'watch', $userId );
297
298
				switch( $view->param( 'wat_action' ) )
299
				{
300
					case 'add':
301
302
						/** client/html/account/watch/standard/maxitems
303
						 * Maximum number of products that can be watched in parallel
304
						 *
305
						 * This option limits the number of products that can be watched
306
						 * after the users added the products to their watch list.
307
						 * It must be a positive integer value greater than 0.
308
						 *
309
						 * Note: It's recommended to set this value not too high as this
310
						 * leads to a high memory consumption when the e-mails are generated
311
						 * to notify the customers. The memory used will up to 100*maxitems
312
						 * of the footprint of one product item including the associated
313
						 * texts, prices and media.
314
						 *
315
						 * @param integer Number of products
316
						 * @since 2014.09
317
						 * @category User
318
						 * @category Developer
319
						 */
320
						$max = $context->getConfig()->get( 'client/html/account/watch/standard/maxitems', 100 );
321
						$cnt = count( $ids );
322
323
						if( $this->checkLimit( $manager, 'watch', $userId, $max, $cnt ) === false )
324
						{
325
							$error = sprintf( $context->getI18n()->dt( 'client', 'You can only watch up to %1$s products' ), $max );
326
							$view->watchErrorList = $view->get( 'watchErrorList', [] ) + array( $error );
327
							break;
328
						}
329
330
						$this->addItems( $manager, $items, $ids, 'watch', $userId );
331
						break;
332
333
					case 'edit':
334
335
						$config = array(
336
							'timeframe' => $view->param( 'wat_timeframe', 7 ),
337
							'pricevalue' => $view->param( 'wat_pricevalue', '0.00' ),
338
							'price' => $view->param( 'wat_price', 0 ),
339
							'stock' => $view->param( 'wat_stock', 0 ),
340
							'currency' => $context->getLocale()->getCurrencyId(),
341
						);
342
						$this->editItems( $manager, $items, $ids, $config );
343
						break;
344
345
					case 'delete':
346
347
						$this->deleteItems( $manager, $items, $ids );
348
						break;
349
				}
350
			}
351
352
			parent::process();
353
		}
354
		catch( \Aimeos\MShop\Exception $e )
355
		{
356
			$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
357
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
358
		}
359
		catch( \Aimeos\Controller\Frontend\Exception $e )
360
		{
361
			$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
362
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
363
		}
364
		catch( \Aimeos\Client\Html\Exception $e )
365
		{
366
			$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
367
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
368
		}
369
		catch( \Exception $e )
370
		{
371
			$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
372
			$view->watchErrorList = $view->get( 'watchErrorList', [] ) + $error;
373
			$this->logException( $e );
374
		}
375
	}
376
377
378
	/**
379
	 * Tests if the maximum number of entries per user is already reached
380
	 *
381
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Customer list manager
382
	 * @param string $type List type of the referenced items
383
	 * @param string $userId Unique user ID
384
	 * @param integer $max Maximum number of items that are allowed
385
	 * @param integer $cnt Number of items that should be added
386
	 * @return boolean True if items can be added, false if not
387
	 */
388
	protected function checkLimit( \Aimeos\MShop\Common\Manager\Iface $manager, $type, $userId, $max, $cnt )
389
	{
390
		$search = $manager->createSearch();
391
		$expr = array(
392
			$search->compare( '==', 'customer.lists.parentid', $userId ),
393
			$search->compare( '==', 'customer.lists.domain', 'product' ),
394
			$search->compare( '==', 'customer.lists.type', $type ),
395
		);
396
		$search->setConditions( $search->combine( '&&', $expr ) );
397
		$search->setSlice( 0, 0 );
398
399
		$total = 0;
400
		$manager->searchItems( $search, [], $total );
401
402
		if( $total + $cnt > $max ) {
403
			return false;
404
		}
405
406
		return true;
407
	}
408
409
410
	/**
411
	 * Adds one or more list items to the given user
412
	 *
413
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Customer list manager
414
	 * @param array $listItems Associative list of the reference IDs as keys and the list items as values
415
	 * @param array $ids List of referenced IDs
416
	 * @param string $type List type of the referenced items
417
	 * @param string $userId Unique user ID
418
	 */
419
	protected function addItems( \Aimeos\MShop\Common\Manager\Iface $manager, array $listItems, array $ids, $type, $userId )
420
	{
421
		$item = $manager->createItem();
422
		$item->setParentId( $userId );
0 ignored issues
show
Bug introduced by
The method setParentId() does not exist on Aimeos\MShop\Attribute\Item\Iface. ( Ignorable by Annotation )

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

422
		$item->/** @scrutinizer ignore-call */ 
423
         setParentId( $userId );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
423
		$item->setDomain( 'product' );
424
		$item->setType( $type );
425
		$item->setStatus( 1 );
426
427
		foreach( $ids as $id )
428
		{
429
			if( !isset( $listItems[$id] ) )
430
			{
431
				$item->setId( null );
432
				$item->setRefId( $id );
0 ignored issues
show
Bug introduced by
The method setRefId() does not exist on Aimeos\MShop\Attribute\Item\Iface. Did you maybe mean setId()? ( Ignorable by Annotation )

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

432
				$item->/** @scrutinizer ignore-call */ 
433
           setRefId( $id );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
433
434
				$item = $manager->saveItem( $item );
435
				$manager->moveItem( $item->getId() );
1 ignored issue
show
Bug introduced by
The method moveItem() does not exist on Aimeos\MShop\Common\Manager\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\MShop\Common\Manager\Decorator\Iface or Aimeos\MShop\Service\Manager\Lists\Type\Iface or Aimeos\MShop\Price\Manager\Iface or Aimeos\MShop\Attribute\Manager\Type\Iface or Aimeos\MShop\Price\Manager\Lists\Type\Iface or Aimeos\MShop\Media\Manager\Type\Iface or Aimeos\MShop\Coupon\Manager\Code\Iface or Aimeos\MShop\Order\Manager\Base\Coupon\Iface or Aimeos\MShop\Product\Manager\Iface or Aimeos\MShop\Supplier\Manager\Iface or Aimeos\MShop\Common\Manager\Property\Iface or Aimeos\MShop\Customer\Manager\Property\Iface or Aimeos\MShop\Order\Manager\Base\Service\Iface or Aimeos\MShop\Order\Manager\Base\Iface or Aimeos\MShop\Price\Manager\Lists\Iface or Aimeos\MShop\Supplier\Manager\Lists\Type\Iface or Aimeos\MShop\Order\Manag...Service\Attribute\Iface or Aimeos\MShop\Service\Manager\Lists\Iface or Aimeos\MShop\Tag\Manager\Type\Iface or Aimeos\MShop\Text\Manager\Lists\Iface or Aimeos\MShop\Price\Manager\Type\Iface or Aimeos\MShop\Locale\Manager\Currency\Iface or Aimeos\MShop\Order\Manag...Product\Attribute\Iface or Aimeos\MShop\Media\Manager\Lists\Type\Iface or Aimeos\MShop\Catalog\Manager\Lists\Iface or Aimeos\MShop\Tag\Manager\Iface or Aimeos\MShop\Coupon\Manager\Iface or Aimeos\MShop\Attribute\Manager\Iface or Aimeos\MShop\Attribute\Manager\Property\Type\Iface or Aimeos\MShop\Service\Manager\Type\Iface or Aimeos\MShop\Product\Manager\Lists\Iface or Aimeos\MShop\Customer\Manager\Property\Type\Iface or Aimeos\MShop\Order\Manager\Iface or Aimeos\MShop\Customer\Manager\Iface or Aimeos\MShop\Media\Manager\Iface or Aimeos\MShop\Customer\Manager\Lists\Type\Iface or Aimeos\MShop\Attribute\Manager\Lists\Iface or Aimeos\MShop\Product\Manager\Property\Type\Iface or Aimeos\MShop\Media\Manager\Lists\Iface or Aimeos\MShop\Plugin\Manager\Iface or Aimeos\MShop\Order\Manager\Base\Address\Iface or Aimeos\MShop\Product\Manager\Type\Iface or Aimeos\MShop\Supplier\Manager\Lists\Iface or Aimeos\MShop\Stock\Manager\Type\Iface or Aimeos\MShop\Text\Manager\Iface or Aimeos\MShop\Common\Manager\Type\Iface or Aimeos\MAdmin\Job\Manager\Iface or Aimeos\MShop\Customer\Manager\Group\Iface or Aimeos\MShop\Product\Manager\Lists\Type\Iface or Aimeos\MShop\Text\Manager\Lists\Type\Iface or Aimeos\MShop\Text\Manager\Type\Iface or Aimeos\MShop\Order\Manager\Status\Iface or Aimeos\MShop\Common\Manager\Address\Iface or Aimeos\MShop\Plugin\Manager\Type\Iface or Aimeos\MShop\Stock\Manager\Iface or Aimeos\MShop\Attribute\Manager\Property\Iface or Aimeos\MShop\Subscription\Manager\Iface or Aimeos\MShop\Media\Manager\Property\Type\Iface or Aimeos\MShop\Product\Manager\Property\Iface or Aimeos\MShop\Locale\Manager\Language\Iface or Aimeos\MShop\Media\Manager\Property\Iface or Aimeos\MShop\Service\Manager\Iface or Aimeos\MShop\Attribute\Manager\Lists\Type\Iface or Aimeos\MAdmin\Log\Manager\Iface or Aimeos\MShop\Locale\Manager\Iface or Aimeos\MAdmin\Cache\Manager\Iface or Aimeos\MShop\Order\Manager\Base\Product\Iface or Aimeos\MShop\Customer\Manager\Lists\Iface or Aimeos\MShop\Catalog\Manager\Lists\Type\Iface or Aimeos\MShop\Index\Manager\Iface or Aimeos\MShop\Index\Manager\Attribute\Iface or Aimeos\MShop\Index\Manager\Text\Iface or Aimeos\MShop\Index\Manager\Supplier\Iface or Aimeos\MShop\Index\Manager\Catalog\Iface or Aimeos\MShop\Index\Manager\Price\Iface or Aimeos\MShop\Supplier\Manager\Address\Iface or Aimeos\MShop\Customer\Manager\Address\Iface. Are you sure you never get one of those? ( Ignorable by Annotation )

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

435
				$manager->/** @scrutinizer ignore-call */ 
436
              moveItem( $item->getId() );
Loading history...
436
			}
437
		}
438
	}
439
440
441
	/**
442
	 * Removes the list items for the given reference IDs
443
	 *
444
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Customer list manager
445
	 * @param array $listItems Associative list of the reference IDs as keys and the list items as values
446
	 * @param array $ids List of referenced IDs
447
	 */
448
	protected function deleteItems( \Aimeos\MShop\Common\Manager\Iface $manager, array $listItems, array $ids )
449
	{
450
		$listIds = [];
451
452
		foreach( $ids as $id )
453
		{
454
			if( isset( $listItems[$id] ) ) {
455
				$listIds[] = $listItems[$id]->getId();
456
			}
457
		}
458
459
		$manager->deleteItems( $listIds );
460
	}
461
462
463
	/**
464
	 * Updates the list items for the given reference IDs
465
	 *
466
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Customer list manager
467
	 * @param array $listItems Associative list of the reference IDs as keys and the list items as values
468
	 * @param array $ids List of referenced IDs
469
	 * @param array $config Configuration settins with "timeframe", "pricevalue", "price", "stock" and "currency"
470
	 */
471
	protected function editItems( \Aimeos\MShop\Common\Manager\Iface $manager, array $listItems, array $ids, array $config )
472
	{
473
		foreach( $ids as $id )
474
		{
475
			if( isset( $listItems[$id] ) )
476
			{
477
				$item = $listItems[$id];
478
				$time = time() + ( $config['timeframe'] + 1 ) * 86400;
479
480
				$item->setDateEnd( date( 'Y-m-d 00:00:00', $time ) );
481
				$item->setConfig( $config );
482
483
				$manager->saveItem( $item );
484
			}
485
		}
486
	}
487
488
489
	/**
490
	 * Returns the list items associated to the given user ID
491
	 *
492
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Customer list manager
493
	 * @param array $refIds IDs of the referenced items
494
	 * @param string $type List type of the referenced items
495
	 * @param string $userId Unique user ID
496
	 * @return array Associative list of the reference IDs as keys and the list items as values
497
	 */
498
	protected function getListItems( \Aimeos\MShop\Common\Manager\Iface $manager, array $refIds, $type, $userId )
499
	{
500
		$search = $manager->createSearch();
501
		$expr = array(
502
			$search->compare( '==', 'customer.lists.parentid', $userId ),
503
			$search->compare( '==', 'customer.lists.refid', $refIds ),
504
			$search->compare( '==', 'customer.lists.domain', 'product' ),
505
			$search->compare( '==', 'customer.lists.type', $type ),
506
		);
507
		$search->setConditions( $search->combine( '&&', $expr ) );
508
509
		$items = [];
510
		foreach( $manager->searchItems( $search ) as $item ) {
511
			$items[$item->getRefId()] = $item;
0 ignored issues
show
Bug introduced by
The method getRefId() does not exist on Aimeos\MShop\Common\Item\Iface. Did you maybe mean getId()? ( Ignorable by Annotation )

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

511
			$items[$item->/** @scrutinizer ignore-call */ getRefId()] = $item;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
512
		}
513
514
		return $items;
515
	}
516
517
518
	/**
519
	 * Returns the list of sub-client names configured for the client.
520
	 *
521
	 * @return array List of HTML client names
522
	 */
523
	protected function getSubClientNames()
524
	{
525
		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
526
	}
527
528
529
	/**
530
	 * Returns the sanitized page from the parameters for the product list.
531
	 *
532
	 * @param \Aimeos\MW\View\Iface $view View instance with helper for retrieving the required parameters
533
	 * @return integer Page number starting from 1
534
	 */
535
	protected function getProductListPage( \Aimeos\MW\View\Iface $view )
536
	{
537
		$page = (int) $view->param( 'wat_page', 1 );
538
		return ( $page < 1 ? 1 : $page );
539
	}
540
541
542
	/**
543
	 * Returns the sanitized page size from the parameters for the product list.
544
	 *
545
	 * @param \Aimeos\MW\View\Iface $view View instance with helper for retrieving the required parameters
546
	 * @return integer Page size
547
	 */
548
	protected function getProductListSize( \Aimeos\MW\View\Iface $view )
549
	{
550
		/** client/html/account/watch/size
551
		 * The number of products shown in a list page for watch products
552
		 *
553
		 * Limits the number of products that is shown in the list pages to the
554
		 * given value. If more products are available, the products are split
555
		 * into bunches which will be shown on their own list page. The user is
556
		 * able to move to the next page (or previous one if it's not the first)
557
		 * to display the next (or previous) products.
558
		 *
559
		 * The value must be an integer number from 1 to 100. Negative values as
560
		 * well as values above 100 are not allowed. The value can be overwritten
561
		 * per request if the "l_size" parameter is part of the URL.
562
		 *
563
		 * @param integer Number of products
564
		 * @since 2014.09
565
		 * @category User
566
		 * @category Developer
567
		 * @see client/html/catalog/lists/size
568
		 */
569
		$defaultSize = $this->getContext()->getConfig()->get( 'client/html/account/watch/size', 48 );
570
571
		$size = (int) $view->param( 'watch-size', $defaultSize );
572
		return ( $size < 1 || $size > 100 ? $defaultSize : $size );
573
	}
574
575
576
	/**
577
	 * Sets the necessary parameter values in the view.
578
	 *
579
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
580
	 * @param array &$tags Result array for the list of tags that are associated to the output
581
	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
582
	 * @return \Aimeos\MW\View\Iface Modified view object
583
	 */
584
	public function addData( \Aimeos\MW\View\Iface $view, array &$tags = [], &$expire = null )
585
	{
586
		$total = 0;
587
		$productIds = [];
588
		$context = $this->getContext();
589
590
		$size = $this->getProductListSize( $view );
591
		$current = $this->getProductListPage( $view );
592
		$last = ( $total != 0 ? ceil( $total / $size ) : 1 );
0 ignored issues
show
introduced by
The condition $total != 0 is always false.
Loading history...
593
594
595
		$manager = \Aimeos\MShop::create( $context, 'customer/lists' );
596
597
		$search = $manager->createSearch();
598
		$expr = array(
599
			$search->compare( '==', 'customer.lists.parentid', $context->getUserId() ),
600
			$search->compare( '==', 'customer.lists.domain', 'product' ),
601
			$search->compare( '==', 'customer.lists.type', 'watch' ),
602
		);
603
		$search->setConditions( $search->combine( '&&', $expr ) );
604
		$search->setSortations( array( $search->sort( '-', 'customer.lists.position' ) ) );
605
		$search->setSlice( ( $current - 1 ) * $size, $size );
606
607
		$view->watchListItems = $manager->searchItems( $search, [], $total );
608
609
610
		/** client/html/account/watch/domains
611
		 * A list of domain names whose items should be available in the account watch view template
612
		 *
613
		 * The templates rendering product details usually add the images,
614
		 * prices and texts associated to the product item. If you want to
615
		 * display additional or less content, you can configure your own
616
		 * list of domains (attribute, media, price, product, text, etc. are
617
		 * domains) whose items are fetched from the storage. Please keep
618
		 * in mind that the more domains you add to the configuration, the
619
		 * more time is required for fetching the content!
620
		 *
621
		 * @param array List of domain names
622
		 * @since 2014.09
623
		 * @category Developer
624
		 * @see client/html/catalog/domains
625
		 */
626
		$default = array( 'text', 'price', 'media' );
627
		$domains = $context->getConfig()->get( 'client/html/account/watch/domains', $default );
628
629
		foreach( $view->watchListItems as $listItem ) {
630
			$productIds[] = $listItem->getRefId();
631
		}
632
633
		$cntl = \Aimeos\Controller\Frontend::create( $context, 'product' );
634
635
		$view->watchProductItems = $cntl->product( $productIds )->search( $domains );
1 ignored issue
show
Bug introduced by
The method product() does not exist on Aimeos\Controller\Frontend\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\Controller\Frontend\Common\Iface or Aimeos\Controller\Frontend\Common\Decorator\Iface or Aimeos\Controller\Fronte...ommon\Decorator\Example. Are you sure you never get one of those? ( Ignorable by Annotation )

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

635
		$view->watchProductItems = $cntl->/** @scrutinizer ignore-call */ product( $productIds )->search( $domains );
Loading history...
636
		$view->watchPageFirst = 1;
637
		$view->watchPagePrev = ( $current > 1 ? $current - 1 : 1 );
638
		$view->watchPageNext = ( $current < $last ? $current + 1 : $last );
639
		$view->watchPageLast = $last;
640
		$view->watchPageCurr = $current;
641
642
		return parent::addData( $view, $tags, $expire );
643
	}
644
}