Inter domain linking

ariflukito - August 27, 2008 - 05:58
Project:Domain Access
Version:5.x-1.10
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:patch (to be ported)
Description

Hi I would like to have an option where DA rewrites all outbound links to other affiliate nodes but not rewriting links to nodes that are published to all affiliates.
To be short and simple, something like SEO but minus rewriting all affiliate links to root domain.

Also it would be nice to have DA checks if url_alias table is prefixed when rewriting links. In case the node has a different alias in other subdomain.

#1

agentrickard - August 27, 2008 - 09:14

Hi I would like to have an option where DA rewrites all outbound links to other affiliate nodes but not rewriting links to nodes that are published to all affiliates.

This already exists. Look under the Advanced Settings for "Default source domain" -- see attached.

Checking the url_alias for prefixing would be possible, but take a little code trickery. I would like to see a patch for that.

AttachmentSize
Picture 1.png 13.4 KB

#2

ariflukito - August 28, 2008 - 05:41

ah I dont have that option, is that D6 only?

what is the best way to alter path aliasing, as far as I know there is no hook for that.
The only way you can do it is by patching core. Am I correct on this one?

#3

agentrickard - August 28, 2008 - 06:47

You must enable Domain Source, even if you do not use it.

[edit: I said "Domain Strict" originally, which is incorrect.

#4

ariflukito - August 28, 2008 - 08:07

#5

agentrickard - August 28, 2008 - 11:30

What am I supposed to be seeing?

#6

agentrickard - August 28, 2008 - 11:51

This feature is in 5.x.1.5 and higher. It does not require Domain Source.

#7

ariflukito - August 29, 2008 - 01:12

sorry I was in hurry yesterday
drupal 5 doesn't have the option "Do not change domain"

D6 -> $options = array('-1' => t('Do not change domain'));
D5 -> $options = array();

edit: attached patch for D5 head

also I edited my comment above after you posted

what is the best way to alter path aliasing, as far as I know there is no hook for that.
The only way you can do it is by patching core. Am I correct on this one?

AttachmentSize
domain_url_rewrites.patch 1.44 KB

#8

agentrickard - August 29, 2008 - 07:54

Now I see. The patch is appropriate, but you should compare the custom_url_rewrite_outbound() function in both versions as well, since we act based on that setting in that function.

You can (in D5) alter path aliasing by using custom_url_rewrite(). DA includes a patch that backports custom_url_rewrite_outbound() and custom_url_rewrite_inbound() from D6. With some modification to custom_url_rewrite_outbound(), you could do domain-specific path lookups.

You would have to determine the target domain for the link, then switch database tables, and then write the link. It is possible, but I do not have time at the moment.

#9

ariflukito - September 1, 2008 - 05:01

yes my patch has already included the change on custom_url_rewrite_outbound()

custom_url_rewrite_outbound() on D5 is called before drupal_get_path_alias() so it is a bit tricky here.

#10

agentrickard - September 1, 2008 - 07:36

custom_url_rewrite_outbound() on D5 is called before drupal_get_path_alias()

The included patch does that? If so, we should rewrite the patch.

#11

ariflukito - September 1, 2008 - 07:42

ok here is my first attempt
patch for drupal 5
patched common.inc to have the same execution path as drupal 6 so that the custom_url_rewrite_outbound() is called after drupal_get_path_alias()
the alias lookup codes mostly borrowed from drupal_lookup_path()

AttachmentSize
settings_custom_url.inc_.patch 1.94 KB
common.inc_.patch 2.15 KB

#12

agentrickard - September 1, 2008 - 07:47

Looks good, just from reading through the code. This will need to go into the 5.x.2 / 6.x.2 release, since it changes the patch that needs to be applied.

Are your tests working as expected?

The only other thing I can think is how to make this optional, so that we only use this routine in certain cases. Maybe we provide a separate include with Domain Prefix so that, if you want this feature, you place a different include file in settings.php.

#13

agentrickard - September 1, 2008 - 16:32
Version:5.x-1.6» 5.x-1.7
Status:active» needs review

Status change!

#14

ariflukito - September 1, 2008 - 23:56

it's not perfect yet, I haven't handled certain cases. I roll out a new one later.

#15

ariflukito - September 2, 2008 - 02:01

ok here is the new one
I separate it into new functions
domain_prefix_get_path_alias() and domain_prefix_lookup_path()
they work the same way like drupal except the domain_prefix_lookup_path() only does aliasing.

I have done a little bit of testing and it is working so far with my setup.

AttachmentSize
settings_custom_url.inc_.patch 3.18 KB

#16

ariflukito - September 2, 2008 - 06:19

patch for D6

I've just found one problem unrelated to the patch but semi-related to the issue
If we have different url alias in different domain for the same node, domain switcher and domain nav will not work.
They will give page not found error.

AttachmentSize
D6 settings_custom_url.inc_.patch 3.66 KB

#17

agentrickard - September 2, 2008 - 08:09

That makes sense. Take a look at the domain_uri() function, it may need to be extneded with your path logic.

#18

ariflukito - September 3, 2008 - 02:45

ok here is the patch for domain_get_uri() function.

now we just need to decide where to put those new functions, you still want to make it optional?

AttachmentSize
D5 domain.module.patch 943 bytes
D6 domain.module.patch 943 bytes

#19

agentrickard - September 3, 2008 - 08:26

I don't know. I am in Budapest after DrupalCON Szeged, and will not get a chance to really think about this until Monday.

#20

agentrickard - September 9, 2008 - 19:24

Just took a look. The one part that I don't like is the direct call to domain_prefix_get_path_alias() and the function_exists() that goes with it.

It would be more Drupal if we used a hook here instead.

So I suppose we would need hook_domainpath(), which would let other modules modify the path.

<?php
hook_domainpath
($domain_id, $path, $path_language = '') {
// code here
}
?>

Then we can just invoke the hook without having to use the function_exists() bit in our code. In this case, we do not need a separate settings.php file for Domain Prefix.

#21

agentrickard - September 9, 2008 - 19:24
Status:needs review» needs work

#22

ariflukito - September 10, 2008 - 05:56

I don't think letting multiple modules modify the path is a good idea. I don't see any benefit doing that.

If module A and module B implement hook_domainpath(). Module A alter the $path to $new_path then what would module B do?
or if both module A and module B return different path based on original path, which one would we choose?

note that using hook indirectly call function_exists()
well I know it's a little bit ugly but I don't see using hook is an option.

what do you think?

#23

agentrickard - September 10, 2008 - 13:52

Using a hook is how we do things. Look at hook_domainload() or hook_nodeapi().

Will there be cases where modules compete? Possibly, but that can be fixed at the module level. Our task is to build a modular framework that supports extension. Running module-specific functions calls (exceptions, really) goes against that goal.

#24

ariflukito - September 11, 2008 - 05:43

Ok here is the new patch

drupal 5 needs new common.inc patch from #11
domain_get_uri() patch is merged into this patch

can you please commit the patch from #7

edit: patch updated with same file name, make sure you don't get the cached one

AttachmentSize
domain-d6.patch 5.49 KB
domain-d5.patch 5.5 KB

#25

agentrickard - September 11, 2008 - 13:36
Status:needs work» needs review

OK, the patch from #7 has been committed to the d5 branch -- it is easy to lose track of multiple patches in an issue.

#26

agentrickard - October 10, 2008 - 21:18
Version:5.x-1.7» 5.x-1.9

This got confused with another patch. #7 has been committed. #24 still needs review.

#27

ariflukito - October 13, 2008 - 04:30

Updated d5 patch
d6 head looks unstable now.

AttachmentSize
domain-d5.patch 5.53 KB

#28

agentrickard - October 13, 2008 - 20:01

D6 HEAD is working. Domain Views is incomplete, but the rest should be fine. See http://drupal.org/node/320388

This should actually apply to D6 pretty cleanly.

#29

agentrickard - October 18, 2008 - 19:36
Status:needs review» patch (to be ported)

This has been committed to HEAD (D6). Note that I took the opportunity to optimize the way this code works.

Two special considerations:

-- Any implementation of this hook will now run on _all_ path lookups, not just when DA rewrites the path. This is by design, since there are paths other than node paths that might need to be rewritten.

-- Because of this, the hook could be _very_ resource intensive. So I broke it out into a special file that is only loaded IFF we know that a prefixed {url_alias} table is present. This saves a ton of potential calls to the function that might not be needed.

For details, see domain_prefix_init() and domain_prefix.path.inc.

Updated patch attached for D5 reference -- though the patch is for D6.

AttachmentSize
domainpath.patch 10.24 KB

#30

ariflukito - October 20, 2008 - 06:21

-- Any implementation of this hook will now run on _all_ path lookups, not just when DA rewrites the path. This is by design, since there are paths other than node paths that might need to be rewritten.

Wasn't that already the case before? The hook is only needed to run when DA changes the base_url or else the lookup will be handled by drupal_get_path_alias().

<?php
if ($path_rewrite > 0) {
   
$path = domain_path($_domain['domain_id'], $original_path, isset($options['language']) ? $options['language']->language : '');
  }
?>

This wouldn't work. The first parameter $_domain['domain_id] causes the lookup on active domain's url_alias table. What we want here is the target domain_id.

