13
13
/**
14
14
* @method int getId()
15
15
* @method void setId(int $id)
16
+ * @psalm-type AllowedTypes = 'json'|'blob'|'datetime'|'string'|'int'|'integer'|'bool'|'boolean'|'float'|'double'|'array'|'object'
16
17
* @since 7.0.0
17
18
* @psalm-consistent-constructor
18
19
*/
@@ -23,6 +24,7 @@ abstract class Entity {
23
24
public $ id ;
24
25
25
26
private array $ _updatedFields = [];
27
+ /** @var array<string, AllowedTypes> */
26
28
private array $ _fieldTypes = ['id ' => 'integer ' ];
27
29
28
30
/**
@@ -64,10 +66,10 @@ public static function fromRow(array $row): static {
64
66
65
67
66
68
/**
67
- * @return array with attribute and type
69
+ * @return array<string, AllowedTypes> with attribute and type
68
70
* @since 7.0.0
69
71
*/
70
- public function getFieldTypes () {
72
+ public function getFieldTypes (): array {
71
73
return $ this ->_fieldTypes ;
72
74
}
73
75
@@ -76,50 +78,63 @@ public function getFieldTypes() {
76
78
* Marks the entity as clean needed for setting the id after the insertion
77
79
* @since 7.0.0
78
80
*/
79
- public function resetUpdatedFields () {
81
+ public function resetUpdatedFields (): void {
80
82
$ this ->_updatedFields = [];
81
83
}
82
84
83
85
/**
84
86
* Generic setter for properties
87
+ *
88
+ * @throws \InvalidArgumentException
85
89
* @since 7.0.0
90
+ *
86
91
*/
87
92
protected function setter (string $ name , array $ args ): void {
88
93
// setters should only work for existing attributes
89
- if (property_exists ($ this , $ name )) {
90
- if ($ args [0 ] === $ this ->$ name ) {
91
- return ;
92
- }
93
- $ this ->markFieldUpdated ($ name );
94
-
95
- // if type definition exists, cast to correct type
96
- if ($ args [0 ] !== null && array_key_exists ($ name , $ this ->_fieldTypes )) {
97
- $ type = $ this ->_fieldTypes [$ name ];
98
- if ($ type === 'blob ' ) {
99
- // (B)LOB is treated as string when we read from the DB
100
- if (is_resource ($ args [0 ])) {
101
- $ args [0 ] = stream_get_contents ($ args [0 ]);
102
- }
103
- $ type = 'string ' ;
94
+ if (!property_exists ($ this , $ name )) {
95
+ throw new \BadFunctionCallException ($ name .
96
+ ' is not a valid attribute ' );
97
+ }
98
+
99
+ if ($ args [0 ] === $ this ->$ name ) {
100
+ return ;
101
+ }
102
+ $ this ->markFieldUpdated ($ name );
103
+
104
+ // if type definition exists, cast to correct type
105
+ if ($ args [0 ] !== null && array_key_exists ($ name , $ this ->_fieldTypes )) {
106
+ $ type = $ this ->_fieldTypes [$ name ];
107
+ if ($ type === 'blob ' ) {
108
+ // (B)LOB is treated as string when we read from the DB
109
+ if (is_resource ($ args [0 ])) {
110
+ $ args [0 ] = stream_get_contents ($ args [0 ]);
104
111
}
112
+ $ type = 'string ' ;
113
+ }
105
114
106
- if ($ type === 'datetime ' ) {
107
- if (!$ args [0 ] instanceof \DateTime) {
108
- $ args [0 ] = new \DateTime ($ args [0 ]);
109
- }
110
- } elseif ($ type === 'json ' ) {
111
- if (!is_array ($ args [0 ])) {
112
- $ args [0 ] = json_decode ($ args [0 ], true );
113
- }
114
- } else {
115
- settype ($ args [0 ], $ type );
115
+ if ($ type === 'datetime ' ) {
116
+ if (!$ args [0 ] instanceof \DateTime) {
117
+ $ args [0 ] = new \DateTime ($ args [0 ]);
118
+ }
119
+ } elseif ($ type === 'json ' ) {
120
+ if (!is_array ($ args [0 ])) {
121
+ $ args [0 ] = json_decode ($ args [0 ], true );
116
122
}
123
+ } else {
124
+ $ args [0 ] = match ($ type ) {
125
+ 'string ' => (string )$ args [0 ],
126
+ 'bool ' , 'boolean ' , => (bool )$ args [0 ],
127
+ 'int ' , 'integer ' , => (int )$ args [0 ],
128
+ 'float ' => (float )$ args [0 ],
129
+ 'double ' => (float )$ args [0 ],
130
+ 'array ' => (array )$ args [0 ],
131
+ 'object ' => (object )$ args [0 ],
132
+ default => new \InvalidArgumentException ()
133
+ };
117
134
}
118
- $ this ->$ name = $ args [0 ];
119
- } else {
120
- throw new \BadFunctionCallException ($ name .
121
- ' is not a valid attribute ' );
122
135
}
136
+ $ this ->$ name = $ args [0 ];
137
+
123
138
}
124
139
125
140
/**
@@ -182,16 +197,17 @@ protected function markFieldUpdated(string $attribute): void {
182
197
183
198
/**
184
199
* Transform a database columnname to a property
200
+ *
185
201
* @param string $columnName the name of the column
186
202
* @return string the property name
187
203
* @since 7.0.0
188
204
*/
189
- public function columnToProperty ($ columnName ) {
205
+ public function columnToProperty (string $ columnName ): string {
190
206
$ parts = explode ('_ ' , $ columnName );
191
- $ property = null ;
207
+ $ property = '' ;
192
208
193
209
foreach ($ parts as $ part ) {
194
- if ($ property === null ) {
210
+ if ($ property === '' ) {
195
211
$ property = $ part ;
196
212
} else {
197
213
$ property .= ucfirst ($ part );
@@ -204,16 +220,17 @@ public function columnToProperty($columnName) {
204
220
205
221
/**
206
222
* Transform a property to a database column name
223
+ *
207
224
* @param string $property the name of the property
208
225
* @return string the column name
209
226
* @since 7.0.0
210
227
*/
211
- public function propertyToColumn ($ property ) {
228
+ public function propertyToColumn (string $ property ): string {
212
229
$ parts = preg_split ('/(?=[A-Z])/ ' , $ property );
213
- $ column = null ;
214
230
231
+ $ column = '' ;
215
232
foreach ($ parts as $ part ) {
216
- if ($ column === null ) {
233
+ if ($ column === '' ) {
217
234
$ column = $ part ;
218
235
} else {
219
236
$ column .= '_ ' . lcfirst ($ part );
@@ -228,32 +245,34 @@ public function propertyToColumn($property) {
228
245
* @return array array of updated fields for update query
229
246
* @since 7.0.0
230
247
*/
231
- public function getUpdatedFields () {
248
+ public function getUpdatedFields (): array {
232
249
return $ this ->_updatedFields ;
233
250
}
234
251
235
252
236
253
/**
237
- * Adds type information for a field so that its automatically casted to
254
+ * Adds type information for a field so that it's automatically cast to
238
255
* that value once its being returned from the database
256
+ *
239
257
* @param string $fieldName the name of the attribute
240
- * @param string $type the type which will be used to call settype()
258
+ * @param AllowedTypes $type the type which will be used to match a cast
241
259
* @since 7.0.0
242
260
*/
243
- protected function addType ($ fieldName , $ type ) {
261
+ protected function addType (string $ fieldName , string $ type ): void {
244
262
$ this ->_fieldTypes [$ fieldName ] = $ type ;
245
263
}
246
264
247
265
248
266
/**
249
267
* Slugify the value of a given attribute
250
268
* Warning: This doesn't result in a unique value
269
+ *
251
270
* @param string $attributeName the name of the attribute, which value should be slugified
252
271
* @return string slugified value
253
272
* @since 7.0.0
254
273
* @deprecated 24.0.0
255
274
*/
256
- public function slugify ($ attributeName ) {
275
+ public function slugify (string $ attributeName ): string {
257
276
// toSlug should only work for existing attributes
258
277
if (property_exists ($ this , $ attributeName )) {
259
278
$ value = $ this ->$ attributeName ;
@@ -262,9 +281,8 @@ public function slugify($attributeName) {
262
281
$ value = strtolower ($ value );
263
282
// trim '-'
264
283
return trim ($ value , '- ' );
265
- } else {
266
- throw new \BadFunctionCallException ($ attributeName .
267
- ' is not a valid attribute ' );
268
284
}
285
+
286
+ throw new \BadFunctionCallException ($ attributeName . ' is not a valid attribute ' );
269
287
}
270
288
}
0 commit comments