Answers.Body: <p>AGH: my problem was only that the redirect value I was passing was incomplete, which caused the template I was redirecting to to itself redirect elsewhere.</p>
  
  <p>Complete solution:</p>
  
  <pre><code>&lt;form action="" method="POST"&gt;
      &lt;input type="hidden" name="action" value="myplugin/mycontroller/myaction"&gt;
      &lt;input type="hidden" name="redirect" value="{{ craft.request.path }}?{{ craft.request.queryStringWithoutPath }}"&gt;{# redirect back to this page #}
      &lt;input type="hidden" name="orderNumber" value="{{ number }}"&gt;
      &lt;input type="submit" class="button warning" value="Disable date restrictions &amp;amp; impersonate customer"/&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>The controller action:</p>
  
  <pre><code>public function actionMyAction()
  {
  
      // basic security precautions
      $this-&gt;requirePostRequest();
      $this-&gt;requireAdmin();
  
      ... some stuff not relevant to the question ...
  
      // get the user we want to impersonate
      $originalUserId = craft()-&gt;userSession-&gt;getId();
      $orderOwnerId = $order-&gt;customer-&gt;user-&gt;id;
  
      // impersonate the user
      craft()-&gt;httpSession-&gt;add(UserSessionService::USER_IMPERSONATE_KEY, $originalUserId);
  
      if (craft()-&gt;userSession-&gt;loginByUserId($orderOwnerId))
      {
          craft()-&gt;userSession-&gt;setNotice(Craft::t('Logged in.'));
          $this-&gt;redirectToPostedUrl();
      }
      else
      {
          craft()-&gt;httpSession-&gt;remove(UserSessionService::USER_IMPERSONATE_KEY);
          craft()-&gt;userSession-&gt;setError(Craft::t('There was a problem impersonating this user.'));
          Craft::log(craft()-&gt;userSession-&gt;getUser()-&gt;username.' tried to impersonate userId: '.$userId.' but something went wrong.', LogLevel::Error);
          }
      }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-11-11T10:25:43.900Z
Answers.LastActivityDate: 2016-11-11T10:25:43.900Z
Answers.UserDisplayName: Matt Wilcox
Answers.Body: <p>Since this is an action in your own plugin's controller, you can literally do anything you want after the login happens.</p>
  
  <pre><code>if (craft()-&gt;userSession-&gt;loginByUserId($orderOwnerId))
  {
      $this-&gt;redirect('https://www.reddit.com/');
  }
  </code></pre>
  
  <blockquote>
    <p>if I uncomment the <code>$this-&gt;_handleSuccessfulLogin(true);</code> line I get an error.</p>
  </blockquote>
  
  <p>Because that's a private method you probably didn't copy over from Craft's <code>UsersController.php</code>.  You don't have to use it if you don't want to.</p>
  
  <blockquote>
    <p>it says the function is deprecated (<a href="https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail" rel="nofollow noreferrer">https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail</a>)</p>
  </blockquote>
  
  <p>Same method name (mostly), but not in the UsersController... it's on the UsersService.  It's also public, not private.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-11-11T09:59:03.027Z
Answers.Text: Thanks Brad,
  
  If that's the case, why doesn't $this->redirectToPostedUrl(); work? Am I right in understanding that should use the URL that was passed via a `<input type='hidden' name='redirect' value='/wherever'>` field in the form?
Answers.UserDisplayName: Matt Wilcox
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-11-10T23:46:12.013Z
Answers.LastActivityDate: 2016-11-10T23:46:12.013Z
Answers.UserDisplayName: Brad Bell
Body: <p>Part of a plugin I am writing needs to handle impersonating a user, in the same way that Craft offers the built in "Log in as X" for admins in the back end.</p>
  
  <p>I have that working by essentially copying the <code>/app/controllers/UsersController actionImpersonate()</code> function into my plugin.</p>
  
  <p>However, when the action is run, the newly logged in user is always being redirected to the homepage - which makes sense as it's the default page that front-end logins go to. But, I want to override it. I want my plugin to take them to a page I dynamically set. I can't seem to get it to happen. Here's my code:</p>
  
  <pre><code>public function actionMyAction()
  {
  
      // basic security precautions
      $this-&gt;requirePostRequest();
      $this-&gt;requireAdmin();
  
      ... some stuff not relevant to the question ...
  
      // get the user we want to impersonate
      $originalUserId = craft()-&gt;userSession-&gt;getId();
      $orderOwnerId = $order-&gt;customer-&gt;user-&gt;id;
  
      // impersonate the user
      craft()-&gt;httpSession-&gt;add(UserSessionService::USER_IMPERSONATE_KEY, $originalUserId);
  
      if (craft()-&gt;userSession-&gt;loginByUserId($orderOwnerId))
      {
          craft()-&gt;userSession-&gt;setNotice(Craft::t('Logged in.'));
          // $this-&gt;_handleSuccessfulLogin(true);
          $this-&gt;redirectToPostedUrl();
      }
      else
      {
          craft()-&gt;httpSession-&gt;remove(UserSessionService::USER_IMPERSONATE_KEY);
          craft()-&gt;userSession-&gt;setError(Craft::t('There was a problem impersonating this user.'));
          Craft::log(craft()-&gt;userSession-&gt;getUser()-&gt;username.' tried to impersonate userId: '.$userId.' but something went wrong.', LogLevel::Error);
          }
      }
  }
  </code></pre>
  
  <p>I'm expecting that to redirect the newly logged in user to the page that the form was posted from - but it doesn't. Also, and I don't know if it's related, if I uncomment the <code>$this-&gt;_handleSuccessfulLogin(true);</code> line I get an error. That line is not commented out in the original function, and looking at the Craft docs to try and learn what it does, it says the function is deprecated ( <a href="https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail" rel="nofollow noreferrer">https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail</a> )</p>
  
