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)