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.
While implementing flagging for anonymous users on Pressflow 6 - I've found that if a user doesn't already have any cookies, Session API will not create one. This is because of how session_api_available() checks if cookies are enabled.
For most of my users, I never want them to have a cookie to allow varnish to cache their traffic, so this essentially breaks Session API for me. Am I understanding this correctly? Do we actually need to check if there in anything in $_COOKIE ?
/**
* Determine if cookies are enabled.
*/
function session_api_available() {
return !empty($_COOKIE);
}
Comment | File | Size | Author |
---|---|---|---|
#4 | no-cookies--1233650--4.patch | 1.51 KB | jessehs |
#1 | no-cookies--1233650--1.patch | 1.6 KB | jessehs |
Comments
Comment #1
jessehsI also am running into this problem on a D6 pressflow site. I'm not sure how to check if a user has cookies enabled on their browser, but I'm also not sure there is a problem with going ahead and trying to save a session even if they do not.
This patch changes the session_api_available function to create an "initialized" cookie if $create is true (which is determined in the session_api_get_sid function). The patch also makes sure not to query the database for the "initialized" cookie.
Comment #2
jessehsJust wanted to add that I think this issue is fundamentally related to this ongoing core issue: http://drupal.org/node/2946
There doesn't really seem to be a sure fire way to determine if a user's browser will accept a cookie without first trying to set one and seeing if it still exists after an additional page load. With Pressflow, this could be a huge performance hit, as it doesn't try to set a cookie for anonymous users.
Comment #3
jhedstromI've been thinking about the approach in #1, and I think it may be too aggressive, since any module calling
session_api_get_sid()
will effectively set cookies on every page.I propose, rather, and additional API function (perhaps
session_api_set_cookie()
) that simple initializes the cookie in the same way the patch in #1 does.This would give modules much finer control over which pages initialize cookies, and which do not.
Comment #4
jessehsHere is a patch suggested in #3. The function name is "session_api_initialize_cookie."
Comment #5
jhedstromCommitted to 6.x. Thanks!
Comment #6
jhedstromComment #7
Roi Danton CreditAttribution: Roi Danton commentedI had a similar issue that session ID cookie is not set when there is no cookie already. Using flag module and D7:
The patch in #1 didn't work for me, since
was always triggered in
session_api_get_sid()
. So I set $create always to TRUE:which fixes the problem. And b/c there is already
in
session_api_get_sid()
the existing cookie is used when there is one. So everything works as expected. Can you tell me which are the possible drawbacks of this method?Comment #8
a.ross CreditAttribution: a.ross commented*Stumble* #1619114: After cleaning cookies, flagging content as an anonymous user causes a PDO exception.
Comment #9
smartango CreditAttribution: smartango commented@Roi the drawback given in comment
http://drupal.org/node/1619114#comment-6309018
- call flag_get_uid(0) [ which call flag_set_sid($uid,FALSE) ] returns 0 and set static $sids[0] to 0
- call flag_set_uid(0) [ which has $create = TRUE as default ] return 0 never start session [WRONG]
maintaining a static $sids array in flag_set_sid make it never start a session
anyway I cant understand how in patch in #4 this function:
called as session_api_available() could ever return false when browser do not support cookies or not. In php if you set a key of an array empty($arrayname) return FALSE, thus this returns TRUE, for any user agent.
If you want TRUE, just use TRUE, don't call a function.
http://php.net/manual/en/reserved.variables.cookies.php
http://www.php.net/manual/en/function.setcookie.php
way of retrieve and set cookies with php
Comment #10
nlisgo CreditAttribution: nlisgo commentedsmartango thanks so much for the explanation and the links.
The link http://www.php.net/manual/en/function.setcookie.php is particularly significantly. We simply cannot tell until the next page whether the browser supports cookies.
For those who need to action something on the first time a user hits the page then either be prepared to be disappointed or rethink your solution.
Comment #11
nlisgo CreditAttribution: nlisgo commentedMy work around was to include a javascript file if session_api_available did not return TRUE. In that javascript file a perform an ajax call on the same page so that the cookie support should be known at that point and I can use rules to set the flag for anonymous users.
Comment #12
smartango CreditAttribution: smartango commentednlisgo I am not following actively this issue, but I would give a comment. Using ajax (with post) is a way to invalid the cached page, this could be done server side in some way too, I think, if server reply with invalid to header request of browser it will download the page again with cookie setted, then you can test (in the next call) if browser accept cookies. (of course the javascript solution is more elegant)
But the problem, I think, is to have an "all cached" site that has cookie support. That is not possible ... or it is? maybe if the relative parts travel on ajax request and javascript client side rendering, the most could be cached, while the user related data not. This is already known, but is not this solution. I suppose is due to the policy of not relying on javascript support for web application (server side application), policy that is becoming outdate, anyway there is the fork option that will not hurt anyone
Comment #13
a.ross CreditAttribution: a.ross commentedI guess this is more of a feature request as HTTP is stateless and sessions are (therefore) managed through cookies. And cookies, as we know, may not be supported by the client.
Basically there are 2 conceptual ways to do this:
As for the latter option, I don't think that's feasible. And as for the former, I'm not sure what the drawbacks of that are.