Tags: <plugin-development><users>
Title: Impersonating a User from a plugin, with specific page redirect
ThreadText: # Impersonating a User from a plugin, with specific page redirect
  
  (Asked by: username_0 on 2016-11-10)
  
  Part of a plugin I am writing needs to handle impersonating a user, in the same way that Craft offers the built in "Log in as X" for admins in the back end.
  
  I have that working by essentially copying the `/app/controllers/UsersController actionImpersonate()` function into my plugin.
  
  However, when the action is run, the newly logged in user is always being redirected to the homepage - which makes sense as it's the default page that front-end logins go to. But, I want to override it. I want my plugin to take them to a page I dynamically set. I can't seem to get it to happen. Here's my code:
  
  ```
  public function actionMyAction()
  {
  
      // basic security precautions
      $this->requirePostRequest();
      $this->requireAdmin();
  
      ... some stuff not relevant to the question ...
  
      // get the user we want to impersonate
      $originalUserId = craft()->userSession->getId();
      $orderOwnerId = $order->customer->user->id;
  
      // impersonate the user
      craft()->httpSession->add(UserSessionService::USER_IMPERSONATE_KEY, $originalUserId);
  
      if (craft()->userSession->loginByUserId($orderOwnerId))
      {
          craft()->userSession->setNotice(Craft::t('Logged in.'));
          // $this->_handleSuccessfulLogin(true);
          $this->redirectToPostedUrl();
      }
      else
      {
          craft()->httpSession->remove(UserSessionService::USER_IMPERSONATE_KEY);
          craft()->userSession->setError(Craft::t('There was a problem impersonating this user.'));
          Craft::log(craft()->userSession->getUser()->username.' tried to impersonate userId: '.$userId.' but something went wrong.', LogLevel::Error);
          }
      }
  }
  
  ```
  
  I'm expecting that to redirect the newly logged in user to the page that the form was posted from - but it doesn't. Also, and I don't know if it's related, if I uncomment the `$this->_handleSuccessfulLogin(true);` line I get an error. That line is not commented out in the original function, and looking at the Craft docs to try and learn what it does, it says the function is deprecated ( <https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail> )
  
  **Tags:** plugin-development, users
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2016-11-11. Score: 1 | Accepted answer
  
  AGH: my problem was only that the redirect value I was passing was incomplete, which caused the template I was redirecting to to itself redirect elsewhere.
  
  Complete solution:
  
  ```
  <form action="" method="POST">
      <input type="hidden" name="action" value="myplugin/mycontroller/myaction">
      <input type="hidden" name="redirect" value="{{ craft.request.path }}?{{ craft.request.queryStringWithoutPath }}">{# redirect back to this page #}
      <input type="hidden" name="orderNumber" value="{{ number }}">
      <input type="submit" class="button warning" value="Disable date restrictions &amp; impersonate customer"/>
  </form>
  
  ```
  
  The controller action:
  
  ```
  public function actionMyAction()
  {
  
      // basic security precautions
      $this->requirePostRequest();
      $this->requireAdmin();
  
      ... some stuff not relevant to the question ...
  
      // get the user we want to impersonate
      $originalUserId = craft()->userSession->getId();
      $orderOwnerId = $order->customer->user->id;
  
      // impersonate the user
      craft()->httpSession->add(UserSessionService::USER_IMPERSONATE_KEY, $originalUserId);
  
      if (craft()->userSession->loginByUserId($orderOwnerId))
      {
          craft()->userSession->setNotice(Craft::t('Logged in.'));
          $this->redirectToPostedUrl();
      }
      else
      {
          craft()->httpSession->remove(UserSessionService::USER_IMPERSONATE_KEY);
          craft()->userSession->setError(Craft::t('There was a problem impersonating this user.'));
          Craft::log(craft()->userSession->getUser()->username.' tried to impersonate userId: '.$userId.' but something went wrong.', LogLevel::Error);
          }
      }
  }
  
  ```
  
  
  ---
  
  ### Answer by username_1 on 2016-11-10. Score: 1
  
  Since this is an action in your own plugin's controller, you can literally do anything you want after the login happens.
  
  ```
  if (craft()->userSession->loginByUserId($orderOwnerId))
  {
      $this->redirect('https://www.reddit.com/');
  }
  
  ```
  
  > if I uncomment the `$this->_handleSuccessfulLogin(true);` line I get an error.
  
  Because that's a private method you probably didn't copy over from Craft's `UsersController.php`. You don't have to use it if you don't want to.
  
  > it says the function is deprecated (<https://craftcms.com/classreference/services/UsersService#handleSuccessfulLogin-detail>)
  
  Same method name (mostly), but not in the UsersController... it's on the UsersService. It's also public, not private.
  
  > **Comments:**
  > **username_0**: Thanks username_1,  If that's the case, why doesn't $this->redirectToPostedUrl(); work? Am I right in understanding that should use the URL that was passed via a `<input type='hidden' name='redirect' value='/wherever'>` field in the form?  
  
  ---
  
  