Completed
Push — master ( b4d1c4...5b98ac )
by Aimeos
05:50
created
client/html/src/Client/Html/Basket/Mini/Main/Standard.php 1 patch
Indentation   +232 added lines, -232 removed lines patch added patch discarded remove patch
@@ -19,259 +19,259 @@
 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/basket/mini/main/standard/subparts
26
-	 * List of HTML sub-clients rendered within the basket mini main 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/basket/mini/main/standard/subparts';
59
-	private $subPartNames = array();
60
-	private $cache;
25
+    /** client/html/basket/mini/main/standard/subparts
26
+     * List of HTML sub-clients rendered within the basket mini main 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/basket/mini/main/standard/subparts';
59
+    private $subPartNames = array();
60
+    private $cache;
61 61
 
62 62
 
63
-	/**
64
-	 * Returns the HTML code for insertion into the body.
65
-	 *
66
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
-	 * @param array &$tags Result array for the list of tags that are associated to the output
68
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
-	 * @return string HTML code
70
-	 */
71
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
-	{
73
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
63
+    /**
64
+     * Returns the HTML code for insertion into the body.
65
+     *
66
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
+     * @param array &$tags Result array for the list of tags that are associated to the output
68
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
+     * @return string HTML code
70
+     */
71
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
+    {
73
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
74 74
 
75
-		$html = '';
76
-		foreach( $this->getSubClients() as $subclient ) {
77
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
-		}
79
-		$view->mainBody = $html;
75
+        $html = '';
76
+        foreach( $this->getSubClients() as $subclient ) {
77
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
+        }
79
+        $view->mainBody = $html;
80 80
 
81
-		/** client/html/basket/mini/main/standard/template-body
82
-		 * Relative path to the HTML body template of the basket mini main client.
83
-		 *
84
-		 * The template file contains the HTML code and processing instructions
85
-		 * to generate the result shown in the body of the frontend. The
86
-		 * configuration string is the path to the template file relative
87
-		 * to the templates directory (usually in client/html/templates).
88
-		 *
89
-		 * You can overwrite the template file configuration in extensions and
90
-		 * provide alternative templates. These alternative templates should be
91
-		 * named like the default one but with the string "standard" replaced by
92
-		 * an unique name. You may use the name of your project for this. If
93
-		 * you've implemented an alternative client class as well, "standard"
94
-		 * should be replaced by the name of the new class.
95
-		 *
96
-		 * @param string Relative path to the template creating code for the HTML page body
97
-		 * @since 2014.03
98
-		 * @category Developer
99
-		 * @see client/html/basket/mini/main/standard/template-header
100
-		 */
101
-		$tplconf = 'client/html/basket/mini/main/standard/template-body';
102
-		$default = 'basket/mini/main-body-default.php';
81
+        /** client/html/basket/mini/main/standard/template-body
82
+         * Relative path to the HTML body template of the basket mini main client.
83
+         *
84
+         * The template file contains the HTML code and processing instructions
85
+         * to generate the result shown in the body of the frontend. The
86
+         * configuration string is the path to the template file relative
87
+         * to the templates directory (usually in client/html/templates).
88
+         *
89
+         * You can overwrite the template file configuration in extensions and
90
+         * provide alternative templates. These alternative templates should be
91
+         * named like the default one but with the string "standard" replaced by
92
+         * an unique name. You may use the name of your project for this. If
93
+         * you've implemented an alternative client class as well, "standard"
94
+         * should be replaced by the name of the new class.
95
+         *
96
+         * @param string Relative path to the template creating code for the HTML page body
97
+         * @since 2014.03
98
+         * @category Developer
99
+         * @see client/html/basket/mini/main/standard/template-header
100
+         */
101
+        $tplconf = 'client/html/basket/mini/main/standard/template-body';
102
+        $default = 'basket/mini/main-body-default.php';
103 103
 
104
-		return $view->render( $view->config( $tplconf, $default ) );
105
-	}
104
+        return $view->render( $view->config( $tplconf, $default ) );
105
+    }
106 106
 
107 107
 
108
-	/**
109
-	 * Returns the HTML string for insertion into the header.
110
-	 *
111
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
-	 * @param array &$tags Result array for the list of tags that are associated to the output
113
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
-	 * @return string|null String including HTML tags for the header on error
115
-	 */
116
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
-	{
118
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
108
+    /**
109
+     * Returns the HTML string for insertion into the header.
110
+     *
111
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
+     * @param array &$tags Result array for the list of tags that are associated to the output
113
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
+     * @return string|null String including HTML tags for the header on error
115
+     */
116
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
+    {
118
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
119 119
 
120
-		$html = '';
121
-		foreach( $this->getSubClients() as $subclient ) {
122
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
-		}
124
-		$view->mainHeader = $html;
120
+        $html = '';
121
+        foreach( $this->getSubClients() as $subclient ) {
122
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
+        }
124
+        $view->mainHeader = $html;
125 125
 
126
-		/** client/html/basket/mini/main/standard/template-header
127
-		 * Relative path to the HTML header template of the basket mini main client.
128
-		 *
129
-		 * The template file contains the HTML code and processing instructions
130
-		 * to generate the HTML code that is inserted into the HTML page header
131
-		 * of the rendered page in the frontend. The configuration string is the
132
-		 * path to the template file relative to the templates directory (usually
133
-		 * in client/html/templates).
134
-		 *
135
-		 * You can overwrite the template file configuration in extensions and
136
-		 * provide alternative templates. These alternative templates should be
137
-		 * named like the default one but with the string "standard" replaced by
138
-		 * an unique name. You may use the name of your project for this. If
139
-		 * you've implemented an alternative client class as well, "standard"
140
-		 * should be replaced by the name of the new class.
141
-		 *
142
-		 * @param string Relative path to the template creating code for the HTML page head
143
-		 * @since 2014.03
144
-		 * @category Developer
145
-		 * @see client/html/basket/mini/main/standard/template-body
146
-		 */
147
-		$tplconf = 'client/html/basket/mini/main/standard/template-header';
148
-		$default = 'basket/mini/main-header-default.php';
126
+        /** client/html/basket/mini/main/standard/template-header
127
+         * Relative path to the HTML header template of the basket mini main client.
128
+         *
129
+         * The template file contains the HTML code and processing instructions
130
+         * to generate the HTML code that is inserted into the HTML page header
131
+         * of the rendered page in the frontend. The configuration string is the
132
+         * path to the template file relative to the templates directory (usually
133
+         * in client/html/templates).
134
+         *
135
+         * You can overwrite the template file configuration in extensions and
136
+         * provide alternative templates. These alternative templates should be
137
+         * named like the default one but with the string "standard" replaced by
138
+         * an unique name. You may use the name of your project for this. If
139
+         * you've implemented an alternative client class as well, "standard"
140
+         * should be replaced by the name of the new class.
141
+         *
142
+         * @param string Relative path to the template creating code for the HTML page head
143
+         * @since 2014.03
144
+         * @category Developer
145
+         * @see client/html/basket/mini/main/standard/template-body
146
+         */
147
+        $tplconf = 'client/html/basket/mini/main/standard/template-header';
148
+        $default = 'basket/mini/main-header-default.php';
149 149
 
150
-		return $view->render( $view->config( $tplconf, $default ) );
151
-	}
150
+        return $view->render( $view->config( $tplconf, $default ) );
151
+    }
152 152
 
153 153
 
154
-	/**
155
-	 * Returns the sub-client given by its name.
156
-	 *
157
-	 * @param string $type Name of the client type
158
-	 * @param string|null $name Name of the sub-client (Default if null)
159
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
160
-	 */
161
-	public function getSubClient( $type, $name = null )
162
-	{
163
-		/** client/html/basket/mini/main/decorators/excludes
164
-		 * Excludes decorators added by the "common" option from the basket mini main html client
165
-		 *
166
-		 * Decorators extend the functionality of a class by adding new aspects
167
-		 * (e.g. log what is currently done), executing the methods of the underlying
168
-		 * class only in certain conditions (e.g. only for logged in users) or
169
-		 * modify what is returned to the caller.
170
-		 *
171
-		 * This option allows you to remove a decorator added via
172
-		 * "client/html/common/decorators/default" before they are wrapped
173
-		 * around the html client.
174
-		 *
175
-		 *  client/html/basket/mini/main/decorators/excludes = array( 'decorator1' )
176
-		 *
177
-		 * This would remove the decorator named "decorator1" from the list of
178
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
-		 * "client/html/common/decorators/default" to the html client.
180
-		 *
181
-		 * @param array List of decorator names
182
-		 * @since 2015.08
183
-		 * @category Developer
184
-		 * @see client/html/common/decorators/default
185
-		 * @see client/html/basket/mini/main/decorators/global
186
-		 * @see client/html/basket/mini/main/decorators/local
187
-		 */
154
+    /**
155
+     * Returns the sub-client given by its name.
156
+     *
157
+     * @param string $type Name of the client type
158
+     * @param string|null $name Name of the sub-client (Default if null)
159
+     * @return \Aimeos\Client\Html\Iface Sub-client object
160
+     */
161
+    public function getSubClient( $type, $name = null )
162
+    {
163
+        /** client/html/basket/mini/main/decorators/excludes
164
+         * Excludes decorators added by the "common" option from the basket mini main html client
165
+         *
166
+         * Decorators extend the functionality of a class by adding new aspects
167
+         * (e.g. log what is currently done), executing the methods of the underlying
168
+         * class only in certain conditions (e.g. only for logged in users) or
169
+         * modify what is returned to the caller.
170
+         *
171
+         * This option allows you to remove a decorator added via
172
+         * "client/html/common/decorators/default" before they are wrapped
173
+         * around the html client.
174
+         *
175
+         *  client/html/basket/mini/main/decorators/excludes = array( 'decorator1' )
176
+         *
177
+         * This would remove the decorator named "decorator1" from the list of
178
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
+         * "client/html/common/decorators/default" to the html client.
180
+         *
181
+         * @param array List of decorator names
182
+         * @since 2015.08
183
+         * @category Developer
184
+         * @see client/html/common/decorators/default
185
+         * @see client/html/basket/mini/main/decorators/global
186
+         * @see client/html/basket/mini/main/decorators/local
187
+         */
188 188
 
189
-		/** client/html/basket/mini/main/decorators/global
190
-		 * Adds a list of globally available decorators only to the basket mini main html client
191
-		 *
192
-		 * Decorators extend the functionality of a class by adding new aspects
193
-		 * (e.g. log what is currently done), executing the methods of the underlying
194
-		 * class only in certain conditions (e.g. only for logged in users) or
195
-		 * modify what is returned to the caller.
196
-		 *
197
-		 * This option allows you to wrap global decorators
198
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
-		 *
200
-		 *  client/html/basket/mini/main/decorators/global = array( 'decorator1' )
201
-		 *
202
-		 * This would add the decorator named "decorator1" defined by
203
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
-		 *
205
-		 * @param array List of decorator names
206
-		 * @since 2015.08
207
-		 * @category Developer
208
-		 * @see client/html/common/decorators/default
209
-		 * @see client/html/basket/mini/main/decorators/excludes
210
-		 * @see client/html/basket/mini/main/decorators/local
211
-		 */
189
+        /** client/html/basket/mini/main/decorators/global
190
+         * Adds a list of globally available decorators only to the basket mini main html client
191
+         *
192
+         * Decorators extend the functionality of a class by adding new aspects
193
+         * (e.g. log what is currently done), executing the methods of the underlying
194
+         * class only in certain conditions (e.g. only for logged in users) or
195
+         * modify what is returned to the caller.
196
+         *
197
+         * This option allows you to wrap global decorators
198
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
+         *
200
+         *  client/html/basket/mini/main/decorators/global = array( 'decorator1' )
201
+         *
202
+         * This would add the decorator named "decorator1" defined by
203
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
+         *
205
+         * @param array List of decorator names
206
+         * @since 2015.08
207
+         * @category Developer
208
+         * @see client/html/common/decorators/default
209
+         * @see client/html/basket/mini/main/decorators/excludes
210
+         * @see client/html/basket/mini/main/decorators/local
211
+         */
212 212
 
213
-		/** client/html/basket/mini/main/decorators/local
214
-		 * Adds a list of local decorators only to the basket mini main html client
215
-		 *
216
-		 * Decorators extend the functionality of a class by adding new aspects
217
-		 * (e.g. log what is currently done), executing the methods of the underlying
218
-		 * class only in certain conditions (e.g. only for logged in users) or
219
-		 * modify what is returned to the caller.
220
-		 *
221
-		 * This option allows you to wrap local decorators
222
-		 * ("\Aimeos\Client\Html\Basket\Decorator\*") around the html client.
223
-		 *
224
-		 *  client/html/basket/mini/main/decorators/local = array( 'decorator2' )
225
-		 *
226
-		 * This would add the decorator named "decorator2" defined by
227
-		 * "\Aimeos\Client\Html\Basket\Decorator\Decorator2" only to the html client.
228
-		 *
229
-		 * @param array List of decorator names
230
-		 * @since 2015.08
231
-		 * @category Developer
232
-		 * @see client/html/common/decorators/default
233
-		 * @see client/html/basket/mini/main/decorators/excludes
234
-		 * @see client/html/basket/mini/main/decorators/global
235
-		 */
236
-		return $this->createSubClient( 'basket/mini/main/' . $type, $name );
237
-	}
213
+        /** client/html/basket/mini/main/decorators/local
214
+         * Adds a list of local decorators only to the basket mini main html client
215
+         *
216
+         * Decorators extend the functionality of a class by adding new aspects
217
+         * (e.g. log what is currently done), executing the methods of the underlying
218
+         * class only in certain conditions (e.g. only for logged in users) or
219
+         * modify what is returned to the caller.
220
+         *
221
+         * This option allows you to wrap local decorators
222
+         * ("\Aimeos\Client\Html\Basket\Decorator\*") around the html client.
223
+         *
224
+         *  client/html/basket/mini/main/decorators/local = array( 'decorator2' )
225
+         *
226
+         * This would add the decorator named "decorator2" defined by
227
+         * "\Aimeos\Client\Html\Basket\Decorator\Decorator2" only to the html client.
228
+         *
229
+         * @param array List of decorator names
230
+         * @since 2015.08
231
+         * @category Developer
232
+         * @see client/html/common/decorators/default
233
+         * @see client/html/basket/mini/main/decorators/excludes
234
+         * @see client/html/basket/mini/main/decorators/global
235
+         */
236
+        return $this->createSubClient( 'basket/mini/main/' . $type, $name );
237
+    }
238 238
 
239 239
 
240
-	/**
241
-	 * Returns the list of sub-client names configured for the client.
242
-	 *
243
-	 * @return array List of HTML client names
244
-	 */
245
-	protected function getSubClientNames()
246
-	{
247
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
-	}
240
+    /**
241
+     * Returns the list of sub-client names configured for the client.
242
+     *
243
+     * @return array List of HTML client names
244
+     */
245
+    protected function getSubClientNames()
246
+    {
247
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
+    }
249 249
 
250 250
 
251
-	/**
252
-	 * Sets the necessary parameter values in the view.
253
-	 *
254
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
255
-	 * @param array &$tags Result array for the list of tags that are associated to the output
256
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
257
-	 * @return \Aimeos\MW\View\Iface Modified view object
258
-	 */
259
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
260
-	{
261
-		if( !isset( $this->cache ) )
262
-		{
263
-			$view->mainPriceItem = $view->miniBasket->getPrice();
251
+    /**
252
+     * Sets the necessary parameter values in the view.
253
+     *
254
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
255
+     * @param array &$tags Result array for the list of tags that are associated to the output
256
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
257
+     * @return \Aimeos\MW\View\Iface Modified view object
258
+     */
259
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
260
+    {
261
+        if( !isset( $this->cache ) )
262
+        {
263
+            $view->mainPriceItem = $view->miniBasket->getPrice();
264 264
 
265
-			$count = 0;
266
-			foreach( $view->miniBasket->getProducts() as $product ) {
267
-				$count += $product->getQuantity();
268
-			}
265
+            $count = 0;
266
+            foreach( $view->miniBasket->getProducts() as $product ) {
267
+                $count += $product->getQuantity();
268
+            }
269 269
 
270
-			$view->mainQuantity = $count;
270
+            $view->mainQuantity = $count;
271 271
 
272
-			$this->cache = $view;
273
-		}
272
+            $this->cache = $view;
273
+        }
274 274
 
275
-		return $this->cache;
276
-	}
275
+        return $this->cache;
276
+    }
277 277
 }
