• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aimeos / aimeos-core / 8e9e29f5-efc2-4de8-8a2b-c3576f489780

17 Sep 2024 08:12AM UTC coverage: 92.154% (-0.03%) from 92.185%
8e9e29f5-efc2-4de8-8a2b-c3576f489780

push

circleci

aimeos
Moved fetching locale/site items to manager decorator

12 of 13 new or added lines in 1 file covered. (92.31%)

3 existing lines in 1 file now uncovered.

9784 of 10617 relevant lines covered (92.15%)

74.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.43
/src/MShop/Product/Manager/Standard.php
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 Product
8
 */
9

10

11
namespace Aimeos\MShop\Product\Manager;
12

13

14
/**
15
 * Default product manager.
16
 *
17
 * @package MShop
18
 * @subpackage Product
19
 */
20
class Standard
21
        extends \Aimeos\MShop\Common\Manager\Base
22
        implements \Aimeos\MShop\Product\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface,
23
                \Aimeos\MShop\Common\Manager\ListsRef\Iface, \Aimeos\MShop\Common\Manager\PropertyRef\Iface
24
{
25
        use \Aimeos\MShop\Common\Manager\ListsRef\Traits;
26
        use \Aimeos\MShop\Common\Manager\PropertyRef\Traits;
27

28

29
        private array $cacheTags = [];
30

31

32
        /**
33
         * Commits the running database transaction on the connection identified by the given name
34
         *
35
         * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
36
         */
37
        public function commit() : \Aimeos\MShop\Common\Manager\Iface
38
        {
39
                parent::commit();
×
40

41
                $this->context()->cache()->deleteByTags( $this->cacheTags );
×
42
                $this->cacheTags = [];
×
43

44
                return $this;
×
45
        }
46

47

48
        /**
49
         * Creates a new empty item instance
50
         *
51
         * @param array $values Values the item should be initialized with
52
         * @return \Aimeos\MShop\Product\Item\Iface New product item object
53
         */
54
        public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
55
        {
56
                $context = $this->context();
276✔
57

58
                $values['.date'] = $context->datetime();
276✔
59
                $values['product.siteid'] = $values['product.siteid'] ?? $context->locale()->getSiteId();
276✔
60

61
                return new \Aimeos\MShop\Product\Item\Standard( 'product.', $values );
276✔
62
        }
63

64

65
        /**
66
         * Removes multiple items.
67
         *
68
         * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $items List of item objects or IDs of the items
69
         * @return \Aimeos\MShop\Product\Manager\Iface Manager object for chaining method calls
70
         */
71
        public function delete( $items ) : \Aimeos\MShop\Common\Manager\Iface
72
        {
73
                parent::delete( $items )->deleteRefItems( $items );
16✔
74

75
                $this->cacheTags = array_merge( $this->cacheTags, map( $items )->copy()->cast()->prefix( 'product-' )->all() );
16✔
76

77
                return $this;
16✔
78
        }
79

80

81
        /**
82
         * Creates a filter object.
83
         *
84
         * @param bool|null $default Add default criteria or NULL for relaxed default criteria
85
         * @param bool $site TRUE for adding site criteria to limit items by the site of related items
86
         * @return \Aimeos\Base\Criteria\Iface Returns the filter object
87
         */
88
        public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
89
        {
90
                $object = $this->filterBase( 'product', $default );
236✔
91

92
                if( $default !== false )
236✔
93
                {
94
                        $date = $this->context()->datetime();
48✔
95

96
                        $start = [
48✔
97
                                $object->compare( '<=', 'product.datestart', $date ),
48✔
98
                                $object->compare( '==', 'product.datestart', null ),
48✔
99
                                $object->compare( '==', 'product.type', 'event' ),
48✔
100
                        ];
48✔
101

102
                        $end = [
48✔
103
                                $object->compare( '>=', 'product.dateend', $date ),
48✔
104
                                $object->compare( '==', 'product.dateend', null ),
48✔
105
                        ];
48✔
106

107
                        /** mshop/product/manager/strict-events
108
                         * Hide events automatically if they are over
109
                         *
110
                         * Events are hidden by default if they are finished, removed from the
111
                         * list view and can't be bought any more. If you sell webinars including
112
                         * an archive of old ones you want to continue to sell for example, then
113
                         * these webinars should be still shown.
114
                         *
115
                         * Setting this configuration option to false will display event products
116
                         * that are already over and customers can still buy them.
117
                         *
118
                         * @param bool TRUE to hide events after they are over (default), FALSE to continue to show them
119
                         * @since 2019.10
120
                         */
121
                        if( !$this->context()->config()->get( 'mshop/product/manager/strict-events', true ) ) {
48✔
122
                                $end[] = $object->compare( '==', 'product.type', 'event' );
1✔
123
                        }
124

125
                        $object->setConditions( $object->and( [
48✔
126
                                $object->getConditions(),
48✔
127
                                $object->or( $start ),
48✔
128
                                $object->or( $end ),
48✔
129
                        ] ) );
48✔
130
                }
131

132
                return $object;
236✔
133
        }
134

135

136
        /**
137
         * Returns the item specified by its code and domain/type if necessary
138
         *
139
         * @param string $code Code of the item
140
         * @param string[] $ref List of domains to fetch list items and referenced items for
141
         * @param string|null $domain Domain of the item if necessary to identify the item uniquely
142
         * @param string|null $type Type code of the item if necessary to identify the item uniquely
143
         * @param bool|null $default Add default criteria or NULL for relaxed default criteria
144
         * @return \Aimeos\MShop\Common\Item\Iface Item object
145
         */
146
        public function find( string $code, array $ref = [], string $domain = null, string $type = null,
147
                ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
148
        {
149
                return $this->findBase( ['product.code' => $code], $ref, $default );
89✔
150
        }
151

152

153
        /**
154
         * Returns the additional column/search definitions
155
         *
156
         * @return array Associative list of column names as keys and items implementing \Aimeos\Base\Criteria\Attribute\Iface
157
         */
158
        public function getSaveAttributes() : array
159
        {
160
                return $this->createAttributes( [
198✔
161
                        'product.type' => [
198✔
162
                                'label' => 'Type',
198✔
163
                                'internalcode' => 'type',
198✔
164
                        ],
198✔
165
                        'product.label' => [
198✔
166
                                'label' => 'Label',
198✔
167
                                'internalcode' => 'label',
198✔
168
                        ],
198✔
169
                        'product.code' => [
198✔
170
                                'label' => 'SKU',
198✔
171
                                'internalcode' => 'code',
198✔
172
                        ],
198✔
173
                        'product.url' => [
198✔
174
                                'label' => 'URL segment',
198✔
175
                                'internalcode' => 'url',
198✔
176
                        ],
198✔
177
                        'product.dataset' => [
198✔
178
                                'label' => 'Data set',
198✔
179
                                'internalcode' => 'dataset',
198✔
180
                        ],
198✔
181
                        'product.datestart' => [
198✔
182
                                'label' => 'Start date/time',
198✔
183
                                'internalcode' => 'start',
198✔
184
                                'type' => 'datetime',
198✔
185
                        ],
198✔
186
                        'product.dateend' => [
198✔
187
                                'label' => 'End date/time',
198✔
188
                                'internalcode' => 'end',
198✔
189
                                'type' => 'datetime',
198✔
190
                        ],
198✔
191
                        'product.instock' => [
198✔
192
                                'label' => 'Product in stock',
198✔
193
                                'internalcode' => 'instock',
198✔
194
                                'type' => 'int',
198✔
195
                        ],
198✔
196
                        'product.status' => [
198✔
197
                                'label' => 'Status',
198✔
198
                                'internalcode' => 'status',
198✔
199
                                'type' => 'int',
198✔
200
                        ],
198✔
201
                        'product.scale' => [
198✔
202
                                'label' => 'Quantity scale',
198✔
203
                                'internalcode' => 'scale',
198✔
204
                                'type' => 'float',
198✔
205
                        ],
198✔
206
                        'product.boost' => [
198✔
207
                                'label' => 'Boost factor',
198✔
208
                                'internalcode' => 'boost',
198✔
209
                                'type' => 'float',
198✔
210
                        ],
198✔
211
                        'product.config' => [
198✔
212
                                'label' => 'Configuration',
198✔
213
                                'internalcode' => 'config',
198✔
214
                                'type' => 'json',
198✔
215
                                'public' => false,
198✔
216
                        ],
198✔
217
                        'product.target' => [
198✔
218
                                'label' => 'URL target',
198✔
219
                                'internalcode' => 'target',
198✔
220
                                'public' => false,
198✔
221
                        ],
198✔
222
                        'product.rating' => [
198✔
223
                                'label' => 'Rating value',
198✔
224
                                'internalcode' => 'rating',
198✔
225
                                'type' => 'decimal',
198✔
226
                                'public' => false,
198✔
227
                        ],
198✔
228
                        'product.ratings' => [
198✔
229
                                'label' => 'Number of ratings',
198✔
230
                                'internalcode' => 'ratings',
198✔
231
                                'type' => 'int',
198✔
232
                                'public' => false,
198✔
233
                        ],
198✔
234
                ] );
198✔
235
        }
236

237

238
        /**
239
         * Returns the attributes that can be used for searching.
240
         *
241
         * @param bool $withsub Return also attributes of sub-managers if true
242
         * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items
243
         */
244
        public function getSearchAttributes( bool $withsub = true ) : array
245
        {
246
                $level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
198✔
247
                $level = $this->context()->config()->get( 'mshop/product/manager/sitemode', $level );
198✔
248

249
                return array_replace( parent::getSearchAttributes( $withsub ), $this->createAttributes( [
198✔
250
                        'product:has' => array(
198✔
251
                                'code' => 'product:has()',
198✔
252
                                'internalcode' => ':site AND :key AND mproli."id"',
198✔
253
                                'internaldeps' => ['LEFT JOIN "mshop_product_list" AS mproli ON ( mproli."parentid" = mpro."id" )'],
198✔
254
                                'label' => 'Product has list item, parameter(<domain>[,<list type>[,<reference ID>)]]',
198✔
255
                                'type' => 'null',
198✔
256
                                'public' => false,
198✔
257
                                        'function' => function( &$source, array $params ) use ( $level ) {
198✔
258
                                        $keys = [];
18✔
259

260
                                        foreach( (array) ( $params[1] ?? '' ) as $type ) {
18✔
261
                                                foreach( (array) ( $params[2] ?? '' ) as $id ) {
18✔
262
                                                        $keys[] = $params[0] . '|' . ( $type ? $type . '|' : '' ) . $id;
18✔
263
                                                }
264
                                        }
265

266
                                        $sitestr = $this->siteString( 'mproli."siteid"', $level );
18✔
267
                                        $keystr = $this->toExpression( 'mproli."key"', $keys, ( $params[2] ?? null ) ? '==' : '=~' );
18✔
268
                                        $source = str_replace( [':site', ':key'], [$sitestr, $keystr], $source );
18✔
269

270
                                        return $params;
18✔
271
                                }
198✔
272
                        ),
198✔
273
                        'product:prop' => array(
198✔
274
                                'code' => 'product:prop()',
198✔
275
                                'internalcode' => ':site AND :key AND mpropr."id"',
198✔
276
                                'internaldeps' => ['LEFT JOIN "mshop_product_property" AS mpropr ON ( mpropr."parentid" = mpro."id" )'],
198✔
277
                                'label' => 'Product has property item, parameter(<property type>[,<language code>[,<property value>]])',
198✔
278
                                'type' => 'null',
198✔
279
                                'public' => false,
198✔
280
                                'function' => function( &$source, array $params ) use ( $level ) {
198✔
281
                                        $keys = [];
3✔
282
                                        $langs = array_key_exists( 1, $params ) ? ( $params[1] ?? 'null' ) : '';
3✔
283

284
                                        foreach( (array) $langs as $lang ) {
3✔
285
                                                foreach( (array) ( $params[2] ?? '' ) as $val ) {
3✔
286
                                                        $keys[] = substr( $params[0] . '|' . ( $lang === null ? 'null|' : ( $lang ? $lang . '|' : '' ) ) . $val, 0, 255 );
3✔
287
                                                }
288
                                        }
289

290
                                        $sitestr = $this->siteString( 'mpropr."siteid"', $level );
3✔
291
                                        $keystr = $this->toExpression( 'mpropr."key"', $keys, ( $params[2] ?? null ) ? '==' : '=~' );
3✔
292
                                        $source = str_replace( [':site', ':key'], [$sitestr, $keystr], $source );
3✔
293

294
                                        return $params;
3✔
295
                                }
198✔
296
                        ),
198✔
297
                ] ) );
198✔
298
        }
299

300

301
        /**
302
         * Updates the rating of the item
303
         *
304
         * @param string $id ID of the item
305
         * @param string $rating Decimal value of the rating
306
         * @param int $ratings Total number of ratings for the item
307
         * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
308
         */
309
        public function rate( string $id, string $rating, int $ratings ) : \Aimeos\MShop\Common\Manager\Iface
310
        {
311
                $context = $this->context();
2✔
312
                $conn = $context->db( $this->getResourceName() );
2✔
313

314
                /** mshop/product/manager/rate/mysql
315
                 * Updates the rating of the product in the database
316
                 *
317
                 * @see mshop/product/manager/rate/ansi
318
                 */
319

320
                /** mshop/product/manager/rate/ansi
321
                 * Updates the rating of the product in the database
322
                 *
323
                 * The SQL statement must be a string suitable for being used as
324
                 * prepared statement. It must include question marks for binding
325
                 * the values for the rating to the statement before they are
326
                 * sent to the database server. The order of the columns must
327
                 * correspond to the order in the rate() method, so the
328
                 * correct values are bound to the columns.
329
                 *
330
                 * The SQL statement should conform to the ANSI standard to be
331
                 * compatible with most relational database systems. This also
332
                 * includes using double quotes for table and column names.
333
                 *
334
                 * @param string SQL statement for update ratings
335
                 * @since 2020.10
336
                 * @see mshop/product/manager/insert/ansi
337
                 * @see mshop/product/manager/update/ansi
338
                 * @see mshop/product/manager/newid/ansi
339
                 * @see mshop/product/manager/delete/ansi
340
                 * @see mshop/product/manager/search/ansi
341
                 * @see mshop/product/manager/count/ansi
342
                 * @see mshop/product/manager/stock/ansi
343
                 */
344
                $path = 'mshop/product/manager/rate';
2✔
345

346
                $stmt = $this->getCachedStatement( $conn, $path, $this->getSqlConfig( $path ) );
2✔
347

348
                $stmt->bind( 1, $rating );
2✔
349
                $stmt->bind( 2, $ratings, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
2✔
350
                $stmt->bind( 3, $context->locale()->getSiteId() );
2✔
351
                $stmt->bind( 4, (int) $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
2✔
352

353
                $stmt->execute()->finish();
2✔
354

355
                return $this;
2✔
356
        }
357

358

359
        /**
360
         * Updates if the product is in stock
361
         *
362
         * @param string $id ID of the procuct item
363
         * @param int $value "0" or "1" if product is in stock or not
364
         * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
365
         */
366
        public function stock( string $id, int $value ) : \Aimeos\MShop\Common\Manager\Iface
367
        {
368
                $context = $this->context();
2✔
369
                $conn = $context->db( $this->getResourceName() );
2✔
370

371
                /** mshop/product/manager/stock/mysql
372
                 * Updates the rating of the product in the database
373
                 *
374
                 * @see mshop/product/manager/stock/ansi
375
                 */
376

377
                /** mshop/product/manager/stock/ansi
378
                 * Updates the rating of the product in the database
379
                 *
380
                 * The SQL statement must be a string suitable for being used as
381
                 * prepared statement. It must include question marks for binding
382
                 * the values for the rating to the statement before they are
383
                 * sent to the database server. The order of the columns must
384
                 * correspond to the order in the stock() method, so the
385
                 * correct values are bound to the columns.
386
                 *
387
                 * The SQL statement should conform to the ANSI standard to be
388
                 * compatible with most relational database systems. This also
389
                 * includes using double quotes for table and column names.
390
                 *
391
                 * @param string SQL statement for update ratings
392
                 * @since 2021.10
393
                 * @see mshop/product/manager/insert/ansi
394
                 * @see mshop/product/manager/update/ansi
395
                 * @see mshop/product/manager/newid/ansi
396
                 * @see mshop/product/manager/delete/ansi
397
                 * @see mshop/product/manager/search/ansi
398
                 * @see mshop/product/manager/count/ansi
399
                 * @see mshop/product/manager/rate/ansi
400
                 */
401
                $path = 'mshop/product/manager/stock';
2✔
402

403
                $stmt = $this->getCachedStatement( $conn, $path, $this->getSqlConfig( $path ) );
2✔
404

405
                $stmt->bind( 1, $value, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
2✔
406
                $stmt->bind( 2, $context->locale()->getSiteId() );
2✔
407
                $stmt->bind( 3, (int) $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );
2✔
408

409
                $stmt->execute()->finish();
2✔
410

411
                return $this;
2✔
412
        }
413

414

415
        /**
416
         * Adds or updates an item object or a list of them.
417
         *
418
         * @param \Aimeos\Map|\Aimeos\MShop\Common\Item\Iface[]|\Aimeos\MShop\Common\Item\Iface $items Item or list of items whose data should be saved
419
         * @param bool $fetch True if the new ID should be returned in the item
420
         * @return \Aimeos\Map|\Aimeos\MShop\Common\Item\Iface Saved item or items
421
         */
422
        public function save( $items, bool $fetch = true )
423
        {
424
                $items = parent::save( $items, $fetch );
20✔
425

426
                if( ( $ids = map( $items )->getId()->filter() )->count() === map( $items )->count() ) {
20✔
427
                        $this->cacheTags = array_merge( $this->cacheTags, map( $ids )->prefix( 'product-' )->all() );
20✔
428
                } else {
429
                        $this->cacheTags[] = 'product';
×
430
                }
431

432
                return $items;
20✔
433
        }
434

435

436
        /**
437
         * Saves the dependent items of the item
438
         *
439
         * @param \Aimeos\MShop\Common\Item\Iface $item Item object
440
         * @param bool $fetch True if the new ID should be returned in the item
441
         * @return \Aimeos\MShop\Common\Item\Iface Updated item
442
         */
443
        public function saveRefs( \Aimeos\MShop\Common\Item\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Common\Item\Iface
444
        {
445
                $this->savePropertyItems( $item, 'product', $fetch );
20✔
446
                $this->saveListItems( $item, 'product', $fetch );
20✔
447

448
                return $item;
20✔
449
        }
450

451

452
        /**
453
         * Merges the data from the given map and the referenced items
454
         *
455
         * @param array $entries Associative list of ID as key and the associative list of property key/value pairs as values
456
         * @param array $ref List of referenced items to fetch and add to the entries
457
         * @return array Associative list of ID as key and the updated entries as value
458
         */
459
        public function searchRefs( array $entries, array $ref ) : array
460
        {
461
                $parentIds = array_keys( $entries );
177✔
462

463
                foreach( $this->getStockItems( $parentIds, $ref ) as $stockId => $stockItem ) {
177✔
464
                        $entries[$stockItem->getProductId()]['.stock'][$stockId] = $stockItem;
2✔
465
                }
466

467
                if( $this->hasRef( $ref, 'product/property' ) )
177✔
468
                {
469
                        $name = 'product/property';
8✔
470
                        $propTypes = isset( $ref[$name] ) && is_array( $ref[$name] ) ? $ref[$name] : null;
8✔
471

472
                        foreach( $this->getPropertyItems( $parentIds, 'product', $propTypes ) as $id => $list ) {
8✔
473
                                $entries[$id]['.propitems'] = $list;
8✔
474
                        }
475
                }
476

477
                foreach( $this->getListItems( $parentIds, $ref, 'product' ) as $id => $listItem ) {
177✔
478
                        $entries[$listItem->getParentId()]['.listitems'][$id] = $listItem;
49✔
479
                }
480

481
                return $entries;
177✔
482
        }
483

484

485
        /**
486
         * Returns the stock items for the given product codes
487
         *
488
         * @param array $entries List of product records
489
         * @return \Aimeos\Map List of product IDs as keys and items implementing \Aimeos\MShop\Locale\Item\Site\Iface as values
490
         * @deprecated 2025.01 Done by site decorator
491
         */
492
        protected function getSiteItems( array $siteIds ) : \Aimeos\Map
493
        {
UNCOV
494
                $manager = \Aimeos\MShop::create( $this->context(), 'locale/site' );
×
UNCOV
495
                $filter = $manager->filter( true )->add( ['locale.site.siteid' => $siteIds] )->slice( 0, 0x7fffffff );
×
496

UNCOV
497
                return $manager->search( $filter )->col( null, 'locale.site.siteid' );
×
498
        }
499

500

501
        /**
502
         * Returns the stock items for the given product codes
503
         *
504
         * @param string[] $ids Unique product codes
505
         * @param string[] $ref List of domains to fetch referenced items for
506
         * @return \Aimeos\Map List of IDs as keys and items implementing \Aimeos\MShop\Stock\Item\Iface as values
507
         */
508
        protected function getStockItems( array $ids, array $ref ) : \Aimeos\Map
509
        {
510
                if( !$this->hasRef( $ref, 'stock' ) ) {
177✔
511
                        return map();
175✔
512
                }
513

514
                $manager = \Aimeos\MShop::create( $this->context(), 'stock' );
2✔
515
                $filter = $manager->filter( true )->add( 'stock.productid', '==', $ids )->slice( 0, 0x7fffffff );
2✔
516

517
                if( isset( $ref['stock'] ) && is_array( $ref['stock'] ) ) {
2✔
518
                        $filter->add( 'stock.type', '==', $ref['stock'] );
×
519
                }
520

521
                return $manager->search( $filter );
2✔
522
        }
523

524

525
        /**
526
         * Returns the prefix for the item properties and search keys.
527
         *
528
         * @return string Prefix for the item properties and search keys
529
         */
530
        protected function prefix() : string
531
        {
532
                return 'product.';
198✔
533
        }
534

535

536
        /** mshop/product/manager/resource
537
         * Name of the database connection resource to use
538
         *
539
         * You can configure a different database connection for each data domain
540
         * and if no such connection name exists, the "db" connection will be used.
541
         * It's also possible to use the same database connection for different
542
         * data domains by configuring the same connection name using this setting.
543
         *
544
         * @param string Database connection name
545
         * @since 2023.04
546
         */
547

548
        /** mshop/product/manager/name
549
         * Class name of the used product manager implementation
550
         *
551
         * Each default manager can be replace by an alternative imlementation.
552
         * To use this implementation, you have to set the last part of the class
553
         * name as configuration value so the manager factory knows which class it
554
         * has to instantiate.
555
         *
556
         * For example, if the name of the default class is
557
         *
558
         *  \Aimeos\MShop\Product\Manager\Standard
559
         *
560
         * and you want to replace it with your own version named
561
         *
562
         *  \Aimeos\MShop\Product\Manager\Mymanager
563
         *
564
         * then you have to set the this configuration option:
565
         *
566
         *  mshop/product/manager/name = Mymanager
567
         *
568
         * The value is the last part of your own class name and it's case sensitive,
569
         * so take care that the configuration value is exactly named like the last
570
         * part of the class name.
571
         *
572
         * The allowed characters of the class name are A-Z, a-z and 0-9. No other
573
         * characters are possible! You should always start the last part of the class
574
         * name with an upper case character and continue only with lower case characters
575
         * or numbers. Avoid chamel case names like "MyManager"!
576
         *
577
         * @param string Last part of the class name
578
         * @since 2014.03
579
         */
580

581
        /** mshop/product/manager/decorators/excludes
582
         * Excludes decorators added by the "common" option from the product manager
583
         *
584
         * Decorators extend the functionality of a class by adding new aspects
585
         * (e.g. log what is currently done), executing the methods of the underlying
586
         * class only in certain conditions (e.g. only for logged in users) or
587
         * modify what is returned to the caller.
588
         *
589
         * This option allows you to remove a decorator added via
590
         * "mshop/common/manager/decorators/default" before they are wrapped
591
         * around the product manager.
592
         *
593
         *  mshop/product/manager/decorators/excludes = array( 'decorator1' )
594
         *
595
         * This would remove the decorator named "decorator1" from the list of
596
         * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
597
         * "mshop/common/manager/decorators/default" for the product manager.
598
         *
599
         * @param array List of decorator names
600
         * @since 2014.03
601
         * @see mshop/common/manager/decorators/default
602
         * @see mshop/product/manager/decorators/global
603
         * @see mshop/product/manager/decorators/local
604
         */
605

606
        /** mshop/product/manager/decorators/global
607
         * Adds a list of globally available decorators only to the product manager
608
         *
609
         * Decorators extend the functionality of a class by adding new aspects
610
         * (e.g. log what is currently done), executing the methods of the underlying
611
         * class only in certain conditions (e.g. only for logged in users) or
612
         * modify what is returned to the caller.
613
         *
614
         * This option allows you to wrap global decorators
615
         * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the product manager.
616
         *
617
         *  mshop/product/manager/decorators/global = array( 'decorator1' )
618
         *
619
         * This would add the decorator named "decorator1" defined by
620
         * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the product
621
         * manager.
622
         *
623
         * @param array List of decorator names
624
         * @since 2014.03
625
         * @see mshop/common/manager/decorators/default
626
         * @see mshop/product/manager/decorators/excludes
627
         * @see mshop/product/manager/decorators/local
628
         */
629

630
        /** mshop/product/manager/decorators/local
631
         * Adds a list of local decorators only to the product manager
632
         *
633
         * Decorators extend the functionality of a class by adding new aspects
634
         * (e.g. log what is currently done), executing the methods of the underlying
635
         * class only in certain conditions (e.g. only for logged in users) or
636
         * modify what is returned to the caller.
637
         *
638
         * This option allows you to wrap local decorators
639
         * ("\Aimeos\MShop\Product\Manager\Decorator\*") around the product manager.
640
         *
641
         *  mshop/product/manager/decorators/local = array( 'decorator2' )
642
         *
643
         * This would add the decorator named "decorator2" defined by
644
         * "\Aimeos\MShop\Product\Manager\Decorator\Decorator2" only to the product
645
         * manager.
646
         *
647
         * @param array List of decorator names
648
         * @since 2014.03
649
         * @see mshop/common/manager/decorators/default
650
         * @see mshop/product/manager/decorators/excludes
651
         * @see mshop/product/manager/decorators/global
652
         */
653

654
        /** mshop/product/manager/submanagers
655
         * List of manager names that can be instantiated by the product manager
656
         *
657
         * Managers provide a generic interface to the underlying storage.
658
         * Each manager has or can have sub-managers caring about particular
659
         * aspects. Each of these sub-managers can be instantiated by its
660
         * parent manager using the getSubManager() method.
661
         *
662
         * The search keys from sub-managers can be normally used in the
663
         * manager as well. It allows you to search for items of the manager
664
         * using the search keys of the sub-managers to further limit the
665
         * retrieved list of items.
666
         *
667
         * @param array List of sub-manager names
668
         * @since 2014.03
669
         */
670

671
        /** mshop/product/manager/delete/mysql
672
         * Deletes the items matched by the given IDs from the database
673
         *
674
         * @see mshop/product/manager/delete/ansi
675
         */
676

677
        /** mshop/product/manager/delete/ansi
678
         * Deletes the items matched by the given IDs from the database
679
         *
680
         * Removes the records specified by the given IDs from the product database.
681
         * The records must be from the site that is configured via the
682
         * context item.
683
         *
684
         * The ":cond" placeholder is replaced by the name of the ID column and
685
         * the given ID or list of IDs while the site ID is bound to the question
686
         * mark.
687
         *
688
         * The SQL statement should conform to the ANSI standard to be
689
         * compatible with most relational database systems. This also
690
         * includes using double quotes for table and column names.
691
         *
692
         * @param string SQL statement for deleting items
693
         * @since 2014.03
694
         * @see mshop/product/manager/insert/ansi
695
         * @see mshop/product/manager/update/ansi
696
         * @see mshop/product/manager/newid/ansi
697
         * @see mshop/product/manager/search/ansi
698
         * @see mshop/product/manager/count/ansi
699
         * @see mshop/product/manager/rate/ansi
700
         * @see mshop/product/manager/stock/ansi
701
         */
702

703
        /** mshop/product/manager/insert/mysql
704
         * Inserts a new product record into the database table
705
         *
706
         * @see mshop/product/manager/insert/ansi
707
         */
708

709
        /** mshop/product/manager/insert/ansi
710
         * Inserts a new product record into the database table
711
         *
712
         * Items with no ID yet (i.e. the ID is NULL) will be created in
713
         * the database and the newly created ID retrieved afterwards
714
         * using the "newid" SQL statement.
715
         *
716
         * The SQL statement must be a string suitable for being used as
717
         * prepared statement. It must include question marks for binding
718
         * the values from the product item to the statement before they are
719
         * sent to the database server. The number of question marks must
720
         * be the same as the number of columns listed in the INSERT
721
         * statement. The order of the columns must correspond to the
722
         * order in the save() method, so the correct values are
723
         * bound to the columns.
724
         *
725
         * The SQL statement should conform to the ANSI standard to be
726
         * compatible with most relational database systems. This also
727
         * includes using double quotes for table and column names.
728
         *
729
         * @param string SQL statement for inserting records
730
         * @since 2014.03
731
         * @see mshop/product/manager/update/ansi
732
         * @see mshop/product/manager/newid/ansi
733
         * @see mshop/product/manager/delete/ansi
734
         * @see mshop/product/manager/search/ansi
735
         * @see mshop/product/manager/count/ansi
736
         * @see mshop/product/manager/rate/ansi
737
         * @see mshop/product/manager/stock/ansi
738
         */
739

740
        /** mshop/product/manager/update/mysql
741
         * Updates an existing product record in the database
742
         *
743
         * @see mshop/product/manager/update/ansi
744
         */
745

746
        /** mshop/product/manager/update/ansi
747
         * Updates an existing product record in the database
748
         *
749
         * Items which already have an ID (i.e. the ID is not NULL) will
750
         * be updated in the database.
751
         *
752
         * The SQL statement must be a string suitable for being used as
753
         * prepared statement. It must include question marks for binding
754
         * the values from the product item to the statement before they are
755
         * sent to the database server. The order of the columns must
756
         * correspond to the order in the save() method, so the
757
         * correct values are bound to the columns.
758
         *
759
         * The SQL statement should conform to the ANSI standard to be
760
         * compatible with most relational database systems. This also
761
         * includes using double quotes for table and column names.
762
         *
763
         * @param string SQL statement for updating records
764
         * @since 2014.03
765
         * @see mshop/product/manager/insert/ansi
766
         * @see mshop/product/manager/newid/ansi
767
         * @see mshop/product/manager/delete/ansi
768
         * @see mshop/product/manager/search/ansi
769
         * @see mshop/product/manager/count/ansi
770
         * @see mshop/product/manager/rate/ansi
771
         * @see mshop/product/manager/stock/ansi
772
         */
773

774
        /** mshop/product/manager/newid/mysql
775
         * Retrieves the ID generated by the database when inserting a new record
776
         *
777
         * @see mshop/product/manager/newid/ansi
778
         */
779

780
        /** mshop/product/manager/newid/ansi
781
         * Retrieves the ID generated by the database when inserting a new record
782
         *
783
         * As soon as a new record is inserted into the database table,
784
         * the database server generates a new and unique identifier for
785
         * that record. This ID can be used for retrieving, updating and
786
         * deleting that specific record from the table again.
787
         *
788
         * For MySQL:
789
         *  SELECT LAST_INSERT_ID()
790
         * For PostgreSQL:
791
         *  SELECT currval('seq_mpro_id')
792
         * For SQL Server:
793
         *  SELECT SCOPE_IDENTITY()
794
         * For Oracle:
795
         *  SELECT "seq_mpro_id".CURRVAL FROM DUAL
796
         *
797
         * There's no way to retrive the new ID by a SQL statements that
798
         * fits for most database servers as they implement their own
799
         * specific way.
800
         *
801
         * @param string SQL statement for retrieving the last inserted record ID
802
         * @since 2014.03
803
         * @see mshop/product/manager/insert/ansi
804
         * @see mshop/product/manager/update/ansi
805
         * @see mshop/product/manager/delete/ansi
806
         * @see mshop/product/manager/search/ansi
807
         * @see mshop/product/manager/count/ansi
808
         * @see mshop/product/manager/rate/ansi
809
         * @see mshop/product/manager/stock/ansi
810
         */
811

812
        /** mshop/product/manager/sitemode
813
         * Mode how items from levels below or above in the site tree are handled
814
         *
815
         * By default, only items from the current site are fetched from the
816
         * storage. If the ai-sites extension is installed, you can create a
817
         * tree of sites. Then, this setting allows you to define for the
818
         * whole product domain if items from parent sites are inherited,
819
         * sites from child sites are aggregated or both.
820
         *
821
         * Available constants for the site mode are:
822
         * * 0 = only items from the current site
823
         * * 1 = inherit items from parent sites
824
         * * 2 = aggregate items from child sites
825
         * * 3 = inherit and aggregate items at the same time
826
         *
827
         * You also need to set the mode in the locale manager
828
         * (mshop/locale/manager/sitelevel) to one of the constants.
829
         * If you set it to the same value, it will work as described but you
830
         * can also use different modes. For example, if inheritance and
831
         * aggregation is configured the locale manager but only inheritance
832
         * in the domain manager because aggregating items makes no sense in
833
         * this domain, then items wil be only inherited. Thus, you have full
834
         * control over inheritance and aggregation in each domain.
835
         *
836
         * @param int Constant from Aimeos\MShop\Locale\Manager\Base class
837
         * @since 2018.01
838
         * @see mshop/locale/manager/sitelevel
839
         */
840

841
        /** mshop/product/manager/search/mysql
842
         * Retrieves the records matched by the given criteria in the database
843
         *
844
         * @see mshop/product/manager/search/ansi
845
         */
846

847
        /** mshop/product/manager/search/ansi
848
         * Retrieves the records matched by the given criteria in the database
849
         *
850
         * Fetches the records matched by the given criteria from the product
851
         * database. The records must be from one of the sites that are
852
         * configured via the context item. If the current site is part of
853
         * a tree of sites, the SELECT statement can retrieve all records
854
         * from the current site and the complete sub-tree of sites.
855
         *
856
         * As the records can normally be limited by criteria from sub-managers,
857
         * their tables must be joined in the SQL context. This is done by
858
         * using the "internaldeps" property from the definition of the ID
859
         * column of the sub-managers. These internal dependencies specify
860
         * the JOIN between the tables and the used columns for joining. The
861
         * ":joins" placeholder is then replaced by the JOIN strings from
862
         * the sub-managers.
863
         *
864
         * To limit the records matched, conditions can be added to the given
865
         * criteria object. It can contain comparisons like column names that
866
         * must match specific values which can be combined by AND, OR or NOT
867
         * operators. The resulting string of SQL conditions replaces the
868
         * ":cond" placeholder before the statement is sent to the database
869
         * server.
870
         *
871
         * If the records that are retrieved should be ordered by one or more
872
         * columns, the generated string of column / sort direction pairs
873
         * replaces the ":order" placeholder. Columns of
874
         * sub-managers can also be used for ordering the result set but then
875
         * no index can be used.
876
         *
877
         * The number of returned records can be limited and can start at any
878
         * number between the begining and the end of the result set. For that
879
         * the ":size" and ":start" placeholders are replaced by the
880
         * corresponding values from the criteria object. The default values
881
         * are 0 for the start and 100 for the size value.
882
         *
883
         * The SQL statement should conform to the ANSI standard to be
884
         * compatible with most relational database systems. This also
885
         * includes using double quotes for table and column names.
886
         *
887
         * @param string SQL statement for searching items
888
         * @since 2014.03
889
         * @see mshop/product/manager/insert/ansi
890
         * @see mshop/product/manager/update/ansi
891
         * @see mshop/product/manager/newid/ansi
892
         * @see mshop/product/manager/delete/ansi
893
         * @see mshop/product/manager/count/ansi
894
         * @see mshop/product/manager/rate/ansi
895
         * @see mshop/product/manager/stock/ansi
896
         */
897

898
        /** mshop/product/manager/count/mysql
899
         * Counts the number of records matched by the given criteria in the database
900
         *
901
         * @see mshop/product/manager/count/ansi
902
         */
903

904
        /** mshop/product/manager/count/ansi
905
         * Counts the number of records matched by the given criteria in the database
906
         *
907
         * Counts all records matched by the given criteria from the product
908
         * database. The records must be from one of the sites that are
909
         * configured via the context item. If the current site is part of
910
         * a tree of sites, the statement can count all records from the
911
         * current site and the complete sub-tree of sites.
912
         *
913
         * As the records can normally be limited by criteria from sub-managers,
914
         * their tables must be joined in the SQL context. This is done by
915
         * using the "internaldeps" property from the definition of the ID
916
         * column of the sub-managers. These internal dependencies specify
917
         * the JOIN between the tables and the used columns for joining. The
918
         * ":joins" placeholder is then replaced by the JOIN strings from
919
         * the sub-managers.
920
         *
921
         * To limit the records matched, conditions can be added to the given
922
         * criteria object. It can contain comparisons like column names that
923
         * must match specific values which can be combined by AND, OR or NOT
924
         * operators. The resulting string of SQL conditions replaces the
925
         * ":cond" placeholder before the statement is sent to the database
926
         * server.
927
         *
928
         * Both, the strings for ":joins" and for ":cond" are the same as for
929
         * the "search" SQL statement.
930
         *
931
         * Contrary to the "search" statement, it doesn't return any records
932
         * but instead the number of records that have been found. As counting
933
         * thousands of records can be a long running task, the maximum number
934
         * of counted records is limited for performance reasons.
935
         *
936
         * The SQL statement should conform to the ANSI standard to be
937
         * compatible with most relational database systems. This also
938
         * includes using double quotes for table and column names.
939
         *
940
         * @param string SQL statement for counting items
941
         * @since 2014.03
942
         * @see mshop/product/manager/insert/ansi
943
         * @see mshop/product/manager/update/ansi
944
         * @see mshop/product/manager/newid/ansi
945
         * @see mshop/product/manager/delete/ansi
946
         * @see mshop/product/manager/search/ansi
947
         * @see mshop/product/manager/rate/ansi
948
         * @see mshop/product/manager/stock/ansi
949
         */
950
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc