feat: implement phase 4 optional ORM features#28
Merged
davebarnwell merged 3 commits intomainfrom Mar 8, 2026
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Implements the remaining optional Phase 4 ORM features in Freshsauce\Model\Model: transaction helpers, configurable timestamp columns, and attribute casting, with corresponding test coverage and documentation updates.
Changes:
- Added thin transaction wrappers (
beginTransaction,commit,rollBack) plus atransaction(callable)helper. - Made automatic timestamps configurable per model (
$_auto_timestamps,$_created_at_column,$_updated_at_column). - Added
$_castssupport to cast attributes on assignment and hydration, and serialize datetime/JSON-backed values on writes; expanded tests and docs accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/Model/Model.php |
Core implementation for transactions, configurable timestamps, and attribute casting (including DB hydration + write serialization). |
tests/Model/CategoryTest.php |
Cross-driver integration tests for new timestamp config, casting behavior, and transaction helpers. |
test-src/Model/DisabledTimestampCategory.php |
Test fixture model for disabling automatic timestamps via config. |
test-src/Model/CustomTimestampCategory.php |
Test fixture model for custom created/updated column names. |
test-src/Model/CastedCategory.php |
Test fixture model defining $_casts for supported cast types. |
docs/guide.md |
User guide updates documenting transactions, timestamp configuration, and attribute casting. |
docs/api-reference.md |
API reference additions for new static config members and transaction methods. |
README.md |
README updates highlighting new opt-in features and providing usage examples. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change implements the remaining optional Phase 4 roadmap items that fit the library's lightweight active-record scope: transaction helpers, configurable timestamp columns, and attribute casting.
Before this change, application code had to drop down to raw PDO to manage transactions, models were hard-wired to the
created_atandupdated_atconvention, and values loaded through the ORM stayed as raw PDO scalars or JSON strings. In practice that meant more boilerplate in calling code, awkward support for legacy schemas, and repeated manual conversion for booleans, numbers, datetimes, and JSON-backed attributes.The root cause was that the base model only exposed raw query execution and a fixed timestamp convention, and hydration reused constructor assignment without any model-level casting contract. The ORM already had the right extension points for validation and strict fields, but not for these common application concerns.
This patch extends
Freshsauce\Model\Modelwith thin transaction wrappers forbeginTransaction(),commit(), androllBack(), plus atransaction(callable $callback)helper that commits on success, rolls back on exceptions, and reuses an already-open outer transaction. It also adds model-level timestamp configuration via$_auto_timestamps,$_created_at_column, and$_updated_at_columnso models can disable automatic timestamps entirely or map them to legacy column names without changing call sites. Finally, it adds$_castssupport for integer, float, boolean, datetime, array, and object attributes, applies casts on assignment and database hydration, and serializes datetime and JSON-backed values correctly on writes.The test suite was expanded with new cross-driver fixtures and coverage for transaction commit and rollback behavior, disabled timestamps, custom timestamp columns, and cast persistence/hydration. The README, guide, and API reference were updated so the new configuration and lifecycle helpers are documented alongside the existing ORM APIs.
Validation used the existing PHPUnit suite against SQLite in-memory and static analysis:
MODEL_ORM_TEST_DSN='sqlite::memory:' MODEL_ORM_TEST_USER='' MODEL_ORM_TEST_PASS='' vendor/bin/phpunit -c phpunit.xml.distvendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M