278 278
\ No newline at end of file
Please login to merge, or discard this patch.
client/html/src/Client/Html/Base.php 1 patch
Indentation   +661 added lines, -661 removed lines patch added patch discarded remove patch
@@ -19,666 +19,666 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 abstract class Base
22
-	implements \Aimeos\Client\Html\Iface
22
+    implements \Aimeos\Client\Html\Iface
23 23
 {
24
-	private $view;
25
-	private $cache;
26
-	private $context;
27
-	private $subclients;
28
-	private $templatePaths;
29
-
30
-
31
-	/**
32
-	 * Initializes the class instance.
33
-	 *
34
-	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
35
-	 * @param array $templatePaths Associative list of the file system paths to the core or the extensions as key
36
-	 * 	and a list of relative paths inside the core or the extension as values
37
-	 */
38
-	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths )
39
-	{
40
-		$this->context = $context;
41
-		$this->templatePaths = $templatePaths;
42
-	}
43
-
44
-
45
-	/**
46
-	 * Returns the view object that will generate the HTML output.
47
-	 *
48
-	 * @return \Aimeos\MW\View\Iface $view The view object which generates the HTML output
49
-	 */
50
-	public function getView()
51
-	{
52
-		if( !isset( $this->view ) ) {
53
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'No view available' ) );
54
-		}
55
-
56
-		return $this->view;
57
-	}
58
-
59
-
60
-	/**
61
-	 * Modifies the cached body content to replace content based on sessions or cookies.
62
-	 *
63
-	 * @param string $content Cached content
64
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
65
-	 * @return string Modified body content
66
-	 */
67
-	public function modifyBody( $content, $uid )
68
-	{
69
-		$view = $this->getView();
70
-
71
-		foreach( $this->getSubClients() as $subclient )
72
-		{
73
-			$subclient->setView( $view );
74
-			$content = $subclient->modifyBody( $content, $uid );
75
-		}
76
-
77
-		return $content;
78
-	}
79
-
80
-
81
-	/**
82
-	 * Modifies the cached header content to replace content based on sessions or cookies.
83
-	 *
84
-	 * @param string $content Cached content
85
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
86
-	 * @return string Modified header content
87
-	 */
88
-	public function modifyHeader( $content, $uid )
89
-	{
90
-		$view = $this->getView();
91
-
92
-		foreach( $this->getSubClients() as $subclient )
93
-		{
94
-			$subclient->setView( $view );
95
-			$content = $subclient->modifyHeader( $content, $uid );
96
-		}
97
-
98
-		return $content;
99
-	}
100
-
101
-
102
-	/**
103
-	 * Processes the input, e.g. store given values.
104
-	 * A view must be available and this method doesn't generate any output
105
-	 * besides setting view variables.
106
-	 *
107
-	 * @return boolean False if processing is stopped, otherwise all processing was completed successfully
108
-	 */
109
-	public function process()
110
-	{
111
-		$view = $this->getView();
112
-
113
-		foreach( $this->getSubClients() as $subclient )
114
-		{
115
-			$subclient->setView( $view );
116
-
117
-			if( $subclient->process() === false ) {
118
-				return false;
119
-			}
120
-		}
121
-
122
-		return true;
123
-	}
124
-
125
-
126
-	/**
127
-	 * Sets the view object that will generate the HTML output.
128
-	 *
129
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
130
-	 * @return \Aimeos\Client\Html\Iface Reference to this object for fluent calls
131
-	 */
132
-	public function setView( \Aimeos\MW\View\Iface $view )
133
-	{
134
-		$this->view = $view;
135
-		return $this;
136
-	}
137
-
138
-
139
-	/**
140
-	 * Adds the decorators to the client object
141
-	 *
142
-	 * @param \Aimeos\Client\Html\Iface $client Client object
143
-	 * @param array $templatePaths List of file system paths where the templates are stored
144
-	 * @param array $decorators List of decorator name that should be wrapped around the client
145
-	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Client\Html\Catalog\Decorator\"
146
-	 * @return \Aimeos\Client\Html\Iface Client object
147
-	 */
148
-	protected function addDecorators( \Aimeos\Client\Html\Iface $client, array $templatePaths,
149
-		array $decorators, $classprefix )
150
-	{
151
-		$iface = '\\Aimeos\\Client\\Html\\Common\\Decorator\\Iface';
152
-
153
-		foreach( $decorators as $name )
154
-		{
155
-			if( ctype_alnum( $name ) === false )
156
-			{
157
-				$classname = is_string( $name ) ? $classprefix . $name : '<not a string>';
158
-				throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid class name "%1$s"', $classname ) );
159
-			}
160
-
161
-			$classname = $classprefix . $name;
162
-
163
-			if( class_exists( $classname ) === false ) {
164
-				throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" not found', $classname ) );
165
-			}
166
-
167
-			$client = new $classname( $client, $this->context, $this->templatePaths );
168
-
169
-			if( !( $client instanceof $iface ) ) {
170
-				throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" does not implement "%2$s"', $classname, $iface ) );
171
-			}
172
-		}
173
-
174
-		return $client;
175
-	}
176
-
177
-
178
-	/**
179
-	 * Adds the decorators to the client object
180
-	 *
181
-	 * @param \Aimeos\Client\Html\Iface $client Client object
182
-	 * @param array $templatePaths List of file system paths where the templates are stored
183
-	 * @param string $path Client string in lower case, e.g. "catalog/detail/basic"
184
-	 * @return \Aimeos\Client\Html\Iface Client object
185
-	 */
186
-	protected function addClientDecorators( \Aimeos\Client\Html\Iface $client, array $templatePaths, $path )
187
-	{
188
-		if( !is_string( $path ) || $path === '' ) {
189
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid domain "%1$s"', $path ) );
190
-		}
191
-
192
-		$localClass = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
193
-		$config = $this->context->getConfig();
194
-
195
-		$decorators = $config->get( 'client/html/common/decorators/default', array() );
196
-		$excludes = $config->get( 'client/html/' . $path . '/decorators/excludes', array() );
197
-
198
-		foreach( $decorators as $key => $name )
199
-		{
200
-			if( in_array( $name, $excludes ) ) {
201
-				unset( $decorators[$key] );
202
-			}
203
-		}
204
-
205
-		$classprefix = '\\Aimeos\\Client\\Html\\Common\\Decorator\\';
206
-		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
207
-
208
-		$classprefix = '\\Aimeos\\Client\\Html\\Common\\Decorator\\';
209
-		$decorators = $config->get( 'client/html/' . $path . '/decorators/global', array() );
210
-		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
211
-
212
-		$classprefix = '\\Aimeos\\Client\\Html\\' . $localClass . '\\Decorator\\';
213
-		$decorators = $config->get( 'client/html/' . $path . '/decorators/local', array() );
214
-		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
215
-
216
-		return $client;
217
-	}
218
-
219
-
220
-	/**
221
-	 * Adds the cache tags to the given list and sets a new expiration date if necessary based on the given item.
222
-	 *
223
-	 * @param array|\Aimeos\MShop\Common\Item\Iface $items Item or list of items, maybe with associated list items
224
-	 * @param string $domain Name of the domain the item is from
225
-	 * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
226
-	 * @param array &$tags List of tags the new tags will be added to
227
-	 */
228
-	protected function addMetaItem( $items, $domain, &$expire, array &$tags )
229
-	{
230
-		/** client/html/common/cache/tag-all
231
-		 * Adds tags for all items used in a cache entry
232
-		 *
233
-		 * Each cache entry storing rendered parts for the HTML header or body
234
-		 * can be tagged with information which items like texts, media, etc.
235
-		 * are used in the HTML. This allows removing only those cache entries
236
-		 * whose content has really changed and only that entries have to be
237
-		 * rebuild the next time.
238
-		 *
239
-		 * The standard behavior stores only tags for each used domain, e.g. if
240
-		 * a text is used, only the tag "text" is added. If you change a text
241
-		 * in the administration interface, all cache entries with the tag
242
-		 * "text" will be removed from the cache. This effectively wipes out
243
-		 * almost all cached entries, which have to be rebuild with the next
244
-		 * request.
245
-		 *
246
-		 * Important: As a list or detail view can use several hundred items,
247
-		 * this configuration option will also add this number of tags to the
248
-		 * cache entry. When using a cache adapter that can't insert all tags
249
-		 * at once, this slows down the initial cache insert (and therefore the
250
-		 * page speed) drastically! It's only recommended to enable this option
251
-		 * if you use the DB, Mysql or Redis adapter that can insert all tags
252
-		 * at once.
253
-		 *
254
-		 * @param boolean True to add tags for all items, false to use only a domain tag
255
-		 * @since 2014.07
256
-		 * @category Developer
257
-		 * @category User
258
-		 * @see client/html/common/cache/force
259
-		 * @see madmin/cache/manager/name
260
-		 * @see madmin/cache/name
261
-		 */
262
-		$tagAll = $this->context->getConfig()->get( 'client/html/common/cache/tag-all', false );
263
-
264
-		if( !is_array( $items ) ) {
265
-			$items = array( $items );
266
-		}
267
-
268
-		if( $tagAll !== true && !empty( $items ) ) {
269
-			$tags[] = $domain;
270
-		}
271
-
272
-		foreach( $items as $item ) {
273
-			$this->addMetaItemSingle( $item, $domain, $expire, $tags, $tagAll );
274
-		}
275
-	}
276
-
277
-
278
-	/**
279
-	 * Adds expire date and tags for a single item.
280
-	 *
281
-	 * @param \Aimeos\MShop\Common\Item\Iface $item Item, maybe with associated list items
282
-	 * @param string $domain Name of the domain the item is from
283
-	 * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
284
-	 * @param array &$tags List of tags the new tags will be added to
285
-	 * @param boolean $tagAll True of tags for all items should be added, false if only for the main item
286
-	 */
287
-	private function addMetaItemSingle( \Aimeos\MShop\Common\Item\Iface $item, $domain, &$expire, array &$tags, $tagAll )
288
-	{
289
-		$expires = array();
290
-		$domain = str_replace( '/', '_', $domain ); // maximum compatiblity
291
-
292
-		if( $tagAll === true ) {
293
-			$tags[] = $domain . '-' . $item->getId();
294
-		}
295
-
296
-		if( $item instanceof \Aimeos\MShop\Common\Item\Time\Iface && ( $date = $item->getDateEnd() ) !== null ) {
297
-			$expires[] = $date;
298
-		}
299
-
300
-		if( $item instanceof \Aimeos\MShop\Common\Item\ListRef\Iface )
301
-		{
302
-			foreach( $item->getListItems() as $listitem )
303
-			{
304
-				if( $tagAll === true ) {
305
-					$tags[] = str_replace( '/', '_', $listitem->getDomain() ) . '-' . $listitem->getRefId();
306
-				}
307
-
308
-				if( ( $date = $listitem->getDateEnd() ) !== null ) {
309
-					$expires[] = $date;
310
-				}
311
-			}
312
-		}
313
-
314
-		if( !empty( $expires ) ) {
315
-			$expire = min( $expires );
316
-		}
317
-	}
318
-
319
-
320
-	/**
321
-	 * Adds a new expiration date if a list item is activated in the future.
322
-	 *
323
-	 * @param array|string $ids Item ID or list of item IDs from the given domain
324
-	 * @param string $domain Name of the domain the item IDs are from
325
-	 * @param string|null &$expire Expiration date that will be overwritten if an start date in the future is available
326
-	 */
327
-	protected function addMetaList( $ids, $domain, &$expire )
328
-	{
329
-		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $domain . '/lists' );
330
-
331
-		$search = $manager->createSearch();
332
-		$expr = array(
333
-			$search->compare( '==', $domain . '.lists.parentid', $ids ),
334
-			$search->compare( '>', $domain . '.lists.datestart', date( 'Y-m-d H:i:00' ) ),
335
-		);
336
-		$search->setConditions( $search->combine( '&&', $expr ) );
337
-		$search->setSortations( array( $search->sort( '+', $domain . '.lists.datestart' ) ) );
338
-		$search->setSlice( 0, 1 );
339
-
340
-		foreach( $manager->searchItems( $search ) as $listItem ) {
341
-			$expire = $this->expires( $expire, $listItem->getDateStart() );
342
-		}
343
-	}
344
-
345
-
346
-	/**
347
-	 * Returns the sub-client given by its name.
348
-	 *
349
-	 * @param string $path Name of the sub-part in lower case (can contain a path like catalog/filter/tree)
350
-	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
351
-	 * @return \Aimeos\Client\Html\Iface Sub-part object
352
-	 */
353
-	protected function createSubClient( $path, $name )
354
-	{
355
-		$path = strtolower( $path );
356
-
357
-		if( $name === null ) {
358
-			$name = $this->context->getConfig()->get( 'client/html/' . $path . '/name', 'Standard' );
359
-		}
360
-
361
-		if( empty( $name ) || ctype_alnum( $name ) === false ) {
362
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in client name "%1$s"', $name ) );
363
-		}
364
-
365
-		$subnames = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
366
-
367
-		$classname = '\\Aimeos\\Client\\Html\\' . $subnames . '\\' . $name;
368
-		$interface = '\\Aimeos\\Client\\Html\\Iface';
369
-
370
-		if( class_exists( $classname ) === false ) {
371
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
372
-		}
373
-
374
-		$object = new $classname( $this->context, $this->templatePaths );
375
-
376
-		if( ( $object instanceof $interface ) === false ) {
377
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface ) );
378
-		}
379
-
380
-		return $this->addClientDecorators( $object, $this->templatePaths, $path );
381
-	}
382
-
383
-
384
-	/**
385
-	 * Returns the minimal expiration date.
386
-	 *
387
-	 * @param string|null $first First expiration date or null
388
-	 * @param string|null $second Second expiration date or null
389
-	 * @return string|null Expiration date
390
-	 */
391
-	protected function expires( $first, $second )
392
-	{
393
-		return ( $first !== null ? ( $second !== null ? min( $first, $second ) : $first ) : $second );
394
-	}
395
-
396
-
397
-	/**
398
-	 * Returns the parameters used by the html client.
399
-	 *
400
-	 * @param array $params Associative list of all parameters
401
-	 * @param array $prefixes List of prefixes the parameters must start with
402
-	 * @return array Associative list of parameters used by the html client
403
-	 */
404
-	protected function getClientParams( array $params, array $prefixes = array( 'f', 'l', 'd', 'a' ) )
405
-	{
406
-		$list = array();
407
-
408
-		foreach( $params as $key => $value )
409
-		{
410
-			if( in_array( $key[0], $prefixes ) && $key[1] === '_' ) {
411
-				$list[$key] = $value;
412
-			}
413
-		}
414
-
415
-		return $list;
416
-	}
417
-
418
-
419
-	/**
420
-	 * Returns the context object.
421
-	 *
422
-	 * @return \Aimeos\MShop\Context\Item\Iface Context object
423
-	 */
424
-	protected function getContext()
425
-	{
426
-		return $this->context;
427
-	}
428
-
429
-
430
-	/**
431
-	 * Generates an unique hash from based on the input suitable to be used as part of the cache key
432
-	 *
433
-	 * @param array $prefixes List of prefixes the parameters must start with
434
-	 * @param string $key Unique identifier if the content is placed more than once on the same page
435
-	 * @param array $config Multi-dimensional array of configuration options used by the client and sub-clients
436
-	 * @return string Unique hash
437
-	 */
438
-	protected function getParamHash( array $prefixes = array( 'f', 'l', 'd' ), $key = '', array $config = array() )
439
-	{
440
-		$locale = $this->getContext()->getLocale();
441
-		$params = $this->getClientParams( $this->getView()->param(), $prefixes );
442
-		ksort( $params );
443
-
444
-		if( ( $pstr = json_encode( $params ) ) === false || ( $cstr = json_encode( $config ) ) === false ) {
445
-			throw new \Aimeos\Client\Html\Exception( 'Unable to encode parameters or configuration options' );
446
-		}
447
-
448
-		return md5( $key . $pstr . $cstr . $locale->getLanguageId() . $locale->getCurrencyId() );
449
-	}
450
-
451
-
452
-	/**
453
-	 * Returns the list of sub-client names configured for the client.
454
-	 *
455
-	 * @return array List of HTML client names
456
-	 */
457
-	abstract protected function getSubClientNames();
458
-
459
-
460
-	/**
461
-	 * Returns the configured sub-clients or the ones named in the default parameter if none are configured.
462
-	 *
463
-	 * @return array List of sub-clients implementing \Aimeos\Client\Html\Iface	ordered in the same way as the names
464
-	 */
465
-	protected function getSubClients()
466
-	{
467
-		if( !isset( $this->subclients ) )
468
-		{
469
-			$this->subclients = array();
470
-
471
-			foreach( $this->getSubClientNames() as $name ) {
472
-				$this->subclients[] = $this->getSubClient( $name );
473
-			}
474
-		}
475
-
476
-		return $this->subclients;
477
-	}
478
-
479
-
480
-	/**
481
-	 * Returns the paths where the layout templates can be found
482
-	 *
483
-	 * @return array List of template paths
484
-	 * @since 2015.09
485
-	 */
486
-	protected function getTemplatePaths()
487
-	{
488
-		return $this->templatePaths;
489
-	}
490
-
491
-
492
-	/**
493
-	 * Returns the attribute type item specified by the code.
494
-	 *
495
-	 * @param string $prefix Domain prefix for the manager, e.g. "media/type"
496
-	 * @param string $domain Domain of the type item
497
-	 * @param string $code Code of the type item
498
-	 * @return \Aimeos\MShop\Common\Item\Type\Iface Type item
499
-	 * @throws \Aimeos\Controller\Jobs\Exception If no item is found
500
-	 */
501
-	protected function getTypeItem( $prefix, $domain, $code )
502
-	{
503
-		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $prefix );
504
-		$prefix = str_replace( '/', '.', $prefix );
505
-
506
-		$search = $manager->createSearch();
507
-		$expr = array(
508
-				$search->compare( '==', $prefix . '.domain', $domain ),
509
-				$search->compare( '==', $prefix . '.code', $code ),
510
-		);
511
-		$search->setConditions( $search->combine( '&&', $expr ) );
512
-		$result = $manager->searchItems( $search );
513
-
514
-		if( ( $item = reset( $result ) ) === false )
515
-		{
516
-			$msg = sprintf( 'No type item for "%1$s/%2$s" in "%3$s" found', $domain, $code, $prefix );
517
-			throw new \Aimeos\Controller\Jobs\Exception( $msg );
518
-		}
519
-
520
-		return $item;
521
-	}
522
-
523
-
524
-	/**
525
-	 * Returns the cache entry for the given unique ID and type.
526
-	 *
527
-	 * @param string $type Type of the cache entry, i.e. "body" or "header"
528
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
529
-	 * @param string[] $prefixes List of prefixes of all parameters that are relevant for generating the output
530
-	 * @param string $confkey Configuration key prefix that matches all relevant settings for the component
531
-	 * @return string Cached entry or empty string if not available
532
-	 */
533
-	protected function getCached( $type, $uid, array $prefixes, $confkey )
534
-	{
535
-		if( !isset( $this->cache ) )
536
-		{
537
-			$context = $this->getContext();
538
-			$config = $context->getConfig();
539
-
540
-			/** client/html/common/cache/force
541
-			 * Enforces content caching regardless of user logins
542
-			 *
543
-			 * Caching the component output is normally disabled as soon as the
544
-			 * user has logged in. This enables displaying user or user group
545
-			 * specific content without mixing standard and user specific output.
546
-			 *
547
-			 * If you don't have any user or user group specific content
548
-			 * (products, categories, attributes, media, prices, texts, etc.),
549
-			 * you can enforce content caching nevertheless to keep response
550
-			 * times as low as possible.
551
-			 *
552
-			 * @param boolean True to cache output regardless of login, false for no caching
553
-			 * @since 2015.08
554
-			 * @category Developer
555
-			 * @category User
556
-			 * @see client/html/common/cache/tag-all
557
-			 */
558
-			$force = $config->get( 'client/html/common/cache/force', false );
559
-
560
-			if( $force == false && $context->getUserId() !== null ) {
561
-				return null;
562
-			}
563
-
564
-			$cfg = $config->get( $confkey, array() );
565
-
566
-			$keys = array(
567
-				'body' => $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':body', $cfg ),
568
-				'header' => $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':header', $cfg ),
569
-			);
570
-
571
-			$entries = $context->getCache()->getList( $keys );
572
-			$this->cache = array();
573
-
574
-			foreach( $keys as $key => $hash ) {
575
-				$this->cache[$key] = ( array_key_exists( $hash, $entries ) ? $entries[$hash] : null );
576
-			}
577
-		}
578
-
579
-		return ( array_key_exists( $type, $this->cache ) ? $this->cache[$type] : null );
580
-	}
581
-
582
-
583
-	/**
584
-	 * Returns the cache entry for the given type and unique ID.
585
-	 *
586
-	 * @param string $type Type of the cache entry, i.e. "body" or "header"
587
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
588
-	 * @param string[] $prefixes List of prefixes of all parameters that are relevant for generating the output
589
-	 * @param string $confkey Configuration key prefix that matches all relevant settings for the component
590
-	 * @param string $value Value string that should be stored for the given key
591
-	 * @param array $tags List of tag strings that should be assoicated to the
592
-	 * 	given value in the cache
593
-	 * @param string|null $expire Date/time string in "YYYY-MM-DD HH:mm:ss"
594
-	 * 	format when the cache entry expires
595
-	 */
596
-	protected function setCached( $type, $uid, array $prefixes, $confkey, $value, array $tags, $expire )
597
-	{
598
-		$context = $this->getContext();
599
-		$config = $context->getConfig();
600
-
601
-		$force = $config->get( 'client/html/common/cache/force', false );
602
-
603
-		if( $force == false && $context->getUserId() !== null ) {
604
-			return;
605
-		}
606
-
607
-		try
608
-		{
609
-			$cfg = $config->get( $confkey, array() );
610
-			$key = $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':' . $type, $cfg );
611
-
612
-			$context->getCache()->set( $key, $value, array_unique( $tags ), $expire );
613
-		}
614
-		catch( \Exception $e )
615
-		{
616
-			$msg = sprintf( 'Unable to set cache entry: %1$s', $e->getMessage() );
617
-			$context->getLogger()->log( $msg, \Aimeos\MW\Logger\Base::NOTICE );
618
-		}
619
-	}
620
-
621
-
622
-	/**
623
-	 * Replaces the section in the content that is enclosed by the marker.
624
-	 *
625
-	 * @param string $content Cached content
626
-	 * @param string $section New section content
627
-	 * @param string $marker Name of the section marker without "<!-- " and " -->" parts
628
-	 */
629
-	protected function replaceSection( $content, $section, $marker )
630
-	{
631
-		$start = 0;
632
-		$len = strlen( $section );
633
-		$marker = '<!-- ' . $marker . ' -->';
634
-
635
-		while( ( $start = @strpos( $content, $marker, $start ) ) !== false )
636
-		{
637
-			if( ( $end = strpos( $content, $marker, $start + 1 ) ) !== false ) {
638
-				$content = substr_replace( $content, $section, $start, $end - $start + strlen( $marker ) );
639
-			}
640
-
641
-			$start += 2 * strlen( $marker ) + $len;
642
-		}
643
-
644
-		return $content;
645
-	}
646
-
647
-
648
-	/**
649
-	 * Sets the necessary parameter values in the view.
650
-	 *
651
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
652
-	 * @param array &$tags Result array for the list of tags that are associated to the output
653
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
654
-	 * @return \Aimeos\MW\View\Iface Modified view object
655
-	 */
656
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
657
-	{
658
-		return $view;
659
-	}
660
-
661
-
662
-	/**
663
-	 * Translates the plugin error codes to human readable error strings.
664
-	 *
665
-	 * @param array $codes Associative list of scope and object as key and error code as value
666
-	 * @return array List of translated error messages
667
-	 */
668
-	protected function translatePluginErrorCodes( array $codes )
669
-	{
670
-		$errors = array();
671
-		$i18n = $this->context->getI18n();
672
-
673
-		foreach( $codes as $scope => $list )
674
-		{
675
-			foreach( $list as $object => $errcode )
676
-			{
677
-				$key = $scope . ( $scope !== 'product' ? '.' . $object : '' ) . '.' . $errcode;
678
-				$errors[] = $i18n->dt( 'mshop/code', $key );
679
-			}
680
-		}
681
-
682
-		return $errors;
683
-	}
24
+    private $view;
25
+    private $cache;
26
+    private $context;
27
+    private $subclients;
28
+    private $templatePaths;
29
+
30
+
31
+    /**
32
+     * Initializes the class instance.
33
+     *
34
+     * @param \Aimeos\MShop\Context\Item\Iface $context Context object
35
+     * @param array $templatePaths Associative list of the file system paths to the core or the extensions as key
36
+     * 	and a list of relative paths inside the core or the extension as values
37
+     */
38
+    public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths )
39
+    {
40
+        $this->context = $context;
41
+        $this->templatePaths = $templatePaths;
42
+    }
43
+
44
+
45
+    /**
46
+     * Returns the view object that will generate the HTML output.
47
+     *
48
+     * @return \Aimeos\MW\View\Iface $view The view object which generates the HTML output
49
+     */
50
+    public function getView()
51
+    {
52
+        if( !isset( $this->view ) ) {
53
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'No view available' ) );
54
+        }
55
+
56
+        return $this->view;
57
+    }
58
+
59
+
60
+    /**
61
+     * Modifies the cached body content to replace content based on sessions or cookies.
62
+     *
63
+     * @param string $content Cached content
64
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
65
+     * @return string Modified body content
66
+     */
67
+    public function modifyBody( $content, $uid )
68
+    {
69
+        $view = $this->getView();
70
+
71
+        foreach( $this->getSubClients() as $subclient )
72
+        {
73
+            $subclient->setView( $view );
74
+            $content = $subclient->modifyBody( $content, $uid );
75
+        }
76
+
77
+        return $content;
78
+    }
79
+
80
+
81
+    /**
82
+     * Modifies the cached header content to replace content based on sessions or cookies.
83
+     *
84
+     * @param string $content Cached content
85
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
86
+     * @return string Modified header content
87
+     */
88
+    public function modifyHeader( $content, $uid )
89
+    {
90
+        $view = $this->getView();
91
+
92
+        foreach( $this->getSubClients() as $subclient )
93
+        {
94
+            $subclient->setView( $view );
95
+            $content = $subclient->modifyHeader( $content, $uid );
96
+        }
97
+
98
+        return $content;
99
+    }
100
+
101
+
102
+    /**
103
+     * Processes the input, e.g. store given values.
104
+     * A view must be available and this method doesn't generate any output
105
+     * besides setting view variables.
106
+     *
107
+     * @return boolean False if processing is stopped, otherwise all processing was completed successfully
108
+     */
109
+    public function process()
110
+    {
111
+        $view = $this->getView();
112
+
113
+        foreach( $this->getSubClients() as $subclient )
114
+        {
115
+            $subclient->setView( $view );
116
+
117
+            if( $subclient->process() === false ) {
118
+                return false;
119
+            }
120
+        }
121
+
122
+        return true;
123
+    }
124
+
125
+
126
+    /**
127
+     * Sets the view object that will generate the HTML output.
128
+     *
129
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
130
+     * @return \Aimeos\Client\Html\Iface Reference to this object for fluent calls
131
+     */
132
+    public function setView( \Aimeos\MW\View\Iface $view )
133
+    {
134
+        $this->view = $view;
135
+        return $this;
136
+    }
137
+
138
+
139
+    /**
140
+     * Adds the decorators to the client object
141
+     *
142
+     * @param \Aimeos\Client\Html\Iface $client Client object
143
+     * @param array $templatePaths List of file system paths where the templates are stored
144
+     * @param array $decorators List of decorator name that should be wrapped around the client
145
+     * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Client\Html\Catalog\Decorator\"
146
+     * @return \Aimeos\Client\Html\Iface Client object
147
+     */
148
+    protected function addDecorators( \Aimeos\Client\Html\Iface $client, array $templatePaths,
149
+        array $decorators, $classprefix )
150
+    {
151
+        $iface = '\\Aimeos\\Client\\Html\\Common\\Decorator\\Iface';
152
+
153
+        foreach( $decorators as $name )
154
+        {
155
+            if( ctype_alnum( $name ) === false )
156
+            {
157
+                $classname = is_string( $name ) ? $classprefix . $name : '<not a string>';
158
+                throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid class name "%1$s"', $classname ) );
159
+            }
160
+
161
+            $classname = $classprefix . $name;
162
+
163
+            if( class_exists( $classname ) === false ) {
164
+                throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" not found', $classname ) );
165
+            }
166
+
167
+            $client = new $classname( $client, $this->context, $this->templatePaths );
168
+
169
+            if( !( $client instanceof $iface ) ) {
170
+                throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" does not implement "%2$s"', $classname, $iface ) );
171
+            }
172
+        }
173
+
174
+        return $client;
175
+    }
176
+
177
+
178
+    /**
179
+     * Adds the decorators to the client object
180
+     *
181
+     * @param \Aimeos\Client\Html\Iface $client Client object
182
+     * @param array $templatePaths List of file system paths where the templates are stored
183
+     * @param string $path Client string in lower case, e.g. "catalog/detail/basic"
184
+     * @return \Aimeos\Client\Html\Iface Client object
185
+     */
186
+    protected function addClientDecorators( \Aimeos\Client\Html\Iface $client, array $templatePaths, $path )
187
+    {
188
+        if( !is_string( $path ) || $path === '' ) {
189
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid domain "%1$s"', $path ) );
190
+        }
191
+
192
+        $localClass = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
193
+        $config = $this->context->getConfig();
194
+
195
+        $decorators = $config->get( 'client/html/common/decorators/default', array() );
196
+        $excludes = $config->get( 'client/html/' . $path . '/decorators/excludes', array() );
197
+
198
+        foreach( $decorators as $key => $name )
199
+        {
200
+            if( in_array( $name, $excludes ) ) {
201
+                unset( $decorators[$key] );
202
+            }
203
+        }
204
+
205
+        $classprefix = '\\Aimeos\\Client\\Html\\Common\\Decorator\\';
206
+        $client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
207
+
208
+        $classprefix = '\\Aimeos\\Client\\Html\\Common\\Decorator\\';
209
+        $decorators = $config->get( 'client/html/' . $path . '/decorators/global', array() );
210
+        $client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
211
+
212
+        $classprefix = '\\Aimeos\\Client\\Html\\' . $localClass . '\\Decorator\\';
213
+        $decorators = $config->get( 'client/html/' . $path . '/decorators/local', array() );
214
+        $client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
215
+
216
+        return $client;
217
+    }
218
+
219
+
220
+    /**
221
+     * Adds the cache tags to the given list and sets a new expiration date if necessary based on the given item.
222
+     *
223
+     * @param array|\Aimeos\MShop\Common\Item\Iface $items Item or list of items, maybe with associated list items
224
+     * @param string $domain Name of the domain the item is from
225
+     * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
226
+     * @param array &$tags List of tags the new tags will be added to
227
+     */
228
+    protected function addMetaItem( $items, $domain, &$expire, array &$tags )
229
+    {
230
+        /** client/html/common/cache/tag-all
231
+         * Adds tags for all items used in a cache entry
232
+         *
233
+         * Each cache entry storing rendered parts for the HTML header or body
234
+         * can be tagged with information which items like texts, media, etc.
235
+         * are used in the HTML. This allows removing only those cache entries
236
+         * whose content has really changed and only that entries have to be
237
+         * rebuild the next time.
238
+         *
239
+         * The standard behavior stores only tags for each used domain, e.g. if
240
+         * a text is used, only the tag "text" is added. If you change a text
241
+         * in the administration interface, all cache entries with the tag
242
+         * "text" will be removed from the cache. This effectively wipes out
243
+         * almost all cached entries, which have to be rebuild with the next
244
+         * request.
245
+         *
246
+         * Important: As a list or detail view can use several hundred items,
247
+         * this configuration option will also add this number of tags to the
248
+         * cache entry. When using a cache adapter that can't insert all tags
249
+         * at once, this slows down the initial cache insert (and therefore the
250
+         * page speed) drastically! It's only recommended to enable this option
251
+         * if you use the DB, Mysql or Redis adapter that can insert all tags
252
+         * at once.
253
+         *
254
+         * @param boolean True to add tags for all items, false to use only a domain tag
255
+         * @since 2014.07
256
+         * @category Developer
257
+         * @category User
258
+         * @see client/html/common/cache/force
259
+         * @see madmin/cache/manager/name
260
+         * @see madmin/cache/name
261
+         */
262
+        $tagAll = $this->context->getConfig()->get( 'client/html/common/cache/tag-all', false );
263
+
264
+        if( !is_array( $items ) ) {
265
+            $items = array( $items );
266
+        }
267
+
268
+        if( $tagAll !== true && !empty( $items ) ) {
269
+            $tags[] = $domain;
270
+        }
271
+
272
+        foreach( $items as $item ) {
273
+            $this->addMetaItemSingle( $item, $domain, $expire, $tags, $tagAll );
274
+        }
275
+    }
276
+
277
+
278
+    /**
279
+     * Adds expire date and tags for a single item.
280
+     *
281
+     * @param \Aimeos\MShop\Common\Item\Iface $item Item, maybe with associated list items
282
+     * @param string $domain Name of the domain the item is from
283
+     * @param string|null &$expire Expiration date that will be overwritten if an earlier date is found
284
+     * @param array &$tags List of tags the new tags will be added to
285
+     * @param boolean $tagAll True of tags for all items should be added, false if only for the main item
286
+     */
287
+    private function addMetaItemSingle( \Aimeos\MShop\Common\Item\Iface $item, $domain, &$expire, array &$tags, $tagAll )
288
+    {
289
+        $expires = array();
290
+        $domain = str_replace( '/', '_', $domain ); // maximum compatiblity
291
+
292
+        if( $tagAll === true ) {
293
+            $tags[] = $domain . '-' . $item->getId();
294
+        }
295
+
296
+        if( $item instanceof \Aimeos\MShop\Common\Item\Time\Iface && ( $date = $item->getDateEnd() ) !== null ) {
297
+            $expires[] = $date;
298
+        }
299
+
300
+        if( $item instanceof \Aimeos\MShop\Common\Item\ListRef\Iface )
301
+        {
302
+            foreach( $item->getListItems() as $listitem )
303
+            {
304
+                if( $tagAll === true ) {
305
+                    $tags[] = str_replace( '/', '_', $listitem->getDomain() ) . '-' . $listitem->getRefId();
306
+                }
307
+
308
+                if( ( $date = $listitem->getDateEnd() ) !== null ) {
309
+                    $expires[] = $date;
310
+                }
311
+            }
312
+        }
313
+
314
+        if( !empty( $expires ) ) {
315
+            $expire = min( $expires );
316
+        }
317
+    }
318
+
319
+
320
+    /**
321
+     * Adds a new expiration date if a list item is activated in the future.
322
+     *
323
+     * @param array|string $ids Item ID or list of item IDs from the given domain
324
+     * @param string $domain Name of the domain the item IDs are from
325
+     * @param string|null &$expire Expiration date that will be overwritten if an start date in the future is available
326
+     */
327
+    protected function addMetaList( $ids, $domain, &$expire )
328
+    {
329
+        $manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $domain . '/lists' );
330
+
331
+        $search = $manager->createSearch();
332
+        $expr = array(
333
+            $search->compare( '==', $domain . '.lists.parentid', $ids ),
334
+            $search->compare( '>', $domain . '.lists.datestart', date( 'Y-m-d H:i:00' ) ),
335
+        );
336
+        $search->setConditions( $search->combine( '&&', $expr ) );
337
+        $search->setSortations( array( $search->sort( '+', $domain . '.lists.datestart' ) ) );
338
+        $search->setSlice( 0, 1 );
339
+
340
+        foreach( $manager->searchItems( $search ) as $listItem ) {
341
+            $expire = $this->expires( $expire, $listItem->getDateStart() );
342
+        }
343
+    }
344
+
345
+
346
+    /**
347
+     * Returns the sub-client given by its name.
348
+     *
349
+     * @param string $path Name of the sub-part in lower case (can contain a path like catalog/filter/tree)
350
+     * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
351
+     * @return \Aimeos\Client\Html\Iface Sub-part object
352
+     */
353
+    protected function createSubClient( $path, $name )
354
+    {
355
+        $path = strtolower( $path );
356
+
357
+        if( $name === null ) {
358
+            $name = $this->context->getConfig()->get( 'client/html/' . $path . '/name', 'Standard' );
359
+        }
360
+
361
+        if( empty( $name ) || ctype_alnum( $name ) === false ) {
362
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in client name "%1$s"', $name ) );
363
+        }
364
+
365
+        $subnames = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
366
+
367
+        $classname = '\\Aimeos\\Client\\Html\\' . $subnames . '\\' . $name;
368
+        $interface = '\\Aimeos\\Client\\Html\\Iface';
369
+
370
+        if( class_exists( $classname ) === false ) {
371
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
372
+        }
373
+
374
+        $object = new $classname( $this->context, $this->templatePaths );
375
+
376
+        if( ( $object instanceof $interface ) === false ) {
377
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface ) );
378
+        }
379
+
380
+        return $this->addClientDecorators( $object, $this->templatePaths, $path );
381
+    }
382
+
383
+
384
+    /**
385
+     * Returns the minimal expiration date.
386
+     *
387
+     * @param string|null $first First expiration date or null
388
+     * @param string|null $second Second expiration date or null
389
+     * @return string|null Expiration date
390
+     */
391
+    protected function expires( $first, $second )
392
+    {
393
+        return ( $first !== null ? ( $second !== null ? min( $first, $second ) : $first ) : $second );
394
+    }
395
+
396
+
397
+    /**
398
+     * Returns the parameters used by the html client.
399
+     *
400
+     * @param array $params Associative list of all parameters
401
+     * @param array $prefixes List of prefixes the parameters must start with
402
+     * @return array Associative list of parameters used by the html client
403
+     */
404
+    protected function getClientParams( array $params, array $prefixes = array( 'f', 'l', 'd', 'a' ) )
405
+    {
406
+        $list = array();
407
+
408
+        foreach( $params as $key => $value )
409
+        {
410
+            if( in_array( $key[0], $prefixes ) && $key[1] === '_' ) {
411
+                $list[$key] = $value;
412
+            }
413
+        }
414
+
415
+        return $list;
416
+    }
417
+
418
+
419
+    /**
420
+     * Returns the context object.
421
+     *
422
+     * @return \Aimeos\MShop\Context\Item\Iface Context object
423
+     */
424
+    protected function getContext()
425
+    {
426
+        return $this->context;
427
+    }
428
+
429
+
430
+    /**
431
+     * Generates an unique hash from based on the input suitable to be used as part of the cache key
432
+     *
433
+     * @param array $prefixes List of prefixes the parameters must start with
434
+     * @param string $key Unique identifier if the content is placed more than once on the same page
435
+     * @param array $config Multi-dimensional array of configuration options used by the client and sub-clients
436
+     * @return string Unique hash
437
+     */
438
+    protected function getParamHash( array $prefixes = array( 'f', 'l', 'd' ), $key = '', array $config = array() )
439
+    {
440
+        $locale = $this->getContext()->getLocale();
441
+        $params = $this->getClientParams( $this->getView()->param(), $prefixes );
442
+        ksort( $params );
443
+
444
+        if( ( $pstr = json_encode( $params ) ) === false || ( $cstr = json_encode( $config ) ) === false ) {
445
+            throw new \Aimeos\Client\Html\Exception( 'Unable to encode parameters or configuration options' );
446
+        }
447
+
448
+        return md5( $key . $pstr . $cstr . $locale->getLanguageId() . $locale->getCurrencyId() );
449
+    }
450
+
451
+
452
+    /**
453
+     * Returns the list of sub-client names configured for the client.
454
+     *
455
+     * @return array List of HTML client names
456
+     */
457
+    abstract protected function getSubClientNames();
458
+
459
+
460
+    /**
461
+     * Returns the configured sub-clients or the ones named in the default parameter if none are configured.
462
+     *
463
+     * @return array List of sub-clients implementing \Aimeos\Client\Html\Iface	ordered in the same way as the names
464
+     */
465
+    protected function getSubClients()
466
+    {
467
+        if( !isset( $this->subclients ) )
468
+        {
469
+            $this->subclients = array();
470
+
471
+            foreach( $this->getSubClientNames() as $name ) {
472
+                $this->subclients[] = $this->getSubClient( $name );
473
+            }
474
+        }
475
+
476
+        return $this->subclients;
477
+    }
478
+
479
+
480
+    /**
481
+     * Returns the paths where the layout templates can be found
482
+     *
483
+     * @return array List of template paths
484
+     * @since 2015.09
485
+     */
486
+    protected function getTemplatePaths()
487
+    {
488
+        return $this->templatePaths;
489
+    }
490
+
491
+
492
+    /**
493
+     * Returns the attribute type item specified by the code.
494
+     *
495
+     * @param string $prefix Domain prefix for the manager, e.g. "media/type"
496
+     * @param string $domain Domain of the type item
497
+     * @param string $code Code of the type item
498
+     * @return \Aimeos\MShop\Common\Item\Type\Iface Type item
499
+     * @throws \Aimeos\Controller\Jobs\Exception If no item is found
500
+     */
501
+    protected function getTypeItem( $prefix, $domain, $code )
502
+    {
503
+        $manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $prefix );
504
+        $prefix = str_replace( '/', '.', $prefix );
505
+
506
+        $search = $manager->createSearch();
507
+        $expr = array(
508
+                $search->compare( '==', $prefix . '.domain', $domain ),
509
+                $search->compare( '==', $prefix . '.code', $code ),
510
+        );
511
+        $search->setConditions( $search->combine( '&&', $expr ) );
512
+        $result = $manager->searchItems( $search );
513
+
514
+        if( ( $item = reset( $result ) ) === false )
515
+        {
516
+            $msg = sprintf( 'No type item for "%1$s/%2$s" in "%3$s" found', $domain, $code, $prefix );
517
+            throw new \Aimeos\Controller\Jobs\Exception( $msg );
518
+        }
519
+
520
+        return $item;
521
+    }
522
+
523
+
524
+    /**
525
+     * Returns the cache entry for the given unique ID and type.
526
+     *
527
+     * @param string $type Type of the cache entry, i.e. "body" or "header"
528
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
529
+     * @param string[] $prefixes List of prefixes of all parameters that are relevant for generating the output
530
+     * @param string $confkey Configuration key prefix that matches all relevant settings for the component
531
+     * @return string Cached entry or empty string if not available
532
+     */
533
+    protected function getCached( $type, $uid, array $prefixes, $confkey )
534
+    {
535
+        if( !isset( $this->cache ) )
536
+        {
537
+            $context = $this->getContext();
538
+            $config = $context->getConfig();
539
+
540
+            /** client/html/common/cache/force
541
+             * Enforces content caching regardless of user logins
542
+             *
543
+             * Caching the component output is normally disabled as soon as the
544
+             * user has logged in. This enables displaying user or user group
545
+             * specific content without mixing standard and user specific output.
546
+             *
547
+             * If you don't have any user or user group specific content
548
+             * (products, categories, attributes, media, prices, texts, etc.),
549
+             * you can enforce content caching nevertheless to keep response
550
+             * times as low as possible.
551
+             *
552
+             * @param boolean True to cache output regardless of login, false for no caching
553
+             * @since 2015.08
554
+             * @category Developer
555
+             * @category User
556
+             * @see client/html/common/cache/tag-all
557
+             */
558
+            $force = $config->get( 'client/html/common/cache/force', false );
559
+
560
+            if( $force == false && $context->getUserId() !== null ) {
561
+                return null;
562
+            }
563
+
564
+            $cfg = $config->get( $confkey, array() );
565
+
566
+            $keys = array(
567
+                'body' => $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':body', $cfg ),
568
+                'header' => $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':header', $cfg ),
569
+            );
570
+
571
+            $entries = $context->getCache()->getList( $keys );
572
+            $this->cache = array();
573
+
574
+            foreach( $keys as $key => $hash ) {
575
+                $this->cache[$key] = ( array_key_exists( $hash, $entries ) ? $entries[$hash] : null );
576
+            }
577
+        }
578
+
579
+        return ( array_key_exists( $type, $this->cache ) ? $this->cache[$type] : null );
580
+    }
581
+
582
+
583
+    /**
584
+     * Returns the cache entry for the given type and unique ID.
585
+     *
586
+     * @param string $type Type of the cache entry, i.e. "body" or "header"
587
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
588
+     * @param string[] $prefixes List of prefixes of all parameters that are relevant for generating the output
589
+     * @param string $confkey Configuration key prefix that matches all relevant settings for the component
590
+     * @param string $value Value string that should be stored for the given key
591
+     * @param array $tags List of tag strings that should be assoicated to the
592
+     * 	given value in the cache
593
+     * @param string|null $expire Date/time string in "YYYY-MM-DD HH:mm:ss"
594
+     * 	format when the cache entry expires
595
+     */
596
+    protected function setCached( $type, $uid, array $prefixes, $confkey, $value, array $tags, $expire )
597
+    {
598
+        $context = $this->getContext();
599
+        $config = $context->getConfig();
600
+
601
+        $force = $config->get( 'client/html/common/cache/force', false );
602
+
603
+        if( $force == false && $context->getUserId() !== null ) {
604
+            return;
605
+        }
606
+
607
+        try
608
+        {
609
+            $cfg = $config->get( $confkey, array() );
610
+            $key = $this->getParamHash( $prefixes, $uid . ':' . $confkey . ':' . $type, $cfg );
611
+
612
+            $context->getCache()->set( $key, $value, array_unique( $tags ), $expire );
613
+        }
614
+        catch( \Exception $e )
615
+        {
616
+            $msg = sprintf( 'Unable to set cache entry: %1$s', $e->getMessage() );
617
+            $context->getLogger()->log( $msg, \Aimeos\MW\Logger\Base::NOTICE );
618
+        }
619
+    }
620
+
621
+
622
+    /**
623
+     * Replaces the section in the content that is enclosed by the marker.
624
+     *
625
+     * @param string $content Cached content
626
+     * @param string $section New section content
627
+     * @param string $marker Name of the section marker without "<!-- " and " -->" parts
628
+     */
629
+    protected function replaceSection( $content, $section, $marker )
630
+    {
631
+        $start = 0;
632
+        $len = strlen( $section );
633
+        $marker = '<!-- ' . $marker . ' -->';
634
+
635
+        while( ( $start = @strpos( $content, $marker, $start ) ) !== false )
636
+        {
637
+            if( ( $end = strpos( $content, $marker, $start + 1 ) ) !== false ) {
638
+                $content = substr_replace( $content, $section, $start, $end - $start + strlen( $marker ) );
639
+            }
640
+
641
+            $start += 2 * strlen( $marker ) + $len;
642
+        }
643
+
644
+        return $content;
645
+    }
646
+
647
+
648
+    /**
649
+     * Sets the necessary parameter values in the view.
650
+     *
651
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
652
+     * @param array &$tags Result array for the list of tags that are associated to the output
653
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
654
+     * @return \Aimeos\MW\View\Iface Modified view object
655
+     */
656
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
657
+    {
658
+        return $view;
659
+    }
660
+
661
+
662
+    /**
663
+     * Translates the plugin error codes to human readable error strings.
664
+     *
665
+     * @param array $codes Associative list of scope and object as key and error code as value
666
+     * @return array List of translated error messages
667
+     */
668
+    protected function translatePluginErrorCodes( array $codes )
669
+    {
670
+        $errors = array();
671
+        $i18n = $this->context->getI18n();
672
+
673
+        foreach( $codes as $scope => $list )
674
+        {
675
+            foreach( $list as $object => $errcode )
676
+            {
677
+                $key = $scope . ( $scope !== 'product' ? '.' . $object : '' ) . '.' . $errcode;
678
+                $errors[] = $i18n->dt( 'mshop/code', $key );
679
+            }
680
+        }
681
+
682
+        return $errors;
683
+    }
684 684
 }
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Stage/Breadcrumb/Standard.php 1 patch
Indentation   +226 added lines, -226 removed lines patch added patch discarded remove patch
@@ -19,231 +19,231 @@
 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/stage/breadcrumb/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog stage breadcrumb 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/stage/breadcrumb/standard/subparts';
