Passed
Push — master ( b143bc...6468ac )
by Aimeos
09:27
created

Standard::locales()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2022
6
 * @package Controller
7
 * @subpackage Jobs
8
 */
9
10
11
namespace Aimeos\Controller\Jobs\Product\Export\Sitemap;
12
13
14
/**
15
 * Job controller for product sitemap.
16
 *
17
 * @package Controller
18
 * @subpackage Jobs
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Jobs\Product\Export\Standard
22
	implements \Aimeos\Controller\Jobs\Iface
23
{
24
	/** controller/jobs/product/export/sitemap/name
25
	 * Class name of the used product suggestions scheduler controller implementation
26
	 *
27
	 * Each default job controller can be replace by an alternative imlementation.
28
	 * To use this implementation, you have to set the last part of the class
29
	 * name as configuration value so the controller factory knows which class it
30
	 * has to instantiate.
31
	 *
32
	 * For example, if the name of the default class is
33
	 *
34
	 *  \Aimeos\Controller\Jobs\Product\Export\Sitemap\Standard
35
	 *
36
	 * and you want to replace it with your own version named
37
	 *
38
	 *  \Aimeos\Controller\Jobs\Product\Export\Sitemap\Mysitemap
39
	 *
40
	 * then you have to set the this configuration option:
41
	 *
42
	 *  controller/jobs/product/export/sitemap/name = Mysitemap
43
	 *
44
	 * The value is the last part of your own class name and it's case sensitive,
45
	 * so take care that the configuration value is exactly named like the last
46
	 * part of the class name.
47
	 *
48
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
49
	 * characters are possible! You should always start the last part of the class
50
	 * name with an upper case character and continue only with lower case characters
51
	 * or numbers. Avoid chamel case names like "MySitemap"!
52
	 *
53
	 * @param string Last part of the class name
54
	 * @since 2015.01
55
	 * @category Developer
56
	 */
57
58
	/** controller/jobs/product/export/sitemap/decorators/excludes
59
	 * Excludes decorators added by the "common" option from the product export sitemap job controller
60
	 *
61
	 * Decorators extend the functionality of a class by adding new aspects
62
	 * (e.g. log what is currently done), executing the methods of the underlying
63
	 * class only in certain conditions (e.g. only for logged in users) or
64
	 * modify what is returned to the caller.
65
	 *
66
	 * This option allows you to remove a decorator added via
67
	 * "controller/jobs/common/decorators/default" before they are wrapped
68
	 * around the job controller.
69
	 *
70
	 *  controller/jobs/product/export/sitemap/decorators/excludes = array( 'decorator1' )
71
	 *
72
	 * This would remove the decorator named "decorator1" from the list of
73
	 * common decorators ("\Aimeos\Controller\Jobs\Common\Decorator\*") added via
74
	 * "controller/jobs/common/decorators/default" to the job controller.
75
	 *
76
	 * @param array List of decorator names
77
	 * @since 2015.01
78
	 * @category Developer
79
	 * @see controller/jobs/common/decorators/default
80
	 * @see controller/jobs/product/export/sitemap/decorators/global
81
	 * @see controller/jobs/product/export/sitemap/decorators/local
82
	 */
83
84
	/** controller/jobs/product/export/sitemap/decorators/global
85
	 * Adds a list of globally available decorators only to the product export sitemap job controller
86
	 *
87
	 * Decorators extend the functionality of a class by adding new aspects
88
	 * (e.g. log what is currently done), executing the methods of the underlying
89
	 * class only in certain conditions (e.g. only for logged in users) or
90
	 * modify what is returned to the caller.
91
	 *
92
	 * This option allows you to wrap global decorators
93
	 * ("\Aimeos\Controller\Jobs\Common\Decorator\*") around the job controller.
94
	 *
95
	 *  controller/jobs/product/export/sitemap/decorators/global = array( 'decorator1' )
96
	 *
97
	 * This would add the decorator named "decorator1" defined by
98
	 * "\Aimeos\Controller\Jobs\Common\Decorator\Decorator1" only to the job controller.
99
	 *
100
	 * @param array List of decorator names
101
	 * @since 2015.01
102
	 * @category Developer
103
	 * @see controller/jobs/common/decorators/default
104
	 * @see controller/jobs/product/export/sitemap/decorators/excludes
105
	 * @see controller/jobs/product/export/sitemap/decorators/local
106
	 */
