3 * FusionForge miscellaneous utils
5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2 of the License,
13 * or (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 * is_utf8($string) - utf-8 detection
29 * From http://www.php.net/manual/en/function.mb-detect-encoding.php#85294
31 function is_utf8($str) {
35 for($i=0; $i<$len; $i++){
38 if(($c >= 254)) return false;
39 elseif($c >= 252) $bits=6;
40 elseif($c >= 248) $bits=5;
41 elseif($c >= 240) $bits=4;
42 elseif($c >= 224) $bits=3;
43 elseif($c >= 192) $bits=2;
45 if(($i+$bits) > $len) return false;
49 if($b < 128 || $b > 191) return false;
58 * removeCRLF() - remove any Carriage Return-Line Feed from a string.
59 * That function is useful to remove the possibility of a CRLF Injection when sending mail
60 * All the data that we will send should be passed through that function
62 * @param string The string that we want to empty from any CRLF
64 function util_remove_CRLF($str) {
65 return strtr($str, "\015\012", ' ');
70 * util_check_fileupload() - determines if a filename is appropriate for upload
72 * @param array The uploaded file as returned by getUploadedFile()
74 function util_check_fileupload($filename) {
76 /* Empty file is a valid file.
77 This is because this function should be called
78 unconditionally at the top of submit action processing
79 and many forms have optional file upload. */
80 if ($filename == 'none' || $filename == '') {
84 /* This should be enough... */
85 if (!is_uploaded_file($filename)) {
88 /* ... but we'd rather be paranoic */
89 if (strstr($filename, '..')) {
92 if (!is_file($filename)) {
95 if (!file_exists($filename)) {
98 if ((dirname($filename) != '/tmp') &&
99 (dirname($filename) != "/var/tmp")) {
106 * util_check_url() - determines if given URL is valid.
108 * Currently, test is very basic, only the protocol is
109 * checked, allowed values are: http, https, ftp.
111 * @param string The URL
112 * @return boolean true if valid, false if not valid.
114 function util_check_url($url) {
115 return (preg_match('/^(http|https|ftp):\/\//', $url) > 0);
119 * util_send_message() - Send email
120 * This function should be used in place of the PHP mail() function
122 * @param string The email recipients address
123 * @param string The email subject
124 * @param string The body of the email message
125 * @param string The optional email sender address. Defaults to 'noreply@'
126 * @param string The addresses to blind-carbon-copy this message
127 * @param string The optional email sender name. Defaults to ''
128 * @param boolean Whether to send plain text or html email
131 function util_send_message($to,$subject,$body,$from='',$BCC='',$sendername='',$extra_headers='',$send_html_email=false) {
135 $to='noreply@'.forge_get_config('web_host');
138 $from='noreply@'.forge_get_config('web_host');
142 $charset = _('UTF-8');
148 if ($extra_headers) {
149 $body2 .= $extra_headers."\n";
152 "\nFrom: ".util_encode_mailaddr($from,$sendername,$charset);
153 if (forge_get_config('bcc_all_emails') != '') {
154 $BCC.=",".forge_get_config('bcc_all_emails');
157 $body2 .= "\nBCC: $BCC";
159 $send_html_email?$type="html":$type="plain";
160 $body2 .= "\n".util_encode_mimeheader("Subject", $subject, $charset).
161 "\nContent-type: text/$type; charset=$charset".
163 util_convert_body($body, $charset);
165 if (!forge_get_config('sendmail_path')){
166 $sys_sendmail_path="/usr/sbin/sendmail";
169 $handle = popen(forge_get_config('sendmail_path')." -f'$from' -t -i", 'w');
170 fwrite ($handle, $body2);
175 * util_encode_mailaddr() - Encode email address to MIME format
177 * @param string The email address
178 * @param string The email's owner name
179 * @param string The converting charset
182 function util_encode_mailaddr($email,$name,$charset) {
183 if (function_exists('mb_convert_encoding') && trim($name) != "") {
184 $name = "=?".$charset."?B?".
185 base64_encode(mb_convert_encoding(
186 $name,$charset,"UTF-8")).
190 return $name." <".$email."> ";
194 * util_encode_mimeheader() - Encode mimeheader
196 * @param string The name of the header (e.g. "Subject")
197 * @param string The email subject
198 * @param string The converting charset (like ISO-2022-JP)
199 * @return string The MIME encoded subject
202 function util_encode_mimeheader($headername,$str,$charset) {
203 if (function_exists('mb_internal_encoding') &&
204 function_exists('mb_encode_mimeheader')) {
205 $x = mb_internal_encoding();
206 mb_internal_encoding("UTF-8");
207 $y = mb_encode_mimeheader($headername . ": " . $str,
209 mb_internal_encoding($x);
213 if (!function_exists('mb_convert_encoding')) {
214 return $headername . ": " . $str;
217 return $headername . ": " . "=?".$charset."?B?".
218 base64_encode(mb_convert_encoding(
219 $str,$charset,"UTF-8")).
224 * util_convert_body() - Convert body of the email message
226 * @param string The body of the email message
227 * @param string The charset of the email message
228 * @return string The converted body of the email message
231 function util_convert_body($str,$charset) {
232 if (!function_exists('mb_convert_encoding') || $charset == 'UTF-8') {
236 return mb_convert_encoding($str,$charset,"UTF-8");
239 function util_send_jabber($to,$subject,$body) {
240 if (!forge_get_config('use_jabber')) {
243 $JABBER = new Jabber();
244 if (!$JABBER->Connect()) {
245 echo '<br />Unable to connect';
248 //$JABBER->SendAuth();
249 //$JABBER->AccountRegistration();
250 if (!$JABBER->SendAuth()) {
251 echo '<br />Auth Failure';
252 $JABBER->Disconnect();
254 //or die("Couldn't authenticate!");
256 $JABBER->SendPresence(NULL, NULL, "online");
258 $body=htmlspecialchars($body);
259 $to_arr=explode(',',$to);
260 for ($i=0; $i<count($to_arr); $i++) {
262 //echo '<br />Sending Jabbers To: '.$to_arr[$i];
263 if (!$JABBER->SendMessage($to_arr[$i], "normal", NULL, array("body" => $body,"subject"=>$subject))) {
264 echo '<br />Error Sending to '.$to_arr[$i];
269 $JABBER->CruiseControl(2);
270 $JABBER->Disconnect();
274 * util_prep_string_for_sendmail() - Prepares a string to be sent by email
276 * @param string The text to be prepared
277 * @returns The prepared text
280 function util_prep_string_for_sendmail($body) {
281 /*$body=str_replace("`","\\`",$body);
282 $body=str_replace("\"","\\\"",$body);
283 $body=str_replace("\$","\\\$",$body);*/
284 $body = escapeshellarg($body);
289 * util_handle_message() - a convenience wrapper which sends messages
290 * to either a jabber account or email account or both, depending on
293 * @param array array of user_id's from the user table
294 * @param string subject of the message
295 * @param string the message body
296 * @param string a comma-separated list of email address
297 * @param string a comma-separated list of jabber address
298 * @param string From header
300 function util_handle_message($id_arr,$subject,$body,$extra_emails='',$extra_jabbers='',$from='') {
303 if (count($id_arr) < 1) {
306 $res = db_query_params ('SELECT user_id,jabber_address,email,jabber_only FROM users WHERE user_id = ANY ($1)',
307 array (db_int_array_to_any_clause ($id_arr))) ;
308 $rows = db_numrows($res) ;
310 for ($i=0; $i<$rows; $i++) {
311 if (db_result($res, $i, 'user_id') == 100) {
312 // Do not send messages to "Nobody"
316 // Build arrays of the jabber address
318 if (db_result($res,$i,'jabber_address')) {
319 $address['jabber_address'][]=db_result($res,$i,'jabber_address');
320 if (db_result($res,$i,'jabber_only') != 1) {
321 $address['email'][]=db_result($res,$i,'email');
324 $address['email'][]=db_result($res,$i,'email');
327 if (isset ($address['email']) && count($address['email']) > 0) {
328 $extra_emails=implode($address['email'],',').',' . $extra_emails;
330 if (isset ($address['jabber_address']) && count($address['jabber_address']) > 0) {
331 $extra_jabbers=implode($address['jabber_address'],',').','.$extra_jabbers;
335 util_send_message('',$subject,$body,$from,$extra_emails);
337 if ($extra_jabbers) {
338 util_send_jabber($extra_jabbers,$subject,$body);
343 * util_unconvert_htmlspecialchars() - Unconverts a string converted with htmlspecialchars()
344 * This function requires PHP 4.0.3 or greater
346 * @param string The string to unconvert
347 * @returns The unconverted string
350 function util_unconvert_htmlspecialchars($string) {
351 if (strlen($string) < 1) {
354 //$trans = get_html_translation_table(HTMLENTITIES, ENT_QUOTES);
355 $trans = get_html_translation_table(HTML_ENTITIES);
356 $trans = array_flip ($trans);
357 $str = strtr ($string, $trans);
363 * util_result_columns_to_assoc() - Takes a result set and turns the column pair into an associative array
365 * @param string The result set ID
366 * @param int The column key
367 * @param int The optional column value
368 * @returns An associative array
371 function util_result_columns_to_assoc($result, $col_key=0, $col_val=1) {
372 $rows=db_numrows($result);
376 for ($i=0; $i<$rows; $i++) {
377 $arr[db_result($result,$i,$col_key)]=db_result($result,$i,$col_val);
386 * util_result_column_to_array() - Takes a result set and turns the optional column into an array
388 * @param int The result set ID
389 * @param int The column
393 function &util_result_column_to_array($result, $col=0) {
395 Takes a result set and turns the optional column into
398 $rows=db_numrows($result);
402 for ($i=0; $i<$rows; $i++) {
403 $arr[$i]=db_result($result,$i,$col);
412 * util_wrap_find_space() - Find the first space in a string
414 * @param string The string in which to find the space (must be UTF8!)
415 * @param int The number of characters to wrap - Default is 80
416 * @returns The position of the first space
419 function util_wrap_find_space($string,$wrap) {
426 //find the first space starting at $start
427 $pos=@strpos($string,' ',$start);
429 //if that space is too far over, go back and start more to the left
430 if (($pos > ($wrap+5)) || !$pos) {
432 $start=($wrap-($try*5));
433 //if we've gotten so far left , just truncate the line
436 $code = ord(substr($string,$wrap,1));
439 //Here is single byte character
440 //or head of multi byte character
443 //Do not break multi byte character
458 * util_line_wrap() - Automatically linewrap text
460 * @param string The text to wrap
461 * @param int The number of characters to wrap - Default is 80
462 * @param string The line break to use - Default is '\n'
463 * @returns The wrapped text
466 function util_line_wrap ($text, $wrap = 80, $break = "\n") {
467 $paras = explode("\n", $text);
471 while ($i < count($paras)) {
472 if (strlen($paras[$i]) <= $wrap) {
473 $result[] = $paras[$i];
476 $pos=util_wrap_find_space($paras[$i],$wrap);
478 $result[] = substr($paras[$i], 0, $pos);
480 $new = trim(substr($paras[$i], $pos, strlen($paras[$i]) - $pos));
483 $pos=util_wrap_find_space($paras[$i],$wrap);
489 return implode($break, $result);
493 * util_make_links() - Turn URL's into HREF's.
495 * @param string The URL
496 * @returns The HREF'ed URL
499 function util_make_links ($data='') {
503 $lines = split("\n",$data);
505 while ( list ($key,$line) = each ($lines)) {
506 // When we come here, we usually have form input
507 // encoded in entities. Our aim is to NOT include
508 // angle brackets in the URL
509 // (RFC2396; http://www.w3.org/Addressing/URL/5.1_Wrappers.html)
510 $line = str_replace('>', "\1", $line);
511 $line = eregi_replace("([ \t]|^)www\."," http://www.",$line);
512 $text = eregi_replace("([[:alnum:]]+)://([^[:space:]<\1]*)([[:alnum:]#?/&=])", "<a href=\"\\1://\\2\\3\" target=\"_new\">\\1://\\2\\3</a>", $line);
513 $text = eregi_replace("([[:space:]]|^)(([a-z0-9_]|\\-|\\.)+@([^[:space:]]*)([[:alnum:]-]))", "\\1<a href=\"mailto:\\2\" target=\"_new\">\\2</a>", $text);
514 $text = str_replace("\1", '>', $text);
521 * show_priority_colors_key() - Show the priority colors legend
524 function show_priority_colors_key() {
525 echo '<p /><strong> '._('Priority Colors').':</strong><br />
527 <table border="0"><tr>';
529 for ($i=1; $i<6; $i++) {
531 <td class="priority'.$i.'">'.$i.'</td>';
533 echo '</tr></table>';
537 * utils_buildcheckboxarray() - Build a checkbox array
539 * @param int Number of options to be in the array
540 * @param string The name of the checkboxes
541 * @param array An array of boxes to be pre-checked
544 function utils_buildcheckboxarray($options,$name,$checked_array) {
545 $option_count=count($options);
546 $checked_count=count($checked_array);
548 for ($i=1; $i<=$option_count; $i++) {
550 <br /><input type="checkbox" name="'.$name.'" value="'.$i.'"';
551 for ($j=0; $j<$checked_count; $j++) {
552 if ($i == $checked_array[$j]) {
556 echo '> '.$options[$i];
561 * utils_requiredField() - Adds the required field marker
563 * @return a string holding the HTML to mark a required field
565 function utils_requiredField() {
566 return '<span class="requiredfield">*</span>';
570 * GraphResult() - Takes a database result set and builds a graph.
571 * The first column should be the name, and the second column should be the values
572 * Be sure to include HTL_Graphs.php before using this function
574 * @author Tim Perdue tperdue@valinux.com
575 * @param int The databse result set ID
576 * @param string The title of the graph
579 Function GraphResult($result,$title) {
580 $rows=db_numrows($result);
582 if ((!$result) || ($rows < 1)) {
588 for ($j=0; $j<db_numrows($result); $j++) {
589 if (db_result($result, $j, 0) != '' && db_result($result, $j, 1) != '' ) {
590 $names[$j]= db_result($result, $j, 0);
591 $values[$j]= db_result($result, $j, 1);
596 This is another function detailed below
598 GraphIt($names,$values,$title);
603 * GraphIt() - Build a graph
605 * @author Tim Perdue tperdue@valinux.com
606 * @param array An array of names
607 * @param array An array of values
608 * @param string The title of the graph
611 Function GraphIt($name_string,$value_string,$title) {
614 $counter=count($name_string);
617 Can choose any color you wish
621 for ($i = 0; $i < $counter; $i++) {
622 $bars[$i]=$HTML->COLOR_LTBACK1;
625 $counter=count($value_string);
628 Figure the max_value passed in, so scale can be determined
633 for ($i = 0; $i < $counter; $i++) {
634 if ($value_string[$i] > $max_value) {
635 $max_value=$value_string[$i];
639 if ($max_value < 1) {
644 I want my graphs all to be 800 pixels wide, so that is my divisor
647 $scale=(400/$max_value);
650 I create a wrapper table around the graph that holds the title
656 echo $GLOBALS['HTML']->listTableTop ($title_arr);
659 Create an associate array to pass in. I leave most of it blank
688 This is the actual call to the HTML_Graphs class
691 html_graph($name_string,$value_string,$bars,$vals);
695 <!-- end outer graph table -->';
696 echo $GLOBALS['HTML']->listTableBottom();
700 * ShowResultSet() - Show a generic result set
701 * Very simple, plain way to show a generic result set
703 * @param int The result set ID
704 * @param string The title of the result set
705 * @param bool The option to turn URL's into links
706 * @param bool The option to display headers
707 * @param array The db field name -> label mapping
708 * @param array Don't display these cols
711 function ShowResultSet($result,$title='',$linkify=false,$displayHeaders=true,$headerMapping=array(), $excludedCols=array()) {
712 global $group_id,$HTML;
715 $rows = db_numrows($result);
716 $cols = db_numfields($result);
718 echo '<table border="0" width="100%">';
720 /* Create the headers */
721 $headersCellData = array();
722 $colsToKeep = array();
723 for ($i=0; $i < $cols; $i++) {
724 $fieldName = db_fieldname($result, $i);
725 if(in_array($fieldName, $excludedCols)) {
729 if(isset($headerMapping[$fieldName])) {
730 if(is_array($headerMapping[$fieldName])) {
731 $headersCellData[] = $headerMapping[$fieldName];
733 $headersCellData[] = array($headerMapping[$fieldName]);
737 $headersCellData[] = array($fieldName);
741 /* Create the title */
742 if(strlen($title) > 0) {
743 $titleCellData = array();
744 $titleCellData[] = array($title, 'colspan="'.count($headersCellData).'"');
745 echo $HTML->multiTableRow('', $titleCellData, TRUE);
748 /* Display the headers */
749 if($displayHeaders) {
750 echo $HTML->multiTableRow('', $headersCellData, TRUE);
753 /* Create the rows */
754 for ($j = 0; $j < $rows; $j++) {
755 echo '<tr '. $HTML->boxGetAltRowStyle($j) . '>';
756 for ($i = 0; $i < $cols; $i++) {
757 if(in_array($i, $colsToKeep)) {
758 if ($linkify && $i == 0) {
759 $link = '<a href="'.getStringFromServer('PHP_SELF').'?';
761 if ($linkify == "bug_cat") {
762 $link .= 'group_id='.$group_id.'&bug_cat_mod=y&bug_cat_id='.db_result($result, $j, 'bug_category_id').'">';
763 } else if($linkify == "bug_group") {
764 $link .= 'group_id='.$group_id.'&bug_group_mod=y&bug_group_id='.db_result($result, $j, 'bug_group_id').'">';
765 } else if($linkify == "patch_cat") {
766 $link .= 'group_id='.$group_id.'&patch_cat_mod=y&patch_cat_id='.db_result($result, $j, 'patch_category_id').'">';
767 } else if($linkify == "support_cat") {
768 $link .= 'group_id='.$group_id.'&support_cat_mod=y&support_cat_id='.db_result($result, $j, 'support_category_id').'">';
769 } else if($linkify == "pm_project") {
770 $link .= 'group_id='.$group_id.'&project_cat_mod=y&project_cat_id='.db_result($result, $j, 'group_project_id').'">';
772 $link = $linkend = '';
775 $link = $linkend = '';
777 echo '<td>'.$link . db_result($result, $j, $i) . $linkend.'</td>';
789 * validate_email() - Validate an email address
791 * @param string The address string to validate
792 * @returns true on success/false on error
795 function validate_email ($address) {
796 return (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'. '@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $address) !== false);
800 * validate_emails() - Validate a list of e-mail addresses
802 * @param string E-mail list
803 * @param char Separator
804 * @returns array Array of invalid e-mail addresses (if empty, all addresses are OK)
806 function validate_emails ($addresses, $separator=',') {
807 if (strlen($addresses) == 0) return array();
809 $emails = explode($separator, $addresses);
812 if (is_array($emails)) {
813 foreach ($emails as $email) {
814 $email = trim($email); // This is done so we can validate lists like "a@b.com, c@d.com"
815 if (!validate_email($email)) $ret[] = $email;
824 * util_is_valid_filename() - Verifies whether a file has a valid filename
826 * @param string The file to verify
827 * @returns true on success/false on error
830 function util_is_valid_filename ($file) {
832 $invalidchars = eregi_replace("[-A-Z0-9+_\. ~]","",$file);
834 if (!empty($invalidchars)) {
837 if (strstr($file,'..')) {
846 * valid_hostname() - Validates a hostname string to make sure it doesn't contain invalid characters
848 * @param string The optional hostname string
849 * @returns true on success/false on failur
852 function valid_hostname ($hostname = "xyz") {
855 $invalidchars = eregi_replace("[-A-Z0-9\.]","",$hostname);
857 if (!empty($invalidchars)) {
861 //double dot, starts with a . or -
862 if (ereg("\.\.",$hostname) || ereg("^\.",$hostname) || ereg("^\-",$hostname)) {
866 $multipoint = explode(".",$hostname);
868 if (!(is_array($multipoint)) || ((count($multipoint) - 1) < 1)) {
878 * human_readable_bytes() - Translates an integer representing bytes to a human-readable format.
880 * Format file size in a human-readable way
881 * such as "xx Megabytes" or "xx Mo"
883 * @author Andrea Paleni <andreaSPAMLESS_AT_SPAMLESScriticalbit.com>
885 * @param int bytes is the size
886 * @param bool base10 enable base 10 representation, otherwise
887 * default base 2 is used
888 * @param int round number of fractional digits
889 * @param array labels strings associated to each 2^10 or
890 * 10^3(base10==true) multiple of base units
892 function human_readable_bytes ($bytes, $base10=false, $round=0, $labels=array(' bytes', ' KB', ' MB', ' GB')) {
893 if ($bytes <= 0 || !is_array($labels) || (count($labels) <= 0)) {
896 $step = $base10 ? 3 : 10;
897 $base = $base10 ? 10 : 2;
898 $log = (int)(log10($bytes)/log10($base));
900 foreach ($labels as $p=>$lab) {
905 if ($lab == " MB" or $lab == " GB") {
908 $text = round($bytes/pow($base,$pow),$round).$lab;
915 * ls - lists a specified directory and returns an array of files
916 * @param string the path of the directory to list
917 * @param boolean whether to filter out directories and illegal filenames
918 * @return array array of file names.
920 function &ls($dir,$filter=false) {
921 if (!is_dir ($dir)) {
925 exec('ls -c1 '.$dir,$out);
927 for ($i=0; $i<count($out); $i++) {
928 if (util_is_valid_filename($out[$i]) && is_file($dir.'/'.$out[$i])) {
929 $filtered[]=$out[$i];
939 * readfile_chunked() - replacement for readfile
941 * @param string The file path
942 * @param bool Whether to return bytes served or just a bool
945 function readfile_chunked($filename, $returnBytes=true) {
946 $chunksize = 1*(1024*1024); // 1MB chunks
950 $handle = fopen($filename, 'rb');
951 if ($handle === false) {
956 while (!feof($handle)) {
957 $buffer = fread($handle, $chunksize);
962 $byteCounter += strlen($buffer);
966 $status = fclose($handle);
967 if ($returnBytes && $status) {
968 return $byteCounter; // return num. bytes delivered like readfile() does.
974 * util_is_root_dir() - Checks if a directory points to the root dir
975 * @param string Directory
978 function util_is_root_dir($dir) {
979 return !preg_match('/[^\\/]/',$dir);
983 * util_strip_accents() - Remove accents from given text.
987 function util_strip_accents($text) {
988 $find = utf8_decode($text);
990 utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'),
991 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
992 return utf8_encode($find);
996 * Constructs the forge's URL prefix out of forge_get_config('url_prefix')
1000 function normalized_urlprefix () {
1001 $prefix = forge_get_config('url_prefix') ;
1002 $prefix = ereg_replace ("^/", "", $prefix) ;
1003 $prefix = ereg_replace ("/$", "", $prefix) ;
1004 $prefix = "/$prefix/" ;
1005 if ($prefix == '//')
1011 * Construct full URL from a relative path
1013 * @param string $path
1014 * @return string URL
1016 function util_make_url ($path) {
1017 if (forge_get_config('use_ssl'))
1022 $url .= forge_get_config('web_host') ;
1023 $url .= util_make_uri ($path) ;
1028 * Construct proper (relative) URI (prepending prefix)
1030 * @param string $path
1031 * @return string URI
1033 function util_make_uri ($path) {
1034 $path = ereg_replace ("^/", "", $path) ;
1035 $uri = normalized_urlprefix () ;
1040 function util_make_link ($path, $text, $extra_params=false, $absolute=false) {
1042 if (is_array($extra_params)) {
1043 foreach ($extra_params as $key => $value) {
1044 $ep .= "$key=\"$value\" ";
1048 return '<a ' . $ep . 'href="' . $path . '">' . $text . '</a>' ;
1050 return '<a ' . $ep . 'href="' . util_make_url ($path) . '">' . $text . '</a>' ;
1055 * Create an HTML link to a user's profile page
1057 * @param string $username
1058 * @param int $user_id
1059 * @param string $text
1062 function util_make_link_u ($username, $user_id,$text) {
1063 return '<a href="' . util_make_url_u ($username, $user_id) . '">' . $text . '</a>' ;
1067 * Create URL for user's profile page
1069 * @param string $username
1070 * @param int $user_id
1071 * @return string URL
1073 function util_make_url_u ($username, $user_id) {
1074 if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
1075 return util_make_url ("/developer/?user_id=$user_id");
1077 return util_make_url ("/users/$username/");
1082 * Create a HTML link to a project's page
1083 * @param string $groupame
1084 * @param int $group_id
1085 * @param string $text
1088 function util_make_link_g ($groupame, $group_id,$text) {
1089 return '<a href="' . util_make_url_g ($groupame, $group_id) . '">' . $text . '</a>' ;
1093 * Create URL for a project's page
1095 * @param string $groupame
1096 * @param int $group_id
1099 function util_make_url_g ($groupame, $group_id) {
1100 if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
1101 return util_make_url ("/project/?group_id=$group_id");
1103 return util_make_url ("/projects/$groupame/");
1107 function util_ensure_value_in_set ($value, $set) {
1108 if (in_array ($value, $set)) {
1115 function check_email_available($group, $email, &$response) {
1116 // Check if a mailing list with same name already exists
1117 $mlFactory = new MailingListFactory($group);
1118 if (!$mlFactory || !is_object($mlFactory) || $mlFactory->isError()) {
1119 $response .= $mlFactory->getErrorMessage();
1122 $mlArray =& $mlFactory->getMailingLists();
1123 if ($mlFactory->isError()) {
1124 $response .= $mlFactory->getErrorMessage();
1127 for ($j = 0; $j < count($mlArray); $j++) {
1128 $currentList =& $mlArray[$j];
1129 if ($email == $currentList->getName()) {
1130 $response .= _('Error: a mailing list with the same email address already exists.');
1135 // Check if a forum with same name already exists
1136 $ff = new ForumFactory($group);
1137 if (!$ff || !is_object($ff) || $ff->isError()) {
1138 $response .= $ff->getErrorMessage();
1141 $farr =& $ff->getForums();
1142 $prefix = $group->getUnixName() . '-';
1143 for ($j = 0; $j < count($farr); $j++) {
1144 if (is_object($farr[$j])) {
1145 if ($email == $prefix . $farr[$j]->getName()) {
1146 $response .= _('Error: a forum with the same email address already exists.');
1152 // Email is available
1156 // array_replace_recursive only appeared in PHP 5.3.0
1157 if (!function_exists('array_replace_recursive')) {
1158 function array_replace_recursive ($a1, $a2) {
1161 if (!is_array ($a2)) {
1165 foreach ($a2 as $k => $v) {
1166 if (!is_array ($v) ||
1167 !isset ($result[$k]) || !is_array ($result[$k])) {
1171 $result[$k] = array_replace_recursive ($result[$k],
1180 * I have absolutely no idea how to write a programming language, I just
1181 * kept adding the next logical step on the way.
1185 /* returns an integer from http://forge/foo/bar.php/123 or false */
1186 function util_path_info_last_numeric_component() {
1187 if (!isset($_SERVER['PATH_INFO']))
1190 /* PHP devs are idiots… ereg_replace is deprecated WTF? */
1192 foreach (str_split($_SERVER['PATH_INFO']) as $x) {
1196 } else if ($ok == false) {
1197 ; /* need reset using slash */
1198 } else if ((ord($x) >= 48) && (ord($x) <= 57)) {
1199 $rv = $rv * 10 + ord($x) - 48;
1211 // c-file-style: "bsd"