Skip to content

Latest commit

 

History

98 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

LombokClarion

GitHub

Stars Forks Issues Pull Requests Release License Last Commit Repo Size

Packagist

Packagist Version Total Downloads Monthly Downloads PHP Required Stability

Quality

CI Tests Tests PHPStan PHP strict_types Domain Boundary Security Docker

SourceForge

SF Downloads SourceForge

Community

Contributors Discussions Sponsors Code of Conduct PRs Welcome

Lombok Ecosystem

LombokCSS LombokCharts LombokQRCode LombokTableSheet LombokStorybook


A PHP 8.3+ Full Stack Web framework built on the philosophy explicit over magic: edge/serverless-first, domain layer with zero framework imports, containerization-ready.

Core capabilities: DI Container + AOT compilation, Routing + 3 runtime adapters (FPM/Function/Swoole), Persistence (QueryBuilder, Schema, Migrations, Seeding), ActiveRecord (opt-in), Auth (HMAC token, RBAC, Gate/Policy), Validation + i18n (24 languages).

Facades and ActiveRecord exist as opt-in packages (lombokclarion/facades, lombokclarion/active-record, lombokclarion/laravel-flavor) but are never loaded by default — no core package depends on them, and the domain-boundary gate blocks them from app/Domain/**. There is no auto-discovery anywhere: every binding, route, command, and migration is registered in an explicit manifest file.

This repo contains working, tested code (377 tests, 0 failures) plus a small end-to-end example app (a Widget CRUD feature) wiring all packages together. It is not a drop-in composer create-project package yet, every piece that exists actually runs, and is covered by tests that actually run (377 tests, 0 failures, see "Running the tests").

Installing / consuming the packages

The packages are published to Packagist under the lombokclarion/* vendor. Pull the whole runtime stack in one shot with the metapackage:

composer require lombokclarion/framework

lombokclarion/framework installs the full runtime (including the opt-in magic packages — requiring it is itself the explicit opt-in choice). It leaves out the two dev-only packages, which you add to require-dev yourself:

composer require --dev lombokclarion/testing lombokclarion/phpstan-rules

Or install packages individually — and note that requiring one never drags in another's optional pieces (require lombokclarion/persistence does not pull ActiveRecord):

composer require lombokclarion/routing lombokclarion/http lombokclarion/persistence
# the "magic" packages, only if you ask for them by name:
composer require lombokclarion/active-record lombokclarion/facades lombokclarion/laravel-flavor

This repository (codinglombok/LombokClarion) is the canonical monorepo where all development happens; each package is mirrored read-only to its own repo, and those mirrors are what Packagist watches. Contribute here, not to the mirrors. The full rationale, the vendor/org mapping (lombokclarion/* on Packagist ↔ codinglombok/* on GitHub), and the release flow live in docs/PUBLISHING.md.

To hack on the framework itself, clone this monorepo and use it directly — the packages resolve to each other as path repositories, so composer install needs no network:

git clone https://github.com/codinglombok/LombokClarion.git
cd LombokClarion && composer install
php bin/lombokclarion migrate && php bin/lombokclarion optimize
php tests/run-all.php

Layout

packages/ 20 packages
  container/       LombokClarion\Container      — DI container + AOT compiler
  http/            LombokClarion\Http           — Request/Response/Middleware/ErrorHandler
  routing/         LombokClarion\Routing        — Router, Kernel, runtime adapters
  bus/             LombokClarion\Bus            — CommandBus/QueryBus/EventBus
  config/          LombokClarion\Config         — typed config compiler
  persistence/     LombokClarion\Persistence    — QueryBuilder/SchemaBuilder/migrations/seeding
  view/            LombokClarion\View           — Blade-like compiler, auto-escaping
  console/         LombokClarion\Console        — CLI kernel + 12 built-in commands
  security/        LombokClarion\Security       — hashing/CSRF/rate-limit/headers/encryption
  auth/            LombokClarion\Auth           — AuthManager/Gate/Policy/RBAC/TokenIssuer
  i18n/            LombokClarion\I18n           — Translator + DetectLocale middleware
  validation/      LombokClarion\Validation     — Validator/FormRequest/Rule (24 locales)
  storage/         LombokClarion\Storage        — LocalStorage with Storage interface
  log/             LombokClarion\Log            — Logger/ChannelLogger/StreamHandler/Redactor
  active-record/   LombokClarion\ActiveRecord   — Model base class + EagerLoader (opt-in magic)
  facades/         LombokClarion\Facades        — Facade base + Bus/Event/Hash (opt-in magic)
  laravel-flavor/  LombokClarion\LaravelFlavor  — Auth/DB facade shims (opt-in magic)
  testing/         LombokClarion\Testing        — HttpTestCase, fakes, ColdStartTest
  phpstan-rules/   LombokClarion\PHPStanRules   — SQL-injection + domain-boundary PHPStan ext
  framework/       (metapackage)                — one-require for full runtime stack

app/
  Domain/Widget/        entity, repository interface, command+query, handlers
                         (zero LombokClarion\* imports — enforced by
                         bin/check-domain-boundary.php)
  Http/Controllers/      thin controller, dispatches to CommandBus/QueryBus
  Http/Requests/         FormRequest (mass-assignment-proof validation)
  Infrastructure/        SqlWidgetRepository (QueryBuilder), migrations,
                         ServiceFactories (array-callable factories so
                         `optimize` can compile them)

bootstrap/
  services.php   every binding, one file, grep-able
  routes.php     every route + its middleware, one file
  console.php    every CLI command, one file
  migrations.php explicit migration manifest (no directory scanning)
  seeders.php    explicit seeder manifest
  externals.php  external library integrations (TableSheet, etc.)

config/config.schema.php   typed config schema
public/index.php           HTTP entrypoint (FpmAdapter)
bin/lombokclarion           CLI entrypoint
bin/check-domain-boundary.php  Deptrac-equivalent CI check (see below)
tests/                      377 tests across 27 files, custom zero-dependency harness

Why a custom autoloader instead of Composer?

This environment has no network access to Packagist, so composer install can't run here. autoload.php at the repo root is a small PSR-4 shim that maps each package's namespace straight to its src/ folder — good enough to run and test everything in this sandbox. Every package still ships a real composer.json with correct autoload.psr-4 blocks; in a normal environment you'd delete autoload.php and just composer install && require 'vendor/autoload.php'.

Running the tests

No PHPUnit (same network restriction), so there's a ~90-line assertion-based harness in tests/harness.php. Run everything:

php tests/run-all.php

Or a single file:

php -r "require 'tests/harness.php'; runTests('tests/ContainerTest.php');"

Trying the example app end-to-end

php bin/lombokclarion migrate        # creates storage/database.sqlite
php -S localhost:8080 -t public      # then curl it, or:
php bin/lombokclarion optimize       # writes storage/services.compiled.php
                                      # and storage/config.compiled.php
php bin/check-domain-boundary.php    # proves app/Domain/** stays framework-free
curl localhost:8080/api/widgets
curl -X POST localhost:8080/api/widgets -d name=Lamp -d price_cents=1500
# -> 419 CSRF token mismatch (correct: CSRF is required on this route)

Design requirements mapping

Section Requirement Where
2.1-2.6 No auto-discovery, explicit config, magic opt-in only Core packages never use facades; lombokclarion/facades is opt-in with forbidden-layers: [app/Domain]; every binding is in bootstrap/services.php
3 Container to Router to Middleware to Container to Controller to Bus to Domain to Repository flow packages/routing/src/Kernel.php
3 Domain layer zero framework imports, CI-enforced app/Domain/Widget/* + bin/check-domain-boundary.php
4.1 Container: explicit binding, no reflection auto-wiring of interfaces packages/container/src/Container.php
4.2 Http: Request/Response value objects packages/http/src/Request.php, Response.php
4.3 Routing: route table, middleware composition, groups packages/routing/src/Router.php, Route.php, Kernel.php
4.4 Bus: Command/Query/EventBus, explicit registration packages/bus/src/*
4.5 Config: typed, schema-generated packages/config/src/ConfigCompiler.php
4.6 Kernel + FpmAdapter, FunctionAdapter, SwooleAdapter packages/routing/src/Adapters/*
4.7 Persistence: bound-params-only QueryBuilder, SchemaBuilder, migration runner packages/persistence/src/*
4.8 View: Blade-like compiler, auto-escaping by default packages/view/src/*
4.9 Console: CLI kernel, same container as HTTP packages/console/src/*
4.10 Testing: HttpTestCase, fakes, InMemoryRepository, ColdStartTest packages/testing/src/*
4.11 Security: Argon2id, CSRF, rate-limit, security headers, Encrypted<T> packages/security/src/*
5 Cold-start budget, compiled/reflection-free boot ContainerCompiler + CompiledContainer + ColdStartTest
6 Security requirements (hashing, CSRF, sessions, validation, rate limit) packages/security/* + AuditSecurityCommand
7 SQL/injection hardening, audit:sql, N+1 with() QueryBuilder/Identifier/RawExpression + AuditSqlCommand
9 Domain tests need zero HTTP/DB; HttpTestCase boots the real container InMemoryRepository + HttpTestCase
10 No implicit retry on queued commands RetryPolicy::none() is the only default; RetriesQueuedCommand is opt-in

Known, deliberate limitations (documented, not bugs)

  • ContainerCompiler can't see inside closures. A binding registered as [FactoryClass::class, 'method'] is compiled as a direct static call (zero reflection), but if that method internally does $c->get(SomethingElse::class), SomethingElse must also have its own explicit binding (or be listed in extraRootIds) or the compiled container won't know about it. This is the correct fix, not a workaround: it's the same "explicit over magic" trade-off applied to compilation.
  • Runtime-constructed singletons (a PDO connection) can't be baked into a static compiled file. ContainerCompiler::compile() takes an $externallyProvided list for exactly this - the adapter constructs the connection fresh per request/invocation (per §5, no pooled connection is assumed) and calls CompiledContainer::instance(PDO::class, $pdo) before handling the request.
  • audit:sql/audit:security are real, working, regex-based heuristics, not a full bundled PHPStan/Psalm ruleset. They catch the concrete cases named in the design spec §6/§7 and are wired into bootstrap/console.php today.
  • Config values are resolved once, at optimize time, per §5's "never re-parsed per request." There's no runtime env-var re-read in the compiled config - that's intentional, not an oversight.

LombokCSS starter kit (§8, §13) — now implemented

  • The real LombokCSS (github.com/codinglombok/LombokCSS) is vendored self-hosted at resources/lombokcss/lombok.min.css (MIT, license included) — never CDN-loaded, per §8.
  • Upstream ships resonant-stark, neo-brutalism, glassmorphism (plus modern-corporate-flat, semantic-minimalist) but not quiet-editorial — so resources/lombokcss/quiet-editorial.css authors it as a preset extension following upstream's own token-remap pattern from src/themes.css.
  • data-style comes from Theme (validated at boot), fed by the THEME_STYLE env var through the typed config — never hardcoded in a layout.
  • lombokclarion optimize now also publishes assets with content-hashed filenames + a PHP manifest (AssetPublisher); StaticAssetsMiddleware serves /assets/* with Cache-Control: public, max-age=31536000, immutable.

Optional packages (§4.12) — now implemented

  • lombokclarion/active-record — full Model base class with create()/find()/update()/delete(), query() with where()/orderBy()/limit(), with() eager-loading via EagerLoader (N+1 safe), $fillable whitelist (mass-assignment blocked structurally). composer.json carries forbidden-layers: ["app/Domain"].
  • lombokclarion/facadesFacade base class + concrete facades (Bus, Event, Hash). Requires explicit Facade::setContainer() opt-in — never auto-discovered. app/Domain/** cannot import either package (enforced by bin/check-domain-boundary.php).

Multi-tenancy (§11) — now implemented

  • Tenancy is a request-scoped container binding pattern, not a framework mode. ResolveTenant middleware is declared per-route/group (never globally).
  • Ships HeaderTenantResolver (reads X-Tenant-ID); TenantAwareConnection builds a per-tenant PDO from a DSN template with {database} placeholder.
  • 8 tests covering: header resolution, missing/unknown tenant, middleware binding into context, no-tenant public routes, connection factory, isolation.

Queue/Worker (§12) — now implemented

  • ShouldQueue marker interface: commands get serialized and pushed to a QueueStore by QueuedCommandBus instead of running inline.
  • Default: single-attempt, no retry (§10). Opt-in via RetriesQueuedCommand + RetryPolicy(maxAttempts, backoffSeconds).
  • lombokclarion work CLI command: --queue=name, --loop, --sleep=N.
  • 8 tests covering: enqueue-vs-inline, worker processing, retry exhaustion, failed-job recording, DB store round-trip.

Plugin system (§10) — now implemented

  • Plugin interface: name() + capabilities() + register(Container). Registration is always explicit in services.php — no composer-extra scanning.
  • PluginRegistrar enforces an optional capability allow-list; violations fail loudly at registration. Duplicate registration throws.
  • 4 tests: registration, duplicates, allow-list blocking, null-allow-all.

Remaining gap vs. the spec

  • A bundled PHPStan/Psalm ruleset distributing the audit rules as real extension packages (today: the TokenScanner static analyzer above).

License

Apache License 2.0 — see LICENSE and NOTICE.

The Apache-2.0 terms cover LombokClarion's own source (packages/, app/, bootstrap/, bin/, config/, tests/, docs/). Third-party frontend assets vendored under resources/ (LombokCSS, LombokCharts) keep their own MIT licenses, recorded in NOTICE and in their LICENSE-* files — they are not relicensed.

About

LombokClarion is a PHP framework (PHP 8.3+, strict_types everywhere) built from scratch, clean code, on the opposite philosophy of Laravel: explicit over magic. No facades by default, no auto-discovery, no ActiveRecord in core, a domain layer with zero framework imports, and an edge/serverless-first design with a cold-start budget enforced at build

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages