Completed
Push — master ( b9f1e5...5ff555 )
by Aimeos
11:02
created

Standard::getSubClient()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 78
rs 8.48
c 0
b 0
f 0
cc 1
nc 1
nop 2

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, 2013
6
 * @copyright Aimeos (aimeos.org), 2015-2021
7
 * @package Client
8
 * @subpackage Html
9
 */
10
11
12
namespace Aimeos\Client\Html\Checkout\Standard\Address\Delivery;
13
14
15
/**
16
 * Default implementation of checkout billing address 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/checkout/standard/address/delivery/subparts
26
	 * List of HTML sub-clients rendered within the checkout standard address delivery 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/checkout/standard/address/delivery/subparts';
59
	private $subPartNames = [];
60
61
	private $mandatory = array(
62
		'order.base.address.salutation',
63
		'order.base.address.firstname',
64
		'order.base.address.lastname',
65
		'order.base.address.address1',
66
		'order.base.address.postal',
67
		'order.base.address.city',
68
		'order.base.address.languageid',
69
	);
70
71
	private $optional = array(
72
		'order.base.address.company',
73
		'order.base.address.vatid',
74
		'order.base.address.address2',
75
		'order.base.address.countryid',
76
		'order.base.address.state',
77
	);
78
79
80
	/**
81
	 * Returns the HTML code for insertion into the body.
82
	 *
83
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
84
	 * @return string HTML code
85
	 */
86
	public function getBody( string $uid = '' ) : string
87
	{
88
		$view = $this->getView();
89
90
		$html = '';
91
		foreach( $this->getSubClients() as $subclient ) {
92
			$html .= $subclient->setView( $view )->getBody( $uid );
93
		}
94
		$view->deliveryBody = $html;
95
96
		/** client/html/checkout/standard/address/delivery/template-body
97
		 * Relative path to the HTML body template of the checkout standard address delivery client.
98
		 *
99
		 * The template file contains the HTML code and processing instructions
100
		 * to generate the result shown in the body of the frontend. The
101
		 * configuration string is the path to the template file relative
102
		 * to the templates directory (usually in client/html/templates).
103
		 *
104
		 * You can overwrite the template file configuration in extensions and
105
		 * provide alternative templates. These alternative templates should be
106
		 * named like the default one but with the string "standard" replaced by
107
		 * an unique name. You may use the name of your project for this. If
108
		 * you've implemented an alternative client class as well, "standard"
109
		 * should be replaced by the name of the new class.
110
		 *
111
		 * @param string Relative path to the template creating code for the HTML page body
112
		 * @since 2014.03
113
		 * @category Developer
114
		 * @see client/html/checkout/standard/address/delivery/template-header
115
		 */
116
		$tplconf = 'client/html/checkout/standard/address/delivery/template-body';
117
		$default = 'checkout/standard/address-delivery-body-standard';
118
119
		return $view->render( $view->config( $tplconf, $default ) );
120
	}
121
122
123
	/**
124
	 * Returns the sub-client given by its name.
125
	 *
126
	 * @param string $type Name of the client type
127
	 * @param string|null $name Name of the sub-client (Default if null)
128
	 * @return \Aimeos\Client\Html\Iface Sub-client object
129
	 */
130
	public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
