Problem/Motivation

The initial problem is that the File Listing page "Delete" link fails with "Oops, something went wrong. Check your browser's developer console for more details." when language negotiation uses domains.

I selected the "language system" component, but this problem spans subsystems.

Steps to reproduce

  1. Setup two domains (.ddev/config.yaml additional_hostnames, I used "local" and "es.local").
  2. Install Drupal, enable media and language modules.
  3. Add a language for the second domain on admin/config/regional/language (I used Spanish). Configure detection on admin/config/regional/language/detection, edit "URL", select "Domain", and set the two domain URL's (I used local.ddev.site and es.local.ddev.site)
  4. Add a media document from admin/content/media
  5. Try to delete the file just added on admin/content/files. You will see the error "Oops, something went wrong. Check your browser's developer console for more details."

Proposed resolution

Fix RedirectDestination::get() method to return only relative paths for destination.
Remove todo for https://www.drupal.org/project/drupal/issues/2980527

Remaining tasks

Why is this solution preferred over #2980527: Domain-based language negotiation strips "destination" URL query argument, causing BigPipe error?

User interface changes

API changes

Data model changes

Release notes snippet

Original proposed resolution

This is a rabbit hole. Working backwards:

ConfirmFormHelper::buildCancelLink() needs a URL. It tries to get it from either the destination parameter or from the entity URL. I think we need to fix both code paths.

Problem #1 - destination

We can't get it from the destination parameter because language negotiation converts the relative URL to a full URL which is then sanitized by RequestSanitizer.

a. Use #2980527: Domain-based language negotiation strips "destination" URL query argument, causing BigPipe error - however once this is applied, we run into Problem #3.
b. See #3424720: LanguageNegotiationUrl unnecessarily adds domain to outbound URL's - Change LanguageNegotiationUrl::outboundUrl() to not set the base_path if it matches the current page's base_path.

Problem #2 - File Entity

If the destination parameter is missing, the URL is retrieved from toUrl() which throws the exception that started this problem. Previous attempts have been made (see [#3371753} and #3421114: [regression] Entity::toUrl() without argument is broken for entity types with a URI callback) to make this not fail, but this still doesn't work for File entities. I can fix my local sites problem with https://drupal.org/project/file_entity which adds the necessary link templates but a contrib solution to a core problem is only an interim fix. We should look there for the minimal required templates to add to core.

Problem #3 - buildCancelLink() external URLs

This code has a rather old comment to "revisit" #2418219: Deprecate destination URLs that don't include the base path. I think that Drupal has moved past this issue, and won't ever revisit it, so IMO we should comment on the issue, and remove the comment.

The try/catch was added in #2512452: Confirm form cancel button can lead to external domain to prevent external URL's, but does not use, and should use, UrlHelper::externalIsLocal() which could now be used.

Issue fork drupal-3424701

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:

Comments

douggreen created an issue. See original summary.

douggreen’s picture

Title: LanguageNegotiationUrl processOutbound unnecessarily sets base_url » Cannot delete file when using language negotiation domains
douggreen’s picture

Issue summary: View changes
douggreen’s picture

Issue summary: View changes

sukr_s made their first commit to this issue’s fork.

sukr_s’s picture

StatusFileSize
new696 bytes

Support for delete-form is required. I've tested this and it works fine.

jenlampton’s picture

Status: Active » Reviewed & tested by the community

Changing to RTBC after the last comment.

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests, +Needs issue summary update

It's not clear to me whether this will fix the original bug report, would be good to add some test coverage if the lack of this is causing user-facing fatal errors. Could also use an issue summary update.

prabuela’s picture

Assigned: Unassigned » prabuela
sukr_s’s picture

Issue summary: View changes
StatusFileSize
new303.49 KB
sukr_s’s picture

Issue summary: View changes
sukr_s’s picture

Assigned: prabuela » Unassigned
Status: Needs work » Needs review
StatusFileSize
new150.3 KB

- Issue summary updated. error screenshot added.
- New test case added
- Screenshot post fix added

The MR has failed at test case testUnmanagedGitIgnoreWhenGitNotAvailable which seems unrelated to the code fix. what should be done?

smustgrave’s picture

Version: 10.2.x-dev » 11.x-dev
Status: Needs review » Needs work

Appears to have test failures

sukr_s’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests, -Needs issue summary update +Needs Review Queue Initiative

Issue summary appears to be updated with solution in #13 so removing that tag

Ran test only feature and got

1) Drupal\Tests\file\Functional\FileListingTest::testFileDeleteWithMultipleDomain
Behat\Mink\Exception\ResponseTextException: The text "Are you sure you want to delete the file image-test.png?" was not found anywhere in the text of the current page.
/builds/issue/drupal-3424701/vendor/behat/mink/src/WebAssert.php:907
/builds/issue/drupal-3424701/vendor/behat/mink/src/WebAssert.php:293
/builds/issue/drupal-3424701/core/tests/Drupal/Tests/WebAssert.php:956
/builds/issue/drupal-3424701/core/modules/file/tests/src/Functional/FileListingTest.php:331
/builds/issue/drupal-3424701/vendor/phpunit/phpunit/src/Framework/TestResult.php:728
ERRORS!
Tests: 3, Assertions: 187, Errors: 1.

So removing that tag

Seems additional condition for deletion seems to be there.

catch’s picture

Status: Reviewed & tested by the community » Needs work

This seems like it would come from lib/Drupal/Core/Entity/EntityListBuilder.php but that passes in 'delete-form' to ::toUrl() so it can't be that.

I think we need a backtrace here with what is calling ::toUrl() with NULL, and fix it there, or at least understand what's going wrong a bit more. Seems weird to default to deleting just because there's no canonical or edit link. Also the exception message would need to be updated which is not done in the MR.

catch’s picture

Is it this in the actual delete form?

 /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    $entity = $this->getEntity();
    if ($entity->hasLinkTemplate('collection')) {
      // If available, return the collection URL.
      return $entity->toUrl('collection');
    }
    else {
      // Otherwise fall back to the default link template.
      return $entity->toUrl();
    }
  }

