Para mí, parece que esto podría ser algo mejor para una instalación de un solo sitio en lugar de un sitio múltiple. Pero realmente depende de cómo deben ser las cosas personalizadas para un solo usuario.
NOTA: esta respuesta no incluirá información sobre la configuración del servidor, etc.
Primero que nada, definiría WP_HOME y WP_SITEURL en wp-config.php
y los haría invariables. Probablemente pueda configurarlos dinámicamente, pero los resultados deben ser que apunten al dominio principal, raíz. Mi instalación local de WP es wordpress.dev
, así que la usaré en esta respuesta.
Ejemplo:
<?php
// in wp-config.php
define('WP_HOME', 'http://wordpress.dev');
define('WP_SITEURL', WP_HOME . '/wp'); // wp in sub directory
// custom content directory
define('WP_CONTENT_DIR', dirname(__FILE__) . '/content');
define('WP_CONTENT_URL', WP_HOME . '/content');
A continuación, debemos configurar el usuario según el subdominio actual. Esto debería ser relativamente fácil: analice el host HTTP, busque un usuario con ese nombre de usuario, configúrelo como usuario para más adelante. Sugiero envolver todo en una clase (un singleton aquí).
<?php
class WPSE66456
{
// container for an instance of this class
private static $ins;
// The current user, based on subdomain.
private $user = null;
/***** Singleton Pattern *****/
public static function init()
{
add_action('plugins_loaded', array(__CLASS__, 'instance'), 0);
}
public static function instance()
{
is_null(self::$ins) && self::$ins = new self;
return self::$ins;
}
/**
* Constructor. Actions really get added here.
*
*/
protected function __construct()
{
// empty for now...
}
} // end class
Luego debemos escribir algo para analizar $_SERVER['HTTP_HOST']
y ver si obtenemos un nombre de usuario válido de él.
<?php
class WPSE66456
{
// snip snip
protected function __construct()
{
$this->set_current_user($_SERVER['HTTP_HOST']);
}
protected function set_current_user($host)
{
if(!is_null($this->user))
return;
list($user, $host) = explode('.', $host, 2);
// gets tricky here. Where is the real site? Is it at the root domain?
// For the purposes of this tutorial, let's assume that we're using a
// nacked root domain for the main, no user site.
// Make sure the $host is still a valid domain, if not we're on the root
if(strpos($host, '.') === false)
{
$this->user = false;
}
else
{
if($u = get_user_by('slug', $user))
{
// we have a user!
$this->user = $u;
}
else
{
// invalid user name. Send them back to the root.
wp_redirect("http://{$host}", 302);
exit;
// Or you could die here and show an error...
// wp_die(__('Invalid User'), __('Invalid User'));
}
}
}
}
Ahora que tiene un nombre de usuario, puede hacer todo tipo de cosas. Como ejemplo, cambiemos el lema del blog por un saludo para ese usuario.
<?php
class WPSE66456
{
// snip snip
protected function __construct()
{
$this->set_current_user($_SERVER['HTTP_HOST']);
add_filter('bloginfo', array($this, 'set_tagline'), 10, 2);
}
// snip snip
public function set_tagline($c, $show)
{
if('description' != $show || !$this->user)
return $c;
return 'Hello, ' . esc_html($this->user->display_name) . '!';
}
}
Suponiendo que utilice la url raíz, desnuda (sin www) para su instalación, WordPress enviará cookies a todos los sudominios. Por lo tanto, puede comprobar si un usuario está viendo su propio subdominio y devolverlo a la raíz, de lo contrario.
<?php
class WPSE66456
{
// snip snip
protected function __construct()
{
$this->set_current_user($_SERVER['HTTP_HOST']);
add_filter('bloginfo', array($this, 'set_tagline'), 10, 2);
add_action('init', array($this, 'check_user'), 1);
}
// snip snip
public function check_user()
{
if($this->user === false || current_user_can('manage_options'));
return; // on the root domain or the user is an admin
$user = wp_get_current_user();
if(!$user || $user != $this->user)
{
wp_redirect(home_url());
exit;
}
}
}
Finalmente, lo último a considerar es que WordPress permite cosas en nombres de usuarios que no funcionarán con el sistema de nombres de dominio. Al igual que user.one
es un nombre de usuario válido. Pero user.one.yoursite.com
tiene dos subdominios de profundidad y no va a funcionar.
Por lo tanto, tendrás que enlazar con pre_user_login
y sanear las cosas.
<?php
class WPSE66456
{
// snip snip
protected function __construct()
{
$this->set_current_user($_SERVER['HTTP_HOST']);
add_filter('bloginfo', array($this, 'set_tagline'), 10, 2);
add_filter('pre_user_login', array($this, 'filter_login'));
add_action('init', array($this, 'check_user'), 1);
}
// snip snip
public function filter_login($login)
{
// replace anything that isn't a-z and 0-9 and a dash
$login = preg_replace('/[^a-z0-9-]/u', '', strtolower($login));
// domains can't begin with a dash
$login = preg_replace('/^-/u', '', $login);
// domains can't end with a dash
$login = preg_replace('/-$/u', '', $login);
// probably don't want users registering the 'www' user name...
if('www' == $login)
$login = 'www2';
return $login;
}
}
todo lo anterior como plugin .
Hay muchas preocupaciones que no se abordan en esta respuesta. ¿Esta escala a donde la necesitas para escalar? ¿De qué manera el tener múltiples subdominios de contenido muy similar impactará la optimización de búsqueda? ¿Cuánto contenido se personaliza? Si es mucho, ¿el multi-sitio sería más adecuado para esta tarea?