In the domain_get_uri(), you added this.

<?php
if ($string == $alias) {
 
$alias = drupal_get_path_alias($path);
}
?>

What is it for? It doesn't seem to do anything. $string is the aliased $path, so drupal_get_path_alias($path) will give you $string. But $alias is already equal to $string based on the condition. I am confused.

#31

agentrickard - October 20, 2008 - 13:38
Version:5.x-1.9» 6.x-2.0-rc4

I took that last bit out last night, so check the newest version of HEAD.

The code in custom_url_rewrite.inc is correct. Because of how the Domain Switcher block works, we have to run some checks against the default 'url_alias' table.

And no, custom_url_rewrite.inc is designed to _only_ rewrite node paths -- see the check for if ($nid) near the top. So it would have had no effect if you wanted to change path aliases for a path like 'user,' so we have to run the multi-domain path lookup on _every_ path. The result, if you have multiple domains, is that you might end up running dozens or hundreds of path lookups per page.

The code seems to be as optimized as it can be, though.

Please test before claiming that something doesn't work.

#32

ariflukito - October 21, 2008 - 01:19

I'm sorry I should say I have already tested that and it didn't work. The first paramater is telling to do the path lookup on this domain.

The result, if you have multiple domains, is that you might end up running dozens or hundreds of path lookups per page.

