3 * Enable cookieless sessions by including $CFG->usesid=true;
5 * Based on code from php manual by Richard at postamble.co.uk
6 * Attempts to use cookies if cookies not present then uses session ids attached to all urls and forms to pass session id from page to page.
7 * If site is open to google, google is given guest access as usual and there are no sessions. No session ids will be attached to urls for googlebot.
8 * This doesn't require trans_sid to be turned on but this is recommended for better performance
10 * session.use_trans_sid = 1
11 * in your php.ini file and make sure that you don't have a line like this in your php.ini
12 * session.use_only_cookies = 1
13 * @author Richard at postamble.co.uk and Jamie Pratt
14 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
16 class cookieless_sid
{
19 * @var string Using this variable to store $CFG->wwwroot. Found that in some versions of php the $CFG global was null in
20 * the callback functions used by the output buffer.
24 * @var string Using this variable to store $CFG->httpswwwroot.
26 var $httpsroot = null;
29 * @var boolean Using this variable to store $CFG->usesid.
34 * You won't call this function directly. This function is used to process
35 * text buffered by php in an output buffer. All output is run through this function
37 * @param string $buffer is the output sent from php
38 * @return string the output sent to the browser
40 function ob_rewrite($buffer){
41 $replacements = array(
42 '/(<\s*(a|link|script|frame|area)\s[^>]*(href|src)\s*=\s*")([^"]*)(")/i',
43 '/(<\s*(a|link|script|frame|area)\s[^>]*(href|src)\s*=\s*\')([^\']*)(\')/i');
45 $buffer = preg_replace_callback($replacements, array($this, "rewrite_link_tag"), $buffer);
46 $buffer = preg_replace('/<form\s[^>]*>/i',
47 '\0<input type="hidden" name="' . session_name() . '" value="' . session_id() . '"/>', $buffer);
52 * You won't call this function directly. This function is used to process
53 * text buffered by php in an output buffer. All output is run through this function
55 * This function only processes absolute urls, it is used when we decide that
56 * php is processing other urls itself but needs some help with internal absolute urls still.
57 * @param string $buffer is the output sent from php
58 * @return string the output sent to the browser
60 function ob_rewrite_absolute($buffer){
61 $replacements = array(
62 '/(<\s*(a|link|script|frame|area)\s[^>]*(href|src)\s*=\s*")((?:http|https)[^"]*)(")/i',
63 '/(<\s*(a|link|script|frame|area)\s[^>]*(href|src)\s*=\s*\')((?:http|https)[^\']*)(\')/i');
65 $buffer = preg_replace_callback($replacements, array($this, "rewrite_link_tag"), $buffer);
66 $buffer = preg_replace('/<form\s[^>]*>/i',
67 '\0<input type="hidden" name="' . session_name() . '" value="' . session_id() . '"/>', $buffer);
71 * A function to process link, a and script tags found
72 * by preg_replace_callback in ob_rewrite($buffer).
74 function rewrite_link_tag($matches){
76 $url= $this->process_url($url);
77 return $matches[1]. $url.$matches[5];
80 * You can call this function directly. This function is used to process
81 * urls to add a moodle session id to the url for internal links.
82 * @param string $url is a url
83 * @return string the processed url
85 function process_url($url) {
86 if ((preg_match('/^(http|https):/i', $url)) // absolute url
87 && ((stripos($url, $this->httproot
)!==0) && stripos($url, $this->httpsroot
)!==0)) { // and not local one
88 //error_log("non local url : $url ; \$CFG->wwwroot : ".$this->httproot);
89 return $url; //don't attach sessid to non local urls
91 if ($url[0]=='#' ||
(stripos($url, 'javascript:')===0)) {
92 //error_log("anchor : $url");
93 return $url; //don't attach sessid to anchors
95 if (strpos($url, session_name())!==FALSE)
97 //error_log("already has one sessid : $url");
98 return $url; //don't attach sessid to url that already has one sessid
100 if (strpos($url, "?")===FALSE){
101 $append="?".strip_tags(session_name() . '=' . session_id() );
103 $append="&".strip_tags(session_name() . '=' . session_id() );
105 //put sessid before any anchor
106 $p = strpos($url, "#");
108 $anch = substr($url, $p);
109 $url = substr($url, 0, $p).$append.$anch ;
113 //error_log("added sid : $url");
120 * Call this function before there has been any output to the browser to
121 * buffer output and add session ids to all internal links.
126 $this->httproot
= $CFG->wwwroot
;
127 $this->httpsroot
= $CFG->httpswwwroot
;
128 $this->usesid
= !empty($CFG->usesid
);
130 //don't attach sess id for bots
132 if (!empty($_SERVER['HTTP_USER_AGENT'])) {
133 if (!empty($CFG->opentogoogle
)) {
134 if (strpos($_SERVER['HTTP_USER_AGENT'], 'Googlebot') !== false ) {
135 @ini_set
('session.use_trans_sid', '0'); // try and turn off trans_sid
139 if (strpos($_SERVER['HTTP_USER_AGENT'], 'google.com') !== false ) {
140 @ini_set
('session.use_trans_sid', '0'); // try and turn off trans_sid
145 if (strpos($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator') !== false ) {
146 @ini_set
('session.use_trans_sid', '0'); // try and turn off trans_sid
151 @ini_set
('session.use_trans_sid', '1'); // try and turn on trans_sid
152 if (ini_get('session.use_trans_sid')!=0 ){
153 // use trans sid as its available
154 ini_set('url_rewriter.tags', 'a=href,area=href,script=src,link=href,'
155 . 'frame=src,form=fakeentry');
156 ob_start(array($this, 'ob_rewrite_absolute'));
158 //rewrite all links ourselves
159 ob_start(array($this, 'ob_rewrite'));
164 $url_processor_for_cookieless_sessions = new cookieless_sid();
165 $url_processor_for_cookieless_sessions->start_ob();
167 * You can call this function directly. This function is used to process
168 * urls to add a moodle session id to the url for internal links.
169 * Still using this function as a facade to access the instantiated object,
170 * that actually does the processing, to preserve the old api.
171 * @param string $url is a url
172 * @return string the processed url
174 function sid_process_url($url) {
175 global $url_processor_for_cookieless_sessions;
176 return $url_processor_for_cookieless_sessions->process_url($url);