Problem/Motivation

I have a site whose base URL is:

http://wren/~d8git/

(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.

CommentFileSizeAuthor
#79 2582295-nr-bot.txt90 bytesneeds-review-queue-bot
#77 2582295-nr-bot.txt90 bytesneeds-review-queue-bot
#69 10.1.x-2582295-69.patch2.64 KBjrockowitz
#67 2582295-10.1-67.patch2.64 KBjrockowitz
#66 2582295-10.x-66.patch2.64 KBjrockowitz
#52 interdiff_50_52.txt414 bytesranjith_kumar_k_u
#52 2582295-52.patch2.52 KBranjith_kumar_k_u
#51 interdiff-50_51.txt8.98 KBGauravvvv
#51 2582295-51.patch9.66 KBGauravvvv
#50 2582295-50.patch2.71 KBranjith_kumar_k_u
#49 confirmation_page_cancel_link_build_fix-2582295-47.patch2.65 KBu7aro
#46 confirmation_page_cancel_link_build_fix-2582295-45.patch2.66 KBgaurav_manerkar
#45 confirmation_page_cancel_link_build_fix-2582295-45.patch2.66 KBgaurav_manerkar
#44 Screenshot 2020-01-28 at 9.10.06 PM.png25.55 KBgaurav_manerkar
#42 2582295-42.patch9.69 KBseanB
#42 interdiff-39-42.txt754 bytesseanB
#39 2582295-39.patch9.65 KBseanB
#39 interdiff-37-39.txt4.8 KBseanB
#37 2582295-37.patch5.69 KBseanB
#27 admin-content-delete-confirmation.png211.95 KBSenthilMohith
#27 admin-custom-block-content-delete-confirmation.png215.79 KBSenthilMohith
#26 confirmation_cancel_subdirectory-2582295-26.patch2.66 KBjulia.klimovsky
#24 confirmation_cancel_subdirectory-2582295-24.patch2.62 KBjulia.klimovsky
#21 confirmation_cancel_subdirectory-2582295-21.patch1016 bytesjulia.klimovsky
#20 confirmation_cancel_subdirectory-2582295-20.patch818 bytesjulia.klimovsky
#12 2582295-12.patch1.57 KBpwolanin
#7 2582295-confirmation-6.patch929 bytestim.plunkett

Issue fork drupal-2582295

Command icon 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:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jhodgdon created an issue. See original summary.

jhodgdon’s picture

Title: Node delete page has wrong cancel URL » Node delete page, if coming from admin/content, has wrong cancel URL
Component: node system » forms system

As 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:

    if ($query->has('destination')) {
      $options = UrlHelper::parse($query->get('destination'));
      // @todo Revisit this in https://www.drupal.org/node/2418219.
      try {
        $url = Url::fromUserInput('/' . ltrim($options['path'], '/'), $options);
      }

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.

jhodgdon’s picture

Adding the @todo issue as Related here.

tim.plunkett’s picture

Title: Node delete page, if coming from admin/content, has wrong cancel URL » Confirmation cancel links are incorrect if installed in a subdirectory
Issue tags: -Usability +Needs tests
tim.plunkett’s picture

That related issue might be helpful, since having the base path only *sometimes* is exactly the problem.

pwolanin’s picture

From 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.

tim.plunkett’s picture

@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

tim.plunkett’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 7: 2582295-confirmation-6.patch, failed testing.

The last submitted patch, 7: 2582295-confirmation-6.patch, failed testing.

pwolanin’s picture

So, 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 ?

pwolanin’s picture

Here's more of a gedanken patch

dawehner’s picture

Yeah I think the gedanken Url::fromUri('generated://this-is-any-previously-generated-url')

pwolanin’s picture

Yes, 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()

Chi’s picture

If 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()));

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

julia.klimovsky’s picture

Remove basepath from the path only if it starts with basepath.

julia.klimovsky’s picture

Oh, forgot to import Unicode class.

bapi_22’s picture

Hi 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

julia.klimovsky’s picture

@bapi_22, I have to disagree :)

While system URLs like ?destination=admin/content indeed work with buildCancelLink, 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...

julia.klimovsky’s picture

Status: Needs work » Needs review
FileSize
2.62 KB

I've updated the patch and tests so it covers "subdirectory" situation properly

Status: Needs review » Needs work

The last submitted patch, 24: confirmation_cancel_subdirectory-2582295-24.patch, failed testing. View results

julia.klimovsky’s picture

Status: Needs work » Needs review
FileSize
2.66 KB
SenthilMohith’s picture

I 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.

SenthilMohith’s picture

Status: Needs review » Reviewed & tested by the community

