Changelog
This page records the public FrankPHP framework release history in a more readable form than the rawCHANGELOG.md file.
Use it when you want to understand what changed between framework versions, whether a release affects existing installs, and which documentation or migration notes should be reviewed before upgrading.
For upgrade planning, read this page alongside Revisions and Migrations. The changelog explains what changed. The migration guidance explains how to apply those changes safely to an existing application.
Formal date and time handling
FrankPHP 1.3.0 introduces the framework’s first formal date/time handling standard:UTC at rest. Local at the edges.The headline addition is
App\Core\Clock, a small framework-owned utility for UTC timestamp generation, UTC/local conversion, timezone validation, timezone resolution, and local-date query boundary calculation.This release is primarily a framework hygiene and portability release. It reduces the risk of timezone drift between applications, servers, databases, and users.Added
Core/Clock.phpas a stateless static framework utility.- UTC timestamp helpers such as
Clock::nowUtcString()andClock::utcOffsetString(). - UTC normalisation helpers such as
Clock::toUtcString()andClock::parseUtc(). - Timezone validation and resolution helpers including
Clock::resolveTimezone(). - Local input conversion helpers including
Clock::localInputToUtcString(). - UTC-to-local display helpers including
Clock::formatUtcForTimezone(). - Local date query-boundary helpers including
Clock::utcRangeForLocalDate()andClock::utcRangeForLocalDates(). - Local “now” helpers for display and input defaults only.
CODEBASE.mddocumentation for Date and Time Handling and Framework Core Utilities.
Timezone resolution order
FrankPHP now has a formal timezone resolution order:UTC.Build rules introduced
- Use
App\Core\Clockfor persisted timestamp generation. - Store exact instants as UTC
DATETIME. - Use
DATEfor date-only values with no time-of-day meaning. - Do not use SQL
NOW()orCURRENT_TIMESTAMPfor application-managed timestamps. - Do not calculate local date windows directly in SQL.
- Convert local user, tenant, or application input into UTC before storage.
- Convert UTC values into the resolved local timezone before display.
- Resolve timezone explicitly using
Clock::resolveTimezone($user, $tenant, $config). - Do not let
Clockread from$_SESSION, request globals, middleware state, controller globals, or the database. - Do not call
Clockfrom views. - Services must prepare display-ready date labels for views.
- Views must not perform timezone conversion, timestamp comparison, date fallback logic, or relative date labelling.
- Document intentional application-level deviations in
MYAPP.md.
Migration notes
Existing applications should addCore/Clock.php before refactoring date/time code.Search existing code for direct date/time handling:Clock, and replace relative SQL date filters with UTC boundary values calculated in PHP.Existing MySQL TIMESTAMP columns should be reviewed and classified before conversion. FrankPHP prefers UTC DATETIME for application-managed timestamps.When converting MySQL TIMESTAMP to DATETIME, run the migration session in UTC:Fixed
This release does not include a runtime bug fix by itself. It prevents future timezone and server portability bugs by defining a single framework-wide date/time contract.Mail configuration fix
FrankPHP 1.2.1 is a small configuration and signup-flow maintenance release.Changed
- Added
admin_emailto theconfig.phpmail array fromMAIL_SITE_ADMIN. - Added
.envsupport forMAIL_SITE_ADMIN=admin@yourdomain.com.
Fixed
- Fixed
SignupService::initiateSignupso it usesEmailServiceand the configured admin email correctly.
Dependency injection and signup email wiring
FrankPHP 1.2.0 adds the framework’s minimal dependency injection container and uses it to cleanly wire email-related services and controllers.Added
Core/Container.php, a minimal explicit DI container withsingleton(),bind(),make(), andhas().- Container singleton registrations for
SignupServiceandPasswordResetServiceinbootstrap.php. - Container bindings for
AuthControllerandSignupController. EmailService::sendSignupVerification()for signup verification emails.EmailService::sendCoachAdvisory()for tenant-owner advisory emails..env.examplekey:MAIL_ADVISORY_TO.- CODEBASE documentation for the DI container, framework services, and signup routes.
Changed
Core/Router.phpnow accepts an optionalContainerand checks for controller bindings before falling back to direct construction.AuthControllernow receivesPasswordResetServiceby constructor injection.SignupControllernow receivesSignupServiceby constructor injection.PasswordResetServiceandSignupServiceno longer fall back to broken zero-argumentnew EmailService()construction.- Signup email methods now delegate to the injected
EmailServiceinstead of carrying SMTP details at the call site. - CODEBASE sections for request lifecycle, controllers, services, security notes, deliberate omissions, and framework ownership were updated.
Fixed
- Removed the
EmailServiceconstruction failure caused by services falling back tonew EmailService()without required SMTP configuration. - Removed hardcoded SMTP credentials from
SignupService; credentials now flow from.envtoconfig['mail'], intoEmailService::fromConfig(), and then through the container singleton.
MYAPP.md template and framework documentation updates
FrankPHP 1.1.1 strengthens the AI context workflow by adding the application-level documentation file used alongsideCODEBASE.md.Added
MYAPP.mdcreated as a template and added to the distribution.
Changed
- CODEBASE section 14 now documents AI instructions for creating and maintaining
MYAPP.md. - CODEBASE section 15 now documents framework tables around user and tenant management.
Framework configuration management
FrankPHP 1.1.0 introduces framework configuration management using.env values for core application settings.Added
- Framework config management for FrankPHP Core and app code using
.env. - Email credentials incorporated into the single
.envfile. - Syncfusion license key incorporated into the main
.envfile.