From dd1ae3093f789a101f0a3065f00320f246482f21 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Mon, 5 Jul 2021 14:45:35 +0200 Subject: [PATCH 1/8] Add a maintenance mode mu-plugins This mu-plugin display a maintenance mode page when it's specified in `.env` file. A list of IPs can be excluded from maintenance mode --- .../web/wp-content/mu-plugins/autoload.php | 13 ++++ .../studiometa-maintenance-mode/README.md | 14 ++++ .../class-studiometamaintenancemode.php | 69 +++++++++++++++++++ .../maintenance.css | 0 .../maintenance.php | 23 +++++++ 5 files changed, 119 insertions(+) create mode 100644 template/web/wp-content/mu-plugins/autoload.php create mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md create mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php create mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css create mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php diff --git a/template/web/wp-content/mu-plugins/autoload.php b/template/web/wp-content/mu-plugins/autoload.php new file mode 100644 index 0000000..36a145c --- /dev/null +++ b/template/web/wp-content/mu-plugins/autoload.php @@ -0,0 +1,13 @@ + + * @copyright 2021 Studio Meta + * @license https://opensource.org/licenses/MIT + * @since 1.0.0 + * @version 1.0.0 + */ + +require WPMU_PLUGIN_DIR . '/studiometa-maintenance-mode/class-studiometamaintenancemode.php'; diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md new file mode 100644 index 0000000..b393a5a --- /dev/null +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md @@ -0,0 +1,14 @@ +# Studio Meta maintenance mode + +Put your site under maintenance with a 503 HTTP status and a dedicated page. + +## Usage + +1. The following server environment variables must be set in order to the maintenance be active: +```bash +MAINTENANCE_ENABLED=true|false # Enable/Disable maitenance mode. +MAINTENANCE_IPS=42.42.42.42.42 # Exclude a list of IPs from maitenance. +``` +2. Customize the maintenance page thanks to `maintenance.php` and `maintenance.css` files. + +> If you use a cache plugin, don't forget to clean caches. diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php new file mode 100644 index 0000000..1412f04 --- /dev/null +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php @@ -0,0 +1,69 @@ + + * @copyright 2021 Studio Meta + * @license https://opensource.org/licenses/MIT + * @since 1.0.0 + * @version 1.0.0 + */ + +/** + * StudiometaMaintenanceMode class. + */ +class StudiometaMaintenanceMode { + /** + * Constructor. + */ + public function __construct() { + add_action( 'init', array( $this, 'redirect_to_maintenance' ) ); + } + + /** + * Is maintenance? + * + * @return boolean Is maintenance? + */ + protected function is_maintenance_mode() { + if ( + 'true' !== getenv( 'MAINTENANCE_ENABLED' ) + || is_admin() + || current_user_can( 'administrator' ) + || ! file_exists( __DIR__ . '/maintenance.php' ) + || 'wp-login.php' === $GLOBALS['pagenow'] + ) { + return false; + } + + $allowed_ips = explode( ',', getenv( 'MAINTENANCE_IPS' ) ); + $remote_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) : false; + + if ( in_array( $remote_ip, $allowed_ips, true ) ) { + return false; + } + + return true; + } + + /** + * Redirect to maintenance mode. + * + * @return void + */ + public function redirect_to_maintenance() { + if ( ! $this->is_maintenance_mode() ) { + return; + } + + $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) && 'HTTP/1.1' === $_SERVER['SERVER_PROTOCOL'] ? 'HTTP/1.1' : 'HTTP/1.0'; + + header( $protocol . ' 503 Service Unavailable', true, 503 ); + header( 'Retry-After: 3600' ); + include_once __DIR__ . '/maintenance.php'; + die(); + } +} + +new StudiometaMaintenanceMode(); diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css new file mode 100644 index 0000000..e69de29 diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php new file mode 100644 index 0000000..09dd059 --- /dev/null +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php @@ -0,0 +1,23 @@ + + + +> + + + + <?php bloginfo( 'name' ) . ( ! empty( get_bloginfo( 'description' ) ) ? ' – ' . bloginfo( 'description' ) : '' ); ?> + + + +> + +

