Passed
Push — master ( 1ec6c2...4d2b3a )
by Aimeos
04:13
created

Standard::iterate()   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
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 * @package MShop
8
 * @subpackage Index
9
 */
10
11
12
namespace Aimeos\MShop\Index\Manager;
13
14
15
/**
16
 * Index index manager for searching in product tables.
17
 *
18
 * @package MShop
19
 * @subpackage Index
20
 */
21
class Standard
22
	extends \Aimeos\MShop\Index\Manager\DBBase
23
	implements \Aimeos\MShop\Index\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	/** mshop/index/manager/name
26
	 * Class name of the used index manager implementation
27
	 *
28
	 * Each default manager can be replace by an alternative imlementation.
29
	 * To use this implementation, you have to set the last part of the class
30
	 * name as configuration value so the manager factory knows which class it
31
	 * has to instantiate.
32
	 *
33
	 * For example, if the name of the default class is
34
	 *
35
	 *  \Aimeos\MShop\Index\Manager\Standard
36
	 *
37
	 * and you want to replace it with your own version named
38
	 *
39
	 *  \Aimeos\MShop\Index\Manager\Mymanager
40
	 *
41
	 * then you have to set the this configuration option:
42
	 *
43
	 *  mshop/index/manager/name = Mymanager
44
	 *
45
	 * The value is the last part of your own class name and it's case sensitive,
46
	 * so take care that the configuration value is exactly named like the last
47
	 * part of the class name.
48
	 *
49
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
50
	 * characters are possible! You should always start the last part of the class
51
	 * name with an upper case character and continue only with lower case characters
52
	 * or numbers. Avoid chamel case names like "MyManager"!
53
	 *
54
	 * @param string Last part of the class name
55
	 * @since 2015.11
56
	 * @category Developer
57
	 */
58
59
	/** mshop/index/manager/decorators/excludes
60
	 * Excludes decorators added by the "common" option from the index manager
61
	 *
62
	 * Decorators extend the functionality of a class by adding new aspects
63
	 * (e.g. log what is currently done), executing the methods of the underlying
64
	 * class only in certain conditions (e.g. only for logged in users) or
65
	 * modify what is returned to the caller.
66
	 *
67
	 * This option allows you to remove a decorator added via
68
	 * "mshop/common/manager/decorators/default" before they are wrapped
69
	 * around the index manager.
70
	 *
71
	 *  mshop/index/manager/decorators/excludes = array( 'decorator1' )
72
	 *
73
	 * This would remove the decorator named "decorator1" from the list of
74
	 * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
75
	 * "mshop/common/manager/decorators/default" for the index manager.
76
	 *
77
	 * @param array List of decorator names
78
	 * @since 2015.11
79
	 * @category Developer
80
	 * @see mshop/common/manager/decorators/default
81
	 * @see mshop/index/manager/decorators/global
82
	 * @see mshop/index/manager/decorators/local
83
	 */
84
85
	/** mshop/index/manager/decorators/global
86
	 * Adds a list of globally available decorators only to the index manager
87
	 *
88
	 * Decorators extend the functionality of a class by adding new aspects
89
	 * (e.g. log what is currently done), executing the methods of the underlying
90
	 * class only in certain conditions (e.g. only for logged in users) or
91
	 * modify what is returned to the caller.
92
	 *
93
	 * This option allows you to wrap global decorators
94
	 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the index manager.
95
	 *
96
	 *  mshop/index/manager/decorators/global = array( 'decorator1' )
97
	 *
98
	 * This would add the decorator named "decorator1" defined by
99
	 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the index manager.
100
	 *
101
	 * @param array List of decorator names
102
	 * @since 2015.11
103
	 * @category Developer
104
	 * @see mshop/common/manager/decorators/default
105
	 * @see mshop/index/manager/decorators/excludes
106
	 * @see mshop/index/manager/decorators/local
107
	 */
