We have set up a node type for flagging by anonymous users.
We have a view that lists all nodes flagged by a particular user.
This view gets displayed in a block where we allow the user to unflag all flagged nodes.
Users are able to "remember" pieces of content.
Flagging works. But sometimes (on some pages) the unflag link is not displayed for a particular nodeID (user 0, page caching turned on). On other pages the link shows.
Maybe a hint: Is there a place to start debugging this?
Comments
Comment #1
manuelBS commentedI dont' exactely now but drupal doesnt have sessions for anonymous user so flagging wont really work. Does flagging work if you have the caching disabled?
Comment #2
quicksketchFlag does work with both anonymous users and page caching enabled. It gives anonymous users a cookie to store which content they have flagged, then uses JavaScript after the page has loaded to swap out all the "Flag" links with "Unflag" links for content they have already flagged.
We'll need more specific instructions on how to reproduce this problem. There's likely a pattern here that can be reproduced at will, right now saying "some pages work but others don't" isn't very helpful.
Comment #3
derjochenmeyer commentedWe use flagging as a "remember these products" feature. We display the flagged products in a block. We update the block via AJAX using the Component module. We eliminated the Component module as a possible reason, because the links are not present even after a full page reload.
The pattern:
1. On a product page (node/ID) we hit the AJAX "remember me" flag link.
2. The product is flagged, the block gets updated, the unflag link is present.
3. The unflag link is present on all non-product nodes AND on its own node view (node/ID)
4. The unflag link does not show on all other product nodes.
The block that we use is a node-view that uses the flag-link field in a table.
The pattern dissolves:
1. On a product page of a flagged product we hit the AJAX "UNremember me" flag link.
2. All unflag links are displayed on all product pages
3. We hit the AJAX "remember me" flag link on a different product.
4. the unflaglinks for all products with a certain taxonomy term are lost.
>> The unflag link on the product page (not the one displayed in the block) is always working.
>> There are no watchdog errors related to this problem.
>> If the link is displayed it looks like this
http://www.domain.com/flag/unflag/rememberme/12360?destination=node%2F12360&token=4612d4fd1758780876489e4730b49757c&has_js=1>> If the link is NOT displayed the table cell is empty
It seems to be related to some kind of taxonomy/access issue (we dont use any taxonomy access control modules)
Comment #4
derjochenmeyer commentedMaybe this is related: #986840: Removing flag for anonymous users returns error: javascript and cookies disabled
Comment #5
mooffie commentedIt's probably not related.
Comment #6
mooffie commentedYes.
First, here's a description of how Flag implements anonymous flagging:
(Nate basically explained this in comment #2.)
Now,
You say:
This means that the problem is in step #4. Because if we omit this step the page will be full of "Flag this!" links. (Verify this: disable JavaScript and refresh the page.)
And it probably means that Drupal.settings.flag.templates doesn't contain a rendition for all the links. In other words, some "Flag this!" links are replaced by a null string.
Perhaps your setup doesn't merge the new link renditions into Drupal.settings? This seems the likely reason. On the other hand, you say "[w]e eliminated the Component module as a possible reason, because the links are not present even after a full page reload."
Whatever, to get you started hacking, locate this line...
...and add the following code before it:
Comment #7
derjochenmeyer commentedAs an anonymous user:
1. I hit the "flag this" link on a product
-- it is flagged, the block gets updated + everything looks good after a page refresh
-- the on page Link now reads "unflag this"
-- the unflag link is present in my block
2. I disable javascript, and refresh
-- the on page Link still reads "unflag this"
-- the unflag link is present in my block
-- the link returns an error because it misses the has_js=1 querystring
3. I navigate to a different product
-- the unflag link in my block is gone (table cell is empty)
4. I disable javascript, and refresh on the same different page
-- the unflag link is there, the table cell contains
5. I enable javascript, and refresh on the same different page
-- the unflag link is gone (table cell is empty)
Comment #8
mooffie commented(This seems to contradict what I said earlier, that the page the server sends contains only "Flag this!" links, but it might be that we have a bug in that mechanism as well. However, it's unrelated to the "disappearing links" we're discussing in this issue, so for the time being it's best to ignore it.)
=======
Do "View Source". Do you see a "rememberme_XYZ" entry in the Drupal.settings.flag.templates array? (replace "XYZ" with the content ID of the item whose link is gone).
(That's a different issue altogether. (You may ask how come we have so many bugs in our module. It's a good question. I guess it could be explained by the Bicycle Shed example: since the anonymous flagging feature was relatively big it might have got a light inspection only.))
Comment #9
derjochenmeyer commentedHey mooffie, I don't ask how come we have so many bugs in this module. I'm happy to help with testing and debugging. Its a very cool module!
Drupal.settings.flag looks like this
But I am on node/812 !!! I only flagged node/360 and the unflag link for node/360 is gone in the block. I didn't flag node/812.
Comment #10
mooffie commented(I think I know what the problem is.)
This part is actually fine: When Flag is asked to print the flag link (whatever the status of the item: flagged or not), it prints the "Flag this!" version of it and it also adds the "Unflag this!" version of the link to the JS array.
That's the only problem: the JS array doesn't contain the renditions for the links you have in your block.
And I suspect I know what's the problem: are your blocks cached? Go to your "admin / performance" settings page (I don't know the exact menu path) and turn off caching for the blocks. (Drupal has several levels of caching.)
Because if the blocks are cached, there are times when Flag isn't actually run when they're called for and it doesn't have a chance to add the renditions to the JS array. (We'll think of a workaround later; first let's verify that's indeed the problem.)
Comment #11
derjochenmeyer commentedThey are not cached, and they were not while debugging this.
We have
- Page cache: "Normal (recommended for production sites, no side effects)" active
- no "Minimum cache lifetime"
- "Page compression" active
- "Block cache" disabled
- "Optimize CSS files" active (with CSS Gzip)
- "Optimize and Minify JavaScript files" active (with Javascript Aggregator)
I disabled CSS and JS optimisation. Thats not the problem.
Comment #12
derjochenmeyer commentedThe strange thing is: It works on ALL pages and nodes with no flagging (all unflag links are there). The problem is only present on product-nodes.
Comment #13
mooffie commented(I'll try to check that next week.)
(BTW, turning on a block that runs a view involving some anon flag [is supposed to] turn[s] off the caching for that page. So eventually you'll instead want to fetch the block/view in an onload JavaScript event.)
Comment #14
derjochenmeyer commentedThanks for the Tipp. That means if we show the views-block on all pages, we thereby disable page caching for all pages :)
Comment #15
mooffie commentedOK, I found the problem. I opened a new issue:
#996700: Anon flagging: Views may make some flag links "disappear"
(There's another bug that awaits a fix, #996710: Anon flagging: Output of "flag this!" links only isn't enforced)
HOWEVER, as I mention in #13, you shouldn't turn on the block of this view because it will turn off caching for the page (it's a feature, not a bug; because otherwise anon users will see the (stale) state of some other anon user). You don't want this to happen: you want page caching. So instead you'll have to display the block using JS: pull it from the server in the page's onload event.
(Tip: add "
<? print 'Time: ' . date('H:i:s', time()); ?>" to your page.tpl.php to know whether the page is cached or not: if the time is current you know the page isn't cached (because, e.g., a view turned caching off (as it should!)).)Comment #16
derjochenmeyer commentedThanks mooffie! The patch in #996700: Anon flagging: Views may make some flag links "disappear" fixes this issue.
Also thanks a lot for the js pull tip! We now use the component module to load the block...
Comment #17
derjochenmeyer commentedFollowup: Hi mooffie, I dont know if this is a flag issue. After pulling in the block with AJAX the destination of the generated unflag link is obviously wrong. Lets say the block is displayed on /node/123 the AJAX-callback points to some other URL (in our case /component/block/views/rememberme-block_1).
Comment #18
mooffie commentedJochen, this isn't quite a bug.
Flag (and many other modules) tell themselves where they need to redirect after they complete some operation (this is usually used only when JS isn't used: either when it's disabled or when using the right mouse button). They default to the path of the "current page". Which is actually the path of the HTTP request being currently served. In your case, since the request is "component/block/...", it's the destination.
You need to override this destination:
(I may have typos here.)
(I'd move the drupal_add_js() snippet into a JS file (You probably have one anyway if you're using our JS API to refresh things upon flagging).)
Comment #19
derjochenmeyer commentedThanks mooffie, for your help! It works!
Comment #20
mooffie commented(You're welcome. Note that I updated my reply to use Drupal.settings (mainly to make it possible to move the JS into its own file). You may have missed it if you read it before I updated it.)
Comment #21
derjochenmeyer commentedFollowup: This might be relevant for other users.
Patch #986840: Removing flag for anonymous users returns error: javascript and cookies disabled does not seem to work with above AJAX pulling on pages that have no flag links. For example our frontpage has no flag links, but it also pulls in the rememberme block via AJAX.
Comment #22
mooffie commentedMmm. That's right. To fix this, add "
Drupal.settings.flag.anonymous = true;" to your JS (before the call to Drupal.attachBehaviors). This will tell Flag's JS (the anti-crawlers mechanism) that it needs to kick in.(Ideally, the 'Component' module should merge whatever JS settings were generated during the page request into the page's Drupal.settings.)
Comment #23
mooffie commentedOn second thought, this will result in JS error because the '.flag' slot doesn't exist.
So, instead, add this to your PHP:
Comment #24
derjochenmeyer commentedWow, thanks. I could create a doc page summing up all of this.
Comment #25
mooffie commentedIndeed. I started a doc page:
Technical notes about "anonymous" flaggings
Feel free to edit it.
(Note: I added a note about efficiency. Search that page for "@todo".)
I've fixed two more bugs related to anon flagging. It will probably take a couple of hours before it's reflected in the 'dev' release. Please use it (in a few hours) and let me know if you encounter any more problems.
Comment #26
derjochenmeyer commentedI added a detailed description to Technical notes about "anonymous" flaggings