Durante las dos últimas semanas, he estado investigando sobre la mejor manera de poner un entorno multisitio de WordPress en “modo de mantenimiento”, lo que equivale a hacerlo inaccesible para todos los visitantes y usuarios del blog excepto para el superadministrador. El objetivo de este proceso es impedir que, durante las tareas de mantenimiento que de vez en cuando hay que llevar a cabo en este tipo de instalaciones, puedan realizarse cambios que comprometan el buen funcionamiento de la aplicación o supongan alguna modificación no deseada de la base de datos.

Lo cierto es que WordPress ya incluye su propio modo de mantenimiento, aunque no es todo lo evidente que debiera, sobre todo si lo comparamos con otros CMS como Joomla!. En efecto, mientras se lleva a cabo una actualización desde el backend de WordPress, el programa se torna inaccesible para los visitantes, a quienes muestra una página con un mensaje de advertencia. Dada la rapidez con que se llevan a cabo las actualizaciones, en la mayoría de las ocasiones este cambio de estado resulta imperceptible tanto para los usuarios registrados como para los visitantes del sitio, pero a veces la actualización se prolonga más de lo esperado (véanse los artículos Actualización a la versión 3.1.3 de WordPress, Actualización (con suspense) a la versión 3.1.2 de WordPress y Actualización a WordPress 3.1.1, con algún susto de por medio), o fracasa, dejando el blog inoperativo.

Tal situación, sin duda muy alarmante, tiene fácil solución, pues a nivel interno, WordPress se pone a sí mismo en modo de mantenimiento creando en el directorio raíz del blog un fichero, denominado .maintenance (el punto delante del nombre indica, en los sistemas UNIX, que se trata de un fichero oculto), que se borra automáticamente cuando el proceso de actualización finaliza. Si por algún motivo dicho proceso termina de forma anómala, y el fichero no se elimina, basta con conectarse al sitio por FTP, borrar el fichero .maintenance y recuperar el modo normal de la aplicación.

Es posible aprovechar este comportamiento de WordPress para forzar el modo de mantenimiento en cualquier momento en que sea necesario detener el funcionamiento de la aplicación. Para ello, basta con crear en el directorio raíz de la instalación el ya citado fichero .maintenance y asociarlo con una página de advertencia personalizada, en la que se pueden incluir informaciones complementarias, logos, etc. Lo más fácil para conseguir esta página personalizada es utilizar las posibilidades que ofrecen los denominados “drop-in” plugins de WordPress, y en concreto el fichero maintenance.php, que debe ubicarse en el directorio /wp-content. A quienes estén interesados en esta técnica les aconsejo que consulten los tres artículos de la serie WordPress Maintenance Mode without a Plugin, o el ejemplo que propone el autor de How to Make an Awesome Maintenance Mode Screen for WordPress.

Por supuesto, existe un recurso más cómodo que no exige ningún tipo de programación, y que pasa por el uso de alguna de las extensiones específicas diseñadas específicamente para poner el blog en modo de mantenimiento, como  por ejemplo Maintenance Mode, que yo he utilizado con cierta frecuencia en La Bitácora del Tigre y WP Maintenance Mode. Ahora bien, ambos plugins están diseñados para blogs individuales, y ninguno funciona correctamente (o al menos yo no he conseguido hacerlos funcionar tal como me gustaría) en entornos multisitio, pues el modo de mantenimiento en este tipo de instalaciones presenta algunas exigencias particulares:

  • Debe impedir las visitas al sitio web principal.
  • Debe impedir las visitas a todos los blogs individuales.
  • Debe impedir el acceso al blog principal de todos los usuarios registrados, excepto del superadministrador.
  • Debe impedir el acceso a los blogs individuales de todos los usuarios registrados, sin excepción.
  • Debe hacer posible el acceso del usuario superadministrador, para poder realizar las tareas de mantenimiento que resulten necesarias.
  • La activación y desactivación del modo de mantenimiento debe poder realizarse de forma rápida y sencilla, en una sola operación, y sin modificar ningún fichero del núcleo de la aplicación.

Aunque teóricamente sería posible conseguir la desactivación de todos los blogs con plugins como los que acabo de citar, para lograrlo no sólo hace falta activarlos en red (es decir, activarlos para todos los blogs del sitio), sino además recorrer todos y cada uno de los blogs para seleccionar las correspondientes casillas de activación y ponerlas en “On”, lo cual puede ser impracticable. Por otro lado, incluso en tales circunstancias los blogs individuales seguirían permitiendo conectarse a sus usuarios administradores, comportamiento que no es deseable si se quiere una inmovilidad total de la instalación multiblog. En cuanto al truco descrito en la serie Maintenance Mode without a Plugin, funciona muy bien para el acceso de los visitantes a todos los blogs del sitio, pero en cambio no impide el acceso de los usuarios registrados al backend.

Hasta donde yo sé, el único plugin que garantiza una desactivación total de una instalación multiblog y al mismo tiempo permite el acceso del superadministrador, es uno que ni siquiera figura en el repositorio oficial de WordPress, denominado Site Shutdown (antes de utilizarlo conviene consultar los hilos Shutdown Plugin? y Maintenance Mode Plugin, is there any?, en los foros de soporte de WPMU DEV), que ofrece la posibilidad de escoger el modo de funcionamiento de la aplicación:

  • Funcionamiento normal: todos los blogs se encuentran en funcionamiento, y pueden acceder tanto los visitantes como los usuarios registrados.
  • Blogs individuales desactivados; solo el blog principal se puede visitar, y se permite el acceso de los usuarios registrados.
  • Blog principal desactivado; sólo los blogs individuales se pueden visitar, y se permite el acceso de los usuarios registrados.
  • Todo el sitio desactivado. En este último estado, el sitio sólo es accesible para el superadministrador mientras éste se encuentre conectado. Si se desconecta, sólo podrá entrar apuntando al fichero wp-login.php.

