mosamy / helpers
Most things I always need in any project
Requires
- php: >=8.1
- dev-master
- 3.0.2
- 3.0.1
- 3.0.0
- 2.8.0
- 2.7.8
- 2.7.7
- 2.7.6
- 2.7.5
- 2.7.4
- 2.7.3
- 2.7.2
- 2.7.1
- 2.7.0
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.1
- 2.5.0
- 2.4.3
- 2.4.2
- 2.4.1
- 2.3.1
- 2.3.0
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.2.2
- 1.2.1
- 1.1.1
- 1.1.0
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2026-04-03 21:04:15 UTC
README
A comprehensive Laravel package providing essential helper functions, traits, and utilities for rapid application development.
Table of Contents
- Installation
- Quick Start
- Query Scopes
- Helper Functions
- Response Functions
- Validation Rules
- Macros
- Resources
- Traits
- Configuration
- Contributing
- License
Installation
composer require mosamy/helpers
Publish configuration file (optional):
php artisan vendor:publish --provider="Mosamy\Helpers\HelpersServiceProvider" --tag="config"
Quick Start
Add the Scopes trait to any Eloquent model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Mosamy\Helpers\Traits\Scopes;
class Post extends Model
{
use Scopes;
}
Then use convenient query methods:
// Conditional where clauses with automatic request parameter detection
Post::whenWhere('status')->get();
Post::whenLike('title')->get();
Post::whenWhereDate('created_at')->get();
Query Scopes
Add the Scopes trait to your Eloquent models to access conditional query methods that automatically use request parameters:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Mosamy\Helpers\Traits\Scopes;
class Post extends Model
{
use Scopes;
}
Conditional Where Clauses
All scope methods accept optional parameters: column name, condition, and value. If not provided, they default to the request parameter matching the column name.
whenWhere($column, $condition = null, $value = null)
Apply a conditional WHERE clause:
// Uses request('status')
Post::whenWhere('status')->get();
// With custom value
Post::whenWhere('status', request('filter_status'))->get();
// With explicit condition and value
Post::whenWhere('status', true, 'active')->get();
whenWhereDate($column, $condition = null, $value = null)
Apply a conditional WHERE DATE clause:
Post::whenWhereDate('created_at')->get();
Post::whenWhereDate('published_at', request('date'))->get();
whenLike($column, $condition = null, $value = null)
Apply a conditional LIKE pattern search:
Post::whenLike('title')->get();
Post::whenLike('title', request('search'))->get();
whenNotLike($column, $condition = null, $value = null)
Apply a conditional NOT LIKE pattern search - opposite of whenLike().
whenWhereIn($column, $condition = null, $value = [])
Apply a conditional WHERE IN clause:
Post::whenWhereIn('status')->get();
Post::whenWhereIn('status', ['active', 'pending'])->get();
whenWhereNotIn($column, $condition = null, $value = [])
Apply a conditional WHERE NOT IN clause - opposite of whenWhereIn().
whenWhereRelation($relation, $column, $condition = null, $value = null)
Apply a conditional WHERE on a related model:
Post::whenWhereRelation('author', 'name')->get();
Post::whenWhereRelation('author', 'name', request('author_name'))->get();
whenWhereRelationIn($relation, $column, $condition = null, $value = [])
Apply a conditional WHERE IN on a related model:
Post::whenWhereRelationIn('category', 'id', ['tech', 'news'])->get();
search($keyword, $attributes = [])
Search across multiple attributes:
// Define searchable attributes in model
class Post extends Model
{
use Scopes;
protected static array $SearchableAttributes = ['title', 'content', 'tags'];
}
// Search by keyword
Post::search('laravel')->get();
// Search with custom attributes
Post::search('laravel', ['title', 'author'])->get();
findInSet($field, $keywords)
Search using MySQL FIND_IN_SET function (useful for comma-separated values):
Post::findInSet('tags', 'laravel')->get();
Post::findInSet('tags', ['laravel', 'php'])->get();
whenWhereBetween($column, $from = null, $to = null)
Apply a conditional WHERE BETWEEN clause:
Post::whenWhereBetween('price', 10, 100)->get();
fromTo($from = null, $to = null, $column = 'created_at', $datetime = true)
Apply a date range filter with optional date parsing:
Post::fromTo('2024-01-01', '2024-12-31')->get();
Post::fromTo('2024-01-01', '2024-12-31', 'published_at', true)->get();
Helper Functions
Standalone utility functions available globally.
String Functions
slug($string, $separator = '-')
Convert a string to a URL-friendly slug (supports Arabic characters):
slug('Hello World') // => 'hello-world'
slug('مرحبا بك') // => 'مرحبا-بك'
clean_content($string)
Remove HTML tags and clean up string content:
clean_content('<p>Hello World</p>') // => 'Hello World'
Array Functions
multi_array_search($array, $keyword)
Search for a keyword in a multi-dimensional array and return the key:
$data = [
'users' => ['john', 'jane', 'bob'],
'roles' => ['admin', 'user']
];
multi_array_search($data, 'jane') // => 'users'
URL Functions
url_with_params($path, $params = [])
Generate a URL with query parameters:
url_with_params('/posts', ['page' => 2, 'sort' => 'desc'])
// => 'http://example.com/posts?page=2&sort=desc'
url_by_guard($segment = null, $params = [], $guard = null)
Generate a URL based on guard configuration:
url_by_guard('dashboard', [], 'admin')
// => 'http://example.com/admin/dashboard'
lastSegment($index = 0)
Get the last segment(s) of the current request URL:
// URL: /posts/123/comments
lastSegment() // => 'comments'
lastSegment(1) // => '123'
Number Functions
number_sign($num)
Format a number with sign prefix (+/-):
number_sign(5) // => '+5'
number_sign(-3) // => '-3'
Boolean Functions
is_boolean($value)
Check if a value can be interpreted as boolean:
is_boolean('true') // => true
is_boolean('1') // => true
is_boolean(false) // => true
is_boolean('anything') // => false
is_true($value)
Check if a value is truthy:
is_true('yes') // => true
is_true(1) // => true
is_true('false') // => false
Media Functions
youtube($link, $return = 'url')
Extract video ID from YouTube URL or get embed/thumbnail URL:
youtube('https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'url')
// => 'https://www.youtube.com/embed/dQw4w9WgXcQ'
youtube('https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'thumbnail')
// => 'http://i3.ytimg.com/vi/dQw4w9WgXcQ/sddefault.jpg'
XML Functions
xmlToArray($xmlElement)
Convert XML element to associative array:
$xml = simplexml_load_string('<root><name>John</name></root>');
xmlToArray($xml) // => ['name' => ['_value' => 'John']]
Model Functions
withoutTrashed($modelName)
Get all records without soft-deleted items (cached with once()):
withoutTrashed('Post') // => Collection of all non-deleted posts
getAll($modelName)
Get all records from a model (cached with once()):
getAll('Category') // => Collection of all categories
Response Functions
Standardized API response helpers available globally.
throwSuccess($data = [], $message = 'Data have been processed successfully', $statusCode = 200)
Return a standardized success response:
throwSuccess(['user' => $user], 'User created', 201);
// => JSON: { "status": "success", "response": {...}, "message": "User created" }
throwFailure($message = '', $errors = [], $statusCode = 422)
Return a standardized failure response:
throwFailure('Validation failed', $validator->errors(), 422);
// => JSON: { "status": "failure", "message": "...", "errors": {...} }
validateRequest($request, $data)
Validate request data and throw failure response on validation error:
validateRequest($request, [
'email' => 'required|email',
'password' => 'required|min:8'
]);
withPagination($query, $resource = null)
Return paginated data with pagination metadata:
$posts = Post::paginate(15);
return withPagination($posts, 'PostResource');
// => { "data": [...], "pagination": { "total": 150, "per_page": 15, "current_page": 1 } }
withTranslations($query)
Include translations for multilingual models:
$posts = Post::with('translations')->paginate();
return withTranslations($posts);
withPaginateTranslation($query, $resource = null)
Combine pagination with translations:
$posts = Post::paginate();
return withPaginateTranslation($posts, 'PostResource');
Validation Rules
Custom validation rule classes for common validation scenarios.
Boolean
Validate that a field is a valid boolean value:
use Mosamy\Helpers\Rules\Boolean;
$validated = $request->validate([
'is_active' => ['required', new Boolean()],
]);
IsValidYoutube
Validate YouTube URL format:
use Mosamy\Helpers\Rules\IsValidYoutube;
$validated = $request->validate([
'video_url' => ['required', new IsValidYoutube()],
]);
ValidArrayKeys
Validate that an array has exact keys (no more, no less):
use Mosamy\Helpers\Rules\ValidArrayKeys;
$validated = $request->validate([
'metadata' => ['required', new ValidArrayKeys(['name', 'email', 'phone'])],
]);
// Will fail if extra or missing keys are found
Macros
Extended functionality added to Laravel classes via macros.
Request Macros
validatedExcept($except = [])
Get validated data excluding specific fields:
$data = $request->validatedExcept(['password', 'password_confirmation']);
validatedExceptWith($except = [], $with = [])
Get validated data excluding some fields and including specific ones:
$data = $request->validatedExceptWith(['password'], ['ip_address' => '192.168.1.1']);
String Macros
snakeToTitle($value)
Convert snake_case to Title Case:
Str::snakeToTitle('first_name') // => 'First Name'
Collection Macros
whenWhere($column, $when = null, $value = null)
Filter collection items conditionally:
$items = collect([...])->whenWhere('status', 'active');
sortKeysAs($order)
Sort collection keys in a specific order:
$data = collect(['b' => 2, 'a' => 1, 'c' => 3]);
$data->sortKeysAs(['a', 'b', 'c']); // => ['a' => 1, 'b' => 2, 'c' => 3]
rename($keys)
Rename collection keys. Works for both a flat associative collection and a collection of arrays:
// Flat associative collection
$data = collect(['first' => 'John', 'last' => 'Doe']);
$data->rename(['first' => 'firstName', 'last' => 'lastName']);
// => ['firstName' => 'John', 'lastName' => 'Doe']
// Collection of arrays
$rows = collect([
['first' => 'John', 'last' => 'Doe'],
['first' => 'Jane', 'last' => 'Smith'],
]);
$rows->rename(['first' => 'firstName', 'last' => 'lastName']);
// => [['firstName' => 'John', 'lastName' => 'Doe'], ...]
### Redirector Macros
#### `notify($title = null, $message = '', $type = 'success')`
Flash a notification and redirect:
redirect('/dashboard')->notify('Success', 'Post created successfully', 'success');
---
## Resources
Base resource classes for API responses.
### `Resource`
Extended JsonResource with collection-aware methods:
namespace App\Http\Resources;
use Mosamy\Helpers\Resources\Resource;
class PostResource extends Resource {
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'author' => $this->whenSingle($this->author_name),
'count' => $this->whenCollection($this->posts_count),
];
}
}
Methods:
- `whenSingle($value)`: Include value only when resource is a single item
- `whenCollection($value)`: Include value only when resource is a collection
### `Pagination`
Resource for pagination metadata:
use Mosamy\Helpers\Resources\Pagination;
$posts = Post::paginate(); return [
'data' => PostResource::collection($posts),
'pagination' => new Pagination($posts)
]; // => { "total": 100, "per_page": 15, "current_page": 1 }
---
## Traits
### `Scopes`
Query scopes for models (documented above in [Query Scopes](#query-scopes) section).
### `WithValidator`
Trait for validating data with automatic failure response:
class MyRequest extends FormRequest {
use WithValidator;
public function rules()
{
return ['email' => 'required|email'];
}
}
### `WithFilters`
Trait for Livewire components to manage filter query strings:
use Livewire\Component; use Mosamy\Helpers\Traits\WithFilters;
class PostList extends Component {
use WithFilters;
public array $filters = ['search' => ''];
public function render()
{
$posts = Post::search($this->filter('search'))->paginate();
return view('livewire.post-list', ['posts' => $posts]);
}
}
Methods:
- `setFilter($key, $value)`: Set a filter value
- `filter($key)`: Get a filter value
- `updatingFilters()`: Hook called when filters change
### `ComponentUtilities`
Utility methods for Livewire components:
use Livewire\Component; use Mosamy\Helpers\Traits\ComponentUtilities;
class PostForm extends Component {
use ComponentUtilities;
public function save()
{
$this->validateForm();
// Save logic...
$this->redirectWithSuccessTo('/posts');
}
public function deleteAttachment($mediaId)
{
$this->deleteMedia($mediaId);
}
}
Methods:
- `validateForm($form = null)`: Validate and handle scroll on error
- `resetErrors()`: Clear validation errors
- `deleteMedia($mediaId, $wireModal = null)`: Delete media from model
- `redirectWithSuccessTo($url)`: Redirect with success notification
- `redirectNotify($url, $notification)`: (Livewire event) Redirect with notification
- `navigate($url)`: (Livewire event) Navigate to URL
---
## Configuration
Publish the configuration file to customize:
php artisan vendor:publish --provider="Mosamy\Helpers\HelpersServiceProvider" --tag="config"
Configuration file location: `config/settings.php`
Available settings:
return [
'pagination' => 60, // Default pagination per page
'status' => ['active', 'inactive'], // Default status options
'languages' => ['en', 'ar'], // Supported languages
'fake_media_path' => env('FAKE_MEDIA_PATH'),
'seed_fake_data' => env('SEED_FAKE_DATA'),
'file_extentions_allowed' => [
'images' => ['jpg', 'jpeg', 'gif', 'png'],
'docs' => ['pdf', 'doc', 'docx', 'xlsx', 'xls', 'csv', 'txt', 'pptx', 'ppt'],
'compressed' => ['zip', 'zipx', 'tz', '7z', 'tar', 'rar'],
'audios' => ['mp3', 'mpeg', 'mpga'],
'videos' => ['mp4']
]
];
### Additional Utilities
#### `FakeMedia` Service
Generate sample media files for seeding:
use Mosamy\Helpers\Services\FakeMedia;
$media = FakeMedia::get(); $samples = $media->samples(5, 'images'); // Get 5 random images
#### `WithTrashedScope`
Global scope to include soft-deleted records:
use Mosamy\Helpers\Scopes\WithTrashedScope;
class Post extends Model {
protected static function booted()
{
static::addGlobalScope(new WithTrashedScope());
}
}
---
## Contributing
Contributions are welcome. When contributing, priority should be given to:
1. Adding PHPUnit test coverage
2. Type hints and PHPDoc improvements
3. New validation rules or helper utilities
4. Localization support for error messages
---
## License
MIT