Passed
Push — master ( 29d5f6...586595 )
by Aimeos
04:48
created

lib/mshoplib/src/MShop/Coupon/Manager/Standard.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2012
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package MShop
8
 * @subpackage Coupon
9
 */
10
11
12
namespace Aimeos\MShop\Coupon\Manager;
13
14
15
/**
16
 * Default coupon manager interface for creating and handling coupons.
17
 *
18
 * @package MShop
19
 * @subpackage Coupon
20
 */
21
class Standard
22
	extends \Aimeos\MShop\Coupon\Manager\Base
23
	implements \Aimeos\MShop\Coupon\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	private $searchConfig = array(
26
		'coupon.id' => array(
27
			'code' => 'coupon.id',
28
			'internalcode' => 'mcou."id"',
29
			'label' => 'ID',
30
			'type' => 'integer',
31
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
32
			'public' => false,
33
		),
34
		'coupon.siteid' => array(
35
			'code' => 'coupon.siteid',
36
			'internalcode' => 'mcou."siteid"',
37
			'label' => 'Site ID',
38
			'type' => 'integer',
39
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
40
			'public' => false,
41
		),
42
		'coupon.label' => array(
43
			'code' => 'coupon.label',
44
			'internalcode' => 'mcou."label"',
45
			'label' => 'Label',
46
			'type' => 'string',
47
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
48
		),
49
		'coupon.provider' => array(
50
			'code' => 'coupon.provider',
51
			'internalcode' => 'mcou."provider"',
52
			'label' => 'Provider',
53
			'type' => 'string',
54
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
55
		),
56
		'coupon.datestart' => array(
57
			'code' => 'coupon.datestart',
58
			'internalcode' => 'mcou."start"',
59
			'label' => 'Start date/time',
60
			'type' => 'datetime',
61
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
62
		),
63
		'coupon.dateend' => array(
64
			'code' => 'coupon.dateend',
65
			'internalcode' => 'mcou."end"',
66
			'label' => 'End date/time',
67
			'type' => 'datetime',
68
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
69
		),
70
		'coupon.status' => array(
71
			'code' => 'coupon.status',
72
			'internalcode' => 'mcou."status"',
73
			'label' => 'Status',
74
			'type' => 'integer',
75
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
76
		),
77
		'coupon.config' => array(
78
			'code' => 'coupon.config',
79
			'internalcode' => 'mcou."config"',
80
			'label' => 'Configuration',
81
			'type' => 'string',
82
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
83
			'public' => false,
84
		),
85
		'coupon.ctime' => array(
86
			'code' => 'coupon.ctime',
87
			'internalcode' => 'mcou."ctime"',
88
			'label' => 'Create date/time',
89
			'type' => 'datetime',
90
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
91
			'public' => false,
92
		),
93
		'coupon.mtime' => array(
94
			'code' => 'coupon.mtime',
95
			'internalcode' => 'mcou."mtime"',
96
			'label' => 'Modification date/time',
97
			'type' => 'datetime',
98
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
99
			'public' => false,
100
		),
101
		'coupon.editor' => array(
102
			'code' => 'coupon.editor',
103
			'internalcode' => 'mcou."editor"',
104
			'label' => 'Editor',
105
			'type' => 'string',
106
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
107
			'public' => false,
108
		),
109
	);
110
111
	private $date;
112
113
114
	/**
115
	 * Initializes the object.
116
	 *
117
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
118
	 */
119
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
120
	{
121
		parent::__construct( $context );
122
		$this->setResourceName( 'db-coupon' );
123
124
		$this->date = $context->getDateTime();
125
	}
126
127
128
	/**
129
	 * Removes old entries from the storage.
130
	 *
131
	 * @param array $siteids List of IDs for sites whose entries should be deleted
132
	 */
133
	public function cleanup( array $siteids )
134
	{
135
		$path = 'mshop/coupon/manager/submanagers';
136
		foreach( $this->getContext()->getConfig()->get( $path, array( 'code' ) ) as $domain ) {
137
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
138
		}
139
140
		$this->cleanupBase( $siteids, 'mshop/coupon/manager/standard/delete' );
141
	}
142
143
144
	/**
145
	 * Creates a new empty item instance
146
	 *
147
	 * @param string|null Type the item should be created with
148
	 * @param string|null Domain of the type the item should be created with
149
	 * @param array $values Values the item should be initialized with
150
	 * @return \Aimeos\MShop\Coupon\Item\Iface New coupon item object
151
	 */
152
	public function createItem( $type = null, $domain = null, array $values = [] )
153
	{
154
		$values['coupon.siteid'] = $this->getContext()->getLocale()->getSiteId();
155
		return $this->createItemBase( $values );
156
	}
157
158
159
	/**
160
	 * Returns the available manager types
161
	 *
162
	 * @param boolean $withsub Return also the resource type of sub-managers if true
163
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
164
	 */
165
	public function getResourceType( $withsub = true )
166
	{
167
		$path = 'mshop/coupon/manager/submanagers';
168
169
		return $this->getResourceTypeBase( 'coupon', $path, array( 'code' ), $withsub );
170
	}
171
172
173
	/**
174
	 * Returns the attributes that can be used for searching.
175
	 *
176
	 * @param boolean $withsub Return also attributes of sub-managers if true
177
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
178
	 */
179
	public function getSearchAttributes( $withsub = true )
180
	{
181
		/** mshop/coupon/manager/submanagers
182
		 * List of manager names that can be instantiated by the coupon manager
183
		 *
184
		 * Managers provide a generic interface to the underlying storage.
185
		 * Each manager has or can have sub-managers caring about particular
186
		 * aspects. Each of these sub-managers can be instantiated by its
187
		 * parent manager using the getSubManager() method.
188
		 *
189
		 * The search keys from sub-managers can be normally used in the
190
		 * manager as well. It allows you to search for items of the manager
191
		 * using the search keys of the sub-managers to further limit the
192
		 * retrieved list of items.
193
		 *
194
		 * @param array List of sub-manager names
195
		 * @since 2014.03
196
		 * @category Developer
197
		 */
198
		$path = 'mshop/coupon/manager/submanagers';
199
200
		return $this->getSearchAttributesBase( $this->searchConfig, $path, array( 'code' ), $withsub );
201
	}
202
203
204
	/**
205
	 * Returns the coupons item specified by its ID.
206
	 *
207
	 * @param string $id Unique ID of the coupon item in the storage
208
	 * @param string[] $ref List of domains to fetch list items and referenced items for
209
	 * @param boolean $default Add default criteria
210
	 * @return \Aimeos\MShop\Coupon\Item\Iface Returns the coupon item of the given ID
211
	 * @throws \Aimeos\MShop\Exception If coupon couldn't be found
212
	 */
213
	public function getItem( $id, array $ref = [], $default = false )
214
	{
215
		return $this->getItemBase( 'coupon.id', $id, $ref, $default );
216
	}
217
218
219
	/**
220
	 * Saves a coupon item to the storage.
221
	 *
222
	 * @param \Aimeos\MShop\Coupon\Item\Iface $item Coupon implementing the coupon interface
223
	 * @param boolean $fetch True if the new ID should be returned in the item
224
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
225
	 * @throws \Aimeos\MShop\Coupon\Exception If coupon couldn't be saved
226
	 */
