| [ Index ] |
PHP Cross Reference of MantisBT |
[Summary view] [Print] [Text view]
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 * Install Helper Functions API 19 * 20 * @package CoreAPI 21 * @subpackage InstallHelperFunctionsAPI 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 database_api.php 27 */ 28 29 require_api( 'database_api.php' ); 30 31 /** 32 * Checks a PHP version number against the version of PHP currently in use 33 * @param string $p_version Version string to compare 34 * @return bool true if the PHP version in use is equal to or greater than the supplied version string 35 */ 36 function check_php_version( $p_version ) { 37 if( $p_version == PHP_MIN_VERSION ) { 38 return true; 39 } else { 40 if( function_exists( 'version_compare' ) ) { 41 if( version_compare( phpversion(), PHP_MIN_VERSION, '>=' ) ) { 42 return true; 43 } else { 44 return false; 45 } 46 } else { 47 return false; 48 } 49 } 50 } 51 52 /** 53 * Legacy pre-1.2 date function used for upgrading from datetime to integer 54 * representation of dates in the database. 55 * @return string Formatted date representing unixtime(0) + 1 second, ready for database insertion 56 */ 57 function db_null_date() { 58 global $g_db; 59 60 return $g_db->BindTimestamp( $g_db->UserTimeStamp( 1, 'Y-m-d H:i:s', true ) ); 61 } 62 63 /** 64 * Legacy pre-1.2 date function used for upgrading from datetime to integer 65 * representation of dates in the database. This function converts a formatted 66 * datetime string to an that represents the number of seconds elapsed since 67 * the Unix epoch. 68 * @param string $p_date Formatted datetime string from a database 69 * @param bool $p_gmt Whether to use UTC (true) or server timezone (false, default) 70 * @return int Unix timestamp representation of a datetime string 71 * @todo Review date handling 72 */ 73 function db_unixtimestamp( $p_date = null, $p_gmt = false ) { 74 global $g_db; 75 76 if( null !== $p_date ) { 77 $p_timestamp = $g_db->UnixTimeStamp( $p_date, $p_gmt ); 78 } else { 79 $p_timestamp = time(); 80 } 81 return $p_timestamp; 82 } 83 84 /** 85 * Migrate the legacy category data to the new category_id-based schema. 86 */ 87 function install_category_migrate() { 88 global $g_db_log_queries; 89 90 $t_bug_table = db_get_table( 'bug' ); 91 $t_category_table = db_get_table( 'category' ); 92 $t_project_category_table = db_get_table( 'project_category' ); 93 94 // disable query logging (even if it's enabled in config for this) 95 if ( $g_db_log_queries !== 0 ) { 96 $t_log_queries = $g_db_log_queries; 97 $g_db_log_queries = 0; 98 } else { 99 $t_log_queries = null; 100 } 101 102 $query = "SELECT project_id, category, user_id FROM $t_project_category_table ORDER BY project_id, category"; 103 $t_category_result = db_query_bound( $query ); 104 105 $query = "SELECT project_id, category FROM $t_bug_table ORDER BY project_id, category"; 106 $t_bug_result = db_query_bound( $query ); 107 108 $t_data = Array(); 109 110 # Find categories specified by project 111 while( $row = db_fetch_array( $t_category_result ) ) { 112 $t_project_id = $row['project_id']; 113 $t_name = $row['category']; 114 $t_data[$t_project_id][$t_name] = $row['user_id']; 115 } 116 117 # Find orphaned categories from bugs 118 while( $row = db_fetch_array( $t_bug_result ) ) { 119 $t_project_id = $row['project_id']; 120 $t_name = $row['category']; 121 122 if ( !isset( $t_data[$t_project_id][$t_name] ) ) { 123 $t_data[$t_project_id][$t_name] = 0; 124 } 125 } 126 127 # In every project, go through all the categories found, and create them and update the bug 128 foreach( $t_data as $t_project_id => $t_categories ) { 129 $t_inserted = array(); 130 foreach( $t_categories as $t_name => $t_user_id ) { 131 $t_lower_name = utf8_strtolower( trim( $t_name ) ); 132 if ( !isset( $t_inserted[$t_lower_name] ) ) { 133 $query = "INSERT INTO $t_category_table ( name, project_id, user_id ) VALUES ( " . 134 db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; 135 db_query_bound( $query, array( $t_name, $t_project_id, $t_user_id ) ); 136 $t_category_id = db_insert_id( $t_category_table ); 137 $t_inserted[$t_lower_name] = $t_category_id; 138 } else { 139 $t_category_id = $t_inserted[$t_lower_name]; 140 } 141 142 $query = "UPDATE $t_bug_table SET category_id=" . db_param() . ' 143 WHERE project_id=' . db_param() . ' AND category=' . db_param(); 144 db_query_bound( $query, array( $t_category_id, $t_project_id, $t_name ) ); 145 } 146 } 147 148 // re-enabled query logging if we disabled it 149 if ( $t_log_queries !== null ) { 150 $g_db_log_queries = $t_log_queries; 151 } 152 153 # return 2 because that's what ADOdb/DataDict does when things happen properly 154 return 2; 155 } 156 157 function install_date_migrate( $p_data) { 158 // $p_data[0] = tablename, [1] id column, [2] = old column, [3] = new column 159 global $g_db_log_queries; 160 161 // disable query logging (even if it's enabled in config for this) 162 if ( $g_db_log_queries !== 0 ) { 163 $t_log_queries = $g_db_log_queries; 164 $g_db_log_queries = 0; 165 } else { 166 $t_log_queries = null; 167 } 168 169 $t_table = $p_data[0]; 170 $t_id_column = $p_data[1]; 171 172 if ( is_array( $p_data[2] ) ) { 173 $t_old_column = implode( ',', $p_data[2] ); 174 $t_date_array = true; 175 $t_cnt_fields = count( $p_data[2] ); 176 $t_pairs = array(); 177 foreach( $p_data[3] as $var ) { 178 array_push( $t_pairs, "$var=" . db_param() ) ; 179 } 180 $t_new_column = implode( ',', $t_pairs ); 181 $query = "SELECT $t_id_column, $t_old_column FROM $t_table"; 182 183 $t_first_column = true; 184 185 # In order to handle large databases where we may timeout during the upgrade, we don't 186 # start form the beginning everytime. Here we will only pickup rows where at least one 187 # of the datetime fields wasn't upgraded yet and upgrade them all. 188 foreach ( $p_data[3] as $t_new_column_name ) { 189 if ( $t_first_column ) { 190 $t_first_column = false; 191 $query .= ' WHERE '; 192 } else { 193 $query .= ' OR '; 194 } 195 196 $query .= "$t_new_column_name = 1"; 197 } 198 } else { 199 $t_old_column = $p_data[2]; 200 $t_new_column = $p_data[3] . "=" . db_param(); 201 $t_date_array = false; 202 203 # The check for timestamp being = 1 is to make sure the field wasn't upgraded 204 # already in a previous run - see bug #12601 for more details. 205 $t_new_column_name = $p_data[3]; 206 $query = "SELECT $t_id_column, $t_old_column FROM $t_table WHERE $t_new_column_name = 1"; 207 } 208 209 $t_result = db_query_bound( $query ); 210 211 while( $row = db_fetch_array( $t_result ) ) { 212 $t_id = (int)$row[$t_id_column]; 213 214 if( $t_date_array ) { 215 for( $i=0; $i < $t_cnt_fields; $i++ ) { 216 $t_old_value = $row[$p_data[2][$i]]; 217 218 $t_new_value[$i] = db_unixtimestamp($t_old_value); 219 if ($t_new_value[$i] < 100000 ) { 220 $t_new_value[$i] = 1; 221 } 222 } 223 $t_values = $t_new_value; 224 $t_values[] = $t_id; 225 } else { 226 $t_old_value = $row[$t_old_column]; 227 228 $t_new_value = db_unixtimestamp($t_old_value); 229 if ($t_new_value < 100000 ) { 230 $t_new_value = 1; 231 } 232 $t_values = array( $t_new_value, $t_id); 233 } 234 235 $query = "UPDATE $t_table SET $t_new_column 236 WHERE $t_id_column=" . db_param(); 237 db_query_bound( $query, $t_values ); 238 } 239 240 // re-enabled query logging if we disabled it 241 if ( $t_log_queries !== null ) { 242 $g_db_log_queries = $t_log_queries; 243 } 244 245 # return 2 because that's what ADOdb/DataDict does when things happen properly 246 return 2; 247 248 } 249 250 /** 251 * Once upon a time multi-select custom field types (checkbox and multiselect) 252 * were stored in the database in the format of "option1|option2|option3" where 253 * they should have been stored in a format of "|option1|option2|option3|". 254 * Additionally, radio custom field types were being stored in the database 255 * with an unnecessary vertical pipe prefix and suffix when there is only ever 256 * one possible value that can be assigned to a radio field. 257 */ 258 function install_correct_multiselect_custom_fields_db_format() { 259 global $g_db_log_queries; 260 261 # Disable query logging due to possibility of mass spam. 262 if ( $g_db_log_queries !== 0 ) { 263 $t_log_queries = $g_db_log_queries; 264 $g_db_log_queries = 0; 265 } else { 266 $t_log_queries = null; 267 } 268 269 $t_value_table = db_get_table( 'custom_field_string' ); 270 $t_field_table = db_get_table( 'custom_field' ); 271 272 # Ensure multilist and checkbox custom field values have a vertical pipe | 273 # as a prefix and suffix. 274 $t_query = "SELECT v.field_id, v.bug_id, v.value from $t_value_table v 275 LEFT JOIN $t_field_table c 276 ON v.field_id = c.id 277 WHERE (c.type = " . CUSTOM_FIELD_TYPE_MULTILIST . " OR c.type = " . CUSTOM_FIELD_TYPE_CHECKBOX . ") 278 AND v.value != '' 279 AND v.value NOT LIKE '|%|'"; 280 $t_result = db_query_bound( $t_query ); 281 282 while( $t_row = db_fetch_array( $t_result ) ) { 283 $c_field_id = (int)$t_row['field_id']; 284 $c_bug_id = (int)$t_row['bug_id']; 285 $c_value = '|' . rtrim( ltrim( $t_row['value'], '|' ), '|' ) . '|'; 286 $t_update_query = "UPDATE $t_value_table 287 SET value = '$c_value' 288 WHERE field_id = $c_field_id 289 AND bug_id = $c_bug_id"; 290 $t_update_result = db_query_bound( $t_update_query ); 291 } 292 293 # Remove vertical pipe | prefix and suffix from radio custom field values. 294 $t_query = "SELECT v.field_id, v.bug_id, v.value from $t_value_table v 295 LEFT JOIN $t_field_table c 296 ON v.field_id = c.id 297 WHERE c.type = " . CUSTOM_FIELD_TYPE_RADIO . " 298 AND v.value != '' 299 AND v.value LIKE '|%|'"; 300 $t_result = db_query_bound( $t_query ); 301 302 while( $t_row = db_fetch_array( $t_result ) ) { 303 $c_field_id = (int)$t_row['field_id']; 304 $c_bug_id = (int)$t_row['bug_id']; 305 $c_value = rtrim( ltrim( $t_row['value'], '|' ), '|' ); 306 $t_update_query = "UPDATE $t_value_table 307 SET value = '$c_value' 308 WHERE field_id = $c_field_id 309 AND bug_id = $c_bug_id"; 310 $t_update_result = db_query_bound( $t_update_query ); 311 } 312 313 # Re-enable query logging if we disabled it. 314 if ( $t_log_queries !== null ) { 315 $g_db_log_queries = $t_log_queries; 316 } 317 318 # Return 2 because that's what ADOdb/DataDict does when things happen properly 319 return 2; 320 } 321 322 /** 323 * The filters have been changed so the field names are the same as the database 324 * field names. This updates any filters stored in the database to use the correct 325 * keys. The 'and_not_assigned' field is no longer used as it is replaced by the meta 326 * filter None. This removes it from all filters. 327 */ 328 function install_stored_filter_migrate() { 329 global $g_db_log_queries; 330 331 # Disable query logging due to possibility of mass spam. 332 if ( $g_db_log_queries !== 0 ) { 333 $t_log_queries = $g_db_log_queries; 334 $g_db_log_queries = 0; 335 } else { 336 $t_log_queries = null; 337 } 338 339 require_api( 'filter_api.php' ); 340 341 $t_cookie_version = config_get( 'cookie_version' ); 342 343 # convert filters to use the same value for the filter key and the form field 344 $t_filter_fields['show_category'] = 'category_id'; 345 $t_filter_fields['show_severity'] = 'severity'; 346 $t_filter_fields['show_status'] = 'status'; 347 $t_filter_fields['show_priority'] = 'priority'; 348 $t_filter_fields['show_resolution'] = 'resolution'; 349 $t_filter_fields['show_build'] = 'build'; 350 $t_filter_fields['show_version'] = 'version'; 351 $t_filter_fields['user_monitor'] = 'monitor_user_id'; 352 $t_filter_fields['show_profile'] = 'profile_id'; 353 $t_filter_fields['do_filter_by_date'] = 'filter_by_date'; 354 $t_filter_fields['and_not_assigned'] = null; 355 $t_filter_fields['sticky_issues'] = 'sticky'; 356 357 $t_filters_table = db_get_table( 'filters' ); 358 $t_query = "SELECT * FROM $t_filters_table"; 359 $t_result = db_query_bound( $t_query ); 360 while( $t_row = db_fetch_array( $t_result ) ) { 361 $t_filter_arr = filter_deserialize( $t_row['filter_string'] ); 362 foreach( $t_filter_fields AS $t_old=>$t_new ) { 363 if ( isset( $t_filter_arr[$t_old] ) ) { 364 $t_value = $t_filter_arr[$t_old]; 365 unset( $t_filter_arr[$t_old] ); 366 if( !is_null( $t_new ) ) { 367 $t_filter_arr[$t_new] = $t_value; 368 } 369 } 370 } 371 372 $t_filter_serialized = serialize( $t_filter_arr ); 373 $t_filter_string = $t_cookie_version . '#' . $t_filter_serialized; 374 375 $t_update_query = "UPDATE $t_filters_table SET filter_string=" . db_param() . ' WHERE id=' . db_param(); 376 $t_update_result = db_query_bound( $t_update_query, array( $t_filter_string, $t_row['id'] ) ); 377 } 378 379 # Re-enable query logging if we disabled it. 380 if ( $t_log_queries !== null ) { 381 $g_db_log_queries = $t_log_queries; 382 } 383 384 # Return 2 because that's what ADOdb/DataDict does when things happen properly 385 return 2; 386 } 387 388 function install_do_nothing() { 389 # return 2 because that's what ADOdb/DataDict does when things happen properly 390 return 2; 391 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jul 28 15:48:31 2011 | Cross-referenced by PHPXref 0.7 |