108
109
	/** mshop/index/manager/decorators/local
110
	 * Adds a list of local decorators only to the index manager
111
	 *
112
	 * Decorators extend the functionality of a class by adding new aspects
113
	 * (e.g. log what is currently done), executing the methods of the underlying
114
	 * class only in certain conditions (e.g. only for logged in users) or
115
	 * modify what is returned to the caller.
116
	 *
117
	 * This option allows you to wrap local decorators
118
	 * ("\Aimeos\MShop\Index\Manager\Decorator\*") around the index manager.
119
	 *
120
	 *  mshop/index/manager/decorators/local = array( 'decorator2' )
121
	 *
122
	 * This would add the decorator named "decorator2" defined by
123
	 * "\Aimeos\MShop\Index\Manager\Decorator\Decorator2" only to the index
124
	 * manager.
125
	 *
126
	 * @param array List of decorator names
127
	 * @since 2015.11
128
	 * @category Developer
129
	 * @see mshop/common/manager/decorators/default
130
	 * @see mshop/index/manager/decorators/excludes
131
	 * @see mshop/index/manager/decorators/global
132
	 */
133
134
135
	private $subManagers;
136
137
138
	/**
139
	 * Counts the number products that are available for the values of the given key.
140
	 *
141
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria
142
	 * @param string $key Search key (usually the ID) to aggregate products for
143
	 * @param string|null $value Search key for aggregating the value column
144
	 * @param string|null $type Type of the aggregation, empty string for count or "sum" or "avg" (average)
145
	 * @return \Aimeos\Map List of ID values as key and the number of counted products as value
146
	 */
147
	public function aggregate( \Aimeos\Base\Criteria\Iface $search, $key, string $value = null, string $type = null ) : \Aimeos\Map
148
	{
149
		/** mshop/index/manager/aggregate/mysql
150
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
151
		 *
152
		 * @see mshop/index/manager/aggregate/ansi
153
		 */
154
155
		/** mshop/index/manager/aggregate/ansi
156
		 * Counts the number of records grouped by the values in the key column and matched by the given criteria
157
		 *
158
		 * Groups all records by the values in the key column and counts their
159
		 * occurence. The matched records can be limited by the given criteria
160
		 * from the order database. The records must be from one of the sites
161
		 * that are configured via the context item. If the current site is part
162
		 * of a tree of sites, the statement can count all records from the
163
		 * current site and the complete sub-tree of sites.
164
		 *
165
		 * As the records can normally be limited by criteria from sub-managers,
166
		 * their tables must be joined in the SQL context. This is done by
167
		 * using the "internaldeps" property from the definition of the ID
168
		 * column of the sub-managers. These internal dependencies specify
169
		 * the JOIN between the tables and the used columns for joining. The
170
		 * ":joins" placeholder is then replaced by the JOIN strings from
171
		 * the sub-managers.
172
		 *
173
		 * To limit the records matched, conditions can be added to the given
174
		 * criteria object. It can contain comparisons like column names that
175
		 * must match specific values which can be combined by AND, OR or NOT
176
		 * operators. The resulting string of SQL conditions replaces the
177
		 * ":cond" placeholder before the statement is sent to the database
178
		 * server.
179
		 *
180
		 * This statement doesn't return any records. Instead, it returns pairs
181
		 * of the different values found in the key column together with the
182
		 * number of records that have been found for that key values.
183
		 *
184
		 * The SQL statement should conform to the ANSI standard to be
185
		 * compatible with most relational database systems. This also
186
		 * includes using double quotes for table and column names.
187
		 *
188
		 * @param string SQL statement for aggregating order items
189
		 * @since 2014.09
190
		 * @category Developer
191
		 * @see mshop/index/manager/count/ansi
192
		 * @see mshop/index/manager/iterate/ansi
193
		 * @see mshop/index/manager/optimize/ansi
194
		 * @see mshop/index/manager/search/ansi
195
		 */
196
		return $this->aggregateBase( $search, $key, 'mshop/index/manager/aggregate', ['product'], $value, $type );
197
	}
198
199
200
	/**
201
	 * Returns the available manager types
202
	 *
203
	 * @param bool $withsub Return also the resource type of sub-managers if true
204
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
205
	 */
206
	public function getResourceType( bool $withsub = true ) : array
207
	{
208
		return $this->getResourceTypeBase( 'index', 'mshop/index/manager/submanagers', [], $withsub );
209
	}
