CakePHP Subdomain Routing & Misc - PullRequest
       11

CakePHP Subdomain Routing & Misc

2 голосов
/ 20 марта 2012

Справочная информация: создание веб-приложения (как введение в CakePHP), которое позволяет пользователям управлять комнатой отдыха. Зал состоит из блога, контактов, календаря и т. Д. Каждый зал связан с поддоменом (поэтому jcotton.lounger.local приведет вас в мой зал). Корень сайта, используемый для создания новых залов, регистрации пользователей и т. Д., Размещен на сайте lounger.local. Я использую Cake 2.0.

Вопросы:

  1. Я хотел иметь возможность отделить действия и представления, связанные с корневым сайтом (lounger.local), от отдельных залов (поддоменов lounger.local). После долгих исследований я остановился на следующем soln. Я установил префикс маршрута "lounge" и добавил следующий код в rout.php. Действия (и представления), связанные с комнатой отдыха, содержат префикс зала (например: lounge_index ()). Как бы вы справились с этим?

         if(preg_match('/^([^.]+)\.lounger\.local$/',env("HTTP_HOST"),$matches)){
               $prefix = "lounge";
               Router::connect('/', array('controller' => 'loungememberships','action' => 'index', 'prefix' => $prefix, $prefix => true));
               /* Not currently using plugins
               Router::connect("/:plugin/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
               Router::connect("/:plugin/:controller/:action/*", array('prefix' => $prefix, $prefix => true));
               */
               Router::connect("/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
               Router::connect("/:controller/:action/*", array('prefix' => $prefix, $prefix => true));
               unset($prefix);
          }
    
  2. Каждый раз, когда пользователь выполняет действие в гостевой комнате, такое как публикация комментария в блоге, добавление контакта и т. Д., Необходимо искать lounge_id (на основе субдомена); это необходимо для проверки того, что пользователь имеет право выполнять это действие, и для сопоставления соответствующих данных с правильным залом. Я реализовал это с помощью функции beforeFilter в AppController. Каждый раз, когда запрос получен с субдомена, выполняется поиск, и lounge_id записывается в переменную сеанса. Каждый контроллер затем загружает CakeSession и читает соответствующий lounge_id. Это лучше, чем вызывать ClassRegistry :: Init ('Lounge') и выполнять поиск в каждом контроллере? Есть ли лучшее солнце?

Заранее спасибо за помощь

1 Ответ

5 голосов
/ 06 августа 2012

Способ, которым я подошел к этому, был с пользовательским маршрутом и некоторыми хитростями с конфигурацией маршрута, подобной вашему примеру.

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

Configure::write('Domain.Master', 'mastersite.local');
Configure::write('Domain.DefaultRoute', array('controller' => 'sites', 'action' => 'add'));

Далее я создал DomainRoute класс маршрута в /Lib/Route/DomainRoute.php:

<?php
App::uses('CakeRoute', 'Routing/Route');
App::uses('CakeResponse', 'Network');
App::uses('Cause', 'Model');

/**
 * Domain Route class will ensure a domain has been setup before allowing
 * users to continue on routes for that domain. Instead, it redirects them
 * to a default route if the domain name is not in the system, allowing
 * creation of accounts, or whatever.
 *
 * @package default
 * @author Graham Weldon (http://grahamweldon.com)
 */
class DomainRoute extends CakeRoute {

/**
 * A CakeResponse object
 *
 * @var CakeResponse
 */
    public $response = null;

/**
 * Flag for disabling exit() when this route parses a url.
 *
 * @var boolean
 */
    public $stop = true;

/**
 * Parses a string url into an array. Parsed urls will result in an automatic
 * redirection
 *
 * @param string $url The url to parse
 * @return boolean False on failure
 */
    public function parse($url) {
        $params = parent::parse($url);
        if ($params === false) {
            return false;
        }

        $domain = env('HTTP_HOST');
        $masterDomain = Configure::read('Domain.Master');

        if ($domain !== $masterDomain) {
            $defaultRoute = Configure::read('Domain.DefaultRoute');
            $Cause = new Cause();
            if (!($Cause->domainExists($domain)) && $params != $defaultRoute) {
                if (!$this->response) {
                    $this->response = new CakeResponse();
                }

                $status = 307;
                $redirect = $defaultRoute;
                $this->response->header(array('Location' => Router::url($redirect, true)));
                $this->response->statusCode($status);
                $this->response->send();
                $this->_stop();
            }
            $params['domain'] = $domain;
        }

        return $params;
    }

/**
 * Stop execution of the current script.  Wraps exit() making
 * testing easier.
 *
 * @param integer|string $status see http://php.net/exit for values
 * @return void
 */ 
    protected function _stop($code = 0) {
        if ($this->stop) {
            exit($code);
        }
    }

}

Этот пользовательский класс маршрута используется в /Config/routes.php файл для настройки мультитенантности.

if (env('HTTP_HOST') === Configure::read('Domain.Master')) {
    // Master domain shows the home page.
    $rootRoute = array('controller' => 'pages', 'action' => 'display', 'home');
} else {
    // Subdomains show  the cause view page.
    $rootRoute = array('controller' => 'causes', 'action' => 'view', env('HTTP_HOST'));
}
Router::connect('/', $rootRoute, array('routeClass' => 'DomainRoute'));

При проверке пользовательского маршрутизатора вы увидите, что я извлекаю текущий домен, к которому осуществляется доступ, и добавляю его в массив $params.

Несмотря на то, что это не позволяет напрямую достичь того, чего вы хотите, незначительные изменения помогут вам в правильном соответствии с вашими требованиями.О пользовательских маршрутах не так много информации, но вот ссылка на документацию CakePHP для пользовательских классов маршрутов.

Надеюсь, это поможет!

...