Completed
Push — master ( 764ed5...7b4a42 )
by Aimeos
02:43
created

Standard::uses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
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, 2014
6
 * @copyright Aimeos (aimeos.org), 2015-2020
7
 * @package Controller
8
 * @subpackage Frontend
9
 */
10
11
12
namespace Aimeos\Controller\Frontend\Order;
13
14
15
/**
16
 * Default implementation of the order frontend controller.
17
 *
18
 * @package Controller
19
 * @subpackage Frontend
20
 */
21
class Standard
22
	extends \Aimeos\Controller\Frontend\Base
23
	implements Iface, \Aimeos\Controller\Frontend\Common\Iface
24
{
25
	private $conditions = [];
26
	private $domains = [];
27
	private $manager;
28
	private $filter;
29
	private $item;
30
31
32
	/**
33
	 * Initializes the controller
34
	 *
35
	 * @param \Aimeos\MShop\Context\Item\Iface $context Common MShop context object
36
	 */
37
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
38
	{
39
		parent::__construct( $context );
40
41
		$this->manager = \Aimeos\MShop::create( $context, 'order' );
42
		$this->item = $this->manager->createItem();
43
44
		$this->filter = $this->manager->createSearch( true );
45
		$this->conditions[] = $this->filter->compare( '==', 'order.base.customerid', $context->getUserId() );
46
		$this->conditions[] = $this->filter->getConditions();
47
	}
48
49
50
	/**
51
	 * Clones objects in controller and resets values
52
	 */
53
	public function __clone()
54
	{
55
		$this->item = clone $this->item;
56
	}
57
58
59
	/**
60
	 * Adds the values to the order object (not yet stored)
61
	 *
62
	 * @param string $baseId ID of the stored basket
63
	 * @param array $values Values added to the order item (new or existing) like "order.type"
64
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
65
	 * @since 2019.04
66
	 */
67
	public function add( string $baseId, array $values = [] ) : Iface
68
	{
69
		$this->item = $this->item->fromArray( $values )->setBaseId( $baseId );
70
		return $this;
71
	}
72
73
74
	/**
75
	 * Adds generic condition for filtering orders
76
	 *
77
	 * @param string $operator Comparison operator, e.g. "==", "!=", "<", "<=", ">=", ">", "=~", "~="
78
	 * @param string $key Search key defined by the order manager, e.g. "order.type"
79
	 * @param array|string $value Value or list of values to compare to
80
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
81
	 * @since 2019.04
82
	 */
83
	public function compare( string $operator, string $key, $value ) : Iface
84
	{
85
		$this->conditions[] = $this->filter->compare( $operator, $key, $value );
86
		return $this;
87
	}
88
89
90
	/**
91
	 * Returns the order for the given order ID
92
	 *
93
	 * @param string $id Unique order ID
94
	 * @param bool $default Use default criteria to limit orders
95
	 * @return \Aimeos\MShop\Order\Item\Iface Order item object
96
	 * @since 2019.04
97
	 */
98
	public function get( string $id, bool $default = true ) : \Aimeos\MShop\Order\Item\Iface
99
	{
100
		return $this->manager->getItem( $id, $this->domains, $default );
101
	}
102
103
104
	/**
105
	 * Parses the given array and adds the conditions to the list of conditions
106
	 *
107
	 * @param array $conditions List of conditions, e.g. ['&&' => [['>' => ['order.statuspayment' => 0]], ['==' => ['order.type' => 'web']]]]
108
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
109
	 * @since 2019.04
110
	 */
111
	public function parse( array $conditions ) : Iface
112
	{
113
		if( ( $cond = $this->filter->toConditions( $conditions ) ) !== null ) {
114
			$this->conditions[] = $cond;
115
		}
116
117
		return $this;
118
	}
119
120
121
	/**
122
	 * Updates the given order item in the storage
123
	 *
124
	 * @param \Aimeos\MShop\Order\Item\Iface $orderItem Order item object
125
	 * @return \Aimeos\MShop\Order\Item\Iface $orderItem Saved order item object
126
	 * @since 2019.04
127
	 */
128
	public function save( \Aimeos\MShop\Order\Item\Iface $orderItem ) : \Aimeos\MShop\Order\Item\Iface
129
	{
130
		return $this->manager->saveItem( $orderItem );
0 ignored issues
show
Bug introduced by
The method saveItem() does not exist on Aimeos\MShop\Common\Manager\Iface. Did you maybe mean saveItems()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
		return $this->manager->/** @scrutinizer ignore-call */ saveItem( $orderItem );

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...
131
	}
132
133
	/**
134
	 * Returns the orders filtered by the previously assigned conditions
135
	 *
136
	 * @param int &$total Parameter where the total number of found attributes will be stored in
137
	 * @return \Aimeos\Map Ordered list of order items implementing \Aimeos\MShop\Order\Item\Iface
138
	 * @since 2019.04
139
	 */
140
	public function search( int &$total = null ) : \Aimeos\Map
141
	{
142
		$this->filter->setConditions( $this->filter->combine( '&&', $this->conditions ) );
143
		return $this->manager->searchItems( $this->filter, $this->domains, $total );
144
	}
145
146
147
	/**
148
	 * Sets the start value and the number of returned orders for slicing the list of found orders
149
	 *
150
	 * @param int $start Start value of the first order in the list
151
	 * @param int $limit Number of returned orders
152
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
153
	 * @since 2019.04
154
	 */
155
	public function slice( int $start, int $limit ) : Iface
156
	{
157
		$this->filter->setSlice( $start, $limit );
158
		return $this;
159
	}
160
161
162
	/**
163
	 * Sets the sorting of the result list
164
	 *
165
	 * @param string|null $key Sorting of the result list like "-order.id", null for no sorting
166
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
167
	 * @since 2019.04
168
	 */
169
	public function sort( string $key = null ) : Iface
170
	{
171
		$sort = [];
172
		$list = ( $key ? explode( ',', $key ) : [] );
173
174
		foreach( $list as $sortkey )
175
		{
176
			$direction = ( $sortkey[0] === '-' ? '-' : '+' );
177
			$sort[] = $this->filter->sort( $direction, ltrim( $sortkey, '+-' ) );
178
		}
179
180
		$this->filter->setSortations( $sort );
181
		return $this;
182
	}
183
184
185
	/**
186
	 * Saves the modified order item in the storage and blocks the stock and coupon codes
187
	 *
188
	 * @return \Aimeos\MShop\Order\Item\Iface New or updated order item object
189
	 * @since 2019.04
190
	 */
191
	public function store() : \Aimeos\MShop\Order\Item\Iface
192
	{
193
		$this->checkLimit( $this->item->getBaseId() );
194
195
		$cntl = \Aimeos\Controller\Common\Order\Factory::create( $this->getContext() );
196
		$this->item = $this->manager->saveItem( $this->item );
197
198
		return $cntl->block( $this->item );
199
	}
200
201
202
	/**
203
	 * Sets the referenced domains that will be fetched too when retrieving items
204
	 *
205
	 * @param array $domains Domain names of the referenced items that should be fetched too
206
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
207
	 * @since 2019.04
208
	 */
209
	public function uses( array $domains ) : Iface
210
	{
211
		$this->domains = $domains;
212
		return $this;
213
	}
214
215
216
	/**
217
	 * Checks if more orders than allowed have been created by the user
218
	 *
219
	 * @param string $baseId Unique ID of the order base item (basket)
220
	 * @return \Aimeos\Controller\Frontend\Order\Iface Order controller for fluent interface
221
	 * @throws \Aimeos\Controller\Frontend\Order\Exception If limit is exceeded
222
	 */
223
	protected function checkLimit( string $baseId ) : Iface
224
	{
225
		/** controller/frontend/order/limit-seconds
226
		 * Order limitation time frame in seconds
227
		 *
228
		 * Creating new orders is limited to avoid abuse and mitigate denial of
229
		 * service attacks. Within the configured time frame, only one order
230
		 * item can be created per order base item. All orders for the order
231
		 * base item within the last X seconds are counted.  If there's already
232
		 * one available, an error message will be shown to the user instead of
233
		 * creating the new order item.
234
		 *
235
		 * @param integer Number of seconds to check order items within
236
		 * @since 2017.05
237
		 * @category Developer
238
		 * @see controller/frontend/basket/limit-count
239
		 * @see controller/frontend/basket/limit-seconds
240
		 */
241
		$seconds = $this->getContext()->getConfig()->get( 'controller/frontend/order/limit-seconds', 300 );
242
243
		$search = $this->manager->createSearch()->setSlice( 0, 0 );
244
		$search->setConditions( $search->combine( '&&', [
245
			$search->compare( '==', 'order.baseid', $baseId ),
246
			$search->compare( '>=', 'order.ctime', date( 'Y-m-d H:i:s', time() - $seconds ) ),
247
		] ) );
248
249
		$total = 0;
250
		$this->manager->searchItems( $search, [], $total );
251
252
		if( $total > 0 ) {
253
			throw new \Aimeos\Controller\Frontend\Order\Exception( sprintf( 'The order has already been created' ) );
254
		}
255
256
		return $this;
257
	}
258
}
259