Completed
Push — master ( 6b6dee...9e516b )
by Joas
59:38 queued 16:03
created
lib/public/AppFramework/Db/SnowflakeAwareEntity.php 1 patch
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -21,38 +21,38 @@
 block discarded – undo
21 21
  */
22 22
 #[Consumable(since: '33.0.0')]
23 23
 abstract class SnowflakeAwareEntity extends Entity {
24
-	protected ?Snowflake $snowflake = null;
25
-
26
-	/** @psalm-param $_fieldTypes array<string, Types::*> */
27
-	protected array $_fieldTypes = ['id' => Types::STRING];
28
-
29
-	public function setId($id): void {
30
-		throw new \LogicException('Use generated id to set a new id to the Snowflake aware entity.');
31
-	}
32
-
33
-	/**
34
-	 * Automatically creates a snowflake ID
35
-	 */
36
-	public function generateId(): void {
37
-		if ($this->id === null) {
38
-			$this->id = Server::get(ISnowflakeGenerator::class)->nextId();
39
-			$this->markFieldUpdated('id');
40
-		}
41
-	}
42
-
43
-	public function getCreatedAt(): ?\DateTimeImmutable {
44
-		return $this->getSnowflake()?->getCreatedAt();
45
-	}
46
-
47
-	public function getSnowflake(): ?Snowflake {
48
-		if ($this->id === null) {
49
-			return null;
50
-		}
51
-
52
-		if ($this->snowflake === null) {
53
-			$this->snowflake = Server::get(ISnowflakeDecoder::class)->decode($this->id);
54
-		}
55
-
56
-		return $this->snowflake;
57
-	}
24
+    protected ?Snowflake $snowflake = null;
25
+
26
+    /** @psalm-param $_fieldTypes array<string, Types::*> */
27
+    protected array $_fieldTypes = ['id' => Types::STRING];
28
+
29
+    public function setId($id): void {
30
+        throw new \LogicException('Use generated id to set a new id to the Snowflake aware entity.');
31
+    }
32
+
33
+    /**
34
+     * Automatically creates a snowflake ID
35
+     */
36
+    public function generateId(): void {
37
+        if ($this->id === null) {
38
+            $this->id = Server::get(ISnowflakeGenerator::class)->nextId();
39
+            $this->markFieldUpdated('id');
40
+        }
41
+    }
42
+
43
+    public function getCreatedAt(): ?\DateTimeImmutable {
44
+        return $this->getSnowflake()?->getCreatedAt();
45
+    }
46
+
47
+    public function getSnowflake(): ?Snowflake {
48
+        if ($this->id === null) {
49
+            return null;
50
+        }
51
+
52
+        if ($this->snowflake === null) {
53
+            $this->snowflake = Server::get(ISnowflakeDecoder::class)->decode($this->id);
54
+        }
55
+
56
+        return $this->snowflake;
57
+    }
58 58
 }
Please login to merge, or discard this patch.
lib/public/AppFramework/Db/Entity.php 2 patches
Indentation   +287 added lines, -287 removed lines patch added patch discarded remove patch
@@ -19,291 +19,291 @@
 block discarded – undo
19 19
  * @psalm-consistent-constructor
20 20
  */
