Passed
Push — master ( 6b06c1...3c4248 )
by Aimeos
04:27
created

Standard::__sleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 * @package MAdmin
8
 * @subpackage Log
9
 */
10
11
12
namespace Aimeos\MAdmin\Log\Manager;
13
14
15
/**
16
 * Default log manager implementation.
17
 *
18
 * @package MAdmin
19
 * @subpackage Log
20
 */
21
class Standard
22
	extends \Aimeos\MAdmin\Common\Manager\Base
23
	implements \Aimeos\MAdmin\Log\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	/** madmin/log/manager/name
26
	 * Class name of the used log manager implementation
27
	 *
28
	 * Each default manager can be replace by an alternative imlementation.
29
	 * To use this implementation, you have to set the last part of the class
30
	 * name as configuration value so the manager factory knows which class it
31
	 * has to instantiate.
32
	 *
33
	 * For example, if the name of the default class is
34
	 *
35
	 *  \Aimeos\MShop\Log\Manager\Standard
36
	 *
37
	 * and you want to replace it with your own version named
38
	 *
39
	 *  \Aimeos\MShop\Log\Manager\Mymanager
40
	 *
41
	 * then you have to set the this configuration option:
42
	 *
43
	 *  madmin/log/manager/name = Mymanager
44
	 *
45
	 * The value is the last part of your own class name and it's case sensitive,
46
	 * so take care that the configuration value is exactly named like the last
47
	 * part of the class name.
48
	 *
49
	 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
50
	 * characters are possible! You should always start the last part of the class
51
	 * name with an upper case character and continue only with lower case characters
52
	 * or numbers. Avoid chamel case names like "MyManager"!
53
	 *
54
	 * @param string Last part of the class name
55
	 * @since 2014.03
56
	 * @category Developer
57
	 */
58
59
	/** madmin/log/manager/decorators/excludes
60
	 * Excludes decorators added by the "common" option from the log manager
61
	 *
62
	 * Decorators extend the functionality of a class by adding new aspects
63
	 * (e.g. log what is currently done), executing the methods of the underlying
64
	 * class only in certain conditions (e.g. only for logged in users) or
65
	 * modify what is returned to the caller.
66
	 *
67
	 * This option allows you to remove a decorator added via
68
	 * "madmin/common/manager/decorators/default" before they are wrapped
69
	 * around the log manager.
70
	 *
71
	 *  madmin/log/manager/decorators/excludes = array( 'decorator1' )
72
	 *
73
	 * This would remove the decorator named "decorator1" from the list of
74
	 * common decorators ("\Aimeos\MShop\Common\Manager\Decorator\*") added via
75
	 * "madmin/common/manager/decorators/default" for the log manager.
76
	 *
77
	 * @param array List of decorator names
78
	 * @since 2014.03
79
	 * @category Developer
80
	 * @see madmin/common/manager/decorators/default
81
	 * @see madmin/log/manager/decorators/global
82
	 * @see madmin/log/manager/decorators/local
83
	 */
84
85
	/** madmin/log/manager/decorators/global
86
	 * Adds a list of globally available decorators only to the log manager
87
	 *
88
	 * Decorators extend the functionality of a class by adding new aspects
89
	 * (e.g. log what is currently done), executing the methods of the underlying
90
	 * class only in certain conditions (e.g. only for logged in users) or
91
	 * modify what is returned to the caller.
92
	 *
93
	 * This option allows you to wrap global decorators
94
	 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the log manager.
95
	 *
96
	 *  madmin/log/manager/decorators/global = array( 'decorator1' )
97
	 *
98
	 * This would add the decorator named "decorator1" defined by
99
	 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator1" only to the log controller.
100
	 *
101
	 * @param array List of decorator names
102
	 * @since 2014.03
103
	 * @category Developer
104
	 * @see madmin/common/manager/decorators/default
105
	 * @see madmin/log/manager/decorators/excludes
106
	 * @see madmin/log/manager/decorators/local
107
	 */