107
108
	/** controller/jobs/product/export/sitemap/decorators/local
109
	 * Adds a list of local decorators only to the product export sitemap job controller
110
	 *
111
	 * Decorators extend the functionality of a class by adding new aspects
112
	 * (e.g. log what is currently done), executing the methods of the underlying
113
	 * class only in certain conditions (e.g. only for logged in users) or
114
	 * modify what is returned to the caller.
115
	 *
116
	 * This option allows you to wrap local decorators
117
	 * ("\Aimeos\Controller\Jobs\Product\Export\Sitemap\Decorator\*") around the job
118
	 * controller.
119
	 *
120
	 *  controller/jobs/product/export/sitemap/decorators/local = array( 'decorator2' )
121
	 *
122
	 * This would add the decorator named "decorator2" defined by
123
	 * "\Aimeos\Controller\Jobs\Product\Export\Sitemap\Decorator\Decorator2"
124
	 * only to the job controller.
125
	 *
126
	 * @param array List of decorator names
127
	 * @since 2015.01
128
	 * @category Developer
129
	 * @see controller/jobs/common/decorators/default
130
	 * @see controller/jobs/product/export/sitemap/export/sitemap/decorators/excludes
131
	 * @see controller/jobs/product/export/sitemap/export/sitemap/decorators/global
132
	 */
133
134
135
	private $locales;
136
137
138
	/**
139
	 * Returns the localized name of the job.
140
	 *
141
	 * @return string Name of the job
142
	 */
143
	public function getName() : string
144
	{
145
		return $this->context()->translate( 'controller/jobs', 'Product site map' );
146
	}
147
148
149
	/**
150
	 * Returns the localized description of the job.
151
	 *
152
	 * @return string Description of the job
153
	 */
154
	public function getDescription() : string
155
	{
156
		return $this->context()->translate( 'controller/jobs', 'Creates a product site map for search engines' );
157
	}
158
159
160
	/**
161
	 * Executes the job.
162
	 *
163
	 * @throws \Aimeos\Controller\Jobs\Exception If an error occurs
164
	 */
165
	public function run()
166
	{
167
		/** controller/jobs/product/export/sitemap/hidden
168
		 * Export hidden products in site map
169
		 *
170
		 * The product site map contains no hidden products by default. If they
171
		 * should be part of the export, set this configuration option to TRUE.
172
		 *
173
		 * @param bool TRUE to export hidden products, FALSE if not
174
		 * @since 2022.01
175
		 * @see controller/jobs/product/export/sitemap/container/options
176
		 * @see controller/jobs/product/export/sitemap/location
177
		 * @see controller/jobs/product/export/sitemap/max-items
178
		 * @see controller/jobs/product/export/sitemap/max-query
179
		 * @see controller/jobs/product/export/sitemap/changefreq
180
		 */
181
		$hidden = $this->context()->config()->get( 'controller/jobs/product/export/sitemap/hidden', false );
182
183
		$container = $this->createContainer();
184
185
		$files = $this->export( $container, $hidden ? null : true );
186
		$this->createSitemapIndex( $container, $files );
187
188
		$container->close();
189
	}
190
191
192
	/**
193
	 * Adds the given products to the content object for the site map file
194
	 *
195
	 * @param \Aimeos\MW\Container\Content\Iface $content File content object
196
	 * @param \Aimeos\Map $items List of product items implementing \Aimeos\MShop\Product\Item\Iface
197
	 */
198
	protected function addItems( \Aimeos\MW\Container\Content\Iface $content, \Aimeos\Map $items )
