Passed
Push — master ( d43b67...7c1687 )
by Aimeos
05:49
created

Base::checkDateFormat()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 18
rs 10
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-2024
7
 * @package MShop
8
 * @subpackage Common
9
 */
10
11
12
namespace Aimeos\MShop\Common\Item;
13
14
15
/**
16
 * Common methods for all item objects.
17
 *
18
 * @package MShop
19
 * @subpackage Common
20
 */
21
class Base implements \Aimeos\MShop\Common\Item\Iface, \Aimeos\Macro\Iface, \ArrayAccess, \JsonSerializable
22
{
23
	use \Aimeos\Macro\Macroable;
24
25
	// protected due to PHP serialization
26
	protected bool $available = true;
27
	protected bool $modified = false;
28
	protected string $bprefix;
29
	protected ?string $type;
30
	protected array $bdata;
31
32
33
	/**
34
	 * Initializes the class properties.
35
	 *
36
	 * @param string $prefix Prefix for the keys returned by toArray()
37
	 * @param array $values Associative list of key/value pairs of the item properties
38
	 * @param string|null $type Item resource type
39
	 */
40
	public function __construct( string $prefix, array $values = [], ?string $type = null )
41
	{
42
		$this->bprefix = $prefix;
43
		$this->bdata = $values;
44
		$this->type = $type;
45
	}
46
47
48
	/**
49
	 * Creates a deep clone of all objects
50
	 */
51
	public function __clone()
52
	{
53
	}
54
55
56
	/**
57
	 * Returns the item property for the given name
58
	 *
59
	 * @param string $name Name of the property
60
	 * @return mixed|null Property value or null if property is unknown
61
	 */
62
	public function __get( string $name )
63
	{
64
		return $this->get( $name );
65
	}
66
67
68
	/**
69
	 * Tests if the item property for the given name is available
70
	 *
71
	 * @param string $name Name of the property
72
	 * @return bool True if the property exists, false if not
73
	 */
74
	public function __isset( string $name ) : bool
75
	{
76
		return array_key_exists( $name, $this->bdata );
77
	}
78
79
80
	/**
81
	 * Sets the new item property for the given name
82
	 *
83
	 * @param string $name Name of the property
84
	 * @param mixed $value New property value
85
	 */
86
	public function __set( string $name, $value )
87
	{
88
		$this->set( $name, $value );
89
	}
90
91
92
	/**
93
	 * Specifies the data which should be serialized to JSON by json_encode().
94
	 *
95
	 * @return array<string,mixed> Data to serialize to JSON
96
	 */
97
	#[\ReturnTypeWillChange]
98
	public function jsonSerialize()
99
	{
100
		return $this->bdata;
101
	}
102
103
104
	/**
105
	 * Tests if the item property for the given name is available
106
	 *
107
	 * @param string $name Name of the property
108
	 * @return bool True if the property exists, false if not
109
	 */
110
	public function offsetExists( $name ) : bool
111
	{
112
		return array_key_exists( $name, $this->bdata );
113
	}
114
115
116
	/**
117
	 * Returns the item property for the given name
118
	 *
119
	 * @param string $name Name of the property
120
	 * @return mixed|null Property value or null if property is unknown
121
	 */
122
	#[\ReturnTypeWillChange]
123
	public function offsetGet( $name )
124
	{
125
		return $this->get( $name );
126
	}
127
128
129
	/**
130
	 * Sets the new item property for the given name
131
	 *
132
	 * @param string $name Name of the property
133
	 * @param mixed $value New property value
134
	 */
135
	public function offsetSet( $name, $value ) : void
136
	{
137
		$this->set( $name, $value );
138
	}
139
140
141
	/**
142
	 * Removes an item property
143
	 * This is not supported by items
144
	 *
145
	 * @param string $name Name of the property
146
	 * @throws \LogicException Always thrown because this method isn't supported
147
	 */
148
	public function offsetUnset( $name ) : void
149
	{
150
		throw new \LogicException( 'Not implemented' );
151
	}
152
153
154
	/**
155
	 * Returns the ID of the items
156
	 *
157
	 * @return string ID of the item or an empty string
158
	 */
159
	public function __toString() : string
160
	{
161
		return (string) $this->getId();
162
	}
163
164
165
	/**
166
	 * Assigns multiple key/value pairs to the item
167
	 *
168
	 * @param iterable $pairs Associative list of key/value pairs
169
	 * @return \Aimeos\MShop\Common\Item\Iface Item for method chaining
170
	 */
171
	public function assign( iterable $pairs ) : \Aimeos\MShop\Common\Item\Iface
172
	{
173
		foreach( $pairs as $key => $value ) {
174
			$this->set( $key, $value );
175
		}
176
177
		return $this;
178
	}
179
180
181
	/**
182
	 * Returns the item property for the given name
183
	 *
184
	 * @param string $name Name of the property
185
	 * @param mixed $default Default value if property is unknown
186
	 * @return mixed|null Property value or default value if property is unknown
187
	 */
188
	public function get( string $name, $default = null )
189
	{
190
		if( array_key_exists( $name, $this->bdata ) ) {
191
			return $this->bdata[$name];
192
		}
193
194
		return $default;
195
	}
196
197
198
	/**
199
	 * Sets the new item property for the given name
200
	 *
201
	 * @param string $name Name of the property
202
	 * @param mixed $value New property value
203
	 * @return \Aimeos\MShop\Common\Item\Iface Item for method chaining
204
	 */
205
	public function set( string $name, $value ) : \Aimeos\MShop\Common\Item\Iface
206
	{
207
		// workaround for NULL values instead of empty strings and stringified integers from database
208
		if( !array_key_exists( $name, $this->bdata ) || $this->bdata[$name] != $value
209
			|| $value === null && $this->bdata[$name] !== null
210
			|| $value !== null && $this->bdata[$name] === null
211
		) {
212
			$this->bdata[$name] = $value;
213
			$this->setModified();
214
		}
215
216
		return $this;
217
	}
218
219
220
	/**
221
	 * Returns the ID of the item if available.
222
	 *
223
	 * @return string|null ID of the item
224
	 */
225
	public function getId() : ?string
226
	{
227
		$key = $this->bprefix . 'id';
228
229
		if( isset( $this->bdata[$key] ) && $this->bdata[$key] != '' ) {
230
			return (string) $this->bdata[$key];
231
		}
232
233
		return null;
234
	}
235
236
237
	/**
238
	 * Sets the new ID of the item.
239
	 *
240
	 * @param string|null $id ID of the item
241
	 * @return \Aimeos\MShop\Common\Item\Iface Item for chaining method calls
242
	 */
243
	public function setId( ?string $id ) : \Aimeos\MShop\Common\Item\Iface
244
	{
245
		$this->bdata[$this->bprefix . 'id'] = $id;
246
		$this->modified = ( $id === null );
247
248
		return $this;
249
	}
250
251
252
	/**
253
	 * Returns the site ID of the item.
254
	 *
255
	 * @return string Site ID or null if no site id is available
256
	 */
257
	public function getSiteId() : string
258
	{
259
		return $this->get( $this->bprefix . 'siteid', $this->get( 'siteid', '' ) );
260
	}
261
262
263
	/**
264
	 * Returns the list site IDs up to the root site item.
265
	 *
266
	 * @return array List of site IDs
267
	 */
268
	public function getSitePath() : array
269
	{
270
		$pos = 0;
271
		$list = [];
272
		$siteId = $this->getSiteId();
273
274
		while( ( $pos = strpos( $siteId, '.', $pos ) ) !== false ) {
275
			$list[] = substr( $siteId, 0, ++$pos );
276
		}
277
278
		return $list;
279
	}
280
281
282
	/**
283
	 * Returns modify date/time of the order coupon.
284
	 *
285
	 * @return string|null Modification time (YYYY-MM-DD HH:mm:ss)
286
	 */
287
	public function getTimeModified() : ?string
288
	{
289
		return $this->get( $this->bprefix . 'mtime', $this->get( 'mtime' ) );
290
	}
291
292
293
	/**
294
	 * Returns the create date of the item.
295
	 *
296
	 * @return string|null ISO date in YYYY-MM-DD hh:mm:ss format
297
	 */
298
	public function getTimeCreated() : ?string
299
	{
300
		return $this->get( $this->bprefix . 'ctime', $this->get( 'ctime' ) );
301
	}
302
303
304
	/**
305
	 * Returns the name of editor who created/modified the item at last.
306
	 *
307
	 * @return string Name of editor who created/modified the item at last
308
	 */
309
	public function editor() : string
310
	{
311
		return $this->get( $this->bprefix . 'editor', $this->get( 'editor', '' ) );
312
	}
313
314
315
	/**
316
	 * Tests if the item is available based on status, time, language and currency
317
	 *
318
	 * @return bool True if available, false if not
319
	 */
320
	public function isAvailable() : bool
321
	{
322
		return $this->available;
323
	}
324
325
326
	/**
327
	 * Sets the general availability of the item
328
	 *
329
	 * @return bool $value True if available, false if not
330
	 * @return \Aimeos\MShop\Common\Item\Iface Item for chaining method calls
331
	 */
332
	public function setAvailable( bool $value ) : \Aimeos\MShop\Common\Item\Iface
333
	{
334
		$this->available = $value;
335
		return $this;
336
	}
337
338
339
	/**
340
	 * Tests if this Item object was modified.
341
	 *
342
	 * @return bool True if modified, false if not
343
	 */
344
	public function isModified() : bool
345
	{
346
		return $this->modified;
347
	}
348
349
350
	/**
351
	 * Sets the modified flag of the object.
352
	 *
353
	 * @return \Aimeos\MShop\Common\Item\Iface Item for chaining method calls
354
	 */
355
	public function setModified() : \Aimeos\MShop\Common\Item\Iface
356
	{
357
		$this->modified = true;
358
		return $this;
359
	}
360
361
362
	/**
363
	 * Returns the item type
364
	 *
365
	 * @return string Item type, subtypes are separated by slashes
366
	 */
367
	public function getResourceType() : string
368
	{
369
		if( !$this->type )
370
		{
371
			$parts = explode( '\\', strtolower( get_class( $this ) ) );
372
			array_shift( $parts ); array_shift( $parts ); // remove "Aimeos\MShop"
373
			array_pop( $parts );
374
375
			$domain = array_shift( $parts ) ?: 'custom';
376
			array_shift( $parts ); // remove "item"
377
			array_unshift( $parts, $domain );
378
379
			$this->type = join( '/', $parts );
380
		}
381
382
		return $this->type;
383
	}
384
385
386
	/**
387
	 * Sets the item values from the given array and removes that entries from the list
388
	 *
389
	 * @param array $list Associative list of item keys and their values
390
	 * @param bool True to set private properties too, false for public only
391
	 * @return \Aimeos\MShop\Common\Item\Iface Item for chaining method calls
392
	 */
393
	public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
394
	{
395
		if( $private && array_key_exists( $this->bprefix . 'id', $list ) )
396
		{
397
			$this->setId( $list[$this->bprefix . 'id'] );
398
			unset( $list[$this->bprefix . 'id'] );
399
		}
400
401
		// Add custom columns
402
		foreach( $list as $key => $value )
403
		{
404
			if( ( is_null( $value ) || is_scalar( $value ) || is_array( $value ) ) && strpos( $key, '.' ) === false ) {
405
				$this->set( $key, $value );
406
			}
407
		}
408
409
		return $this;
410
	}
411
412
413
	/**
414
	 * Returns the item values as array.
415
	 *
416
	 * @param bool True to return private properties, false for public only
417
	 * @return array Associative list of item properties and their values
418
	 */
419
	public function toArray( bool $private = false ) : array
420
	{
421
		$list = [$this->bprefix . 'id' => $this->getId()];
422
423
		if( $private === true )
424
		{
425
			$list[$this->bprefix . 'siteid'] = $this->getSiteId();
426
			$list[$this->bprefix . 'ctime'] = $this->getTimeCreated();
427
			$list[$this->bprefix . 'mtime'] = $this->getTimeModified();
428
			$list[$this->bprefix . 'editor'] = $this->editor();
429
		}
430
431
		foreach( $this->bdata as $key => $value )
432
		{
433
			if( strpos( $key, '.' ) === false ) {
434
				$list[$key] = $value;
435
			}
436
		}
437
438
		return $list;
439
	}
440
441
442
	/**
443
	 * Returns the prefix for the item properties
444
	 *
445
	 * @return string Prefix for the item properties
446
	 */
447
	protected function prefix() : string
448
	{
449
		return $this->bprefix;
450
	}
451
}
452