Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements “Phase 1” ORM correctness/safety fixes by tightening error handling (new exception hierarchy), fixing serialization round-trips, correcting persisted-state detection for zero-like primary keys, and defining safe behavior for dynamic finders with unknown fields or empty match arrays.
Changes:
- Introduces
Freshsauce\Model\Exception\*exceptions and replaces several generic\Exceptionthrows with model-specific failures. - Fixes model serialization by adding
__serialize()/__unserialize()and making__sleep()safe. - Updates dynamic finders to fail fast on unknown fields and short-circuit empty-array matches to predictable empty/null/0 results; fixes
save()to treat any non-null PK (including0/'0') as persisted.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/Model/Model.php |
Core ORM fixes: exception types, serialization support, PK persistence detection, dynamic finder field validation, and empty-match handling. |
src/Model/Exception/ModelException.php |
Adds base ORM exception type. |
src/Model/Exception/UnknownFieldException.php |
Adds dedicated exception for unknown fields. |
src/Model/Exception/MissingDataException.php |
Adds dedicated exception for uninitialised model state access. |
src/Model/Exception/InvalidDynamicMethodException.php |
Adds dedicated exception for invalid dynamic static methods. |
src/Model/Exception/ConnectionException.php |
Adds dedicated exception for missing DB connection failures. |
src/Model/Exception/ConfigurationException.php |
Adds dedicated exception for misconfiguration/driver/quoting failures. |
tests/Model/CategoryTest.php |
Adds/updates regression tests for serialization round-trip, exception types, unknown dynamic field handling, and empty-array matcher behavior. |
tests/Model/SqliteModelTest.php |
Adds SQLite regression tests for save() update behavior with zero-like custom primary keys. |
test-src/Model/SqliteCodeCategory.php |
Adds SQLite helper model with integer custom PK for regression tests. |
test-src/Model/SqliteStringCodeCategory.php |
Adds SQLite helper model with string custom PK for regression tests. |
README.md |
Documents the new predictable exception behavior and links the roadmap. |
ROADMAP.md |
Adds a phased roadmap describing the correctness work and follow-on plans. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
This PR implements the Phase 1 roadmap work for the ORM and packages the roadmap itself into the repository so the next phases are explicit.
The user-visible effect is that several edge cases now fail predictably instead of leaking through as generic runtime or PDO failures. Model serialization also round-trips cleanly, zero-like primary keys no longer trigger accidental inserts, and dynamic finder helpers now define safe behavior for empty arrays.
The root cause was that the base model relied on a few permissive legacy behaviors:
__sleep()exposed table field names instead of the actual internal state container,save()treated primary keys using truthiness rather than persistence semantics, unknown dynamic fields fell through to SQL generation, and empty array matches were allowed to drift toward invalidIN ()queries. The library also surfaced genericExceptionobjects, which made it harder for calling code to handle failures precisely.The fix introduces a small exception hierarchy under
Freshsauce\\Model\\Exception, replaces the broken serialization path with__serialize()and__unserialize()while keeping__sleep()safe, changes persistence detection to treat any non-null primary key as existing state, makes unknown dynamic fields fail fast with a library exception, and short-circuits empty-array query helpers so they return[],null, or0as appropriate. The PR also adds SQLite-only helper models and regression tests that lock down zero-like custom primary keys, serialization, invalid dynamic field lookups, and empty-array matching behavior across the public helper surface.The README now documents the exception behavior, and
ROADMAP.mdcaptures the phased follow-up work so future changes stay aligned with the package's lightweight scope.Validation
I validated the changes with the existing quality gates:
vendor/bin/phpunit -c phpunit.xml.distvendor/bin/phpstan analyse -c phpstan.neon