[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/core/ -> helper_api.php (source)

   1  <?php
   2  # MantisBT - A PHP based bugtracking system
   3  
   4  # MantisBT is free software: you can redistribute it and/or modify
   5  # it under the terms of the GNU General Public License as published by
   6  # the Free Software Foundation, either version 2 of the License, or
   7  # (at your option) any later version.
   8  #
   9  # MantisBT is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Helper API
  19   *
  20   * @package CoreAPI
  21   * @subpackage HelperAPI
  22   * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
  23   * @copyright Copyright (C) 2002 - 2011  MantisBT Team - mantisbt-dev@lists.sourceforge.net
  24   * @link http://www.mantisbt.org
  25   *
  26   * @uses access_api.php
  27   * @uses authentication_api.php
  28   * @uses config_api.php
  29   * @uses constant_inc.php
  30   * @uses current_user_api.php
  31   * @uses error_api.php
  32   * @uses gpc_api.php
  33   * @uses html_api.php
  34   * @uses lang_api.php
  35   * @uses print_api.php
  36   * @uses project_api.php
  37   * @uses user_api.php
  38   * @uses user_pref_api.php
  39   * @uses utility_api.php
  40   */
  41  
  42  require_api( 'access_api.php' );
  43  require_api( 'authentication_api.php' );
  44  require_api( 'config_api.php' );
  45  require_api( 'constant_inc.php' );
  46  require_api( 'current_user_api.php' );
  47  require_api( 'error_api.php' );
  48  require_api( 'gpc_api.php' );
  49  require_api( 'html_api.php' );
  50  require_api( 'lang_api.php' );
  51  require_api( 'print_api.php' );
  52  require_api( 'project_api.php' );
  53  require_api( 'user_api.php' );
  54  require_api( 'user_pref_api.php' );
  55  require_api( 'utility_api.php' );
  56  
  57  /**
  58   * alternate color function
  59   * If no index is given, continue alternating based on the last index given
  60   * @param int $p_index
  61   * @param string $p_odd_color
  62   * @param string $p_even_color
  63   * @return string
  64   */
  65  function helper_alternate_colors( $p_index, $p_odd_color, $p_even_color ) {
  66      static $t_index = 1;
  67  
  68      if( null !== $p_index ) {
  69          $t_index = $p_index;
  70      }
  71  
  72      if( 1 == $t_index++ % 2 ) {
  73          return $p_odd_color;
  74      } else {
  75          return $p_even_color;
  76      }
  77  }
  78  
  79  /**
  80   * alternate classes for table rows
  81   * If no index is given, continue alternating based on the last index given
  82   * @param int $p_index
  83   * @param string $p_odd_class default: row-1
  84   * @param string $p_even_class default: row-2
  85   * @return string
  86   */
  87  function helper_alternate_class( $p_index = null, $p_odd_class = 'row-1', $p_even_class = 'row-2' ) {
  88      static $t_index = 1;
  89  
  90      if( null !== $p_index ) {
  91          $t_index = $p_index;
  92      }
  93  
  94      if( 1 == $t_index++ % 2 ) {
  95          return "class=\"$p_odd_class\"";
  96      } else {
  97          return "class=\"$p_even_class\"";
  98      }
  99  }
 100  
 101  /**
 102   * return alternate classes for rows, no attribute
 103   * If no index is given, continue alternating based on the last index given
 104   * @param int $p_index
 105   * @param string $p_odd_class default: odd
 106   * @param string $p_even_class default: even
 107   * @return string
 108   */
 109  function helper_alternate_class_no_attribute( $p_index = null, $p_odd_class = 'odd', $p_even_class = 'even' ) {
 110      static $t_index = 1;
 111  
 112      if( null !== $p_index ) {
 113          $t_index = $p_index;
 114      }
 115  
 116      if( 1 == $t_index++ % 2 ) {
 117          return $p_odd_class;
 118      } else {
 119          return $p_even_class;
 120      }
 121  }
 122  
 123  /**
 124   * get the color string for the given status
 125   * @param int $p_status
 126   * @return string
 127   */
 128  function get_status_color( $p_status ) {
 129      $t_status_label = MantisEnum::getLabel( config_get( 'status_enum_string' ), $p_status );
 130      $t_status_colors = config_get( 'status_colors' );
 131      $t_color = '#ffffff';
 132  
 133      if ( isset( $t_status_colors[$t_status_label] ) ) {
 134          $t_color = $t_status_colors[$t_status_label];
 135      }
 136  
 137      return $t_color;
 138  }
 139  
 140  /**
 141   * get the status percentages
 142   * @return array key is the status value, value is the percentage of bugs for the status
 143   */
 144  function get_percentage_by_status() {
 145      $t_mantis_bug_table = db_get_table( 'bug' );
 146      $t_project_id = helper_get_current_project();
 147      $t_user_id = auth_get_current_user_id();
 148  
 149      # checking if it's a per project statistic or all projects
 150      $t_specific_where = helper_project_specific_where( $t_project_id, $t_user_id );
 151  
 152      $query = "SELECT status, COUNT(*) AS number
 153                  FROM $t_mantis_bug_table
 154                  WHERE $t_specific_where";
 155      if ( !access_has_project_level( config_get( 'private_bug_threshold' ) ) ) {
 156          $query .= ' AND view_state < ' . VS_PRIVATE;
 157      }
 158      $query .= ' GROUP BY status';
 159      $result = db_query_bound( $query );
 160  
 161      $t_bug_count = 0;
 162      $t_status_count_array = array();
 163  
 164      while( $row = db_fetch_array( $result ) ) {
 165          $t_status_count_array[$row['status']] = $row['number'];
 166      }
 167      $t_bug_count = array_sum( $t_status_count_array );
 168      foreach( $t_status_count_array AS $t_status=>$t_value ) {
 169          $t_status_count_array[$t_status] = round(( $t_value / $t_bug_count ) * 100 );
 170      }
 171  
 172      return $t_status_count_array;
 173  }
 174  
 175  /**
 176   * Given a enum string and num, return the appropriate string
 177   * @param string $p_enum_name
 178   * @param int $p_val
 179   * @return string
 180   */
 181  function get_enum_element( $p_enum_name, $p_val ) {
 182      $config_var = config_get( $p_enum_name . '_enum_string' );
 183      $string_var = lang_get( $p_enum_name . '_enum_string' );
 184  
 185      return MantisEnum::getLocalizedLabel( $config_var, $string_var, $p_val );
 186  }
 187  
 188  /**
 189   * If $p_var is not an array and is equal to $p_val then we PRINT SELECTED.
 190   * If $p_var is an array, then if any member is equal to $p_val we PRINT SELECTED.
 191   * This is used when we want to know if a variable indicated a certain
 192   * option element is selected
 193   *
 194   * If the second parameter is not given, the first parameter is compared
 195   *  to the boolean value true
 196   * @param mixed $p_var
 197   * @param mixed $p_val
 198   * @return null
 199   */
 200  function check_selected( $p_var, $p_val = true ) {
 201      if( is_array( $p_var ) ) {
 202          foreach( $p_var as $t_this_var ) {
 203  
 204              # catch the case where one entry is 0 and the other is a string.
 205              if( is_string( $t_this_var ) && is_string( $p_val ) ) {
 206                  if( $t_this_var === $p_val ) {
 207                      echo ' selected="selected"';
 208                      return;
 209                  }
 210              }
 211              else if( $t_this_var == $p_val ) {
 212                  echo ' selected="selected"';
 213                  return;
 214              }
 215          }
 216      } else {
 217          if( is_string( $p_var ) && is_string( $p_val ) ) {
 218              if( $p_var === $p_val ) {
 219                  echo ' selected="selected"';
 220                  return;
 221              }
 222          }
 223          else if( $p_var == $p_val ) {
 224              echo ' selected="selected"';
 225              return;
 226          }
 227      }
 228  }
 229  
 230  /**
 231   * If $p_var is not an array and is equal to $p_val then we PRINT CHECKED.
 232   * If $p_var is an array, then if any member is equal to $p_val we PRINT CHECKED.
 233   * This is used when we want to know if a variable indicated a certain
 234   * option element is selected
 235   *
 236   * If the second parameter is not given, the first parameter is compared
 237   *  to the boolean value true
 238   * @param mixed $p_var
 239   * @param mixed $p_val
 240   * @return null
 241   */
 242  function check_checked( $p_var, $p_val = true ) {
 243      if( is_array( $p_var ) ) {
 244          foreach( $p_var as $t_this_var ) {
 245  
 246              # catch the case where one entry is 0 and the other is a string.
 247              if( is_string( $t_this_var ) && is_string( $p_val ) ) {
 248                  if( $t_this_var === $p_val ) {
 249                      echo ' checked="checked"';
 250                      return;
 251                  }
 252              }
 253              else if( $t_this_var == $p_val ) {
 254                  echo ' checked="checked"';
 255                  return;
 256              }
 257          }
 258      } else {
 259          if( is_string( $p_var ) && is_string( $p_val ) ) {
 260              if( $p_var === $p_val ) {
 261                  echo ' checked="checked"';
 262                  return;
 263              }
 264          }
 265          else if( $p_var == $p_val ) {
 266              echo ' checked="checked"';
 267              return;
 268          }
 269      }
 270  }
 271  
 272  /**
 273   * Set up PHP for a long process execution
 274   * The script timeout is set based on the value of the long_process_timeout config option.
 275   * $p_ignore_abort specified whether to ignore user aborts by hitting
 276   * the Stop button (the default is not to ignore user aborts)
 277   * @param bool $p_ignore_abort
 278   * @return int
 279   */
 280  function helper_begin_long_process( $p_ignore_abort = false ) {
 281      $t_timeout = config_get( 'long_process_timeout' );
 282  
 283      # silent errors or warnings reported when safe_mode is ON.
 284      @set_time_limit( $t_timeout );
 285  
 286      ignore_user_abort( $p_ignore_abort );
 287      return $t_timeout;
 288  }
 289  
 290  # this allows pages to override the current project settings.
 291  #  This typically applies to the view bug pages where the "current"
 292  #  project as used by the filters, etc, does not match the bug being viewed.
 293  $g_project_override = null;
 294  $g_cache_current_project = null;
 295  
 296  /**
 297   * Return the current project id as stored in a cookie
 298   *  If no cookie exists, the user's default project is returned
 299   * @return int
 300   */
 301  function helper_get_current_project() {
 302      global $g_project_override, $g_cache_current_project;
 303  
 304      if( $g_project_override !== null ) {
 305          return $g_project_override;
 306      }
 307  
 308      if( $g_cache_current_project === null ) {
 309          $t_cookie_name = config_get( 'project_cookie' );
 310  
 311          $t_project_id = gpc_get_cookie( $t_cookie_name, null );
 312  
 313          if( null === $t_project_id ) {
 314              $t_pref = user_pref_get( auth_get_current_user_id(), ALL_PROJECTS, false );
 315              $t_project_id = $t_pref->default_project;
 316          } else {
 317              $t_project_id = explode( ';', $t_project_id );
 318              $t_project_id = $t_project_id[count( $t_project_id ) - 1];
 319          }
 320  
 321          if( !project_exists( $t_project_id ) || ( 0 == project_get_field( $t_project_id, 'enabled' ) ) || !access_has_project_level( VIEWER, $t_project_id ) ) {
 322              $t_project_id = ALL_PROJECTS;
 323          }
 324          $g_cache_current_project = (int) $t_project_id;
 325      }
 326      return $g_cache_current_project;
 327  }
 328  
 329  /**
 330   * Return the current project id as stored in a cookie, in an Array
 331   * If no cookie exists, the user's default project is returned
 332   * If the current project is a subproject, the return value will include
 333   * any parent projects
 334   * @return array
 335   */
 336  function helper_get_current_project_trace() {
 337      $t_cookie_name = config_get( 'project_cookie' );
 338  
 339      $t_project_id = gpc_get_cookie( $t_cookie_name, null );
 340  
 341      if( null === $t_project_id ) {
 342          $t_bottom = current_user_get_pref( 'default_project' );
 343          $t_project_id = Array(
 344              $t_bottom,
 345          );
 346      } else {
 347          $t_project_id = explode( ';', $t_project_id );
 348          $t_bottom = $t_project_id[count( $t_project_id ) - 1];
 349      }
 350  
 351      if( !project_exists( $t_bottom ) || ( 0 == project_get_field( $t_bottom, 'enabled' ) ) || !access_has_project_level( VIEWER, $t_bottom ) ) {
 352          $t_project_id = Array(
 353              ALL_PROJECTS,
 354          );
 355      }
 356  
 357      return $t_project_id;
 358  }
 359  
 360  /**
 361   * Set the current project id (stored in a cookie)
 362   * @param int $p_project_id
 363   * @return bool always true
 364   */
 365  function helper_set_current_project( $p_project_id ) {
 366      $t_project_cookie_name = config_get( 'project_cookie' );
 367  
 368      gpc_set_cookie( $t_project_cookie_name, $p_project_id, true );
 369  
 370      return true;
 371  }
 372  
 373  /**
 374   * Clear all known user preference cookies
 375   * @return null
 376   */
 377  function helper_clear_pref_cookies() {
 378      gpc_clear_cookie( config_get( 'project_cookie' ) );
 379      gpc_clear_cookie( config_get( 'manage_cookie' ) );
 380  }
 381  
 382  /**
 383   * Check whether the user has confirmed this action.
 384   *
 385   * If the user has not confirmed the action, generate a page which asks
 386   * the user to confirm and then submits a form back to the current page
 387   * with all the GET and POST data and an additional field called _confirmed
 388   * to indicate that confirmation has been done.
 389   * @param string $p_message
 390   * @param string $p_button_label
 391   * @return bool
 392   * @todo improve this formatting - to only be about 50% of the screen width so that it doesn't become hard to read.
 393   */
 394  function helper_ensure_confirmed( $p_message, $p_button_label ) {
 395      if( true == gpc_get_bool( '_confirmed' ) ) {
 396          return true;
 397      }
 398  
 399      html_page_top();
 400  
 401      echo "<br />\n<div class=\"center\">\n<hr />";
 402      echo "\n$p_message\n";
 403  
 404      echo '<form method="post" action="">' . "\n";
 405      # CSRF protection not required here - user needs to confirm action
 406      # before the form is accepted.
 407      print_hidden_inputs( gpc_strip_slashes( $_POST ) );
 408      print_hidden_inputs( gpc_strip_slashes( $_GET ) );
 409  
 410      echo "<input type=\"hidden\" name=\"_confirmed\" value=\"1\" />\n";
 411      echo '<br /><br /><input type="submit" class="button" value="' . $p_button_label . '" />';
 412      echo "\n</form>\n";
 413  
 414      echo "<hr /></div>\n";
 415      html_page_bottom();
 416      exit;
 417  }
 418  
 419  /**
 420   * Call custom function.
 421   *
 422   * $p_function - Name of function to call (eg: do_stuff).  The function will call custom_function_override_do_stuff()
 423   *        if found, otherwise, will call custom_function_default_do_stuff().
 424   * $p_args_array - Parameters to function as an array
 425   * @param string $p_function
 426   * @param array $p_args_array
 427   * @return mixed
 428   */
 429  function helper_call_custom_function( $p_function, $p_args_array ) {
 430      $t_function = 'custom_function_override_' . $p_function;
 431  
 432      if( !function_exists( $t_function ) ) {
 433          $t_function = 'custom_function_default_' . $p_function;
 434      }
 435  
 436      return call_user_func_array( $t_function, $p_args_array );
 437  }
 438  
 439  /**
 440   * return string to use in db queries containing projects of given user
 441   * @param int $p_project_id
 442   * @param int $p_user_id
 443   * @return string
 444   */
 445  function helper_project_specific_where( $p_project_id, $p_user_id = null ) {
 446      if( null === $p_user_id ) {
 447          $p_user_id = auth_get_current_user_id();
 448      }
 449  
 450      $t_project_ids = user_get_all_accessible_projects( $p_user_id, $p_project_id );
 451  
 452      if( 0 == count( $t_project_ids ) ) {
 453          $t_project_filter = ' 1<>1';
 454      } else if( 1 == count( $t_project_ids ) ) {
 455          $t_project_filter = ' project_id=' . $t_project_ids[0];
 456      } else {
 457          $t_project_filter = ' project_id IN (' . join( ',', $t_project_ids ) . ')';
 458      }
 459  
 460      return $t_project_filter;
 461  }
 462  
 463  /**
 464   *
 465   * @param int $p_columns_target
 466   * @param bool $p_viewable_only
 467   * @param int $p_user_id
 468   * @return array
 469   */
 470  function helper_get_columns_to_view( $p_columns_target = COLUMNS_TARGET_VIEW_PAGE, $p_viewable_only = true, $p_user_id = null ) {
 471      $t_columns = helper_call_custom_function( 'get_columns_to_view', array( $p_columns_target, $p_user_id ) );
 472  
 473      if( !$p_viewable_only ) {
 474          return $t_columns;
 475      }
 476  
 477      $t_keys_to_remove = array();
 478  
 479      if( $p_columns_target == COLUMNS_TARGET_CSV_PAGE || $p_columns_target == COLUMNS_TARGET_EXCEL_PAGE ) {
 480          $t_keys_to_remove[] = 'selection';
 481          $t_keys_to_remove[] = 'edit';
 482          $t_keys_to_remove[] = 'bugnotes_count';
 483          $t_keys_to_remove[] = 'attachment_count';
 484          $t_keys_to_remove[] = 'overdue';
 485      }
 486  
 487      if( $p_columns_target == COLUMNS_TARGET_CSV_PAGE || $p_columns_target == COLUMNS_TARGET_EXCEL_PAGE || OFF == config_get( 'show_attachment_indicator' ) ) {
 488          $t_keys_to_remove[] = 'attachment';
 489      }
 490  
 491      $t_current_project_id = helper_get_current_project();
 492  
 493      if( $t_current_project_id != ALL_PROJECTS && !access_has_project_level( config_get( 'view_handler_threshold' ), $t_current_project_id ) ) {
 494          $t_keys_to_remove[] = 'handler_id';
 495      }
 496  
 497      if( $t_current_project_id != ALL_PROJECTS && !access_has_project_level( config_get( 'roadmap_view_threshold' ), $t_current_project_id ) ) {
 498          $t_keys_to_remove[] = 'target_version';
 499      }
 500  
 501      foreach( $t_keys_to_remove as $t_key_to_remove ) {
 502          $t_keys = array_keys( $t_columns, $t_key_to_remove );
 503  
 504          foreach( $t_keys as $t_key ) {
 505              unset( $t_columns[$t_key] );
 506          }
 507      }
 508  
 509      # get the array values to remove gaps in the array which causes issue
 510      # if the array is accessed using an index.
 511      return array_values( $t_columns );
 512  }
 513  
 514  /**
 515   * if all projects selected, default to <prefix><username><suffix><extension>, otherwise default to
 516   * <prefix><projectname><suffix><extension>.
 517   * @param string $p_extension_with_dot
 518   * @param string $p_prefix
 519   * @param string $p_suffix
 520   * @return string
 521   */
 522  function helper_get_default_export_filename( $p_extension_with_dot, $p_prefix = '', $p_suffix = '' ) {
 523      $t_filename = $p_prefix;
 524  
 525      $t_current_project_id = helper_get_current_project();
 526  
 527      if( ALL_PROJECTS == $t_current_project_id ) {
 528          $t_filename .= user_get_name( auth_get_current_user_id() );
 529      } else {
 530          $t_filename .= project_get_field( $t_current_project_id, 'name' );
 531      }
 532  
 533      return $t_filename . $p_suffix . $p_extension_with_dot;
 534  }
 535  
 536  /**
 537   * returns a tab index value and increments it by one.  This is used to give sequential tab index on a form.
 538   * @return int
 539   */
 540  function helper_get_tab_index_value() {
 541      static $tab_index = 0;
 542      return ++$tab_index;
 543  }
 544  
 545  /**
 546   * returns a tab index and increments internal state by 1.  This is used to give sequential tab index on
 547   * a form.  For example, this function returns: tabindex="1"
 548   * @return string
 549   */
 550  function helper_get_tab_index() {
 551      return 'tabindex="' . helper_get_tab_index_value() . '"';
 552  }
 553  
 554  /**
 555   * returns a boolean indicating whether SQL queries executed should be shown or not.
 556   * @return bool
 557   */
 558  function helper_log_to_page() {
 559      # Check is authenticated before checking access level, otherwise user gets
 560      # redirected to login_page.php.  See #8461.
 561      return config_get_global( 'log_destination' ) === 'page' && auth_is_user_authenticated() && access_has_global_level( config_get( 'show_log_threshold' ) );
 562  }
 563  
 564  /**
 565   * returns a boolean indicating whether SQL queries executed should be shown or not.
 566   * @return bool
 567   */
 568  function helper_show_query_count() {
 569      return ON == config_get( 'show_queries_count' );
 570  }
 571  
 572  /**
 573   * Return a URL relative to the web root, compatible with other applications
 574   * @param string $p_url
 575   * @return string
 576   */
 577  function helper_mantis_url( $p_url ) {
 578      if( is_blank( $p_url ) ) {
 579          return $p_url;
 580      }
 581      return config_get_global( 'short_path' ) . $p_url;
 582  }
 583  
 584  /**
 585   * convert a duration string in "[h]h:mm" to an integer (minutes)
 586   * @param string $p_hhmm
 587   * @return int
 588   */
 589  function helper_duration_to_minutes( $p_hhmm ) {
 590      if( is_blank( $p_hhmm ) ) {
 591          return 0;
 592      }
 593  
 594      $t_a = explode( ':', $p_hhmm );
 595      $t_min = 0;
 596  
 597      // time can be composed of max 3 parts (hh:mm:ss)
 598      if( count( $t_a ) > 3 ) {
 599          error_parameters( 'p_hhmm', $p_hhmm );
 600          trigger_error( ERROR_CONFIG_OPT_INVALID, ERROR );
 601      }
 602  
 603      $t_count = count( $t_a );
 604      for( $i = 0;$i < $t_count;$i++ ) {
 605          // all time parts should be integers and non-negative.
 606          if( !is_numeric( $t_a[$i] ) || ( (integer) $t_a[$i] < 0 ) ) {
 607              error_parameters( 'p_hhmm', $p_hhmm );
 608              trigger_error( ERROR_CONFIG_OPT_INVALID, ERROR );
 609          }
 610  
 611          // minutes and seconds are not allowed to exceed 59.
 612          if(( $i > 0 ) && ( $t_a[$i] > 59 ) ) {
 613              error_parameters( 'p_hhmm', $p_hhmm );
 614              trigger_error( ERROR_CONFIG_OPT_INVALID, ERROR );
 615          }
 616      }
 617  
 618      switch( $t_count ) {
 619          case 1:
 620              $t_min = (integer) $t_a[0];
 621              break;
 622          case 2:
 623              $t_min = (integer) $t_a[0] * 60 + (integer) $t_a[1];
 624              break;
 625          case 3:
 626              // if seconds included, approxiate it to minutes
 627              $t_min = (integer) $t_a[0] * 60 + (integer) $t_a[1];
 628  
 629              if( (integer) $t_a[2] >= 30 ) {
 630                  $t_min++;
 631              }
 632              break;
 633      }
 634  
 635      return (int) $t_min;
 636  }


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7