199
	{
200
		$config = $this->context()->config();
201
202
		/** controller/jobs/product/export/sitemap/changefreq
203
		 * Change frequency of the products
204
		 *
205
		 * Depending on how often the product content changes (e.g. price updates)
206
		 * and the site map files are generated you can give search engines a
207
		 * hint how often they should reindex your site. The site map schema
208
		 * allows a few pre-defined strings for the change frequency:
209
		 *
210
		 * * always
211
		 * * hourly
212
		 * * daily
213
		 * * weekly
214
		 * * monthly
215
		 * * yearly
216
		 * * never
217
		 *
218
		 * More information can be found at
219
		 * {@link http://www.sitemaps.org/protocol.html#xmlTagDefinitions sitemap.org}
220
		 *
221
		 * @param string One of the pre-defined strings (see description)
222
		 * @since 2015.01
223
		 * @category User
224
		 * @category Developer
225
		 * @see controller/jobs/product/export/sitemap/container/options
226
		 * @see controller/jobs/product/export/sitemap/location
227
		 * @see controller/jobs/product/export/sitemap/max-items
228
		 * @see controller/jobs/product/export/sitemap/max-query
229
		 */
230
		$changefreq = $config->get( 'controller/jobs/product/export/sitemap/changefreq', 'daily' );
231
232
		/** controller/jobs/product/export/sitemap/template-items
233
		 * Relative path to the XML items template of the product site map job controller.
234
		 *
235
		 * The template file contains the XML code and processing instructions
236
		 * to generate the site map files. The configuration string is the path
237
		 * to the template file relative to the templates directory (usually in
238
		 * controller/jobs/templates).
239
		 *
240
		 * You can overwrite the template file configuration in extensions and
241
		 * provide alternative templates. These alternative templates should be
242
		 * named like the default one but with the string "standard" replaced by
243
		 * an unique name. You may use the name of your project for this. If
244
		 * you've implemented an alternative client class as well, "standard"
245
		 * should be replaced by the name of the new class.
246
		 *
247
		 * @param string Relative path to the template creating XML code for the site map items
248
		 * @since 2015.01
249
		 * @category Developer
250
		 * @see controller/jobs/product/export/sitemap/template-header
251
		 * @see controller/jobs/product/export/sitemap/template-footer
252
		 * @see controller/jobs/product/export/sitemap/template-index
253
		 */
254
		$tplconf = 'controller/jobs/product/export/sitemap/template-items';
255
		$default = 'product/export/sitemap-items-body-standard';
256
257
		$context = $this->context();
258
		$view = $context->view();
259
260
		$view->siteItems = $items;
261
		$view->siteFreq = $changefreq;
262
		$view->siteLocales = $this->locales();
263
264
		$content->add( $view->render( $context->config()->get( $tplconf, $default ) ) );
265
	}
266
267
268
	/**
269
	 * Creates a new container for the site map file
270
	 *
271
	 * @return \Aimeos\MW\Container\Iface Container object
272
	 */
273
	protected function createContainer() : \Aimeos\MW\Container\Iface
