2012-01-20 10 views
5

En mi sitio, los usuarios tienen perfiles públicos a los que se puede acceder a través del http://mysite.com/vanity_url. Quiero permitir que los usuarios dirijan sus propios dominios a su página de perfil en mi sitio. Just like Bandcamp does.¿Cuál es la forma más elegante de manejar los dominios personalizados de los usuarios?

Mi modelo Profile tiene estos dos campos para hacer frente a esto: vanity_url, que es el tipo de nombre de usuario normal del campo; y un nuevo custom_domain que es el nombre de sus propios dominios, por ejemplo, example.com.

Esto es lo que he hecho hasta ahora, pero me temo que podría no ser la forma más elegante, segura y eficiente de hacerlo.

Primero, me aseguré de que el DocumentRoot de Apache esté configurado en el directorio webroot de mi aplicación, por lo que puedo indicar a los usuarios que dirijan sus DNS a la dirección IP de mi sitio.

Ahora, así es como las reglas de enrutamiento en mi routes.php aspecto:

if (preg_match('/mysite\.com\.?$/', $_SERVER['SERVER_NAME'])){ 
    // Normal routes when visitors go to my domain 
    Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); 
    Router::connect('/pages/**', array('controller' => 'pages', 'action' => 'display')); 

    // Move all other actions to a separate '/app/' area 
    Router::connect('/app/:controller/:action/**'); 
    Router::connect('/app/:controller/**'); 

    // Handle profile URLs 
    Router::connect('/:profile/**', 
     array('controller' => 'profiles', 'action' => 'view'), 
     array('pass' => array('profile'), 'profile' => '[0-9a-zA-Z\-\_]+') 
    ); 
} 
else{ 
    // If visitors come via a URL different to mysite.com, I let 
    // the ProfilesController deal with it passing the current SERVER_NAME 
    // as a param to the 'view' action 
    Router::connect('/', array(
     'controller' => 'profiles', 
     'action' => 'view', 
     $_SERVER['SERVER_NAME'], // 'url' param 
     true // 'customDomain' param 
    )); 
    Router::redirect('/*', 'http://mysite.com'); 
} 

y es así como la acción view en el ProfilesController parece:

public function view($url = null, $customDomain = false) { 
    if ($url){ 
     // Find the profile by its vanity_url or its custom_domain 
     $findOptions = array(
      'conditions' => $customDomain? 
       array('custom_domain' => $url) : 
       array('vanity_url' => $url) 
     ); 
     if ($profile = $this->Profile->find('first', $findOptions)) { 
      $this->set('profile', $profile); 
     } 
    } 
    else throw new NotFoundException(__('Invalid profile')); 
} 

¿Qué problemas podría enfrentar con este enfoque?

Además, ¿alguien sabe por qué Bandcamp pide a los usuarios para crear un CNAME en lugar de un Un registro para configurar un subdominio? ¿Me estoy perdiendo algo que debería considerar aquí?

Editar Alguien me ayudó a que el último bit de salida: Parece que no se puede utilizar fácilmente un registro CNAME para apuntar un dominio simple a otro. La pregunta principal sigue abierta.

+0

que no es necesario tocar sus rutas con honestidad. –

Respuesta

1

he hecho algo similar con la torta 1.3 hace un año

Hay 4 pasos importantes en esta solución:

  1. tener un modelo de dominio y dominios tabla de datos que registra todos los posibles dominios y Vistas para personalizados sus usuarios ingresen sus dominios personalizados
  2. crean código de comprobación de dominio en beforeFilter en AppController y guardan los datos de usuario en la sesión
  3. la acción del controlador que es responsable de ver el perfil público necesita hacer referencia a los mismos datos de usuario que se guarda en la sesión
  4. los usuarios necesitan para configurar registros CNAME y A correctamente con sus registradores de dominios

Paso modelo 1 Dominio y DataTable

Lo que hice fue lo tenía una tabla llamada dominios

