[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/api/soap/ -> mc_api.php (source)

   1  <?php
   2  # MantisConnect - A webservice interface to Mantis Bug Tracker
   3  # Copyright (C) 2004-2011  Victor Boctor - vboctor@users.sourceforge.net
   4  # This program is distributed under dual licensing.  These include
   5  # GPL and a commercial licenses.  Victor Boctor reserves the right to
   6  # change the license of future releases.
   7  # See docs/ folder for more details
   8  
   9  # set up error_handler() as the new default error handling function
  10  set_error_handler( 'mc_error_handler' );
  11  
  12  # override some MantisBT configurations
  13  $g_show_detailed_errors = OFF;
  14  $g_stop_on_errors = ON;
  15  $g_display_errors = array(
  16      E_WARNING => 'halt',
  17      E_NOTICE => 'halt',
  18      E_USER_ERROR => 'halt',
  19      E_USER_WARNING => 'halt',
  20      E_USER_NOTICE => 'halt',
  21  );
  22  
  23  /**
  24   * Get the MantisConnect webservice version.
  25   */
  26  function mc_version() {
  27      return MANTIS_VERSION;
  28  }
  29  
  30  # Checks if MantisBT installation is marked as offline by the administrator.
  31  # true: offline, false: online
  32  function mci_is_mantis_offline() {
  33      $t_offline_file = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'mantis_offline.php';
  34      return file_exists( $t_offline_file );
  35  }
  36  
  37  # return user_id if successful, otherwise false.
  38  function mci_check_login( $p_username, $p_password ) {
  39      if( mci_is_mantis_offline() ) {
  40          return false;
  41      }
  42  
  43      # if no user name supplied, then attempt to login as anonymous user.
  44      if( is_blank( $p_username ) ) {
  45          $t_anon_allowed = config_get( 'allow_anonymous_login' );
  46          if( OFF == $t_anon_allowed ) {
  47              return false;
  48          }
  49  
  50          $p_username = config_get( 'anonymous_account' );
  51  
  52          # do not use password validation.
  53          $p_password = null;
  54      }
  55  
  56      if( false === auth_attempt_script_login( $p_username, $p_password ) ) {
  57          return false;
  58      }
  59  
  60      return auth_get_current_user_id();
  61  }
  62  
  63  function mci_has_readonly_access( $p_user_id, $p_project_id = ALL_PROJECTS ) {
  64      $t_access_level = user_get_access_level( $p_user_id, $p_project_id );
  65      return( $t_access_level >= config_get( 'mc_readonly_access_level_threshold' ) );
  66  }
  67  
  68  function mci_has_readwrite_access( $p_user_id, $p_project_id = ALL_PROJECTS ) {
  69      $t_access_level = user_get_access_level( $p_user_id, $p_project_id );
  70      return( $t_access_level >= config_get( 'mc_readwrite_access_level_threshold' ) );
  71  }
  72  
  73  function mci_has_access( $p_access_level, $p_user_id, $p_project_id = ALL_PROJECTS ) {
  74      $t_access_level = user_get_access_level( $p_user_id, $p_project_id );
  75      return( $t_access_level >= (int) $p_access_level );
  76  }
  77  
  78  function mci_has_administrator_access( $p_user_id, $p_project_id = ALL_PROJECTS ) {
  79      $t_access_level = user_get_access_level( $p_user_id, $p_project_id );
  80      return( $t_access_level >= config_get( 'mc_admin_access_level_threshold' ) );
  81  }
  82  
  83  function mci_get_project_id( $p_project ) {
  84      if( (int) $p_project['id'] != 0 ) {
  85          $t_project_id = (int) $p_project['id'];
  86      } else {
  87          $t_project_id = project_get_id_by_name( $p_project['name'] );
  88      }
  89  
  90      return $t_project_id;
  91  }
  92  
  93  function mci_get_project_status_id( $p_status ) {
  94      return mci_get_enum_id_from_objectref( 'project_status', $p_status );
  95  }
  96  
  97  function mci_get_project_view_state_id( $p_view_state ) {
  98      return mci_get_enum_id_from_objectref( 'project_view_state', $p_view_state );
  99  }
 100  
 101  function mci_get_user_id( $p_user ) {
 102      $t_user_id = 0;
 103  
 104      if ( isset( $p_user['id'] ) && (int) $p_user['id'] != 0 ) {
 105          $t_user_id = (int) $p_user['id'];
 106      } elseif ( isset( $p_user['name'] ) ) {
 107          $t_user_id = user_get_id_by_name( $p_user['name'] );
 108      }
 109  
 110      return $t_user_id;
 111  }
 112  
 113  function mci_get_user_lang( $p_user_id ) {
 114      $t_lang = user_pref_get_pref( $p_user_id, 'language' );
 115      if( $t_lang == 'auto' ) {
 116          $t_lang = config_get( 'fallback_language' );
 117      }
 118      return $t_lang;
 119  }
 120  
 121  function mci_get_status_id( $p_status ) {
 122      return mci_get_enum_id_from_objectref( 'status', $p_status );
 123  }
 124  
 125  function mci_get_severity_id( $p_severity ) {
 126      return mci_get_enum_id_from_objectref( 'severity', $p_severity );
 127  }
 128  
 129  function mci_get_priority_id( $p_priority ) {
 130  
 131      return mci_get_enum_id_from_objectref( 'priority', $p_priority );
 132  }
 133  
 134  function mci_get_reproducibility_id( $p_reproducibility ) {
 135      return mci_get_enum_id_from_objectref( 'reproducibility', $p_reproducibility );
 136  }
 137  
 138  function mci_get_resolution_id( $p_resolution ) {
 139      return mci_get_enum_id_from_objectref( 'resolution', $p_resolution );
 140  }
 141  
 142  function mci_get_projection_id( $p_projection ) {
 143      return mci_get_enum_id_from_objectref( 'projection', $p_projection );
 144  }
 145  
 146  function mci_get_eta_id( $p_eta ) {
 147      return mci_get_enum_id_from_objectref( 'eta', $p_eta );
 148  }
 149  
 150  function mci_get_view_state_id( $p_view_state ) {
 151      return mci_get_enum_id_from_objectref( 'view_state', $p_view_state );
 152  }
 153  
 154  # Get null on empty value.
 155  #
 156  # @param Object $p_value  The value
 157  # @return Object  The value if not empty; null otherwise.
 158  #
 159  function mci_null_if_empty( $p_value ) {
 160      if( !is_blank( $p_value ) ) {
 161          return $p_value;
 162      }
 163  
 164      return null;
 165  }
 166  
 167  /**
 168   * Gets the url for MantisBT.
 169   *
 170   * @return MantisBT URL terminated by a /.
 171   */
 172  function mci_get_mantis_path() {
 173      
 174      return config_get( 'path' );
 175  }
 176  
 177  # Given a enum string and num, return the appropriate localized string
 178  function mci_get_enum_element( $p_enum_name, $p_val, $p_lang ) {
 179      $t_enum_string = config_get( $p_enum_name . '_enum_string' );
 180      $t_localized_enum_string = lang_get( $p_enum_name . '_enum_string', $p_lang );
 181  
 182      return MantisEnum::getLocalizedLabel( $t_enum_string, $t_localized_enum_string, $p_val );
 183  }
 184  
 185  # Gets the sub-projects that are accessible to the specified user / project.
 186  function mci_user_get_accessible_subprojects( $p_user_id, $p_parent_project_id, $p_lang = null ) {
 187      if( $p_lang === null ) {
 188          $t_lang = mci_get_user_lang( $p_user_id );
 189      } else {
 190          $t_lang = $p_lang;
 191      }
 192  
 193      $t_result = array();
 194      foreach( user_get_accessible_subprojects( $p_user_id, $p_parent_project_id ) as $t_subproject_id ) {
 195          $t_subproject_row = project_cache_row( $t_subproject_id );
 196          $t_subproject = array();
 197          $t_subproject['id'] = $t_subproject_id;
 198          $t_subproject['name'] = $t_subproject_row['name'];
 199          $t_subproject['status'] = mci_enum_get_array_by_id( $t_subproject_row['status'], 'project_status', $t_lang );
 200          $t_subproject['enabled'] = $t_subproject_row['enabled'];
 201          $t_subproject['view_state'] = mci_enum_get_array_by_id( $t_subproject_row['view_state'], 'project_view_state', $t_lang );
 202          $t_subproject['access_min'] = mci_enum_get_array_by_id( $t_subproject_row['access_min'], 'access_levels', $t_lang );
 203          $t_subproject['file_path'] = array_key_exists( 'file_path', $t_subproject_row ) ? $t_subproject_row['file_path'] : "";
 204          $t_subproject['description'] = array_key_exists( 'description', $t_subproject_row ) ? $t_subproject_row['description'] : "";
 205          $t_subproject['subprojects'] = mci_user_get_accessible_subprojects( $p_user_id, $t_subproject_id, $t_lang );
 206          $t_result[] = $t_subproject;
 207      }
 208  
 209      return $t_result;
 210  }
 211  
 212  function translate_category_name_to_id( $p_category_name, $p_project_id ) {
 213      if ( !isset( $p_category_name ) ) {
 214          return 0;
 215      }
 216  
 217      $t_cat_array = category_get_all_rows( $p_project_id );
 218      foreach( $t_cat_array as $t_category_row ) {
 219          if( $t_category_row['name'] == $p_category_name ) {
 220              return $t_category_row['id'];
 221          }
 222      }
 223      return 0;
 224  }
 225  
 226  /**
 227   * Basically this is a copy of core/filter_api.php#filter_db_get_available_queries().
 228   * The only difference is that the result of this function is not an array of filter
 229   * names but an array of filter structures.
 230   */
 231  function mci_filter_db_get_available_queries( $p_project_id = null, $p_user_id = null ) {
 232      $t_filters_table = db_get_table( 'filters' );
 233      $t_overall_query_arr = array();
 234  
 235      if( null === $p_project_id ) {
 236          $t_project_id = helper_get_current_project();
 237      } else {
 238          $t_project_id = db_prepare_int( $p_project_id );
 239      }
 240  
 241      if( null === $p_user_id ) {
 242          $t_user_id = auth_get_current_user_id();
 243      } else {
 244          $t_user_id = db_prepare_int( $p_user_id );
 245      }
 246  
 247      # If the user doesn't have access rights to stored queries, just return
 248      if( !access_has_project_level( config_get( 'stored_query_use_threshold' ) ) ) {
 249          return $t_overall_query_arr;
 250      }
 251  
 252      # Get the list of available queries. By sorting such that public queries are
 253      # first, we can override any query that has the same name as a private query
 254      # with that private one
 255      $query = "SELECT * FROM $t_filters_table
 256                  WHERE (project_id='$t_project_id'
 257                  OR project_id='0')
 258                  AND name!=''
 259                  ORDER BY is_public DESC, name ASC";
 260      $result = db_query( $query );
 261      $query_count = db_num_rows( $result );
 262  
 263      for( $i = 0;$i < $query_count;$i++ ) {
 264          $row = db_fetch_array( $result );
 265          if(( $row['user_id'] == $t_user_id ) || db_prepare_bool( $row['is_public'] ) ) {
 266  
 267              $t_filter_detail = explode( '#', $row['filter_string'], 2 );
 268              if ( !isset($t_filter_detail[1]) ) {
 269                  continue;
 270              }
 271              $t_filter = unserialize( $t_filter_detail[1] );
 272              $t_filter = filter_ensure_valid_filter( $t_filter );
 273              $row['url'] = filter_get_url( $t_filter );
 274              $t_overall_query_arr[$row['name']] = $row;
 275          }
 276      }
 277  
 278      return array_values( $t_overall_query_arr );
 279  }
 280  
 281  /**
 282   * Get a category definition.
 283   *
 284   * @param integer $p_category_id  The id of the category to retrieve.
 285   * @return Array an Array containing the id and the name of the category.
 286   */
 287  function mci_category_as_array_by_id( $p_category_id ) {
 288      $t_result = array();
 289      $t_result['id'] = $p_category_id;
 290      $t_result['name'] = category_get_name( $p_category_id );
 291      return $t_result;
 292  }
 293  
 294  /**
 295   * Transforms a version array into an array suitable for marshalling into ProjectVersionData
 296   * 
 297   * @param array $p_version
 298   */
 299  function mci_project_version_as_array( $p_version ) {
 300      
 301      return array(
 302              'id' => $p_version['id'],
 303              'name' => $p_version['version'],
 304              'project_id' => $p_version['project_id'],
 305              'date_order' => timestamp_to_iso8601( $p_version['date_order'] ),
 306              'description' => mci_null_if_empty( $p_version['description'] ),
 307              'released' => $p_version['released'],
 308              'obsolete' => $p_version['obsolete']
 309          );
 310  }
 311  
 312  /**
 313   * Returns time tracking information from a bug note.
 314   *
 315   * @param int $p_issue_id The id of the issue
 316   * @param Array $p_note A note as passed to the soap api methods
 317   *
 318   * @return String the string time entry to be added to the bugnote, in 'HH:mm' format
 319   */
 320  function mci_get_time_tracking_from_note( $p_issue_id, $p_note) {
 321  
 322      if ( !access_has_bug_level( config_get( 'time_tracking_view_threshold' ), $p_issue_id ) )
 323          return '00:00';
 324  
 325      if ( !isset( $p_note['time_tracking'] ))
 326          return '00:00';
 327  
 328      return db_minutes_to_hhmm($p_note['time_tracking']);
 329  }
 330  
 331  /**
 332   * SECURITY NOTE: these globals are initialized here to prevent them
 333   * being spoofed if register_globals is turned on
 334   */
 335  $g_error_parameters = array();
 336  $g_error_handled = false;
 337  $g_error_proceed_url = null;
 338  
 339  # Default error handler
 340  #
 341  # This handler will not receive E_ERROR, E_PARSE, E_CORE_*, or E_COMPILE_*
 342  #  errors.
 343  #
 344  # E_USER_* are triggered by us and will contain an error constant in $p_error
 345  # The others, being system errors, will come with a string in $p_error
 346  #
 347  function mc_error_handler( $p_type, $p_error, $p_file, $p_line, $p_context ) {
 348      global $g_error_parameters, $g_error_handled, $g_error_proceed_url;
 349      global $g_lang_overrides;
 350      global $g_error_send_page_header;
 351      global $l_oServer;
 352  
 353      # check if errors were disabled with @ somewhere in this call chain
 354      # also suppress php 5 strict warnings
 355      if( 0 == error_reporting() || 2048 == $p_type ) {
 356          return;
 357      }
 358  
 359      $t_lang_pushed = false;
 360  
 361      # flush any language overrides to return to user's natural default
 362      if( function_exists( 'db_is_connected' ) ) {
 363          if( db_is_connected() ) {
 364              lang_push( lang_get_default() );
 365              $t_lang_pushed = true;
 366          }
 367      }
 368  
 369      $t_short_file = basename( $p_file );
 370      $t_method_array = config_get( 'display_errors' );
 371      if( isset( $t_method_array[$p_type] ) ) {
 372          $t_method = $t_method_array[$p_type];
 373      } else {
 374          $t_method = 'none';
 375      }
 376  
 377      # build an appropriate error string
 378      switch( $p_type ) {
 379          case E_WARNING:
 380              $t_error_type = 'SYSTEM WARNING';
 381              $t_error_description = $p_error;
 382              break;
 383          case E_NOTICE:
 384              $t_error_type = 'SYSTEM NOTICE';
 385              $t_error_description = $p_error;
 386              break;
 387          case E_USER_ERROR:
 388              $t_error_type = "APPLICATION ERROR #$p_error";
 389              $t_error_description = error_string( $p_error );
 390              break;
 391          case E_USER_WARNING:
 392              $t_error_type = "APPLICATION WARNING #$p_error";
 393              $t_error_description = error_string( $p_error );
 394              break;
 395          case E_USER_NOTICE:
 396  
 397              # used for debugging
 398              $t_error_type = 'DEBUG';
 399              $t_error_description = $p_error;
 400              break;
 401          default:
 402  
 403              #shouldn't happen, just display the error just in case
 404              $t_error_type = '';
 405              $t_error_description = $p_error;
 406      }
 407  
 408      $t_error_description = $t_error_description;
 409      $t_error_stack = error_get_stack_trace();
 410  
 411      $l_oServer->fault( 'Server', "Error Type: $t_error_type,\nError Description:\n$t_error_description,\nStack Trace:\n$t_error_stack" );
 412      $l_oServer->send_response();
 413      exit();
 414  }
 415  
 416  # Get a stack trace if PHP provides the facility or xdebug is present
 417  function error_get_stack_trace() {
 418      $t_trace = '';
 419  
 420      if ( extension_loaded( 'xdebug' ) ) {
 421  
 422          #check for xdebug presence
 423          $t_stack = xdebug_get_function_stack();
 424  
 425          # reverse the array in a separate line of code so the
 426          #  array_reverse() call doesn't appear in the stack
 427          $t_stack = array_reverse( $t_stack );
 428          array_shift( $t_stack );
 429  
 430          #remove the call to this function from the stack trace
 431          foreach( $t_stack as $t_frame ) {
 432              $t_trace .= ( isset( $t_frame['file'] ) ? basename( $t_frame['file'] ) : 'UnknownFile' ) . ' L' . ( isset( $t_frame['line'] ) ? $t_frame['line'] : '?' ) . ' ' . ( isset( $t_frame['function'] ) ? $t_frame['function'] : 'UnknownFunction' );
 433  
 434              $t_args = array();
 435              if ( isset( $t_frame['params'] ) && ( count( $t_frame['params'] ) > 0 ) ) {
 436                  $t_trace .= ' Params: ';
 437                  foreach( $t_frame['params'] as $t_value ) {
 438                      $t_args[] = error_build_parameter_string( $t_value );
 439                  }
 440  
 441                  $t_trace .= '(' . implode( $t_args, ', ' ) . ')';
 442              } else {
 443                  $t_trace .= '()';
 444              }
 445  
 446              $t_trace .= "\n";
 447          }
 448      } else {
 449          $t_stack = debug_backtrace();
 450  
 451          array_shift( $t_stack ); #remove the call to this function from the stack trace
 452          array_shift( $t_stack ); #remove the call to the error handler from the stack trace
 453  
 454          foreach( $t_stack as $t_frame ) {
 455              $t_trace .= ( isset( $t_frame['file'] ) ? basename( $t_frame['file'] ) : 'UnknownFile' ) . ' L' . ( isset( $t_frame['line'] ) ? $t_frame['line'] : '?' ) . ' ' . ( isset( $t_frame['function'] ) ? $t_frame['function'] : 'UnknownFunction' );
 456  
 457              $t_args = array();
 458              if( isset( $t_frame['args'] ) ) {
 459                  foreach( $t_frame['args'] as $t_value ) {
 460                      $t_args[] = error_build_parameter_string( $t_value );
 461                  }
 462  
 463                  $t_trace .= '(' . implode( $t_args, ', ' ) . ')';
 464              } else {
 465                  $t_trace .= '()';
 466              }
 467  
 468              $t_trace .= "\n";
 469          }
 470      }
 471  
 472      return $t_trace;
 473  }
 474  
 475  /**
 476   * Returns a soap_fault signalling corresponding to a failed login
 477   * situation
 478   *
 479   * @return soap_fault
 480   */
 481  function mci_soap_fault_login_failed() {
 482      return new soap_fault('Client', '', 'Access denied.');
 483  }
 484  
 485  /**
 486   * Returns a soap_fault signalling that the user does not have
 487   * access rights for the specific action.
 488   *
 489   * @param int $p_user_id a valid user id
 490   * @param string $p_detail The optional details to append to the error message
 491   * @return soap_fault
 492   */
 493  function mci_soap_fault_access_denied( $p_user_id, $p_detail = '' ) {
 494      $t_user_name = user_get_name( $p_user_id );
 495      $t_reason = 'Access denied for user '. $t_user_name . '.';
 496      if ( !is_blank( $p_detail ))
 497          $t_reason .= ' Reason: ' . $p_detail . '.';
 498  
 499      return new soap_fault( 'Client', '',  $t_reason );
 500  }


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