Different Twig-Layout for Authentication in special controller? - symfony

I open a modal with an iFrame, which serve restriced pages of a special controller. So, when I'm not logged in, the iFrame redirects to the general login-route, which actually extends the standard-layout file.
Now, what I want to achieve is, that if the the user isn't logged in and opens up the modal, the login/registration page should extend a different layout (without navigation bar etc.).
So, how can I set a different layout for the authentication views, only if the user is redirected to it through the modal? Any advice?
Thanks!

I would pass along a request parameter from the IFrame, to let the controller know that the request came from the modal, e.g. path/to/your/page?ref=modal-iframe:
Then in the controller I would check if the request parameter is present and correct or the user is logged in. In that case you go on outputing your template, otherwise redirect to the general login route.
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MyController extends Controller
{
/*
* #Template("YourBundle:User:login_registration.html.twig")
*/
public function myAction(Request $request)
{
$securityContext = $this->container->get('security.context');
if (($request->get('ref') && $request->get('ref') == 'modal-iframe') ||
$securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return array();
}
else {
return new RedirectResponse($this->generateUrl('login'));
}
}
}
The template would then take care of loading the correct layout, depending on whether the user is logged in or not:
{% extends (app.user ? "layout1.html" : "layout2.html") %}

Related

How to redirect user after registration on Drupal 8?

How to redirect user to a particular page after the user is successfully registered into the site?
Here drupal_goto() does not work. We need to work with the form redirection. How can this be achieved?
// include the Url namespace in your custom module
use Drupal\Core\Url;
// Add CUSTOM SUBMIT HANDLER FOR REGISTRATION
$form['actions']['submit']['#submit'][] = '__tmp_registration_submit';
function __tmp_registration_submit(&$form, FormStateInterface $form_state) {
// set relative internal path
$redirect_path = "\user\uid\payment-history";
$url = url::fromUserInput($redirect_path);
// set redirect
$form_state->setRedirectUrl($url);
}
Maybe a bit heavy, but you could also use the Rules module.

Get data in twig function

Is it bad practice to get data from db in twig function or I should pass it to view in controller?
My function is some kind of interface widget that is used on all pages of site admin section. Then on data change I will have to make changes in all actions. But when I get data directly in extension class our teamlead tells that it's bad MVC.
It would be best if you pass it to a view from a controller.
Your team leader is right. What you can do is create an action specific to render that widget. I.e create a custom widget, let's say you want to show the number of current active users:
class WidgetController extends Controller
{
public function usersCountWidgetAction()
{
return $this->render('widget/usersCount.html.twig', array(
"usersCount" => $this->getUsersCount();
));
}
public function getUsersCount()
{
// call the manager and get the result
}
}
Now in all your other twigs you can use
{{ render(controller('AppBundle:Widget:usersCountWidget')) }}

Check User profile When change page Symfony2

I create User with FOSUserBundle, and when user created I create also a profile
User And Profile
I'd like that whenever the user changes the page, actually check that the user is navigating is authenticated and has also the profile
for now in my Controller i do
$user = $this->getUser();
if (!is_object($user)) { //i have to add || null !== $user->getProfile()
throw new AccessDeniedException('This user does not have access to this section.');
}
But I would not repeat this code in all controllers, and I would also check if the user has a profile, otherwise redirect to the home page
you can use JMSSecurityExtraBundle to add annotation for each action:
/**
* #Secure(roles="ROLE_USER, ROLE_FOO, ROLE_ADMIN")
*/
or without using of the bundle:
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}
its more simple. Maybe theres another solution to make it for all your controller but i don't know it.
You can use the request listener :
http://symfony.com/doc/current/cookbook/service_container/event_listener.html#request-events-checking-types
Just add your magic and redirect through the event to the homepage

Drupal 6 - Redirect Anonymous Users to Login Page

Drupal 6
I'm trying to make it so anonymous users can access a few overview pages, but if they click on any other menu item they'll be taken to the login page. Right now the way my site is set up, using the "Node Privacy by Role" module, I can restrict content based on whether or not the user is anonymous, but I can't leave the menu items visible if it's restricted. If I set a node to be not accessible for anonymous users, it just disappears from the menu.
Does anyone know if there is a way to restrict anonymous users from certain menu items, yet leave the menu items visible in the menu so when they click on them they get sent to the login page?
Hope the following links could help u.. :)
https://drupal.org/node/300607
https://drupal.stackexchange.com/questions/51523/content-access-module-hiding-menu-links
Though this question is old, and the OP asked for Drupal 6, I am gonna answer this for Drupal 7, 8, and 9 since it is one of the first results on Google.
When following this guide, it will be compatible for Drupal 8, and 9, but if you want to find the answer for Drupal 7, go to the bottom of the post.
First, you register the event subscriber in redirect_anonymous_users.services.yml in your module folder:
services:
redirect_anonymous_users.event_subscriber:
class: Drupal\redirect_anonymous_users\EventSubscriber\RedirectAnonymousSubscriber
arguments: []
tags:
- {name: event_subscriber}
Then add RedirectAnonymousSubscriber.php for your custom event subscriber in your module in the /src/EventSubscriber/ folder.
namespace Drupal\redirect_anonymous_users\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/**
* Event subscriber subscribing to KernelEvents::REQUEST.
*/
class RedirectAnonymousSubscriber implements EventSubscriberInterface {
public function checkAuthStatus(GetResponseEvent $event) {
if (
\Drupal::currentUser()->isAnonymous() &&
\Drupal::routeMatch()->getRouteName() != 'user.login'
) {
$response = new RedirectResponse('/user/login', 302);
$response->send();
}
}
/**
* {#inheritDoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('checkAuthStatus');
return $events;
}
}
Now for Drupal 7, go ahead and replace this line:
$response->send();
with these lines:
$event->setResponse($response);
$event->stopPropagation();

Check database fields on each request Symfony2

What I want to do if when a user loging check if he/she has all fields (user fields) complete in the database.
I can check when they loging those fields and then redirect to the profile view, but once they are in the profile view they still can see the menu, so they can easily go to others options and since they are already loging I cannot check it anymore in this way.
So I though that maybe using the controller Event listener I can check that, so I check is the controller is different to the accountController(which have the view to edit profile) and if is different I can check the fields.
The problem with that approach is in the accountController and in other controller they are twig {%render....%} that fires again the controller event and that give me infinity calls.
What approach would better? Thanks
Your idea of using the controller event (kernel.controller) to check for the fields is correct. In your event handler, you just need to check whether the request is the master request...
use Symfony\Component\HttpKernel\HttpKernel;
class FieldUpdater
{
/**
* Updates user's fields
*
* #param \Symfony\Component\HttpKernel\Event\FilterControllerEvent $event
*
* #return void
*/
public function onCoreController(FilterControllerEvent $event)
{
//if this isn't the main http request, then we aren't interested...
if (HttpKernel::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
// update fields
}
}
This way you won't end up with this being fired on every call to {% render ... %}

Resources