If so, I think the problem is file module missing a 'collection' link for the cancel link to point to, it shouldn't point to the delete page, that's what we're on.

sukr_s’s picture

Issue summary: View changes
sukr_s’s picture

Status: Needs work » Needs review

- IS updated
- fix as per #20 done

catch’s picture

Status: Needs review » Needs work

Sorry I don't think that fix is right either because views is an optional module and therefore the route may or may not exist.

Couple of questions:

1. What happens if we remove the exception from EntityBase::toUrl() and fall back to <front> for the route there - I don't think that's the correct fix but I would like to see what happens.

2. It would be useful to manually test this in 10.1 or 10.0.x from before the regression was introduced, and see what the cancel button actually did on this form, I have a feeling the button was broken but it rendered and no-one ever noticed.

sukr_s’s picture

Status: Needs work » Needs review

If the views module does not exist, then this screen is not accessible and therefore it's not possible to reach the error.

I tried to add the collection route conditionally but the REST tests fail.

1. If the exception is commented out, it tries to create URL with entity.file.collection and ends up throwing an exception. If that is commented out too and URL to is created, then the dialog pops up. Click on cancel, it remains on the same page.
2. The problem occurs only when the language module is enabled and multiple languages are configured. If it's a single language site then the functionality works fine. The cancel stays on the same page, which would be the expected behavior. If multiple languages are configured then the delete confirmation popup doesn't open, it ends up with exception.

If the original fix of adding 'delete-form' is enabled then the delete confirmation pops-up and clicking on cancel, it remains on the same page.

smustgrave’s picture

Status: Needs review » Needs work

Proposed solution shouldn't point to a comment, for ease of review please update issue summary with actual proposed solution.

Find saying "Go to this link" the same as when people put "see patch"

sukr_s’s picture

Status: Needs work » Needs review

@smustgrave the correct solution needs to be confirmed by @catch. once done can update the same

putting it back to NR for @catch attention.

catch’s picture

Status: Needs review » Needs work
Issue tags: +Needs manual testing

If the views module does not exist, then this screen is not accessible and therefore it's not possible to reach the error.

I think it would still be possible to browse directly to the URL, and definitely possible to set up an alternative view at a different path to do the same thing (or just change the path on the default view).

I think someone should do this:

It would be useful to manually test this in 10.1 or 10.0.x from before the regression was introduced, and see what the cancel button actually did on this form, I have a feeling the button was broken but it rendered and no-one ever noticed.

Once we know what the original behaviour was and whether it was broken already in a different way, it will help inform what the solution here should be.

Also, does this really require language negotiation to reproduce?

sukr_s’s picture

Results of manual testing

10.0.8 - View does not provide the option to delete.

10.1.0
- Without language module enabled, Delete confirmation is shown and clicking Cancel, closes the dialog
- With language module enabled, Error as per screenshot error-on-delete.png

sukr_s’s picture

After further analysis, I've found that the URL generated for delete without language module or language with url detection is

https://d10n.ddev.site/file/1/delete?destination=/admin/content/files&_wrapper_format=drupal_modal

and with language module with domain detection is