59
-	private $subPartNames = array();
60
-
61
-
62
-	/**
63
-	 * Returns the HTML code for insertion into the body.
64
-	 *
65
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
66
-	 * @param array &$tags Result array for the list of tags that are associated to the output
67
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
68
-	 * @return string HTML code
69
-	 */
70
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
71
-	{
72
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
73
-
74
-		$html = '';
75
-		foreach( $this->getSubClients() as $subclient ) {
76
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
77
-		}
78
-		$view->breadcrumbBody = $html;
79
-
80
-		/** client/html/catalog/stage/breadcrumb/standard/template-body
81
-		 * Relative path to the HTML body template of the catalog stage breadcrumb client.
82
-		 *
83
-		 * The template file contains the HTML code and processing instructions
84
-		 * to generate the result shown in the body of the frontend. The
85
-		 * configuration string is the path to the template file relative
86
-		 * to the templates directory (usually in client/html/templates).
87
-		 *
88
-		 * You can overwrite the template file configuration in extensions and
89
-		 * provide alternative templates. These alternative templates should be
90
-		 * named like the default one but with the string "standard" replaced by
91
-		 * an unique name. You may use the name of your project for this. If
92
-		 * you've implemented an alternative client class as well, "standard"
93
-		 * should be replaced by the name of the new class.
94
-		 *
95
-		 * @param string Relative path to the template creating code for the HTML page body
96
-		 * @since 2014.03
97
-		 * @category Developer
98
-		 * @see client/html/catalog/stage/breadcrumb/standard/template-header
99
-		 */
100
-		$tplconf = 'client/html/catalog/stage/breadcrumb/standard/template-body';
101
-		$default = 'catalog/stage/breadcrumb-body-default.php';
102
-
103
-		return $view->render( $view->config( $tplconf, $default ) );
104
-	}
105
-
106
-
107
-	/**
108
-	 * Returns the HTML string for insertion into the header.
109
-	 *
110
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
111
-	 * @param array &$tags Result array for the list of tags that are associated to the output
112
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
113
-	 * @return string|null String including HTML tags for the header on error
114
-	 */
115
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
116
-	{
117
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
118
-
119
-		$html = '';
120
-		foreach( $this->getSubClients() as $subclient ) {
121
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
122
-		}
123
-		$view->breadcrumbHeader = $html;
124
-
125
-		/** client/html/catalog/stage/breadcrumb/standard/template-header
126
-		 * Relative path to the HTML header template of the catalog stage breadcrumb client.
127
-		 *
128
-		 * The template file contains the HTML code and processing instructions
129
-		 * to generate the HTML code that is inserted into the HTML page header
130
-		 * of the rendered page in the frontend. The configuration string is the
131
-		 * path to the template file relative to the templates directory (usually
132
-		 * in client/html/templates).
133
-		 *
134
-		 * You can overwrite the template file configuration in extensions and
135
-		 * provide alternative templates. These alternative templates should be
136
-		 * named like the default one but with the string "standard" replaced by
137
-		 * an unique name. You may use the name of your project for this. If
138
-		 * you've implemented an alternative client class as well, "standard"
139
-		 * should be replaced by the name of the new class.
140
-		 *
141
-		 * @param string Relative path to the template creating code for the HTML page head
142
-		 * @since 2014.03
143
-		 * @category Developer
144
-		 * @see client/html/catalog/stage/breadcrumb/standard/template-body
145
-		 */
146
-		$tplconf = 'client/html/catalog/stage/breadcrumb/standard/template-header';
147
-		$default = 'catalog/stage/breadcrumb-header-default.php';
148
-
149
-		return $view->render( $view->config( $tplconf, $default ) );
150
-	}
151
-
152
-
153
-	/**
154
-	 * Returns the sub-client given by its name.
155
-	 *
156
-	 * @param string $type Name of the client type
157
-	 * @param string|null $name Name of the sub-client (Default if null)
158
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
159
-	 */
160
-	public function getSubClient( $type, $name = null )
161
-	{
162
-		/** client/html/catalog/stage/breadcrumb/decorators/excludes
163
-		 * Excludes decorators added by the "common" option from the catalog stage breadcrumb html client
164
-		 *
165
-		 * Decorators extend the functionality of a class by adding new aspects
166
-		 * (e.g. log what is currently done), executing the methods of the underlying
167
-		 * class only in certain conditions (e.g. only for logged in users) or
168
-		 * modify what is returned to the caller.
169
-		 *
170
-		 * This option allows you to remove a decorator added via
171
-		 * "client/html/common/decorators/default" before they are wrapped
172
-		 * around the html client.
173
-		 *
174
-		 *  client/html/catalog/stage/breadcrumb/decorators/excludes = array( 'decorator1' )
175
-		 *
176
-		 * This would remove the decorator named "decorator1" from the list of
177
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
178
-		 * "client/html/common/decorators/default" to the html client.
179
-		 *
180
-		 * @param array List of decorator names
181
-		 * @since 2014.05
182
-		 * @category Developer
183
-		 * @see client/html/common/decorators/default
184
-		 * @see client/html/catalog/stage/breadcrumb/decorators/global
185
-		 * @see client/html/catalog/stage/breadcrumb/decorators/local
186
-		 */
187
-
188
-		/** client/html/catalog/stage/breadcrumb/decorators/global
189
-		 * Adds a list of globally available decorators only to the catalog stage breadcrumb html client
190
-		 *
191
-		 * Decorators extend the functionality of a class by adding new aspects
192
-		 * (e.g. log what is currently done), executing the methods of the underlying
193
-		 * class only in certain conditions (e.g. only for logged in users) or
194
-		 * modify what is returned to the caller.
195
-		 *
196
-		 * This option allows you to wrap global decorators
197
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
198
-		 *
199
-		 *  client/html/catalog/stage/breadcrumb/decorators/global = array( 'decorator1' )
200
-		 *
201
-		 * This would add the decorator named "decorator1" defined by
202
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
203
-		 *
204
-		 * @param array List of decorator names
205
-		 * @since 2014.05
206
-		 * @category Developer
207
-		 * @see client/html/common/decorators/default
208
-		 * @see client/html/catalog/stage/breadcrumb/decorators/excludes
209
-		 * @see client/html/catalog/stage/breadcrumb/decorators/local
210
-		 */
211
-
212
-		/** client/html/catalog/stage/breadcrumb/decorators/local
213
-		 * Adds a list of local decorators only to the catalog stage breadcrumb html client
214
-		 *
215
-		 * Decorators extend the functionality of a class by adding new aspects
216
-		 * (e.g. log what is currently done), executing the methods of the underlying
217
-		 * class only in certain conditions (e.g. only for logged in users) or
218
-		 * modify what is returned to the caller.
219
-		 *
220
-		 * This option allows you to wrap local decorators
221
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
222
-		 *
223
-		 *  client/html/catalog/stage/breadcrumb/decorators/local = array( 'decorator2' )
224
-		 *
225
-		 * This would add the decorator named "decorator2" defined by
226
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
227
-		 *
228
-		 * @param array List of decorator names
229
-		 * @since 2014.05
230
-		 * @category Developer
231
-		 * @see client/html/common/decorators/default
232
-		 * @see client/html/catalog/stage/breadcrumb/decorators/excludes
233
-		 * @see client/html/catalog/stage/breadcrumb/decorators/global
234
-		 */
235
-
236
-		return $this->createSubClient( 'catalog/stage/breadcrumb/' . $type, $name );
237
-	}
238
-
239
-
240
-	/**
241
-	 * Returns the list of sub-client names configured for the client.
242
-	 *
243
-	 * @return array List of HTML client names
244
-	 */
245
-	protected function getSubClientNames()
246
-	{
247
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
-	}
25
+    /** client/html/catalog/stage/breadcrumb/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog stage breadcrumb 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/stage/breadcrumb/standard/subparts';
59
+    private $subPartNames = array();
60
+
61
+
62
+    /**
63
+     * Returns the HTML code for insertion into the body.
64
+     *
65
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
66
+     * @param array &$tags Result array for the list of tags that are associated to the output
67
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
68
+     * @return string HTML code
69
+     */
70
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
71
+    {
72
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
73
+
74
+        $html = '';
75
+        foreach( $this->getSubClients() as $subclient ) {
76
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
77
+        }
78
+        $view->breadcrumbBody = $html;
79
+
80
+        /** client/html/catalog/stage/breadcrumb/standard/template-body
81
+         * Relative path to the HTML body template of the catalog stage breadcrumb client.
82
+         *
83
+         * The template file contains the HTML code and processing instructions
84
+         * to generate the result shown in the body of the frontend. The
85
+         * configuration string is the path to the template file relative
86
+         * to the templates directory (usually in client/html/templates).
87
+         *
88
+         * You can overwrite the template file configuration in extensions and
89
+         * provide alternative templates. These alternative templates should be
90
+         * named like the default one but with the string "standard" replaced by
91
+         * an unique name. You may use the name of your project for this. If
92
+         * you've implemented an alternative client class as well, "standard"
93
+         * should be replaced by the name of the new class.
94
+         *
95
+         * @param string Relative path to the template creating code for the HTML page body
96
+         * @since 2014.03
97
+         * @category Developer
98
+         * @see client/html/catalog/stage/breadcrumb/standard/template-header
99
+         */
100
+        $tplconf = 'client/html/catalog/stage/breadcrumb/standard/template-body';
101
+        $default = 'catalog/stage/breadcrumb-body-default.php';
102
+
103
+        return $view->render( $view->config( $tplconf, $default ) );
104
+    }
105
+
106
+
107
+    /**
108
+     * Returns the HTML string for insertion into the header.
109
+     *
110
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
111
+     * @param array &$tags Result array for the list of tags that are associated to the output
112
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
113
+     * @return string|null String including HTML tags for the header on error
114
+     */
115
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
116
+    {
117
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
118
+
119
+        $html = '';
120
+        foreach( $this->getSubClients() as $subclient ) {
121
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
122
+        }
123
+        $view->breadcrumbHeader = $html;
124
+
125
+        /** client/html/catalog/stage/breadcrumb/standard/template-header
126
+         * Relative path to the HTML header template of the catalog stage breadcrumb client.
127
+         *
128
+         * The template file contains the HTML code and processing instructions
129
+         * to generate the HTML code that is inserted into the HTML page header
130
+         * of the rendered page in the frontend. The configuration string is the
131
+         * path to the template file relative to the templates directory (usually
132
+         * in client/html/templates).
133
+         *
134
+         * You can overwrite the template file configuration in extensions and
135
+         * provide alternative templates. These alternative templates should be
136
+         * named like the default one but with the string "standard" replaced by
137
+         * an unique name. You may use the name of your project for this. If
138
+         * you've implemented an alternative client class as well, "standard"
139
+         * should be replaced by the name of the new class.
140
+         *
141
+         * @param string Relative path to the template creating code for the HTML page head
142
+         * @since 2014.03
143
+         * @category Developer
144
+         * @see client/html/catalog/stage/breadcrumb/standard/template-body
145
+         */
146
+        $tplconf = 'client/html/catalog/stage/breadcrumb/standard/template-header';
147
+        $default = 'catalog/stage/breadcrumb-header-default.php';
148
+
149
+        return $view->render( $view->config( $tplconf, $default ) );
150
+    }
151
+
152
+
153
+    /**
154
+     * Returns the sub-client given by its name.
155
+     *
156
+     * @param string $type Name of the client type
157
+     * @param string|null $name Name of the sub-client (Default if null)
158
+     * @return \Aimeos\Client\Html\Iface Sub-client object
159
+     */
160
+    public function getSubClient( $type, $name = null )
161
+    {
162
+        /** client/html/catalog/stage/breadcrumb/decorators/excludes
163
+         * Excludes decorators added by the "common" option from the catalog stage breadcrumb html client
164
+         *
165
+         * Decorators extend the functionality of a class by adding new aspects
166
+         * (e.g. log what is currently done), executing the methods of the underlying
167
+         * class only in certain conditions (e.g. only for logged in users) or
168
+         * modify what is returned to the caller.
169
+         *
170
+         * This option allows you to remove a decorator added via
171
+         * "client/html/common/decorators/default" before they are wrapped
172
+         * around the html client.
173
+         *
174
+         *  client/html/catalog/stage/breadcrumb/decorators/excludes = array( 'decorator1' )
175
+         *
176
+         * This would remove the decorator named "decorator1" from the list of
177
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
178
+         * "client/html/common/decorators/default" to the html client.
179
+         *
180
+         * @param array List of decorator names
181
+         * @since 2014.05
182
+         * @category Developer
183
+         * @see client/html/common/decorators/default
184
+         * @see client/html/catalog/stage/breadcrumb/decorators/global
185
+         * @see client/html/catalog/stage/breadcrumb/decorators/local
186
+         */
187
+
188
+        /** client/html/catalog/stage/breadcrumb/decorators/global
189
+         * Adds a list of globally available decorators only to the catalog stage breadcrumb html client
190
+         *
191
+         * Decorators extend the functionality of a class by adding new aspects
192
+         * (e.g. log what is currently done), executing the methods of the underlying
193
+         * class only in certain conditions (e.g. only for logged in users) or
194
+         * modify what is returned to the caller.
195
+         *
196
+         * This option allows you to wrap global decorators
197
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
198
+         *
199
+         *  client/html/catalog/stage/breadcrumb/decorators/global = array( 'decorator1' )
200
+         *
201
+         * This would add the decorator named "decorator1" defined by
202
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
203
+         *
204
+         * @param array List of decorator names
205
+         * @since 2014.05
206
+         * @category Developer
207
+         * @see client/html/common/decorators/default
208
+         * @see client/html/catalog/stage/breadcrumb/decorators/excludes
209
+         * @see client/html/catalog/stage/breadcrumb/decorators/local
210
+         */
211
+
212
+        /** client/html/catalog/stage/breadcrumb/decorators/local
213
+         * Adds a list of local decorators only to the catalog stage breadcrumb html client
214
+         *
215
+         * Decorators extend the functionality of a class by adding new aspects
216
+         * (e.g. log what is currently done), executing the methods of the underlying
217
+         * class only in certain conditions (e.g. only for logged in users) or
218
+         * modify what is returned to the caller.
219
+         *
220
+         * This option allows you to wrap local decorators
221
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
222
+         *
223
+         *  client/html/catalog/stage/breadcrumb/decorators/local = array( 'decorator2' )
224
+         *
225
+         * This would add the decorator named "decorator2" defined by
226
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
227
+         *
228
+         * @param array List of decorator names
229
+         * @since 2014.05
230
+         * @category Developer
231
+         * @see client/html/common/decorators/default
232
+         * @see client/html/catalog/stage/breadcrumb/decorators/excludes
233
+         * @see client/html/catalog/stage/breadcrumb/decorators/global
234
+         */
235
+
236
+        return $this->createSubClient( 'catalog/stage/breadcrumb/' . $type, $name );
237
+    }
238
+
239
+
240
+    /**
241
+     * Returns the list of sub-client names configured for the client.
242
+     *
243
+     * @return array List of HTML client names
244
+     */
245
+    protected function getSubClientNames()
246
+    {
247
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
+    }
249 249
 }
