Skip to content

Commit 6c36c54

Browse files
committed
feat(db): switch from settype to casts
Signed-off-by: Anna Larch <[email protected]>
1 parent 3fe3f8d commit 6c36c54

File tree

5 files changed

+81
-60
lines changed

5 files changed

+81
-60
lines changed

lib/private/Tagging/Tag.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@ public function __construct($owner = null, $type = null, $name = null) {
4545
* @todo migrate existing database columns to the correct names
4646
* to be able to drop this direct mapping
4747
*/
48-
public function columnToProperty($columnName) {
48+
public function columnToProperty(string $columnName): string {
4949
if ($columnName === 'category') {
5050
return 'name';
51-
} elseif ($columnName === 'uid') {
51+
}
52+
53+
if ($columnName === 'uid') {
5254
return 'owner';
53-
} else {
54-
return parent::columnToProperty($columnName);
5555
}
56+
57+
return parent::columnToProperty($columnName);
5658
}
5759

5860
/**
@@ -61,13 +63,15 @@ public function columnToProperty($columnName) {
6163
* @param string $property the name of the property
6264
* @return string the column name
6365
*/
64-
public function propertyToColumn($property) {
66+
public function propertyToColumn(string $property): string {
6567
if ($property === 'name') {
6668
return 'category';
67-
} elseif ($property === 'owner') {
69+
}
70+
71+
if ($property === 'owner') {
6872
return 'uid';
69-
} else {
70-
return parent::propertyToColumn($property);
7173
}
74+
75+
return parent::propertyToColumn($property);
7276
}
7377
}

lib/public/AppFramework/Db/Entity.php

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
/**
1414
* @method int getId()
1515
* @method void setId(int $id)
16+
* @psalm-type AllowedTypes = 'json'|'blob'|'datetime'|'string'|'int'|'integer'|'bool'|'boolean'|'float'|'double'|'array'|'object'
1617
* @since 7.0.0
1718
* @psalm-consistent-constructor
1819
*/
@@ -23,6 +24,7 @@ abstract class Entity {
2324
public $id;
2425

2526
private array $_updatedFields = [];
27+
/** @var array<string, AllowedTypes> */
2628
private array $_fieldTypes = ['id' => 'integer'];
2729

2830
/**
@@ -64,10 +66,10 @@ public static function fromRow(array $row): static {
6466

6567

6668
/**
67-
* @return array with attribute and type
69+
* @return array<string, AllowedTypes> with attribute and type
6870
* @since 7.0.0
6971
*/
70-
public function getFieldTypes() {
72+
public function getFieldTypes(): array {
7173
return $this->_fieldTypes;
7274
}
7375

@@ -76,50 +78,62 @@ public function getFieldTypes() {
7678
* Marks the entity as clean needed for setting the id after the insertion
7779
* @since 7.0.0
7880
*/
79-
public function resetUpdatedFields() {
81+
public function resetUpdatedFields(): void {
8082
$this->_updatedFields = [];
8183
}
8284

8385
/**
8486
* Generic setter for properties
87+
*
88+
* @throws \InvalidArgumentException
8589
* @since 7.0.0
90+
*
8691
*/
8792
protected function setter(string $name, array $args): void {
8893
// 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 . ' is not a valid attribute');
96+
}
97+
98+
if ($args[0] === $this->$name) {
99+
return;
100+
}
101+
$this->markFieldUpdated($name);
102+
103+
// if type definition exists, cast to correct type
104+
if ($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) {
105+
$type = $this->_fieldTypes[$name];
106+
if ($type === 'blob') {
107+
// (B)LOB is treated as string when we read from the DB
108+
if (is_resource($args[0])) {
109+
$args[0] = stream_get_contents($args[0]);
104110
}
111+
$type = 'string';
112+
}
105113

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);
114+
if ($type === 'datetime') {
115+
if (!$args[0] instanceof \DateTime) {
116+
$args[0] = new \DateTime($args[0]);
116117
}
118+
} elseif ($type === 'json') {
119+
if (!is_array($args[0])) {
120+
$args[0] = json_decode($args[0], true);
121+
}
122+
} else {
123+
$args[0] = match($type) {
124+
'string' => (string)$args[0],
125+
'bool', 'boolean', => (bool)$args[0],
126+
'int', 'integer', => (int)$args[0],
127+
'float' => (float)$args[0],
128+
'double' => (float)$args[0],
129+
'array' => (array)$args[0],
130+
'object' => (object)$args[0],
131+
default => new \InvalidArgumentException()
132+
};
117133
}
118-
$this->$name = $args[0];
119-
} else {
120-
throw new \BadFunctionCallException($name .
121-
' is not a valid attribute');
122134
}
135+
$this->$name = $args[0];
136+
123137
}
124138

125139
/**
@@ -182,16 +196,17 @@ protected function markFieldUpdated(string $attribute): void {
182196

183197
/**
184198
* Transform a database columnname to a property
199+
*
185200
* @param string $columnName the name of the column
186201
* @return string the property name
187202
* @since 7.0.0
188203
*/
189-
public function columnToProperty($columnName) {
204+
public function columnToProperty(string $columnName): string {
190205
$parts = explode('_', $columnName);
191-
$property = null;
206+
$property = '';
192207

193208
foreach ($parts as $part) {
194-
if ($property === null) {
209+
if ($property === '') {
195210
$property = $part;
196211
} else {
197212
$property .= ucfirst($part);
@@ -204,16 +219,17 @@ public function columnToProperty($columnName) {
204219

205220
/**
206221
* Transform a property to a database column name
222+
*
207223
* @param string $property the name of the property
208224
* @return string the column name
209225
* @since 7.0.0
210226
*/
211-
public function propertyToColumn($property) {
227+
public function propertyToColumn(string $property): string {
212228
$parts = preg_split('/(?=[A-Z])/', $property);
213-
$column = null;
214229

230+
$column = '';
215231
foreach ($parts as $part) {
216-
if ($column === null) {
232+
if ($column === '') {
217233
$column = $part;
218234
} else {
219235
$column .= '_' . lcfirst($part);
@@ -228,32 +244,34 @@ public function propertyToColumn($property) {
228244
* @return array array of updated fields for update query
229245
* @since 7.0.0
230246
*/
231-
public function getUpdatedFields() {
247+
public function getUpdatedFields(): array {
232248
return $this->_updatedFields;
233249
}
234250

235251

236252
/**
237-
* Adds type information for a field so that its automatically casted to
253+
* Adds type information for a field so that it's automatically cast to
238254
* that value once its being returned from the database
255+
*
239256
* @param string $fieldName the name of the attribute
240-
* @param string $type the type which will be used to call settype()
257+
* @param AllowedTypes $type the type which will be used to match a cast
241258
* @since 7.0.0
242259
*/
243-
protected function addType($fieldName, $type) {
260+
protected function addType(string $fieldName, string $type): void {
244261
$this->_fieldTypes[$fieldName] = $type;
245262
}
246263

247264

248265
/**
249266
* Slugify the value of a given attribute
250267
* Warning: This doesn't result in a unique value
268+
*
251269
* @param string $attributeName the name of the attribute, which value should be slugified
252270
* @return string slugified value
253271
* @since 7.0.0
254272
* @deprecated 24.0.0
255273
*/
256-
public function slugify($attributeName) {
274+
public function slugify(string $attributeName): string {
257275
// toSlug should only work for existing attributes
258276
if (property_exists($this, $attributeName)) {
259277
$value = $this->$attributeName;
@@ -262,9 +280,8 @@ public function slugify($attributeName) {
262280
$value = strtolower($value);
263281
// trim '-'
264282
return trim($value, '-');
265-
} else {
266-
throw new \BadFunctionCallException($attributeName .
267-
' is not a valid attribute');
268283
}
284+
285+
throw new \BadFunctionCallException($attributeName . ' is not a valid attribute');
269286
}
270287
}

tests/lib/AppTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,9 @@ public function appConfigValuesProvider() {
460460
public function testEnabledApps($user, $expectedApps, $forceAll) {
461461
$userManager = \OC::$server->getUserManager();
462462
$groupManager = \OC::$server->getGroupManager();
463-
$user1 = $userManager->createUser(self::TEST_USER1, self::TEST_USER1);
464-
$user2 = $userManager->createUser(self::TEST_USER2, self::TEST_USER2);
465-
$user3 = $userManager->createUser(self::TEST_USER3, self::TEST_USER3);
463+
$user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
464+
$user2 = $userManager->createUser(self::TEST_USER2, 'NotAnEasyPassword123456_');
465+
$user3 = $userManager->createUser(self::TEST_USER3, 'NotAnEasyPassword123456?');
466466

467467
$group1 = $groupManager->createGroup(self::TEST_GROUP1);
468468
$group1->addUser($user1);
@@ -508,7 +508,7 @@ public function testEnabledApps($user, $expectedApps, $forceAll) {
508508
*/
509509
public function testEnabledAppsCache() {
510510
$userManager = \OC::$server->getUserManager();
511-
$user1 = $userManager->createUser(self::TEST_USER1, self::TEST_USER1);
511+
$user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
512512

513513
\OC_User::setUserId(self::TEST_USER1);
514514

tests/lib/Comments/ManagerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ public function testDeleteReferencesOfActor() {
671671
}
672672

673673
public function testDeleteReferencesOfActorWithUserManagement() {
674-
$user = \OC::$server->getUserManager()->createUser('xenia', '123456');
674+
$user = \OC::$server->getUserManager()->createUser('xenia', 'NotAnEasyPassword123456+');
675675
$this->assertTrue($user instanceof IUser);
676676

677677
$manager = \OC::$server->get(ICommentsManager::class);

tests/lib/Files/Cache/UpdaterLegacyTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ protected function setUp(): void {
5656
self::$user = $this->getUniqueID();
5757
}
5858

59-
\OC::$server->getUserManager()->createUser(self::$user, 'password');
59+
\OC::$server->getUserManager()->createUser(self::$user, 'NotAnEasyPassword123456+');
6060
$this->loginAsUser(self::$user);
6161

6262
Filesystem::init(self::$user, '/' . self::$user . '/files');

0 commit comments

Comments
 (0)