Wermerb Wermerb - 3 months ago 7
PHP Question

ZfcUser redirect dynamic url after login

I'm learning to develop a website with ZF2. I have downloaded 2 modules ZfcUser and BjyAuthorize.
The configurations was fairly straight forward after i read the documentations. How ever i did not find any solution for the following situation:


Guest lands on a blog post (www.yourdomain.com/blog/541) ->
BjyAuthorize will redirect guest to the login page -> after successful
login redirect to www.yourdomian.com/blog/541


I have a solution for the redirection when a guest arriving for a restricted area:

public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$app->getEventManager()->attach(
'route',
function($e) {
$app = $e->getApplication();
$routeMatch = $e->getRouteMatch();
$sm = $app->getServiceManager();
$auth = $sm->get('zfcuser_auth_service');
if (!$auth->hasIdentity() && $routeMatch->getMatchedRouteName() != 'user/login'
&& $routeMatch->getMatchedRouteName() != 'zfcuser/login') {
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine(
'Location',
$e->getRouter()->assemble(
array(),
array('name' => 'zfcuser/login')
)
);
$response->setStatusCode(302);
return $response;
}
},
-100
);
}


But i don't know how should i extend this to solve the above explained action.

Any help is greatly appreciated.

UPDATE

My route:

'blog' => array(
'type' => 'Segment',
'options' => array(
'route' => '/blog/:id',
'constraints' => array (
'id' => '[0-9]+'
),
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'view',
),
),
),


This is my Zfcuser config:

return array(
'zfcuser' => array(
'password_cost' => 4,
'login_after_registration' => true,
'use_redirect_parameter_if_present' => true,
'enable_display_name' => true
)


);

After your updated code i see it should be worked this is what happening with the URL:

http://localhost:10088/BlogProject/user/login?redirect=/BlogProject/blog/1


But when i try to login i received this error:

Route with name "" not found


UPDATE 2

Zend\Mvc\Router\Exception\RuntimeException
File:
/usr/local/zend/var/apps/http/__default__/0/ProjectManager/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/TreeRouteStack.php:317
Message:
Route with name "" not found

Stack trace:
#0 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Url.php(99): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)
#1 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Redirect.php(48): Zend\Mvc\Controller\Plugin\Url->fromRoute('/BlogProject...', Array, Array, false)
#2 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zf-commons/zfc-user/src/ZfcUser/Controller/UserController.php(158): Zend\Mvc\Controller\Plugin\Redirect->toRoute('/BlogProject...')
#3 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): ZfcUser\Controller\UserController->authenticateAction()
#4 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#5 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#6 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#7 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Forward.php(138): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#9 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zf-commons/zfc-user/src/ZfcUser/Controller/UserController.php(106): Zend\Mvc\Controller\Plugin\Forward->dispatch('zfcuser', Array)
#10 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): ZfcUser\Controller\UserController->loginAction()
#11 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#12 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#13 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#16 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#17 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#18 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#19 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(313): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#20 /usr/local/zend/var/apps/http/__default__/0/BlogProject/1.0.0_46/public/index.php(12): Zend\Mvc\Application->run()
#21 {main}


This is my viewAction:

public function viewAction()
{
$flashMsg = $this->flashMessenger();
if($flashMsg->hasMessages()){
$variables['success'] = $flashMsg->getMessages()[0];
$flashMsg->clearMessages();
}
$variables['blogs'] = $this->mapper->getAllMyBlogs($this->zfcUserAuthentication()->getIdentity()->getId());
$variables['contributedBlogs'] = $this->mapper->getAllMyContributedBlogs($this->zfcUserAuthentication()->getIdentity()->getId());
$variables['activeBlog'] = $this->getEvent()->getRouteMatch()->getParam('id');
$this->vm->setVariables($variables);
$this->vm->setTemplate('application/index/index.phtml');
return $this->vm;
}


SOLUTION

I've found the solution:

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


This one is has to be changed:

if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
return $this->redirect()->toUrl($redirect);
}


And your code will work totally fine.
You can find it in UserController line 157.

Answer

You can take advantage of the use_redirect_parameter_if_present option implemented in ZfcUser. If it's set to true (which is by default), and you add a redirect parameter to the login route, it will automatically redirects you to this route once you're logged. Your function could be:

$eventManager->attach( MvcEvent::EVENT_ROUTE, function( $e ) use ( $serviceManager ) {
    $routeMatch = $e->getRouteMatch();

    $auth = $serviceManager->get('zfcuser_auth_service');
    if (!$auth->hasIdentity() && $routeMatch->getMatchedRouteName() != 'user/login'
            && $routeMatch->getMatchedRouteName() != 'zfcuser/login') {
            //GENERATE THE URL FROM CURRENT ROUTE (YOUR blog ONE)
            $redirect = $e->getRouter()->assemble(
                $routeMatch->getParams(),
                array(
                    'name' => $routeMatch->getMatchedRouteName(),
                )
            );

            $response = $e->getResponse();
            $response->getHeaders()->addHeaderLine(
                'Location',
                $e->getRouter()->assemble(
                    array(),
                    array(
                        'name' => 'zfcuser/login',
                        'query' => array( 'redirect' => $redirect )
                    )
                )
            );
            $response->setStatusCode(302);
            return $response;
        }

    } );