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

lib/mshoplib/src/MShop/Price/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, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package MShop
8
 * @subpackage Price
9
 */
10
11
12
namespace Aimeos\MShop\Price\Manager;
13
14
15
/**
16
 * Default implementation of a price manager.
17
 *
18
 * @package MShop
19
 * @subpackage Price
20
 */
21
class Standard
22
	extends \Aimeos\MShop\Price\Manager\Base
23
	implements \Aimeos\MShop\Price\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	private $searchConfig = array(
26
		'price.id' => array(
27
			'code' => 'price.id',
28
			'internalcode' => 'mpri."id"',
29
			'label' => 'Price ID',
30
			'type' => 'integer',
31
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
32
		),
33
		'price.siteid' => array(
34
			'code' => 'price.siteid',
35
			'internalcode' => 'mpri."siteid"',
36
			'label' => 'Price site ID',
37
			'type' => 'integer',
38
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
39
			'public' => false,
40
		),
41
		'price.typeid' => array(
42
			'label' => 'Price type ID',
43
			'code' => 'price.typeid',
44
			'internalcode' => 'mpri."typeid"',
45
			'type' => 'string',
46
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
47
			'public' => false,
48
		),
49
		'price.currencyid' => array(
50
			'code' => 'price.currencyid',
51
			'internalcode' => 'mpri."currencyid"',
52
			'label' => 'Price currency code',
53
			'type' => 'string',
54
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
55
		),
56
		'price.domain' => array(
57
			'code' => 'price.domain',
58
			'internalcode' => 'mpri."domain"',
59
			'label' => 'Price domain',
60
			'type' => 'string',
61
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
62
		),
63
		'price.label' => array(
64
			'code' => 'price.label',
65
			'internalcode' => 'mpri."label"',
66
			'label' => 'Price label',
67
			'type' => 'string',
68
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
69
		),
70
		'price.quantity' => array(
71
			'code' => 'price.quantity',
72
			'internalcode' => 'mpri."quantity"',
73
			'label' => 'Price quantity',
74
			'type' => 'integer',
75
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
76
		),
77
		'price.value' => array(
78
			'code' => 'price.value',
79
			'internalcode' => 'mpri."value"',
80
			'label' => 'Price regular value',
81
			'type' => 'decimal',
82
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
83
		),
84
		'price.costs' => array(
85
			'code' => 'price.costs',
86
			'internalcode' => 'mpri."costs"',
87
			'label' => 'Price shipping costs',
88
			'type' => 'decimal',
89
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
90
		),
91
		'price.rebate' => array(
92
			'code' => 'price.rebate',
93
			'internalcode' => 'mpri."rebate"',
94
			'label' => 'Price rebate amount',
95
			'type' => 'decimal',
96
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
97
		),
98
		'price.taxrate' => array(
99
			'code' => 'price.taxrate',
100
			'internalcode' => 'mpri."taxrate"',
101
			'label' => 'Price tax in percent',
102
			'type' => 'decimal',
103
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
104
		),
105
		'price.status' => array(
106
			'code' => 'price.status',
107
			'internalcode' => 'mpri."status"',
108
			'label' => 'Price status',
109
			'type' => 'integer',
110
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
111
		),
112
		'price.mtime' => array(
113
			'code' => 'price.mtime',
114
			'internalcode' => 'mpri."mtime"',
115
			'label' => 'Price modify date',
116
			'type' => 'datetime',
117
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
118
		),
119
		'price.ctime' => array(
120
			'code' => 'price.ctime',
121
			'internalcode' => 'mpri."ctime"',
122
			'label' => 'Price create date/time',
123
			'type' => 'datetime',
124
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
125
		),
126
		'price.editor' => array(
127
			'code' => 'price.editor',
128
			'internalcode' => 'mpri."editor"',
129
			'label' => 'Price editor',
130
			'type' => 'string',
131
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
132
		),
133
	);
134
135
	private $currencyId;
136
	private $taxflag;
137
138
139
	/**
140
	 * Initializes the object.
141
	 *
142
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
143
	 */
144
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
145
	{
146
		parent::__construct( $context );
147
		$this->setResourceName( 'db-price' );
148
149
		/** mshop/price/taxflag
150
		 * Configuration setting if prices are inclusive or exclusive tax
151
		 *
152
		 * In Aimeos, prices can be entered either completely with or without tax. The
153
		 * default is that prices contains tax. You must specifiy the tax rate for each
154
		 * prices to prevent wrong calculations.
155
		 *
156
		 * @param boolean True if gross prices are used, false for net prices
157
		 * @category Developer
158
		 * @category User
159
		 * @since 2016.02
160
		 */
161
		$this->taxflag = $context->getConfig()->get( 'mshop/price/taxflag', true );
162
163
		$this->currencyId = $context->getLocale()->getCurrencyId();
164
	}
165
166
167
	/**
168
	 * Removes old entries from the storage.
169
	 *
170
	 * @param array $siteids List of IDs for sites whose entries should be deleted
171
	 */
172
	public function cleanup( array $siteids )
173
	{
174
		$path = 'mshop/price/manager/submanagers';
175
		foreach( $this->getContext()->getConfig()->get( $path, array( 'type', 'lists' ) ) as $domain ) {
176
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
177
		}
178
179
		$this->cleanupBase( $siteids, 'mshop/price/manager/standard/delete' );
180
	}
181
182
183
	/**
184
	 * Creates a new empty item instance
185
	 *
186
	 * @param string|null Type the item should be created with
187
	 * @param string|null Domain of the type the item should be created with
188
	 * @param array $values Values the item should be initialized with
189
	 * @return \Aimeos\MShop\Price\Item\Iface New price item object
190
	 */
191
	public function createItem( $type = null, $domain = null, array $values = [] )
192
	{
193
		$locale = $this->getContext()->getLocale();
194
		$values['price.siteid'] = $locale->getSiteId();
195
196
		if( $locale->getCurrencyId() !== null ) {
197
			$values['price.currencyid'] = $locale->getCurrencyId();
198
		}
199
200
		if( $type !== null )
201
		{
202
			$values['price.typeid'] = $this->getTypeId( $type, $domain );
203
			$values['price.type'] = $type;
204
		}
205
206
		return $this->createItemBase( $values );
207
	}
208
209
210
211
	/**
212
	 * Returns the available manager types
213
	 *
214
	 * @param boolean $withsub Return also the resource type of sub-managers if true
215
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
216
	 */
217
	public function getResourceType( $withsub = true )
218
	{
219
		$path = 'mshop/price/manager/submanagers';
220
221
		return $this->getResourceTypeBase( 'price', $path, array( 'type', 'lists' ), $withsub );
222
	}
223
224
225
	/**
226
	 * Returns the attributes that can be used for searching.
227
	 *
228
	 * @param boolean $withsub Return also attributes of sub-managers if true
229
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
230
	 */
231
	public function getSearchAttributes( $withsub = true )
232
	{
233
		/** mshop/price/manager/submanagers
234
		 * List of manager names that can be instantiated by the price manager
235
		 *
236
		 * Managers provide a generic interface to the underlying storage.
237
		 * Each manager has or can have sub-managers caring about particular
238
		 * aspects. Each of these sub-managers can be instantiated by its
239
		 * parent manager using the getSubManager() method.
240
		 *
241
		 * The search keys from sub-managers can be normally used in the
242
		 * manager as well. It allows you to search for items of the manager
243
		 * using the search keys of the sub-managers to further limit the
244
		 * retrieved list of items.
245
		 *
246
		 * @param array List of sub-manager names
247
		 * @since 2014.03
248
		 * @category Developer
249
		 */
250
		$path = 'mshop/price/manager/submanagers';
251
252
		return $this->getSearchAttributesBase( $this->searchConfig, $path, array( 'type', 'lists' ), $withsub );
253
	}
254
255
256
	/**
257
	 * Removes multiple items specified by ids in the array.
258
	 *
259
	 * @param array $ids List of IDs
260
	 */
261
	public function deleteItems( array $ids )
262
	{
263
		/** mshop/price/manager/standard/delete/mysql
264
		 * Deletes the items matched by the given IDs from the database
265
		 *
266
		 * @see mshop/price/manager/standard/delete/ansi
267
		 */
268
269
		/** mshop/price/manager/standard/delete/ansi
270
		 * Deletes the items matched by the given IDs from the database
271
		 *
272
		 * Removes the records specified by the given IDs from the price database.
273
		 * The records must be from the site that is configured via the
274
		 * context item.
275
		 *
276
		 * The ":cond" placeholder is replaced by the name of the ID column and
277
		 * the given ID or list of IDs while the site ID is bound to the question
278
		 * mark.
279
		 *
280
		 * The SQL statement should conform to the ANSI standard to be
281
		 * compatible with most relational database systems. This also
282
		 * includes using double quotes for table and column names.
283
		 *
284
		 * @param string SQL statement for deleting items
285
		 * @since 2014.03
286
		 * @category Developer
287
		 * @see mshop/price/manager/standard/insert/ansi
288
		 * @see mshop/price/manager/standard/update/ansi
289
		 * @see mshop/price/manager/standard/newid/ansi
290
		 * @see mshop/price/manager/standard/search/ansi
291
		 * @see mshop/price/manager/standard/count/ansi
292
		 */
293
		$path = 'mshop/price/manager/standard/delete';
294
		$this->deleteItemsBase( $ids, $path );
295
	}
296
297
298
	/**
299
	 * Returns the price item object specificed by its ID.
300
	 *
301
	 * @param integer $id Unique price ID referencing an existing price
302
	 * @param string[] $ref List of domains to fetch list items and referenced items for
303
	 * @param boolean $default Add default criteria
304
	 * @return \Aimeos\MShop\Price\Item\Iface $item Returns the price item of the given id
305
	 * @throws \Aimeos\MShop\Exception If item couldn't be found
306
	 */
307
	public function getItem( $id, array $ref = [], $default = false )
308
	{
309
		return $this->getItemBase( 'price.id', $id, $ref, $default );
310
	}
311
312
313
	/**
314
	 * Saves a price item object.
315
	 *
316
	 * @param \Aimeos\MShop\Price\Item\Iface $item Price item object
317
	 * @param boolean $fetch True if the new ID should be returned in the item
318
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
319
	 * @throws \Aimeos\MShop\Price\Exception If price couldn't be saved
320
	 */
321
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
322
	{
323
		self::checkClass( '\\Aimeos\\MShop\\Price\\Item\\Iface', $item );
324
325
		if( !$item->isModified() ) {
326
			return $this->saveListItems( $item, 'price', $fetch );
327
		}
328
329
		$context = $this->getContext();
330
331
		$dbm = $context->getDatabaseManager();
332
		$dbname = $this->getResourceName();
333
		$conn = $dbm->acquire( $dbname );
334
335
		try
336
		{
337
			$id = $item->getId();
338
			$date = date( 'Y-m-d H:i:s' );
339
340
			if( $id === null )
341
			{
342
				/** mshop/price/manager/standard/insert/mysql
343
				 * Inserts a new price record into the database table
344
				 *
345
				 * @see mshop/price/manager/standard/insert/ansi
346
				 */
347
348
				/** mshop/price/manager/standard/insert/ansi
349
				 * Inserts a new price record into the database table
350
				 *
351
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
352
				 * the database and the newly created ID retrieved afterwards
353
				 * using the "newid" SQL statement.
354
				 *
355
				 * The SQL statement must be a string suitable for being used as
356
				 * prepared statement. It must include question marks for binding
357
				 * the values from the price item to the statement before they are
358
				 * sent to the database server. The number of question marks must
359
				 * be the same as the number of columns listed in the INSERT
360
				 * statement. The order of the columns must correspond to the
361
				 * order in the saveItems() method, so the correct values are
362
				 * bound to the columns.
363
				 *
364
				 * The SQL statement should conform to the ANSI standard to be
365
				 * compatible with most relational database systems. This also
366
				 * includes using double quotes for table and column names.
367
				 *
368
				 * @param string SQL statement for inserting records
369
				 * @since 2014.03
370
				 * @category Developer
371
				 * @see mshop/price/manager/standard/update/ansi
372
				 * @see mshop/price/manager/standard/newid/ansi
373
				 * @see mshop/price/manager/standard/delete/ansi
374
				 * @see mshop/price/manager/standard/search/ansi
375
				 * @see mshop/price/manager/standard/count/ansi
376
				 */
377
				$path = 'mshop/price/manager/standard/insert';
378
			}
379
			else
380
			{
381
				/** mshop/price/manager/standard/update/mysql
382
				 * Updates an existing price record in the database
383
				 *
384
				 * @see mshop/price/manager/standard/update/ansi
385
				 */
386
387
				/** mshop/price/manager/standard/update/ansi
388
				 * Updates an existing price record in the database
389
				 *
390
				 * Items which already have an ID (i.e. the ID is not NULL) will
391
				 * be updated in the database.
392
				 *
393
				 * The SQL statement must be a string suitable for being used as
394
				 * prepared statement. It must include question marks for binding
395
				 * the values from the price item to the statement before they are
396
				 * sent to the database server. The order of the columns must
397
				 * correspond to the order in the saveItems() method, so the
398
				 * correct values are bound to the columns.
399
				 *
400
				 * The SQL statement should conform to the ANSI standard to be
401
				 * compatible with most relational database systems. This also
402
				 * includes using double quotes for table and column names.
403
				 *
404
				 * @param string SQL statement for updating records
405
				 * @since 2014.03
406
				 * @category Developer
407
				 * @see mshop/price/manager/standard/insert/ansi
408
				 * @see mshop/price/manager/standard/newid/ansi
409
				 * @see mshop/price/manager/standard/delete/ansi
410
				 * @see mshop/price/manager/standard/search/ansi
411
				 * @see mshop/price/manager/standard/count/ansi
412
				 */
413
				$path = 'mshop/price/manager/standard/update';
414
			}
415
416
			$stmt = $this->getCachedStatement( $conn, $path );
417
418
			$stmt->bind( 1, $item->getTypeId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
419
			$stmt->bind( 2, $item->getCurrencyId() );
420
			$stmt->bind( 3, $item->getDomain() );
421
			$stmt->bind( 4, $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

421
			$stmt->bind( 4, $item->/** @scrutinizer ignore-call */ getLabel() );
Loading history...
422
			$stmt->bind( 5, $item->getQuantity(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
423
			$stmt->bind( 6, $item->getValue() );
424
			$stmt->bind( 7, $item->getCosts() );
425
			$stmt->bind( 8, $item->getRebate() );
426
			$stmt->bind( 9, $item->getTaxRate() );
427
			$stmt->bind( 10, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
428
			$stmt->bind( 11, $date ); //mtime
429
			$stmt->bind( 12, $context->getEditor() );
430
			$stmt->bind( 13, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
431
432
			if( $id !== null ) {
433
				$stmt->bind( 14, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
434
				$item->setId( $id );
435
			} else {
436
				$stmt->bind( 14, $date ); //ctime
437
			}
438
439
			$stmt->execute()->finish();
440
441
			if( $id === null )
442
			{
443
				/** mshop/price/manager/standard/newid/mysql
444
				 * Retrieves the ID generated by the database when inserting a new record
445
				 *
446
				 * @see mshop/price/manager/standard/newid/ansi
447
				 */
448
449
				/** mshop/price/manager/standard/newid/ansi
450
				 * Retrieves the ID generated by the database when inserting a new record
451
				 *
452
				 * As soon as a new record is inserted into the database table,
453
				 * the database server generates a new and unique identifier for
454
				 * that record. This ID can be used for retrieving, updating and
455
				 * deleting that specific record from the table again.
456
				 *
457
				 * For MySQL:
458
				 *  SELECT LAST_INSERT_ID()
459
				 * For PostgreSQL:
460
				 *  SELECT currval('seq_mpri_id')
461
				 * For SQL Server:
462
				 *  SELECT SCOPE_IDENTITY()
463
				 * For Oracle:
464
				 *  SELECT "seq_mpri_id".CURRVAL FROM DUAL
465
				 *
466
				 * There's no way to retrive the new ID by a SQL statements that
467
				 * fits for most database servers as they implement their own
468
				 * specific way.
469
				 *
470
				 * @param string SQL statement for retrieving the last inserted record ID
471
				 * @since 2014.03
472
				 * @category Developer
473
				 * @see mshop/price/manager/standard/insert/ansi
474
				 * @see mshop/price/manager/standard/update/ansi
475
				 * @see mshop/price/manager/standard/delete/ansi
476
				 * @see mshop/price/manager/standard/search/ansi
477
				 * @see mshop/price/manager/standard/count/ansi
478
				 */
479
				$path = 'mshop/price/manager/standard/newid';
480
				$item->setId( $this->newId( $conn, $path ) );
481
			}
482
483
			$dbm->release( $conn, $dbname );
484
		}
485
		catch( \Exception $e )
486
		{
487
			$dbm->release( $conn, $dbname );
488
			throw $e;
489
		}
490
491
		return $this->saveListItems( $item, 'price', $fetch );
492
	}
493
494
495
	/**
496
	 * Returns the item objects matched by the given search criteria.
497
	 *
498
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
499
	 * @param string[] $ref List of domains to fetch list items and referenced items for
500
	 * @param integer|null &$total Number of items that are available in total
501
	 * @return array List of items implementing \Aimeos\MShop\Price\Item\Iface
502
	 */
503
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
504
	{
505
		$map = $typeIds = [];
506
		$context = $this->getContext();
507
508
		$dbm = $context->getDatabaseManager();
509
		$dbname = $this->getResourceName();
510
		$conn = $dbm->acquire( $dbname );
511
512
		try
513
		{
514
			$required = array( 'price' );
515
516
			/** mshop/price/manager/sitemode
517
			 * Mode how items from levels below or above in the site tree are handled
518
			 *
519
			 * By default, only items from the current site are fetched from the
520
			 * storage. If the ai-sites extension is installed, you can create a
521
			 * tree of sites. Then, this setting allows you to define for the
522
			 * whole price domain if items from parent sites are inherited,
523
			 * sites from child sites are aggregated or both.
524
			 *
525
			 * Available constants for the site mode are:
526
			 * * 0 = only items from the current site
527
			 * * 1 = inherit items from parent sites
528
			 * * 2 = aggregate items from child sites
529
			 * * 3 = inherit and aggregate items at the same time
530
			 *
531
			 * You also need to set the mode in the locale manager
532
			 * (mshop/locale/manager/standard/sitelevel) to one of the constants.
533
			 * If you set it to the same value, it will work as described but you
534
			 * can also use different modes. For example, if inheritance and
535
			 * aggregation is configured the locale manager but only inheritance
536
			 * in the domain manager because aggregating items makes no sense in
537
			 * this domain, then items wil be only inherited. Thus, you have full
538
			 * control over inheritance and aggregation in each domain.
539
			 *
540
			 * @param integer Constant from Aimeos\MShop\Locale\Manager\Base class
541
			 * @category Developer
542
			 * @since 2018.01
543
			 * @see mshop/locale/manager/standard/sitelevel
544
			 */
545
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
546
			$level = $context->getConfig()->get( 'mshop/price/manager/sitemode', $level );
547
548
			/** mshop/price/manager/standard/search/mysql
549
			 * Retrieves the records matched by the given criteria in the database
550
			 *
551
			 * @see mshop/price/manager/standard/search/ansi
552
			 */
553
554
			/** mshop/price/manager/standard/search/ansi
555
			 * Retrieves the records matched by the given criteria in the database
556
			 *
557
			 * Fetches the records matched by the given criteria from the price
558
			 * database. The records must be from one of the sites that are
559
			 * configured via the context item. If the current site is part of
560
			 * a tree of sites, the SELECT statement can retrieve all records
561
			 * from the current site and the complete sub-tree of sites.
562
			 *
563
			 * As the records can normally be limited by criteria from sub-managers,
564
			 * their tables must be joined in the SQL context. This is done by
565
			 * using the "internaldeps" property from the definition of the ID
566
			 * column of the sub-managers. These internal dependencies specify
567
			 * the JOIN between the tables and the used columns for joining. The
568
			 * ":joins" placeholder is then replaced by the JOIN strings from
569
			 * the sub-managers.
570
			 *
571
			 * To limit the records matched, conditions can be added to the given
572
			 * criteria object. It can contain comparisons like column names that
573
			 * must match specific values which can be combined by AND, OR or NOT
574
			 * operators. The resulting string of SQL conditions replaces the
575
			 * ":cond" placeholder before the statement is sent to the database
576
			 * server.
577
			 *
578
			 * If the records that are retrieved should be ordered by one or more
579
			 * columns, the generated string of column / sort direction pairs
580
			 * replaces the ":order" placeholder. In case no ordering is required,
581
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
582
			 * markers is removed to speed up retrieving the records. Columns of
583
			 * sub-managers can also be used for ordering the result set but then
584
			 * no index can be used.
585
			 *
586
			 * The number of returned records can be limited and can start at any
587
			 * number between the begining and the end of the result set. For that
588
			 * the ":size" and ":start" placeholders are replaced by the
589
			 * corresponding values from the criteria object. The default values
590
			 * are 0 for the start and 100 for the size value.
591
			 *
592
			 * The SQL statement should conform to the ANSI standard to be
593
			 * compatible with most relational database systems. This also
594
			 * includes using double quotes for table and column names.
595
			 *
596
			 * @param string SQL statement for searching items
597
			 * @since 2014.03
598
			 * @category Developer
599
			 * @see mshop/price/manager/standard/insert/ansi
600
			 * @see mshop/price/manager/standard/update/ansi
601
			 * @see mshop/price/manager/standard/newid/ansi
602
			 * @see mshop/price/manager/standard/delete/ansi
603
			 * @see mshop/price/manager/standard/count/ansi
604
			 */
605
			$cfgPathSearch = 'mshop/price/manager/standard/search';
606
607
			/** mshop/price/manager/standard/count/mysql
608
			 * Counts the number of records matched by the given criteria in the database
609
			 *
610
			 * @see mshop/price/manager/standard/count/ansi
611
			 */
612
613
			/** mshop/price/manager/standard/count/ansi
614
			 * Counts the number of records matched by the given criteria in the database
615
			 *
616
			 * Counts all records matched by the given criteria from the price
617
			 * database. The records must be from one of the sites that are
618
			 * configured via the context item. If the current site is part of
619
			 * a tree of sites, the statement can count all records from the
620
			 * current site and the complete sub-tree of sites.
621
			 *
622
			 * As the records can normally be limited by criteria from sub-managers,
623
			 * their tables must be joined in the SQL context. This is done by
624
			 * using the "internaldeps" property from the definition of the ID
625
			 * column of the sub-managers. These internal dependencies specify
626
			 * the JOIN between the tables and the used columns for joining. The
627
			 * ":joins" placeholder is then replaced by the JOIN strings from
628
			 * the sub-managers.
629
			 *
630
			 * To limit the records matched, conditions can be added to the given
631
			 * criteria object. It can contain comparisons like column names that
632
			 * must match specific values which can be combined by AND, OR or NOT
633
			 * operators. The resulting string of SQL conditions replaces the
634
			 * ":cond" placeholder before the statement is sent to the database
635
			 * server.
636
			 *
637
			 * Both, the strings for ":joins" and for ":cond" are the same as for
638
			 * the "search" SQL statement.
639
			 *
640
			 * Contrary to the "search" statement, it doesn't return any records
641
			 * but instead the number of records that have been found. As counting
642
			 * thousands of records can be a long running task, the maximum number
643
			 * of counted records is limited for performance reasons.
644
			 *
645
			 * The SQL statement should conform to the ANSI standard to be
646
			 * compatible with most relational database systems. This also
647
			 * includes using double quotes for table and column names.
648
			 *
649
			 * @param string SQL statement for counting items
650
			 * @since 2014.03
651
			 * @category Developer
652
			 * @see mshop/price/manager/standard/insert/ansi
653
			 * @see mshop/price/manager/standard/update/ansi
654
			 * @see mshop/price/manager/standard/newid/ansi
655
			 * @see mshop/price/manager/standard/delete/ansi
656
			 * @see mshop/price/manager/standard/search/ansi
657
			 */
658
			$cfgPathCount = 'mshop/price/manager/standard/count';
659
660
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
661
662
			while( ( $row = $results->fetch() ) !== false )
663
			{
664
				$map[$row['price.id']] = $row;
665
				$typeIds[$row['price.typeid']] = null;
666
			}
667
668
			$dbm->release( $conn, $dbname );
669
		}
670
		catch( \Exception $e )
671
		{
672
			$dbm->release( $conn, $dbname );
673
			throw $e;
674
		}
675
676
		if( !empty( $typeIds ) )
677
		{
678
			$typeManager = $this->getObject()->getSubManager( 'type' );
679
			$typeSearch = $typeManager->createSearch();
680
			$typeSearch->setConditions( $typeSearch->compare( '==', 'price.type.id', array_keys( $typeIds ) ) );
681
			$typeSearch->setSlice( 0, $search->getSliceSize() );
682
			$typeItems = $typeManager->searchItems( $typeSearch );
683
684
			foreach( $map as $id => $row )
685
			{
686
				if( isset( $typeItems[$row['price.typeid']] ) )
687
				{
688
					$map[$id]['price.type'] = $typeItems[$row['price.typeid']]->getCode();
689
					$map[$id]['price.typename'] = $typeItems[$row['price.typeid']]->getName();
690
				}
691
			}
692
		}
693
694
		return $this->buildItems( $map, null, 'price' );
695
	}
696
697
698
	/**
699
	 * creates a search object and sets base criteria
700
	 *
701
	 * @param boolean $default Prepopulate object with default criterias
702
	 * @return \Aimeos\MW\Criteria\Iface
703
	 */
704
	public function createSearch( $default = false )
705
	{
706
		if( $default === true )
707
		{
708
			$object = $this->createSearchBase( 'price' );
709
			$currencyid = $this->getContext()->getLocale()->getCurrencyId();
710
711
			if( $currencyid !== null )
712
			{
713
				$expr = array(
714
					$object->compare( '==', 'price.currencyid', $currencyid ),
715
					$object->getConditions(),
716
				);
717
718
				$object->setConditions( $object->combine( '&&', $expr ) );
719
			}
720
721
			return $object;
722
		}
723
724
		return parent::createSearch();
725
	}
726
727
728
	/**
729
	 * Returns a new manager for price extensions.
730
	 *
731
	 * @param string $manager Name of the sub manager type in lower case
732
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
733
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g type, etc.
734
	 */
735
	public function getSubManager( $manager, $name = null )
736
	{
737
		return $this->getSubManagerBase( 'price', $manager, $name );
738
	}
739
740
741
	/**
742
	 * Creates a new price item
743
	 *
744
	 * @param array $values List of attributes for price item
745
	 * @param array $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
746
	 * @param array $refItems List of items implementing \Aimeos\MShop\Common\Item\Iface
747
	 * @return \Aimeos\MShop\Price\Item\Iface New price item
748
	 */
749
	protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [] )
750
	{
751
		$values['currencyid'] = $this->currencyId;
752
753
		if( !isset( $values['price.taxflag'] ) ) {
754
			$values['price.taxflag'] = $this->taxflag;
755
		}
756
757
		return new \Aimeos\MShop\Price\Item\Standard( $values, $listItems, $refItems );
758
	}
759
}
760