Problem/Motivation
I have a site whose base URL is:
(my local machine is called "wren").
I installed with standard profile in English, then turned on the 4 multilingual modules, added Spanish, and made nodes translatable. I added some content and translated it.
Then I go to the admin/content page. The full URL of that page is:
http://wren/~d8git/admin/content
In one of the lines, I click the Delete link in the operations drop-down, which either takes me to a node delete confirm page or a translation delete confirm page. The URL is one of these:
http://wren/~d8git/node/3/delete?destination=/%7Ed8git/admin/content
http://wren/~d8git/es/node/3/delete?destination=/%7Ed8git/admin/content
But on both of those pages, if I click Cancel, it tries to take me back to:
http://wren/~d8git/~d8git/admin/content
This URL does not work. The link has the wrong URL.
If I instead click the Delete confirmation button, I get back to
http://wren/~d8git/admin/content
so it is just the confirm URL that is not right.
Proposed resolution
Fix the confirm URL in the node/translation delete confirm form.
Remaining tasks
Make a patch. Test it. May need an automated test but right now the automated tests are passing... do we have a way to test installing where the base URL is something like this?
User interface changes
The cancel link will work on sites with different base URLs.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|
Issue fork drupal-2582295
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
jhodgdonAs a note: If you just go to node/1/delete the cancel URL is fine (takes you back to node/1). So it is only if you come at it from admin/content (which puts a destination parameter into the URL).
Also, I traced this down to a problem in
\Drupal\Core\Form\ConfirmFormHelper::buildCancelLink()
So moving to Form system component.
Here's the code:
This is where the problem is. The destination parameter in the format given is working fine for Submit on forms, but it is NOT working fine here.
Comment #3
jhodgdonAdding the @todo issue as Related here.
Comment #4
tim.plunkettComment #5
tim.plunkettThat related issue might be helpful, since having the base path only *sometimes* is exactly the problem.
Comment #6
pwolanin CreditAttribution: pwolanin at Acquia commentedFrom the RedirectResponseSubscriber - if the destination has a leading slash we should treat it as a URL that includes the base path already. If it doesn't have a leading slash the code would be correct.
Comment #7
tim.plunkett@pwolanin suggested that we assume every link that begins with a leading slash includes the base path.
This will break the test coverage we added in #2501655: ConfirmFormHelper::buildCancelLink() incorrectly handles ?destination URLs with a leading slash
Comment #8
tim.plunkettComment #11
pwolanin CreditAttribution: pwolanin at Acquia commentedSo, this is not really the right approach and I don't see a trivial fix fix here.
In #2418219: Deprecate destination URLs that don't include the base path and in the code in \Drupal\Core\EventSubscriber\RedirectResponseSubscriber::getDestinationAsAbsoluteUrl() we assume if the destination has a leading slash is includes the base path already.
There is currently no way to construct a Url object and tell it to strip the base path.
So, we either need a special case here, or directly construct the markup, or ?
Comment #12
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedHere's more of a gedanken patch
Comment #13
dawehnerYeah I think the gedanken
Url::fromUri('generated://this-is-any-previously-generated-url')
Comment #14
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedYes, so basically we might need another scheme that tells the unrouted url assember to use the value as if it already includes any necessary pas path/script.
This would just be a couple small tweaks to \Drupal\Core\Utility\UnroutedUrlAssembler::buildLocalUrl()
Comment #15
Chi CreditAttribution: Chi commentedIf this is only case handling this sort of urls I would strip base path right there instead of creating another scheme.
$options['path'] = substr($options['path'], Unicode::strlen($request->getBasePath()));
Comment #20
julia.klimovsky CreditAttribution: julia.klimovsky at Sitrus Agency commentedRemove basepath from the path only if it starts with basepath.
Comment #21
julia.klimovsky CreditAttribution: julia.klimovsky at Sitrus Agency commentedOh, forgot to import Unicode class.
Comment #22
bapi_22 CreditAttribution: bapi_22 at Cybage Software Pvt Ltd. commentedHi julia.klimovsky,
If you will try to pass the destination value without drupal sub directory name, It will work properly. No need to patch inside ConfirmFormHelper.php file.
instead of /drupaldemo/node/{nid}/delete?destination=/drupaldemo/admin/content
you have to find a way to pass the destination like below
/drupaldemo/node/{nid}/delete?destination=/admin/content
Comment #23
julia.klimovsky CreditAttribution: julia.klimovsky at Sitrus Agency commented@bapi_22, I have to disagree :)
While system URLs like
?destination=admin/content
indeed work withbuildCancelLink
, but...The destination value is generated by the
RedirectDestinationInterface
and Core decided to change its behavior in #2417645: Change destination query string handling to break dependence on system path to generate destinations WITH base_bath. Long time ago. So, I still can't see better way of fixing the cancel links than strip the base path. This way, we still support both?destination=/subdir/admin/content
and legacy?destination=admin/content
PS. I will look into failing tests asap...
Comment #24
julia.klimovsky CreditAttribution: julia.klimovsky at Sitrus Agency commentedI've updated the patch and tests so it covers "subdirectory" situation properly
Comment #26
julia.klimovsky CreditAttribution: julia.klimovsky at Sitrus Agency commentedComment #27
SenthilMohith CreditAttribution: SenthilMohith as a volunteer and at DrupalPartners, Innoppl Technologies Pvt. Ltd commentedI have tested the patch #26 manually and it seems to be working fine for confirmation pages. Please refer the attached screenshots.
Test case 1:
Created a new content and trying to delete the content confirmation page. Previously it shows page not found. After applying the patch it's redirecting to the content management page.
Testcase 2:
Created new custom block using Block layout and created a new test block content. After that, I'm trying to delete the content and it's redirecting properly to block content management page. Previously, it redirects to page not found.
Comment #28
SenthilMohith CreditAttribution: SenthilMohith as a volunteer and at DrupalPartners, Innoppl Technologies Pvt. Ltd commentedComment #30
larowlancould the argument be made that this logic belongs in Url::fromUserInput instead of in ConfirmFormHelper?
It seems to be embedding intimate knowledge of the routing system in this form, when you could easily argue that it would belong better in the Uri::fromUserInput factory method
I'd like to get some input from @pwolanin, @dawehner and @tim.plunkett here as there are threads of an alternate approach being discussed but then the patch takes a right turn and goes with the
strpos
approachComment #31
SenthilMohith CreditAttribution: SenthilMohith as a volunteer and at DrupalPartners, Innoppl Technologies Pvt. Ltd commentedComment #32
SenthilMohith CreditAttribution: SenthilMohith as a volunteer and at DrupalPartners, Innoppl Technologies Pvt. Ltd commentedComment #35
seanB+1 to adding this logic to
Url::fromUserInput
! Updated the issue title to make this more generic. We have similar issues in:#2990664: Media library does not work when Drupal is installed into a sub-directory
#3002805: Media Widget Cannot Select Media - Page not Found/ReWrite Base Conflict
#3042038: Allow UrlGenerator to process action URLs in FormBuilder::buildFormAction()
Comment #36
Berdir#2646744: \Drupal\Core\Url does not accept root-relative (file) URLs, making it impossible to let LinkGenerator create root-relative file URL links is also closely related, aka the same but for base: aka file URLs, if I understand this correctly.
Comment #37
seanBHere is a first attempt to fix this in
Url::fromUserInput()
.Comment #39
seanBThis should fix the tests.
Comment #40
BerdirI haven't tested it yet, but I think the flaw with this approach is that it is going to do pretty horrible things if the base path matches the drupal internal URL, e.g. imagine the base path is /admin/, so you have /admin/admin/...
Comment #42
seanBI thought about that. Not really sure how to deal with it though. The URL object currently seems to be inconsistent in that
UnroutedUrlAssembler::buildLocalUrl()
adds the basepath when callingUrl::toString()
, but if you feed that same URL toUrl::fromUserInput()
, it is not stripping the base path off again.This would indeed break for the situation where the subdirectory is /admin, but the
Url::fromUserInput()
method does not receive the subdirectory when called. On the other hand, it currently breaks for every case we the subdirectory IS passed toUrl::fromUserInput()
. If anyone has an idea to have it both ways I'm open to suggestions?Comment #43
seanBThat is totally true. After discussing this with berdir on slack, I think we agreed that changing this in
Url::fromUserInput()
is probably not a good idea. There is no reliable way to detect a subdirectory if the subdirectory is also a valid Drupal path. I guess only the calling code would know if a subdirectory is expected or not.Url::fromUserInput()
already mentions that it only accept valid Drupal paths relative to the root directory. We could add a helper function to strip subdirectories from paths though. Created #3044656: Add a helper method to strip subdirectories from URL paths to fix that.Let's change this issue back to its original purpose. It could be postponed on #3044656: Add a helper method to strip subdirectories from URL paths, or not :)
Comment #44
gaurav_manerkar CreditAttribution: gaurav_manerkar at EPAM Systems commentedAny update on this.
Issue still present on Drupal 8.8.1
Comment #45
gaurav_manerkar CreditAttribution: gaurav_manerkar at EPAM Systems commentedFor Drupal 8.8.x
Comment #46
gaurav_manerkar CreditAttribution: gaurav_manerkar at EPAM Systems commentedFor Drupal 8.8.x
Comment #49
u7aro CreditAttribution: u7aro at Studio Umi commentedFor Drupal 9.2.x
Unicode::strlen() used in the #46 patch have been removed from version Drupal 9. Use mb_strlen() instead.
Comment #50
ranjith_kumar_k_u CreditAttribution: ranjith_kumar_k_u at Zyxware Technologies commentedThe last patch failed to apply on 9.2, so re-rolled it for 9.2
Comment #51
Gauravvvv CreditAttribution: Gauravvvv at OpenSense Labs commentedRe-rolled patch for 9.3, Attached interdiff for same. Please review.
Comment #52
ranjith_kumar_k_u CreditAttribution: ranjith_kumar_k_u at Zyxware Technologies commentedUpdated
Comment #55
olli CreditAttribution: olli commentedI tried patch #52 and found two cases where the cancel link was not what I expected:
/subsite/node/2/delete?destination=/subsite/fi/admin/content
the cancel link is missing the language prefix/subsite/admin/content
.At
/subsite/fi/node/2/delete?destination=/subsite/fi/admin/content
the language prefix is included./subsite/node/2/delete?destination=/subsites/admin/content
the cancel link points to/subsite/s/admin/content
.The first case seems to happen also on a site without subdirectory but should the second case be fixed in this issue?
Comment #56
Kristen PolTagging for bugsmash.
Comment #57
Kristen PolPossible duplicate with a different scenario for steps to reproduce.
#3179708: When Drupal is installed in a sub-path, the cancel link adds the sub-path twice
Comment #58
claudiu.cristeaIt's a bug. I don't think it needs "Needs subsystem maintainer review".
Comment #60
Darren OhComment #61
Darren OhComment #64
Darren OhComment #66
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Webform module Open Collective, The Big Blue House commentedComment #67
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Webform module Open Collective, The Big Blue House commentedComment #68
smustgrave CreditAttribution: smustgrave at Mobomo commentedThink we should still be able to cover when nothing is based in 2nd.
Comment #69
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Webform module Open Collective, The Big Blue House commentedHere is a 10.1.x patch for composer.json. Please do NOT give me commit credit for this patch.
Comment #70
claudiu.cristeaComment #71
joseph.olstadThank you to everyone above, I just spent 90 minutes trying to figure out this issue and then determined that it had to be a core bug. And sure enough, you all have done my work !
Thank you!
Comment #72
smustgrave CreditAttribution: smustgrave at Mobomo commentedElevating to framework manager
Comment #73
catchThere is outstanding feedback on the MR, it needs work, not a framework manager review.
Comment #75
Nikolay ShapovalovI added changes suggested by Mohammed Nassar to the MR 4160.
It would be great to fix this issue, it will be more issues, because many contrib modules moving to Gitlab CI and it runs webserver with the prefix.
I don't understand @smustgrave's suggestion:
Can someone please explain?
Is it possible to hide patch files, and branches that not in use?
Comment #76
Nikolay ShapovalovI think this is ready for review.
Comment #77
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #78
Nikolay ShapovalovMR 4160 is mergeable, update status back to needs review.
Comment #79
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #80
Nikolay ShapovalovComment #81
gaurav_manerkar CreditAttribution: gaurav_manerkar at EPAM Systems commentedI have tested MR https://git.drupalcode.org/project/drupal/-/merge_requests/4160
Looks good, can be moved to RTBC.
Comment #88
alexpottHiding the irrelevant MRs and patches... someone needs to fix the 11.x MR as it has merge conflicts.
Comment #89
gaurav_manerkar CreditAttribution: gaurav_manerkar at EPAM Systems commentedRebased MRs.
Comment #91
smustgrave CreditAttribution: smustgrave at Mobomo commentedwas going to post this issue for a weekly review but issue summary could use some work before reaching out to maintainers to take a look.
Don't see anything in the MR that seems to just be targeting that form but more general Confirmation Form. S
User interface changes usually should contain before/after sceenshots if it's a UI change, probably will need a CR too.
Left some comments on the MR as well.