Migrating from v1.1.0 to v1.2.0¶
Table of Contents¶
New Features¶
Logging¶
ZubZet now includes a built-in logging system powered by Monolog. It supports two backends — database and stream — and is enabled by default. The framework automatically records system events such as logins, page views, and REST errors.
Maintenance System¶
ZubZet now ships with a built-in maintenance system that lets you put your application into maintenance mode. While active, incoming requests are intercepted and visitors see a dedicated maintenance page instead of the regular site. This makes it easy to perform deployments, database migrations, or other administrative work without risking inconsistent state for users.
info:startup command¶
A new info:startup console command gives you a quick overview of your runtime environment.
It prints information such as your PHP version, the installed ZubZet version, the configured port, the active environment, and other relevant details.
Static Argument Support for Routes, Middlewares and Afterwares¶
Routes, middlewares, and afterwares now accept static arguments directly in their definition. You can now pass them inline when declaring a route, which keeps route definitions self-contained and easier to read. This is particularly useful for reusable middlewares that need slightly different parameters on different routes.
Coverage Report¶
You can now collect a code coverage report at runtime.
Run testing:coverage:start to begin recording, execute the code paths you want to measure (through tests, manual requests, or any other means), and then run testing:coverage:stop to finish the session.
A full coverage report is generated for you, making it easy to see which parts of your application are exercised and which still need test coverage.
$res->json()¶
The response object now exposes a dedicated $res->json() helper for sending JSON responses.
It takes care of encoding the payload and returning the response in one concise call.
Slow Query and Slow Request Logging¶
The logging system now automatically records slow database queries and slow requests. When a query or request exceeds the configured threshold, it is written to the log along with timing information, making it much easier to spot performance bottlenecks in production. You no longer need to instrument your code by hand to find the parts of your application that are dragging down response times.
PHP Debug Bar¶
A PHP Debug Bar has been integrated into the framework and is available in the test environment.
It surfaces information about the current request, executed database queries, rendered templates, log records with full context, and other runtime details directly in the browser.
See the Debug Bar documentation for configuration, internal-query filtering, and how to mark your own models as internal.
Whoops Error Page¶
The Whoops error page has been added for the test environment.
Instead of a plain error message, unhandled exceptions are now rendered with full stack traces, source code snippets, and request context.
This provides a significantly richer debugging experience and helps you pinpoint the cause of errors much faster during development.
Auto Start and Stop¶
ZubZet projects now start and stop automatically when you open or close them in your editor. You no longer need to manually run a start command every time you switch projects — the framework detects the context and brings the project up or tears it down on its own. This streamlines the development workflow, especially when working on multiple ZubZet projects at once.
Asset Proxy¶
Assets are no longer served directly as static files. Instead, an asset proxy now sits in front of the file delivery and handles the requests, which opens the door to on-the-fly processing, access control, and caching strategies. Existing asset URLs continue to work as before, so this change is transparent for applications that simply serve files.
Include / Exclude Environments in Seed Command¶
The seed command now accepts explicit include and exclude filters for environments. You can target a specific environment with its seeds, or exclude certain environments from a broader seed run. This makes it much easier to maintain separate seed data sets for development, testing, and production without accidentally mixing them up.
PHP 8.5 Support¶
ZubZet now officially supports PHP 8.5. The framework has been tested against the latest PHP release and runs out of the box on 8.5, so you can take advantage of the newest language features and runtime improvements. Older supported PHP versions continue to work as before, allowing you to upgrade on your own schedule.
Native Argon2id Password Hashing¶
Password storage now uses PHP's native Argon2id, the algorithm recommended by the current OWASP Password Storage guidance, in place of the previous SHA-512 based scheme. Argon2id is memory hard and purpose built for password storage, and the native PHP functions embed the algorithm, cost, and salt in every stored value. Existing passwords are safe and keep working: they are upgraded to Argon2id automatically the next time their owner logs in, so adopting the modern format requires no password reset. See the new Password Handling documentation for the full picture, including the verify and hash API and how to add users.
Bugfixes¶
Missing Migration Folder¶
Running migrations no longer fails when the migration folder does not exist. Instead of raising an error, the framework now creates the folder automatically and continues as expected. This removes a common friction point when setting up a fresh project or working in a freshly cloned checkout.
Larger File Size Support¶
The size column of the z_file table has been changed from a regular integer to a BIGINT.
This raises the supported file size well beyond the previous ~2 GB limit and allows ZubZet to correctly handle very large uploads and stored files.
Applications that deal with video, archives, or other large binary assets will benefit from this change immediately.
Breaking Changes¶
Removed: Log category methods on models¶
The following methods have been removed from the base model class:
getLogCategoryIdByName()logAction()logActionByCategory()
If your application calls any of these methods, replace them with the new logger() helper. See the Logging documentation for usage.
Removed: z_interaction_log_category table¶
The z_interaction_log_category table has been dropped entirely. The categoryId column has also been removed from z_interaction_log.
Removed: Log viewer in Admin Panel¶
The log viewer previously available in the Admin Panel has been removed.
Removed: Global request variables¶
The PHP superglobals ($_GET, $_POST, $_REQUEST, $_COOKIE, etc.) are no longer populated or used by the framework for accessing request data.
All request input must now be read through the request object, for example via $req->input.
This keeps request handling consistent, testable, and decoupled from PHP's global state — but it does mean that any code still relying on the superglobals needs to be migrated to the request API.
Upgrade Steps¶
Follow these steps to upgrade your project to v1.2.0.
1. Automated migration (recommended)¶
Most of the changes below can be applied automatically with the ZubZet Version Migrator.
- Clone the tool: zubzet/version-migration
- Preview the changes with a dry run, then apply them:
php application.php upgrade {PATH_TO_YOUR_PROJECT} 1.1.0 1.2.0 --dry
php application.php upgrade {PATH_TO_YOUR_PROJECT} 1.1.0 1.2.0
The migrator bumps the framework dependency, adds the new z_settings.ini keys (logging,
maintenance mode, debug bar, editor), updates .gitignore and package.json, rewrites direct
superglobal and php://input access to the request API, and installs the VS Code tasks. Review each
prompted change before accepting it.
After the migrator finishes, apply the database changes (step 4) and rebuild your stack.
2. Replace removed model methods¶
Search your application code for the removed methods and replace them with logger():
// Before
$this->logAction("Something happened");
$this->logActionByCategory("Something happened", "category");
// After
logger()->info("Something happened");
3. Move request input off superglobals¶
The framework no longer populates $_GET, $_POST, $_COOKIE, etc. Read input through the request
object instead (the migrator automates this rewrite):
// Before
$_POST["email"];
file_get_contents("php://input");
// After
request()->input->POST["email"];
request()->input->body;
4. Apply the database migrations¶
The framework-bundled migrations below are applied automatically by the project's normal start/seed
flow (npm run start, which runs db:seed → migrations then seed) or directly with:
docker exec application php index.php db:migrate
New since v1.1.0:
| Migration | Change |
|---|---|
2026-03-27_session-handling.sql |
Adds z_logintoken.extended_seconds and active. Corrects a file misdated 2027-03-27 in 1.1.0 — it re-applies safely (idempotent). |
2026-04-02_deprecate_interactionlog.sql |
Drops z_interaction_log_category and z_interaction_log.categoryId. |
2026-04-27_organization.sql |
Creates z_organization; adds z_user.organizationId. |
2026-05-04_organization_role.sql |
Adds z_organization.groupId for organization-level roles. |
If you manage schema by hand, the equivalent statements are idempotent (... IF NOT EXISTS /
IF EXISTS).
5. Configure logging (optional)¶
Logging is enabled by default with the database backend at info level. To adjust the
behavior, set the relevant keys in z_config/z_settings.ini:
logger_enabled = true
logger_type = database
logger_level = info
To disable logging entirely:
logger_enabled = false
See the Logging documentation for all available options.
4. Adopt native password hashing¶
The schema migration runs automatically when the framework updates. It adds a
password_scheme and a last_password_rehash_at column to z_user and marks
every existing password row as legacy. No action is required for accounts to
keep working: they verify through the legacy path and upgrade themselves to
Argon2id on the next successful login.
Rehash on login only reaches accounts that log in. To bring accounts that have not logged in yet onto Argon2id as well, run the onion migration once. It is idempotent and safe to re run:
php index.php auth:migrate-hashing
See the Password Handling documentation for the verify and hash API, the scheme model, and how to add users.