Redirect to internal URL after login - Drupal 8 - drupal

On my D8 site I want to redirect all users to an internal URL after they login. below is my snippet:
function mymodule_user_login($account) {
$url = Url::fromUri('internal:/dashboard-overview');
$response = new RedirectResponse($url->toString());
$response->send();
}
This snippet redirects to "Access denied" error page even for administrators. There is no permission set to visit this URL. Still the page is not loading even for admins. Any help ?

Have you tried this module? https://www.drupal.org/project/redirect_after_login
i think it will do the task you are looking for.

Drupal 8 and 9
You need to alter the login form and add a submit handler which will take care of the redirection. You cannot use $form_state->setRedirectUrl() directly in the form alter, since it will be overwritten by UserForm::submitForm().
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_user_login_form_alter(&$form, FormStateInterface $form_state) {
$form['#submit'][] = 'mymodule_user_login_submit';
}
/**
* Form submission handler for user_login_form().
*
* Redirects the user to the dashboard after logging in.
*/
function mymodule_user_login_submit(&$form, FormStateInterface $form_state) {
$url = Url::fromRoute('mymodule.dashboard');
// Check if a destination was set, probably on an exception controller.
// #see \Drupal\user\Form\UserLoginForm::submitForm()
$request = \Drupal::service('request_stack')->getCurrentRequest();
if (!$request->request->has('destination')) {
$form_state->setRedirectUrl($url);
}
else {
$request->query->set('destination', $request->request->get('destination'));
}
}

Related

Mail Attachment not send when using Cron

Email Attachment is sent correctly when I call my function by visiting the url that I set with the hook menu
EX :When I visit /admin/config/send the hook_menu will call main() method and send the email with the attachment.
but when I call the same function main() from inside the hook_cron() the mail is sent(body and message is set) but not with the attachment :
function hook_cron(){
main();
}
Sounds like you have to ensure the cron is executed with an authenticated/admin user loaded.
In Drupal 8 this would be like following (source).
use Drupal\user\Entity\User;
/**
* Implements hook_cron().
*/
function my_module_cron() {
// Login as user 1
$user = User::load(1);
user_login_finalize($user);
// Your custom cron functions
// Login as user 0 (anonymous)
$user = User::load(0);
user_login_finalize($user);
}

403 "rest_forbidden" error in WordPress REST API (but only for settings)?

i got all API from WordPress except settings (/wp/v2/settings). its returning rest_forbidden error
{
"code": "rest_forbidden",
"message": "Sorry, you are not allowed to do that.",
"data": {
"status": 403
}
}
Your user does not have the correct permissions to access the data at that route. Out of the box the /settings/ route requires the manage_options permission (see the get_item_permissions_check method).
// found in WP Core class-wp-rest-settings-controller.php
/**
* Checks if a given request has access to read and manage settings.
*
* #since 4.7.0
*
* #param WP_REST_Request $request Full details about the request.
* #return bool True if the request has read access for the item, otherwise false.
*/
public function get_item_permissions_check( $request ) {
return current_user_can( 'manage_options' );
}
What user is associated with the API credentials?
The settings endpoint needs the user to have manage_options permission; if you're using a custom role, you can add it with
"manage_options" => true;
Otherwise just make the user Administrator role.
If somebody has an issue then try installing this plugin: https://wordpress.org/plugins/application-passwords/
Generate an application password from your profile and use that with basic auth, your username will be the same as WordPress username or email and the password will be new generated password.
You may also need to add HTTP header rewrite rule in your .htaccess file, for that please follow: https://github.com/WordPress/application-passwords/wiki/Basic-Authorization-Header----Missing

symfony 3 session flashdata not working

