Passed
Push — master ( 49f6b0...199364 )
by Aimeos
09:07
created

Typo3::delete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 35
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2021
6
 * @package MShop
7
 * @subpackage Customer
8
 */
9
10
11
namespace Aimeos\MShop\Customer\Manager\Group;
12
13
14
/**
15
 * TYPO3 implementation of the customer group class
16
 *
17
 * @package MShop
18
 * @subpackage Customer
19
 */
20
class Typo3
21
	extends \Aimeos\MShop\Customer\Manager\Group\Standard
22
{
23
	private $searchConfig = array(
24
		'customer.group.id' => array(
25
			'code' => 'customer.group.id',
26
			'internalcode' => 'mcusgr."uid"',
27
			'label' => 'Customer group ID',
28
			'type' => 'integer',
29
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
30
		),
31
		'customer.group.code' => array(
32
			'code' => 'customer.group.code',
33
			'internalcode' => 'mcusgr."title"',
34
			'label' => 'Customer group code',
35
			'type' => 'string',
36
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
37
		),
38
		'customer.group.label' => array(
39
			'code' => 'customer.group.label',
40
			'internalcode' => 'mcusgr."description"',
41
			'label' => 'Customer group label',
42
			'type' => 'string',
43
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
44
		),
45
		'customer.group.ctime'=> array(
46
			'code' => 'customer.group.ctime',
47
			'internalcode' => 'mcusgr."crdate"',
48
			'label' => 'Customer group creation time',
49
			'type' => 'datetime',
50
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
51
		),
52
		'customer.group.mtime'=> array(
53
			'code' => 'customer.group.mtime',
54
			'internalcode' => 'mcusgr."tstamp"',
55
			'label' => 'Customer group modification time',
56
			'type' => 'datetime',
57
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
58
		),
59
		'customer.group.editor'=> array(
60
			'code' => 'customer.group.editor',
61
			'internalcode' => '1',
62
			'label' => 'Customer group editor',
63
			'type' => 'string',
64
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
65
		),
66
	);
67
68
	private $plugins = [];
69
	private $reverse = [];
70
	private $pid;
71
72
73
	/**
74
	 * Initializes the customer group manager object
75
	 *
76
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object with required objects
77
	 */
78
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
79
	{
80
		parent::__construct( $context );
81
82
		$plugin = new \Aimeos\MW\Criteria\Plugin\T3Datetime();
83
		$this->plugins['customer.ctime'] = $this->reverse['crdate'] = $plugin;
84
		$this->plugins['customer.mtime'] = $this->reverse['tstamp'] = $plugin;
85
86
		/** mshop/customer/manager/group/typo3/pid-default
87
		 * Page ID the customer records are assigned to
88
		 *
89
		 * In TYPO3, you can assign fe_group records to different sysfolders based
90
		 * on their page ID. These sysfolders can be use for user authorization and
91
		 * therefore, you need to assign the correct page ID to customer groups
92
		 * created or modified by the Aimeos admin backend.
93
		 *
94
		 * @param int TYPO3 page ID
95
		 * @since 2018.10
96
		 * @see mshop/customer/manager/typo3/pid-default
97
		 */
98
		$this->pid = $context->getConfig()->get( 'mshop/customer/manager/typo3/pid-default', 0 );
99
		$this->pid = $context->getConfig()->get( 'mshop/customer/manager/group/typo3/pid-default', $this->pid );
100
	}
101
102
103
	/**
104
	 * Removes old entries from the database
105
	 *
106
	 * @param integer[] $siteids List of IDs for sites whose entries should be deleted
107
	 * @return \Aimeos\MShop\Common\Manager\Iface Same object for fluent interface
108
	 */
109
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
110
	{
111
		$path = 'mshop/customer/manager/group/submanagers';
112
113
		foreach( $this->getContext()->getConfig()->get( $path, [] ) as $domain ) {
114
			$this->getObject()->getSubManager( $domain )->clear( $siteids );
115
		}
116
117
		return $this;
118
	}
119
120
121
	/**
122
	 * Removes multiple items.
123
	 *
124
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
125
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
126
	 */
127
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
128
	{
129
		/** mshop/customer/manager/group/typo3/delete/mysql
130
		 * Deletes the items matched by the given IDs from the database
131
		 *
132
		 * @see mshop/customer/manager/group/typo3/delete/ansi
133
		 */
134
135
		/** mshop/customer/manager/group/typo3/delete/ansi
136
		 * Deletes the items matched by the given IDs from the database
137
		 *
138
		 * Removes the records specified by the given IDs from the customer group
139
		 * database. The records must be from the site that is configured via the
140
		 * context item.
141
		 *
142
		 * The ":cond" placeholder is replaced by the name of the ID column and
143
		 * the given ID or list of IDs while the site ID is bound to the question
144
		 * mark.
145
		 *
146
		 * The SQL statement should conform to the ANSI standard to be
147
		 * compatible with most relational database systems. This also
148
		 * includes using double quotes for table and column names.
149
		 *
150
		 * @param string SQL statement for deleting items
151
		 * @since 2015.08
152
		 * @category Developer
153
		 * @see mshop/customer/manager/group/typo3/insert/ansi
154
		 * @see mshop/customer/manager/group/typo3/update/ansi
155
		 * @see mshop/customer/manager/group/typo3/newid/ansi
156
		 * @see mshop/customer/manager/group/typo3/search/ansi
157
		 * @see mshop/customer/manager/group/typo3/count/ansi
158
		 */
159
		$path = 'mshop/customer/manager/group/typo3/delete';
160
161
		return $this->deleteItemsBase( $itemIds, $path, false, 'uid' );
162
	}
163
164
165
	/**
166
	 * Returns the attributes that can be used for searching
167
	 *
168
	 * @param bool $withsub Return attributes of sub-managers too if true
169
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
170
	 */
171
	public function getSearchAttributes( bool $withsub = true ) : array
172
	{
173
		$path = 'mshop/customer/manager/group/submanagers';
174
175
		return $this->getSearchAttributesBase( $this->searchConfig, $path, [], $withsub );
176
	}
177
178
179
	/**
180
	 * Returns a new manager for customer group extensions
181
	 *
182
	 * @param string $manager Name of the sub manager type in lower case
183
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
184
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions
185
	 */
186
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
187
	{
188
		return $this->getSubManagerBase( 'customer/group', $manager, ( $name === null ? 'Typo3' : $name ) );
189
	}
190
191
192
	/**
193
	 * Inserts a new or updates an existing customer group item
194
	 *
195
	 * @param \Aimeos\MShop\Customer\Item\Group\Iface $item Customer group item
196
	 * @param boolean $fetch True if the new ID should be returned in the item
197
	 * @return \Aimeos\MShop\Customer\Item\Group\Iface $item Updated item including the generated ID
198
	 */
199
	public function saveItem( \Aimeos\MShop\Customer\Item\Group\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Customer\Item\Group\Iface
200
	{
201
		if( !$item->isModified() ) {
202
			return $item;
203
		}
204
205
		$context = $this->getContext();
206
207
		$dbm = $context->getDatabaseManager();
208
		$dbname = $this->getResourceName();
209
		$conn = $dbm->acquire( $dbname );
210
211
		try
212
		{
213
			$id = $item->getId();
214
			$columns = $this->getObject()->getSaveAttributes();
215
216
			if( $id === null )
217
			{
218
				/** mshop/customer/manager/group/typo3/insert/mysql
219
				 * Inserts a new customer group record into the database table
220
				 *
221
				 * @see mshop/customer/manager/group/typo3/insert/ansi
222
				 */
223
224
				/** mshop/customer/manager/group/typo3/insert/ansi
225
				 * Inserts a new customer group record into the database table
226
				 *
227
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
228
				 * the database and the newly created ID retrieved afterwards
229
				 * using the "newid" SQL statement.
230
				 *
231
				 * The SQL statement must be a string suitable for being used as
232
				 * prepared statement. It must include question marks for binding
233
				 * the values from the customer group item to the statement before
234
				 * they are sent to the database server. The number of question
235
				 * marks must be the same as the number of columns listed in the
236
				 * INSERT statement. The order of the columns must correspond to
237
				 * the order in the save() method, so the correct values are
238
				 * bound to the columns.
239
				 *
240
				 * The SQL statement should conform to the ANSI standard to be
241
				 * compatible with most relational database systems. This also
242
				 * includes using double quotes for table and column names.
243
				 *
244
				 * @param string SQL statement for inserting records
245
				 * @since 2015.08
246
				 * @category Developer
247
				 * @see mshop/customer/manager/group/typo3/update/ansi
248
				 * @see mshop/customer/manager/group/typo3/newid/ansi
249
				 * @see mshop/customer/manager/group/typo3/delete/ansi
250
				 * @see mshop/customer/manager/group/typo3/search/ansi
251
				 * @see mshop/customer/manager/group/typo3/count/ansi
252
				 */
253
				$path = 'mshop/customer/manager/group/typo3/insert';
254
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getSqlConfig($path) can also be of type array; however, parameter $sql of Aimeos\MShop\Common\Manager\Base::addSqlColumns() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

254
				$sql = $this->addSqlColumns( array_keys( $columns ), /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ) );
Loading history...
255
			}
256
			else
257
			{
258
				/** mshop/customer/manager/group/typo3/update/mysql
259
				 * Updates an existing customer group record in the database
260
				 *
261
				 * @see mshop/customer/manager/group/typo3/update/ansi
262
				 */
263
264
				/** mshop/customer/manager/group/typo3/update/ansi
265
				 * Updates an existing customer group record in the database
266
				 *
267
				 * Items which already have an ID (i.e. the ID is not NULL) will
268
				 * be updated in the database.
269
				 *
270
				 * The SQL statement must be a string suitable for being used as
271
				 * prepared statement. It must include question marks for binding
272
				 * the values from the customer group item to the statement before
273
				 * they are sent to the database server. The order of the columns
274
				 * must correspond to the order in the save() method, so the
275
				 * correct values are bound to the columns.
276
				 *
277
				 * The SQL statement should conform to the ANSI standard to be
278
				 * compatible with most relational database systems. This also
279
				 * includes using double quotes for table and column names.
280
				 *
281
				 * @param string SQL statement for updating records
282
				 * @since 2015.08
283
				 * @category Developer
284
				 * @see mshop/customer/manager/group/typo3/insert/ansi
285
				 * @see mshop/customer/manager/group/typo3/newid/ansi
286
				 * @see mshop/customer/manager/group/typo3/delete/ansi
287
				 * @see mshop/customer/manager/group/typo3/search/ansi
288
				 * @see mshop/customer/manager/group/typo3/count/ansi
289
				 */
290
				$path = 'mshop/customer/manager/group/typo3/update';
291
				$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );
292
			}
293
294
			$idx = 1;
295
			$stmt = $this->getCachedStatement( $conn, $path, $sql );
296
297
			foreach( $columns as $name => $entry ) {
298
				$stmt->bind( $idx++, $item->get( $name ), $entry->getInternalType() );
299
			}
300
301
			$stmt->bind( $idx++, $this->pid, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
302
			$stmt->bind( $idx++, $item->getCode() );
303
			$stmt->bind( $idx++, $item->getLabel() );
304
			$stmt->bind( $idx++, time(), \Aimeos\MW\DB\Statement\Base::PARAM_INT ); // mtime
305
306
			if( $id !== null ) {
307
				$stmt->bind( $idx++, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
308
				$item->setId( $id );
309
			} else {
310
				$stmt->bind( $idx++, time(), \Aimeos\MW\DB\Statement\Base::PARAM_INT ); // ctime
311
			}
312
313
			$stmt->execute()->finish();
314
315
			if( $id === null && $fetch === true )
316
			{
317
				/** mshop/customer/manager/group/typo3/newid/mysql
318
				 * Retrieves the ID generated by the database when inserting a new record
319
				 *
320
				 * @see mshop/customer/manager/group/typo3/newid/ansi
321
				 */
322
323
				/** mshop/customer/manager/group/typo3/newid/ansi
324
				 * Retrieves the ID generated by the database when inserting a new record
325
				 *
326
				 * As soon as a new record is inserted into the database table,
327
				 * the database server generates a new and unique identifier for
328
				 * that record. This ID can be used for retrieving, updating and
329
				 * deleting that specific record from the table again.
330
				 *
331
				 * For MySQL:
332
				 *  SELECT LAST_INSERT_ID()
333
				 * For PostgreSQL:
334
				 *  SELECT currval('seq_mcus_id')
335
				 * For SQL Server:
336
				 *  SELECT SCOPE_IDENTITY()
337
				 * For Oracle:
338
				 *  SELECT "seq_mcus_id".CURRVAL FROM DUAL
339
				 *
340
				 * There's no way to retrive the new ID by a SQL statements that
341
				 * fits for most database servers as they implement their own
342
				 * specific way.
343
				 *
344
				 * @param string SQL statement for retrieving the last inserted record ID
345
				 * @since 2015.08
346
				 * @category Developer
347
				 * @see mshop/customer/manager/group/typo3/insert/ansi
348
				 * @see mshop/customer/manager/group/typo3/update/ansi
349
				 * @see mshop/customer/manager/group/typo3/delete/ansi
350
				 * @see mshop/customer/manager/group/typo3/search/ansi
351
				 * @see mshop/customer/manager/group/typo3/count/ansi
352
				 */
353
				$path = 'mshop/customer/manager/group/typo3/newid';
354
				$item->setId( $this->newId( $conn, $path ) );
355
			}
356
357
			$dbm->release( $conn, $dbname );
358
		}
359
		catch( \Exception $e )
360
		{
361
			$dbm->release( $conn, $dbname );
362
			throw $e;
363
		}
364
365
		return $item;
366
	}
367
368
369
	/**
370
	 * Returns the item objects matched by the given search criteria.
371
	 *
372
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
373
	 * @param array $ref List of domain items that should be fetched too
374
	 * @param int|null &$total Number of items that are available in total
375
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Customer\Item\Group\Iface
376
	 * @throws \Aimeos\MShop\Exception If retrieving items failed
377
	 */
378
	public function search( \Aimeos\MW\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map
379
	{
380
		$map = [];
381
		$context = $this->getContext();
382
383
		$dbm = $context->getDatabaseManager();
384
		$dbname = $this->getResourceName();
385
		$conn = $dbm->acquire( $dbname );
386
387
		try
388
		{
389
			$required = array( 'customer.group' );
390
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
391
392
			/** mshop/customer/manager/group/typo3/search
393
			 * Retrieves the records matched by the given criteria in the database
394
			 *
395
			 * Fetches the records matched by the given criteria from the customer
396
			 * database. The records must be from one of the sites that are
397
			 * configured via the context item. If the current site is part of
398
			 * a tree of sites, the SELECT statement can retrieve all records
399
			 * from the current site and the complete sub-tree of sites.
400
			 *
401
			 * As the records can normally be limited by criteria from sub-managers,
402
			 * their tables must be joined in the SQL context. This is done by
403
			 * using the "internaldeps" property from the definition of the ID
404
			 * column of the sub-managers. These internal dependencies specify
405
			 * the JOIN between the tables and the used columns for joining. The
406
			 * ":joins" placeholder is then replaced by the JOIN strings from
407
			 * the sub-managers.
408
			 *
409
			 * To limit the records matched, conditions can be added to the given
410
			 * criteria object. It can contain comparisons like column names that
411
			 * must match specific values which can be combined by AND, OR or NOT
412
			 * operators. The resulting string of SQL conditions replaces the
413
			 * ":cond" placeholder before the statement is sent to the database
414
			 * server.
415
			 *
416
			 * If the records that are retrieved should be ordered by one or more
417
			 * columns, the generated string of column / sort direction pairs
418
			 * replaces the ":order" placeholder. In case no ordering is required,
419
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
420
			 * markers is removed to speed up retrieving the records. Columns of
421
			 * sub-managers can also be used for ordering the result set but then
422
			 * no index can be used.
423
			 *
424
			 * The number of returned records can be limited and can start at any
425
			 * number between the begining and the end of the result set. For that
426
			 * the ":size" and ":start" placeholders are replaced by the
427
			 * corresponding values from the criteria object. The default values
428
			 * are 0 for the start and 100 for the size value.
429
			 *
430
			 * The SQL statement should conform to the ANSI standard to be
431
			 * compatible with most relational database systems. This also
432
			 * includes using double quotes for table and column names.
433
			 *
434
			 * @param string SQL statement for searching items
435
			 * @since 2015.08
436
			 * @category Developer
437
			 * @see mshop/customer/manager/group/typo3/count
438
			 */
439
			$cfgPathSearch = 'mshop/customer/manager/group/typo3/search';
440
441
			/** mshop/customer/manager/group/typo3/count
442
			 * Counts the number of records matched by the given criteria in the database
443
			 *
444
			 * Counts all records matched by the given criteria from the customer
445
			 * database. The records must be from one of the sites that are
446
			 * configured via the context item. If the current site is part of
447
			 * a tree of sites, the statement can count all records from the
448
			 * current site and the complete sub-tree of sites.
449
			 *
450
			 * As the records can normally be limited by criteria from sub-managers,
451
			 * their tables must be joined in the SQL context. This is done by
452
			 * using the "internaldeps" property from the definition of the ID
453
			 * column of the sub-managers. These internal dependencies specify
454
			 * the JOIN between the tables and the used columns for joining. The
455
			 * ":joins" placeholder is then replaced by the JOIN strings from
456
			 * the sub-managers.
457
			 *
458
			 * To limit the records matched, conditions can be added to the given
459
			 * criteria object. It can contain comparisons like column names that
460
			 * must match specific values which can be combined by AND, OR or NOT
461
			 * operators. The resulting string of SQL conditions replaces the
462
			 * ":cond" placeholder before the statement is sent to the database
463
			 * server.
464
			 *
465
			 * Both, the strings for ":joins" and for ":cond" are the same as for
466
			 * the "search" SQL statement.
467
			 *
468
			 * Contrary to the "search" statement, it doesn't return any records
469
			 * but instead the number of records that have been found. As counting
470
			 * thousands of records can be a long running task, the maximum number
471
			 * of counted records is limited for performance reasons.
472
			 *
473
			 * The SQL statement should conform to the ANSI standard to be
474
			 * compatible with most relational database systems. This also
475
			 * includes using double quotes for table and column names.
476
			 *
477
			 * @param string SQL statement for counting items
478
			 * @since 2015.08
479
			 * @category Developer
480
			 * @see mshop/customer/manager/group/typo3/search
481
			 */
482
			$cfgPathCount = 'mshop/customer/manager/group/typo3/count';
483
484
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
485
486
			while( ( $row = $results->fetch() ) !== null ) {
487
				$map[(string) $row['customer.group.id']] = $this->createItemBase( $row );
488
			}
489
490
			$dbm->release( $conn, $dbname );
491
		}
492
		catch( \Exception $e )
493
		{
494
			$dbm->release( $conn, $dbname );
495
			throw $e;
496
		}
497
498
		return map( $map );
499
	}
500
501
502
	/**
503
	 * Creates a new customer item.
504
	 *
505
	 * @param array $values List of attributes for customer item
506
	 * @return \Aimeos\MShop\Customer\Item\Group\Iface New customer item
507
	 */
508
	protected function createItemBase( array $values = [] ) : \Aimeos\MShop\Customer\Item\Group\Iface
509
	{
510
		$values['customer.group.siteid'] = $this->getContext()->getLocale()->getSiteId();
511
512
		if( array_key_exists( 'tstamp', $values ) ) {
513
			$values['customer.group.mtime'] = $this->reverse['tstamp']->reverse( $values['tstamp'] );
514
		}
515
516
		if( array_key_exists( 'crdate', $values ) ) {
517
			$values['customer.group.ctime'] = $this->reverse['crdate']->reverse( $values['crdate'] );
518
		}
519
520
		return new \Aimeos\MShop\Customer\Item\Group\Standard( $values );
521
	}
522
}
523