source: branches/1.1dev/lib/Utilities.inc.php @ 649

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

Backport dump(), fancyDump(), and truncate() from v2.x

File size: 29.8 KB
Line 
1<?php
2/**
3 * Utilities.inc.php
4 * Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information
5 */
6
7
8/**
9 * Print variable dump.
10 *
11 * @param  mixed    $var        The variable to dump.
12 * @param  bool     $display    Print the dump in <pre> tags or hide it in html comments (non-CLI only).
13 * @param  bool     $dump_method   Dump method. See SC_DUMP_* constants.
14 * @param  string   $file       Value of __FILE__.
15 * @param  string   $line       Value of __LINE__
16 */
17define('SC_DUMP_PRINT_R', 0);
18define('SC_DUMP_VAR_DUMP', 1);
19define('SC_DUMP_VAR_EXPORT', 2);
20function dump($var, $display=false, $dump_method=SC_DUMP_PRINT_R, $file='', $line='')
21{
22    $app =& App::getInstance();
23
24    if ('cli' === php_sapi_name() || defined('_CLI')) {
25        echo "DUMP FROM: $file $line\n";
26    } else {
27        echo $display ? "\n<br />DUMP <strong>$file $line</strong><br /><pre>\n" : "\n<!-- DUMP $file $line\n";
28    }
29
30    switch ($dump_method) {
31    case SC_DUMP_PRINT_R:
32    default:
33        // Print human-readable descriptions of invisible types.
34        if (null === $var) {
35            echo '(null)';
36        } else if (true === $var) {
37            echo '(bool: true)';
38        } else if (false === $var) {
39            echo '(bool: false)';
40        } else if (is_scalar($var) && '' === $var) {
41            echo '(empty string)';
42        } else if (is_scalar($var) && preg_match('/^\s+$/', $var)) {
43            echo '(only white space)';
44        } else {
45            print_r($var);
46        }
47        break;
48
49    case SC_DUMP_VAR_DUMP:
50        var_dump($var);
51        break;
52
53    case SC_DUMP_VAR_EXPORT:
54        var_export($var);
55        break;
56    }
57
58    if ('cli' === php_sapi_name() || defined('_CLI')) {
59        echo "\n";
60    } else {
61        echo $display ? "\n</pre><br />\n" : "\n-->\n";
62    }
63}
64
65/**
66 * Return dump as variable.
67 *
68 * @param  mixed $var      Variable to dump.
69 *
70 * @return string Dump of var.
71 */
72function getDump($var)
73{
74    ob_start();
75    print_r($var);
76    $d = ob_get_contents();
77    ob_end_clean();
78    return $d;
79}
80
81/**
82 * Return dump as cleaned text. Useful for dumping data into emails.
83 *
84 * @param  array    $var        Variable to dump.
85 * @param  strong   $indent     A string to prepend indented lines (tab for example).
86 * @return string Dump of var.
87 */
88function fancyDump($var, $indent='')
89{
90    $output = '';
91    if (is_array($var)) {
92        foreach ($var as $k=>$v) {
93            $k = ucfirst(mb_strtolower(str_replace(array('_', '  '), ' ', $k)));
94            if (is_array($v)) {
95                $output .= sprintf("\n%s%s: %s\n", $indent, $k, fancyDump($v, $indent . $indent));
96            } else {
97                $output .= sprintf("%s%s: %s\n", $indent, $k, $v);
98            }
99        }
100    } else {
101        $output .= sprintf("%s%s\n", $indent, $var);
102    }
103    return preg_replace(['/^[ \t]+$/', '/\n\n\n+/'], ['', "\n\n"], $output);
104}
105
106/**
107 * Returns text with appropriate html translations.
108 *
109 * @param  string $txt              Text to clean.
110 * @param  bool   $preserve_html    If set to true, oTxt will not translage <, >, ", or '
111 *                                  characters into HTML entities. This allows HTML to pass
112 *                                  through unmunged.
113 *
114 * @return string                   Cleaned text.
115 */
116function oTxt($txt, $preserve_html=false)
117{
118    global $CFG;
119
120    $search = array();
121    $replace = array();
122
123    // Make converted ampersand entities into normal ampersands (they will be done manually later) to retain HTML entities.
124    $search['retain_ampersand']     = '/&amp;/';
125    $replace['retain_ampersand']    = '&';
126
127    if ($preserve_html) {
128        // Convert characters that must remain non-entities for displaying HTML.
129        $search['retain_left_angle']       = '/&lt;/';
130        $replace['retain_left_angle']      = '<';
131
132        $search['retain_right_angle']      = '/&gt;/';
133        $replace['retain_right_angle']     = '>';
134
135        $search['retain_single_quote']     = '/&#039;/';
136        $replace['retain_single_quote']    = "'";
137
138        $search['retain_double_quote']     = '/&quot;/';
139        $replace['retain_double_quote']    = '"';
140    }
141
142    // & becomes &amp;
143    $search['ampersand']        = '/&((?![\w\d#]{1,10};))/';
144    $replace['ampersand']       = '&amp;\\1';
145
146    return preg_replace($search, $replace, htmlentities($txt, ENT_QUOTES, $CFG->character_set));
147}
148
149/**
150 * Returns text with stylistic modifications.
151 *
152 * @param  string   $txt  Text to clean.
153 *
154 * @return string         Cleaned text.
155 */
156function fancyTxt($txt)
157{
158    $search = array();
159    $replace = array();
160
161    // "double quoted text"  becomes  &ldquo;double quoted text&rdquo;
162    $search['double_quotes']    = '/(^|[^\w=])(?:"|&quot;|&#34;|&#x22;|&ldquo;)([^"]+?)(?:"|&quot;|&#34;|&#x22;|&rdquo;)([^\w]|$)/'; // " is the same as &quot; and &#34; and &#x22;
163    $replace['double_quotes']   = '\\1&ldquo;\\2&rdquo;\\3';
164
165    // text's apostrophes  become  text&rsquo;s apostrophes
166    $search['apostrophe']       = '/(\w)(?:\'|&#39;)(\w)/';
167    $replace['apostrophe']      = '\\1&rsquo;\\2';
168
169    // "single quoted text"  becomes  &lsquo;single quoted text&rsquo;
170    $search['single_quotes']    = '/(^|[^\w=])(?:\'|&#39;|&lsquo;)([^\']+?)(?:\'|&#39;|&rsquo;)([^\w]|$)/';
171    $replace['single_quotes']   = '\\1&lsquo;\\2&rsquo;\\3';
172
173    // em--dashes  become em&mdash;dashes
174    $search['em_dash']          = '/(\s*[^!<-])--([^>-]\s*)/';
175    $replace['em_dash']         = '\\1&mdash;\\2';
176
177    // & becomes &amp;
178    $search['ampersand']        = '/&((?![\w\d#]{1,10};))/';
179    $replace['ampersand']       = '&amp;\\1';
180
181    return preg_replace($search, $replace, $txt);
182}
183
184/*
185* Finds all URLs in text and hyperlinks them.
186*
187* @access   public
188* @param    string  $text   Text to search for URLs.
189* @param    bool    $strict True to only include URLs starting with a scheme (http:// ftp:// im://), or false to include URLs starting with 'www.'.
190* @param    mixed   $length Number of characters to truncate URL, or NULL to disable truncating.
191* @param    string  $delim  Delimiter to append, indicate truncation.
192* @return   string          Same input text, but URLs hyperlinked.
193* @author   Quinn Comendant <quinn@strangecode.com>
194* @version  2.1
195* @since    22 Mar 2015 23:29:04
196*/
197function hyperlinkTxt($text, $strict=false, $length=null, $delim='
')
198{
199    // A list of schemes we allow at the beginning of a URL.
200    $schemes = 'mailto:|tel:|skype:|callto:|facetime:|bitcoin:|geo:|magnet:\?|sip:|sms:|xmpp:|view-source:(?:https?://)?|[\w-]{2,}://';
201
202    // Capture the full URL into the first match and only the first X characters into the second match.
203    // This will match URLs not preceded by " ' or = (URLs inside an attribute) or ` (Markdown quoted) or double-scheme (http://http://www.asdf.com)
204    // Valid URL characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
205    $regex = '@
206        \b                              # Start with a word-boundary.
207        (?<!"|\'|=|>|`|\]\(|[:/]/) # Negative look-behind to exclude URLs already in <a> tag, <tags>beween</tags>, `Markdown quoted`, [Markdown](link), and avoid broken:/ and doubled://schemes://
208        (                               # Begin match 1
209            (                           # Begin match 2
210                (?:%s)                  # URL starts with known scheme or www. if strict = false
211                [^\s/$.?#]+             # Any domain-valid characters
212                [^\s"`<>]{1,%s}         # Match 2 is limited to a maximum of LENGTH valid URL characters
213            )
214            [^\s"`<>]*                  # Match 1 continues with any further valid URL characters
215            ([^\P{Any}\s
<>«»"—–%s])    # Final character not a space or common end-of-sentence punctuation (.,:;?!, etc). Using double negation set, see http://stackoverflow.com/a/4786560/277303
216        )
217        @Suxi
218    ';
219    $regex = sprintf($regex,
220        ($strict ? $schemes : $schemes . '|www\.'), // Strict=false adds "www." to the list of allowed start-of-URL.
221        ($length ? $length : ''),
222        ($strict ? '' : '?!.,:;)\'-') // Strict=false excludes some "URL-valid" characters from the last character of URL. (Hyphen must remain last character in this class.)
223    );
224
225    // Use a callback function to decide when to append the delim.
226    // Also encode special chars with oTxt().
227    return preg_replace_callback($regex, function ($m) use ($length, $delim) {
228        $url = $m[1];
229        $truncated_url = $m[2] . $m[3];
230        $absolute_url = preg_replace('!^www\.!', 'http://www.', $url);
231        if (is_null($length) || $url == $truncated_url) {
232            // If not truncating, or URL was not truncated.
233            // Remove http schemas, and any single trailing / to make the display URL.
234            $display_url = preg_replace(['!^https?://!', '!^([^/]+)/$!'], ['', '$1'], $url);
235            return sprintf('<a href="%s">%s</a>', oTxt($absolute_url), $display_url);
236        } else {
237            // Truncated URL.
238            // Remove http schemas, and any single trailing / to make the display URL.
239            $display_url = preg_replace(['!^https?://!', '!^([^/]+)/$!'], ['', '$1'], trim($truncated_url));
240            return sprintf('<a href="%s">%s%s</a>', oTxt($absolute_url), $display_url, $delim);
241        }
242    }, $text);
243}
244
245/**
246 * Turns "a really long string" into "a rea...string"
247 *
248 * @access  public
249 * @param   string  $str    Input string
250 * @param   int     $len    Maximum string length.
251 * @param   string  $where  Where to cut the string. One of: 'start', 'middle', or 'end'.
252 * @return  string          Truncated output string
253 * @author  Quinn Comendant <quinn@strangecode.com>
254 * @since   29 Mar 2006 13:48:49
255 */
256function truncate($str, $len=50, $where='end', $delim='
')
257{
258    $dlen = mb_strlen($delim);
259    if ($len <= $dlen || mb_strlen($str) <= $dlen) {
260        return substr($str, 0, $len);
261    }
262    $part1 = floor(($len - $dlen) / 2);
263    $part2 = ceil(($len - $dlen) / 2);
264
265    if ($len > ini_get('pcre.backtrack_limit')) {
266        logMsg(sprintf('Asked to truncate string len of %s > pcre.backtrack_limit of %s', $len, ini_get('pcre.backtrack_limit')), LOG_DEBUG, __FILE__, __LINE__);
267        ini_set('pcre.backtrack_limit', $len);
268    }
269
270    switch ($where) {
271    case 'start' :
272        return preg_replace(array(sprintf('/^.{%s,}(.{%s})$/su', $dlen + 1, $part1 + $part2), sprintf('/\s*%s{%s,}\s*/su', preg_quote($delim), $dlen)), array($delim . '$1', $delim), $str);
273
274    case 'middle' :
275        return preg_replace(array(sprintf('/^(.{%s}).{%s,}(.{%s})$/su', $part1, $dlen + 1, $part2), sprintf('/\s*%s{%s,}\s*/su', preg_quote($delim), $dlen)), array('$1' . $delim . '$2', $delim), $str);
276
277    case 'end' :
278    default :
279        return preg_replace(array(sprintf('/^(.{%s}).{%s,}$/su', $part1 + $part2, $dlen + 1), sprintf('/\s*%s{%s,}\s*/su', preg_quote($delim), $dlen)), array('$1' . $delim, $delim), $str);
280    }
281}
282
283/**
284 * Generates a hexadecimal html color based on provided word.
285 *
286 * @access public
287 *
288 * @param  string $text  A string for which to convert to color.
289 *
290 * @return string  A hexadecimal html color.
291 */
292function getTextColor($text, $method=1)
293{
294    $hash = md5($text);
295    $rgb = array(
296        substr($hash, 0, 1),
297        substr($hash, 1, 1),
298        substr($hash, 2, 1),
299        substr($hash, 3, 1),
300        substr($hash, 4, 1),
301        substr($hash, 5, 1),
302    );
303
304    switch ($method) {
305    case 1 :
306    default :
307        // Reduce all hex values slighly to avoid all white.
308        array_walk($rgb, create_function('&$v', '$v = dechex(round(hexdec($v) * 0.87));'));
309        break;
310    case 2 :
311        foreach ($rgb as $i => $v) {
312            if (hexdec($v) > hexdec('c')) {
313                $rgb[$i] = dechex(hexdec('f') - hexdec($v));
314            }
315        }
316        break;
317    }
318
319    return join('', $rgb);
320}
321
322/**
323 * Encodes a string into unicode values 128-255.
324 * Useful for hiding an email address from spambots.
325 *
326 * @access  public
327 *
328 * @param   string   $text   A line of text to encode.
329 *
330 * @return  string   Encoded text.
331 */
332function encodeAscii($text)
333{
334    $ouput = '';
335    $num = strlen($text);
336    for ($i=0; $i<$num; $i++) {
337        $output .= sprintf('&#%03s', ord($text{$i}));
338    }
339    return $output;
340}
341
342/**
343 * Encodes an email into a user (at) domain (dot) com format.
344 *
345 * @access  public
346 * @param   string   $email   An email to encode.
347 * @param   string   $at      Replaces the @.
348 * @param   string   $dot     Replaces the ..
349 * @return  string   Encoded email.
350 */
351function encodeEmail($email, $at=' at ', $dot=' dot ')
352{
353    $search = array('/@/', '/\./');
354    $replace = array($at, $dot);
355    return preg_replace($search, $replace, $email);
356}
357
358/**
359 * Return a human readable filesize.
360 *
361 * @param       int    $size        Size
362 * @param       int    $unit        The maximum unit
363 * @param       int    $format      The return string format
364 * @author      Aidan Lister <aidan@php.net>
365 * @version     1.1.0
366 */
367function humanFileSize($size, $unit=null, $format='%01.2f %s')
368{
369    // Units
370    $units = array('B', 'KB', 'MB', 'GB', 'TB');
371    $ii = count($units) - 1;
372
373    // Max unit
374    $unit = array_search((string) $unit, $units);
375    if ($unit === null || $unit === false) {
376        $unit = $ii;
377    }
378
379    // Loop
380    $i = 0;
381    while ($unit != $i && $size >= 1024 && $i < $ii) {
382        $size /= 1024;
383        $i++;
384    }
385
386    return sprintf($format, $size, $units[$i]);
387}
388
389/**
390 * If $var is net set or null, set it to $default. Otherwise leave it alone.
391 * Returns the final value of $var. Use to find a default value of one is not avilable.
392 *
393 * @param  mixed $var       The variable that is being set.
394 * @param  mixed $default   What to set it to if $val is not currently set.
395 * @return mixed            The resulting value of $var.
396 */
397function setDefault(&$var, $default='')
398{
399    if (!isset($var)) {
400        $var = $default;
401    }
402    return $var;
403}
404
405/**
406 * Like preg_quote() except for arrays, it takes an array of strings and puts
407 * a backslash in front of every character that is part of the regular
408 * expression syntax.
409 *
410 * @param  array $array    input array
411 * @param  array $delim    optional character that will also be excaped.
412 *
413 * @return array    an array with the same values as $array1 but shuffled
414 */
415function pregQuoteArray($array, $delim='/')
416{
417    if (!empty($array)) {
418        if (is_array($array)) {
419            foreach ($array as $key=>$val) {
420                $quoted_array[$key] = preg_quote($val, $delim);
421            }
422            return $quoted_array;
423        } else {
424            return preg_quote($array, $delim);
425        }
426    }
427}
428
429/**
430 * Converts a PHP Array into encoded URL arguments and return them as an array.
431 *
432 * @param  mixed $data        An array to transverse recursively, or a string
433 *                            to use directly to create url arguments.
434 * @param  string $prefix     The name of the first dimension of the array.
435 *                            If not specified, the first keys of the array will be used.
436 *
437 * @return array              URL with array elements as URL key=value arguments.
438 */
439function urlEncodeArray($data, $prefix='', $_return=true) {
440
441    // Data is stored in static variable.
442    static $args;
443
444    if (is_array($data)) {
445        foreach ($data as $key => $val) {
446            // If the prefix is empty, use the $key as the name of the first dimension of the "array".
447            // ...otherwise, append the key as a new dimension of the "array".
448            $new_prefix = ('' == $prefix) ? urlencode($key) : $prefix . '[' . urlencode($key) . ']';
449            // Enter recursion.
450            urlEncodeArray($val, $new_prefix, false);
451        }
452    } else {
453        // We've come to the last dimension of the array, save the "array" and it's value.
454        $args[$prefix] = urlencode($data);
455    }
456
457    if ($_return) {
458        // This is not a recursive execution. All recursion is complete.
459        // Reset static var and return the result.
460        $ret = $args;
461        $args = array();
462        return is_array($ret) ? $ret : array();
463    }
464}
465
466/**
467 * Converts a PHP Array into encoded URL arguments and return them in a string.
468 *
469 * @param  mixed $data        An array to transverse recursively, or a string
470 *                            to use directly to create url arguments.
471 * @param  string $prefix     The name of the first dimension of the array.
472 *                            If not specified, the first keys of the array will be used.
473 *
474 * @return string url         A string ready to append to a url.
475 */
476function urlEncodeArrayToString($data, $prefix='') {
477
478    $array_args = urlEncodeArray($data, $prefix);
479    $url_args = '';
480    $delim = '';
481    foreach ($array_args as $key=>$val) {
482        $url_args .= $delim . $key . '=' . $val;
483        $delim = ini_get('arg_separator.output');
484    }
485    return $url_args;
486}
487
488/**
489 * An alternative to "shuffle()" that actually works.
490 *
491 * @param  array $array1   input array
492 * @param  array $array2   argument used internally through recursion
493 *
494 * @return array    an array with the same values as $array1 but shuffled
495 */
496function arrayRand(&$array1, $array2 = array())
497{
498    if (!sizeof($array1)) {
499        return array();
500    }
501
502    srand((double) microtime() * 10000000);
503    $rand = array_rand($array1);
504
505    $array2[] = $array1[$rand];
506    unset ($array1[$rand]);
507
508    return $array2 + arrayRand($array1, $array2);
509}
510
511/**
512 * Fills an arrray with the result from a multiple ereg search.
513 * Curtesy of Bruno - rbronosky@mac.com - 10-May-2001
514 * Blame him for the funky do...while loop.
515 *
516 * @param  mixed $pattern   regular expression needle
517 * @param  mixed $string   haystack
518 *
519 * @return array    populated with each found result
520 */
521function eregAll($pattern, $string)
522{
523    do {
524        if (!ereg($pattern, $string, $temp)) {
525             continue;
526        }
527        $string = str_replace($temp[0], '', $string);
528        $results[] = $temp;
529    } while (ereg($pattern, $string, $temp));
530    return $results;
531}
532
533/**
534 * Prints the word "checked" if a variable is set, and optionally matches
535 * the desired value, otherwise prints nothing,
536 * used for printing the word "checked" in a checkbox form input.
537 *
538 * @param  mixed $var     the variable to compare
539 * @param  mixed $value   optional, what to compare with if a specific value is required.
540 */
541function frmChecked($var, $value=null)
542{
543    if (func_num_args() == 1 && $var) {
544        // 'Checked' if var is true.
545        echo ' checked="checked" ';
546    } else if (func_num_args() == 2 && $var == $value) {
547        // 'Checked' if var and value match.
548        echo ' checked="checked" ';
549    } else if (func_num_args() == 2 && is_array($var)) {
550        // 'Checked' if the value is in the key or the value of an array.
551        if (isset($var[$value])) {
552            echo ' checked="checked" ';
553        } else if (in_array($value, $var)) {
554            echo ' checked="checked" ';
555        }
556    }
557}
558
559/**
560 * prints the word "selected" if a variable is set, and optionally matches
561 * the desired value, otherwise prints nothing,
562 * otherwise prints nothing, used for printing the word "checked" in a
563 * select form input
564 *
565 * @param  mixed $var     the variable to compare
566 * @param  mixed $value   optional, what to compare with if a specific value is required.
567 */
568function frmSelected($var, $value=null)
569{
570    if (func_num_args() == 1 && $var) {
571        // 'selected' if var is true.
572        echo ' selected="selected" ';
573    } else if (func_num_args() == 2 && $var == $value) {
574        // 'selected' if var and value match.
575        echo ' selected="selected" ';
576    } else if (func_num_args() == 2 && is_array($var)) {
577        // 'selected' if the value is in the key or the value of an array.
578        if (isset($var[$value])) {
579            echo ' selected="selected" ';
580        } else if (in_array($value, $var)) {
581            echo ' selected="selected" ';
582        }
583    }
584}
585
586/**
587 * Adds slashes to values of an array and converts the array to a
588 * comma delimited list. If value provided is not an array or is empty
589 * return nothing. This is useful for putting values coming in from
590 * posted checkboxes into a SET column of a database.
591 *
592 * @param  array $array   Array to convert.
593 * @return string         Comma list of array values.
594 */
595function dbArrayToList($array)
596{
597    if (is_array($array) && !empty($array)) {
598        return join(',', array_map('mysql_real_escape_string', array_keys($array)));
599    }
600}
601
602/**
603 * Converts a human string date into a SQL-safe date.
604 * Dates nearing infinity use the date 2038-01-01 so conversion to unix time
605 * format remain within valid range.
606 *
607 * @param  array $date     String date to convert.
608 * @param  array $format   Date format to pass to date().
609 *                         Default produces MySQL datetime: 0000-00-00 00:00:00.
610 *
611 * @return string          SQL-safe date.
612 */
613function strToSQLDate($date, $format='Y-m-d H:i:s')
614{
615    // Translate the human string date into SQL-safe date format.
616    if (empty($date) || '0000-00-00' == $date || strtotime($date) === -1) {
617        $sql_date = '0000-00-00';
618    } else {
619        $sql_date = date($format, strtotime($date));
620    }
621
622    return $sql_date;
623}
624
625/**
626 * If magic_quotes_gpc is in use, run stripslashes() on $var. If $var is an
627 * array, stripslashes is run on each value, recursively, and the stripped
628 * array is returned
629 *
630 * @param  mixed $var   The string or array to un-quote, if necessary.
631 * @return mixed        $var, minus any magic quotes.
632 */
633function dispelMagicQuotes($var)
634{
635    static $magic_quotes_gpc;
636
637    if (!isset($magic_quotes_gpc)) {
638        $magic_quotes_gpc = get_magic_quotes_gpc();
639    }
640
641    if ($magic_quotes_gpc) {
642        if (!is_array($var)) {
643            $var = stripslashes($var);
644        } else {
645            foreach ($var as $key=>$val) {
646                if (is_array($val)) {
647                    $var[$key] = dispelMagicQuotes($val);
648                } else {
649                    $var[$key] = stripslashes($val);
650                }
651            }
652        }
653    }
654    return $var;
655}
656
657/**
658 * Get a form variable from GET or POST data, stripped of magic
659 * quotes if necessary.
660 *
661 * @param string $var (optional) The name of the form variable to look for.
662 * @param string $default (optional) The value to return if the
663 *                                   variable is not there.
664 *
665 * @return mixed      A cleaned GET or POST if no $var specified.
666 * @return string     A cleaned form $var if found, or $default.
667 */
668function getFormData($var=null, $default=null)
669{
670    if ('POST' == $_SERVER['REQUEST_METHOD'] && is_null($var)) {
671        return dispelMagicQuotes($_POST);
672    } else if ('GET' == $_SERVER['REQUEST_METHOD'] && is_null($var)) {
673        return dispelMagicQuotes($_GET);
674    }
675    if (isset($_POST[$var])) {
676        return dispelMagicQuotes($_POST[$var]);
677    } else if (isset($_GET[$var])) {
678        return dispelMagicQuotes($_GET[$var]);
679    } else {
680        return $default;
681    }
682}
683function getPost($var=null, $default=null)
684{
685    if (is_null($var)) {
686        return dispelMagicQuotes($_POST);
687    }
688    if (isset($_POST[$var])) {
689        return dispelMagicQuotes($_POST[$var]);
690    } else {
691        return $default;
692    }
693}
694function getGet($var=null, $default=null)
695{
696    if (is_null($var)) {
697        return dispelMagicQuotes($_GET);
698    }
699    if (isset($_GET[$var])) {
700        return dispelMagicQuotes($_GET[$var]);
701    } else {
702        return $default;
703    }
704}
705
706/**
707 * Signs a value using md5 and a simple text key. In order for this
708 * function to be useful (i.e. secure) the key must be kept secret, which
709 * means keeping it as safe as database credentials. Putting it into an
710 * environment variable set in httpd.conf is a good place.
711 *
712 * @access  public
713 *
714 * @param   string  $val    The string to sign.
715 * @param   string  $key    (Optional) A text key to use for computing the signature.
716 *
717 * @return  string  The original value with a signature appended.
718 */
719function addSignature($val, $key=null)
720{
721    global $CFG;
722
723    if ('' == $val) {
724        logMsg(sprintf('Adding signature to empty string.', null), LOG_NOTICE, __FILE__, __LINE__);
725    }
726
727    if (!isset($key)) {
728        $key = $CFG->signing_key;
729    }
730
731    return $val . '-' . substr(md5($val . $key), 0, 18);
732}
733
734/**
735 * Strips off the signature appended by addSignature().
736 *
737 * @access  public
738 *
739 * @param   string  $signed_val     The string to sign.
740 *
741 * @return  string  The original value with a signature removed.
742 */
743function removeSignature($signed_val)
744{
745    return substr($signed_val, 0, strrpos($signed_val, '-'));
746}
747
748
749/**
750 * Verifies a signature appened to a value by addSignature().
751 *
752 * @access  public
753 *
754 * @param   string  $signed_val A value with appended signature.
755 * @param   string  $key        (Optional) A text key to use for computing the signature.
756 *
757 * @return  bool    True if the signature matches the var.
758 */
759function verifySignature($signed_val, $key=null)
760{
761    // Strip the value from the signed value.
762    $val = substr($signed_val, 0, strrpos($signed_val, '-'));
763    // If the signed value matches the original signed value we consider the value safe.
764    if ($signed_val == addSignature($val, $key)) {
765        // Signature verified.
766        return true;
767    } else {
768        return false;
769    }
770}
771
772/**
773 * Stub functions used when installation does not have
774 * GNU gettext extension installed
775 */
776if (!extension_loaded('gettext')) {
777    /**
778    * Translates text
779    *
780    * @access public
781    * @param string $text the text to be translated
782    * @return string translated text
783    */
784    function gettext($text) {
785        return $text;
786    }
787
788    /**
789    * Translates text
790    *
791    * @access public
792    * @param string $text the text to be translated
793    * @return string translated text
794    */
795    function _($text) {
796        return $text;
797    }
798
799    /**
800    * Translates text by domain
801    *
802    * @access public
803    * @param string $domain the language to translate the text into
804    * @param string $text the text to be translated
805    * @return string translated text
806    */
807    function dgettext($domain, $text) {
808        return $text;
809    }
810
811    /**
812    * Translates text by domain and category
813    *
814    * @access public
815    * @param string $domain the language to translate the text into
816    * @param string $text the text to be translated
817    * @param string $category the language dialect to use
818    * @return string translated text
819    */
820    function dcgettext($domain, $text, $category) {
821        return $text;
822    }
823
824    /**
825    * Binds the text domain
826    *
827    * @access public
828    * @param string $domain the language to translate the text into
829    * @param string
830    * @return string translated text
831    */
832    function bindtextdomain($domain, $directory) {
833        return $domain;
834    }
835
836    /**
837    * Sets the text domain
838    *
839    * @access public
840    * @param string $domain the language to translate the text into
841    * @return string translated text
842    */
843    function textdomain($domain) {
844        return $domain;
845    }
846}
847
848/**
849 * Sends empty output to the browser and flushes the php buffer so the client
850 * will see data before the page is finished processing.
851 */
852function flushBuffer() {
853    echo str_repeat('          ', 205);
854    flush();
855}
856
857/**
858 * Adds email address to mailman mailing list. Requires /etc/sudoers entry for apache to sudo execute add_members.
859 * Don't forget to allow php_admin_value open_basedir access to "/var/mailman/bin".
860 *
861 * @access  public
862 *
863 * @param   string  $email     Email address to add.
864 * @param   string  $list      Name of list to add to.
865 * @param   bool    $send_welcome_message   True to send welcome message to subscriber.
866 *
867 * @return  bool    True on success, false on failure.
868 */
869function mailmanAddMember($email, $list, $send_welcome_message=false)
870{
871   $add_members = '/usr/lib/mailman/bin/add_members';
872    if (true || is_executable($add_members) && is_readable($add_members)) {
873        $welcome_msg = $send_welcome_message ? 'y' : 'n';
874        exec(sprintf('/bin/echo %s | /usr/bin/sudo %s -r - --welcome-msg=%s --admin-notify=n %s', escapeshellarg($email), escapeshellarg($add_members), $welcome_msg, escapeshellarg($list)), $stdout, $return_code);
875        $stdout = is_array($stdout) ? getDump($stdout) : $stdout;
876        if (0 == $return_code) {
877            logMsg(sprintf('Mailman add member success for list: %s, user: %s', $list, $email, $stdout), LOG_INFO, __FILE__, __LINE__);
878            return true;
879        } else {
880            logMsg(sprintf('Mailman add member failed for list: %s, user: %s, with message: %s', $list, $email, $stdout), LOG_WARNING, __FILE__, __LINE__);
881            return false;
882        }
883    } else {
884        logMsg(sprintf('Mailman add member program not executable: %s', $add_members), LOG_ALERT, __FILE__, __LINE__);
885        return false;
886    }
887}
888
889/**
890 * Removes email address from mailman mailing list. Requires /etc/sudoers entry for apache to sudo execute add_members.
891 * Don't forget to allow php_admin_value open_basedir access to "/var/mailman/bin".
892 *
893 * @access  public
894 *
895 * @param   string  $email     Email address to add.
896 * @param   string  $list      Name of list to add to.
897 * @param   bool    $send_user_ack   True to send goodbye message to subscriber.
898 *
899 * @return  bool    True on success, false on failure.
900 */
901function mailmanRemoveMember($email, $list, $send_user_ack=false)
902{
903    $remove_members = '/usr/lib/mailman/bin/remove_members';
904    if (true || is_executable($remove_members) && is_readable($remove_members)) {
905        $userack = $send_user_ack ? '' : '--nouserack';
906        exec(sprintf('/usr/bin/sudo %s %s --noadminack %s %s', escapeshellarg($remove_members), $userack, escapeshellarg($list), escapeshellarg($email)), $stdout, $return_code);
907        $stdout = is_array($stdout) ? getDump($stdout) : $stdout;
908        if (0 == $return_code) {
909            logMsg(sprintf('Mailman remove member success for list: %s, user: %s', $list, $email, $stdout), LOG_INFO, __FILE__, __LINE__);
910            return true;
911        } else {
912            logMsg(sprintf('Mailman remove member failed for list: %s, user: %s, with message: %s', $list, $email, $stdout), LOG_WARNING, __FILE__, __LINE__);
913            return false;
914        }
915    } else {
916        logMsg(sprintf('Mailman remove member program not executable: %s', $remove_members), LOG_ALERT, __FILE__, __LINE__);
917        return false;
918    }
919}
920
921
922
923?>
Note: See TracBrowser for help on using the repository browser.