Aunque funciona aceptablemente en las últimas versiones de WordPress en configuración multisitio, la gran desventaja de esta extensión es que no está preparada para integrarse en el sistema de menús de WP 3.0, y además presenta la pantalla de configuración y los mensajes para los usuarios en inglés, mediante una disposición que no resulta fácil de modificar si no se tienen conocimientos avanzados de PHP y HTML.

Así que estábamos como al principio, lo cual nos obliga a explorar otras vías. Una de ellas podría ser la de recurrir a uno o varios ficheros .htaccess (para el directorio principal y el directorio /wp-admin) que contengan las directivas adecuadas para desactivar el sitio y reenviar a los visitantes a una página de advertencia (véase, por ejemplo, las soluciones que se proponen en 10 awesome .htaccess hacks for WordPress y en A to Z of WordPress .htaccess Hacks). Sin embargo, la manipulación de los ficheros .htaccess es siempre una tarea potencialmente peligrosa, que sólo debe recomendarse a usuarios expertos.

¿Cómo romper este círculo vicioso? A mí me ha costado una eternidad de búsquedas, pruebas y experimentos, que al final han llegado a un puerto relativamente seguro gracias a la inspiración de dos artículos de WordPress Code Snippets, los titulados Maintenance mode without plug-in y Maintenance mode for the admin only. El primer artículo propone integrar en el fichero functions.php del tema utilizado por el blog el código necesario para cerrar el acceso al frontend; el segundo (y esta es la clave del invento) hace lo mismo, pero con el backend, al cual impide todo acceso, excepto cuando se trate del usuario superadministrador

La desventaja del enfoque propuesto por WordPress Code Snippets es que depende de un tema determinado, con los problemas consiguientes si éste se cambia o actualiza. Mucho mejor sería integrar ambos scripts en un plugin, tarea a la que rápidamente me entregué con el entusiasmo del converso, la experiencia acumulada tras el caso que ya describí en Mi primer plugin para WordPress y la inestimable ayuda del artículo How to create your own WordPress functionality plugin. El código que presento a continuación –en los comentarios figuran las aclaraciones necesarias para instalarlo y activarlo- es bastante chapucero, ya lo sé, pero cumple las condiciones que me había fijado para las instalaciones multisitio, y es fácilmente modificable para adaptarlo a otros casos. Yo lo he probado en tres instalaciones situadas en dos servidores diferentes, y funciona bien, como puede observarse en las figuras 1 y 2. No obstante, soy consciente de sus limitaciones y de lo tosco de su elaboración; por eso, si alguien encuentra cómo mejorarlo, le agradeceré mucho que me lo diga.

<?php

/*
Plugin Name: Modo de mantenimiento para multisitios
Description: Pone una instalación multisitio de WordPress en modo de mantenimiento, y muestra una página de aviso personalizada, tanto en el frontend como en el backend. El superadministrador del sitio siempre puede acceder al backend. Debe instalarse en el directorio /mu-plugins. 
Version: 0.1
License: GPL
Author: Eduardo Larequi
Author URI: http://www.labitacoradeltigre.com
*/

/* Esta función impide el acceso al frontend de todos los blogs. El código es una adaptación del que propone http://wp-snippets.com/maintenance-mode/. En la línea 16, se ha sustituido la capacidad original, que era "edit_themes", propia de los administradores, por "manage_network", que es exclusiva de los superadministradores. */

function maintenance_mode() {

  if ( !current_user_can( 'manage_network' ) || !is_user_logged_in() ) {
	wp_die( /* Código HTML personalizable */'<div class="anuncio_mantenimiento" style="margin-top:5cm;margin-bottom:5cm;">
	<p style="text-align:center"><img src="http://www.misitioweb.com/wp-content/uploads/logo.png" title="Mi sitio web" alt="Mi sitio web" /></p>
    <h3 style="text-align:center;margin-top:1cm;">Este sitio se encuentra cerrado por el momento, debido a tareas de mantenimiento.<br />
	Por favor, espera media hora antes de volver a conectarte.</h3></div>', 'Cerrado por mantenimiento');
		}
}
add_action('get_header', 'maintenance_mode');

/* Esta función impide el acceso al backend de todos los blogs, excepto para el usuario administrador. El código es una adaptación del que propone http://wpsnipp.com/index.php/functions-php/maintenance-mode-for-the-admin-only/. */

function admin_maintenance_mode() {

    global $current_user;
    get_currentuserinfo();
    if($current_user->user_login != 'NOMBRE_SUPERADMIN') /* Sustituir en cada caso por el nombre de usuario del superadministrador */ { 
	wp_die( /* Código HTML personalizable */'<div class="anuncio_mantenimiento" style="margin-top:5cm;margin-bottom:5cm;">
	<p style="text-align:center"><img src="http://www.misitioweb.com/wp-content/uploads/logo.png" title="Mi sitio web" alt="Mi sitio web" /></p>
    <h3 style="text-align:center;margin-top:1cm;">Este sitio se encuentra cerrado por el momento, debido a tareas de mantenimiento.<br />
	Por favor, espera media hora antes de volver a conectarte.</h3></div>', 'Cerrado por mantenimiento');
		}
}
add_action('admin_head', 'admin_maintenance_mode');

?>

Figura 1 - Frontend del blog en modo de mantenimiento

Figura 1 - Frontend del blog en modo de mantenimiento


Figura 2 - Backend del blog en modo de mantenimiento

Figura 2 - Backend del blog en modo de mantenimiento

alojamiento wordpress