210
211
212
	/**
213
	 * Returns a list of objects describing the available criterias for searching.
214
	 *
215
	 * @param bool $withsub Return also attributes of sub-managers if true
216
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
217
	 */
218
	public function getSearchAttributes( bool $withsub = true ) : array
219
	{
220
		$list = parent::getSearchAttributes( $withsub );
221
222
		/** mshop/index/manager/submanagers
223
		 * Replaced by mshop/index/manager/submanagers since 2016.01
224
		 *
225
		 * @see mshop/index/manager/submanagers
226
		 */
227
		$path = 'mshop/index/manager/submanagers';
228
229
		return $list + $this->getSearchAttributesBase( [], $path, [], $withsub );
230
	}
231
232
233
	/**
234
	 * Returns a new manager for product extensions.
235
	 *
236
	 * @param string $manager Name of the sub manager type in lower case
237
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
238
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
239
	 */
240
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
241
	{
242
		return $this->getSubManagerBase( 'index', $manager, $name );
243
	}
244
245
246
	/**
247
	 * Optimizes the index if necessary.
248
	 * Execution of this operation can take a very long time and shouldn't be
249
	 * called through a web server enviroment.
250
	 *
251
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
252
	 */
253
	public function optimize() : \Aimeos\MShop\Index\Manager\Iface
254
	{
255
		/** mshop/index/manager/optimize/mysql
256
		 * Optimizes the stored product data for retrieving the records faster
257
		 *
258
		 * @see mshop/index/manager/optimize/ansi
259
		 */
260
261
		/** mshop/index/manager/optimize/ansi
262
		 * Optimizes the stored product data for retrieving the records faster
263
		 *
264
		 * The SQL statement should reorganize the data in the DBMS storage to
265
		 * optimize access to the records of the table or tables. Some DBMS
266
		 * offer specialized statements to optimize indexes and records. This
267
		 * statement doesn't return any records.
268
		 *
269
		 * The SQL statement should conform to the ANSI standard to be
270
		 * compatible with most relational database systems. This also
271
		 * includes using double quotes for table and column names.
272
		 *
273
		 * @param string SQL statement for optimizing the stored product data
274
		 * @since 2014.09
275
		 * @category Developer
276
		 * @see mshop/index/manager/count/ansi
277
		 * @see mshop/index/manager/search/ansi
278
		 * @see mshop/index/manager/iterate/ansi
279
		 * @see mshop/index/manager/aggregate/ansi
280
		 */
281
		return $this->optimizeBase( 'mshop/index/manager/optimize' );
282
	}
283
284
285
	/**
286
	 * Removes old entries from the storage.
287
	 *
288
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
289
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
290
	 */
291
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
292
	{
293
		foreach( $this->getSubManagers() as $submanager ) {
294
			$submanager->clear( $siteids );
295
		}
296
297
		return $this;
298
	}
299
300
301
	/**
302
	 * Removes all entries not touched after the given timestamp in the index.
303
	 * This can be a long lasting operation.
304
	 *
305
	 * @param string $timestamp Timestamp in ISO format (YYYY-MM-DD HH:mm:ss)
306
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
307
	 */
308
	public function cleanup( string $timestamp ) : \Aimeos\MShop\Index\Manager\Iface
309
	{
310
		foreach( $this->getSubManagers() as $submanager ) {
311
			$submanager->cleanup( $timestamp );
312
		}
313
314
		return $this;
315
	}
316
317
318
	/**
319
	 * Removes multiple items.
320
	 *
321
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
322
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
323
	 */
324
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
325
	{
326
		$this->getManager()->delete( $itemIds );
327
		parent::delete( $itemIds );
328
329
		$this->context()->cache()->deleteByTags( map( $itemIds ) ->prefix( 'product-' )->toArray() );
330
		return $this;
331
	}
332
333
334
	/**
335
	 * Creates a new iterator based on the filter criteria
336
	 *
337
	 * @param \Aimeos\Base\Criteria\Iface $filter Criteria object with conditions, sortations, etc.
338
	 * @return \Aimeos\MShop\Common\Iterator\Iface Iterator object
339
	 */