The last submitted patch, 12: 2582295-12.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Needs tests +Needs subsystem maintainer review
+++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
@@ -31,6 +32,10 @@ class ConfirmFormHelper {
+        if ($base_path && strpos($options['path'], $base_path) === 0) {
+          $options['path'] = substr($options['path'], Unicode::strlen($base_path));
+        }

could 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 approach

SenthilMohith’s picture

Assigned: Unassigned » SenthilMohith
SenthilMohith’s picture

Assigned: SenthilMohith » Unassigned

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

seanB’s picture

Title: Confirmation cancel links are incorrect if installed in a subdirectory » Url::fromUserInput() links are incorrect if installed in a subdirectory
Berdir’s picture

#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.

seanB’s picture

Here is a first attempt to fix this in Url::fromUserInput().

Status: Needs review » Needs work

The last submitted patch, 37: 2582295-37.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

seanB’s picture

Status: Needs work » Needs review
FileSize
4.8 KB
9.65 KB

This should fix the tests.

Berdir’s picture

+++ b/core/lib/Drupal/Core/Url.php
@@ -206,9 +206,9 @@ public static function fromUserInput($user_input, $options = []) {
     // base path.
-    $base_path = \Drupal::requestStack()->getCurrentRequest()->getBasePath();
-    if ($base_path && strpos($user_input, $base_path) === 0) {
-      $user_input = substr($user_input, mb_strlen($base_path));
+    $current_request = \Drupal::requestStack()->getCurrentRequest();
+    if ($current_request && strpos($user_input, $current_request->getBasePath()) === 0) {
+      $user_input = substr($user_input, mb_strlen($current_request->getBasePath()));
     }
 

I 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/...

Status: Needs review » Needs work

The last submitted patch, 39: 2582295-39.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

seanB’s picture

Status: Needs work » Needs review
FileSize
754 bytes
9.69 KB

I 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 calling Url::toString(), but if you feed that same URL to Url::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 to Url::fromUserInput(). If anyone has an idea to have it both ways I'm open to suggestions?

seanB’s picture

Title: Url::fromUserInput() links are incorrect if installed in a subdirectory » Confirmation cancel links are incorrect if installed in a subdirectory

I 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/

That 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 :)

gaurav_manerkar’s picture

Any update on this.
Issue still present on Drupal 8.8.1

gaurav_manerkar’s picture

gaurav_manerkar’s picture

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

u7aro’s picture

For Drupal 9.2.x

Unicode::strlen() used in the #46 patch have been removed from version Drupal 9. Use mb_strlen() instead.

ranjith_kumar_k_u’s picture

The last patch failed to apply on 9.2, so re-rolled it for 9.2

Gauravvvv’s picture

Re-rolled patch for 9.3, Attached interdiff for same. Please review.

ranjith_kumar_k_u’s picture

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.1.10 (June 4, 2021) and Drupal 9.2.10 (November 24, 2021) were the last bugfix releases of those minor version series. Drupal 9 bug reports should be targeted for the 9.3.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

olli’s picture

+++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
@@ -31,6 +31,10 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ
+        $base_path = $request->getBasePath();
+        if ($base_path && strpos($options['path'], $base_path) === 0) {
+          $options['path'] = substr($options['path'], mb_strlen($base_path));
+        }
         $url = Url::fromUserInput('/' . ltrim($options['path'], '/'), $options);

I tried patch #52 and found two cases where the cancel link was not what I expected:

  1. At /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.
  2. At /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?

Kristen Pol’s picture

Issue tags: +Bug Smash Initiative

Tagging for bugsmash.

Kristen Pol’s picture

claudiu.cristea’s picture

Status: Needs review » Needs work
Issue tags:

It's a bug. I don't think it needs "Needs subsystem maintainer review".

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Darren Oh’s picture

Darren Oh’s picture

Status: Needs work » Needs review

jrockowitz’s picture

jrockowitz’s picture

FileSize
2.64 KB
smustgrave’s picture

Status: Needs review » Needs work
-    $data[] = ['baz'];
-    $data[] = ['/baz'];
+    $data[] = ['baz', ''];
+    $data[] = ['/baz', ''];
+    $data[] = ['baz', '/base/path'];
+    $data[] = ['/base/path/baz', '/base/path'];

Think we should still be able to cover when nothing is based in 2nd.

jrockowitz’s picture

Here is a 10.1.x patch for composer.json. Please do NOT give me commit credit for this patch.

claudiu.cristea’s picture

Version: 9.5.x-dev » 11.x-dev
Status: Needs work » Needs review
joseph.olstad’s picture

Thank 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!

smustgrave’s picture

Elevating to framework manager

catch’s picture

Status: Needs review » Needs work
Issue tags: -Needs framework manager review +Needs subsystem maintainer review

There is outstanding feedback on the MR, it needs work, not a framework manager review.

Nikolay Shapovalov made their first commit to this issue’s fork.

Nikolay Shapovalov’s picture

I 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:

Think we should still be able to cover when nothing is based in 2nd.

Can someone please explain?

Is it possible to hide patch files, and branches that not in use?

Nikolay Shapovalov’s picture

Status: Needs work » Needs review

I think this is ready for review.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
FileSize
90 bytes

The 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.

Nikolay Shapovalov’s picture

Status: Needs work » Needs review

MR 4160 is mergeable, update status back to needs review.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
FileSize
90 bytes

The 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.

Nikolay Shapovalov’s picture

Status: Needs work » Needs review
Issue tags: +no-needs-review-bot
gaurav_manerkar’s picture

Status: Needs review » Reviewed & tested by the community

I have tested MR https://git.drupalcode.org/project/drupal/-/merge_requests/4160
Looks good, can be moved to RTBC.

alexpott changed the visibility of the branch 2582295-confirmation-cancel-links-10.1.x to hidden.

alexpott changed the visibility of the branch 2582295-confirmation-cancel-links-10.0.x to hidden.

alexpott changed the visibility of the branch 2582295-confirmation-cancel-links-11.x to hidden.

alexpott changed the visibility of the branch 2582295-confirmation-cancel-links to hidden.

alexpott changed the visibility of the branch 2582295-confirmation-cancel-links-11.x to active.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Hiding the irrelevant MRs and patches... someone needs to fix the 11.x MR as it has merge conflicts.

gaurav_manerkar’s picture

Status: Needs work » Needs review

Rebased MRs.

smustgrave changed the visibility of the branch 2582295-confirmation-cancel-links-10.2.x to hidden.

smustgrave’s picture

Status: Needs review » Needs work

was 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.

Fix the confirm URL in the node/translation delete confirm form.

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.