Zend - условно перенаправить все страницы

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

Нет.htaccess перенаправляет, так как условие должно быть проверено в PHP

Вот что я хотел бы:

if( $condition ) {
    // Redirect ALL Pages/Requests
}

// else, continue dispatch as normal...

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

4 ответа

Решение

Действительно, я бы пошел на плагин.

В library/My/Plugin/ConditionallyRedirect.php:

class My_Plugin_ConditionallyRedirect extends Zend_Controller_Plugin_Abstract
{
    public function routeStartup(Zend_Http_Request_Abstract $request)
    {
        // perform your conditional check
        if ($this->_someCondition()){
             $front = Zend_Controller_Front::getInstance();
             $response = $front->getResponse();
             $response->setRedirect('/where/to/go');
        }
    }

    protected function _someCondition()
    {
        // return the result of your check
        return false; // for example
    }

}

Затем зарегистрируйте свой плагин в application/configs/application.ini с:

autoloaderNamespaces[]                        = "My_"
resources.frontController.plugins.conditional = "My_Plugin_ConditionallyRedirect"

Конечно, другие предпочтения / требования для префикса имени класса и для местоположения файла повлекут за собой несколько другие шаги для автозагрузки и вызова.

Зачем беспокоиться о маршрутизации? Просто простой редирект.

может быть что-то подобное в Bootstrap.php:

public function initSplash(){
    if($splashtime && $requestIsNotForComingSoonAlready){
        header('Location: /coming-soon',true,302);
        die();
    }
}

или вы можете просто вставить оператор if вверху вашего index.php и избежать полной загрузки фреймворка

Спасибо @David Weinraub, я пошел с плагином, похожим на ваш. Я должен был изменить пару вещей вокруг, вот мой окончательный результат (с некоторыми из моих специфических вещей приложения, упрощенных для примера здесь)

<?php

/**
 * Lanch project within valid dates, otherwise show the splash page
 */

class App_Launcher extends Zend_Controller_Plugin_Abstract
{
// The splash page
private $_splashPage = array(
    'module' => 'default',
    'controller' => 'coming-soon',
    'action' => 'index'
);

// These pages are still accessible
private $_whiteList = array(
    'rules' => array(
        'module' => 'default',
        'controller' => 'sweepstakes',
        'action' => 'rules'
    )
);


/**
 * Check the request and determine if we need to redirect it to the splash page
 * 
 * @param Zend_Controller_Request_Http $request
 * @return void
 */
public function preDispatch(Zend_Controller_Request_Http $request)
{
    // Redirect to Splash Page if needed
    if ( !$this->isSplashPage($request) && !$this->isWhiteListPage($request) && !$this->isSiteActive() ) {

        // Create URL for Redirect
        $urlHelper = new Zend_View_Helper_Url();
        $url = $urlHelper->url( $this->_splashPage );

        // Set Redirect
        $front = Zend_Controller_Front::getInstance();
        $response = $front->getResponse();
        $response->setRedirect( $url );

    }
}


/**
 * Determine if this request is for the splash page
 * 
 * @param Zend_Controller_Request_Http $request
 * @return bool
 */
public function isSplashPage($request) {

    if( $this->isPageMatch($request, $this->_splashPage) )
        return true;

    return false;

}


/**
 * Check for certain pages that are OK to be shown while not 
 * in active mode
 * 
 * @param Zend_Controller_Request_Http $request
 * @return bool
 */
public function isWhiteListPage($request) {

    foreach( $this->_whiteList as $page )
        if( $this->isPageMatch($request, $page) )
            return true;            

    return false;

}


/**
 * Determine if page parameters match the request 
 * 
 * @param Zend_Controller_Request_Http $request
 * @param array $page (with indexes module, controller, index)
 * @return bool
 */
public function isPageMatch($request, $page) {

    if(  $request->getModuleName() == $page['module']
      && $request->getControllerName() == $page['controller']
      && $request->getActionName() == $page['action'] )
        return true;

    return false;
}


/**
 * Check valid dates to determine if the site is active
 * 
 * @return bool
 */
protected function isSiteActive() {

    // We're always active outside of production
    if( !App_Info::isProduction() )
        return true;

    // Test for your conditions here...
    return false; 
            // ... or return true;

}

}

Есть место для некоторых улучшений, но сейчас это будет соответствовать моим потребностям. Примечание: мне пришлось изменить функцию обратно на preDispatch, потому что $ request не имел имен модулей, контроллеров и действий, доступных в routeStartup, что было необходимо для того, чтобы мы больше не перенаправляли запросы на страницу-заставку (вызывая бесконечный цикл перенаправления)

(Также добавлен "белый список" для других страниц, которые все еще должны быть доступны)

Если вы хотите сделать это правильно, вам нужно будет сделать это в классе после создания запроса, чтобы вы могли изменить его до отправки ответа. Обычно не совсем в начальной загрузке. Я бы сказал, поместите его где-нибудь с плагином, который имеет доступ к фронт-контроллеру (аналогично тому, как будет работать ACL)

Другие вопросы по тегам