A complete PHP framework
Placeholder homepage copy. Scroll down to watch the logo shrink into the header and lock in place, with the menu rising underneath it.
Modular by design
Dummy content. The framework is built from around one hundred and thirty small, single concern modules. Each one owns its own data, database access, services and user interface, and declares every module it depends on.
Validated and safe
Dummy content. Every input is checked, data objects are immutable and carry no behaviour, and all output is built with the declarative Ui library rather than raw markup.
One consistent shape
Dummy content. Learn the conventions once and they hold across every module, so a pattern you pick up in one place transfers everywhere else.
This is a card
A card is used only when we explicitly want one, with the card class. The titles and paragraphs above are plain content, not cards.
Start with a module
Dummy content for testing scroll. A module is a folder with an index file that requires the modules it depends on, a handful of small classes, and its own database scripts. Nothing is loaded for you behind the scenes, so the shape of an application is always the list of modules it includes.
Because a module owns one concern, you can read it end to end in a few minutes. The same layout repeats everywhere, so once you have seen one module you can find your way around any of them.
Data objects
Dummy content for testing scroll. Data moves through the system as small immutable objects with a constructor and nothing else. They carry fields, not behaviour, so there is never a question of where a value came from or whether a method changed it.
Every field that can be absent is named so you can tell at a glance. Anything without that marker is guaranteed to be present, which removes a whole class of checks from the code that uses it.
The database layer
Dummy content for testing scroll. Each entity has one database class, and every query returns a data object built through a single private mapper. Reads and writes are kept apart, and identifiers only appear on the paths that legitimately need them.
Tables from different modules are never joined in a query. When two modules need to be brought together, that happens in plain code, so a module can always be understood and changed on its own.
Building the interface
Dummy content for testing scroll. Pages are assembled from a declarative interface library rather than written as markup. You describe the content and the layout, and the theme turns that into the finished page, so there is one look across the whole system.
There are no developer or diagnostic features on public pages, no hidden query flags, and nothing shipped just to test something. What is on the page is what a visitor is meant to see.
Members and access
Dummy content for testing scroll. Membership, identity, verification and settings are separate modules that fit together, so an application takes only the parts it needs. Sign in can be by email or by mobile, and each method is its own small module.
Sessions, permissions and folders build on the same foundations, which keeps the rules for who can do what in one predictable place.
Services and providers
Dummy content for testing scroll. Messaging, payments, storage, location and cloud are each split into a core module and a provider. The core describes what the service does; the provider connects it to a particular vendor, so swapping a vendor is a small change.
Background work runs through queues and scheduled jobs, so slow tasks never block a page, and the same job can be picked up by a worker outside the request.
Configuration
Dummy content for testing scroll. Configuration flows from the environment into each module through a single provide step, and a security check confirms that everything a module needs has actually been supplied before the application serves a request.
The same values reach the node services that sit alongside the framework, so there is one source of truth for how a deployment is wired together.