108
109
	/** madmin/log/manager/decorators/local
110
	 * Adds a list of local decorators only to the log manager
111
	 *
112
	 * Decorators extend the functionality of a class by adding new aspects
113
	 * (e.g. log what is currently done), executing the methods of the underlying
114
	 * class only in certain conditions (e.g. only for logged in users) or
115
	 * modify what is returned to the caller.
116
	 *
117
	 * This option allows you to wrap local decorators
118
	 * ("\Aimeos\MShop\Common\Manager\Decorator\*") around the log manager.
119
	 *
120
	 *  madmin/log/manager/decorators/local = array( 'decorator2' )
121
	 *
122
	 * This would add the decorator named "decorator2" defined by
123
	 * "\Aimeos\MShop\Common\Manager\Decorator\Decorator2" only to the log
124
	 * controller.
125
	 *
126
	 * @param array List of decorator names
127
	 * @since 2014.03
128
	 * @category Developer
129
	 * @see madmin/common/manager/decorators/default
130
	 * @see madmin/log/manager/decorators/excludes
131
	 * @see madmin/log/manager/decorators/global
132
	 */
133
134
135
	use \Aimeos\Base\Logger\Traits;
136
137
138
	private $conn;
139
	private $loglevel;
140
	private $requestid;
141
142
	private $searchConfig = array(
143
		'log.id' => array(
144
			'code' => 'log.id',
145
			'internalcode' => 'malog."id"',
146
			'label' => 'Log ID',
147
			'type' => 'integer',
148
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
149
		),
150
		'log.siteid' => array(
151
			'code' => 'log.siteid',
152
			'internalcode' => 'malog."siteid"',
153
			'label' => 'Log site ID',
154
			'type' => 'string',
155
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
156
			'public' => false,
157
		),
158
		'log.message' => array(
159
			'code' => 'log.message',
160
			'internalcode' => 'malog."message"',
161
			'label' => 'Log message',
162
			'type' => 'string',
163
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
164
		),
165
		'log.facility' => array(
166
			'code' => 'log.facility',
167
			'internalcode' => 'malog."facility"',
168
			'label' => 'Log facility',
169
			'type' => 'string',
170
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
171
		),
172
		'log.priority' => array(
173
			'code' => 'log.priority',
174
			'internalcode' => 'malog."priority"',
175
			'label' => 'Log priority',
176
			'type' => 'integer',
177
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
178
		),
179
		'log.timestamp' => array(
180
			'code' => 'log.timestamp',
181
			'internalcode' => 'malog."timestamp"',
182
			'label' => 'Log create date/time',
183
			'type' => 'datetime',
184
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
185
		),
186
		'log.request' => array(
187
			'code' => 'log.request',
188
			'internalcode' => 'malog."request"',
189
			'label' => 'Log request',
190
			'type' => 'string',
191
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
192
		)
193
	);
194
195
196
	/**
197
	 * Creates the log manager that will use the given context object.
198
	 *
199
	 * @param \Aimeos\MShop\ContextIface $context Context object with required objects
200
	 */
201
	public function __construct( \Aimeos\MShop\ContextIface $context )
202
	{
203
		parent::__construct( $context );
204
		$this->setResourceName( 'db-log' );
205
206
		$config = $context->config();
207
208
		/** madmin/log/manager/loglevel
209
		 * Sets the severity level for messages to be written to the log
210
		 *
211
		 * Manager, provider and other active components write messages about
212
		 * problems, informational and debug output to the logs. The messages
213
		 * that are actually written to the logs can be limited with the
214
		 * "loglevel" configuration.
215
		 *
216
		 * Available log levels are:
217
		 * * Emergency (0): system is unusable
218
		 * * Alert (1): action must be taken immediately
219
		 * * Critical (2): critical conditions
220
		 * * Error (3): error conditions
221
		 * * Warning (4): warning conditions
222
		 * * Notice (5): normal but significant condition
223
		 * * Informational (6): informational messages
224
		 * * Debug (7): debug messages
225
		 *
226
		 * The "loglevel" configuration option defines the severity of messages
227
		 * that will be written to the logs, e.g. a log level of "3" (error)
228
		 * will allow all messages with an associated level of three and below
229
		 * (error, critical, alert and emergency) to be written to the storage.
230
		 * Messages with other log levels (warning, notice, informational and
231
		 * debug) would be discarded and won't be written to the storage.
232
		 *
233
		 * The higher the log level, the more messages will be written to the
234
		 * storage. Keep in mind that a higher volume of messages will slow
235
		 * down the system and the debug log level shouldn't be used in
236
		 * production environments with a high number of visitors!
237
		 *
238
		 * @param int Log level number
239
		 * @since 2014.03
240
		 * @category Developer
241
		 * @category User
242
		 */
243
		$this->loglevel = $config->get( 'madmin/log/manager/loglevel', \Aimeos\Base\Logger\Iface::NOTICE );
244
		$this->requestid = md5( php_uname( 'n' ) . getmypid() . date( 'Y-m-d H:i:s' ) );
245
	}
246
247
248
	/**
249
	 * Remove open database connections
250
	 */
251
	public function __sleep()
252
	{
253
		unset( $this->conn );
254
		return get_object_vars( $this );
255
	}
256
257
258
	/**
259
	 * Removes old entries from the storage.
260
	 *
261
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
262
	 * @return \Aimeos\MAdmin\Log\Manager\Iface Manager object for chaining method calls
263
	 */
264
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
265
	{
266
		$path = 'madmin/log/manager/submanagers';
267
		foreach( $this->context()->config()->get( $path, [] ) as $domain ) {
268
			$this->object()->getSubManager( $domain )->clear( $siteids );
269
		}
270
271
		return $this->clearBase( $siteids, 'madmin/log/manager/delete' );
272
	}
273
274
275
	/**
276
	 * Creates a new empty item instance
277
	 *
278
	 * @param array $values Values the item should be initialized with
279
	 * @return \Aimeos\MAdmin\Log\Item\Iface New log item object
280
	 */
281
	public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
282
	{
283
		try {
284
			$values['log.siteid'] = $values['log.siteid'] ?? $this->context()->locale()->getSiteId();
285
		} catch( \Exception $e ) {} // if no locale item is available
286
287
		return $this->createItemBase( $values );
288
	}
289
290
291
	/**
292
	 * Removes multiple items.
293
	 *
294
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
295
	 * @return \Aimeos\MAdmin\Log\Manager\Iface Manager object for chaining method calls
296
	 */
297
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
298
	{
299
		/** madmin/log/manager/delete/mysql
300
		 * Deletes the items matched by the given IDs from the database
301
		 *
302
		 * @see madmin/log/manager/delete/ansi
303
		 */
304
305
		/** madmin/log/manager/delete/ansi
306
		 * Deletes the items matched by the given IDs from the database
307
		 *
308
		 * Removes the records specified by the given IDs from the log database.
309
		 * The records must be from the site that is configured via the
310
		 * context item.
311
		 *
312
		 * The ":cond" placeholder is replaced by the name of the ID column and
313
		 * the given ID or list of IDs while the site ID is bound to the question
314
		 * mark.
315
		 *
316
		 * The SQL statement should conform to the ANSI standard to be
317
		 * compatible with most relational database systems. This also
318
		 * includes using double quotes for table and column names.
319
		 *
320
		 * @param string SQL statement for deleting items
321
		 * @since 2014.03
322
		 * @category Developer
323
		 * @see madmin/log/manager/insert/ansi
324
		 * @see madmin/log/manager/update/ansi
325
		 * @see madmin/log/manager/newid/ansi
326
		 * @see madmin/log/manager/search/ansi
327
		 * @see madmin/log/manager/count/ansi
328
		 */
329
		$path = 'madmin/log/manager/delete';
330
331
		return $this->deleteItemsBase( $itemIds, $path );
332
	}
333
334
335
	/**
336
	 * Creates the log object for the given log id.
337
	 *
338
	 * @param string $id Log ID to fetch log object for
339
	 * @param string[] $ref List of domains to fetch list items and referenced items for
340
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
341
	 * @return \Aimeos\MAdmin\Log\Item\Iface Returns the log item of the given id
342
	 * @throws \Aimeos\MAdmin\Log\Exception If item couldn't be found
343
	 */
344
	public function get( string $id, array $ref = [], ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
345
	{
346
		$criteria = $this->object()->filter( $default );
347
		$expr = [
348
			$criteria->compare( '==', 'log.id', $id ),
349
			$criteria->getConditions()
350
		];
351
		$criteria->setConditions( $criteria->and( $expr ) );
352
353
		if( ( $item = $this->object()->search( $criteria, $ref )->first() ) ) {
354
			return $item;
355
		}
356
357
		$msg = $this->context()->translate( 'mshop', 'Log entry with ID "%1$s" not found' );
358
		throw new \Aimeos\MAdmin\Log\Exception( sprintf( $msg, $id ) );
359
	}
360
361
362
	/**
363
	 * Returns the available manager types
364
	 *
365
	 * @param bool $withsub Return also the resource type of sub-managers if true
366
	 * @return string[] Type of the manager and submanagers, subtypes are separated by slashes
367
	 */
368
	public function getResourceType( bool $withsub = true ) : array
369
	{
370
		$path = 'madmin/log/manager/submanagers';
371
		return $this->getResourceTypeBase( 'log', $path, [], $withsub );
372
	}
373
374
375
	/**
376
	 * Returns the attributes that can be used for searching.
377
	 *
378
	 * @param bool $withsub Return also attributes of sub-managers if true
379
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] Returns a list of search attributes
380
	 */
381
	public function getSearchAttributes( bool $withsub = true ) : array
382
	{
383
		/** madmin/log/manager/submanagers
384
		 * List of manager names that can be instantiated by the log manager
385
		 *
386
		 * Managers provide a generic interface to the underlying storage.
387
		 * Each manager has or can have sub-managers caring about particular
388
		 * aspects. Each of these sub-managers can be instantiated by its
389
		 * parent manager using the getSubManager() method.
390
		 *
391
		 * The search keys from sub-managers can be normally used in the
392
		 * manager as well. It allows you to search for items of the manager
393
		 * using the search keys of the sub-managers to further limit the
394
		 * retrieved list of items.
395
		 *
396
		 * @param array List of sub-manager names
397
		 * @since 2014.03
398
		 * @category Developer
399
		 */
400
		$path = 'madmin/log/manager/submanagers';
401
402
		return $this->getSearchAttributesBase( $this->searchConfig, $path, [], $withsub );
403
	}
404
405
406
	/**
407
	 * Returns a new manager for log extensions
408
	 *
409
	 * @param string $manager Name of the sub manager type in lower case
410
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
411
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
412
	 */
413
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
414
	{
415
		return $this->getSubManagerBase( 'log', $manager, $name );
416
	}
417
418
419
	/**
420
	 * Writes a message to the configured log facility.
421
	 *
422
	 * @param string|array|object $message Message text that should be written to the log facility
423
	 * @param int $priority Priority of the message for filtering
424
	 * @param string $facility Facility for logging different types of messages (e.g. message, auth, user, changelog)
425
	 * @return \Aimeos\Base\Logger\Iface Logger object for method chaining
426
	 */
427
	public function log( $message, int $priority = \Aimeos\Base\Logger\Iface::ERR, string $facility = 'message' ) : \Aimeos\Base\Logger\Iface
428
	{
429
		if( $priority <= $this->loglevel )
430
		{
431
			if( !is_scalar( $message ) ) {
432
				$message = json_encode( $message );
433
			}
434
435
			$item = $this->object()->create();
436
437
			$item->setFacility( $facility );
438
			$item->setPriority( $priority );
439
			$item->setMessage( $message );
440
			$item->setRequest( $this->requestid );
441
442
			$this->object()->save( $item );
443
		}
444
445
		return $this;
446
	}
447
448
449
	/**
450
	 * Adds a new log to the storage.
451
	 *
452
	 * @param \Aimeos\MAdmin\Log\Item\Iface $item Log item that should be saved to the storage
453
	 * @param bool $fetch True if the new ID should be returned in the item
454
	 * @return \Aimeos\MAdmin\Log\Item\Iface Updated item including the generated ID
455
	 */
456
	protected function saveItem( \Aimeos\MAdmin\Log\Item\Iface $item, bool $fetch = true ) : \Aimeos\MAdmin\Log\Item\Iface
457
	{
458
		if( !$item->isModified() ) {
459
			return $item;
460
		}
461
462
		try {
463
			$siteid = $this->context()->locale()->getSiteId();
464
		} catch( \Exception $e ) {
465
			$siteid = '';
466
		}
467
468
		$id = $item->getId();
469
		$conn = $this->getConnection();
470
		$columns = $this->object()->getSaveAttributes();
471
472
		if( $id === null )
473
		{
474
			/** madmin/log/manager/insert/mysql
475
			 * Inserts a new log record into the database table
476
			 *
477
			 * @see madmin/log/manager/insert/ansi
478
			 */
479
480
			/** madmin/log/manager/insert/ansi
481
			 * Inserts a new log record into the database table
482
			 *
483
			 * Items with no ID yet (i.e. the ID is NULL) will be created in
484
			 * the database and the newly created ID retrieved afterwards
485
			 * using the "newid" SQL statement.
486
			 *
487
			 * The SQL statement must be a string suitable for being used as
488
			 * prepared statement. It must include question marks for binding
489
			 * the values from the log item to the statement before they are
490
			 * sent to the database server. The number of question marks must
491
			 * be the same as the number of columns listed in the INSERT
492
			 * statement. The order of the columns must correspond to the
493
			 * order in the save() method, so the correct values are
494
			 * bound to the columns.
495
			 *
496
			 * The SQL statement should conform to the ANSI standard to be
497
			 * compatible with most relational database systems. This also
498
			 * includes using double quotes for table and column names.
499
			 *
500
			 * @param string SQL statement for inserting records
501
			 * @since 2014.03
502
			 * @category Developer
503
			 * @see madmin/log/manager/update/ansi
504
			 * @see madmin/log/manager/newid/ansi
505
			 * @see madmin/log/manager/delete/ansi
506
			 * @see madmin/log/manager/search/ansi
507
			 * @see madmin/log/manager/count/ansi
508
			 */
509
			$path = 'madmin/log/manager/insert';
510
			$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

510
			$sql = $this->addSqlColumns( array_keys( $columns ), /** @scrutinizer ignore-type */ $this->getSqlConfig( $path ) );
Loading history...
511
		}
512
		else
513
		{
514
			/** madmin/log/manager/update/mysql
515
			 * Updates an existing log record in the database
516
			 *
517
			 * @see madmin/log/manager/update/ansi
518
			 */
519
520
			/** madmin/log/manager/update/ansi
521
			 * Updates an existing log record in the database
522
			 *
523
			 * Items which already have an ID (i.e. the ID is not NULL) will
524
			 * be updated in the database.
525
			 *
526
			 * The SQL statement must be a string suitable for being used as
527
			 * prepared statement. It must include question marks for binding
528
			 * the values from the log item to the statement before they are
529
			 * sent to the database server. The order of the columns must
530
			 * correspond to the order in the save() method, so the
531
			 * correct values are bound to the columns.
532
			 *
533
			 * The SQL statement should conform to the ANSI standard to be
534
			 * compatible with most relational database systems. This also
535
			 * includes using double quotes for table and column names.
536
			 *
537
			 * @param string SQL statement for updating records
538
			 * @since 2014.03
539
			 * @category Developer
540
			 * @see madmin/log/manager/insert/ansi
541
			 * @see madmin/log/manager/newid/ansi
542
			 * @see madmin/log/manager/delete/ansi
543
			 * @see madmin/log/manager/search/ansi
544
			 * @see madmin/log/manager/count/ansi
545
			 */
546
			$path = 'madmin/log/manager/update';
547
			$sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );
548
		}
549
550
		$idx = 1;
551
		$stmt = $this->getCachedStatement( $conn, $path, $sql );
552
553
		foreach( $columns as $name => $entry ) {
554
			$stmt->bind( $idx++, $item->get( $name ), $entry->getInternalType() );
555
		}
556
557
558
		$stmt->bind( $idx++, $item->getFacility() );
559
		$stmt->bind( $idx++, date( 'Y-m-d H:i:s' ) );
560
		$stmt->bind( $idx++, $item->getPriority(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
561
		$stmt->bind( $idx++, $item->getMessage() );
562
		$stmt->bind( $idx++, $item->getRequest() );
563
		$stmt->bind( $idx++, $siteid );
564
565
		if( $item->getId() !== null ) {
566
			$stmt->bind( $idx++, $item->getId(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );
567
		}
568
569
		$stmt->execute()->finish();
570
571
		if( $id === null && $fetch === true )
572
		{
573
			/** madmin/log/manager/newid/mysql
574
			 * Retrieves the ID generated by the database when inserting a new record
575
			 *
576
			 * @see madmin/log/manager/newid/ansi
577
			 */
578
579
			/** madmin/log/manager/newid/ansi
580
			 * Retrieves the ID generated by the database when inserting a new record
581
			 *
582
			 * As soon as a new record is inserted into the database table,
583
			 * the database server generates a new and unique identifier for
584
			 * that record. This ID can be used for retrieving, updating and
585
			 * deleting that specific record from the table again.
586
			 *
587
			 * For MySQL:
588
			 *  SELECT LAST_INSERT_ID()
589
			 * For PostgreSQL:
590
			 *  SELECT currval('seq_malog_id')
591
			 * For SQL Server:
592
			 *  SELECT SCOPE_IDENTITY()
593
			 * For Oracle:
594
			 *  SELECT "seq_malog_id".CURRVAL FROM DUAL
595
			 *
596
			 * There's no way to retrive the new ID by a SQL statements that
597
			 * fits for most database servers as they implement their own
598
			 * specific way.
599
			 *
600
			 * @param string SQL statement for retrieving the last inserted record ID
601
			 * @since 2014.03
602
			 * @category Developer
603
			 * @see madmin/log/manager/insert/ansi
604
			 * @see madmin/log/manager/update/ansi
605
			 * @see madmin/log/manager/delete/ansi
606
			 * @see madmin/log/manager/search/ansi
607
			 * @see madmin/log/manager/count/ansi
608
			 */
609
			$id = $this->newId( $conn, 'madmin/log/manager/newid' );
610
		}
611
612
		$item->setId( $id );
613
614
		return $item;
615
	}
616
617
618
	/**
619
	 * Search for log entries based on the given criteria.
620
	 *
621
	 * @param \Aimeos\Base\Criteria\Iface $search Search object containing the conditions
622
	 * @param string[] $ref List of domains to fetch list items and referenced items for
623
	 * @param int &$total Number of items that are available in total
624
	 * @return \Aimeos\Map List of items implementing Aimeos\MAdmin\Log\Item\Iface with ids as keys
625
	 */
626
	public function search( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map
627
	{
628
		$items = [];
629
		$context = $this->context();
630
		$conn = $context->db( $this->getResourceName() );
631
632
		$required = array( 'log' );
633
		$level = \Aimeos\MShop\Locale\Manager\Base::SITE_SUBTREE;
634
635
		/** madmin/log/manager/search/mysql
636
		 * Retrieves the records matched by the given criteria in the database
637
		 *
638
		 * @see madmin/log/manager/search/ansi
639
		 */
640
641
		/** madmin/log/manager/search/ansi
642
		 * Retrieves the records matched by the given criteria in the database
643
		 *
644
		 * Fetches the records matched by the given criteria from the log
645
		 * database. The records must be from one of the sites that are
646
		 * configured via the context item. If the current site is part of
647
		 * a tree of sites, the SELECT statement can retrieve all records
648
		 * from the current site and the complete sub-tree of sites.
649
		 *
650
		 * As the records can normally be limited by criteria from sub-managers,
651
		 * their tables must be joined in the SQL context. This is done by
652
		 * using the "internaldeps" property from the definition of the ID
653
		 * column of the sub-managers. These internal dependencies specify
654
		 * the JOIN between the tables and the used columns for joining. The
655
		 * ":joins" placeholder is then replaced by the JOIN strings from
656
		 * the sub-managers.
657
		 *
658
		 * To limit the records matched, conditions can be added to the given
659
		 * criteria object. It can contain comparisons like column names that
660
		 * must match specific values which can be combined by AND, OR or NOT
661
		 * operators. The resulting string of SQL conditions replaces the
662
		 * ":cond" placeholder before the statement is sent to the database
663
		 * server.
664
		 *
665
		 * If the records that are retrieved should be ordered by one or more
666
		 * columns, the generated string of column / sort direction pairs
667
		 * replaces the ":order" placeholder. In case no ordering is required,
668
		 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
669
		 * markers is removed to speed up retrieving the records. Columns of
670
		 * sub-managers can also be used for ordering the result set but then
671
		 * no index can be used.
672
		 *
673
		 * The number of returned records can be limited and can start at any
674
		 * number between the begining and the end of the result set. For that
675
		 * the ":size" and ":start" placeholders are replaced by the
676
		 * corresponding values from the criteria object. The default values
677
		 * are 0 for the start and 100 for the size value.
678
		 *
679
		 * The SQL statement should conform to the ANSI standard to be
680
		 * compatible with most relational database systems. This also
681
		 * includes using double quotes for table and column names.
682
		 *
683
		 * @param string SQL statement for searching items
684
		 * @since 2014.03
685
		 * @category Developer
686
		 * @see madmin/log/manager/insert/ansi
687
		 * @see madmin/log/manager/update/ansi
688
		 * @see madmin/log/manager/newid/ansi
689
		 * @see madmin/log/manager/delete/ansi
690
		 * @see madmin/log/manager/count/ansi
691
		 */
692
		$cfgPathSearch = 'madmin/log/manager/search';
693
694
		/** madmin/log/manager/count/mysql
695
		 * Counts the number of records matched by the given criteria in the database
696
		 *
697
		 * @see madmin/log/manager/count/ansi
698
		 */
699
700
		/** madmin/log/manager/count/ansi
701
		 * Counts the number of records matched by the given criteria in the database
702
		 *
703
		 * Counts all records matched by the given criteria from the log
704
		 * database. The records must be from one of the sites that are
705
		 * configured via the context item. If the current site is part of
706
		 * a tree of sites, the statement can count all records from the
707
		 * current site and the complete sub-tree of sites.
708
		 *
709
		 * As the records can normally be limited by criteria from sub-managers,
710
		 * their tables must be joined in the SQL context. This is done by
711
		 * using the "internaldeps" property from the definition of the ID
712
		 * column of the sub-managers. These internal dependencies specify
713
		 * the JOIN between the tables and the used columns for joining. The
714
		 * ":joins" placeholder is then replaced by the JOIN strings from
715
		 * the sub-managers.
716
		 *
717
		 * To limit the records matched, conditions can be added to the given
718
		 * criteria object. It can contain comparisons like column names that
719
		 * must match specific values which can be combined by AND, OR or NOT
720
		 * operators. The resulting string of SQL conditions replaces the
721
		 * ":cond" placeholder before the statement is sent to the database
722
		 * server.
723
		 *
724
		 * Both, the strings for ":joins" and for ":cond" are the same as for
725
		 * the "search" SQL statement.
726
		 *
727
		 * Contrary to the "search" statement, it doesn't return any records
728
		 * but instead the number of records that have been found. As counting
729
		 * thousands of records can be a long running task, the maximum number
730
		 * of counted records is limited for performance reasons.
731
		 *
732
		 * The SQL statement should conform to the ANSI standard to be
733
		 * compatible with most relational database systems. This also
734
		 * includes using double quotes for table and column names.
735
		 *
736
		 * @param string SQL statement for counting items
737
		 * @since 2014.03
738
		 * @category Developer
739
		 * @see madmin/log/manager/insert/ansi
740
		 * @see madmin/log/manager/update/ansi
741
		 * @see madmin/log/manager/newid/ansi
742
		 * @see madmin/log/manager/delete/ansi
743
		 * @see madmin/log/manager/search/ansi
744
		 */
745
		$cfgPathCount = 'madmin/log/manager/count';
746
747
		$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
748
749
		while( ( $row = $results->fetch() ) !== null )
750
		{
751
			if( $item = $this->applyFilter( $this->createItemBase( $row ) ) ) {
752
				$items[$row['log.id']] = $item;
753
			}
754
		}
755
756
		return map( $items );
757
	}
758
759
760
	/**
761
	 * Create new admin log item object initialized with given parameters.
762
	 *
763
	 * @param array $values Associative list of key/value pairs of a job
764
	 * @return \Aimeos\MAdmin\Log\Item\Iface New log item
765
	 */
766
	protected function createItemBase( array $values = [] ) : \Aimeos\MAdmin\Log\Item\Iface
767
	{
768
		return new \Aimeos\MAdmin\Log\Item\Standard( $values );
769
	}
770
771
772
	/**
773
	 * Returns the connection for logging
774
	 *
775
	 * @return \Aimeos\Base\DB\Connection\Iface Database connection
776
	 */
777
	protected function getConnection() : \Aimeos\Base\DB\Connection\Iface
778
	{
779
		if( !isset( $this->conn ) ) {
780
			$this->conn = $this->context()->db( $this->getResourceName(), true );
781
		}
782
783
		return $this->conn;
784
	}
785
}
786