batteryincluded/batteryincluded-bundle
Installation
composer require batteryincluded/batteryincluded-bundle
Add to config/app.php under providers:
BatteryIncluded\Bundle\BatteryIncludedBundleServiceProvider::class,
Publish the config (if needed):
php artisan vendor:publish --provider="BatteryIncluded\Bundle\BatteryIncludedBundleServiceProvider"
First Use Case Register a basic "battery" (e.g., a feature flag or module) via a service provider:
use BatteryIncluded\Bundle\Contracts\Battery;
public function register()
{
$this->app->singleton('my-battery', function ($app) {
return new class implements Battery {
public function isActive(): bool { return true; }
public function getName(): string { return 'My Feature'; }
};
});
}
Check Battery Status
Inject the BatteryManager into a controller or service:
use BatteryIncluded\Bundle\Services\BatteryManager;
public function __construct(private BatteryManager $batteryManager) {}
public function index()
{
if ($this->batteryManager->isActive('my-battery')) {
return 'Feature is ON!';
}
return 'Feature is OFF.';
}
Workflow:
FeatureFlagsServiceProvider).BatteryManager to toggle features dynamically:
$this->batteryManager->setActive('analytics', false); // Disable via config/DB
public function dashboard()
{
$this->middleware('battery:analytics')->only(['dashboard']);
}
Integration Tips:
batteries table and hydrate via a BatteryRepository..env:
BATTERY_INCLUDED_ENABLED_BATTERIES=analytics,notifications
BatteryActivated/BatteryDeactivated events to trigger side effects (e.g., cache invalidation).Mocking Batteries:
$batteryManager->shouldReceive('isActive')
->with('my-battery')
->andReturn(false);
Circular Dependencies:
Avoid injecting BatteryManager into the service provider registering batteries. Use the container directly instead.
// ❌ Anti-pattern
$this->app->singleton('battery', function ($app) {
return new MyBattery($app->make(BatteryManager::class)); // Circular!
});
// ✅ Fix: Pass dependencies via constructor.
Missing getName():
Batteries must implement getName(). Omitting this throws a RuntimeException at runtime.
Configuration Overrides:
Published config (config/batteryincluded.php) is merged with defaults. Ensure your overrides use the correct key structure:
'batteries' => [
'analytics' => [
'enabled' => env('BATTERY_ANALYTICS_ENABLED', true),
],
],
Log Battery States:
Enable debug mode in config/batteryincluded.php:
'debug' => env('APP_DEBUG', false),
Logs battery checks to storage/logs/laravel.log.
Check Active Batteries:
php artisan battery:list
Custom Storage:
Implement BatteryIncluded\Bundle\Contracts\BatteryRepository to persist states to Redis, DynamoDB, etc.
Middleware:
Extend BatteryMiddleware to add custom logic (e.g., rate-limiting for disabled features):
public function handle($request, Closure $next)
{
if (!$this->batteryManager->isActive('api-limit')) {
return response('Rate limit exceeded.', 429);
}
return $next($request);
}
Battery Events: Dispatch events when batteries change state:
event(new BatteryActivated('notifications'));
How can I help you explore Laravel packages today?