├── .gitignore ├── .gitattributes ├── ArtgrisMaintenanceBundle.php ├── Resources ├── config │ └── services.yml └── views │ └── maintenance.html.twig ├── Tests └── MaintenanceTest.php ├── composer.json ├── .php_cs ├── DependencyInjection ├── ArtgrisMaintenanceExtension.php └── Configuration.php ├── README.md ├── EventListener └── MaintenanceListener.php └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html linguist-vendored -------------------------------------------------------------------------------- /ArtgrisMaintenanceBundle.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class MaintenanceTest extends WebTestCase 16 | { 17 | public function testMaintenance() 18 | { 19 | $client = static::createClient(); 20 | $client->request('GET', '/'); 21 | static::assertEquals( 22 | Response::HTTP_SERVICE_UNAVAILABLE, 23 | $client->getResponse()->getStatusCode()); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "artgris/maintenance-bundle", 3 | "type": "symfony-bundle", 4 | "description": "Symfony Bundle to place your Symfony website in maintenance mode", 5 | "keywords": [ 6 | "symfony", 7 | "maintenance", 8 | "bundle" 9 | ], 10 | "homepage": "https://github.com/artgris/MaintenanceBundle", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "Arthur Gribet", 15 | "email": "a.gribet@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=8.0.2", 20 | "twig/twig": "^2.12|^3.0", 21 | "symfony/config": "^5.0|^6.0|^7.0" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "~3.7" 25 | }, 26 | "autoload": { 27 | "psr-0": { 28 | "Artgris\\MaintenanceBundle": "" 29 | } 30 | }, 31 | "target-dir": "Artgris/MaintenanceBundle" 32 | } 33 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in(__DIR__) 5 | ->ignoreDotFiles(true) 6 | ->ignoreVCS(true) 7 | ->exclude(array('build', 'vendor')) 8 | ->files() 9 | ->name('*.php') 10 | ; 11 | return PhpCsFixer\Config::create() 12 | ->setUsingCache(true) 13 | ->setRiskyAllowed(true) 14 | ->setFinder($finder) 15 | ->setRules(array( 16 | '@Symfony' => true, 17 | '@Symfony:risky' => true, 18 | 'array_syntax' => array('syntax' => 'short'), 19 | 'binary_operator_spaces' => array( 20 | 'align_double_arrow' => false, 21 | ), 22 | 'combine_consecutive_unsets' => true, 23 | 'no_useless_else' => true, 24 | 'no_useless_return' => true, 25 | 'ordered_imports' => true, 26 | 'php_unit_strict' => true, 27 | 'phpdoc_summary' => false, 28 | 'strict_comparison' => true, 29 | )) 30 | ; -------------------------------------------------------------------------------- /DependencyInjection/ArtgrisMaintenanceExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 25 | 26 | $container->setParameter('artgris_maintenance', $config); 27 | 28 | $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 29 | $loader->load('services.yml'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | getRootNode(); 23 | 24 | $rootNode 25 | ->children() 26 | ->scalarNode("enable")->defaultValue(false)->end() 27 | ->scalarNode("response")->defaultValue(Response::HTTP_SERVICE_UNAVAILABLE)->end() 28 | ->arrayNode("ips") 29 | ->prototype('scalar')->end() 30 | ->end() 31 | ->end(); 32 | 33 | return $treeBuilder; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaintenanceBundle 2 | Symfony Bundle to place your Symfony website in maintenance mode - [**Default Maintenance Page**](https://artgris.github.io/MaintenanceBundle/) 3 | 4 | Installation 5 | ============ 6 | 7 | ### 1) Download 8 | 9 | `composer require artgris/maintenance-bundle` 10 | 11 | ### 2) Configure the Bundle 12 | 13 | Adds following configurations 14 | 15 | to ` config/packages/artgris_maintenance.yaml` : 16 | 17 | ```yml 18 | artgris_maintenance: 19 | enable: true # Enable|Disable maintenance - default: false 20 | ips: ["127.0.0.1","::1",...] # IPs allow (prod) - default: [] 21 | response: 503 # Maintenance Page HTTP Status Code - default: 503 22 | ``` 23 | 24 | ### 3) Override maintenance.html.twig (optional) 25 | 26 | in `templates/bundles/ArtgrisMaintenanceBundle/maintenance.html.twig` 27 | 28 | ex: 29 | ```twig 30 | {% extends "@!ArtgrisMaintenance/maintenance.html.twig" %} 31 | 32 | {% block content %} 33 |

Site en cours de maintenance

34 |

Nous reviendrons bientôt. Désolé pour le dérangement.

35 | {% endblock %} 36 | ``` 37 | 38 | Usage 39 | ===== 40 | 41 | The `dev` environment was not affected by maintenance. 42 | 43 | - Enable|Disable maintenance : `enable: true|false` 44 | - Add authorized IPs to prod : `ips: ["127.0.0.1","::1",...]` 45 | - Maintenance Page HTTP Status Code : `response: 503` 46 | 47 | 48 | Don't forget to clear the `prod` cache : 49 | 50 | php bin/console cache:clear 51 | 52 | -------------------------------------------------------------------------------- /EventListener/MaintenanceListener.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class MaintenanceListener 19 | { 20 | /** 21 | * @var bool 22 | */ 23 | private $enable; 24 | /** 25 | * @var array 26 | */ 27 | private $ips; 28 | /** 29 | * @var KernelInterface 30 | */ 31 | private $kernel; 32 | /** 33 | * @var Environment 34 | */ 35 | private $twig_Environment; 36 | /** 37 | * @var mixed 38 | */ 39 | private $response; 40 | 41 | /** 42 | * MaintenanceListener constructor. 43 | * 44 | * @param array $maintenance 45 | * @param KernelInterface $kernel 46 | * @param Environment $twig_Environment 47 | */ 48 | public function __construct(array $maintenance, KernelInterface $kernel, Environment $twig_Environment) 49 | { 50 | $this->enable = $maintenance['enable'] ?: false; 51 | $this->ips = $maintenance['ips'] ?: []; 52 | $this->response = $maintenance['response']; 53 | $this->kernel = $kernel; 54 | $this->twig_Environment = $twig_Environment; 55 | } 56 | 57 | public function onKernelRequest(RequestEvent $event) 58 | { 59 | 60 | if (!$event->isMainRequest()) { 61 | return; 62 | } 63 | 64 | $request = $event->getRequest(); 65 | 66 | if ($this->enable && $this->kernel->getEnvironment() != 'dev' && !IpUtils::checkIp($request->getClientIp(), $this->ips)) { 67 | $content = $this->twig_Environment->render('@ArtgrisMaintenance/maintenance.html.twig'); 68 | $event->setResponse(new Response($content, $this->response)); 69 | } 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | Maintenance 9 | 10 | 64 | 65 | 66 |
67 |

Site under maintenance

68 |

We'll be back soon. Sorry for inconvenience.

69 |
70 | 71 | 97 | 98 | -------------------------------------------------------------------------------- /Resources/views/maintenance.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | {% block title %}Maintenance{% endblock %} 9 | {% block stylesheets %} 10 | 11 | 64 | {% endblock %} 65 | 66 | 67 | {% block body %} 68 |
69 | {% block content %} 70 |

Site under maintenance

71 |

We'll be back soon. Sorry for inconvenience.

72 | {% endblock %} 73 |
74 | {% endblock %} 75 | 76 | {% block javascripts %} 77 | 78 | 104 | {% endblock %} 105 | 106 | --------------------------------------------------------------------------------