Completed
Push — master ( 5d98f5...246d8b )
by Aimeos
08:56
created

Base::getDeletedItems()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2017
7
 * @package MShop
8
 * @subpackage Common
9
 */
10
11
12
namespace Aimeos\MShop\Common\Item\ListRef;
13
14
15
/**
16
 * Abstract class for items containing referenced list items.
17
 *
18
 * @package MShop
19
 * @subpackage Common
20
 */
21
abstract class Base extends \Aimeos\MShop\Common\Item\Base
22
{
23
	private $refItems;
24
	private $listItems;
25
	private $rmItems = [];
26
	private $prepared = false;
27
	private $max = 0;
28
29
30
	/**
31
	 * Initializes the item with the given values.
32
	 *
33
	 * @param string $prefix Prefix for the keys returned by toArray()
34
	 * @param array $values Associative list of key/value pairs of the item properties
35
	 * @param array $listItems Two dimensional associative list of domain / ID / list items that implement \Aimeos\MShop\Common\Item\Lists\Iface
36
	 * @param array $refItems Two dimensional associative list of domain / ID / domain items that implement \Aimeos\MShop\Common\Item\Iface
37
	 */
38
	public function __construct( $prefix, array $values = [], array $listItems = [], array $refItems = [] )
39
	{
40
		parent::__construct( $prefix, $values );
41
42
		$this->listItems = $listItems;
43
		$this->refItems = $refItems;
44
	}
45
46
47
	/**
48
	 * Adds a new item to the given domain and references it by a list item
49
	 *
50
	 * @param string $domain Name of the domain (e.g. media, text, etc.)
51
	 * @param \Aimeos\MShop\Common\Item\Lists\Iface $listItem List item referencing the new domain item
52
	 * @param \Aimeos\MShop\Common\Item\Iface|null $refItem New item added to the given domain or null if no item should be referenced
53
	 * @return \Aimeos\MShop\Common\Item\ListRef\Iface Self object for method chaining
54
	 */
55
	public function addRefItem( $domain, \Aimeos\MShop\Common\Item\Lists\Iface $listItem, \Aimeos\MShop\Common\Item\Iface $refItem = null )
56
	{
57
		$id = $listItem->getId() ?: 'tmp-' . $this->max++;
58
		$this->listItems[$domain][$id] = $listItem->setDomain( $domain )->setRefItem( $refItem );
59
60
		if( $refItem !== null )
61
		{
62
			$id = $refItem->getId() ?: 'tmp-' . $this->max++;
63
			$listItem->setRefId( $id );
64
65
			$this->refItems[$domain][$id] = $refItem;
66
		}
67
68
		return $this;
69
	}
70
71
72
	/**
73
	 * Removes an item from the given domain and its list item referencing it
74
	 *
75
	 * @param string $domain Name of the domain (e.g. media, text, etc.)
76
	 * @param \Aimeos\MShop\Common\Item\Lists\Iface $listItem List item referencing the domain item
77
	 * @param \Aimeos\MShop\Common\Item\Iface|null $refItem Existing item removed from the given domain or null if item shouldn't be removed
78
	 * @return \Aimeos\MShop\Common\Item\ListRef\Iface Self object for method chaining
79
	 */
80
	public function deleteRefItem( $domain, \Aimeos\MShop\Common\Item\Lists\Iface $listItem, \Aimeos\MShop\Common\Item\Iface $refItem = null )
81
	{
82
		if( isset( $this->listItems[$domain] ) )
83
		{
84
			foreach( $this->listItems[$domain] as $key => $litem )
85
			{
86
				if( $litem === $listItem && $listItem->getDomain() === $domain )
87
				{
88
					$this->rmItems[] = $listItem->setRefItem( $refItem );
89
					unset( $this->listItems[$domain][$key] );
90
91
					return $this;
92
				}
93
			}
94
		}
95
96
		throw new \Aimeos\MShop\Exception( sprintf( 'List item for removal from domain "%1$s" not found', $domain ) );
97
	}
98
99
100
	/**
101
	 * Returns the deleted list items
102
	 *
103
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface[] List items with referenced items attached (optional)
104
	 */
105
	public function getDeletedItems()
106
	{
107
		return $this->rmItems;
108
	}
109
110
111
	/**
112
	 * Returns the list item for the given reference ID, domain, list type and type.
113
	 *
114
	 * @param string $refId Unique ID of the referenced item
115
	 * @param string $domain Name of the domain (e.g. product, text, etc.)
116
	 * @param string $listtype Name of the list item type
117
	 * @param boolean $active True to return only active items, false to return all
118
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface|null Matching list item or null if none
119
	 */
120
	public function getListItem( $refId, $domain, $listtype, $active = true )
121
	{
122
		if( isset( $this->listItems[$domain] ) )
123
		{
124
			foreach( $this->listItems[$domain] as $listItem )
125
			{
126
				if( $listItem->getRefId() == $refId && $listItem->getType() === $listtype
127
					&& ( $active === false || $listItem->isAvailable() )
128
				) {
129
					return $listItem;
130
				}
131
			}
132
		}
133
	}
134
135
136
	/**
137
	 * Returns the list items attached, optionally filtered by domain and list type.
138
	 *
139
	 * The reference parameter in searchItems() must have been set accordingly
140
	 * to the requested domain to get the items. Otherwise, no items will be
141
	 * returned by this method.
142
	 *
143
	 * @param array|string|null $domain Name/Names of the domain (e.g. product, text, etc.) or null for all
144
	 * @param array|string|null $listtype Name/Names of the list item type or null for all
145
	 * @param array|string|null $type Name/Names of the item type or null for all
146
	 * @param boolean $active True to return only active items, false to return all
147
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
148
	 */
149
	public function getListItems( $domain = null, $listtype = null, $type = null, $active = true )
150
	{
151
		$result = [];
152
		$this->prepareListItems();
153
154
		$iface = '\\Aimeos\\MShop\\Common\\Item\\Typeid\\Iface';
155
		$listTypes = ( is_array( $listtype ) ? $listtype : array( $listtype ) );
156
		$types = ( is_array( $type ) ? $type : array( $type ) );
157
158
159
		foreach( $this->listItems as $dname => $list )
160
		{
161
			if( is_array( $domain ) && !in_array( $dname, $domain ) || $domain !== null && $dname !== $domain ) {
162
				continue;
163
			}
164
165
			foreach( $list as $id => $item )
166
			{
167
				if( $listtype && ( !($item instanceof $iface) || !in_array( $item->getType(), $listTypes ) ) ) {
168
					continue;
169
				}
170
171
				if( $type && ( !($item->getRefItem() instanceof $iface) || !in_array( $item->getRefItem()->getType(), $types ) ) ) {
172
					continue;
173
				}
174
175
				if( $active && !$item->isAvailable() ) {
176
					continue;
177
				}
178
179
				$result[$id] = $item;
180
			}
181
		}
182
183
		return $result;
184
	}
185
186
187
	/**
188
	 * Returns the product, text, etc. items filtered by domain and optionally by type and list type.
189
	 *
190
	 * The reference parameter in searchItems() must have been set accordingly
191
	 * to the requested domain to get the items. Otherwise, no items will be
192
	 * returned by this method.
193
	 *
194
	 * @param array|string|null $domain Name/Names of the domain (e.g. product, text, etc.) or null for all
195
	 * @param array|string|null $type Name/Names of the item type or null for all
196
	 * @param array|string|null $listtype Name/Names of the list item type or null for all
197
	 * @param boolean $active True to return only active items, false to return all
198
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
199
	 */
200
	public function getRefItems( $domain = null, $type = null, $listtype = null, $active = true )
201
	{
202
		$list = [];
203
204
		foreach( $this->getListItems( $domain, $listtype, $type, $active ) as $listItem )
205
		{
206
			if( ( $refItem = $listItem->getRefItem() ) !== null && ( $active === false || $refItem->isAvailable() ) ) {
207
				$list[$listItem->getDomain()][$listItem->getRefId()] = $refItem;
208
			}
209
		}
210
211
		if( is_array( $domain ) || $domain === null ) {
212
			return $list;
213
		}
214
215
		if( isset( $list[$domain] ) ) {
216
			return $list[$domain];
217
		}
218
219
		return [];
220
	}
221
222
223
	/**
224
	 * Returns the label of the item.
225
	 * This method should be implemented in the derived class if a label column is available.
226
	 *
227
	 * @return string Label of the item
228
	 */
229
	public function getLabel()
230
	{
231
		return '';
232
	}
233
234
235
	/**
236
	 * Returns the localized text type of the item or the internal label if no name is available.
237
	 *
238
	 * @param string $type Text type to be returned
239
	 * @return string Specified text type or label of the item
240
	 */
241
	public function getName( $type = 'name' )
242
	{
243
		$items = $this->getRefItems( 'text', $type );
244
245
		if( ( $item = reset( $items ) ) !== false ) {
246
			return $item->getContent();
247
		}
248
249
		return $this->getLabel();
250
	}
251
252
253
	/**
254
	 * Compares the positions of two items for sorting.
255
	 *
256
	 * @param \Aimeos\MShop\Common\Item\Position\Iface $a First item
257
	 * @param \Aimeos\MShop\Common\Item\Position\Iface $b Second item
258
	 * @return integer -1 if position of $a < $b, 1 if position of $a > $b and 0 if both positions are equal
259
	 */
260
	protected function comparePosition( \Aimeos\MShop\Common\Item\Position\Iface $a, \Aimeos\MShop\Common\Item\Position\Iface $b )
261
	{
262
		if( $a->getPosition() === $b->getPosition() ) {
263
			return 0;
264
		}
265
266
		return ( $a->getPosition() < $b->getPosition() ) ? -1 : 1;
267
	}
268
269
270
	/**
271
	 * Sorts the list items according to their position value and attaches the referenced item
272
	 */
273
	protected function prepareListItems()
274
	{
275
		if( $this->prepared === true ) {
276
			return;
277
		}
278
279
		foreach( $this->listItems as $domain => $list )
280
		{
281
			foreach( $list as $listItem )
282
			{
283
				$refId = $listItem->getRefId();
284
285
				if( isset( $this->refItems[$domain][$refId] ) ) {
286
					$listItem->setRefItem( $this->refItems[$domain][$refId] );
287
				}
288
			}
289
290
			uasort( $this->listItems[$domain], array( $this, 'comparePosition' ) );
291
		}
292
293
		$this->prepared = true;
294
	}
295
}
296