https://d10n.ddev.site/file/1/delete?destination=https%3A//d10n.ddev.site/admin/content/files&_wrapper_format=drupal_modal

the issue is that in the second case the destination is a fully qualified url and in the first case it's relative path. Since we have fully qualified URL, the RequestSanitizer removes the destination URL and thus it ends up in getCancelUrl and subsequently throws the error.

sukr_s’s picture

sukr_s’s picture

Issue tags: -Needs manual testing

removing "needs manual testing" tag. done in #28

smustgrave’s picture

Status: Needs review » Needs work

Comment in MR.

sukr_s’s picture

Status: Needs work » Needs review

without correcting the assertion, the test will fail. do confirm if you want this to be removed. will the merge happen with test failing?

smustgrave’s picture

Status: Needs review » Needs work

So going to pivot since the todo and test update is needed here. Lets expand test coverage to make sure it includes scenarios in #2980527: Domain-based language negotiation strips "destination" URL query argument, causing BigPipe error. Which I'll close and move over credit for.

sukr_s’s picture

Status: Needs work » Needs review

The test case testBlockPlacementIndicator in BlockUITest.php has the issue described in #2980527: Domain-based language negotiation strips "destination" URL query argument, causing BigPipe error. This has been fixed. I don't think we need additional test case for this.

nicodh’s picture

Works for me (I had the issue described in #2980527).

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Fine if we don't expand test coverage. Will let committers decide if needed though.

quietone’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs framework manager review

Thanks for the working on improving multi-lingual sites!

An issue summary update removed a large block of testing and explanation that I found useful to help understand this issue. Maybe that should be restored?

I read the comments and MR at #2980527: Domain-based language negotiation strips "destination" URL query argument, causing BigPipe error the fix there is very different from this. That MR was created by a core committer and another core committer worked on this issue. I think we need to get confirmation of which solution is preferred. Apologies if I missed it. For now, I will tag for framework manager review. The other issue also has test and it would help to know if that should be kept or not.

There are also comments in the MR to resolve.

sukr_s’s picture

Issue summary: View changes

An issue summary update removed a large block of testing and explanation that I found useful to help understand this issue. Maybe that should be restored?

restored original proposed solution

sukr_s’s picture

Status: Needs work » Needs review
sleitner’s picture

Status: Needs review » Reviewed & tested by the community

solves the problem. All threads were resolved. The large block of testing was restored.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Looks like this needs work based on @quietone's review.

sukr_s’s picture

Status: Needs work » Needs review
slawrence10’s picture

This same problem exists in Drupal 10 but wasn't sure how to document it?

Error thrown when trying to delete file entities at /admin/content/files

Turn off URL detection that uses domain at /admin/config/regional/language/detection, clear cache and file entities can be deleted error free.

smustgrave’s picture

Issue summary: View changes
Status: Needs review » Needs work

Updated proposed solution to mention that the todo around https://www.drupal.org/project/drupal/issues/2980527 is also being removed.

Resolved the rest of the threads and believe all feedback has been addressed.

Only request I would make is if the MR can be rebased since it's 800+ commits back.

sleitner’s picture

Status: Needs work » Needs review

Rebased

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks believe all feedback has been addressed

berdir’s picture

Feels like the issue that was closed as a duplicate better (more generically) describes what this is about, while this issue title is just about one specific aspect of that? Maybe we should update it?

quietone’s picture

Title: Cannot delete file when using language negotiation domains » Domain-based language negotiation should retain "destination" URL query argument

From #53, Trying for a better title.

catch’s picture

Status: Reviewed & tested by the community » Needs work

One comment on the MR - I think the new logic needs an explanation as to why it's there.

xlyz’s picture

From what I understand the current implementation add the domain to the destination uri so that the user after the POST get redirected to the domain is currently using.

For instance if I have a site in english and italian, each with its own domain, and I'm using the english one, if I try to delete the italian translation of a node the delete link is built with the italian domain, and then destination=english_domain/current_path is added to bring back the user to the current page with the current language. Otherwise he'll switch to the language of the page he has deleted.

Current implementaion seems to create problem:
1. delete file does not works
2. if i try to delete a translation of a node I currently get this error:

Redirects to external URLs are not allowed by default, use \Drupal\Core\Routing\TrustedRedirectResponse for it.

(on Drupal 10.5)

The proposed patch is not perfect (to user will switch to the language of the translation that need to edit / delete) but it's still better that the current implementation.

P.S. is a backport to 10.x planned?

charlliequadros’s picture

A version compatible with Drupal 11.3.2 has been created.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

shivansunfire’s picture

Didn't https://www.drupal.org/project/drupal/issues/3424720 already closed and comitted to 11.1.x fix this problem?