Completed
Push — master ( 48d21c...8ed5cd )
by Aimeos
12:02
created

Base::getRefItems()   D

Complexity

Conditions 17
Paths 15

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 20
c 0
b 0
f 0
nc 15
nop 4
dl 0
loc 37
rs 4.9807

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 $sortedLists;
26
	private $sortedRefs;
27
28
29
	/**
30
	 * Initializes the item with the given values.
31
	 *
32
	 * @param string $prefix Prefix for the keys returned by toArray()
33
	 * @param array $values Associative list of key/value pairs of the item properties
34
	 * @param array $listItems Two dimensional associative list of domain / ID / list items that implement \Aimeos\MShop\Common\Item\Lists\Iface
35
	 * @param array $refItems Two dimensional associative list of domain / ID / domain items that implement \Aimeos\MShop\Common\Item\Iface
36
	 */
37
	public function __construct( $prefix, array $values = [], array $listItems = [], array $refItems = [] )
38
	{
39
		parent::__construct( $prefix, $values );
40
41
		$this->listItems = $listItems;
42
		$this->refItems = $refItems;
43
	}
44
45
46
	/**
47
	 * Returns the list items attached, optionally filtered by domain and list type.
48
	 *
49
	 * The reference parameter in searchItems() must have been set accordingly
50
	 * to the requested domain to get the items. Otherwise, no items will be
51
	 * returned by this method.
52
	 *
53
	 * @param array|string|null $domain Name/Names of the domain (e.g. product, text, etc.) or null for all
54
	 * @param array|string|null $listtype Name/Names of the list item type or null for all
55
	 * @param array|string|null $type Name/Names of the item type or null for all
56
	 * @param boolean $active True to return only active items, false to return all
57
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
58
	 */
59
	public function getListItems( $domain = null, $listtype = null, $type = null, $active = true )
60
	{
61
		$list = [];
62
		$this->sortListItems();
63
64
		if( is_array( $domain ) || $domain === null )
65
		{
66
			foreach( $this->listItems as $domain => $items ) {
67
				$list += $this->filterItems( $items, $active );
68
			}
69
70
			return $list;
71
		}
72
73
		if( !isset( $this->listItems[$domain] ) ) {
74
			return [];
75
		}
76
77
		$list = $this->listItems[$domain];
78
79
		if( $listtype !== null )
80
		{
81
			$iface = '\\Aimeos\\MShop\\Common\\Item\\Typeid\\Iface';
82
			$listTypes = ( is_array( $listtype ) ? $listtype : array( $listtype ) );
83
84
			foreach( $list as $id => $item )
85
			{
86
				if( !( $item instanceof $iface ) || !in_array( $item->getType(), $listTypes ) ) {
87
					unset( $list[$id] );
88
				}
89
			}
90
		}
91
92
		if( $type !== null )
93
		{
94
			$iface = '\\Aimeos\\MShop\\Common\\Item\\Typeid\\Iface';
95
			$types = ( is_array( $type ) ? $type : array( $type ) );
96
97
			foreach( $list as $id => $item )
98
			{
99
				if( !( $item->getRefItem() instanceof $iface ) || !in_array( $item->getRefItem()->getType(), $types ) ) {
100
					unset( $list[$id] );
101
				}
102
			}
103
		}
104
105
		return $this->filterItems( $list, $active );
106
	}
107
108
109
	/**
110
	 * Returns the product, text, etc. items filtered by domain and optionally by type and list type.
111
	 *
112
	 * The reference parameter in searchItems() must have been set accordingly
113
	 * to the requested domain to get the items. Otherwise, no items will be
114
	 * returned by this method.
115
	 *
116
	 * @param array|string|null $domain Name/Names of the domain (e.g. product, text, etc.) or null for all
117
	 * @param array|string|null $type Name/Names of the item type or null for all
118
	 * @param array|string|null $listtype Name/Names of the list item type or null for all
119
	 * @param boolean $active True to return only active items, false to return all
120
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
121
	 */
122
	public function getRefItems( $domain = null, $type = null, $listtype = null, $active = true )
123
	{
124
		$list = [];
125
		$this->sortRefItems();
126
127
		if( is_array( $domain ) || $domain === null )
128
		{
129
			foreach( $this->refItems as $domain => $items ) {
130
				$list[$domain] = $this->filterItems( $items, $active );
131
			}
132
133
			return $list;
134
		}
135
136
		if( !isset( $this->refItems[$domain] ) || !isset( $this->listItems[$domain] ) ) {
137
			return [];
138
		}
139
140
		$iface = '\\Aimeos\\MShop\\Common\\Item\\Lists\\Iface';
141
		$types = ( is_array( $type ) ? $type : array( $type ) );
142
		$listtypes = ( is_array( $listtype ) ? $listtype : array( $listtype ) );
143
144
		foreach( $this->listItems[$domain] as $listItem )
145
		{
146
			$refId = $listItem->getRefId();
147
148
			if( isset( $this->refItems[$domain][$refId] ) && $listItem instanceof $iface
149
				&& ( $type === null || in_array( $this->refItems[$domain][$refId]->getType(), $types ) )
150
				&& ( $listtype === null || in_array( $listItem->getType(), $listtypes ) )
151
				&& ( $active === false || $listItem->isAvailable() )
152
			) {
153
				$list[$refId] = $this->refItems[$domain][$refId];
154
			}
155
		}
156
157
		return $this->filterItems( $list, $active );
158
	}