I think it doesn't matter on how many domains you have, there is only one lookup per path.

I think you may have a different use case to mine. My use case is I want to have a same alias for 2 different nodes. First node is assigned to domain A and the other to domain B. I want to link both nodes from root domain. So I have something like this:

a.example.com/products -> node/1
b.example.com/products -> node/2

the alias on root domain
example.com/products-a -> node/1
example.com/products-b -> node/2

without the rewrite I get this
a.example.com/products-a and
b.example.com/products-b
and as a result I get page not found error.

edit: this is unrelated I noticed on Node Link Patterns you have this "node\%n\outline". It uses forward slashes instead of back slashes like other patterns.

#33

ariflukito - October 21, 2008 - 05:13

performance improvement, avoid calling db_table_exists multiple times

AttachmentSize
domain_prefix.patch 676 bytes

#34

agentrickard - October 21, 2008 - 13:43

Yes, you were correct. I had tested it in the Domain Switcher, but not in custom_url_rewrite().

Patches committed to HEAD.

The problem that remains -- which I am not sure how to solve -- is what to do if you have two separate aliases for a path that is not a node. The Domain Switcher handles this through the use of domain_get_uri(). But normal links do not, and I do not see any way to handle that without some very nasty regex code that I don't think we need.

In most cases, this will not be an issue, though I could see problems with menu links that span multiple domains -- unless they are node paths, they will not be aliased correctly. So perhaps just a documentation note about the limitations of this approach.

