Passed
Push — master ( c6e392...14ba76 )
by Aimeos
03:51
created

Standard::getSubClientNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2022
6
 * @package Client
7
 * @subpackage Html
8
 */
9
10
11
namespace Aimeos\Client\Html\Basket\Standard;
12
13
14
/**
15
 * Default implementation of standard basket HTML client.
16
 *
17
 * @package Client
18
 * @subpackage Html
19
 */
20
class Standard
21
	extends \Aimeos\Client\Html\Basket\Base
22
	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
23
{
24
	/**
25
	 * Sets the necessary parameter values in the view.
26
	 *
27
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
28
	 * @param array &$tags Result array for the list of tags that are associated to the output
29
	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
30
	 * @return \Aimeos\MW\View\Iface Modified view object
31
	 */
32
	public function data( \Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : \Aimeos\MW\View\Iface
33
	{
34
		$context = $this->context();
35
		$site = $context->locale()->getSiteItem()->getCode();
36
37
		if( !empty( $params = $context->session()->get( 'aimeos/catalog/detail/params/last/' . $site ) ) ){
0 ignored issues
show
Unused Code introduced by
The assignment to $params is dead and can be removed.
Loading history...
38
			$view->standardBackUrl = $view->link( 'client/html/catalog/detail/url' );
39
		} elseif( !empty( $params = $context->session()->get( 'aimeos/catalog/lists/params/last/' . $site, [] ) ) ) {
40
			$view->standardBackUrl = $view->link( 'client/html/catalog/lists/url' );
41
		}
42
43
		$basket = \Aimeos\Controller\Frontend::create( $this->context(), 'basket' )->get();
44
45
		$view->standardBasket = $basket;
46
		$view->standardTaxRates = $this->getTaxRates( $basket );
47
		$view->standardNamedTaxes = $this->getNamedTaxes( $basket );
48
		$view->standardCostsDelivery = $this->getCostsDelivery( $basket );
49
		$view->standardCostsPayment = $this->getCostsPayment( $basket );
50
51
		return parent::data( $view, $tags, $expire );
52
	}
53
54
55
	/**
56
	 * Sets the necessary parameter values in the view.
57
	 *
58
	 * A view must be available and this method doesn't generate any output
59
	 * besides setting view variables if necessary.
60
	 */
61
	public function init()
62
	{
63
		$view = $this->view();
64
		$context = $this->context();
65
		$controller = \Aimeos\Controller\Frontend::create( $context, 'basket' );
66
67
		try
68
		{
69
			switch( $view->param( 'b_action' ) )
70
			{
71
				case 'add':
72
					$this->addProducts( $view );
73
					break;
74
				case 'coupon-delete':
75
					$this->deleteCoupon( $view );
76
					break;
77
				case 'delete':
78
					$this->deleteProducts( $view );
79
					break;
80
				default:
81
					$this->updateProducts( $view );
82
					$this->addCoupon( $view );
83
			}
84
85
			/** client/html/basket/standard/check
86
			 * Alters the behavior of the product checks before continuing with the checkout
87
			 *
88
			 * By default, the product related checks are performed every time the basket
89
			 * is shown. They test if there are any products in the basket and execute all
90
			 * basket plugins that have been registered for the "check.before" and "check.after"
91
			 * events.
92
			 *
93
			 * Using this configuration setting, you can either disable all checks completely
94
			 * (0) or display a "Check" button instead of the "Checkout" button (2). In the
95
			 * later case, customers have to click on the "Check" button first to perform
96
			 * the checks and if everything is OK, the "Checkout" button will be displayed
97
			 * that allows the customers to continue the checkout process. If one of the
98
			 * checks fails, the customers have to fix the related basket item and must click
99
			 * on the "Check" button again before they can continue.
100
			 *
101
			 * Available values are:
102
			 *  0 = no product related checks
103
			 *  1 = checks are performed every time when the basket is displayed
104
			 *  2 = checks are performed only when clicking on the "check" button
105
			 *
106
			 * @param integer One of the allowed values (0, 1 or 2)
107
			 * @since 2016.08
108
			 * @category Developer
109
			 * @category User
110
			 */
111
			$check = (int) $view->config( 'client/html/basket/standard/check', 1 );
112
113
			switch( $check )
114
			{
115
				case 2: if( $view->param( 'b_check', 0 ) == 0 ) { break; }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
116
				case 1: $controller->get()->check( ['order/base/product'] );
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
117
				default: $view->standardCheckout = true;
118
			}
119
		}
120
		catch( \Exception $e )
121
		{
122
			$controller->save();
123
			throw $e;
124
		}
125
126
		$controller->save();
127
	}
128
129
130
	/**
131
	 * Adds the coupon specified by the view parameters from the basket.
132
	 *
133
	 * @param \Aimeos\MW\View\Iface $view View object
134
	 */
135
	protected function addCoupon( \Aimeos\MW\View\Iface $view )
136
	{
137
		if( ( $coupon = $view->param( 'b_coupon' ) ) != '' )
138
		{
139
			$context = $this->context();
140
			$cntl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
141
			$code = $cntl->get()->getCoupons()->keys()->first();
142
143
			/** client/html/basket/standard/coupon/overwrite
144
			 * Replace previous coupon codes each time the user enters a new one
145
			 *
146
			 * If you want to allow only one coupon code per order and replace a
147
			 * previously entered one automatically, this configuration option
148
			 * should be set to true.
149
			 *
150
			 * @param boolean True to overwrite a previous coupon, false to keep them
151
			 * @since 2020.04
152
			 * @category Developer
153
			 * @category User
154
			 */
155
			if( $code && $context->config()->get( 'client/html/basket/standard/coupon/overwrite', false ) ) {
156
				$cntl->deleteCoupon( $code );
157
			}
158
159
			$cntl->addCoupon( $coupon );
160
			$this->clearCached();
161
		}
162
	}
163
164
165
	/**
166
	 * Adds the products specified by the view parameters to the basket.
167
	 *
168
	 * @param \Aimeos\MW\View\Iface $view View object
169
	 */
170
	protected function addProducts( \Aimeos\MW\View\Iface $view )
171
	{
172
		$context = $this->context();
173
		$domains = ['attribute', 'catalog', 'media', 'price', 'product', 'text'];
174
175
		$basketCntl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
176
		$productCntl = \Aimeos\Controller\Frontend::create( $context, 'product' )->uses( $domains );
177
178
		if( ( $prodid = $view->param( 'b_prodid', '' ) ) !== '' && $view->param( 'b_quantity', 0 ) > 0 )
179
		{
180
			$basketCntl->addProduct(
181
				$productCntl->get( $prodid ),
182
				(float) $view->param( 'b_quantity', 0 ),
183
				(array) $view->param( 'b_attrvarid', [] ),
184
				$this->getAttributeMap( $view->param( 'b_attrconfid', [] ) ),
185
				array_filter( (array) $view->param( 'b_attrcustid', [] ) ),
186
				(string) $view->param( 'b_stocktype', 'default' ),
187
				(string) $view->param( 'b_supplier', '' ),
188
				$view->param( 'b_siteid' )
189
			);
190
		}
191
		else
192
		{
193
			foreach( (array) $view->param( 'b_prod', [] ) as $values )
194
			{
195
				if( ( $values['prodid'] ?? null ) && ( $values['quantity'] ?? 0 ) > 0 )
196
				{
197
					$basketCntl->addProduct( $productCntl->get( $values['prodid'] ),
198
						(float) ( $values['quantity'] ?? 0 ),
199
						array_filter( (array) ( $values['attrvarid'] ?? [] ) ),
200
						$this->getAttributeMap( (array) ( $values['attrconfid'] ?? [] ) ),
201
						array_filter( (array) ( $values['attrcustid'] ?? [] ) ),
202
						(string) ( $values['stocktype'] ?? 'default' ),
203
						(string) ( $values['supplier'] ?? '' ),
204
						$values['siteid'] ?? null
205
					);
206
				}
207
			}
208
		}
209
210
		$this->clearCached();
211
	}
212
213
214
	/**
215
	 * Removes the coupon specified by the view parameters from the basket.
216
	 *
217
	 * @param \Aimeos\MW\View\Iface $view View object
218
	 */
219
	protected function deleteCoupon( \Aimeos\MW\View\Iface $view )
220
	{
221
		if( ( $coupon = $view->param( 'b_coupon' ) ) != '' )
222
		{
223
			\Aimeos\Controller\Frontend::create( $this->context(), 'basket' )->deleteCoupon( $coupon );
224
			$this->clearCached();
225
		}
226
	}
227
228
229
	/**
230
	 * Removes the products specified by the view parameters from the basket.
231
	 *
232
	 * @param \Aimeos\MW\View\Iface $view View object
233
	 */
234
	protected function deleteProducts( \Aimeos\MW\View\Iface $view )
235
	{
236
		$controller = \Aimeos\Controller\Frontend::create( $this->context(), 'basket' );
237
		$products = (array) $view->param( 'b_position', [] );
238
239
		foreach( $products as $position ) {
240
			$controller->deleteProduct( $position );
241
		}
242
243
		$this->clearCached();
244
	}
245
246
247
	protected function getAttributeMap( array $values )
248
	{
249
		$list = [];
250
		$confIds = ( isset( $values['id'] ) ? array_filter( (array) $values['id'] ) : [] );
251
		$confQty = ( isset( $values['qty'] ) ? array_filter( (array) $values['qty'] ) : [] );
252
253
		foreach( $confIds as $idx => $id )
254
		{
255
			if( isset( $confQty[$idx] ) && $confQty[$idx] > 0 ) {
256
				$list[$id] = $confQty[$idx];
257
			}
258
		}
259
260
		return $list;
261
	}
262
263
264
	/**
265
	 * Edits the products specified by the view parameters to the basket.
266
	 *
267
	 * @param \Aimeos\MW\View\Iface $view View object
268
	 */
269
	protected function updateProducts( \Aimeos\MW\View\Iface $view )
270
	{
271
		$controller = \Aimeos\Controller\Frontend::create( $this->context(), 'basket' );
272
		$products = (array) $view->param( 'b_prod', [] );
273
274
		if( ( $position = $view->param( 'b_position', '' ) ) !== '' )
275
		{
276
			$products[] = array(
277
				'position' => $position,
278
				'quantity' => $view->param( 'b_quantity', 1 )
279
			);
280
		}
281
282
		foreach( $products as $values )
283
		{
284
			$controller->updateProduct(
285
				( isset( $values['position'] ) ? (int) $values['position'] : 0 ),
286
				( isset( $values['quantity'] ) ? (float) $values['quantity'] : 1 )
287
			);
288
		}
289
290
		$this->clearCached();
291
	}
292
293
	/** client/html/basket/template-body
294
	 * Relative path to the HTML body template of the basket standard client.
295
	 *
296
	 * The template file contains the HTML code and processing instructions
297
	 * to generate the result shown in the body of the frontend. The
298
	 * configuration string is the path to the template file relative
299
	 * to the templates directory (usually in client/html/templates).
300
	 *
301
	 * You can overwrite the template file configuration in extensions and
302
	 * provide alternative templates. These alternative templates should be
303
	 * named like the default one but suffixed by
304
	 * an unique name. You may use the name of your project for this. If
305
	 * you've implemented an alternative client class as well, it
306
	 * should be suffixed by the name of the new class.
307
	 *
308
	 * @param string Relative path to the template creating code for the HTML page body
309
	 * @since 2014.03
310
	 * @category Developer
311
	 * @see client/html/basket/template-header
312
	 */
313
314
	/** client/html/basket/template-header
315
	 * Relative path to the HTML header template of the basket standard client.
316
	 *
317
	 * The template file contains the HTML code and processing instructions
318
	 * to generate the HTML code that is inserted into the HTML page header
319
	 * of the rendered page in the frontend. The configuration string is the
320
	 * path to the template file relative to the templates directory (usually
321
	 * in client/html/templates).
322
	 *
323
	 * You can overwrite the template file configuration in extensions and
324
	 * provide alternative templates. These alternative templates should be
325
	 * named like the default one but suffixed by
326
	 * an unique name. You may use the name of your project for this. If
327
	 * you've implemented an alternative client class as well, it
328
	 * should be suffixed by the name of the new class.
329
	 *
330
	 * @param string Relative path to the template creating code for the HTML page head
331
	 * @since 2014.03
332
	 * @category Developer
333
	 * @see client/html/basket/template-body
334
	 */
335
}
336