Skip to main content

Redirect, la manera correcta de hacerlo

Mon, 20/06/2022 - 21:43
10
mins.
cover_redirect
Categoria
Tutorial

Al momento de hacer una redirección desde nuestro modulo custom o nuestro theme custom debemos tener en cuenta el contexto desde el que lo estamos haciendo para poder hacerlo de la manera correcta.

Cuando hablo de contextos quiero decir Controllers, Events, Forms y Hooks. Vamos a ver como resolverlo en cada caso.

Redirección en Controller

Hacer una redirección dentro de controller puede ser algo simple. Solamente necestimos retornar un objeto de Symfony\Component\HttpFoundation\RedirectResponse. El objeto de redirección acepta un string que sea una url que apunta a una pagina. Esto se puede hacer creando una instancia de Drupal\Core\Url.

$url = Url::fromRoute('entity.node.canonical', ['node' => 1]);
return new RedirectResponse($url->toString());

Drupal encontrará que el objeto retornado es de tipo RedirectResponse y retornanrá la página solicitada.

Redirección en Form

Si lo queremos es redireccionar al submitear un Form necestimos usar el metodo setRedirect() que pertenece al objeto form_state. Esto la haremos en metodo Submit del formulario. Este método toma como parametro la ruta a la que queremos redirigir.

$form_state->setRedirect('entity.node.canonical', ['node' => 1]);

Como alternativa se puede utilizar el método setRedirectUrl() que toma como parámetro una instancia de Drupal\Core\Url.

$url = Url::fromRoute('entity.node.canonical', ['node' => 1]);
$form_state->setRedirectUrl($url);

La única advertencia para este método es que no debe usar también el método setRebuild() en el estado del formulario, ya que esto hará que la redirección no se procese.

En los ejemplos anteriores se asume que estamos escribiendo una clase Form, pero cómo hacemos si necesitamos hacerlo en un formulario existente? Para esto usaremos la hook hook_form_alter(). A través de esta hook podemos agrear una función mas de submit y dentro de esta función realizar el redirect.

Esta es la hook_form_alter()

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    if ($form_id === 'node_article_form') {
    $form['actions']['submit']['#submit'][] = 'mymodule_article_form_submit';
  } 
}

La función de submit puede quedaría de la siguiente manera.

function mymodule_article_form_submit($form, FormStateInterface $form_state) {
  $form_state->setRedirect('entity.node.canonical', ['node' => 1]);
}

Redirección en Event

Para el caso de que necesitemos hacer una redirección en un evento el enfoque cambia respecto de los anteriores. En este caso debemos enviar la redirección a través del método setResponse() del objeto event. 

class MyEventSubscriber implements EventSubscriberInterface {

  public static function getSubscribedEvents() {
    $events['kernel.request'] = ['someEvent', 28];
    return $events;
  }

  private function someEvent(KernelEvent $event) {
    if (/* some condition */) {
      $url = Url::fromRoute('entity.node.canonical', ['node' => 1]);
      $response = new RedirectResponse($url->toString());
      $event->setResponse($response);
    }
  }
}

Redirección en Hook

También es posible realizar una redirección desde una hook y lo podemos hacer de la siguiente manera

use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;

function mymodule_node_insert(EntityInterface $entity) {
  if ($entity->getType() == 'article') {
    $url = Url::fromRoute('entity.node.canonical', ['node' => 1]);
    $redirect = new RedirectResponse($url->toString());
    $redirect->send();
  }
}

 

Estas son diferentes variantes a las que nos podemos enfrentar cuando necesitamos resolver el problema de la redirección