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

lib/mshoplib/src/MAdmin/Job/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 MAdmin
8
 * @subpackage Job
9
 */
10
11
12
namespace Aimeos\MAdmin\Job\Manager;
13
14
15
/**
16
 * Default job manager implementation.
17
 *
18
 * @package MAdmin
19
 * @subpackage Job
20
 */
21
class Standard
22
	extends \Aimeos\MAdmin\Common\Manager\Base
23
	implements \Aimeos\MAdmin\Job\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface
24
{
25
	private $searchConfig = array(
26
		'job.id' => array(
27
			'code' => 'job.id',
28
			'internalcode' => 'majob."id"',
29
			'label' => 'ID',
30
			'type' => 'integer',
31
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
32
		),
33
		'job.siteid' => array(
34
			'code' => 'job.siteid',
35
			'internalcode' => 'majob."siteid"',
36
			'label' => 'Site ID',
37
			'type' => 'integer',
38
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
39
			'public' => false,
40
		),
41
		'job.label' => array(
42
			'code' => 'job.label',
43
			'internalcode' => 'majob."label"',
44
			'label' => 'Label',
45
			'type' => 'string',
46
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
47
		),
48
		'job.status' => array(
49
			'code' => 'job.status',
50
			'internalcode' => 'majob."status"',
51
			'label' => 'Status',
52
			'type' => 'integer',
53
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
54
		),
55
		'job.method' => array(
56
			'code' => 'job.method',
57
			'internalcode' => 'majob."method"',
58
			'label' => 'Method',
59
			'type' => 'string',
60
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
61
		),
62
		'job.parameter' => array(
63
			'code' => 'job.parameter',
64
			'internalcode' => 'majob."parameter"',
65
			'label' => 'Parameter',
66
			'type' => 'string',
67
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
68
		),
69
		'job.result' => array(
70
			'code' => 'job.result',
71
			'internalcode' => 'majob."result"',
72
			'label' => 'Result',
73
			'type' => 'string',
74
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
75
		),
76
		'job.ctime' => array(
77
			'code' => 'job.ctime',
78
			'internalcode' => 'majob."ctime"',
79
			'label' => 'Create date/time',
80
			'type' => 'datetime',
81
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
82
		),
83
		'job.mtime' => array(
84
			'code' => 'job.mtime',
85
			'internalcode' => 'majob."mtime"',
86
			'label' => 'Modify date/time',
87
			'type' => 'datetime',
88
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
89
		),
90
		'job.editor' => array(
91
			'code' => 'job.editor',
92
			'internalcode' => 'majob."editor"',
93
			'label' => 'Editor',
94
			'type' => 'string',
95
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
96
		),
97
	);
98
99
100
	/**
101
	 * Initializes the object.
102
	 *
103
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
104
	 */
105
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
106
	{
107
		parent::__construct( $context );
108
		$this->setResourceName( 'db-job' );
109
	}
110
111
112
	/**
113
	 * Removes old entries from the storage.
114
	 *
115
	 * @param integer[] $siteids List of IDs for sites whose entries should be deleted
116
	 */
117
	public function cleanup( array $siteids )
118
	{
119
		$path = 'madmin/job/manager/submanagers';
120
		foreach( $this->getContext()->getConfig()->get( $path, [] ) as $domain ) {
121
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
122
		}
123
124
		$this->cleanupBase( $siteids, 'madmin/job/manager/standard/delete' );
125
	}
126
127
128
	/**
129
	 * Creates a new empty item instance
130
	 *
131
	 * @param string|null Type the item should be created with
132
	 * @param string|null Domain of the type the item should be created with
133
	 * @return \Aimeos\MAdmin\Job\Item\Iface New job item object
134
	 */
135
	public function createItem( $type = null, $domain = null )
136
	{
137
		$values = array( 'job.siteid' => $this->getContext()->getLocale()->getSiteId() );
138
		return $this->createItemBase( $values );
139
	}
140
141
142
	/**
143
	 * Creates a search object and optionally sets base criteria.
144
	 *
145
	 * @param boolean $default Add default criteria
146
	 * @return \Aimeos\MW\Criteria\Iface Criteria object
147
	 */
148
	public function createSearch( $default = false )
149
	{
150
		if( $default === true ) {
151
			return $this->createSearchBase( 'job' );
152
		}
153
154
		return parent::createSearch();
155
	}
156
157
158
	/**
159
	 * Adds a new job to the storage.
160
	 *
161
	 * @param \Aimeos\MAdmin\Job\Item\Iface $item Job item that should be saved to the storage
162
	 * @param boolean $fetch True if the new ID should be returned in the item
163
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
164
	 */
165
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
166
	{
167
		self::checkClass( '\\Aimeos\\MAdmin\\Job\\Item\\Iface', $item );
168
169
		if( !$item->isModified() ) {
170
			return $item;
171
		}
172
173
		$context = $this->getContext();
174
175
		$dbm = $context->getDatabaseManager();
176
		$dbname = $this->getResourceName();
177
		$conn = $dbm->acquire( $dbname );
178
179
		try
180
		{
181
			$id = $item->getId();
182
			$date = date( 'Y-m-d H:i:s' );
183
184
			if( $id === null )
185
			{
186
				/** madmin/job/manager/standard/insert/mysql
187
				 * Inserts a new job record into the database table
188
				 *
189
				 * @see madmin/job/manager/standard/insert/ansi
190
				 */
191
192
				/** madmin/job/manager/standard/insert/ansi
193
				 * Inserts a new job record into the database table
194
				 *
195
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
196
				 * the database and the newly created ID retrieved afterwards
197
				 * using the "newid" SQL statement.
198
				 *
199
				 * The SQL statement must be a string suitable for being used as
200
				 * prepared statement. It must include question marks for binding
201
				 * the values from the job item to the statement before they are
202
				 * sent to the database server. The number of question marks must
203
				 * be the same as the number of columns listed in the INSERT
204
				 * statement. The order of the columns must correspond to the
205
				 * order in the saveItems() method, so the correct values are
206
				 * bound to the columns.
207
				 *
208
				 * The SQL statement should conform to the ANSI standard to be
209
				 * compatible with most relational database systems. This also
210
				 * includes using double quotes for table and column names.
211
				 *
212
				 * @param string SQL statement for inserting records
213
				 * @since 2014.03
214
				 * @category Developer
215
				 * @see madmin/job/manager/standard/update/ansi
216
				 * @see madmin/job/manager/standard/newid/ansi
217
				 * @see madmin/job/manager/standard/delete/ansi
218
				 * @see madmin/job/manager/standard/search/ansi
219
				 * @see madmin/job/manager/standard/count/ansi
220
				 */
221
				$path = 'madmin/job/manager/standard/insert';
222
			}
223
			else
224
			{
225
				/** madmin/job/manager/standard/update/mysql
226
				 * Updates an existing job record in the database
227
				 *
228
				 * @see madmin/job/manager/standard/update/ansi
229
				 */
230
231
				/** madmin/job/manager/standard/update/ansi
232
				 * Updates an existing job record in the database
233
				 *
234
				 * Items which already have an ID (i.e. the ID is not NULL) will
235
				 * be updated in the database.
236
				 *
237
				 * The SQL statement must be a string suitable for being used as
238
				 * prepared statement. It must include question marks for binding
239
				 * the values from the job item to the statement before they are
240
				 * sent to the database server. The order of the columns must
241
				 * correspond to the order in the saveItems() method, so the
242
				 * correct values are bound to the columns.
243
				 *
244
				 * The SQL statement should conform to the ANSI standard to be
245
				 * compatible with most relational database systems. This also
246
				 * includes using double quotes for table and column names.
247
				 *
248
				 * @param string SQL statement for updating records
249
				 * @since 2014.03
250
				 * @category Developer
251
				 * @see madmin/job/manager/standard/insert/ansi
252
				 * @see madmin/job/manager/standard/newid/ansi
253
				 * @see madmin/job/manager/standard/delete/ansi
254
				 * @see madmin/job/manager/standard/search/ansi
255
				 * @see madmin/job/manager/standard/count/ansi
256
				 */
257
				$path = 'madmin/job/manager/standard/update';
258
			}
259
260
			$stmt = $this->getCachedStatement( $conn, $path );
261
			$stmt->bind( 1, $item->getLabel() );
1 ignored issue
show
The method getLabel() does not exist on Aimeos\MShop\Common\Item\Iface. It seems like you code against a sub-type of Aimeos\MShop\Common\Item\Iface such as Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Locale\Item\Site\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Customer\Item\Group\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Tag\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Catalog\Item\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Attribute\Item\Standard or Aimeos\MShop\Catalog\Item\Standard or Aimeos\MShop\Customer\Item\Base or Aimeos\MShop\Plugin\Item\Standard or Aimeos\MShop\Tag\Item\Standard or Aimeos\MShop\Customer\Item\Group\Standard or Aimeos\MShop\Media\Item\Standard or Aimeos\MAdmin\Job\Item\Standard or Aimeos\MShop\Common\Item\Type\Standard or Aimeos\MShop\Locale\Item\Site\Standard or Aimeos\MShop\Locale\Item\Currency\Standard or Aimeos\MShop\Text\Item\Standard or Aimeos\MShop\Locale\Item\Language\Standard or Aimeos\MShop\Service\Item\Standard or Aimeos\MShop\Common\Item\ListRef\Base or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Supplier\Item\Standard or Aimeos\MShop\Coupon\Item\Standard or Aimeos\MShop\Product\Item\Standard or Aimeos\MShop\Product\Item\Iface or Aimeos\MShop\Service\Item\Iface or Aimeos\MShop\Customer\Item\Iface or Aimeos\MShop\Text\Item\Iface or Aimeos\MShop\Media\Item\Iface or Aimeos\MShop\Coupon\Item\Iface or Aimeos\MAdmin\Job\Item\Iface or Aimeos\MShop\Common\Item\Type\Iface or Aimeos\MShop\Attribute\Item\Iface or Aimeos\MShop\Locale\Item\Language\Iface or Aimeos\MShop\Common\Item\Tree\Iface or Aimeos\MShop\Plugin\Item\Iface or Aimeos\MShop\Supplier\Item\Iface or Aimeos\MShop\Locale\Item\Currency\Iface or Aimeos\MShop\Price\Item\Base or Aimeos\MShop\Price\Item\Base. ( Ignorable by Annotation )

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

261
			$stmt->bind( 1, $item->/** @scrutinizer ignore-call */ getLabel() );
Loading history...
262
			$stmt->bind( 2, $item->getMethod() );
263
			$stmt->bind( 3, json_encode( $item->getParameter() ) );
264
			$stmt->bind( 4, json_encode( $item->getResult() ) );
265
			$stmt->bind( 5, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
266
			$stmt->bind( 6, $context->getEditor() );
267
			$stmt->bind( 7, $date );
268
			$stmt->bind( 8, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
269
270
			if( $id !== null ) {
271
				$stmt->bind( 9, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
272
				$item->setId( $id ); // so item is no longer modified
273
			} else {
274
				$stmt->bind( 9, $date );
275
			}
276
277
			$stmt->execute()->finish();
278
279
			if( $id === null && $fetch === true )
280
			{
281
				/** madmin/job/manager/standard/newid/mysql
282
				 * Retrieves the ID generated by the database when inserting a new record
283
				 *
284
				 * @see madmin/job/manager/standard/newid/ansi
285
				 */
286
287
				/** madmin/job/manager/standard/newid/ansi
288
				 * Retrieves the ID generated by the database when inserting a new record
289
				 *
290
				 * As soon as a new record is inserted into the database table,
291
				 * the database server generates a new and unique identifier for
292
				 * that record. This ID can be used for retrieving, updating and
293
				 * deleting that specific record from the table again.
294
				 *
295
				 * For MySQL:
296
				 *  SELECT LAST_INSERT_ID()
297
				 * For PostgreSQL:
298
				 *  SELECT currval('seq_majob_id')
299
				 * For SQL Server:
300
				 *  SELECT SCOPE_IDENTITY()
301
				 * For Oracle:
302
				 *  SELECT "seq_majob_id".CURRVAL FROM DUAL
303
				 *
304
				 * There's no way to retrive the new ID by a SQL statements that
305
				 * fits for most database servers as they implement their own
306
				 * specific way.
307
				 *
308
				 * @param string SQL statement for retrieving the last inserted record ID
309
				 * @since 2014.03
310
				 * @category Developer
311
				 * @see madmin/job/manager/standard/insert/ansi
312
				 * @see madmin/job/manager/standard/update/ansi
313
				 * @see madmin/job/manager/standard/delete/ansi
314
				 * @see madmin/job/manager/standard/search/ansi
315
				 * @see madmin/job/manager/standard/count/ansi
316
				 */
317
				$path = 'madmin/job/manager/standard/newid';
318
				$item->setId( $this->newId( $conn, $path ) );
319
			}
320
321
			$dbm->release( $conn, $dbname );
322
		}
323
		catch( \Exception $e )
324
		{
325
			$dbm->release( $conn, $dbname );
326
			throw $e;
327
		}
328
329
		return $item;
330
	}
331
332
333
	/**
334
	 * Removes multiple items specified by ids in the array.
335
	 *
336
	 * @param array $ids List of IDs
337
	 */
338
	public function deleteItems( array $ids )
339
	{
340
		/** madmin/job/manager/standard/delete/mysql
341
		 * Deletes the items matched by the given IDs from the database
342
		 *
343
		 * @see madmin/job/manager/standard/delete/ansi
344
		 */
345
346
		/** madmin/job/manager/standard/delete/ansi
347
		 * Deletes the items matched by the given IDs from the database
348
		 *
349
		 * Removes the records specified by the given IDs from the job database.
350
		 * The records must be from the site that is configured via the
351
		 * context item.
352
		 *
353
		 * The ":cond" placeholder is replaced by the name of the ID column and
354
		 * the given ID or list of IDs while the site ID is bound to the question
355
		 * mark.
356
		 *
357
		 * The SQL statement should conform to the ANSI standard to be
358
		 * compatible with most relational database systems. This also
359
		 * includes using double quotes for table and column names.
360
		 *
361
		 * @param string SQL statement for deleting items
362
		 * @since 2014.03
363
		 * @category Developer
364
		 * @see madmin/job/manager/standard/insert/ansi
365
		 * @see madmin/job/manager/standard/update/ansi
366
		 * @see madmin/job/manager/standard/newid/ansi
367
		 * @see madmin/job/manager/standard/search/ansi
368
		 * @see madmin/job/manager/standard/count/ansi
369
		 */
370
		$path = 'madmin/job/manager/standard/delete';
371
		$this->deleteItemsBase( $ids, $path );
372
	}
373
374
375
	/**
376
	 * Creates the job object for the given job ID.
377
	 *
378
	 * @param integer $id Job ID to fetch job object for
379
	 * @param array $ref List of domains to fetch list items and referenced items for
380
	 * @param boolean $default Add default criteria
381
	 * @return \Aimeos\MAdmin\Job\Item\Iface Returns the job item of the given id
382
	 * @throws \Aimeos\MAdmin\Job\Exception If item couldn't be found
383
	 */
384
	public function getItem( $id, array $ref = [], $default = false )
385
	{
386
		$criteria = $this->getObject()->createSearch( $default );
387
		$expr = [
388
			$criteria->compare( '==', 'job.id', $id ),
389
			$criteria->getConditions()
390
		];
391
		$criteria->setConditions( $criteria->combine( '&&', $expr ) );
392
		$items = $this->getObject()->searchItems( $criteria, $ref );
393
394
		if( ( $item = reset( $items ) ) === false ) {
395
			throw new \Aimeos\MAdmin\Job\Exception( sprintf( 'Job with ID "%1$s" not found', $id ) );
396
		}
397
398
		return $item;
399
	}
400
401
402
	/**
403
	 * Search for jobs based on the given criteria.
404
	 *
405
	 * @param \Aimeos\MW\Criteria\Iface $search Search object containing the conditions
406
	 * @param array $ref List of domains to fetch list items and referenced items for
407
	 * @param integer &$total Number of items that are available in total
408
	 * @return array List of jobs implementing \Aimeos\MAdmin\Job\Item\Iface
409
	 */
410
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
411
	{
412
		$items = [];
413
		$context = $this->getContext();
414
		$logger = $context->getLogger();
415
416
		$dbm = $context->getDatabaseManager();
417
		$dbname = $this->getResourceName();
418
		$conn = $dbm->acquire( $dbname );
419
420
		try
421
		{
422
			$required = array( 'job' );
423
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ONE;
424
425
			/** madmin/job/manager/standard/search/mysql
426
			 * Retrieves the records matched by the given criteria in the database
427
			 *
428
			 * @see madmin/job/manager/standard/search/ansi
429
			 */
430
431
			/** madmin/job/manager/standard/search/ansi
432
			 * Retrieves the records matched by the given criteria in the database
433
			 *
434
			 * Fetches the records matched by the given criteria from the job
435
			 * database. The records must be from one of the sites that are
436
			 * configured via the context item. If the current site is part of
437
			 * a tree of sites, the SELECT statement can retrieve all records
438
			 * from the current site and the complete sub-tree of sites.
439
			 *
440
			 * As the records can normally be limited by criteria from sub-managers,
441
			 * their tables must be joined in the SQL context. This is done by
442
			 * using the "internaldeps" property from the definition of the ID
443
			 * column of the sub-managers. These internal dependencies specify
444
			 * the JOIN between the tables and the used columns for joining. The
445
			 * ":joins" placeholder is then replaced by the JOIN strings from
446
			 * the sub-managers.
447
			 *
448
			 * To limit the records matched, conditions can be added to the given
449
			 * criteria object. It can contain comparisons like column names that
450
			 * must match specific values which can be combined by AND, OR or NOT
451
			 * operators. The resulting string of SQL conditions replaces the
452
			 * ":cond" placeholder before the statement is sent to the database
453
			 * server.
454
			 *
455
			 * If the records that are retrieved should be ordered by one or more
456
			 * columns, the generated string of column / sort direction pairs
457
			 * replaces the ":order" placeholder. In case no ordering is required,
458
			 * the complete ORDER BY part including the "\/*-orderby*\/...\/*orderby-*\/"
459
			 * markers is removed to speed up retrieving the records. Columns of
460
			 * sub-managers can also be used for ordering the result set but then
461
			 * no index can be used.
462
			 *
463
			 * The number of returned records can be limited and can start at any
464
			 * number between the begining and the end of the result set. For that
465
			 * the ":size" and ":start" placeholders are replaced by the
466
			 * corresponding values from the criteria object. The default values
467
			 * are 0 for the start and 100 for the size value.
468
			 *
469
			 * The SQL statement should conform to the ANSI standard to be
470
			 * compatible with most relational database systems. This also
471
			 * includes using double quotes for table and column names.
472
			 *
473
			 * @param string SQL statement for searching items
474
			 * @since 2014.03
475
			 * @category Developer
476
			 * @see madmin/job/manager/standard/insert/ansi
477
			 * @see madmin/job/manager/standard/update/ansi
478
			 * @see madmin/job/manager/standard/newid/ansi
479
			 * @see madmin/job/manager/standard/delete/ansi
480
			 * @see madmin/job/manager/standard/count/ansi
481
			 */
482
			$cfgPathSearch = 'madmin/job/manager/standard/search';
483
484
			/** madmin/job/manager/standard/count/mysql
485
			 * Counts the number of records matched by the given criteria in the database
486
			 *
487
			 * @see madmin/job/manager/standard/count/ansi
488
			 */
489
490
			/** madmin/job/manager/standard/count/ansi
491
			 * Counts the number of records matched by the given criteria in the database
492
			 *
493
			 * Counts all records matched by the given criteria from the job
494
			 * database. The records must be from one of the sites that are
495
			 * configured via the context item. If the current site is part of
496
			 * a tree of sites, the statement can count all records from the
497
			 * current site and the complete sub-tree of sites.
498
			 *
499
			 * As the records can normally be limited by criteria from sub-managers,
500
			 * their tables must be joined in the SQL context. This is done by
501
			 * using the "internaldeps" property from the definition of the ID
502
			 * column of the sub-managers. These internal dependencies specify
503
			 * the JOIN between the tables and the used columns for joining. The
504
			 * ":joins" placeholder is then replaced by the JOIN strings from
505
			 * the sub-managers.
506
			 *
507
			 * To limit the records matched, conditions can be added to the given
508
			 * criteria object. It can contain comparisons like column names that
509
			 * must match specific values which can be combined by AND, OR or NOT
510
			 * operators. The resulting string of SQL conditions replaces the
511
			 * ":cond" placeholder before the statement is sent to the database
512
			 * server.
513
			 *
514
			 * Both, the strings for ":joins" and for ":cond" are the same as for
515
			 * the "search" SQL statement.
516
			 *
517
			 * Contrary to the "search" statement, it doesn't return any records
518
			 * but instead the number of records that have been found. As counting
519
			 * thousands of records can be a long running task, the maximum number
520
			 * of counted records is limited for performance reasons.
521
			 *
522
			 * The SQL statement should conform to the ANSI standard to be
523
			 * compatible with most relational database systems. This also
524
			 * includes using double quotes for table and column names.
525
			 *
526
			 * @param string SQL statement for counting items
527
			 * @since 2014.03
528
			 * @category Developer
529
			 * @see madmin/job/manager/standard/insert/ansi
530
			 * @see madmin/job/manager/standard/update/ansi
531
			 * @see madmin/job/manager/standard/newid/ansi
532
			 * @see madmin/job/manager/standard/delete/ansi
533
			 * @see madmin/job/manager/standard/search/ansi
534
			 */
535
			$cfgPathCount = 'madmin/job/manager/standard/count';
536
537
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
538
539
			while( ( $row = $results->fetch() ) !== false )
540
			{
541
				$config = $row['job.parameter'];
542
				if( ( $row['job.parameter'] = json_decode( $row['job.parameter'], true ) ) === null )
543
				{
544
					$msg = sprintf( 'Invalid JSON as result of search for ID "%2$s" in "%1$s": %3$s', 'madmin_job.parameter', $row['id'], $config );
545
					$logger->log( $msg, \Aimeos\MW\Logger\Base::WARN );
546
				}
547
548
				$config = $row['job.result'];
549
				if( ( $row['job.result'] = json_decode( $row['job.result'], true ) ) === null )
550
				{
551
					$msg = sprintf( 'Invalid JSON as result of search for ID "%2$s" in "%1$s": %3$s', 'madmin_job.result', $row['id'], $config );
552
					$logger->log( $msg, \Aimeos\MW\Logger\Base::WARN );
553
				}
554
555
				$items[$row['job.id']] = $this->createItemBase( $row );
556
			}
557
558
			$dbm->release( $conn, $dbname );
559
		}
560
		catch( \Exception $e )
561
		{
562
			$dbm->release( $conn, $dbname );
563
			throw $e;
564
		}
565
566
		return $items;
567
	}
568
569
570
	/**
571
	 * Returns the available manager types
572
	 *
573
	 * @param boolean $withsub Return also the resource type of sub-managers if true
574
	 * @return array Type of the manager and submanagers, subtypes are separated by slashes
575
	 */
576
	public function getResourceType( $withsub = true )
577
	{
578
		$path = 'madmin/job/manager/submanagers';
579
580
		return $this->getResourceTypeBase( 'job', $path, [], $withsub );
581
	}
582
583
584
	/**
585
	 * Returns the attributes that can be used for searching.
586
	 *
587
	 * @param boolean $withsub Return also attributes of sub-managers if true
588
	 * @return array Returns a list of attributes implementing \Aimeos\MW\Criteria\Attribute\Iface
589
	 */
590
	public function getSearchAttributes( $withsub = true )
591
	{
592
		/** madmin/job/manager/submanagers
593
		 * List of manager names that can be instantiated by the job manager
594
		 *
595
		 * Managers provide a generic interface to the underlying storage.
596
		 * Each manager has or can have sub-managers caring about particular
597
		 * aspects. Each of these sub-managers can be instantiated by its
598
		 * parent manager using the getSubManager() method.
599
		 *
600
		 * The search keys from sub-managers can be normally used in the
601
		 * manager as well. It allows you to search for items of the manager
602
		 * using the search keys of the sub-managers to further limit the
603
		 * retrieved list of items.
604
		 *
605
		 * @param array List of sub-manager names
606
		 * @since 2014.03
607
		 * @category Developer
608
		 */
609
		$path = 'madmin/job/manager/submanagers';
610
611
		return $this->getSearchAttributesBase( $this->searchConfig, $path, [], $withsub );
612
	}
613
614
615
	/**
616
	 * Returns a new manager for job extensions
617
	 *
618
	 * @param string $manager Name of the sub manager type in lower case
619
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
620
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g stock, tags, locations, etc.
621
	 */
622
	public function getSubManager( $manager, $name = null )
623
	{
624
		return $this->getSubManagerBase( 'job', $manager, $name );
625
	}
626
627
628
	/**
629
	 * Create new admin job item object initialized with given parameters.
630
	 *
631
	 * @param array $values Associative list of key/value pairs of a job
632
	 * @return \Aimeos\MAdmin\Job\Item\Iface
633
	 */
634
	protected function createItemBase( array $values = [] )
635
	{
636
		return new \Aimeos\MAdmin\Job\Item\Standard( $values );
637
	}
638
}
639