[ Index ] |
PHP Cross Reference of Eventum |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */ 3 // +----------------------------------------------------------------------+ 4 // | Eventum - Issue Tracking System | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB | 7 // | | 8 // | This program is free software; you can redistribute it and/or modify | 9 // | it under the terms of the GNU General Public License as published by | 10 // | the Free Software Foundation; either version 2 of the License, or | 11 // | (at your option) any later version. | 12 // | | 13 // | This program is distributed in the hope that it will be useful, | 14 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 // | GNU General Public License for more details. | 17 // | | 18 // | You should have received a copy of the GNU General Public License | 19 // | along with this program; if not, write to: | 20 // | | 21 // | Free Software Foundation, Inc. | 22 // | 59 Temple Place - Suite 330 | 23 // | Boston, MA 02111-1307, USA. | 24 // +----------------------------------------------------------------------+ 25 // | Authors: João Prado Maia <jpm@mysql.com> | 26 // +----------------------------------------------------------------------+ 27 // 28 29 require_once (APP_INC_PATH . "class.error_handler.php"); 30 require_once (APP_INC_PATH . "class.setup.php"); 31 32 /** 33 * Class to hold methods and algorythms that woudln't fit in other classes, such 34 * as functions to work around PHP bugs or incompatibilities between separate 35 * PHP configurations. 36 * 37 * @version 1.0 38 * @author João Prado Maia <jpm@mysql.com> 39 */ 40 41 class Misc 42 { 43 /** 44 * Method used to simulate the correct behavior of array_diff(). 45 * 46 * @access public 47 * @param array $foo The first array 48 * @param array $bar The second array 49 * @return array The different values 50 */ 51 function arrayDiff($foo, $bar) 52 { 53 if (!is_array($bar)) { 54 $bar = array(); 55 } 56 $diffs = array(); 57 $foo_values = array_values($foo); 58 $bar_values = array_values($bar); 59 if (count($foo_values) > count($bar_values)) { 60 $total = count($foo_values); 61 $first = &$foo_values; 62 $second = &$bar_values; 63 } else { 64 $total = count($bar_values); 65 $first = &$bar_values; 66 $second = &$foo_values; 67 } 68 for ($i = 0; $i < $total; $i++) { 69 if ((!empty($first[$i])) && (!@in_array($first[$i], $second))) { 70 $diffs[] = $first[$i]; 71 } 72 if ((!empty($second[$i])) && (!@in_array($second[$i], $first))) { 73 $diffs[] = $second[$i]; 74 } 75 } 76 return $diffs; 77 } 78 79 80 /** 81 * Method used to get the title given to the current installation of Eventum. 82 * 83 * @access public 84 * @return string The installation title 85 */ 86 function getToolCaption() 87 { 88 $setup = Setup::load(); 89 return @$setup['tool_caption'] ? $setup['tool_caption'] : APP_NAME; 90 } 91 92 93 /** 94 * Method used to print a prompt asking the user for information. 95 * 96 * @access public 97 * @param string $message The message to print 98 * @param string $default_value The default value to be used if the user just press <enter> 99 * @return string The user response 100 */ 101 function prompt($message, $default_value) 102 { 103 echo $message; 104 if ($default_value !== FALSE) { 105 echo " [default: $default_value] -> "; 106 } else { 107 echo " [required] -> "; 108 } 109 flush(); 110 $input = trim(Misc::getInput(true)); 111 if (empty($input)) { 112 if ($default_value === FALSE) { 113 die("ERROR: Required parameter was not provided!\n"); 114 } else { 115 return $default_value; 116 } 117 } else { 118 return $input; 119 } 120 } 121 122 123 /** 124 * Method used to get the standard input. 125 * 126 * @access public 127 * @return string The standard input value 128 */ 129 function getInput($is_one_liner = FALSE) 130 { 131 static $return; 132 133 if (!empty($return)) { 134 return $return; 135 } 136 137 $terminator = "\n"; 138 139 $stdin = fopen("php://stdin", "r"); 140 $input = ''; 141 while (!feof($stdin)) { 142 $buffer = fgets($stdin, 256); 143 $input .= $buffer; 144 if (($is_one_liner) && (strstr($input, $terminator))) { 145 break; 146 } 147 } 148 fclose($stdin); 149 $return = $input; 150 return $input; 151 } 152 153 154 /** 155 * Method used to check the spelling of a given text. 156 * 157 * @access public 158 * @param string $text The text to check the spelling against 159 * @return array Information about the mispelled words, if any 160 */ 161 function checkSpelling($text) 162 { 163 $temptext = tempnam("/tmp", "spelltext"); 164 if ($fd = fopen($temptext, "w")) { 165 $textarray = explode("\n", $text); 166 fwrite($fd, "!\n"); 167 foreach ($textarray as $key => $value) { 168 // adding the carat to each line prevents the use of aspell commands within the text... 169 fwrite($fd,"^$value\n"); 170 } 171 fclose($fd); 172 $return = shell_exec("cat $temptext | /usr/bin/aspell -a"); 173 unlink($temptext); 174 } 175 $lines = explode("\n", $return); 176 // remove the first line that is only the aspell copyright banner 177 array_shift($lines); 178 // remove all blank lines 179 foreach ($lines as $key => $value) { 180 if (empty($value)) { 181 unset($lines[$key]); 182 } 183 } 184 $lines = array_values($lines); 185 186 $misspelled_words = array(); 187 $spell_suggestions = array(); 188 for ($i = 0; $i < count($lines); $i++) { 189 if (substr($lines[$i], 0, 1) == '&') { 190 // found suggestions for this word 191 $first_part = substr($lines[$i], 0, strpos($lines[$i], ':')); 192 $pieces = explode(' ', $first_part); 193 $misspelled_word = $pieces[1]; 194 $last_part = substr($lines[$i], strpos($lines[$i], ':')+2); 195 $suggestions = explode(', ', $last_part); 196 } elseif (substr($lines[$i], 0, 1) == '#') { 197 // found no suggestions for this word 198 $pieces = explode(' ', $lines[$i]); 199 $misspelled_word = $pieces[1]; 200 $suggestions = array(); 201 } else { 202 // no spelling mistakes could be found 203 continue; 204 } 205 // prevent duplicates... 206 if (in_array($misspelled_word, $misspelled_words)) { 207 continue; 208 } 209 $misspelled_words[] = $misspelled_word; 210 $spell_suggestions[$misspelled_word] = $suggestions; 211 } 212 213 return array( 214 'total_words' => count($misspelled_words), 215 'words' => $misspelled_words, 216 'suggestions' => $spell_suggestions 217 ); 218 } 219 220 221 /** 222 * Method used to get the full contents of the given file. 223 * 224 * @access public 225 * @param string $full_path The full path to the file 226 * @return string The full contents of the file 227 */ 228 function getFileContents($full_path) 229 { 230 if (!@file_exists($full_path)) { 231 return ''; 232 } 233 $fp = @fopen($full_path, "rb"); 234 if (!$fp) { 235 return ''; 236 } 237 $contents = @fread($fp, filesize($full_path)); 238 @fclose($fp); 239 return $contents; 240 } 241 242 243 /** 244 * Method used to replace all special whitespace characters (\n, 245 * \r and \t) by their string equivalents. It is usually used in 246 * JavaScript code. 247 * 248 * @access public 249 * @param string $str The string to be escaped 250 * @return string The escaped string 251 */ 252 function escapeWhitespace($str) 253 { 254 $str = str_replace("\n", '\n', $str); 255 $str = str_replace("\r", '\r', $str); 256 $str = str_replace("\t", '\t', $str); 257 return $str; 258 } 259 260 261 /** 262 * Method used to simulate array_map()'s functionality in a deeply nested 263 * array. The PHP built-in function does not allow that. 264 * 265 * @access public 266 * @param array $in_array The array to run the function against 267 * @param string $in_func The function to run 268 * @param array $in_args The array of arguments to pass to the function 269 * @param integer $in_index Internal parameter to specify which index of the array we are currently mapping 270 * @return array The mapped array 271 */ 272 function array_map_deep(&$in_array, $in_func, $in_args = array(), $in_index = 1) 273 { 274 // fix people from messing up the index of the value 275 if ($in_index < 1) { 276 $in_index = 1; 277 } 278 foreach (array_keys($in_array) as $key) { 279 // we need a reference, not a copy, normal foreach won't do 280 $value =& $in_array[$key]; 281 // we need to copy args because we are doing 282 // manipulation on it farther down 283 $args = $in_args; 284 if (is_array($value)) { 285 Misc::array_map_deep($value, $in_func, $in_args, $in_index); 286 } else { 287 array_splice($args, $in_index - 1, $in_index - 1, $value); 288 $value = call_user_func_array($in_func, $args); 289 } 290 } 291 return $in_array; 292 } 293 294 295 /** 296 * Method used to format a filesize in bytes to the appropriate string, 297 * showing 'Kb' and 'Mb'. 298 * 299 * @access public 300 * @param integer $bytes The filesize to format 301 * @return string The formatted filesize 302 */ 303 function formatFileSize($bytes) 304 { 305 $kb = 1024; 306 $mb = 1024 * 1024; 307 if ($bytes <= $kb) { 308 return "$bytes bytes"; 309 } elseif (($bytes > $kb) && ($bytes <= $mb)) { 310 $kbytes = $bytes / 1024; 311 return sprintf("%.1f", round($kbytes, 1)) . " Kb"; 312 } else { 313 $mbytes = ($bytes / 1024) / 1024; 314 return sprintf("%.1f", round($mbytes, 1)) . " Mb"; 315 } 316 } 317 318 319 /** 320 * The Util:: class provides generally useful methods of different kinds. 321 * 322 * $Horde: framework/Util/Util.php,v 1.366 2004/03/30 17:03:58 jan Exp $ 323 * 324 * Copyright 1999-2004 Chuck Hagenbuch <chuck@horde.org> 325 * Copyright 1999-2004 Jon Parise <jon@horde.org> 326 * 327 * See the enclosed file COPYING for license information (LGPL). If you 328 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 329 * 330 * @author Chuck Hagenbuch <chuck@horde.org> 331 * @author Jon Parise <jon@horde.org> 332 * @version $Revision: 1.366 $ 333 * @since Horde 3.0 334 * @package Horde_Util 335 */ 336 function dispelMagicQuotes(&$var) 337 { 338 static $magic_quotes; 339 340 if (!isset($magic_quotes)) { 341 $magic_quotes = get_magic_quotes_gpc(); 342 } 343 344 if ($magic_quotes) { 345 if (!is_array($var)) { 346 $var = stripslashes($var); 347 } else { 348 array_walk($var, array('Misc', 'dispelMagicQuotes')); 349 } 350 } 351 352 return $var; 353 } 354 355 356 /** 357 * Method used to escape a string before using it in a query. 358 * 359 * @access public 360 * @param string $str The original string 361 * @return string The escaped (or not) string 362 */ 363 function escapeString($input) 364 { 365 if (is_array($input)) { 366 foreach ($input as $key => $value) { 367 $input[$key] = Misc::escapeString($value); 368 } 369 } else { 370 $input = $GLOBALS["db_api"]->escapeString($input); 371 } 372 return $input; 373 } 374 375 376 /** 377 * Accepts a value and cleans it to only contain numeric values 378 * 379 * @access public 380 * @param mixed $input The original input. 381 * @return integer The input converted to an integer 382 */ 383 function escapeInteger($input) 384 { 385 if (is_array($input)) { 386 foreach ($input as $key => $value) { 387 $input[$key] = Misc::escapeInteger($value); 388 } 389 } else { 390 settype($input, 'integer'); 391 } 392 return $input; 393 } 394 395 396 /** 397 * Method used to prepare a set of fields and values for a boolean search 398 * 399 * @access public 400 * @param string $field The field name 401 * @param string $value The value for that field 402 * @return string The prepared boolean search string 403 */ 404 function prepareBooleanSearch($field, $value) 405 { 406 $boolean = array(); 407 $pieces = explode(" ", $value); 408 for ($i = 0; $i < count($pieces); $i++) { 409 $boolean[] = "$field LIKE '%" . Misc::escapeString($pieces[$i]) . "%'"; 410 } 411 return "(" . implode(" OR ", $boolean) . ")"; 412 } 413 414 415 /** 416 * Method used to get a random file from the 'daily tips' directory. 417 * 418 * @access public 419 * @param object $tpl The template object 420 * @return string Random filename 421 */ 422 function getRandomTip($tpl) 423 { 424 $tip_dir = $tpl->smarty->template_dir . "/tips"; 425 $files = Misc::getFileList($tip_dir); 426 $i = rand(0, (integer)count($files)); 427 // some weird bug in the rand() function where sometimes the 428 // second parameter is non-inclusive makes us have to do this 429 if (!isset($files[$i])) { 430 return Misc::getRandomTip($tpl); 431 } else { 432 return $files[$i]; 433 } 434 } 435 436 437 /** 438 * Method used to get the full list of files contained in a specific 439 * directory. 440 * 441 * @access public 442 * @param string $directory The path to list the files from 443 * @return array The list of files 444 */ 445 function getFileList($directory) 446 { 447 $files = array(); 448 $dir = @opendir($directory); 449 while ($item = @readdir($dir)){ 450 if (($item == '.') || ($item == '..') || ($item == 'CVS') || ($item == 'SCCS')) { 451 continue; 452 } 453 $files[] = $item; 454 } 455 return $files; 456 } 457 458 459 /** 460 * Method used to format the given number of minutes in a string showing 461 * the number of hours and minutes (02:30) 462 * 463 * @access public 464 * @param integer $minutes The number of minutes to format 465 * @param boolean $omit_days If days should not be used, hours will just show up as greater then 24. 466 * @param boolean $omit_empty If true, values that are "00" will be omitted. 467 * @return string The formatted time 468 */ 469 function getFormattedTime($minutes, $omit_days = false, $omit_empty = false) 470 { 471 $hours = $minutes / 60; 472 if ((!empty($minutes)) && ($minutes < 6)) { 473 $return = sprintf("%02dm", $minutes); 474 } elseif ($hours > 24 && $omit_days == false) { 475 $return = sprintf("%dd %dh %dm (%dh %dm)", floor($minutes/24/60), floor($minutes/60)%24, $minutes%60, floor($minutes/60), $minutes%60); 476 } else { 477 $return = sprintf("%dh %dm", floor($minutes/60), $minutes%60); 478 } 479 if ($omit_empty) { 480 $chunks = explode(" ", $return); 481 foreach ($chunks as $index => $chunk) { 482 preg_match("/(\d*)\S/i", $chunk, $matches); 483 if ($matches[1] == '00') { 484 unset($chunks[$index]); 485 } 486 } 487 $return = join(" ", $chunks); 488 } 489 return $return; 490 } 491 492 493 /** 494 * Method used to parse the given string for references to URLs and create 495 * real links out of those. 496 * 497 * @param string $text The text to search against 498 * @param string $class The CSS class to use on the actual links 499 * @return string The parsed string 500 */ 501 function activateLinks($text, $class = "link") 502 { 503 $range = '[-\w+@=?.%/:&;~|,#]+'; 504 $text = preg_replace("'(\w+)://($range)(\.)?'", '<a title="open $1://$2 in a new window" class="' . $class . '" href="$1://$2" target="_$2">$1://$2</a>', $text); 505 $text = preg_replace("'(\s+)(www\.$range)(\.\s|\s)'", '$1<a title="open http://$2 in a new window" class="' . $class . '" href="http://$2" target="_$2">$2</a>$3' , $text); 506 507 $mail_pat = '/([-+a-z0-9_.]+@(?:[-a-z0-9_.]{2,63}\.)+[a-z]{2,6})/i'; 508 $text = preg_replace($mail_pat, '<a title="open mailto:$1 in a new window" class="' . $class . '" href="mailto:$1" target="_$1">$1</a>' , $text); 509 510 return $text; 511 } 512 513 514 /** 515 * Method used to indent a given string. 516 * 517 * @access public 518 * @param string $str The string to be indented 519 * @return string The indented string 520 */ 521 function indent($str) 522 { 523 return "> " . $str; 524 } 525 526 527 /** 528 * Method used to format the reply of someone's email that is available in 529 * the system. 530 * 531 * @access public 532 * @param string $str The string to be formatted 533 * @return string the formatted string 534 */ 535 function formatReply($str) 536 { 537 $lines = explode("\n", str_replace("\r", "", $str)); 538 // COMPAT: the next line requires PHP >= 4.0.6 539 $lines = array_map(array("Misc", "indent"), $lines); 540 return implode("\n", $lines); 541 } 542 543 544 /** 545 * Method used to format a RFC 822 compliant date for the given unix 546 * timestamp. 547 * 548 * @access public 549 * @param integer $ts The unix timestamp 550 * @return string The formatted date string 551 */ 552 function formatReplyDate($ts) 553 { 554 // On Fri, 01 Apr 2005, 17:07:44 GMT 555 return Date_API::getFormattedDate($ts); 556 } 557 558 559 /** 560 * Method used to check whether the given directory is writable by the 561 * web server user or not. 562 * 563 * @access public 564 * @param string $file The full path to the directory 565 * @return boolean 566 */ 567 function isWritableDirectory($file) 568 { 569 clearstatcache(); 570 if (!file_exists($file)) { 571 if (!@mkdir($file)) { 572 return false; 573 } 574 } 575 clearstatcache(); 576 if (!is_writable($file)) { 577 if (!stristr(PHP_OS, "win")) { 578 // let's try to change the permissions ourselves 579 @chmod($file, 0755); 580 clearstatcache(); 581 if (!is_writable($file)) { 582 return false; 583 } 584 } else { 585 return false; 586 } 587 } 588 if (stristr(PHP_OS, "win")) { 589 // need to check whether we can really create files in this directory or not 590 // since is_writable() is not trustworthy on windows platforms 591 if (is_dir($file)) { 592 $fp = @fopen($file . '/dummy.txt', 'w'); 593 if (!$fp) { 594 return false; 595 } 596 @fwrite($fp, 'test'); 597 @fclose($fp); 598 // clean up after ourselves 599 @unlink($file . '/dummy.txt'); 600 } 601 } 602 return true; 603 } 604 605 606 /** 607 * Highlights quoted replies. Relies on a smarty plugin written by 608 * Joscha Feth, joscha@feth.com, www.feth.com 609 * 610 * @access public 611 * @param string $text The text to highlight 612 * @return string The highlighted text 613 */ 614 function highlightQuotedReply($text) 615 { 616 require_once(APP_SMARTY_PATH . "plugins/modifier.highlight_quoted.php"); 617 return smarty_modifier_highlight_quoted($text); 618 } 619 620 621 /** 622 * Method used to display a nice error message when one (or more) of the 623 * system requirements for Eventum is not found. 624 * 625 * @access public 626 * @param array $errors The list of errors 627 * @return void 628 */ 629 function displayRequirementErrors($errors) 630 { 631 echo '<html> 632 <head> 633 <style type="text/css"> 634 <!-- 635 .default { 636 font-family: Verdana, Arial, Helvetica, sans-serif; 637 font-style: normal; 638 font-weight: normal; 639 font-size: 70%; 640 } 641 --> 642 </style> 643 <title>Configuration Error</title> 644 </head> 645 <body> 646 647 <br /><br /> 648 649 <table width="500" bgcolor="#003366" border="0" cellspacing="0" cellpadding="1" align="center"> 650 <tr> 651 <td> 652 <table bgcolor="#FFFFFF" width="100%" cellspacing="1" cellpadding="2" border="0"> 653 <tr> 654 <td><img src="../images/icons/error.gif" hspace="2" vspace="2" border="0" align="left"></td> 655 <td width="100%" class="default"><span style="font-weight: bold; font-size: 160%; color: red;">Configuration Error:</span></td> 656 </tr> 657 <tr> 658 <td colspan="2" class="default"> 659 <br /> 660 <b>The following problems regarding file and/or directory permissions were found:</b> 661 <br /><br /> 662 ' . implode("<br />", $errors) . ' 663 <br /><br /> 664 <b>Please provide the appropriate permissions to the user that the web server run as to write in the directories and files specified above.</b> 665 <br /><br /> 666 </td> 667 </tr> 668 </table> 669 </td> 670 </tr> 671 </table> 672 673 </body> 674 </html>'; 675 } 676 677 678 /** 679 * Base 64 encodes all elements of an array. 680 * 681 * @access public 682 * @param array $values The values to encode 683 * @return array The array of encoded values. 684 */ 685 function base64encode($values) 686 { 687 foreach ($values as $key => $value) { 688 if (is_array($value)) { 689 $values[$key] = Misc::base64encode($value); 690 } elseif (is_object($value)) { 691 $values[$key] = $value; 692 } else { 693 $values[$key] = base64_encode($value); 694 } 695 } 696 return $values; 697 } 698 699 700 /** 701 * Changes a boolean value to either "Yes" or "No". 702 * 703 * @access public 704 * @param boolean $value The boolean value 705 * @return string Either 'Yes' or 'No'. 706 */ 707 function getBooleanDisplayValue($value) 708 { 709 if ($value == true) { 710 return ev_gettext('Yes'); 711 } else { 712 return ev_gettext('No'); 713 } 714 } 715 } 716 717 // benchmarking the included file (aka setup time) 718 if (APP_BENCHMARK) { 719 $GLOBALS['bench']->setMarker('Included Misc Class'); 720 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 19 21:21:33 2007 | Cross-referenced by PHPXref 0.7 |