Skip to content

Complexity Refactor#29

Merged
hparadiz merged 6 commits intomainfrom
develop
Mar 29, 2026
Merged

Complexity Refactor#29
hparadiz merged 6 commits intomainfrom
develop

Conversation

@hparadiz
Copy link
Copy Markdown
Collaborator

@hparadiz hparadiz commented Mar 29, 2026

Complexity Refactor

This PR continues the cleanup and simplification work across the model/database layer and the controller/request handling layer. No existing external APIs are broken — all public-facing interfaces remain intact.


What's New for Developers

Model: Type Hints & Null Hints Now Drive Schema Generation

You can now use PHP native type hints and nullable type hints (?string, ?int, etc.) on your model properties to declare nullability, instead of relying on the notnull column attribute. The schema generator reads these directly from your class definitions. This brings model declarations in line with modern PHP and reduces the need for extra attribute boilerplate.

Getters Converted to First-Class Classes

Getter behavior (e.g. getBy*, getAllBy*) has been moved into dedicated getter classes under Factory/Getters. Factory is now the single source of truth for getter registration — each getter is registered once and dispatched through a small map.

For model code using the Getters trait: nothing changes. Static calls like MyModel::getByField(...) continue to work exactly as before. Internally they now bubble through Factory, but the call signature is identical.

For developers extending or adding getters: you now only need to define a getter class in one place rather than maintaining parallel definitions in both Factory and the Getters trait.

Controllers: Records & Media Endpoints Split into Dedicated Classes

Request/response logic for RecordsRequestHandler and MediaRequestHandler has been broken out of the large monolithic handler classes and into individual endpoint classes under:

  • src/Controllers/Records/Endpoints/
  • src/Controllers/Media/Endpoints/

Shared behavior (access control, error handling, template rendering, hooks) stays in the base handler. Endpoint-specific logic lives in its own class.

Dispatch is now centralized in RequestHandler, which owns endpoint registration and __call() routing. Both records and media handlers register their endpoints against this shared mechanism. Media browse/delete routes use distinct method names to avoid colliding with the inherited record-level routes.

SQL Schema Writers: Shared Base for Create Table Logic

The MySQL, PostgreSQL, and SQLite schema writers all shared the same create-table orchestration flow, repeated three times. That shared flow now lives in a common base class. Each backend writer is now focused exclusively on its backend-specific SQL rules.


Summary of Changes

Area Before After
SQL writers Duplicated create-table flow across 3 backends Shared base, backend-specific subclasses
Getter registration Defined in both Factory and Getters trait Defined once in Factory/Getters classes
Static getter calls Handled directly in Getters trait Forwarded through Factory (same public API)
Controller endpoints Logic concentrated in large handler classes Each endpoint in its own focused class
Endpoint dispatch Duplicated in each handler Centralized in RequestHandler
Schema nullability notnull attribute PHP type hints / nullable type hints

Net: 2,871 lines added, 2,019 removed across 58 files — meaningfully less complexity with no breaking changes.

Getter classes are registered with the Factory and become methods you can run on the Factory.
The existing Getters trait for ActiveRecord models scans Factory for Getters and attached them to itself as well providing $className::$methodName() as static calls while using a Factory backend.
@hparadiz hparadiz merged commit d8d49d5 into main Mar 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant