Passed
Push — master ( 0f1828...ed6c8e )
by Aimeos
04:20
created

Standard::data()   B

Complexity

Conditions 8
Paths 64

Size

Total Lines 85
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 38
nc 64
nop 3
dl 0
loc 85
rs 8.0675
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, 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.firstname',
63
		'order.base.address.lastname',
64
		'order.base.address.address1',
65
		'order.base.address.postal',
66
		'order.base.address.city',
67
		'order.base.address.languageid',
68
	);
69
70
	private $optional = array(
71
		'order.base.address.salutation',
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 body( string $uid = '' ) : string
87
	{
88
		$view = $this->getView();
89
90
		$html = '';
91
		foreach( $this->getSubClients() as $subclient ) {
92
			$html .= $subclient->setView( $view )->body( $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 init()
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::init();
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
		 * @param array List of field keys
287
		 * @since 2015.02
288
		 * @category User
289
		 * @category Developer
290
		 * @see client/html/checkout/standard/address/delivery/disable-new
291
		 * @see client/html/checkout/standard/address/delivery/salutations
292
		 * @see client/html/checkout/standard/address/delivery/optional
293
		 * @see client/html/checkout/standard/address/delivery/hidden
294
		 * @see client/html/checkout/standard/address/validate
295
		 * @see common/countries
296
		 * @see common/states
297
		 */
298
		$mandatory = $view->config( 'client/html/checkout/standard/address/delivery/mandatory', $this->mandatory );
299
300
		/** client/html/checkout/standard/address/delivery/optional
301
		 * List of delivery address input fields that are optional
302
		 *
303
		 * You can configure the list of delivery address fields that
304
		 * customers can fill but don't have to before they can
305
		 * continue the checkout process. Available field keys are:
306
		 *
307
		 * * order.base.address.company
308
		 * * order.base.address.vatid
309
		 * * order.base.address.salutation
310
		 * * order.base.address.firstname
311
		 * * order.base.address.lastname
312
		 * * order.base.address.address1
313
		 * * order.base.address.address2
314
		 * * order.base.address.address3
315
		 * * order.base.address.postal
316
		 * * order.base.address.city
317
		 * * order.base.address.state
318
		 * * order.base.address.languageid
319
		 * * order.base.address.countryid
320
		 * * order.base.address.telephone
321
		 * * order.base.address.telefax
322
		 * * order.base.address.email
323
		 * * order.base.address.website
324
		 * * nostore
325
		 *
326
		 * Using the "nostore" field displays the option to avoid storing the
327
		 * delivery address permanently in the customer account.
328
		 *
329
		 * @param array List of field keys
330
		 * @since 2015.02
331
		 * @category User
332
		 * @category Developer
333
		 * @see client/html/checkout/standard/address/delivery/disable-new
334
		 * @see client/html/checkout/standard/address/delivery/salutations
335
		 * @see client/html/checkout/standard/address/delivery/mandatory
336
		 * @see client/html/checkout/standard/address/delivery/hidden
337
		 * @see client/html/checkout/standard/address/validate
338
		 * @see common/countries
339
		 * @see common/states
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
		 * @param array List of field keys
371
		 * @since 2015.02
372
		 * @category User
373
		 * @category Developer
374
		 * @see client/html/checkout/standard/address/delivery/disable-new
375
		 * @see client/html/checkout/standard/address/delivery/salutations
376
		 * @see client/html/checkout/standard/address/delivery/mandatory
377
		 * @see client/html/checkout/standard/address/delivery/optional
378
		 * @see common/countries
379
		 * @see common/states
380
		 */
381
		$hidden = $view->config( 'client/html/checkout/standard/address/delivery/hidden', [] );
382
383
		/** client/html/checkout/standard/address/validate
384
		 *
385
		 * @see client/html/checkout/standard/address/delivery/mandatory
386
		 * @see client/html/checkout/standard/address/delivery/optional
387
		 */
388
389
		$allFields = array_flip( array_merge( $mandatory, $optional, $hidden ) );
390
		$invalid = $this->validateFields( $params, $allFields );
391
		$this->checkSalutation( $params, $mandatory );
392
393
		foreach( $invalid as $key => $name )
394
		{
395
			$msg = $view->translate( 'client', 'Delivery address part "%1$s" is invalid' );
396
			$invalid[$key] = sprintf( $msg, $name );
397
		}
398
399
		foreach( $mandatory as $key )
400
		{
401
			if( !isset( $params[$key] ) || $params[$key] == '' )
402
			{
403
				$msg = $view->translate( 'client', 'Delivery address part "%1$s" is missing' );
404
				$invalid[$key] = sprintf( $msg, substr( $key, 19 ) );
405
				unset( $params[$key] );
406
			}
407
		}
408
409
		return $invalid;
410
	}
411
412
413
	/**
414
	 * Additional checks for the salutation
415
	 *
416
	 * @param array &$params Associative list of address keys (order.base.address.* or customer.address.*) and their values
417
	 * @param array &$mandatory List of mandatory field names
418
	 * @since 2016.05
419
	 */
420
	protected function checkSalutation( array &$params, array &$mandatory )
421
	{
422
		if( isset( $params['order.base.address.salutation'] )
423
				&& $params['order.base.address.salutation'] === \Aimeos\MShop\Common\Item\Address\Base::SALUTATION_COMPANY
424
				&& in_array( 'order.base.address.company', $mandatory ) === false
425
		) {
426
			$mandatory[] = 'order.base.address.company';
427
		}
428
	}
429
430
431
	/**
432
	 * Returns the address as string
433
	 *
434
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
435
	 * @param \Aimeos\MShop\Order\Item\Base\Address\Iface $addr Order address item
436
	 * @return string Address as string
437
	 */
438
	protected function getAddressString( \Aimeos\MW\View\Iface $view, \Aimeos\MShop\Order\Item\Base\Address\Iface $addr )
439
	{
440
		return preg_replace( "/\n+/m", "\n", trim( sprintf(
441
			/// Address format with company (%1$s), salutation (%2$s), title (%3$s), first name (%4$s), last name (%5$s),
442
			/// 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),
443
			/// postal/zip code (%9$s), city (%10$s), state (%11$s), country (%12$s), language (%13$s),
444
			/// e-mail (%14$s), phone (%15$s), facsimile/telefax (%16$s), web site (%17$s), vatid (%18$s)
445
			$view->translate( 'client', '%1$s
446
%2$s %3$s %4$s %5$s
447
%6$s %7$s
448
%8$s
449
%9$s %10$s
450
%11$s
451
%12$s
452
%13$s
453
%14$s
454
%15$s
455
%16$s
456
%17$s
457
%18$s
458
'
459
			),
460
			$addr->getCompany(),
461
			$view->translate( 'mshop/code', (string) $addr->getSalutation() ),
462
			$addr->getTitle(),
463
			$addr->getFirstName(),
464
			$addr->getLastName(),
465
			$addr->getAddress1(),
466
			$addr->getAddress2(),
467
			$addr->getAddress3(),
468
			$addr->getPostal(),
469
			$addr->getCity(),
470
			$addr->getState(),
471
			$view->translate( 'country', (string) $addr->getCountryId() ),
472
			$view->translate( 'language', (string) $addr->getLanguageId() ),
473
			$addr->getEmail(),
474
			$addr->getTelephone(),
475
			$addr->getTelefax(),
476
			$addr->getWebsite(),
477
			$addr->getVatID()
478
		) ) );
479
	}
480
481
482
	/**
483
	 * Returns the list of sub-client names configured for the client.
484
	 *
485
	 * @return array List of HTML client names
486
	 */
487
	protected function getSubClientNames() : array
488
	{
489
		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
490
	}
491
492
493
	/**
494
	 * Sets the new address
495
	 *
496
	 * @param \Aimeos\MW\View\Iface $view View object
497
	 * @throws \Aimeos\Client\Html\Exception If an error occurs
498
	 * @since 2016.05
499
	 */
500
	protected function setAddress( \Aimeos\MW\View\Iface $view )
501
	{
502
		$address = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $address is dead and can be removed.
Loading history...
503
		$context = $this->getContext();
504
		$ctrl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
505
506
		/** client/html/checkout/standard/address/delivery/disable-new
507
		 * Disables the option to enter a different delivery address for an order
508
		 *
509
		 * Besides the billing address, customers can usually enter a different
510
		 * delivery address as well. To suppress displaying the form fields for
511
		 * a delivery address, you can set this configuration option to "1".
512
		 *
513
		 * @param boolean A value of "1" to disable, "0" enables the delivery address form
514
		 * @since 2015.02
515
		 * @category User
516
		 * @category Developer
517
		 * @see client/html/checkout/standard/address/delivery/salutations
518
		 * @see client/html/checkout/standard/address/delivery/mandatory
519
		 * @see client/html/checkout/standard/address/delivery/optional
520
		 * @see client/html/checkout/standard/address/delivery/hidden
521
		 */
522
		$disable = $view->config( 'client/html/checkout/standard/address/delivery/disable-new', false );
523
		$type = \Aimeos\MShop\Order\Item\Base\Address\Base::TYPE_DELIVERY;
524
525
		if( ( $option = $view->param( 'ca_deliveryoption', 'null' ) ) === 'null' && $disable === false ) // new address
0 ignored issues
show
Unused Code introduced by
The assignment to $option is dead and can be removed.
Loading history...
526
		{
527
			$params = $view->param( 'ca_delivery', [] );
528
529
			if( ( $view->addressDeliveryError = $this->checkFields( $params ) ) !== [] ) {
530
				throw new \Aimeos\Client\Html\Exception( sprintf( 'At least one delivery address part is missing or invalid' ) );
531
			}
532
533
			$ctrl->addAddress( $type, $params, 0 );
534
		}
535
		else if( ( $option = $view->param( 'ca_deliveryoption' ) ) !== 'like' ) // existing address
536
		{
537
			$params = $view->param( 'ca_delivery_' . $option, [] );
538
539
			if( !empty( $params ) && ( $view->addressDeliveryError = $this->checkFields( $params ) ) !== [] ) {
540
				throw new \Aimeos\Client\Html\Exception( sprintf( 'At least one delivery address part is missing or invalid' ) );
541
			}
542
543
			$custCntl = \Aimeos\Controller\Frontend::create( $context, 'customer' );
544
545
			if( ( $address = $custCntl->uses( ['customer/address'] )->get()->getAddressItem( $option ) ) !== null )
546
			{
547
				$params = array_replace( $address->toArray(), $params + ['order.base.address.addressid' => $option] );
548
				$addr = $ctrl->addAddress( $type, $params, 0 )->get()->getAddress( $type, 0 ); // sanitize address first
549
				$custCntl->addAddressItem( $address->copyFrom( $addr ), $option )->store(); // update existing address
550
			}
551
			else
552
			{
553
				$ctrl->addAddress( $type, $params, 0 );
554
			}
555
		}
556
		else
557
		{
558
			$ctrl->deleteAddress( $type );
559
		}
560
	}
561
562
563
	/**
564
	 * Sets the necessary parameter values in the view.
565
	 *
566
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
567
	 * @param array &$tags Result array for the list of tags that are associated to the output
568
	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
569
	 * @return \Aimeos\MW\View\Iface Modified view object
570
	 */
571
	public function data( \Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : \Aimeos\MW\View\Iface
572
	{
573
		$context = $this->getContext();
574
		$manager = \Aimeos\MShop::create( $context, 'order/base/address' );
575
		$basketCntl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
576
577
		$addrStrings = $addrValues = [];
578
		$addrMap = map( $basketCntl->get()->getAddress( 'delivery' ) );
579
580
		foreach( $view->get( 'addressDeliveryItems', [] ) as $id => $address )
581
		{
582
			$params = $view->param( 'ca_delivery_' . $id, [] );
583
			$basketValues = $addrMap->get( $id, map() )->toArray();
584
			$addr = $manager->create()->copyFrom( $address )->fromArray( $basketValues )->fromArray( $params );
585
586
			$addrStrings[$id] = $this->getAddressString( $view, $addr );
587
			$addrValues[$id] = $addr->toArray();
588
		}
589
590
		$values = !$addrMap->isEmpty() ? $addrMap->first()->toArray() : [];
591
		$values = array_merge( $values, $view->param( 'ca_delivery', [] ) );
592
		$addrNew = $manager->create()->fromArray( $values );
593
594
		$addrStringNew = $this->getAddressString( $view, $addrNew );
595
		$option = $addrNew->getAddressId() ?: ( $addrMap->isEmpty() ? 'like' : 'null' );
596
597
		$view->addressDeliveryOption = $view->param( 'ca_deliveryoption', $option );
598
		$view->addressDeliveryValuesNew = $addrNew->toArray();
599
		$view->addressDeliveryStringNew = $addrStringNew;
600
		$view->addressDeliveryStrings = $addrStrings;
601
		$view->addressDeliveryValues = $addrValues;
602
603
		$salutations = $context->getConfig()->get( 'client/html/common/address/salutations', ['', 'mr', 'ms'] );
604
605
		/** client/html/checkout/standard/address/delivery/salutations
606
		 * List of salutions the customer can select from for the delivery address
607
		 *
608
		 * The following salutations are available:
609
		 *
610
		 * * empty string for "unknown"
611
		 * * company
612
		 * * mr
613
		 * * ms
614
		 *
615
		 * You can modify the list of salutation codes and remove the ones
616
		 * which shouldn't be used or add new ones.
617
		 *
618
		 * @param array List of available salutation codes
619
		 * @since 2015.02
620
		 * @category User
621
		 * @category Developer
622
		 * @see client/html/checkout/standard/address/delivery/disable-new
623
		 * @see client/html/checkout/standard/address/delivery/mandatory
624
		 * @see client/html/checkout/standard/address/delivery/optional
625
		 * @see client/html/checkout/standard/address/delivery/hidden
626
		 * @see client/html/common/address/salutations
627
		 * @see common/countries
628
		 * @see common/states
629
		 */
630
		$view->addressDeliverySalutations = $view->config( 'client/html/checkout/standard/address/delivery/salutations', $salutations );
631
632
		$mandatory = $view->config( 'client/html/checkout/standard/address/delivery/mandatory', $this->mandatory );
633
		$optional = $view->config( 'client/html/checkout/standard/address/delivery/optional', $this->optional );
634
		$hidden = $view->config( 'client/html/checkout/standard/address/delivery/hidden', [] );
635
636
		$css = [];
637
638
		foreach( $mandatory as $name ) {
639
			$css[$name][] = 'mandatory';
640
		}
641
642
		foreach( $optional as $name ) {
643
			$css[$name][] = 'optional';
644
		}
645
646
		foreach( $hidden as $name ) {
647
			$css[$name][] = 'hidden';
648
		}
649
650
		$view->addressDeliveryMandatory = $mandatory;
651
		$view->addressDeliveryOptional = $optional;
652
		$view->addressDeliveryHidden = $hidden;
653
		$view->addressDeliveryCss = $css;
654
655
		return parent::data( $view, $tags, $expire );
656
	}
657
658
659
	/**
660
	 * Validate the address key/value pairs using regular expressions
661
	 *
662
	 * @param array &$params Associative list of address keys (order.base.address.* or customer.address.*) and their values
663
	 * @param array $fields List of field names to validate
664
	 * @return array List of invalid address keys
665
	 * @since 2016.05
666
	 */
667
	protected function validateFields( array &$params, array $fields ) : array
668
	{
669
		$config = $this->getContext()->getConfig();
670
671
		/** client/html/checkout/standard/address/validate/company
672
		 * Regular expression to check the "company" address value
673
		 *
674
		 * @see client/html/checkout/standard/address/validate
675
		 */
676
677
		/** client/html/checkout/standard/address/validate/vatid
678
		 * Regular expression to check the "vatid" address value
679
		 *
680
		 * @see client/html/checkout/standard/address/validate
681
		 */
682
683
		/** client/html/checkout/standard/address/validate/salutation
684
		 * Regular expression to check the "salutation" address value
685
		 *
686
		 * @see client/html/checkout/standard/address/validate
687
		 */
688
689
		/** client/html/checkout/standard/address/validate/firstname
690
		 * Regular expression to check the "firstname" address value
691
		 *
692
		 * @see client/html/checkout/standard/address/validate
693
		 */
694
695
		/** client/html/checkout/standard/address/validate/lastname
696
		 * Regular expression to check the "lastname" address value
697
		 *
698
		 * @see client/html/checkout/standard/address/validate
699
		 */
700
701
		/** client/html/checkout/standard/address/validate/address1
702
		 * Regular expression to check the "address1" address value
703
		 *
704
		 * @see client/html/checkout/standard/address/validate
705
		 */
706
707
		/** client/html/checkout/standard/address/validate/address2
708
		 * Regular expression to check the "address2" address value
709
		 *
710
		 * @see client/html/checkout/standard/address/validate
711
		 */
712
713
		/** client/html/checkout/standard/address/validate/address3
714
		 * Regular expression to check the "address3" address value
715
		 *
716
		 * @see client/html/checkout/standard/address/validate
717
		 */
718
719
		/** client/html/checkout/standard/address/validate/postal
720
		 * Regular expression to check the "postal" address value
721
		 *
722
		 * @see client/html/checkout/standard/address/validate
723
		 */
724
725
		/** client/html/checkout/standard/address/validate/city
726
		 * Regular expression to check the "city" address value
727
		 *
728
		 * @see client/html/checkout/standard/address/validate
729
		 */
730
731
		/** client/html/checkout/standard/address/validate/state
732
		 * Regular expression to check the "state" address value
733
		 *
734
		 * @see client/html/checkout/standard/address/validate
735
		 */
736
737
		/** client/html/checkout/standard/address/validate/languageid
738
		 * Regular expression to check the "languageid" address value
739
		 *
740
		 * @see client/html/checkout/standard/address/validate
741
		 */
742
743
		/** client/html/checkout/standard/address/validate/countryid
744
		 * Regular expression to check the "countryid" address value
745
		 *
746
		 * @see client/html/checkout/standard/address/validate
747
		 */
748
749
		/** client/html/checkout/standard/address/validate/telephone
750
		 * Regular expression to check the "telephone" address value
751
		 *
752
		 * @see client/html/checkout/standard/address/validate
753
		 */
754
755
		/** client/html/checkout/standard/address/validate/telefax
756
		 * Regular expression to check the "telefax" address value
757
		 *
758
		 * @see client/html/checkout/standard/address/validate
759
		 */
760
761
		/** client/html/checkout/standard/address/validate/email
762
		 * Regular expression to check the "email" address value
763
		 *
764
		 * @see client/html/checkout/standard/address/validate
765
		 */
766
767
		/** client/html/checkout/standard/address/validate/website
768
		 * Regular expression to check the "website" address value
769
		 *
770
		 * @see client/html/checkout/standard/address/validate
771
		 */
772
773
		$invalid = [];
774
775
		foreach( $params as $key => $value )
776
		{
777
			if( isset( $fields[$key] ) )
778
			{
779
				$name = ( $pos = strrpos( $key, '.' ) ) ? substr( $key, $pos + 1 ) : $key;
780
				$regex = $config->get( 'client/html/checkout/standard/address/validate/' . $name );
781
782
				if( $regex && preg_match( '/' . $regex . '/', $value ) !== 1 )
783
				{
784
					$invalid[$key] = $name;
785
					unset( $params[$key] );
786
				}
787
			}
788
			else
789
			{
790
				unset( $params[$key] );
791
			}
792
		}
793
794
		return $invalid;
795
	}
796
}
797