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

Last change on this file since 577 was 549, checked in by anonymous, 9 years ago

Backporting minor debugging niceites.

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