Problem/Motivation

\Drupal::token()->generate() throws an exception when generating URLs that differ from the current path and require object parameters. For example, when used with ctools (latest stable version):

Error: Call to a member function bundle() on string in Drupal\ctools\Plugin\Condition\EntityBundle->evaluate() (line 107 of modules/contrib/ctools/src/Plugin/Condition/EntityBundle.php).

Why this happens: Url::createFromRequest() does not convert scalar route parameters to objects.

Proposed resolution

use Url::fromRoute(')'.

Remaining tasks

- Write the patch
- Write tests.

User interface changes

No UI change

API changes

No API change

Comments

valthebald created an issue. See original summary.

valthebald’s picture

Status: Active » Needs work
Issue tags: +Needs tests
StatusFileSize
new587 bytes
nicrodgers’s picture

StatusFileSize
new1.04 KB
new602 bytes

We ran in to a related issue with createFromRequest. The problem with createFromRequest is it doesn't take in to account user access, so in our case it's returning a pathalias that the current user doesn't have access to. This patch also replaces the remaining createFromRequest usage with Url::fromRoute('').

Still needs tests, and need to investigate the failing tests. Also need to check the try/catch logic around these changes and update the comments accordingly.

ngkoutsaik’s picture

Assigned: Unassigned » ngkoutsaik
ngkoutsaik’s picture

Assigned: ngkoutsaik » Unassigned

Hi,

I reviewed the issue and the supplied patch by @nicrodgers.

I troubleshoot the failing tests. First the functional tests.
Url:createFromRequest does not throw an exception when the route does not exist. Instead, It returns a system/404 URL. That is why I extended the patch and added

    if (strpos($url->toString(), '404') !== FALSE) {
          $url = Url::fromUserInput($request->getPathInfo(), $url_options);
        }

Then the functional tests run.

Next on the kernel tests, speciffically the URLtests. I updated the first line from expectedCurrentRequestUrlResults on UrlTest to Url::fromUserInput(Request::createFromGlobals()->getPathInfo())->setAbsolute()->toString()]. That way the outputs match. I am not certain if this the optimal way to go about it.

The test with the 'does-not-exist' URL works without any issues.

The last 2 are the tests with the malformed URL test. And this is where I got stuck. Because of Url::fromRoute('<current>') the URL is never null and so a token is created. Additionally, I don't know why but fromRoute does not return system/404 during the kernel tests. It just returns HTTP://localhost

If I set the $url variable to null by hand the 2 last tests pass.
I am attaching my patch in hope that someone else might have an idea on how to proceed.

ngkoutsaik’s picture

StatusFileSize
new2.25 KB
new2.63 KB
nicrodgers’s picture

Status: Needs work » Closed (outdated)

I went to re-roll the patch for 1.17 but don't think it's needed anymore, due to the refactoring of the code in the OOP conversion. I've done some manual testing and can't reproduce the issues we were experiencing in < 1.17 so am going to close this down. Feel free to reopen if I'm wrong!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.