laika-framework

Project Structure

myproject/
├── .github/workflows/  # CI: lint on push, release zip on v*.*.* tags
├── assets/             # public static assets used by the default pages (css/js/img)
├── docs/               # documentation (this folder)
├── lf-app/             # application code — controllers, models, pipelines, jobs, ...
├── lf-boot/app.php     # bootstrap, run before every request and every CLI command
├── lf-config/          # config files, one PHP array per file
├── lf-hooks/           # hook files — every *.php here is loaded at boot
├── lf-inc/const.php    # DEBUG, MEMORY_LIMIT, CLI_MEMORY_LIMIT
├── lf-lang/            # language files (en.local.php, ...)
├── lf-logs/            # error logs, written only while DEBUG is true
├── lf-routes/          # route files — every *.php here is loaded on dispatch
├── lf-storage/         # generated runtime state (see below) — never served
├── template/           # Twig views, template/assets/, template/loader.php
├── uploads/            # user-uploaded files
├── vendor/             # Composer dependencies
├── public/             # the web server's document root
│   ├── index.php       # the web entry point
│   └── .htaccess       # Apache rewrite rules (generated by app:sync if missing)
├── .htaccess           # deny-all, in case a vhost points at the project root
├── composer.json
├── laika               # CLI executable (generated)
├── worker              # queue worker executable (generated)
├── nginx.conf          # nginx rules fragment, for your own server block (nginx:make)
├── LICENSE
└── README.md

lf-app/ — Application Code

Every subdirectory maps to a PSR-4 namespace under App\, and each is a resource the framework discovers on its own — there is nothing to register.

Directory Namespace Contains Must extend / implement
Controller/ App\Controller Route handlers —
Model/ App\Model Database models Laika\Engine\Model\Model
Schema/ App\Schema Table definitions, run by php laika app:migrate Laika\Engine\Model\Contract\SchemaAbstract
Pipeline/ App\Pipeline Middleware that runs before the controller Laika\Engine\Route\Contracts\PipelineInterface
Filter/ App\Filter Middleware that runs after the controller Laika\Engine\Route\Contracts\FilterInterface
Job/ App\Job Queue jobs Laika\Engine\Queue\Abstracts\Job
Command/ App\Command Your own php laika commands Laika\Engine\Cli\Contracts\CommandInterface
Relay/ App\Relay Relay providers — bind services into the container Laika\Engine\Relay\RelayProvider
Service/ App\Service Relay classes — the static proxies your code calls Laika\Engine\Relay\Relay

All of these can be scaffolded with the CLI — see CLI Reference.

lf-storage/ — Runtime State

Everything under lf-storage/ is created by the framework. It is git-ignored, the front controller never serves it, and app:sync drops a Deny from all .htaccess into it.

Path Holds
keys/app.key The application secret — encryption, CSRF, JWT all derive from it
cache/template/ Compiled Twig templates
cache/resources.php The compiled resource manifest (used when DEBUG is false)
queues/jobs.json, queues/failed.json The json queue driver
json/ JsonStorage documents
files/ LocalStorage’s default root
sessions/ File sessions, if you point Init::file(['path' => ...]) here

php laika app:sync deletes the contents of lf-storage/cache/ (templates included) and rebuilds the resource manifest.

Other Key Directories

Entry Points

File Runs
public/index.php Every web request: loads lf-boot/app.php, then calls Laika\Engine\Route\Url::dispatch()
laika php laika <command> — the CLI, generated by laikait/laika-engine
worker php worker [queue] — the queue worker, generated by laikait/laika-engine
public/.htaccess / nginx.conf Rewrite every request to public/index.php. See Deployment

What to Commit

The skeleton’s .gitignore already excludes vendor/, lf-logs/, lf-storage/, composer.lock, laika, worker and .htaccess — all of them are generated.

Writable Directories

The web server user (and the user that runs php laika / php worker) must be able to write: