Is it possible to replace an object of the UserLoginForm class with one of my own class?

What I want to do is replacing the login form with a custom one which would ask users to enter a code sent to their email address, once they entered the correct user credentials.

The problem is that an object of that class is created from UserController::userPage().

if ($user->id()) {
  $response = new RedirectResponse(url('user/' . $user->id(), array('absolute' => TRUE)));
else {
  $response = drupal_get_form(UserLoginForm::create($this->container), $request);

I know I can implement hook_form_alter() to alter the form, but I would like to use a class like UserLogin, and replacing $form_state['build_info']['callback_object'] with the object of my class in hook_form_alter() is probably too late.

Is it possible to use a class for altering the user login form? How?

  • 2
    That is an extremely good question, because there is no real solution. Please please file a bug pointing out your problem. This is not a common pattern in core, but it needs to be fixed ASAP and not used elsewhere. Aug 23, 2013 at 22:31
  • Please see drupal.org/node/2073165, once that issue is resolved I will write an answer with the correct way to override a form that is not directly accessed from a route. Until that issue is resolved, the answer is still "too bad". Aug 24, 2013 at 7:40

1 Answer 1


As I said in the question, the problem was that UserController::userPage() expressly created an object of the class UserLoginForm. The method has been changed, and now it contains the following code, which doesn't contain any explicit reference to that class.

public function userPage() {
  return $this->redirect('entity.user.canonical', array('user' => $this->currentUser()->id()));

Using a route subscriber that extends RouteSubscriberBase is possible to change the form associated with a route.

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

class MymoduleRouteSubscriber extends RouteSubscriberBase {
  public function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('user.login')) {
      $route->setDefault('_form', '\Drupal\mymodule\Form\MyModuleLoginForm');

Your Answer

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

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