250 250
\ No newline at end of file
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Stage/Navigator/Standard.php 1 patch
Indentation   +323 added lines, -323 removed lines patch added patch discarded remove patch
@@ -19,328 +19,328 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 class Standard
22
-	extends \Aimeos\Client\Html\Catalog\Base
23
-	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
22
+    extends \Aimeos\Client\Html\Catalog\Base
23
+    implements \Aimeos\Client\Html\Common\Client\Factory\Iface
24 24
 {
25
-	/** client/html/catalog/stage/navigator/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog stage navigator 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/stage/navigator/standard/subparts';
59
-	private $subPartNames = array();
60
-	private $view;
61
-
62
-
63
-	/**
64
-	 * Returns the HTML code for insertion into the body.
65
-	 *
66
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
-	 * @param array &$tags Result array for the list of tags that are associated to the output
68
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
-	 * @return string HTML code
70
-	 */
71
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
-	{
73
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
74
-
75
-		$html = '';
76
-		foreach( $this->getSubClients() as $subclient ) {
77
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
-		}
79
-		$view->navigatorBody = $html;
80
-
81
-		/** client/html/catalog/stage/navigator/standard/template-body
82
-		 * Relative path to the HTML body template of the catalog stage navigator client.
83
-		 *
84
-		 * The template file contains the HTML code and processing instructions
85
-		 * to generate the result shown in the body of the frontend. The
86
-		 * configuration string is the path to the template file relative
87
-		 * to the templates directory (usually in client/html/templates).
88
-		 *
89
-		 * You can overwrite the template file configuration in extensions and
90
-		 * provide alternative templates. These alternative templates should be
91
-		 * named like the default one but with the string "standard" replaced by
92
-		 * an unique name. You may use the name of your project for this. If
93
-		 * you've implemented an alternative client class as well, "standard"
94
-		 * should be replaced by the name of the new class.
95
-		 *
96
-		 * @param string Relative path to the template creating code for the HTML page body
97
-		 * @since 2014.03
98
-		 * @category Developer
99
-		 * @see client/html/catalog/stage/navigator/standard/template-header
100
-		 */
101
-		$tplconf = 'client/html/catalog/stage/navigator/standard/template-body';
102
-		$default = 'catalog/stage/navigator-body-default.php';
103
-
104
-		return $view->render( $view->config( $tplconf, $default ) );
105
-	}
106
-
107
-
108
-	/**
109
-	 * Returns the HTML string for insertion into the header.
110
-	 *
111
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
-	 * @param array &$tags Result array for the list of tags that are associated to the output
113
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
-	 * @return string|null String including HTML tags for the header on error
115
-	 */
116
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
-	{
118
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
119
-
120
-		$html = '';
121
-		foreach( $this->getSubClients() as $subclient ) {
122
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
-		}
124
-		$view->navigatorHeader = $html;
125
-
126
-		/** client/html/catalog/stage/navigator/standard/template-header
127
-		 * Relative path to the HTML header template of the catalog stage navigator client.
128
-		 *
129
-		 * The template file contains the HTML code and processing instructions
130
-		 * to generate the HTML code that is inserted into the HTML page header
131
-		 * of the rendered page in the frontend. The configuration string is the
132
-		 * path to the template file relative to the templates directory (usually
133
-		 * in client/html/templates).
134
-		 *
135
-		 * You can overwrite the template file configuration in extensions and
136
-		 * provide alternative templates. These alternative templates should be
137
-		 * named like the default one but with the string "standard" replaced by
138
-		 * an unique name. You may use the name of your project for this. If
139
-		 * you've implemented an alternative client class as well, "standard"
140
-		 * should be replaced by the name of the new class.
141
-		 *
142
-		 * @param string Relative path to the template creating code for the HTML page head
143
-		 * @since 2014.03
144
-		 * @category Developer
145
-		 * @see client/html/catalog/stage/navigator/standard/template-body
146
-		 */
147
-		$tplconf = 'client/html/catalog/stage/navigator/standard/template-header';
148
-		$default = 'catalog/stage/navigator-header-default.php';
149
-
150
-		return $view->render( $view->config( $tplconf, $default ) );
151
-	}
152
-
153
-
154
-	/**
155
-	 * Returns the sub-client given by its name.
156
-	 *
157
-	 * @param string $type Name of the client type
158
-	 * @param string|null $name Name of the sub-client (Default if null)
159
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
160
-	 */
161
-	public function getSubClient( $type, $name = null )
162
-	{
163
-		/** client/html/catalog/stage/navigator/decorators/excludes
164
-		 * Excludes decorators added by the "common" option from the catalog stage navigator html client
165
-		 *
166
-		 * Decorators extend the functionality of a class by adding new aspects
167
-		 * (e.g. log what is currently done), executing the methods of the underlying
168
-		 * class only in certain conditions (e.g. only for logged in users) or
169
-		 * modify what is returned to the caller.
170
-		 *
171
-		 * This option allows you to remove a decorator added via
172
-		 * "client/html/common/decorators/default" before they are wrapped
173
-		 * around the html client.
174
-		 *
175
-		 *  client/html/catalog/stage/navigator/decorators/excludes = array( 'decorator1' )
176
-		 *
177
-		 * This would remove the decorator named "decorator1" from the list of
178
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
-		 * "client/html/common/decorators/default" to the html client.
180
-		 *
181
-		 * @param array List of decorator names
182
-		 * @since 2014.05
183
-		 * @category Developer
184
-		 * @see client/html/common/decorators/default
185
-		 * @see client/html/catalog/stage/navigator/decorators/global
186
-		 * @see client/html/catalog/stage/navigator/decorators/local
187
-		 */
188
-
189
-		/** client/html/catalog/stage/navigator/decorators/global
190
-		 * Adds a list of globally available decorators only to the catalog stage navigator html client
191
-		 *
192
-		 * Decorators extend the functionality of a class by adding new aspects
193
-		 * (e.g. log what is currently done), executing the methods of the underlying
194
-		 * class only in certain conditions (e.g. only for logged in users) or
195
-		 * modify what is returned to the caller.
196
-		 *
197
-		 * This option allows you to wrap global decorators
198
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
-		 *
200
-		 *  client/html/catalog/stage/navigator/decorators/global = array( 'decorator1' )
201
-		 *
202
-		 * This would add the decorator named "decorator1" defined by
203
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
-		 *
205
-		 * @param array List of decorator names
206
-		 * @since 2014.05
207
-		 * @category Developer
208
-		 * @see client/html/common/decorators/default
209
-		 * @see client/html/catalog/stage/navigator/decorators/excludes
210
-		 * @see client/html/catalog/stage/navigator/decorators/local
211
-		 */
212
-
213
-		/** client/html/catalog/stage/navigator/decorators/local
214
-		 * Adds a list of local decorators only to the catalog stage navigator html client
215
-		 *
216
-		 * Decorators extend the functionality of a class by adding new aspects
217
-		 * (e.g. log what is currently done), executing the methods of the underlying
218
-		 * class only in certain conditions (e.g. only for logged in users) or
219
-		 * modify what is returned to the caller.
220
-		 *
221
-		 * This option allows you to wrap local decorators
222
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
223
-		 *
224
-		 *  client/html/catalog/stage/navigator/decorators/local = array( 'decorator2' )
225
-		 *
226
-		 * This would add the decorator named "decorator2" defined by
227
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
228
-		 *
229
-		 * @param array List of decorator names
230
-		 * @since 2014.05
231
-		 * @category Developer
232
-		 * @see client/html/common/decorators/default
233
-		 * @see client/html/catalog/stage/navigator/decorators/excludes
234
-		 * @see client/html/catalog/stage/navigator/decorators/global
235
-		 */
236
-
237
-		return $this->createSubClient( 'catalog/stage/navigator/' . $type, $name );
238
-	}
239
-
240
-
241
-	/**
242
-	 * Modifies the cached body content to replace content based on sessions or cookies.
243
-	 *
244
-	 * @param string $content Cached content
245
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
246
-	 * @return string Modified body content
247
-	 */
248
-	public function modifyBody( $content, $uid )
249
-	{
250
-		return $this->replaceSection( $content, $this->getBody( $uid ), 'catalog.stage.navigator' );
251
-	}
252
-
253
-
254
-	/**
255
-	 * Modifies the cached header content to replace content based on sessions or cookies.
256
-	 *
257
-	 * @param string $content Cached content
258
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
259
-	 * @return string Modified body content
260
-	 */
261
-	public function modifyHeader( $content, $uid )
262
-	{
263
-		return $this->replaceSection( $content, $this->getHeader( $uid ), 'catalog.stage.navigator' );
264
-	}
265
-
266
-
267
-	/**
268
-	 * Returns the list of sub-client names configured for the client.
269
-	 *
270
-	 * @return array List of HTML client names
271
-	 */
272
-	protected function getSubClientNames()
273
-	{
274
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
275
-	}
276
-
277
-
278
-	/**
279
-	 * Sets the necessary parameter values in the view.
280
-	 *
281
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
282
-	 * @param array &$tags Result array for the list of tags that are associated to the output
283
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
284
-	 * @return \Aimeos\MW\View\Iface Modified view object
285
-	 */
286
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
287
-	{
288
-		if( !isset( $this->view ) )
289
-		{
290
-			if( ( $pos = $view->param( 'l_pos' ) ) !== null && ( $pid = $view->param( 'd_prodid' ) ) !== null )
291
-			{
292
-				if( $pos < 1 ) {
293
-					$start = 0; $size = 2;
294
-				} else {
295
-					$start = $pos - 1; $size = 3;
296
-				}
297
-
298
-				$context = $this->getContext();
299
-				$site = $context->getLocale()->getSite()->getCode();
300
-				$params = $context->getSession()->get( 'aimeos/catalog/lists/params/last/' . $site, array() );
301
-
302
-				$filter = $this->getProductListFilterByParam( $params );
303
-				$filter->setSlice( $start, $size );
304
-				$total = null;
305
-
306
-				$controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
307
-				$products = $controller->getIndexItems( $filter, array( 'text' ), $total );
308
-
309
-				if( ( $count = count( $products ) ) > 1 )
310
-				{
311
-					$enc = $view->encoder();
312
-					$listPos = array_search( $pid, array_keys( $products ) );
313
-
314
-					$target = $view->config( 'client/html/catalog/detail/url/target' );
315
-					$controller = $view->config( 'client/html/catalog/detail/url/controller', 'catalog' );
316
-					$action = $view->config( 'client/html/catalog/detail/url/action', 'detail' );
317
-					$config = $view->config( 'client/html/catalog/detail/url/config', array() );
318
-
319
-					if( $listPos > 0 && ( $product = reset( $products ) ) !== false )
320
-					{
321
-						$param = array(
322
-							'd_prodid' => $product->getId(),
323
-							'd_name' => $enc->url( $product->getName( 'url ' ) ),
324
-							'l_pos' => $pos - 1
325
-						);
326
-						$view->navigationPrev = $view->url( $target, $controller, $action, $param, array(), $config );
327
-					}
328
-
329
-					if( $listPos < $count - 1 && ( $product = end( $products ) ) !== false )
330
-					{
331
-						$param = array(
332
-							'd_prodid' => $product->getId(),
333
-							'd_name' => $enc->url( $product->getName( 'url' ) ),
334
-							'l_pos' => $pos + 1
335
-						);
336
-						$view->navigationNext = $view->url( $target, $controller, $action, $param, array(), $config );
337
-					}
338
-				}
339
-			}
340
-
341
-			$this->view = $view;
342
-		}
343
-
344
-		return $this->view;
345
-	}
25
+    /** client/html/catalog/stage/navigator/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog stage navigator 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/stage/navigator/standard/subparts';
59
+    private $subPartNames = array();
60
+    private $view;
61
+
62
+
63
+    /**
64
+     * Returns the HTML code for insertion into the body.
65
+     *
66
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
+     * @param array &$tags Result array for the list of tags that are associated to the output
68
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
+     * @return string HTML code
70
+     */
71
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
+    {
73
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
74
+
75
+        $html = '';
76
+        foreach( $this->getSubClients() as $subclient ) {
77
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
+        }
79
+        $view->navigatorBody = $html;
80
+
81
+        /** client/html/catalog/stage/navigator/standard/template-body
82
+         * Relative path to the HTML body template of the catalog stage navigator client.
83
+         *
84
+         * The template file contains the HTML code and processing instructions
85
+         * to generate the result shown in the body of the frontend. The
86
+         * configuration string is the path to the template file relative
87
+         * to the templates directory (usually in client/html/templates).
88
+         *
89
+         * You can overwrite the template file configuration in extensions and
90
+         * provide alternative templates. These alternative templates should be
91
+         * named like the default one but with the string "standard" replaced by
92
+         * an unique name. You may use the name of your project for this. If
93
+         * you've implemented an alternative client class as well, "standard"
94
+         * should be replaced by the name of the new class.
95
+         *
96
+         * @param string Relative path to the template creating code for the HTML page body
97
+         * @since 2014.03
98
+         * @category Developer
99
+         * @see client/html/catalog/stage/navigator/standard/template-header
100
+         */
101
+        $tplconf = 'client/html/catalog/stage/navigator/standard/template-body';
102
+        $default = 'catalog/stage/navigator-body-default.php';
103
+
104
+        return $view->render( $view->config( $tplconf, $default ) );
105
+    }
106
+
107
+
108
+    /**
109
+     * Returns the HTML string for insertion into the header.
110
+     *
111
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
+     * @param array &$tags Result array for the list of tags that are associated to the output
113
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
+     * @return string|null String including HTML tags for the header on error
115
+     */
116
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
+    {
118
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
119
+
120
+        $html = '';
121
+        foreach( $this->getSubClients() as $subclient ) {
122
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
+        }
124
+        $view->navigatorHeader = $html;
125
+
126
+        /** client/html/catalog/stage/navigator/standard/template-header
127
+         * Relative path to the HTML header template of the catalog stage navigator client.
128
+         *
129
+         * The template file contains the HTML code and processing instructions
130
+         * to generate the HTML code that is inserted into the HTML page header
131
+         * of the rendered page in the frontend. The configuration string is the
132
+         * path to the template file relative to the templates directory (usually
133
+         * in client/html/templates).
134
+         *
135
+         * You can overwrite the template file configuration in extensions and
136
+         * provide alternative templates. These alternative templates should be
137
+         * named like the default one but with the string "standard" replaced by
138
+         * an unique name. You may use the name of your project for this. If
139
+         * you've implemented an alternative client class as well, "standard"
140
+         * should be replaced by the name of the new class.
141
+         *
142
+         * @param string Relative path to the template creating code for the HTML page head
143
+         * @since 2014.03
144
+         * @category Developer
145
+         * @see client/html/catalog/stage/navigator/standard/template-body
146
+         */
147
+        $tplconf = 'client/html/catalog/stage/navigator/standard/template-header';
148
+        $default = 'catalog/stage/navigator-header-default.php';
149
+
150
+        return $view->render( $view->config( $tplconf, $default ) );
151
+    }
152
+
153
+
154
+    /**
155
+     * Returns the sub-client given by its name.
156
+     *
157
+     * @param string $type Name of the client type
158
+     * @param string|null $name Name of the sub-client (Default if null)
159
+     * @return \Aimeos\Client\Html\Iface Sub-client object
160
+     */
161
+    public function getSubClient( $type, $name = null )
162
+    {
163
+        /** client/html/catalog/stage/navigator/decorators/excludes
164
+         * Excludes decorators added by the "common" option from the catalog stage navigator html client
165
+         *
166
+         * Decorators extend the functionality of a class by adding new aspects
167
+         * (e.g. log what is currently done), executing the methods of the underlying
168
+         * class only in certain conditions (e.g. only for logged in users) or
169
+         * modify what is returned to the caller.
170
+         *
171
+         * This option allows you to remove a decorator added via
172
+         * "client/html/common/decorators/default" before they are wrapped
173
+         * around the html client.
174
+         *
175
+         *  client/html/catalog/stage/navigator/decorators/excludes = array( 'decorator1' )
176
+         *
177
+         * This would remove the decorator named "decorator1" from the list of
178
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
+         * "client/html/common/decorators/default" to the html client.
180
+         *
181
+         * @param array List of decorator names
182
+         * @since 2014.05
183
+         * @category Developer
184
+         * @see client/html/common/decorators/default
185
+         * @see client/html/catalog/stage/navigator/decorators/global
186
+         * @see client/html/catalog/stage/navigator/decorators/local
187
+         */
188
+
189
+        /** client/html/catalog/stage/navigator/decorators/global
190
+         * Adds a list of globally available decorators only to the catalog stage navigator html client
191
+         *
192
+         * Decorators extend the functionality of a class by adding new aspects
193
+         * (e.g. log what is currently done), executing the methods of the underlying
194
+         * class only in certain conditions (e.g. only for logged in users) or
195
+         * modify what is returned to the caller.
196
+         *
197
+         * This option allows you to wrap global decorators
198
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
+         *
200
+         *  client/html/catalog/stage/navigator/decorators/global = array( 'decorator1' )
201
+         *
202
+         * This would add the decorator named "decorator1" defined by
203
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
+         *
205
+         * @param array List of decorator names
206
+         * @since 2014.05
207
+         * @category Developer
208
+         * @see client/html/common/decorators/default
209
+         * @see client/html/catalog/stage/navigator/decorators/excludes
210
+         * @see client/html/catalog/stage/navigator/decorators/local
211
+         */
212
+
213
+        /** client/html/catalog/stage/navigator/decorators/local
214
+         * Adds a list of local decorators only to the catalog stage navigator html client
215
+         *
216
+         * Decorators extend the functionality of a class by adding new aspects
217
+         * (e.g. log what is currently done), executing the methods of the underlying
218
+         * class only in certain conditions (e.g. only for logged in users) or
219
+         * modify what is returned to the caller.
220
+         *
221
+         * This option allows you to wrap local decorators
222
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
223
+         *
224
+         *  client/html/catalog/stage/navigator/decorators/local = array( 'decorator2' )
225
+         *
226
+         * This would add the decorator named "decorator2" defined by
227
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
228
+         *
229
+         * @param array List of decorator names
230
+         * @since 2014.05
231
+         * @category Developer
232
+         * @see client/html/common/decorators/default
233
+         * @see client/html/catalog/stage/navigator/decorators/excludes
234
+         * @see client/html/catalog/stage/navigator/decorators/global
235
+         */
236
+
237
+        return $this->createSubClient( 'catalog/stage/navigator/' . $type, $name );
238
+    }
239
+
240
+
241
+    /**
242
+     * Modifies the cached body content to replace content based on sessions or cookies.
243
+     *
244
+     * @param string $content Cached content
245
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
246
+     * @return string Modified body content
247
+     */
248
+    public function modifyBody( $content, $uid )
249
+    {
250
+        return $this->replaceSection( $content, $this->getBody( $uid ), 'catalog.stage.navigator' );
251
+    }
252
+
253
+
254
+    /**
255
+     * Modifies the cached header content to replace content based on sessions or cookies.
256
+     *
257
+     * @param string $content Cached content
258
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
259
+     * @return string Modified body content
260
+     */
261
+    public function modifyHeader( $content, $uid )
262
+    {
263
+        return $this->replaceSection( $content, $this->getHeader( $uid ), 'catalog.stage.navigator' );
264
+    }
265
+
266
+
267
+    /**
268
+     * Returns the list of sub-client names configured for the client.
269
+     *
270
+     * @return array List of HTML client names
271
+     */
272
+    protected function getSubClientNames()
273
+    {
274
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
275
+    }
276
+
277
+
278
+    /**
279
+     * Sets the necessary parameter values in the view.
280
+     *
281
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
282
+     * @param array &$tags Result array for the list of tags that are associated to the output
283
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
284
+     * @return \Aimeos\MW\View\Iface Modified view object
285
+     */
286
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
287
+    {
288
+        if( !isset( $this->view ) )
289
+        {
290
+            if( ( $pos = $view->param( 'l_pos' ) ) !== null && ( $pid = $view->param( 'd_prodid' ) ) !== null )
291
+            {
292
+                if( $pos < 1 ) {
293
+                    $start = 0; $size = 2;
294
+                } else {
295
+                    $start = $pos - 1; $size = 3;
296
+                }
297
+
298
+                $context = $this->getContext();
299
+                $site = $context->getLocale()->getSite()->getCode();
300
+                $params = $context->getSession()->get( 'aimeos/catalog/lists/params/last/' . $site, array() );
301
+
302
+                $filter = $this->getProductListFilterByParam( $params );
303
+                $filter->setSlice( $start, $size );
304
+                $total = null;
305
+
306
+                $controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
307
+                $products = $controller->getIndexItems( $filter, array( 'text' ), $total );
308
+
309
+                if( ( $count = count( $products ) ) > 1 )
310
+                {
311
+                    $enc = $view->encoder();
312
+                    $listPos = array_search( $pid, array_keys( $products ) );
313
+
314
+                    $target = $view->config( 'client/html/catalog/detail/url/target' );
315
+                    $controller = $view->config( 'client/html/catalog/detail/url/controller', 'catalog' );
316
+                    $action = $view->config( 'client/html/catalog/detail/url/action', 'detail' );
317
+                    $config = $view->config( 'client/html/catalog/detail/url/config', array() );
318
+
319
+                    if( $listPos > 0 && ( $product = reset( $products ) ) !== false )
320
+                    {
321
+                        $param = array(
322
+                            'd_prodid' => $product->getId(),
323
+                            'd_name' => $enc->url( $product->getName( 'url ' ) ),
324
+                            'l_pos' => $pos - 1
325
+                        );
326
+                        $view->navigationPrev = $view->url( $target, $controller, $action, $param, array(), $config );
327
+                    }
328
+
329
+                    if( $listPos < $count - 1 && ( $product = end( $products ) ) !== false )
330
+                    {
331
+                        $param = array(
332
+                            'd_prodid' => $product->getId(),
333
+                            'd_name' => $enc->url( $product->getName( 'url' ) ),
334
+                            'l_pos' => $pos + 1
335
+                        );
336
+                        $view->navigationNext = $view->url( $target, $controller, $action, $param, array(), $config );
337
+                    }
338
+                }
339
+            }
340
+
341
+            $this->view = $view;
342
+        }
343
+
344
+        return $this->view;
345
+    }
346 346
 }
