Major version upgrade from 1.0.0 to 2.0.0 including copyright year updates, website URL migration to syspanel.com.br, and comprehensive CSRF token handling improvements. The Twig csrf() helper now returns a complete hidden input field instead of a raw token value, and token generation is now automatic when empty. Session initialization has been centralized in BaseController, and child controllers now properly call parent constructors. CRUD views have been modernized with flexbox layouts and consistent CSRF rendering. Documentation has been expanded with features, requirements, and project structure sections, and donation sections have been added across all pages.
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.syspanel.com.br](https://sysmvc.syspanel.com.br)
|
|
- **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.
|
|
|
|
© 2026 Marco Costa — All rights reserved under the MIT License.
|