Skip to content

Commit

Permalink
Change redirect strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielss89 committed Jul 3, 2014
1 parent 206ead0 commit 6dd4372
Show file tree
Hide file tree
Showing 6 changed files with 728 additions and 283 deletions.
12 changes: 12 additions & 0 deletions Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods;
use ZfcUser\Controller\RedirectCallback;

class Module implements
AutoloaderProviderInterface,
Expand Down Expand Up @@ -88,7 +89,18 @@ public function getServiceConfig()
'zfcuser_register_form_hydrator' => 'Zend\Stdlib\Hydrator\ClassMethods',
),
'factories' => array(
'zfcuser_redirect_callback' => function ($sm) {
/* @var RouteInterface $router */
$router = $sm->get('Router');

/* @var Application $application */
$application = $sm->get('Application');

/* @var ModuleOptions $options */
$options = $sm->get('zfcuser_module_options');

return new RedirectCallback($application, $router, $options);
},
'zfcuser_module_options' => function ($sm) {
$config = $sm->get('Config');
return new Options\ModuleOptions(isset($config['zfcuser']) ? $config['zfcuser'] : array());
Expand Down
18 changes: 16 additions & 2 deletions config/module.config.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
<?php
use ZfcUser\Controller\UserController;

return array(
'view_manager' => array(
'template_path_stack' => array(
'zfcuser' => __DIR__ . '/../view',
),
),
'controllers' => array(
'invokables' => array(
'zfcuser' => 'ZfcUser\Controller\UserController',

'factories' => array(
'zfcuser' => function($controllerManager){
/* @var ControllerManager $controllerManager*/
$serviceManager = $controllerManager->getServiceLocator();

/* @var RedirectCallback $redirectCallback */
$redirectCallback = $serviceManager->get('zfcuser_redirect_callback');

/* @var UserController $controller */
$controller = new UserController($redirectCallback);

return $controller;
},
),
),
'service_manager' => array(
Expand Down
116 changes: 116 additions & 0 deletions src/ZfcUser/Controller/RedirectCallback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace ZfcUser\Controller;

use Zend\Mvc\Application;
use Zend\Mvc\Router\RouteInterface;
use Zend\Mvc\Router\Exception;
use Zend\Http\PhpEnvironment\Response;
use ZfcUser\Options\ModuleOptions;

/**
* Returns a redirect response based on the current routing and parameters
*/
class RedirectCallback
{

/** @var RouteInterface */
private $router;

/** @var Application */
private $application;

/** @var ModuleOptions */
private $options;

/**
* @param Application $application
* @param RouteInterface $router
* @param ModuleOptions $options
*/
public function __construct(Application $application, RouteInterface $router, ModuleOptions $options)
{
$this->router = $router;
$this->application = $application;
$this->options = $options;
}

/**
* @return Response
*/
public function __invoke()
{
$routeMatch = $this->application->getMvcEvent()->getRouteMatch();
$redirect = $this->getRedirect($routeMatch->getMatchedRouteName(), $this->getRedirectRouteFromRequest());

$response = $this->application->getResponse();
$response->getHeaders()->addHeaderLine('Location', $redirect);
$response->setStatusCode(302);
return $response;
}

/**
* Return the redirect from param.
* First checks GET then POST
* @return string
*/
protected function getRedirectRouteFromRequest()
{
$request = $this->application->getRequest();
$redirect = $request->getQuery('redirect');
if ($redirect && $this->routeExists($redirect)) {
return $redirect;
}

$redirect = $request->getPost('redirect');
if ($redirect && $this->routeExists($redirect)) {
return $redirect;
}

return false;
}

/**
* @param $route
* @return bool
*/
protected function routeExists($route)
{
try {
$this->router->assemble([], ['name' => $route]);
} catch (Exception\RuntimeException $e) {
return false;
}
return true;
}

/**
* Returns the url to redirect to based on current route.
* If $redirect is set and the option to use redirect is set to true, it will return the $redirect url.
*
* @param string $currentRoute
* @param bool $redirect
* @return mixed
*/
protected function getRedirect($currentRoute, $redirect = false)
{
$useRedirect = $this->options->getUseRedirectParameterIfPresent();
$routeExists = ($redirect && $this->routeExists($redirect));
if (!$useRedirect || !$routeExists) {
$redirect = false;
}

switch ($currentRoute) {
case 'zfcuser/login':
$route = ($redirect) ?: $this->options->getLoginRedirectRoute();
return $this->router->assemble([], ['name' => $route]);
break;
case 'zfcuser/logout':
$route = ($redirect) ?: $this->options->getLogoutRedirectRoute();
return $this->router->assemble([], ['name' => $route]);
break;
default:
return $this->router->assemble([], ['name' => 'zfcuser']);
}
}
}
30 changes: 20 additions & 10 deletions src/ZfcUser/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ class UserController extends AbstractActionController
*/
protected $options;

/**
* @var callable $redirectCallback
*/
protected $redirectCallback;

/**
* @param callable $redirectCallback
*/
public function __construct($redirectCallback)
{
if (!is_callable($redirectCallback)) {
throw new \InvalidArgumentException('You must supply a callable redirectCallback');
}
$this->redirectCallback = $redirectCallback;
}

/**
* User page
*/
Expand Down Expand Up @@ -115,13 +131,9 @@ public function logoutAction()
$this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
$this->zfcUserAuthentication()->getAuthService()->clearIdentity();

$redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));

if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
return $this->redirect()->toRoute($redirect);
}
$redirect = $this->redirectCallback;

return $this->redirect()->toRoute($this->getOptions()->getLogoutRedirectRoute());
return $redirect();
}

/**
Expand Down Expand Up @@ -154,11 +166,9 @@ public function authenticateAction()
);
}

if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {

This comment has been minimized.

Copy link
@derlhurgoyf

derlhurgoyf Jan 15, 2015

Removing this breaks redirects from the loginAction as in this use case
http://stackoverflow.com/questions/25001558/zfcuser-redirect-dynamic-url-after-login
Now the redirect parameter passed to the loginAction is totally ignored in the authenticateAction.
How is this supposed to work now?

return $this->redirect()->toRoute($redirect);
}
$redirect = $this->redirectCallback;

return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
return $redirect();
}

/**
Expand Down
Loading

0 comments on commit 6dd4372

Please sign in to comment.