Completed
Push — master ( 45e578...7fd2c2 )
by smiley
02:10
created

SettingsContainerAbstract::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
/**
3
 * Class SettingsContainerAbstract
4
 *
5
 * @filesource   SettingsContainerAbstract.php
6
 * @created      28.08.2018
7
 * @package      chillerlan\Settings
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2018 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Settings;
14
15
use Exception, ReflectionClass, ReflectionProperty;
16
17
use function call_user_func, call_user_func_array, get_object_vars, json_decode, json_encode, method_exists, property_exists;
18
19
abstract class SettingsContainerAbstract implements SettingsContainerInterface{
20
21
	/**
22
	 * SettingsContainerAbstract constructor.
23
	 *
24
	 * @param iterable|null $properties
25
	 */
26
	public function __construct(iterable $properties = null){
27
28
		if(!empty($properties)){
29
			$this->fromIterable($properties);
30
		}
31
32
		$this->construct();
33
	}
34
35
	/**
36
	 * calls a method with trait name as replacement constructor for each used trait
37
	 * (remember pre-php5 classname constructors? yeah, basically this.)
38
	 *
39
	 * @return void
40
	 */
41
	protected function construct():void{
42
		$traits = (new ReflectionClass($this))->getTraits();
43
44
		foreach($traits as $trait){
45
			$method = $trait->getShortName();
46
47
			if(method_exists($this, $method)){
48
				call_user_func([$this, $method]);
49
			}
50
		}
51
52
	}
53
54
	/**
55
	 * @inheritdoc
56
	 */
57
	public function __get(string $property){
58
59
		if($this->__isset($property)){
60
61
			if(method_exists($this, 'get_'.$property)){
62
				return call_user_func([$this, 'get_'.$property]);
63
			}
64
65
			return $this->{$property};
66
		}
67
68
		return null;
69
	}
70
71
	/**
72
	 * @inheritdoc
73
	 */
74
	public function __set(string $property, $value):void{
75
76
		if(!property_exists($this, $property) || $this->isPrivate($property)){
77
			return;
78
		}
79
80
		if(method_exists($this, 'set_'.$property)){
81
			call_user_func_array([$this, 'set_'.$property], [$value]);
82
83
			return;
84
		}
85
86
		$this->{$property} = $value;
87
	}
88
89
	/**
90
	 * @inheritdoc
91
	 */
92
	public function __isset(string $property):bool{
93
		return isset($this->{$property}) && !$this->isPrivate($property);
94
	}
95
96
	/**
97
	 * @internal Checks if a property is private
98
	 *
99
	 * @param string $property
100
	 *
101
	 * @return bool
102
	 */
103
	protected function isPrivate(string $property):bool{
104
		return (new ReflectionProperty($this, $property))->isPrivate();
105
	}
106
107
	/**
108
	 * @inheritdoc
109
	 */
110
	public function __unset(string $property):void{
111
112
		if($this->__isset($property)){
113
			unset($this->{$property});
114
		}
115
116
	}
117
118
	/**
119
	 * @inheritdoc
120
	 */
121
	public function __toString():string{
122
		return $this->toJSON();
123
	}
124
125
	/**
126
	 * @inheritdoc
127
	 */
128
	public function toArray():array{
129
		return get_object_vars($this);
130
	}
131
132
	/**
133
	 * @inheritdoc
134
	 */
135
	public function fromIterable(iterable $properties):SettingsContainerInterface{
136
137
		foreach($properties as $key => $value){
138
			$this->__set($key, $value);
139
		}
140
141
		return $this;
142
	}
143
144
	/**
145
	 * @inheritdoc
146
	 */
147
	public function toJSON(int $jsonOptions = null):string{
148
		return json_encode($this, $jsonOptions ?? 0);
149
	}
150
151
	/**
152
	 * @inheritdoc
153
	 */
154
	public function fromJSON(string $json):SettingsContainerInterface{
155
156
		$data = json_decode($json, true); // as of PHP 7.3: JSON_THROW_ON_ERROR
157
158
		if($data === false || $data === null){
159
			throw new Exception('error while decoding JSON');
160
		}
161
162
		return $this->fromIterable($data);
163
	}
164
165
	/**
166
	 * @inheritdoc
167
	 */
168
	public function jsonSerialize(){
169
		return $this->toArray();
170
	}
171
172
}
173