347 347
\ No newline at end of file
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Stage/Factory.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -19,69 +19,69 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 class Factory
22
-	extends \Aimeos\Client\Html\Common\Factory\Base
23
-	implements \Aimeos\Client\Html\Common\Factory\Iface
22
+    extends \Aimeos\Client\Html\Common\Factory\Base
23
+    implements \Aimeos\Client\Html\Common\Factory\Iface
24 24
 {
25
-	/**
26
-	 * Creates a stage client object.
27
-	 *
28
-	 * @param \Aimeos\MShop\Context\Item\Iface $context Shop context instance with necessary objects
29
-	 * @param array $templatePaths List of file system paths where the templates are stored
30
-	 * @param string|null $name Client name (default: "Standard")
31
-	 * @return \Aimeos\Client\Html\Iface Filter part implementing \Aimeos\Client\Html\Iface
32
-	 * @throws \Aimeos\Client\Html\Exception If requested client implementation couldn't be found or initialisation fails
33
-	 */
34
-	public static function createClient( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths, $name = null )
35
-	{
36
-		/** client/html/catalog/stage/name
37
-		 * Class name of the used catalog stage client implementation
38
-		 *
39
-		 * Each default HTML client can be replace by an alternative imlementation.
40
-		 * To use this implementation, you have to set the last part of the class
41
-		 * name as configuration value so the client factory knows which class it
42
-		 * has to instantiate.
43
-		 *
44
-		 * For example, if the name of the default class is
45
-		 *
46
-		 *  \Aimeos\Client\Html\Catalog\Stage\Standard
47
-		 *
48
-		 * and you want to replace it with your own version named
49
-		 *
50
-		 *  \Aimeos\Client\Html\Catalog\Stage\Mystage
51
-		 *
52
-		 * then you have to set the this configuration option:
53
-		 *
54
-		 *  client/html/catalog/stage/name = Mystage
55
-		 *
56
-		 * The value is the last part of your own class name and it's case sensitive,
57
-		 * so take care that the configuration value is exactly named like the last
58
-		 * part of the class name.
59
-		 *
60
-		 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
61
-		 * characters are possible! You should always start the last part of the class
62
-		 * name with an upper case character and continue only with lower case characters
63
-		 * or numbers. Avoid chamel case names like "MyStage"!
64
-		 *
65
-		 * @param string Last part of the class name
66
-		 * @since 2014.03
67
-		 * @category Developer
68
-		 */
69
-		if( $name === null ) {
70
-			$name = $context->getConfig()->get( 'client/html/catalog/stage/name', 'Standard' );
71
-		}
25
+    /**
26
+     * Creates a stage client object.
27
+     *
28
+     * @param \Aimeos\MShop\Context\Item\Iface $context Shop context instance with necessary objects
29
+     * @param array $templatePaths List of file system paths where the templates are stored
30
+     * @param string|null $name Client name (default: "Standard")
31
+     * @return \Aimeos\Client\Html\Iface Filter part implementing \Aimeos\Client\Html\Iface
32
+     * @throws \Aimeos\Client\Html\Exception If requested client implementation couldn't be found or initialisation fails
33
+     */
34
+    public static function createClient( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths, $name = null )
35
+    {
36
+        /** client/html/catalog/stage/name
37
+         * Class name of the used catalog stage client implementation
38
+         *
39
+         * Each default HTML client can be replace by an alternative imlementation.
40
+         * To use this implementation, you have to set the last part of the class
41
+         * name as configuration value so the client factory knows which class it
42
+         * has to instantiate.
43
+         *
44
+         * For example, if the name of the default class is
45
+         *
46
+         *  \Aimeos\Client\Html\Catalog\Stage\Standard
47
+         *
48
+         * and you want to replace it with your own version named
49
+         *
50
+         *  \Aimeos\Client\Html\Catalog\Stage\Mystage
51
+         *
52
+         * then you have to set the this configuration option:
53
+         *
54
+         *  client/html/catalog/stage/name = Mystage
55
+         *
56
+         * The value is the last part of your own class name and it's case sensitive,
57
+         * so take care that the configuration value is exactly named like the last
58
+         * part of the class name.
59
+         *
60
+         * The allowed characters of the class name are A-Z, a-z and 0-9. No other
61
+         * characters are possible! You should always start the last part of the class
62
+         * name with an upper case character and continue only with lower case characters
63
+         * or numbers. Avoid chamel case names like "MyStage"!
64
+         *
65
+         * @param string Last part of the class name
66
+         * @since 2014.03
67
+         * @category Developer
68
+         */
69
+        if( $name === null ) {
70
+            $name = $context->getConfig()->get( 'client/html/catalog/stage/name', 'Standard' );
71
+        }
72 72
 
73
-		if( ctype_alnum( $name ) === false )
74
-		{
75
-			$classname = is_string( $name ) ? '\\Aimeos\\Client\\Html\\Catalog\\Stage\\' . $name : '<not a string>';
76
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
77
-		}
73
+        if( ctype_alnum( $name ) === false )
74
+        {
75
+            $classname = is_string( $name ) ? '\\Aimeos\\Client\\Html\\Catalog\\Stage\\' . $name : '<not a string>';
76
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
77
+        }
78 78
 
79
-		$iface = '\\Aimeos\\Client\\Html\\Iface';
80
-		$classname = '\\Aimeos\\Client\\Html\\Catalog\\Stage\\' . $name;
79
+        $iface = '\\Aimeos\\Client\\Html\\Iface';
80
+        $classname = '\\Aimeos\\Client\\Html\\Catalog\\Stage\\' . $name;
81 81
 
82
-		$client = self::createClientBase( $context, $classname, $iface, $templatePaths );
82
+        $client = self::createClientBase( $context, $classname, $iface, $templatePaths );
83 83
 
84
-		return self::addClientDecorators( $context, $client, $templatePaths, 'catalog/stage' );
85
-	}
84
+        return self::addClientDecorators( $context, $client, $templatePaths, 'catalog/stage' );
85
+    }
86 86
 }
87 87
 
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Stage/Image/Standard.php 1 patch
Indentation   +236 added lines, -236 removed lines patch added patch discarded remove patch
@@ -19,264 +19,264 @@
 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/stage/image/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog stage image 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/stage/image/standard/subparts';
59
-	private $subPartNames = array();
60
-	private $cache;
25
+    /** client/html/catalog/stage/image/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog stage image 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/stage/image/standard/subparts';
59
+    private $subPartNames = array();
60
+    private $cache;
61 61
 
62 62
 
63
-	/**
64
-	 * Returns the HTML code for insertion into the body.
65
-	 *
66
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
-	 * @param array &$tags Result array for the list of tags that are associated to the output
68
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
-	 * @return string HTML code
70
-	 */
71
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
-	{
73
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
63
+    /**
64
+     * Returns the HTML code for insertion into the body.
65
+     *
66
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
67
+     * @param array &$tags Result array for the list of tags that are associated to the output
68
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
69
+     * @return string HTML code
70
+     */
71
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
72
+    {
73
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
74 74
 
75
-		$html = '';
76
-		foreach( $this->getSubClients() as $subclient ) {
77
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
-		}
79
-		$view->imageBody = $html;
75
+        $html = '';
76
+        foreach( $this->getSubClients() as $subclient ) {
77
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
78
+        }
79
+        $view->imageBody = $html;
80 80
 
81
-		/** client/html/catalog/stage/image/standard/template-body
82
-		 * Relative path to the HTML body template of the catalog stage image client.
83
-		 *
84
-		 * The template file contains the HTML code and processing instructions
85
-		 * to generate the result shown in the body of the frontend. The
86
-		 * configuration string is the path to the template file relative
87
-		 * to the templates directory (usually in client/html/templates).
88
-		 *
89
-		 * You can overwrite the template file configuration in extensions and
90
-		 * provide alternative templates. These alternative templates should be
91
-		 * named like the default one but with the string "standard" replaced by
92
-		 * an unique name. You may use the name of your project for this. If
93
-		 * you've implemented an alternative client class as well, "standard"
94
-		 * should be replaced by the name of the new class.
95
-		 *
96
-		 * @param string Relative path to the template creating code for the HTML page body
97
-		 * @since 2014.03
98
-		 * @category Developer
99
-		 * @see client/html/catalog/stage/image/standard/template-header
100
-		 */
101
-		$tplconf = 'client/html/catalog/stage/image/standard/template-body';
102
-		$default = 'catalog/stage/image-body-default.php';
81
+        /** client/html/catalog/stage/image/standard/template-body
82
+         * Relative path to the HTML body template of the catalog stage image client.
83
+         *
84
+         * The template file contains the HTML code and processing instructions
85
+         * to generate the result shown in the body of the frontend. The
86
+         * configuration string is the path to the template file relative
87
+         * to the templates directory (usually in client/html/templates).
88
+         *
89
+         * You can overwrite the template file configuration in extensions and
90
+         * provide alternative templates. These alternative templates should be
91
+         * named like the default one but with the string "standard" replaced by
92
+         * an unique name. You may use the name of your project for this. If
93
+         * you've implemented an alternative client class as well, "standard"
94
+         * should be replaced by the name of the new class.
95
+         *
96
+         * @param string Relative path to the template creating code for the HTML page body
97
+         * @since 2014.03
98
+         * @category Developer
99
+         * @see client/html/catalog/stage/image/standard/template-header
100
+         */
101
+        $tplconf = 'client/html/catalog/stage/image/standard/template-body';
102
+        $default = 'catalog/stage/image-body-default.php';
103 103
 
104
-		return $view->render( $view->config( $tplconf, $default ) );
105
-	}
104
+        return $view->render( $view->config( $tplconf, $default ) );
105
+    }
106 106
 
107 107
 
108
-	/**
109
-	 * Returns the HTML string for insertion into the header.
110
-	 *
111
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
-	 * @param array &$tags Result array for the list of tags that are associated to the output
113
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
-	 * @return string|null String including HTML tags for the header on error
115
-	 */
116
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
-	{
118
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
108
+    /**
109
+     * Returns the HTML string for insertion into the header.
110
+     *
111
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
112
+     * @param array &$tags Result array for the list of tags that are associated to the output
113
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
114
+     * @return string|null String including HTML tags for the header on error
115
+     */
116
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
117
+    {
118
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
119 119
 
120
-		$html = '';
121
-		foreach( $this->getSubClients() as $subclient ) {
122
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
-		}
124
-		$view->imageHeader = $html;
120
+        $html = '';
121
+        foreach( $this->getSubClients() as $subclient ) {
122
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
123
+        }
124
+        $view->imageHeader = $html;
125 125
 
126
-		/** client/html/catalog/stage/image/standard/template-header
127
-		 * Relative path to the HTML header template of the catalog stage image client.
128
-		 *
129
-		 * The template file contains the HTML code and processing instructions
130
-		 * to generate the HTML code that is inserted into the HTML page header
131
-		 * of the rendered page in the frontend. The configuration string is the
132
-		 * path to the template file relative to the templates directory (usually
133
-		 * in client/html/templates).
134
-		 *
135
-		 * You can overwrite the template file configuration in extensions and
136
-		 * provide alternative templates. These alternative templates should be
137
-		 * named like the default one but with the string "standard" replaced by
138
-		 * an unique name. You may use the name of your project for this. If
139
-		 * you've implemented an alternative client class as well, "standard"
140
-		 * should be replaced by the name of the new class.
141
-		 *
142
-		 * @param string Relative path to the template creating code for the HTML page head
143
-		 * @since 2014.03
144
-		 * @category Developer
145
-		 * @see client/html/catalog/stage/image/standard/template-body
146
-		 */
147
-		$tplconf = 'client/html/catalog/stage/image/standard/template-header';
148
-		$default = 'catalog/stage/image-header-default.php';
126
+        /** client/html/catalog/stage/image/standard/template-header
127
+         * Relative path to the HTML header template of the catalog stage image client.
128
+         *
129
+         * The template file contains the HTML code and processing instructions
130
+         * to generate the HTML code that is inserted into the HTML page header
131
+         * of the rendered page in the frontend. The configuration string is the
132
+         * path to the template file relative to the templates directory (usually
133
+         * in client/html/templates).
134
+         *
135
+         * You can overwrite the template file configuration in extensions and
136
+         * provide alternative templates. These alternative templates should be
137
+         * named like the default one but with the string "standard" replaced by
138
+         * an unique name. You may use the name of your project for this. If
139
+         * you've implemented an alternative client class as well, "standard"
140
+         * should be replaced by the name of the new class.
141
+         *
142
+         * @param string Relative path to the template creating code for the HTML page head
143
+         * @since 2014.03
144
+         * @category Developer
145
+         * @see client/html/catalog/stage/image/standard/template-body
146
+         */
147
+        $tplconf = 'client/html/catalog/stage/image/standard/template-header';
148
+        $default = 'catalog/stage/image-header-default.php';
149 149
 
150
-		return $view->render( $view->config( $tplconf, $default ) );
151
-	}
150
+        return $view->render( $view->config( $tplconf, $default ) );
151
+    }
152 152
 
153 153
 