159
160
161
	/**
162
	 * Returns the label of the item.
163
	 * This method should be implemented in the derived class if a label column is available.
164
	 *
165
	 * @return string Label of the item
166
	 */
167
	public function getLabel()
168
	{
169
		return '';
170
	}
171
172
173
	/**
174
	 * Returns the localized text type of the item or the internal label if no name is available.
175
	 *
176
	 * @param string $type Text type to be returned
177
	 * @return string Specified text type or label of the item
178
	 */
179
	public function getName( $type = 'name' )
180
	{
181
		$items = $this->getRefItems( 'text', $type );
182
183
		if( ( $item = reset( $items ) ) !== false ) {
184
			return $item->getContent();
185
		}
186
187
		return $this->getLabel();
188
	}
189
190
191
	/**
192
	 * Compares the positions of two items for sorting.
193
	 *
194
	 * @param \Aimeos\MShop\Common\Item\Position\Iface $a First item
195
	 * @param \Aimeos\MShop\Common\Item\Position\Iface $b Second item
196
	 * @return integer -1 if position of $a < $b, 1 if position of $a > $b and 0 if both positions are equal
197
	 */
198
	protected function comparePosition( \Aimeos\MShop\Common\Item\Position\Iface $a, \Aimeos\MShop\Common\Item\Position\Iface $b )
199
	{
200
		if( $a->getPosition() === $b->getPosition() ) {
201
			return 0;
202
		}
203
204
		return ( $a->getPosition() < $b->getPosition() ) ? -1 : 1;
205
	}
206
207
208
	/**
209
	 * Compares the positions of two referenced items for sorting.
210
	 *
211
	 * @param \Aimeos\MShop\Common\Item\Iface $a First referenced item
212
	 * @param \Aimeos\MShop\Common\Item\Iface $b Second referenced item
213
	 * @return integer -1 if position of $a < $b, 1 if position of $a > $b and 0 if both positions are equal
214
	 */
215
	protected function compareRefPosition( \Aimeos\MShop\Common\Item\Iface $a, \Aimeos\MShop\Common\Item\Iface $b )
216
	{
217
		if( $a->position === $b->position ) {
218
			return 0;
219
		}
220
221
		return ( $a->position < $b->position ) ? -1 : 1;
222
	}
223
224
225
	/**
226
	 * Returns only active items
227
	 *
228
	 * @param \Aimeos\MShop\Common\Item\Lists\Iface[] $list Associative list of items with ID as key and objects as value
229
	 * @param boolean $active True for active items only, false for all
230
	 * @return \Aimeos\MShop\Common\Item\Lists\Iface[] Filtered associative list of items with ID as key and objects as value
231
	 */
232
	protected function filterItems( array $list, $active )
233
	{
234
		if( (bool) $active === false ) {
235
			return $list;
236
		}
237
238
		$result = [];
239
240
		foreach( $list as $id => $item )
241
		{
242
			if( $item->isAvailable() ) {
243
				$result[$id] = $item;
244
			}
245
		}
246
247
		return $result;
248
	}
249
250
251
	/**
252
	 * Sorts the list items according to their position value and attaches the referenced item
253
	 */
254
	protected function sortListItems()
255
	{
256
		if( isset( $this->sortedLists ) ) {
257
			return;
258
		}
259
260
		foreach( $this->listItems as $domain => $list )
261
		{
262
			foreach( $list as $listItem )
263
			{
264
				$refId = $listItem->getRefId();
265
266
				if( isset( $this->refItems[$domain][$refId] ) ) {
267
					$listItem->setRefItem( $this->refItems[$domain][$refId] );
268
				}
269
			}
270
271
			uasort( $this->listItems[$domain], array( $this, 'comparePosition' ) );
272
		}
273
274
		$this->sortedLists = true;
275
	}
276
277
278
	/**
279
	 * Sorts the referenced items according to their position value
280
	 */
281
	protected function sortRefItems()
282
	{
283
		if( isset( $this->sortedRefs ) ) {
284
			return;
285
		}
286
287
		foreach( $this->listItems as $domain => $list )
288
		{
289
			foreach( $list as $listItem )
290
			{
291
				$refId = $listItem->getRefId();
292
293
				if( isset( $this->refItems[$domain][$refId] ) ) {
294
					$this->refItems[$domain][$refId]->position = $listItem->getPosition();
295
				}
296
			}
297
298
			uasort( $this->refItems[$domain], array( $this, 'compareRefPosition' ) );
299
		}
300
301
		$this->sortedRefs = true;
302
	}
303
}
304