Artisan Generator
Create specifications with php artisan make:specification - includes domain organization, model binding, and multiple template types
Transform messy business logic into clean, testable, maintainable code using the Specification Pattern
public function searchProducts(Request $request)
{
$query = Product::query();
if ($request->category) {
if (is_array($request->category)) {
$query->whereIn('category_id', $request->category);
} else {
$query->where('category_id', $request->category);
}
}
if ($request->min_price || $request->max_price) {
if ($request->sale_only) {
$query->where(function($q) use ($request) {
if ($request->min_price) {
$q->where('sale_price', '>=', $request->min_price * 100);
}
if ($request->max_price) {
$q->where('sale_price', '<=', $request->max_price * 100);
}
})->whereNotNull('sale_price');
} else {
$query->where(function($q) use ($request) {
if ($request->min_price) {
$q->where(function($subQ) use ($request) {
$subQ->where('sale_price', '>=', $request->min_price * 100)
->orWhere(function($orQ) use ($request) {
$orQ->whereNull('sale_price')
->where('price', '>=', $request->min_price * 100);
});
});
}
if ($request->max_price) {
// ... 50 more lines of conditional hell
}
});
}
}
// Rating, availability, brand filtering nightmare continues...
// ... another 100+ lines of nested conditions
return $query->paginate();
}
public function searchProducts(ProductSearchRequest $request)
{
$spec = ProductSearchSpecification::fromRequest($request);
return Product::whereSpecification($spec)->paginate();
}
Generated with:
php artisan make:specification Product/ProductSearchSpecification --composite --cacheable
Individual specifications are clean, testable, and reusable:
// php artisan make:specification Product/PriceRangeSpecification --model=Product
// php artisan make:specification Product/CategorySpecification --model=Product
// php artisan make:specification Product/InStockSpecification --model=Product
Transform Complex Logic Into Simple Rules
Reduce hundreds of lines of conditional logic down to clean, composable specifications. Make your business rules readable and maintainable for developers at any experience level.
Generate Specifications in Seconds
Use powerful Artisan generators to scaffold domain-organized specifications instantly. Keep your codebase clean and consistent with automated boilerplate generation.
Bring Elegance to Business Logic
Finally make your business rules as elegant as the rest of your Laravel application. The specification pattern integrates seamlessly with Laravel's philosophy and conventions.
Transform complex product search logic into clean, composable specifications
$spec = ProductSearchSpecification::create()
->withPriceRange($minPrice, $maxPrice)
->withCategories($categories)
->onlyInStock()
->build();
Clean up authorization logic with testable specifications
$canAccess = UserAccessSpecification::for($user, $resource)
->isSatisfiedBy(['user' => $user, 'resource' => $resource]);
Replace conditional hell with composable report filters
$reportData = Sale::whereSpecification(
SalesReportSpecification::fromRequest($request)
)->get();
Implement complex content rules with readable specifications
$shouldApprove = ContentModerationSpecification::create()
->allowedForUser($user)
->meetsSafetyGuidelines()
->withinRateLimit()
->isSatisfiedBy($content);