Passed
Push — master ( 3e2417...b4e8a9 )
by Aimeos
41:27 queued 26:41
created

Typo3::search()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 108
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 3
dl 0
loc 108
rs 9.9
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2023
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 array $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\Base\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\Base\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\Base\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\Base\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\Base\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\Base\DB\Statement\Base::PARAM_STR,
65
		),
66
	);
67
68
	private array $plugins = [];
69
	private array $reverse = [];
70
	private int $pid;
71
72
73
	/**
74
	 * Initializes the customer group manager object
75
	 *
76
	 * @param \Aimeos\MShop\ContextIface $context Context object with required objects
77
	 */
78
	public function __construct( \Aimeos\MShop\ContextIface $context )
79
	{
80
		parent::__construct( $context );
81
82
		$plugin = new \Aimeos\Base\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->config()->get( 'mshop/customer/manager/typo3/pid-default', 0 );
99
		$this->pid = $context->config()->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->context()->config()->get( $path, [] ) as $domain ) {
114
			$this->object()->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\Base\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
	protected 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->context();
206
		$conn = $context->db( $this->getResourceName() );
207
208
			$id = $item->getId();
209
			$columns = $this->object()->getSaveAttributes();
210
211
			if( $id === null )
212
			{
213
				/** mshop/customer/manager/group/typo3/insert/mysql
214
				 * Inserts a new customer group record into the database table
215
				 *
216
				 * @see mshop/customer/manager/group/typo3/insert/ansi
217
				 */
218
219
				/** mshop/customer/manager/group/typo3/insert/ansi
220
				 * Inserts a new customer group record into the database table
221
				 *
222
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
223
				 * the database and the newly created ID retrieved afterwards
224
				 * using the "newid" SQL statement.
225
				 *
226
				 * The SQL statement must be a string suitable for being used as
227
				 * prepared statement. It must include question marks for binding
228
				 * the values from the customer group item to the statement before
229
				 * they are sent to the database server. The number of question
230
				 * marks must be the same as the number of columns listed in the
231
				 * INSERT statement. The order of the columns must correspond to
232
				 * the order in the save() method, so the correct values are
233
				 * bound to the columns.
234
				 *
235
				 * The SQL statement should conform to the ANSI standard to be
236
				 * compatible with most relational database systems. This also
237
				 * includes using double quotes for table and column names.
238
				 *
239
				 * @param string SQL statement for inserting records
240
				 * @since 2015.08
241
				 * @category Developer
242
				 * @see mshop/customer/manager/group/typo3/update/ansi
243
				 * @see mshop/customer/manager/group/typo3/newid/ansi
244
				 * @see mshop/customer/manager/group/typo3/delete/ansi
245
				 * @see mshop/customer/manager/group/typo3/search/ansi
246
				 * @see mshop/customer/manager/group/typo3/count/ansi
247
				 */
248
				$path = 'mshop/customer/manager/group/typo3/insert';
249
				$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

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