source: branches/1.1dev/lib/App.inc.php @ 646

Last change on this file since 646 was 633, checked in by anonymous, 6 years ago

Add disabled session_use_trans_sid to defaults

File size: 29.9 KB
Line 
1<?php
2/**
3 * App.inc.php
4 * Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information
5 */
6
7/******************************************************************************
8 * CONFIG
9 ******************************************************************************
10
11 This library has some functions that require globally defined values.
12 These are defined here.
13 */
14
15//  Message Types
16/** @constant MSG_NOTICE
17    An informational message: Welcome to asdf, Logout successful, etc. */
18define('MSG_NOTICE', 0);
19
20/** @constant MSG_SUCCESS
21    A success message: Message sent, You are logged-in, etc. */
22define('MSG_SUCCESS', 1);
23
24/** @constant MSG_WARNING
25    A warning message: Access denied, Email address invalid, Article not found, etc. */
26define('MSG_WARNING', 2);
27
28/** @constant MSG_ERR
29    Unrecoverable failure: Message could not be sent, File not found, etc. */
30define('MSG_ERR', 4); // PHP user error style.
31define('MSG_ERROR', 4);
32
33
34
35/******************************************************************************
36 * FUNCTIONS
37 ******************************************************************************
38
39/**
40 * Add a message to the string globalmessage, which is printed in the header.
41 * Just a simple way to print messages to the user.
42 *
43 * @access public
44 *
45 * @param string $message The text description of the message.
46 * @param int    $type    The type of message: MSG_NOTICE,
47 *                        MSG_SUCCESS, MSG_WARNING, or MSG_ERR.
48 * @param string $file    __FILE__.
49 * @param string $line    __LINE__.
50 */
51function raiseMsg($message, $type=MSG_NOTICE, $file=null, $line=null)
52{
53    $_SESSION['_messages'][] = array(
54        'type'    => $type,
55        'message' => $message,
56        'file'    => $file,
57        'line'    => $line
58    );
59}
60
61/**
62 * Logs a message to a user defined log file. Additional actions to take for
63 * different types of message types can be specified (ERROR, NOTICE, etc).
64 *
65 * @access public
66 *
67 * @param string $message   The text description of the message.
68 * @param int    $priority  The type of message priority (in descending order):
69 *                          LOG_EMERG     system is unusable
70 *                          LOG_ALERT     action must be taken immediately
71 *                          LOG_CRIT      critical conditions
72 *                          LOG_ERR       error conditions
73 *                          LOG_WARNING   warning conditions
74 *                          LOG_NOTICE    normal, but significant, condition
75 *                          LOG_INFO      informational message
76 *                          LOG_DEBUG     debug-level message
77 * @param string $file      The file where the log event occurs.
78 * @param string $line      The line of the file where the log event occurs.
79 */
80function logMsg($message, $priority=LOG_INFO, $file=null, $line=null)
81{
82    global $CFG;
83
84    // If priority is not specified, assume the worst.
85    if (!priorityToString($priority)) {
86        logMsg(sprintf('Log priority %s not defined. (Message: %s)', $priority, $message), LOG_EMERG, $file, $line);
87        $priority = LOG_EMERG;
88    }
89
90    // If log file is not specified, create one in the codebase root.
91    if (!is_dir($CFG->log_directory) || !is_writable($CFG->log_directory)) {
92        // We must use trigger_error rather than calling logMsg, which might lead to an infinite loop.
93        trigger_error(sprintf('Codebase error: log directory not found or writable: %s', $CFG->log_directory), E_USER_NOTICE);
94        $CFG->log_directory = '/tmp';
95        $CFG->log_filename = sprintf('%s_%s.log', getenv('USER'), getenv('HTTP_HOST'));
96    }
97
98    // In case __FILE__ and __LINE__ are not provided, note that fact.
99    $file = '' == $file ? 'unknown-file' : $file;
100    $line = '' == $line ? 'unknown-line' : $line;
101
102    // Strip HTML tags except any with more than 7 characters because that's probably not a HTML tag, e.g. <email@address.com>.
103    preg_match_all('/(<[^>\s]{7,})[^>]*>/', $message, $strip_tags_allow);
104    $message = strip_tags(preg_replace('/\s+/', ' ', $message), (!empty($strip_tags_allow[1]) ? join('> ', $strip_tags_allow[1]) . '>' : null));
105
106    // Serialize multi-line messages.
107    $message = preg_replace('/\s+/m', ' ', trim($message));
108
109    // Data to be stored for a log event.
110    $event = array(
111        'date'      => date('Y-m-d H:i:s'),
112        'remote ip' => getRemoteAddr(),
113        'pid'       => getmypid(),
114        'type'      => priorityToString($priority),
115        'file:line' => "$file : $line",
116        'url'       => (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''),
117        'message'   => $message
118    );
119    // Here's a shortened version of event data.
120    $event_short = $event;
121    $event_short['url'] = truncate($event_short['url'], 120);
122
123    // FILE ACTION
124    if ($CFG->log_file_priority && $priority <= $CFG->log_file_priority) {
125        $event_str = '[' . join('] [', $event_short) . ']';
126        error_log($event_str . "\n", 3, $CFG->log_directory . '/' . $CFG->log_filename);
127    }
128
129    // EMAIL ACTION
130    if ($CFG->log_email_priority && $priority <= $CFG->log_email_priority) {
131        if (empty($CFG->log_to_email)) {
132            $CFG->log_to_email = 'bug@strangecode.com';
133        }
134        $hostname = (isset($_SERVER['HTTP_HOST']) && '' != $_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : php_uname('n');
135        $subject = sprintf('[%s %s] %s', $hostname, $event['type'], mb_substr($event['message'], 0, 64));
136        $email_msg = sprintf("A log event of type '%s' occurred on %s\n\n", $event['type'], $hostname);
137        $headers = "From: codebase@strangecode.com\r\n";
138        foreach ($event as $k=>$v) {
139            $email_msg .= sprintf("%-11s%s\n", $k, $v);
140        }
141        mail($CFG->log_to_email, $subject, $email_msg, $headers, '-f codebase@strangecode.com');
142    }
143
144    // SMS ACTION
145    if ($CFG->log_sms_priority && $priority <= $CFG->log_sms_priority) {
146        if (empty($CFG->log_to_email)) {
147            $CFG->log_to_sms = 'bug@strangecode.com';
148        }
149        $hostname = (isset($_SERVER['HTTP_HOST']) && '' != $_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : php_uname('n');
150        $subject = sprintf('[%s %s]', $hostname, $priority);
151        $sms_msg = sprintf('%s [%s:%s]', mb_substr($event_short['message'], 0, 64), basename($file), $line);
152        $headers = 'From: ' . $this->getParam('site_email');
153        mb_send_mail($CFG->log_to_sms, $subject, $sms_msg, $headers);
154    }
155
156    // SCREEN ACTION
157    if ($CFG->log_screen_priority && $priority <= $CFG->log_screen_priority) {
158        echo "[{$event['date']}] [{$event['type']}] [{$event['file:line']}] [{$event['message']}]\n";
159    }
160}
161
162/**
163 * Returns the string representation of a LOG_* integer constant.
164 *
165 * @param int  $priority  The LOG_* integer constant.
166 *
167 * @return                The string representation of $priority.
168 */
169function priorityToString ($priority) {
170    $priorities = array(
171        LOG_EMERG   => 'emergency',
172        LOG_ALERT   => 'alert',
173        LOG_CRIT    => 'critical',
174        LOG_ERR     => 'error',
175        LOG_WARNING => 'warning',
176        LOG_NOTICE  => 'notice',
177        LOG_INFO    => 'info',
178        LOG_DEBUG   => 'debug'
179    );
180    if (isset($priorities[$priority])) {
181        return $priorities[$priority];
182    } else {
183        return false;
184    }
185}
186
187/**
188 * Set the URL to return to when dieBoomerangURL() is called.
189 *
190 * @param string  $url  A fully validated URL.
191 * @param bool  $id     An identification tag for this url.
192 * FIXME: url garbage collection?
193 */
194function setBoomerangURL($url=null, $id=null)
195{
196    // A redirection will never happen immediatly after setting the boomerangURL.
197    // Set the time so ensure this doesn't happen. See validBoomerangURL for more.
198
199    if (isset($url) && is_string($url)) {
200        // Delete any boomerang request keys in the query string (along with any trailing delimiters after the deletion).
201        $url = preg_replace(array('/([&?])boomerang=[^&?]+[&?]?/', '/[&?]$/'), array('$1', ''), $url);
202
203        if (isset($_SESSION['_boomerang']['url']) && is_array($_SESSION['_boomerang']['url']) && !empty($_SESSION['_boomerang']['url'])) {
204            // If the URL currently exists in the boomerang array, delete.
205            while ($existing_key = array_search($url, $_SESSION['_boomerang']['url'])) {
206                unset($_SESSION['_boomerang']['url'][$existing_key]);
207            }
208        }
209
210        if (isset($id)) {
211            $_SESSION['_boomerang']['url'][$id] = $url;
212        } else {
213            $_SESSION['_boomerang']['url'][] = $url;
214        }
215        logMsg(sprintf('setBoomerangURL added URL %s to session %s=%s', $url, session_name(), session_id()), LOG_DEBUG, __FILE__, __LINE__);
216        return true;
217    } else {
218        return false;
219    }
220}
221
222/**
223 * Return the URL set for the specified $id.
224 *
225 * @param string  $id     An identification tag for this url.
226 */
227function getBoomerangURL($id=null)
228{
229    if (isset($id)) {
230        if (isset($_SESSION['_boomerang']['url'][$id])) {
231            return $_SESSION['_boomerang']['url'][$id];
232        } else {
233            return '';
234        }
235    } else if (is_array($_SESSION['_boomerang']['url'])) {
236        return end($_SESSION['_boomerang']['url']);
237    } else {
238        return false;
239    }
240}
241
242/**
243 * Delete the URL set for the specified $id.
244 *
245 * @param string  $id     An identification tag for this url.
246 */
247function deleteBoomerangURL($id=null)
248{
249    if (isset($id) && isset($_SESSION['_boomerang']['url'][$id])) {
250        unset($_SESSION['_boomerang']['url'][$id]);
251    } else if (is_array($_SESSION['_boomerang']['url'])) {
252        array_pop($_SESSION['_boomerang']['url']);
253    }
254}
255
256/**
257 * Check if a valid boomerang URL value has been set.
258 * if it is not the current url, and has not been accessed within n seconds.
259 *
260 * @return bool  True if it is set and not the current URL.
261 */
262function validBoomerangURL($id=null, $use_nonspecific_boomerang=false)
263{
264    if (!isset($_SESSION['_boomerang']['url'])) {
265        logMsg(sprintf('validBoomerangURL no URL set in session %s=%s', session_name(), session_id()), LOG_DEBUG, __FILE__, __LINE__);
266        return false;
267    }
268
269    // Time is the timestamp of a boomerangURL redirection, or setting of a boomerangURL.
270    // a boomerang redirection will always occur at least several seconds after the last boomerang redirect
271    // or a boomerang being set.
272    $boomerang_time = isset($_SESSION['_boomerang']['time']) ? $_SESSION['_boomerang']['time'] : 0;
273
274    if (isset($id) && isset($_SESSION['_boomerang']['url'][$id])) {
275        $url = $_SESSION['_boomerang']['url'][$id];
276    } else if (!isset($id) || $use_nonspecific_boomerang) {
277        // Use non specific boomerang if available.
278        $url = end($_SESSION['_boomerang']['url']);
279    }
280
281    logMsg(sprintf('validBoomerangURL testing url: %s', $url), LOG_DEBUG, __FILE__, __LINE__);
282    if (empty($url)) {
283        return false;
284    }
285    if ($url == absoluteMe()) {
286        // The URL we are directing to is not the current page.
287        logMsg(sprintf('Boomerang URL not valid, same as absoluteMe: %s', $url), LOG_DEBUG, __FILE__, __LINE__);
288        return false;
289    }
290    if ($boomerang_time >= (time() - 2)) {
291        // Last boomerang direction was more than 2 seconds ago.
292        logMsg(sprintf('Boomerang URL not valid, boomerang_time too short: %s', time() - $boomerang_time), LOG_DEBUG, __FILE__, __LINE__);
293        return false;
294    }
295
296    return true;
297}
298
299/*
300* Redirects a user by calling App::dieURL(). It will use:
301* 1. the stored boomerang URL, it it exists
302* 2. a specified $default_url, it it exists
303* 3. the referring URL, it it exists.
304* 4. redirect_home_url configuration variable.
305*
306* @access   public
307* @param    string  $id             Identifier for this script.
308* @param    mixed   $carry_args     Additional arguments to carry in the URL automatically (see App::oHREF()).
309* @param    string  $default_url    A default URL if there is not a valid specified boomerang URL.
310* @return   bool                    False if the session is not running. No return otherwise.
311* @author   Quinn Comendant <quinn@strangecode.com>
312* @since    31 Mar 2006 19:17:00
313*/
314function dieBoomerangURL($id=null, $carry_args=null, $default_url=null)
315{
316    // Get URL from stored boomerang. Allow non specific URL if ID not valid.
317    if (validBoomerangURL($id, true)) {
318        if (isset($id) && isset($_SESSION['_boomerang']['url'][$id])) {
319            $url = $_SESSION['_boomerang']['url'][$id];
320        } else {
321            $url = end($_SESSION['_boomerang']['url']);
322        }
323    } else if (isset($default_url)) {
324        $url = $default_url;
325    } else if (!refererIsMe()) {
326        // Ensure that the redirecting page is not also the referrer.
327        $url = getenv('HTTP_REFERER');
328    } else {
329        $url = '';
330    }
331
332    logMsg(sprintf('dieBoomerangURL found URL: %s', $url), LOG_DEBUG, __FILE__, __LINE__);
333
334    // Delete stored boomerang.
335    deleteBoomerangURL($id);
336
337    // A redirection will never happen immediately twice.
338    // Set the time so ensure this doesn't happen.
339    $_SESSION['_boomerang']['time'] = time();
340    dieURL($url, $carry_args);
341}
342
343/**
344 * Uses an http header to redirect the client to the given $url. If sessions are not used
345 * and the session is not already defined in the given $url, the SID is appended as a URI query.
346 * As with all header generating functions, make sure this is called before any other output.
347 *
348 * @param   string  $url                    The URL the client will be redirected to.
349 * @param   mixed   $carry_args             Additional url arguments to carry in the query,
350 *                                          or FALSE to prevent carrying queries. Can be any of the following formats:
351 *                                          -array('key1', key2', key3')  <-- to save these keys if in the form data.
352 *                                          -array('key1'=>'value', key2'='value')  <-- to set keys to default values if not present in form data.
353 *                                          -false  <-- To not carry any queries. If URL already has queries those will be retained.
354 * @param   bool    $always_include_sid     Force session id to be added to Location header.
355 */
356function dieURL($url, $carry_args=null, $always_include_sid=false)
357{
358    global $CFG;
359
360    if ('' == $url) {
361        // If URL is not specified, use the redirect_home.
362        $url = $CFG->redirect_home;
363    }
364
365    if (preg_match('!^/!', $url)) {
366        // If relative URL is given, prepend correct local hostname.
367        $hostname = ('on' == getenv('HTTPS')) ? 'https://' . getenv('HTTP_HOST') : 'http://' . getenv('HTTP_HOST');
368        $url = $hostname . $url;
369    }
370
371    $url = url($url, $carry_args, $always_include_sid);
372
373    header(sprintf('Location: %s', $url));
374    logMsg(sprintf('dieURL dying to URL: %s', $url), LOG_DEBUG, __FILE__, __LINE__);
375    die;
376}
377
378/**
379 * Prints a hidden form element with the PHPSESSID when cookies are not used, as well
380 * as hidden form elements for GET_VARS that might be in use.
381 *
382 * @global string $carry_queries     An array of keys to define which values to
383 *                                   carry through from the POST or GET.
384 *                                   $carry_queries = array('qry'); for example
385 *
386 * @param  mixed  $carry_args        Additional url arguments to carry in the query,
387 *                                   or FALSE to prevent carrying queries. Can be any of the following formats:
388 *                                   -array('key1', key2', key3')  <-- to save these keys if in the form data.
389 *                                   -array('key1'=>'value', key2'='value')  <-- to set keys to default values if not present in form data.
390 *                                   -false  <-- To not carry any queries. If URL already has queries those will be retained.
391 */
392function printHiddenSession($carry_args=null)
393{
394    static $_using_trans_sid;
395    global $carry_queries;
396
397    // Save the trans_sid setting.
398    if (!isset($_using_trans_sid)) {
399        $_using_trans_sid = ini_get('session.use_trans_sid');
400    }
401
402    // Initialize the carried queries.
403    if (!isset($carry_queries['_carry_queries_init'])) {
404        if (!is_array($carry_queries)) {
405            $carry_queries = array($carry_queries);
406        }
407        $tmp = $carry_queries;
408        $carry_queries = array();
409        foreach ($tmp as $key) {
410            if (!empty($key) && getFormData($key, false)) {
411                $carry_queries[$key] = getFormData($key);
412            }
413        }
414        $carry_queries['_carry_queries_init'] = true;
415    }
416
417    // Get any additional query names to add to the $carry_queries array
418    // that are found as function arguments.
419    // If FALSE is a function argument, DO NOT carry the queries.
420    $do_carry_queries = true;
421    $one_time_carry_queries = array();
422    if (!is_null($carry_args)) {
423        if (is_array($carry_args) && !empty($carry_args)) {
424            foreach ($carry_args as $key=>$arg) {
425                // Get query from appropriate source.
426                if (false === $arg) {
427                    $do_carry_queries = false;
428                } else if (false !== getFormData($arg, false)) {
429                    $one_time_carry_queries[$arg] = getFormData($arg); // Set arg to form data if available.
430                } else if (!is_numeric($key) && '' != $arg) {
431                    $one_time_carry_queries[$key] = getFormData($key, $arg); // Set to arg to default if specified (overwritten by form data).
432                }
433            }
434        } else if (false !== getFormData($carry_args, false)) {
435            $one_time_carry_queries[$carry_args] = getFormData($carry_args);
436        } else if (false === $carry_args) {
437            $do_carry_queries = false;
438        }
439    }
440
441    // For each existing POST value, we create a hidden input to carry it through a form.
442    if ($do_carry_queries) {
443        // Join the perm and temp carry_queries and filter out the _carry_queries_init element for the final query args.
444        $query_args = array_diff_assoc(array_merge($carry_queries, $one_time_carry_queries), array('_carry_queries_init' => true));
445        foreach ($query_args as $key=>$val) {
446            echo '<input type="hidden" name="' . $key . '" value="' . $val . '" />';
447        }
448    }
449
450    // Include the SID if cookies are disabled.
451    if (!isset($_COOKIE[session_name()]) && !$_using_trans_sid) {
452        echo '<input type="hidden" name="' . session_name() . '" value="' . session_id() . '" />';
453    }
454}
455
456/**
457 * Outputs a fully qualified URL with a query of all the used (ie: not empty)
458 * keys and values, including optional queries. This allows simple printing of
459 * links without needing to know which queries to add to it. If cookies are not
460 * used, the session id will be propogated in the URL.
461 *
462 * @global string $carry_queries       An array of keys to define which values to
463 *                                     carry through from the POST or GET.
464 *                                     $carry_queries = array('qry'); for example.
465 *
466 * @param  string $url                 The initial url
467 * @param  mixed  $carry_args          Additional url arguments to carry in the query,
468 *                                     or FALSE to prevent carrying queries. Can be any of the following formats:
469 *                                     -array('key1', key2', key3')  <-- to save these keys if in the form data.
470 *                                     -array('key1'=>'value', key2'='value')  <-- to set keys to default values if not present in form data.
471 *                                     -false  <-- To not carry any queries. If URL already has queries those will be retained.
472 *
473 * @param  mixed  $always_include_sid  Always add the session id, even if using_trans_sid = true. This is required when
474 *                                     URL starts with http, since PHP using_trans_sid doesn't do those and also for
475 *                                     header('Location...') redirections.
476 *
477 * @return string url with attached queries and, if not using cookies, the session id
478 */
479function url($url='', $carry_args=null, $always_include_sid=false)
480{
481    static $_using_trans_sid;
482    global $carry_queries;
483    global $CFG;
484
485    // Save the trans_sid setting.
486    if (!isset($_using_trans_sid)) {
487        $_using_trans_sid = ini_get('session.use_trans_sid');
488    }
489
490    // Initialize the carried queries.
491    if (!isset($carry_queries['_carry_queries_init'])) {
492        if (!is_array($carry_queries)) {
493            $carry_queries = array($carry_queries);
494        }
495        $tmp = $carry_queries;
496        $carry_queries = array();
497        foreach ($tmp as $key) {
498            if (!empty($key) && getFormData($key, false)) {
499                $carry_queries[$key] = getFormData($key);
500            }
501        }
502        $carry_queries['_carry_queries_init'] = true;
503    }
504
505    // Get any additional query arguments to add to the $carry_queries array.
506    // If FALSE is a function argument, DO NOT carry the queries.
507    $do_carry_queries = true;
508    $one_time_carry_queries = array();
509    if (!is_null($carry_args)) {
510        if (is_array($carry_args) && !empty($carry_args)) {
511            foreach ($carry_args as $key=>$arg) {
512                // Get query from appropriate source.
513                if (false === $arg) {
514                    $do_carry_queries = false;
515                } else if (false !== getFormData($arg, false)) {
516                    $one_time_carry_queries[$arg] = getFormData($arg); // Set arg to form data if available.
517                } else if (!is_numeric($key) && '' != $arg) {
518                    $one_time_carry_queries[$key] = getFormData($key, $arg); // Set to arg to default if specified (overwritten by form data).
519                }
520            }
521        } else if (false !== getFormData($carry_args, false)) {
522            $one_time_carry_queries[$carry_args] = getFormData($carry_args);
523        } else if (false === $carry_args) {
524            $do_carry_queries = false;
525        }
526    }
527
528    // Get the first delimiter that is needed in the url.
529    $delim = preg_match('/\?/', $url) ? ini_get('arg_separator.output') : '?';
530
531    $q = '';
532    if ($do_carry_queries) {
533        // Join the perm and temp carry_queries and filter out the _carry_queries_init element for the final query args.
534        $query_args = array_diff_assoc(urlEncodeArray(array_merge($carry_queries, $one_time_carry_queries)), array('_carry_queries_init' => true));
535        foreach ($query_args as $key=>$val) {
536            // Check value is set and value does not already exist in the url.
537            if (!preg_match('/[?&]' . preg_quote($key) . '=/', $url)) {
538                $q .= $delim . $key . '=' . $val;
539                $delim = ini_get('arg_separator.output');
540            }
541        }
542    }
543
544    // Include the necessary SID if the following is true:
545    // - no cookie in http request OR cookies disabled in config
546    // - sessions are enabled
547    // - the link stays on our site
548    // - transparent SID propagation with session.use_trans_sid is not being used OR url begins with protocol (using_trans_sid has no effect here)
549    // OR
550    // - we must include the SID because we say so (it's used in a context where cookies will not be effective, ie. moving from http to https)
551    // AND
552    // - the SID is not already in the query.
553    if (
554        (
555            (
556                (
557                    !isset($_COOKIE[session_name()])
558                    || !$CFG->session_use_cookies
559                )
560                && $CFG->session_use_trans_sid
561                && $CFG->enable_session
562                && isMyDomain($url)
563                &&
564                (
565                    !$_using_trans_sid
566                    || preg_match('!^(http|https)://!i', $url)
567                )
568            )
569            || $always_include_sid
570        )
571        && !preg_match('/[?&]' . preg_quote(session_name()) . '=/', $url)
572    ) {
573        $url .= $q . $delim . session_name() . '=' . session_id();
574//         logMsg(sprintf('oHREF appending session id to URL: %s', $url), LOG_DEBUG, __FILE__, __LINE__);
575    } else {
576        $url .= $q;
577    }
578
579    return $url;
580}
581
582/**
583 * Returns a URL processed with App::url and htmlentities for printing in html.
584 *
585 * @access  public
586 * @param   string  $url    Input URL to parse.
587 * @return  string          URL with App::url() and htmlentities() applied.
588 * @author  Quinn Comendant <quinn@strangecode.com>
589 * @since   09 Dec 2005 17:58:45
590 */
591function oHREF($url, $carry_args=null, $always_include_sid=false)
592{
593    $url = url($url, $carry_args, $always_include_sid);
594    // Replace any & not followed by an html or unicode entity with it's &amp; equivalent.
595    $url = preg_replace('/&(?![\w\d#]{1,10};)/', '&amp;', $url);
596    return $url;
597}
598
599/**
600 * Force the user to connect via https (port 443) by redirecting them to
601 * the same page but with https.
602 */
603function sslOn()
604{
605    global $CFG;
606
607    if (function_exists('apache_get_modules')) {
608        $modules = apache_get_modules();
609    } else {
610        // It's safe to assume we have mod_ssl if we can't determine otherwise.
611        $modules = array('mod_ssl');
612    }
613
614    if ('on' != getenv('HTTPS') && $CFG->ssl_enabled && in_array('mod_ssl', $modules)) {
615        raiseMsg(sprintf(_("Secure SSL connection made to %s"), $CFG->ssl_domain), MSG_NOTICE, __FILE__, __LINE__);
616        // Always append session because some browsers do not send cookie when crossing to SSL URL.
617        dieURL('https://' . $CFG->ssl_domain . getenv('REQUEST_URI'), null, true);
618    }
619}
620
621
622/**
623 * to enforce the user to connect via http (port 80) by redirecting them to
624 * a http version of the current url.
625 */
626function sslOff()
627{
628    if ('on' == getenv('HTTPS')) {
629        dieURL('http://' . getenv('HTTP_HOST') . getenv('REQUEST_URI'), null, true);
630    }
631}
632
633/**
634 * If the given $url is on the same web site, return true. This can be used to
635 * prevent from sending sensitive info in a get query (like the SID) to another
636 * domain. $method can be "ip" or "domain". The domain method might be preferred
637 * if your domain spans mutiple IP's (load sharing servers)
638 *
639 * @param  string $url    the URI to test.
640 * @param  mixed $method  the method to use. Either 'domain' or 'ip'.
641 *
642 * @return bool    true if given $url is this domain or has no domain (is a
643 *                 relative url), false if it's another
644 */
645function isMyDomain($url)
646{
647    if (!preg_match('|\w{1,}\.\w{2,5}/|', $url)) {
648        // If we can't find a domain we assume the URL is relative.
649        return true;
650    } else {
651        return preg_match('/' . preg_quote(getenv('HTTP_HOST')) . '/', $url);
652    }
653}
654
655/**
656 * Loads a list of tables in the current database into an array, and returns
657 * true if the requested table is found. Use this function to enable/disable
658 * funtionality based upon the current available db tables.
659 *
660 * @param  string $table    The name of the table to search.
661 *
662 * @return bool    true if given $table exists.
663 */
664function dbTableExists($table)
665{
666    static $existing_tables;
667
668    // Save the trans_sid setting.
669    if (!isset($existing_tables)) {
670        // Get DB tables.
671        $existing_tables = array();
672        $qid = dbQuery("SHOW TABLES");
673        while (list($row) = mysql_fetch_row($qid)) {
674            $existing_tables[] = $row;
675        }
676    }
677
678    // Test if requested table is in database.
679    return in_array($table, $existing_tables);
680}
681
682/**
683 * Takes a URL and returns it without the query or anchor portion
684 *
685 * @param  string $url   any kind of URI
686 *
687 * @return string        the URI with ? or # and everything after removed
688 */
689function stripQuery($url)
690{
691    return preg_replace('![?#].*!', '', $url);
692}
693
694/**
695 * Returns the remote IP address, taking into consideration proxy servers.
696 *
697 * @param  bool $dolookup   If true we resolve to IP to a host name,
698 *                          if false we don't.
699 *
700 * @return string    IP address if $dolookup is false or no arg
701 *                   Hostname if $dolookup is true
702 */
703function getRemoteAddr($dolookup=false)
704{
705    $ip = getenv('HTTP_CLIENT_IP');
706    if (empty($ip) || $ip == 'unknown' || $ip == 'localhost' || $ip == '127.0.0.1') {
707        $ip = getenv('HTTP_X_FORWARDED_FOR');
708        if (empty($ip) || $ip == 'unknown' || $ip == 'localhost' || $ip == '127.0.0.1') {
709            $ip = getenv('REMOTE_ADDR');
710        }
711    }
712    return $dolookup && '' != $ip ? gethostbyaddr($ip) : $ip;
713}
714
715/**
716 * Tests whether a given iP address can be found in an array of IP address networks.
717 * Elements of networks array can be single IP addresses or an IP address range in CIDR notation
718 * See: http://en.wikipedia.org/wiki/Classless_inter-domain_routing
719 *
720 * @access  public
721 *
722 * @param   string  IP address to search for.
723 * @param   array   Array of networks to search within.
724 *
725 * @return  mixed   Returns the network that matched on success, false on failure.
726 */
727function ipInRange($my_ip, $ip_pool)
728{
729    if (!is_array($ip_pool)) {
730        $ip_pool = array($ip_pool);
731    }
732
733    $my_ip_binary = sprintf('%032b', ip2long($my_ip));
734    foreach ($ip_pool as $ip) {
735        if (preg_match('![\d\.]{7,15}/\d{1,2}!', $ip)) {
736            // IP is in CIDR notation.
737            list($cidr_ip, $cidr_bitmask) = split('/', $ip);
738            $cidr_ip_binary = sprintf('%032b', ip2long($cidr_ip));
739            if (substr($my_ip_binary, 0, $cidr_bitmask) === substr($cidr_ip_binary, 0, $cidr_bitmask)) {
740               // IP address is within the specified IP range.
741               return $ip;
742            }
743        } else {
744            if ($my_ip === $ip) {
745               // IP address exactly matches.
746               return $ip;
747            }
748        }
749    }
750
751    return false;
752}
753
754/**
755 * Returns a fully qualified URL to the current script, including the query.
756 *
757 * @return string    a full url to the current script
758 */
759function absoluteMe()
760{
761    $protocol = ('on' == getenv('HTTPS')) ? 'https://' : 'http://';
762    return $protocol . getenv('HTTP_HOST') . getenv('REQUEST_URI');
763}
764
765/**
766 * Compares the current url with the referring url.
767 *
768 * @param  string  $compary_query  Include the query string in the comparison.
769 *
770 * @return bool    true if the current script (or specified valid_referer)
771 *                 is the referrer. false otherwise.
772 */
773function refererIsMe($exclude_query=false)
774{
775    if ($exclude_query) {
776        return (stripQuery(absoluteMe()) == stripQuery(getenv('HTTP_REFERER')));
777    } else {
778        return (absoluteMe() == getenv('HTTP_REFERER'));
779    }
780}
781
782?>
Note: See TracBrowser for help on using the repository browser.