154
-	/**
155
-	 * Returns the sub-client given by its name.
156
-	 *
157
-	 * @param string $type Name of the client type
158
-	 * @param string|null $name Name of the sub-client (Default if null)
159
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
160
-	 */
161
-	public function getSubClient( $type, $name = null )
162
-	{
163
-		/** client/html/catalog/stage/image/decorators/excludes
164
-		 * Excludes decorators added by the "common" option from the catalog stage image html client
165
-		 *
166
-		 * Decorators extend the functionality of a class by adding new aspects
167
-		 * (e.g. log what is currently done), executing the methods of the underlying
168
-		 * class only in certain conditions (e.g. only for logged in users) or
169
-		 * modify what is returned to the caller.
170
-		 *
171
-		 * This option allows you to remove a decorator added via
172
-		 * "client/html/common/decorators/default" before they are wrapped
173
-		 * around the html client.
174
-		 *
175
-		 *  client/html/catalog/stage/image/decorators/excludes = array( 'decorator1' )
176
-		 *
177
-		 * This would remove the decorator named "decorator1" from the list of
178
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
-		 * "client/html/common/decorators/default" to the html client.
180
-		 *
181
-		 * @param array List of decorator names
182
-		 * @since 2014.05
183
-		 * @category Developer
184
-		 * @see client/html/common/decorators/default
185
-		 * @see client/html/catalog/stage/image/decorators/global
186
-		 * @see client/html/catalog/stage/image/decorators/local
187
-		 */
154
+    /**
155
+     * Returns the sub-client given by its name.
156
+     *
157
+     * @param string $type Name of the client type
158
+     * @param string|null $name Name of the sub-client (Default if null)
159
+     * @return \Aimeos\Client\Html\Iface Sub-client object
160
+     */
161
+    public function getSubClient( $type, $name = null )
162
+    {
163
+        /** client/html/catalog/stage/image/decorators/excludes
164
+         * Excludes decorators added by the "common" option from the catalog stage image html client
165
+         *
166
+         * Decorators extend the functionality of a class by adding new aspects
167
+         * (e.g. log what is currently done), executing the methods of the underlying
168
+         * class only in certain conditions (e.g. only for logged in users) or
169
+         * modify what is returned to the caller.
170
+         *
171
+         * This option allows you to remove a decorator added via
172
+         * "client/html/common/decorators/default" before they are wrapped
173
+         * around the html client.
174
+         *
175
+         *  client/html/catalog/stage/image/decorators/excludes = array( 'decorator1' )
176
+         *
177
+         * This would remove the decorator named "decorator1" from the list of
178
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
179
+         * "client/html/common/decorators/default" to the html client.
180
+         *
181
+         * @param array List of decorator names
182
+         * @since 2014.05
183
+         * @category Developer
184
+         * @see client/html/common/decorators/default
185
+         * @see client/html/catalog/stage/image/decorators/global
186
+         * @see client/html/catalog/stage/image/decorators/local
187
+         */
188 188
 
189
-		/** client/html/catalog/stage/image/decorators/global
190
-		 * Adds a list of globally available decorators only to the catalog stage image html client
191
-		 *
192
-		 * Decorators extend the functionality of a class by adding new aspects
193
-		 * (e.g. log what is currently done), executing the methods of the underlying
194
-		 * class only in certain conditions (e.g. only for logged in users) or
195
-		 * modify what is returned to the caller.
196
-		 *
197
-		 * This option allows you to wrap global decorators
198
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
-		 *
200
-		 *  client/html/catalog/stage/image/decorators/global = array( 'decorator1' )
201
-		 *
202
-		 * This would add the decorator named "decorator1" defined by
203
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
-		 *
205
-		 * @param array List of decorator names
206
-		 * @since 2014.05
207
-		 * @category Developer
208
-		 * @see client/html/common/decorators/default
209
-		 * @see client/html/catalog/stage/image/decorators/excludes
210
-		 * @see client/html/catalog/stage/image/decorators/local
211
-		 */
189
+        /** client/html/catalog/stage/image/decorators/global
190
+         * Adds a list of globally available decorators only to the catalog stage image html client
191
+         *
192
+         * Decorators extend the functionality of a class by adding new aspects
193
+         * (e.g. log what is currently done), executing the methods of the underlying
194
+         * class only in certain conditions (e.g. only for logged in users) or
195
+         * modify what is returned to the caller.
196
+         *
197
+         * This option allows you to wrap global decorators
198
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
199
+         *
200
+         *  client/html/catalog/stage/image/decorators/global = array( 'decorator1' )
201
+         *
202
+         * This would add the decorator named "decorator1" defined by
203
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
204
+         *
205
+         * @param array List of decorator names
206
+         * @since 2014.05
207
+         * @category Developer
208
+         * @see client/html/common/decorators/default
209
+         * @see client/html/catalog/stage/image/decorators/excludes
210
+         * @see client/html/catalog/stage/image/decorators/local
211
+         */
212 212
 
213
-		/** client/html/catalog/stage/image/decorators/local
214
-		 * Adds a list of local decorators only to the catalog stage image html client
215
-		 *
216
-		 * Decorators extend the functionality of a class by adding new aspects
217
-		 * (e.g. log what is currently done), executing the methods of the underlying
218
-		 * class only in certain conditions (e.g. only for logged in users) or
219
-		 * modify what is returned to the caller.
220
-		 *
221
-		 * This option allows you to wrap local decorators
222
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
223
-		 *
224
-		 *  client/html/catalog/stage/image/decorators/local = array( 'decorator2' )
225
-		 *
226
-		 * This would add the decorator named "decorator2" defined by
227
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
228
-		 *
229
-		 * @param array List of decorator names
230
-		 * @since 2014.05
231
-		 * @category Developer
232
-		 * @see client/html/common/decorators/default
233
-		 * @see client/html/catalog/stage/image/decorators/excludes
234
-		 * @see client/html/catalog/stage/image/decorators/global
235
-		 */
236
-		return $this->createSubClient( 'catalog/stage/image/' . $type, $name );
237
-	}
213
+        /** client/html/catalog/stage/image/decorators/local
214
+         * Adds a list of local decorators only to the catalog stage image html client
215
+         *
216
+         * Decorators extend the functionality of a class by adding new aspects
217
+         * (e.g. log what is currently done), executing the methods of the underlying
218
+         * class only in certain conditions (e.g. only for logged in users) or
219
+         * modify what is returned to the caller.
220
+         *
221
+         * This option allows you to wrap local decorators
222
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
223
+         *
224
+         *  client/html/catalog/stage/image/decorators/local = array( 'decorator2' )
225
+         *
226
+         * This would add the decorator named "decorator2" defined by
227
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
228
+         *
229
+         * @param array List of decorator names
230
+         * @since 2014.05
231
+         * @category Developer
232
+         * @see client/html/common/decorators/default
233
+         * @see client/html/catalog/stage/image/decorators/excludes
234
+         * @see client/html/catalog/stage/image/decorators/global
235
+         */
236
+        return $this->createSubClient( 'catalog/stage/image/' . $type, $name );
237
+    }
238 238
 
239 239
 
240
-	/**
241
-	 * Returns the list of sub-client names configured for the client.
242
-	 *
243
-	 * @return array List of HTML client names
244
-	 */
245
-	protected function getSubClientNames()
246
-	{
247
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
-	}
240
+    /**
241
+     * Returns the list of sub-client names configured for the client.
242
+     *
243
+     * @return array List of HTML client names
244
+     */
245
+    protected function getSubClientNames()
246
+    {
247
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
+    }
249 249
 
250 250
 
251
-	/**
252
-	 * Sets the necessary parameter values in the view.
253
-	 *
254
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
255
-	 * @param array &$tags Result array for the list of tags that are associated to the output
256
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
257
-	 * @return \Aimeos\MW\View\Iface Modified view object
258
-	 */
259
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
260
-	{
261
-		if( !isset( $this->cache ) )
262
-		{
263
-			$mediaItems = array();
264
-			$catPath = $view->get( 'stageCatPath', array() );
251
+    /**
252
+     * Sets the necessary parameter values in the view.
253
+     *
254
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
255
+     * @param array &$tags Result array for the list of tags that are associated to the output
256
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
257
+     * @return \Aimeos\MW\View\Iface Modified view object
258
+     */
259
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
260
+    {
261
+        if( !isset( $this->cache ) )
262
+        {
263
+            $mediaItems = array();
264
+            $catPath = $view->get( 'stageCatPath', array() );
265 265
 
266
-			foreach( array_reverse( $catPath ) as $catItem )
267
-			{
268
-				$mediaItems = $catItem->getRefItems( 'media', 'default', 'stage' );
266
+            foreach( array_reverse( $catPath ) as $catItem )
267
+            {
268
+                $mediaItems = $catItem->getRefItems( 'media', 'default', 'stage' );
269 269
 
270
-				if( !empty( $mediaItems ) ) {
271
-					break;
272
-				}
273
-			}
270
+                if( !empty( $mediaItems ) ) {
271
+                    break;
272
+                }
273
+            }
274 274
 
275
-			$view->imageItems = $mediaItems;
275
+            $view->imageItems = $mediaItems;
276 276
 
277
-			$this->cache = $view;
278
-		}
277
+            $this->cache = $view;
278
+        }
279 279
 
280
-		return $this->cache;
281
-	}
280
+        return $this->cache;
281
+    }
282 282
 }
283 283
\ No newline at end of file
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Lists/Head/Standard.php 1 patch
Indentation   +226 added lines, -226 removed lines patch added patch discarded remove patch
@@ -19,231 +19,231 @@
 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/lists/head/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog list head 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/lists/head/standard/subparts';
59
-	private $subPartNames = array();
60
-
61
-
62
-	/**
63
-	 * Returns the HTML code for insertion into the body.
64
-	 *
65
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
66
-	 * @param array &$tags Result array for the list of tags that are associated to the output
67
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
68
-	 * @return string HTML code
69
-	 */
70
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
71
-	{
72
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
73
-
74
-		$html = '';
75
-		foreach( $this->getSubClients() as $subclient ) {
76
-			$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
77
-		}
78
-		$view->headBody = $html;
79
-
80
-		/** client/html/catalog/lists/head/standard/template-body
81
-		 * Relative path to the HTML body template of the catalog list head client.
82
-		 *
83
-		 * The template file contains the HTML code and processing instructions
84
-		 * to generate the result shown in the body of the frontend. The
85
-		 * configuration string is the path to the template file relative
86
-		 * to the templates directory (usually in client/html/templates).
87
-		 *
88
-		 * You can overwrite the template file configuration in extensions and
89
-		 * provide alternative templates. These alternative templates should be
90
-		 * named like the default one but with the string "standard" replaced by
91
-		 * an unique name. You may use the name of your project for this. If
92
-		 * you've implemented an alternative client class as well, "standard"
93
-		 * should be replaced by the name of the new class.
94
-		 *
95
-		 * @param string Relative path to the template creating code for the HTML page body
96
-		 * @since 2014.03
97
-		 * @category Developer
98
-		 * @see client/html/catalog/lists/head/standard/template-header
99
-		 */
100
-		$tplconf = 'client/html/catalog/lists/head/standard/template-body';
101
-		$default = 'catalog/lists/head-body-default.php';
102
-
103
-		return $view->render( $view->config( $tplconf, $default ) );
104
-	}
105
-
106
-
107
-	/**
108
-	 * Returns the HTML string for insertion into the header.
109
-	 *
110
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
111
-	 * @param array &$tags Result array for the list of tags that are associated to the output
112
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
113
-	 * @return string|null String including HTML tags for the header on error
114
-	 */
115
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
116
-	{
117
-		$view = $this->setViewParams( $this->getView(), $tags, $expire );
118
-
119
-		$html = '';
120
-		foreach( $this->getSubClients() as $subclient ) {
121
-			$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
122
-		}
123
-		$view->headHeader = $html;
124
-
125
-		/** client/html/catalog/lists/head/standard/template-header
126
-		 * Relative path to the HTML header template of the catalog list head client.
127
-		 *
128
-		 * The template file contains the HTML code and processing instructions
129
-		 * to generate the HTML code that is inserted into the HTML page header
130
-		 * of the rendered page in the frontend. The configuration string is the
131
-		 * path to the template file relative to the templates directory (usually
132
-		 * in client/html/templates).
133
-		 *
134
-		 * You can overwrite the template file configuration in extensions and
135
-		 * provide alternative templates. These alternative templates should be
136
-		 * named like the default one but with the string "standard" replaced by
137
-		 * an unique name. You may use the name of your project for this. If
138
-		 * you've implemented an alternative client class as well, "standard"
139
-		 * should be replaced by the name of the new class.
140
-		 *
141
-		 * @param string Relative path to the template creating code for the HTML page head
142
-		 * @since 2014.03
143
-		 * @category Developer
144
-		 * @see client/html/catalog/lists/head/standard/template-body
145
-		 */
146
-		$tplconf = 'client/html/catalog/lists/head/standard/template-header';
147
-		$default = 'catalog/lists/head-header-default.php';
148
-
149
-		return $view->render( $view->config( $tplconf, $default ) );
150
-	}
151
-
152
-
153
-	/**
154
-	 * Returns the sub-client given by its name.
155
-	 *
156
-	 * @param string $type Name of the client type
157
-	 * @param string|null $name Name of the sub-client (Default if null)
158
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
159
-	 */
160
-	public function getSubClient( $type, $name = null )
161
-	{
162
-		/** client/html/catalog/lists/head/decorators/excludes
163
-		 * Excludes decorators added by the "common" option from the catalog list head html client
164
-		 *
165
-		 * Decorators extend the functionality of a class by adding new aspects
166
-		 * (e.g. log what is currently done), executing the methods of the underlying
167
-		 * class only in certain conditions (e.g. only for logged in users) or
168
-		 * modify what is returned to the caller.
169
-		 *
170
-		 * This option allows you to remove a decorator added via
171
-		 * "client/html/common/decorators/default" before they are wrapped
172
-		 * around the html client.
173
-		 *
174
-		 *  client/html/catalog/lists/head/decorators/excludes = array( 'decorator1' )
175
-		 *
176
-		 * This would remove the decorator named "decorator1" from the list of
177
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
178
-		 * "client/html/common/decorators/default" to the html client.
179
-		 *
180
-		 * @param array List of decorator names
181
-		 * @since 2015.08
182
-		 * @category Developer
183
-		 * @see client/html/common/decorators/default
184
-		 * @see client/html/catalog/lists/head/decorators/global
185
-		 * @see client/html/catalog/lists/head/decorators/local
186
-		 */
187
-
188
-		/** client/html/catalog/lists/head/decorators/global
189
-		 * Adds a list of globally available decorators only to the catalog list head html client
190
-		 *
191
-		 * Decorators extend the functionality of a class by adding new aspects
192
-		 * (e.g. log what is currently done), executing the methods of the underlying
193
-		 * class only in certain conditions (e.g. only for logged in users) or
194
-		 * modify what is returned to the caller.
195
-		 *
196
-		 * This option allows you to wrap global decorators
197
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
198
-		 *
199
-		 *  client/html/catalog/lists/head/decorators/global = array( 'decorator1' )
200
-		 *
201
-		 * This would add the decorator named "decorator1" defined by
202
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
203
-		 *
204
-		 * @param array List of decorator names
205
-		 * @since 2015.08
206
-		 * @category Developer
207
-		 * @see client/html/common/decorators/default
208
-		 * @see client/html/catalog/lists/head/decorators/excludes
209
-		 * @see client/html/catalog/lists/head/decorators/local
210
-		 */
211
-
212
-		/** client/html/catalog/lists/head/decorators/local
213
-		 * Adds a list of local decorators only to the catalog list head html client
214
-		 *
215
-		 * Decorators extend the functionality of a class by adding new aspects
216
-		 * (e.g. log what is currently done), executing the methods of the underlying
217
-		 * class only in certain conditions (e.g. only for logged in users) or
218
-		 * modify what is returned to the caller.
219
-		 *
220
-		 * This option allows you to wrap local decorators
221
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
222
-		 *
223
-		 *  client/html/catalog/lists/head/decorators/local = array( 'decorator2' )
224
-		 *
225
-		 * This would add the decorator named "decorator2" defined by
226
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
227
-		 *
228
-		 * @param array List of decorator names
229
-		 * @since 2015.08
230
-		 * @category Developer
231
-		 * @see client/html/common/decorators/default
232
-		 * @see client/html/catalog/lists/head/decorators/excludes
233
-		 * @see client/html/catalog/lists/head/decorators/global
234
-		 */
235
-
236
-		return $this->createSubClient( 'catalog/lists/head/' . $type, $name );
237
-	}
238
-
239
-
240
-	/**
241
-	 * Returns the list of sub-client names configured for the client.
242
-	 *
243
-	 * @return array List of HTML client names
244
-	 */
245
-	protected function getSubClientNames()
246
-	{
247
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
-	}
25
+    /** client/html/catalog/lists/head/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog list head 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/lists/head/standard/subparts';
59
+    private $subPartNames = array();
60
+
61
+
62
+    /**
63
+     * Returns the HTML code for insertion into the body.
64
+     *
65
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
66
+     * @param array &$tags Result array for the list of tags that are associated to the output
67
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
68
+     * @return string HTML code
69
+     */
70
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
71
+    {
72
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
73
+
74
+        $html = '';
75
+        foreach( $this->getSubClients() as $subclient ) {
76
+            $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
77
+        }
78
+        $view->headBody = $html;
79
+
80
+        /** client/html/catalog/lists/head/standard/template-body
81
+         * Relative path to the HTML body template of the catalog list head client.
82
+         *
83
+         * The template file contains the HTML code and processing instructions
84
+         * to generate the result shown in the body of the frontend. The
85
+         * configuration string is the path to the template file relative
86
+         * to the templates directory (usually in client/html/templates).
87
+         *
88
+         * You can overwrite the template file configuration in extensions and
89
+         * provide alternative templates. These alternative templates should be
90
+         * named like the default one but with the string "standard" replaced by
91
+         * an unique name. You may use the name of your project for this. If
92
+         * you've implemented an alternative client class as well, "standard"
93
+         * should be replaced by the name of the new class.
94
+         *
95
+         * @param string Relative path to the template creating code for the HTML page body
96
+         * @since 2014.03
97
+         * @category Developer
98
+         * @see client/html/catalog/lists/head/standard/template-header
99
+         */
100
+        $tplconf = 'client/html/catalog/lists/head/standard/template-body';
101
+        $default = 'catalog/lists/head-body-default.php';
102
+
103
+        return $view->render( $view->config( $tplconf, $default ) );
104
+    }
105
+
106
+
107
+    /**
108
+     * Returns the HTML string for insertion into the header.
109
+     *
110
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
111
+     * @param array &$tags Result array for the list of tags that are associated to the output
112
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
113
+     * @return string|null String including HTML tags for the header on error
114
+     */
115
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
116
+    {
117
+        $view = $this->setViewParams( $this->getView(), $tags, $expire );
118
+
119
+        $html = '';
120
+        foreach( $this->getSubClients() as $subclient ) {
121
+            $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
122
+        }
123
+        $view->headHeader = $html;
124
+
125
+        /** client/html/catalog/lists/head/standard/template-header
126
+         * Relative path to the HTML header template of the catalog list head client.
127
+         *
128
+         * The template file contains the HTML code and processing instructions
129
+         * to generate the HTML code that is inserted into the HTML page header
130
+         * of the rendered page in the frontend. The configuration string is the
131
+         * path to the template file relative to the templates directory (usually
132
+         * in client/html/templates).
133
+         *
134
+         * You can overwrite the template file configuration in extensions and
135
+         * provide alternative templates. These alternative templates should be
136
+         * named like the default one but with the string "standard" replaced by
137
+         * an unique name. You may use the name of your project for this. If
138
+         * you've implemented an alternative client class as well, "standard"
139
+         * should be replaced by the name of the new class.
140
+         *
141
+         * @param string Relative path to the template creating code for the HTML page head
142
+         * @since 2014.03
143
+         * @category Developer
144
+         * @see client/html/catalog/lists/head/standard/template-body
145
+         */
146
+        $tplconf = 'client/html/catalog/lists/head/standard/template-header';
147
+        $default = 'catalog/lists/head-header-default.php';
148
+
149
+        return $view->render( $view->config( $tplconf, $default ) );
150
+    }
151
+
152
+
153
+    /**
154
+     * Returns the sub-client given by its name.
155
+     *
156
+     * @param string $type Name of the client type
157
+     * @param string|null $name Name of the sub-client (Default if null)
158
+     * @return \Aimeos\Client\Html\Iface Sub-client object
159
+     */
160
+    public function getSubClient( $type, $name = null )
161
+    {
162
+        /** client/html/catalog/lists/head/decorators/excludes
163
+         * Excludes decorators added by the "common" option from the catalog list head html client
164
+         *
165
+         * Decorators extend the functionality of a class by adding new aspects
166
+         * (e.g. log what is currently done), executing the methods of the underlying
167
+         * class only in certain conditions (e.g. only for logged in users) or
168
+         * modify what is returned to the caller.
169
+         *
170
+         * This option allows you to remove a decorator added via
171
+         * "client/html/common/decorators/default" before they are wrapped
172
+         * around the html client.
173
+         *
174
+         *  client/html/catalog/lists/head/decorators/excludes = array( 'decorator1' )
175
+         *
176
+         * This would remove the decorator named "decorator1" from the list of
177
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
178
+         * "client/html/common/decorators/default" to the html client.
179
+         *
180
+         * @param array List of decorator names
181
+         * @since 2015.08
182
+         * @category Developer
183
+         * @see client/html/common/decorators/default
184
+         * @see client/html/catalog/lists/head/decorators/global
185
+         * @see client/html/catalog/lists/head/decorators/local
186
+         */
187
+
188
+        /** client/html/catalog/lists/head/decorators/global
189
+         * Adds a list of globally available decorators only to the catalog list head html client
190
+         *
191
+         * Decorators extend the functionality of a class by adding new aspects
192
+         * (e.g. log what is currently done), executing the methods of the underlying
193
+         * class only in certain conditions (e.g. only for logged in users) or
194
+         * modify what is returned to the caller.
195
+         *
196
+         * This option allows you to wrap global decorators
197
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
198
+         *
199
+         *  client/html/catalog/lists/head/decorators/global = array( 'decorator1' )
200
+         *
201
+         * This would add the decorator named "decorator1" defined by
202
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
203
+         *
204
+         * @param array List of decorator names
205
+         * @since 2015.08
206
+         * @category Developer
207
+         * @see client/html/common/decorators/default
208
+         * @see client/html/catalog/lists/head/decorators/excludes
209
+         * @see client/html/catalog/lists/head/decorators/local
210
+         */
211
+
212
+        /** client/html/catalog/lists/head/decorators/local
213
+         * Adds a list of local decorators only to the catalog list head html client
214
+         *
215
+         * Decorators extend the functionality of a class by adding new aspects
216
+         * (e.g. log what is currently done), executing the methods of the underlying
217
+         * class only in certain conditions (e.g. only for logged in users) or
218
+         * modify what is returned to the caller.
219
+         *
220
+         * This option allows you to wrap local decorators
221
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
222
+         *
223
+         *  client/html/catalog/lists/head/decorators/local = array( 'decorator2' )
224
+         *
225
+         * This would add the decorator named "decorator2" defined by
226
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
227
+         *
228
+         * @param array List of decorator names
229
+         * @since 2015.08
230
+         * @category Developer
231
+         * @see client/html/common/decorators/default
232
+         * @see client/html/catalog/lists/head/decorators/excludes
233
+         * @see client/html/catalog/lists/head/decorators/global
234
+         */
235
+
236
+        return $this->createSubClient( 'catalog/lists/head/' . $type, $name );
237
+    }
238
+
239
+
240
+    /**
241
+     * Returns the list of sub-client names configured for the client.
242
+     *
243
+     * @return array List of HTML client names
244
+     */
245
+    protected function getSubClientNames()
246
+    {
247
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
248
+    }
249 249
 }
