Problem/Motivation
The Domain Source module sets a redirect response on the the form_state object.
When a response object exists the form redirect URL is totally ignored.
Steps to reproduce
Install the Domain module and its submodule Domain Source.
Create a basic domain.
Create a new content and select the created domain as its source.
Once the domain source is selected, save the content using the Save & Edit button.
You get redirected to the content view using the source Domain URL instead of returning back to the edit form.
Proposed resolution
When setting the form state redirect URL, replace any existing response object from the form state by our own redirect response.
Here is the code from the FormSubmitter.php core file where we can see that Drupal is checking that the form state doesn't have a response already defined before creating a new redirect response using the redirect URL:
// If no response has been set, process the form redirect.
if (!$form_state->getResponse() && $redirect = $this->redirectForm($form_state)) {
$form_state->setResponse($redirect);
}
// If there is a response was set, return it instead of continuing.
if (($response = $form_state->getResponse()) && $response instanceof Response) {
return $response;
}
Issue fork save_edit-3541709
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
Comment #2
mably commentedComment #4
mably commentedComment #5
mably commentedComment #6
caesius commentedI was hoping someone would eventually come along and say "yeah this fixes a big conflict with other contrib modules and definitely doesn't break anything else" but that never happened. The fact that the steps to reproduce require setting up a module I've never used before didn't help, so I never got around to this.
I used an AI assistant to evaluate the MR and here's what it came up with:
Comment #7
mably commentedThanks for the review, both points are addressed.
The handler keeps its
setRedirectUrl()call and only promotes the redirect to a response when another submit handler has already set one. That promotion is gated onFormState::getRedirect(), which already returns FALSE for a programmed form, a rebuilding form and one whose redirect has been disabled, so the guards are core's own rather than a copy of them.TrustedRedirectResponseis replaced by a plainRedirectResponse.The branch also adds a kernel test covering the redirect target, the replacement of an existing response, the destination parameter and those three no-redirect cases. It fails against 2.x and passes with the change.
One thing outside the scope of this issue: the project had no
.gitlab-ci.yml, so nothing ran the test. I added one in its own commit, with a handful of small pre-existing lint fixes it turned up. Please drop that commit if you would rather handle CI separately.AI-Generated: Yes (Claude Code was used to help write the change, the test and this comment. I reviewed all of them. The test was confirmed to fail against the unpatched code and to pass with the change.)
Comment #8
mably commented[DELETED]
Comment #9
caesius commentedHi, I'd like to avoid performing any "linting" on 2.x given that Drupal 10 is EOL soon and I'd like to cut over to a 3.0.0 release not long into the new year. Feel free to add tests but please do not do any 2.x linting since it clutters commits with unrelated changes. Also, if possible, ensure that *identical* bug fixes and tests are provided for both 2.x and 3.x (or at least, functionally identical bugfix code on 3.x)
Linting and code cleanup will be handled separately at #3619151 for 3.x only.
Comment #10
mably commentedFeel free to remove anything you want from my MR.
Comment #12
caesius commentedComment #15
caesius commentedComment #17
mably commentedThanks for the merge @caesius!