use Symfony\Component\HttpFoundation\Session\Session;
...
public function __construct()
{
//echo ini_get('session.auto_start'); die;
$this->session = new Session();
/**
* #Route("/", name="registration_index")
* #Route("/user/registration", name="registration")
* #Method("GET")
*/
public function indexAction()
{
//$this->session->getFlashBag()->add('notice', 'Profile updated');
$errors = $this->session->getFlashBag()->get('notice', array());
print_r($errors);
return $this->render('registration.html.twig', ['errors' => $errors]);
}
/**
* #Route("/user/registration", name="post_registration")
* #Method("POST")
* #return mixed
*/
public function postAction()
{
//$this->session->getFlashBag()->add('errors', 'hahaha');
$this->session->getFlashBag()->add('notice', 'Profile updated');
return $this->redirectToRoute('registration');
}
I will want to display error messages near input fields if there is registration failure. Trying to use session flashdata.
When user goes to postAction method, he is redirected to indexAction. But
print_r($errors);
prints empty array. Why is that? Without redirect - it works ok.
This was not symfony problem, but php server problem. Even code examples from php manual without symfony did not work.
I was running server like this:
php -S 0.0.0.0:8000
and for some reasons the session did not work on it.
When I started using nginx server, session started working.
Is there a reason why you are not using symfony Forms to get this functionality? Symfony Forms are perfect for registration pages.
By the way, if you are doing this in a controller then you don't need the constructor method. Instead get the session from Request->getSession()
I confirm that WebCookie sais in his comment: In the controller please use $this->addFlash() if your need to add a flash message within a controller.
Notice you can also use session service like this: $this->get('session')->getFlashBag()->add()
For further informations Flash messages.

PreExecute() function in symfony2

I developed an application using symfony2, I want to know how to write preExecute() function symfony2 for following case:
when I log-in into the system; it redirect me on user profile section when I log-out from same screen, It killed session and redirect me on login screen, but when I hit browser's back button then it will redirect me on profile screen, which shows me all user information but when I click for next process from same screen then I redirect me on login page.
I just want to add preExecute function like symfony1.4 for this case, so I checked session and if it is null then it will redirect me on login page if I hit browser's back button when I alrady log-out from the system.
I already added following code in profileController.php files,
public function indexAction() {
$session = $this->get('request')->getSession();
$userId = $session->get('id');
if ($userId == 0 || $userId == '') {
return $this->redirect($this->generateUrl('_security_login'));
} else {
//my code
}
}
//logout action
public function dologoutAction(){
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$this->container->get('request')->getSession('session')->clear();
return $this->redirect($this->generateUrl('_security_login'));
}
if there is any other way to handle this case then please help me for the same.
Thank you.
Just require the ROLE_USER role on the profile action and the firewall will do the redirect-to-the-login-form-and-then-redirect-back stuff:
/**
* #Secure("ROLE_USER")
*/
public function profileAction()
{
// ...
}
For more information read the Security chapter of the Symfony book.

Symfony2 Templating without request

I'm trying to send an email from a ContainerAwareCommand in Symfony2. But I get this exception when the email template is render by:
$body = $this->templating->render($template, $data);
Exception:
("You cannot create a service ("templating.helper.assets") of an inactive scope ("request").")
I found in github that this helper need the request object. Anybody knows how can I to instance the Request object?
You need to set the container into the right scope and give it a (fake) request. In most cases this will be enough:
//before you render template add bellow code
$this->getContainer()->enterScope('request');
$this->getContainer()->set('request', new Request(), 'request');
The full story is here. If you want to know the details read this issue on github.
The problem arises because you use asset() function in your template.
By default, asset() relies on Request service to generate urls to your assets (it needs to know what is the base path to you web site or what is the domain name if you use absolute asset urls, for example).
But when you run your application from command line there is no Request.
One way to fix this it to explicitely define base urls to your assets in config.yml like this:
framework:
templating:
assets_base_urls: { http: ["http://yoursite.com"], ssl: ["http://yoursite.com"] }
It is important to define both http and ssl, because if you omit one of them asset() will still depend on Request service.
The (possible) downside is that all urls to assets will now be absolute.
Since you don't have a request, you need to call the templating service directly like this:
$this->container->get('templating')->render($template, $data);
Following BetaRide's answer put me on the right track but that wasn't sufficient. Then it was complaining: "Unable to generate a URL for the named route "" as such route does not exist."
To create a valid request I've modified it to request the root of the project like so:
$request = new Request();
$request->create('/');
$this->container->enterScope('request');
$this->container->set('request', $request, 'request');
You might need to call a different route (secured root?), root worked for me just fine.
Symfony2 Docs
Bonus addition:
I had to do so much templating/routing in cli through Symfony2 commands that I've updated the initializeContainer() method in AppKernel. It creates a route to the root of the site, sets the router context and fakes a user login:
protected function initializeContainer()
{
parent::initializeContainer();
if (PHP_SAPI == 'cli') {
$container = $this->getContainer();
/**
* Fake request to home page for cli router.
* Need to set router base url to request uri because when request object
* is created it perceives the "/portal" part as path info only, not base
* url and thus router will not include it in the generated url's.
*/
$request = Request::create($container->getParameter('domain'));
$container->enterScope('request');
$container->set('request', $request, 'request');
$context = new RequestContext();
$context->fromRequest($request);
$container->get('router')->setContext($context);
$container->get('router')->getContext()->setBaseUrl($request->getRequestUri());
/**
* Fake admin user login for cli. Try database read,
* gracefully print error message if failed and continue.
* Continue mainly for doctrine:fixture:load when db still empty.
*/
try {
$user = $container->get('fos_user.user_manager')->findUserByUsername('admin');
if ($user !== null) {
$token = $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->getContainer()->get('security.token_storage')->setToken($token);
}
} catch (\Exception $e) {
echo "Fake Admin user login failed.\n";
}
}
}
You might not need the last $container->get('router')->getContext()->setBaseUrl($request->getRequestUri()); part, but I had to do it because my site root was at domain.com/siteroot/ and the router was stripping /siteroot/ away for url generation.

Resources