250 250
\ No newline at end of file
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Lists/Factory.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -19,69 +19,69 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 class Factory
22
-	extends \Aimeos\Client\Html\Common\Factory\Base
23
-	implements \Aimeos\Client\Html\Common\Factory\Iface
22
+    extends \Aimeos\Client\Html\Common\Factory\Base
23
+    implements \Aimeos\Client\Html\Common\Factory\Iface
24 24
 {
25
-	/**
26
-	 * Creates a list client object.
27
-	 *
28
-	 * @param \Aimeos\MShop\Context\Item\Iface $context Shop context instance with necessary objects
29
-	 * @param array $templatePaths List of file system paths where the templates are stored
30
-	 * @param string|null $name Client name (default: "Standard")
31
-	 * @return \Aimeos\Client\Html\Iface Filter part implementing \Aimeos\Client\Html\Iface
32
-	 * @throws \Aimeos\Client\Html\Exception If requested client implementation couldn't be found or initialisation fails
33
-	 */
34
-	public static function createClient( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths, $name = null )
35
-	{
36
-		/** client/html/catalog/lists/name
37
-		 * Class name of the used catalog list client implementation
38
-		 *
39
-		 * Each default HTML client can be replace by an alternative imlementation.
40
-		 * To use this implementation, you have to set the last part of the class
41
-		 * name as configuration value so the client factory knows which class it
42
-		 * has to instantiate.
43
-		 *
44
-		 * For example, if the name of the default class is
45
-		 *
46
-		 *  \Aimeos\Client\Html\Catalog\Lists\Standard
47
-		 *
48
-		 * and you want to replace it with your own version named
49
-		 *
50
-		 *  \Aimeos\Client\Html\Catalog\Lists\Mylist
51
-		 *
52
-		 * then you have to set the this configuration option:
53
-		 *
54
-		 *  client/html/catalog/lists/name = Mylist
55
-		 *
56
-		 * The value is the last part of your own class name and it's case sensitive,
57
-		 * so take care that the configuration value is exactly named like the last
58
-		 * part of the class name.
59
-		 *
60
-		 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
61
-		 * characters are possible! You should always start the last part of the class
62
-		 * name with an upper case character and continue only with lower case characters
63
-		 * or numbers. Avoid chamel case names like "MyList"!
64
-		 *
65
-		 * @param string Last part of the class name
66
-		 * @since 2014.03
67
-		 * @category Developer
68
-		 */
69
-		if( $name === null ) {
70
-			$name = $context->getConfig()->get( 'client/html/catalog/lists/name', 'Standard' );
71
-		}
25
+    /**
26
+     * Creates a list client object.
27
+     *
28
+     * @param \Aimeos\MShop\Context\Item\Iface $context Shop context instance with necessary objects
29
+     * @param array $templatePaths List of file system paths where the templates are stored
30
+     * @param string|null $name Client name (default: "Standard")
31
+     * @return \Aimeos\Client\Html\Iface Filter part implementing \Aimeos\Client\Html\Iface
32
+     * @throws \Aimeos\Client\Html\Exception If requested client implementation couldn't be found or initialisation fails
33
+     */
34
+    public static function createClient( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths, $name = null )
35
+    {
36
+        /** client/html/catalog/lists/name
37
+         * Class name of the used catalog list client implementation
38
+         *
39
+         * Each default HTML client can be replace by an alternative imlementation.
40
+         * To use this implementation, you have to set the last part of the class
41
+         * name as configuration value so the client factory knows which class it
42
+         * has to instantiate.
43
+         *
44
+         * For example, if the name of the default class is
45
+         *
46
+         *  \Aimeos\Client\Html\Catalog\Lists\Standard
47
+         *
48
+         * and you want to replace it with your own version named
49
+         *
50
+         *  \Aimeos\Client\Html\Catalog\Lists\Mylist
51
+         *
52
+         * then you have to set the this configuration option:
53
+         *
54
+         *  client/html/catalog/lists/name = Mylist
55
+         *
56
+         * The value is the last part of your own class name and it's case sensitive,
57
+         * so take care that the configuration value is exactly named like the last
58
+         * part of the class name.
59
+         *
60
+         * The allowed characters of the class name are A-Z, a-z and 0-9. No other
61
+         * characters are possible! You should always start the last part of the class
62
+         * name with an upper case character and continue only with lower case characters
63
+         * or numbers. Avoid chamel case names like "MyList"!
64
+         *
65
+         * @param string Last part of the class name
66
+         * @since 2014.03
67
+         * @category Developer
68
+         */
69
+        if( $name === null ) {
70
+            $name = $context->getConfig()->get( 'client/html/catalog/lists/name', 'Standard' );
71
+        }
72 72
 
73
-		if( ctype_alnum( $name ) === false )
74
-		{
75
-			$classname = is_string( $name ) ? '\\Aimeos\\Client\\Html\\Catalog\\Lists\\' . $name : '<not a string>';
76
-			throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
77
-		}
73
+        if( ctype_alnum( $name ) === false )
74
+        {
75
+            $classname = is_string( $name ) ? '\\Aimeos\\Client\\Html\\Catalog\\Lists\\' . $name : '<not a string>';
76
+            throw new \Aimeos\Client\Html\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
77
+        }
78 78
 
79
-		$iface = '\\Aimeos\\Client\\Html\\Iface';
80
-		$classname = '\\Aimeos\\Client\\Html\\Catalog\\Lists\\' . $name;
79
+        $iface = '\\Aimeos\\Client\\Html\\Iface';
80
+        $classname = '\\Aimeos\\Client\\Html\\Catalog\\Lists\\' . $name;
81 81
 
82
-		$client = self::createClientBase( $context, $classname, $iface, $templatePaths );
82
+        $client = self::createClientBase( $context, $classname, $iface, $templatePaths );
83 83
 
84
-		return self::addClientDecorators( $context, $client, $templatePaths, 'catalog/lists' );
85
-	}
84
+        return self::addClientDecorators( $context, $client, $templatePaths, 'catalog/lists' );
85
+    }
86 86
 }
87 87
 
Please login to merge, or discard this patch.
client/html/src/Client/Html/Catalog/Lists/Standard.php 1 patch
Indentation   +582 added lines, -582 removed lines patch added patch discarded remove patch
@@ -19,587 +19,587 @@
 block discarded – undo
19 19
  * @subpackage Html
20 20
  */
21 21
 class Standard
