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

Last change on this file since 391 was 308, checked in by quinn, 16 years ago

General bug fixes. Backported email checking regex from codebase 2.1.2. Some css mods.

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