Skip to content

v1.75.0 - Algieba

Choose a tag to compare

@MichaelSowah MichaelSowah released this 07 Aug 13:02
· 19 commits to main since this release
663252a

The whole framework now type-checks at PHPStan level 8 with zero suppressed errors. A 31-area campaign cleaned 914 errors of typing
debt, raised the CI gate from level 6 to level 8 over src/ and config/, upgraded the engine to PHPStan 2.x, and finished by fixing all
111 baseline entries and deleting the baseline file. The sweep surfaced and fixed genuinely latent bugs along the way.

Highlights

Level 8 everywhere, with no baseline

All 31 areas of src/ were cleaned area-by-area — each behind the full test suite — and the gate in phpstan.neon was raised from level 6
to level: 8. The frozen PHPStan-2 upgrade baseline was then burned down entirely and deleted, so the gate runs with zero suppressed
errors. Analysis is pinned to PHP 8.3 (phpVersion: 80300) so results are identical on every machine. The one permanent, documented ignore
is trait.unused — the framework ships traits as public API for applications and extensions.

The sweep fixed real bugs, not just annotations

  • orHas() / orDoesntHave() / orWhereHas() / orWhereDoesntHave() crashed with an undefined-method fatal —
    QueryBuilder::orWhereRaw() now exists and is public API.
  • The post-auth request attributes email and username were always null (the middleware read private properties instead of accessors).
  • Soft-delete restore/delete on joined queries never qualified the deleted_at column — an unreachable branch since day one, now served by
    the new QueryBuilder::hasJoins().
  • QueryCacheService's default key prefix never applied; failed-job retry name mangling; JWT and webhook signing of "false" payloads;
    RedisCacheDriver::zadd() erroring on an empty map.

Honest contracts and hardened edges

The ORM relation machinery is typed against Model instead of object, with class-string<Model> relation definitions. Model::toJson()
/ Collection::toJson() throw named errors instead of returning false typed as string, as does FileUploader::calculateChecksum() on
an unreadable file. WhereClauseInterface now declares orWhereRaw(). Dozens of preg_match conditions were pinned with the correct
operator, and false-returning calls (glob, file_get_contents, json_encode, preg_replace) are guarded throughout — fail-closed where
the value feeds redaction, hashing, or signing.

PHPStan 2.x engine and advisory Rector

Static analysis runs on PHPStan 2.2 with the phpunit, strict-rules, and deprecation-rules extensions on their 2.x majors, using
identifier-tagged errors. Rector joins as dev-only tooling with a conservative wave-0 config (PHP 8.3 + PHPUnit sets; readonly-class
rectors permanently skipped as BC hazards) — composer rector dry-runs it on demand; it does not run in CI.

Upgrade Notes

  • Applications: composer update glueful/framework is enough — no new env vars, config keys, migrations, or default changes.
  • If you implement WhereClauseInterface (rare): add the orWhereRaw() method.
  • If you subclass ORM relation classes: parents/related instances are typed Model, not object.
  • If you catch around toJson(): unencodable payloads now throw a named error instead of returning false.
  • Installs with an empty query-cache keyPrefix get the intended default prefix — the query cache re-keys once after upgrade (one round of
    cache misses, not an error).
  • Contributors / CI forks: the analysis gate is now level 8 with no baseline file, pinned to PHP 8.3.