Completed
Push — master ( 7658b0...33a95e )
by Aimeos
05:49
created
client/html/src/Client/Html/Catalog/Filter/Tree/Standard.php 2 patches
Indentation   +443 added lines, -443 removed lines patch added patch discarded remove patch
@@ -19,448 +19,448 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 class Standard
22
-	extends \Aimeos\Client\Html\Common\Client\Factory\Base
23
-	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
22
+    extends \Aimeos\Client\Html\Common\Client\Factory\Base
23
+    implements \Aimeos\Client\Html\Common\Client\Factory\Iface
24 24
 {
25
-	/** client/html/catalog/filter/tree/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog filter tree 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/filter/tree/standard/subparts';
59
-	private $subPartNames = array();
60
-	private $tags = array();
61
-	private $expire;
62
-	private $cache;
63
-
64
-
65
-	/**
66
-	 * Returns the HTML code for insertion into the body.
67
-	 *
68
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
69
-	 * @param array &$tags Result array for the list of tags that are associated to the output
70
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
71
-	 * @return string HTML code
72
-	 */
73
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
74
-	{
75
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
76
-
77
-		$html = '';
78
-		foreach( $this->getSubClients() as $subclient ) {
79
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
80
-		}
81
-		$view->treeBody = $html;
82
-
83
-		/** client/html/catalog/filter/tree/standard/template-body
84
-		 * Relative path to the HTML body template of the catalog filter tree client.
85
-		 *
86
-		 * The template file contains the HTML code and processing instructions
87
-		 * to generate the result shown in the body of the frontend. The
88
-		 * configuration string is the path to the template file relative
89
-		 * to the templates directory (usually in client/html/templates).
90
-		 *
91
-		 * You can overwrite the template file configuration in extensions and
92
-		 * provide alternative templates. These alternative templates should be
93
-		 * named like the default one but with the string "standard" replaced by
94
-		 * an unique name. You may use the name of your project for this. If
95
-		 * you've implemented an alternative client class as well, "standard"
96
-		 * should be replaced by the name of the new class.
97
-		 *
98
-		 * @param string Relative path to the template creating code for the HTML page body
99
-		 * @since 2014.03
100
-		 * @category Developer
101
-		 * @see client/html/catalog/filter/tree/standard/template-header
102
-		 */
103
-		$tplconf = 'client/html/catalog/filter/tree/standard/template-body';
104
-		$default = 'catalog/filter/tree-body-default.php';
105
-
106
-		return $view->render( $view->config( $tplconf, $default ) );
107
-	}
108
-
109
-
110
-	/**
111
-	 * Returns the HTML string for insertion into the header.
112
-	 *
113
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
114
-	 * @param array &$tags Result array for the list of tags that are associated to the output
115
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
116
-	 * @return string|null String including HTML tags for the header on error
117
-	 */
118
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
119
-	{
120
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
121
-
122
-		$html = '';
123
-		foreach( $this->getSubClients() as $subclient ) {
124
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
125
-		}
126
-		$view->treeHeader = $html;
127
-
128
-		/** client/html/catalog/filter/tree/standard/template-header
129
-		 * Relative path to the HTML header template of the catalog filter tree client.
130
-		 *
131
-		 * The template file contains the HTML code and processing instructions
132
-		 * to generate the HTML code that is inserted into the HTML page header
133
-		 * of the rendered page in the frontend. The configuration string is the
134
-		 * path to the template file relative to the templates directory (usually
135
-		 * in client/html/templates).
136
-		 *
137
-		 * You can overwrite the template file configuration in extensions and
138
-		 * provide alternative templates. These alternative templates should be
139
-		 * named like the default one but with the string "standard" replaced by
140
-		 * an unique name. You may use the name of your project for this. If
141
-		 * you've implemented an alternative client class as well, "standard"
142
-		 * should be replaced by the name of the new class.
143
-		 *
144
-		 * @param string Relative path to the template creating code for the HTML page head
145
-		 * @since 2014.03
146
-		 * @category Developer
147
-		 * @see client/html/catalog/filter/tree/standard/template-body
148
-		 */
149
-		$tplconf = 'client/html/catalog/filter/tree/standard/template-header';
150
-		$default = 'catalog/filter/tree-header-default.php';
151
-
152
-		return $view->render( $view->config( $tplconf, $default ) );
153
-	}
154
-
155
-
156
-	/**
157
-	 * Returns the sub-client given by its name.
158
-	 *
159
-	 * @param string $type Name of the client type
160
-	 * @param string|null $name Name of the sub-client (Default if null)
161
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
162
-	 */
163
-	public function getSubClient( $type, $name = null )
164
-	{
165
-		/** client/html/catalog/filter/tree/decorators/excludes
166
-		 * Excludes decorators added by the "common" option from the catalog filter tree html client
167
-		 *
168
-		 * Decorators extend the functionality of a class by adding new aspects
169
-		 * (e.g. log what is currently done), executing the methods of the underlying
170
-		 * class only in certain conditions (e.g. only for logged in users) or
171
-		 * modify what is returned to the caller.
172
-		 *
173
-		 * This option allows you to remove a decorator added via
174
-		 * "client/html/common/decorators/default" before they are wrapped
175
-		 * around the html client.
176
-		 *
177
-		 *  client/html/catalog/filter/tree/decorators/excludes = array( 'decorator1' )
178
-		 *
179
-		 * This would remove the decorator named "decorator1" from the list of
180
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
181
-		 * "client/html/common/decorators/default" to the html client.
182
-		 *
183
-		 * @param array List of decorator names
184
-		 * @since 2015.08
185
-		 * @category Developer
186
-		 * @see client/html/common/decorators/default
187
-		 * @see client/html/catalog/filter/tree/decorators/global
188
-		 * @see client/html/catalog/filter/tree/decorators/local
189
-		 */
190
-
191
-		/** client/html/catalog/filter/tree/decorators/global
192
-		 * Adds a list of globally available decorators only to the catalog filter tree html client
193
-		 *
194
-		 * Decorators extend the functionality of a class by adding new aspects
195
-		 * (e.g. log what is currently done), executing the methods of the underlying
196
-		 * class only in certain conditions (e.g. only for logged in users) or
197
-		 * modify what is returned to the caller.
198
-		 *
199
-		 * This option allows you to wrap global decorators
200
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
201
-		 *
202
-		 *  client/html/catalog/filter/tree/decorators/global = array( 'decorator1' )
203
-		 *
204
-		 * This would add the decorator named "decorator1" defined by
205
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
206
-		 *
207
-		 * @param array List of decorator names
208
-		 * @since 2015.08
209
-		 * @category Developer
210
-		 * @see client/html/common/decorators/default
211
-		 * @see client/html/catalog/filter/tree/decorators/excludes
212
-		 * @see client/html/catalog/filter/tree/decorators/local
213
-		 */
214
-
215
-		/** client/html/catalog/filter/tree/decorators/local
216
-		 * Adds a list of local decorators only to the catalog filter tree html client
217
-		 *
218
-		 * Decorators extend the functionality of a class by adding new aspects
219
-		 * (e.g. log what is currently done), executing the methods of the underlying
220
-		 * class only in certain conditions (e.g. only for logged in users) or
221
-		 * modify what is returned to the caller.
222
-		 *
223
-		 * This option allows you to wrap local decorators
224
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
225
-		 *
226
-		 *  client/html/catalog/filter/tree/decorators/local = array( 'decorator2' )
227
-		 *
228
-		 * This would add the decorator named "decorator2" defined by
229
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
230
-		 *
231
-		 * @param array List of decorator names
232
-		 * @since 2015.08
233
-		 * @category Developer
234
-		 * @see client/html/common/decorators/default
235
-		 * @see client/html/catalog/filter/tree/decorators/excludes
236
-		 * @see client/html/catalog/filter/tree/decorators/global
237
-		 */
238
-
239
-		return $this->createSubClient( 'catalog/filter/tree/' . $type, $name );
240
-	}
241
-
242
-
243
-	/**
244
-	 * Returns the list of sub-client names configured for the client.
245
-	 *
246
-	 * @return array List of HTML client names
247
-	 */
248
-	protected function getSubClientNames()
249
-	{
250
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
251
-	}
252
-
253
-
254
-	/**
255
-	 * Sets the necessary parameter values in the view.
256
-	 *
257
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
258
-	 * @param array &$tags Result array for the list of tags that are associated to the output
259
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
260
-	 * @return \Aimeos\MW\View\Iface Modified view object
261
-	 */
262
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
263
-	{
264
-		if( !isset( $this->cache ) )
265
-		{
266
-			$catItems = array();
267
-			$context = $this->getContext();
268
-			$controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
269
-
270
-			$currentid = (string) $view->param( 'f_catid', '' );
271
-			$currentid = ( $currentid != '' ? $currentid : null );
272
-
273
-			/** client/html/catalog/filter/tree/startid
274
-			 * The ID of the category node that should be the root of the displayed category tree
275
-			 *
276
-			 * If you want to display only a part of your category tree, you can
277
-			 * configure the ID of the category node from which rendering the
278
-			 * remaining sub-tree should start.
279
-			 *
280
-			 * In most cases you can set this value via the administration interface
281
-			 * of the shop application. In that case you often can configure the
282
-			 * start ID individually for each catalog filter.
283
-			 *
284
-			 * @param string Category ID
285
-			 * @since 2014.03
286
-			 * @category User
287
-			 * @category Developer
288
-			 * @see client/html/catalog/filter/tree/levels-always
289
-			 * @see client/html/catalog/filter/tree/levels-only
290
-			 * @see client/html/catalog/filter/tree/domains
291
-			 */
292
-			$startid = $view->config( 'client/html/catalog/filter/tree/startid', '' );
293
-			$startid = ( $startid != '' ? $startid : null );
294
-
295
-			/** client/html/catalog/filter/tree/domains
296
-			 * List of domain names whose items should be fetched with the filter categories
297
-			 *
298
-			 * The templates rendering the categories in the catalog filter usually
299
-			 * add the images and texts associated to each item. If you want to
300
-			 * display additional content, you can configure your own list of
301
-			 * domains (attribute, media, price, product, text, etc. are domains)
302
-			 * whose items are fetched from the storage. Please keep in mind that
303
-			 * the more domains you add to the configuration, the more time is
304
-			 * required for fetching the content!
305
-			 *
306
-			 * @param array List of domain item names
307
-			 * @since 2014.03
308
-			 * @category Developer
309
-			 * @see client/html/catalog/filter/tree/startid
310
-			 * @see client/html/catalog/filter/tree/levels-always
311
-			 * @see client/html/catalog/filter/tree/levels-only
312
-			 */
313
-			$ref = $view->config( 'client/html/catalog/filter/tree/domains', array( 'text', 'media' ) );
314
-
315
-
316
-			if( $currentid !== null )
317
-			{
318
-				$catItems = $controller->getCatalogPath( $currentid );
319
-
320
-				if( $startid )
321
-				{
322
-					foreach( $catItems as $key => $item )
323
-					{
324
-						if( $key == $startid ) {
325
-							break;
326
-						}
327
-						unset( $catItems[$key] );
328
-					}
329
-				}
330
-			}
331
-
332
-			if( ( $node = reset( $catItems ) ) === false )
333
-			{
334
-				$node = $controller->getCatalogTree( $startid, array(), \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE );
335
-				$catItems = array( $node->getId() => $node );
336
-			}
337
-
338
-
339
-			$search = $controller->createCatalogFilter();
340
-			$expr = $search->compare( '==', 'catalog.parentid', array_keys( $catItems ) );
341
-			$expr = $search->combine( '||', array( $expr, $search->compare( '==', 'catalog.id', $node->getId() ) ) );
342
-
343
-			/** client/html/catalog/filter/tree/levels-always
344
-			 * The number of levels in the category tree that should be always displayed
345
-			 *
346
-			 * Usually, only the root node and the first level of the category
347
-			 * tree is shown in the frontend. Only if the user clicks on a
348
-			 * node in the first level, the page reloads and the sub-nodes of
349
-			 * the chosen category are rendered as well.
350
-			 *
351
-			 * Using this configuration option you can enforce the given number
352
-			 * of levels to be always displayed. The root node uses level 0, the
353
-			 * categories below level 1 and so on.
354
-			 *
355
-			 * In most cases you can set this value via the administration interface
356
-			 * of the shop application. In that case you often can configure the
357
-			 * levels individually for each catalog filter.
358
-			 *
359
-			 * @param integer Number of tree levels
360
-			 * @since 2014.03
361
-			 * @category User
362
-			 * @category Developer
363
-			 * @see client/html/catalog/filter/tree/startid
364
-			 * @see client/html/catalog/filter/tree/levels-only
365
-			 * @see client/html/catalog/filter/tree/domains
366
-			 */
367
-			if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-always' ) ) != null ) {
368
-				$expr = $search->combine( '||', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
369
-			}
370
-
371
-			/** client/html/catalog/filter/tree/levels-only
372
-			 * No more than this number of levels in the category tree should be displayed
373
-			 *
374
-			 * If the user clicks on a category node, the page reloads and the
375
-			 * sub-nodes of the chosen category are rendered as well.
376
-			 * Using this configuration option you can enforce that no more than
377
-			 * the given number of levels will be displayed at all. The root
378
-			 * node uses level 0, the categories below level 1 and so on.
379
-			 *
380
-			 * In most cases you can set this value via the administration interface
381
-			 * of the shop application. In that case you often can configure the
382
-			 * levels individually for each catalog filter.
383
-			 *
384
-			 * @param integer Number of tree levels
385
-			 * @since 2014.03
386
-			 * @category User
387
-			 * @category Developer
388
-			 * @see client/html/catalog/filter/tree/startid
389
-			 * @see client/html/catalog/filter/tree/levels-always
390
-			 * @see client/html/catalog/filter/tree/domains
391
-			 */
392
-			if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-only' ) ) != null ) {
393
-				$expr = $search->combine( '&&', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
394
-			}
395
-
396
-			$search->setConditions( $expr );
397
-
398
-			$level = \Aimeos\MW\Tree\Manager\Base::LEVEL_TREE;
399
-
400
-			$view->treeCatalogPath = $catItems;
401
-			$view->treeCatalogTree = $controller->getCatalogTree( $startid, $ref, $level, $search );
402
-			$view->treeCatalogIds = $this->getCatalogIds( $view->treeCatalogTree, $catItems, $currentid );
403
-			$view->treeFilterParams = $this->getClientParams( $view->param(), array( 'f' ) );
404
-
405
-			$this->addMetaItemCatalog( $view->treeCatalogTree, $this->expire, $this->tags );
406
-
407
-			$this->cache = $view;
408
-		}
409
-
410
-		$expire = $this->expires( $this->expire, $expire );
411
-		$tags = array_merge( $tags, $this->tags );
412
-
413
-		return $this->cache;
414
-	}
415
-
416
-
417
-	/**
418
-	 * Returns the category IDs of the given catalog tree.
419
-	 *
420
-	 * Only the IDs of the children of the current category are returned.
421
-	 *
422
-	 * @param \Aimeos\MShop\Catalog\Item\Iface $tree Catalog node as entry point of the tree
423
-	 * @param array $path Associative list of category IDs as keys and the catalog
424
-	 * 	nodes from the currently selected category up to the root node
425
-	 * @param string $currentId Currently selected category
426
-	 * @return array List of category IDs
427
-	 */
428
-	protected function getCatalogIds( \Aimeos\MShop\Catalog\Item\Iface $tree, array $path, $currentId )
429
-	{
430
-		if( $tree->getId() == $currentId )
431
-		{
432
-			$ids = array();
433
-			foreach( $tree->getChildren() as $item ) {
434
-				$ids[] = $item->getId();
435
-			}
436
-
437
-			return $ids;
438
-		}
439
-
440
-		foreach( $tree->getChildren() as $child )
441
-		{
442
-			if( isset( $path[$child->getId()] ) ) {
443
-				return $this->getCatalogIds( $child, $path, $currentId );
444
-			}
445
-		}
446
-
447
-		return array();
448
-	}
449
-
450
-
451
-	/**
452
-	 * Adds the cache tags to the given list and sets a new expiration date if necessary based on the given catalog tree.
453
-	 *
454
-	 * @param \Aimeos\MShop\Catalog\Item\Iface $tree Tree node, maybe with sub-nodes
455
-	 * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
456
-	 * @param array &$tags List of tags the new tags will be added to
457
-	 */
458
-	protected function addMetaItemCatalog( \Aimeos\MShop\Catalog\Item\Iface $tree, &$expire, array &$tags = array() )
459
-	{
460
-		$this->addMetaItem( $tree, 'catalog', $expire, $tags );
461
-
462
-		foreach( $tree->getChildren() as $child ) {
463
-			$this->addMetaItemCatalog( $child, $expire, $tags );
464
-		}
465
-	}
25
+    /** client/html/catalog/filter/tree/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog filter tree 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/filter/tree/standard/subparts';
59
+    private $subPartNames = array();
60
+    private $tags = array();
61
+    private $expire;
62
+    private $cache;
63
+
64
+
65
+    /**
66
+     * Returns the HTML code for insertion into the body.
67
+     *
68
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
69
+     * @param array &$tags Result array for the list of tags that are associated to the output
70
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
71
+     * @return string HTML code
72
+     */
73
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
74
+    {
75
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
76
+
77
+        $html = '';
78
+        foreach( $this->getSubClients() as $subclient ) {
79
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
80
+        }
81
+        $view->treeBody = $html;
82
+
83
+        /** client/html/catalog/filter/tree/standard/template-body
84
+         * Relative path to the HTML body template of the catalog filter tree client.
85
+         *
86
+         * The template file contains the HTML code and processing instructions
87
+         * to generate the result shown in the body of the frontend. The
88
+         * configuration string is the path to the template file relative
89
+         * to the templates directory (usually in client/html/templates).
90
+         *
91
+         * You can overwrite the template file configuration in extensions and
92
+         * provide alternative templates. These alternative templates should be
93
+         * named like the default one but with the string "standard" replaced by
94
+         * an unique name. You may use the name of your project for this. If
95
+         * you've implemented an alternative client class as well, "standard"
96
+         * should be replaced by the name of the new class.
97
+         *
98
+         * @param string Relative path to the template creating code for the HTML page body
99
+         * @since 2014.03
100
+         * @category Developer
101
+         * @see client/html/catalog/filter/tree/standard/template-header
102
+         */
103
+        $tplconf = 'client/html/catalog/filter/tree/standard/template-body';
104
+        $default = 'catalog/filter/tree-body-default.php';
105
+
106
+        return $view->render( $view->config( $tplconf, $default ) );
107
+    }
108
+
109
+
110
+    /**
111
+     * Returns the HTML string for insertion into the header.
112
+     *
113
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
114
+     * @param array &$tags Result array for the list of tags that are associated to the output
115
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
116
+     * @return string|null String including HTML tags for the header on error
117
+     */
118
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
119
+    {
120
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
121
+
122
+        $html = '';
123
+        foreach( $this->getSubClients() as $subclient ) {
124
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
125
+        }
126
+        $view->treeHeader = $html;
127
+
128
+        /** client/html/catalog/filter/tree/standard/template-header
129
+         * Relative path to the HTML header template of the catalog filter tree client.
130
+         *
131
+         * The template file contains the HTML code and processing instructions
132
+         * to generate the HTML code that is inserted into the HTML page header
133
+         * of the rendered page in the frontend. The configuration string is the
134
+         * path to the template file relative to the templates directory (usually
135
+         * in client/html/templates).
136
+         *
137
+         * You can overwrite the template file configuration in extensions and
138
+         * provide alternative templates. These alternative templates should be
139
+         * named like the default one but with the string "standard" replaced by
140
+         * an unique name. You may use the name of your project for this. If
141
+         * you've implemented an alternative client class as well, "standard"
142
+         * should be replaced by the name of the new class.
143
+         *
144
+         * @param string Relative path to the template creating code for the HTML page head
145
+         * @since 2014.03
146
+         * @category Developer
147
+         * @see client/html/catalog/filter/tree/standard/template-body
148
+         */
149
+        $tplconf = 'client/html/catalog/filter/tree/standard/template-header';
150
+        $default = 'catalog/filter/tree-header-default.php';
151
+
152
+        return $view->render( $view->config( $tplconf, $default ) );
153
+    }
154
+
155
+
156
+    /**
157
+     * Returns the sub-client given by its name.
158
+     *
159
+     * @param string $type Name of the client type
160
+     * @param string|null $name Name of the sub-client (Default if null)
161
+     * @return \Aimeos\Client\Html\Iface Sub-client object
162
+     */
163
+    public function getSubClient( $type, $name = null )
164
+    {
165
+        /** client/html/catalog/filter/tree/decorators/excludes
166
+         * Excludes decorators added by the "common" option from the catalog filter tree html client
167
+         *
168
+         * Decorators extend the functionality of a class by adding new aspects
169
+         * (e.g. log what is currently done), executing the methods of the underlying
170
+         * class only in certain conditions (e.g. only for logged in users) or
171
+         * modify what is returned to the caller.
172
+         *
173
+         * This option allows you to remove a decorator added via
174
+         * "client/html/common/decorators/default" before they are wrapped
175
+         * around the html client.
176
+         *
177
+         *  client/html/catalog/filter/tree/decorators/excludes = array( 'decorator1' )
178
+         *
179
+         * This would remove the decorator named "decorator1" from the list of
180
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
181
+         * "client/html/common/decorators/default" to the html client.
182
+         *
183
+         * @param array List of decorator names
184
+         * @since 2015.08
185
+         * @category Developer
186
+         * @see client/html/common/decorators/default
187
+         * @see client/html/catalog/filter/tree/decorators/global
188
+         * @see client/html/catalog/filter/tree/decorators/local
189
+         */
190
+
191
+        /** client/html/catalog/filter/tree/decorators/global
192
+         * Adds a list of globally available decorators only to the catalog filter tree html client
193
+         *
194
+         * Decorators extend the functionality of a class by adding new aspects
195
+         * (e.g. log what is currently done), executing the methods of the underlying
196
+         * class only in certain conditions (e.g. only for logged in users) or
197
+         * modify what is returned to the caller.
198
+         *
199
+         * This option allows you to wrap global decorators
200
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
201
+         *
202
+         *  client/html/catalog/filter/tree/decorators/global = array( 'decorator1' )
203
+         *
204
+         * This would add the decorator named "decorator1" defined by
205
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
206
+         *
207
+         * @param array List of decorator names
208
+         * @since 2015.08
209
+         * @category Developer
210
+         * @see client/html/common/decorators/default
211
+         * @see client/html/catalog/filter/tree/decorators/excludes
212
+         * @see client/html/catalog/filter/tree/decorators/local
213
+         */
214
+
215
+        /** client/html/catalog/filter/tree/decorators/local
216
+         * Adds a list of local decorators only to the catalog filter tree html client
217
+         *
218
+         * Decorators extend the functionality of a class by adding new aspects
219
+         * (e.g. log what is currently done), executing the methods of the underlying
220
+         * class only in certain conditions (e.g. only for logged in users) or
221
+         * modify what is returned to the caller.
222
+         *
223
+         * This option allows you to wrap local decorators
224
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
225
+         *
226
+         *  client/html/catalog/filter/tree/decorators/local = array( 'decorator2' )
227
+         *
228
+         * This would add the decorator named "decorator2" defined by
229
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
230
+         *
231
+         * @param array List of decorator names
232
+         * @since 2015.08
233
+         * @category Developer
234
+         * @see client/html/common/decorators/default
235
+         * @see client/html/catalog/filter/tree/decorators/excludes
236
+         * @see client/html/catalog/filter/tree/decorators/global
237
+         */
238
+
239
+        return $this->createSubClient( 'catalog/filter/tree/' . $type, $name );
240
+    }
241
+
242
+
243
+    /**
244
+     * Returns the list of sub-client names configured for the client.
245
+     *
246
+     * @return array List of HTML client names
247
+     */
248
+    protected function getSubClientNames()
249
+    {
250
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
251
+    }
252
+
253
+
254
+    /**
255
+     * Sets the necessary parameter values in the view.
256
+     *
257
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
258
+     * @param array &$tags Result array for the list of tags that are associated to the output
259
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
260
+     * @return \Aimeos\MW\View\Iface Modified view object
261
+     */
262
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
263
+    {
264
+        if( !isset( $this->cache ) )
265
+        {
266
+            $catItems = array();
267
+            $context = $this->getContext();
268
+            $controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
269
+
270
+            $currentid = (string) $view->param( 'f_catid', '' );
271
+            $currentid = ( $currentid != '' ? $currentid : null );
272
+
273
+            /** client/html/catalog/filter/tree/startid
274
+             * The ID of the category node that should be the root of the displayed category tree
275
+             *
276
+             * If you want to display only a part of your category tree, you can
277
+             * configure the ID of the category node from which rendering the
278
+             * remaining sub-tree should start.
279
+             *
280
+             * In most cases you can set this value via the administration interface
281
+             * of the shop application. In that case you often can configure the
282
+             * start ID individually for each catalog filter.
283
+             *
284
+             * @param string Category ID
285
+             * @since 2014.03
286
+             * @category User
287
+             * @category Developer
288
+             * @see client/html/catalog/filter/tree/levels-always
289
+             * @see client/html/catalog/filter/tree/levels-only
290
+             * @see client/html/catalog/filter/tree/domains
291
+             */
292
+            $startid = $view->config( 'client/html/catalog/filter/tree/startid', '' );
293
+            $startid = ( $startid != '' ? $startid : null );
294
+
295
+            /** client/html/catalog/filter/tree/domains
296
+             * List of domain names whose items should be fetched with the filter categories
297
+             *
298
+             * The templates rendering the categories in the catalog filter usually
299
+             * add the images and texts associated to each item. If you want to
300
+             * display additional content, you can configure your own list of
301
+             * domains (attribute, media, price, product, text, etc. are domains)
302
+             * whose items are fetched from the storage. Please keep in mind that
303
+             * the more domains you add to the configuration, the more time is
304
+             * required for fetching the content!
305
+             *
306
+             * @param array List of domain item names
307
+             * @since 2014.03
308
+             * @category Developer
309
+             * @see client/html/catalog/filter/tree/startid
310
+             * @see client/html/catalog/filter/tree/levels-always
311
+             * @see client/html/catalog/filter/tree/levels-only
312
+             */
313
+            $ref = $view->config( 'client/html/catalog/filter/tree/domains', array( 'text', 'media' ) );
314
+
315
+
316
+            if( $currentid !== null )
317
+            {
318
+                $catItems = $controller->getCatalogPath( $currentid );
319
+
320
+                if( $startid )
321
+                {
322
+                    foreach( $catItems as $key => $item )
323
+                    {
324
+                        if( $key == $startid ) {
325
+                            break;
326
+                        }
327
+                        unset( $catItems[$key] );
328
+                    }
329
+                }
330
+            }
331
+
332
+            if( ( $node = reset( $catItems ) ) === false )
333
+            {
334
+                $node = $controller->getCatalogTree( $startid, array(), \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE );
335
+                $catItems = array( $node->getId() => $node );
336
+            }
337
+
338
+
339
+            $search = $controller->createCatalogFilter();
340
+            $expr = $search->compare( '==', 'catalog.parentid', array_keys( $catItems ) );
341
+            $expr = $search->combine( '||', array( $expr, $search->compare( '==', 'catalog.id', $node->getId() ) ) );
342
+
343
+            /** client/html/catalog/filter/tree/levels-always
344
+             * The number of levels in the category tree that should be always displayed
345
+             *
346
+             * Usually, only the root node and the first level of the category
347
+             * tree is shown in the frontend. Only if the user clicks on a
348
+             * node in the first level, the page reloads and the sub-nodes of
349
+             * the chosen category are rendered as well.
350
+             *
351
+             * Using this configuration option you can enforce the given number
352
+             * of levels to be always displayed. The root node uses level 0, the
353
+             * categories below level 1 and so on.
354
+             *
355
+             * In most cases you can set this value via the administration interface
356
+             * of the shop application. In that case you often can configure the
357
+             * levels individually for each catalog filter.
358
+             *
359
+             * @param integer Number of tree levels
360
+             * @since 2014.03
361
+             * @category User
362
+             * @category Developer
363
+             * @see client/html/catalog/filter/tree/startid
364
+             * @see client/html/catalog/filter/tree/levels-only
365
+             * @see client/html/catalog/filter/tree/domains
366
+             */
367
+            if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-always' ) ) != null ) {
368
+                $expr = $search->combine( '||', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
369
+            }
370
+
371
+            /** client/html/catalog/filter/tree/levels-only
372
+             * No more than this number of levels in the category tree should be displayed
373
+             *
374
+             * If the user clicks on a category node, the page reloads and the
375
+             * sub-nodes of the chosen category are rendered as well.
376
+             * Using this configuration option you can enforce that no more than
377
+             * the given number of levels will be displayed at all. The root
378
+             * node uses level 0, the categories below level 1 and so on.
379
+             *
380
+             * In most cases you can set this value via the administration interface
381
+             * of the shop application. In that case you often can configure the
382
+             * levels individually for each catalog filter.
383
+             *
384
+             * @param integer Number of tree levels
385
+             * @since 2014.03
386
+             * @category User
387
+             * @category Developer
388
+             * @see client/html/catalog/filter/tree/startid
389
+             * @see client/html/catalog/filter/tree/levels-always
390
+             * @see client/html/catalog/filter/tree/domains
391
+             */
392
+            if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-only' ) ) != null ) {
393
+                $expr = $search->combine( '&&', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
394
+            }
395
+
396
+            $search->setConditions( $expr );
397
+
398
+            $level = \Aimeos\MW\Tree\Manager\Base::LEVEL_TREE;
399
+
400
+            $view->treeCatalogPath = $catItems;
401
+            $view->treeCatalogTree = $controller->getCatalogTree( $startid, $ref, $level, $search );
402
+            $view->treeCatalogIds = $this->getCatalogIds( $view->treeCatalogTree, $catItems, $currentid );
403
+            $view->treeFilterParams = $this->getClientParams( $view->param(), array( 'f' ) );
404
+
405
+            $this->addMetaItemCatalog( $view->treeCatalogTree, $this->expire, $this->tags );
406
+
407
+            $this->cache = $view;
408
+        }
409
+
410
+        $expire = $this->expires( $this->expire, $expire );
411
+        $tags = array_merge( $tags, $this->tags );
412
+
413
+        return $this->cache;
414
+    }
415
+
416
+
417
+    /**
418
+     * Returns the category IDs of the given catalog tree.
419
+     *
420
+     * Only the IDs of the children of the current category are returned.
421
+     *
422
+     * @param \Aimeos\MShop\Catalog\Item\Iface $tree Catalog node as entry point of the tree
423
+     * @param array $path Associative list of category IDs as keys and the catalog
424
+     * 	nodes from the currently selected category up to the root node
425
+     * @param string $currentId Currently selected category
426
+     * @return array List of category IDs
427
+     */
428
+    protected function getCatalogIds( \Aimeos\MShop\Catalog\Item\Iface $tree, array $path, $currentId )
429
+    {
430
+        if( $tree->getId() == $currentId )
431
+        {
432
+            $ids = array();
433
+            foreach( $tree->getChildren() as $item ) {
434
+                $ids[] = $item->getId();
435
+            }
436
+
437
+            return $ids;
438
+        }
439
+
440
+        foreach( $tree->getChildren() as $child )
441
+        {
442
+            if( isset( $path[$child->getId()] ) ) {
443
+                return $this->getCatalogIds( $child, $path, $currentId );
444
+            }
445
+        }
446
+
447
+        return array();
448
+    }
449
+
450
+
451
+    /**
452
+     * Adds the cache tags to the given list and sets a new expiration date if necessary based on the given catalog tree.
453
+     *
454
+     * @param \Aimeos\MShop\Catalog\Item\Iface $tree Tree node, maybe with sub-nodes
455
+     * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
456
+     * @param array &$tags List of tags the new tags will be added to
457
+     */
458
+    protected function addMetaItemCatalog( \Aimeos\MShop\Catalog\Item\Iface $tree, &$expire, array &$tags = array() )
459
+    {
460
+        $this->addMetaItem( $tree, 'catalog', $expire, $tags );
461
+
462
+        foreach( $tree->getChildren() as $child ) {
463
+            $this->addMetaItemCatalog( $child, $expire, $tags );
464
+        }
465
+    }
466 466
 }
Please login to merge, or discard this patch.
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -70,13 +70,13 @@  discard block
 block discarded – undo
70 70
 	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
71 71
 	 * @return string HTML code
72 72
 	 */
73
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
73
+	public function getBody($uid = '', array &$tags = array(), &$expire = null)
74 74
 	{
75
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
75
+		$view = $this->setViewParams($this->getView(), $tags, $expire);
76 76
 
77 77
 		$html = '';
78
-		foreach( $this->getSubClients() as $subclient ) {
79
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
+		foreach ($this->getSubClients() as $subclient) {
79
+			$html .= $subclient->setView($view)->getBody($uid, $tags, $expire);
80 80
 		}
81 81
 		$view->treeBody = $html;
82 82
 
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 		$tplconf = 'client/html/catalog/filter/tree/standard/template-body';
104 104
 		$default = 'catalog/filter/tree-body-default.php';
105 105
 
106
-		return $view->render( $view->config( $tplconf, $default ) );
106
+		return $view->render($view->config($tplconf, $default));
107 107
 	}
108 108
 
109 109
 
@@ -115,13 +115,13 @@  discard block
 block discarded – undo
115 115
 	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
116 116
 	 * @return string|null String including HTML tags for the header on error
117 117
 	 */
118
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
118
+	public function getHeader($uid = '', array &$tags = array(), &$expire = null)
119 119
 	{
120
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
120
+		$view = $this->setViewParams($this->getView(), $tags, $expire);
121 121
 
122 122
 		$html = '';
123
-		foreach( $this->getSubClients() as $subclient ) {
124
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
+		foreach ($this->getSubClients() as $subclient) {
124
+			$html .= $subclient->setView($view)->getHeader($uid, $tags, $expire);
125 125
 		}
126 126
 		$view->treeHeader = $html;
127 127
 
@@ -149,7 +149,7 @@  discard block
 block discarded – undo
149 149
 		$tplconf = 'client/html/catalog/filter/tree/standard/template-header';
150 150
 		$default = 'catalog/filter/tree-header-default.php';
151 151
 
152
-		return $view->render( $view->config( $tplconf, $default ) );
152
+		return $view->render($view->config($tplconf, $default));
153 153
 	}
154 154
 
155 155
 
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
 	 * @param string|null $name Name of the sub-client (Default if null)
161 161
 	 * @return \Aimeos\Client\Html\Iface Sub-client object
162 162
 	 */
163
-	public function getSubClient( $type, $name = null )
163
+	public function getSubClient($type, $name = null)
164 164
 	{
165 165
 		/** client/html/catalog/filter/tree/decorators/excludes
166 166
 		 * Excludes decorators added by the "common" option from the catalog filter tree html client
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
 		 * @see client/html/catalog/filter/tree/decorators/global
237 237
 		 */
238 238
 
239
-		return $this->createSubClient( 'catalog/filter/tree/' . $type, $name );
239
+		return $this->createSubClient('catalog/filter/tree/'.$type, $name);
240 240
 	}
241 241
 
242 242
 
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
 	 */
248 248
 	protected function getSubClientNames()
249 249
 	{
250
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
250
+		return $this->getContext()->getConfig()->get($this->subPartPath, $this->subPartNames);
251 251
 	}
252 252
 
253 253
 
@@ -259,16 +259,16 @@  discard block
 block discarded – undo
259 259
 	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
260 260
 	 * @return \Aimeos\MW\View\Iface Modified view object
261 261
 	 */
262
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
262
+	protected function setViewParams(\Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null)
263 263
 	{
264
-		if( !isset( $this->cache ) )
264
+		if (!isset($this->cache))
265 265
 		{
266 266
 			$catItems = array();
267 267
 			$context = $this->getContext();
268
-			$controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
268
+			$controller = \Aimeos\Controller\Frontend\Factory::createController($context, 'catalog');
269 269
 
270
-			$currentid = (string) $view->param( 'f_catid', '' );
271
-			$currentid = ( $currentid != '' ? $currentid : null );
270
+			$currentid = (string) $view->param('f_catid', '');
271
+			$currentid = ($currentid != '' ? $currentid : null);
272 272
 
273 273
 			/** client/html/catalog/filter/tree/startid
274 274
 			 * The ID of the category node that should be the root of the displayed category tree
@@ -289,8 +289,8 @@  discard block
 block discarded – undo
289 289
 			 * @see client/html/catalog/filter/tree/levels-only
290 290
 			 * @see client/html/catalog/filter/tree/domains
291 291
 			 */
292
-			$startid = $view->config( 'client/html/catalog/filter/tree/startid', '' );
293
-			$startid = ( $startid != '' ? $startid : null );
292
+			$startid = $view->config('client/html/catalog/filter/tree/startid', '');
293
+			$startid = ($startid != '' ? $startid : null);
294 294
 
295 295
 			/** client/html/catalog/filter/tree/domains
296 296
 			 * List of domain names whose items should be fetched with the filter categories
@@ -310,35 +310,35 @@  discard block
 block discarded – undo
310 310
 			 * @see client/html/catalog/filter/tree/levels-always
311 311
 			 * @see client/html/catalog/filter/tree/levels-only
312 312
 			 */
313
-			$ref = $view->config( 'client/html/catalog/filter/tree/domains', array( 'text', 'media' ) );
313
+			$ref = $view->config('client/html/catalog/filter/tree/domains', array('text', 'media'));
314 314
 
315 315
 
316
-			if( $currentid !== null )
316
+			if ($currentid !== null)
317 317
 			{
318
-				$catItems = $controller->getCatalogPath( $currentid );
318
+				$catItems = $controller->getCatalogPath($currentid);
319 319
 
320
-				if( $startid )
320
+				if ($startid)
321 321
 				{
322
-					foreach( $catItems as $key => $item )
322
+					foreach ($catItems as $key => $item)
323 323
 					{
324
-						if( $key == $startid ) {
324
+						if ($key == $startid) {
325 325
 							break;
326 326
 						}
327
-						unset( $catItems[$key] );
327
+						unset($catItems[$key]);
328 328
 					}
329 329
 				}
330 330
 			}
331 331
 
332
-			if( ( $node = reset( $catItems ) ) === false )
332
+			if (($node = reset($catItems)) === false)
333 333
 			{
334
-				$node = $controller->getCatalogTree( $startid, array(), \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE );
335
-				$catItems = array( $node->getId() => $node );
334
+				$node = $controller->getCatalogTree($startid, array(), \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE);
335
+				$catItems = array($node->getId() => $node);
336 336
 			}
337 337
 
338 338
 
339 339
 			$search = $controller->createCatalogFilter();
340
-			$expr = $search->compare( '==', 'catalog.parentid', array_keys( $catItems ) );
341
-			$expr = $search->combine( '||', array( $expr, $search->compare( '==', 'catalog.id', $node->getId() ) ) );
340
+			$expr = $search->compare('==', 'catalog.parentid', array_keys($catItems));
341
+			$expr = $search->combine('||', array($expr, $search->compare('==', 'catalog.id', $node->getId())));
342 342
 
343 343
 			/** client/html/catalog/filter/tree/levels-always
344 344
 			 * The number of levels in the category tree that should be always displayed
@@ -364,8 +364,8 @@  discard block
 block discarded – undo
364 364
 			 * @see client/html/catalog/filter/tree/levels-only
365 365
 			 * @see client/html/catalog/filter/tree/domains
366 366
 			 */
367
-			if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-always' ) ) != null ) {
368
-				$expr = $search->combine( '||', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
367
+			if (($levels = $view->config('client/html/catalog/filter/tree/levels-always')) != null) {
368
+				$expr = $search->combine('||', array($expr, $search->compare('<=', 'catalog.level', $levels)));
369 369
 			}
370 370
 
371 371
 			/** client/html/catalog/filter/tree/levels-only
@@ -389,26 +389,26 @@  discard block
 block discarded – undo
389 389
 			 * @see client/html/catalog/filter/tree/levels-always
390 390
 			 * @see client/html/catalog/filter/tree/domains
391 391
 			 */
392
-			if( ( $levels = $view->config( 'client/html/catalog/filter/tree/levels-only' ) ) != null ) {
393
-				$expr = $search->combine( '&&', array( $expr, $search->compare( '<=', 'catalog.level', $levels ) ) );
392
+			if (($levels = $view->config('client/html/catalog/filter/tree/levels-only')) != null) {
393
+				$expr = $search->combine('&&', array($expr, $search->compare('<=', 'catalog.level', $levels)));
394 394
 			}
395 395
 
396
-			$search->setConditions( $expr );
396
+			$search->setConditions($expr);
397 397
 
398 398
 			$level = \Aimeos\MW\Tree\Manager\Base::LEVEL_TREE;
399 399
 
400 400
 			$view->treeCatalogPath = $catItems;
401
-			$view->treeCatalogTree = $controller->getCatalogTree( $startid, $ref, $level, $search );
402
-			$view->treeCatalogIds = $this->getCatalogIds( $view->treeCatalogTree, $catItems, $currentid );
403
-			$view->treeFilterParams = $this->getClientParams( $view->param(), array( 'f' ) );
401
+			$view->treeCatalogTree = $controller->getCatalogTree($startid, $ref, $level, $search);
402
+			$view->treeCatalogIds = $this->getCatalogIds($view->treeCatalogTree, $catItems, $currentid);
403
+			$view->treeFilterParams = $this->getClientParams($view->param(), array('f'));
404 404
 
405
-			$this->addMetaItemCatalog( $view->treeCatalogTree, $this->expire, $this->tags );
405
+			$this->addMetaItemCatalog($view->treeCatalogTree, $this->expire, $this->tags);
406 406
 
407 407
 			$this->cache = $view;
408 408
 		}
409 409
 
410
-		$expire = $this->expires( $this->expire, $expire );
411
-		$tags = array_merge( $tags, $this->tags );
410
+		$expire = $this->expires($this->expire, $expire);
411
+		$tags = array_merge($tags, $this->tags);
412 412
 
413 413
 		return $this->cache;
414 414
 	}
@@ -425,22 +425,22 @@  discard block
 block discarded – undo
425 425
 	 * @param string $currentId Currently selected category
426 426
 	 * @return array List of category IDs
427 427
 	 */
428
-	protected function getCatalogIds( \Aimeos\MShop\Catalog\Item\Iface $tree, array $path, $currentId )
428
+	protected function getCatalogIds(\Aimeos\MShop\Catalog\Item\Iface $tree, array $path, $currentId)
429 429
 	{
430
-		if( $tree->getId() == $currentId )
430
+		if ($tree->getId() == $currentId)
431 431
 		{
432 432
 			$ids = array();
433
-			foreach( $tree->getChildren() as $item ) {
433
+			foreach ($tree->getChildren() as $item) {
434 434
 				$ids[] = $item->getId();
435 435
 			}
436 436
 
437 437
 			return $ids;
438 438
 		}
439 439
 
440
-		foreach( $tree->getChildren() as $child )
440
+		foreach ($tree->getChildren() as $child)
441 441
 		{
442
-			if( isset( $path[$child->getId()] ) ) {
443
-				return $this->getCatalogIds( $child, $path, $currentId );
442
+			if (isset($path[$child->getId()])) {
443
+				return $this->getCatalogIds($child, $path, $currentId);
444 444
 			}
445 445
 		}
446 446
 
@@ -455,12 +455,12 @@  discard block
 block discarded – undo
455 455
 	 * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
456 456
 	 * @param array &$tags List of tags the new tags will be added to
457 457
 	 */
458
-	protected function addMetaItemCatalog( \Aimeos\MShop\Catalog\Item\Iface $tree, &$expire, array &$tags = array() )
458
+	protected function addMetaItemCatalog(\Aimeos\MShop\Catalog\Item\Iface $tree, &$expire, array &$tags = array())
459 459
 	{
460
-		$this->addMetaItem( $tree, 'catalog', $expire, $tags );
460
+		$this->addMetaItem($tree, 'catalog', $expire, $tags);
461 461
 
462
-		foreach( $tree->getChildren() as $child ) {
463
-			$this->addMetaItemCatalog( $child, $expire, $tags );
462
+		foreach ($tree->getChildren() as $child) {
463
+			$this->addMetaItemCatalog($child, $expire, $tags);
464 464
 		}
465 465
 	}
466 466
 }
Please login to merge, or discard this patch.
client/html/src/Client/Html/Common/Client/Factory/Iface.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -19,14 +19,14 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 interface Iface
22
-	extends \Aimeos\Client\Html\Iface
22
+    extends \Aimeos\Client\Html\Iface
23 23
 {
24
-	/**
25
-	 * Initializes the class instance.
26
-	 *
27
-	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
28
-	 * @param array $templatePaths Associative list of the file system paths to the core or the extensions as key
29
-	 * 	and a list of relative paths inside the core or the extension as values
30
-	 */
31
-	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths );
24
+    /**
25
+     * Initializes the class instance.
26
+     *
27
+     * @param \Aimeos\MShop\Context\Item\Iface $context Context object
28
+     * @param array $templatePaths Associative list of the file system paths to the core or the extensions as key
29
+     * 	and a list of relative paths inside the core or the extension as values
30
+     */
31
+    public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths );
32 32
 }
Please login to merge, or discard this patch.
client/html/src/Client/Html/Checkout/Standard/Process/Standard.php 1 patch
Indentation   +654 added lines, -654 removed lines patch added patch discarded remove patch
@@ -22,659 +22,659 @@
 block discarded – undo
22 22
  * @subpackage Html
23 23
  */
24 24
 class Standard
25
-	extends \Aimeos\Client\Html\Common\Client\Factory\Base
26
-	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
25
+    extends \Aimeos\Client\Html\Common\Client\Factory\Base
26
+    implements \Aimeos\Client\Html\Common\Client\Factory\Iface
27 27
 {
28
-	/** client/html/checkout/standard/process/standard/subparts
29
-	 * List of HTML sub-clients rendered within the checkout standard process section
30
-	 *
31
-	 * The output of the frontend is composed of the code generated by the HTML
32
-	 * clients. Each HTML client can consist of serveral (or none) sub-clients
33
-	 * that are responsible for rendering certain sub-parts of the output. The
34
-	 * sub-clients can contain HTML clients themselves and therefore a
35
-	 * hierarchical tree of HTML clients is composed. Each HTML client creates
36
-	 * the output that is placed inside the container of its parent.
37
-	 *
38
-	 * At first, always the HTML code generated by the parent is printed, then
39
-	 * the HTML code of its sub-clients. The order of the HTML sub-clients
40
-	 * determines the order of the output of these sub-clients inside the parent
41
-	 * container. If the configured list of clients is
42
-	 *
43
-	 *  array( "subclient1", "subclient2" )
44
-	 *
45
-	 * you can easily change the order of the output by reordering the subparts:
46
-	 *
47
-	 *  client/html/<clients>/subparts = array( "subclient1", "subclient2" )
48
-	 *
49
-	 * You can also remove one or more parts if they shouldn't be rendered:
50
-	 *
51
-	 *  client/html/<clients>/subparts = array( "subclient1" )
52
-	 *
53
-	 * As the clients only generates structural HTML, the layout defined via CSS
54
-	 * should support adding, removing or reordering content by a fluid like
55
-	 * design.
56
-	 *
57
-	 * @param array List of sub-client names
58
-	 * @since 2014.03
59
-	 * @category Developer
60
-	 */
61
-	private $subPartPath = 'client/html/checkout/standard/process/standard/subparts';
62
-	private $subPartNames = array();
63
-	private $cache;
64
-
65
-
66
-	/**
67
-	 * Returns the HTML code for insertion into the body.
68
-	 *
69
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
70
-	 * @param array &$tags Result array for the list of tags that are associated to the output
71
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
72
-	 * @return string HTML code
73
-	 */
74
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
75
-	{
76
-		$view = $this->getView();
77
-
78
-		if( !in_array( $view->get( 'standardStepActive' ), array( 'order', 'process' ) ) ) {
79
-			return '';
80
-		}
81
-
82
-		$view = $this->setViewParams( $view, $tags, $expire );
83
-
84
-		$html = '';
85
-		foreach( $this->getSubClients() as $subclient ) {
86
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
87
-		}
88
-		$view->processBody = $html;
89
-
90
-		/** client/html/checkout/standard/process/standard/template-body
91
-		 * Relative path to the HTML body template of the checkout standard process client.
92
-		 *
93
-		 * The template file contains the HTML code and processing instructions
94
-		 * to generate the result shown in the body of the frontend. The
95
-		 * configuration string is the path to the template file relative
96
-		 * to the templates directory (usually in client/html/templates).
97
-		 *
98
-		 * You can overwrite the template file configuration in extensions and
99
-		 * provide alternative templates. These alternative templates should be
100
-		 * named like the default one but with the string "standard" replaced by
101
-		 * an unique name. You may use the name of your project for this. If
102
-		 * you've implemented an alternative client class as well, "standard"
103
-		 * should be replaced by the name of the new class.
104
-		 *
105
-		 * @param string Relative path to the template creating code for the HTML page body
106
-		 * @since 2014.03
107
-		 * @category Developer
108
-		 * @see client/html/checkout/standard/process/standard/template-header
109
-		 */
110
-		$tplconf = 'client/html/checkout/standard/process/standard/template-body';
111
-		$default = 'checkout/standard/process-body-default.php';
112
-
113
-		return $view->render( $view->config( $tplconf, $default ) );
114
-	}
115
-
116
-
117
-	/**
118
-	 * Returns the HTML string for insertion into the header.
119
-	 *
120
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
121
-	 * @param array &$tags Result array for the list of tags that are associated to the output
122
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
123
-	 * @return string|null String including HTML tags for the header on error
124
-	 */
125
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
126
-	{
127
-		$view = $this->getView();
128
-
129
-		if( !in_array( $view->param( 'standardStepActive' ), array( 'order', 'process' ) ) ) {
130
-			return '';
131
-		}
132
-
133
-		$view = $this->setViewParams( $view, $tags, $expire );
134
-
135
-		$html = '';
136
-		foreach( $this->getSubClients() as $subclient ) {
137
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
138
-		}
139
-		$view->processHeader = $html;
140
-
141
-		/** client/html/checkout/standard/process/standard/template-header
142
-		 * Relative path to the HTML header template of the checkout standard process client.
143
-		 *
144
-		 * The template file contains the HTML code and processing instructions
145
-		 * to generate the HTML code that is inserted into the HTML page header
146
-		 * of the rendered page in the frontend. The configuration string is the
147
-		 * path to the template file relative to the templates directory (usually
148
-		 * in client/html/templates).
149
-		 *
150
-		 * You can overwrite the template file configuration in extensions and
151
-		 * provide alternative templates. These alternative templates should be
152
-		 * named like the default one but with the string "standard" replaced by
153
-		 * an unique name. You may use the name of your project for this. If
154
-		 * you've implemented an alternative client class as well, "standard"
155
-		 * should be replaced by the name of the new class.
156
-		 *
157
-		 * @param string Relative path to the template creating code for the HTML page head
158
-		 * @since 2014.03
159
-		 * @category Developer
160
-		 * @see client/html/checkout/standard/process/standard/template-body
161
-		 */
162
-		$tplconf = 'client/html/checkout/standard/process/standard/template-header';
163
-		$default = 'checkout/standard/process-header-default.php';
164
-
165
-		return $view->render( $view->config( $tplconf, $default ) );
166
-	}
167
-
168
-
169
-	/**
170
-	 * Returns the sub-client given by its name.
171
-	 *
172
-	 * @param string $type Name of the client type
173
-	 * @param string|null $name Name of the sub-client (Default if null)
174
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
175
-	 */
176
-	public function getSubClient( $type, $name = null )
177
-	{
178
-		/** client/html/checkout/standard/process/decorators/excludes
179
-		 * Excludes decorators added by the "common" option from the checkout standard process html client
180
-		 *
181
-		 * Decorators extend the functionality of a class by adding new aspects
182
-		 * (e.g. log what is currently done), executing the methods of the underlying
183
-		 * class only in certain conditions (e.g. only for logged in users) or
184
-		 * modify what is returned to the caller.
185
-		 *
186
-		 * This option allows you to remove a decorator added via
187
-		 * "client/html/common/decorators/default" before they are wrapped
188
-		 * around the html client.
189
-		 *
190
-		 *  client/html/checkout/standard/process/decorators/excludes = array( 'decorator1' )
191
-		 *
192
-		 * This would remove the decorator named "decorator1" from the list of
193
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
194
-		 * "client/html/common/decorators/default" to the html client.
195
-		 *
196
-		 * @param array List of decorator names
197
-		 * @since 2015.08
198
-		 * @category Developer
199
-		 * @see client/html/common/decorators/default
200
-		 * @see client/html/checkout/standard/process/decorators/global
201
-		 * @see client/html/checkout/standard/process/decorators/local
202
-		 */
203
-
204
-		/** client/html/checkout/standard/process/decorators/global
205
-		 * Adds a list of globally available decorators only to the checkout standard process html client
206
-		 *
207
-		 * Decorators extend the functionality of a class by adding new aspects
208
-		 * (e.g. log what is currently done), executing the methods of the underlying
209
-		 * class only in certain conditions (e.g. only for logged in users) or
210
-		 * modify what is returned to the caller.
211
-		 *
212
-		 * This option allows you to wrap global decorators
213
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
214
-		 *
215
-		 *  client/html/checkout/standard/process/decorators/global = array( 'decorator1' )
216
-		 *
217
-		 * This would add the decorator named "decorator1" defined by
218
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
219
-		 *
220
-		 * @param array List of decorator names
221
-		 * @since 2015.08
222
-		 * @category Developer
223
-		 * @see client/html/common/decorators/default
224
-		 * @see client/html/checkout/standard/process/decorators/excludes
225
-		 * @see client/html/checkout/standard/process/decorators/local
226
-		 */
227
-
228
-		/** client/html/checkout/standard/process/decorators/local
229
-		 * Adds a list of local decorators only to the checkout standard process html client
230
-		 *
231
-		 * Decorators extend the functionality of a class by adding new aspects
232
-		 * (e.g. log what is currently done), executing the methods of the underlying
233
-		 * class only in certain conditions (e.g. only for logged in users) or
234
-		 * modify what is returned to the caller.
235
-		 *
236
-		 * This option allows you to wrap local decorators
237
-		 * ("\Aimeos\Client\Html\Checkout\Decorator\*") around the html client.
238
-		 *
239
-		 *  client/html/checkout/standard/process/decorators/local = array( 'decorator2' )
240
-		 *
241
-		 * This would add the decorator named "decorator2" defined by
242
-		 * "\Aimeos\Client\Html\Checkout\Decorator\Decorator2" only to the html client.
243
-		 *
244
-		 * @param array List of decorator names
245
-		 * @since 2015.08
246
-		 * @category Developer
247
-		 * @see client/html/common/decorators/default
248
-		 * @see client/html/checkout/standard/process/decorators/excludes
249
-		 * @see client/html/checkout/standard/process/decorators/global
250
-		 */
251
-
252
-		return $this->createSubClient( 'checkout/standard/process/' . $type, $name );
253
-	}
254
-
255
-
256
-	/**
257
-	 * Processes the input, e.g. store given order.
258
-	 * A view must be available and this method doesn't generate any output
259
-	 * besides setting view variables.
260
-	 */
261
-	public function process()
262
-	{
263
-		$view = $this->getView();
264
-		$errors = $view->get( 'standardErrorList', array() );
265
-
266
-		if( !in_array( $view->param( 'c_step' ), array( 'order', 'process' ) ) || !empty( $errors ) ) {
267
-			return;
268
-		}
269
-
270
-		$context = $this->getContext();
271
-		$session = $context->getSession();
272
-		$orderid = $session->get( 'aimeos/orderid' );
273
-		$config = array( 'absoluteUri' => true, 'namespace' => false );
274
-
275
-		try
276
-		{
277
-			$orderItem = \Aimeos\MShop\Factory::createManager( $context, 'order' )->getItem( $orderid );
278
-
279
-			if( ( $code = $this->getOrderServiceCode( $orderItem->getBaseId() ) ) !== null )
280
-			{
281
-				$serviceItem = $this->getServiceItem( $code );
282
-
283
-				$serviceManager = \Aimeos\MShop\Factory::createManager( $context, 'service' );
284
-				$provider = $serviceManager->getProvider( $serviceItem );
285
-
286
-				$params = array( 'code' => $serviceItem->getCode(), 'orderid' => $orderid );
287
-				$urls = array(
288
-					'payment.url-self' => $this->getUrlSelf( $view, $params + array( 'c_step' => 'process' ), array() ),
289
-					'payment.url-success' => $this->getUrlConfirm( $view, $params, $config ),
290
-					'payment.url-update' => $this->getUrlUpdate( $view, $params, $config ),
291
-					'client.ipaddress' => $view->request()->getClientAddress(),
292
-				);
293
-				$provider->injectGlobalConfigBE( $urls );
294
-
295
-				if( ( $form = $provider->process( $orderItem, $view->param() ) ) === null )
296
-				{
297
-					$msg = sprintf( 'Invalid process response from service provider with code "%1$s"', $serviceItem->getCode() );
298
-					throw new \Aimeos\Client\Html\Exception( $msg );
299
-				}
300
-
301
-				$view->standardUrlNext = $form->getUrl();
302
-				$view->standardMethod = $form->getMethod();
303
-				$view->standardProcessParams = $form->getValues();
304
-				$view->standardUrlExternal = $form->getExternal();
305
-			}
306
-			else
307
-			{
308
-				$view->standardUrlNext = $this->getUrlConfirm( $view, array(), array() );
309
-				$view->standardMethod = 'GET';
310
-			}
311
-
312
-
313
-			parent::process();
314
-		}
315
-		catch( \Aimeos\Client\Html\Exception $e )
316
-		{
317
-			$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
318
-			$view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
319
-		}
320
-		catch( \Aimeos\Controller\Frontend\Exception $e )
321
-		{
322
-			$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
323
-			$view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
324
-		}
325
-		catch( \Aimeos\MShop\Exception $e )
326
-		{
327
-			$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
328
-			$view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
329
-		}
330
-		catch( \Exception $e )
331
-		{
332
-			$context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
333
-
334
-			$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
335
-			$view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
336
-		}
337
-	}
338
-
339
-
340
-	/**
341
-	 * Returns the payment service code from the order with the given base ID.
342
-	 *
343
-	 * @param string $baseid ID of the order base item
344
-	 * @return string|null Code of the service item or null if not found
345
-	 */
346
-	protected function getOrderServiceCode( $baseid )
347
-	{
348
-		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'order/base/service' );
349
-
350
-		$search = $manager->createSearch();
351
-		$expr = array(
352
-			$search->compare( '==', 'order.base.service.baseid', $baseid ),
353
-			$search->compare( '==', 'order.base.service.type', \Aimeos\MShop\Order\Item\Base\Service\Base::TYPE_PAYMENT ),
354
-		);
355
-		$search->setConditions( $search->combine( '&&', $expr ) );
356
-
357
-		$result = $manager->searchItems( $search );
358
-
359
-		if( ( $item = reset( $result ) ) !== false ) {
360
-			return $item->getCode();
361
-		}
362
-	}
363
-
364
-
365
-	/**
366
-	 * Returns the payment service item for the given code.
367
-	 *
368
-	 * @param string $code Unique service code
369
-	 * @throws \Aimeos\Client\Html\Exception If no service item for this code is found
370
-	 * @return \Aimeos\MShop\Service\Item\Iface Service item object
371
-	 */
372
-	protected function getServiceItem( $code )
373
-	{
374
-		$serviceManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'service' );
375
-
376
-		$search = $serviceManager->createSearch();
377
-		$expr = array(
378
-			$search->compare( '==', 'service.code', $code ),
379
-			$search->compare( '==', 'service.type.code', 'payment' ),
380
-		);
381
-		$search->setConditions( $search->combine( '&&', $expr ) );
382
-
383
-		$result = $serviceManager->searchItems( $search );
384
-
385
-		if( ( $serviceItem = reset( $result ) ) === false )
386
-		{
387
-			$msg = sprintf( 'No service for code "%1$s" found', $code );
388
-			throw new \Aimeos\Client\Html\Exception( $msg );
389
-		}
390
-
391
-		return $serviceItem;
392
-	}
393
-
394
-
395
-	/**
396
-	 * Returns the list of sub-client names configured for the client.
397
-	 *
398
-	 * @return array List of HTML client names
399
-	 */
400
-	protected function getSubClientNames()
401
-	{
402
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
403
-	}
404
-
405
-
406
-	/**
407
-	 * Returns the URL to the confirm page.
408
-	 *
409
-	 * @param \Aimeos\MW\View\Iface $view View object
410
-	 * @param array $params Parameters that should be part of the URL
411
-	 * @param array $config Default URL configuration
412
-	 * @return string URL string
413
-	 */
414
-	protected function getUrlConfirm( \Aimeos\MW\View\Iface $view, array $params, array $config )
415
-	{
416
-		/** client/html/checkout/confirm/url/target
417
-		 * Destination of the URL where the controller specified in the URL is known
418
-		 *
419
-		 * The destination can be a page ID like in a content management system or the
420
-		 * module of a software development framework. This "target" must contain or know
421
-		 * the controller that should be called by the generated URL.
422
-		 *
423
-		 * @param string Destination of the URL
424
-		 * @since 2014.03
425
-		 * @category Developer
426
-		 * @see client/html/checkout/confirm/url/controller
427
-		 * @see client/html/checkout/confirm/url/action
428
-		 * @see client/html/checkout/confirm/url/config
429
-		 */
430
-		$target = $view->config( 'client/html/checkout/confirm/url/target' );
431
-
432
-		/** client/html/checkout/confirm/url/controller
433
-		 * Name of the controller whose action should be called
434
-		 *
435
-		 * In Model-View-Controller (MVC) applications, the controller contains the methods
436
-		 * that create parts of the output displayed in the generated HTML page. Controller
437
-		 * names are usually alpha-numeric.
438
-		 *
439
-		 * @param string Name of the controller
440
-		 * @since 2014.03
441
-		 * @category Developer
442
-		 * @see client/html/checkout/confirm/url/target
443
-		 * @see client/html/checkout/confirm/url/action
444
-		 * @see client/html/checkout/confirm/url/config
445
-		 */
446
-		$cntl = $view->config( 'client/html/checkout/confirm/url/controller', 'checkout' );
447
-
448
-		/** client/html/checkout/confirm/url/action
449
-		 * Name of the action that should create the output
450
-		 *
451
-		 * In Model-View-Controller (MVC) applications, actions are the methods of a
452
-		 * controller that create parts of the output displayed in the generated HTML page.
453
-		 * Action names are usually alpha-numeric.
454
-		 *
455
-		 * @param string Name of the action
456
-		 * @since 2014.03
457
-		 * @category Developer
458
-		 * @see client/html/checkout/confirm/url/target
459
-		 * @see client/html/checkout/confirm/url/controller
460
-		 * @see client/html/checkout/confirm/url/config
461
-		 */
462
-		$action = $view->config( 'client/html/checkout/confirm/url/action', 'confirm' );
463
-
464
-		/** client/html/checkout/confirm/url/config
465
-		 * Associative list of configuration options used for generating the URL
466
-		 *
467
-		 * You can specify additional options as key/value pairs used when generating
468
-		 * the URLs, like
469
-		 *
470
-		 *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
471
-		 *
472
-		 * The available key/value pairs depend on the application that embeds the e-commerce
473
-		 * framework. This is because the infrastructure of the application is used for
474
-		 * generating the URLs. The full list of available config options is referenced
475
-		 * in the "see also" section of this page.
476
-		 *
477
-		 * @param string Associative list of configuration options
478
-		 * @since 2014.03
479
-		 * @category Developer
480
-		 * @see client/html/checkout/confirm/url/target
481
-		 * @see client/html/checkout/confirm/url/controller
482
-		 * @see client/html/checkout/confirm/url/action
483
-		 * @see client/html/url/config
484
-		 */
485
-		$config = $view->config( 'client/html/checkout/confirm/url/config', $config );
486
-
487
-		return $view->url( $target, $cntl, $action, $params, array(), $config );
488
-	}
489
-
490
-
491
-	/**
492
-	 * Returns the URL to the current page.
493
-	 *
494
-	 * @param \Aimeos\MW\View\Iface $view View object
495
-	 * @param array $params Parameters that should be part of the URL
496
-	 * @param array $config Default URL configuration
497
-	 * @return string URL string
498
-	 */
499
-	protected function getUrlSelf( \Aimeos\MW\View\Iface $view, array $params, array $config )
500
-	{
501
-		/** client/html/checkout/standard/url/target
502
-		 * Destination of the URL where the controller specified in the URL is known
503
-		 *
504
-		 * The destination can be a page ID like in a content management system or the
505
-		 * module of a software development framework. This "target" must contain or know
506
-		 * the controller that should be called by the generated URL.
507
-		 *
508
-		 * @param string Destination of the URL
509
-		 * @since 2014.03
510
-		 * @category Developer
511
-		 * @see client/html/checkout/standard/url/controller
512
-		 * @see client/html/checkout/standard/url/action
513
-		 * @see client/html/checkout/standard/url/config
514
-		 */
515
-		$target = $view->config( 'client/html/checkout/standard/url/target' );
516
-
517
-		/** client/html/checkout/standard/url/controller
518
-		 * Name of the controller whose action should be called
519
-		 *
520
-		 * In Model-View-Controller (MVC) applications, the controller contains the methods
521
-		 * that create parts of the output displayed in the generated HTML page. Controller
522
-		 * names are usually alpha-numeric.
523
-		 *
524
-		 * @param string Name of the controller
525
-		 * @since 2014.03
526
-		 * @category Developer
527
-		 * @see client/html/checkout/standard/url/target
528
-		 * @see client/html/checkout/standard/url/action
529
-		 * @see client/html/checkout/standard/url/config
530
-		 */
531
-		$cntl = $view->config( 'client/html/checkout/standard/url/controller', 'checkout' );
532
-
533
-		/** client/html/checkout/standard/url/action
534
-		 * Name of the action that should create the output
535
-		 *
536
-		 * In Model-View-Controller (MVC) applications, actions are the methods of a
537
-		 * controller that create parts of the output displayed in the generated HTML page.
538
-		 * Action names are usually alpha-numeric.
539
-		 *
540
-		 * @param string Name of the action
541
-		 * @since 2014.03
542
-		 * @category Developer
543
-		 * @see client/html/checkout/standard/url/target
544
-		 * @see client/html/checkout/standard/url/controller
545
-		 * @see client/html/checkout/standard/url/config
546
-		 */
547
-		$action = $view->config( 'client/html/checkout/standard/url/action', 'standard' );
548
-
549
-		/** client/html/checkout/standard/url/config
550
-		 * Associative list of configuration options used for generating the URL
551
-		 *
552
-		 * You can specify additional options as key/value pairs used when generating
553
-		 * the URLs, like
554
-		 *
555
-		 *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
556
-		 *
557
-		 * The available key/value pairs depend on the application that embeds the e-commerce
558
-		 * framework. This is because the infrastructure of the application is used for
559
-		 * generating the URLs. The full list of available config options is referenced
560
-		 * in the "see also" section of this page.
561
-		 *
562
-		 * @param string Associative list of configuration options
563
-		 * @since 2014.03
564
-		 * @category Developer
565
-		 * @see client/html/checkout/standard/url/target
566
-		 * @see client/html/checkout/standard/url/controller
567
-		 * @see client/html/checkout/standard/url/action
568
-		 * @see client/html/url/config
569
-		 */
570
-		$config = $view->config( 'client/html/checkout/standard/url/config', $config );
571
-
572
-		return $view->url( $target, $cntl, $action, $params, array(), $config );
573
-	}
574
-
575
-
576
-	/**
577
-	 * Returns the URL to the update page.
578
-	 *
579
-	 * @param \Aimeos\MW\View\Iface $view View object
580
-	 * @param array $params Parameters that should be part of the URL
581
-	 * @param array $config Default URL configuration
582
-	 * @return string URL string
583
-	 */
584
-	protected function getUrlUpdate( \Aimeos\MW\View\Iface $view, array $params, array $config )
585
-	{
586
-		/** client/html/checkout/update/url/target
587
-		 * Destination of the URL where the controller specified in the URL is known
588
-		 *
589
-		 * The destination can be a page ID like in a content management system or the
590
-		 * module of a software development framework. This "target" must contain or know
591
-		 * the controller that should be called by the generated URL.
592
-		 *
593
-		 * @param string Destination of the URL
594
-		 * @since 2014.03
595
-		 * @category Developer
596
-		 * @see client/html/checkout/update/url/controller
597
-		 * @see client/html/checkout/update/url/action
598
-		 * @see client/html/checkout/update/url/config
599
-		 */
600
-		$target = $view->config( 'client/html/checkout/update/url/target' );
601
-
602
-		/** client/html/checkout/update/url/controller
603
-		 * Name of the controller whose action should be called
604
-		 *
605
-		 * In Model-View-Controller (MVC) applications, the controller contains the methods
606
-		 * that create parts of the output displayed in the generated HTML page. Controller
607
-		 * names are usually alpha-numeric.
608
-		 *
609
-		 * @param string Name of the controller
610
-		 * @since 2014.03
611
-		 * @category Developer
612
-		 * @see client/html/checkout/update/url/target
613
-		 * @see client/html/checkout/update/url/action
614
-		 * @see client/html/checkout/update/url/config
615
-		 */
616
-		$cntl = $view->config( 'client/html/checkout/update/url/controller', 'checkout' );
617
-
618
-		/** client/html/checkout/update/url/action
619
-		 * Name of the action that should create the output
620
-		 *
621
-		 * In Model-View-Controller (MVC) applications, actions are the methods of a
622
-		 * controller that create parts of the output displayed in the generated HTML page.
623
-		 * Action names are usually alpha-numeric.
624
-		 *
625
-		 * @param string Name of the action
626
-		 * @since 2014.03
627
-		 * @category Developer
628
-		 * @see client/html/checkout/update/url/target
629
-		 * @see client/html/checkout/update/url/controller
630
-		 * @see client/html/checkout/update/url/config
631
-		 */
632
-		$action = $view->config( 'client/html/checkout/update/url/action', 'update' );
633
-
634
-		/** client/html/checkout/update/url/config
635
-		 * Associative list of configuration options used for generating the URL
636
-		 *
637
-		 * You can specify additional options as key/value pairs used when generating
638
-		 * the URLs, like
639
-		 *
640
-		 *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
641
-		 *
642
-		 * The available key/value pairs depend on the application that embeds the e-commerce
643
-		 * framework. This is because the infrastructure of the application is used for
644
-		 * generating the URLs. The full list of available config options is referenced
645
-		 * in the "see also" section of this page.
646
-		 *
647
-		 * @param string Associative list of configuration options
648
-		 * @since 2014.03
649
-		 * @category Developer
650
-		 * @see client/html/checkout/update/url/target
651
-		 * @see client/html/checkout/update/url/controller
652
-		 * @see client/html/checkout/update/url/action
653
-		 * @see client/html/url/config
654
-		 */
655
-		$config = $view->config( 'client/html/checkout/update/url/config', $config );
656
-
657
-		return $view->url( $target, $cntl, $action, $params, array(), $config );
658
-	}
659
-
660
-
661
-	/**
662
-	 * Sets the necessary parameter values in the view.
663
-	 *
664
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
665
-	 * @param array &$tags Result array for the list of tags that are associated to the output
666
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
667
-	 * @return \Aimeos\MW\View\Iface Modified view object
668
-	 */
669
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
670
-	{
671
-		if( !isset( $this->cache ) )
672
-		{
673
-			$view->standardUrlPayment = $this->getUrlSelf( $view, array( 'c_step' => 'payment' ), array() );
674
-
675
-			$this->cache = $view;
676
-		}
677
-
678
-		return $this->cache;
679
-	}
28
+    /** client/html/checkout/standard/process/standard/subparts
29
+     * List of HTML sub-clients rendered within the checkout standard process section
30
+     *
31
+     * The output of the frontend is composed of the code generated by the HTML
32
+     * clients. Each HTML client can consist of serveral (or none) sub-clients
33
+     * that are responsible for rendering certain sub-parts of the output. The
34
+     * sub-clients can contain HTML clients themselves and therefore a
35
+     * hierarchical tree of HTML clients is composed. Each HTML client creates
36
+     * the output that is placed inside the container of its parent.
37
+     *
38
+     * At first, always the HTML code generated by the parent is printed, then
39
+     * the HTML code of its sub-clients. The order of the HTML sub-clients
40
+     * determines the order of the output of these sub-clients inside the parent
41
+     * container. If the configured list of clients is
42
+     *
43
+     *  array( "subclient1", "subclient2" )
44
+     *
45
+     * you can easily change the order of the output by reordering the subparts:
46
+     *
47
+     *  client/html/<clients>/subparts = array( "subclient1", "subclient2" )
48
+     *
49
+     * You can also remove one or more parts if they shouldn't be rendered:
50
+     *
51
+     *  client/html/<clients>/subparts = array( "subclient1" )
52
+     *
53
+     * As the clients only generates structural HTML, the layout defined via CSS
54
+     * should support adding, removing or reordering content by a fluid like
55
+     * design.
56
+     *
57
+     * @param array List of sub-client names
58
+     * @since 2014.03
59
+     * @category Developer
60
+     */
61
+    private $subPartPath = 'client/html/checkout/standard/process/standard/subparts';
62
+    private $subPartNames = array();
63
+    private $cache;
64
+
65
+
66
+    /**
67
+     * Returns the HTML code for insertion into the body.
68
+     *
69
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
70
+     * @param array &$tags Result array for the list of tags that are associated to the output
71
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
72
+     * @return string HTML code
73
+     */
74
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
75
+    {
76
+        $view = $this->getView();
77
+
78
+        if( !in_array( $view->get( 'standardStepActive' ), array( 'order', 'process' ) ) ) {
79
+            return '';
80
+        }
81
+
82
+        $view = $this->setViewParams( $view, $tags, $expire );
83
+
84
+        $html = '';
85
+        foreach( $this->getSubClients() as $subclient ) {
86
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
87
+        }
88
+        $view->processBody = $html;
89
+
90
+        /** client/html/checkout/standard/process/standard/template-body
91
+         * Relative path to the HTML body template of the checkout standard process client.
92
+         *
93
+         * The template file contains the HTML code and processing instructions
94
+         * to generate the result shown in the body of the frontend. The
95
+         * configuration string is the path to the template file relative
96
+         * to the templates directory (usually in client/html/templates).
97
+         *
98
+         * You can overwrite the template file configuration in extensions and
99
+         * provide alternative templates. These alternative templates should be
100
+         * named like the default one but with the string "standard" replaced by
101
+         * an unique name. You may use the name of your project for this. If
102
+         * you've implemented an alternative client class as well, "standard"
103
+         * should be replaced by the name of the new class.
104
+         *
105
+         * @param string Relative path to the template creating code for the HTML page body
106
+         * @since 2014.03
107
+         * @category Developer
108
+         * @see client/html/checkout/standard/process/standard/template-header
109
+         */
110
+        $tplconf = 'client/html/checkout/standard/process/standard/template-body';
111
+        $default = 'checkout/standard/process-body-default.php';
112
+
113
+        return $view->render( $view->config( $tplconf, $default ) );
114
+    }
115
+
116
+
117
+    /**
118
+     * Returns the HTML string for insertion into the header.
119
+     *
120
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
121
+     * @param array &$tags Result array for the list of tags that are associated to the output
122
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
123
+     * @return string|null String including HTML tags for the header on error
124
+     */
125
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
126
+    {
127
+        $view = $this->getView();
128
+
129
+        if( !in_array( $view->param( 'standardStepActive' ), array( 'order', 'process' ) ) ) {
130
+            return '';
131
+        }
132
+
133
+        $view = $this->setViewParams( $view, $tags, $expire );
134
+
135
+        $html = '';
136
+        foreach( $this->getSubClients() as $subclient ) {
137
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
138
+        }
139
+        $view->processHeader = $html;
140
+
141
+        /** client/html/checkout/standard/process/standard/template-header
142
+         * Relative path to the HTML header template of the checkout standard process client.
143
+         *
144
+         * The template file contains the HTML code and processing instructions
145
+         * to generate the HTML code that is inserted into the HTML page header
146
+         * of the rendered page in the frontend. The configuration string is the
147
+         * path to the template file relative to the templates directory (usually
148
+         * in client/html/templates).
149
+         *
150
+         * You can overwrite the template file configuration in extensions and
151
+         * provide alternative templates. These alternative templates should be
152
+         * named like the default one but with the string "standard" replaced by
153
+         * an unique name. You may use the name of your project for this. If
154
+         * you've implemented an alternative client class as well, "standard"
155
+         * should be replaced by the name of the new class.
156
+         *
157
+         * @param string Relative path to the template creating code for the HTML page head
158
+         * @since 2014.03
159
+         * @category Developer
160
+         * @see client/html/checkout/standard/process/standard/template-body
161
+         */
162
+        $tplconf = 'client/html/checkout/standard/process/standard/template-header';
163
+        $default = 'checkout/standard/process-header-default.php';
164
+
165
+        return $view->render( $view->config( $tplconf, $default ) );
166
+    }
167
+
168
+
169
+    /**
170
+     * Returns the sub-client given by its name.
171
+     *
172
+     * @param string $type Name of the client type
173
+     * @param string|null $name Name of the sub-client (Default if null)
174
+     * @return \Aimeos\Client\Html\Iface Sub-client object
175
+     */
176
+    public function getSubClient( $type, $name = null )
177
+    {
178
+        /** client/html/checkout/standard/process/decorators/excludes
179
+         * Excludes decorators added by the "common" option from the checkout standard process html client
180
+         *
181
+         * Decorators extend the functionality of a class by adding new aspects
182
+         * (e.g. log what is currently done), executing the methods of the underlying
183
+         * class only in certain conditions (e.g. only for logged in users) or
184
+         * modify what is returned to the caller.
185
+         *
186
+         * This option allows you to remove a decorator added via
187
+         * "client/html/common/decorators/default" before they are wrapped
188
+         * around the html client.
189
+         *
190
+         *  client/html/checkout/standard/process/decorators/excludes = array( 'decorator1' )
191
+         *
192
+         * This would remove the decorator named "decorator1" from the list of
193
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
194
+         * "client/html/common/decorators/default" to the html client.
195
+         *
196
+         * @param array List of decorator names
197
+         * @since 2015.08
198
+         * @category Developer
199
+         * @see client/html/common/decorators/default
200
+         * @see client/html/checkout/standard/process/decorators/global
201
+         * @see client/html/checkout/standard/process/decorators/local
202
+         */
203
+
204
+        /** client/html/checkout/standard/process/decorators/global
205
+         * Adds a list of globally available decorators only to the checkout standard process html client
206
+         *
207
+         * Decorators extend the functionality of a class by adding new aspects
208
+         * (e.g. log what is currently done), executing the methods of the underlying
209
+         * class only in certain conditions (e.g. only for logged in users) or
210
+         * modify what is returned to the caller.
211
+         *
212
+         * This option allows you to wrap global decorators
213
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
214
+         *
215
+         *  client/html/checkout/standard/process/decorators/global = array( 'decorator1' )
216
+         *
217
+         * This would add the decorator named "decorator1" defined by
218
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
219
+         *
220
+         * @param array List of decorator names
221
+         * @since 2015.08
222
+         * @category Developer
223
+         * @see client/html/common/decorators/default
224
+         * @see client/html/checkout/standard/process/decorators/excludes
225
+         * @see client/html/checkout/standard/process/decorators/local
226
+         */
227
+
228
+        /** client/html/checkout/standard/process/decorators/local
229
+         * Adds a list of local decorators only to the checkout standard process html client
230
+         *
231
+         * Decorators extend the functionality of a class by adding new aspects
232
+         * (e.g. log what is currently done), executing the methods of the underlying
233
+         * class only in certain conditions (e.g. only for logged in users) or
234
+         * modify what is returned to the caller.
235
+         *
236
+         * This option allows you to wrap local decorators
237
+         * ("\Aimeos\Client\Html\Checkout\Decorator\*") around the html client.
238
+         *
239
+         *  client/html/checkout/standard/process/decorators/local = array( 'decorator2' )
240
+         *
241
+         * This would add the decorator named "decorator2" defined by
242
+         * "\Aimeos\Client\Html\Checkout\Decorator\Decorator2" only to the html client.
243
+         *
244
+         * @param array List of decorator names
245
+         * @since 2015.08
246
+         * @category Developer
247
+         * @see client/html/common/decorators/default
248
+         * @see client/html/checkout/standard/process/decorators/excludes
249
+         * @see client/html/checkout/standard/process/decorators/global
250
+         */
251
+
252
+        return $this->createSubClient( 'checkout/standard/process/' . $type, $name );
253
+    }
254
+
255
+
256
+    /**
257
+     * Processes the input, e.g. store given order.
258
+     * A view must be available and this method doesn't generate any output
259
+     * besides setting view variables.
260
+     */
261
+    public function process()
262
+    {
263
+        $view = $this->getView();
264
+        $errors = $view->get( 'standardErrorList', array() );
265
+
266
+        if( !in_array( $view->param( 'c_step' ), array( 'order', 'process' ) ) || !empty( $errors ) ) {
267
+            return;
268
+        }
269
+
270
+        $context = $this->getContext();
271
+        $session = $context->getSession();
272
+        $orderid = $session->get( 'aimeos/orderid' );
273
+        $config = array( 'absoluteUri' => true, 'namespace' => false );
274
+
275
+        try
276
+        {
277
+            $orderItem = \Aimeos\MShop\Factory::createManager( $context, 'order' )->getItem( $orderid );
278
+
279
+            if( ( $code = $this->getOrderServiceCode( $orderItem->getBaseId() ) ) !== null )
280
+            {
281
+                $serviceItem = $this->getServiceItem( $code );
282
+
283
+                $serviceManager = \Aimeos\MShop\Factory::createManager( $context, 'service' );
284
+                $provider = $serviceManager->getProvider( $serviceItem );
285
+
286
+                $params = array( 'code' => $serviceItem->getCode(), 'orderid' => $orderid );
287
+                $urls = array(
288
+                    'payment.url-self' => $this->getUrlSelf( $view, $params + array( 'c_step' => 'process' ), array() ),
289
+                    'payment.url-success' => $this->getUrlConfirm( $view, $params, $config ),
290
+                    'payment.url-update' => $this->getUrlUpdate( $view, $params, $config ),
291
+                    'client.ipaddress' => $view->request()->getClientAddress(),
292
+                );
293
+                $provider->injectGlobalConfigBE( $urls );
294
+
295
+                if( ( $form = $provider->process( $orderItem, $view->param() ) ) === null )
296
+                {
297
+                    $msg = sprintf( 'Invalid process response from service provider with code "%1$s"', $serviceItem->getCode() );
298
+                    throw new \Aimeos\Client\Html\Exception( $msg );
299
+                }
300
+
301
+                $view->standardUrlNext = $form->getUrl();
302
+                $view->standardMethod = $form->getMethod();
303
+                $view->standardProcessParams = $form->getValues();
304
+                $view->standardUrlExternal = $form->getExternal();
305
+            }
306
+            else
307
+            {
308
+                $view->standardUrlNext = $this->getUrlConfirm( $view, array(), array() );
309
+                $view->standardMethod = 'GET';
310
+            }
311
+
312
+
313
+            parent::process();
314
+        }
315
+        catch( \Aimeos\Client\Html\Exception $e )
316
+        {
317
+            $error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
318
+            $view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
319
+        }
320
+        catch( \Aimeos\Controller\Frontend\Exception $e )
321
+        {
322
+            $error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
323
+            $view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
324
+        }
325
+        catch( \Aimeos\MShop\Exception $e )
326
+        {
327
+            $error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
328
+            $view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
329
+        }
330
+        catch( \Exception $e )
331
+        {
332
+            $context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
333
+
334
+            $error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
335
+            $view->standardErrorList = $view->get( 'standardErrorList', array() ) + $error;
336
+        }
337
+    }
338
+
339
+
340
+    /**
341
+     * Returns the payment service code from the order with the given base ID.
342
+     *
343
+     * @param string $baseid ID of the order base item
344
+     * @return string|null Code of the service item or null if not found
345
+     */
346
+    protected function getOrderServiceCode( $baseid )
347
+    {
348
+        $manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'order/base/service' );
349
+
350
+        $search = $manager->createSearch();
351
+        $expr = array(
352
+            $search->compare( '==', 'order.base.service.baseid', $baseid ),
353
+            $search->compare( '==', 'order.base.service.type', \Aimeos\MShop\Order\Item\Base\Service\Base::TYPE_PAYMENT ),
354
+        );
355
+        $search->setConditions( $search->combine( '&&', $expr ) );
356
+
357
+        $result = $manager->searchItems( $search );
358
+
359
+        if( ( $item = reset( $result ) ) !== false ) {
360
+            return $item->getCode();
361
+        }
362
+    }
363
+
364
+
365
+    /**
366
+     * Returns the payment service item for the given code.
367
+     *
368
+     * @param string $code Unique service code
369
+     * @throws \Aimeos\Client\Html\Exception If no service item for this code is found
370
+     * @return \Aimeos\MShop\Service\Item\Iface Service item object
371
+     */
372
+    protected function getServiceItem( $code )
373
+    {
374
+        $serviceManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'service' );
375
+
376
+        $search = $serviceManager->createSearch();
377
+        $expr = array(
378
+            $search->compare( '==', 'service.code', $code ),
379
+            $search->compare( '==', 'service.type.code', 'payment' ),
380
+        );
381
+        $search->setConditions( $search->combine( '&&', $expr ) );
382
+
383
+        $result = $serviceManager->searchItems( $search );
384
+
385
+        if( ( $serviceItem = reset( $result ) ) === false )
386
+        {
387
+            $msg = sprintf( 'No service for code "%1$s" found', $code );
388
+            throw new \Aimeos\Client\Html\Exception( $msg );
389
+        }
390
+
391
+        return $serviceItem;
392
+    }
393
+
394
+
395
+    /**
396
+     * Returns the list of sub-client names configured for the client.
397
+     *
398
+     * @return array List of HTML client names
399
+     */
400
+    protected function getSubClientNames()
401
+    {
402
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
403
+    }
404
+
405
+
406
+    /**
407
+     * Returns the URL to the confirm page.
408
+     *
409
+     * @param \Aimeos\MW\View\Iface $view View object
410
+     * @param array $params Parameters that should be part of the URL
411
+     * @param array $config Default URL configuration
412
+     * @return string URL string
413
+     */
414
+    protected function getUrlConfirm( \Aimeos\MW\View\Iface $view, array $params, array $config )
415
+    {
416
+        /** client/html/checkout/confirm/url/target
417
+         * Destination of the URL where the controller specified in the URL is known
418
+         *
419
+         * The destination can be a page ID like in a content management system or the
420
+         * module of a software development framework. This "target" must contain or know
421
+         * the controller that should be called by the generated URL.
422
+         *
423
+         * @param string Destination of the URL
424
+         * @since 2014.03
425
+         * @category Developer
426
+         * @see client/html/checkout/confirm/url/controller
427
+         * @see client/html/checkout/confirm/url/action
428
+         * @see client/html/checkout/confirm/url/config
429
+         */
430
+        $target = $view->config( 'client/html/checkout/confirm/url/target' );
431
+
432
+        /** client/html/checkout/confirm/url/controller
433
+         * Name of the controller whose action should be called
434
+         *
435
+         * In Model-View-Controller (MVC) applications, the controller contains the methods
436
+         * that create parts of the output displayed in the generated HTML page. Controller
437
+         * names are usually alpha-numeric.
438
+         *
439
+         * @param string Name of the controller
440
+         * @since 2014.03
441
+         * @category Developer
442
+         * @see client/html/checkout/confirm/url/target
443
+         * @see client/html/checkout/confirm/url/action
444
+         * @see client/html/checkout/confirm/url/config
445
+         */
446
+        $cntl = $view->config( 'client/html/checkout/confirm/url/controller', 'checkout' );
447
+
448
+        /** client/html/checkout/confirm/url/action
449
+         * Name of the action that should create the output
450
+         *
451
+         * In Model-View-Controller (MVC) applications, actions are the methods of a
452
+         * controller that create parts of the output displayed in the generated HTML page.
453
+         * Action names are usually alpha-numeric.
454
+         *
455
+         * @param string Name of the action
456
+         * @since 2014.03
457
+         * @category Developer
458
+         * @see client/html/checkout/confirm/url/target
459
+         * @see client/html/checkout/confirm/url/controller
460
+         * @see client/html/checkout/confirm/url/config
461
+         */
462
+        $action = $view->config( 'client/html/checkout/confirm/url/action', 'confirm' );
463
+
464
+        /** client/html/checkout/confirm/url/config
465
+         * Associative list of configuration options used for generating the URL
466
+         *
467
+         * You can specify additional options as key/value pairs used when generating
468
+         * the URLs, like
469
+         *
470
+         *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
471
+         *
472
+         * The available key/value pairs depend on the application that embeds the e-commerce
473
+         * framework. This is because the infrastructure of the application is used for
474
+         * generating the URLs. The full list of available config options is referenced
475
+         * in the "see also" section of this page.
476
+         *
477
+         * @param string Associative list of configuration options
478
+         * @since 2014.03
479
+         * @category Developer
480
+         * @see client/html/checkout/confirm/url/target
481
+         * @see client/html/checkout/confirm/url/controller
482
+         * @see client/html/checkout/confirm/url/action
483
+         * @see client/html/url/config
484
+         */
485
+        $config = $view->config( 'client/html/checkout/confirm/url/config', $config );
486
+
487
+        return $view->url( $target, $cntl, $action, $params, array(), $config );
488
+    }
489
+
490
+
491
+    /**
492
+     * Returns the URL to the current page.
493
+     *
494
+     * @param \Aimeos\MW\View\Iface $view View object
495
+     * @param array $params Parameters that should be part of the URL
496
+     * @param array $config Default URL configuration
497
+     * @return string URL string
498
+     */
499
+    protected function getUrlSelf( \Aimeos\MW\View\Iface $view, array $params, array $config )
500
+    {
501
+        /** client/html/checkout/standard/url/target
502
+         * Destination of the URL where the controller specified in the URL is known
503
+         *
504
+         * The destination can be a page ID like in a content management system or the
505
+         * module of a software development framework. This "target" must contain or know
506
+         * the controller that should be called by the generated URL.
507
+         *
508
+         * @param string Destination of the URL
509
+         * @since 2014.03
510
+         * @category Developer
511
+         * @see client/html/checkout/standard/url/controller
512
+         * @see client/html/checkout/standard/url/action
513
+         * @see client/html/checkout/standard/url/config
514
+         */
515
+        $target = $view->config( 'client/html/checkout/standard/url/target' );
516
+
517
+        /** client/html/checkout/standard/url/controller
518
+         * Name of the controller whose action should be called
519
+         *
520
+         * In Model-View-Controller (MVC) applications, the controller contains the methods
521
+         * that create parts of the output displayed in the generated HTML page. Controller
522
+         * names are usually alpha-numeric.
523
+         *
524
+         * @param string Name of the controller
525
+         * @since 2014.03
526
+         * @category Developer
527
+         * @see client/html/checkout/standard/url/target
528
+         * @see client/html/checkout/standard/url/action
529
+         * @see client/html/checkout/standard/url/config
530
+         */
531
+        $cntl = $view->config( 'client/html/checkout/standard/url/controller', 'checkout' );
532
+
533
+        /** client/html/checkout/standard/url/action
534
+         * Name of the action that should create the output
535
+         *
536
+         * In Model-View-Controller (MVC) applications, actions are the methods of a
537
+         * controller that create parts of the output displayed in the generated HTML page.
538
+         * Action names are usually alpha-numeric.
539
+         *
540
+         * @param string Name of the action
541
+         * @since 2014.03
542
+         * @category Developer
543
+         * @see client/html/checkout/standard/url/target
544
+         * @see client/html/checkout/standard/url/controller
545
+         * @see client/html/checkout/standard/url/config
546
+         */
547
+        $action = $view->config( 'client/html/checkout/standard/url/action', 'standard' );
548
+
549
+        /** client/html/checkout/standard/url/config
550
+         * Associative list of configuration options used for generating the URL
551
+         *
552
+         * You can specify additional options as key/value pairs used when generating
553
+         * the URLs, like
554
+         *
555
+         *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
556
+         *
557
+         * The available key/value pairs depend on the application that embeds the e-commerce
558
+         * framework. This is because the infrastructure of the application is used for
559
+         * generating the URLs. The full list of available config options is referenced
560
+         * in the "see also" section of this page.
561
+         *
562
+         * @param string Associative list of configuration options
563
+         * @since 2014.03
564
+         * @category Developer
565
+         * @see client/html/checkout/standard/url/target
566
+         * @see client/html/checkout/standard/url/controller
567
+         * @see client/html/checkout/standard/url/action
568
+         * @see client/html/url/config
569
+         */
570
+        $config = $view->config( 'client/html/checkout/standard/url/config', $config );
571
+
572
+        return $view->url( $target, $cntl, $action, $params, array(), $config );
573
+    }
574
+
575
+
576
+    /**
577
+     * Returns the URL to the update page.
578
+     *
579
+     * @param \Aimeos\MW\View\Iface $view View object
580
+     * @param array $params Parameters that should be part of the URL
581
+     * @param array $config Default URL configuration
582
+     * @return string URL string
583
+     */
584
+    protected function getUrlUpdate( \Aimeos\MW\View\Iface $view, array $params, array $config )
585
+    {
586
+        /** client/html/checkout/update/url/target
587
+         * Destination of the URL where the controller specified in the URL is known
588
+         *
589
+         * The destination can be a page ID like in a content management system or the
590
+         * module of a software development framework. This "target" must contain or know
591
+         * the controller that should be called by the generated URL.
592
+         *
593
+         * @param string Destination of the URL
594
+         * @since 2014.03
595
+         * @category Developer
596
+         * @see client/html/checkout/update/url/controller
597
+         * @see client/html/checkout/update/url/action
598
+         * @see client/html/checkout/update/url/config
599
+         */
600
+        $target = $view->config( 'client/html/checkout/update/url/target' );
601
+
602
+        /** client/html/checkout/update/url/controller
603
+         * Name of the controller whose action should be called
604
+         *
605
+         * In Model-View-Controller (MVC) applications, the controller contains the methods
606
+         * that create parts of the output displayed in the generated HTML page. Controller
607
+         * names are usually alpha-numeric.
608
+         *
609
+         * @param string Name of the controller
610
+         * @since 2014.03
611
+         * @category Developer
612
+         * @see client/html/checkout/update/url/target
613
+         * @see client/html/checkout/update/url/action
614
+         * @see client/html/checkout/update/url/config
615
+         */
616
+        $cntl = $view->config( 'client/html/checkout/update/url/controller', 'checkout' );
617
+
618
+        /** client/html/checkout/update/url/action
619
+         * Name of the action that should create the output
620
+         *
621
+         * In Model-View-Controller (MVC) applications, actions are the methods of a
622
+         * controller that create parts of the output displayed in the generated HTML page.
623
+         * Action names are usually alpha-numeric.
624
+         *
625
+         * @param string Name of the action
626
+         * @since 2014.03
627
+         * @category Developer
628
+         * @see client/html/checkout/update/url/target
629
+         * @see client/html/checkout/update/url/controller
630
+         * @see client/html/checkout/update/url/config
631
+         */
632
+        $action = $view->config( 'client/html/checkout/update/url/action', 'update' );
633
+
634
+        /** client/html/checkout/update/url/config
635
+         * Associative list of configuration options used for generating the URL
636
+         *
637
+         * You can specify additional options as key/value pairs used when generating
638
+         * the URLs, like
639
+         *
640
+         *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
641
+         *
642
+         * The available key/value pairs depend on the application that embeds the e-commerce
643
+         * framework. This is because the infrastructure of the application is used for
644
+         * generating the URLs. The full list of available config options is referenced
645
+         * in the "see also" section of this page.
646
+         *
647
+         * @param string Associative list of configuration options
648
+         * @since 2014.03
649
+         * @category Developer
650
+         * @see client/html/checkout/update/url/target
651
+         * @see client/html/checkout/update/url/controller
652
+         * @see client/html/checkout/update/url/action
653
+         * @see client/html/url/config
654
+         */
655
+        $config = $view->config( 'client/html/checkout/update/url/config', $config );
656
+
657
+        return $view->url( $target, $cntl, $action, $params, array(), $config );
658
+    }
659
+
660
+
661
+    /**
662
+     * Sets the necessary parameter values in the view.
663
+     *
664
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
665
+     * @param array &$tags Result array for the list of tags that are associated to the output
666
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
667
+     * @return \Aimeos\MW\View\Iface Modified view object
668
+     */
669
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
670
+    {
671
+        if( !isset( $this->cache ) )
672
+        {
673
+            $view->standardUrlPayment = $this->getUrlSelf( $view, array( 'c_step' => 'payment' ), array() );
674
+
675
+            $this->cache = $view;
676
+        }
677
+
678
+        return $this->cache;
679
+    }
680 680
 }
Please login to merge, or discard this patch.