Completed
Push — master ( 45554e...1a0e9a )
by Aimeos
02:10
created

Standard::searchItems()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017
6
 * @package Controller
7
 * @subpackage Frontend
8
 */
9
10
11
namespace Aimeos\Controller\Frontend\Index;
12
13
14
/**
15
 * Default implementation of the index frontend controller.
16
 *
17
 * @package Controller
18
 * @subpackage Frontend
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Frontend\Base
2 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements Iface, \Aimeos\Controller\Frontend\Common\Iface
1 ignored issue
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	/**
25
	 * Returns the given search filter with the conditions attached for filtering by attribute.
26
	 *
27
	 * @param \Aimeos\MW\Criteria\Iface $filter Criteria object used for product search
28
	 * @param array $attrIds List of attribute IDs for faceted search
29
	 * @param array $optIds List of OR-combined attribute IDs for faceted search
30
	 * @param array $attrIds Associative list of OR-combined attribute IDs per attribute type for faceted search
31
	 * @return \Aimeos\MW\Criteria\Iface Criteria object containing the conditions for searching
32
	 * @since 2017.03
33
	 */
34
	public function addFilterAttribute( \Aimeos\MW\Criteria\Iface $filter, array $attrIds, array $optIds, array $oneIds )
35
	{
36
		if( !empty( $attrIds ) )
37
		{
38
			$attrIds = $this->validateIds( $attrIds );
39
40
			$func = $filter->createFunction( 'index.attributeaggregate', array( $attrIds ) );
41
			$expr = array(
42
				$filter->compare( '==', $func, count( $attrIds ) ),
43
				$filter->getConditions(),
44
			);
45
			$filter->setConditions( $filter->combine( '&&', $expr ) );
46
		}
47
48
		if( !empty( $optIds ) )
49
		{
50
			$optIds = $this->validateIds( $optIds );
51
52
			$func = $filter->createFunction( 'index.attributeaggregate', array( $optIds ) );
53
			$expr = array(
54
				$filter->compare( '>', $func, 0 ),
55
				$filter->getConditions(),
56
			);
57
			$filter->setConditions( $filter->combine( '&&', $expr ) );
58
		}
59
60
		foreach( $oneIds as $type => $list )
61
		{
62
			if( ( $list = $this->validateIds( (array) $list ) ) !== array() )
63
			{
64
				$func = $filter->createFunction( 'index.attributeaggregate', array( $list ) );
65
				$expr = array(
66
					$filter->compare( '>', $func, 0 ),
67
					$filter->getConditions(),
68
				);
69
				$filter->setConditions( $filter->combine( '&&', $expr ) );
70
			}
71
		}
72
73
		return $filter;
74
	}
75
76
77
	/**
78
	 * Returns the given search filter with the conditions attached for filtering by category.
79
	 *
80
	 * @param \Aimeos\MW\Criteria\Iface $filter Criteria object used for product search
81
	 * @param string|array $catId Selected category by the user
82
	 * @param integer $level Constant for current category only, categories of next level (LEVEL_LIST) or whole subtree (LEVEL_SUBTREE)
83
	 * @param string|null $sort Sortation of the product list like "name", "code", "price" and "position", null for no sortation
84
	 * @param string $direction Sort direction of the product list ("+", "-")
85
	 * @param string $listtype List type of the product associated to the category, usually "default"
86
	 * @return \Aimeos\MW\Criteria\Iface Criteria object containing the conditions for searching
87
	 * @since 2017.03
88
	 */
89
	public function addFilterCategory( \Aimeos\MW\Criteria\Iface $filter, $catId,
90
		$level = \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE, $sort = null, $direction = '+', $listtype = 'default' )