22
-	extends \Aimeos\Client\Html\Catalog\Base
23
-	implements \Aimeos\Client\Html\Common\Client\Factory\Iface
22
+    extends \Aimeos\Client\Html\Catalog\Base
23
+    implements \Aimeos\Client\Html\Common\Client\Factory\Iface
24 24
 {
25
-	/** client/html/catalog/lists/standard/subparts
26
-	 * List of HTML sub-clients rendered within the catalog list 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/lists/standard/subparts';
59
-
60
-	/** client/html/catalog/lists/head/name
61
-	 * Name of the head part used by the catalog list client implementation
62
-	 *
63
-	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Head\Myname".
64
-	 * The name is case-sensitive and you should avoid camel case names like "MyName".
65
-	 *
66
-	 * @param string Last part of the client class name
67
-	 * @since 2014.03
68
-	 * @category Developer
69
-	 */
70
-
71
-	/** client/html/catalog/lists/promo/name
72
-	 * Name of the promotion part used by the catalog list client implementation
73
-	 *
74
-	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Promo\Myname".
75
-	 * The name is case-sensitive and you should avoid camel case names like "MyName".
76
-	 *
77
-	 * @param string Last part of the client class name
78
-	 * @since 2014.03
79
-	 * @category Developer
80
-	 */
81
-
82
-	/** client/html/catalog/lists/quote/name
83
-	 * Name of the quote part used by the catalog list client implementation
84
-	 *
85
-	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Quote\Myname".
86
-	 * The name is case-sensitive and you should avoid camel case names like "MyName".
87
-	 *
88
-	 * @param string Last part of the client class name
89
-	 * @since 2014.03
90
-	 * @category Developer
91
-	 */
92
-
93
-	/** client/html/catalog/lists/pagination/name
94
-	 * Name of the pagination part used by the catalog list client implementation
95
-	 *
96
-	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Pagination\Myname".
97
-	 * The name is case-sensitive and you should avoid camel case names like "MyName".
98
-	 *
99
-	 * @param string Last part of the client class name
100
-	 * @since 2014.03
101
-	 * @category Developer
102
-	 */
103
-
104
-	/** client/html/catalog/lists/items/name
105
-	 * Name of the items part used by the catalog list client implementation
106
-	 *
107
-	 * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Items\Myname".
108
-	 * The name is case-sensitive and you should avoid camel case names like "MyName".
109
-	 *
110
-	 * @param string Last part of the client class name
111
-	 * @since 2014.03
112
-	 * @category Developer
113
-	 */
114
-	private $subPartNames = array( 'head', 'quote', 'promo', 'pagination', 'items', 'pagination' );
115
-
116
-	private $tags = array();
117
-	private $expire;
118
-	private $cache;
119
-
120
-
121
-	/**
122
-	 * Returns the HTML code for insertion into the body.
123
-	 *
124
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
125
-	 * @param array &$tags Result array for the list of tags that are associated to the output
126
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
127
-	 * @return string HTML code
128
-	 */
129
-	public function getBody( $uid = '', array &$tags = array(), &$expire = null )
130
-	{
131
-		$prefixes = array( 'f', 'l' );
132
-		$context = $this->getContext();
133
-
134
-		/** client/html/catalog/list
135
-		 * All parameters defined for the catalog list component and its subparts
136
-		 *
137
-		 * This returns all settings related to the filter component.
138
-		 * Please refer to the single settings for details.
139
-		 *
140
-		 * @param array Associative list of name/value settings
141
-		 * @category Developer
142
-		 * @see client/html/catalog#list
143
-		 */
144
-		$confkey = 'client/html/catalog/list';
145
-
146
-		if( $context->getUserId() != null || ( $html = $this->getCached( 'body', $uid, $prefixes, $confkey ) ) === null )
147
-		{
148
-			$view = $this->getView();
149
-
150
-			try
151
-			{
152
-				$view = $this->setViewParams( $view, $tags, $expire );
153
-
154
-				$html = '';
155
-				foreach( $this->getSubClients() as $subclient ) {
156
-					$html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
157
-				}
158
-				$view->listBody = $html;
159
-			}
160
-			catch( \Aimeos\Client\Html\Exception $e )
161
-			{
162
-				$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
163
-				$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
164
-			}
165
-			catch( \Aimeos\Controller\Frontend\Exception $e )
166
-			{
167
-				$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
168
-				$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
169
-			}
170
-			catch( \Aimeos\MShop\Exception $e )
171
-			{
172
-				$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
173
-				$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
174
-			}
175
-			catch( \Exception $e )
176
-			{
177
-				$context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
178
-
179
-				$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
180
-				$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
181
-			}
182
-
183
-			/** client/html/catalog/lists/standard/template-body
184
-			 * Relative path to the HTML body template of the catalog list client.
185
-			 *
186
-			 * The template file contains the HTML code and processing instructions
187
-			 * to generate the result shown in the body of the frontend. The
188
-			 * configuration string is the path to the template file relative
189
-			 * to the templates directory (usually in client/html/templates).
190
-			 *
191
-			 * You can overwrite the template file configuration in extensions and
192
-			 * provide alternative templates. These alternative templates should be
193
-			 * named like the default one but with the string "standard" replaced by
194
-			 * an unique name. You may use the name of your project for this. If
195
-			 * you've implemented an alternative client class as well, "standard"
196
-			 * should be replaced by the name of the new class.
197
-			 *
198
-			 * @param string Relative path to the template creating code for the HTML page body
199
-			 * @since 2014.03
200
-			 * @category Developer
201
-			 * @see client/html/catalog/lists/standard/template-header
202
-			 */
203
-			$tplconf = 'client/html/catalog/lists/standard/template-body';
204
-			$default = 'catalog/lists/body-default.php';
205
-
206
-			$html = $view->render( $view->config( $tplconf, $default ) );
207
-
208
-			$this->setCached( 'body', $uid, $prefixes, $confkey, $html, $tags, $expire );
209
-		}
210
-		else
211
-		{
212
-			$html = $this->modifyBody( $html, $uid );
213
-		}
214
-
215
-		return $html;
216
-	}
217
-
218
-
219
-	/**
220
-	 * Returns the HTML string for insertion into the header.
221
-	 *
222
-	 * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
223
-	 * @param array &$tags Result array for the list of tags that are associated to the output
224
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
225
-	 * @return string|null String including HTML tags for the header on error
226
-	 */
227
-	public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
228
-	{
229
-		$prefixes = array( 'f', 'l' );
230
-		$context = $this->getContext();
231
-		$confkey = 'client/html/catalog/list';
232
-
233
-		if( $context->getUserId() != null || ( $html = $this->getCached( 'header', $uid, $prefixes, $confkey ) ) === null )
234
-		{
235
-			$view = $this->getView();
236
-
237
-			try
238
-			{
239
-				$view = $this->setViewParams( $view, $tags, $expire );
240
-
241
-				$html = '';
242
-				foreach( $this->getSubClients() as $subclient ) {
243
-					$html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
244
-				}
245
-				$view->listHeader = $html;
246
-			}
247
-			catch( \Exception $e )
248
-			{
249
-				$context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
250
-			}
251
-
252
-			/** client/html/catalog/lists/standard/template-header
253
-			 * Relative path to the HTML header template of the catalog list client.
254
-			 *
255
-			 * The template file contains the HTML code and processing instructions
256
-			 * to generate the HTML code that is inserted into the HTML page header
257
-			 * of the rendered page in the frontend. The configuration string is the
258
-			 * path to the template file relative to the templates directory (usually
259
-			 * in client/html/templates).
260
-			 *
261
-			 * You can overwrite the template file configuration in extensions and
262
-			 * provide alternative templates. These alternative templates should be
263
-			 * named like the default one but with the string "standard" replaced by
264
-			 * an unique name. You may use the name of your project for this. If
265
-			 * you've implemented an alternative client class as well, "standard"
266
-			 * should be replaced by the name of the new class.
267
-			 *
268
-			 * @param string Relative path to the template creating code for the HTML page head
269
-			 * @since 2014.03
270
-			 * @category Developer
271
-			 * @see client/html/catalog/lists/standard/template-body
272
-			 */
273
-			$tplconf = 'client/html/catalog/lists/standard/template-header';
274
-			$default = 'catalog/lists/header-default.php';
275
-
276
-			$html = $view->render( $view->config( $tplconf, $default ) );
277
-
278
-			$this->setCached( 'header', $uid, $prefixes, $confkey, $html, $tags, $expire );
279
-		}
280
-		else
281
-		{
282
-			$html = $this->modifyHeader( $html, $uid );
283
-		}
284
-
285
-		return $html;
286
-	}
287
-
288
-
289
-	/**
290
-	 * Returns the sub-client given by its name.
291
-	 *
292
-	 * @param string $type Name of the client type
293
-	 * @param string|null $name Name of the sub-client (Default if null)
294
-	 * @return \Aimeos\Client\Html\Iface Sub-client object
295
-	 */
296
-	public function getSubClient( $type, $name = null )
297
-	{
298
-		/** client/html/catalog/lists/decorators/excludes
299
-		 * Excludes decorators added by the "common" option from the catalog list html client
300
-		 *
301
-		 * Decorators extend the functionality of a class by adding new aspects
302
-		 * (e.g. log what is currently done), executing the methods of the underlying
303
-		 * class only in certain conditions (e.g. only for logged in users) or
304
-		 * modify what is returned to the caller.
305
-		 *
306
-		 * This option allows you to remove a decorator added via
307
-		 * "client/html/common/decorators/default" before they are wrapped
308
-		 * around the html client.
309
-		 *
310
-		 *  client/html/catalog/lists/decorators/excludes = array( 'decorator1' )
311
-		 *
312
-		 * This would remove the decorator named "decorator1" from the list of
313
-		 * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
314
-		 * "client/html/common/decorators/default" to the html client.
315
-		 *
316
-		 * @param array List of decorator names
317
-		 * @since 2014.05
318
-		 * @category Developer
319
-		 * @see client/html/common/decorators/default
320
-		 * @see client/html/catalog/lists/decorators/global
321
-		 * @see client/html/catalog/lists/decorators/local
322
-		 */
323
-
324
-		/** client/html/catalog/lists/decorators/global
325
-		 * Adds a list of globally available decorators only to the catalog list html client
326
-		 *
327
-		 * Decorators extend the functionality of a class by adding new aspects
328
-		 * (e.g. log what is currently done), executing the methods of the underlying
329
-		 * class only in certain conditions (e.g. only for logged in users) or
330
-		 * modify what is returned to the caller.
331
-		 *
332
-		 * This option allows you to wrap global decorators
333
-		 * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
334
-		 *
335
-		 *  client/html/catalog/lists/decorators/global = array( 'decorator1' )
336
-		 *
337
-		 * This would add the decorator named "decorator1" defined by
338
-		 * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
339
-		 *
340
-		 * @param array List of decorator names
341
-		 * @since 2014.05
342
-		 * @category Developer
343
-		 * @see client/html/common/decorators/default
344
-		 * @see client/html/catalog/lists/decorators/excludes
345
-		 * @see client/html/catalog/lists/decorators/local
346
-		 */
347
-
348
-		/** client/html/catalog/lists/decorators/local
349
-		 * Adds a list of local decorators only to the catalog list html client
350
-		 *
351
-		 * Decorators extend the functionality of a class by adding new aspects
352
-		 * (e.g. log what is currently done), executing the methods of the underlying
353
-		 * class only in certain conditions (e.g. only for logged in users) or
354
-		 * modify what is returned to the caller.
355
-		 *
356
-		 * This option allows you to wrap local decorators
357
-		 * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
358
-		 *
359
-		 *  client/html/catalog/lists/decorators/local = array( 'decorator2' )
360
-		 *
361
-		 * This would add the decorator named "decorator2" defined by
362
-		 * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
363
-		 *
364
-		 * @param array List of decorator names
365
-		 * @since 2014.05
366
-		 * @category Developer
367
-		 * @see client/html/common/decorators/default
368
-		 * @see client/html/catalog/lists/decorators/excludes
369
-		 * @see client/html/catalog/lists/decorators/global
370
-		 */
371
-
372
-		return $this->createSubClient( 'catalog/lists/' . $type, $name );
373
-	}
374
-
375
-
376
-	/**
377
-	 * Processes the input, e.g. store given values.
378
-	 * A view must be available and this method doesn't generate any output
379
-	 * besides setting view variables.
380
-	 */
381
-	public function process()
382
-	{
383
-		$context = $this->getContext();
384
-		$view = $this->getView();
385
-
386
-		try
387
-		{
388
-			$site = $context->getLocale()->getSite()->getCode();
389
-			$params = $this->getClientParams( $view->param() );
390
-			$context->getSession()->set( 'aimeos/catalog/lists/params/last/' . $site, $params );
391
-
392
-			parent::process();
393
-		}
394
-		catch( \Aimeos\Client\Html\Exception $e )
395
-		{
396
-			$error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
397
-			$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
398
-		}
399
-		catch( \Aimeos\Controller\Frontend\Exception $e )
400
-		{
401
-			$error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
402
-			$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
403
-		}
404
-		catch( \Aimeos\MShop\Exception $e )
405
-		{
406
-			$error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
407
-			$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
408
-		}
409
-		catch( \Exception $e )
410
-		{
411
-			$context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
412
-
413
-			$error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
414
-			$view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
415
-		}
416
-	}
417
-
418
-
419
-	/**
420
-	 * Returns the list of sub-client names configured for the client.
421
-	 *
422
-	 * @return array List of HTML client names
423
-	 */
424
-	protected function getSubClientNames()
425
-	{
426
-		return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
427
-	}
428
-
429
-
430
-	/**
431
-	 * Sets the necessary parameter values in the view.
432
-	 *
433
-	 * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
434
-	 * @param array &$tags Result array for the list of tags that are associated to the output
435
-	 * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
436
-	 * @return \Aimeos\MW\View\Iface Modified view object
437
-	 */
438
-	protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
439
-	{
440
-		if( !isset( $this->cache ) )
441
-		{
442
-			$context = $this->getContext();
443
-			$config = $context->getConfig();
444
-
445
-			$products = $this->getProductList( $view );
446
-
447
-			$text = (string) $view->param( 'f_search' );
448
-			$catid = (string) $view->param( 'f_catid' );
449
-
450
-			if( $catid == '' ) {
451
-				$catid = $config->get( 'client/html/catalog/lists/catid-default', '' );
452
-			}
453
-
454
-			if( $text === '' && $catid !== '' )
455
-			{
456
-				$domains = $config->get( 'client/html/catalog/domains', array( 'media', 'text' ) );
457
-				$controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
458
-
459
-				$listCatPath = $controller->getCatalogPath( $catid, $domains );
460
-
461
-				if( ( $categoryItem = end( $listCatPath ) ) !== false ) {
462
-					$view->listCurrentCatItem = $categoryItem;
463
-				}
464
-
465
-				$view->listCatPath = $listCatPath;
466
-
467
-				$this->addMetaItem( $listCatPath, 'catalog', $this->expire, $this->tags );
468
-				$this->addMetaList( array_keys( $listCatPath ), 'catalog', $this->expire );
469
-			}
470
-
471
-			/** client/html/catalog/lists/stock/enable
472
-			 * Enables or disables displaying product stock levels in product list views
473
-			 *
474
-			 * This configuration option allows shop owners to display product
475
-			 * stock levels for each product in list views or to disable
476
-			 * fetching product stock information.
477
-			 *
478
-			 * The stock information is fetched via AJAX and inserted via Javascript.
479
-			 * This allows to cache product items by leaving out such highly
480
-			 * dynamic content like stock levels which changes with each order.
481
-			 *
482
-			 * @param boolean Value of "1" to display stock levels, "0" to disable displaying them
483
-			 * @since 2014.03
484
-			 * @category User
485
-			 * @category Developer
486
-			 * @see client/html/catalog/detail/stock/enable
487
-			 * @see client/html/catalog/stock/url/target
488
-			 * @see client/html/catalog/stock/url/controller
489
-			 * @see client/html/catalog/stock/url/action
490
-			 * @see client/html/catalog/stock/url/config
491
-			 */
492
-			if( !empty( $products ) && $config->get( 'client/html/catalog/lists/stock/enable', true ) === true ) {
493
-				$view->listStockUrl = $this->getStockUrl( $view, array_keys( $products ) );
494
-			}
495
-
496
-
497
-			$this->addMetaItem( $products, 'product', $this->expire, $this->tags );
498
-			$this->addMetaList( array_keys( $products ), 'product', $this->expire );
499
-
500
-			// Delete cache when products are added or deleted even when in "tag-all" mode
501
-			$this->tags[] = 'product';
502
-
503
-			$view->listParams = $this->getClientParams( $view->param() );
504
-			$view->listPageCurr = $this->getProductListPage( $view );
505
-			$view->listPageSize = $this->getProductListSize( $view );
506
-			$view->listProductTotal = $this->getProductListTotal( $view );
507
-			$view->listProductSort = $view->param( 'f_sort', 'relevance' );
508
-			$view->listProductItems = $products;
509
-
510
-			$this->cache = $view;
511
-		}
512
-
513
-		$expire = $this->expires( $this->expire, $expire );
514
-		$tags = array_merge( $tags, $this->tags );
515
-
516
-		return $this->cache;
517
-	}
518
-
519
-
520
-	/**
521
-	 * Returns the URL to fetch the stock level details of the given products
522
-	 *
523
-	 * @param \Aimeos\MW\View\Iface $view View object
524
-	 * @param array $productIds List of product IDs
525
-	 * @return string Generated stock level URL
526
-	 */
527
-	protected function getStockUrl( \Aimeos\MW\View\Iface $view, array $productIds )
528
-	{
529
-		/** client/html/catalog/stock/url/target
530
-		 * Destination of the URL where the controller specified in the URL is known
531
-		 *
532
-		 * The destination can be a page ID like in a content management system or the
533
-		 * module of a software development framework. This "target" must contain or know
534
-		 * the controller that should be called by the generated URL.
535
-		 *
536
-		 * @param string Destination of the URL
537
-		 * @since 2014.03
538
-		 * @category Developer
539
-		 * @see client/html/catalog/stock/url/controller
540
-		 * @see client/html/catalog/stock/url/action
541
-		 * @see client/html/catalog/stock/url/config
542
-		 */
543
-		$stockTarget = $view->config( 'client/html/catalog/stock/url/target' );
544
-
545
-		/** client/html/catalog/stock/url/controller
546
-		 * Name of the controller whose action should be called
547
-		 *
548
-		 * In Model-View-Controller (MVC) applications, the controller contains the methods
549
-		 * that create parts of the output displayed in the generated HTML page. Controller
550
-		 * names are usually alpha-numeric.
551
-		 *
552
-		 * @param string Name of the controller
553
-		 * @since 2014.03
554
-		 * @category Developer
555
-		 * @see client/html/catalog/stock/url/target
556
-		 * @see client/html/catalog/stock/url/action
557
-		 * @see client/html/catalog/stock/url/config
558
-		*/
559
-		$stockController = $view->config( 'client/html/catalog/stock/url/controller', 'catalog' );
560
-
561
-		/** client/html/catalog/stock/url/action
562
-		 * Name of the action that should create the output
563
-		 *
564
-		 * In Model-View-Controller (MVC) applications, actions are the methods of a
565
-		 * controller that create parts of the output displayed in the generated HTML page.
566
-		 * Action names are usually alpha-numeric.
567
-		 *
568
-		 * @param string Name of the action
569
-		 * @since 2014.03
570
-		 * @category Developer
571
-		 * @see client/html/catalog/stock/url/target
572
-		 * @see client/html/catalog/stock/url/controller
573
-		 * @see client/html/catalog/stock/url/config
574
-		*/
575
-		$stockAction = $view->config( 'client/html/catalog/stock/url/action', 'stock' );
576
-
577
-		/** client/html/catalog/stock/url/config
578
-		 * Associative list of configuration options used for generating the URL
579
-		 *
580
-		 * You can specify additional options as key/value pairs used when generating
581
-		 * the URLs, like
582
-		 *
583
-		 *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
584
-		 *
585
-		 * The available key/value pairs depend on the application that embeds the e-commerce
586
-		 * framework. This is because the infrastructure of the application is used for
587
-		 * generating the URLs. The full list of available config options is referenced
588
-		 * in the "see also" section of this page.
589
-		 *
590
-		 * @param string Associative list of configuration options
591
-		 * @since 2014.03
592
-		 * @category Developer
593
-		 * @see client/html/catalog/stock/url/target
594
-		 * @see client/html/catalog/stock/url/controller
595
-		 * @see client/html/catalog/stock/url/action
596
-		 * @see client/html/url/config
597
-		*/
598
-		$stockConfig = $view->config( 'client/html/catalog/stock/url/config', array() );
599
-
600
-		sort( $productIds );
601
-
602
-		$params = array( 's_prodid' => implode( ' ', $productIds ) );
603
-		return $view->url( $stockTarget, $stockController, $stockAction, $params, array(), $stockConfig );
604
-	}
25
+    /** client/html/catalog/lists/standard/subparts
26
+     * List of HTML sub-clients rendered within the catalog list 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/lists/standard/subparts';
59
+
60
+    /** client/html/catalog/lists/head/name
61
+     * Name of the head part used by the catalog list client implementation
62
+     *
63
+     * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Head\Myname".
64
+     * The name is case-sensitive and you should avoid camel case names like "MyName".
65
+     *
66
+     * @param string Last part of the client class name
67
+     * @since 2014.03
68
+     * @category Developer
69
+     */
70
+
71
+    /** client/html/catalog/lists/promo/name
72
+     * Name of the promotion part used by the catalog list client implementation
73
+     *
74
+     * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Promo\Myname".
75
+     * The name is case-sensitive and you should avoid camel case names like "MyName".
76
+     *
77
+     * @param string Last part of the client class name
78
+     * @since 2014.03
79
+     * @category Developer
80
+     */
81
+
82
+    /** client/html/catalog/lists/quote/name
83
+     * Name of the quote part used by the catalog list client implementation
84
+     *
85
+     * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Quote\Myname".
86
+     * The name is case-sensitive and you should avoid camel case names like "MyName".
87
+     *
88
+     * @param string Last part of the client class name
89
+     * @since 2014.03
90
+     * @category Developer
91
+     */
92
+
93
+    /** client/html/catalog/lists/pagination/name
94
+     * Name of the pagination part used by the catalog list client implementation
95
+     *
96
+     * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Pagination\Myname".
97
+     * The name is case-sensitive and you should avoid camel case names like "MyName".
98
+     *
99
+     * @param string Last part of the client class name
100
+     * @since 2014.03
101
+     * @category Developer
102
+     */
103
+
104
+    /** client/html/catalog/lists/items/name
105
+     * Name of the items part used by the catalog list client implementation
106
+     *
107
+     * Use "Myname" if your class is named "\Aimeos\Client\Html\Catalog\Lists\Items\Myname".
108
+     * The name is case-sensitive and you should avoid camel case names like "MyName".
109
+     *
110
+     * @param string Last part of the client class name
111
+     * @since 2014.03
112
+     * @category Developer
113
+     */
114
+    private $subPartNames = array( 'head', 'quote', 'promo', 'pagination', 'items', 'pagination' );
115
+
116
+    private $tags = array();
117
+    private $expire;
118
+    private $cache;
119
+
120
+
121
+    /**
122
+     * Returns the HTML code for insertion into the body.
123
+     *
124
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
125
+     * @param array &$tags Result array for the list of tags that are associated to the output
126
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
127
+     * @return string HTML code
128
+     */
129
+    public function getBody( $uid = '', array &$tags = array(), &$expire = null )
130
+    {
131
+        $prefixes = array( 'f', 'l' );
132
+        $context = $this->getContext();
133
+
134
+        /** client/html/catalog/list
135
+         * All parameters defined for the catalog list component and its subparts
136
+         *
137
+         * This returns all settings related to the filter component.
138
+         * Please refer to the single settings for details.
139
+         *
140
+         * @param array Associative list of name/value settings
141
+         * @category Developer
142
+         * @see client/html/catalog#list
143
+         */
144
+        $confkey = 'client/html/catalog/list';
145
+
146
+        if( $context->getUserId() != null || ( $html = $this->getCached( 'body', $uid, $prefixes, $confkey ) ) === null )
147
+        {
148
+            $view = $this->getView();
149
+
150
+            try
151
+            {
152
+                $view = $this->setViewParams( $view, $tags, $expire );
153
+
154
+                $html = '';
155
+                foreach( $this->getSubClients() as $subclient ) {
156
+                    $html .= $subclient->setView( $view )->getBody( $uid, $tags, $expire );
157
+                }
158
+                $view->listBody = $html;
159
+            }
160
+            catch( \Aimeos\Client\Html\Exception $e )
161
+            {
162
+                $error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
163
+                $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
164
+            }
165
+            catch( \Aimeos\Controller\Frontend\Exception $e )
166
+            {
167
+                $error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
168
+                $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
169
+            }
170
+            catch( \Aimeos\MShop\Exception $e )
171
+            {
172
+                $error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
173
+                $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
174
+            }
175
+            catch( \Exception $e )
176
+            {
177
+                $context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
178
+
179
+                $error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
180
+                $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
181
+            }
182
+
183
+            /** client/html/catalog/lists/standard/template-body
184
+             * Relative path to the HTML body template of the catalog list client.
185
+             *
186
+             * The template file contains the HTML code and processing instructions
187
+             * to generate the result shown in the body of the frontend. The
188
+             * configuration string is the path to the template file relative
189
+             * to the templates directory (usually in client/html/templates).
190
+             *
191
+             * You can overwrite the template file configuration in extensions and
192
+             * provide alternative templates. These alternative templates should be
193
+             * named like the default one but with the string "standard" replaced by
194
+             * an unique name. You may use the name of your project for this. If
195
+             * you've implemented an alternative client class as well, "standard"
196
+             * should be replaced by the name of the new class.
197
+             *
198
+             * @param string Relative path to the template creating code for the HTML page body
199
+             * @since 2014.03
200
+             * @category Developer
201
+             * @see client/html/catalog/lists/standard/template-header
202
+             */
203
+            $tplconf = 'client/html/catalog/lists/standard/template-body';
204
+            $default = 'catalog/lists/body-default.php';
205
+
206
+            $html = $view->render( $view->config( $tplconf, $default ) );
207
+
208
+            $this->setCached( 'body', $uid, $prefixes, $confkey, $html, $tags, $expire );
209
+        }
210
+        else
211
+        {
212
+            $html = $this->modifyBody( $html, $uid );
213
+        }
214
+
215
+        return $html;
216
+    }
217
+
218
+
219
+    /**
220
+     * Returns the HTML string for insertion into the header.
221
+     *
222
+     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
223
+     * @param array &$tags Result array for the list of tags that are associated to the output
224
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
225
+     * @return string|null String including HTML tags for the header on error
226
+     */
227
+    public function getHeader( $uid = '', array &$tags = array(), &$expire = null )
228
+    {
229
+        $prefixes = array( 'f', 'l' );
230
+        $context = $this->getContext();
231
+        $confkey = 'client/html/catalog/list';
232
+
233
+        if( $context->getUserId() != null || ( $html = $this->getCached( 'header', $uid, $prefixes, $confkey ) ) === null )
234
+        {
235
+            $view = $this->getView();
236
+
237
+            try
238
+            {
239
+                $view = $this->setViewParams( $view, $tags, $expire );
240
+
241
+                $html = '';
242
+                foreach( $this->getSubClients() as $subclient ) {
243
+                    $html .= $subclient->setView( $view )->getHeader( $uid, $tags, $expire );
244
+                }
245
+                $view->listHeader = $html;
246
+            }
247
+            catch( \Exception $e )
248
+            {
249
+                $context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
250
+            }
251
+
252
+            /** client/html/catalog/lists/standard/template-header
253
+             * Relative path to the HTML header template of the catalog list client.
254
+             *
255
+             * The template file contains the HTML code and processing instructions
256
+             * to generate the HTML code that is inserted into the HTML page header
257
+             * of the rendered page in the frontend. The configuration string is the
258
+             * path to the template file relative to the templates directory (usually
259
+             * in client/html/templates).
260
+             *
261
+             * You can overwrite the template file configuration in extensions and
262
+             * provide alternative templates. These alternative templates should be
263
+             * named like the default one but with the string "standard" replaced by
264
+             * an unique name. You may use the name of your project for this. If
265
+             * you've implemented an alternative client class as well, "standard"
266
+             * should be replaced by the name of the new class.
267
+             *
268
+             * @param string Relative path to the template creating code for the HTML page head
269
+             * @since 2014.03
270
+             * @category Developer
271
+             * @see client/html/catalog/lists/standard/template-body
272
+             */
273
+            $tplconf = 'client/html/catalog/lists/standard/template-header';
274
+            $default = 'catalog/lists/header-default.php';
275
+
276
+            $html = $view->render( $view->config( $tplconf, $default ) );
277
+
278
+            $this->setCached( 'header', $uid, $prefixes, $confkey, $html, $tags, $expire );
279
+        }
280
+        else
281
+        {
282
+            $html = $this->modifyHeader( $html, $uid );
283
+        }
284
+
285
+        return $html;
286
+    }
287
+
288
+
289
+    /**
290
+     * Returns the sub-client given by its name.
291
+     *
292
+     * @param string $type Name of the client type
293
+     * @param string|null $name Name of the sub-client (Default if null)
294
+     * @return \Aimeos\Client\Html\Iface Sub-client object
295
+     */
296
+    public function getSubClient( $type, $name = null )
297
+    {
298
+        /** client/html/catalog/lists/decorators/excludes
299
+         * Excludes decorators added by the "common" option from the catalog list html client
300
+         *
301
+         * Decorators extend the functionality of a class by adding new aspects
302
+         * (e.g. log what is currently done), executing the methods of the underlying
303
+         * class only in certain conditions (e.g. only for logged in users) or
304
+         * modify what is returned to the caller.
305
+         *
306
+         * This option allows you to remove a decorator added via
307
+         * "client/html/common/decorators/default" before they are wrapped
308
+         * around the html client.
309
+         *
310
+         *  client/html/catalog/lists/decorators/excludes = array( 'decorator1' )
311
+         *
312
+         * This would remove the decorator named "decorator1" from the list of
313
+         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
314
+         * "client/html/common/decorators/default" to the html client.
315
+         *
316
+         * @param array List of decorator names
317
+         * @since 2014.05
318
+         * @category Developer
319
+         * @see client/html/common/decorators/default
320
+         * @see client/html/catalog/lists/decorators/global
321
+         * @see client/html/catalog/lists/decorators/local
322
+         */
323
+
324
+        /** client/html/catalog/lists/decorators/global
325
+         * Adds a list of globally available decorators only to the catalog list html client
326
+         *
327
+         * Decorators extend the functionality of a class by adding new aspects
328
+         * (e.g. log what is currently done), executing the methods of the underlying
329
+         * class only in certain conditions (e.g. only for logged in users) or
330
+         * modify what is returned to the caller.
331
+         *
332
+         * This option allows you to wrap global decorators
333
+         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
334
+         *
335
+         *  client/html/catalog/lists/decorators/global = array( 'decorator1' )
336
+         *
337
+         * This would add the decorator named "decorator1" defined by
338
+         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
339
+         *
340
+         * @param array List of decorator names
341
+         * @since 2014.05
342
+         * @category Developer
343
+         * @see client/html/common/decorators/default
344
+         * @see client/html/catalog/lists/decorators/excludes
345
+         * @see client/html/catalog/lists/decorators/local
346
+         */
347
+
348
+        /** client/html/catalog/lists/decorators/local
349
+         * Adds a list of local decorators only to the catalog list html client
350
+         *
351
+         * Decorators extend the functionality of a class by adding new aspects
352
+         * (e.g. log what is currently done), executing the methods of the underlying
353
+         * class only in certain conditions (e.g. only for logged in users) or
354
+         * modify what is returned to the caller.
355
+         *
356
+         * This option allows you to wrap local decorators
357
+         * ("\Aimeos\Client\Html\Catalog\Decorator\*") around the html client.
358
+         *
359
+         *  client/html/catalog/lists/decorators/local = array( 'decorator2' )
360
+         *
361
+         * This would add the decorator named "decorator2" defined by
362
+         * "\Aimeos\Client\Html\Catalog\Decorator\Decorator2" only to the html client.
363
+         *
364
+         * @param array List of decorator names
365
+         * @since 2014.05
366
+         * @category Developer
367
+         * @see client/html/common/decorators/default
368
+         * @see client/html/catalog/lists/decorators/excludes
369
+         * @see client/html/catalog/lists/decorators/global
370
+         */
371
+
372
+        return $this->createSubClient( 'catalog/lists/' . $type, $name );
373
+    }
374
+
375
+
376
+    /**
377
+     * Processes the input, e.g. store given values.
378
+     * A view must be available and this method doesn't generate any output
379
+     * besides setting view variables.
380
+     */
381
+    public function process()
382
+    {
383
+        $context = $this->getContext();
384
+        $view = $this->getView();
385
+
386
+        try
387
+        {
388
+            $site = $context->getLocale()->getSite()->getCode();
389
+            $params = $this->getClientParams( $view->param() );
390
+            $context->getSession()->set( 'aimeos/catalog/lists/params/last/' . $site, $params );
391
+
392
+            parent::process();
393
+        }
394
+        catch( \Aimeos\Client\Html\Exception $e )
395
+        {
396
+            $error = array( $context->getI18n()->dt( 'client', $e->getMessage() ) );
397
+            $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
398
+        }
399
+        catch( \Aimeos\Controller\Frontend\Exception $e )
400
+        {
401
+            $error = array( $context->getI18n()->dt( 'controller/frontend', $e->getMessage() ) );
402
+            $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
403
+        }
404
+        catch( \Aimeos\MShop\Exception $e )
405
+        {
406
+            $error = array( $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
407
+            $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
408
+        }
409
+        catch( \Exception $e )
410
+        {
411
+            $context->getLogger()->log( $e->getMessage() . PHP_EOL . $e->getTraceAsString() );
412
+
413
+            $error = array( $context->getI18n()->dt( 'client', 'A non-recoverable error occured' ) );
414
+            $view->listErrorList = $view->get( 'listErrorList', array() ) + $error;
415
+        }
416
+    }
417
+
418
+
419
+    /**
420
+     * Returns the list of sub-client names configured for the client.
421
+     *
422
+     * @return array List of HTML client names
423
+     */
424
+    protected function getSubClientNames()
425
+    {
426
+        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
427
+    }
428
+
429
+
430
+    /**
431
+     * Sets the necessary parameter values in the view.
432
+     *
433
+     * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
434
+     * @param array &$tags Result array for the list of tags that are associated to the output
435
+     * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
436
+     * @return \Aimeos\MW\View\Iface Modified view object
437
+     */
438
+    protected function setViewParams( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
439
+    {
440
+        if( !isset( $this->cache ) )
441
+        {
442
+            $context = $this->getContext();
443
+            $config = $context->getConfig();
444
+
445
+            $products = $this->getProductList( $view );
446
+
447
+            $text = (string) $view->param( 'f_search' );
448
+            $catid = (string) $view->param( 'f_catid' );
449
+
450
+            if( $catid == '' ) {
451
+                $catid = $config->get( 'client/html/catalog/lists/catid-default', '' );
452
+            }
453
+
454
+            if( $text === '' && $catid !== '' )
455
+            {
456
+                $domains = $config->get( 'client/html/catalog/domains', array( 'media', 'text' ) );
457
+                $controller = \Aimeos\Controller\Frontend\Factory::createController( $context, 'catalog' );
458
+
459
+                $listCatPath = $controller->getCatalogPath( $catid, $domains );
460
+
461
+                if( ( $categoryItem = end( $listCatPath ) ) !== false ) {
462
+                    $view->listCurrentCatItem = $categoryItem;
463
+                }
464
+
465
+                $view->listCatPath = $listCatPath;
466
+
467
+                $this->addMetaItem( $listCatPath, 'catalog', $this->expire, $this->tags );
468
+                $this->addMetaList( array_keys( $listCatPath ), 'catalog', $this->expire );
469
+            }
470
+
471
+            /** client/html/catalog/lists/stock/enable
472
+             * Enables or disables displaying product stock levels in product list views
473
+             *
474
+             * This configuration option allows shop owners to display product
475
+             * stock levels for each product in list views or to disable
476
+             * fetching product stock information.
477
+             *
478
+             * The stock information is fetched via AJAX and inserted via Javascript.
479
+             * This allows to cache product items by leaving out such highly
480
+             * dynamic content like stock levels which changes with each order.
481
+             *
482
+             * @param boolean Value of "1" to display stock levels, "0" to disable displaying them
483
+             * @since 2014.03
484
+             * @category User
485
+             * @category Developer
486
+             * @see client/html/catalog/detail/stock/enable
487
+             * @see client/html/catalog/stock/url/target
488
+             * @see client/html/catalog/stock/url/controller
489
+             * @see client/html/catalog/stock/url/action
490
+             * @see client/html/catalog/stock/url/config
491
+             */
492
+            if( !empty( $products ) && $config->get( 'client/html/catalog/lists/stock/enable', true ) === true ) {
493
+                $view->listStockUrl = $this->getStockUrl( $view, array_keys( $products ) );
494
+            }
495
+
496
+
497
+            $this->addMetaItem( $products, 'product', $this->expire, $this->tags );
498
+            $this->addMetaList( array_keys( $products ), 'product', $this->expire );
499
+
500
+            // Delete cache when products are added or deleted even when in "tag-all" mode
501
+            $this->tags[] = 'product';
502
+
503
+            $view->listParams = $this->getClientParams( $view->param() );
504
+            $view->listPageCurr = $this->getProductListPage( $view );
505
+            $view->listPageSize = $this->getProductListSize( $view );
506
+            $view->listProductTotal = $this->getProductListTotal( $view );
507
+            $view->listProductSort = $view->param( 'f_sort', 'relevance' );
508
+            $view->listProductItems = $products;
509
+
510
+            $this->cache = $view;
511
+        }
512
+
513
+        $expire = $this->expires( $this->expire, $expire );
514
+        $tags = array_merge( $tags, $this->tags );
515
+
516
+        return $this->cache;
517
+    }
518
+
519
+
520
+    /**
521
+     * Returns the URL to fetch the stock level details of the given products
522
+     *
523
+     * @param \Aimeos\MW\View\Iface $view View object
524
+     * @param array $productIds List of product IDs
525
+     * @return string Generated stock level URL
526
+     */
527
+    protected function getStockUrl( \Aimeos\MW\View\Iface $view, array $productIds )
528
+    {
529
+        /** client/html/catalog/stock/url/target
530
+         * Destination of the URL where the controller specified in the URL is known
531
+         *
532
+         * The destination can be a page ID like in a content management system or the
533
+         * module of a software development framework. This "target" must contain or know
534
+         * the controller that should be called by the generated URL.
535
+         *
536
+         * @param string Destination of the URL
537
+         * @since 2014.03
538
+         * @category Developer
539
+         * @see client/html/catalog/stock/url/controller
540
+         * @see client/html/catalog/stock/url/action
541
+         * @see client/html/catalog/stock/url/config
542
+         */
543
+        $stockTarget = $view->config( 'client/html/catalog/stock/url/target' );
544
+
545
+        /** client/html/catalog/stock/url/controller
546
+         * Name of the controller whose action should be called
547
+         *
548
+         * In Model-View-Controller (MVC) applications, the controller contains the methods
549
+         * that create parts of the output displayed in the generated HTML page. Controller
550
+         * names are usually alpha-numeric.
551
+         *
552
+         * @param string Name of the controller
553
+         * @since 2014.03
554
+         * @category Developer
555
+         * @see client/html/catalog/stock/url/target
556
+         * @see client/html/catalog/stock/url/action
557
+         * @see client/html/catalog/stock/url/config
558
+         */
559
+        $stockController = $view->config( 'client/html/catalog/stock/url/controller', 'catalog' );
560
+
561
+        /** client/html/catalog/stock/url/action
562
+         * Name of the action that should create the output
563
+         *
564
+         * In Model-View-Controller (MVC) applications, actions are the methods of a
565
+         * controller that create parts of the output displayed in the generated HTML page.
566
+         * Action names are usually alpha-numeric.
567
+         *
568
+         * @param string Name of the action
569
+         * @since 2014.03
570
+         * @category Developer
571
+         * @see client/html/catalog/stock/url/target
572
+         * @see client/html/catalog/stock/url/controller
573
+         * @see client/html/catalog/stock/url/config
574
+         */
575
+        $stockAction = $view->config( 'client/html/catalog/stock/url/action', 'stock' );
576
+
577
+        /** client/html/catalog/stock/url/config
578
+         * Associative list of configuration options used for generating the URL
579
+         *
580
+         * You can specify additional options as key/value pairs used when generating
581
+         * the URLs, like
582
+         *
583
+         *  client/html/<clientname>/url/config = array( 'absoluteUri' => true )
584
+         *
585
+         * The available key/value pairs depend on the application that embeds the e-commerce
586
+         * framework. This is because the infrastructure of the application is used for
587
+         * generating the URLs. The full list of available config options is referenced
588
+         * in the "see also" section of this page.
589
+         *
590
+         * @param string Associative list of configuration options
591
+         * @since 2014.03
592
+         * @category Developer
593
+         * @see client/html/catalog/stock/url/target
594
+         * @see client/html/catalog/stock/url/controller
595
+         * @see client/html/catalog/stock/url/action
596
+         * @see client/html/url/config
597
+         */
598
+        $stockConfig = $view->config( 'client/html/catalog/stock/url/config', array() );
599
+
600
+        sort( $productIds );
601
+
602
+        $params = array( 's_prodid' => implode( ' ', $productIds ) );
603
+        return $view->url( $stockTarget, $stockController, $stockAction, $params, array(), $stockConfig );
604
+    }
605 605
 }
Please login to merge, or discard this patch.