Codegs Framework v2.0
Lightweight PHP AMVFC framework. Fast, direct, no magic. Built for real projects.
⚡ Quick Start
phpMyAdmin এ database বানাও,
codegs.sql import করো।.env.example কপি করে .env বানাও। DB_OFFLINE_NAME এ তোমার DB নাম দাও।.env এ APP_URL=http://localhost/yourproject দাও।http://localhost/yourproject/setup.php — email + password দাও।Login করার পরপরই
setup.php delete করো।APP_URL এ trailing slash দিও না। সঠিক: http://localhost/codegs — ভুল: http://localhost/codegs/📁 Folder Structure
yourproject/
├── index.php ← Front controller — সব request এখান থেকে শুরু
├── .env ← Credentials (git এ push করো না!)
├── .env.example ← Template
├── config/
│ ├── config.php ← সব constants define হয় এখানে
│ ├── env.php ← .env file loader
│ └── Router.php ← সব route এক জায়গায়
├── controller/
│ ├── GS_GUI.php ← Auth, home, profile, password reset
│ ├── BlogController.php ← Blog CRUD + public show
│ ├── ContactController.php ← Contact form + admin inbox
│ ├── UserController.php ← User management (admin)
│ ├── SettingsController.php ← Site settings + Route Manager
│ ├── NewsletterController.php← Subscribe/unsubscribe + broadcast
│ ├── TestimonialController.php← Testimonials CRUD
│ ├── ActivityController.php ← Activity log viewer
│ ├── BaseController.php ← সব controller এর parent
│ └── supporters/
│ └── supporters.php ← Supporter class (helpers সব এখানে)
├── middleware/
│ ├── MiddlewarePipeline.php ← Pipeline — order এখানে
│ ├── AuthMiddleware.php ← Login check + public routes whitelist
│ ├── RateLimitMiddleware.php ← Brute force protection
│ └── VisitorMiddleware.php ← Auto visitor tracking
├── model/
│ ├── db.php ← Database + GS_Model + QueryBuilder
│ ├── Blog_Model.php
│ ├── Contact_Model.php
│ └── User_Model.php
├── view/
│ ├── index.php ← Homepage (blog section সহ)
│ ├── get_in.php ← Login page
│ ├── sign_up.php ← Register page
│ ├── forgot_password.php ← Forgot password
│ ├── reset_password.php ← Reset password
│ ├── my_profile.php ← User profile
│ ├── change_password.php ← Change password
│ ├── admin/ ← Admin panel views
│ ├── gs/ ← Public frontend views
│ └── errors/ ← 404, 403, 500, 419
├── features/
│ └── CGS_Mailer.php ← Email sending (PHPMailer wrapper)
├── logs/ ← Spam logs (browser থেকে access বন্ধ)
├── assets/ ← CSS, JS, images, uploads
│ └── uploads/
│ ├── blog/ ← Blog images
│ └── users/ ← User avatars
└── setup.php ← Admin setup (use করার পর delete করো)
🧩 AMVFC Pattern
Codegs এর নিজস্ব pattern — Laravel বা CodeIgniter না, একদম সরল।
| Letter | কী | কোথায় |
|---|---|---|
| A | Assets — CSS, JS, images | assets/ |
| M | Model — Database queries | model/ |
| V | View — HTML templates | view/ |
| F | Features — External tools | features/ (Mailer, SMS) |
| C | Controller — Logic | controller/ |
Request flow: Browser → index.php → Middleware → Controller → Model → View
🗃️ Database Tables
Framework এর সাথে আসা সব tables — codegs.sql import করলেই ready।
নিজের project এর জন্য নতুন table বানাতে হলে phpMyAdmin এ বানাও বা CLI migration use করো।
🛣️ Routing System v2.0 নতুন
সব URL এক জায়গায় manage হয় — config/Router.php এ।
তিনটি URL format কাজ করে
| Type | Example | কখন ব্যবহার করবে |
|---|---|---|
| Clean URL | /blog, /contact | সবসময় — recommended |
| Controller/Function | /BlogController/index | .htaccess active থাকলে |
| Query String | ?controller=Blog&function=index | Form action এ, legacy support |
Route define করা
// config/Router.php এ যোগ করো:
// Public route (login ছাড়া access করা যাবে)
Router::get('products', 'ProductController', 'index', ['label' => 'Products', 'group' => 'public']);
// POST route
Router::post('do-subscribe', 'NewsletterController', 'subscribe', ['group' => 'public']);
// Login required
Router::any('profile', 'GS_GUI', 'profile', ['auth' => true, 'group' => 'account']);
// Admin only
Router::any('admin-products', 'ProductController', 'admin', ['admin' => true, 'group' => 'admin']);
middleware/AuthMiddleware.php এর $publicRoutes array তেও যোগ করতে হবে।URL Alias — Settings থেকে change করো
Admin → Settings → URL Route Manager থেকে যেকোনো route এর URL পরিবর্তন করা যায়, code না ছুঁয়েই।
| Route Key | Default URL | Custom Alias উদাহরণ |
|---|---|---|
| blog | /blog | /articles |
| contact | /contact | /reach-us |
| register | /register | /join-us |
View এ URL বানাও
<!-- Named route (alias থাকলে alias URL দেবে) -->
<a href="<?= $Supporter->route('blog') ?>">Blog</a>
<!-- Controller + function থেকে -->
<a href="<?= $Supporter->url('BlogController', 'index') ?>">Blog</a>
<!-- Direct query string (সবসময় কাজ করবে) -->
<a href="index.php?controller=BlogController&function=index">Blog</a>
🎮 Controllers
নতুন Controller তৈরি
php codegs make:controller Product
# → controller/ProductController.php তৈরি হবে
Controller structure
<?php
require_once __DIR__ . '/BaseController.php';
require_once __DIR__ . '/../model/Product_Model.php';
class ProductController extends BaseController
{
private Product_Model $product;
public function __construct()
{
parent::__construct();
$this->product = new Product_Model();
}
// Admin list
public function index(): void
{
$this->requireAdmin();
$items = $this->product->get_all();
$this->view('admin/products', compact('items'));
}
// Public page
public function show(): void
{
// requireAdmin() বা requireLogin() নেই = public
$items = $this->product->get_published();
$this->view('gs/products', compact('items'));
}
// Form save
public function store(): void
{
$this->requireAdmin();
$this->csrf(); // CSRF check
$this->Supporter->spam_guard(); // Spam check
$name = trim($_POST['name'] ?? '');
if (!$name) {
$this->back_with_error('Name required.', 'ProductController', 'index');
}
$this->product->create(['name' => $name]);
$this->back_with_success('Product added!', 'ProductController', 'index');
}
public function delete(): void
{
$this->requireAdmin();
$id = (int)($_GET['id'] ?? 0);
$this->product->delete($id);
$this->back_with_success('Deleted.', 'ProductController', 'index');
}
}
BaseController methods
| Method | কী করে |
|---|---|
$this->view('admin/page', $data) | View render করো — $data array এর keys view এ variable হয়ে যায় |
$this->requireAdmin() | Admin / Super admin login required — না থাকলে login page এ redirect |
$this->requireLogin() | যেকোনো logged-in user — না থাকলে login page এ redirect |
$this->csrf() | POST form এর CSRF token verify করো |
$this->back_with_success($msg, $ctrl, $fn) | Flash success + redirect |
$this->back_with_error($msg, $ctrl, $fn) | Flash error + redirect |
$this->json($data, $status) | JSON response + exit |
$this->showError(404) | Error page দেখাও + exit |
$this->redirectTo($ctrl, $fn) | Simple redirect |
🗄️ Models & Database
নতুন Model তৈরি
php codegs make:model Product
# → model/Product_Model.php তৈরি হবে
GS_Model — Direct SQL
// সব rows
$rows = $this->model->read_query("SELECT * FROM posts WHERE status = ?", ['published']);
// একটা row
$post = $this->model->read_one("SELECT * FROM posts WHERE id = ? LIMIT 1", [$id]);
// Single value (count, sum, etc.)
$count = $this->model->read_value("SELECT COUNT(*) FROM users");
// Insert / Update / Delete
$this->model->execute_query(
"INSERT INTO posts (title, slug) VALUES (?, ?)",
[$title, $slug]
);
// Last inserted ID
$newId = $this->model->last_insert_id();
// Table exists check
if ($this->model->tableExist('products')) { ... }
QueryBuilder — Fluent Style
// SELECT
$posts = $this->model->table('posts')
->select('id, title, slug, created_at')
->where('status', '=', 'published')
->where('user_id', '=', $userId)
->orderBy('created_at', 'DESC')
->limit(10)
->offset(20)
->get();
// Count
$total = $this->model->table('posts')->where('status','=','published')->count();
// First
$post = $this->model->table('posts')->where('slug','=',$slug)->first();
// Insert
$id = $this->model->table('posts')->insert([
'title' => 'Hello',
'slug' => 'hello',
]);
// Update
$this->model->table('posts')->where('id', '=', $id)->update(['title' => 'New Title']);
// Delete
$this->model->table('posts')->where('id', '=', $id)->delete();
// whereIn
$this->model->table('posts')->whereIn('id', [1, 2, 3])->get();
Transaction
$this->model->transaction(function($db) use ($data) {
$db->execute_query("INSERT INTO orders ...", [...]);
$db->execute_query("UPDATE stock SET qty = qty - 1 WHERE ...", [...]);
});
🛠️ Supporter Class
controller/supporters/supporters.php — framework এর সব helper এক জায়গায়। Controller এ $this->Supporter দিয়ে access করো, view এ $Supporter দিয়ে।
Auth
Flash Messages
Security
Routing
Validation
$errors = $this->Supporter->validate($_POST, [
'name' => 'required|min:2|max:100',
'email' => 'required|email',
'age' => 'required|numeric',
'phone' => 'min:11|max:14',
'password'=> 'required|min:6',
]);
if ($errors) {
// $errors['name'][0] = 'Name is required.'
}
Password
Utilities
🔗 Middleware
প্রতিটা request এ controller এর আগে চলে।
Default Pipeline — MiddlewarePipeline.php
public static function default(): static
{
return (new static())
->add(new VisitorMiddleware()) // IP log করে visitors table এ
->add(new RateLimitMiddleware()) // login brute force block করে
->add(new AuthMiddleware()); // login check করে
}
Public Routes — AuthMiddleware.php
এই routes গুলো login ছাড়াই access করা যাবে। নতুন public route যোগ করলে এখানে add করো।
private array $publicRoutes = [
'GS_GUI:home',
'GS_GUI:get_in',
'GS_GUI:login',
'GS_GUI:sign_up',
'GS_GUI:register',
'GS_GUI:forgot_password',
'GS_GUI:forgot_send',
'GS_GUI:reset_password',
'GS_GUI:reset_do',
'GS_GUI:ajax_ping',
'BlogController:show',
'ContactController:index',
'ContactController:submit',
'NewsletterController:subscribe',
'NewsletterController:unsubscribe',
// নতুন public route এখানে যোগ করো:
// 'ProductController:index',
];
নতুন Middleware
php codegs make:middleware RoleCheck
🛡️ SpamGuard — 5 Layer Protection Security
যেকোনো public form এ একটা লাইনে সম্পূর্ণ spam protection।
hp_website) bot fill করলেই block। Human দেখতে পায় না, tab করা যায় না।form_token() দিয়ে timestamp set হয়।ব্যবহার
// Controller — csrf() এর পরে:
$this->csrf();
$this->Supporter->spam_guard();
// Custom options:
$this->Supporter->spam_guard([
'min_time' => 3, // minimum 3 seconds to fill form
'max_per_hour' => 5, // max 5 submissions per IP per hour
'log_path' => 'logs/', // spam log save location
'bot_ua' => true, // bot user-agent detection
'honeypot' => true, // honeypot field check
'keywords' => true, // spam keyword scan
]);
// View — form এর ভেতরে:
<input type="hidden" name="_token" value="<?= $Supporter->csrf_token() ?>">
<?= (new Supporter())->form_token() ?> <!-- honeypot + timestamp -->
reCAPTCHA (optional)
// .env এ:
RECAPTCHA_SITE_KEY=your_site_key
RECAPTCHA_SECRET=your_secret_key
// View এ:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="<?= RECAPTCHA_SITE_KEY ?>"></div>
// Controller এ (spam_guard এর পরে):
if (!$this->Supporter->verify_recaptcha()) {
$this->back_with_error('reCAPTCHA failed.', 'ContactController', 'index');
}
logs/spam.log এ save হয়। Browser থেকে access বন্ধ (logs/.htaccess দিয়ে)।🔐 CSRF Protection
<!-- View — প্রতিটা POST form এ অবশ্যই: -->
<form method="POST">
<input type="hidden" name="controller" value="ProductController">
<input type="hidden" name="function" value="store">
<input type="hidden" name="_token" value="<?= $Supporter->csrf_token() ?>">
<!-- অথবা shorthand: -->
<?= $Supporter->csrf_field() ?>
...
</form>
// Controller এ:
$this->csrf(); // fail হলে session expired page দেখাবে
👤 Auth & Roles — RBAC v3 আপডেট
Role System
| Role | Slug | Default Access |
|---|---|---|
| Super Admin | super-admin | সব কিছু — কোনো restriction নেই |
| Admin | admin | Blog, Users, Contacts, Settings, Newsletter, Testimonials |
| Editor | editor | Blog manage, Testimonials view |
| Support | support | Contacts view ও edit |
| User | user | নিজের Profile, Change Password |
Permission Check — Controller এ
// পুরনো method (এখনো কাজ করে)
$this->requireAdmin(); // admin + super admin চেক
$this->requireLogin(); // যেকোনো logged-in user
// নতুন RBAC method
$this->Supporter->requirePermission('blog', 'create'); // না থাকলে 403
$this->Supporter->requirePermission('users', 'delete'); // না থাকলে 403
// Boolean check
if ($this->Supporter->can('blog', 'edit')) {
// edit button দেখাও
}
if ($this->Supporter->can('settings', 'view')) {
// settings menu দেখাও
}
// Actions: view | create | edit | delete
View এ Permission Check
// View file এ $Supporter available থাকে
if ($Supporter->can('blog', 'create')) {
echo '<a href="...">New Post</a>';
}
if ($Supporter->is_super_admin()) {
// super admin only
}
if ($Supporter->is_admin()) {
// admin menu
}
Custom Role বানানো
Admin Panel → Users → Roles এ গিয়ে নতুন role তৈরি করো, তারপর প্রতিটা module এর জন্য permission set করো।
php codegs migrate একবার run করো — roles ও permissions table তৈরি হবে।🔑 Password Reset
Forgot password → email link → reset password flow সম্পূর্ণ built-in।
| URL | কী করে |
|---|---|
/forgot-password | Email input form |
| Email এ link আসে | Token generate হয়, password_resets table এ save |
/reset-password?token=... | New password set করো |
.env এ SMTP credentials দিতে হবে।📝 Blog Module
Admin URLs
/admin-blog— Post list?function=create— নতুন post?function=edit&id=X— Edit?function=toggle&id=X— Draft/Published?function=delete&id=X— Delete
Public URL
/blog— Homepage blog section?controller=BlogController&function=show&slug=post-slug— Post detail
Image upload, auto slug, view count, author name — সব built-in।
👥 User Module
| URL / Action | কী করে |
|---|---|
/admin-users | All users list (paginated) |
?function=create | নতুন user বানাও (admin করতে পারে) |
?function=edit&id=X | User edit করো — role, status, password change |
?function=toggle&id=X | Active ↔ Inactive toggle |
?function=delete&id=X | User delete (নিজেকে করা যাবে না) |
/profile | নিজের profile edit |
/change-password | Password change |
📬 Contact Module
Public Form
/contact — Visitor এখানে message পাঠায়।
- SpamGuard protection আছে
- Settings থেকে contact info দেখায়
Admin Inbox
/admin-contacts — সব messages।
- Read / Unread badge
- Message detail view
- Reply via email link
- Delete
📨 Newsletter Module
| Action | কী করে |
|---|---|
| Public subscribe | Email form submit → subscribers table এ save |
| Unsubscribe | Email link এ click করলে auto unsubscribe |
/admin-newsletter | Subscriber list + broadcast email |
| Broadcast | সব active subscriber কে email পাঠাও — SMTP required |
Homepage এ subscribe form যোগ করো
<?php include 'view/gs/partials/newsletter_form.php'; ?>
⭐ Testimonials Module
| URL | কী করে |
|---|---|
/admin → Testimonials menu | All testimonials list |
| Create / Edit / Delete | Name, designation, company, rating, message, avatar |
| Toggle | Active ↔ Inactive |
// Homepage বা যেকোনো view এ testimonials দেখাতে:
$testimonials = $this->model->read_query(
"SELECT * FROM testimonials WHERE status = 'active' ORDER BY id DESC"
);
📋 Activity Log
Admin এর সব action log হয় — কে কখন কী করেছে।
// যেকোনো জায়গা থেকে log করো:
ActivityController::log(
'post_created',
'Created blog post: Hello World',
$_SESSION['user_id'] // optional
);
// Admin এ দেখো:
// /admin-activity → সব log list
// Clear all logs button আছে
⚙️ Settings Module
Admin → /admin-settings থেকে সব site settings control করো।
General Info
- Site name, email, phone, address
- Site logo upload
- SEO meta title & description
System Mode
- Active — Normal
- Maintenance — Visitors maintenance page দেখবে
- Coming Soon — Coming soon page দেখাবে
URL Route Manager
যেকোনো route এর URL slug পরিবর্তন করো — code না ছুঁয়েই।
DB এর route_aliases table এ save হয়।
Social Links
Facebook, WhatsApp, Instagram, YouTube — সব manage করো। Platform, URL, icon class দাও।
View এ settings access করো
// GS_GUI home() এ already load হয়:
$general_settings['site_name']
$general_settings['site_email']
$general_settings['system_mode']
// যেকোনো controller থেকে:
$settings = $this->Supporter->get_settings();
📧 Mailer — CGS_Mailer
require_once __DIR__ . '/../features/CGS_Mailer.php';
// Static call — সহজ
$sent = CGS_Mailer::send(
to: 'user@example.com',
subject: 'Welcome to ' . APP_NAME,
body: CGS_Mailer::template('Welcome!', '<p>Your account is ready.</p>')
);
if (!$sent) {
// email fail হয়েছে — log করো বা error দেখাও
}
Built-in HTML template
$body = CGS_Mailer::template(
title: 'Password Reset',
body: '<p>Click the link below to reset your password:</p>
<a href="' . $resetUrl . '">Reset Password</a>'
);
CGS_Mailer::send('user@example.com', 'Reset your password', $body);
.env SMTP config
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your@gmail.com
SMTP_PASS=your_app_password # Gmail App Password (2FA এ)
SMTP_FROM=your@gmail.com
SMTP_FROM_NAME=CodeGS
💻 CLI Commands
php codegs help → সব command দেখো
php codegs --version → version
php codegs serve → Dev server localhost:8000
php codegs serve localhost:9000 → Custom port
# Code generation
php codegs make:controller Product → controller/ProductController.php
php codegs make:model Product → model/Product_Model.php
php codegs make:middleware RoleCheck → middleware/RoleCheckMiddleware.php
php codegs make:migration products → model/migrations/YYYY_MM_DD_products.php
php codegs make:command notify:send → commands/notify_send.php
# Security
php codegs key:generate → নতুন JWT secret key
Database Migration Commands v3 নতুন
# Pending সব migration run করো — DB automatically update হবে
php codegs migrate
# কোন migration ran, কোনটা pending দেখো
php codegs migrate:status
# সর্বশেষ migration rollback করো
php codegs migrate:rollback
# সব rollback করে fresh migrate করো (সতর্ক!)
php codegs migrate:fresh
model/migrations/ folder এর সব .php file alphabetical order এ run হয়।
প্রতিটা migration এ version, up, down থাকে। _migrations table এ track রাখা হয় কোনটা already ran।
Module এর migrations/ folder ও automatically scan হয়।
Migration file structure
<?php
// model/migrations/2026_04_20_create_products.php
return [
'version' => '2026_04_20_create_products',
'description' => 'Create products table',
'up' => "
CREATE TABLE IF NOT EXISTS `products` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`price` DECIMAL(10,2) NOT NULL DEFAULT 0,
`status` ENUM('active','inactive') DEFAULT 'active',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
",
'down' => "DROP TABLE IF EXISTS `products`;",
];
🧩 Module System v3 নতুন
Codegs এ দুটো উপায়ে module বানানো যায়:
- Classic way — controller/ + model/ + view/ তে file রাখো, Router.php এ route যোগ করো
- Pluggable Module —
modules/folder এ self-contained module, কোনো core file ছুঁতে হবে না
Pluggable Module — কীভাবে কাজ করে
প্রতিটা module modules/ folder এর ভেতরে একটা আলাদা folder। ভেতরে একটা module.json manifest থাকে। index.php boot করার সময় ModuleLoader সব enabled module automatically load করে — routes, migrations, event listeners সব।
modules/
└── InvoiceModule/
├── module.json ← manifest (required)
├── InvoiceController.php ← auto-loaded
├── Invoice_Model.php ← auto-loaded
├── views/
│ ├── index.php
│ └── admin.php
└── migrations/
└── 2026_04_20_invoices.php
module.json — Manifest
{
"name": "InvoiceModule",
"version": "1.0.0",
"description": "Invoice management module",
"author": "Alamin",
"enabled": true,
"routes": [
{
"method": "any",
"slug": "invoices",
"controller": "InvoiceController",
"function": "index",
"options": { "label": "Invoices", "group": "admin", "admin": true }
}
],
"permissions": ["invoice.view", "invoice.create", "invoice.edit", "invoice.delete"],
"events": {
"contact.submitted": "InvoiceNotificationListener"
},
"depends": []
}
নতুন Pluggable Module বানানোর steps
mkdir -p modules/MyModule/views
mkdir -p modules/MyModule/migrations
modules/ExampleModule/module.json copy করে rename করো, তারপর edit করো।
<?php
require_once __DIR__ . '/../../controller/BaseController.php';
class MyController extends BaseController
{
public function index(): void
{
$this->Supporter->requirePermission('my-module', 'view');
$viewPath = ModuleLoader::viewPath('MyModule', 'index');
$Supporter = $this->Supporter;
include $viewPath;
}
}
<?php
// modules/MyModule/migrations/2026_04_20_my_table.php
return [
'version' => '2026_04_20_my_table',
'description' => 'Create my_items table',
'up' => "CREATE TABLE IF NOT EXISTS `my_items` (...);",
'down' => "DROP TABLE IF EXISTS `my_items`;",
];
module.json এ "enabled": true করো।
php codegs migrate
Module এর migrations/ folder ও automatically scan হবে।
Event Listener (Module এ)
<?php
// modules/MyModule/ContactListener.php
class ContactListener
{
public function handle(array $data): void
{
// contact submit হলে এই function call হবে
// $data['name'], $data['email'] etc. পাবে
}
}
// module.json এ:
// "events": { "contact.submitted": "ContactListener" }
Event fire করা (core controller থেকে)
// যেকোনো controller এ:
EventDispatcher::fire('contact.submitted', [
'name' => $name,
'email' => $email,
'message' => $message,
]);
Module disable করা
module.json এ "enabled": false করলে module পুরোপুরি বন্ধ — কোনো code change নেই।
অন্য project এ Module নিয়ে যাওয়া
পুরো modules/MyModule/ folder copy করো নতুন project এ। তারপর php codegs migrate। ব্যস।
➕ Classic Module বানানো (পুরনো way)
উদাহরণ: Product module।
php codegs make:migration products
# model/migrations/YYYY_MM_DD_products.php এ SQL লেখো
php codegs migrate # run করো
php codegs make:model Product
# model/Product_Model.php এ query methods লেখো
php codegs make:controller Product
# controller/ProductController.php এ logic লেখো
Router::get('products', 'ProductController', 'show', ['group' => 'public']);
Router::any('admin-products', 'ProductController', 'index', ['admin' => true, 'group' => 'admin']);
// Controller এ:
$this->Supporter->requirePermission('products', 'view');
🚀 Production Deploy Checklist
DEV_MODE=false
APP_URL=https://yourdomain.com # trailing slash দিও না
DB_ONLINE_HOST=your_host
DB_ONLINE_USER=your_user
DB_ONLINE_PASS=your_pass
DB_ONLINE_NAME=your_db
php codegs key:generate
# output টা .env এর JWT_SECRET এ দাও
Server এ upload করার আগেই delete করো।
.gitignore এ already আছে — তবু confirm করো।
logs/ এবং assets/uploads/ folder এ write permission দাও (755 বা 775)।
RECAPTCHA_SITE_KEY=your_site_key
RECAPTCHA_SECRET=your_secret
Local এ test করা password production এ রাখো না।
🛡️ Role Manager — কোথায় পাবো, কীভাবে ব্যবহার করবো
index.php?controller=SettingsController&function=rolesAdmin sidebar → Role Manager link থেকেও যেতে পারবে।
Role Manager হলো RBAC-এর visual control center। এখান থেকে কোন role কোন module access করতে পারবে সেটা checkbox দিয়ে toggle করা যায় — কোনো SQL লিখতে হবে না।
Permission Matrix — কীভাবে কাজ করে
| Column | মানে |
|---|---|
View | সেই module-এর list/index দেখতে পারবে |
Create | নতুন item তৈরি করতে পারবে |
Edit | existing item update করতে পারবে |
Delete | item মুছতে পারবে |
All (হলুদ checkbox) | একসাথে সব toggle করে |
Default Roles এবং তাদের Access
| Role | Blog | Users | Contacts | Settings | Roles |
|---|---|---|---|---|---|
| Super Admin | ✅ সব | ✅ সব | ✅ সব | ✅ সব | ✅ সব |
| Admin | ✅ সব | View+Create+Edit | View+Edit+Delete | View+Edit | ❌ নেই |
| Editor | View+Create+Edit | ❌ নেই | ❌ নেই | ❌ নেই | ❌ নেই |
| Support | View only | ❌ নেই | View+Edit | ❌ নেই | ❌ নেই |
| User | ❌ নেই | ❌ নেই | ❌ নেই | ❌ নেই | ❌ নেই |
নতুন Role তৈরি করতে
Role Manager page-এর ডানদিকে "New Role" form আছে। Name + Description দিয়ে Create করো। Role তৈরি হওয়ার পর Permission Matrix থেকে সেই role select করে permissions set করো।
is_system=1 তাই delete করা যাবে না। Editor ও Support delete করা যাবে।User কে Role assign করতে
Admin Panel → Users → Edit → Role dropdown থেকে role select করো। User login করলে সেই role-এর permissions automatically load হবে।
🔐 RBAC System — কোথায় কোথায় কাজ করে
requirePermission() apply করা হয়েছে।Controller এ RBAC ব্যবহার
// BaseController এ built-in — যেকোনো controller এ call করো
$this->Supporter->requirePermission('blog', 'delete');
// Permission না থাকলে → 403 page দেখাবে, exit করবে
কোন Controller এ কোন Permission চেক হয়
| Controller | Method | Required Permission |
|---|---|---|
| BlogController | index() | blog → view |
| create(), store() | blog → create | |
| edit(), update(), toggle() | blog → edit | |
| delete() | blog → delete | |
| show() | — (public, no check) | |
| UserController | index() | users → view |
| create(), store() | users → create | |
| edit(), update(), toggle() | users → edit | |
| delete() | users → delete | |
| ContactController | inbox(), show() | contacts → view |
| toggle_read() | contacts → edit | |
| delete() | contacts → delete | |
| submit() | — (public form) |
View থেকে Permission check করতে
// View file এ Supporter সবসময় available
<?php if ($Supporter->can('blog', 'delete')): ?>
<a href="...delete...">Delete</a>
<?php endif; ?>
Session Cache
Permissions login করার সময় $_SESSION['permissions'] এ cache হয়। Role Manager থেকে permissions update করলে সেই user-এর session এ cache clear হয় — পরের request থেকে নতুন permissions load হবে।
⚡ Event System — কোথায় fire হয়, কীভাবে listen করবো
contact.submitted event fire হয়।এখন পর্যন্ত যেসব Events fire হয়
| Event Name | কোথায় fire হয় | Data যা পাওয়া যায় |
|---|---|---|
contact.submitted | ContactController::submit() | name, email, phone, subject, message |
Listener তৈরি করতে (Module এ)
// modules/MyModule/ContactListener.php
class ContactListener {
public function handle(array $data): void {
// $data['name'], $data['email'], $data['message']
// e.g. Slack notification, CRM integration
error_log("New contact from: " . $data['name']);
}
}
তারপর module.json এ register করো:
"events": {
"contact.submitted": "ContactListener"
}
নিজে Event fire করতে
// যেকোনো controller বা model থেকে
EventDispatcher::fire('user.registered', [
'user_id' => $id,
'email' => $email,
]);
// Listener register করতে (bootstrap এ)
EventDispatcher::listen('user.registered', function(array $data) {
// welcome email পাঠাও
});
🧩 Module System — কীভাবে কাজ করে
index.php এ module controller lookup যোগ হয়েছে। এখন module enable করলে controller সঠিকভাবে found হবে।Module Structure
modules/
└── MyModule/
├── module.json ← manifest (required)
├── MyModuleController.php
├── MyModule_Model.php ← optional
├── views/
│ ├── index.php
│ └── admin.php
└── migrations/
└── 2026_01_01_my_table.php
module.json এর structure
{
"name": "MyModule",
"version": "1.0.0",
"enabled": true,
"routes": [
{
"method": "any",
"slug": "my-page",
"controller": "MyModuleController",
"function": "index"
}
],
"permissions": ["my-module.view", "my-module.create"],
"events": {
"contact.submitted": "MyContactListener"
},
"depends": []
}
Module enable/disable করতে
module.json এ "enabled": true করলে framework automatically boot করবে। false করলে ignore করবে — কোনো code change লাগবে না।
Module এর view load করতে
// Controller এ
$viewPath = ModuleLoader::viewPath('MyModule', 'index');
if (file_exists($viewPath)) {
$Supporter = $this->Supporter;
include $viewPath;
}
📦 make:module CLI Command
php codegs make:module InvoiceModule
এটা automatically তৈরি করবে:
modules/InvoiceModule/InvoiceModuleController.phpmodules/InvoiceModule/module.json(enabled: false)modules/InvoiceModule/views/index.phpmodules/InvoiceModule/views/admin.phpmodules/InvoiceModule/migrations/(empty)
তারপর করতে হবে:
module.json এ "enabled": true করোinvoice-module)php codegs make:migration invoice_items চালাওCLI browser UI থেকেও চালানো যাবে: cli.php → sidebar এ make:module দেখবে।
✅ v4 — সব Changes এক জায়গায়
| Category | কী পরিবর্তন হয়েছে | কোথায় কন্ট্রোল করবে |
|---|---|---|
| Bug Fix | index.php — module controller lookup |
Automatic — module enable করলেই কাজ করবে |
| Bug Fix | cli.php — migrate commands এখন browser CLI তে কাজ করে |
cli.php → Database group → migrate/status/rollback |
| RBAC | BlogController, UserController, ContactController এ permission check | Admin → Role Manager থেকে permission দাও/সরাও |
| Role Manager | নতুন admin page — permission matrix visual UI | ?controller=SettingsController&function=roles |
| Event System | contact.submitted event fire হয় ContactController এ |
Module এর module.json → events block |
| make:module | CLI command — পুরো module scaffold auto-generate | php codegs make:module ModuleName বা cli.php |
| ExampleModule | views/index.php + views/admin.php তৈরি হয়েছে | module.json এ enabled: true করলে error হবে না |
| Database | roles + permissions table, users.role_id column |
codegs.sql import করো বা php codegs migrate চালাও |