+ From 56c4a1c70bda4b64413ce5332dee7b7674ca1fe7 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Mon, 5 Jul 2021 14:47:44 +0200 Subject: [PATCH 2/8] Add maintenance mode environment variables example to `.env.example` file --- template/.env.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/template/.env.example b/template/.env.example index 2f8a563..fbd97d0 100644 --- a/template/.env.example +++ b/template/.env.example @@ -26,6 +26,9 @@ DISABLE_PLUGINS_LOCAL=test/test.php DISABLE_PLUGINS_PREPROD=test/test.php DISABLE_PLUGINS_PRODUCTION=test/test.php +MAINTENANCE_ENABLED=true|false +MAINTENANCE_IPS=127.0.0.1,127.0.0.2 + AUTH_KEY='' SECURE_AUTH_KEY='' LOGGED_IN_KEY='' From 044a1655432eb528f29b8e02befd67d22ea8e906 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Mon, 12 Jul 2021 11:32:34 +0200 Subject: [PATCH 3/8] Fix maintenance page HTML --- .../maintenance.php | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php index 09dd059..0b0f273 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php @@ -10,14 +10,15 @@ > - - - - <?php bloginfo( 'name' ) . ( ! empty( get_bloginfo( 'description' ) ) ? ' – ' . bloginfo( 'description' ) : '' ); ?> - - + + + + <?php bloginfo( 'name' ) . ( ! empty( get_bloginfo( 'description' ) ) ? ' – ' . bloginfo( 'description' ) : '' ); ?> + + -> - -

- + > + +