131
	{
132
		/** client/html/checkout/standard/address/delivery/decorators/excludes
133
		 * Excludes decorators added by the "common" option from the checkout standard address delivery html client
134
		 *
135
		 * Decorators extend the functionality of a class by adding new aspects
136
		 * (e.g. log what is currently done), executing the methods of the underlying
137
		 * class only in certain conditions (e.g. only for logged in users) or
138
		 * modify what is returned to the caller.
139
		 *
140
		 * This option allows you to remove a decorator added via
141
		 * "client/html/common/decorators/default" before they are wrapped
142
		 * around the html client.
143
		 *
144
		 *  client/html/checkout/standard/address/delivery/decorators/excludes = array( 'decorator1' )
145
		 *
146
		 * This would remove the decorator named "decorator1" from the list of
147
		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
148
		 * "client/html/common/decorators/default" to the html client.
149
		 *
150
		 * @param array List of decorator names
151
		 * @since 2015.08
152
		 * @category Developer
153
		 * @see client/html/common/decorators/default
154
		 * @see client/html/checkout/standard/address/delivery/decorators/global
155
		 * @see client/html/checkout/standard/address/delivery/decorators/local
156
		 */
157
158
		/** client/html/checkout/standard/address/delivery/decorators/global
159
		 * Adds a list of globally available decorators only to the checkout standard address delivery html client
160
		 *
161
		 * Decorators extend the functionality of a class by adding new aspects
162
		 * (e.g. log what is currently done), executing the methods of the underlying
163
		 * class only in certain conditions (e.g. only for logged in users) or
164
		 * modify what is returned to the caller.
165
		 *
166
		 * This option allows you to wrap global decorators
167
		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
168
		 *
169
		 *  client/html/checkout/standard/address/delivery/decorators/global = array( 'decorator1' )
170
		 *
171
		 * This would add the decorator named "decorator1" defined by
172
		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
173
		 *
174
		 * @param array List of decorator names
175
		 * @since 2015.08
176
		 * @category Developer
177
		 * @see client/html/common/decorators/default
178
		 * @see client/html/checkout/standard/address/delivery/decorators/excludes
179
		 * @see client/html/checkout/standard/address/delivery/decorators/local
180
		 */
181
182
		/** client/html/checkout/standard/address/delivery/decorators/local
183
		 * Adds a list of local decorators only to the checkout standard address delivery html client
184
		 *
185
		 * Decorators extend the functionality of a class by adding new aspects
186
		 * (e.g. log what is currently done), executing the methods of the underlying
187
		 * class only in certain conditions (e.g. only for logged in users) or
188
		 * modify what is returned to the caller.
189
		 *
190
		 * This option allows you to wrap local decorators
191
		 * ("\Aimeos\Client\Html\Checkout\Decorator\*") around the html client.
192
		 *
193
		 *  client/html/checkout/standard/address/delivery/decorators/local = array( 'decorator2' )
194
		 *
195
		 * This would add the decorator named "decorator2" defined by
196
		 * "\Aimeos\Client\Html\Checkout\Decorator\Decorator2" only to the html client.
197
		 *
198
		 * @param array List of decorator names
199
		 * @since 2015.08
200
		 * @category Developer
201
		 * @see client/html/common/decorators/default
202
		 * @see client/html/checkout/standard/address/delivery/decorators/excludes
203
		 * @see client/html/checkout/standard/address/delivery/decorators/global
204
		 */
205
206
		return $this->createSubClient( 'checkout/standard/address/delivery/' . $type, $name );
207
	}
208
209
210
	/**
211
	 * Stores the given or fetched billing address in the basket.
212
	 *
213
	 * A view must be available and this method doesn't generate any output
214
	 * besides setting view variables if necessary.
215
	 */
216
	public function process()
217
	{
218
		$context = $this->getContext();
219
		$view = $this->getView();
220
221
		try
222
		{
223
			if( ( $id = $view->param( 'ca_delivery_delete', null ) ) !== null )
224
			{
225
				$cntl = \Aimeos\Controller\Frontend::create( $context, 'customer' );
226
227
				if( ( $item = $cntl->uses( ['customer/address'] )->get()->getAddressItem( $id ) ) !== null )
228
				{
229
					$cntl->deleteAddressItem( $item )->store();
230
					throw new \Aimeos\Client\Html\Exception( sprintf( 'Delivery address deleted successfully' ) );
231
				}
232
			}
233
234
			// only start if there's something to do
235
			if( $view->param( 'ca_deliveryoption' ) === null ) {
236
				return;
237
			}
238
239
			$this->setAddress( $view );
240
241
			parent::process();
242
		}
243
		catch( \Aimeos\Controller\Frontend\Exception $e )
244
		{
245
			$view->addressDeliveryError = $e->getErrorList();
246
			throw $e;
247
		}
248
	}
249
250
251
	/**
252
	 * Checks the address fields for missing data and sanitizes the given parameter list.
253
	 *
254
	 * @param array &$params Associative list of address keys (order.base.address.* or customer.address.*) and their values
255
	 * @return array List of missing field names
256
	 */
257
	protected function checkFields( array &$params ) : array