21 21
 abstract class Entity {
22
-	public int|string|null $id = null;
23
-	private array $_updatedFields = [];
24
-	/** @psalm-param $_fieldTypes array<string, Types::*> */
25
-	protected array $_fieldTypes = ['id' => 'integer'];
26
-
27
-	/**
28
-	 * Simple alternative constructor for building entities from a request
29
-	 * @param array $params the array which was obtained via $this->params('key')
30
-	 *                      in the controller
31
-	 * @since 7.0.0
32
-	 */
33
-	public static function fromParams(array $params): static {
34
-		$instance = new static();
35
-
36
-		foreach ($params as $key => $value) {
37
-			$method = 'set' . ucfirst($key);
38
-			$instance->$method($value);
39
-		}
40
-
41
-		return $instance;
42
-	}
43
-
44
-	/**
45
-	 * Maps the keys of the row array to the attributes
46
-	 * @param array $row the row to map onto the entity
47
-	 * @since 7.0.0
48
-	 */
49
-	public static function fromRow(array $row): static {
50
-		$instance = new static();
51
-
52
-		foreach ($row as $key => $value) {
53
-			$prop = $instance->columnToProperty($key);
54
-			$instance->setter($prop, [$value]);
55
-		}
56
-
57
-		$instance->resetUpdatedFields();
58
-
59
-		return $instance;
60
-	}
61
-
62
-
63
-	/**
64
-	 * @return array<string, Types::*> with attribute and type
65
-	 * @since 7.0.0
66
-	 */
67
-	public function getFieldTypes(): array {
68
-		return $this->_fieldTypes;
69
-	}
70
-
71
-
72
-	/**
73
-	 * Marks the entity as clean needed for setting the id after the insertion
74
-	 * @since 7.0.0
75
-	 */
76
-	public function resetUpdatedFields(): void {
77
-		$this->_updatedFields = [];
78
-	}
79
-
80
-	/**
81
-	 * Generic setter for properties
82
-	 *
83
-	 * @throws \InvalidArgumentException
84
-	 * @since 7.0.0
85
-	 *
86
-	 */
87
-	protected function setter(string $name, array $args): void {
88
-		// setters should only work for existing attributes
89
-		if (!property_exists($this, $name)) {
90
-			throw new \BadFunctionCallException($name . ' is not a valid attribute');
91
-		}
92
-
93
-		if ($args[0] === $this->$name) {
94
-			return;
95
-		}
96
-		$this->markFieldUpdated($name);
97
-
98
-		// if type definition exists, cast to correct type
99
-		if ($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) {
100
-			$type = $this->_fieldTypes[$name];
101
-			if ($type === Types::BLOB) {
102
-				// (B)LOB is treated as string when we read from the DB
103
-				if (is_resource($args[0])) {
104
-					$args[0] = stream_get_contents($args[0]);
105
-				}
106
-				$type = Types::STRING;
107
-			}
108
-
109
-			switch ($type) {
110
-				case Types::BIGINT:
111
-				case Types::SMALLINT:
112
-					settype($args[0], Types::INTEGER);
113
-					break;
114
-				case Types::BINARY:
115
-				case Types::DECIMAL:
116
-				case Types::TEXT:
117
-					settype($args[0], Types::STRING);
118
-					break;
119
-				case Types::TIME:
120
-				case Types::DATE:
121
-				case Types::DATETIME:
122
-				case Types::DATETIME_TZ:
123
-					if (!$args[0] instanceof \DateTime) {
124
-						$args[0] = new \DateTime($args[0]);
125
-					}
126
-					break;
127
-				case Types::TIME_IMMUTABLE:
128
-				case Types::DATE_IMMUTABLE:
129
-				case Types::DATETIME_IMMUTABLE:
130
-				case Types::DATETIME_TZ_IMMUTABLE:
131
-					if (!$args[0] instanceof \DateTimeImmutable) {
132
-						$args[0] = new \DateTimeImmutable($args[0]);
133
-					}
134
-					break;
135
-				case Types::JSON:
136
-					if (!is_array($args[0])) {
137
-						$args[0] = json_decode($args[0], true);
138
-					}
139
-					break;
140
-				default:
141
-					settype($args[0], $type);
142
-			}
143
-		}
144
-		$this->$name = $args[0];
145
-
146
-	}
147
-
148
-	/**
149
-	 * Generic getter for properties
150
-	 * @since 7.0.0
151
-	 */
152
-	protected function getter(string $name): mixed {
153
-		// getters should only work for existing attributes
154
-		if (property_exists($this, $name)) {
155
-			return $this->$name;
156
-		} else {
157
-			throw new \BadFunctionCallException($name
158
-				. ' is not a valid attribute');
159
-		}
160
-	}
161
-
162
-
163
-	/**
164
-	 * Each time a setter is called, push the part after set
165
-	 * into an array: for instance setId will save Id in the
166
-	 * updated fields array so it can be easily used to create the
167
-	 * getter method
168
-	 * @since 7.0.0
169
-	 */
170
-	public function __call(string $methodName, array $args) {
171
-		if (str_starts_with($methodName, 'set')) {
172
-			$this->setter(lcfirst(substr($methodName, 3)), $args);
173
-		} elseif (str_starts_with($methodName, 'get')) {
174
-			return $this->getter(lcfirst(substr($methodName, 3)));
175
-		} elseif ($this->isGetterForBoolProperty($methodName)) {
176
-			return $this->getter(lcfirst(substr($methodName, 2)));
177
-		} else {
178
-			throw new \BadFunctionCallException($methodName
179
-				. ' does not exist');
180
-		}
181
-	}
182
-
183
-	/**
184
-	 * @param string $methodName
185
-	 * @return bool
186
-	 * @since 18.0.0
187
-	 */
188
-	protected function isGetterForBoolProperty(string $methodName): bool {
189
-		if (str_starts_with($methodName, 'is')) {
190
-			$fieldName = lcfirst(substr($methodName, 2));
191
-			return isset($this->_fieldTypes[$fieldName]) && str_starts_with($this->_fieldTypes[$fieldName], 'bool');
192
-		}
193
-		return false;
194
-	}
195
-
196
-	/**
197
-	 * Mark am attribute as updated
198
-	 * @param string $attribute the name of the attribute
199
-	 * @since 7.0.0
200
-	 */
201
-	protected function markFieldUpdated(string $attribute): void {
202
-		$this->_updatedFields[$attribute] = true;
203
-	}
204
-
205
-
206
-	/**
207
-	 * Transform a database columnname to a property
208
-	 *
209
-	 * @param string $columnName the name of the column
210
-	 * @return string the property name
211
-	 * @since 7.0.0
212
-	 */
213
-	public function columnToProperty(string $columnName) {
214
-		$parts = explode('_', $columnName);
215
-		$property = '';
216
-
217
-		foreach ($parts as $part) {
218
-			if ($property === '') {
219
-				$property = $part;
220
-			} else {
221
-				$property .= ucfirst($part);
222
-			}
223
-		}
224
-
225
-		return $property;
226
-	}
227
-
228
-
229
-	/**
230
-	 * Transform a property to a database column name
231
-	 *
232
-	 * @param string $property the name of the property
233
-	 * @return string the column name
234
-	 * @since 7.0.0
235
-	 */
236
-	public function propertyToColumn(string $property): string {
237
-		$parts = preg_split('/(?=[A-Z])/', $property);
238
-
239
-		$column = '';
240
-		foreach ($parts as $part) {
241
-			if ($column === '') {
242
-				$column = $part;
243
-			} else {
244
-				$column .= '_' . lcfirst($part);
245
-			}
246
-		}
247
-
248
-		return $column;
249
-	}
250
-
251
-
252
-	/**
253
-	 * @return array array of updated fields for update query
254
-	 * @since 7.0.0
255
-	 */
256
-	public function getUpdatedFields(): array {
257
-		return $this->_updatedFields;
258
-	}
259
-
260
-
261
-	/**
262
-	 * Adds type information for a field so that it's automatically cast to
263
-	 * that value once its being returned from the database
264
-	 *
265
-	 * @param string $fieldName the name of the attribute
266
-	 * @param Types::* $type the type which will be used to match a cast
267
-	 * @since 31.0.0 Parameter $type is now restricted to {@see Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly.
268
-	 * @since 7.0.0
269
-	 */
270
-	protected function addType(string $fieldName, string $type): void {
271
-		/** @psalm-suppress TypeDoesNotContainType */
272
-		if (in_array($type, ['bool', 'double', 'int', 'array', 'object'], true)) {
273
-			// Mapping legacy strings to the actual types
274
-			$type = match ($type) {
275
-				'int' => Types::INTEGER,
276
-				'bool' => Types::BOOLEAN,
277
-				'double' => Types::FLOAT,
278
-				'array',
279
-				'object' => Types::STRING,
280
-			};
281
-		}
282
-
283
-		$this->_fieldTypes[$fieldName] = $type;
284
-	}
285
-
286
-
287
-	/**
288
-	 * Slugify the value of a given attribute
289
-	 * Warning: This doesn't result in a unique value
290
-	 *
291
-	 * @param string $attributeName the name of the attribute, which value should be slugified
292
-	 * @return string slugified value
293
-	 * @since 7.0.0
294
-	 * @deprecated 24.0.0
295
-	 */
296
-	public function slugify(string $attributeName): string {
297
-		// toSlug should only work for existing attributes
298
-		if (property_exists($this, $attributeName)) {
299
-			$value = $this->$attributeName;
300
-			// replace everything except alphanumeric with a single '-'
301
-			$value = preg_replace('/[^A-Za-z0-9]+/', '-', $value);
302
-			$value = strtolower($value);
303
-			// trim '-'
304
-			return trim($value, '-');
305
-		}
306
-
307
-		throw new \BadFunctionCallException($attributeName . ' is not a valid attribute');
308
-	}
22
+    public int|string|null $id = null;
23
+    private array $_updatedFields = [];
24
+    /** @psalm-param $_fieldTypes array<string, Types::*> */
25
+    protected array $_fieldTypes = ['id' => 'integer'];
26
+
27
+    /**
28
+     * Simple alternative constructor for building entities from a request
29
+     * @param array $params the array which was obtained via $this->params('key')
30
+     *                      in the controller
31
+     * @since 7.0.0
32
+     */
33
+    public static function fromParams(array $params): static {
34
+        $instance = new static();
35
+
36
+        foreach ($params as $key => $value) {
37
+            $method = 'set' . ucfirst($key);
38
+            $instance->$method($value);
39
+        }
40
+
41
+        return $instance;
42
+    }
43
+
44
+    /**
45
+     * Maps the keys of the row array to the attributes
46
+     * @param array $row the row to map onto the entity
47
+     * @since 7.0.0
48
+     */
49
+    public static function fromRow(array $row): static {
50
+        $instance = new static();
51
+
52
+        foreach ($row as $key => $value) {
53
+            $prop = $instance->columnToProperty($key);
54
+            $instance->setter($prop, [$value]);
55
+        }
56
+
57
+        $instance->resetUpdatedFields();
58
+
59
+        return $instance;
60
+    }
61
+
62
+
63
+    /**
64
+     * @return array<string, Types::*> with attribute and type
65
+     * @since 7.0.0
66
+     */
67
+    public function getFieldTypes(): array {
68
+        return $this->_fieldTypes;
69
+    }
70
+
71
+
72
+    /**
73
+     * Marks the entity as clean needed for setting the id after the insertion
74
+     * @since 7.0.0
75
+     */
76
+    public function resetUpdatedFields(): void {
77
+        $this->_updatedFields = [];
78
+    }
79
+
80
+    /**
81
+     * Generic setter for properties
82
+     *
83
+     * @throws \InvalidArgumentException
84
+     * @since 7.0.0
85
+     *
86
+     */
87
+    protected function setter(string $name, array $args): void {
88
+        // setters should only work for existing attributes
89
+        if (!property_exists($this, $name)) {
90
+            throw new \BadFunctionCallException($name . ' is not a valid attribute');
91
+        }
92
+
93
+        if ($args[0] === $this->$name) {
94
+            return;
95
+        }
96
+        $this->markFieldUpdated($name);
97
+
98
+        // if type definition exists, cast to correct type
99
+        if ($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) {
100
+            $type = $this->_fieldTypes[$name];
101
+            if ($type === Types::BLOB) {
102
+                // (B)LOB is treated as string when we read from the DB
103
+                if (is_resource($args[0])) {
104
+                    $args[0] = stream_get_contents($args[0]);
105
+                }
106
+                $type = Types::STRING;
107
+            }
108
+
109
+            switch ($type) {
110
+                case Types::BIGINT:
111
+                case Types::SMALLINT:
112
+                    settype($args[0], Types::INTEGER);
113
+                    break;
114
+                case Types::BINARY:
115
+                case Types::DECIMAL:
116
+                case Types::TEXT:
117
+                    settype($args[0], Types::STRING);
118
+                    break;
119
+                case Types::TIME:
120
+                case Types::DATE:
121
+                case Types::DATETIME:
122
+                case Types::DATETIME_TZ:
123
+                    if (!$args[0] instanceof \DateTime) {
124
+                        $args[0] = new \DateTime($args[0]);
125
+                    }
126
+                    break;
127
+                case Types::TIME_IMMUTABLE:
128
+                case Types::DATE_IMMUTABLE:
129
+                case Types::DATETIME_IMMUTABLE:
130
+                case Types::DATETIME_TZ_IMMUTABLE:
131
+                    if (!$args[0] instanceof \DateTimeImmutable) {
132
+                        $args[0] = new \DateTimeImmutable($args[0]);
133
+                    }
134
+                    break;
135
+                case Types::JSON:
136
+                    if (!is_array($args[0])) {
137
+                        $args[0] = json_decode($args[0], true);
138
+                    }
139
+                    break;
140
+                default:
141
+                    settype($args[0], $type);
142
+            }
143
+        }
144
+        $this->$name = $args[0];
145
+
146
+    }
147
+
148
+    /**
149
+     * Generic getter for properties
150
+     * @since 7.0.0
151
+     */
152
+    protected function getter(string $name): mixed {
153
+        // getters should only work for existing attributes
154
+        if (property_exists($this, $name)) {
155
+            return $this->$name;
156
+        } else {
157
+            throw new \BadFunctionCallException($name
158
+                . ' is not a valid attribute');
159
+        }
160
+    }
161
+
162
+
163
+    /**
164
+     * Each time a setter is called, push the part after set
165
+     * into an array: for instance setId will save Id in the
166
+     * updated fields array so it can be easily used to create the
167
+     * getter method
168
+     * @since 7.0.0
169
+     */
170
+    public function __call(string $methodName, array $args) {
171
+        if (str_starts_with($methodName, 'set')) {
172
+            $this->setter(lcfirst(substr($methodName, 3)), $args);
173
+        } elseif (str_starts_with($methodName, 'get')) {
174
+            return $this->getter(lcfirst(substr($methodName, 3)));
175
+        } elseif ($this->isGetterForBoolProperty($methodName)) {
176
+            return $this->getter(lcfirst(substr($methodName, 2)));
177
+        } else {
178
+            throw new \BadFunctionCallException($methodName
179
+                . ' does not exist');
180
+        }
181
+    }
182
+
183
+    /**
184
+     * @param string $methodName
185
+     * @return bool
186
+     * @since 18.0.0
187
+     */
188
+    protected function isGetterForBoolProperty(string $methodName): bool {
189
+        if (str_starts_with($methodName, 'is')) {
190
+            $fieldName = lcfirst(substr($methodName, 2));
191
+            return isset($this->_fieldTypes[$fieldName]) && str_starts_with($this->_fieldTypes[$fieldName], 'bool');
192
+        }
193
+        return false;
194
+    }
195
+
196
+    /**
197
+     * Mark am attribute as updated
198
+     * @param string $attribute the name of the attribute
199
+     * @since 7.0.0
200
+     */
201
+    protected function markFieldUpdated(string $attribute): void {
202
+        $this->_updatedFields[$attribute] = true;
203
+    }
204
+
205
+
206
+    /**
207
+     * Transform a database columnname to a property
208
+     *
209
+     * @param string $columnName the name of the column
210
+     * @return string the property name
211
+     * @since 7.0.0
212
+     */
213
+    public function columnToProperty(string $columnName) {
214
+        $parts = explode('_', $columnName);
215
+        $property = '';
216
+
217
+        foreach ($parts as $part) {
218
+            if ($property === '') {
219
+                $property = $part;
220
+            } else {
221
+                $property .= ucfirst($part);
222
+            }
223
+        }
224
+
225
+        return $property;
226
+    }
227
+
228
+
229
+    /**
230
+     * Transform a property to a database column name
231
+     *
232
+     * @param string $property the name of the property
233
+     * @return string the column name
234
+     * @since 7.0.0
235
+     */
236
+    public function propertyToColumn(string $property): string {
237
+        $parts = preg_split('/(?=[A-Z])/', $property);
238
+
239
+        $column = '';
240
+        foreach ($parts as $part) {
241
+            if ($column === '') {
242
+                $column = $part;
243
+            } else {
244
+                $column .= '_' . lcfirst($part);
245
+            }
246
+        }
247
+
248
+        return $column;
249
+    }
250
+
251
+
252
+    /**
253
+     * @return array array of updated fields for update query
254
+     * @since 7.0.0
255
+     */
256
+    public function getUpdatedFields(): array {
257
+        return $this->_updatedFields;
258
+    }
259
+
260
+
261
+    /**
262
+     * Adds type information for a field so that it's automatically cast to
263
+     * that value once its being returned from the database
264
+     *
265
+     * @param string $fieldName the name of the attribute
266
+     * @param Types::* $type the type which will be used to match a cast
267
+     * @since 31.0.0 Parameter $type is now restricted to {@see Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly.
268
+     * @since 7.0.0
269
+     */
270
+    protected function addType(string $fieldName, string $type): void {
271
+        /** @psalm-suppress TypeDoesNotContainType */
272
+        if (in_array($type, ['bool', 'double', 'int', 'array', 'object'], true)) {
273
+            // Mapping legacy strings to the actual types
274
+            $type = match ($type) {
275
+                'int' => Types::INTEGER,
276
+                'bool' => Types::BOOLEAN,
277
+                'double' => Types::FLOAT,
278
+                'array',
279
+                'object' => Types::STRING,
280
+            };
281
+        }
282
+
283
+        $this->_fieldTypes[$fieldName] = $type;
284
+    }
285
+
286
+
287
+    /**
288
+     * Slugify the value of a given attribute
289
+     * Warning: This doesn't result in a unique value
290
+     *
291
+     * @param string $attributeName the name of the attribute, which value should be slugified
292
+     * @return string slugified value
293
+     * @since 7.0.0
294
+     * @deprecated 24.0.0
295
+     */
296
+    public function slugify(string $attributeName): string {
297
+        // toSlug should only work for existing attributes
298
+        if (property_exists($this, $attributeName)) {
299
+            $value = $this->$attributeName;
300
+            // replace everything except alphanumeric with a single '-'
301
+            $value = preg_replace('/[^A-Za-z0-9]+/', '-', $value);
302
+            $value = strtolower($value);
303
+            // trim '-'
304
+            return trim($value, '-');
305
+        }
306
+
307
+        throw new \BadFunctionCallException($attributeName . ' is not a valid attribute');
308
+    }
309 309
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
  * @psalm-consistent-constructor
20 20
  */
21 21
 abstract class Entity {
22
-	public int|string|null $id = null;
22
+	public int | string | null $id = null;
23 23
 	private array $_updatedFields = [];
24 24
 	/** @psalm-param $_fieldTypes array<string, Types::*> */
25 25
 	protected array $_fieldTypes = ['id' => 'integer'];
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
 		$instance = new static();
35 35
 
36 36
 		foreach ($params as $key => $value) {
37
-			$method = 'set' . ucfirst($key);
37
+			$method = 'set'.ucfirst($key);
38 38
 			$instance->$method($value);
39 39
 		}
40 40
 
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 	protected function setter(string $name, array $args): void {
88 88
 		// setters should only work for existing attributes
89 89
 		if (!property_exists($this, $name)) {
90
-			throw new \BadFunctionCallException($name . ' is not a valid attribute');
90
+			throw new \BadFunctionCallException($name.' is not a valid attribute');
91 91
 		}
92 92
 
93 93
 		if ($args[0] === $this->$name) {
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
 			if ($column === '') {
242 242
 				$column = $part;
243 243
 			} else {
244
-				$column .= '_' . lcfirst($part);
244
+				$column .= '_'.lcfirst($part);
245 245
 			}
246 246
 		}
247 247
 
@@ -304,6 +304,6 @@  discard block
 block discarded – undo
304 304
 			return trim($value, '-');
305 305
 		}
306 306
 
307
-		throw new \BadFunctionCallException($attributeName . ' is not a valid attribute');
307
+		throw new \BadFunctionCallException($attributeName.' is not a valid attribute');
308 308
 	}
309 309
 }
Please login to merge, or discard this patch.