websk / skif
Skif Admin
Requires
- php: 8.5.*
- ext-fileinfo: *
- ext-gd: *
- ext-json: *
- ext-mbstring: *
- ext-pdo: *
- ext-pdo_mysql: *
- ext-session: *
- ext-xmlwriter: *
- hkvstore/richfilemanager-php: ^2.4
- phpmailer/phpmailer: ^7.1
- slim/php-view: 3.4.*
- slim/slim: 4.15.*
- websk/php-auth: 4.0.*
- websk/php-cache: 3.0.*
- websk/php-captcha: 3.0.*
- websk/php-config: 2.2.*
- websk/php-crud: 4.0.*
- websk/php-db: 3.0.*
- websk/php-entity: 3.0.*
- websk/php-imagemanager: 3.0.*
- websk/php-keyvalue: 4.0.*
- websk/php-logger: 4.0.*
- websk/php-simple-router: 3.0.*
- websk/php-slim: 2.4.*
- websk/php-utils: 3.0.*
- websk/php-view: 3.1.*
Requires (Dev)
- phpstan/phpstan: ^2.3
- phpunit/phpunit: ^12.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-08 16:57:01 UTC
README
Skif is an admin panel and CMS toolkit built on Slim 4 and the WebSK PHP components. It includes modules for authentication, settings, logging, content, blocks, comments, forms, polls, redirects, menus, CAPTCHA, images, and file management.
- Package: websk/skif on Packagist
- Changes: CHANGELOG.md
- PHP policy:
8.5.*(Composer platform:8.5.12) - Docker runtime: PHP 8.5.12
- License: MIT
Main components
- Slim 4 with PHP-DI integration
- WebSK PHP 3.x components with CRUD, Auth, Logger, and KeyValue 4.x
- MySQL and Memcached
- AdminLTE 4.10, Bootstrap 5.3, jQuery 3.7, and Jodit 4
- RichFileManager 3.2 frontend with the 2.4 PHP backend
- Nginx and PHP-FPM for the Docker development environment
The HTTP entry point is public/index.php. The administration interface is available under /admin, and public/ must be configured as the web-server document root.
Requirements
- PHP 8.5.x
- PHP extensions required by Composer:
fileinfogdjsonmbstringpdopdo_mysqlsessionxmlwriter
- Composer 2
- MySQL 8.x or a compatible server
- Memcached and the PHP
memcachedextension when using the default cache configuration - Node.js 24 LTS and npm 11 when rebuilding frontend assets
- Docker Compose and mkcert for the local HTTPS environment
Use Skif from another Composer project
The Composer package provides the complete WebSK\Skif\SkifApp Slim application, including its admin and public routes, templates, database migrations, and frontend assets. The consuming project supplies the root configuration, public entry point, writable directories, database, cache, and web-server rules.
The examples below assume this consumer layout:
project/
├── config/config.default.php
├── config/config.php
├── public/index.php
├── public/assets/
├── public/filemanager/filemanager.php
├── public/files/
├── public/static/
└── vendor/
1. Install the package
composer require websk/skif mkdir -p config public/assets public/filemanager public/files public/static log tmp
The PHP process must be able to write to public/files, public/static, log, and tmp.
2. Create the consumer configuration
Use the supplied default configuration and override example as the reference. In an installed Composer package, the same files are available under vendor/websk/skif/config/.
Copy both files into the consumer project:
cp vendor/websk/skif/config/config.default.php config/config.default.php cp vendor/websk/skif/config/config.example.php config/config.php
config/config.php loads the adjacent config.default.php and applies local overrides with array_replace_recursive(). Keep environment-specific changes in config/config.php; after updating websk/skif, compare the copied default file with vendor/websk/skif/config/config.default.php for new or changed settings.
At minimum, review and override:
- all four entries under
settings.db:db_auth,db_keyvalue,db_logger, anddb_skif; - the cache server under
settings.cache.servers; settings.site_domainandsettings.site_full_path;settings.log_path,settings.tmp_path,settings.static_data_path, andsettings.files_data_path;settings.storages.files.root_pathand its publicurl_path;- every path under
settings.layoutandsettings.skif.layout; settings.displayErrorDetails, which should be disabled outside development.
The four database entries must remain present because their migration dump paths come from the corresponding WebSK packages. They may all point to the same physical database.
The supplied defaults use /var/www paths from the included Docker environment. For an external project, point the layout settings to vendor/websk/skif/views/layouts/, or copy vendor/websk/skif/views/ into the consumer project before replacing those paths.
3. Create the public entry point
Create public/index.php:
<?php declare(strict_types=1); use Jgut\Slim\PHPDI\Configuration; use Jgut\Slim\PHPDI\ContainerBuilder; use Psr\Http\Message\ServerRequestInterface; use Slim\Factory\ServerRequestCreatorFactory; use WebSK\Config\ConfWrapper; use WebSK\Skif\SkifApp; require dirname(__DIR__) . '/vendor/autoload.php'; $config = require dirname(__DIR__) . '/config/config.php'; $configuration = new Configuration(); $configuration->setDefinitions([$config]); $configuration->setUseAttributes(true); $container = ContainerBuilder::build($configuration); $container->set( ServerRequestInterface::class, static fn (): ServerRequestInterface => ServerRequestCreatorFactory::create() ->createServerRequestFromGlobals() ); ConfWrapper::setConfig($config['settings']); $app = new SkifApp($container); $app->run();
SkifApp constructs the Slim application and registers the Skif route set. Use this entry point as the application kernel; /admin and the public module routes are registered by its constructor. The package does not currently expose a single installer for mounting the complete Skif route set into an already constructed Slim\App; that integration requires registering the individual WebSK service providers and route classes in the host application.
4. Publish public files
Copy the packaged assets and RichFileManager connector into the consumer document root:
cp -R vendor/websk/skif/public/assets/. public/assets/ cp vendor/websk/skif/public/filemanager/filemanager.php public/filemanager/filemanager.php
Repeat this step after updating websk/skif. The copied connector expects the standard paths vendor/autoload.php and config/config.php shown above.
Skif generates versioned URLs such as /assets/1/styles/skif.css, while the physical file is stored as public/assets/styles/skif.css. Configure the web server to remove the numeric version segment internally. RichFileManager also needs /filemanager to resolve to its PHP connector. The included Nginx configuration uses:
location ~ ^/assets/\d+/.* { rewrite ^/assets/\d+/(.*) /assets/$1; } location /filemanager { try_files $uri /filemanager/filemanager.php$is_args$args; } location = /filemanager/filemanager.php { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-upstream; include fastcgi_params; }
Configure the remaining requests through public/index.php, and use public/ as the document root.
5. Initialize the database and administrator
Run the package-provided Composer binaries from the consumer project root:
php vendor/bin/websk_db_migration.php migrations:migration_auto php vendor/bin/websk_auth_create_user.php auth:create_user
The command generates random credentials; use the exact Email and Password printed by the command when signing in.
Complete migrations before serving the first HTTP request: public content route initialization may query the Skif database. The administration interface is then available at /admin. RichFileManager uses settings.files_data_path and accepts requests only from authenticated administrators.
Install a source checkout
Install PHP dependencies and create the local configuration:
composer install cp config/config.example.php config/config.php mkdir -p public/files public/static log tmp
config/config.php and uploaded files under public/files/ are intentionally ignored by Git. Ensure that public/files, public/static, log, and tmp are writable by the PHP-FPM user in your environment.
Frontend assets are committed to the repository. Rebuild them after changing package.json, package-lock.json, or scripts/build-assets.mjs:
npm ci npm run build npm run check npm run audit:production npm run audit:high
Use Node 24 and npm 11 as declared in package.json; .nvmrc and .node-version are provided for local version managers.
npm run check lints project and browser-test JavaScript, rejects Bootstrap 3/AdminLTE 2 contracts, validates local CSS and source-map references, enforces the generated asset budget, rejects server-side files under public/assets, and compares committed assets with a clean temporary build. audit:production fails on any production advisory of moderate severity or higher; audit:high checks the complete dependency tree for high and critical findings.
The build script copies an explicit set of third-party files from node_modules/ to managed directories under public/assets/libraries/. RichFileManager is included in the same reproducible build from the exact npm version recorded in package-lock.json; its public tree contains only the files required at runtime.
Project-owned browser code is stored directly under public/assets/scripts/. This includes the content photo uploader, which validates GIF/JPEG/PNG files, reports upload progress, and refreshes the photo list. Blueimp File Upload and MediumEditor remain published only for their websk/php-crud widgets.
After starting Docker, install Chromium once and run the browser smoke suite:
npm run test:e2e:install npm run test:e2e
The unauthenticated login smoke always runs. To exercise the authenticated AdminLTE shell, set SKIF_E2E_EMAIL and SKIF_E2E_PASSWORD for a dedicated test administrator. Set SKIF_E2E_CONTENT_EDIT_URL to an editable fixture URL to test content tabs. The suite fails on browser console errors and failed document, script, stylesheet, font, or image requests, and runs at desktop and mobile viewports.
The current browser behavior and upgrade-sensitive integration points are recorded in the frontend baseline. The dependency inventory records package ownership, versions, licenses, known audit findings, and the intended migration direction.
Run the Docker environment
Create a locally trusted certificate:
mkcert --install mkdir -p var/docker/nginx/ssl cd var/docker/nginx/ssl mkcert skif.devbox cd ../../../..
Add the following entry to /etc/hosts on Linux or macOS, or to %WINDIR%\System32\drivers\etc\hosts on Windows:
127.0.0.1 skif.devbox
Prepare the application and Docker configuration:
cp config/config.example.php config/config.php mkdir -p public/files public/static log tmp cp var/docker/.example.env var/docker/.env
Start the services and install PHP dependencies inside the PHP 8.5.12 container:
cd var/docker docker compose up -d --build docker compose exec php-fpm composer install
Run database migrations and create an administrator:
docker compose exec php-fpm php vendor/bin/websk_db_migration.php migrations:migration_auto docker compose exec php-fpm php vendor/bin/websk_auth_create_user.php auth:create_user
The command prints the generated Email and Password required for authorization.
For interactive migration selection, use:
docker compose exec php-fpm php vendor/bin/websk_db_migration.php migrations:migration_handle
Open https://skif.devbox/admin and sign in with the administrator account you created.
Useful Docker commands:
docker compose ps docker compose logs -f php-fpm nginx docker compose down
Configuration
config/config.example.php merges local development overrides into config/config.default.php. Copy the example to the ignored config/config.php and keep environment-specific settings there.
Review these settings when adapting the application:
| Setting | Purpose | Docker default |
|---|---|---|
settings.displayErrorDetails |
Detailed Slim error responses | true in the example |
settings.db.* |
Database connection for each WebSK module | MySQL service, skif database |
settings.cache.* |
Cache engine, prefix, lifetime, and servers | Memcached service |
settings.skif.url_path |
URL prefix used for versioned assets | / |
settings.skif.assets_version |
Version segment in asset URLs | 1 |
settings.site_domain |
Canonical application URL used in links and messages | https://skif.devbox |
settings.files_data_path |
Local file-manager storage | /var/www/public/files |
settings.storages.files |
File storage adapter, URL, and allowed file types | Local storage under /files |
settings.layout.* |
Absolute paths to PHP layout templates | /var/www/views/layouts/... |
settings.rich_text_editor.styles |
Stylesheets loaded into the isolated Jodit editing area | /assets/<version>/styles/main.css when empty |
settings.rich_text_editor.filemanager_path |
Optional RichFileManager frontend URL | /assets/<version>/libraries/filemanager/index.html when empty |
For compatibility with existing integrations, the editor also reads the former settings.ckeditor.styles and settings.ckeditor.filemanager_path keys when the corresponding rich_text_editor value is absent.
The default configuration contains development credentials suitable for the included Docker environment. Replace credentials, site_domain, filesystem paths, and displayErrorDetails for deployment.
The Docker environment is configured through var/docker/.env, copied from var/docker/.example.env. It controls ports, bind-mount paths, MySQL, and optional PHP extensions. If database names or credentials change, update both Docker and application configuration.
RichFileManager
Jodit provides separate image and file buttons that open the frontend from /assets/<version>/libraries/filemanager/index.html. RichFileManager returns the selected resource to the active editor through a same-origin postMessage. Its connector sends requests to /filemanager, which is handled by public/filemanager/filemanager.php and the hkvstore/richfilemanager-php backend.
The connector uses settings.files_data_path as its root and permits access only to authenticated administrators. Keep the Nginx /filemanager locations when replacing the supplied server configuration.
The RichFileManager 3.2 runtime is generated from the pinned @hkvstore/rich-filemanager npm package. Skif copies only the files used at runtime; upstream demos, tests, Node/PHP connectors, and sample upload endpoints are excluded. Project-specific frontend settings are maintained in resources/frontend/filemanager/ and copied by npm run build.
Development checks
composer lint
composer phpstan
composer test
composer check
composer validate --strict
composer lintchecks PHP syntax insrc,public,config, andtests.composer phpstananalyzessrcandtestsat level 6 using the PHP 8.5.12 target.composer testruns PHPUnit 12 with warnings and deprecations treated as failures.composer checkruns lint, PHPStan, and PHPUnit in sequence.
Project structure
config/— default and local application configurationpublic/— document root, front controller, assets, uploads, and file-manager connectorsrc/WebSK/Skif/— application, routes, handlers, services, and modulestests/— PHPUnit tests and PHP 8.5 deprecation gateviews/— application layouts and shared templatesvar/docker/— Nginx, PHP-FPM, MySQL, and Memcached development environmentscripts/build-assets.mjs— deterministic frontend asset copying and verification
Troubleshooting
- Missing
config/config.php: copyconfig/config.example.phpbefore running HTTP or CLI entry points. - Database connection errors: verify
settings.db.*, the MySQL service state, and values invar/docker/.env. - Cache connection errors: start Memcached or configure another supported cache engine.
- Asset 404 responses: run
npm ci && npm run buildand keep the Nginx rewrite for/assets/<version>/.... - File-manager errors: verify the
/filemanagerNginx locations and write access tosettings.files_data_path. - HTTPS errors: confirm that
skif.devbox.pemandskif.devbox-key.pemexist invar/docker/nginx/ssl/and are trusted by the local mkcert CA.
License
Skif is released under the MIT License.