Passed
Push — master ( 04e202...9b7189 )
by Aimeos
05:11
created

Methods::setResourceName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
dl 0
loc 11
rs 10
c 1
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2023
6
 * @package MShop
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\MShop\Common\Manager;
12
13
14
/**
15
 * Method trait for managers
16
 *
17
 * @package MShop
18
 * @subpackage Common
19
 */
20
trait Methods
21
{
22
	private $filterFcn = [];
23
	private $resourceName;
24
	private $object;
25
26
27
	/**
28
	 * Returns the context object.
29
	 *
30
	 * @return \Aimeos\MShop\ContextIface Context object
31
	 */
32
	abstract protected function context() : \Aimeos\MShop\ContextIface;
33
34
35
	/**
36
	 * Adds a filter callback for an item type
37
	 *
38
	 * @param string $iface Interface name of the item to apply the filter to
39
	 * @param \Closure $fcn Anonymous function receiving the item to check as first parameter
40
	 */
41
	public function addFilter( string $iface, \Closure $fcn )
42
	{
43
		if( !isset( $this->filterFcn[$iface] ) ) {
44
			$this->filterFcn[$iface] = [];
45
		}
46
47
		$this->filterFcn[$iface][] = $fcn;
48
	}
49
50
51
	/**
52
	 * Returns the class names of the manager and used decorators.
53
	 *
54
	 * @return array List of class names
55
	 */
56
	public function classes() : array
57
	{
58
		return [get_class( $this )];
59
	}
60
61
62
	/**
63
	 * Removes old entries from the storage.
64
	 *
65
	 * @param iterable $siteids List of IDs for sites whose entries should be deleted
66
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
67
	 */
68
	public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface
69
	{
70
		return $this;
71
	}
72
73
74
	/**
75
	 * Creates a new empty item instance
76
	 *
77
	 * @param array $values Values the item should be initialized with
78
	 * @return \Aimeos\MShop\Attribute\Item\Iface New attribute item object
79
	 */
80
	public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface
81
	{
82
		throw new \Aimeos\MShop\Exception( $this->context()->translate( 'mshop', 'Not implemented' ) );
83
	}
84
85
86
	/**
87
	 * Creates a new cursor based on the filter criteria
88
	 *
89
	 * @param \Aimeos\Base\Criteria\Iface $filter Criteria object with conditions, sortations, etc.
90
	 * @return \Aimeos\MShop\Common\Cursor\Iface Cursor object
91
	 */
92
	public function cursor( \Aimeos\Base\Criteria\Iface $filter ) : \Aimeos\MShop\Common\Cursor\Iface
93
	{
94
		return new \Aimeos\MShop\Common\Cursor\Standard( $filter );
95
	}
96
97
98
	/**
99
	 * Removes multiple items.
100
	 *
101
	 * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items
102
	 * @return \Aimeos\MShop\Attribute\Manager\Iface Manager object for chaining method calls
103
	 */
104
	public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface
105
	{
106
		return $this;
107
	}
108
109
	/**
110
	 * Creates a search critera object
111
	 *
112
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
113
	 * @param bool $site TRUE for adding site criteria to limit items by the site of related items
114
	 * @return \Aimeos\Base\Criteria\Iface New search criteria object
115
	 */
116
	public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
117
	{
118
		$context = $this->context();
119
		$db = $this->getResourceName();
120
		$conn = $context->db( $db );
121
		$config = $context->config();
122
123
		if( ( $adapter = $config->get( 'resource/' . $db . '/adapter' ) ) === null ) {
124
			$adapter = $config->get( 'resource/db/adapter' );
125
		}
126
127
		switch( $adapter )
128
		{
129
			case 'pgsql':
130
				$search = new \Aimeos\Base\Criteria\PgSQL( $conn ); break;
131
			default:
132
				$search = new \Aimeos\Base\Criteria\SQL( $conn ); break;
133
		}
134
135
		return $search;
136
	}
137
138
139
	/**
140
	 * Returns the item specified by its code and domain/type if necessary
141
	 *
142
	 * @param string $code Code of the item
143
	 * @param string[] $ref List of domains to fetch list items and referenced items for
144
	 * @param string $domain Domain of the item if necessary to identify the item uniquely
145
	 * @param string|null $type Type code of the item if necessary to identify the item uniquely
146
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
147
	 * @return \Aimeos\MShop\Attribute\Item\Iface Attribute item object
148
	 */
149
	public function find( string $code, array $ref = [], string $domain = 'product', string $type = null,
150
		?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
151
	{
152
		throw new \Aimeos\MShop\Exception( $this->context()->translate( 'mshop', 'Not implemented' ) );
153
	}
154
155
156
	/**
157
	 * Returns the attributes item specified by its ID.
158
	 *
159
	 * @param string $id Unique ID of the attribute item in the storage
160
	 * @param string[] $ref List of domains to fetch list items and referenced items for
161
	 * @param bool|null $default Add default criteria or NULL for relaxed default criteria
162
	 * @return \Aimeos\MShop\Attribute\Item\Iface Returns the attribute item of the given id
163
	 * @throws \Aimeos\MShop\Exception If item couldn't be found
164
	 */
165
	public function get( string $id, array $ref = [], ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
166
	{
167
		throw new \Aimeos\MShop\Exception( $this->context()->translate( 'mshop', 'Not implemented' ) );
168
	}
169
170
171
	/**
172
	 * Returns the available manager types
173
	 *
174
	 * @param bool $withsub Return also the resource type of sub-managers if true
175
	 * @return string[] Type of the manager and submanagers, subtypes are separated by slashes
176
	 */
177
	public function getResourceType( bool $withsub = true ) : array
178
	{
179
		return [];
180
	}
181
182
183
	/**
184
	 * Returns the additional column/search definitions
185
	 *
186
	 * @return array Associative list of column names as keys and items implementing \Aimeos\Base\Criteria\Attribute\Iface
187
	 */
188
	public function getSaveAttributes() : array
189
	{
190
		return [];
191
	}
192
193
194
	/**
195
	 * Returns the attributes that can be used for searching.
196
	 *
197
	 * @param bool $withsub Return also attributes of sub-managers if true
198
	 * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of attribute items
199
	 */
200
	public function getSearchAttributes( bool $withsub = true ) : array
201
	{
202
		return [];
203
	}
204
205
206
	/**
207
	 * Returns a new manager for attribute extensions
208
	 *
209
	 * @param string $manager Name of the sub manager type in lower case
210
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
211
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g Type, List's etc.
212
	 */
213
	public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface
214
	{
215
		throw new \Aimeos\MShop\Exception( $this->context()->translate( 'mshop', 'Not implemented' ) );
216
	}
217
218
219
	/**
220
	 * Iterates over all matched items and returns the found ones
221
	 *
222
	 * @param \Aimeos\MShop\Common\Cursor\Iface $cursor Cursor object with filter, domains and cursor
223
	 * @param string[] $ref List of domains whose items should be fetched too
224
	 * @return \Aimeos\Map|null List of items implementing \Aimeos\MShop\Common\Item\Iface with ids as keys
225
	 */
226
	public function iterate( \Aimeos\MShop\Common\Cursor\Iface $cursor, array $ref = [] ) : ?\Aimeos\Map
227
	{
228
		if( $cursor->value() === '' ) {
229
			return null;
230
		}
231
232
		$prefix = str_replace( '/', '.', (string) current( $this->getResourceType( false ) ) );
233
		$filter = $cursor->filter()->add( $prefix . '.id', '>', (int) $cursor->value() )->order( $prefix . '.id' );
234
235
		$items = $this->search( $filter, $ref );
236
		$cursor->setValue( $items->lastKey() ?: '' );
237
238
		return !$items->isEmpty() ? $items : null;
239
	}
240
241
242
	/**
243
	 * Adds or updates an item object or a list of them.
244
	 *
245
	 * @param \Aimeos\Map|\Aimeos\MShop\Common\Item\Iface[]|\Aimeos\MShop\Common\Item\Iface $items Item or list of items whose data should be saved
246
	 * @param bool $fetch True if the new ID should be returned in the item
247
	 * @return \Aimeos\Map|\Aimeos\MShop\Common\Item\Iface Saved item or items
248
	 */
249
	public function save( $items, bool $fetch = true )
250
	{
251
		if( is_iterable( $items ) )
252
		{
253
			foreach( $items as $id => $item ) {
254
				$items[$id] = $this->saveItem( $item, $fetch );
0 ignored issues
show
Bug introduced by
It seems like saveItem() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

254
				/** @scrutinizer ignore-call */ 
255
    $items[$id] = $this->saveItem( $item, $fetch );
Loading history...
255
			}
256
			return map( $items );
257
		}
258
259
		return $this->saveItem( $items, $fetch );
260
	}
261
262
263
	/**
264
	 * Searches for all items matching the given critera.
265
	 *
266
	 * @param \Aimeos\Base\Criteria\Iface $filter Criteria object with conditions, sortations, etc.
267
	 * @param string[] $ref List of domains to fetch list items and referenced items for
268
	 * @param int &$total Number of items that are available in total
269
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Common\Item\Iface with ids as keys
270
	 */
271
	public function search( \Aimeos\Base\Criteria\Iface $filter, array $ref = [], int &$total = null ) : \Aimeos\Map
272
	{
273
		return map();
274
	}
275
276
277
	/**
278
	 * Injects the reference of the outmost object
279
	 *
280
	 * @param \Aimeos\MShop\Common\Manager\Iface $object Reference to the outmost manager or decorator
281
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
282
	 */
283
	public function setObject( \Aimeos\MShop\Common\Manager\Iface $object ) : \Aimeos\MShop\Common\Manager\Iface
284
	{
285
		$this->object = $object;
286
		return $this;
287
	}
288
289
290
	/**
291
	 * Starts a database transaction on the connection identified by the given name
292
	 *
293
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
294
	 */
295
	public function begin() : \Aimeos\MShop\Common\Manager\Iface
296
	{
297
		$this->context->db( $this->getResourceName() )->begin();
298
		return $this;
299
	}
300
301
302
	/**
303
	 * Commits the running database transaction on the connection identified by the given name
304
	 *
305
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
306
	 */
307
	public function commit() : \Aimeos\MShop\Common\Manager\Iface
308
	{
309
		$this->context->db( $this->getResourceName() )->commit();
310
		return $this;
311
	}
312
313
314
	/**
315
	 * Rolls back the running database transaction on the connection identified by the given name
316
	 *
317
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
318
	 */
319
	public function rollback() : \Aimeos\MShop\Common\Manager\Iface
320
	{
321
		$this->context->db( $this->getResourceName() )->rollback();
322
		return $this;
323
	}
324
325
326
	/**
327
	 * Applies the filters for the item type to the item
328
	 *
329
	 * @param object $item Item to apply the filter to
330
	 * @return object|null Object if the item should be used, null if not
331
	 */
332
	protected function applyFilter( $item )
333
	{
334
		foreach( $this->filterFcn as $iface => $fcnList )
335
		{
336
			if( is_object( $item ) && $item instanceof $iface )
337
			{
338
				foreach( $fcnList as $fcn )
339
				{
340
					if( $fcn( $item ) === null ) {
341
						return null;
342
					}
343
				}
344
			}
345
		}
346
347
		return $item;
348
	}
349
350
351
	/**
352
	 * Returns the name of the resource or of the default resource.
353
	 *
354
	 * @return string Name of the resource
355
	 */
356
	protected function getResourceName() : string
357
	{
358
		if( $this->resourceName === null ) {
359
			$this->resourceName = $this->context()->config()->get( 'resource/default', 'db' );
360
		}
361
362
		return $this->resourceName;
363
	}
364
	/**
365
	 * Returns the attribute helper functions for searching defined by the manager.
366
	 *
367
	 * @param \Aimeos\Base\Criteria\Attribute\Iface[] $attributes List of search attribute items
368
	 * @return array Associative array of attribute code and helper function
369
	 */
370
	protected function getSearchFunctions( array $attributes ) : array
371
	{
372
		$list = [];
373
		$iface = \Aimeos\Base\Criteria\Attribute\Iface::class;
374
375
		foreach( $attributes as $key => $item )
376
		{
377
			if( $item instanceof $iface ) {
378
				$list[$item->getCode()] = $item->getFunction();
379
			} else if( isset( $item['code'] ) ) {
380
				$list[$item['code']] = $item['function'] ?? null;
381
			} else {
382
				throw new \Aimeos\MW\Common\Exception( sprintf( 'Invalid attribute at position "%1$d"', $key ) );
0 ignored issues
show
Bug introduced by
The type Aimeos\MW\Common\Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
383
			}
384
		}
385
386
		return $list;
387
	}
388
389
390
	/**
391
	 * Returns the attribute translations for searching defined by the manager.
392
	 *
393
	 * @param \Aimeos\Base\Criteria\Attribute\Iface[] $attributes List of search attribute items
394
	 * @return array Associative array of attribute code and internal attribute code
395
	 */
396
	protected function getSearchTranslations( array $attributes ) : array
397
	{
398
		$translations = [];
399
		$iface = \Aimeos\Base\Criteria\Attribute\Iface::class;
400
401
		foreach( $attributes as $key => $item )
402
		{
403
			if( $item instanceof $iface ) {
404
				$translations[$item->getCode()] = $item->getInternalCode();
405
			} else if( isset( $item['code'] ) ) {
406
				$translations[$item['code']] = $item['internalcode'];
407
			} else {
408
				throw new \Aimeos\MW\Common\Exception( sprintf( 'Invalid attribute at position "%1$d"', $key ) );
409
			}
410
		}
411
412
		return $translations;
413
	}
414
415
416
	/**
417
	 * Returns the attribute types for searching defined by the manager.
418
	 *
419
	 * @param \Aimeos\Base\Criteria\Attribute\Iface[] $attributes List of search attribute items
420
	 * @return array Associative array of attribute code and internal attribute type
421
	 */
422
	protected function getSearchTypes( array $attributes ) : array
423
	{
424
		$types = [];
425
		$iface = \Aimeos\Base\Criteria\Attribute\Iface::class;
426
427
		foreach( $attributes as $key => $item )
428
		{
429
			if( $item instanceof $iface ) {
430
				$types[$item->getCode()] = $item->getInternalType();
431
			} else if( isset( $item['code'] ) ) {
432
				$types[$item['code']] = $item['internaltype'];
433
			} else {
434
				throw new \Aimeos\MW\Common\Exception( sprintf( 'Invalid attribute at position "%1$d"', $key ) );
435
			}
436
		}
437
438
		return $types;
439
	}
440
441
442
	/**
443
	 * Returns the outmost decorator of the decorator stack
444
	 *
445
	 * @return \Aimeos\MShop\Common\Manager\Iface Outmost decorator object
446
	 */
447
	protected function object() : \Aimeos\MShop\Common\Manager\Iface
448
	{
449
		return $this->object ?? $this;
450
	}
451
452
453
	/**
454
	 * Sets the name of the database resource that should be used.
455
	 *
456
	 * @param string $name Name of the resource
457
	 * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
458
	 */
459
	protected function setResourceName( string $name ) : \Aimeos\MShop\Common\Manager\Iface
460
	{
461
		$config = $this->context()->config();
462
463
		if( $config->get( 'resource/' . $name ) === null ) {
464
			$this->resourceName = $config->get( 'resource/default', 'db' );
465
		} else {
466
			$this->resourceName = $name;
467
		}
468
469
		return $this;
470
	}
471
}
472