SettingsContainerAbstract::toJSON()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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