Completed
Push — master ( 160839...2955b1 )
by Aimeos
01:48
created

Standard::getDomainItems()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2018
6
 * @package Client
7
 * @subpackage JsonApi
8
 */
9
10
11
namespace Aimeos\Client\JsonApi\Product;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API standard client
19
 *
20
 * @package Client
21
 * @subpackage JsonApi
22
 */
23
class Standard
24
	extends \Aimeos\Client\JsonApi\Base
25
	implements \Aimeos\Client\JsonApi\Iface
26
{
27
	/**
28
	 * Returns the resource or the resource list
29
	 *
30
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
31
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
32
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
33
	 */
34
	public function get( ServerRequestInterface $request, ResponseInterface $response )
35
	{
36
		$view = $this->getView();
37
38
		try
39
		{
40
			if( $view->param( 'aggregate' ) != '' ) {
41
				$response = $this->aggregate( $view, $request, $response );
42
			} elseif( $view->param( 'id' ) != '' ) {
43
				$response = $this->getItem( $view, $request, $response );
44
			} else {
45
				$response = $this->getItems( $view, $request, $response );
46
			}
47
48
			$status = 200;
49
		}
50
		catch( \Aimeos\MShop\Exception $e )
51
		{
52
			$status = 404;
53
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
54
		}
55
		catch( \Exception $e )
56
		{
57
			$status = 500;
58
			$view->errors = $this->getErrorDetails( $e );
59
		}
60
61
		if( $view->param( 'aggregate' ) != '' )
62
		{
63
			/** client/jsonapi/product/standard/template-aggregate
64
			 * Relative path to the product aggregate JSON API template
65
			 *
66
			 * The template file contains the code and processing instructions
67
			 * to generate the result shown in the JSON API body. The
68
			 * configuration string is the path to the template file relative
69
			 * to the templates directory (usually in client/jsonapi/templates).
70
			 *
71
			 * You can overwrite the template file configuration in extensions and
72
			 * provide alternative templates. These alternative templates should be
73
			 * named like the default one but with the string "standard" replaced by
74
			 * an unique name. You may use the name of your project for this. If
75
			 * you've implemented an alternative client class as well, "standard"
76
			 * should be replaced by the name of the new class.
77
			 *
78
			 * @param string Relative path to the template creating the list of aggregated product counts
79
			 * @since 2017.03
80
			 * @category Developer
81
			 */
82
			$tplconf = 'client/jsonapi/product/standard/template-aggregate';
83
			$default = 'aggregate-standard';
84
		}
85
		else
86
		{
87
			/** client/jsonapi/product/standard/template
88
			 * Relative path to the product JSON API template
89
			 *
90
			 * The template file contains the code and processing instructions
91
			 * to generate the result shown in the JSON API body. The
92
			 * configuration string is the path to the template file relative
93
			 * to the templates directory (usually in client/jsonapi/templates).
94
			 *
95
			 * You can overwrite the template file configuration in extensions and
96
			 * provide alternative templates. These alternative templates should be
97
			 * named like the default one but with the string "standard" replaced by
98
			 * an unique name. You may use the name of your project for this. If
99
			 * you've implemented an alternative client class as well, "standard"
100
			 * should be replaced by the name of the new class.
101
			 *
102
			 * @param string Relative path to the template creating the body for the GET method of the JSON API
103
			 * @since 2017.03
104
			 * @category Developer
105
			 */
106
			$tplconf = 'client/jsonapi/product/standard/template';
107
			$default = 'product/standard';
108
		}
109
110
		$body = $view->render( $view->config( $tplconf, $default ) );
111
112
		return $response->withHeader( 'Allow', 'GET,OPTIONS' )
113
			->withHeader( 'Cache-Control', 'max-age=300' )
114
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
115
			->withBody( $view->response()->createStreamFromString( $body ) )
116
			->withStatus( $status );
117
	}
118
119
120
	/**
121
	 * Returns the available REST verbs and the available parameters
122
	 *
123
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
124
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
125
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
126
	 */
127
	public function options( ServerRequestInterface $request, ResponseInterface $response )
128
	{
129
		$view = $this->getView();
130
131
		$view->filter = [
132
			'f_search' => [
133
				'label' => 'Return products whose text matches the user input',
134
				'type' => 'string', 'default' => '', 'required' => false,
135
			],
136
			'f_catid' => [
137
				'label' => 'Return products associated to this category ID',
138
				'type' => 'string|array', 'default' => '', 'required' => false,
139
			],
140
			'f_listtype' => [
141
				'label' => 'Return products which are associated to categories with this list type',
142
				'type' => 'string', 'default' => 'default', 'required' => false,
143
			],
144
			'f_attrid' => [
145
				'label' => 'Return products that reference all attribute IDs',
146
				'type' => 'array', 'default' => '[]', 'required' => false,
147
			],
148
			'f_optid' => [
149
				'label' => 'Return products that reference at least one of the attribute IDs',
150
				'type' => 'array', 'default' => '[]', 'required' => false,
151
			],
152
			'f_oneid' => [
153
				'label' => 'Return products that reference at least one of the attribute IDs per attribute type',
154
				'type' => 'array[<typecode>]', 'default' => '[]', 'required' => false,
155
			],
156
			'f_supid' => [
157
				'label' => 'Return products that reference at least one of the supplier IDs',
158
				'type' => 'array', 'default' => '[]', 'required' => false,
159
			],
160
		];
161
162
		$view->sort = [
163
			'relevance' => [
164
				'label' => 'Sort products by their category position',
165
				'type' => 'string', 'default' => true, 'required' => false,
166
			],
167
			'name' => [
168
				'label' => 'Sort products by their name (ascending, "-name" for descending)',
169
				'type' => 'string', 'default' => false, 'required' => false,
170
			],
171
			'price' => [
172
				'label' => 'Sort products by their price (ascending, "-price" for descending)',
173
				'type' => 'string', 'default' => false, 'required' => false,
174
			],
175
			'ctime' => [
176
				'label' => 'Sort products by their creating date/time (ascending, "-ctime" for descending)',
177
				'type' => 'string', 'default' => false, 'required' => false,
178
			],
179
		];
180
181
		$tplconf = 'client/jsonapi/standard/template-options';
182
		$default = 'options-standard';
183
184
		$body = $view->render( $view->config( $tplconf, $default ) );
185
186
		return $response->withHeader( 'Allow', 'GET,OPTIONS' )
187
			->withHeader( 'Cache-Control', 'max-age=300' )
188
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
189
			->withBody( $view->response()->createStreamFromString( $body ) )
190
			->withStatus( 200 );
191
	}
192
193
194
	/**
195
	 * Counts the number of products for the requested key
196
	 *
197
	 * @param \Aimeos\MW\View\Iface $view View instance
198
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
199
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
200
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
201
	 */
202
	protected function aggregate( \Aimeos\MW\View\Iface $view, ServerRequestInterface $request, ResponseInterface $response )
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
203
	{
204
		$view->data = $this->getController( $view )->sort()
0 ignored issues
show
Bug introduced by
The call to sort() misses some required arguments starting with $operator.
Loading history...
Bug introduced by
The method slice() does not seem to exist on object<Aimeos\MW\Criteria\Expression\Sort\Iface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
205
			->slice( $view->param( 'page/offset', 0 ), $view->param( 'page/limit', 10000 ) )
206
			->aggregate( $view->param( 'aggregate' ) );
207
208
		return $response;
209
	}
210
211
212
	/**
213
	 * Returns the initialized search filter
214
	 *
215
	 * @param \Aimeos\MW\View\Iface $view View instance
216
	 * @return \Aimeos\MW\Criteria\Iface Initialize search filter
217
	 */
218
	protected function getController( \Aimeos\MW\View\Iface $view )
219
	{
220
		$context = $this->getContext();
221
		$cntl = \Aimeos\Controller\Frontend::create( $context, 'product' );
222
223
		/** client/jsonapi/product/levels
224
		 * Include products of sub-categories in the product list of the current category
225
		 *
226
		 * Sometimes it may be useful to show products of sub-categories in the
227
		 * current category product list, e.g. if the current category contains
228
		 * no products at all or if there are only a few products in all categories.
229
		 *
230
		 * Possible constant values for this setting are:
231
		 * * 1 : Only products from the current category
232
		 * * 2 : Products from the current category and the direct child categories
233
		 * * 3 : Products from the current category and the whole category sub-tree
234
		 *
235
		 * Caution: Please keep in mind that displaying products of sub-categories
236
		 * can slow down your shop, especially if it contains more than a few
237
		 * products! You have no real control over the positions of the products
238
		 * in the result list too because all products from different categories
239
		 * with the same position value are placed randomly.
240
		 *
241
		 * Usually, a better way is to associate products to all categories they
242
		 * should be listed in. This can be done manually if there are only a few
243
		 * ones or during the product import automatically.
244
		 *
245
		 * @param integer Tree level constant
246
		 * @since 2017.03
247
		 * @category Developer
248
		 */
249
		$level = $context->getConfig()->get( 'client/jsonapi/product/levels', \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE );
250
251
		foreach( (array) $view->param( 'filter/f_oneid', [] ) as $list ) {
252
			$cntl->oneOf( $list );
253
		}
254
255
		$cntl->allOf( $view->param( 'filter/f_attrid', [] ) )
256
			->oneOf( $view->param( 'filter/f_optid', [] ) )
257
			->text( $view->param( 'filter/f_search' ) )
258
			->supplier( $view->param( 'filter/f_supid', [] ), $view->param( 'filter/f_listtype', 'default' ) )
259
			->category( $view->param( 'filter/f_catid' ), $view->param( 'filter/f_listtype', 'default' ), $level );
260
261
		$params = $view->param( 'filter', [] );
262
263
		unset( $params['f_supid'], $params['f_search'] );
264
		unset( $params['f_catid'], $params['f_listtype'] );
265
		unset( $params['f_attrid'], $params['f_optid'], $params['f_oneid'] );
266
267
		return $cntl->parse( $params )
268
			->sort( $view->param( 'sort', 'relevance' ) )
269
			->slice( $view->param( 'page/offset', 0 ), $view->param( 'page/limit', 48 ) );
270
	}
271
272
273
	/**
274
	 * Retrieves the item and adds the data to the view
275
	 *
276
	 * @param \Aimeos\MW\View\Iface $view View instance
277
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
278
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
279
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
280
	 */
281
	protected function getItem( \Aimeos\MW\View\Iface $view, ServerRequestInterface $request, ResponseInterface $response )
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
282
	{
283
		$ref = $view->param( 'include', [] );
284
285
		if( is_string( $ref ) ) {
286
			$ref = explode( ',', $ref );
287
		}
288
289
		$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'product' );
290
291
		$view->items = $cntl->get( $view->param( 'id' ), $ref );
292
		$view->total = 1;
293
294
		return $response;
295
	}
296
297
298
	/**
299
	 * Retrieves the items and adds the data to the view
300
	 *
301
	 * @param \Aimeos\MW\View\Iface $view View instance
302
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
303
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
304
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
305
	 */
306
	protected function getItems( \Aimeos\MW\View\Iface $view, ServerRequestInterface $request, ResponseInterface $response )
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
307
	{
308
		$total = 0;
309
		$ref = $view->param( 'include', [] );
310
311
		if( is_string( $ref ) ) {
312
			$ref = explode( ',', $ref );
313
		}
314
315
		$view->items = $this->getController( $view )->search( $ref, $total );
0 ignored issues
show
Bug introduced by
The method search() does not seem to exist on object<Aimeos\MW\Criteria\Iface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
316
		$view->total = $total;
317
318
		return $response;
319
	}
320
}
321