It took my entire day, but here are all my findings on this one. First of all description of the bug:
Domain A = main domain aka domain_id 0
Domain B = second domain aka domain_id 2
When I create a node on Domain B which should only be available to Domain B with source domain B as well and hit the save button it gets saved, but then gets a redirect to the node but on the main domain aka Domain A.
At first I thought it might have something to do with #623394: No $_domain Global in domain_node_save_redirect, but it seems that function is merely there for nodes that created on for example Domain A that are intended for Domain B so you get redirected to the right "viewing" domain when you save it. And after checking that functionality that functions seems to be working just fine.
After that I also checked what it does when i update a node. Updating a node seems to be working just fine and I stay on the correct domain. So it seems to only happen on first time save.
For now Ive reverted back to RC9, but if you need more info just give me a nudge.
General info:
MySQL database 5.0.51a
PHP 5.2.9-0.dotdeb.2
Installed Domain modules: Domain Access, Domain Configuration, Domain Content, Domain Navigation, Domain Prefix, Domain Source, Domain Theme, Domain Views
Other modules installed is a list that is way too long
| Comment | File | Size | Author |
|---|---|---|---|
| #102 | 624360-node-match.patch | 1.09 KB | agentrickard |
| #101 | 624360-node-match.patch | 1.3 KB | agentrickard |
| #95 | domain-domain_get_node_match_fix-624360-95.patch | 1.1 KB | bpresles |
| #47 | 624360-a-redirect.patch | 2.49 KB | agentrickard |
| #36 | 624360-redirect.patch | 2.74 KB | agentrickard |
Comments
Comment #1
TCRobbert commentedIt seems staring at code the entire day has affected my english writing. If the above needs explaining let me know :)
Comment #2
agentrickardIt means that node_save_redirect() doesn't have enough information, or that the main domain is the proper place for that node, based on the logic.
Comment #3
agentrickardSee #227947: After editing nodes user is redirected to the main domain for the background. My guess is that the lack of the $_domain global is the problem.
Comment #4
TCRobbert commentedI actually checked that and it seems to go through the entire function and reach the if statement as well, but doesnt go into the if statement. Which seems logical if i read your comments correctly in the file.
Comment #5
TCRobbert commentedI actually applied the patch described in #623394: No $_domain Global in domain_node_save_redirect as well. But had no succes
Comment #6
agentrickardThe function
domain_node_save_redirectshould be refactored to usedomain_get_node_match($nid). This was a late API improvement that didn't get factored in.Try the attached against 6.x.2.0.
Comment #7
TCRobbert commentedOk running update.php again and something I noticed this time that it automatically sets the update script to 6203 even though there is also a 6204 available. Running update.php again doesnt give the 6204 as a possible update.
After applying the test i tried creating a node on domain B, but unfortunately still get redirected to domain A on hitting the save button.
Comment #8
agentrickardWhat settings are you giving the node?
The update problem is a core issue. Check the 'schema' value in your {system} table.
Comment #9
TCRobbert commentedAt first I was sending it to all affiliates but with the source domain set to Domain B.
After this problem started occurring I changed it to just domain B and set the source on Domain B as well.
I checked the schema value in the DB and it does indeed say 6204.
Just as a heads up, im off to bed now and will be online tomorrow again. You can also find me on irc if you prefer.
Comment #10
agentrickardI totally cannot replicate this.
If it is set to 'all affiliates' it should not redirect, unless its the missing globals problem.
Comment #11
TCRobbert commentedWell I have been thinking we might be looking in the wrong spot. From what I understand from you here and the comments in the module it is only supposed to run:
drupal_goto($source['path'] . drupal_get_path_alias("node/$nid"));
when it should really go to a different domain, for example when you create something on domain A which is for domain B. And this seems to work just fine. So even after trying to comment out that drupal_goto it still results in a drupal_goto call being made somewhere.
Does this make sense what im saying here?
The other thing is that Ive lost count on how many modules im using so there might be others hooking into the node form. One thing i am sure about is that this problem started happening since i updated to domain 2.0 final.
As my project is quite dependent on the domain module Im willing to give you access and maybe together we can figure this one out.
Comment #12
TCRobbert commentedOk my findings so far:
- the node form calls upon drupal_goto on save which requests url()
- which at first only has the option absolute
- then the global $base_url is called and correctly sets the $options["base_url"] to domain B
- then custom_url_rewrite_outbound() is called which is processed by settings_custom_url.inc
- after this the $options["base_url"] is set to domain A.
Im not sure if this helps you, but maybe you can figure it out now or give me a nudge in the right direction where i should look now.
Comment #13
netw3rker commentedI'm running into this same problem as well. for reference here's the config steps:
0) start with a clean install of drupal with normal base modules. enable domain access, domain configuration and domain theme modules
1) follow the install_quickstart.txt file (add the settings include line)
2) configure primary domain:
domainx.localhost
3) configure additional domain:
sub.domainx.localhost
4) create page from sub.domainx.localhost:
dont check "all affiliates" ensure that "sub.domainx.localhost" is checked and "domainx.localhost" is NOT checked.
5) hit save
you will be redirected to "domainx.localhost" as configured in your primary domain.
given that i just followed the instructions, there shouldnt be anything 'missing' (such as the $domain global). if there is, maybe an addition to the quickstart text is in order?
-Chris
Comment #14
TCRobbert commented@netwerker Actually the $domain global has not been implemented yet to ensure you really have the same bug apply the patch in http://drupal.org/node/624360#comment-2230398
Comment #15
TCRobbert commentedOk the final bit Ive been able to trace is the following:
Placing the a bit of code in this function
On hitting the save button this gave the following output (see attachment).
Where for some reason the static $domain returned domain A for the first times it ran through that piece of code.
Hope it helps some more.
Comment #16
netw3rker commented@tcrobert
applied the patch. but it didnt fix the problem. I'll do some digging as well to see if i can help narrow this down. could it have anything to do with the the site directory that the settings file is using? one thing i forgot to mention is that this is running under: sites/domainx.localhost/settings.php and note sites/default/settings.php
lemme know!
-Chris
Comment #17
agentrickardDid anyone test the patch in #6? That is the correct approach. The settings folder shouldn't have anything to do with it.
The real question is: does
domain_get_node_match($nid)from the _patch_ return the right domain value.Note also that if the matching domain is invalid, you will not be redirected. And invalid domains redirect to the default domain unless you have the new 'access inactive domains' permission, which should have been granted when you ran the module update.
See:
if ($source['domain_id'] != -1 && $source['domain_id'] != $_domain['domain_id'] && ($source['valid'] || user_access('access inactive domains')))Comment #18
agentrickardI do notice that in the var_dump Domain-B returns 'valid' as a string (from the database) rather than a Boolean. I wonder if that is causing the IF check to fail.
Comment #19
TCRobbert commentedI did run the patch, but without success.
agentrickard, if i understand correctly you are saying that the function node_save_redirect() should return the ppl to domain B? because i figured it should only do that under different circumstances.
Ive been wondering about that string as well (being not a boolean).
Comment #20
agentrickardThe first part of your comment in #11 is correct. node_save_redirect() is designed to make sure that, on node save, you don't go to an inaccessible domain. If you save the node on Domain A and it is not viewable there, you are redirected to Domain B.
You have to see the long, painful history of #227947: After editing nodes user is redirected to the main domain to understand why this is here.
Comment #21
netw3rker commented@agentrickard
as noted in comment #16, Yes we've both run the patch and that has not solved the problem. are you *sure* that you cant reproduce this using clean copies of drupal and domain module by following the steps we provided? these arent elaborate setups we are using.
Comment #22
TCRobbert commented@agentrickard
So what you are saying is that it should go into the if() statement -->
so that drupal_goto sends the user back to domain B even if it was created on domain B in the first place.
As that doesnt really make sense to me as it should only go into the if statement when source domain and current domain are unequal to each other. Which would only happen when something would be created on say domain A which is for domain B.
Comment #23
agentrickardThat is not what I am saying. If it belongs to B but is created on A, you should be directed to B. If it belongs on A, nothing should happen. See the != in the IF.
I am tempted to rip this out entirely, since it was designed to end confusion and seems to be causing different confusion.
Comment #24
TCRobbert commentedIm sorry, my mistake. The main reason why I wanted to get it clear what is happening is to figure out which drupal_goto is being used. If the one from the function domain_node_save_redirect() is not being used it means it simply runs the the drupal_goto from the node form itself. Meaning that the function domain_node_save_redirect() actually isnt really the problem here. But apparently something that creates the url aka the custom_url bit.
If there is something I can test for you to exclude things or main localize where the true problem lies just give me a nudge in the right direction. Im currently on holiday though so im not sure what time i can sort it out.
Comment #25
agentrickardAnd I'm in Stockholm for DrupalCamp Sweden, so this is a bad week for more testing.
Comment #26
Netbuddy commentedI have a sneaking suspicion its got something to do with URL rewrites. If I create a book page and have it save as a normal node (eg node/10) it does not redirect back to the primary domain. If I create a book page, and save it under a book parent which is subject to URL rewrite, it will redirect back to the primary domain.
Im using Drupal 6.20, Domain Access 6.x-2.0 with Domain Config, Domain Nav, Domain Content, Domain Source, and Domain Theme enabled. I also have SSO installed and the latest release candidates of Token and Pathauto. 4 Main Modules overall.
Could it be URL rewrites problem in Domain Access, or something going on with pathauto?.
Im wondering what happens if the Domain Sourcce sub-module is disabled....Ill try that now.
Comment #27
Netbuddy commentedOk with Domain Source disabled, and if, under the "Advanced Settings" area of the primary domain I have:
- Search Engine Optimization - Rewrite All URLS to point to a single source.
- Default Source Domain - Do not change.
I wont get redirected if I create a book page as a normal node without rewrite, or a book page with a book parent that does rewrite. So basically I can now create any book page, on second domain, and it wont redirect back to the primary domain. So now its working as intended.
I should mention my primary domain is like site1.com and my second domain is like site2.com....2 top level domains. I havent applied the patch mentioned in #6.
Comment #28
TCRobbert commented@Netbuddy, Interesting info.
As soon as I get back behind one of my working pc's ill have a look and try that out as well. Im curious to see what the end result would be.
Comment #29
TCRobbert commentedI tried the same settings and disabled Domain Source like suggested in #27. Unfortunately not with the same result.
After that ive been trying some other things as well. And have come to the conclusion that for some reason when I create a stadard "page" node it stays on the correct domain. But with the content types Ive created on node creation / save I get redirected back to the main domain. Im now trying to figure out if there is something specific that is different between the content types which is maybe causing it.
Comment #30
TCRobbert commentedAs Im using quite some cck fields for my content types it was a bit of a search, but finally figured out what was doing it. It appears as soon as that I enable the cck field for an image upload via FileField it has the effect of redirecting me to the main domain on first time node safe. As im using quite a few modules to change the behavior of ImageField I was wondering if somebody could test this with a clean install. To see if with merely the basic cck FileField it already has this behavior.
Comment #31
agentrickardIt may be that the redirect is too aggressive. Right now, it takes all saved content to the perferred link domain.
It may be better to ensure that it goes to a domain where the node is visible.
Prior to 6.x.2.0, people had the problem where saving a node automatically redirected them to the primary domain. This is due to an unchangeable redirect hardcoded in the node module.
Comment #32
TCRobbert commentedSo if I understand you correctly it thinks it needs to be showing the file on a different domain (the too aggressive part). After which it thinks its on another domain and moves to show the node on the wrong domain as well.
All in all is it something you would be able to figure out a fix for?
Comment #33
agentrickardThe proper fix is probably to ensure that a user is redirected back to the domain from which the edits were made, which did not always happen prior to 6.x.2.0.
However, in that case, it is possible that the content is not viewable on that domain, which triggers an access denied. Which is what we are trying to avoid.
Comment #34
TCRobbert commentedJust as a reminder, but editing a node works fine (which makes the thing so strange). Its merely on creation and then actually saving the node that it redirects to the main domain.
Is there anything else I can do to find a solution for this?
Comment #35
agentrickardNo. We have a difference of opinion as to what the behavior should be. If the node is assigned to the main domain, then this behavior is acceptable and BY DESIGN.
If it is not, then its a bug and I'm going to revert the damn patch.
Comment #36
agentrickardHere's a better patch that does the following.
PLEASE READ THIS CAREFULLY, as this is the intended behavior.
1) On node save or update, store two session values, the NID and the current DOMAIN_ID.
2) If these values are present, check to be sure that the form returned the user to the proper domain, which is defined as:
2a) If the node is sent to 'all affiliates', the domain from which the form was submitted (the DOMAIN_ID).
2b) Otherwise, the proper 'source' domain of the node, which is defined as the canonical domain for this content. If not using Domain Source, this domain is the _first_ matching domain that a node is assigned to.
Now, the only possible bugs are:
A) You are redirected to a domain where the node is not visible.
B) The rule in 2b is not correct, and should instead be "Issue a redirect only if the node is not visible on this domain."
Comment #37
TCRobbert commentedSorry for the late response. Its been hectic the last few days.
Im sorry to be the bringer of bad news, but unfortunately the problem remains. Content types with CCK FileFields still redirect me back to main domain. Content types without CCK FileFields work as intended.
Updating the node works as intended so its still only on first time node save.
Comment #38
agentrickardThe FileField is interfering. Look at the logic. We're issuing a redirect _after_ the form has completed its process, based on a $_SESSION value.
If the redirect is going to primary domain it is because the node belongs there.
Comment #39
TCRobbert commentedBut then the question should be why is FileField interfering now, since DA 2.0?
Right?
Comment #40
agentrickardI don't think it is. I don't think you are understanding the designed behavior.
Comment #41
TCRobbert commentedIm sorry agentrickard, my php knowledge and general logic in how it works is pretty good, but not as good as I would hope. Like you say I probably do not fully understand the designed behavior. The only thing I can say is that I really would like to get it to work properly and if there is anything I can do let me know.
Thanks again for delivering such a great module and investing all this time into it.
Comment #42
agentrickardIt's ok. This is a nasty problem. My shortness is due to the fact that you don't seem to be testing the patches or responding to the questions.
Please re-read #36, test that patch, and argue about the business logic. We just had a separate request that said: "On editing, always return to the domain that the form was entered on."
If that is the behavior people want, we can make it happen.
Comment #43
iancawthorne commentedEdit / Create node submission would be best to return to the current domain when "administer nodes"and "Enforce rules on administrators" is set to "do not enforce". These settings suggest to the system that the user is an administrator of all domains and does not need to be redirected to the domain the content is assigned to.
Comment #44
agentrickardThat logic seems too complex to me, given the problem that we are trying to solve.
The original issue is that, in some cases, users are returned to the primary domain after editing. I really don't want to introduce another setting, just a logical default to prevent that from happening.
So I think the two options are:
a) Return the user to the domain the form was sent from.
b) Return the user to the canonical source domain of the node.
Having a setting for those two behaviors seems like overkill to me.
Comment #45
iancawthorne commentedYou are probably right. Is there a patch in this thread than can achieve (a) Return the user to the domain the form was sent from?
I tried the path from #36, but it appeared to have no effect. If this patch does work, can you confirm and I will have another go.
Comment #46
agentrickardThe patch in #36 does b), not a).
Comment #47
agentrickardHere's a patch for logic a).
Comment #48
iancawthorne commentedHi agentrickard,
I applied this patch and it seems to work sometimes, but not others. I can't figure out when it is.
I have two domains checked to publish to. One of which is the one the form is on. Sometimes when I submit, I stay on the domain I'm on (which is what I want to achieve), but on other occasions, I get taken to the other domain. Without changing any settings, this is just between clicking edit and submitting the form.
One other thing to add is that, if I try to edit from a view following the edit link with &destination=xxxxx in it, this is overruled and the node view page is used.
Comment #49
agentrickardI am now even more tempted to simply remove this behavior entirely, and let Drupal do what it wants.
Comment #50
guysung commentedI guess I have similar issue with TCRobbert, The redirection to main domain happens only once at the time of creation.
Let me explain what I've found in terms of sequence of function calls after you fill out the node creation form and click save button.
I tried every patches above and have same sequence below.
1. domain_init()
2. domain_node_save_redirect()
===============================> bootstrap done!
3. domain_nodeapi()
4. drupal_process_form()
5. drupal_redirect_form()
===============================> redirect to main domain and got access denied page.
As you can see, I think domain_nodeapi() should get called early than domain_node_save_redirect() so this is why all above patches are not working for me in my opinion. Any idea?
Comment #51
agentrickardYou want to check the execution of domain_nodeapi() with $op of 'insert' and 'update' only. It should have no effect on other operations.
But it sounds like domain_init() is being called during the form processing stage.
Try this in domain_init():
Comment #52
guysung commentedThanks for quick response in advance.
I've checked domain_nodeapi() with $op of 'insert' and 'update' with your code snippet above, and saw $_SESSION['domain_save_id'] got updated properly but it seemed
it never been used until I got redirected through the last function call of drupal_redirect_form().
Thanks again.
Comment #53
TCRobbert commentedagentrickard,
Sorry for my very late response and from what I understand now my unclear explanation in #37. I actually did try the patch in #36 and that didnt work out, thats why i said: "Im sorry to be the bringer of bad news, but unfortunately the problem remains." :)
It seems ppl have joined this thread with more knowledge about your proposed logic so Ill stay out of the way. If there is anything I can do or test let me know.
Comment #54
iancawthorne commentedJust a quick update to this post #48. I discovered that the destination in the url does actually work with domain module. I had been using &destination?xxx rather than ?destination=xxx so apologies, that was my bad.
Comment #55
agentrickard@djmystic82 cool. Where does that leave us?
@TCRobbert -- If you just provide a simple explanation of the behavior you want, that would be helpful. I am assuming you want b) "Return user to the domain the form was entered from".
Comment #56
guysung commented@agentrickard I traced my case more, further steps are below.
1. domain_init()
2. domain_node_save_redirect()
===============================> bootstrap done!
3. domain_nodeapi()
4. drupal_process_form()
5. drupal_redirect_form()
6. form_execute_handlers()
7. node_save()
8. domain_get_node_match()
9. drupal_alter()
10. domain_source_domain_source_alter()
11. domain_source_lookup()
12. domain_get_node_domains() =======> $domain_id got FALSE value
13. domain_lookup =================> fail to look up current domain here
===============================> redirect to main domain and got access denied page.
Could you please check these sequence and tell me why step 12, 13 got fail to lookup current domain so later I got redirected to main domain? Obviously, domain_access table didn't updated with a new node at the time of step 12, 13.
Any idea or suggestions would be much appreciated...
Comment #57
iancawthorne commented@agentrickard : I opted for an alternative method for administration rather than using a domain name just for that task as we were on a tight deadline to provide our site to the client.
As for the problem, the patch appeared to work for editing as long as the administration domain was the primary domain, so I would consider that the correct behaviour. I couldn't get it to work for creating a node though.
I think an overview would be that that the domain module works well for multiple sites with content managed from each site individually. It becomes a problem when the intention is to manage all content for multiple sites from one admin interface as you get redirected and logged out depending on where you assign the content to.
Comment #58
agentrickard@djmystic82 That is only a problem if your domains don't share a top-level cookie (e.g. .example.com) or you don't use the SSO module to configure multiple logins (see 1.4.1 of README.txt). It also suggests that for form behavior should be "return to the domain where the form was submitted."
@guysung
My confusion in your chart is "where in this sequence do you submit the form?"
Comment #59
guysung commented@agentrickard My chart is all about sequence of major function calls with debugger after I submit the form to create a node.
In domain_source_lookup() , $domain_id got FALSE value, because domain_get_node_domains() returned FALSE of $domain_site and null of $domains.
Thanks much.
Comment #60
nonsieComing to this discussion way too late but I think the behavior should be "return to the domain where the form was submitted". Just my 2 cents.
Comment #61
agentrickard@nonsie
Let's make that work, then. The patch to test is #47.
Comment #62
guysung commented@agentrickard
I've solved my case through long tracking with debugger. It is very interesting.
I set trigger/action to send a email for newly posted content. when I turned off trigger/action email for newly posted content, the redirection issue was solved.
The issue is that trigger_nodeapi() invoke domain_url_outbound_alter() before the domain_access table updated by domain_node_access_record().
( As you know, node_invoke_nodeapi() is followed by node_access_acquire_grants() in node_save() )
For detail sequences, trigger_nodeapi() call system_mail() and domain_url_outbound_alter() in turn, this cause wrong cached $domain variable in domain_get_node_match() because it is too early to look at the domain_access table which didn't updated yet.
You may want to try to create a new node after setting action of "send a email to moderation team" for "Trigger: After saving a new post" .
You can experience the redirection to main domain.
Could it be bug? Any Idea?
@djmystic82 , TCRobbert : Did you set "send a email" actions for "After saving a new post" trigger ?
Comment #63
TCRobbert commented@agentrickard,
Yes for me the best logic is that the user is redirected to the domain he started creating the node on.
@guysung,
No I currently have no actions set. I figured out that for me it is only happening when I have a CCK Filefield enabled for that content type. See #30
Comment #64
agentrickard@guysung
Wow. Thanks. But I don't see where trigger_nodeapi() would call l() or url() to invoke domain_url_outbound_alter().
This may be an unsolvable problem, due to how the form redirects are handled by core. I thought the session handler would do the trick.
Comment #65
guysung commented@agentrickard
Invoking domain_url_outbound_alter() in trigger_nodeapi() only happens when you set "send a email to..." action to "After saving a new post" trigger.
system_mail() invoke url() and domain_url_outbound_alter() in turn.
Detail sequence are below for your information.
1. node_save() ---------------> node.module(929)
2. node_invoke_nodeapi() ---------------> node.module(673)
3. trigger_nodeapi() ---------------> trigger.module(243)
4. actions_do() ---------------> actions.inc(100)
5. system_send_email_action() ---------------> system.module(1745)
6. drupal_mail() ---------------> mail.inc(119)
7. system_mail() ---------------> system.module(1781)
8. url() ---------------> common.inc(1480)
9. custom_url_rewrite_outbound() ---------------> settings.custom.url.inc(18)
10. domain_url_outbound_alter() ---------------> settings.custom.url.inc(108)
11. domain_get_node_match() ----------------> domain.module(1167)
Is there any way to skip invoking domain_url_outbound_alter() by trigger_nodeapi()? so that, I can use trigger/actions with solving the redirection issue.
Any code snippet or Idea?
Thanks.
Comment #66
agentrickardNo. We're getting bitten by the static variable in domain_url_outbound_alter() here. But the patch in #47 ought to correct that, since the URL that function uses doesn't care about domain_url_outbound_alter() -- unless it is getting invoked by drupal_goto(), which would make sense. Ugh.
The solution seems to be to ensure that domain_node_save_redirect() fires in the proper sequence, which probably means watching the form process functions more closely and putting in a delay if the form is still being processed.
Comment #67
agentrickardI cannot replicate the behavior in #65 when using the patch from #47.
Comment #68
eabrand commentedLooks good to me!
Comment #69
agentrickard#47 has been committed to HEAD and 6.x.
Comment #70
guysung commented@agentrickard,
It's been a while but here is what I found from the testing.
I couldn't replicate the redirection issue with having the #47 patch and "Trigger: When either saving a new post or updating an existing post" trigger set just like you, but I am still having the redirection issue with having the #47 patch and "Trigger: After saving a new post" trigger set.
It seems the module works differently depending on which trigger we are using.
In #67, Were you using exact "Trigger: When either saving a new post or updating an existing post" trigger set? If so, "Trigger: After saving a new post" trigger set would be the one you may need to test it.
Appreciate for all your work.
Comment #71
agentrickardUsing "Trigger: After saving a new post" --> Send Email (from Drupal core actions).
Comment #72
agentrickardHave you tested 6.x.2.1?
Comment #73
guysung commentedYes, I have tested it and using 6.x.2.1 with the issue now. Thanks.
Comment #74
agentrickard"With the issue now" means that you are still having a problem? I would look to see if another module is issuing a redirect.
Comment #75
guysung commentedYes, I am still having the issue. I've been tracking both "Trigger: When either saving a new post or updating an existing post" and
"Trigger: After saving a new post" cases.
I tried to describe the source tracking as best as I can
and hope it will help you understand what I've tracked down. Feel free to ask if you need more detail information.
======> No problem!
======> Having the redirection to main domain issue.
As you can see in step b.1.a.2.e,
node_access table doesn't have a entry for the new content at the time of calling domain_get_node_match(), afterward
node_access table is updated by domain_node_grants() call in step b.1.a.3.a
I think there are chances that domain_get_node_match() would be called early before node_access table updated by domain_node_grants().
Comment #76
agentrickardI still don't see how that would affect the redirect. None of that code is relevant to the redirect in 6.x.2.1. The logic is simply:
So what's in the $_SESSION during your routine?
Comment #77
guysung commented@agentrickard,
I think $_SESSION['domain_save_id'] have a right value of 3 for the current domain where a node is created.
Let me simplify the flow of function calls add more info. below for the better understanding in the issue.
In sum, when I get the redirection issue, domain_node_save_redirect() has never been used.
Thanks.
Comment #78
agentrickardThen some other module is interfering with your $_SESSION, because if that value is present, the redirect should happen on the next non-cached page load.
Comment #79
guysung commentedCould you give me some idea where $_SESSION is used for the next non-cached page load? So that I can trace it down.
Comment #80
agentrickardIt's in domain_node_save_redirect(), triggered by domain_init().
http://api.therickards.com/api/function/domain_node_save_redirect/domain
This might be a caching issue, and that may need to be triggered by domain_boot().
Comment #81
guysung commentedI can't believe why it's taken so long to figure this out, it was really long way around.
Actually, I have set $cookie_domain dynamically per domain basis for some other features.
Different $cookie_domain among domains has been blocking use of domain_node_save_redirect().
Not sharing cookies among domains could make domain_node_save_redire() useless. Documenting or notes may be required.
@agentrickard, I am really thankful for helping me track down this issue and creating/supporting nice module.
Comment #82
agentrickardHandling the multiple login issue is outside the project scope. The behavior works as designed. Setting back to fixed.
But it makes sense, if $cookie_domain is different, so are the $_SESSION values, I believe.
Comment #84
TCRobbert commented@agentrickard
First of im sorry for digging up the old issue by now and for the lack of activity in the past month. The amount of work to deal with and the holidays at the end of the year were rather time consuming.
The reason for me to dig it up is that for me the issue still remains. By now ive updated the module to 2.1. I tried the solution described in #81 (as I also have it dynamically set) unfortunately without success.
To check it out if my problem still only emerged under certain circumstances i tried a few things out. When I disable my CCK FileField for that content type the module works as it is supposed to and stays on the correct domain.
Understanding now what you meant with #38 and #36 it is filefield causing the switch to the main domain after which the redirect sends it to the domain which is stored in the session value. At least that is how I interpret it.
Anyways I was hoping if you could look into this again or give me a hint to where I can disable the entire logic that came with DA 2.0.
Again many thanks for this amazing module and support.
PS I didnt change the status as maybe you rather want me to create a new issue. If that is the case just let me know and ill open up a new one.
Comment #85
TCRobbert commentedChanged it to active just for the above comment and for not showing up in the open issues. If it shouldnt be reopened just close it again.
Comment #86
agentrickardAFAIK, this only occurs when domain 1 and domain 2 do not share a $_SESSION cookie.
There is nothing I can do, given that the $_SESSION doesn't persist across different domains.
Since $_SESSION['domain_save_id'] is not set, domain_node_save_redirect() should not fire.
If it _is_ firing, you need to tell me what values it uses.
Otherwise, you should look at what filefield is doing that causes the redirect, and fix it there.
Comment #87
TCRobbert commented@agentrickard
Thanks for the quick response as usual. As development for this site has been fully picked up again I have been backtracing this problem as much as i can.
I tested what exactly was doing it. Actually it is not FileField itself, but ImageField (which hooks into FileField). As soon as I enable an ImageField for a content type the problem appears.
Trying to figure what exactly goes wrong I first backtraced which steps it takes in your code.
As you said domain_node_save_redirect() never gets fired. The problem seems to be in domain_url_outbound_alter() and domain_get_node_match() when drupal_goto is fired at node save.
The first time when domain_url_outbound_alter() runs with the option path node/id-number it runs domain_get_node_match() feeding it the id-number. And this is the point where the problem starts. At the moment it runs that function for the first time it checks what the domain should be by querying domain_access. With an ImageField enabled in this situation that query returns an empty value as if it the correct values have not been written to the DB yet. This builds up the static $domain with main domain details. After which it goes through domain_url_outbound_alter() a few more times and as the static $domain has been set by then it seems to keep the same values.
As soon as drupal reports back the node has been fully saved (right after the drupal_goto) the query in domain_get_node_match() returns the correct value and gives no more problems.
The question coming from this would be why at the point of querying the DB it would return an empty value. This is something I assume I can blame ImageField for.
As I believe Im still the only one with this problem Ill be going over this problem with one of our inhouse Devs. If we figure it out ill let you know. But for now I figured Ill let you know what I found out so far and maybe if you have an idea give me a notch in the right direction.
Thanks again for your time and patience.
Comment #88
TCRobbert commentedMy bad, it remembered my setting from yesterday. Changing it back to won't fix.
Comment #89
agentrickardYou should probably open a new issue. The big thing to note is this: Are you running subdomains that share login and session cookies or not?
In other cases, the sites were not sharing session cookies, which means I can't really do anything about this problem.
Comment #90
abuzakaria commentedSorry for re-opening this ticket. I wasn't sure if I would open a new ticket or not because my issue falls very close to what was initially mentioned in this ticket. However, amongst 89 replies it seems that the same issue was being reproduced various different ways. But in my case just one simple step when a new node created only for one subdomain, from that subdomain is causing a redirecting to the primary domain. Please see my comments below:
I have domain1 (primary domain) and domain2. I switched to domain 2 and created a page node only for Domain 2 making Domain 2 the source. When I create it without providing any menu settings the node gets created fine and the page view is redirected to domain 2. However, when I create this node and provide a menu item for the node, I get redirected to primary domain.
I have tried the patches but its not working. Any help or suggestion would be highly appreciated. Thanks!
Comment #91
agentrickardThis is not a solvable issue.
Comment #92
webwriter commentedIt looks like the behavior should be "return user to the domain they created the node from" and that code has been committed but I am using 6.x-2.5 and having a similar issue to the OP.
I do not have Imagefields or Filefields on my content type but it is a custom content type. I am not creating menu items. They are just straightforward nodes. All subdomains are the same as the parent domain, so there shouldn't be any session issues, I would think.
When someone adds a node from atlanta.domain.com or newyork.domain.com they are redirected to the submitted node on domain.com where they are given an access error (unless they have edit/access rights to domain.com.) Simple node assigned to a single subdomain, using the add page on the subdomain that the node is assigned to appear on.
Editing nodes returns them to the correct place, it's just the initial save that causes this redirect. Sorry if I should create a new issue... but the behavior seems to be what is described in this issue and maybe there's a clue here I'm just not getting.
If this is truly something that can't be fixed at the module level, can you tell me if it can be hacked modified for a specific installation? It's causing lots of confusion as people think the error they get means their node wasn't added and readd... and add another... then again...
It seems that the basic operation of the module ought to allow people to add a node on a subdomain and stay on that subdomain.
Thanks!
Comment #93
bleen commentedsubscribing
Comment #94
pgrond commentedI just had a conversation on irc with TCRobbert and we figured out that the domain source module has to be enabled. So for anyone still having this issue check if that is enabled.
Comment #95
bpresles commentedSorry, but this is a perfectly fixable issue, and I provide the file patch attached.
There is a mistake in domain_get_node_match() function implementation that caches FALSE results (bad programming practice! invalid results should never be saved in anyway and of course not in a cache variable!).
This makes the static $domains array() cache variable contains a '' => array(), because it calls domain_lookup() with FALSE param, which is of course a nonsense.
This results to the fact that then the static $domain cache variable to have the default domain as value, because even though FALSE was passed to domain_lookup(), as you can guess from the fact that '' => array() is added to $domains static cache variable, domain_lookup does pass FALSE to the query as domain_id and drupal convert FALSE to 0, which is the default domain domain_id, and so domain_lookup does return default domain data even though FALSE was passed.
The fix is:
Which means nothing should be return (so NULL) from domain_get_node_match() when the db_result() return FALSE, as it means that there is no valid value found, and so default drupal and domain behavior should be used.
What cause the domain_get_node_match() to have db_result() returning FALSE is when a module call url() (via l() or directly) in its hook_nodeapi() implementation and when it's called before the hook_nodeapi() implementation of Domain module.
This for example occurs when you have both Workflow and Domain installed, Workflow hook_nodeapi() with op "insert" is called before the domain's one, and in its implementation, there is a watchdog() call that contains a l() call (that calls url(), that calls custom_url_outbound() that calls domain_url_outbound_alter(), that calls domain_get_node_match() but as this is before any domain info is saved for the node, the db_result() of domain_get_node_match() returns FALSE.
Please find the patch file attached.
Comment #96
agentrickardThis makes sense to me. I'd love to see some other testers.
The other module call to url() or l() has been the problem all along.
I don't quite agree about caching FALSE. Why waste cycles on a known failure? Though in this case, the return of an empty/invalid array does appear to be the bug.
Nice work!
Comment #97
agentrickard@bpresles what's the reliable way to replicate this error? Just install default Workflow module?
One of the biggest problems in fixing this one has been reliably replicating the error.
Comment #98
bpresles commented@agentrickard
Yes, if you install the workflow module and enable it (of course), next time you create a content on another domain than the default one and save it, you'll be redirected to the default one.
In fact any invocation of domain_url_rewrite_outbound() before the domain data are saved for the node, will trigger the error. This is invoked for example anytime url() is called, so as long as a module calls url() with a 'node/' path (directly or via l() or any other function invoking url()) before the domain data are saved for a node, this will trigger the error.
It just happens that Workflow modules does call l() with a node/ path, before domain data are saved. But it may happens with other modules too, so you can't really predict that, so it's important that domain_node_match() don't cache invalid result (db_result() returning false) in that case. This is exactly what my patch does.
The line triggering the issue on workflow.module is line 570 (workflow module version 6.x-1.4), inside workflow_execute_transition():
watchdog('workflow', 'State of @type %node_title set to %state_name', array('@type' => $type, '%node_title' => $node->title, '%state_name' => $state_name), WATCHDOG_NOTICE, l('view', 'node/' . $node->nid));
workflow_execute_transition() is called by workflow_transition() that is called in 'insert' and 'update' operation of workflow_nodeapi() (line 251);
As you can see, it calls
- l('view', 'node/' . $node->nid)
- which calls url()
- which calls customl_url_rewrite_outbound() implementations on all modules
- And so domain_url_rewrite_outbound() is called
- Which calls domain_url_outbound_alter()
- Which calls domain_get_node_match()
And as workflow_nodeapi() is invoked before domain data being saved, the db_result() of the query done by domain_get_node_match() returns FALSE.
My patch only avoids that anything is done (domain_lookup(), caching result...) when the db_result() of domain_get_node_match() returns FALSE, as it's obvious that in that case, the result is invalid and should not be processed in any way.
Comment #99
agentrickardThanks. This is the most awesome bug fix EVER.
This one drove me crazy for a long time, because it was never reliably pinned down. It's a combination of modules doing something odd (calling l() during node save?) and bad code on my part.
Once I test and confirm, I will commit.
Comment #100
bleen commentedbpresles++++
I havent had this problem in a while, but glad to see someone seems to have gotten a handle on it.
Comment #101
agentrickardFor the record, it took me 20 minutes to replicate this error. I finally forced it to happen by setting the weight of workflow module < 0.
Here's the D6 patch that went in.
Comment #102
agentrickardHEAD patch.
Comment #103
agentrickardHEAD applies to 7.x.2 with mild offset.
Comment #105
franzJust a +1, this saved me! Definitely wainting for a stable release with it...