Passed
Push — master ( e7ec1e...e85a3f )
by Aimeos
05:27
created

Standard::prefix()   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 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2024
6
 * @package MShop
7
 * @subpackage Locale
8
 */
9
10
11
namespace Aimeos\MShop\Locale\Manager\Site;
12
13
14
/**
15
 * Default implementation for managing sites.
16
 *
17
 * @package MShop
18
 * @subpackage Locale
19
 */
20
class Standard
21
	extends \Aimeos\MShop\Common\Manager\Base
22
	implements \Aimeos\MShop\Locale\Manager\Site\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
23
{
24
	private array $cache = [];
25
26
	private array $searchConfig = [
27
		'locale.site.id' => [
28
			'label' => 'Site ID',
29
			'internaldeps' => ['LEFT JOIN "mshop_locale_site" AS mlocsi ON ( mloc."siteid" = mlocsi."siteid" )'],
30
			'internalcode' => 'id',
31
			'type' => 'int',
32
			'public' => false,
33
		],
34
		'locale.site.siteid' => [
35
			'label' => 'Unique site ID',
36
			'internalcode' => 'siteid',
37
			'type' => 'string',
38
			'public' => false,
39
		],
40
		'locale.site.parentid' => [
41
			'label' => 'Parent site ID',
42
			'internalcode' => 'parentid',
43
			'type' => 'int',
44
			'public' => false,
45
		],
46
		'locale.site.label' => [
47
			'label' => 'Site label',
48
			'internalcode' => 'label',
49
			'type' => 'string',
50
		],
51
		'locale.site.code' => [
52
			'label' => 'Site code',
53
			'internalcode' => 'code',
54
			'type' => 'string',
55
		],
56
		'locale.site.status' => [
57
			'label' => 'Site status',
58
			'internalcode' => 'status',
59
			'type' => 'int',
60
		],
61
		'locale.site.position' => [
62
			'label' => 'Site position',
63
			'internalcode' => 'id',
64
			'type' => 'int',
65
		],
66
		'locale.site.level' => [
67
			'label' => 'Site tree level',
68
			'internalcode' => 'level',
69
			'type' => 'int',
70
			'public' => false,
71
		],
72
		'locale.site.config' => [
73
			'label' => 'Site config',
74
			'internalcode' => 'config',
75
			'type' => 'json',
76
			'public' => false,
77
		],
78
		'locale.site.icon' => [
79
			'label' => 'Site icon',
80
			'internalcode' => 'icon',
81
			'type' => 'string',
82
			'public' => false,
83
		],
84
		'locale.site.logo' => [
85
			'label' => 'Site logo',
86
			'internalcode' => 'logo',
87
			'type' => 'json',
88
			'public' => false,
89
		],
90
		'locale.site.rating' => [
91
			'label' => 'Rating value',
92
			'internalcode' => 'rating',
93
			'type' => 'decimal',
94
			'public' => false,
95
		],
96
		'locale.site.ratings' => [
97
			'label' => 'Number of ratings',
98
			'internalcode' => 'ratings',
99
			'type' => 'int',
100
			'public' => false,
101
		],
102
		'locale.site.refid' => [
103
			'label' => 'Site-related supplier ID',
104
			'internalcode' => 'refid',
105
			'type' => 'string',
106
			'public' => false,
107
		],
108
		'locale.site.theme' => [
109
			'label' => 'Site theme',
110
			'internalcode' => 'theme',
111
			'type' => 'string',
112
			'public' => false,
113
		],
114
		'locale.site.ctime' => [
115
			'label' => 'Site create date/time',
116
			'internalcode' => 'ctime',
117
			'type' => 'datetime',
118
			'public' => false,
119
		],
120
		'locale.site.mtime' => [
121
			'label' => 'Site modify date/time',
122
			'internalcode' => 'mtime',
123
			'type' => 'datetime',
124
			'public' => false,
125
		],
126
		'locale.site.editor' => [
127
			'label' => 'Site editor',
128
			'internalcode' => 'editor',
129
			'type' => 'string',
130
			'public' => false,
131
		],
132
	];
133
134
135
	/**
136
	 * Removes old entries from the storage.
137
	 *
138
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
139
	 * @return \Aimeos\MShop\Locale\Manager\Site\Iface Manager object for chaining method calls
140
	 */
141
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
142
	{
143
		if( empty( $siteids ) ) {
144
			return $this;
145
		}
146
147
		$context = $this->context();
148
		$config = $context->config();
149
150
		/** mshop/locale/manager/site/cleanup/shop/domains
151
		 * List of madmin domains names whose items referring to the same site should be deleted as well
152
		 *
153
		 * As items for each domain can be stored in a separate database, the
154
		 * site manager needs a list of domain names used to connect to the
155
		 * correct database and to remove all items that belong the the deleted
156
		 * site.
157
		 *
158
		 * For each domain the cleanup will be done by the corresponding MShop
159
		 * manager. To keep records for old sites in the database even if the
160
		 * site was already deleted, you can configure a new list with the
161
		 * domains removed you would like to keep, e.g. the "order" domain to
162
		 * keep all orders ever placed.
163
		 *
164
		 * @param array List of domain names in lower case
165
		 * @since 2015.10
166
		 * @see mshop/locale/manager/site/cleanup/admin/domains
167
		 */
168
		$path = 'mshop/locale/manager/site/cleanup/shop/domains';
169
170
		foreach( $config->get( $path, [] ) as $domain ) {
171
			\Aimeos\MShop::create( $context, $domain )->clear( $siteids );
172
		}
173
174
		/** mshop/locale/manager/site/cleanup/admin/domains
175
		 * List of mshop domains names whose items referring to the same site should be deleted as well
176
		 *
177
		 * As items for each domain can be stored in a separate database, the
178
		 * site manager needs a list of domain names used to connect to the
179
		 * correct database and to remove all items that belong the the deleted
180
		 * site.
181
		 *
182
		 * For each domain the cleanup will be done by the corresponding MAdmin
183
		 * manager. To keep records for old sites in the database even if the
184
		 * site was already deleted, you can configure a new list with the
185
		 * domains removed you would like to keep, e.g. the "log" domain to
186
		 * keep all log entries ever written.
187
		 *
188
		 * @param array List of domain names in lower case
189
		 * @since 2015.10
190
		 * @see mshop/locale/manager/site/cleanup/shop/domains
191
		 */
192
		$path = 'mshop/locale/manager/site/cleanup/admin/domains';
193
194
		foreach( $config->get( $path, [] ) as $domain ) {
195
			\Aimeos\MAdmin::create( $context, $domain )->clear( $siteids );
196
		}
197
198
		return $this;
199
	}
200
201
202
	/**
203
	 * Creates a new empty item instance
204
	 *
205
	 * @param array $values Values the item should be initialized with
206
	 * @return \Aimeos\MShop\Locale\Item\Site\Iface New locale site item object
207
	 */
208
	public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
209
	{
210
		return new \Aimeos\MShop\Locale\Item\Site\Standard( 'locale.site.', $values );
211
	}
212
213
214
	/**
215
	 * Removes multiple items.
216
	 *
217
	 * @param \Aimeos\MShop\Common\Item\Iface|array|string $items List of item objects or IDs of the items
218
	 * @return \Aimeos\MShop\Locale\Manager\Site\Iface Manager object for chaining method calls
219
	 */
220
	public function delete( $items ) : \Aimeos\MShop\Common\Manager\Iface
221
	{
222
		if( is_map( $items ) ) { $items = $items->toArray(); }
223
		if( !is_array( $items ) ) { $items = [$items]; }
224
		if( empty( $items ) ) { return $this; }
225
226
227
		$filter = $this->object()->filter()
228
			->add( ['locale.site.id' => $items] )
229
			->slice( 0, count( $items ) );
230
231
		$siteIds = $this->object()->search( $filter )->getSiteId()->toArray();
232
		$this->object()->clear( $siteIds );
233
234
235
		/** mshop/locale/manager/site/delete/mysql
236
		 * Deletes the items matched by the given IDs from the database
237
		 *
238
		 * @see mshop/locale/manager/site/delete/ansi
239
		 */
240
241
		/** mshop/locale/manager/site/delete/ansi
242
		 * Deletes the items matched by the given IDs from the database
243
		 *
244
		 * Removes the site records specified by the given IDs from the
245
		 * locale database. The records must be from the site that is configured
246
		 * via the context item.
247
		 *
248
		 * The ":cond" placeholder is replaced by the name of the ID column and
249
		 * the given ID or list of IDs while the site ID is bound to the question
250
		 * mark.
251
		 *
252
		 * The SQL statement should conform to the ANSI standard to be
253
		 * compatible with most relational database systems. This also
254
		 * includes using double quotes for table and column names.
255
		 *
256
		 * @param string SQL statement for deleting items
257
		 * @since 2015.10
258
		 * @see mshop/locale/manager/site/insert/ansi
259
		 * @see mshop/locale/manager/site/update/ansi
260
		 * @see mshop/locale/manager/site/search/ansi
261
		 * @see mshop/locale/manager/site/count/ansi
262
		 * @see mshop/locale/manager/site/newid/ansi
263
		 * @see mshop/locale/manager/site/rate/ansi
264
		 */
265
		$path = 'mshop/locale/manager/site/delete';
266
267
		return $this->deleteItemsBase( $items, $path, false );
268
	}
269
270
271
	/**
272
	 * Creates a filter object.
273
	 *
274
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
275
	 * @param bool $site TRUE for adding site criteria to limit items by the site of related items
276
	 * @return \Aimeos\Base\Criteria\Iface Returns the filter object
277
	 */
278
	public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
279
	{
280
		return $this->filterBase( 'locale.site', $default )->add( 'locale.site.level', '==', 0 );
281
	}
282
283
284
	/**
285
	 * Returns the item specified by its code and domain/type if necessary
286
	 *
287
	 * @param string $code Code of the item
288
	 * @param string[] $ref List of domains to fetch list items and referenced items for
289
	 * @param string|null $domain Domain of the item if necessary to identify the item uniquely
290
	 * @param string|null $type Type code of the item if necessary to identify the item uniquely
291
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
292
	 * @return \Aimeos\MShop\Common\Item\Iface Item object
293
	 */
294
	public function find( string $code, array $ref = [], string $domain = null, string $type = null,
295
		?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
296
	{
297
		return $this->findBase( ['locale.site.code' => $code], $ref, $default );
298
	}
299
300
301
	/**
302
	 * Returns a list of item IDs, that are in the path of given item ID.
303
	 *
304
	 * @param string $id ID of item to get the path for
305
	 * @param string[] $ref List of domains to fetch list items and referenced items for
306
	 * @return \Aimeos\Map List of IDs as keys and items implementing \Aimeos\MShop\Locale\Item\Site\Iface
307
	 */
308
	public function getPath( string $id, array $ref = [] ) : \Aimeos\Map
309
	{
310
		$item = $this->getTree( $id, $ref, \Aimeos\MW\Tree\Manager\Base::LEVEL_ONE );
311
		return map( [$item->getId() => $item] );
312
	}
313
314
315
	/**
316
	 * Returns the attributes that can be used for searching.
317
	 *
318
	 * @param bool $withsub Return also attributes of sub-managers if true
319
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
320
	 */
321
	public function getSearchAttributes( bool $withsub = true ) : array
322
	{
323
		/** mshop/locale/manager/site/submanagers
324
		 * List of manager names that can be instantiated by the locale site manager
325
		 *
326
		 * Managers provide a generic interface to the underlying storage.
327
		 * Each manager has or can have sub-managers caring about particular
328
		 * aspects. Each of these sub-managers can be instantiated by its
329
		 * parent manager using the getSubManager() method.
330
		 *
331
		 * The search keys from sub-managers can be normally used in the
332
		 * manager as well. It allows you to search for items of the manager
333
		 * using the search keys of the sub-managers to further limit the
334
		 * retrieved list of items.
335
		 *
336
		 * @param array List of sub-manager names
337
		 * @since 2015.10
338
		 */
339
		$path = 'mshop/locale/manager/site/submanagers';
340
341
		return $this->getSearchAttributesBase( $this->searchConfig, $path, [], $withsub );
342
	}
343
344
345
	/**
346
	 * Returns a node and its descendants depending on the given resource.
347
	 *
348
	 * @param string|null $id Retrieve nodes starting from the given ID
349
	 * @param string[] $ref List of domains (e.g. text, media, etc.) whose referenced items should be attached to the objects
350
	 * @param int $level One of the level constants from \Aimeos\MW\Tree\Manager\Base
351
	 * @param \Aimeos\Base\Criteria\Iface|null $criteria Optional criteria object with conditions
352
	 * @return \Aimeos\MShop\Locale\Item\Site\Iface Site node, maybe with subnodes
353
	 */
354
	public function getTree( string $id = null, array $ref = [], int $level = \Aimeos\MW\Tree\Manager\Base::LEVEL_TREE,
355
		\Aimeos\Base\Criteria\Iface $criteria = null ) : \Aimeos\MShop\Locale\Item\Site\Iface
356
	{
357
		if( $id !== null )
358
		{
359
			if( count( $ref ) > 0 ) {
360
				return $this->object()->get( $id, $ref );
361
			}
362
363
			if( !isset( $this->cache[$id] ) ) {
364
				$this->cache[$id] = $this->object()->get( $id, $ref );
365
			}
366
367
			return $this->cache[$id];
368
		}
369
370
		$criteria = $criteria ? clone $criteria : $this->object()->filter();
371
		$criteria->add( ['locale.site.code' => 'default'] )->slice( 0, 1 );
372
373
		if( ( $item = $this->object()->search( $criteria, $ref )->first() ) === null )
374
		{
375
			$msg = $this->context()->translate( 'mshop', 'Tree root with code "%1$s" in "%2$s" not found' );
376
			throw new \Aimeos\MShop\Locale\Exception( sprintf( $msg, 'default', 'locale.site.code' ) );
377
		}
378
379
		$this->cache[$item->getId()] = $item;
380
381
		return $item;
382
	}
383
384
385
	/**
386
	 * Adds a new item object.
387
	 *
388
	 * @param \Aimeos\MShop\Locale\Item\Site\Iface $item Item which should be inserted
389
	 * @param string|null $parentId ID of the parent item where the item should be inserted into
390
	 * @param string|null $refId ID of the item where the item should be inserted before (null to append)
391
	 * @return \Aimeos\MShop\Locale\Item\Site\Iface $item Updated item including the generated ID
392
	 */
393
	public function insert( \Aimeos\MShop\Locale\Item\Site\Iface $item, string $parentId = null, string $refId = null ) : \Aimeos\MShop\Locale\Item\Site\Iface
394
	{
395
		$context = $this->context();
396
		$conn = $context->db( $this->getResourceName() );
397
398
		$columns = $this->object()->getSaveAttributes();
399
400
		/** mshop/locale/manager/site/insert/mysql
401
		 * Inserts a new currency record into the database table
402
		 *
403
		 * @see mshop/locale/manager/site/insert/ansi
404
		 */
405
406
		/** mshop/locale/manager/site/insert/ansi
407
		 * Inserts a new currency record into the database table
408
		 *
409
		 * The SQL statement must be a string suitable for being used as
410
		 * prepared statement. It must include question marks for binding
411
		 * the values from the site item to the statement before they are
412
		 * sent to the database server. The number of question marks must
413
		 * be the same as the number of columns listed in the INSERT
414
		 * statement. The order of the columns must correspond to the
415
		 * order in the save() method, so the correct values are
416
		 * bound to the columns.
417
		 *
418
		 * The SQL statement should conform to the ANSI standard to be
419
		 * compatible with most relational database systems. This also
420
		 * includes using double quotes for table and column names.
421
		 *
422
		 * @param string SQL statement for inserting records
423
		 * @since 2015.10
424
		 * @see mshop/locale/manager/site/update/ansi
425
		 * @see mshop/locale/manager/site/delete/ansi
426
		 * @see mshop/locale/manager/site/search/ansi
427
		 * @see mshop/locale/manager/site/count/ansi
428
		 * @see mshop/locale/manager/site/newid/ansi
429
		 * @see mshop/locale/manager/site/rate/ansi
430
		 */
431
		$path = 'mshop/locale/manager/site/insert';
432
		$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getSqlConfig($path) can also be of type array; however, parameter $sql of Aimeos\MShop\Common\Manager\Base::addSqlColumns() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

432
		$sql = $this->addSqlColumns( array_keys( $columns ), /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ) );
Loading history...
433
434
		$idx = 1;
435
		$stmt = $this->getCachedStatement( $conn, $path, $sql );
436
437
		foreach( $columns as $name => $entry ) {
438
			$stmt->bind( $idx++, $item->get( $name ), \Aimeos\Base\Criteria\SQL::type( $entry->getType() ) );
439
		}
440
441
		$stmt->bind( $idx++, '' ); // site ID
442
		$stmt->bind( $idx++, $item->getCode() );
443
		$stmt->bind( $idx++, $item->getLabel() );
444
		$stmt->bind( $idx++, json_encode( $item->getConfig(), JSON_FORCE_OBJECT ) );
445
		$stmt->bind( $idx++, $item->getStatus(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
446
		$stmt->bind( $idx++, $item->getIcon() );
447
		$stmt->bind( $idx++, json_encode( $item->getLogos(), JSON_FORCE_OBJECT ) );
448
		$stmt->bind( $idx++, $item->getRefId() );
449
		$stmt->bind( $idx++, $item->getTheme() );
450
		$stmt->bind( $idx++, $context->editor() );
451
		$stmt->bind( $idx++, $context->datetime() ); // mtime
452
		$stmt->bind( $idx++, $context->datetime() ); // ctime
453
454
		$stmt->execute()->finish();
455
456
		/** mshop/locale/manager/site/newid/mysql
457
		 * Retrieves the ID generated by the database when inserting a new record
458
		 *
459
		 * @see mshop/locale/manager/site/newid/ansi
460
		 */
461
462
		/** mshop/locale/manager/site/newid/ansi
463
		 * Retrieves the ID generated by the database when inserting a new record
464
		 *
465
		 * As soon as a new record is inserted into the database table,
466
		 * the database server generates a new and unique identifier for
467
		 * that record. This ID can be used for retrieving, updating and
468
		 * deleting that specific record from the table again.
469
		 *
470
		 * For MySQL:
471
		 *  SELECT LAST_INSERT_ID()
472
		 * For PostgreSQL:
473
		 *  SELECT currval('seq_matt_id')
474
		 * For SQL Server:
475
		 *  SELECT SCOPE_IDENTITY()
476
		 * For Oracle:
477
		 *  SELECT "seq_matt_id".CURRVAL FROM DUAL
478
		 *
479
		 * There's no way to retrive the new ID by a SQL statements that
480
		 * fits for most database servers as they implement their own
481
		 * specific way.
482
		 *
483
		 * @param string SQL statement for retrieving the last inserted record ID
484
		 * @since 2015.10
485
		 * @see mshop/locale/manager/site/insert/ansi
486
		 * @see mshop/locale/manager/site/update/ansi
487
		 * @see mshop/locale/manager/site/delete/ansi
488
		 * @see mshop/locale/manager/site/search/ansi
489
		 * @see mshop/locale/manager/site/count/ansi
490
		 * @see mshop/locale/manager/site/rate/ansi
491
		 */
492
		$path = 'mshop/locale/manager/newid';
493
		$item->setId( $this->newId( $conn, $path ) );
494
495
		// Add unique site identifier
496
		$item = $this->object()->save( $item->setSiteId( $item->getId() . '.' ) );
497
498
		return $item;
499
	}
500
501
502
	/**
503
	 * Moves an existing item to the new parent in the storage.
504
	 *
505
	 * @param string $id ID of the item that should be moved
506
	 * @param string|null $oldParentId ID of the old parent item which currently contains the item that should be removed
507
	 * @param string|null $newParentId ID of the new parent item where the item should be moved to
508
	 * @param string|null $refId ID of the item where the item should be inserted before (null to append)
509
	 * @return \Aimeos\MShop\Locale\Manager\Site\Iface Manager object for chaining method calls
510
	 */
511
	public function move( string $id, string $oldParentId = null, string $newParentId = null,
512
		string $refId = null ) : \Aimeos\MShop\Locale\Manager\Site\Iface
513
	{
514
		$msg = $this->context()->translate( 'mshop', 'Method "%1$s" for locale site manager not available' );
515
		throw new \Aimeos\MShop\Locale\Exception( sprintf( $msg, 'move()' ) );
516
	}
517
518
519
	/**
520
	 * Updates the rating of the item
521
	 *
522
	 * @param string $id ID of the item
523
	 * @param string $rating Decimal value of the rating
524
	 * @param int $ratings Total number of ratings for the item
525
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
526
	 */
527
	public function rate( string $id, string $rating, int $ratings ) : \Aimeos\MShop\Common\Manager\Iface
528
	{
529
		$context = $this->context();
530
		$conn = $context->db( $this->getResourceName() );
531
532
			/** mshop/locale/manager/site/rate/mysql
533
			 * Updates the rating of the product in the database
534
			 *
535
			 * @see mshop/locale/manager/site/rate/ansi
536
			 */
537
538
			/** mshop/locale/manager/site/rate/ansi
539
			 * Updates the rating of the product in the database
540
			 *
541
			 * The SQL statement must be a string suitable for being used as
542
			 * prepared statement. It must include question marks for binding
543
			 * the values for the rating to the statement before they are
544
			 * sent to the database server. The order of the columns must
545
			 * correspond to the order in the rate() method, so the
546
			 * correct values are bound to the columns.
547
			 *
548
			 * The SQL statement should conform to the ANSI standard to be
549
			 * compatible with most relational database systems. This also
550
			 * includes using double quotes for table and column names.
551
			 *
552
			 * @param string SQL statement for update ratings
553
			 * @since 2022.10
554
			 * @see mshop/locale/manager/site/update/ansi
555
			 * @see mshop/locale/manager/site/delete/ansi
556
			 * @see mshop/locale/manager/site/search/ansi
557
			 * @see mshop/locale/manager/site/count/ansi
558
			 * @see mshop/locale/manager/site/newid/ansi
559
			 */
560
			$path = 'mshop/locale/manager/site/rate';
561
562
			$stmt = $this->getCachedStatement( $conn, $path, $this->getSqlConfig( $path ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getSqlConfig($path) can also be of type array; however, parameter $sql of Aimeos\MShop\Common\Mana...e::getCachedStatement() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

562
			$stmt = $this->getCachedStatement( $conn, $path, /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ) );
Loading history...
563
564
			$stmt->bind( 1, $rating );
565
			$stmt->bind( 2, $ratings, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
566
			$stmt->bind( 3, (int) $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
567
568
			$stmt->execute()->finish();
569
570
		return $this;
571
	}
572
573
574
	/**
575
	 * Registers a new item filter for the given name
576
	 *
577
	 * Not used for site items but required for trees
578
	 *
579
	 * @param string $name Filter name
580
	 * @param \Closure $fcn Callback function
581
	 */
582
	public function registerItemFilter( string $name, \Closure $fcn ) : \Aimeos\MShop\Locale\Manager\Site\Iface
583
	{
584
		return $this;
585
	}
586
587
588
	/**
589
	 * Returns the table alias name.
590
	 *
591
	 * @param string|null $attrcode Search attribute code
592
	 * @return string Table alias name
593
	 */
594
	protected function alias( string $attrcode = null ) : string
595
	{
596
		return 'mlocsi';
597
	}
598
599
600
	/**
601
	 * Returns the raw search config array.
602
	 *
603
	 * @return array List of search config arrays
604
	 */
605
	protected function getSearchConfig() : array
606
	{
607
		return $this->searchConfig;
608
	}
609
610
611
	/**
612
	 * Returns the site coditions for the search request
613
	 *
614
	 * @param string[] $keys Sorted list of criteria keys
615
	 * @param \Aimeos\Base\Criteria\Attribute\Iface[] $attributes Associative list of search keys and criteria attribute items as values
616
	 * @param int $sitelevel Site level constant from \Aimeos\MShop\Locale\Manager\Base
617
	 * @return \Aimeos\Base\Criteria\Expression\Iface[] List of search conditions
618
	 */
619
	protected function getSiteConditions( array $keys, array $attributes, int $sitelevel ) : array
620
	{
621
		return [];
622
	}
623
624
625
	/**
626
	 * Returns the prefix for the item properties and search keys.
627
	 *
628
	 * @return string Prefix for the item properties and search keys
629
	 */
630
	protected function prefix() : string
631
	{
632
		return 'locale.site.';
633
	}
634
635
636
	/**
637
	 * Adds a new site to the storage or updates an existing one.
638
	 *
639
	 * @param \Aimeos\MShop\Locale\Item\Site\Iface $item New site item for saving to the storage
640
	 * @param bool $fetch True if the new ID should be returned in the item
641
	 * @return \Aimeos\MShop\Locale\Item\Site\Iface $item Updated item including the generated ID
642
	 */
643
	protected function saveBase( \Aimeos\MShop\Common\Item\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Common\Item\Iface
644
	{
645
		if( $item->getId() === null )
646
		{
647
			$msg = $this->context()->translate( 'mshop', 'Newly created item can not be saved using method "save()", use "insert()" instead' );
648
			throw new \Aimeos\MShop\Locale\Exception( $msg );
649
		}
650
651
		if( !$item->isModified() ) {
652
			return $item;
653
		}
654
655
		$context = $this->context();
656
		$conn = $context->db( $this->getResourceName() );
657
658
		$id = $item->getId();
659
		$columns = $this->object()->getSaveAttributes();
660
661
		/** mshop/locale/manager/site/update/mysql
662
		 * Updates an existing site record in the database
663
		 *
664
		 * @see mshop/locale/manager/site/update/ansi
665
		 */
666
667
		/** mshop/locale/manager/site/update/ansi
668
		 * Updates an existing site record in the database
669
		 *
670
		 * The SQL statement must be a string suitable for being used as
671
		 * prepared statement. It must include question marks for binding
672
		 * the values from the site item to the statement before they are
673
		 * sent to the database server. The order of the columns must
674
		 * correspond to the order in the save() method, so the
675
		 * correct values are bound to the columns.
676
		 *
677
		 * The SQL statement should conform to the ANSI standard to be
678
		 * compatible with most relational database systems. This also
679
		 * includes using double quotes for table and column names.
680
		 *
681
		 * @param string SQL statement for updating records
682
		 * @since 2015.10
683
		 * @see mshop/locale/manager/site/insert/ansi
684
		 * @see mshop/locale/manager/site/delete/ansi
685
		 * @see mshop/locale/manager/site/search/ansi
686
		 * @see mshop/locale/manager/site/count/ansi
687
		 * @see mshop/locale/manager/site/newid/ansi
688
		 */
689
		$path = 'mshop/locale/manager/site/update';
690
		$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );
0 ignored issues
show
Bug introduced by
It seems like $this->getSqlConfig($path) can also be of type array; however, parameter $sql of Aimeos\MShop\Common\Manager\Base::addSqlColumns() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

690
		$sql = $this->addSqlColumns( array_keys( $columns ), /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ), false );
Loading history...
691
692
		$idx = 1;
693
		$stmt = $this->getCachedStatement( $conn, $path, $sql );
694
695
		foreach( $columns as $name => $entry ) {
696
			$stmt->bind( $idx++, $item->get( $name ), \Aimeos\Base\Criteria\SQL::type( $entry->getType() ) );
697
		}
698
699
		$stmt->bind( $idx++, $item->getSiteId() );
700
		$stmt->bind( $idx++, $item->getCode() );
701
		$stmt->bind( $idx++, $item->getLabel() );
702
		$stmt->bind( $idx++, json_encode( $item->getConfig(), JSON_FORCE_OBJECT ) );
703
		$stmt->bind( $idx++, $item->getStatus(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
704
		$stmt->bind( $idx++, $item->getIcon() );
705
		$stmt->bind( $idx++, json_encode( $item->getLogos(), JSON_FORCE_OBJECT ) );
706
		$stmt->bind( $idx++, $item->getRefId() );
707
		$stmt->bind( $idx++, $item->getTheme() );
708
		$stmt->bind( $idx++, $context->editor() );
709
		$stmt->bind( $idx++, $context->datetime() ); // mtime
710
		$stmt->bind( $idx++, $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
711
712
		$stmt->execute()->finish();
713
		$item->setId( $id ); // set Modified false
714
715
		return $item;
716
	}
717
718
719
	/** mshop/locale/manager/site/name
720
	 * Class name of the used locale site manager implementation
721
	 *
722
	 * Each default locale site manager can be replaced by an alternative imlementation.
723
	 * To use this implementation, you have to set the last part of the class
724
	 * name as configuration value so the manager factory knows which class it
725
	 * has to instantiate.
726
	 *
727
	 * For example, if the name of the default class is
728
	 *
729
	 *  \Aimeos\MShop\Locale\Manager\Site\Standard
730
	 *
731
	 * and you want to replace it with your own version named
732
	 *
733
	 *  \Aimeos\MShop\Locale\Manager\Site\Mysite
734
	 *
735
	 * then you have to set the this configuration option:
736
	 *
737
	 *  mshop/locale/manager/site/name = Mysite
738
	 *
739
	 * The value is the last part of your own class name and it's case sensitive,
740
	 * so take care that the configuration value is exactly named like the last
741
	 * part of the class name.
742
	 *
743
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
744
	 * characters are possible! You should always start the last part of the class
745
	 * name with an upper case character and continue only with lower case characters
746
	 * or numbers. Avoid chamel case names like "MySite"!
747
	 *
748
	 * @param string Last part of the class name
749
	 * @since 2015.10
750
	 */
751
752
	/** mshop/locale/manager/site/decorators/excludes
753
	 * Excludes decorators added by the "common" option from the locale site manager
754
	 *
755
	 * Decorators extend the functionality of a class by adding new aspects
756
	 * (e.g. log what is currently done), executing the methods of the underlying
757
	 * class only in certain conditions (e.g. only for logged in users) or
758
	 * modify what is returned to the caller.
759
	 *
760
	 * This option allows you to remove a decorator added via
761
	 * "mshop/common/manager/decorators/default" before they are wrapped
762
	 * around the locale site manager.
763
	 *
764
	 *  mshop/locale/manager/site/decorators/excludes = array( 'decorator1' )
765
	 *
766
	 * This would remove the decorator named "decorator1" from the list of
767
	 * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
768
	 * "mshop/common/manager/decorators/default" for the locale site manager.
769
	 *
770
	 * @param array List of decorator names
771
	 * @since 2015.10
772
	 * @see mshop/common/manager/decorators/default
773
	 * @see mshop/locale/manager/site/decorators/global
774
	 * @see mshop/locale/manager/site/decorators/local
775
	 */
776
777
	/** mshop/locale/manager/site/decorators/global
778
	 * Adds a list of globally available decorators only to the locale site manager
779
	 *
780
	 * Decorators extend the functionality of a class by adding new aspects
781
	 * (e.g. log what is currently done), executing the methods of the underlying
782
	 * class only in certain conditions (e.g. only for logged in users) or
783
	 * modify what is returned to the caller.
784
	 *
785
	 * This option allows you to wrap global decorators
786
	 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the locale site
787
	 * manager.
788
	 *
789
	 *  mshop/locale/manager/site/decorators/global = array( 'decorator1' )
790
	 *
791
	 * This would add the decorator named "decorator1" defined by
792
	 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the locale
793
	 * site manager.
794
	 *
795
	 * @param array List of decorator names
796
	 * @since 2015.10
797
	 * @see mshop/common/manager/decorators/default
798
	 * @see mshop/locale/manager/site/decorators/excludes
799
	 * @see mshop/locale/manager/site/decorators/local
800
	 */
801
802
	/** mshop/locale/manager/site/decorators/local
803
	 * Adds a list of local decorators only to the locale site manager
804
	 *
805
	 * Decorators extend the functionality of a class by adding new aspects
806
	 * (e.g. log what is currently done), executing the methods of the underlying
807
	 * class only in certain conditions (e.g. only for logged in users) or
808
	 * modify what is returned to the caller.
809
	 *
810
	 * This option allows you to wrap local decorators
811
	 * ("\Aimeos\MShop\Locale\Manager\Site\Decorator\*") around the locale site
812
	 * manager.
813
	 *
814
	 *  mshop/locale/manager/site/decorators/local = array( 'decorator2' )
815
	 *
816
	 * This would add the decorator named "decorator2" defined by
817
	 * "\Aimeos\MShop\Locale\Manager\Site\Decorator\Decorator2" only to the
818
	 * locale site manager.
819
	 *
820
	 * @param array List of decorator names
821
	 * @since 2015.10
822
	 * @see mshop/common/manager/decorators/default
823
	 * @see mshop/locale/manager/site/decorators/excludes
824
	 * @see mshop/locale/manager/site/decorators/global
825
	 */
826
827
	/** mshop/locale/manager/site/search/mysql
828
	 * Retrieves the records matched by the given criteria in the database
829
	 *
830
	 * @see mshop/locale/manager/site/search/ansi
831
	 */
832
833
	/** mshop/locale/manager/site/search/ansi
834
	 * Retrieves the records matched by the given criteria in the database
835
	 *
836
	 * Fetches the records matched by the given criteria from the attribute
837
	 * database. The records must be from one of the sites that are
838
	 * configured via the context item. If the current site is part of
839
	 * a tree of sites, the SELECT statement can retrieve all records
840
	 * from the current site and the complete sub-tree of sites.
841
	 *
842
	 * As the records can normally be limited by criteria from sub-managers,
843
	 * their tables must be joined in the SQL context. This is done by
844
	 * using the "internaldeps" property from the definition of the ID
845
	 * column of the sub-managers. These internal dependencies specify
846
	 * the JOIN between the tables and the used columns for joining. The
847
	 * ":joins" placeholder is then replaced by the JOIN strings from
848
	 * the sub-managers.
849
	 *
850
	 * To limit the records matched, conditions can be added to the given
851
	 * criteria object. It can contain comparisons like column names that
852
	 * must match specific values which can be combined by AND, OR or NOT
853
	 * operators. The resulting string of SQL conditions replaces the
854
	 * ":cond" placeholder before the statement is sent to the database
855
	 * server.
856
	 *
857
	 * If the records that are retrieved should be ordered by one or more
858
	 * columns, the generated string of column / sort direction pairs
859
	 * replaces the ":order" placeholder. Columns of
860
	 * sub-managers can also be used for ordering the result set but then
861
	 * no index can be used.
862
	 *
863
	 * The number of returned records can be limited and can start at any
864
	 * number between the begining and the end of the result set. For that
865
	 * the ":size" and ":start" placeholders are replaced by the
866
	 * corresponding values from the criteria object. The default values
867
	 * are 0 for the start and 100 for the size value.
868
	 *
869
	 * The SQL statement should conform to the ANSI standard to be
870
	 * compatible with most relational database systems. This also
871
	 * includes using double quotes for table and column names.
872
	 *
873
	 * @param string SQL statement for searching items
874
	 * @since 2015.10
875
	 * @see mshop/locale/manager/site/insert/ansi
876
	 * @see mshop/locale/manager/site/update/ansi
877
	 * @see mshop/locale/manager/site/delete/ansi
878
	 * @see mshop/locale/manager/site/count/ansi
879
	 * @see mshop/locale/manager/site/newid/ansi
880
	 * @see mshop/locale/manager/site/rate/ansi
881
	 */
882
883
	/** mshop/locale/manager/site/count/mysql
884
	 * Counts the number of records matched by the given criteria in the database
885
	 *
886
	 * @see mshop/locale/manager/site/count/ansi
887
	 */
888
889
	/** mshop/locale/manager/site/count/ansi
890
	 * Counts the number of records matched by the given criteria in the database
891
	 *
892
	 * Counts all records matched by the given criteria from the attribute
893
	 * database. The records must be from one of the sites that are
894
	 * configured via the context item. If the current site is part of
895
	 * a tree of sites, the statement can count all records from the
896
	 * current site and the complete sub-tree of sites.
897
	 *
898
	 * As the records can normally be limited by criteria from sub-managers,
899
	 * their tables must be joined in the SQL context. This is done by
900
	 * using the "internaldeps" property from the definition of the ID
901
	 * column of the sub-managers. These internal dependencies specify
902
	 * the JOIN between the tables and the used columns for joining. The
903
	 * ":joins" placeholder is then replaced by the JOIN strings from
904
	 * the sub-managers.
905
	 *
906
	 * To limit the records matched, conditions can be added to the given
907
	 * criteria object. It can contain comparisons like column names that
908
	 * must match specific values which can be combined by AND, OR or NOT
909
	 * operators. The resulting string of SQL conditions replaces the
910
	 * ":cond" placeholder before the statement is sent to the database
911
	 * server.
912
	 *
913
	 * Both, the strings for ":joins" and for ":cond" are the same as for
914
	 * the "search" SQL statement.
915
	 *
916
	 * Contrary to the "search" statement, it doesn't return any records
917
	 * but instead the number of records that have been found. As counting
918
	 * thousands of records can be a long running task, the maximum number
919
	 * of counted records is limited for performance reasons.
920
	 *
921
	 * The SQL statement should conform to the ANSI standard to be
922
	 * compatible with most relational database systems. This also
923
	 * includes using double quotes for table and column names.
924
	 *
925
	 * @param string SQL statement for counting items
926
	 * @since 2015.10
927
	 * @see mshop/locale/manager/site/insert/ansi
928
	 * @see mshop/locale/manager/site/update/ansi
929
	 * @see mshop/locale/manager/site/delete/ansi
930
	 * @see mshop/locale/manager/site/search/ansi
931
	 * @see mshop/locale/manager/site/newid/ansi
932
	 */
933
}
934