Skip to content

Commit d63a82c

Browse files
committed
Address PR review feedback
1 parent e8d9e02 commit d63a82c

5 files changed

Lines changed: 27 additions & 9 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class Product extends Freshsauce\Model\Model
178178

179179
Supported cast types are `integer`, `float`, `boolean`, `datetime`, `array`, and `object`.
180180

181+
`datetime` casts assume stored strings are UTC wall-time values. If you do not want implicit timezone conversion by the database, prefer `DATETIME`-style columns or ensure the connection session timezone is UTC before using `TIMESTAMP` columns.
182+
181183
### Dynamic finders and counters
182184

183185
Build expressive queries straight from method names:

‎docs/api-reference.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Optional. Defaults to `updated_at`. Set to a different column name to customise
4242

4343
Optional. Field cast map. Supported cast types are `integer`, `float`, `boolean`, `datetime`, `array`, and `object`.
4444

45+
For `datetime`, string values are interpreted as UTC wall-time values. Prefer `DATETIME`-style columns, or ensure the connection session timezone is UTC when using database types that perform timezone conversion.
46+
4547
### `public static $_db`
4648

4749
Inherited shared PDO connection. Redeclare this in a subclass only when that subclass needs an isolated connection.

‎docs/guide.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ Notes:
578578
- `datetime` returns `DateTimeImmutable`
579579
- `array` and `object` are stored as JSON strings in the database
580580
- `toArray()` returns the current cast PHP values
581+
- `datetime` assumes stored strings are UTC wall-time values; prefer `DATETIME`-style columns or a UTC session timezone when using databases that convert `TIMESTAMP`
581582

582583
## Exceptions
583584

‎src/Model/Model.php‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,18 +1286,29 @@ public static function transaction(callable $callback): mixed
12861286
return $callback();
12871287
}
12881288

1289-
$db->beginTransaction();
1289+
if (!$db->beginTransaction()) {
1290+
throw new \PDOException('Failed to start transaction.');
1291+
}
12901292

12911293
try {
12921294
$result = $callback();
1293-
$db->commit();
1295+
1296+
if (!$db->commit()) {
1297+
try {
1298+
$db->rollBack();
1299+
} catch (\Throwable) {
1300+
// Ignore rollback failures when the transaction is already closed or rollback itself fails.
1301+
}
1302+
1303+
throw new \PDOException('Failed to commit transaction.');
1304+
}
12941305

12951306
return $result;
12961307
} catch (\Throwable $throwable) {
12971308
try {
12981309
$db->rollBack();
1299-
} catch (\PDOException) {
1300-
// Ignore rollback failures when the callback already closed the transaction.
1310+
} catch (\Throwable) {
1311+
// Ignore rollback failures when the callback already closed the transaction or rollback itself fails.
13011312
}
13021313

13031314
throw $throwable;
@@ -1638,9 +1649,11 @@ protected static function supportsDeleteLimit(): bool
16381649
*/
16391650
protected static function newInstanceFromDatabaseRow(array $row): static
16401651
{
1641-
$instance = new static();
1642-
$instance->hydrateFromDatabase($row);
1652+
$reflection = new \ReflectionClass(static::class);
1653+
/** @var static $instance */
1654+
$instance = $reflection->newInstanceWithoutConstructor();
16431655
$instance->clearDirtyFields();
1656+
$instance->hydrateFromDatabase($row);
16441657

16451658
return $instance;
16461659
}
@@ -1656,9 +1669,9 @@ protected function hydrateFromDatabase(array $data): void
16561669
{
16571670
foreach (static::getFieldnames() as $fieldname) {
16581671
if (array_key_exists($fieldname, $data)) {
1659-
$this->assignAttribute($fieldname, $data[$fieldname], true, true);
1672+
$this->assignAttribute($fieldname, $data[$fieldname], false, true);
16601673
} elseif (!isset($this->$fieldname)) {
1661-
$this->assignAttribute($fieldname, null, true, true);
1674+
$this->assignAttribute($fieldname, null, false, true);
16621675
}
16631676
}
16641677
}

‎tests/Model/CategoryTest.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static function setUpBeforeClass(): void
7777
`quantity` INT(11) NULL,
7878
`rating` DOUBLE NULL,
7979
`is_active` TINYINT(1) NULL,
80-
`published_at` TIMESTAMP NULL DEFAULT NULL,
80+
`published_at` DATETIME NULL DEFAULT NULL,
8181
`meta_array` TEXT NULL,
8282
`meta_object` TEXT NULL,
8383
PRIMARY KEY (`id`)

0 commit comments

Comments
 (0)