Installation:
composer require awaresoft/maintenance-bundle
Ensure your composer.json includes the package under require.
Enable the Bundle:
Add to config/bundles.php:
return [
// ...
Awaresoft\MaintenanceBundle\AwaresoftMaintenanceBundle::class => ['all' => true],
];
Basic Configuration:
Override lexik_maintenance.yaml (or create it) in config/packages/awaresoft_maintenance.yaml:
awaresoft_maintenance:
enabled: true
allow_access: ['127.0.0.1', '192.168.1.100'] # Whitelist IPs
ip_key: 'AWARESOFT_MAINTENANCE_IP' # Optional: Custom env var for IP storage
First Use Case: Trigger maintenance mode via CLI:
php bin/console awaresoft:maintenance:enable
Disable with:
php bin/console awaresoft:maintenance:disable
Conditional Maintenance: Use environment variables to toggle maintenance dynamically:
# config/packages/awaresoft_maintenance.yaml
awaresoft_maintenance:
enabled: '%env(bool:AWARESOFT_MAINTENANCE_ENABLED)%'
Custom Routes/Exceptions:
Extend the bundle’s MaintenanceController to add custom logic:
// src/Controller/CustomMaintenanceController.php
namespace App\Controller;
use Awaresoft\MaintenanceBundle\Controller\MaintenanceController;
use Symfony\Component\HttpFoundation\Response;
class CustomMaintenanceController extends MaintenanceController {
public function customPageAction(): Response {
return $this->render('maintenance/custom.html.twig');
}
}
Update routing (config/routes.yaml):
awaresoft_maintenance_custom:
path: /custom-maintenance
controller: App\Controller\CustomMaintenanceController::customPageAction
Database-Driven Control:
Store maintenance state in a custom table (e.g., maintenance_logs) and hook into MaintenanceListener:
// src/EventListener/MaintenanceLogger.php
namespace App\EventListener;
use Awaresoft\MaintenanceBundle\Event\MaintenanceEvent;
use Doctrine\ORM\EntityManagerInterface;
class MaintenanceLogger {
public function __construct(private EntityManagerInterface $em) {}
public function onMaintenanceChange(MaintenanceEvent $event): void {
$this->em->persist(new MaintenanceLog($event->isEnabled()));
$this->em->flush();
}
}
Register in services.yaml:
services:
App\EventListener\MaintenanceLogger:
tags:
- { name: kernel.event_listener, event: awaresoft.maintenance.change, method: onMaintenanceChange }
API-Specific Rules:
Exclude API routes from maintenance checks by overriding the MaintenanceChecker:
// src/Checker/CustomMaintenanceChecker.php
namespace App\Checker;
use Awaresoft\MaintenanceBundle\Checker\MaintenanceChecker;
use Symfony\Component\HttpFoundation\Request;
class CustomMaintenanceChecker extends MaintenanceChecker {
protected function isMaintenanceRequest(Request $request): bool {
return $request->isXmlHttpRequest() || parent::isMaintenanceRequest($request);
}
}
Update services.yaml:
services:
Awaresoft\MaintenanceBundle\Checker\MaintenanceChecker:
class: App\Checker\CustomMaintenanceChecker
Lexik Bundle Dependency:
lexik/maintenance-bundle. Ensure compatibility by checking:
composer why-not lexik/maintenance-bundle 2.0
awaresoft_maintenance settings.Caching Issues:
php bin/console cache:clear
X-Symfony-Debug-Token) are respected.IP Whitelisting:
allow_access config uses exact IP matches. For CIDR ranges, extend the IpChecker:
// src/Checker/CidrIpChecker.php
use Awaresoft\MaintenanceBundle\Checker\IpChecker;
use Symfony\Component\HttpFoundation\Request;
class CidrIpChecker extends IpChecker {
protected function isAllowedIp(Request $request): bool {
return in_array($request->getClientIp(), ['192.168.1.0/24']) || parent::isAllowedIp($request);
}
}
Environment-Specific Config:
config/packages/dev/awaresoft_maintenance.yaml):
awaresoft_maintenance:
enabled: false # Disable in dev
Check Maintenance Status:
php bin/console debug:config awaresoft_maintenance
Outputs current settings (e.g., enabled, allow_access).
Log IP Bypass Attempts: Add a listener to log blocked requests:
// src/EventListener/MaintenanceLogger.php
use Awaresoft\MaintenanceBundle\Event\MaintenanceEvent;
use Psr\Log\LoggerInterface;
class MaintenanceLogger {
public function __construct(private LoggerInterface $logger) {}
public function onMaintenanceBlocked(MaintenanceEvent $event): void {
$this->logger->warning('Maintenance blocked IP: ' . $event->getRequest()->getClientIp());
}
}
Register in services.yaml:
services:
App\EventListener\MaintenanceLogger:
tags:
- { name: kernel.event_listener, event: awaresoft.maintenance.blocked, method: onMaintenanceBlocked }
Custom Templates:
Override Twig templates in templates/bundles/awaresoftmaintenance/:
templates/
└── bundles/
└── awaresoftmaintenance/
├── maintenance.html.twig # Customize HTML
└── maintenance.txt.twig # Customize text version
Pre/Post Maintenance Hooks: Use events to run logic before/after mode changes:
# services.yaml
services:
App\Command\CustomMaintenanceCommand:
tags:
- { name: kernel.event_listener, event: awaresoft.maintenance.pre_enable, method: onPreEnable }
- { name: kernel.event_listener, event: awaresoft.maintenance.post_disable, method: onPostDisable }
Multi-Tenant Support:
Extend MaintenanceChecker to support tenant-specific rules:
class TenantAwareMaintenanceChecker extends MaintenanceChecker {
public function isMaintenanceRequest(Request $request): bool {
$tenant = $request->attributes->get('tenant');
return $this->isMaintenanceEnabled() && !$this->isTenantAllowed($tenant);
}
private function isTenantAllowed(string $tenant): bool {
return in_array($tenant, ['admin', 'premium']);
}
}
How can I help you explore Laravel packages today?