teksite / extralaravel
A collection of reusable utilities, validation rules, middleware, Eloquent casts, traits, Artisan commands, helpers, and developer tools for Laravel applications.
Requires
- php: ^8.3
- laravel/framework: ^13.0
- morilog/jalali: ^3.5
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A collection of reusable utilities, helpers, casts, validation rules, traits, Artisan commands, route macros and Laravel developer tools.
ExtraLaravel is designed to provide commonly needed functionality for Laravel applications without introducing unnecessary dependencies or forcing a specific architecture.
Features
- Custom Eloquent Casts
- IP Address Cast
- Jalali Date Cast
- Slug Cast
- Custom Validation Rules
- Iranian National Code
- Mobile Number
- Strong Password
- No HTML
- Never Pass
- API Form Request with standardized JSON validation responses
- Phone Verification Trait
- Soft Delete / Trash Management Trait
- Custom Artisan Generator Commands
- Cache Cleanup Command
- Honeypot Middleware
- Recursive Blade Directive
- Useful Global Helpers
- Configurable package behavior
- Route macro for soft-deleted resources
Requirements
- PHP 8.2+
- Laravel 10+
- Laravel 11+
- Laravel 12+
The package is designed to work with modern Laravel applications.
Installation
Step 1: Install via Composer
Install the package through Composer:
composer require teksite/extralaravel
Step 2: Register the Service Provider
For Laravel > 9
Add the service provider to the bootstrap/providers.php file:
<?php return [ // Other providers Teksite\Extralaravel\ExtraLaravelServiceProvider::class, ];
For Laravel 5.x and Earlier
Add the service provider to the config/app.php file under the providers array:
'providers' => [ // Other Service Providers Teksite\Extralaravel\ExtraLaravelServiceProvider::class, ],
Note: Laravel 5.5 and above supports auto-discovery, so this step is not required for newer versions.
Configuration
Publish the package configuration:
php artisan vendor:publish --provider="Teksite\Extralaravel\ExtraLaravelServiceProvider"
Or publish a specific configuration group if you expose individual publish tags.
The package configuration can contain:
return [ 'honeypot' => [ 'enabled' => true, 'status' => 403, 'field_name' => env('HONEYPOT_FIELD_NAME', 'honeypot'), ], 'data_path' => '/app/data', ];
Eloquent Casts
IP Cast
The IpCast automatically uses the request IP address when no value is explicitly provided.
use Teksite\Extralaravel\Casts\IpCast; protected $casts = [ 'ip' => IpCast::class, ];
When creating a model:
$model->ip = null; $model->save();
The current request IP will be stored automatically.
You can also explicitly provide an IP:
$model->ip = '192.168.1.10';
Jalali Date Cast
JalaliDateCast provides automatic Jalali/Gregorian conversion based on the current application locale.
use Teksite\Extralaravel\Casts\JalaliDateCast; protected $casts = [ 'published_at' => JalaliDateCast::class, ];
When the application locale is:
app()->setLocale('fa');
the date is converted to Jalali when reading the model.
When saving a Jalali date, it can be converted back to Gregorian automatically.
The cast expects the following helper functions to be available:
dateToJalali()
dateToGregorian()
If these functions are unavailable, the original value is returned.
Slug Cast
The SlugCast automatically converts a value into a URL-friendly slug.
use Teksite\Extralaravel\Casts\SlugCast; protected $casts = [ 'slug' => SlugCast::class, ];
Example:
$post->slug = 'My Awesome Post'; $post->save();
The stored value becomes:
my-awesome-post
Enum Files
The package provides Enum files for various purposes, such as:
- Areas: Geographic regions
- Langs: Language settings
- Currencies: Currency formats
- LocalLangs: Localized language settings
- MobilePatterns: Mobile number formats
Validation Rules
Iranian National Code
Validate an Iranian National Code using:
use Teksite\Extralaravel\Rules\CodeMeliRule; $request->validate([ 'national_code' => [ 'required', new CodeMeliRule(), ], ]);
The rule validates the 10-digit Iranian national identification code and its check digit.
Mobile Number Rule
The MobileRule supports country-specific mobile number validation through the package's MobilePatterns enum.
Example:
use Teksite\Extralaravel\Rules\MobileRule; $request->validate([ 'mobile' => [ 'required', new MobileRule(), ], ]);
By default, Iran is used:
new MobileRule()
You can also specify a country:
new MobileRule('iran')
Or multiple countries:
new MobileRule([ 'iran', 'germany', ])
The exact supported countries depend on the available MobilePatterns enum values.
Password Rule
Validate password strength:
use Teksite\Extralaravel\Rules\PasswordRule; $request->validate([ 'password' => [ 'required', new PasswordRule(), ], ]);
The rule checks for:
- Lowercase characters
- Uppercase characters
- Numbers
- Special characters
- Minimum password length
No HTML Rule
Prevent HTML tags from being submitted:
use Teksite\Extralaravel\Rules\NoHtmlRule; $request->validate([ 'name' => [ 'required', new NoHtmlRule(), ], ]);
For example:
John Doe
is accepted, while:
<strong>John Doe</strong>
is rejected.
This rule is intended for validation. It should not be considered a replacement for output escaping or XSS protection.
Never Pass Rule
NeverPassRule is a rule that always fails validation.
use Teksite\Extralaravel\Rules\NeverPassRule; $request->validate([ 'field' => [ new NeverPassRule(), ], ]);
This can be useful for temporarily disabling fields or testing validation flows.
API Form Request
The package provides:
Teksite\Extralaravel\Http\ApiFormRequest
Instead of Laravel's default validation response, validation errors are returned as JSON.
Example:
namespace App\Http\Requests; use Teksite\Extralaravel\Http\ApiFormRequest; class StoreUserRequest extends ApiFormRequest { public function rules(): array { return [ 'name' => ['required', 'string'], 'email' => ['required', 'email'], ]; } }
A validation failure returns a response similar to:
{
"message": "Validation failed.",
"errors": {
"email": [
"The email field is required."
]
},
"status": 422,
"data": []
}
Authorization failures return:
{
"message": "Forbidden.",
"errors": {
"auth": [
"Forbidden You don't have permission"
]
},
"status": 403,
"data": []
}
Phone Verification
The MustVerifyPhone trait provides phone verification functionality similar to Laravel's email verification system.
Add the trait to your User model:
use Teksite\Extralaravel\Traits\MustVerifyPhone; class User extends Authenticatable { use MustVerifyPhone; // ... }
Your model must have:
phone
phone_verified_at
columns.
Check Phone Verification
$user->hasVerifiedPhone();
Returns:
true
or:
false
Mark Phone as Verified
$user->markPhoneAsVerified();
Mark Phone as Unverified
$user->markPhoneAsUnverified();
Get Phone for Verification
$user->getPhoneForVerification();
By default, the value of:
$user->phone
is returned.
Send Verification Notification
The model using this trait must implement:
public function sendPhoneVerificationNotification(): void { // Send SMS or verification notification }
This allows the package to remain independent of a specific SMS provider.
Trash / Soft Delete Management
The TrashMethods trait provides a reusable API for managing soft-deleted models.
Your model must use Laravel's:
Illuminate\Database\Eloquent\SoftDeletes
trait.
Example manager:
use Teksite\Extralaravel\Traits\TrashMethods; class UserTrashManager { use TrashMethods; protected function getModelClass(): string { return User::class; } }
Count Trashed Records
$manager->trashCount();
Get Trashed Records
$manager->getTrashes();
Custom pagination:
$manager->getTrashes( perPage: 50 );
Restore Records
Restore one record:
$manager->restoreOne(10);
Restore multiple records:
$manager->restore([10, 20, 30]);
Restore All
$manager->restoreAll();
Permanently Delete Records
Permanently delete one:
$manager->wipeOne(10);
Multiple records:
$manager->wipe([10, 20, 30]);
Permanently Delete Everything in Trash
$manager->wipeAll();
wipe()andwipeAll()use Laravel'sforceDelete()and permanently remove records.
Trash Resource Routes
ExtraLaravel provides a trashResource() route macro for creating standardized soft-delete routes.
Example:
use App\Http\Controllers\UserController; Route::trashResource( 'users', UserController::class );
This can generate routes for:
| Action | Method | URI |
|---|---|---|
| Index | GET | /users/trash |
| Reinstate | PATCH | /users/trash/{id} |
| Prune | DELETE | /users/trash/{id} |
| Restore | PATCH | /users/trash |
| Flush | DELETE | /users/trash |
The controller should provide the corresponding methods:
public function index() { // } public function reinstate($id) { // } public function prune($id) { // } public function restore() { // } public function flush() { // }
Route Middleware
Middleware can be supplied through the options array:
Route::trashResource( 'users', UserController::class, [ 'middleware' => ['auth'], ] );
Custom Prefix
Route::trashResource( 'users', UserController::class, [ 'prefix' => 'admin', ] );
Custom Route Name Prefix
Route::trashResource( 'users', UserController::class, [ 'as' => 'admin.users', ] );
Only Specific Actions
Route::trashResource( 'users', UserController::class, [ 'only' => [ 'index', 'restore', ], ] );
Exclude Actions
Route::trashResource( 'users', UserController::class, [ 'except' => [ 'flush', ], ] );
Artisan Commands
ExtraLaravel provides several custom Artisan commands.
API Request Generator
Create an API Form Request:
php artisan make:request-api StoreUserRequest
Example nested request:
php artisan make:request-api Admin/StoreUserRequest
The generated class extends:
Teksite\Extralaravel\Http\ApiFormRequest
Logic Generator
Create a Logic class:
php artisan make:logic UserLogic
Nested class:
php artisan make:logic User/UserLogic
Logic classes can be used for database queries and application-specific business/query logic.
Trash Controller Generator
Create a soft-delete controller:
php artisan make:controller-trash UserController
For an API controller:
php artisan make:controller-trash UserController --api
Cache Purge Command
ExtraLaravel provides:
php artisan cache:purge
The command can clean:
- Expired database cache
- Expired file cache
- Expired Sanctum tokens
Dry Run
To inspect what would be deleted without deleting anything:
php artisan cache:purge --dry-run
Force Production Execution
By default, destructive execution in production asks for confirmation.
To force execution:
php artisan cache:purge --force
Batch Size
Default batch size:
1000
Custom:
php artisan cache:purge --limit=500
Skip Database Cache
php artisan cache:purge --skip-database
Skip File Cache
php artisan cache:purge --skip-files
Skip Sanctum Tokens
php artisan cache:purge --skip-tokens
Custom Database Connection
php artisan cache:purge --connection=mysql
Honeypot Middleware
ExtraLaravel provides a simple honeypot middleware to detect automated form submissions.
Configuration:
'honeypot' => [ 'enabled' => true, 'status' => 403, 'field_name' => env( 'HONEYPOT_FIELD_NAME', 'honeypot' ), ],
Register the middleware in your application according to your Laravel version and apply it to the routes/forms you want to protect.
Example form field:
<input type="text" name="honeypot" tabindex="-1" autocomplete="off" >
The field should normally remain empty.
If a request submits a non-empty honeypot field, the middleware rejects the request.
Blade Recursive Directive
ExtraLaravel provides a recursive Blade directive.
Example:
@recursive($items, $item) {{ $item }} @endrecursive
It can be used for recursively rendering nested arrays or traversable data.
For arrays stored in variables that may need casting:
@recursive((array)$items, $item) {{ $item }} @endrecursive
Helper Functions
ExtraLaravel provides several global helper functions.
changeToSlug
Convert text to a slug:
changeToSlug('My Awesome Post');
Result:
my-awesome-post
Custom separator:
changeToSlug( 'My Awesome Post', '_' );
toEnglishNumber
Convert Persian and Arabic digits to English digits:
toEnglishNumber('۱۲۳۴۵');
Result:
12345
Arabic digits are also supported:
toEnglishNumber('١٢٣٤٥');
normalizePersianText
Normalize common Arabic characters to their Persian equivalents:
normalizePersianText('ي ك ة');
The helper also removes Arabic diacritics.
convertSeconds
Convert seconds to:
HH:MM:SS
Example:
convertSeconds(3661);
Result:
01:01:01
You can request an array:
convertSeconds( 3661, 'array' );
Result:
[
'hours' => 1,
'minutes' => 1,
'seconds' => 1,
]
currentUrlWithoutQueries
Get the current URL without query parameters:
currentUrlWithoutQueries();
exploding
Split a string using both English and Persian commas:
exploding('one,two،three');
Returns a Laravel Collection.
var_export_short
A shorter array representation of var_export():
var_export_short($data);
To return the generated string:
$output = var_export_short( $data, true );
arrayToDot
Convert Laravel-style array notation to dot notation:
arrayToDot('users[0][name]');
Result:
users.0.name
dotToArray
Convert dot notation to array-style notation:
dotToArray('users.0.name');
Result:
users][0][name]
normalizePath
Normalize filesystem paths:
normalizePath( 'foo/bar\\baz' );
is_rtl
Determine whether a language is RTL:
is_rtl('fa');
Result:
true
If no language is provided, the current application locale is used:
is_rtl();
get_error
Retrieve validation errors using array-style field names:
get_error( $errors, 'users[0][email]' );
getStaticData
Read static data from PHP files using dot notation.
Example directory:
app/
├── data/
│ └── times/
│ └── canada/
│ └── torentu.php
If tehran.php contains:
<?php return [ 'timezone' => 'Asia/Tehran', ];
You can retrieve it using:
getStaticData( 'app.data.times.iran.tehran.timezone' );
Result:
Asia/Tehran
A default value can be provided:
getStaticData( 'app.data.unknown', 'default value' );
Suggested Project Structure
A typical application using ExtraLaravel can organize its code as:
app/
├── Http/
│ ├── Controllers/
│ └── Requests/
│
├── Logics/
│
├── Models/
│
└── ...
Generated classes can then follow a predictable structure:
app/
├── Http/
│ ├── Controllers/
│ │ └── UserController.php
│ │
│ └── Requests/
│ └── StoreUserRequest.php
│
└── Logics/
└── UserLogic.php
Design Philosophy
ExtraLaravel intentionally focuses on small, reusable Laravel components rather than providing a large framework on top of Laravel.
The package follows several principles:
- Prefer Laravel's native functionality where possible.
- Keep utilities independent from application-specific business logic.
- Avoid unnecessary dependencies.
- Make functionality configurable.
- Provide reusable Artisan generators.
- Keep API responses predictable.
- Keep validation rules independent and composable.
- Support Persian/Jalali-oriented Laravel applications without forcing them on other applications.
Security Notes
ExtraLaravel does not replace Laravel's built-in security mechanisms.
In particular:
- Always use Laravel's authorization system.
- Always escape user-controlled output.
- Do not rely on
NoHtmlRuleas your only XSS protection. - Validate and sanitize uploaded files independently.
- Protect destructive commands in production.
- Restrict trash management routes using proper authentication and authorization.
- Do not expose permanent-delete endpoints without authorization.
- Configure honeypot fields correctly.
Contributing
Contributions are welcome.
Before submitting a pull request:
- Write or update tests.
- Follow Laravel coding conventions.
- Run the test suite.
- Run static analysis if configured.
- Run the code formatter.
- Keep changes focused and backwards compatible where possible.
License
This package is open-sourced software licensed under the MIT license.
See the LICENSE file for more information.
Roadmap
Possible future additions:
- More Laravel-specific validation rules
- Additional Eloquent casts
- More reusable traits
- Additional Artisan generators
- Improved API response helpers
- More storage utilities
- Queue-related utilities
- Additional Persian/Jalali helpers
- Expanded automated test coverage
Author
Developed by Sina Zangiband.
Contact
- Website:
- Email: sina.zangiband@gmail.com