1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
/** |
4
|
|
|
* Created by PhpStorm. |
5
|
|
|
* User: benedikt |
6
|
|
|
* Date: 10/4/16 |
7
|
|
|
* Time: 10:10 PM |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace Tfboe\FmLib\Entity\Helpers; |
11
|
|
|
|
12
|
|
|
use Tfboe\FmLib\Exceptions\MethodNotExistingException; |
13
|
|
|
use Tfboe\FmLib\Exceptions\PropertyNotExistingException; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Trait SubClassData |
17
|
|
|
* implements magic methods for getting and setting subclass data. Stores them in one field, which is stored via |
18
|
|
|
* doctrine as json_array / string (if json_array is not supported). |
19
|
|
|
* @package Tfboe\FmLib\Entity |
20
|
|
|
*/ |
21
|
|
|
trait SubClassData |
22
|
|
|
{ |
23
|
|
|
//<editor-fold desc="Fields"> |
24
|
|
|
/** |
25
|
|
|
* @var array |
26
|
|
|
* @ORM\Column(type="json_array") |
27
|
|
|
*/ |
28
|
|
|
private $subClassData; |
29
|
|
|
|
30
|
|
|
//</editor-fold desc="Fields"> |
31
|
|
|
|
32
|
|
|
//<editor-fold desc="Public Final Methods"> |
33
|
|
|
/** |
34
|
|
|
* Gets a property or throws an error if the property does not exist. |
35
|
|
|
* @param string $name the name of the property |
36
|
|
|
* @return mixed the value of the property |
37
|
|
|
* @throws PropertyNotExistingException |
38
|
|
|
*/ |
39
|
|
View Code Duplication |
public final function getProperty($name) |
|
|
|
|
40
|
|
|
{ |
41
|
|
|
if (!array_key_exists(strtolower($name), $this->subClassData)) { |
42
|
|
|
throw new PropertyNotExistingException(get_class($this), strtolower($name), "getProperty"); |
43
|
|
|
} |
44
|
|
|
return $this->subClassData[strtolower($name)]; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Sets a property with the given name and the given value |
49
|
|
|
* @param string $name the name of the property to set |
50
|
|
|
* @param mixed $value the new value for the property |
51
|
|
|
* @return $this|SubClassData |
|
|
|
|
52
|
|
|
* @throws PropertyNotExistingException |
53
|
|
|
*/ |
54
|
|
View Code Duplication |
public final function setProperty(string $name, $value) |
|
|
|
|
55
|
|
|
{ |
56
|
|
|
if (!array_key_exists(strtolower($name), $this->subClassData)) { |
57
|
|
|
throw new PropertyNotExistingException(get_class($this), strtolower($name), "setProperty"); |
58
|
|
|
} |
59
|
|
|
$this->subClassData[strtolower($name)] = $value; |
60
|
|
|
return $this; |
61
|
|
|
} |
62
|
|
|
//</editor-fold desc="Public Final Methods"> |
63
|
|
|
|
64
|
|
|
//<editor-fold desc="Public Methods"> |
65
|
|
|
/** |
66
|
|
|
* Magic function call for getters and setters of subclass data. |
67
|
|
|
* Triggers an error if the function was not a get or set method. |
68
|
|
|
* @param string $name function name |
69
|
|
|
* @param mixed[] $arguments the function arguments |
70
|
|
|
* @return $this|SubClassData|mixed either the value if it was a get request or $this if it was a set method |
71
|
|
|
* @throws MethodNotExistingException |
72
|
|
|
* @throws PropertyNotExistingException |
73
|
|
|
*/ |
74
|
|
|
public function __call(string $name, $arguments) |
75
|
|
|
{ |
76
|
|
|
if (substr($name, 0, 3) === "get") { |
77
|
|
|
return $this->getProperty(substr($name, 3)); |
78
|
|
|
} else if (substr($name, 0, 2) === "is") { |
79
|
|
|
return $this->getProperty(substr($name, 2)); |
80
|
|
|
} else if (substr($name, 0, 3) === "set" && count($arguments) == 1) { |
81
|
|
|
return $this->setProperty(substr($name, 3), $arguments[0]); |
82
|
|
|
} |
83
|
|
|
throw new MethodNotExistingException(get_class($this), $name); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Adds an subclass property if it is not already existent. The default value is used as value. |
88
|
|
|
* @param string $name the property name |
89
|
|
|
* @param mixed $default the default value for the property |
90
|
|
|
* @return $this|SubClassData |
|
|
|
|
91
|
|
|
*/ |
92
|
|
|
public function addPropertyIfNotExistent(string $name, $default) |
93
|
|
|
{ |
94
|
|
|
if (!array_key_exists(strtolower($name), $this->subClassData)) { |
95
|
|
|
$this->subClassData[strtolower($name)] = $default; |
96
|
|
|
} |
97
|
|
|
return $this; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* clones the subclass data from other into this |
102
|
|
|
* @param SubClassData $other |
|
|
|
|
103
|
|
|
*/ |
104
|
|
|
public function cloneSubClassDataFrom($other) |
105
|
|
|
{ |
106
|
|
|
$this->subClassData = $other->subClassData; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Checks if the contains the given property as subclass data. |
111
|
|
|
* @param string $property the property name |
112
|
|
|
* @return bool true if it has the property and false otherwise |
113
|
|
|
*/ |
114
|
|
|
public function hasProperty(string $property): bool |
115
|
|
|
{ |
116
|
|
|
return array_key_exists(strtolower($property), $this->subClassData) || property_exists($this, $property); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Initializes the subclassData structure and adds the given keys with null values to it. |
121
|
|
|
* @param string[] $keys the keys of the subclass data properties (the names). |
122
|
|
|
* @return $this|SubClassData |
|
|
|
|
123
|
|
|
*/ |
124
|
|
|
public function initSubClassData(array $keys) |
125
|
|
|
{ |
126
|
|
|
$this->subClassData = []; |
127
|
|
|
foreach ($keys as $key) { |
128
|
|
|
$this->subClassData[strtolower($key)] = null; |
129
|
|
|
} |
130
|
|
|
return $this; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Checks if a method with the given name exists considering also getter and setter for subclass properties |
135
|
|
|
* @param string $method |
136
|
|
|
* @return bool |
137
|
|
|
*/ |
138
|
|
|
public function methodExists(string $method): bool |
139
|
|
|
{ |
140
|
|
|
if (method_exists($this, $method)) { |
141
|
|
|
return true; |
142
|
|
|
} |
143
|
|
|
//check if method corresponds to existing property |
144
|
|
|
if (substr($method, 0, 3) === "get") { |
145
|
|
|
return $this->hasProperty(substr($method, 3)); |
146
|
|
|
} else if (substr($method, 0, 2) === "is") { |
147
|
|
|
return $this->hasProperty(substr($method, 2)); |
148
|
|
|
} else if (substr($method, 0, 3) === "set") { |
149
|
|
|
return $this->hasProperty(substr($method, 3)); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
return false; |
153
|
|
|
} |
154
|
|
|
//</editor-fold desc="Public Methods"> |
155
|
|
|
|
156
|
|
|
//<editor-fold desc="Private Methods"> |
157
|
|
|
//</editor-fold desc="Private Methods"> |
158
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.