274
	{
275
		$config = $this->context()->config();
276
277
		/** controller/jobs/product/export/sitemap/location
278
		 * Directory where the generated site maps should be placed into
279
		 *
280
		 * The site maps must be publically available for download by the search
281
		 * engines. Therefore, you have to configure a directory for the site
282
		 * maps in your web space that is writeable by the process generating
283
		 * the files, e.g.
284
		 *
285
		 * /var/www/yourshop/your/sitemap/path
286
		 *
287
		 * The location of the site map index file should then be
288
		 * added to the robots.txt in the document root of your domain:
289
		 *
290
		 * Sitemap: https://www.yourshop.com/your/sitemap/path/aimeos-sitemap-index.xml
291
		 *
292
		 * The "sitemapindex-aimeos.xml" file is the site map index file that
293
		 * references the real site map files which contains the links to the
294
		 * products. Please make sure that the protocol and domain
295
		 * (https://www.yourshop.com/) is the same as the ones used in the
296
		 * product links!
297
		 *
298
		 * More details about site maps can be found at
299
		 * {@link http://www.sitemaps.org/protocol.html sitemaps.org}
300
		 *
301
		 * @param string Absolute directory to store the site maps into
302
		 * @since 2015.01
303
		 * @category Developer
304
		 * @category User
305
		 * @see controller/jobs/product/export/sitemap/container/options
306
		 * @see controller/jobs/product/export/sitemap/max-items
307
		 * @see controller/jobs/product/export/sitemap/max-query
308
		 * @see controller/jobs/product/export/sitemap/changefreq
309
		 */
310
		$location = $config->get( 'controller/jobs/product/export/sitemap/location' );
311
312
		/** controller/jobs/product/export/sitemap/container/options
313
		 * List of file container options for the site map files
314
		 *
315
		 * The directory and the generated site map files are stored using
316
		 * container/content objects from the core, namely the "Directory"
317
		 * container and the "Binary" content classes. Both implementations
318
		 * support some options:
319
		 *
320
		 * * dir-perm (default: 0755): Permissions if the directory must be created
321
		 * * gzip-level (default: 5): GZip compression level from 0 to 9 (0 = fast, 9 = best)
322
		 * * gzip-mode (default: "wb"): Overwrite existing files in binary mode
323
		 *
324
		 * @param array Associative list of option name/value pairs
325
		 * @since 2015.01
326
		 * @category Developer
327
		 * @see controller/jobs/product/export/sitemap/location
328
		 * @see controller/jobs/product/export/sitemap/max-items
329
		 * @see controller/jobs/product/export/sitemap/max-query
330
		 * @see controller/jobs/product/export/sitemap/changefreq
331
		 */
332
		$default = array( 'gzip-mode' => 'wb' );
333
		$options = $config->get( 'controller/jobs/product/export/sitemap/container/options', $default );
334
335
		if( $location == null )
336
		{
337
			$msg = sprintf( 'Required configuration for "%1$s" is missing', 'controller/jobs/product/export/sitemap/location' );
338
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
339
		}
340
341
		return \Aimeos\MW\Container\Factory::getContainer( $location, 'Directory', 'Gzip', $options );
342
	}
343
344
345
	/**
346
	 * Creates a new site map content object
347
	 *
348
	 * @param \Aimeos\MW\Container\Iface $container Container object
349
	 * @param int $filenum New file number
350
	 * @return \Aimeos\MW\Container\Content\Iface New content object
351
	 */
352
	protected function createContent( \Aimeos\MW\Container\Iface $container, int $filenum ) : \Aimeos\MW\Container\Content\Iface
353
	{
354
		/** controller/jobs/product/export/sitemap/template-header
355
		 * Relative path to the XML site map header template of the product site map job controller.
356
		 *
357
		 * The template file contains the XML code and processing instructions
358
		 * to generate the site map header. The configuration string is the path
359
		 * to the template file relative to the templates directory (usually in
360
		 * controller/jobs/templates).
361
		 *
362
		 * You can overwrite the template file configuration in extensions and
363
		 * provide alternative templates. These alternative templates should be
364
		 * named like the default one but with the string "standard" replaced by
365
		 * an unique name. You may use the name of your project for this. If
366
		 * you've implemented an alternative client class as well, "standard"
367
		 * should be replaced by the name of the new class.
368
		 *
369
		 * @param string Relative path to the template creating XML code for the site map header
370
		 * @since 2015.01
371
		 * @category Developer
372
		 * @see controller/jobs/product/export/sitemap/template-items
373
		 * @see controller/jobs/product/export/sitemap/template-footer
374
		 * @see controller/jobs/product/export/sitemap/template-index
375
		 */
376
		$tplconf = 'controller/jobs/product/export/sitemap/template-header';
377
		$default = 'product/export/sitemap-items-header-standard';
378
379
		$context = $this->context();
380
		$view = $context->view();
381
382
		$content = $container->create( $this->getFilename( $filenum ) );
383
		$content->add( $view->render( $context->config()->get( $tplconf, $default ) ) );
384
		$container->add( $content );
385
386
		return $content;
387
	}
