jaikumar0101/laravel-inputbag
Fluent builder to standardize Laravel request inputs for search, pagination, and sorting. Provides sensible defaults, configurable global settings, and custom field mappings so controllers stay clean and API responses remain consistent (array or collection output).
Installation:
composer require jaikumar0101/laravel-inputbag
No additional configuration is required for basic usage.
First Use Case: In a controller, replace raw request handling with the fluent builder:
use Jaikumar0101\InputBag\Request\InputBag;
public function index(Request $request)
{
$inputs = InputBag::make($request)
->search('q', 'query') // Search field mapping
->paginate(10) // Default pagination
->sort('created_at', 'desc'); // Default sorting
return YourModel::query()
->when($inputs->search, fn($q) => $q->where('name', 'like', "%{$inputs->search}%"))
->when($inputs->sort, fn($q) => $q->orderBy($inputs->sort->field, $inputs->sort->direction))
->paginate($inputs->paginate);
}
Where to Look First:
InputBag::make($request): Entry point for building input rules.config/inputbag.php: Defaults and custom field mappings (published via php artisan vendor:publish --provider="Jaikumar0101\InputBag\InputBagServiceProvider").InputBag class methods: Search, paginate, sort, and custom field mappings.Standardized Search Handling:
$inputs = InputBag::make($request)
->search('user_query', 'user_search') // Map request field to internal key
->search('advanced_query', 'advanced_search', fn($val) => strtolower($val)); // Custom transformation
when() in queries:
$query->when($inputs->search, fn($q, $search) => $q->where('name', 'like', "%{$search}%"));
Pagination:
$inputs = InputBag::make($request)
->paginate(20, 'per_page') // Custom request field for pagination
->maxPaginate(100); // Enforce max limit
YourModel::paginate($inputs->paginate);
Sorting:
$inputs = InputBag::make($request)
->sort('date', 'desc') // Default sort
->sortableFields(['name', 'created_at', 'updated_at']); // Whitelist fields
$query->when($inputs->sort, fn($q) => $q->orderBy($inputs->sort->field, $inputs->sort->direction));
Custom Fields:
$inputs = InputBag::make($request)
->field('status', 'active') // Map request field to internal key
->field('filter', 'premium', fn($val) => in_array($val, ['basic', 'premium'])); // Validation/transformation
$inputs->status or $inputs->filter.Chaining and Reusability: Create a base controller or trait to standardize input handling:
trait HandlesInputBag
{
protected function buildInputs(Request $request): InputBag
{
return InputBag::make($request)
->search('q', 'query')
->paginate(15)
->sort('id', 'desc')
->sortableFields(['name', 'id', 'created_at']);
}
}
API Resources: Return standardized input metadata in responses:
return response()->json([
'data' => YourModel::paginate($inputs->paginate),
'meta' => [
'search' => $inputs->search,
'sort' => $inputs->sort,
'pagination' => $inputs->paginate,
],
]);
Form Requests:
Combine with Laravel’s FormRequest for validation:
public function rules()
{
return [
'q' => 'nullable|string|max:255',
'per_page' => 'nullable|integer|min:1|max:100',
];
}
Dynamic Config: Override defaults per route/controller:
$inputs = InputBag::make($request)
->config(['paginate.default' => 50, 'sort.default' => 'name']);
Field Name Collisions:
sort) conflicts with an InputBag method, use custom mappings:
$inputs = InputBag::make($request)
->field('custom_sort', 'sort'); // Rename to avoid conflict
Sorting Security:
$inputs->sortableFields(['name', 'created_at']);
sort direction (e.g., asc/desc) in FormRequest or manually:
$inputs->sort->direction = strtolower($inputs->sort->direction) === 'asc' ? 'asc' : 'desc';
Pagination Edge Cases:
paginate() values are integers:
$inputs->paginate = (int) $inputs->paginate;
null or invalid values gracefully:
$limit = $inputs->paginate ?? 15;
Case Sensitivity:
$inputs->field('UserQuery', 'query', fn($val) => strtolower($val));
dd($inputs->all()); // Returns array of all processed fields
dd($inputs->request->all()); // Fallback to raw request if needed
Published Config:
php artisan vendor:publish --provider="Jaikumar0101\InputBag\InputBagServiceProvider" --tag="inputbag-config"
config/inputbag.php:
'defaults' => [
'paginate' => 15,
'sort' => [
'field' => 'created_at',
'direction' => 'desc',
],
],
'fields' => [
'search' => 'q',
'status' => 'active',
],
Dynamic Overrides:
$inputs = InputBag::make($request)
->config(['paginate.default' => 100]);
Custom Transformers:
$inputs->field('price_range', 'range', fn($val) => explode('-', $val));
Validation Integration:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($inputs->all(), [
'query' => 'sometimes|string|max:100',
'per_page' => 'sometimes|integer|between:1,100',
]);
Event Hooks:
// Hypothetical event (check package docs)
InputBag::listen('processed', fn($inputs) => Log::info('Inputs processed', $inputs->all()));
Testing:
InputBag in tests:
$inputs = InputBag::make($request)
->search('test_query', 'query')
->paginate(1);
$this->assertEquals('test_query', $inputs->search);
How can I help you explore Laravel packages today?