340
	public function iterator( \Aimeos\Base\Criteria\Iface $filter ) : \Aimeos\MShop\Common\Iterator\Iface
341
	{
342
		/** mshop/index/manager/iterate/ansi
343
		 * Retrieves the records matched by the given criteria in the database
344
		 *
345
		 * Fetches the records matched by the given criteria from the order
346
		 * database. The records must be from one of the sites that are
347
		 * configured via the context item. If the current site is part of
348
		 * a tree of sites, the SELECT statement can retrieve all records
349
		 * from the current site and the complete sub-tree of sites.
350
		 *
351
		 * As the records can normally be limited by criteria from sub-managers,
352
		 * their tables must be joined in the SQL context. This is done by
353
		 * using the "internaldeps" property from the definition of the ID
354
		 * column of the sub-managers. These internal dependencies specify
355
		 * the JOIN between the tables and the used columns for joining. The
356
		 * ":joins" placeholder is then replaced by the JOIN strings from
357
		 * the sub-managers.
358
		 *
359
		 * To limit the records matched, conditions can be added to the given
360
		 * criteria object. It can contain comparisons like column names that
361
		 * must match specific values which can be combined by AND, OR or NOT
362
		 * operators. The resulting string of SQL conditions replaces the
363
		 * ":cond" placeholder before the statement is sent to the database
364
		 * server.
365
		 *
366
		 * If the records that are retrieved should be ordered by one or more
367
		 * columns, the generated string of column / sort direction pairs
368
		 * replaces the ":order" placeholder. In case no ordering is required,
369
		 * the complete ORDER BY part including the ":order"
370
		 * markers is removed to speed up retrieving the records. Columns of
371
		 * sub-managers can also be used for ordering the result set but then
372
		 * no index can be used.
373
		 *
374
		 * The SQL statement should conform to the ANSI standard to be
375
		 * compatible with most relational database systems. This also
376
		 * includes using double quotes for table and column names.
377
		 *
378
		 * @param string SQL statement for iterate over items
379
		 * @since 2022.10
380
		 * @category Developer
381
		 * @see mshop/index/manager/count/ansi
382
		 * @see mshop/index/manager/search/ansi
383
		 * @see mshop/index/manager/optimize/ansi
384
		 * @see mshop/index/manager/aggregate/ansi
385
		 */
386
387
		return $this->iteratorIndexBase( $filter, 'mshop/index/manager/iterate' );
388
	}
389
390
391
	/**
392
	 * Iterates over all matching items and returns the found ones
393
	 *
394
	 * @param \Aimeos\MShop\Common\Iterator\Iface $iterator Iterator object with conditions, sortations, etc.
395
	 * @param string[] $ref List of domains to fetch list items and referenced items for
396
	 * @param int $count Maximum number of items which should be returned
397
	 * @return \Aimeos\Map|null List of items implementing \Aimeos\MShop\Common\Item\Iface with ids as keys
398
	 */
399
	public function iterate( \Aimeos\MShop\Common\Iterator\Iface $iterator, array $ref = [], int $count = 100 ) : ?\Aimeos\Map
400
	{
401
		return $this->iterateIndexBase( $iterator, $ref, $count );
402
	}
403
404
405
	/**
406
	 * Rebuilds the index for searching products or specified list of products.
407
	 * This can be a long lasting operation.
408
	 *
409
	 * @param \Aimeos\MShop\Product\Item\Iface[] $items Associative list of product IDs as keys and items as values
410
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
411
	 */
412
	public function rebuild( iterable $items = [] ) : \Aimeos\MShop\Index\Manager\Iface
