0

We have a plugin that logs you in and out of a third party service.

Login is easy as we can POST to a controller action, but for logout, we have a link that goes straight to an action URL.

My problem is that I want to redirect back to the URL the user submitted from, with some data that we use in the view (a message to say you've logged out).

redirectToPostedUrl() is no good as this isn't a POST request, and from what I can see in the docs redirect() doesn't give us the option to add data and anything we add in craft()->urlManager->setRouteVariables() doesn't come through when you redirect.

And if we don't redirect or return, we get a 404 as the user is just left on the controller action URL, for which there is no template output.

2 Answers 2

1

$_SERVER['HTTP_REFERER'] should give you the url the request was coming from, which you can then pass in to the redirect function. You could add some URL parameters like ?message='Logged%20out!' and have your template check for the message existing and display it.

Be aware that this function comes with a small caveat from the PHP documentation:

The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

Here's the full documentation on the PHP $_SERVER array.

Edit: Other Option Using a Form

It might be a little bit clunky, but you would have the like to logout actually be a form submit. You could post the current URL to your controller and use craft()->urlManager->setRouteVariables(array('message' => $myMessageObject)); to send your message back to the user.

Form:

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="{{ actionUrl('pluginHandle/controller/method', { return: 'this/page/url' }) }}">
    <input type="submit" value="{{ 'Log out'|t }}">
</form>

All you'll need is a little bit of CSS to style the submit link, or even somme javascript to trigger the form submit. If you wanted to get even fancier, you could AJAX the request and avoid the form all together.

Here's the documentation on posting to controller actions for reference.

3
  • I was hoping for something more native to craft, where we could pass anything back such as a model. Same was we can with POSTed actions
    – Russ Back
    Commented Apr 11, 2015 at 6:18
  • I've added an answer that works without using referrer, still not as good as I'd like as it's limited to a string.
    – Russ Back
    Commented Apr 11, 2015 at 6:27
  • Hey @RussBack - just edited my answer with an alternative solution. I think AJAXing the request would probably be most elegant, but a form works too! Commented Apr 11, 2015 at 13:59
0

I can do this:

<a href="{{ actionUrl('pluginHandle/controller/method', { return: 'this/page/url' }) }}">Log out</a>

And in my plugin method:

public function actionLogout ($return)
{
    // do something with an external API here

    $this->redirect("{$return}?message=You have been logged out", $terminate = true, $statusCode = 302);
}

That's OK for a simple message but I was hoping we could pass something back outside of the URL in the same we can with POSTed actions, and also not be limited to what that data is, for example passing back an array or a model instance.

1
  • 1
    Are you providing an answer to the question? Or is this simply an extension to your original question? If so, I'd recommend editing your original question to show your though process so far. Posting it as an answer indicates you're considering it as a viable solution.
    – Lindsey D
    Commented Apr 11, 2015 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.