Passed
Push — master ( 494e53...aeeda4 )
by Aimeos
09:49
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/optimize/ansi
193
		 * @see mshop/index/manager/search/ansi
194
		 */
195
		return $this->aggregateBase( $search, $key, 'mshop/index/manager/aggregate', ['product'], $value, $type );
196
	}
197
198
199
	/**
200
	 * Returns the available manager types
201
	 *
202
	 * @param bool $withsub Return also the resource type of sub-managers if true
203
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
204
	 */
205
	public function getResourceType( bool $withsub = true ) : array
206
	{
207
		return $this->getResourceTypeBase( 'index', 'mshop/index/manager/submanagers', [], $withsub );
208
	}
209
210
211
	/**
212
	 * Returns a list of objects describing the available criterias for searching.
213
	 *
214
	 * @param bool $withsub Return also attributes of sub-managers if true
215
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
216
	 */
217
	public function getSearchAttributes( bool $withsub = true ) : array
218
	{
219
		$list = parent::getSearchAttributes( $withsub );
220
221
		/** mshop/index/manager/submanagers
222
		 * Replaced by mshop/index/manager/submanagers since 2016.01
223
		 *
224
		 * @see mshop/index/manager/submanagers
225
		 */
226
		$path = 'mshop/index/manager/submanagers';
227
228
		return $list + $this->getSearchAttributesBase( [], $path, [], $withsub );
229
	}
230
231
232
	/**
233
	 * Returns a new manager for product extensions.
234
	 *
235
	 * @param string $manager Name of the sub manager type in lower case
236
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
237
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
238
	 */
239
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
240
	{
241
		return $this->getSubManagerBase( 'index', $manager, $name );
242
	}
243
244
245
	/**
246
	 * Optimizes the index if necessary.
247
	 * Execution of this operation can take a very long time and shouldn't be
248
	 * called through a web server enviroment.
249
	 *
250
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
251
	 */
252
	public function optimize() : \Aimeos\MShop\Index\Manager\Iface
253
	{
254
		/** mshop/index/manager/optimize/mysql
255
		 * Optimizes the stored product data for retrieving the records faster
256
		 *
257
		 * @see mshop/index/manager/optimize/ansi
258
		 */
259
260
		/** mshop/index/manager/optimize/ansi
261
		 * Optimizes the stored product data for retrieving the records faster
262
		 *
263
		 * The SQL statement should reorganize the data in the DBMS storage to
264
		 * optimize access to the records of the table or tables. Some DBMS
265
		 * offer specialized statements to optimize indexes and records. This
266
		 * statement doesn't return any records.
267
		 *
268
		 * The SQL statement should conform to the ANSI standard to be
269
		 * compatible with most relational database systems. This also
270
		 * includes using double quotes for table and column names.
271
		 *
272
		 * @param string SQL statement for optimizing the stored product data
273
		 * @since 2014.09
274
		 * @category Developer
275
		 * @see mshop/index/manager/count/ansi
276
		 * @see mshop/index/manager/search/ansi
277
		 * @see mshop/index/manager/aggregate/ansi
278
		 */
279
		return $this->optimizeBase( 'mshop/index/manager/optimize' );
280
	}
281
282
283
	/**
284
	 * Removes old entries from the storage.
285
	 *
286
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
287
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
288
	 */
289
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
290
	{
291
		foreach( $this->getSubManagers() as $submanager ) {
292
			$submanager->clear( $siteids );
293
		}
294
295
		return $this;
296
	}
297
298
299
	/**
300
	 * Removes all entries not touched after the given timestamp in the index.
301
	 * This can be a long lasting operation.
302
	 *
303
	 * @param string $timestamp Timestamp in ISO format (YYYY-MM-DD HH:mm:ss)
304
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
305
	 */
306
	public function cleanup( string $timestamp ) : \Aimeos\MShop\Index\Manager\Iface
307
	{
308
		foreach( $this->getSubManagers() as $submanager ) {
309
			$submanager->cleanup( $timestamp );
310
		}
311
312
		return $this;
313
	}
314
315
316
	/**
317
	 * Removes multiple items.
318
	 *
319
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
320
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
321
	 */