413
	{
414
		$context = $this->context();
415
		$config = $context->config();
416
417
		/** mshop/index/manager/chunksize
418
		 * Number of products that should be indexed at once
419
		 *
420
		 * When rebuilding the product index, several products are updated at
421
		 * once within a transaction. This speeds up the time that is needed
422
		 * for reindexing.
423
		 *
424
		 * Usually, the more products are updated in one bunch, the faster the
425
		 * process of rebuilding the index will be up to a certain limit. The
426
		 * downside of big bunches is a higher memory consumption that can
427
		 * exceed the maximum allowed memory of the process.
428
		 *
429
		 * @param int Number of products
430
		 * @since 2014.09
431
		 * @category User
432
		 * @category Developer
433
		 * @see mshop/index/manager/domains
434
		 * @see mshop/index/manager/index
435
		 * @see mshop/index/manager/subdomains
436
		 * @see mshop/index/manager/submanagers
437
		 */
438
		$size = $config->get( 'mshop/index/manager/chunksize', 100 );
439
440
		/** mshop/index/manager/domains
441
		 * A list of domain names whose items should be retrieved together with the product
442
		 *
443
		 * To speed up the indexing process, items like texts, prices, media,
444
		 * attributes etc. which have been associated to products can be
445
		 * retrieved together with the products.
446
		 *
447
		 * Please note that the index submanagers expect that the items
448
		 * associated to the products are fetched together with the products.
449
		 * Thus, if you leave out a domain, this information won't be part
450
		 * of the indexed product and therefore won't be found when searching
451
		 * the index.
452
		 *
453
		 * @param string List of MShop domain names
454
		 * @since 2014.09
455
		 * @category Developer
456
		 * @see mshop/index/manager/chunksize
457
		 * @see mshop/index/manager/index
458
		 * @see mshop/index/manager/subdomains
459
		 * @see mshop/index/manager/submanagers
460
		 */
461
		$domains = $config->get( 'mshop/index/manager/domains', [] );
462
463
		$submanagers = $this->getSubManagers();
0 ignored issues
show
Unused Code introduced by
The assignment to $submanagers is dead and can be removed.
Loading history...
464
		$items = map( $items );
465
466
		if( !$items->isEmpty() )
467
		{
468
			$context->cache()->deleteByTags( $this->index( $items )->getId()->prefix( 'product-' ) );
469
			return $this;
470
		}
471
472
473
		$manager = \Aimeos\MShop::create( $context, 'product' );
474
		$iterator = $manager->iterator( $manager->filter() );
475
476
		while( $items = $manager->iterate( $iterator, $domains, $size ) ) {
477
			$this->index( $items );
478
		}
479
480
		$context->cache()->deleteByTags( ['product'] );
481
		return $this;
482
	}
483
484
485
	/**
486
	 * Searches for items matching the given criteria.
487
	 *
488
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria object
489
	 * @param string[] $ref List of domains to fetch list items and referenced items for
490
	 * @param int|null &$total Number of items that are available in total
491
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Product\Item\Iface with ids as keys
492
	 */
