The `redirect.api.php` file appears to be a mashup between D7 and D8. I found myself going down a few paths trying to figure out why the documented `hook_redirect_alter()` hook was not working for me.
It seems logical to me that a developer should be able to interact with the redirect in another module before the redirect takes place.

Issue fork redirect-2909182

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

dpagini created an issue. See original summary.

dpagini’s picture

StatusFileSize
new14.35 KB

I didnt want to keep the hook_redirect_alter() hook name, b/c that conflicts with hook_ENTITY_TYPE_alter() (even though that hook doesn't exist, it just seems too close to the entity API hook names), so I decided to use hook_redirect_response_alter() as my hook name.

I tried to cleanup the API docs just a little bit, but this is where I'm the least confident. I also added a test for my hook. I used some other modules like hooks_example, coffee and domain to figure out where/how to build tests. I also created a RedirectTestBase so I could re-use the assertRedirect() method.

dpagini’s picture

Assigned: dpagini » Unassigned
Status: Active » Needs review
dpagini’s picture

I also cleaned up the RedirectRequestSubscriber. There were a bunch of DI services not being used, unused "use" statements, and an unused protected method. I can revert any of these changes if we want to keep that stuff in there, but it all really just felt like clutter to me.

Status: Needs review » Needs work

The last submitted patch, 2: api_redirect_alter_hook-2909182-2.patch, failed testing. View results

dpagini’s picture

Status: Needs work » Needs review
StatusFileSize
new9.84 KB

Oops, patch was created with dirty branch. Think this fixes it.

dpagini’s picture

StatusFileSize
new14.19 KB

Sorry, I'm still not great at creating my own patches. Missed the new files in the last patch.

Status: Needs review » Needs work

The last submitted patch, 7: api_redirect_alter_hook-2909182-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dpagini’s picture

StatusFileSize
new15.39 KB

(sorry for all the comments)
Updates other broken tests with the DI updates.

dpagini’s picture

Status: Needs work » Needs review

Woohoo, I've got a pass... Ha. Sorry again for all the comments. Please let me know what you think.

berdir’s picture

Can you maybe explain a bit more what your use case for this is? What do you think that hook should allow to do?

I could imagine that a standard response event subscriber might also work, but you for example wouldn't have access to the redirect entity and it might not be trivial to identify whether a redirect is actually coming from redirect.module, possibly by checking some headers.

A possible option would be to either have a custom redirect class that also contains the redirect entity and/or have a custom event, we probably shouldn't add "new" hooks.

dpagini’s picture

Sure.... so, I realized I don't have an urgent need for this about 75% through building this, but am still going to utilize the patch as is now (or if it gets reworked).
Here is a similar, but probably better use case...
I have a large site using the domain module, with many domains. I want to limit redirects to only be valid on certain domains. I can extend the Redirect entity with a new domain reference field. I can use ALL the utility of Redirect as it's built, but I want to make sure that redirects are somehow limited by domain (either ensure the redirect incorporates the domain name, or is limited to the domains selected, etc.). When this hook is fired, I can check the redirect entity, along with the response that's about to be sent to the user. In this case, maybe I want to even cancel the redirect altogether and just serve a page not found.
I hope that helps?

amaisano’s picture

I'd like to be able to strip or alter certain query parameters during the redirect execution, so that the destination does not have for instance "id=5" in it (I want this for certain redirects - otherwise use the global "preserve params" option).

awolfey’s picture

I can use this, at least temporarily, to avoid what's happening in #2984272: Dots in query parameter names converted to underscores.

dpagini’s picture

StatusFileSize
new15.19 KB

Re-rolled for latest version. Would love to get some feedback on the idea of this patch. Happy to put more work in here as well.

Status: Needs review » Needs work

The last submitted patch, 15: api_redirect_alter_hook-2909182-15.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dpagini’s picture

Status: Needs work » Needs review
StatusFileSize
new11.44 KB
kenorb’s picture

(removed, ignore this)

dpagini’s picture

Did you try a cache clear? I've seen that type of error before and it's usually fixed with a `$ drush cr`. If this were truly broken, I would expect the test to fail as well.

kenorb’s picture

Maybe it's my Docker environment, will re-test that tomorrow.

kenorb’s picture

I think it was some file sync error with Docker. Secondly I was testing the wrong hook (D7 version of it instead of new one).

I've tested hook_redirect_response_alter() and I've got the dump of $redirect, which is correct.

kenorb’s picture

Status: Needs review » Reviewed & tested by the community

I've managed successfully implement hook_redirect_response_alter using the #17 patch in order to implement token support and it works.

More information at: #1331582-12: Use tokens for redirects

berdir’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/redirect.api.php
    @@ -53,6 +53,31 @@
    +  // Set a drupal message.
    +  if (!$redirect->getRedirectUrl()->isExternal()) {
    +    drupal_set_message(t('You are not being directed off-site.'), 'status');
    +  }
    

    Sorry, but this is referencing deprecated code, should use \Drupal::messenger().

  2. +++ b/src/EventSubscriber/RedirectRequestSubscriber.php
    @@ -167,32 +145,10 @@ class RedirectRequestSubscriber implements EventSubscriberInterface {
    -   * @param \Drupal\Core\Url $url
    -   *   The Url where we want to redirect.
    -   */
    -  protected function setResponse(GetResponseEvent $event, Url $url) {
    -    $request = $event->getRequest();
    -    $this->context->fromRequest($request);
     
    -    parse_str($request->getQueryString(), $query);
    -    $url->setOption('query', $query);
    -    $url->setAbsolute(TRUE);
    +      // Invoke hook_redirect_response_alter().
    +      $this->moduleHandler->alter('redirect_response', $response, $redirect);
     
    -    // We can only check access for routed URLs.
    -    if (!$url->isRouted() || $this->checker->canRedirect($request, $url->getRouteName())) {
    -      // Add the 'rendered' cache tag, so that we can invalidate all responses
    -      // when settings are changed.
    -      $response = new TrustedRedirectResponse($url->toString(), 301);
    -      $response->addCacheableDependency(CacheableMetadata::createFromRenderArray([])->addCacheTags(['rendered']));
           $event->setResponse($response);
         }
    

    This removes a lot of unrelated code, I'd rather keep this issue to a minimum and clean it up separately, easier if someone ever needs to debug that and I need to check whether this code really can be removed.

I'm also wondering if the canonical redirect handling would also need an alter hook. And still not 100% convinced the hook is the right way to go. Just thinking out loud, an option might be to have a custom redirect class that has the redirect entity included, so that people can implement response events instead and check for that type of response.

jcmartinez’s picture

This patch provides a very quick way of implementing redirect logic. It is very useful on my project that uses the domain access module and I'd love to see this patch make it to a release.

One thing that I would like to understand better is the following mention by dpagini:

In this case, maybe I want to even cancel the redirect altogether and just serve a page not found.

I have a case where I want for the redirect to fire only under a specific set of conditions; otherwise, I want to serve the page without redirecting. How can I cancel the redirect and serve the original page?

Quicksaver’s picture

StatusFileSize
new11.42 KB

Re-rolled patch #17 to apply to the latest 1.4.0 release.

fabiansierra5191’s picture

I tested the patch #25 and the redirect.api.php file was updated and the hook_redirect_response_alter is working when you create it.

fabiansierra5191’s picture

Status: Needs work » Needs review
Phil Wolstenholme’s picture

#25 no longer applies against 1.5.0

angrytoast’s picture

StatusFileSize
new5.38 KB

Updating with a re-roll of #25 to latest changes in 8.x-1.x. This should fix the patch issue per #28

This addresses the concerns in #23. It removes the changes that refactor out unnecessary class properties and dependency injection. This is because it involves both dependency deprecation which is getting addressed in https://www.drupal.org/project/redirect/issues/3102143, but also unused dependencies, which while it is cruft, doesn't need to be addressed in this feature addition.

berdir’s picture

Status: Needs review » Needs work
+++ b/tests/modules/redirect_test/redirect_test.info.yml
@@ -0,0 +1,7 @@
+package: Testing
+core: 8.x

this needs to use the new compatibility key like other modules to be D9 compatible.

Sorry for the nitpick and slow response.

angrytoast’s picture

Status: Needs work » Needs review
StatusFileSize
new5.41 KB

Not at all. Here is a patch to updateredirect_test.info.yml's core_version_requirement to match the main redirect.info.yml

bmango’s picture

Patch applied cleanly for me (on version 1.4). Many thanks!

recrit’s picture

Added a "$defaultTheme" to "tests/src/Functional/RedirectHooksTest.php" in order to be D9 compatible.

paulocs made their first commit to this issue’s fork.

paulocs’s picture

I created a MR for this issue.

I changed the parameter in the documentation file redirect.api.php... I also changed it in the tests.

Replaced RedirectResponse with TrustedRedirectResponse.

gabrielda’s picture

Assigned: Unassigned » gabrielda

Reviewing this one

gabrielda’s picture

Assigned: gabrielda » Unassigned
Status: Needs review » Reviewed & tested by the community

I've successfully implemented MR!15. This correctly adress the issue. Moving to RTBC.

Dave Reid made their first commit to this issue’s fork.

  • Berdir committed 7ba64cc on 8.x-1.x authored by paulocs
    Issue #2909182 by dpagini, angrytoast, recrit, Berdir, Quicksaver: API...
berdir’s picture

Status: Reviewed & tested by the community » Fixed

Merged, thanks.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

jweowu’s picture

As part of my re-roll of https://www.drupal.org/project/redirect/issues/2957751#comment-15248419 I wrote the following commit:

https://git.drupalcode.org/issue/redirect-2957751/-/commit/2de86d1ef5ce2...

At the time that had seemed to me like a bug fix for this issue, so I'm leaving a comment about it here so that the appropriate people can review/confirm whether this change should be applied, as it looks like it was left out of the subsequent re-roll that was ultimately committed for that other issue.