322
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
323
	{
324
		$this->getManager()->delete( $itemIds );
325
		parent::delete( $itemIds );
326
327
		$this->context()->cache()->deleteByTags( map( $itemIds ) ->prefix( 'product-' )->toArray() );
328
		return $this;
329
	}
330
331
332
	/**
333
	 * Rebuilds the index for searching products or specified list of products.
334
	 * This can be a long lasting operation.
335
	 *
336
	 * @param \Aimeos\MShop\Product\Item\Iface[] $items Associative list of product IDs as keys and items as values
337
	 * @return \Aimeos\MShop\Index\Manager\Iface Manager object for chaining method calls
338
	 */
339
	public function rebuild( iterable $items = [] ) : \Aimeos\MShop\Index\Manager\Iface
340
	{
341
		$context = $this->context();
342
		$config = $context->config();
343
344
		/** mshop/index/manager/chunksize
345
		 * Number of products that should be indexed at once
346
		 *
347
		 * When rebuilding the product index, several products are updated at
348
		 * once within a transaction. This speeds up the time that is needed
349
		 * for reindexing.
350
		 *
351
		 * Usually, the more products are updated in one bunch, the faster the
352
		 * process of rebuilding the index will be up to a certain limit. The
353
		 * downside of big bunches is a higher memory consumption that can
354
		 * exceed the maximum allowed memory of the process.
355
		 *
356
		 * @param int Number of products
357
		 * @since 2014.09
358
		 * @category User
359
		 * @category Developer
360
		 * @see mshop/index/manager/domains
361
		 * @see mshop/index/manager/index
362
		 * @see mshop/index/manager/subdomains
363
		 * @see mshop/index/manager/submanagers
364
		 */
365
		$size = $config->get( 'mshop/index/manager/chunksize', 100 );
366
367
		/** mshop/index/manager/domains
368
		 * A list of domain names whose items should be retrieved together with the product
369
		 *
370
		 * To speed up the indexing process, items like texts, prices, media,
371
		 * attributes etc. which have been associated to products can be
372
		 * retrieved together with the products.
373
		 *
374
		 * Please note that the index submanagers expect that the items
375
		 * associated to the products are fetched together with the products.
376
		 * Thus, if you leave out a domain, this information won't be part
377
		 * of the indexed product and therefore won't be found when searching
378
		 * the index.
379
		 *
380
		 * @param string List of MShop domain names
381
		 * @since 2014.09
382
		 * @category Developer
383
		 * @see mshop/index/manager/chunksize
384
		 * @see mshop/index/manager/index
385
		 * @see mshop/index/manager/subdomains
386
		 * @see mshop/index/manager/submanagers
387
		 */
388
		$domains = $config->get( 'mshop/index/manager/domains', [] );
389
390
		$items = map( $items );
391
392
		if( !$items->isEmpty() )
393
		{
394
			$context->cache()->deleteByTags( $this->index( $items )->getId()->prefix( 'product-' ) );
395
			return $this;
396
		}
397
398
399
		$manager = \Aimeos\MShop::create( $context, 'product' );
400
		$cursor = $manager->cursor( $manager->filter()->slice( 0, $size ) );
401
402
		while( $items = $manager->iterate( $cursor, $domains ) ) {
403
			$this->index( $items );
404
		}
405
406
		$context->cache()->deleteByTags( ['product'] );
407
		return $this;
408
	}
409
410
411
	/**
412
	 * Searches for items matching the given criteria.
413
	 *
414
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria object
415
	 * @param string[] $ref List of domains to fetch list items and referenced items for
416
	 * @param int|null &$total Number of items that are available in total
417
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Product\Item\Iface with ids as keys
418
	 */