91
	{
92
		$catIds = ( !is_array( $catId ) ? explode( ',', $catId ) : $catId );
93
94
		if( $level != \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE )
95
		{
96
			$list = array();
97
			$cntl = \Aimeos\Controller\Frontend\Factory::createController( $this->getContext(), 'catalog' );
98
99
			foreach( $catIds as $catId )
100
			{
101
				$tree = $cntl->getCatalogTree( $catId, array(), $level );
102
				$list = array_merge( $list, $this->getCatalogIdsFromTree( $tree ) );
103
			}
104
105
			$catIds = $list;
106
		}
107
108
		$expr = array( $filter->compare( '==', 'index.catalog.id', array_unique( $catIds ) ) );
109
		$expr[] = $filter->getConditions();
110
111
		if( $sort === 'relevance' )
112
		{
113
			$cmpfunc = $filter->createFunction( 'index.catalog.position', array( $listtype, $catIds ) );
114
			$expr[] = $filter->compare( '>=', $cmpfunc, 0 );
115
116
			$sortfunc = $filter->createFunction( 'sort:index.catalog.position', array( $listtype, $catIds ) );
117
			$filter->setSortations( array( $filter->sort( $direction, $sortfunc ) ) );
118
		}
119
120
		$filter->setConditions( $filter->combine( '&&', $expr ) );
121
122
		return $filter;
123
	}
124
125
126
	/**
127
	 * Returns the given search filter with the conditions attached for filtering by text.
128
	 *
129
	 * @param \Aimeos\MW\Criteria\Iface $filter Criteria object used for product search
130
	 * @param string $input Search string entered by the user
131
	 * @param string|null $sort Sortation of the product list like "name", "code", "price" and "position", null for no sortation
132
	 * @param string $direction Sort direction of the product list ("+", "-")
133
	 * @param string $listtype List type of the text associated to the product, usually "default"
134
	 * @return \Aimeos\MW\Criteria\Iface Criteria object containing the conditions for searching
135
	 * @since 2017.03
136
	 */
137
	public function addFilterText( \Aimeos\MW\Criteria\Iface $filter, $input, $sort = null, $direction = '+', $listtype = 'default' )
138
	{
139
		$langid = $this->getContext()->getLocale()->getLanguageId();
140
		$cmpfunc = $filter->createFunction( 'index.text.relevance', array( $listtype, $langid, $input ) );
141
		$expr = array( $filter->compare( '>', $cmpfunc, 0 ), $filter->getConditions() );
142
143
		return $filter->setConditions( $filter->combine( '&&', $expr ) );
144
	}
145
146
147
	/**
148
	 * Returns the aggregated count of products for the given key.
149
	 *
150
	 * @param \Aimeos\MW\Criteria\Iface $filter Critera object which contains the filter conditions
151
	 * @param string $key Search key to aggregate for, e.g. "index.attribute.id"
152
	 * @return array Associative list of key values as key and the product count for this key as value
153
	 * @since 2017.03
154
	 */
155
	public function aggregate( \Aimeos\MW\Criteria\Iface $filter, $key )
156
	{
157
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'index' )->aggregate( $filter, $key );
158
	}
159
160
161
	/**
162
	 * Returns the default index filter.
163
	 *
164
	 * @param string|null $sort Sortation of the product list like "name", "code", "price" and "position", null for no sortation
165
	 * @param string $direction Sort direction of the product list ("+", "-")
166
	 * @param integer $start Position in the list of found products where to begin retrieving the items
167
	 * @param integer $size Number of products that should be returned
168
	 * @param string $listtype Type of the product list, e.g. default, promotion, etc.
169
	 * @return \Aimeos\MW\Criteria\Iface Criteria object containing the conditions for searching
170
	 * @since 2017.03
171
	 */
172
	public function createFilter( $sort = null, $direction = '+', $start = 0, $size = 100, $listtype = 'default' )
173
	{
174
		$sortations = array();
175
		$context = $this->getContext();
176
177
		$search = \Aimeos\MShop\Factory::createManager( $context, 'index' )->createSearch( true );
178
		$expr = array( $search->compare( '!=', 'index.catalog.id', null ) );
179
180
		switch( $sort )
181
		{
182
			case 'code':
183
				$sortations[] = $search->sort( $direction, 'product.code' );
184
				break;
185
186
			case 'name':
187
				$langid = $context->getLocale()->getLanguageId();
188
189
				$cmpfunc = $search->createFunction( 'index.text.value', array( $listtype, $langid, 'name', 'product' ) );
190
				$expr[] = $search->compare( '>=', $cmpfunc, '' );
191
192
				$sortfunc = $search->createFunction( 'sort:index.text.value', array( $listtype, $langid, 'name' ) );
193
				$sortations[] = $search->sort( $direction, $sortfunc );
194
				break;
195
196
			case 'price':
197
				$currencyid = $context->getLocale()->getCurrencyId();
198
199
				$cmpfunc = $search->createFunction( 'index.price.value', array( $listtype, $currencyid, 'default' ) );
200
				$expr[] = $search->compare( '>=', $cmpfunc, '0.00' );
201
202
				$sortfunc = $search->createFunction( 'sort:index.price.value', array( $listtype, $currencyid, 'default' ) );
203
				$sortations[] = $search->sort( $direction, $sortfunc );
204
				break;
205
		}
206
207
		$expr[] = $search->getConditions();
208
209
		$search->setConditions( $search->combine( '&&', $expr ) );
210
		$search->setSortations( $sortations );
211
		$search->setSlice( $start, $size );
212
213
		return $search;
214
	}
215
216
217
	/**
218
	 * Returns the product for the given product ID from the index
219
	 *
220
	 * @param string $productId Unique product ID
221
	 * @param string[] $domains Domain names of items that are associated with the products and that should be fetched too
222
	 * @return \Aimeos\MShop\Product\Item\Iface Product item including the referenced domains items
223
	 * @since 2017.03
224
	 */
225
	public function getItem( $productId, array $domains = array( 'attribute', 'media', 'price', 'product', 'product/property', 'text' ) )
226
	{
227
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'product' )->getItem( $productId, $domains );
228
	}
229
230
231
	/**
232
	 * Returns the products from the index filtered by the given criteria object.
233
	 *
234
	 * @param \Aimeos\MW\Criteria\Iface $filter Critera object which contains the filter conditions
235
	 * @param string[] $domains Domain names of items that are associated with the products and that should be fetched too
236
	 * @param integer &$total Parameter where the total number of found products will be stored in
237
	 * @return array Ordered list of product items implementing \Aimeos\MShop\Product\Item\Iface
238
	 * @since 2017.03
239
	 */
240
	public function searchItems( \Aimeos\MW\Criteria\Iface $filter, array $domains = array( 'media', 'price', 'text' ), &$total = null )
241
	{
242
		return \Aimeos\MShop\Factory::createManager( $this->getContext(), 'index' )->searchItems( $filter, $domains, $total );
243
	}
244
245
246
	/**
247
	 * Returns the list of catalog IDs for the given catalog tree
248
	 *
249
	 * @param \Aimeos\MShop\Catalog\Item\Iface $item Catalog item with children
250
	 * @return array List of catalog IDs
251
	 */
252
	protected function getCatalogIdsFromTree( \Aimeos\MShop\Catalog\Item\Iface $item )
253
	{
254
		$list = array( $item->getId() );
255
256
		foreach( $item->getChildren() as $child ) {
257
			$list = array_merge( $list, $this->getCatalogIdsFromTree( $child ) );
258
		}
259
260
		return $list;
261
	}
262
263
264
	/**
265
	 * Validates the given IDs as integers
266
	 *
267
	 * @param array $ids List of IDs to validate
268
	 * @return array List of validated IDs
269
	 */
270
	protected function validateIds( array $ids )
271
	{
272
		$list = array();
273
274
		foreach( $ids as $id )
275
		{
276
			if( $id != '' ) {
277
				$list[] = (int) $id;
278
			}
279
		}
280
281
		return $ids;
282
	}
283
}
284