Completed
Push — master ( 9b51fc...1cffcf )
by Aimeos
03:25
created

Standard::getAddressString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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