419
	public function search( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map
420
	{
421
		/** mshop/index/manager/search/mysql
422
		 * Retrieves the records matched by the given criteria in the database
423
		 *
424
		 * @see mshop/index/manager/search/ansi
425
		 */
426
427
		/** mshop/index/manager/search/ansi
428
		 * Retrieves the records matched by the given criteria in the database
429
		 *
430
		 * Fetches the records matched by the given criteria from the order
431
		 * database. The records must be from one of the sites that are
432
		 * configured via the context item. If the current site is part of
433
		 * a tree of sites, the SELECT statement can retrieve all records
434
		 * from the current site and the complete sub-tree of sites.
435
		 *
436
		 * As the records can normally be limited by criteria from sub-managers,
437
		 * their tables must be joined in the SQL context. This is done by
438
		 * using the "internaldeps" property from the definition of the ID
439
		 * column of the sub-managers. These internal dependencies specify
440
		 * the JOIN between the tables and the used columns for joining. The
441
		 * ":joins" placeholder is then replaced by the JOIN strings from
442
		 * the sub-managers.
443
		 *
444
		 * To limit the records matched, conditions can be added to the given
445
		 * criteria object. It can contain comparisons like column names that
446
		 * must match specific values which can be combined by AND, OR or NOT
447
		 * operators. The resulting string of SQL conditions replaces the
448
		 * ":cond" placeholder before the statement is sent to the database
449
		 * server.
450
		 *
451
		 * If the records that are retrieved should be ordered by one or more
452
		 * columns, the generated string of column / sort direction pairs
453
		 * replaces the ":order" placeholder. In case no ordering is required,
454
		 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
455
		 * markers is removed to speed up retrieving the records. Columns of
456
		 * sub-managers can also be used for ordering the result set but then
457
		 * no index can be used.
458
		 *
459
		 * The number of returned records can be limited and can start at any
460
		 * number between the begining and the end of the result set. For that
461
		 * the ":size" and ":start" placeholders are replaced by the
462
		 * corresponding values from the criteria object. The default values
463
		 * are 0 for the start and 100 for the size value.
464
		 *
465
		 * The SQL statement should conform to the ANSI standard to be
466
		 * compatible with most relational database systems. This also
467
		 * includes using double quotes for table and column names.
468
		 *
469
		 * @param string SQL statement for searching items
470
		 * @since 2014.03
471
		 * @category Developer
472
		 * @see mshop/index/manager/count/ansi
473
		 * @see mshop/index/manager/optimize/ansi
474
		 * @see mshop/index/manager/aggregate/ansi
475
		 */
476
		$cfgPathSearch = 'mshop/index/manager/search';
477
478
		/** mshop/index/manager/count/mysql
479
		 * Counts the number of records matched by the given criteria in the database
480
		 *
481
		 * @see mshop/index/manager/count/ansi
482
		 */
483
484
		/** mshop/index/manager/count/ansi
485
		 * Counts the number of records matched by the given criteria in the database
486
		 *
487
		 * Counts all records matched by the given criteria from the order
488
		 * database. The records must be from one of the sites that are
489
		 * configured via the context item. If the current site is part of
490
		 * a tree of sites, the statement can count all records from the
491
		 * current site and the complete sub-tree of sites.
492
		 *
493
		 * As the records can normally be limited by criteria from sub-managers,
494
		 * their tables must be joined in the SQL context. This is done by
495
		 * using the "internaldeps" property from the definition of the ID
496
		 * column of the sub-managers. These internal dependencies specify
497
		 * the JOIN between the tables and the used columns for joining. The
498
		 * ":joins" placeholder is then replaced by the JOIN strings from
499
		 * the sub-managers.
500
		 *
501
		 * To limit the records matched, conditions can be added to the given
502
		 * criteria object. It can contain comparisons like column names that
503
		 * must match specific values which can be combined by AND, OR or NOT
504
		 * operators. The resulting string of SQL conditions replaces the
505
		 * ":cond" placeholder before the statement is sent to the database
506
		 * server.
507
		 *
508
		 * Both, the strings for ":joins" and for ":cond" are the same as for
509
		 * the "search" SQL statement.
510
		 *
511
		 * Contrary to the "search" statement, it doesn't return any records
512
		 * but instead the number of records that have been found. As counting
513
		 * thousands of records can be a long running task, the maximum number
514
		 * of counted records is limited for performance reasons.
515
		 *
516
		 * The SQL statement should conform to the ANSI standard to be
517
		 * compatible with most relational database systems. This also
518
		 * includes using double quotes for table and column names.
519
		 *
520
		 * @param string SQL statement for counting items
521
		 * @since 2014.03
522
		 * @category Developer
523
		 * @see mshop/index/manager/search/ansi
524
		 * @see mshop/index/manager/optimize/ansi
525
		 * @see mshop/index/manager/aggregate/ansi
526
		 */
527
		$cfgPathCount = 'mshop/index/manager/count';
528
529
		return $this->searchItemsIndexBase( $search, $ref, $total, $cfgPathSearch, $cfgPathCount );
530
	}
531
532
533
	/**
534
	 * Indexes all given product items
535
	 *
536
	 * @param \Aimeos\Map $items Product items with associated attributes, categories, media, prices, products, texts, etc.
537
	 * @return \Aimeos\Map Indexed product items
538
	 */
539
	protected function index( \Aimeos\Map $items ) : \Aimeos\Map
540
	{
541
		try
542
		{
543
			$this->begin();
544
545
			$this->remove( $items );
546
547
			foreach( $this->getSubManagers() as $submanager ) {
548
				$submanager->rebuild( $items );
549
			}
550
551
			$this->commit();
552
		}
553
		catch( \Exception $e )
554
		{
555
			$this->rollback();
556
			throw $e;
557
		}
558
559
		return $items;
560
	}
561
562
563
	/**
564
	 * Re-writes the index entries for all products that are search result of given criteria
565
	 *
566
	 * @param \Aimeos\Base\Criteria\Iface $search Search criteria
567
	 * @param string[] $domains List of domains to be
568
	 * @param int $size Size of a chunk of products to handle at a time
569
	 * @deprecated 2023.01 Use index() instead
570
	 */
571
	protected function writeIndex( \Aimeos\Base\Criteria\Iface $search, array $domains, int $size )
572
	{
573
		$context = $this->context();
574
		$manager = \Aimeos\MShop::create( $context, 'product' );
575
		$submanagers = $this->getSubManagers();
576
		$start = 0;
577
578
		do
579
		{
580
			$search->slice( $start, $size );
581
			$products = $manager->search( $search, $domains );
582
583
			try
584
			{
585
				$this->begin();
586
587
				$this->remove( $products );
588
589
				foreach( $submanagers as $submanager ) {
590
					$submanager->rebuild( $products );
591
				}
592
593
				$this->commit();
594
			}
595
			catch( \Exception $e )
596
			{
597
				$this->rollback();
598
				throw $e;
599
			}
600
601
			$context->cache()->deleteByTags( $products->keys()->prefix( 'product-' )->all() );
602
603
			$count = count( $products );
604
			$start += $count;
605
		}
606
		while( $count == $search->getLimit() );
607
	}
608
609
610
	/**
611
	 * Returns the list of sub-managers available for the index attribute manager.
612
	 *
613
	 * @return \Aimeos\MShop\Index\Manager\Iface[] Associative list of the sub-domain as key and the manager object as value
614
	 */
615
	protected function getSubManagers() : array
616
	{
617
		if( $this->subManagers === null )
618
		{
619
			$this->subManagers = [];
620
			$config = $this->context()->config();
621
622
			/** mshop/index/manager/submanagers
623
			 * A list of sub-manager names used for indexing associated items
624
			 *
625
			 * All items referenced by a product (e.g. texts, prices, media,
626
			 * etc.) are added to the product index via specialized index
627
			 * managers. You can add the name of new sub-managers to add more
628
			 * data to the index or remove existing ones if you don't want to
629
			 * index that data at all.
630
			 *
631
			 * Caution: Please note that the list of sub-manager names should
632
			 * correspond to the list of domains that are fetched together with
633
			 * the products as the sub-manager depends on the items being
634
			 * retrieved there and fetching items that won't be indexed is a
635
			 * waste of resources.
636
			 *
637
			 * @param string List of index sub-manager names
638
			 * @since 2016.02
639
			 * @category User
640
			 * @category Developer
641
			 * @see mshop/index/manager/chunksize
642
			 * @see mshop/index/manager/domains
643
			 * @see mshop/index/manager/index
644
			 * @see mshop/index/manager/subdomains
645
			 */
646
			foreach( $config->get( 'mshop/index/manager/submanagers', [] ) as $domain )
647
			{
648
				$name = $config->get( 'mshop/index/manager/' . $domain . '/name' );
649
				$this->subManagers[$domain] = $this->object()->getSubManager( $domain, $name );
650
			}
651
652
			return $this->subManagers;
653
		}
654
655
		return $this->subManagers;
656
	}
657
}
658