#35

ariflukito - October 22, 2008 - 02:07

Couple things:

- $domain[$nid]['domain_id'] is not always set, so I introduce a new variable $target_domain_id default to $_domain['domain_id']. And if we use default source, the target would be default source domain id.
- I added check $path != '' because I saw '' and '' (empty string) were being passed around.
- Added drupal_is_front_page() check in domain_get_uri(), so we don't see something like http://example.com/node, http://a.example.com/node in the domain switcher when we are in the front page.

One more thing that I am thinking now. In the domain_prefix_domainpath(), it's not needed to do the path lookup if the target domain id is equal to the active domain id (ie: $domain_id == $_domain['domain_id']). Because it is just duplicating the job of drupal_get_path_alias(). We just need to return the original aliased path but then we need to pass it to the function.

I am not really getting the problem you mentioned. How can you get two separate aliases, you have 2 separate aliases for the path in same url_alias table? Mind giving me some examples.

AttachmentSize
domain.patch 2.21 KB

#36

agentrickard - October 22, 2008 - 02:30

I mean 'two separate aliases (on two different prefixed domains) for the same path that is not a node path.'

New patch committed. Nice fixes.

#37

ariflukito - October 22, 2008 - 04:45

hmm right but that's a rare case unless you construct the URL yourself, it won't be any problem. I believe if you want to have menu links that span multiple domains, you need to give the absolute URLs there and those URLs don't get passed to url() function.

One more thing that I am thinking now. In the domain_prefix_domainpath(), it's not needed to do the path lookup if the target domain id is equal to the active domain id (ie: $domain_id == $_domain['domain_id']). Because it is just duplicating the job of drupal_get_path_alias(). We just need to return the original aliased path but then we need to pass it to the function.

what do you think about this one? Just to clarify the last part, add the original alias to the hook's argument.

#38

agentrickard - October 22, 2008 - 13:28

I think that needs to be accounted for. Committed to HEAD.

