3 * utils.php - Misc utils common to all aspects of the site
5 * Copyright 1999-2001 (c) VA Linux Systems
9 * This file is part of GForge.
11 * GForge is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * GForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with GForge; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US
28 * removeCRLF() - remove any Cariage Return-Line Feed from a string.
29 * That function is usefull to remove the possibility of a CRLF Injection when sending mail
30 * All the data that we will send should be passed through that function
32 * @param string The string that we want to empty from any CRLF
34 function util_remove_CRLF($str) {
35 return strtr($str, "\015\012", ' ');
40 * util_check_fileupload() - determines if a filename is appropriate for upload
42 * @param string The name of the file being uploaded
44 function util_check_fileupload($filename) {
46 /* Empty file is a valid file.
47 This is because this function should be called
48 unconditionally at the top of submit action processing
49 and many forms have optional file upload. */
50 if ($filename == 'none' || $filename == '') {
54 /* This should be enough... */
55 if (!is_uploaded_file($filename)) {
58 /* ... but we'd rather be paranoic */
59 if (strstr($filename, '..')) {
62 if (!is_file($filename)) {
65 if (!file_exists($filename)) {
68 if ((dirname($filename) != '/tmp') &&
69 (dirname($filename) != "/var/tmp")) {
76 * util_send_message() - Send email
77 * This function should be used in place of the PHP mail() function
79 * @param string The email recipients address
80 * @param string The email subject
81 * @param string The body of the email message
82 * @param string The optional email sender address. Defaults to 'noreply@'
83 * @param string The addresses to blind-carbon-copy this message
84 * @param string The optional email sender name. Defaults to ''
87 function util_send_message($to,$subject,$body,$from='',$BCC='',$sendername='') {
89 global $sys_sendmail_path;
92 $to='noreply@'.$GLOBALS['sys_default_domain'];
95 $from='noreply@'.$GLOBALS['sys_default_domain'];
98 $charset = $Language->getText('conf','mail_charset');
100 "\nFrom: ".util_encode_mailaddr($from,$sendername,$charset).
102 "\nSubject: ".util_encode_mimeheader($subject, $charset).
103 "\nContent-type: text/plain; charset=$charset".
105 util_convert_body($body, $charset);
107 if (!$sys_sendmail_path){
108 $sys_sendmail_path="/usr/sbin/sendmail";
111 exec ("/bin/echo \"". util_prep_string_for_sendmail($body) .
112 "\" | ".$sys_sendmail_path." -f'$from' -t -i > /dev/null 2>&1 &");
116 * util_encode_mailaddr() - Encode email address to MIME format
118 * @param string The email address
119 * @param string The email's owner name
120 * @param string The converting charset
123 function util_encode_mailaddr($email,$name,$charset) {
124 if (function_exists('mb_convert_encoding') && trim($name) != "") {
125 $name = "=?".$charset."?B?".
126 base64_encode(mb_convert_encoding(
127 $name,$charset,"UTF-8")).
131 return $name." <".$email."> ";
135 * util_encode_mimeheader() - Encode mimeheader
137 * @param string The email subject
138 * @param string The converting charset (like ISO-2022-JP)
139 * @return string The MIME encoded subject
142 function util_encode_mimeheader($str,$charset) {
143 if (!function_exists('mb_convert_encoding')) {
147 return "=?".$charset."?B?".
148 base64_encode(mb_convert_encoding(
149 $str,$charset,"UTF-8")).
154 * util_convert_body() - Convert body of the email message
156 * @param string The body of the email message
157 * @param string The charset of the email message
158 * @return string The converted body of the email message
161 function util_convert_body($str,$charset) {
162 if (!function_exists('mb_convert_encoding')) {
166 return mb_convert_encoding($str,$charset,"UTF-8");
169 function util_send_jabber($to,$subject,$body) {
170 if (!$GLOBALS['sys_use_jabber']) {
173 $JABBER = new Jabber();
174 if (!$JABBER->Connect()) {
175 echo '<br />Unable to connect';
178 //$JABBER->SendAuth();
179 //$JABBER->AccountRegistration();
180 if (!$JABBER->SendAuth()) {
181 echo '<br />Auth Failure';
182 $JABBER->Disconnect();
184 //or die("Couldn't authenticate!");
186 $JABBER->SendPresence(NULL, NULL, "online");
188 $body=htmlspecialchars($body);
189 $to_arr=explode(',',$to);
190 for ($i=0; $i<count($to_arr); $i++) {
192 //echo '<br />Sending Jabbers To: '.$to_arr[$i];
193 if (!$JABBER->SendMessage($to_arr[$i], "normal", NULL, array("body" => $body,"subject"=>$subject))) {
194 echo '<br />Error Sending to '.$to_arr[$i];
199 $JABBER->CruiseControl(2);
200 $JABBER->Disconnect();
204 * util_prep_string_for_sendmail() - Prepares a string to be sent by email
206 * @param string The text to be prepared
207 * @returns The prepared text
210 function util_prep_string_for_sendmail($body) {
211 //$body=str_replace("\\","\\\\",$body);
212 $body=str_replace("`","\\`",$body);
213 $body=str_replace("\"","\\\"",$body);
214 $body=str_replace("\$","\\\$",$body);
219 * util_handle_message() - a convenience wrapper which sends messages
220 * to either a jabber account or email account or both, depending on
223 * @param array array of user_id's from the user table
224 * @param string subject of the message
225 * @param string the message body
226 * @param string a comma-separated list of email address
227 * @param string a comma-separated list of jabber address
229 function util_handle_message($id_arr,$subject,$body,$extra_emails='',$extra_jabbers='') {
232 if (count($id_arr) < 1) {
235 $res=db_query("SELECT user_id, jabber_address,email,jabber_only
236 FROM users WHERE user_id IN (". implode($id_arr,',') .")");
237 $rows=db_numrows($res);
239 for ($i=0; $i<$rows; $i++) {
240 if (db_result($res, $i, 'user_id') == 100) {
241 // Do not send messages to "Nobody"
245 // Build arrays of the jabber address
247 if (db_result($res,$i,'jabber_address')) {
248 $address['jabber_address'][]=db_result($res,$i,'jabber_address');
249 if (db_result($res,$i,'jabber_only') != 1) {
250 $address['email'][]=db_result($res,$i,'email');
253 $address['email'][]=db_result($res,$i,'email');
256 if (count($address['email']) > 0) {
257 $extra_email1=implode($address['email'],',').',';
259 if (count($address['jabber_address']) > 0) {
260 $extra_jabber1=implode($address['jabber_address'],',').',';
263 if ($extra_email1 || $extra_emails) {
264 util_send_message('',$subject,$body,'',$extra_email1.$extra_emails);
266 if ($extra_jabber1 || $extra_jabbers) {
267 util_send_jabber($extra_jabber1.$extra_jabbers,$subject,$body);
272 * util_unconvert_htmlspecialchars() - Unconverts a string converted with htmlspecialchars()
273 * This function requires PHP 4.0.3 or greater
275 * @param string The string to unconvert
276 * @returns The unconverted string
279 function util_unconvert_htmlspecialchars($string) {
280 if (strlen($string) < 1) {
283 //$trans = get_html_translation_table(HTMLENTITIES, ENT_QUOTES);
284 $trans = get_html_translation_table(HTML_ENTITIES);
285 $trans = array_flip ($trans);
286 $str = strtr ($string, $trans);
292 * util_result_columns_to_assoc() - Takes a result set and turns the column pair into an associative array
294 * @param string The result set ID
295 * @param int The column key
296 * @param int The optional column value
297 * @returns An associative array
300 function util_result_columns_to_assoc($result, $col_key=0, $col_val=1) {
301 $rows=db_numrows($result);
305 for ($i=0; $i<$rows; $i++) {
306 $arr[db_result($result,$i,$col_key)]=db_result($result,$i,$col_val);
315 * util_result_column_to_array() - Takes a result set and turns the optional column into an array
317 * @param int The result set ID
318 * @param int The column
322 function &util_result_column_to_array($result, $col=0) {
324 Takes a result set and turns the optional column into
327 $rows=db_numrows($result);
331 for ($i=0; $i<$rows; $i++) {
332 $arr[$i]=db_result($result,$i,$col);
341 * util_wrap_find_space() - Find the first space in a string
343 * @param string The string in which to find the space (must be UTF8!)
344 * @param int The number of characters to wrap - Default is 80
345 * @returns The position of the first space
348 function util_wrap_find_space($string,$wrap) {
355 //find the first space starting at $start
356 $pos=@strpos($string,' ',$start);
358 //if that space is too far over, go back and start more to the left
359 if (($pos > ($wrap+5)) || !$pos) {
361 $start=($wrap-($try*5));
362 //if we've gotten so far left , just truncate the line
365 $code = ord(substr($string,$wrap,1));
368 //Here is single byte character
369 //or head of multi byte character
372 //Do not break multi byte character
387 * util_line_wrap() - Automatically linewrap text
389 * @param string The text to wrap
390 * @param int The number of characters to wrap - Default is 80
391 * @param string The line break to use - Default is '\n'
392 * @returns The wrapped text
395 function util_line_wrap ($text, $wrap = 80, $break = "\n") {
396 $paras = explode("\n", $text);
400 while ($i < count($paras)) {
401 if (strlen($paras[$i]) <= $wrap) {
402 $result[] = $paras[$i];
405 $pos=util_wrap_find_space($paras[$i],$wrap);
407 $result[] = substr($paras[$i], 0, $pos);
409 $new = trim(substr($paras[$i], $pos, strlen($paras[$i]) - $pos));
412 $pos=util_wrap_find_space($paras[$i],$wrap);
418 return implode($break, $result);
422 * util_make_links() - Turn URL's into HREF's.
424 * @param string The URL
425 * @returns The HREF'ed URL
428 function util_make_links ($data='') {
429 if(empty($data)) { return $data; }
431 $lines = split("\n",$data);
432 while ( list ($key,$line) = each ($lines)) {
433 // When we come here, we usually have form input
434 // encoded in entities. Our aim is to NOT include
435 // angle brackets in the URL
436 // (RFC2396; http://www.w3.org/Addressing/URL/5.1_Wrappers.html)
437 $line = str_replace('>', "\1", $line);
438 $line = eregi_replace("([ \t]|^)www\."," http://www.",$line);
439 $text = eregi_replace("([[:alnum:]]+)://([^[:space:]<\1]*)([[:alnum:]#?/&=])", "<a href=\"\\1://\\2\\3\" target=\"_new\">\\1://\\2\\3</a>", $line);
440 $text = eregi_replace("([[:space:]]|^)(([a-z0-9_]|\\-|\\.)+@([^[:space:]]*)([[:alnum:]-]))", "\\1<a href=\"mailto:\\2\" target=\"_new\">\\2</a>", $text);
441 $text = str_replace("\1", '>', $text);
448 * show_priority_colors_key() - Show the priority colors legend
451 function show_priority_colors_key() {
453 echo '<p /><strong> '.$Language->getText('common_utils','priority_colors').':</strong><br />
455 <table border="0"><tr>';
457 for ($i=1; $i<10; $i++) {
459 <td bgcolor="'.html_get_priority_color($i).'">'.$i.'</td>';
461 echo '</tr></table>';
465 * utils_buildcheckboxarray() - Build a checkbox array
467 * @param int Number of options to be in the array
468 * @param string The name of the checkboxes
469 * @param array An array of boxes to be pre-checked
472 function utils_buildcheckboxarray($options,$name,$checked_array) {
473 $option_count=count($options);
474 $checked_count=count($checked_array);
476 for ($i=1; $i<=$option_count; $i++) {
478 <br /><input type="checkbox" name="'.$name.'" value="'.$i.'"';
479 for ($j=0; $j<$checked_count; $j++) {
480 if ($i == $checked_array[$j]) {
484 echo '> '.$options[$i];
489 * utils_requiredField() - Adds the required field marker
491 * @return a string holding the HTML to mark a required field
493 function utils_requiredField() {
494 return '<span><font color="red">*</font></span>';
498 * GraphResult() - Takes a database result set and builds a graph.
499 * The first column should be the name, and the second column should be the values
500 * Be sure to include HTL_Graphs.php before using this function
502 * @author Tim Perdue tperdue@valinux.com
503 * @param int The databse result set ID
504 * @param string The title of the graph
507 Function GraphResult($result,$title) {
508 $rows=db_numrows($result);
510 if ((!$result) || ($rows < 1)) {
516 for ($j=0; $j<db_numrows($result); $j++) {
517 if (db_result($result, $j, 0) != '' && db_result($result, $j, 1) != '' ) {
518 $names[$j]= db_result($result, $j, 0);
519 $values[$j]= db_result($result, $j, 1);
524 This is another function detailed below
526 GraphIt($names,$values,$title);
531 * GraphIt() - Build a graph
533 * @author Tim Perdue tperdue@valinux.com
534 * @param array An array of names
535 * @param array An array of values
536 * @param string The title of the graph
539 Function GraphIt($name_string,$value_string,$title) {
542 $counter=count($name_string);
545 Can choose any color you wish
549 for ($i = 0; $i < $counter; $i++) {
550 $bars[$i]=$HTML->COLOR_LTBACK1;
553 $counter=count($value_string);
556 Figure the max_value passed in, so scale can be determined
561 for ($i = 0; $i < $counter; $i++) {
562 if ($value_string[$i] > $max_value) {
563 $max_value=$value_string[$i];
567 if ($max_value < 1) {
572 I want my graphs all to be 800 pixels wide, so that is my divisor
575 $scale=(400/$max_value);
578 I create a wrapper table around the graph that holds the title
584 echo $GLOBALS['HTML']->listTableTop ($title_arr);
587 Create an associate array to pass in. I leave most of it blank
616 This is the actual call to the HTML_Graphs class
619 html_graph($name_string,$value_string,$bars,$vals);
623 <!-- end outer graph table -->';
624 echo $GLOBALS['HTML']->listTableBottom();
628 * ShowResultSet() - Show a generic result set
629 * Very simple, plain way to show a generic result set
631 * @param int The result set ID
632 * @param string The title of the result set
633 * @param bool The option to turn URL's into links
634 * @param bool The option to display headers
635 * @param array The db field name -> label mapping
636 * @param array Don't display these cols
639 function ShowResultSet($result,$title='',$linkify=false,$displayHeaders=true,$headerMapping=array(), $excludedCols=array()) {
640 global $group_id,$HTML;
643 $rows = db_numrows($result);
644 $cols = db_numfields($result);
646 echo '<table border="0" width="100%">';
648 /* Create the headers */
649 $headersCellData = array();
650 $colsToKeep = array();
651 for ($i=0; $i < $cols; $i++) {
652 $fieldName = db_fieldname($result, $i);
653 if(in_array($fieldName, $excludedCols)) {
657 if(isset($headerMapping[$fieldName])) {
658 $headersCellData[] = array($headerMapping[$fieldName]);
661 $headersCellData[] = array($fieldName);
665 /* Create the title */
666 if(strlen($title) > 0) {
667 $titleCellData = array();
668 $titleCellData[] = array($title, 'colspan="'.count($headersCellData).'"');
669 echo $HTML->multiTableRow('', $titleCellData, TRUE);
672 /* Display the headers */
673 echo $HTML->multiTableRow('', $headersCellData, TRUE);
675 /* Create the rows */
676 for ($j = 0; $j < $rows; $j++) {
677 echo '<tr '. $HTML->boxGetAltRowStyle($j) . '>';
678 for ($i = 0; $i < $cols; $i++) {
679 if(in_array($i, $colsToKeep)) {
680 if ($linkify && $i == 0) {
681 $link = '<a href="'.$PHP_SELF.'?';
683 if ($linkify == "bug_cat") {
684 $link .= 'group_id='.$group_id.'&bug_cat_mod=y&bug_cat_id='.db_result($result, $j, 'bug_category_id').'">';
685 } else if($linkify == "bug_group") {
686 $link .= 'group_id='.$group_id.'&bug_group_mod=y&bug_group_id='.db_result($result, $j, 'bug_group_id').'">';
687 } else if($linkify == "patch_cat") {
688 $link .= 'group_id='.$group_id.'&patch_cat_mod=y&patch_cat_id='.db_result($result, $j, 'patch_category_id').'">';
689 } else if($linkify == "support_cat") {
690 $link .= 'group_id='.$group_id.'&support_cat_mod=y&support_cat_id='.db_result($result, $j, 'support_category_id').'">';
691 } else if($linkify == "pm_project") {
692 $link .= 'group_id='.$group_id.'&project_cat_mod=y&project_cat_id='.db_result($result, $j, 'group_project_id').'">';
694 $link = $linkend = '';
697 $link = $linkend = '';
699 echo '<td>'.$link . db_result($result, $j, $i) . $linkend.'</td>';
711 * validate_email() - Validate an email address
713 * @param string The address string to validate
714 * @returns true on success/false on error
717 function validate_email ($address) {
718 return (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'. '@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $address));
722 * util_is_valid_filename() - Verifies whether a file has a valid filename
724 * @param string The file to verify
725 * @returns true on success/false on error
728 function util_is_valid_filename ($file) {
730 $invalidchars = eregi_replace("[-A-Z0-9_\.]","",$file);
732 if (!empty($invalidchars)) {
735 if (strstr($file,'..')) {
744 * valid_hostname() - Validates a hostname string to make sure it doesn't contain invalid characters
746 * @param string The optional hostname string
747 * @returns true on success/false on failur
750 function valid_hostname ($hostname = "xyz") {
753 $invalidchars = eregi_replace("[-A-Z0-9\.]","",$hostname);
755 if (!empty($invalidchars)) {
759 //double dot, starts with a . or -
760 if (ereg("\.\.",$hostname) || ereg("^\.",$hostname) || ereg("^\-",$hostname)) {
764 $multipoint = explode(".",$hostname);
766 if (!(is_array($multipoint)) || ((count($multipoint) - 1) < 1)) {