258
	{
259
		$view = $this->getView();
260
261
		/** client/html/checkout/standard/address/delivery/mandatory
262
		 * List of delivery address input fields that are required
263
		 *
264
		 * You can configure the list of delivery address fields that are
265
		 * necessary and must be filled by the customer before he can
266
		 * continue the checkout process. Available field keys are:
267
		 *
268
		 * * order.base.address.company
269
		 * * order.base.address.vatid
270
		 * * order.base.address.salutation
271
		 * * order.base.address.firstname
272
		 * * order.base.address.lastname
273
		 * * order.base.address.address1
274
		 * * order.base.address.address2
275
		 * * order.base.address.address3
276
		 * * order.base.address.postal
277
		 * * order.base.address.city
278
		 * * order.base.address.state
279
		 * * order.base.address.languageid
280
		 * * order.base.address.countryid
281
		 * * order.base.address.telephone
282
		 * * order.base.address.telefax
283
		 * * order.base.address.email
284
		 * * order.base.address.website
285
		 *
286
		 * Until 2015-02, the configuration option was available as
287
		 * "client/html/common/address/delivery/mandatory" starting from 2014-03.
288
		 *
289
		 * @param array List of field keys
290
		 * @since 2015.02
291
		 * @category User
292
		 * @category Developer
293
		 * @see client/html/checkout/standard/address/delivery/disable-new
294
		 * @see client/html/checkout/standard/address/delivery/salutations
295
		 * @see client/html/checkout/standard/address/delivery/optional
296
		 * @see client/html/checkout/standard/address/delivery/hidden
297
		 * @see client/html/checkout/standard/address/countries
298
		 * @see client/html/checkout/standard/address/validate
299
		 */
300
		$mandatory = $view->config( 'client/html/checkout/standard/address/delivery/mandatory', $this->mandatory );
301
302
		/** client/html/checkout/standard/address/delivery/optional
303
		 * List of delivery address input fields that are optional
304
		 *
305
		 * You can configure the list of delivery address fields that
306
		 * customers can fill but don't have to before they can
307
		 * continue the checkout process. Available field keys are:
308
		 *
309
		 * * order.base.address.company
310
		 * * order.base.address.vatid
311
		 * * order.base.address.salutation
312
		 * * order.base.address.firstname
313
		 * * order.base.address.lastname
314
		 * * order.base.address.address1
315
		 * * order.base.address.address2
316
		 * * order.base.address.address3
317
		 * * order.base.address.postal
318
		 * * order.base.address.city
319
		 * * order.base.address.state
320
		 * * order.base.address.languageid
321
		 * * order.base.address.countryid
322
		 * * order.base.address.telephone
323
		 * * order.base.address.telefax
324
		 * * order.base.address.email
325
		 * * order.base.address.website
326
		 *
327
		 * Until 2015-02, the configuration option was available as
328
		 * "client/html/common/address/delivery/optional" starting from 2014-03.
329
		 *
330
		 * @param array List of field keys
331
		 * @since 2015.02
332
		 * @category User
333
		 * @category Developer
334
		 * @see client/html/checkout/standard/address/delivery/disable-new
335
		 * @see client/html/checkout/standard/address/delivery/salutations
336
		 * @see client/html/checkout/standard/address/delivery/mandatory
337
		 * @see client/html/checkout/standard/address/delivery/hidden
338
		 * @see client/html/checkout/standard/address/countries
339
		 * @see client/html/checkout/standard/address/validate
340
		 */
341
		$optional = $view->config( 'client/html/checkout/standard/address/delivery/optional', $this->optional );
342
343
		/** client/html/checkout/standard/address/delivery/hidden
344
		 * List of delivery address input fields that are optional
345
		 *
346
		 * You can configure the list of delivery address fields that
347
		 * are hidden when a customer enters his delivery address.
348
		 * Available field keys are:
349
		 *
350
		 * * order.base.address.company
351
		 * * order.base.address.vatid
352
		 * * order.base.address.salutation
353
		 * * order.base.address.firstname
354
		 * * order.base.address.lastname
355
		 * * order.base.address.address1
356
		 * * order.base.address.address2
357
		 * * order.base.address.address3
358
		 * * order.base.address.postal
359
		 * * order.base.address.city
360
		 * * order.base.address.state
361
		 * * order.base.address.languageid
362
		 * * order.base.address.countryid
363
		 * * order.base.address.telephone
364
		 * * order.base.address.telefax
365
		 * * order.base.address.email
366
		 * * order.base.address.website
367
		 *
368
		 * Caution: Only hide fields that don't require any input
369
		 *
370
		 * Until 2015-02, the configuration option was available as
371
		 * "client/html/common/address/delivery/hidden" starting from 2014-03.
372
		 *
373
		 * @param array List of field keys
374
		 * @since 2015.02
375
		 * @category User
376
		 * @category Developer
377
		 * @see client/html/checkout/standard/address/delivery/disable-new
378
		 * @see client/html/checkout/standard/address/delivery/salutations
379
		 * @see client/html/checkout/standard/address/delivery/mandatory
380
		 * @see client/html/checkout/standard/address/delivery/optional
381
		 * @see client/html/checkout/standard/address/countries
382
		 */
383
		$hidden = $view->config( 'client/html/checkout/standard/address/delivery/hidden', [] );
384
385
		/** client/html/checkout/standard/address/validate
386
		 *
387
		 * @see client/html/checkout/standard/address/delivery/mandatory
388
		 * @see client/html/checkout/standard/address/delivery/optional
389
		 */
390
391
		$allFields = array_flip( array_merge( $mandatory, $optional, $hidden ) );
392
		$invalid = $this->validateFields( $params, $allFields );
393
		$this->checkSalutation( $params, $mandatory );
394
395
		foreach( $invalid as $key => $name )
396
		{
397
			$msg = $view->translate( 'client', 'Delivery address part "%1$s" is invalid' );
398
			$invalid[$key] = sprintf( $msg, $name );
399
		}
400
401
		foreach( $mandatory as $key )
402
		{
403
			if( !isset( $params[$key] ) || $params[$key] == '' )
404
			{
405
				$msg = $view->translate( 'client', 'Delivery address part "%1$s" is missing' );
406
				$invalid[$key] = sprintf( $msg, substr( $key, 19 ) );
407
				unset( $params[$key] );
408
			}
409
		}
410
411
		return $invalid;
412
	}