493
	public function search( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map
494
	{
495
		/** mshop/index/manager/search/mysql
496
		 * Retrieves the records matched by the given criteria in the database
497
		 *
498
		 * @see mshop/index/manager/search/ansi
499
		 */
500
501
		/** mshop/index/manager/search/ansi
502
		 * Retrieves the records matched by the given criteria in the database
503
		 *
504
		 * Fetches the records matched by the given criteria from the order
505
		 * database. The records must be from one of the sites that are
506
		 * configured via the context item. If the current site is part of
507
		 * a tree of sites, the SELECT statement can retrieve all records
508
		 * from the current site and the complete sub-tree of sites.
509
		 *
510
		 * As the records can normally be limited by criteria from sub-managers,
511
		 * their tables must be joined in the SQL context. This is done by
512
		 * using the "internaldeps" property from the definition of the ID
513
		 * column of the sub-managers. These internal dependencies specify
514
		 * the JOIN between the tables and the used columns for joining. The
515
		 * ":joins" placeholder is then replaced by the JOIN strings from
516
		 * the sub-managers.
517
		 *
518
		 * To limit the records matched, conditions can be added to the given
519
		 * criteria object. It can contain comparisons like column names that
520
		 * must match specific values which can be combined by AND, OR or NOT
521
		 * operators. The resulting string of SQL conditions replaces the
522
		 * ":cond" placeholder before the statement is sent to the database
523
		 * server.
524
		 *
525
		 * If the records that are retrieved should be ordered by one or more
526
		 * columns, the generated string of column / sort direction pairs
527
		 * replaces the ":order" placeholder. In case no ordering is required,
528
		 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
529
		 * markers is removed to speed up retrieving the records. Columns of
530
		 * sub-managers can also be used for ordering the result set but then
531
		 * no index can be used.
532
		 *
533
		 * The number of returned records can be limited and can start at any
534
		 * number between the begining and the end of the result set. For that
535
		 * the ":size" and ":start" placeholders are replaced by the
536
		 * corresponding values from the criteria object. The default values
537
		 * are 0 for the start and 100 for the size value.
538
		 *
539
		 * The SQL statement should conform to the ANSI standard to be
540
		 * compatible with most relational database systems. This also
541
		 * includes using double quotes for table and column names.
542
		 *
543
		 * @param string SQL statement for searching items
544
		 * @since 2014.03
545
		 * @category Developer
546
		 * @see mshop/index/manager/count/ansi
547
		 * @see mshop/index/manager/iterate/ansi
548
		 * @see mshop/index/manager/optimize/ansi
549
		 * @see mshop/index/manager/aggregate/ansi
550
		 */
551
		$cfgPathSearch = 'mshop/index/manager/search';
552
553
		/** mshop/index/manager/count/mysql
554
		 * Counts the number of records matched by the given criteria in the database
555
		 *
556
		 * @see mshop/index/manager/count/ansi
557
		 */
558
559
		/** mshop/index/manager/count/ansi
560
		 * Counts the number of records matched by the given criteria in the database
561
		 *
562
		 * Counts all records matched by the given criteria from the order
563
		 * database. The records must be from one of the sites that are
564
		 * configured via the context item. If the current site is part of
565
		 * a tree of sites, the statement can count all records from the
566
		 * current site and the complete sub-tree of sites.
567
		 *
568
		 * As the records can normally be limited by criteria from sub-managers,
569
		 * their tables must be joined in the SQL context. This is done by
570
		 * using the "internaldeps" property from the definition of the ID
571
		 * column of the sub-managers. These internal dependencies specify
572
		 * the JOIN between the tables and the used columns for joining. The
573
		 * ":joins" placeholder is then replaced by the JOIN strings from
574
		 * the sub-managers.
575
		 *
576
		 * To limit the records matched, conditions can be added to the given
577
		 * criteria object. It can contain comparisons like column names that
578
		 * must match specific values which can be combined by AND, OR or NOT
579
		 * operators. The resulting string of SQL conditions replaces the
580
		 * ":cond" placeholder before the statement is sent to the database
581
		 * server.
582
		 *
583
		 * Both, the strings for ":joins" and for ":cond" are the same as for
584
		 * the "search" SQL statement.
585
		 *
586
		 * Contrary to the "search" statement, it doesn't return any records
587
		 * but instead the number of records that have been found. As counting
588
		 * thousands of records can be a long running task, the maximum number
589
		 * of counted records is limited for performance reasons.
590
		 *
591
		 * The SQL statement should conform to the ANSI standard to be
592
		 * compatible with most relational database systems. This also
593
		 * includes using double quotes for table and column names.
594
		 *
595
		 * @param string SQL statement for counting items
596
		 * @since 2014.03
597
		 * @category Developer
598
		 * @see mshop/index/manager/search/ansi
599
		 * @see mshop/index/manager/iterate/ansi
600
		 * @see mshop/index/manager/optimize/ansi
601
		 * @see mshop/index/manager/aggregate/ansi
602
		 */
603
		$cfgPathCount = 'mshop/index/manager/count';
604
605
		return $this->searchItemsIndexBase( $search, $ref, $total, $cfgPathSearch, $cfgPathCount );
606
	}
607
608
609
	/**
610
	 * Indexes all given product items
611
	 *
612
	 * @param \Aimeos\Map $items Product items with associated attributes, categories, media, prices, products, texts, etc.
613
	 * @return \Aimeos\Map Indexed product items
614
	 */
615
	protected function index( \Aimeos\Map $items ) : \Aimeos\Map
616
	{
617
		try
618
		{
619
			$this->begin();
620
621
			$this->remove( $items );
0 ignored issues
show
Bug introduced by
$items of type Aimeos\Map is incompatible with the type array|string expected by parameter $ids of Aimeos\MShop\Index\Manager\DBBase::remove(). ( Ignorable by Annotation )

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

621
			$this->remove( /** @scrutinizer ignore-type */ $items );
Loading history...
622
623
			foreach( $this->getSubManagers() as $submanager ) {
624
				$submanager->rebuild( $items );
625
			}
626
627
			$this->commit();
628
		}
629
		catch( \Exception $e )
630
		{
631
			$this->rollback();
632
			throw $e;
633
		}
634
635
		return $items;
636
	}
637
638
639
	/**
640
	 * Re-writes the index entries for all products that are search result of given criteria
641
	 *
642
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria
643
	 * @param string[] $domains List of domains to be
644
	 * @param int $size Size of a chunk of products to handle at a time
645
	 * @deprecated 2023.01 Use index() instead
646
	 */
647
	protected function writeIndex( \Aimeos\Base\Criteria\Iface $search, array $domains, int $size )
648
	{
649
		$context = $this->context();
650
		$manager = \Aimeos\MShop::create( $context, 'product' );
651
		$submanagers = $this->getSubManagers();
652
		$start = 0;
653
654
		do
655
		{
656
			$search->slice( $start, $size );
657
			$products = $manager->search( $search, $domains );
658
659
			try
660
			{
661
				$this->begin();
662
663
				$this->remove( $products );
0 ignored issues
show
Bug introduced by
$products of type Aimeos\Map is incompatible with the type array|string expected by parameter $ids of Aimeos\MShop\Index\Manager\DBBase::remove(). ( Ignorable by Annotation )

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

663
				$this->remove( /** @scrutinizer ignore-type */ $products );
Loading history...
664
665
				foreach( $submanagers as $submanager ) {
666
					$submanager->rebuild( $products );
667
				}
668
669
				$this->commit();
670
			}
671
			catch( \Exception $e )
672
			{
673
				$this->rollback();
674
				throw $e;
675
			}
676
677
			$context->cache()->deleteByTags( $products->keys()->prefix( 'product-' )->all() );
678
679
			$count = count( $products );
680
			$start += $count;
681
		}
682
		while( $count == $search->getLimit() );
683
	}
684
685
686
	/**
687
	 * Returns the list of sub-managers available for the index attribute manager.
688
	 *
689
	 * @return \Aimeos\MShop\Index\Manager\Iface[] Associative list of the sub-domain as key and the manager object as value
690
	 */
691
	protected function getSubManagers() : array
692
	{
693
		if( $this->subManagers === null )
694
		{
695
			$this->subManagers = [];
696
			$config = $this->context()->config();
697
698
			/** mshop/index/manager/submanagers
699
			 * A list of sub-manager names used for indexing associated items
700
			 *
701
			 * All items referenced by a product (e.g. texts, prices, media,
702
			 * etc.) are added to the product index via specialized index
703
			 * managers. You can add the name of new sub-managers to add more
704
			 * data to the index or remove existing ones if you don't want to
705
			 * index that data at all.
706
			 *
707
			 * Caution: Please note that the list of sub-manager names should
708
			 * correspond to the list of domains that are fetched together with
709
			 * the products as the sub-manager depends on the items being
710
			 * retrieved there and fetching items that won't be indexed is a
711
			 * waste of resources.
712
			 *
713
			 * @param string List of index sub-manager names
714
			 * @since 2016.02
715
			 * @category User
716
			 * @category Developer
717
			 * @see mshop/index/manager/chunksize
718
			 * @see mshop/index/manager/domains
719
			 * @see mshop/index/manager/index
720
			 * @see mshop/index/manager/subdomains
721
			 */
722
			foreach( $config->get( 'mshop/index/manager/submanagers', [] ) as $domain )
723
			{
724
				$name = $config->get( 'mshop/index/manager/' . $domain . '/name' );
725
				$this->subManagers[$domain] = $this->object()->getSubManager( $domain, $name );
726
			}
727
728
			return $this->subManagers;
729
		}
730
731
		return $this->subManagers;
732
	}
733
}
734