Skip to content
V
For developers
Architecture, conventions, the core and security
For developers / Overview

For developers#

Documentation of the CoolCMS architecture — for whoever is going to extend the system.

Where to start#

If you are reading this for the first time, go through it in this order:

  1. Five-layer model — without it the rest makes no sense.
  2. Project structure — where things belong.
  3. Code conventions — what a file you write should look like.
  4. Manager lifecycle — where side effects belong.
  5. Identity map — the landmine you will hit within a week.

I want to…#

Task Chapter
a new presenter in the administration Admin presenter
a new listing with filters and sorting Working with tables
a form Forms
pick from thousands of items instead of a select Picker
a component Components
an entity and a manager Code conventions
a recount or a notification after saving Manager lifecycle
a new API endpoint Calling the API + RBAC in the API
a scheduled task Cron presenters
an email Sending emails
a new front-end URL Routing
to add a text or a language Translations
to speed up reads Cache
to wire content into search Elasticsearch
to change the appearance Front-end themesSCSS
to deploy onto an older database Database check

Sections#

Section Contents
Introduction layers, structure, conventions, installation, deployment, scheduled tasks
Core calling the API, cache, routing, hooks, hydrators, the identity map, column attributes, filters, emails, Elasticsearch
UI the admin presenter, DataGrid, Picker, forms, components, Latte, cron
Security authentication, RBAC, CORS and rate limiting, audit
Appearance themes, SCSS, the design system
Modules e-shop, warehouse, invoicing, classifieds, company catalogue, blog, discussion
Translations the NEON layer and the database layer
Tests and tooling PHPUnit, PHPStan, pre-commit, skills

Six things you have to know#

  1. The five-layer model. Presenter → Manager → Service → Mapper → Repository. SQL lives exclusively in the repository.
  2. The front end does not touch the database. It calls the Api section through the bridge — which is why the same module has two sets of entities and what flows between them is an array, not an object.
  3. There are two hydrators. OrmEntityHydrator on the Api side (built on Doctrine), EntityHydrator on the Front/Admin side (reflection and attributes only). Do not mix them up.
  4. Every Api read empties the identity map. An object graph under construction loses its connection to the database and the next save fails.
  5. Side effects belong in the manager's hooks, not in database triggers — and only the reversible ones belong in after*.
  6. Saving an object graph replaces, it does not append. Whatever is missing from the payload gets deleted.

Production and development share one database

There is no "let me try it on dev first". Every write is live. Run experiments in a transaction with a rollback.

The skills are binding, the manual is the explanation

The canonical way to write code lives in skills/ — this manual turns them into a guide with the reasoning behind them. When the two diverge, the skill wins.