Completed
Push — master ( 264759...40d38a )
by smiley
04:42
created

ImmutableSettingsContainer::__set()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Trait ImmutableSettingsContainer
4
 *
5
 * @filesource   ImmutableSettingsContainer.php
6
 * @created      13.11.2017
7
 * @package      chillerlan\Traits
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Traits;
14
15
use ReflectionClass, ReflectionProperty;
16
17
/**
18
 * a generic container with magic getter and setter
19
 */
20
trait ImmutableSettingsContainer{
21
22
	/**
23
	 * @param iterable|null $properties
24
	 */
25
	public function __construct(iterable $properties = null){
26
27
		if(!empty($properties)){
28
			$this->__fromIterable($properties);
29
		}
30
31
		// call a method with trait name as replacement constructor for each trait
32
		$traits = (new ReflectionClass($this))->getTraits();
33
34
		foreach($traits as $trait){
35
			$method = $trait->getShortName();
36
37
			if(method_exists($this, $method)){
38
				call_user_func([$this, $trait->getShortName()]);
39
			}
40
		}
41
	}
42
43
	/**
44
	 * @param string $property
45
	 *
46
	 * @return mixed
47
	 */
48
	public function __get(string $property){
49
50
		if($this->__isset($property)){
51
			return $this->{$property};
52
		}
53
54
		return null;
55
	}
56
57
	/**
58
	 * @param string $property
59
	 * @param mixed  $value
60
	 *
61
	 * @return void
62
	 */
63
	public function __set(string $property, $value):void{
64
65
		// avoid overwriting private properties
66
		if(property_exists($this, $property) && !$this->__isPrivate($property)){
67
			$this->{$property} = $value;
68
			return;
69
		}
70
71
		return; // should not see me
72
	}
73
74
	/**
75
	 * @param string $property
76
	 *
77
	 * @return bool
78
	 */
79
	public function __isset(string $property):bool{
80
		return (isset($this->{$property}) && !$this->__isPrivate($property));
81
	}
82
83
	/**
84
	 * @param string $property
85
	 *
86
	 * @return bool
87
	 */
88
	protected function __isPrivate(string $property):bool{
89
		return (new ReflectionProperty($this, $property))->isPrivate();
90
	}
91
92
	/**
93
	 * @param string $property
94
	 *
95
	 * @return void
96
	 */
97
	public function __unset(string $property):void{
98
99
		// avoid unsetting private properties
100
		if($this->__isset($property)){
101
			unset($this->{$property});
102
		}
103
104
	}
105
106
	/**
107
	 * @return string
108
	 */
109
	public function __toString():string{
110
		return $this->__toJSON();
111
	}
112
113
	/**
114
	 * @return array
115
	 */
116
	public function __toArray():array{
117
		$data = [];
118
119
		foreach($this as $property => $value){
120
121
			// exclude private properties
122
			if($this->__isset($property)){
123
				$data[$property] = $value;
124
			}
125
126
		}
127
128
		return $data;
129
	}
130
131
	/**
132
	 * @param iterable $properties
133
	 *
134
	 * @return $this
135
	 */
136
	public function __fromIterable(iterable $properties){
137
138
		foreach($properties as $key => $value){
139
			$this->__set($key, $value);
140
		}
141
142
		return $this;
143
	}
144
145
	/**
146
	 * @param bool|null $prettyprint
147
	 *
148
	 * @return string
149
	 */
150
	public function __toJSON(bool $prettyprint = null):string{
151
		return json_encode($this->__toArray(), $prettyprint ? JSON_PRETTY_PRINT : 0);
152
	}
153
154
	/**
155
	 * @param string $json
156
	 *
157
	 * @return $this
158
	 */
159
	public function __fromJSON(string $json){
160
		return $this->__fromIterable(json_decode($json, true));
161
	}
162
163
}
164