MultiLink now does re-direction using its rules and Secure Pages does redirection using its rules. There may be other "redirect" modules too, and if not one will probably come along sooner or later. Can I suggest we need a way for multiple "redirect" modules to integrate. The objective is two avoid duplicated code, multiple redirects and possible loops or conflicts, etc. Here's a proposal:

1. Agree that Global Redirect is the "master" module which will do the actual redirection (i.e. trap hook_init and do drupal_goto)

2. Define a hook that will be called by Global Redirect e.g. something like hook_global_redirect_path_alter which will allow other modules to have their say as to where the user will be redirected to.

3. Provide a way of detecting, reporting and perhaps handling conflicts (when one module thinks the user should be redirected to path/a but another says it should be path/b).

An alternative to [1] could be a new "top-level" redirector which called hooks in GR and other modules, but that doesn't seem necessary to me as GR is already proven and used by large numbers of sites.

So other redirect modules would have something like:

function my_module_global_redirect_path_alter($requested_path, $proposed_path) {
  ...
  if (i_agree_with_the_proposed_path) {
    return $proposed_path;
  }
  else {
    return $my_path;
  }
}

I don't know how to handle the idea of "conflicts", and in any case there probably needs to be a defined order of execution (without having to muck around with the system table). So maybe have a "priority" configuration page where the admin can define a "weight", possibly multiple values associated with wildcard paths.

Comments

nicholasThompson’s picture

It's an interesting idea, however I cant quite see what it would solve...

From what I know, very little code would be saved between GR and SecurePages. I've never used MultiLink (need to look into that, thanks for the pointer!)...
In terms of efficiency, one could argue that you'd still need sub-modules enabled under the "master" module so any code saves would be spent on the extra module invoking.

Like you, I dont know how to handle conflicts. As you already know the order of execution can already be handled using the system table.

The idea is very neat and could have the advantage of being easier for the user...

I would, however, rather have the discussion about getting GR into core...

Andy Inman’s picture

I agree that savings on code size and execution time would be minimal, but since we talking about modules that load on every page, small savings are worth some effort if they don't cause complication elsewhere. We could have some common code for basic stuff like the hook_init trap basic checks (e.g. checking for front-page) and later other common functions such as checking for redirect loops and error/conflict reporting/handling. A redirect loop is especially nasty, and I would suggest that a "good" redirect module should have loop detection/prevention built in. Overall the chances of compatibility problems between different redirect modules should be reduced if they're all working to a common design.

MultiLink is one of my modules and fairly hot off the press. It's mainly only relevant to multi-language sites - its primary purpose is to generate node links in content to automatically handle translated verions of nodes. The redirect feature is optional and adds redirection using the same rules (and cached data) as used for link generation.

Secure Pages now has some 7000 users, GR has some 35,000. So there's almost certainly overlap. I remembered today, there is Path Redirect too, and that has some 20,000 users. MultiLink will never hit those numbers because there are relatively few multi-language sites. But my point is there are multiple redirect modules, that fundamentally all do the same thing, only using different rule-sets.

I agree that GR functionality could/should go into core. I would go further and say that other url and link generation should then integrate with it (e.g. hook_link_alter and probably l() and url() functions, maybe menu links), so that there is some kind of "master" concept as to how paths should be generated/handled. After all, the whole reason why GR is needed is because it's all to easy to end up with multiple paths to the same content, and that is really the underlying issue. Anyway...

How about the idea of a "master" redirector as a new module rather than a change to GR? It would do something like the following:

1. Trap hook_init (maybe also hook_boot like SP does)

2. Call hooks in all other redirect modules ("plug-ins")

3. Do drupal_goto or similar to the final url.

In addition it would provide supporting functionality:

1. Caching if appropriate, to minimise processing time. E.g., if a plug-in is cacheable (path/a always redirects to path/b) then using a cached result rather than calling that plug-in may be more efficient. Multi-language related redirects are probably especially relevant because they're relatively expensive in terms of DB queries.

2. Some method for prioritising, probably simple "weight" of each plug-in, but independent of the system db table (hardly user friendly to expect people to go there.)

3. Detection of loops, and reporting handling - e.g. bail out to a common "redirection loop error" page (ok, modern browsers do loop detection, but it's not very impressive for a site visitor to hit that.)

4. url and link generation intelligence for other processes. After all, why let the system ever generate a url of node/123 if it will always end up being redirected elsewhere - better to output the "final" url in the first place and so fix the problem at source.

5. Logging/reporting services. Frequent redirects may indicate a problem elsewhere, and is certainly not good for overall performance, so some way to detect such conditions would be useful.

6. Maybe a common admin page or at least a common sub-menu for configuration of plug-ins.

What do you think? Ok, there's no huge need for this currently, just one of those things that might pave the way for a better future!

donquixote’s picture

I was about to write a patch for globalredirect, but found that I don't like the code that much.
I then came to a similar idea as you, a module that I would call it "redirectapi".
I am still thinking about the details.
- I want a complete replacement for globalredirect.
- I would like to reuse the settings from globalredirect, if this has been installed before. This means, you would: (i) disable globalredirect, (ii) enable redirectapi, (iii) uninstall globalredirect.
- I want to use full PHP5 OOP, which is one reason why I don't want to make this a globalredirect patch. GR has to be PHP4 compatible for existing sites (I hate this).

Implementation:
- The idea is to pass a destination object around to each hook implementation, where modules can do things like $destination->setPath(..), $destination->setInterfaceLanguage(..), etc.
- The passing around will be repeated until none of the modules wants to alter the path any more. The algorithm will detect and stop different types of recursion.
- A redirect will only happen if the destination is different from the current url.
- The module's own implementation of its hook will do all the stuff that globalredirect already does.
- Some redirect rules might be outside of the hooks, if they don't fit into a scheme.

Dave Reid’s picture

I've actually been working on seeing how modules like FeedBurner, Global Redirect can take advantage of a unified redirection API.

For now I've assigned myself the http://drupal.org/project/redirect namespace. I think my ideal solution would be to move the Path redirect module to the new namespace, and add Global redirect as a sub-module. New ideas like the language redirection could either be a sub-module as well. This way we'd provide a unified interface and settings.

donquixote’s picture

Seems to be some overlap..
As I am already working on this, I propose that I finish a draft/preview for a redirectapi module, then present it here and we can discuss how to proceed. Renaming the module should not be a big problem, and maybe Dave or netgenius or myself wants to be co-maintainer of whatever we end up with.

The little problem I see with my approach is PHP4. How important is that?
Or, if you do your own approach, when do you think you want to start working on this?

Dave Reid’s picture

I'm also thinking this coordination should be a D7 project as we have lots more apis and better requirements to enable such collaborations. Then we can also ignore PHP4.

How about we discuss this in the groups.drupal.org/paths (http://groups.drupal.org/node/69933) first before we commit ourselves to code?

donquixote’s picture

I would like to have a solution in D6 - either a patch to Global Redirect, or a new module.

I started some refactoring, I hope this will help to continue working on this project, or to adapt the code somewhere else.
#803830: A bit of refactoring + mixed language redirects

nicholasThompson’s picture

I quite like the idea of an "API" which helps out for all the redirection modules... However... I'm not overly blown away by the idea of starting it as a separate project. Global Redirect has been around a long time and has a certain amount of "good will" attached to the name.

Maybe it's worth starting 2.x branch of GR for D6 and D7 with PHP5 as a minimum requirement?

Dave Reid’s picture

If it's providing a broader API for other modules, then I don't think it's appropriate for it to stay under the 'Global redirect' namespace. I would really like to join forces with everyone and provide a kick ass module for Drupal 7. Please let's discuss and plan on the Path group: http://groups.drupal.org/node/69933.

BTW an initial poll and response on Twitter has been 100% for merging the effort together. The community wants this too.

nicholasThompson’s picture

I have absolutely no problem merging things together to make a god-like module... In fact I wholeheartedly support it!

I just wanted to try to avoid the project pool having yet another redirect module added into it. Also by using GR, the +35,000 existing users will get an "upgrade" notice when 2.x is released. (that's my "pro" points for it! :) hehe).

However I do see the appeal of a simpler name like RedirectAPI or just Redirect....

donquixote’s picture

An all-inclusive patch (heavy refactoring + mixed language redirects + hook for other modules) can be found here:
http://drupal.org/node/803830#comment-2991412
("A bit of refactoring / code readability")

@others:
Now we can discuss :)

Andy Inman’s picture

Following Dave's lead, I'll move to http://groups.drupal.org/node/69933 - I do think we need a D6 solution though.