Passed
Push — master ( 370395...07340f )
by Aimeos
13:03
created

Standard::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2012
6
 * @copyright Aimeos (aimeos.org), 2015-2025
7
 * @package Controller
8
 * @subpackage Frontend
9
 */
10
11
12
namespace Aimeos\Controller\Frontend\Service;
13
14
use \Psr\Http\Message\ServerRequestInterface;
0 ignored issues
show
Bug introduced by
The type \Psr\Http\Message\ServerRequestInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use \Psr\Http\Message\ResponseInterface;
0 ignored issues
show
Bug introduced by
The type \Psr\Http\Message\ResponseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
17
18
/**
19
 * Default implementation of the service frontend controller.
20
 *
21
 * @package Controller
22
 * @subpackage Frontend
23
 */
24
class Standard
25
	extends \Aimeos\Controller\Frontend\Base
26
	implements Iface, \Aimeos\Controller\Frontend\Common\Iface
27
{
28
	/** controller/frontend/service/name
29
	 * Class name of the used service frontend controller implementation
30
	 *
31
	 * Each default frontend controller can be replace by an alternative imlementation.
32
	 * To use this implementation, you have to set the last part of the class
33
	 * name as configuration value so the controller factory knows which class it
34
	 * has to instantiate.
35
	 *
36
	 * For example, if the name of the default class is
37
	 *
38
	 *  \Aimeos\Controller\Frontend\Service\Standard
39
	 *
40
	 * and you want to replace it with your own version named
41
	 *
42
	 *  \Aimeos\Controller\Frontend\Service\Myservice
43
	 *
44
	 * then you have to set the this configuration option:
45
	 *
46
	 *  controller/jobs/frontend/service/name = Myservice
47
	 *
48
	 * The value is the last part of your own class name and it's case sensitive,
49
	 * so take care that the configuration value is exactly named like the last
50
	 * part of the class name.
51
	 *
52
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
53
	 * characters are possible! You should always start the last part of the class
54
	 * name with an upper case character and continue only with lower case characters
55
	 * or numbers. Avoid chamel case names like "MyService"!
56
	 *
57
	 * @param string Last part of the class name
58
	 * @since 2014.03
59
	 * @category Developer
60
	 */
61
62
	/** controller/frontend/service/decorators/excludes
63
	 * Excludes decorators added by the "common" option from the service frontend controllers
64
	 *
65
	 * Decorators extend the functionality of a class by adding new aspects
66
	 * (e.g. log what is currently done), executing the methods of the underlying
67
	 * class only in certain conditions (e.g. only for logged in users) or
68
	 * modify what is returned to the caller.
69
	 *
70
	 * This option allows you to remove a decorator added via
71
	 * "controller/frontend/common/decorators/default" before they are wrapped
72
	 * around the frontend controller.
73
	 *
74
	 *  controller/frontend/service/decorators/excludes = array( 'decorator1' )
75
	 *
76
	 * This would remove the decorator named "decorator1" from the list of
77
	 * common decorators ("\Aimeos\Controller\Frontend\Common\Decorator\*") added via
78
	 * "controller/frontend/common/decorators/default" for the service frontend controller.
79
	 *
80
	 * @param array List of decorator names
81
	 * @since 2014.03
82
	 * @category Developer
83
	 * @see controller/frontend/common/decorators/default
84
	 * @see controller/frontend/service/decorators/global
85
	 * @see controller/frontend/service/decorators/local
86
	 */
87
88
	/** controller/frontend/service/decorators/global
89
	 * Adds a list of globally available decorators only to the service frontend controllers
90
	 *
91
	 * Decorators extend the functionality of a class by adding new aspects
92
	 * (e.g. log what is currently done), executing the methods of the underlying
93
	 * class only in certain conditions (e.g. only for logged in users) or
94
	 * modify what is returned to the caller.
95
	 *
96
	 * This option allows you to wrap global decorators
97
	 * ("\Aimeos\Controller\Frontend\Common\Decorator\*") around the frontend controller.
98
	 *
99
	 *  controller/frontend/service/decorators/global = array( 'decorator1' )
100
	 *
101
	 * This would add the decorator named "decorator1" defined by
102
	 * "\Aimeos\Controller\Frontend\Common\Decorator\Decorator1" only to the frontend controller.
103
	 *
104
	 * @param array List of decorator names
105
	 * @since 2014.03
106
	 * @category Developer
107
	 * @see controller/frontend/common/decorators/default
108
	 * @see controller/frontend/service/decorators/excludes
109
	 * @see controller/frontend/service/decorators/local
110
	 */
111
112
	/** controller/frontend/service/decorators/local
113
	 * Adds a list of local decorators only to the service frontend controllers
114
	 *
115
	 * Decorators extend the functionality of a class by adding new aspects
116
	 * (e.g. log what is currently done), executing the methods of the underlying
117
	 * class only in certain conditions (e.g. only for logged in users) or
118
	 * modify what is returned to the caller.
119
	 *
120
	 * This option allows you to wrap local decorators
121
	 * ("\Aimeos\Controller\Frontend\Service\Decorator\*") around the frontend controller.
122
	 *
123
	 *  controller/frontend/service/decorators/local = array( 'decorator2' )
124
	 *
125
	 * This would add the decorator named "decorator2" defined by
126
	 * "\Aimeos\Controller\Frontend\Catalog\Decorator\Decorator2" only to the frontend
127
	 * controller.
128
	 *
129
	 * @param array List of decorator names
130
	 * @since 2014.03
131
	 * @category Developer
132
	 * @see controller/frontend/common/decorators/default
133
	 * @see controller/frontend/service/decorators/excludes
134
	 * @see controller/frontend/service/decorators/global
135
	 */
136
137
138
	private array $config = [];
139
	private array $domains = [];
140
	private \Aimeos\Base\Criteria\Iface $filter;
141
	private \Aimeos\MShop\Common\Manager\Iface $manager;
142
143
144
	/**
145
	 * Common initialization for controller classes
146
	 *
147
	 * @param \Aimeos\MShop\ContextIface $context Common MShop context object
148
	 */
149
	public function __construct( \Aimeos\MShop\ContextIface $context )
150
	{
151
		parent::__construct( $context );
152
153
		$this->manager = \Aimeos\MShop::create( $context, 'service' );
154
		$this->filter = $this->manager->filter( true );
155
156
		$this->addExpression( $this->filter->sort( '+', 'service.position' ) );
157
	}
158
159
160
	/**
161
	 * Clones objects in controller
162
	 */
163
	public function __clone()
164
	{
165
		$this->filter = clone $this->filter;
166
		parent::__clone();
167
	}
168
169
170
	/**
171
	 * Adds generic condition for filtering services
172
	 *
173
	 * @param string $operator Comparison operator, e.g. "==", "!=", "<", "<=", ">=", ">", "=~", "~="
174
	 * @param string $key Search key defined by the service manager, e.g. "service.status"
175
	 * @param array|string $value Value or list of values to compare to
176
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
177
	 * @since 2019.04
178
	 */
179
	public function compare( string $operator, string $key, $value ) : Iface
180
	{
181
		$this->addExpression( $this->filter->compare( $operator, $key, $value ) );
182
		return $this;
183
	}
184
185
186
	/**
187
	 * Sets the global configuration for the service providers
188
	 *
189
	 * @param array $conf Associative list of global provider configuration options
190
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
191
	 * @since 2024.10
192
	 */
193
	public function config( array $conf ) : Iface
194
	{
195
		$this->config = $conf;
196
		return $this;
197
	}
198
199
200
	/**
201
	 * Returns the service for the given code
202
	 *
203
	 * @param string $code Unique service code
204
	 * @return \Aimeos\MShop\Service\Item\Iface Service item including the referenced domains items
205
	 * @since 2019.04
206
	 */
207
	public function find( string $code ) : \Aimeos\MShop\Service\Item\Iface
208
	{
209
		return $this->manager->find( $code, $this->domains, null, null, null );
210
	}
211
212
213
	/**
214
	 * Creates a search function string for the given name and parameters
215
	 *
216
	 * @param string $name Name of the search function without parenthesis, e.g. "service:has"
217
	 * @param array $params List of parameters for the search function with numeric keys starting at 0
218
	 * @return string Search function string that can be used in compare()
219
	 */
220
	public function function( string $name, array $params ) : string
221
	{
222
		return $this->filter->make( $name, $params );
223
	}
224
225
226
	/**
227
	 * Returns the service for the given ID
228
	 *
229
	 * @param string $id Unique service ID
230
	 * @return \Aimeos\MShop\Service\Item\Iface Service item including the referenced domains items
231
	 * @since 2019.04
232
	 */
233
	public function get( string $id ) : \Aimeos\MShop\Service\Item\Iface
234
	{
235
		return $this->manager->get( $id, $this->domains, null );
236
	}
237
238
239
	/**
240
	 * Returns the service item for the given ID
241
	 *
242
	 * @param string $serviceId Unique service ID
243
	 * @return \Aimeos\MShop\Service\Provider\Iface Service provider object
244
	 */
245
	public function getProvider( string $serviceId ) : \Aimeos\MShop\Service\Provider\Iface
246
	{
247
		$item = $this->manager->get( $serviceId, $this->domains, true );
248
		$provider = $this->manager->getProvider( $item, $item->getType() );
249
250
		return $provider->injectGlobalConfigBE( $this->config );
251
	}
252
253
254
	/**
255
	 * Returns the service providers of the given type
256
	 *
257
	 * @return \Aimeos\Map List of service IDs as keys and service provider objects as values
258
	 */
259
	public function getProviders() : \Aimeos\Map
260
	{
261
		$list = [];
262
		$filter = clone $this->filter;
263
		$filter->add( $filter->and( $this->getConditions() ) )->order( 'service.position' );
264
265
		foreach( $this->manager->search( $filter, $this->domains ) as $id => $item )
266
		{
267
			$list[$id] = $this->manager->getProvider( $item, $item->getType() );
268
			$list[$id]->injectGlobalConfigBE( $this->config );
269
		}
270
271
		return map( $list );
272
	}
273
274
275
	/**
276
	 * Parses the given array and adds the conditions to the list of conditions
277
	 *
278
	 * @param array $conditions List of conditions, e.g. ['&&' => [['>' => ['service.status' => 0]], ['==' => ['service.type' => 'default']]]]
279
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
280
	 * @since 2019.04
281
	 */
282
	public function parse( array $conditions ) : Iface
283
	{
284
		if( ( $cond = $this->filter->parse( $conditions ) ) !== null ) {
285
			$this->addExpression( $cond );
286
		}
287
288
		return $this;
289
	}
290
291
292
	/**
293
	 * Processes the payment service for the given order
294
	 *
295
	 * @param \Aimeos\MShop\Order\Item\Iface $orderItem Order which should be processed
296
	 * @param string $serviceId Unique service item ID
297
	 * @param array $urls Associative list of keys and the corresponding URLs
298
	 * 	(keys are payment.url-self, payment.url-success, payment.url-update)
299
	 * @param array $params Request parameters and order service attributes
300
	 * @return \Aimeos\MShop\Common\Helper\Form\Iface|null Form object with URL, parameters, etc.
301
	 * 	or null if no form data is required
302
	 */
303
	public function process( \Aimeos\MShop\Order\Item\Iface $orderItem,
304
		string $serviceId, array $urls, array $params ) : ?\Aimeos\MShop\Common\Helper\Form\Iface
305
	{
306
		$item = $this->manager->get( $serviceId, [], true );
307
308
		$provider = $this->manager->getProvider( $item, $item->getType() );
309
		$provider->injectGlobalConfigBE( $urls + $this->config );
310
311
		return $provider->process( $orderItem, $params );
312
	}
313
314
315
	/**
316
	 * Returns the services filtered by the previously assigned conditions
317
	 *
318
	 * @param int &$total Parameter where the total number of found services will be stored in
319
	 * @return \Aimeos\Map Ordered list of service items implementing \Aimeos\MShop\Service\Item\Iface
320
	 * @since 2019.04
321
	 */
322
	public function search( ?int &$total = null ) : \Aimeos\Map
323
	{
324
		$filter = clone $this->filter;
325
		$filter->add( $filter->and( $this->getConditions() ) );
326
		$filter->setSortations( $this->getSortations() );
327
328
		return $this->manager->search( $filter, $this->domains, $total );
329
	}
330
331
332
	/**
333
	 * Sets the start value and the number of returned services for slicing the list of found services
334
	 *
335
	 * @param int $start Start value of the first attribute in the list
336
	 * @param int $limit Number of returned services
337
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
338
	 * @since 2019.04
339
	 */
340
	public function slice( int $start, int $limit ) : Iface
341
	{
342
		$maxsize = $this->context()->config()->get( 'controller/frontend/common/max-size', 500 );
343
		$this->filter->slice( $start, min( $limit, $maxsize ) );
344
		return $this;
345
	}
346
347
348
	/**
349
	 * Sets the sorting of the result list
350
	 *
351
	 * @param string|null $key Sorting of the result list like "position", null for no sorting
352
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
353
	 * @since 2019.04
354
	 */
355
	public function sort( ?string $key = null ) : Iface
356
	{
357
		$list = $this->splitKeys( $key );
358
359
		foreach( $list as $sortkey )
360
		{
361
			$direction = ( $sortkey[0] === '-' ? '-' : '+' );
362
			$sortkey = ltrim( $sortkey, '+-' );
363
364
			switch( $sortkey )
365
			{
366
				case 'type':
367
					$this->addExpression( $this->filter->sort( $direction, 'service.type' ) ); break;
368
				default:
369
					$this->addExpression( $this->filter->sort( $direction, $sortkey ) );
370
			}
371
		}
372
373
		return $this;
374
	}
375
376
377
	/**
378
	 * Adds attribute types for filtering
379
	 *
380
	 * @param array|string $code Service type or list of types
381
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
382
	 * @since 2019.04
383
	 */
384
	public function type( $code ) : Iface
385
	{
386
		if( $code ) {
387
			$this->addExpression( $this->filter->compare( '==', 'service.type', $code ) );
388
		}
389
390
		return $this;
391
	}
392
393
394
	/**
395
	 * Updates the order status sent by payment gateway notifications
396
	 *
397
	 * @param ServerRequestInterface $request Request object
398
	 * @param ResponseInterface $response Response object that will contain HTTP status and response body
399
	 * @param string $code Unique code of the service used for the current order
400
	 * @return \Psr\Http\Message\ResponseInterface Response object
401
	 */
402
	public function updatePush( ServerRequestInterface $request, ResponseInterface $response,
403
		string $code ) : \Psr\Http\Message\ResponseInterface
404
	{
405
		$item = $this->manager->find( $code );
406
407
		$provider = $this->manager->getProvider( $item, $item->getType() );
408
		$provider->injectGlobalConfigBE( $this->config );
409
410
		return $provider->updatePush( $request, $response );
411
	}
412
413
414
	/**
415
	 * Updates the payment or delivery status for the given request
416
	 *
417
	 * @param ServerRequestInterface $request Request object with parameters and request body
418
	 * @param string $code Unique code of the service used for the current order
419
	 * @param string $orderid ID of the order whose payment status should be updated
420
	 * @return \Aimeos\MShop\Order\Item\Iface $orderItem Order item that has been updated
421
	 */
422
	public function updateSync( ServerRequestInterface $request,
423
		string $code, string $orderid ) : \Aimeos\MShop\Order\Item\Iface
424
	{
425
		$ref = $this->context()->config()->get( 'mshop/order/manager/subdomains', [] );
426
		$orderItem = \Aimeos\MShop::create( $this->context(), 'order' )->get( $orderid, $ref );
427
		$serviceItem = $this->manager->find( $code );
428
429
		$provider = $this->manager->getProvider( $serviceItem, $serviceItem->getType() );
430
		$provider->injectGlobalConfigBE( $this->config );
431
432
433
		if( ( $orderItem = $provider->updateSync( $request, $orderItem ) ) !== null )
434
		{
435
			if( $orderItem->getStatusPayment() === \Aimeos\MShop\Order\Item\Base::PAY_UNFINISHED
436
				&& $provider->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_QUERY )
437
			) {
438
				$provider->query( $orderItem );
439
			}
440
		}
441
442
		return $orderItem;
443
	}
444
445
446
	/**
447
	 * Sets the referenced domains that will be fetched too when retrieving items
448
	 *
449
	 * @param array $domains Domain names of the referenced items that should be fetched too
450
	 * @return \Aimeos\Controller\Frontend\Service\Iface Service controller for fluent interface
451
	 * @since 2019.04
452
	 */
453
	public function uses( array $domains ) : Iface
454
	{
455
		$this->domains = $domains;
456
		return $this;
457
	}
458
459
460
	/**
461
	 * Returns the manager used by the controller
462
	 *
463
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object
464
	 */
465
	protected function getManager() : \Aimeos\MShop\Common\Manager\Iface
466
	{
467
		return $this->manager;
468
	}
469
}
470