20steps/commons-ensure-bundle
Installation:
composer require 20steps/commons-ensure-bundle
Add the bundle to config/bundles.php (Symfony) or register the service provider in config/app.php (Laravel):
'providers' => [
// ...
Twentysteps\Commons\EnsureBundle\TwentystepsCommonsEnsureBundle::class,
],
First Use Case: Validate input early in a controller or service method:
use Twentysteps\Commons\Ensure\Ensure;
public function update(Request $request, $id)
{
Ensure::state($request->has('name'), 'Name is required.');
Ensure::state($id > 0, 'ID must be positive.');
// Proceed with logic...
}
Ensure::state(), Ensure::notNull(), Ensure::true(), and Ensure::false() in the source.EnsureException for error handling (e.g., logging, custom responses).TwentystepsCommonsEnsureBundle for service registration.Input Validation:
// Validate request data
Ensure::state($request->filled('email'), 'Email is required.');
Ensure::state(filter_var($request->email, FILTER_VALIDATE_EMAIL), 'Invalid email.');
Pre-Conditions in Services:
public function processOrder(Order $order)
{
Ensure::state($order->isPaid(), 'Order must be paid before processing.');
Ensure::state($order->hasItems(), 'Order must contain items.');
// Process...
}
Post-Conditions:
public function deleteUser(User $user)
{
$deleted = $user->delete();
Ensure::state($deleted, 'Failed to delete user.');
}
Custom Assertions:
Ensure::state(
strlen($password) >= 8,
'Password must be at least 8 characters.'
);
Early Failure: Use in constructors or method entry points to fail fast.
Logging: Wrap Ensure calls in try-catch to log EnsureException details:
try {
Ensure::state($condition, 'Error message.');
} catch (EnsureException $e) {
\Log::error($e->getMessage());
abort(400, $e->getMessage());
}
API Responses: Return JSON errors for API endpoints:
catch (EnsureException $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
Laravel Form Requests: Combine with Laravel’s FormRequest validation for layered checks:
public function rules()
{
return ['email' => 'required|email'];
}
public function withValidator($validator)
{
Ensure::state($validator->passes(), 'Validation failed.');
}
Dependency Injection: Inject Ensure as a service (if extended):
public function __construct(private Ensure $ensure) {}
Testing: Use EnsureException in unit tests to verify pre-conditions:
$this->expectException(EnsureException::class);
$this->expectExceptionMessage('ID must be positive.');
$service->process(-1);
Always-On Assertions:
Unlike PHP’s assert(), these checks never disable. Avoid using them for non-critical logic (e.g., performance-sensitive paths).
Exception Handling:
EnsureException will terminate execution. Always wrap in try-catch for APIs or CLI.Ensure::state($user->exists(), 'User not found.');
Performance:
Ensure calls can slow down validation. Offload to lighter checks where possible.Outdated Package:
Stack Traces: EnsureException includes the failing condition and message. Use for debugging:
catch (EnsureException $e) {
\Log::debug('Failed condition: ' . $e->getCondition());
}
Custom Exceptions: Extend EnsureException for domain-specific errors:
class ValidationException extends EnsureException {}
Ensure::state($condition, 'Error.', new ValidationException());
Consistent Messaging: Use consistent error formats (e.g., "Field {field} is required.") for API responses.
Localization:
Store messages in language files (e.g., Laravel’s resources/lang) and pass them dynamically:
Ensure::state($condition, __('validation.required', ['field' => 'email']));
Combine with Laravel:
Ensure for business logic and Laravel’s validator for input sanitization.$validator = Validator::make($request->all(), ['email' => 'required|email']);
Ensure::state($validator->passes(), 'Invalid input.');
Extending the Bundle:
Ensure by extending the class:
class CustomEnsure extends Ensure {
public static function isActive(User $user) {
self::state($user->active, 'User must be active.');
}
}
AppServiceProvider:
$this->app->bind(Ensure::class, function () {
return new CustomEnsure();
});
Testing Edge Cases:
Ensure with null, false, and edge values (e.g., 0, empty strings) to ensure robust validation.How can I help you explore Laravel packages today?