Skip to content

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.


Most of the changes below can be applied automatically with the ZubZet Version Migrator.

  1. Clone the tool: zubzet/version-migration
  2. 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.