Cada dominio contiene la dirección web que asumí que era solo una http: // ....

dominio belongsTo usuario

usuario hasMany dominio

domains 
========== 
id web_address user_id main 

el principal es un tinyint que indica si este es el URL principal para ser utilizado desde hasMany dominio de usuario.

entonces lo que sucede es que el usuario necesita crear un nuevo registro o más para el dominio.

Código Paso 2 en beforeFilter de AppController averiguar qué perfil público para mostrar A continuación, el código necesita ser capaz de recuperar el ID de usuario basado en la url presentado a cada solicitud HTTP.

El usuario de ahora en adelante se refiere al usuario cuyo perfil público se visualiza. NO confunda esto con el Usuario conectado, si tiene uno.

Le sugiero que haga esto en su beforeFilter of AppController.

Algo como esto

$currentUser = $this->User->getByDomain(FULL_BASE_URL); 
    $this->Session->write('CurrentUser', $currentUser); 

El código para getByDomain para el modelo del usuario es también un ejercicio para usted. Debería ser bastante fácil dado que he explicado el esquema para Dominios

Puede que necesite verificar contra el Usuario actual dentro de sus datos de Sesión antes de escribir el Usuario actual porque no desea escribir los datos de la Sesión todo el tiempo especialmente cuando el visitante está visitando la misma página web una y otra vez.

Es posible que tenga que cambiar el código anterior a algo como esto:

$currentUser = $this->Session->read('CurrentUser'); 

    if(empty($currentUser) OR (!$this->checkUrlAgainstDomain(FULL_BASE_URL, $currentUser['Domain']['domain']))) { 
     $currentUser = $this->User->getByDomain(FULL_BASE_URL); 
        $this->Session->write('CurrentUser', $currentUser); 
    } 

Una vez más la función de checkUrlAgainstDomain es un ejercicio para usted.

Código Paso 3 en beforeFilter de AppController averiguar qué perfil público para mostrar que va a utilizar los datos guardados en el CurrentUser Sesión para determinar qué página pública del usuario que desee mostrar.

dejo esto como un ejercicio para que usted pueda averiguar en su UsersController bajo acción de la vista

Paso 4 los usuarios necesitan para entrar en el siguiente en sus registros de dominios A continuación, los usuarios necesitan para ir a su dominio registradores y hagan algo similar a los usuarios de BandCamp en el faq al que se ha vinculado.

  • del usuario subdominio "www" debe apuntar usando CNAME para example.Lucho.com

  • dominio raíz del usuario (sin www) debe tener un Registro que apunta a la dirección IP de su servidor es decir, donde su Lucho.com reside en

  • El usuario debe agregar ambas páginas de administración de dominios tal como se explicó anteriormente en la parte superior.El dominio puede tardar hasta 48 horas en actualizarse por completo.

+0

si necesita que haga una descripción detallada de todo, lo haré. Sólo házmelo saber. He dejado algunas partes en mi respuesta aquí. Las partes que dejé, creo que puedes trabajar por tu cuenta. Pero estaré feliz de escribir todo en detalles claros. La longitud de una respuesta súper detallada no es ideal para la respuesta stackoverflow –

+0

¡Finalmente alguien contestó! Creo que tu enfoque es bueno, pero me parece innecesario (al menos para mis necesidades) tener una relación hasMany entre el usuario y el dominio. Mis usuarios solo tendrán un dominio. También me mantendría alejado de guardar estos datos en la sesión, puede causar confusión más adelante. En general, me quedaría con mi enfoque porque parece más simple (aunque estoy seguro de que podría modificarse), pero el tuyo también funciona bien y las personas que buscan algo así en SO pueden encontrarlo útil. Muchas gracias. – luchomolina

+0

@luchomolina dijiste que tu pregunta principal seguía abierta. Entonces, ¿cuál es tu pregunta principal? –

Cuestiones relacionadas