2012-01-20 3 views
5

На моем сайте пользователи имеют общедоступные профили, к которым можно получить доступ через http://mysite.com/vanity_url. Я хочу разрешить пользователям указывать свои собственные домены на странице своего профиля на моем сайте. Just like Bandcamp does.Какой самый элегантный способ обработки пользовательских доменов?

Модель Profile имеет следующие два поля: vanity_url, что является обычным полем типа имени пользователя; и новый custom_domain, который является их собственным доменным именем, например, example.com.

Это то, что я сделал до сих пор, но я боюсь, что это не самый элегантный, безопасный и эффективный способ сделать это.

Во-первых, я убедился, что DocumentRoot для Apache установлен в каталог моего приложения webroot, поэтому я могу указать пользователям указать их DNS на IP-адрес моего сайта.

Теперь это как правила маршрутизации на моем routes.php выглядеть следующим образом:

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'); 
} 

И это, как view действие на ProfilesController выглядит следующим образом:

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')); 
} 

Какие проблемы я мог бы столкнуться с таким подходом?

Кроме того, кто-нибудь знает, почему Bandcamp просит пользователей создать CNAME вместо A запись о создании поддомена? Я что-то упускаю из виду?

Редактировать Кто-то помогло мне понять, что последний бит из: Кажется, вы не можете легко использовать запись CNAME, чтобы указать голый домен к другому. Главный вопрос по-прежнему остается открытым.

+0

вам не нужно трогать ваши маршруты честно. –

ответ

1

я сделал что-то подобное, используя торт 1,3 года назад

Есть 4 основных шага в этом решении:

  1. есть модель домена и домены DataTable, которая записывает все возможные пользовательские домены и представление для ваши пользователи должны ввести свои пользовательские домены
  2. создать код проверки домена в beforeFilter в AppController и сохранить данные пользователя на сеанс
  3. Действие контроллера, которое отвечает за просмотр общего профиля, должно ссылаться на те же данные пользователя, сохраненные в сессию
  4. пользователям нужны установить CNAME и A запись правильно с их доменными регистраторами

Шага моделью 1 домена и DataTable

То, что я сделал, я имела таблицу под названием домены

Каждый домен содержит веб-адрес, который я предположил как http: // ....

домена belongsTo пользователя

пользователя hasMany домена

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

главным является TINYINT, который указывает, является ли основной URL для использования, так как пользователя hasMany домена.

, так что вам нужно создать новую запись или больше для домена.

Шаг 2 Код в beforeFilter из AppController чтобы выяснить, какой профиль для отображения Далее, ваш код должен иметь возможность получить идентификатор пользователя на основе URL, представленных на каждом запросе HTTP.

Пользователь с этого момента указывает на пользователя, просмотр которого просматривается. Не путайте это с пользователем LoggedIn, если он у вас есть.

Предлагаю вам сделать это в своем beforeFilter of AppController.

Что-то вроде этого

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

Код для getByDomain для модели пользователя также упражнение для вас. Должно быть достаточно легко, учитывая, что я объяснил схему для доменов

Возможно, вам нужно будет проверить текущий пользователь в данных сеанса перед записью текущего пользователя, потому что вы не хотите постоянно записывать данные сеанса, особенно когда посетитель посещает ту же веб-страницу снова и снова.

Вы, возможно, потребуется изменить выше фрагмент кода на что-то вроде этого:

$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); 
    } 

Опять функция checkUrlAgainstDomain это упражнение для вас.

Шаг 3 Код в beforeFilter из AppController чтобы выяснить, какой профиль для отображения Вы будете использовать данные CurrentUser, сохраненные в вашей сессии, чтобы определить, какие пользователя публичной страницы, которую вы хотите отобразить.

Я оставляю это как упражнение для вас, чтобы выяснить, в вашем UsersController под видом действий

Шаг 4 пользователям необходимо ввести в состав своих регистраторами доменов Затем пользователи должны пойти в свой домен регистраторов и делать аналогичные вещи, как пользователи BandCamp в faq, с которыми вы связались.

  • «WWW» субдомен пользователя следует указать с помощью CNAME для example.Lucho.com

  • корневой домен пользователя (без WWW) должны иметь Запись, указывающие на IP-адрес вашего сервера, т.е. где ваш Lucho.com проживает в

  • Пользователь должен добавить обе обе страницы управления доменами, как объяснялось ранее в верхней части.Для полного обновления домена может потребоваться до 48 часов.

+0

Если вам нужно, чтобы я подробно описал все это, я сделаю это. Просто дай мне знать. В моем ответе я оставил некоторые части. Части, которые я забыл, я думаю, что вы можете работать самостоятельно. Но я буду счастлив написать все это в ясных подробностях. Длина супер подробного ответа не идеальна для ответа stackoverflow –

+0

Наконец-то кто-то ответил! Я думаю, что вы подход хороший, но я считаю ненужным (по крайней мере, для моих нужд) иметь hasMany отношения между пользователем и доменом. У моих пользователей будет только один домен. Я также избегаю сохранения этих данных на сеанс, это может привести к путанице позже. В общем, я придерживаюсь своего подхода, потому что это кажется более простым (хотя я уверен, что это может быть изменено), но ваш тоже хорошо работает, и люди, которые ищут что-то подобное на SO, могут оказаться полезными. Большое спасибо. – luchomolina

+0

@luchomolina вы сказали, что ваш главный вопрос по-прежнему открыт. Итак, каков ваш главный вопрос? –

 Смежные вопросы

  • Нет связанных вопросов^_^