413
414
415
	/**
416
	 * Additional checks for the salutation
417
	 *
418
	 * @param array &$params Associative list of address keys (order.base.address.* or customer.address.*) and their values
419
	 * @param array &$mandatory List of mandatory field names
420
	 * @since 2016.05
421
	 */
422
	protected function checkSalutation( array &$params, array &$mandatory )
423
	{
424
		if( isset( $params['order.base.address.salutation'] )
425
				&& $params['order.base.address.salutation'] === \Aimeos\MShop\Common\Item\Address\Base::SALUTATION_COMPANY
426
				&& in_array( 'order.base.address.company', $mandatory ) === false
427
		) {
428
			$mandatory[] = 'order.base.address.company';
429
		}
430
	}
431
432
433
	/**
434
	 * Returns the address as string
435
	 *
436
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
437
	 * @param \Aimeos\MShop\Order\Item\Base\Address\Iface $addr Order address item
438
	 * @return string Address as string
439
	 */
440
	protected function getAddressString( \Aimeos\MW\View\Iface $view, \Aimeos\MShop\Order\Item\Base\Address\Iface $addr )
441
	{
442
		return preg_replace( "/\n+/m", "\n", trim( sprintf(
443
			/// Address format with company (%1$s), salutation (%2$s), title (%3$s), first name (%4$s), last name (%5$s),
444
			/// address part one (%6$s, e.g street), address part two (%7$s, e.g house number), address part three (%8$s, e.g additional information),
445
			/// postal/zip code (%9$s), city (%10$s), state (%11$s), country (%12$s), language (%13$s),
446
			/// e-mail (%14$s), phone (%15$s), facsimile/telefax (%16$s), web site (%17$s), vatid (%18$s)
447
			$view->translate( 'client', '%1$s
448
%2$s %3$s %4$s %5$s
449
%6$s %7$s
450
%8$s
451
%9$s %10$s
452
%11$s
453
%12$s
454
%13$s
455
%14$s
456
%15$s
457
%16$s
458
%17$s
459
%18$s
460
'
461
			),
462
			$addr->getCompany(),
463
			$view->translate( 'mshop/code', (string) $addr->getSalutation() ),
464
			$addr->getTitle(),
465
			$addr->getFirstName(),
466
			$addr->getLastName(),
467
			$addr->getAddress1(),
468
			$addr->getAddress2(),
469
			$addr->getAddress3(),
470
			$addr->getPostal(),
471
			$addr->getCity(),
472
			$addr->getState(),
473
			$view->translate( 'country', (string) $addr->getCountryId() ),
474
			$view->translate( 'language', (string) $addr->getLanguageId() ),
475
			$addr->getEmail(),
476
			$addr->getTelephone(),
477
			$addr->getTelefax(),
478
			$addr->getWebsite(),
479
			$addr->getVatID()
480
		) ) );
481
	}
