campanda/commons-ensure-bundle
Installation:
composer require campanda/commons-ensure-bundle
Add to config/bundles.php (Symfony) or ensure autoloading is configured in composer.json:
"autoload": {
"psr-4": {
"campanda\\Commons\\EnsureBundle\\": "vendor/campanda/commons-ensure-bundle"
}
}
First Use Case: Validate input in a controller or service method:
use campanda\Commons\EnsureBundle\Ensure;
public function update(Request $request, $id) {
$name = $request->input('name');
Ensure::isNotEmpty($name, 'Name cannot be empty');
// Proceed with logic...
}
Key Classes:
Ensure: Static facade for assertions.EnsureException: Thrown on failed checks (extends \RuntimeException).Input Validation:
// Validate required fields
Ensure::isNotEmpty($userInput, 'Field "%s" is required', $fieldName);
Ensure::isTrue($isValid, 'Invalid %s provided', $fieldName);
// Validate ranges
Ensure::isGreaterThan(0, $age, 'Age must be positive');
Ensure::isLessThan(120, $age, 'Age must be realistic');
Pre-Conditions in Methods:
public function processOrder(Order $order) {
Ensure::isInstanceOf($order, Order::class, 'Order must be an instance of Order');
Ensure::isTrue($order->isValid(), 'Order is not valid for processing');
// Process...
}
Post-Conditions:
public function save(): bool {
$result = $this->repository->save();
Ensure::isTrue($result, 'Failed to save entity');
return true;
}
Collection Checks:
Ensure::isNotEmpty($items, 'No items provided');
Ensure::isArray($items, 'Items must be an array');
Ensure::isTrue(count($items) <= 100, 'Max 100 items allowed');
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
Ensure::isTrue(isset($data['required_field']), 'Required field missing');
});
}
abstract class ApiController extends Controller {
protected function validateRequest(array $rules) {
foreach ($rules as $field => $message) {
Ensure::isNotEmpty(request($field), $message);
}
}
}
public function transfer(Account $from, Account $to, float $amount) {
Ensure::isTrue($from->hasSufficientFunds($amount), 'Insufficient funds');
// Transfer logic...
}
Performance Overhead:
Ensure::isNotEmpty($users); // Do this once, not per loop iteration
foreach ($users as $user) { ... }
Message Formatting:
sprintf-style placeholders carefully. Malformed messages may cause errors:
// ❌ Avoid unmatched placeholders
Ensure::isTrue($valid, 'User %s is invalid', $user->name); // Throws if $valid is true
Ensure::isTrue($valid, 'User "%s" is invalid', $user->name);
Exception Handling:
EnsureException extends \RuntimeException. Handle globally if needed:
// In AppServiceProvider@boot()
app()->error(function (EnsureException $e, $request) {
return response()->json(['error' => $e->getMessage()], 400);
});
Legacy Code:
Stack Traces:
Ensure::isTrue($condition, 'Failed at step "%s" with data: %s', $step, json_encode($data));
Logging:
try {
Ensure::isTrue($condition, 'Critical check failed');
} catch (EnsureException $e) {
\Log::error($e->getMessage(), ['trace' => $e->getTraceAsString()]);
throw $e;
}
Testing:
Ensure in unit tests to simulate failures:
$this->partialMock(Ensure::class, 'isTrue')
->method('isTrue')
->with($this->equalTo(false), $this->anything())
->willThrowException(new EnsureException('Test failure'));
Custom Assertions:
class CustomEnsure extends Ensure {
public static function isValidEmail(string $email): void {
Ensure::isNotEmpty($email, 'Email cannot be empty');
Ensure::isTrue(filter_var($email, FILTER_VALIDATE_EMAIL), 'Invalid email format');
}
}
Global Configuration:
Ensure class in Laravel’s service container:
$this->app->bind(Ensure::class, function () {
return new CustomEnsure();
});
Localization:
Ensure::isNotEmpty($name, __('validation.required', ['attribute' => 'name']));
How can I help you explore Laravel packages today?