The README has been significantly updated to provide better project documentation: - Updated project description and metadata formatting - Added comprehensive Features section listing all framework capabilities - Added Requirements table with PHP, Composer, Web Server, and Database versions - Added Project Structure section with directory tree visualization - Removed outdated donation button section
338 lines
10 KiB
Markdown
Executable File
338 lines
10 KiB
Markdown
Executable File
# SysMVC
|
|
|
|
**SysMVC** is a lightweight PHP MVC framework created by **Marco Costa** ([syspanel@gmx.com](mailto:syspanel@gmx.com)), licensed under the **MIT License**.
|
|
|
|
This software is free to use, modify, and distribute under the terms of the MIT License.
|
|
|
|
- **Website:** [https://sysmvc.duckdns.org](https://sysmvc.duckdns.org)
|
|
- **GitHub:** [https://github.com/syspanel/SysMVC](https://github.com/syspanel/SysMVC)
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- **MVC Architecture** — clean separation of concerns with Models, Views, and Controllers
|
|
- **ORM (Eloquent)** — database access via `illuminate/database` (Laravel's Eloquent ORM)
|
|
- **Twin Template Engines** — BladeOne and Twig, configured side by side
|
|
- **Dependency Injection** — PHP-DI container with autowiring
|
|
- **Routing** — flexible HTTP routing via Pecee SimpleRouter
|
|
- **CSRF Protection** — built-in token generation and validation
|
|
- **Security Headers** — applied automatically via `BaseController`
|
|
- **Input/Output Sanitisation** — `Sanitizer` service with email and URL awareness
|
|
- **CLI Console** — Symfony Console commands for key generation and database migrations
|
|
- **Logging** — Monolog writes to `logs/app.log`
|
|
- **Mail** — Symfony Mailer integration
|
|
- **Authentication** — Delight Auth and PHP Auth libraries
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
| Requirement | Version |
|
|
|---|---|
|
|
| PHP | >= 7.4 |
|
|
| Composer | latest stable |
|
|
| Web Server | Apache or Nginx |
|
|
| Database | MySQL 5.7+ |
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
app/
|
|
├── app/
|
|
│ ├── Controllers/ # HTTP controllers
|
|
│ ├── Models/ # Eloquent models
|
|
│ ├── Services/ # Shared services (BaseController, Sanitizer)
|
|
│ └── Console/Command/ # CLI console commands
|
|
├── bootstrap/
|
|
│ ├── app.php # Bootstrap: loads config, routes, container
|
|
│ ├── csrf.php # CSRF token helpers
|
|
│ └── helpers.php # Global helper functions
|
|
├── config/
|
|
│ ├── container.php # DI container definitions (Blade, Twig, Monolog)
|
|
│ ├── database.php # Eloquent ORM connection setup
|
|
│ ├── envread.php # .env loader (defines constants)
|
|
│ ├── paths.php # VIEWS_PATH and CACHE_PATH constants
|
|
│ └── templateengine.php # CSRF template helpers
|
|
├── database/
|
|
│ └── crudexample.sql # Sample SQL schema
|
|
├── routes/
|
|
│ ├── web.php # Web routes
|
|
│ ├── api.php # API routes (extend as needed)
|
|
│ └── auth.php # Auth routes (extend as needed)
|
|
├── resources/views/ # Blade and Twig template files
|
|
├── public/
|
|
│ └── index.php # Application entry point
|
|
├── storage/ # Uploads and generated files
|
|
├── cache/ # Compiled template cache
|
|
├── logs/ # Application log files
|
|
├── tests/
|
|
│ ├── Feature/ # Feature tests
|
|
│ └── Unit/ # Unit tests
|
|
├── bin/
|
|
│ └── console # CLI entry point
|
|
├── composer.json
|
|
└── .env # Environment configuration (gitignored)
|
|
```
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
### 1. Clone or unzip the project
|
|
|
|
```bash
|
|
unzip sysmvc.zip -d sysmvc
|
|
cd sysmvc
|
|
```
|
|
|
|
### 2. Install PHP dependencies
|
|
|
|
```bash
|
|
composer install
|
|
```
|
|
|
|
### 3. Configure the environment
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Edit `.env` with your database and application settings:
|
|
|
|
```ini
|
|
# Application
|
|
APP_NAME=SysMVC
|
|
APP_ENV=production
|
|
APP_DEBUG=false
|
|
APP_URL=http://localhost:16270
|
|
|
|
# Database
|
|
DB_CONNECTION=mysql
|
|
DB_HOST=127.0.0.1
|
|
DB_PORT=3306
|
|
DB_DATABASE=your_database_name
|
|
DB_USERNAME=your_username
|
|
DB_PASSWORD=your_password
|
|
```
|
|
|
|
### 4. Set directory permissions
|
|
|
|
```bash
|
|
chmod -R 775 storage
|
|
chmod -R 775 cache
|
|
chmod -R 775 logs
|
|
chmod -R 775 bootstrap/cache
|
|
```
|
|
|
|
### 5. Generate the application key
|
|
|
|
```bash
|
|
php bin/console generate:app-key
|
|
```
|
|
|
|
### 6. Set up the database
|
|
|
|
Create the database manually or run the sample migration command:
|
|
|
|
```bash
|
|
php bin/console migrate:crudexample
|
|
```
|
|
|
|
### 7. Configure the web server
|
|
|
|
**Apache** — add a virtual host pointing to the `public/` directory:
|
|
|
|
```apache
|
|
<VirtualHost *:80>
|
|
ServerName sysmvc.local
|
|
DocumentRoot /path/to/sysmvc/public
|
|
|
|
<Directory /path/to/sysmvc/public>
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
</VirtualHost>
|
|
```
|
|
|
|
**Nginx** — add a server block pointing to the `public/` directory:
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name sysmvc.local;
|
|
root /path/to/sysmvc/public;
|
|
|
|
index index.php index.html;
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.php?$query_string;
|
|
}
|
|
|
|
location ~ \.php$ {
|
|
include snippets/fastcgi-php.conf;
|
|
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## CLI Commands
|
|
|
|
All CLI commands are available through the `bin/console` entry point:
|
|
|
|
```bash
|
|
php bin/console [command]
|
|
```
|
|
|
|
| Command | Description |
|
|
|---|---|
|
|
| `generate:app-key` | Generates a new `APP_KEY` and writes it to `.env` |
|
|
| `generate:api-keys` | Generates `API_PUBLIC_KEY` and `API_SECRET_KEY` in `.env` |
|
|
| `migrate:crudexample` | Creates the `crudexample` table with 30 sample records |
|
|
| `say:hello` | Example / demo command |
|
|
|
|
---
|
|
|
|
## Routing
|
|
|
|
Routes are defined in `routes/web.php` using Pecee SimpleRouter syntax.
|
|
|
|
### Example routes
|
|
|
|
```php
|
|
Router::get('/', [HomeController::class, 'index'])->name('home');
|
|
Router::get('/about', function () { ... })->name('about');
|
|
Router::post('/crudexample', [CrudExampleController::class, 'store'])->name('crudexample.store');
|
|
```
|
|
|
|
### Route groups
|
|
|
|
```php
|
|
Router::group(['prefix' => '/crudexample'], function () {
|
|
Router::get('/', 'CrudExampleController@index')->name('crudexample.index');
|
|
Router::get('/create', 'CrudExampleController@create')->name('crudexample.create');
|
|
Router::get('/edit/{id}', 'CrudExampleController@edit')->name('crudexample.edit');
|
|
Router::post('/store', 'CrudExampleController@store')->name('crudexample.store');
|
|
Router::post('/update/{id}', 'CrudExampleController@update')->name('crudexample.update');
|
|
Router::post('/delete/{id}', 'CrudExampleController@delete')->name('crudexample.delete');
|
|
Router::get('/show/{id}', 'CrudExampleController@show')->name('crudexample.show');
|
|
});
|
|
```
|
|
|
|
404 errors are handled by a global error handler that renders `resources/views/errors/404.html`.
|
|
|
|
---
|
|
|
|
## Security
|
|
|
|
SysMVC includes multiple security layers, all applied automatically.
|
|
|
|
### Security Headers (`BaseController`)
|
|
|
|
Applied to every controller that extends `BaseController`:
|
|
|
|
| Header | Value |
|
|
|---|---|
|
|
| `Content-Security-Policy` | `default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:` |
|
|
| `X-Frame-Options` | `DENY` |
|
|
| `X-Content-Type-Options` | `nosniff` |
|
|
| `Referrer-Policy` | `no-referrer` |
|
|
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains; preload` |
|
|
|
|
### CSRF Protection
|
|
|
|
Tokens are generated per session via `generateCsrfToken()` in `bootstrap/csrf.php`. Include the hidden field in forms with:
|
|
|
|
```php
|
|
<?= csrf() ?>
|
|
<!-- or -->
|
|
<input type="hidden" name="csrf_token" value="<?= getCsrfToken() ?>">
|
|
```
|
|
|
|
### Input Sanitisation
|
|
|
|
All form inputs are sanitised through `Sanitizer::sanitizeInput()` before storage. Output escaping is applied via `Sanitizer::sanitizeOutput()` before rendering.
|
|
|
|
### Password Storage
|
|
|
|
Passwords are hashed with `password_hash($password, PASSWORD_BCRYPT)` before being persisted.
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
Key environment variables loaded from `.env`:
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `APP_NAME` | `SysMVC` | Application name |
|
|
| `APP_KEY` | — | Random encryption key |
|
|
| `APP_ENV` | `production` | Environment: `production` / `local` / `testing` |
|
|
| `APP_DEBUG` | `false` | Display error details |
|
|
| `APP_URL` | — | Base URL of the application |
|
|
| `DB_CONNECTION` | `mysql` | Database driver |
|
|
| `DB_HOST` | `127.0.0.1` | Database host |
|
|
| `DB_PORT` | `3306` | Database port |
|
|
| `DB_DATABASE` | — | Database name |
|
|
| `DB_USERNAME` | — | Database user |
|
|
| `DB_PASSWORD` | — | Database password |
|
|
| `SESSION_DRIVER` | `file` | Session driver |
|
|
| `SESSION_LIFETIME` | `120` | Session duration in minutes |
|
|
|
|
PHP runtime settings are also configurable via `PHP_MEMORY_LIMIT`, `PHP_MAX_EXECUTION_TIME`, `PHP_DISPLAY_ERRORS`, and related variables in `.env`.
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
| Package | Version | License |
|
|
|---|---|---|
|
|
| `illuminate/database` | ^8.0 | MIT |
|
|
| `phpauth/phpauth` | ^1.0 | MIT |
|
|
| `monolog/monolog` | ^2.0 | MIT |
|
|
| `eftec/bladeone` | ^4.0 | MIT |
|
|
| `eftec/bladeonehtml` | ^2.5 | MIT |
|
|
| `twig/twig` | ^3.20 | BSD-3-Clause |
|
|
| `symfony/console` | ^5.0 | MIT |
|
|
| `symfony/mailer` | ^7.2 | MIT |
|
|
| `symfony/cache` | ^5.0 | MIT |
|
|
| `symfony/dotenv` | ^6.4 | MIT |
|
|
| `symfony/event-dispatcher` | ^5.0 | MIT |
|
|
| `symfony/filesystem` | ^5.0 | MIT |
|
|
| `symfony/translation` | ^5.0 | MIT |
|
|
| `symfony/mime` | ^6.4 | MIT |
|
|
| `robmorgan/phinx` | ^0.12.0 | MIT |
|
|
| `defuse/php-encryption` | ^2.2 | MIT |
|
|
| `paragonie/random_compat` | ^9.99 | MIT |
|
|
| `rakit/validation` | ^1.4 | MIT |
|
|
| `nesbot/carbon` | ^2.0 | MIT |
|
|
| `league/flysystem` | ^1.1 | MIT |
|
|
| `intervention/image` | ^2.5 | MIT |
|
|
| `predis/predis` | ^1.1 | MIT |
|
|
| `php-di/php-di` | ^7.0 | MIT |
|
|
| `pecee/simple-router` | ^5.4 | MIT |
|
|
| `nyholm/psr7` | ^1.8 | MIT |
|
|
| `fakerphp/faker` | ^1.24 | MIT |
|
|
| `delight-im/auth` | ^8.3 | MIT |
|
|
| `delight-im/db` | ^8.3 | MIT |
|
|
| `delight-im/cookie` | ^8.3 | MIT |
|
|
| `delight-im/http` | ^8.3 | MIT |
|
|
| `google/recaptcha` | ^1.2 | BSD-3-Clause |
|
|
| `guzzlehttp/guzzle` | ^7.0 | MIT |
|
|
| `guzzlehttp/promises` | ^1.5 | MIT |
|
|
| `guzzlehttp/psr7` | ^2.0 | MIT |
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
This project is licensed under the **MIT License**. You may use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, provided the original license and copyright notice are included.
|
|
|
|
See [LICENSE](LICENSE) for the full license text.
|
|
|
|
© 2025 Marco Costa — All rights reserved under the MIT License.
|