<?php
function domain_prefix_domainpath($domain_id, &$path, $path_language = NULL) {
  global
$language, $_domain;
 
// $map[$domain_id] keys are Drupal paths and the values are the corresponding aliases
 
static $map = array(), $count = array(), $status = array(), $tablename = array();

 
// If the alias is for the current domain, do nothing.
 
if ($domain_id == $_domain['domain_id']) {
    return;
  }
// ... rest of function ...
?>

#39

ariflukito - October 22, 2008 - 22:47

The problem with that is it will just return the original path (node/$nid) not the original aliased path.

<?php
$path
= domain_path($target_domain_id, $original_path, isset($options['language']) ? $options['language']->language : '');
?>

See we only pass the $original_path to the hook.

#40

ariflukito - October 23, 2008 - 02:24

new custom_url_rewrite_outbound.patch for d5

AttachmentSize
custom_url_rewrite_outbound.patch 2.13 KB

#41

agentrickard - October 23, 2008 - 13:53

So you mean:

<?php
 
// If the alias is for the current domain, do nothing.
 
if ($domain_id == $_domain['domain_id']) {
   
$path = drupal_get_path_alias($path);
    return;
  }
?>

#42

ariflukito - October 23, 2008 - 22:38

no something like this

<?php
$path
= domain_path($target_domain_id, $original_path, $original_alias, isset($options['language']) ? $options['language']->language : '');

function
domain_prefix_domainpath($domain_id, &$path, $original_alias, $path_language = NULL) {

 
//snip..

  // If the alias is for the current domain, do nothing.
 
if ($domain_id == $_domain['domain_id']) {
    return 
$original_alias;
  }

 
//snip..
}
?>

#43

agentrickard - October 24, 2008 - 12:33
Status:patch (to be ported)» needs work

Ah. I didn't see the extra parameter in the function. This will have to wait until I get home.

#44

ariflukito - October 26, 2008 - 22:34

I added the extra paramater, it is not in the original function.

#45

agentrickard - October 27, 2008 - 13:06

If we do this check inside domain_path() itself, do we need to worry about the $original_path var?

#46

ariflukito - October 27, 2008 - 23:22

If we do the check inside domain_path() then there will be no path altering for all paths to current domain. That's not a problem for domain prefix but I don't know if other modules will need it.

Also I think probably it's not a good way to pass the path by reference, the other hook implementations will get the altered path instead of the original one.

#47

ariflukito - January 5, 2009 - 06:01

here is patch for D5 port and small fix for D6 (wrong table naming when we have global prefix)

note: in domain_prefix_table_exists(), we don't need to call db_escape_table() explicitly since db_table_exists() is going to do it for us.

AttachmentSize
D5 port 8.1 KB
D6 patch 759 bytes

#48

agentrickard - February 20, 2009 - 20:14
Version:6.x-2.0-rc4» 6.x-2.0-rc5
Status:needs work» patch (to be ported)

The small D6 patch has been committed. Marking as to be ported.

#49

agentrickard - February 21, 2009 - 23:12
Version:6.x-2.0-rc5» 6.x-2.0-rc6
Status:patch (to be ported)» needs review

I just committed a change to HEAD, since we were accidentally dropping language paths.

So this needs a retest.

#50

agentrickard - June 7, 2009 - 17:45
Status:needs review» fixed

This will need to be tested post-release, it appears.

#51

ariflukito - June 9, 2009 - 03:40
Version:6.x-2.0-rc6» 5.x-1.9
Status:fixed» patch (to be ported)

this hasn't been ported to D5 and custom_url_rewrite_outbound.patch from #40 is needed to make sure custom_url_rewrite_outbound is called after drupal_get_path_alias.

AttachmentSize
D5 port 8.6 KB

#52

agentrickard - June 9, 2009 - 14:08
Version:5.x-1.9» 5.x-1.10
Status:patch (to be ported)» needs review

#53

agentrickard - June 13, 2009 - 20:20
Status:needs review» needs work

Here's the patch from #51 revised for 5.x-dev.

I am confused about the note referring to #40.

Can you simply update the patch file with the changes to the custom_url patch?

AttachmentSize
300454-domain-url.patch 6.69 KB

#54

ariflukito - June 15, 2009 - 00:03

Hi Ken, in your revised patch it doesn't include the added new file domain_prefix.path.inc

The patch on #40 is meant to replace the custom_url patch. What the patch actually does is change the code flow so that the custom_url_rewrite_outbound function is called after drupal_get_path_alias since both functions modify the $path.

#55

agentrickard - June 15, 2009 - 12:28

Can you re-roll?

#56

ariflukito - June 16, 2009 - 02:53

The patch on #51 still applies cleanly but I reroll anyway

I attach 2 custom_url_rewrite_outbound.patch
- the first one is a reroll of #40, it's basically a backport from D6
- the second one is smaller patch, it works as well based on my test

AttachmentSize
domain-url.patch 8.62 KB
custom_url_rewrite_outbound.patch 2.21 KB
custom_url_rewrite_outbound_2.patch 1.33 KB

#57

ariflukito - July 16, 2009 - 02:16
Status:needs work» needs review

#58

agentrickard - November 1, 2009 - 15:45
Status:needs review» patch (to be ported)
 
 

Drupal is a registered trademark of Dries Buytaert.