482
483
484
	/**
485
	 * Returns the list of sub-client names configured for the client.
486
	 *
487
	 * @return array List of HTML client names
488
	 */
489
	protected function getSubClientNames() : array
490
	{
491
		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
492
	}
493
494
495
	/**
496
	 * Sets the new address
497
	 *
498
	 * @param \Aimeos\MW\View\Iface $view View object
499
	 * @throws \Aimeos\Client\Html\Exception If an error occurs
500
	 * @since 2016.05
501
	 */
502
	protected function setAddress( \Aimeos\MW\View\Iface $view )
503
	{
504
		$address = null;
0 ignored issues
show
Unused Code introduced by
$address is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
505
		$context = $this->getContext();
506
		$ctrl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
507
508
		/** client/html/checkout/standard/address/delivery/disable-new
509
		 * Disables the option to enter a different delivery address for an order
510
		 *
511
		 * Besides the billing address, customers can usually enter a different
512
		 * delivery address as well. To suppress displaying the form fields for
513
		 * a delivery address, you can set this configuration option to "1".
514
		 *
515
		 * Until 2015-02, the configuration option was available as
516
		 * "client/html/common/address/delivery/disable-new" starting from 2014-03.
517
		 *
518
		 * @param boolean A value of "1" to disable, "0" enables the delivery address form
519
		 * @since 2015.02
520
		 * @category User
521
		 * @category Developer
522
		 * @see client/html/checkout/standard/address/delivery/salutations
523
		 * @see client/html/checkout/standard/address/delivery/mandatory
524
		 * @see client/html/checkout/standard/address/delivery/optional
525
		 * @see client/html/checkout/standard/address/delivery/hidden
526
		 */
527
		$disable = $view->config( 'client/html/checkout/standard/address/delivery/disable-new', false );
528
		$type = \Aimeos\MShop\Order\Item\Base\Address\Base::TYPE_DELIVERY;
529
530
		if( ( $option = $view->param( 'ca_deliveryoption', 'null' ) ) === 'null' && $disable === false ) // new address
531
		{
532
			$params = $view->param( 'ca_delivery', [] );
533
534
			if( ( $view->addressDeliveryError = $this->checkFields( $params ) ) !== [] ) {
535
				throw new \Aimeos\Client\Html\Exception( sprintf( 'At least one delivery address part is missing or invalid' ) );
536
			}
537
538
			$ctrl->addAddress( $type, $params, 0 );
539
		}
540
		else if( ( $option = $view->param( 'ca_deliveryoption' ) ) !== 'like' ) // existing address
541
		{
542
			$params = $view->param( 'ca_delivery_' . $option, [] );
543
544
			if( !empty( $params ) && ( $view->addressDeliveryError = $this->checkFields( $params ) ) !== [] ) {
545
				throw new \Aimeos\Client\Html\Exception( sprintf( 'At least one delivery address part is missing or invalid' ) );
546
			}
547
548
			$custCntl = \Aimeos\Controller\Frontend::create( $context, 'customer' );
549
550
			if( ( $address = $custCntl->uses( ['customer/address'] )->get()->getAddressItem( $option ) ) !== null )
551
			{
552
				$params = array_replace( $address->toArray(), $params + ['order.base.address.addressid' => $option] );
553
				$addr = $ctrl->addAddress( $type, $params, 0 )->get()->getAddress( $type, 0 ); // sanitize address first
554
				$custCntl->addAddressItem( $address->copyFrom( $addr ), $option )->store(); // update existing address
555
			}
556
			else
557
			{
558
				$ctrl->addAddress( $type, $params, 0 );
559
			}
560
		}
561
		else
562
		{
563
			$ctrl->deleteAddress( $type );
564
		}
565
	}
566
567
568
	/**
569
	 * Sets the necessary parameter values in the view.
570
	 *
571
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
572
	 * @param array &$tags Result array for the list of tags that are associated to the output
573
	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
574
	 * @return \Aimeos\MW\View\Iface Modified view object
575
	 */
