Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Everytime I add/remove an item from a bookmark list, while using the Pathauto module, the module redirects me to the internal URI (node/[nid]) instead of the Pathauto URL. I created a RedirectResponse with a toString() method attached to the $url_info object given.
I also noticed no "flashdata" (or w/e drupal calls them) are displayed so I added 2 flashdata and attached them to the un/flag methods.
Comment | File | Size | Author |
---|---|---|---|
#34 | interdiff-2372065-30-34.txt | 802 bytes | beram |
#34 | redirect_alias_missing-2732065-34.patch | 2.51 KB | beram |
#32 | interdiff-2732065-28-30.txt | 560 bytes | beram |
#32 | redirect_alias_missing-2732065-30.patch | 2.23 KB | beram |
#28 | redirect_alias_missing-2732065-28.patch | 1.64 KB | beram |
Comments
Comment #2
socketwench CreditAttribution: socketwench at FFW commentedWhy these two additions? They don't look related to the issue...
Comment #3
BerdirI don't understand the issue here. This should work fine, it also doesn't matter if you use pathauto or not. Pathauto generates aliases, it has 0 impact on url generation at runtime.
Sending redirects and existing is wrong and against the API.
Comment #4
socketwench CreditAttribution: socketwench at FFW commentedCan you also list your steps to reproduce?
Comment #5
TheDucksLover CreditAttribution: TheDucksLover commentedas I said, I can't get the module to work. Everytime I tried to add an element to my bookmarks, it doesn't add it, and it reloads the page without any confirmation message :/. And when I say "it reloads", I mean it reloads to the "/node/{nid}" url, this is why I was talking about the alias.
I simply installed the moduled and configured it to accept the content type I needed it to use.
As for the drupal_set_message, this is the "flashdata" part :p
Comment #6
TheDucksLover CreditAttribution: TheDucksLover commentedOkay guys, apparently I've been fooled by drupal's cache.. It looks like it's working from the beginning, except the fact that the button I was creating was kept in the cache.
Here's the code I used (in a preprocess function) to display the link to flag/unflag an element:
Where
$node->getEntityTypeId()
means "node",$node->id()
is the nid of the current node and'bookmarks'
is the flag machine name..I managed to get it working tho with this line (disabling the cache for this button...) :
$flag_link['#cache']['max-age'] = 0;
But I still got 2 issues here :
1) There are no confirmation messages displaying so I had to keep the lines
drupal_set_message($flag->getFlagMessage(), 'status');
anddrupal_set_message($flag->getUnflagMessage(), 'status');
from the patch I posted.2) The redirection is still not using the path that the module pathauto generates, it's still working but it'd be cool to figure a way to redirect using a path if it exists..
Comment #7
socketwench CreditAttribution: socketwench at FFW commentedI'm curious why you need to build the flag link yourself in the first place.
Comment #8
TheDucksLover CreditAttribution: TheDucksLover commentedSo I can place it whereever I want in the template. I haven't figured a way to place it with a simple token or w/e so I had to go that way, but how would u place it? I know there is a section dedicated to this in the flag configuration but it's not rly flexible.
Comment #9
joachim CreditAttribution: joachim commentedHave you used the pseudofield setting? What configurability do you need that that doesn't give you?
Comment #10
Blanca.Esqueda CreditAttribution: Blanca.Esqueda as a volunteer and at Portage CyberTech commentedI also have an issue with the flag not respecting the URL alias (PathAuto).
When the flag is completed/uncompleted then it redirects to the internal path instead of the alias..
Destination argument is not using the url alias created with pathauto, this causes some unwanted behaviour as sample breadcrumbs (base on url) - beside the end users noticing that the url changed.
Using the Ajax option would resolve the issue (because it won't be redirection), but unfortunately for some restrictions we can not use it.
How to replicate it:
Create a content type, include a flag, create content with an alias, when you try to click the flag link you can see something like this:
/flag/flag/task_completion/136?destination=/node/142&token=UglbmpbkSbO8cspQ4f_4jJAoX2htrizCNULAVlygqqk
instead of
/flag/flag/task_completion/136?destination=/dashboard&token=UglbmpbkSbO8cspQ4f_4jJAoX2htrizCNULAVlygqqk
Same behaviour if you add try to use the flag link in views.
Attached a patch to use alias instead of internal path, if an alias exist it would use it, if not it would maintain the regular path.
Comment #11
Blanca.Esqueda CreditAttribution: Blanca.Esqueda as a volunteer and at Portage CyberTech commentedComment #14
BerdirAs you can see on the test fails, getPath and getInternalPath() work differently. getPath() returns the path prefix if drupal runs in a subfolder.
If anything, you need to use '/' . getInternalPath() for the alias.
But this is a bit strange, I'd expect the destination handling will then forward to the alias, if not then that seems like an issue with that, not with this module and will affect many other things too?
As a workaround, you could use the canonical redirect settings from the redirect module
Comment #15
Blanca.Esqueda CreditAttribution: Blanca.Esqueda as a volunteer and at Portage CyberTech commentedI did a simpletest.me only core and the flag module.
To make sure that there was not other module causing the issue. Not even enabled PathAuto, used the default path option to update the alias.
And following the same steps added in #10, the issue of the destination argument not using alias is replicable.
Comment #16
joachim CreditAttribution: joachim commentedOk so clearly when we're getting the current URL to put into the link's query destination string, we're getting the system path, not the actual current path.
Here's our code:
getInternalPath() is clearly wrong.
It occurs to me that getAlias() -- if such a thing exists -- might not be right either, as there might be more than one alias for the current path.
So, what is the RIGHT way to get a destination query string for the current path? Surely that's something core provides?
Comment #17
Blanca.Esqueda CreditAttribution: Blanca.Esqueda as a volunteer and at Portage CyberTech commentedHi @joachim,
And there is something that I believe it is a major issue... the language prefix is never set either.
So if you are in a FR section the flag destination path never gets the language prefix. Causing a redirection to the default language page.
/fr/flag/flag/task_completion/136?destination=/node/142&token=Uglbmpbk
instead of:
/fr/flag/flag/task_completion/136?destination=fr/node/142&token=Uglbmpbk
or even better:
/fr/flag/flag/task_completion/136?destination=fr/path_alias&token=Uglbmpbk
We needed a way to have the path with the correct language and alias, so for now we changed the line:
for this:
I know there is not an elegant way to get the language prefix, but at least is working and the alias is language base too.
Comment #18
joachim CreditAttribution: joachim commentedThat's really overthinking it! It's not flag's job to know how paths are put together, and indeed, about the different ways in which language URLs can be constructed.
All we care about is that the user is currently on www.domain.com/foo/bar and that they should go back there once they've performed the flagging action.
It looks like \Drupal::request()->getRequestUri(); will get us what we want in getDestination() -- obviously instead of ::request() we need to inject the service.
Comment #19
BerdirIf anything, then the problem isn't in the code that generates the destination string but where we actually do the redirect. That is supposed to run it through the usual outbound processing which should take care of all that. I'll try to have a look at what's exactly happening.
Comment #20
joachim CreditAttribution: joachim commented> I also noticed no "flashdata" (or w/e drupal calls them) are displayed so I added 2 flashdata and attached them to the un/flag methods.
Split this off to #2834455: [Regression] Flag/unflag messages don't show for reload and confirm link types.
Comment #21
dawehnerThat's an interesting point. I'm expecting
\Drupal\Core\Routing\RedirectDestination::get
to totally return a path alias, given that it calls out to::generateFromRoute()
.Comment #22
Blanca.Esqueda CreditAttribution: Blanca.Esqueda as a volunteer and at Portage CyberTech commented@joachim
You are completely right, I was overthinking,
return \Drupal::request()->getRequestUri();
Instead of
return $current_url->getInternalPath();
Using the uri resolves my issues, it works even when I'm using the flag in the front page (destination '/').
Could you explain the service injection?
Thank you so much!
Blanca
Comment #23
joachim CreditAttribution: joachim commented> obviously instead of ::request() we need to inject the service.
The \Drupal:: static is for procedural code. In classes such as this one, the service should be injected instead: the class constructor and factory method should together set the service on the object. Then instead of \Drupal:foo(), we have $this->someService->foo().
Have a look at what the \Drupal::request() method does, that will probably be a wrapper around a call to a service.
> That is supposed to run it through the usual outbound processing which should take care of all that.
There's a potential problem there if the current path has more than 1 alias. Suppose we're on /alias-b. The processing could give us /alias-a for /system-path instead.
Comment #24
martin107 CreditAttribution: martin107 as a volunteer commented@Blanca.Esqueda
\Drupal::request()->getRequestUri()
is a function call to this
From the container it gets services, in this case 'request_stack'
using \Drupal::Xyz() is an anti pattern. Injecting the service directly is done by adding the service to the construct function
looking at the ActionLinkTypeBase definition below the create() method pulls in the 'current_user' service and adds it to a list of other things that will when the object is created become the parameters passed into the __construct() method.
if you add request_stack service to the end of the list in the create() method and then add an extra parameter to the constructor then I hope you will see the pattern
If you have any questions just let me know...
Comment #25
matthew.perry CreditAttribution: matthew.perry commented@Blanca.Esqueda, @joachim
I've been having a similar problem with the flag respecting path aliases on destination redirect and found this approach to work.
By Replacing the original call to getInternalPath
with a call to toString the current url
This will allow the destination to always respect the current url path that is being accessed prior to triggering the flag whether or not it is an alias path.
Comment #26
joachim CreditAttribution: joachim commentedThanks for the patch!
(Though remember to set an issue to 'needs review' so people know to look at your patch.)
This fixes the problem, but it's not as good a fix as using getRequestUri(), as that will also preserve any query string in the current URL.
(The use case for that is a view that has exposed filters and is showing flag links. You might apply some filters, then flag something. You'd expect to return to the filtered view you were on.)
Comment #27
joachim CreditAttribution: joachim commentedNot sure how I failed to spot this hadn't been classed as a bug...
Comment #28
beram CreditAttribution: beram as a volunteer and at Smile commentedHi,
I don't understand why not using the 'redirect.destination' service instead?
It already does what you need no? Implementing the request stack, preserving the query string, take care of alias and langcode etc.. etc..
Or am I missing a point?
Just in case I added a patch that implements the 'redirect.destination' service. Since it is a different approach I did not provide an interdiff.
(If necessary I'll take a look at the tests (I expect it to fail))
Comment #30
socketwench CreditAttribution: socketwench commentedDoes that handle the destination query parameter as well?
Also it seems like it changes the redirect, breaking the test:
Comment #31
beram CreditAttribution: beram as a volunteer and at Smile commentedSorry I'm not sure to understand the question but I'll try to answer.
It is a service that provide helpers for redirect destinations. If you take a look at the
get
method you can see that it handle the destination query parameter :I'll take a look a the tests as soon as I could.
Comment #32
beram CreditAttribution: beram as a volunteer and at Smile commentedI upload a patch to try passing the test:
I don't have the same behavior on my test environment because there is no
checkout
on the URL.It seems that the other fails are not related to this patch since they exist without it on my environment but I will take a look to be sure.
Comment #33
beram CreditAttribution: beram as a volunteer and at Smile commentedSorry I forgot to change the status..
Comment #34
beram CreditAttribution: beram as a volunteer and at Smile commentedThis patch take into account the /checkout/ on drupalci for the
LinkTypeFieldEntrydoEditFlagFieldield()
test. To have the correct destination to assert it needs to construct it usingUrl::fromRoute('entity.node.canonical', ['node' => $this->nodeId]);
The other fails are not related to this patch since they exist without it.
Comment #35
martin107 CreditAttribution: martin107 as a volunteer commentedYep those issue are known failures and set to be fixed in the issue above.
Comment #36
beram CreditAttribution: beram as a volunteer and at Smile commentedThanks! I was looking for this issue!
Comment #37
martin107 CreditAttribution: martin107 as a volunteer commentedSorry I included the wrong issue as our branch blocker. Let us call it a dozy sunday morning thing :)
Comment #39
socketwench CreditAttribution: socketwench commentedFixed! Thanks all!