+ + From 315a2382e3e9bb231c077eab5eee44ce85bb6ecb Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Mon, 19 Jul 2021 09:54:10 +0200 Subject: [PATCH 4/8] Delete manual autoloader Autoload done with boxuk/wp-muplugin-loader --- template/web/wp-content/mu-plugins/autoload.php | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 template/web/wp-content/mu-plugins/autoload.php diff --git a/template/web/wp-content/mu-plugins/autoload.php b/template/web/wp-content/mu-plugins/autoload.php deleted file mode 100644 index 36a145c..0000000 --- a/template/web/wp-content/mu-plugins/autoload.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @copyright 2021 Studio Meta - * @license https://opensource.org/licenses/MIT - * @since 1.0.0 - * @version 1.0.0 - */ - -require WPMU_PLUGIN_DIR . '/studiometa-maintenance-mode/class-studiometamaintenancemode.php'; From 969611fedadb207dcf37a59f8941920a481f0f79 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Wed, 10 Aug 2022 16:45:33 +0200 Subject: [PATCH 5/8] Use Wordpress maintenance mode instead of custom one --- .../studiometa-maintenance-mode/README.md | 4 +- .../example/maintenance.css | 1 + .../{ => example}/maintenance.php | 2 +- .../maintenance.css | 0 ...de.php => studiometa-maintenance-mode.php} | 56 ++++++++++--------- 5 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.css rename template/web/wp-content/mu-plugins/studiometa-maintenance-mode/{ => example}/maintenance.php (85%) delete mode 100644 template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css rename template/web/wp-content/mu-plugins/studiometa-maintenance-mode/{class-studiometamaintenancemode.php => studiometa-maintenance-mode.php} (51%) diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md index b393a5a..340fc67 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md @@ -1,6 +1,6 @@ # Studio Meta maintenance mode -Put your site under maintenance with a 503 HTTP status and a dedicated page. +Put your site under maintenance depends on server environment variables. ## Usage @@ -9,6 +9,6 @@ Put your site under maintenance with a 503 HTTP status and a dedicated page. MAINTENANCE_ENABLED=true|false # Enable/Disable maitenance mode. MAINTENANCE_IPS=42.42.42.42.42 # Exclude a list of IPs from maitenance. ``` -2. Customize the maintenance page thanks to `maintenance.php` and `maintenance.css` files. +2. You can customize the maintenance page by adding a `maintenance.php` file in `WP_CONTENT_DIR` (see https://developer.wordpress.org/reference/functions/wp_maintenance/). You can find a maintenance page example in [this folder](`./example/maintenance.php`) > If you use a cache plugin, don't forget to clean caches. diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.css b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.css new file mode 100644 index 0000000..5ce768c --- /dev/null +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.css @@ -0,0 +1 @@ +h1 { color: red; } diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.php similarity index 85% rename from template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php rename to template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.php index 0b0f273..848458e 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.php +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/example/maintenance.php @@ -14,7 +14,7 @@ <?php bloginfo( 'name' ) . ( ! empty( get_bloginfo( 'description' ) ) ? ' – ' . bloginfo( 'description' ) : '' ); ?> - + > diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/maintenance.css deleted file mode 100644 index e69de29..0000000 diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php similarity index 51% rename from template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php rename to template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php index 1412f04..0ddbedd 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/class-studiometamaintenancemode.php +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php @@ -1,12 +1,15 @@ * @copyright 2021 Studio Meta * @license https://opensource.org/licenses/MIT - * @since 1.0.0 * @version 1.0.0 */ @@ -14,11 +17,31 @@ * StudiometaMaintenanceMode class. */ class StudiometaMaintenanceMode { - /** - * Constructor. - */ public function __construct() { - add_action( 'init', array( $this, 'redirect_to_maintenance' ) ); + add_action( 'wp_loaded', array( $this, 'toggle_maintenance' ) ); + } + + public function toggle_maintenance() { + if ( ! $this->is_maintenance_mode() ) { + return; + } + + if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) { + $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) && 'HTTP/1.1' === $_SERVER['SERVER_PROTOCOL'] ? 'HTTP/1.1' : 'HTTP/1.0'; + + header( $protocol . ' 503 Service Unavailable', true, 503 ); + require_once WP_CONTENT_DIR . '/maintenance.php'; + die(); + } + + require_once ABSPATH . WPINC . '/functions.php'; + wp_load_translations_early(); + + wp_die( + __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ), + __( 'Maintenance' ), + 503 + ); } /** @@ -30,8 +53,7 @@ protected function is_maintenance_mode() { if ( 'true' !== getenv( 'MAINTENANCE_ENABLED' ) || is_admin() - || current_user_can( 'administrator' ) - || ! file_exists( __DIR__ . '/maintenance.php' ) + || current_user_can( 'manage_options' ) || 'wp-login.php' === $GLOBALS['pagenow'] ) { return false; @@ -46,24 +68,6 @@ protected function is_maintenance_mode() { return true; } - - /** - * Redirect to maintenance mode. - * - * @return void - */ - public function redirect_to_maintenance() { - if ( ! $this->is_maintenance_mode() ) { - return; - } - - $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) && 'HTTP/1.1' === $_SERVER['SERVER_PROTOCOL'] ? 'HTTP/1.1' : 'HTTP/1.0'; - - header( $protocol . ' 503 Service Unavailable', true, 503 ); - header( 'Retry-After: 3600' ); - include_once __DIR__ . '/maintenance.php'; - die(); - } } new StudiometaMaintenanceMode(); From 4ca140027be789ac735ed78ef7ea5b91a9d302f8 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Wed, 10 Aug 2022 16:56:00 +0200 Subject: [PATCH 6/8] Change method to fetch remote address --- .../studiometa-maintenance-mode.php | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php index 0ddbedd..77b76f0 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php @@ -44,6 +44,38 @@ public function toggle_maintenance() { ); } + /** + * Get the server variable REMOTE_ADDR, or the first ip of HTTP_X_FORWARDED_FOR (when using proxy). + * + * @return string $remote_addr ip of client + */ + private static function get_remote_addr() + { + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + } else { + $headers = $_SERVER; + } + + if (array_key_exists('X-Forwarded-For', $headers)) { + $_SERVER['HTTP_X_FORWARDED_FOR'] = $headers['X-Forwarded-For']; + } + + if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && (!isset($_SERVER['REMOTE_ADDR']) + || preg_match('/^127\..*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^172\.16.*/i', trim($_SERVER['REMOTE_ADDR'])) + || preg_match('/^192\.168\.*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^10\..*/i', trim($_SERVER['REMOTE_ADDR'])))) { + if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')) { + $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + + return $ips[0]; + } else { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + } else { + return $_SERVER['REMOTE_ADDR']; + } + } + /** * Is maintenance? * @@ -60,9 +92,8 @@ protected function is_maintenance_mode() { } $allowed_ips = explode( ',', getenv( 'MAINTENANCE_IPS' ) ); - $remote_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ), FILTER_VALIDATE_IP ) : false; - if ( in_array( $remote_ip, $allowed_ips, true ) ) { + if ( $allowed_ips && in_array( $this->get_remote_addr(), $allowed_ips, true ) ) { return false; } From 7e8893d7868201ef34d93bc944f51d1e2de6ed59 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Wed, 10 Aug 2022 17:01:46 +0200 Subject: [PATCH 7/8] Update studiometa maintenance mode readme --- template/readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/template/readme.md b/template/readme.md index 86384a4..f5fb044 100644 --- a/template/readme.md +++ b/template/readme.md @@ -87,6 +87,10 @@ Par défaut, tout ce qui se trouve dans les sous-dossiers de `web/wp-content` es ## Fonctionnalités additionnelles +### Activation/Désactivation du mode maintenance via variables d'environnement serveur + +Le MU-plugin [Studiometa maintenance mode](./web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md) permet d'activer le mode maintenance du site. [Voir le readme](./web/wp-content/mu-plugins/studiometa-maintenance-mode/README.md) pour plus d'informations. + ### Désactivation de plugins par environnement Le MU-plugin [Studiometa plugin disabler](./web/wp-content/mu-plugins/studiometa-plugin-disabler/README.md) permet de forcer la désactivation des plugins en fonction de l'environnement. [Voir le readme](./web/wp-content/mu-plugins/studiometa-plugin-disabler/README.md) pour plus d'informations. From 8f2e4e9a029ba02072f9fd38b800cc819aaab625 Mon Sep 17 00:00:00 2001 From: Lucas Simeon Date: Wed, 10 Aug 2022 17:43:52 +0200 Subject: [PATCH 8/8] Fix code style --- .../studiometa-maintenance-mode.php | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php index 77b76f0..061016a 100644 --- a/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php +++ b/template/web/wp-content/mu-plugins/studiometa-maintenance-mode/studiometa-maintenance-mode.php @@ -30,51 +30,51 @@ public function toggle_maintenance() { $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) && 'HTTP/1.1' === $_SERVER['SERVER_PROTOCOL'] ? 'HTTP/1.1' : 'HTTP/1.0'; header( $protocol . ' 503 Service Unavailable', true, 503 ); - require_once WP_CONTENT_DIR . '/maintenance.php'; - die(); - } + require_once WP_CONTENT_DIR . '/maintenance.php'; + die(); + } - require_once ABSPATH . WPINC . '/functions.php'; - wp_load_translations_early(); + require_once ABSPATH . WPINC . '/functions.php'; + wp_load_translations_early(); - wp_die( - __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ), - __( 'Maintenance' ), - 503 - ); + wp_die( + __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ), + __( 'Maintenance' ), + 503 + ); } - /** - * Get the server variable REMOTE_ADDR, or the first ip of HTTP_X_FORWARDED_FOR (when using proxy). - * - * @return string $remote_addr ip of client - */ - private static function get_remote_addr() - { - if (function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - } else { - $headers = $_SERVER; - } + /** + * Get the server variable REMOTE_ADDR, or the first ip of HTTP_X_FORWARDED_FOR (when using proxy). + * + * @return string $remote_addr ip of client + */ + private static function get_remote_addr() + { + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + } else { + $headers = $_SERVER; + } - if (array_key_exists('X-Forwarded-For', $headers)) { - $_SERVER['HTTP_X_FORWARDED_FOR'] = $headers['X-Forwarded-For']; - } + if (array_key_exists('X-Forwarded-For', $headers)) { + $_SERVER['HTTP_X_FORWARDED_FOR'] = $headers['X-Forwarded-For']; + } - if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && (!isset($_SERVER['REMOTE_ADDR']) - || preg_match('/^127\..*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^172\.16.*/i', trim($_SERVER['REMOTE_ADDR'])) - || preg_match('/^192\.168\.*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^10\..*/i', trim($_SERVER['REMOTE_ADDR'])))) { - if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')) { - $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && (!isset($_SERVER['REMOTE_ADDR']) + || preg_match('/^127\..*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^172\.16.*/i', trim($_SERVER['REMOTE_ADDR'])) + || preg_match('/^192\.168\.*/i', trim($_SERVER['REMOTE_ADDR'])) || preg_match('/^10\..*/i', trim($_SERVER['REMOTE_ADDR'])))) { + if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')) { + $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - return $ips[0]; - } else { - return $_SERVER['HTTP_X_FORWARDED_FOR']; - } - } else { - return $_SERVER['REMOTE_ADDR']; - } - } + return $ips[0]; + } else { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + } else { + return $_SERVER['REMOTE_ADDR']; + } + } /** * Is maintenance?