machinjiri / framework
Machinjiri is a lightweight, flexible PHP framework for rapid web development.
Requires
- php: ^8.3
- dragonmantank/cron-expression: ^3.6.0
- phpmailer/phpmailer: ^7.0.1
- predis/predis: ^3.3.0
- symfony/console: ^5.3
- symfony/filesystem: ^5.3
- symfony/process: ^5.3
Requires (Dev)
- brianium/paratest: *
- fakerphp/faker: ^1.20
- mockery/mockery: ^1.5
- phpunit/phpunit: ^10.0
README
Machinjiri is a flexible, powerful PHP framework designed for rapid web development. Built for PHP 8.3+, it provides a modular architecture, elegant routing system, comprehensive database abstraction, authentication and authorization, and robust security features. Designed for speed, scalability, and developer experience, Machinjiri empowers developers to build secure, maintainable applications efficiently.
Current stable version: 2.2.2
What’s New in 2.2.2
- Added a persistent task scheduler with cron expressions, queued execution, overlap locks, task groups, priorities, retries, caching, and health checks
- Added scheduler Artisan commands for creating, listing, running, enabling, disabling, and inspecting scheduled tasks
- Improved webhook processing with provider subscriptions, configurable synchronous or asynchronous handling, signature verification, response handling, and idempotency support
- Reworked exception handling into separate context, logging, reporting, rendering, and throttling services
- Added configurable SMS transports with synchronous delivery and queue-backed asynchronous delivery
- Updated core routing, middleware resolution, service-provider loading, generators, and mail integration
- Updated framework support to PHP 8.3+ and package version
2.2.2
Table of Contents
- Introduction
- Features
- System Requirements
- Installation
- Quick Start
- Project Structure
- Core Components
- Usage Examples
- Configuration
- API Reference
- Error Handling
- Testing
- Console Commands (Artisan)
- Contributing
- License
- Support
Introduction
Machinjiri is designed to accelerate web development with:
- Modular architecture with service providers and dependency injection
- Elegant routing with middleware, groups, and named routes
- Powerful view templating with inheritance and asset management
- Multi-database support with migrations and query builders
- Built-in authentication with OAuth, sessions, and cookies
- Advanced security with encryption, hashing, CSRF tokens, and SQL injection prevention
- Job queues for background processing
- Task scheduling with cron expressions and persistent execution history
- Webhook handling with signature verification and synchronous or queued dispatch
- SMS transport with configurable providers and asynchronous delivery
- Comprehensive logging and error handling
Features
Core Architecture
- Singleton Application Container: Centralized management of application resources and configuration
- Service Container: Powerful dependency injection with service binding and resolution
- Provider System: Modular service providers with lazy loading and bootstrapping
- Configuration Management: Environment-aware config loading with
.envsupport - Service Facades: Quick access to complex services with simple syntax
- FTP Filesystem Adapter: Remote storage operations with FTP disk support
- Redis Integration: Distributed cache and queue support for scalable workflows
- Webhook Processing: Signature verification, idempotency, and async dispatch for webhook handling
- ULID & OTP Utilities: ULID generation/validation and OTP/TOTP support for secure workflows
Routing System
- Flexible HTTP Routing: RESTful routes with GET, POST, PUT, DELETE, PATCH methods
- Route Groups: Apply middleware, prefixes, and CORS to multiple routes
- Route Parameters: Capture and validate route parameters
- AJAX Handling: Built-in AJAX-only and traditional route segregation
- Named Routes: Generate URLs using route names and parameters
- CORS Support: Automatic CORS header handling and preflight requests
- Rate Limiting: Configurable request rate limiting per route
- Route Caching: Performance optimization through route caching
View Engine
- Template Inheritance: Blade-like template inheritance with layouts and sections
- Custom Template Tags:
<% %>syntax with PHP logic support - Partial Includes: Component-based development with fragment includes
- Asset Management: Automatic CSS/JS resource loading
- Data Sharing: Share data across multiple views globally
- Loop Directives: Enhanced foreach loops with context variables
Database & ORM
- Multi-Driver Support: MySQL, PostgreSQL, SQLite database drivers
- Query Builder: Expressive, fluent query construction
- Migrations: Built-in migration system for database schema management
- Schema Builder: Create, modify, and drop tables programmatically
- Seeders & Factories: Database seeding and model factories for testing
- Connection Pool: Manage multiple database connections
- Transaction Support: ACID compliance with transaction handling
Authentication & Security
- Session Management: Secure session handling with configurable drivers
- OAuth Integration: Third-party authentication (Google, GitHub, etc.)
- Cookie Management: Secure cookie handling with encryption options
- Password Hashing: Built-in password hashing with bcrypt/Argon2
- CSRF Token Protection: Automatic CSRF token generation and validation
- SQL Injection Prevention: Parameterized queries via query builder
- Encryption: AES encryption/decryption for sensitive data
- JWT Tokens: JSON Web Token support for API authentication
Forms & Validation
- Form Validation: Comprehensive validation rules engine
- Rule Builder: Fluent interface for building complex validation rules
- Password Rules: Special validation rules for password strength
- Error Messages: Custom error messages and localization support
- Form Handler: Server-side form processing and CSRF protection
Queues & Jobs
- Background Job Processing: Defer heavy operations to background queues
- Database Queue Driver: Persist jobs in database for reliability
- Redis Queue Driver: High-performance Redis-backed job queue with delayed dispatch, reservation, and retry handling
- Job Dispatcher: Flexible job scheduling and dispatching
- Workers: Process jobs with configurable retry logic
- Event System: Event listeners and viewers for queue events
- Artisan Commands: Generate jobs and manage queue processing
Task Scheduler
- Persistent schedules: Store scheduled tasks and execution history through the database repository
- Cron expressions: Define when tasks run using standard cron syntax
- Queued execution: Dispatch due tasks to the scheduler queue
- Overlap protection: Lock tasks to prevent concurrent execution
- Task management: Register, sync, enable, disable, run, and delete tasks
- Operational controls: Group and prioritize tasks, configure retries, cache schedule data, and inspect scheduler health
Webhooks
- Provider subscriptions: Register event handlers and provider-specific behavior
- Signature verification: Support HMAC, timestamped HMAC, and custom verification callbacks
- Synchronous or asynchronous processing: Route providers to immediate handling or the
webhooksqueue - Idempotency support: Track processed webhook keys through the cache-backed idempotency store
- Response handling: Return accepted, unauthorized, not-found, and other HTTP responses based on processing results
SMS
- Transport registry: Configure and select SMS transports through the SMS manager
- Synchronous delivery: Send messages immediately through the default transport
- Asynchronous delivery: Queue SMS sends on the
smsqueue when enabled - Extensible providers: Add custom transports and receive structured delivery responses
Components
- Component Factory: Create UI components programmatically
- Pre-built Components: Alert, Button, Card, Form, Input, Modal, Nav, ProgressBar
- Component Traits: Reusable component functionality
- Attributes Management: Flexible attribute handling for HTML elements
- CSS Classes Builder: Dynamic CSS class generation
HTTP Layer
- Request/Response Objects: Object-oriented HTTP request and response handling
- Request Utilities: Easy access to GET/POST/FILE data, headers, and server info
- Response Types: JSON, redirects, downloads, streaming responses
- Middleware Support: Stack-based middleware pipeline with arguments
- Header Management: Easy header manipulation and CORS configuration
- Status Codes: Comprehensive HTTP status code support
Logging & Monitoring
- Multi-Channel Logging: Database, file, and event-based logging
- Structured Logging: Log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
- Event System: Event listeners for application events
- Error Logging: Automatic logging of exceptions and errors
- Environment-Aware: Different logging behavior for dev/production
Date & Time Handling
- DateTime Handler: Unified date/time manipulation
- Timezone Support: Configurable timezone handling
- Format Support: Multiple date format support
- Utility Methods: Common date operations built-in
Network Utilities
- HTTP Client: cURL-based HTTP client for API calls
- Server Management: PHP built-in server management for development
- Connection Handling: Request/response HTTP utilities
System Requirements
- PHP: 8.3 or higher
- Extensions:
- PDO (for database support)
- cURL (for HTTP client)
- JSON (for API support)
- OpenSSL (for encryption)
- ftp (optional, for FTP filesystem support)
- ldap (optional, for LDAP authentication and directory integration)
- Composer: 2.0 or higher
- Database: MySQL 5.7+, PostgreSQL 10+, or SQLite 3+
Installation
Install with Composer
Install Machinjiri as a dependency in your project:
composer require machinjiri/framework
Local development
To run the framework repository locally:
git clone https://github.com/mlangeni/machinjiri.git
cd machinjiri
composer install
Recommended setup
- Copy
.env.exampleto.env - Set
APP_KEY, database, and mail credentials - Run
composer testto verify the installation
Quick Start
1. Create Your First Route
// routes/web.php use Mlangeni\Machinjiri\Core\Routing\Router; Router::get('/', function() { return 'Welcome to Machinjiri!'; }); Router::get('/hello/{name}', function($name) { return "Hello, {$name}!"; }, 'greeting');
2. Create a Controller
// app/Controllers/HomeController.php namespace App\Controllers; class HomeController { public function index() { return view('home', ['title' => 'Home Page']); } }
3. Create a View
<!-- resources/views/home.view.php --> <% extend('layouts.app') %> <% section('content') %> <div class="container"> <h1><%= $title %></h1> <p>Welcome to your Machinjiri application!</p> </div> <% endsection %>
4. Connect Route to Controller
// routes/web.php Router::get('/', 'HomeController@index', 'home');
5. Start Development Server
php artisan run:dev
Visit http://localhost:3000 in your browser.
Project Structure
your-project/
├── app/
│ ├── Controllers/ # Application controllers
│ ├── Jobs/ # Application Jobs
│ ├── Middleware/ # Custom middleware classes
│ ├── Queue/ # Queue Drivers
│ │ └── Drivers/ # Driver Files (Custom Queue Drivers)
│ ├── Models/ # Data models
│ ├── Providers/ # Service providers
│ └── Exceptions/ # Custom exceptions
├── bootstrap/
│ ├── app.php/ # Application bootstrap file
│ ├── artisan.php/ # Application bootstrap file
│ └── helpers.php # Helper functions (API)
├── config/
│ ├── app.php # Application configuration
│ ├── database.php # Database configuration
│ ├── mail.php # Mail service configuration
│ ├── auth.php # Authentication configuration
│ └── providers.php # Service providers list
├── database/
│ ├── migrations/ # Database migration files
│ ├── seeders/ # Database seeder classes
│ └── factories/ # Model factory classes
├── resources/
│ └── views/ # View templates
│ ├── layouts/ # Layout templates
│ ├── partials/ # Reusable view fragments
│ └── pages/ # Page-specific views
├── routes/
│ └── web.php # Web application routes
├── storage/
│ ├── cache/ # Cached data files
│ ├── cookies/ # Cookie storage
│ ├── logs/ # Application logs
│ └── sessions/ # Session files
├── public/
│ ├── src/
│ │ ├── css/ # Stylesheets
│ │ ├── js/ # JavaScript files
│ │ └── images/ # Image assets
│ ├── .htaccess # .htaccess config file
│ └── index.php # Application entry point
├── vendor/ # Composer dependencies
├── .env # Environment configuration
├── artisan # Console application
├── composer.json # Project dependencies
└── phpunit.xml # PHPUnit configuration
Core Components
Routing System
The router handles all HTTP requests and directs them to appropriate controllers or callbacks.
Basic Routing:
use Mlangeni\Machinjiri\Core\Routing\Router; // Simple routes Router::get('/users', 'UserController@list'); Router::post('/users', 'UserController@store'); Router::put('/users/{id}', 'UserController@update'); Router::delete('/users/{id}', 'UserController@destroy'); Router::patch('/users/{id}', 'UserController@patch'); Router::any('/path', 'Controller@method'); // Named routes Router::get('/profile/{id}', 'UserController@show', 'user.profile'); // Route groups Router::group(['prefix' => '/api', 'middleware' => 'api'], function() { Router::get('/users', 'ApiUserController@list'); Router::post('/users', 'ApiUserController@store'); }); // AJAX routes Router::ajax('/api/data', 'ApiController@getData'); // Traditional routes Router::traditional('/contact', 'ContactController@show'); // Generate URLs $url = Router::route('user.profile', ['id' => 5]); $absoluteUrl = Router::absoluteRoute('user.profile', ['id' => 5]);
Middleware:
// Apply middleware to routes Router::group(['middleware' => 'auth'], function() { Router::get('/dashboard', 'DashboardController@index'); }); // Multiple middleware Router::group(['middleware' => ['auth', 'admin']], function() { Router::get('/admin', 'AdminController@dashboard'); }); // Middleware with parameters Router::group(['middleware' => 'role:admin'], function() { Router::delete('/users/{id}', 'UserController@destroy'); });
CORS Configuration:
Router::cors([ 'allowed_origins' => ['https://example.com'], 'allowed_methods' => ['GET', 'POST', 'OPTIONS'], 'allowed_headers' => ['Content-Type', 'Authorization'], ], function() { Router::get('/api/public', 'ApiController@public'); });
View Engine
Machinjiri provides a powerful templating engine with a clean, readable syntax.
Template Syntax:
<% if $user->isAdmin() %> <a href="/admin">Admin Panel</a> <% else %> <a href="/profile">My Profile</a> <% endif %> <% foreach $products as $product %> <div>{{ $product->name }} - {{ $product->price }}</div> <% endforeach %>
Layout Example:
<!-- resources/views/layouts/app.view.php --> <!DOCTYPE html> <html> <head> <title><%= $title ?? 'My App' %></title> <% include 'partials.stylesheets' %> </head> <body> <header> <% include 'partials.navbar' %> </header> <main> <% yield('content') %> </main> <footer> <% include 'partials.footer' %> </footer> <% include 'partials.scripts' %> </body> </html>
Usage in Controller:
use Mlangeni\Machinjiri\Core\Views\View; public function index($req, $res) { return View::make('home', [ 'title' => 'Home Page', 'featured' => $featured, ])->render(); // Or display directly View::make('home', ['title' => 'Home'])->display(); // Share data globally View::share('user', auth()->user()); }
Database & ORM
Machinjiri provides a powerful query builder and migration system for database operations.
Database Configuration:
// config/database.php return [ 'driver' => env('DB_CONNECTION', 'mysql'), 'host' => env('DB_HOST', 'localhost'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'database' => env('DB_DATABASE', 'machinjiri'), 'port' => env('DB_PORT', 3306), ];
Query Builder:
use Mlangeni\Machinjiri\Core\Database\Builders\QueryBuilder; // Simple queries $users = (new QueryBuilder('users'))->select()->get(); $user = (new QueryBuilder('users')) ->select() ->where('id', '=', 5) ->first(); // Complex queries $result = (new QueryBuilder('users')) ->select(['id', 'name', 'email']) ->where('active', '=', true) ->where('role', '=', 'admin') ->orderBy('name', 'asc') ->limit(10) ->get(); // Insert (new QueryBuilder('users'))->insert([ 'name' => 'John', 'email' => 'john@example.com', ]); // Update (new QueryBuilder('users')) ->where('id', '=', 5) ->update(['name' => 'Jane']); // Delete (new QueryBuilder('users'))->where('id', '=', 5)->delete(); // Aggregate functions $count = (new QueryBuilder('users'))->select()->count(); $max = (new QueryBuilder('posts'))->max('views');
Migrations:
# Create migration php artisan make:migration create_users_table # Run migrations php artisan migrate # Rollback php artisan migrate:rollback
// database/migrations/2024_01_01_000000_create_users_table.php class CreateUsersTable { public function up() { Schema::create('users', function($table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('users'); } }
Seeders:
php artisan make:seeder UserSeeder php artisan db:seed
Authentication & Security
Machinjiri provides comprehensive authentication and security features.
Session-Based Authentication:
// config/auth.php return [ 'guard' => 'web', 'providers' => [ 'users' => [ 'driver' => 'database', 'table' => 'users', ], ], ];
Login/Logout:
// In your controller public function login($req, $res) { $credentials = $req->only(['email', 'password']); if (auth()->attempt($credentials)) { return $res->redirect('/dashboard'); } return view('auth.login', ['error' => 'Invalid credentials']); } public function logout($req, $res) { auth()->logout(); return $res->redirect('/'); }
OAuth Integration:
use Mlangeni\Machinjiri\Core\Authentication\OAuth; $oauth = new OAuth($config); $token = $oauth->getAccessToken($code); $user = $oauth->getUserInfo($token);
Password Security:
use Mlangeni\Machinjiri\Core\Forms\Password; // Hash password $hashed = Password::hash('secret123'); // Verify password if (Password::verify('secret123', $hashed)) { // Password is correct }
CSRF Protection:
// Automatically handled in forms <form method="POST" action="/users"> <input type="hidden" name="_token" value="<%= csrf_token() %>"> <!-- form fields --> </form>
Encryption:
use Mlangeni\Machinjiri\Core\Security\Encryption\Cipher; $encrypter = new Cipher($key); $encrypted = $encrypter->encrypt($data); $decrypted = $encrypter->decrypt($encrypted);
LDAP
The LDAP component provides configured connections, escaped query filters, and LDAP entry objects. The PHP LDAP extension must be enabled before using it.
Register an LDAP manager:
// app/Providers/LdapServiceProvider.php namespace App\Providers; use Mlangeni\Machinjiri\Core\Components\LDAP\Manager as LdapManager; use Mlangeni\Machinjiri\Core\Container; use Mlangeni\Machinjiri\Core\Providers\ServiceProvider; class LdapServiceProvider extends ServiceProvider { public function register(): void { $this->app->singleton('ldap.manager', function (Container $app) { return new LdapManager([ 'default' => 'directory', 'connections' => [ 'directory' => [ 'hosts' => [env('LDAP_HOST', 'ldap.example.com')], 'port' => (int) env('LDAP_PORT', 389), 'base_dn' => env('LDAP_BASE_DN', 'dc=example,dc=com'), 'username' => env('LDAP_BIND_DN'), 'password' => env('LDAP_BIND_PASSWORD'), 'use_tls' => (bool) env('LDAP_USE_TLS', true), ], ], ]); }); } }
Add the provider to config/providers.php, then query the directory from a controller or service:
use Mlangeni\Machinjiri\Core\Components\LDAP\Manager as LdapManager; public function directoryUsers(LdapManager $ldap): array { return $ldap->connection()->query() ->where('objectClass', '=', 'inetOrgPerson') ->where('mail', 'contains', '@example.com') ->select(['uid', 'cn', 'mail']) ->sizeLimit(100) ->get(); } foreach (directoryUsers(resolve('ldap.manager')) as $entry) { echo $entry->getAttribute('cn'); echo $entry->getAttribute('mail'); echo $entry->getDn(); }
For LDAP-backed authentication, configure the guard with the ldap provider driver. The provider searches by uid and mail, synchronizes selected attributes to the local user model, and validates passwords by binding with the user DN:
// config/auth.php return [ 'default' => 'web', 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => [ 'driver' => 'ldap', 'model' => App\Models\User::class, 'username_attribute' => 'uid', 'search_fields' => ['uid', 'mail'], 'sync_attributes' => [ 'name' => 'cn', 'email' => 'mail', ], ], ], ], ];
Forms & Validation
Create and validate forms with ease.
Form Validation:
use Mlangeni\Machinjiri\Core\Forms\FormValidator; public function store($req, $res) { $validator = new FormValidator($req->all()); $validator->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|min:8|confirmed', ]); if ($validator->fails()) { return view('register', ['errors' => $validator->errors()]); } // Create user User::create($validator->validated()); }
Custom Rules:
$validator = new FormValidator($data); $validator->validate([ 'age' => [ 'required', 'integer', function($attribute, $value, $fail) { if ($value < 18) { $fail('Must be 18 or older'); } }, ], ]);
Queues & Jobs
Process background jobs asynchronously.
Create a Job:
php artisan make:job SendWelcomeEmail
// app/Jobs/SendWelcomeEmail.php namespace App\Jobs; use Mlangeni\Machinjiri\Core\Artisans\Contracts\JobInterface; class SendWelcomeEmail implements JobInterface { public $data; public function __construct($userId) { $this->data = ['user_id' => $userId]; } public function handle() { $user = User::find($this->data['user_id']); Mail::to($user->email)->send(new WelcomeEmail($user)); } }
Dispatch Job:
// In a controller or callback dispatch(new SendWelcomeEmail($user->id)); // Or queue for later dispatch(new SendWelcomeEmail($user->id))->onQueue('default');
Process Jobs:
php artisan queue:work
Task Scheduler
Scheduled tasks extend ScheduledTask, define a cron expression, and implement handle(). Register task classes with the task manager or use the generator to create and register one:
php artisan scheduler:create-task SendDailyReport --cron="0 9 * * *" --register
php artisan scheduler:list
php artisan scheduler:run
The scheduler persists task definitions and execution history, dispatches work to the scheduler queue, prevents overlapping runs by default, and supports task groups, priorities, retries, maintenance-mode behavior, and cached status data. Use scheduler:status, scheduler:stats, scheduler:enable, and scheduler:disable to operate it.
Webhooks
Configure provider subscriptions with their signing secret, verification method, event handlers, and whether processing should be synchronous or queued. Incoming requests are processed through WebhookManager:
$response = $webhookManager->process($payload);
Queued providers are dispatched to the webhooks queue and return an accepted response. Synchronous providers invoke all matching handlers and return the first failed response, or the final successful response. HMAC, timestamped HMAC, and custom signature callbacks are supported.
SMS
Configure one or more SMS transports and send through the manager. Delivery can be immediate or queued on the sms queue:
$response = $smsManager->send($message); $queuedResponse = $smsManager->send($message, true);
The manager returns a structured response, logs delivery failures, and supports custom transports through the transport registry.
Components
Create reusable UI components programmatically.
Available Components:
use Mlangeni\Machinjiri\Components\Alert; use Mlangeni\Machinjiri\Components\Button; use Mlangeni\Machinjiri\Components\Card; use Mlangeni\Machinjiri\Components\Form; use Mlangeni\Machinjiri\Components\Input; use Mlangeni\Machinjiri\Components\Modal; use Mlangeni\Machinjiri\Components\Nav; use Mlangeni\Machinjiri\Components\ProgressBar; // Alert component $alert = new Alert('Success!', 'success'); echo $alert->render(); // Button component $button = new Button('Click Me', 'btn-primary'); echo $button->render(); // Form component $form = new Form('POST', '/submit'); $form->addField('email', 'email'); $form->addField('password', 'password'); echo $form->render(); // Input component $input = new Input('email', 'user@example.com'); echo $input->render(); // Card component $card = new Card('Title', 'Content'); echo $card->render();
⚙️ Configuration
Environment Configuration
Configuration is managed through .env files and config classes:
# .env APP_NAME=Machinjiri APP_ENV=local APP_DEBUG=true APP_KEY=your-app-key-here DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=machinjiri DB_USERNAME=root DB_PASSWORD= MAIL_DRIVER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=465 MAIL_USERNAME=your-username MAIL_PASSWORD=your-password MAIL_FROM_ADDRESS=noreply@machinjiri.com
Application Configuration
// config/app.php return [ 'name' => env('APP_NAME', 'Machinjiri'), 'env' => env('APP_ENV', 'production'), 'debug' => env('APP_DEBUG', false), 'key' => env('APP_KEY'), 'timezone' => 'UTC', 'locale' => 'en', 'url' => env('APP_URL', 'http://localhost'), ];
Service Provider Configuration
// config/providers.php return [ 'providers' => [ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\RouteServiceProvider::class, ], 'aliases' => [ 'Router' => Mlangeni\Machinjiri\Core\Routing\Router::class, 'View' => Mlangeni\Machinjiri\Core\Views\View::class, ], ];
Mail Configuration
// config/mail.php return [ 'default' => env('MAIL_DRIVER', 'phpmailer'), 'transports' => [ 'phpmailer' => [ 'transport' => 'phpmailer', 'host' => env('MAIL_HOST', 'smtp.mailtrap.io'), 'port' => env('MAIL_PORT', 2525), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, 'auth_mode' => null, 'debug' => false, //debug mode for smtp 'from_address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), ], // Add other transports as needed ] ];
API Reference
Application Container
use Mlangeni\Machinjiri\Core\Machinjiri; // Get application instance $app = Machinjiri::getInstance(); // Bind service $app->bind('key', function($app) { return new Service(); }); // Resolve service $service = $app->resolve('key'); // Check environment $isProduction = Machinjiri::getEnvironment() === 'production'; $isDevelopment = Machinjiri::getEnvironment() === 'development'; // Get configuration $config = $app->config('app.timezone');
Router API
use Mlangeni\Machinjiri\Core\Routing\Router; // HTTP Methods Router::get($pattern, $handler, $name = null, $options = []); Router::post($pattern, $handler, $name = null, $options = []); Router::put($pattern, $handler, $name = null, $options = []); Router::delete($pattern, $handler, $name = null, $options = []); Router::patch($pattern, $handler, $name = null, $options = []); Router::any($pattern, $handler, $name = null, $options = []); Router::match($methods, $pattern, $handler, $name = null, $options = []); // Special Routes Router::ajax($pattern, $handler, $name = null, $options = []); Router::traditional($pattern, $handler, $name = null, $options = []); // Route Groups Router::group($attributes, $callback); // Middleware Router::middleware($middleware, $callback); // CORS Router::cors($config, $callback); // URL Generation Router::route($name, $parameters = []); Router::absoluteRoute($name, $parameters = []); // Dispatching Router::dispatch();
View API
use Mlangeni\Machinjiri\Core\Views\View; // Create and render View::make($view, $data = []); View::make($view, $data)->render(); View::make($view, $data)->display(); // Share data globally View::share($key, $value); // Template functions (in view files) <%= $variable %> // Output variable <% section('name') %>...<%endsection %> // Define section <% yield('name') %> // Output section <% extend('layout') %> // Extend layout <% include 'partial' %> // Include partial <% if($cond): %> ... <% endif; %> // Conditionals <% foreach($items as $item): %> ... <% endforeach; %>
Request API
// In route handler or controller public function handle($request, $response) { // Get data $all = $request->all(); $input = $request->input('name'); $only = $request->only(['email', 'password']); $except = $request->except(['password']); // Check methods $isPost = $request->isPost(); $isJson = $request->isJson(); $isAjax = $request->isAjax(); // Get headers $auth = $request->header('Authorization'); $headers = $request->headers(); // Files $file = $request->file('avatar'); $files = $request->files(); // Server info $method = $request->method(); $uri = $request->uri(); $path = $request->path(); }
Response API
// In route handler or controller public function handle($request, $response) { // Simple responses return "String response"; // JSON response return $response->json(['data' => $data]); // Redirect return $response->redirect('/home'); return $response->redirectBack(); // View response return view('page', ['data' => $data]); // File download return $response->download('/path/to/file'); // Set headers $response->header('X-Custom', 'value'); // Set status $response->status(201); // Cookies $response->cookie('name', 'value', 3600); }
Database API
use Mlangeni\Machinjiri\Core\Database\Builders\QueryBuilder; // Query builder $result = (new QueryBuilder('users')) ->select(['id', 'name', 'email']) ->where('active', true) ->whereIn('role', ['admin', 'moderator']) ->orderBy('name', 'asc') ->limit(10) ->get(); // Retrieve single $user = (new QueryBuilder('users'))->select()->where('id', 5)->first(); // Insert (new QueryBuilder('users'))->insert([ 'name' => 'John', 'email' => 'john@example.com', ]); // Update (new QueryBuilder('users')) ->where('id', 5) ->update(['name' => 'Jane']); // Delete (new QueryBuilder('users'))->where('id', 5)->delete(); // Aggregate $count = (new QueryBuilder('users'))->count(); $max = (new QueryBuilder('posts'))->max('views'); $avg = (new QueryBuilder('orders'))->select()->avg('amount'); // Exists $exists = (new QueryBuilder('users'))->where('email', $email)->exists();
Error Handling
Machinjiri provides comprehensive error handling with environment-aware output:
use Mlangeni\Machinjiri\Core\Exceptions\MachinjiriException; try { // Your code if (!$user) { throw new MachinjiriException('User not found', 404); } } catch (MachinjiriException $e) { // Access error details $message = $e->getMessage(); $code = $e->getCode(); // Display error (different in dev/prod) $e->show(); // Or handle manually return view('error', ['error' => $e->getMessage()]); }
Error Handler Features:
- Environment-specific error pages (development vs production)
- Automatic logging of uncaught exceptions
- User-friendly error messages in production
- Detailed stack traces in development
- HTTP status code mapping
- Custom error handlers per exception type
- Request and application context attached to error reports
- Configurable error reporting by email through the mail manager
- Error throttling to prevent repeated failures from overwhelming logs or notifications
- Error, exception, and shutdown handlers for runtime and fatal errors
- Custom exception renderers through
ErrorHandler::setExceptionRenderer()
Console Commands (Artisan)
Machinjiri includes an Artisan console for many development workflows. Common commands include:
# Server management php artisan run:dev # Start development server php artisan stop:dev # Stop development server # Database and migrations php artisan db:migration:create # Create a new migration file php artisan db:migration:list # List available migrations php artisan db:migration:migrate # Run migrations php artisan db:migration:rollback # Roll back the last batch of migrations php artisan db:seeder:create # Create a new seeder php artisan db:seeder:run # Run a seeder php artisan db:seeder:run-all # Run all seeders php artisan db:seeder:refresh # Refresh seeders php artisan db:factory:create # Create a new factory # Code generation php artisan make:controller Name # Create controller php artisan make:middleware Name # Create middleware php artisan make:job Name # Create job php artisan make:webhook Name # Create webhook scaffolding php artisan view:make Name # Create a view template php artisan provider:make Name # Create a service provider # Queue and worker management php artisan queue:init # Initialize queue resources php artisan queue:work # Process jobs php artisan queue:failed # List failed jobs php artisan queue:retry # Retry a failed job php artisan queue:clear # Clear queued jobs php artisan queue:status # Show queue status php artisan queue:health # Report queue health # Scheduled task management php artisan scheduler:create-task Name --register php artisan scheduler:list php artisan scheduler:run php artisan scheduler:status php artisan scheduler:enable ID php artisan scheduler:disable ID php artisan scheduler:stats [ID] php artisan scheduler:clean --days=30 php artisan scheduler:cache-preload php artisan scheduler:cache-clear # Utilities php artisan test # Run test suite php artisan get:env # Display environment variables php artisan config:cache # Cache configuration php artisan route:cache # Cache routes php artisan view:cache # Cache views
Testing
Run tests with PHPUnit:
# Run all tests composer test # Run specific test vendor/bin/phpunit tests/Unit/UserTest.php # Run with coverage vendor/bin/phpunit --coverage-html coverage
Example Test:
// tests/Unit/UserTest.php namespace Mlangeni\Machinjiri\Tests\Unit; use PHPUnit\Framework\TestCase; class UserTest extends TestCase { public function testUserCreation() { $user = User::create([ 'name' => 'John', 'email' => 'john@example.com', 'password' => password_hash('secret', PASSWORD_BCRYPT), ]); $this->assertIsNotNull($user->id); $this->assertEquals('John', $user->name); } }
Contributing
We welcome contributions! Here's how to get started:
-
Fork the Repository
git clone https://github.com/yourusername/machinjiri.git cd machinjiri -
Create a Feature Branch
git checkout -b feature/amazing-feature
-
Make Your Changes
- Follow PSR-12 coding standards
- Add tests for new features
- Update documentation
-
Commit and Push
git add . git commit -m 'Add amazing feature' git push origin feature/amazing-feature
-
Open a Pull Request
- Describe your changes clearly
- Reference any related issues
- Ensure tests pass
Development Setup
# Install dependencies composer install # Run tests composer test # Check code standards composer cs-check # Fix code standards composer cs-fix
License
This project is licensed under a proprietary license - see the LICENSE file for details.
Support
- GitHub Issues: Report bugs and request features
- Discussions: Ask questions and share ideas
- Email: precious.lyson@gmail.com
Authors
Acknowledgments
- Inspired by Laravel's elegant syntax and structure
- Built on modern PHP 8.3+ features
- Community contributions and feedback
Full Documentation:
Built with ❤️ by the Machinjiri Team
Made for developers, by developers.