hostkurd / flocms
FloCMS is a light weight PHP Framework Developed by HostKurd
Requires
- php: ^8.1
- hostkurd/flocms-api: 1.2.0
- hostkurd/flocms-captcha: 1.1.0
- hostkurd/flocms-cli: 2.0.1
- hostkurd/flocms-core: 2.3.2
- hostkurd/flocms-uploader: 1.2.0
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
- hostkurd/flocms-admin: The admin panel: dashboard, users management, profile and your own content resources (php flo admin:install)
- hostkurd/flocms-reactive: Optional PHP reactive components for interactive pages without full-page reloads
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v1.8.2
- v1.8.1
- v1.8.0
- v1.7.8
- v1.7.7
- v1.7.6
- v1.7.5
- v1.7.4
- v1.7.3
- v1.7.2
- v1.7.1
- v1.7.0
- v1.6.0
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.12
- v1.2.11
- v1.2.10
- v1.2.9
- v1.2.8
- v1.2.7.1
- v1.2.7
- v1.2.6
- v1.2.5
- 1.2.4
- v1.2.3
- v1.2.2
- v1.1.4
- dev-release/1.8.2-core-2.3.2
- dev-release/1.8.1-admin-flow
- dev-release/1.8.0
- dev-fix/admin-layout-assets
- dev-release/1.7.7
- dev-release/1.7.6
This package is auto-updated.
Last update: 2026-10-13 09:53:04 UTC
README
About FloCMS
FloCMS is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. FLoCMS takes the pain out of development by easing common tasks used in many web projects, such as:
Table of Contents
Features
- Easy Routing: FloCMS Offers easy and fast routing engine.
- Caching: Multi backends for session and cache storage.
- Template Engine: With Flo Template Engine you can use PHP Codes easy inside templates.
- Multilingual: Powerfull Multilingual skeleton gives you ability to create a multilingual website.
Installation
To Create a new project, install it via Composer:
composer create-project hostkurd/flocms
Upgrading to Core 2.3.2
The skeleton pins Core 2.3.2. To update an existing project:
composer require hostkurd/flocms-core:2.3.2 -W
Page controllers can now return FloCMS\Core\Http\Response directly for
HTML fragments, JSON or other explicit responses. Existing template and
layout rendering continues to work. No application-file changes are needed
when upgrading from the 1.8.1 skeleton.
flocms-reactive is optional. FloCMS runs independently of it. To add reactive components:
composer require hostkurd/flocms-reactive
Follow the package's README to register components and include its assets.
Command line (php flo)
php flo runs flocms-cli. The flo
file in the project root only boots the CLI from vendor/, so
composer update brings new commands and fixes.
php flo # every command, grouped php flo help make:controller # usage, arguments, options, examples php flo doctor # check the installation (PHP, extensions, permissions, .env, database) php flo make:route Blog # controller + model + view php flo make:migration create_posts_table && php flo migrate php flo user:create --role=super-admin # create the first admin php flo down --allow=203.0.113.7 && php flo up php flo route:list # web and /api/v1 routes with permissions
Commands by area:
| Area | Commands |
|---|---|
| Generators | make:controller, make:model, make:view, make:route, make:api-controller, make:resource, make:middleware, make:request, make:migration, make:seeder, make:command, make:test, make:module (all with --dry-run and --force); delete:* |
| Database | migrate, migrate:status, migrate:rollback, migrate:fresh, db:seed, db:show, db:check |
| Application | about, doctor, key:generate, env:check, serve, down / up |
| Cache | cache:clear, view:clear, optimize, optimize:clear |
| Inspection | route:list, permission:list |
| Users | user:create, user:password, user:role, user:suspend, user:unsuspend, user:list, login:unlock |
| Translations | lang:missing, lang:add |
| Scheduler | schedule:run, schedule:list |
| Logs | log:tail, log:clear, log:rotate, storage:check |
| API | api:*, from flocms-api |
| Other | completion |
Exit codes: 0 success, 1 failure, 2 invalid usage. Errors go to STDERR, so scripts and cron jobs can rely on them.
Your own commands. Classes in commands/ (namespace App\Commands) are
commands too. commands/LoginUnlockCommand.php (php flo login:unlock <email|ip>) is an example; php flo make:command creates a new one.
Scheduler. One cron job runs the tasks in config/schedule.php. In cPanel,
use Cron Jobs → Once Per Minute:
* * * * * php /home/USER/site/flo schedule:run >> /dev/null 2>&1
Maintenance mode. php flo down makes the site and the API answer 503
until php flo up. Pass --allow=YOUR.IP to keep access yourself.
See the flocms-cli README for every option.
API (recommended: /api/v1)
public/api.php serves the routes in api/routes.php under /api with
hostkurd/flocms-api. Controllers
and resources live in api/ (namespace App\Api\):
return static function (Router $router): void { $router->version('v1', static function (Router $router): void { $router->get('/health', new HealthController())->name('health'); $router->post('/contact', [ContactController::class, 'store']) ->middleware('throttle:forms', 'idempotent'); $router->group('/users', static function (Router $router): void { $router->get('', [UsersController::class, 'index'])->name('index'); $router->get('/{id:\d+}', [UsersController::class, 'show'])->name('show'); }, ['auth:users.manage'], namePrefix: 'users.'); }); };
Every response is JSON with security headers. CORS is enabled for the origins
in API_CORS_ORIGINS (https://*.example.com patterns allowed), the locale
comes from ?lang= or Accept-Language, and requests are rate limited per
client (API_RATE_LIMIT per minute). The API path has no session and no CSRF
check by default. Route middleware:
| Middleware | Effect |
|---|---|
throttle:public, throttle:forms, throttle:auth |
named rate limits (60/min, 5/min, 10 per 15 min) |
auth, auth:users.manage |
a personal access token (Authorization: Bearer ...) or the admin session from same-origin JavaScript (with X-CSRF-TOKEN), optionally with permissions from config/config.php |
idempotent |
retries with the same Idempotency-Key header get the first response |
The examples show validation (ContactController), pagination with filters
and sorting, and a resource that keeps the password and token columns out of
responses (UsersController, UserResource).
Commands (php flo list api):
php flo api:install-schema # tables for tokens, API keys, idempotency php flo api:token:create 1 "Mobile app" # prints the token once php flo api:routes # list routes php flo api:docs --out=public/openapi.json # OpenAPI 3.1 (also at /api/v1/openapi.json when APP_DEBUG=true) php flo api:gc # clean up rate-limit and idempotency files (cron)
See the flocms-api README for validation rules, resources, caching, uploads
and testing your API with TestClient.
The old /api/<controller>/<action> route (methods prefixed api_) skips
CSRF checks and has no authentication. It is off unless LEGACY_API=true is
set in .env; move endpoints to api/routes.php.
The admin area
The skeleton gives you signing in and a protected area; the admin screens come from a package.
- Included: the login and logout pages (
/admin/users/login,/admin/users/logout), theuserstable, roles and permissions inconfig/config.php, thephp flo user:*commands, and a simple/adminpage. Any controller method namedadmin_...is served under/admin/...and requires a logged-in user with admin access. - The admin panel:
composer require hostkurd/flocms-adminandphp flo admin:installadd a dashboard (which/adminthen opens), users management, a profile page and pages for your own tables. See flocms-admin. - Your own admin instead: add
admin_actions to your controllers (php flo make:controller Reports --admin), protect them with$actionPermissions, and useUsersModelandAuthfor users. The documentation's "Build your own admin" guide shows a complete users page.
/admin follows the admin.home setting when one is set: a path under /admin ('dashboard'), or a non-string callable returning one. flocms-admin sets it; set it in config/config.php to choose another page, or to null to keep the skeleton's page. Strings are always paths, including names such as 'mail'. Use a closure for a dynamic destination. Paths to the skeleton's dashboard or an admin login action are ignored to prevent redirect loops.
Permissions (flocms-core 2.1+)
Admin panel access is controlled by roles and permissions. config/config.php maps each role to its permissions:
| Role | Name | Permissions |
|---|---|---|
| 0 | User | none |
| 1 | Editor | content.* |
| 2 | Admin | content.*, users.manage, users.assign_role, settings.* |
| 3 | Super Admin | * |
Controllers declare the permission each action needs; actions not listed fall back to '*', and null means no check:
protected array $actionPermissions = [ '*' => 'users.manage', 'admin_login' => null, ];
Inside an action, use Auth::can('settings.edit') or Auth::authorize('settings.edit') (throws 403).
For user management, Auth::canAssignRole($role) only allows roles up to your own, and Auth::canManageUser($role) only lower roles (Super Admins, with users.manage_any, can manage everyone).
Upgrading an existing site
- Require
hostkurd/flocms-core2.1.0. - Copy the
permissionsblock fromconfig/config.php, adjusting it to your roles. - Add
$actionPermissionsto your admin controllers, and useAuth::canAssignRole()/Auth::canManageUser()where users are edited. - Copy
templates/default/errors/403.htmland thepage.forbiddenstrings fromlang/*.php.
Until step 2 is done, the site behaves exactly as before (any role with admin access can do everything). Role changes take effect on the user's next login.
Upgrading to 1.5 (flocms-core 2.2)
FloCMS 1.5 requires hostkurd/flocms-core 2.2.0. Versions are pinned exactly,
so each site upgrades when you choose. Copy the changes below into an existing
site as needed; see CHANGELOG.md for the details.
Fresh install without a database
- In
composer.json, require"hostkurd/flocms-core": "2.2.0"and runcomposer update hostkurd/flocms-core. - Add
Config::set('db.port', Env::get('DB_PORT', 3306));toconfig/config.php. - Copy
templates/default/errors/nodbserver.htmlanddberror.html. They receive$message,$errorCodeand, in debug mode only,$detail. - Optional: copy the lazy
model()helper fromcontrollers/PagesController.phpand the database card fromviews/pages/index.html.
Models now connect on first query, so controllers that create a model in their constructor no longer fail when the database is down until they actually query it.
Session freshness and login throttling
- Add
"FloCMS\\Support\\": "support/"toautoload.psr-4incomposer.json, copysupport/LoginThrottle.php, and runcomposer dump-autoload. - In
controllers/UsersController.php(admin_login), copy theLoginThrottleblock, theclientIp()method,$throttle->clear($email)andSession::set('user_id', ...). - Copy the
auth.user_loader,login_throttleandtrusted_proxiessettings fromconfig/config.php, and addTRUSTED_PROXIES=to.env. - Copy the
auth.*strings fromlang/en.php. - Make sure
storage/cacheis writable and ignored by git (see.gitignore).
Users who are logged in when you deploy this are logged out once (their
session has no user_id yet).
Template cache
Templates are compiled to views/cache/ automatically. Make sure the web
server can write to it, keep it out of git (copy views/cache/.gitignore), and
delete old files such as views/cache/pages_index.php. Set
Config::set('view.cache_path', ...) to use another directory.
API, APP_KEY and CSRF
- Copy
public/api.phpandapi/routes.php, and add theapi/v1rule frompublic/.htaccessabove theindex.phprule. AddAPI_CORS_ORIGINS=andAPI_RATE_LIMIT=60to.env. - If your
.envstill has theAPP_KEYthat older skeletons shipped (base64:YFHTnSHarB6...), runphp flo key:generate --force(with the 1.7 launcher, see the CHANGELOG). Nothing usesAPP_KEYyet, so replacing it is safe. - Add
<meta name="csrf-token" ...>and thejs/csrf.jsscript fromtemplates/default/layouts/admin.htmlto your admin layout, copypublic/themes/default/js/csrf.js, and put@csrfin every POST form.
Uploads (flocms-uploader 1.2)
Require "hostkurd/flocms-uploader": "1.2.0". Video uploads
(Uploader::video()) and chunked uploads (->chunked()) are new and opt-in;
see the uploader README for the video and chunks config sections. Keep the
chunk directory outside public/ (e.g. storage/uploads/.chunks).
Running the tests
composer install
composer test
Tests that need MySQL/MariaDB are skipped unless FLO_TEST_MYSQL_HOST is set
(also FLO_TEST_MYSQL_PORT, _USER, _PASS, _NAME; default database
flocms_test).
Security Vulnerabilities
If you discover a security vulnerability within FLoCMS, please send an e-mail to Dev Team via dev@flocms.com. All security vulnerabilities will be promptly addressed.
License
The FloCMS framework is open-sourced software licensed under the MIT license.