388
389
390
	/**
391
	 * Closes the site map content object
392
	 *
393
	 * @param \Aimeos\MW\Container\Content\Iface $content
394
	 */
395
	protected function closeContent( \Aimeos\MW\Container\Content\Iface $content )
396
	{
397
		/** controller/jobs/product/export/sitemap/template-footer
398
		 * Relative path to the XML site map footer template of the product site map job controller.
399
		 *
400
		 * The template file contains the XML code and processing instructions
401
		 * to generate the site map footer. The configuration string is the path
402
		 * to the template file relative to the templates directory (usually in
403
		 * controller/jobs/templates).
404
		 *
405
		 * You can overwrite the template file configuration in extensions and
406
		 * provide alternative templates. These alternative templates should be
407
		 * named like the default one but with the string "standard" replaced by
408
		 * an unique name. You may use the name of your project for this. If
409
		 * you've implemented an alternative client class as well, "standard"
410
		 * should be replaced by the name of the new class.
411
		 *
412
		 * @param string Relative path to the template creating XML code for the site map footer
413
		 * @since 2015.01
414
		 * @category Developer
415
		 * @see controller/jobs/product/export/sitemap/template-header
416
		 * @see controller/jobs/product/export/sitemap/template-items
417
		 * @see controller/jobs/product/export/sitemap/template-index
418
		 */
419
		$tplconf = 'controller/jobs/product/export/sitemap/template-footer';
420
		$default = 'product/export/sitemap-items-footer-standard';
421
422
		$context = $this->context();
423
		$view = $context->view();
424
425
		$content->add( $view->render( $context->config()->get( $tplconf, $default ) ) );
426
	}
427
428
429
	/**
430
	 * Adds the content for the site map index file
431
	 *
432
	 * @param \Aimeos\MW\Container\Iface $container File container object
433
	 * @param array $files List of generated site map file names
434
	 */
435
	protected function createSitemapIndex( \Aimeos\MW\Container\Iface $container, array $files )
436
	{
437
		$context = $this->context();
438
		$config = $context->config();
439
		$view = $context->view();
440
441
		/** controller/jobs/product/export/sitemap/template-index
442
		 * Relative path to the XML site map index template of the product site map job controller.
443
		 *
444
		 * The template file contains the XML code and processing instructions
445
		 * to generate the site map index files. The configuration string is the path
446
		 * to the template file relative to the templates directory (usually in
447
		 * controller/jobs/templates).
448
		 *
449
		 * You can overwrite the template file configuration in extensions and
450
		 * provide alternative templates. These alternative templates should be
451
		 * named like the default one but with the string "standard" replaced by
452
		 * an unique name. You may use the name of your project for this. If
453
		 * you've implemented an alternative client class as well, "standard"
454
		 * should be replaced by the name of the new class.
455
		 *
456
		 * @param string Relative path to the template creating XML code for the site map index
457
		 * @since 2015.01
458
		 * @category Developer
459
		 * @see controller/jobs/product/export/sitemap/template-header
460
		 * @see controller/jobs/product/export/sitemap/template-items
461
		 * @see controller/jobs/product/export/sitemap/template-footer
462
		 */
463
		$tplconf = 'controller/jobs/product/export/sitemap/template-index';
464
		$default = 'product/export/sitemap-index-standard';
465
466
		/** controller/jobs/product/export/sitemap/baseurl
467
		 * URL to the folder where the site maps can be accessed, without the filenames.
468
		 *
469
		 * The site maps must be publically available for download by the search
470
		 * engines. Individual site map files need a fully qualified URL in the index file.
471
		 *
472
		 * https://www.yourshop.com/your/sitemap/path/
473
		 *
474
		 * The location of the site map index file should then be
475
		 * added to the robots.txt in the document root of your domain:
476
		 *
477
		 * Sitemap: https://www.yourshop.com/your/sitemap/path/aimeos-sitemap-index.xml
478
		 *
479
		 * More details about site maps can be found at
480
		 * {@link http://www.sitemaps.org/protocol.html sitemaps.org}
481
		 *
482
		 * @param string Absolute URL
483
		 * @since 2019.06
484
		 * @category Developer
485
		 * @category User
486
		 * @see controller/jobs/product/export/sitemap/container/options
487
		 * @see controller/jobs/product/export/sitemap/max-items
488
		 * @see controller/jobs/product/export/sitemap/max-query
489
		 * @see controller/jobs/product/export/sitemap/changefreq
490
		 * @see controller/jobs/product/export/sitemap/location
491
		 */
492
		$baseUrl = $config->get( 'resource/fs/baseurl' );
493
		$baseUrl = $config->get( 'controller/jobs/product/export/sitemap/baseurl', $baseUrl );
494
495
		if( $baseUrl == null )
496
		{
497
			$msg = sprintf( 'Required configuration for "%1$s" is missing', 'controller/jobs/product/export/sitemap/baseurl' );
498
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
499
		}
500
501
		$view->baseUrl = rtrim( $baseUrl, '/' ) . '/';
502
		$view->siteFiles = $files;
503
504
		$content = $container->create( 'aimeos-sitemap-index.xml' );
505
		$content->add( $view->render( $config->get( $tplconf, $default ) ) );
506
		$container->add( $content );
507
	}
508
509
510
	/**
511
	 * Exports the products into the given container
512
	 *
513
	 * @param \Aimeos\MW\Container\Iface $container Container object
514
	 * @param bool|null $default TRUE to use default criteria, NULL for relaxed criteria
515
	 * @return array List of content (file) names
516
	 */
517
	protected function export( \Aimeos\MW\Container\Iface $container, ?bool $default = true ) : array
518
	{
519
		$domains = $this->getConfig( 'domains', ['text'] );
520
		$maxItems = $this->getConfig( 'max-items', 10000 );
521
		$maxQuery = $this->getConfig( 'max-query', 1000 );
522
523
		$start = 0; $filenum = 1;
524
		$names = [];
525
526
		$manager = \Aimeos\MShop::create( $this->context(), 'index' );
527
528
		$search = $manager->filter( $default );
529
		$search->setConditions( $search->and( [
530
			$search->compare( '!=', 'index.catalog.id', null ),
531
			$search->getConditions()
532
		] ) );
533
		$search->setSortations( array( $search->sort( '+', 'product.id' ) ) );
534
		$search->slice( 0, $maxQuery );
535
536
		$content = $this->createContent( $container, $filenum );
537
		$names[] = $content->getResource();
538
539
		do
540
		{
541
			$items = $manager->search( $search, $domains );
542
			$remaining = $maxItems * $filenum - $start;
543
			$count = count( $items );
544
545
			if( $remaining < $count )
546
			{
547
				$this->addItems( $content, $items->slice( 0, $remaining ) );
548
				$items = $items->slice( $remaining );
549
550
				$this->closeContent( $content );
551
				$content = $this->createContent( $container, ++$filenum );
552
				$names[] = $content->getResource();
553
			}
554
555
			$this->addItems( $content, $items );
556
557
			$start += $count;
558
			$search->slice( $start, $maxQuery );
559
		}
560
		while( $count >= $search->getLimit() );
561
562
		$this->closeContent( $content );
563
564
		return $names;
565
	}
566
567
568
	/**
569
	 * Returns the configuration value for the given name
570
	 *
571
	 * @param string $name One of "domain", "max-items" or "max-query"
572
	 * @param mixed $default Default value if name is unknown
573
	 * @return mixed Configuration value
574
	 */
575
	protected function getConfig( string $name, $default = null )
576
	{
577
		$config = $this->context()->config();
578
579
		switch( $name )
580
		{
581
			case 'domains':
582
				/** controller/jobs/product/export/sitemap/domains
583
				 * List of associated items from other domains that should be fetched for the sitemap
584
				 *
585
				 * Products consist not only of the base data but also of texts, media
586
				 * files, prices, attrbutes and other details. Those information is
587
				 * associated to the products via their lists. Using the "domains" option
588
				 * you can make more or less associated items available in the template.
589
				 *
590
				 * @param array List of domain names
591
				 * @since 2018.07
592
				 * @category Developer
593
				 * @category User
594
				 * @see controller/jobs/product/export/sitemap/container/options
595
				 * @see controller/jobs/product/export/sitemap/location
596
				 * @see controller/jobs/product/export/sitemap/max-items
597
				 * @see controller/jobs/product/export/sitemap/max-query
598
				 * @see controller/jobs/product/export/sitemap/changefreq
599
				 */
600
				return $config->get( 'controller/jobs/product/export/sitemap/domains', $default );
601
602
			case 'max-items':
603
				/** controller/jobs/product/export/sitemap/max-items
604
				 * Maximum number of products per site map
605
				 *
606
				 * Each site map file must not contain more than 50,000 links and it's
607
				 * size must be less than 10MB. If your product URLs are rather long
608
				 * and one of your site map files is bigger than 10MB, you should set
609
				 * the number of products per file to a smaller value until each file
610
				 * is less than 10MB.
611
				 *
612
				 * More details about site maps can be found at
613
				 * {@link http://www.sitemaps.org/protocol.html sitemaps.org}
614
				 *
615
				 * @param integer Number of products per file
616
				 * @since 2015.01
617
				 * @category Developer
618
				 * @category User
619
				 * @see controller/jobs/product/export/sitemap/container/options
620
				 * @see controller/jobs/product/export/sitemap/location
621
				 * @see controller/jobs/product/export/sitemap/max-query
622
				 * @see controller/jobs/product/export/sitemap/changefreq
623
				 * @see controller/jobs/product/export/sitemap/domains
624
				 */
625
				return $config->get( 'controller/jobs/product/export/sitemap/max-items', 50000 );
626
627
			case 'max-query':
628
				/** controller/jobs/product/export/sitemap/max-query
629
				 * Maximum number of products per query
630
				 *
631
				 * The products are fetched from the database in bunches for efficient
632
				 * retrieval. The higher the value, the lower the total time the database
633
				 * is busy finding the records. Higher values also means that record
634
				 * updates in the tables need to wait longer and the memory consumption
635
				 * of the PHP process is higher.
636
				 *
637
				 * Note: The value of max-query must be smaller than or equal to
638
				 * {@see controller/jobs/product/export/sitemap/max-items max-items}
639
				 *
640
				 * @param integer Number of products per query
641
				 * @since 2015.01
642
				 * @category Developer
643
				 * @see controller/jobs/product/export/sitemap/container/options
644
				 * @see controller/jobs/product/export/sitemap/location
645
				 * @see controller/jobs/product/export/sitemap/max-items
646
				 * @see controller/jobs/product/export/sitemap/changefreq
647
				 * @see controller/jobs/product/export/sitemap/domains
648
				 */
649
				return $config->get( 'controller/jobs/product/export/sitemap/max-query', 1000 );
650
		}
651
652
		return $default;
653
	}
654
655
656
	/**
657
	 * Returns the file name for the new content file
658
	 *
659
	 * @param int $number Current file number
660
	 * @return string New file name
661
	 */
662
	protected function getFilename( int $number ) : string
663
	{
664
		return sprintf( 'aimeos-sitemap-%d.xml', $number );
665
	}
666
667
668
	/**
669
	 * Returns the available locale items for the current site
670
	 *
671
	 * @return \Aimeos\Map List of locale items
672
	 */
673
	protected function locales() : \Aimeos\Map
674
	{
675
		if( !isset( $this->locales ) )
676
		{
677
			$manager = \Aimeos\MShop::create( $this->context(), 'locale' );
678
			$filter = $manager->filter()->add( ['locale.siteid' => $this->context()->locale()->getSiteId()] );
679
680
			$this->locales = $manager->search( $filter->slice( 0, 10000 ) );
681
		}
682
683
		return $this->locales;
684
	}
685
}
686