[ Index ]

PHP Cross Reference of Eventum

title

Body

[close]

/include/ -> class.misc.php (source)

   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  }


Generated: Wed Dec 19 21:21:33 2007 Cross-referenced by PHPXref 0.7