576
	public function addData( \Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : \Aimeos\MW\View\Iface
577
	{
578
		$context = $this->getContext();
579
		$manager = \Aimeos\MShop::create( $context, 'order/base/address' );
580
		$basketCntl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
581
582
		$addrStrings = $addrValues = [];
583
		$addrMap = map( $basketCntl->get()->getAddress( 'delivery' ) );
584
585
		foreach( $view->get( 'addressDeliveryItems', [] ) as $id => $address )
586
		{
587
			$params = $view->param( 'ca_delivery_' . $id, [] );
588
			$basketValues = $addrMap->get( $id, map() )->toArray();
589
			$addr = $manager->create()->copyFrom( $address )->fromArray( $basketValues )->fromArray( $params );
590
591
			$addrStrings[$id] = $this->getAddressString( $view, $addr );
592
			$addrValues[$id] = $addr->toArray();
593
		}
594
595
		$values = !$addrMap->isEmpty() ? $addrMap->first()->toArray() : [];
596
		$values = array_merge( $values, $view->param( 'ca_delivery', [] ) );
597
		$addrNew = $manager->create()->fromArray( $values );
598
599
		$addrStringNew = $this->getAddressString( $view, $addrNew );
600
		$option = $addrNew->getAddressId() ?: ( $addrMap->isEmpty() ? 'like' : 'null' );
601
602
		$view->addressDeliveryOption = $view->param( 'ca_deliveryoption', $option );
603
		$view->addressDeliveryValuesNew = $addrNew->toArray();
604
		$view->addressDeliveryStringNew = $addrStringNew;
605
		$view->addressDeliveryStrings = $addrStrings;
606
		$view->addressDeliveryValues = $addrValues;
607
608
		$salutations = $context->getConfig()->get( 'client/html/common/address/salutations', ['', 'company', 'mr', 'ms'] );
609
610
		/** client/html/checkout/standard/address/delivery/salutations
611
		 * List of salutions the customer can select from for the delivery address
612
		 *
613
		 * The following salutations are available:
614
		 *
615
		 * * empty string for "unknown"
616
		 * * company
617
		 * * mr
618
		 * * ms
619
		 *
620
		 * You can modify the list of salutation codes and remove the ones
621
		 * which shouldn't be used or add new ones.
622
		 *
623
		 * @param array List of available salutation codes
624
		 * @since 2015.02
625
		 * @category User
626
		 * @category Developer
627
		 * @see client/html/checkout/standard/address/delivery/disable-new
628
		 * @see client/html/checkout/standard/address/delivery/mandatory
629
		 * @see client/html/checkout/standard/address/delivery/optional
630
		 * @see client/html/checkout/standard/address/delivery/hidden
631
		 * @see client/html/checkout/standard/address/countries
632
		 * @see client/html/common/address/salutations
633
		 */
634
		$view->addressDeliverySalutations = $view->config( 'client/html/checkout/standard/address/delivery/salutations', $salutations );
635
636
		$mandatory = $view->config( 'client/html/checkout/standard/address/delivery/mandatory', $this->mandatory );
637
		$optional = $view->config( 'client/html/checkout/standard/address/delivery/optional', $this->optional );
638
		$hidden = $view->config( 'client/html/checkout/standard/address/delivery/hidden', [] );
639
640
		$css = [];
641
642
		foreach( $mandatory as $name ) {
643
			$css[$name][] = 'mandatory';
644
		}
645
646
		foreach( $optional as $name ) {
647
			$css[$name][] = 'optional';
648
		}
649
650
		foreach( $hidden as $name ) {
651
			$css[$name][] = 'hidden';
652
		}
653
654
		$view->addressDeliveryMandatory = $mandatory;
655
		$view->addressDeliveryOptional = $optional;
656
		$view->addressDeliveryHidden = $hidden;
657
		$view->addressDeliveryCss = $css;
658
659
		return parent::addData( $view, $tags, $expire );
660
	}
661
662
663
	/**
664
	 * Validate the address key/value pairs using regular expressions
665
	 *
666
	 * @param array &$params Associative list of address keys (order.base.address.* or customer.address.*) and their values
667
	 * @param array $fields List of field names to validate
668
	 * @return array List of invalid address keys
669
	 * @since 2016.05
670
	 */
671
	protected function validateFields( array &$params, array $fields ) : array
672
	{
673
		$config = $this->getContext()->getConfig();
674
675
		/** client/html/checkout/standard/address/validate/company
676
		 * Regular expression to check the "company" address value
677
		 *
678
		 * @see client/html/checkout/standard/address/validate
679
		 */
680
681
		/** client/html/checkout/standard/address/validate/vatid
682
		 * Regular expression to check the "vatid" address value
683
		 *
684
		 * @see client/html/checkout/standard/address/validate
685
		 */
686
687
		/** client/html/checkout/standard/address/validate/salutation
688
		 * Regular expression to check the "salutation" address value
689
		 *
690
		 * @see client/html/checkout/standard/address/validate
691
		 */
692
693
		/** client/html/checkout/standard/address/validate/firstname
694
		 * Regular expression to check the "firstname" address value
695
		 *
696
		 * @see client/html/checkout/standard/address/validate
697
		 */
698
699
		/** client/html/checkout/standard/address/validate/lastname
700
		 * Regular expression to check the "lastname" address value
701
		 *
702
		 * @see client/html/checkout/standard/address/validate
703
		 */
704
705
		/** client/html/checkout/standard/address/validate/address1
706
		 * Regular expression to check the "address1" address value
707
		 *
708
		 * @see client/html/checkout/standard/address/validate
709
		 */
710
711
		/** client/html/checkout/standard/address/validate/address2
712
		 * Regular expression to check the "address2" address value
713
		 *
714
		 * @see client/html/checkout/standard/address/validate
715
		 */
716
717
		/** client/html/checkout/standard/address/validate/address3
718
		 * Regular expression to check the "address3" address value
719
		 *
720
		 * @see client/html/checkout/standard/address/validate
721
		 */
722
723
		/** client/html/checkout/standard/address/validate/postal
724
		 * Regular expression to check the "postal" address value
725
		 *
726
		 * @see client/html/checkout/standard/address/validate
727
		 */
728
729
		/** client/html/checkout/standard/address/validate/city
730
		 * Regular expression to check the "city" address value
731
		 *
732
		 * @see client/html/checkout/standard/address/validate
733
		 */
734
735
		/** client/html/checkout/standard/address/validate/state
736
		 * Regular expression to check the "state" address value
737
		 *
738
		 * @see client/html/checkout/standard/address/validate
739
		 */
740
741
		/** client/html/checkout/standard/address/validate/languageid
742
		 * Regular expression to check the "languageid" address value
743
		 *
744
		 * @see client/html/checkout/standard/address/validate
745
		 */
746
747
		/** client/html/checkout/standard/address/validate/countryid
748
		 * Regular expression to check the "countryid" address value
749
		 *
750
		 * @see client/html/checkout/standard/address/validate
751
		 */
752
753
		/** client/html/checkout/standard/address/validate/telephone
754
		 * Regular expression to check the "telephone" address value
755
		 *
756
		 * @see client/html/checkout/standard/address/validate
757
		 */
758
759
		/** client/html/checkout/standard/address/validate/telefax
760
		 * Regular expression to check the "telefax" address value
761
		 *
762
		 * @see client/html/checkout/standard/address/validate
763
		 */
764
765
		/** client/html/checkout/standard/address/validate/email
766
		 * Regular expression to check the "email" address value
767
		 *
768
		 * @see client/html/checkout/standard/address/validate
769
		 */
770
771
		/** client/html/checkout/standard/address/validate/website
772
		 * Regular expression to check the "website" address value
773
		 *
774
		 * @see client/html/checkout/standard/address/validate
775
		 */
776
777
		$invalid = [];
778
779
		foreach( $params as $key => $value )
780
		{
781
			if( isset( $fields[$key] ) )
782
			{
783
				$name = substr( $key, 19 );
784
				$regex = $config->get( 'client/html/checkout/standard/address/validate/' . $name );
785
786
				if( $regex && preg_match( '/' . $regex . '/', $value ) !== 1 )
787
				{
788
					$invalid[$key] = $name;
789
					unset( $params[$key] );
790
				}
791
			}
792
			else
793
			{
794
				unset( $params[$key] );
795
			}
796
		}
797
798
		return $invalid;
799
	}
800
}
801