mosamy/helpers

Most things I always need in any project

Maintainers

Package info

bitbucket.org/mohamedsamy_10/helpers

pkg:composer/mosamy/helpers

Statistics

Installs: 231

Dependents: 0

Suggesters: 0

3.0.2 2026-04-03 21:03 UTC

README

A comprehensive Laravel package providing essential helper functions, traits, and utilities for rapid application development.

Table of Contents

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&nbsp;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