227
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
228
	{
229
		self::checkClass( '\\Aimeos\\MShop\\Coupon\\Item\\Iface', $item );
230
231
		if( !$item->isModified() ) {
232
			return $item;
233
		}
234
235
		$context = $this->getContext();
236
237
		$dbm = $context->getDatabaseManager();
238
		$dbname = $this->getResourceName();
239
		$conn = $dbm->acquire( $dbname );
240
241
		try
242
		{
243
			$id = $item->getId();
244
			$date = date( 'Y-m-d H:i:s' );
245
246
			if( $id === null )
247
			{
248
				/** mshop/coupon/manager/standard/insert/mysql
249
				 * Inserts a new coupon record into the database table
250
				 *
251
				 * @see mshop/coupon/manager/standard/insert/ansi
252
				 */
253
254
				/** mshop/coupon/manager/standard/insert/ansi
255
				 * Inserts a new coupon record into the database table
256
				 *
257
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
258
				 * the database and the newly created ID retrieved afterwards
259
				 * using the "newid" SQL statement.
260
				 *
261
				 * The SQL statement must be a string suitable for being used as
262
				 * prepared statement. It must include question marks for binding
263
				 * the values from the coupon item to the statement before they are
264
				 * sent to the database server. The number of question marks must
265
				 * be the same as the number of columns listed in the INSERT
266
				 * statement. The order of the columns must correspond to the
267
				 * order in the saveItems() method, so the correct values are
268
				 * bound to the columns.
269
				 *
270
				 * The SQL statement should conform to the ANSI standard to be
271
				 * compatible with most relational database systems. This also
272
				 * includes using double quotes for table and column names.
273
				 *
274
				 * @param string SQL statement for inserting records
275
				 * @since 2014.03
276
				 * @category Developer
277
				 * @see mshop/coupon/manager/standard/update/ansi
278
				 * @see mshop/coupon/manager/standard/newid/ansi
279
				 * @see mshop/coupon/manager/standard/delete/ansi
280
				 * @see mshop/coupon/manager/standard/search/ansi
281
				 * @see mshop/coupon/manager/standard/count/ansi
282
				 */
283
				$path = 'mshop/coupon/manager/standard/insert';
284
			}
285
			else
286
			{
287
				/** mshop/coupon/manager/standard/update/mysql
288
				 * Updates an existing coupon record in the database
289
				 *
290
				 * @see mshop/coupon/manager/standard/update/ansi
291
				 */
292
293
				/** mshop/coupon/manager/standard/update/ansi
294
				 * Updates an existing coupon record in the database
295
				 *
296
				 * Items which already have an ID (i.e. the ID is not NULL) will
297
				 * be updated in the database.
298
				 *
299
				 * The SQL statement must be a string suitable for being used as
300
				 * prepared statement. It must include question marks for binding
301
				 * the values from the coupon item to the statement before they are
302
				 * sent to the database server. The order of the columns must
303
				 * correspond to the order in the saveItems() method, so the
304
				 * correct values are bound to the columns.
305
				 *
306
				 * The SQL statement should conform to the ANSI standard to be
307
				 * compatible with most relational database systems. This also
308
				 * includes using double quotes for table and column names.
309
				 *
310
				 * @param string SQL statement for updating records
311
				 * @since 2014.03
312
				 * @category Developer
313
				 * @see mshop/coupon/manager/standard/insert/ansi
314
				 * @see mshop/coupon/manager/standard/newid/ansi
315
				 * @see mshop/coupon/manager/standard/delete/ansi
316
				 * @see mshop/coupon/manager/standard/search/ansi
317
				 * @see mshop/coupon/manager/standard/count/ansi
318
				 */
319
				$path = 'mshop/coupon/manager/standard/update';
320
			}
321
322
			$stmt = $this->getCachedStatement( $conn, $path );
323
324
			$stmt->bind( 1, $item->getLabel() );
1 ignored issue
show
The method getLabel() does not exist on Aimeos\MShop\Common\Item\Iface. It seems like you code against a sub-type of Aimeos\MShop\Common\Item\Iface such as Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Locale\Item\Site\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Customer\Item\Group\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Tag\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Catalog\Item\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Attribute\Item\Standard or Aimeos\MShop\Catalog\Item\Standard or Aimeos\MShop\Customer\Item\Base or Aimeos\MShop\Plugin\Item\Standard or Aimeos\MShop\Tag\Item\Standard or Aimeos\MShop\Customer\Item\Group\Standard or Aimeos\MShop\Media\Item\Standard or Aimeos\MAdmin\Job\Item\Standard or Aimeos\MShop\Common\Item\Type\Standard or Aimeos\MShop\Locale\Item\Site\Standard or Aimeos\MShop\Locale\Item\Currency\Standard or Aimeos\MShop\Text\Item\Standard or Aimeos\MShop\Locale\Item\Language\Standard or Aimeos\MShop\Service\Item\Standard or Aimeos\MShop\Common\Item\ListRef\Base or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Supplier\Item\Standard or Aimeos\MShop\Coupon\Item\Standard or Aimeos\MShop\Product\Item\Standard or Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Common\Item\Tree\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Price\Item\Base. ( Ignorable by Annotation )

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

324
			$stmt->bind( 1, $item->/** @scrutinizer ignore-call */ getLabel() );
Loading history...
325
			$stmt->bind( 2, $item->getProvider() );
326
			$stmt->bind( 3, json_encode( $item->getConfig() ) );
327
			$stmt->bind( 4, $item->getDateStart() );
328
			$stmt->bind( 5, $item->getDateEnd() );
329
			$stmt->bind( 6, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
330
			$stmt->bind( 7, $date ); // mtime
331
			$stmt->bind( 8, $context->getEditor() );
332
			$stmt->bind( 9, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
333
334
			if( $id !== null ) {
335
				$stmt->bind( 10, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
336
				$item->setId( $id );
337
			} else {
338
				$stmt->bind( 10, $date ); // ctime
339
			}
340
341
			$stmt->execute()->finish();
342
343
			if( $id === null && $fetch === true )
344
			{
345
				/** mshop/coupon/manager/standard/newid/mysql
346
				 * Retrieves the ID generated by the database when inserting a new record
347
				 *
348
				 * @see mshop/coupon/manager/standard/newid/ansi
349
				 */
350
351
				/** mshop/coupon/manager/standard/newid/ansi
352
				 * Retrieves the ID generated by the database when inserting a new record
353
				 *
354
				 * As soon as a new record is inserted into the database table,
355
				 * the database server generates a new and unique identifier for
356
				 * that record. This ID can be used for retrieving, updating and
357
				 * deleting that specific record from the table again.
358
				 *
359
				 * For MySQL:
360
				 *  SELECT LAST_INSERT_ID()
361
				 * For PostgreSQL:
362
				 *  SELECT currval('seq_mcou_id')
363
				 * For SQL Server:
364
				 *  SELECT SCOPE_IDENTITY()
365
				 * For Oracle:
366
				 *  SELECT "seq_mcou_id".CURRVAL FROM DUAL
367
				 *
368
				 * There's no way to retrive the new ID by a SQL statements that
369
				 * fits for most database servers as they implement their own
370
				 * specific way.
371
				 *
372
				 * @param string SQL statement for retrieving the last inserted record ID
373
				 * @since 2014.03
374
				 * @category Developer
375
				 * @see mshop/coupon/manager/standard/insert/ansi
376
				 * @see mshop/coupon/manager/standard/update/ansi
377
				 * @see mshop/coupon/manager/standard/delete/ansi
378
				 * @see mshop/coupon/manager/standard/search/ansi
379
				 * @see mshop/coupon/manager/standard/count/ansi
380
				 */
381
				$path = 'mshop/coupon/manager/standard/newid';
382
				$item->setId( $this->newId( $conn, $path ) );
383
			}
384
385
			$dbm->release( $conn, $dbname );
386
		}
387
		catch( \Exception $e )
388
		{
389
			$dbm->release( $conn, $dbname );
390
			throw $e;
391
		}
392
393
		return $item;
394
	}
395
396
397
	/**
398
	 * Removes multiple items specified by ids in the array.
399
	 *
400
	 * @param array $ids List of IDs
401
	 */
402
	public function deleteItems( array $ids )
403
	{
404
		/** mshop/coupon/manager/standard/delete/mysql
405
		 * Deletes the items matched by the given IDs from the database
406
		 *
407
		 * @see mshop/coupon/manager/standard/delete/ansi
408
		 */
409
410
		/** mshop/coupon/manager/standard/delete/ansi
411
		 * Deletes the items matched by the given IDs from the database
412
		 *
413
		 * Removes the records specified by the given IDs from the coupon database.
414
		 * The records must be from the site that is configured via the
415
		 * context item.
416
		 *
417
		 * The ":cond" placeholder is replaced by the name of the ID column and
418
		 * the given ID or list of IDs while the site ID is bound to the question
419
		 * mark.
420
		 *
421
		 * The SQL statement should conform to the ANSI standard to be
422
		 * compatible with most relational database systems. This also
423
		 * includes using double quotes for table and column names.
424
		 *
425
		 * @param string SQL statement for deleting items
426
		 * @since 2014.03
427
		 * @category Developer
428
		 * @see mshop/coupon/manager/standard/insert/ansi
429
		 * @see mshop/coupon/manager/standard/update/ansi
430
		 * @see mshop/coupon/manager/standard/newid/ansi
431
		 * @see mshop/coupon/manager/standard/search/ansi
432
		 * @see mshop/coupon/manager/standard/count/ansi
433
		 */
434
		$path = 'mshop/coupon/manager/standard/delete';
435
		$this->deleteItemsBase( $ids, $path );
436
	}
437
438
439
	/**
440
	 * Searchs for coupon items based on the given criteria.
441
	 *
442
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
443
	 * @param string[] $ref List of domains to fetch list items and referenced items for
444
	 * @param integer|null &$total Number of items that are available in total
445
	 * @return array Returns a list of coupon items implementing \Aimeos\MShop\Coupon\Item\Iface
446
	 */
447
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
448
	{
449
		$context = $this->getContext();
450
		$dbm = $context->getDatabaseManager();
451
		$dbname = $this->getResourceName();
452
		$conn = $dbm->acquire( $dbname );
453
		$items = [];
454
455
		try
456
		{
457
			$required = array( 'coupon' );
458
459
			/** mshop/coupon/manager/sitemode
460
			 * Mode how items from levels below or above in the site tree are handled
461
			 *
462
			 * By default, only items from the current site are fetched from the
463
			 * storage. If the ai-sites extension is installed, you can create a
464
			 * tree of sites. Then, this setting allows you to define for the
465
			 * whole coupon domain if items from parent sites are inherited,
466
			 * sites from child sites are aggregated or both.
467
			 *
468
			 * Available constants for the site mode are:
469
			 * * 0 = only items from the current site
470
			 * * 1 = inherit items from parent sites
471
			 * * 2 = aggregate items from child sites
472
			 * * 3 = inherit and aggregate items at the same time
473
			 *
474
			 * You also need to set the mode in the locale manager
475
			 * (mshop/locale/manager/standard/sitelevel) to one of the constants.
476
			 * If you set it to the same value, it will work as described but you
477
			 * can also use different modes. For example, if inheritance and
478
			 * aggregation is configured the locale manager but only inheritance
479
			 * in the domain manager because aggregating items makes no sense in
480
			 * this domain, then items wil be only inherited. Thus, you have full
481
			 * control over inheritance and aggregation in each domain.
482
			 *
483
			 * @param integer Constant from Aimeos\MShop\Locale\Manager\Base class
484
			 * @category Developer
485
			 * @since 2018.01
486
			 * @see mshop/locale/manager/standard/sitelevel
487
			 */
488
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_PATH;
489
			$level = $context->getConfig()->get( 'mshop/coupon/manager/sitemode', $level );
490
491
			/** mshop/coupon/manager/standard/search/mysql
492
			 * Retrieves the records matched by the given criteria in the database
493
			 *
494
			 * @see mshop/coupon/manager/standard/search/ansi
495
			 */
496
497
			/** mshop/coupon/manager/standard/search/ansi
498
			 * Retrieves the records matched by the given criteria in the database
499
			 *
500
			 * Fetches the records matched by the given criteria from the coupon
501
			 * database. The records must be from one of the sites that are
502
			 * configured via the context item. If the current site is part of
503
			 * a tree of sites, the SELECT statement can retrieve all records
504
			 * from the current site and the complete sub-tree of sites.
505
			 *
506
			 * As the records can normally be limited by criteria from sub-managers,
507
			 * their tables must be joined in the SQL context. This is done by
508
			 * using the "internaldeps" property from the definition of the ID
509
			 * column of the sub-managers. These internal dependencies specify
510
			 * the JOIN between the tables and the used columns for joining. The
511
			 * ":joins" placeholder is then replaced by the JOIN strings from
512
			 * the sub-managers.
513
			 *
514
			 * To limit the records matched, conditions can be added to the given
515
			 * criteria object. It can contain comparisons like column names that
516
			 * must match specific values which can be combined by AND, OR or NOT
517
			 * operators. The resulting string of SQL conditions replaces the
518
			 * ":cond" placeholder before the statement is sent to the database
519
			 * server.
520
			 *
521
			 * If the records that are retrieved should be ordered by one or more
522
			 * columns, the generated string of column / sort direction pairs
523
			 * replaces the ":order" placeholder. In case no ordering is required,
524
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
525
			 * markers is removed to speed up retrieving the records. Columns of
526
			 * sub-managers can also be used for ordering the result set but then
527
			 * no index can be used.
528
			 *
529
			 * The number of returned records can be limited and can start at any
530
			 * number between the begining and the end of the result set. For that
531
			 * the ":size" and ":start" placeholders are replaced by the
532
			 * corresponding values from the criteria object. The default values
533
			 * are 0 for the start and 100 for the size value.
534
			 *
535
			 * The SQL statement should conform to the ANSI standard to be
536
			 * compatible with most relational database systems. This also
537
			 * includes using double quotes for table and column names.
538
			 *
539
			 * @param string SQL statement for searching items
540
			 * @since 2014.03
541
			 * @category Developer
542
			 * @see mshop/coupon/manager/standard/insert/ansi
543
			 * @see mshop/coupon/manager/standard/update/ansi
544
			 * @see mshop/coupon/manager/standard/newid/ansi
545
			 * @see mshop/coupon/manager/standard/delete/ansi
546
			 * @see mshop/coupon/manager/standard/count/ansi
547
			 */
548
			$cfgPathSearch = 'mshop/coupon/manager/standard/search';
549
550
			/** mshop/coupon/manager/standard/count/mysql
551
			 * Counts the number of records matched by the given criteria in the database
552
			 *
553
			 * @see mshop/coupon/manager/standard/count/ansi
554
			 */
555
556
			/** mshop/coupon/manager/standard/count/ansi
557
			 * Counts the number of records matched by the given criteria in the database
558
			 *
559
			 * Counts all records matched by the given criteria from the coupon
560
			 * database. The records must be from one of the sites that are
561
			 * configured via the context item. If the current site is part of
562
			 * a tree of sites, the statement can count all records from the
563
			 * current site and the complete sub-tree of sites.
564
			 *
565
			 * As the records can normally be limited by criteria from sub-managers,
566
			 * their tables must be joined in the SQL context. This is done by
567
			 * using the "internaldeps" property from the definition of the ID
568
			 * column of the sub-managers. These internal dependencies specify
569
			 * the JOIN between the tables and the used columns for joining. The
570
			 * ":joins" placeholder is then replaced by the JOIN strings from
571
			 * the sub-managers.
572
			 *
573
			 * To limit the records matched, conditions can be added to the given
574
			 * criteria object. It can contain comparisons like column names that
575
			 * must match specific values which can be combined by AND, OR or NOT
576
			 * operators. The resulting string of SQL conditions replaces the
577
			 * ":cond" placeholder before the statement is sent to the database
578
			 * server.
579
			 *
580
			 * Both, the strings for ":joins" and for ":cond" are the same as for
581
			 * the "search" SQL statement.
582
			 *
583
			 * Contrary to the "search" statement, it doesn't return any records
584
			 * but instead the number of records that have been found. As counting
585
			 * thousands of records can be a long running task, the maximum number
586
			 * of counted records is limited for performance reasons.
587
			 *
588
			 * The SQL statement should conform to the ANSI standard to be
589
			 * compatible with most relational database systems. This also
590
			 * includes using double quotes for table and column names.
591
			 *
592
			 * @param string SQL statement for counting items
593
			 * @since 2014.03
594
			 * @category Developer
595
			 * @see mshop/coupon/manager/standard/insert/ansi
596
			 * @see mshop/coupon/manager/standard/update/ansi
597
			 * @see mshop/coupon/manager/standard/newid/ansi
598
			 * @see mshop/coupon/manager/standard/delete/ansi
599
			 * @see mshop/coupon/manager/standard/search/ansi
600
			 */
601
			$cfgPathCount = 'mshop/coupon/manager/standard/count';
602
603
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
604
605
			try
606
			{
607
				while( ( $row = $results->fetch() ) !== false )
608
				{
609
					$config = $row['coupon.config'];
610
611
					if( ( $row['coupon.config'] = json_decode( $row['coupon.config'], true ) ) === null )
612
					{
613
						$msg = sprintf( 'Invalid JSON as result of search for ID "%2$s" in "%1$s": %3$s', 'mshop_locale.config', $row['id'], $config );
614
						$context->getLogger()->log( $msg, \Aimeos\MW\Logger\Base::WARN );
615
					}
616
617
					$items[$row['coupon.id']] = $this->createItemBase( $row );
618
				}
619
			}
620
			catch( \Exception $e )
621
			{
622
				$results->finish();
623
				throw $e;
624
			}
625
626
			$dbm->release( $conn, $dbname );
627
		}
628
		catch( \Exception $e )
629
		{
630
			$dbm->release( $conn, $dbname );
631
			throw $e;
632
		}
633
634
		return $items;
635
	}
636
637
638
	/**
639
	 * Returns a new sub manager of the given type and name.
640
	 *
641
	 * @param string $manager Name of the sub manager type in lower case
642
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
643
	 * @return \Aimeos\MShop\Common\Manager\Lists\Iface List manager
644
	 */
645
	public function getSubManager( $manager, $name = null )
646
	{
647
		return $this->getSubManagerBase( 'coupon', $manager, $name );
648
	}
649
650
651
	/**
652
	 * Creates a search object and sets base criteria
653
	 *
654
	 * @param boolean $default
655
	 * @return \Aimeos\MW\Criteria\Iface
656
	 */
657
	public function createSearch( $default = false )
658
	{
659
		if( $default === true )
660
		{
661
			$object = $this->createSearchBase( 'coupon' );
662
663
			$expr = [];
664
			$expr[] = $object->getConditions();
665
666
			$temp = [];
667
			$temp[] = $object->compare( '==', 'coupon.datestart', null );
668
			$temp[] = $object->compare( '<=', 'coupon.datestart', $this->date );
669
			$expr[] = $object->combine( '||', $temp );
670
671
			$temp = [];
672
			$temp[] = $object->compare( '==', 'coupon.dateend', null );
673
			$temp[] = $object->compare( '>=', 'coupon.dateend', $this->date );
674
			$expr[] = $object->combine( '||', $temp );
675
676
			$object->setConditions( $object->combine( '&&', $expr ) );
677
678
			return $object;
679
		}
680
681
		return parent::createSearch();
682
	}
683
684
685
	/**
686
	 * Creates a new coupon item instance
687
	 *
688
	 * @param array $values Values of the coupon item from the storage
689
	 * @return \Aimeos\MShop\Coupon\Item\Standard Returns a new created coupon item instance
690
	 */
691
	protected function createItemBase( array $values = [] )
692
	{
693
		$values['date'] = $this->date;
694
695
		return new \Aimeos\MShop\Coupon\Item\Standard( $values );
696
	}
697
}