Passed
Push — master ( 9d248b...fd488e )
by Aimeos
04:39
created

Standard::getSubClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 77
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 77
rs 10
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, 2012
6
 * @copyright Aimeos (aimeos.org), 2015-2021
7
 * @package Client
8
 * @subpackage Html
9
 */
10
11
12
namespace Aimeos\Client\Html\Catalog\Detail;
13
14
15
/**
16
 * Default implementation of catalog detail section HTML clients.
17
 *
18
 * @package Client
19
 * @subpackage Html
20
 */
21
class Standard
22
	extends \Aimeos\Client\Html\Catalog\Base
23
	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
24
{
25
	/** client/html/catalog/detail/subparts
26
	 * List of HTML sub-clients rendered within the catalog detail 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/catalog/detail/subparts';
59
60
	/** client/html/catalog/detail/service/name
61
	 * Name of the shipping cost part used by the catalog detail client implementation
62
	 *
63
	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Detail\Service\Myname".
64
	 * The name is case-sensitive and you should avoid camel case names like "MyName".
65
	 *
66
	 * @param string Last part of the client class name
67
	 * @since 2017.01
68
	 * @category Developer
69
	 */
70
71
	/** client/html/catalog/detail/seen/name
72
	 * Name of the seen part used by the catalog detail client implementation
73
	 *
74
	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Detail\Seen\Myname".
75
	 * The name is case-sensitive and you should avoid camel case names like "MyName".
76
	 *
77
	 * @param string Last part of the client class name
78
	 * @since 2014.03
79
	 * @category Developer
80
	 */
81
	private $subPartNames = ['seen', 'service'];
82
83
	private $tags = [];
84
	private $expire;
85
	private $view;
86
87
88
	/**
89
	 * Returns the HTML code for insertion into the body.
90
	 *
91
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
92
	 * @return string HTML code
93
	 */
94
	public function getBody( string $uid = '' ) : string
95
	{
96
		$view = $this->getView();
97
		$context = $this->getContext();
98
		$prefixes = ['d_prodid', 'd_name'];
99
100
		$code = $context->getConfig()->get( 'client/html/catalog/detail/prodcode-default' );
101
		$id = $context->getConfig()->get( 'client/html/catalog/detail/prodid-default', $code );
102
103
		if( !$view->param( 'd_prodid', $id ) && !$view->param( 'd_name' ) ) {
104
			return '';
105
		}
106
107
		/** client/html/catalog/detail/cache
108
		 * Enables or disables caching only for the catalog detail component
109
		 *
110
		 * Disable caching for components can be useful if you would have too much
111
		 * entries to cache or if the component contains non-cacheable parts that
112
		 * can't be replaced using the modifyBody() and modifyHeader() methods.
113
		 *
114
		 * @param boolean True to enable caching, false to disable
115
		 * @category Developer
116
		 * @category User
117
		 * @see client/html/catalog/filter/cache
118
		 * @see client/html/catalog/lists/cache
119
		 * @see client/html/catalog/stage/cache
120
		 */
121
122
		/** client/html/catalog/detail
123
		 * All parameters defined for the catalog detail component and its subparts
124
		 *
125
		 * This returns all settings related to the detail component.
126
		 * Please refer to the single settings for details.
127
		 *
128
		 * @param array Associative list of name/value settings
129
		 * @category Developer
130
		 * @see client/html/catalog#detail
131
		 */
132
		$confkey = 'client/html/catalog/detail';
133
134
		if( ( $html = $this->getCached( 'body', $uid, $prefixes, $confkey ) ) === null )
135
		{
136
			/** client/html/catalog/detail/template-body
137
			 * Relative path to the HTML body template of the catalog detail client.
138
			 *
139
			 * The template file contains the HTML code and processing instructions
140
			 * to generate the result shown in the body of the frontend. The
141
			 * configuration string is the path to the template file relative
142
			 * to the templates directory (usually in client/html/templates).
143
			 *
144
			 * You can overwrite the template file configuration in extensions and
145
			 * provide alternative templates. These alternative templates should be
146
			 * named like the default one but with the string "standard" replaced by
147
			 * an unique name. You may use the name of your project for this. If
148
			 * you've implemented an alternative client class as well, "standard"
149
			 * should be replaced by the name of the new class.
150
			 *
151
			 * @param string Relative path to the template creating code for the HTML page body
152
			 * @since 2014.03
153
			 * @category Developer
154
			 * @see client/html/catalog/detail/template-header
155
			 * @see client/html/catalog/detail/404
156
			 */
157
			$tplconf = 'client/html/catalog/detail/template-body';
158
			$default = 'catalog/detail/body-standard';
159
160
			try
161
			{
162
				$html = '';
163
164
				if( !isset( $this->view ) ) {
165
					$view = $this->view = $this->getObject()->addData( $view, $this->tags, $this->expire );
166
				}
167
168
				foreach( $this->getSubClients() as $subclient ) {
169
					$html .= $subclient->setView( $view )->getBody( $uid );
170
				}
171
				$view->detailBody = $html;
172
173
				$html = $view->render( $view->config( $tplconf, $default ) );
174
				$this->setCached( 'body', $uid, $prefixes, $confkey, $html, $this->tags, $this->expire );
175
176
				return $html;
177
			}
178
			catch( \Aimeos\Client\Html\Exception $e )
179
			{
180
				$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
181
				$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
182
			}
183
			catch( \Aimeos\Controller\Frontend\Exception $e )
184
			{
185
				$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
186
				$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
187
188
				/** client/html/catalog/detail/404
189
				 * Configures 404 handling for catalog detail pages
190
				 *
191
				 * By default, no HTTP 404 status code is returned to the browser, just
192
				 * an error message that the product could not be found. Changing this
193
				 * setting to TRUE will return a 404 page depending on the host application.
194
				 *
195
				 * @param bool TRUE to return HTTP status code 404, FALSE to return an error message
196
				 * @since 2021.10
197
				 * @see client/html/catalog/detail/template-header
198
				 * @see client/html/catalog/detail/template-body
199
				 */
200
				$throw = $context->config()->get( 'client/html/catalog/detail/404', false );
201
202
				if( $throw && $e->getCode() === 404 ) { throw $e; }
203
			}
204
			catch( \Aimeos\MShop\Exception $e )
205
			{
206
				$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
207
				$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
208
			}
209
			catch( \Exception $e )
210
			{
211
				$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
212
				$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
213
				$this->logException( $e );
214
			}
215
216
			$html = $view->render( $view->config( $tplconf, $default ) );
217
		}
218
		else
219
		{
220
			$html = $this->modifyBody( $html, $uid );
221
		}
222
223
		return $html;
224
	}
225
226
227
	/**
228
	 * Returns the HTML string for insertion into the header.
229
	 *
230
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
231
	 * @return string|null String including HTML tags for the header on error
232
	 */
233
	public function getHeader( string $uid = '' ) : ?string
234
	{
235
		$view = $this->getView();
236
		$context = $this->getContext();
237
		$prefixes = ['d_prodid', 'd_name'];
238
		$confkey = 'client/html/catalog/detail';
239
240
		$code = $context->getConfig()->get( 'client/html/catalog/detail/prodcode-default' );
241
		$id = $context->getConfig()->get( 'client/html/catalog/detail/prodid-default', $code );
242
243
		if( !$view->param( 'd_prodid', $id ) && !$view->param( 'd_name' ) ) {
244
			return '';
245
		}
246
247
		if( ( $html = $this->getCached( 'header', $uid, $prefixes, $confkey ) ) === null )
248
		{
249
			/** client/html/catalog/detail/template-header
250
			 * Relative path to the HTML header template of the catalog detail client.
251
			 *
252
			 * The template file contains the HTML code and processing instructions
253
			 * to generate the HTML code that is inserted into the HTML page header
254
			 * of the rendered page in the frontend. The configuration string is the
255
			 * path to the template file relative to the templates directory (usually
256
			 * in client/html/templates).
257
			 *
258
			 * You can overwrite the template file configuration in extensions and
259
			 * provide alternative templates. These alternative templates should be
260
			 * named like the default one but with the string "standard" replaced by
261
			 * an unique name. You may use the name of your project for this. If
262
			 * you've implemented an alternative client class as well, "standard"
263
			 * should be replaced by the name of the new class.
264
			 *
265
			 * @param string Relative path to the template creating code for the HTML page head
266
			 * @since 2014.03
267
			 * @category Developer
268
			 * @see client/html/catalog/detail/template-body
269
			 * @see client/html/catalog/detail/404
270
			 */
271
			$tplconf = 'client/html/catalog/detail/template-header';
272
			$default = 'catalog/detail/header-standard';
273
274
			try
275
			{
276
				$html = '';
277
278
				if( !isset( $this->view ) ) {
279
					$view = $this->view = $this->getObject()->addData( $view, $this->tags, $this->expire );
280
				}
281
282
				foreach( $this->getSubClients() as $subclient ) {
283
					$html .= $subclient->setView( $view )->getHeader( $uid );
284
				}
285
				$view->detailHeader = $html;
286
287
				$html = $view->render( $view->config( $tplconf, $default ) );
288
				$this->setCached( 'header', $uid, $prefixes, $confkey, $html, $this->tags, $this->expire );
289
290
				return $html;
291
			}
292
			catch( \Exception $e )
293
			{
294
				$this->logException( $e );
295
			}
296
		}
297
		else
298
		{
299
			$html = $this->modifyHeader( $html, $uid );
300
		}
301
302
		return $html;
303
	}
304
305
306
	/**
307
	 * Returns the sub-client given by its name.
308
	 *
309
	 * @param string $type Name of the client type
310
	 * @param string|null $name Name of the sub-client (Default if null)
311
	 * @return \Aimeos\Client\Html\Iface Sub-client object
312
	 */
313
	public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
314
	{
315
		/** client/html/catalog/detail/decorators/excludes
316
		 * Excludes decorators added by the "common" option from the catalog detail html client
317
		 *
318
		 * Decorators extend the functionality of a class by adding new aspects
319
		 * (e.g. log what is currently done), executing the methods of the underlying
320
		 * class only in certain conditions (e.g. only for logged in users) or
321
		 * modify what is returned to the caller.
322
		 *
323
		 * This option allows you to remove a decorator added via
324
		 * "client/html/common/decorators/default" before they are wrapped
325
		 * around the html client.
326
		 *
327
		 *  client/html/catalog/detail/decorators/excludes = array( 'decorator1' )
328
		 *
329
		 * This would remove the decorator named "decorator1" from the list of
330
		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
331
		 * "client/html/common/decorators/default" to the html client.
332
		 *
333
		 * @param array List of decorator names
334
		 * @since 2014.05
335
		 * @category Developer
336
		 * @see client/html/common/decorators/default
337
		 * @see client/html/catalog/detail/decorators/global
338
		 * @see client/html/catalog/detail/decorators/local
339
		 */
340
341
		/** client/html/catalog/detail/decorators/global
342
		 * Adds a list of globally available decorators only to the catalog detail html client
343
		 *
344
		 * Decorators extend the functionality of a class by adding new aspects
345
		 * (e.g. log what is currently done), executing the methods of the underlying
346
		 * class only in certain conditions (e.g. only for logged in users) or
347
		 * modify what is returned to the caller.
348
		 *
349
		 * This option allows you to wrap global decorators
350
		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
351
		 *
352
		 *  client/html/catalog/detail/decorators/global = array( 'decorator1' )
353
		 *
354
		 * This would add the decorator named "decorator1" defined by
355
		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
356
		 *
357
		 * @param array List of decorator names
358
		 * @since 2014.05
359
		 * @category Developer
360
		 * @see client/html/common/decorators/default
361
		 * @see client/html/catalog/detail/decorators/excludes
362
		 * @see client/html/catalog/detail/decorators/local
363
		 */
364
365
		/** client/html/catalog/detail/decorators/local
366
		 * Adds a list of local decorators only to the catalog detail html client
367
		 *
368
		 * Decorators extend the functionality of a class by adding new aspects
369
		 * (e.g. log what is currently done), executing the methods of the underlying
370
		 * class only in certain conditions (e.g. only for logged in users) or
371
		 * modify what is returned to the caller.
372
		 *
373
		 * This option allows you to wrap local decorators
374
		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
375
		 *
376
		 *  client/html/catalog/detail/decorators/local = array( 'decorator2' )
377
		 *
378
		 * This would add the decorator named "decorator2" defined by
379
		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
380
		 *
381
		 * @param array List of decorator names
382
		 * @since 2014.05
383
		 * @category Developer
384
		 * @see client/html/common/decorators/default
385
		 * @see client/html/catalog/detail/decorators/excludes
386
		 * @see client/html/catalog/detail/decorators/global
387
		 */
388
389
		return $this->createSubClient( 'catalog/detail/' . $type, $name );
390
	}
391
392
393
	/**
394
	 * Modifies the cached body content to replace content based on sessions or cookies.
395
	 *
396
	 * @param string $content Cached content
397
	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
398
	 * @return string Modified body content
399
	 */
400
	public function modifyBody( string $content, string $uid ) : string
401
	{
402
		$content = parent::modifyBody( $content, $uid );
403
404
		return $this->replaceSection( $content, $this->getView()->csrf()->formfield(), 'catalog.detail.csrf' );
405
	}
406
407
408
	/**
409
	 * Processes the input, e.g. store given values.
410
	 *
411
	 * A view must be available and this method doesn't generate any output
412
	 * besides setting view variables if necessary.
413
	 */
414
	public function process()
415
	{
416
		$context = $this->getContext();
417
		$view = $this->getView();
418
419
		try
420
		{
421
			$site = $context->getLocale()->getSiteItem()->getCode();
422
			$params = $this->getClientParams( $view->param() );
423
			$context->getSession()->set( 'aimeos/catalog/detail/params/last/' . $site, $params );
424
425
			parent::process();
426
		}
427
		catch( \Aimeos\Client\Html\Exception $e )
428
		{
429
			$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
430
			$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
431
		}
432
		catch( \Aimeos\Controller\Frontend\Exception $e )
433
		{
434
			$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
435
			$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
436
		}
437
		catch( \Aimeos\MShop\Exception $e )
438
		{
439
			$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
440
			$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
441
		}
442
		catch( \Exception $e )
443
		{
444
			$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
445
			$view->detailErrorList = array_merge( $view->get( 'detailErrorList', [] ), $error );
446
			$this->logException( $e );
447
		}
448
	}
449
450
451
	/**
452
	 * Returns the list of sub-client names configured for the client.
453
	 *
454
	 * @return array List of HTML client names
455
	 */
456
	protected function getSubClientNames() : array
457
	{
458
		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
459
	}
460
461
462
	/**
463
	 * Sets the necessary parameter values in the view.
464
	 *
465
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
466
	 * @param array &$tags Result array for the list of tags that are associated to the output
467
	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
468
	 * @return \Aimeos\MW\View\Iface Modified view object
469
	 */
470
	public function addData( \Aimeos\MW\View\Iface $view, array &$tags = [], string &$expire = null ) : \Aimeos\MW\View\Iface
471
	{
472
		$context = $this->getContext();
473
		$config = $context->getConfig();
474
		$domains = [
475
			'attribute', 'media', 'media/property', 'price', 'product', 'product/property', 'text',
476
			'supplier' => ['text', 'media', 'supplier/address']
477
		];
478
479
		/** client/html/catalog/domains
480
		 * A list of domain names whose items should be available in the catalog view templates
481
		 *
482
		 * @see client/html/catalog/detail/domains
483
		 */
484
		$domains = $config->get( 'client/html/catalog/domains', $domains );
485
486
		/** client/html/catalog/detail/domains
487
		 * A list of domain names whose items should be available in the product detail view template
488
		 *
489
		 * The templates rendering product details usually add the images,
490
		 * prices, texts, attributes, products, etc. associated to the product
491
		 * item. If you want to display additional or less content, you can
492
		 * configure your own list of domains (attribute, media, price, product,
493
		 * text, etc. are domains) whose items are fetched from the storage.
494
		 * Please keep in mind that the more domains you add to the configuration,
495
		 * the more time is required for fetching the content!
496
		 *
497
		 * Since version 2014.05 this configuration option overwrites the
498
		 * "client/html/catalog/domains" option that allows to configure the
499
		 * domain names of the items fetched for all catalog related data.
500
		 *
501
		 * @param array List of domain names
502
		 * @since 2014.03
503
		 * @category Developer
504
		 * @see client/html/catalog/domains
505
		 * @see client/html/catalog/lists/domains
506
		 */
507
		$domains = $config->get( 'client/html/catalog/detail/domains', $domains );
508
509
		/** client/html/catalog/detail/prodid-default
510
		 * The default product ID used if none is given as parameter
511
		 *
512
		 * To display a product detail view or a part of it for a specific
513
		 * product, you can configure its ID using this setting. This is
514
		 * most useful in a CMS where the product ID can be configured
515
		 * separately for each content node.
516
		 *
517
		 * @param string Product ID
518
		 * @since 2016.01
519
		 * @category User
520
		 * @category Developer
521
		 * @see client/html/catalog/detail/prodid-default
522
		 * @see client/html/catalog/lists/catid-default
523
		 */
524
		$id = $view->param( 'd_prodid', $config->get( 'client/html/catalog/detail/prodid-default' ) );
525
526
		/** client/html/catalog/detail/prodcode-default
527
		 * The default product code used if none is given as parameter
528
		 *
529
		 * To display a product detail view or a part of it for a specific
530
		 * product, you can configure its code using this setting. This is
531
		 * most useful in a CMS where the product code can be configured
532
		 * separately for each content node.
533
		 *
534
		 * @param string Product code
535
		 * @since 2019.10
536
		 * @category User
537
		 * @category Developer
538
		 * @see client/html/catalog/detail/prodid-default
539
		 * @see client/html/catalog/lists/catid-default
540
		 */
541
		$code = $config->get( 'client/html/catalog/detail/prodcode-default' );
542
543
		$name = $view->param( 'd_name', '' );
544
		$cntl = \Aimeos\Controller\Frontend::create( $context, 'product' )->uses( $domains );
545
546
		$productItem = ( $id ? $cntl->get( $id ) : ( $code ? $cntl->find( $code ) : $cntl->resolve( $name ) ) );
547
548
		$this->addMetaItems( $productItem, $expire, $tags );
549
		$this->addMetaItems( $productItem->getSupplierItems(), $expire, $tags );
550
551
		$propMap = $attrMap = [];
552
		$propItems = $productItem->getPropertyItems();
553
		$attrItems = $productItem->getRefItems( 'attribute', null, 'default' );
554
		$mediaItems = $productItem->getRefItems( 'media', 'default', 'default' );
555
556
		if( in_array( $productItem->getType(), ['bundle', 'select'] ) )
557
		{
558
			foreach( $productItem->getRefItems( 'product', null, 'default' ) as $subProdId => $subProduct )
559
			{
560
				$propItems->merge( $subProduct->getPropertyItems()->assign( ['parent' => $subProdId] ) );
561
				$mediaItems->merge( $subProduct->getRefItems( 'media', 'default', 'default' ) );
562
				$attrItems->merge( $subProduct->getRefItems( 'attribute', null, 'default' )
563
					->merge( $subProduct->getRefItems( 'attribute', null, 'variant' ) )
564
					->assign( ['parent' => $subProdId] ) );
565
			}
566
		}
567
568
		foreach( $attrItems as $attrId => $attrItem ) {
569
			$attrMap[$attrItem->getType()][$attrId] = $attrItem;
570
		}
571
572
		foreach( $propItems as $propItem ) {
573
			$propMap[$propItem->getType()][$propItem->getId()] = $propItem;
574
		}
575
576
577
		/** client/html/catalog/detail/stock/enable
578
		 * Enables or disables displaying product stock levels in product detail view
579
		 *
580
		 * This configuration option allows shop owners to display product
581
		 * stock levels for each product in the detail views or to disable
582
		 * fetching product stock information.
583
		 *
584
		 * The stock information is fetched via AJAX and inserted via Javascript.
585
		 * This allows to cache product items by leaving out such highly
586
		 * dynamic content like stock levels which changes with each order.
587
		 *
588
		 * @param boolean Value of "1" to display stock levels, "0" to disable displaying them
589
		 * @since 2014.03
590
		 * @category User
591
		 * @category Developer
592
		 * @see client/html/catalog/lists/stock/enable
593
		 * @see client/html/catalog/stock/url/target
594
		 * @see client/html/catalog/stock/url/controller
595
		 * @see client/html/catalog/stock/url/action
596
		 * @see client/html/catalog/stock/url/config
597
		 */
598
599
		if( (bool) $view->config( 'client/html/catalog/detail/stock/enable', true ) === true )
600
		{
601
			$products = $productItem->getRefItems( 'product', null, 'default' )->push( $productItem );
602
			$view->detailStockUrl = $this->getStockUrl( $view, $products );
603
		}
604
605
		$view->detailMediaItems = $mediaItems;
606
		$view->detailProductItem = $productItem;
607
		$view->detailPropertyMap = map( $propMap );
608
		$view->detailAttributeMap = map( $attrMap );
609
610
		return parent::addData( $view, $tags, $expire );
611
	}
612
}
613