├── .gitignore ├── Csv_import.php ├── README.md ├── doc └── readme.txt ├── lang ├── strings_dutch.txt ├── strings_english.txt ├── strings_french.txt ├── strings_german.txt └── strings_italian.txt └── pages ├── config.php ├── config_edit.php ├── import_issues.php ├── import_issues_inc.php ├── import_issues_page_col_set.php └── import_issues_page_init.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /Csv_import.php: -------------------------------------------------------------------------------- 1 | name = plugin_lang_get( 'title' ); 6 | $this->description = plugin_lang_get( 'description' ); 7 | $this->version = '2.0.0'; 8 | $this->requires = array( 'MantisCore' => '2.0.0' ); 9 | $this->author = 'Bug 4220 Team'; 10 | $this->contact = 'https://github.com/mantisbt-plugins/csv-import/'; 11 | $this->url = 'https://github.com/mantisbt-plugins/csv-import/'; 12 | $this->page = 'config'; 13 | } 14 | 15 | function config() { 16 | return array( 17 | 'import_issues_threshold' => MANAGER , 18 | ); 19 | } 20 | 21 | function hooks() { 22 | return array( 23 | 'EVENT_MENU_MANAGE' => 'csv_import_menu', 24 | ); 25 | } 26 | 27 | function csv_import_menu() { 28 | return array( 29 | '' . plugin_lang_get( 'manage_issues_link' ) . '', 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CSV Issues Importer 2 | =================== 3 | 4 | A plugin that imports issues from CSV files. 5 | 6 | Install 7 | ------- 8 | 9 | - Download or clone the repository and place it under the MantisBT plugins folder. 10 | Make sure you get the correct version for your MantisBT (See [Compatibility](#compatibility) below). 11 | - Rename the folder to Csv_import (case sensitive) 12 | - Go to Manage - Manage Plugins and install the plugin. 13 | - Go to Manage - Import Issues 14 | 15 | Features 16 | -------- 17 | 18 | The plugin supports: 19 | 20 | - auto-creating users as part of import. 21 | - auto-creating categories as part of import. 22 | - custom fields importing. 23 | - importing as new issues. 24 | - updating issues after matching by ids. 25 | - updating issues after matching by selected fields assuming a single match. 26 | 27 | A few hints about usability 28 | --------------------------- 29 | 30 | - Have a separate csv file per project. 31 | - Switch to the project before importing. 32 | - If the goal is to add the rows from csv, then make sure to map Id fields (if in CSV) to be ignored. 33 | - If the id is supplied, then issues with be updated based on data from the csv after matching by id. 34 | - Users that are auto-created will 35 | - be disabled 36 | - have random passwords, 37 | - have email as `username@localhost`. 38 | 39 | Compatibility 40 | ------------- 41 | 42 | Depending on which version of MantisBT you are using, please make sure to 43 | get the appropriate version of the source code. 44 | Use [release tags](https://github.com/mantisbt-plugins/csv-import/releases), 45 | or the relevant branch in the Plugin's GitHub repository, as per the table below: 46 | 47 | MantisBT version | Plugin version | Branch 48 | :---:|:---:|--- 49 | 2.x | v2.x | [master](https://github.com/mantisbt-plugins/csv-import/archive/master.zip) 50 | 1.3.x | v1.5.x | [master-1.3.x](https://github.com/mantisbt-plugins/csv-import/archive/master-1.3.x.zip) 51 | 1.2.x | v1.4.1 | [master-1.2.x](https://github.com/mantisbt-plugins/csv-import/archive/master-1.2.x.zip) 52 | 53 | Support 54 | ------- 55 | 56 | Report issue in the [MantisBT bug tracker](https://mantisbt.org/bugs) 57 | under the **Plugin - CsvImport** project. 58 | 59 | However, please note that this plugin is not actively supported by its original authors. 60 | -------------------------------------------------------------------------------- /doc/readme.txt: -------------------------------------------------------------------------------- 1 | Mantis Issue Importer 2 | ===================== 3 | 4 | History: 5 | ________ 6 | 7 | Version | Author | Action 8 | -------------------------------------------------------------------------------------- 9 | 1.3.0b | lionheart33806 | Added "primay key" feature 10 | | (sorry for my english) | Bug fixes (updates were impossible, sometimes first column was ignored) 11 | | | Removed "alternative import" feature (original import is RFC compliant !!) 12 | | | Column detection is less strict 13 | | | Some HTML and PHP format corrections 14 | | | Corrected some errors display 15 | 1.2.0 | lionheart33806 | import_issues_page.php splitted to become 16 | | | import_issues_page_init.php and import_issues_page_col_set.php 17 | | | Can create unknown categories 18 | | | Little JS to use tab as separator 19 | 1.1.5 | lionheart33806 | Code closer of mantis coding conventions 20 | | | "all projects" categories reusable 21 | | | Can import "submitted date" with DD/MM/YYYY format 22 | | | Checkbox for alternative import 23 | | | because of double quotes 24 | | | Added helper_begin_long_process() for very long imports 25 | 1.1.4 | Stéphane Veyret | Add german version of jojow 26 | 1.1.3 | Stéphane Veyret | Make the strings "private" with plugin_lang_get 27 | | | Add french version 28 | 1.1.2 | Udo Sommer and Cas Nuy | Transformed into plugin 29 | 1.0 | Stéphane Veyret | Improvements 30 | (old) | ave | Importer creation 31 | 32 | 33 | Known Issues: 34 | _____________ 35 | 36 | * Please, see https://github.com/lionheart33806/Csv-import-4-MantisBT/issues 37 | 38 | 39 | Licence: 40 | ________ 41 | 42 | The licence of CSV Import remains untouched, means GPL, 43 | as stated in THE GPL. 44 | 45 | 46 | Installation: 47 | _____________ 48 | 49 | Create a "Csv_import" directory in "plugins" directory of mantis. 50 | Extract all the files in "Csv_import". 51 | 52 | In "Manage" module, you should find "Import CSV file". 53 | 54 | NB : "Csv_import" is case sensitive. 55 | 56 | 57 | Function: 58 | _________ 59 | 60 | Imports/update one or more issues from a CSV text file into the current project of Mantis. 61 | 62 | 63 | Requirements: 64 | _____________ 65 | 66 | Made for and tested against Mantis version 1.2.0 67 | 68 | 69 | Usage: 70 | ______ 71 | 72 | Take care that this importing functionality can make a mess in your database. It is recommanded that you make 73 | a backup of your database before importing. 74 | 75 | Dates can be given with timestamp, "European" (d-m-y) or American (m/d/y) format. 76 | 77 | 1. In the "Manage" menu, select "Import CSV file". 78 | 79 | 2. Select the file to import. Your file must be in a correct CSV format (see above), and must only contain 80 | importable columns. The first line of the file can be a title line. In that case do not forget to 81 | select "Skip first line". 82 | 83 | 3. Select the "Import file" button. 84 | 85 | 4. The importer will try to recognize if the file use standard column names, or the name as given in 86 | your current language. 87 | If the importer did not detect your columns automatically, select them. Please, always verify the columns. 88 | If you import many times from an another bug tracker, you should previously create a custom field which will contain 89 | the other bug tracker bug id. Then, check in "Primay key" column the line corresponding to the custom field. 90 | 91 | If you define a column as a mantis ID, "primary key" checkboxes will be ignored. 92 | 93 | 5. Select the "Import" button. 94 | 95 | 6. Review the results to ensure they are as expected. 96 | 97 | 98 | About CSV format: 99 | _________________ 100 | 101 | Be sure your file is RFC compliant 102 | Look at : 103 | http://tools.ietf.org/html/rfc4180 104 | or 105 | http://en.wikipedia.org/wiki/Comma-separated_values 106 | -------------------------------------------------------------------------------- /lang/strings_dutch.txt: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 |

22 | 23 | 24 |

25 |
26 |
27 |
28 |
29 |
30 | 31 |
32 | 33 |
34 | 37 | 42 | 43 | 44 |
35 | 36 | 38 | 41 |
45 |
46 |
47 |
48 | 49 |
50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | $value) { 69 | if ($value == 'ignore_column') { 70 | unset($f_columns[$key]); 71 | } 72 | } 73 | 74 | # Other columns check 75 | if( count( $f_columns ) != count( array_unique( $f_columns ) ) ) { 76 | error_parameters( plugin_lang_get( 'error_col_multiple' ) ); 77 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 78 | } 79 | 80 | # Some default values for filter 81 | $t_page_number = 1; 82 | $t_issues_per_page = 25; 83 | $t_page_count = 0; 84 | $t_issues_count = 0; 85 | 86 | # Import file content 87 | $t_success_count = array(); 88 | $t_success_count['update'] = 0; 89 | $t_success_count['new'] = 0; 90 | $t_success_count['nothing'] = 0; 91 | 92 | $t_failure_count = 0; 93 | $t_error_messages = ''; 94 | 95 | # Determine import mode 96 | $t_import_mode = 'all_new'; 97 | if(array_isearch( 'id', $f_columns ) !== false) { 98 | $t_import_mode = 'by_id'; 99 | } 100 | else { 101 | if(count($f_keys) > 0) { 102 | $t_import_mode = 'by_keys'; 103 | } 104 | } 105 | 106 | # Let's go 107 | $t_dry_mode = false; 108 | $lineNumber = 0; 109 | helper_begin_long_process( ); 110 | 111 | foreach( $t_file_content as $t_file_row ) { 112 | $lineNumber++; 113 | $t_operation_type = 'undefined'; 114 | 115 | # Check if first row skipped 116 | if( $lineNumber == 1 && $f_skip_first ) { 117 | continue; 118 | } 119 | 120 | # Explode into elements 121 | $t_file_row = read_csv_row( $t_file_row, $f_separator ); 122 | 123 | # Get Id 124 | $t_bug_id = null; 125 | switch($t_import_mode) { 126 | case 'by_id' : 127 | $t_operation_type = 'update'; 128 | $t_bug_id = get_column_value( 'id', $t_file_row ); 129 | break; 130 | 131 | case 'by_keys' : 132 | $t_filter = filter_get_default(); 133 | $t_filter[FILTER_PROPERTY_HIDE_STATUS_ID] = array( 134 | '0' => META_FILTER_ANY, 135 | ); 136 | 137 | $t_values_for_error = array(); 138 | foreach($f_keys as $aKey => $v) { 139 | $filterValue = array(get_column_value( $aKey, $t_file_row, '' )); 140 | if($v == 'standard') { 141 | $t_filter[$aKey] = $filterValue; 142 | } 143 | else { 144 | $t_filter['custom_fields'][$v] = $filterValue; 145 | } 146 | $t_values_for_error[] = $filterValue[0]; 147 | } 148 | 149 | $t_issues = filter_get_bug_rows( $t_page_number, $t_issues_per_page, $t_page_count, $t_issues_count, $t_filter ); 150 | 151 | switch($t_issues_count) { 152 | case 1: 153 | $t_operation_type = 'update'; 154 | $t_bug_id = $t_issues[0]->id; 155 | break; 156 | case 0: 157 | $t_operation_type = 'new'; 158 | $t_bug_id = null; 159 | break; 160 | default : 161 | $t_bugs_id = array(); 162 | foreach($t_issues as $issue) { 163 | $t_bugs_id[] = $issue->id; 164 | } 165 | 166 | $t_failure_count++; 167 | $t_error_messages .= sprintf( $lineNumber . ' : ' . plugin_lang_get( 'error_keys' ), implode('/', $t_values_for_error), 168 | implode('/', $t_bugs_id)) . '
'; 169 | continue 3; 170 | } 171 | 172 | break; 173 | 174 | default : 175 | $t_operation_type = 'new'; 176 | $t_bug_id = null; 177 | } 178 | 179 | # If new, set default parameters 180 | if( $t_bug_id === null ) { 181 | #Default bug will be with default values 182 | $t_bug_data = new BugData; 183 | 184 | $t_bug_data->project_id = $g_project_id; 185 | $t_bug_data->category_id = get_csv_import_category_id( $g_project_id, 'General' ); 186 | $t_bug_data->reporter_id = auth_get_current_user_id(); 187 | $t_bug_data->priority = config_get( 'default_bug_priority' ); 188 | $t_bug_data->severity = config_get( 'default_bug_severity' ); 189 | $t_bug_data->reproducibility = config_get( 'default_bug_reproducibility' ); 190 | $t_bug_data->handler_id = 0; 191 | $t_bug_data->status = config_get( 'bug_submit_status' ); 192 | $t_bug_data->resolution = OPEN; 193 | $t_bug_data->view_state = config_get( 'default_bug_view_status' ); 194 | $t_bug_data->profile_id = 0; 195 | $t_bug_data->due_date = date_get_null(); 196 | } else { 197 | # If existing bug 198 | if( !bug_exists( $t_bug_id ) ) { 199 | $t_failure_count++; 200 | $t_error_messages .= sprintf( $lineNumber . ' : ' . plugin_lang_get( 'error_bug_not_exist' ), $t_bug_id) . '
'; 201 | continue; 202 | } 203 | $t_bug_data = bug_get( $t_bug_id, true ); 204 | if( $t_bug_data->project_id != $g_project_id ) { 205 | $t_failure_count++; 206 | $t_error_messages .= sprintf( $lineNumber . ' : ' . plugin_lang_get( 'error_bug_bad_project' ), $t_bug_id) . '
'; 207 | continue; 208 | } 209 | } 210 | 211 | # From selected columns, get value 212 | 213 | $detectChanges = false; 214 | $callUpdate = false; 215 | $t_custom_fields_to_set = array(); 216 | $t_date_submitted = null; 217 | $t_last_updated = null; 218 | $t_description_set = false; 219 | 220 | foreach($f_columns as $i => $aColumn) { 221 | $v = null; 222 | $valueSet = true; 223 | 224 | switch($aColumn) { 225 | case 'priority' : 226 | case 'severity' : 227 | case 'reproducibility' : 228 | case 'projection' : 229 | case 'eta' : 230 | case 'view_state' : 231 | $v = get_enum_column_value( $aColumn, $t_file_row, '' ); 232 | break; 233 | case 'date_submitted' : 234 | case 'last_updated' : 235 | $v = get_date_column_value( $aColumn, $t_file_row, '' ); 236 | break; 237 | case 'due_date' : 238 | $v = get_date_column_value( $aColumn, $t_file_row, date_get_null() ); 239 | break; 240 | case 'handler_id' : 241 | case 'reporter_id' : 242 | $v = get_user_column_value( $aColumn, $t_file_row, '' ); 243 | break; 244 | case 'status' : 245 | case 'resolution' : 246 | $v = get_column_value( $aColumn, $t_file_row ); 247 | if($v != '' && !is_numeric($v)) { 248 | $v = get_enum_column_value( $aColumn, $t_file_row, '' ); 249 | } 250 | break; 251 | case 'summary' : 252 | case 'os' : 253 | case 'os_build' : 254 | case 'platform' : 255 | case 'version' : 256 | case 'target_version' : 257 | case 'build' : 258 | case 'steps_to_reproduce' : 259 | case 'additional_information' : 260 | case 'fixed_in_version' : 261 | $v = get_column_value( $aColumn, $t_file_row, ''); 262 | break; 263 | case 'description' : 264 | $t_description_set = true; 265 | $v = get_column_value( $aColumn, $t_file_row, ''); 266 | break; 267 | case 'category' : 268 | $v = get_category_column_value('category', $t_file_row, $t_bug_data->project_id , null ); 269 | 270 | if( $v == null ) { 271 | $t_cat = trim ( get_column_value( 'category', $t_file_row ) ); 272 | if( $t_cat != '' && $f_create_unknown_cats ) { 273 | get_csv_import_category_id($g_project_id, $t_cat); 274 | $v = get_category_column_value('category', $t_file_row, $t_bug_data->project_id , '' ); 275 | } else { 276 | # If user hasn't selected create unknown categories, then select a default category 277 | # when category is not already defined. 278 | $v = config_get( 'default_category_for_moves' ); 279 | } 280 | } 281 | 282 | $aColumn = 'category_id'; 283 | 284 | break; 285 | default : 286 | $valueSet = false; 287 | if(isset($t_custom_fields[$aColumn])) { 288 | $t_id = $t_custom_fields[$aColumn]; 289 | $t_def = custom_field_get_definition( $t_id ); 290 | 291 | # Prepare value 292 | if ( $t_def['type'] == CUSTOM_FIELD_TYPE_DATE ) { 293 | $t_value = get_date_column_value( $aColumn, $t_file_row, '' ); 294 | } else { 295 | $t_value = get_column_value( $aColumn, $t_file_row ); 296 | } 297 | 298 | # Have to be different 299 | if( $t_bug_id && $t_value == custom_field_get_value( $t_id, $t_bug_id) ) { 300 | continue; 301 | } 302 | 303 | $detectChanges = true; 304 | 305 | $t_custom_fields_to_set[$t_id] = $t_value; 306 | } 307 | } 308 | 309 | if( $valueSet && ($t_bug_id === null || $t_bug_data->$aColumn != $v) ) { 310 | $detectChanges = true; 311 | 312 | if($aColumn == 'date_submitted') { 313 | $t_date_submitted = $v ; 314 | } else if ( $aColumn == 'last_updated' ) { 315 | $t_last_updated = $v; 316 | } else { 317 | $t_bug_data->$aColumn = $v; 318 | $callUpdate = true; 319 | } 320 | } 321 | } 322 | 323 | if( $t_operation_type == 'update' && !$detectChanges ) { 324 | $t_operation_type = 'nothing'; 325 | } 326 | 327 | $t_success_count[$t_operation_type]++; 328 | 329 | # Set values 330 | if(!$t_dry_mode && $t_operation_type != 'nothing') { 331 | if ( !$t_description_set ) { 332 | $t_bug_data->description = $t_bug_data->summary; 333 | } 334 | # Set non-custom fields 335 | if( $t_bug_id === null) { 336 | $t_bug_id = $t_bug_data->create(); 337 | } else { 338 | if( $callUpdate ) { 339 | $t_bug_data->update( true, ( false == $t_notify ) ); 340 | } 341 | } 342 | 343 | # Set custom fields (can be set only after bug creation) 344 | foreach($t_custom_fields_to_set as $t_id => $t_value) { 345 | if( custom_field_set_value( $t_id, $t_bug_id, $t_value ) ) { 346 | # Mantis core doesn't update "last_updated" when setting custom fields 347 | bug_update_date( $t_bug_id ); 348 | } 349 | else { 350 | $t_failure_count++; 351 | $t_error_messages .= sprintf( $lineNumber . ' : ' . plugin_lang_get( 'error_custom_field' ), 352 | $t_def['name'], $t_bug_data->summary) . '
'; 353 | continue; 354 | } 355 | } 356 | 357 | # Set date_submitted (can be set only after bug creation) 358 | if($t_date_submitted) { 359 | bug_set_field( $t_bug_id, 'date_submitted', $t_date_submitted ); 360 | } 361 | 362 | # Set last_updated (can be set only after bug creation / updated) 363 | if ( $t_last_updated ) { 364 | bug_set_field( $t_bug_id, 'last_updated', $t_last_updated ); 365 | } 366 | } 367 | } 368 | 369 | if( $t_failure_count == 0 ) { 370 | $t_redirect_url = 'view_all_bug_page.php'; 371 | } else { 372 | $t_redirect_url = null; 373 | } 374 | 375 | layout_page_header( null, $t_redirect_url ); 376 | 377 | if( $t_failure_count ) { 378 | $t_alert_style = 'alert-danger'; 379 | } else { 380 | $t_alert_style = 'alert-success'; 381 | } 382 | ?> 383 | 384 |
385 |
386 |
387 | 388 | '; 390 | echo sprintf( plugin_lang_get( 'result_import_success_ct' ), $t_success_count['new']) . '
'; 391 | echo sprintf( plugin_lang_get( 'result_nothing_success_ct' ), $t_success_count['nothing']) . '
'; 392 | 393 | if( $t_failure_count ) { 394 | echo ''.sprintf( plugin_lang_get( 'result_failure_ct' ), $t_failure_count) . ' :
'; 395 | echo $t_error_messages . '
'; 396 | } 397 | print_bracket_link( $t_redirect_url, lang_get( 'proceed' ) ); 398 | ?> 399 |
400 |
401 | 402 | 'reporter', 63 | 'last_updated' => 'updated', 64 | 'handler_id' => 'assigned_to', 65 | 'os_build' => 'os_version', 66 | 'version' => 'product_version', 67 | 'view_state' => 'view_status', 68 | ); 69 | 70 | # Create the translated array 71 | $t_fields = array(); 72 | foreach( array_unique( $p_all_fields ) as $t_element ) 73 | { 74 | $t_lang_id = $t_element; 75 | if( strpos( $t_element, $g_custom_field_identifier ) === 0 ) 76 | $t_lang_id = substr( $t_element, strlen( $g_custom_field_identifier ) ); 77 | elseif( isset( $t_translated_fields[$t_element] ) ) 78 | $t_lang_id = $t_translated_fields[$t_element]; 79 | $t_fields[$t_element] = lang_get_defaulted( $t_lang_id ); 80 | } 81 | 82 | # Set to all fields 83 | return $t_fields; 84 | } 85 | 86 | # -------------------- 87 | function print_all_fields_option_list( $p_selected ) { 88 | global $g_all_fields; 89 | foreach( $g_all_fields as $t_element => $t_translated ) 90 | { 91 | echo ""; 94 | } 95 | } 96 | 97 | # -------------------- 98 | function csv_string_unescape( $p_string ) { 99 | $t_wo_quotes = preg_replace( '/\A"(.*)"\z/sm', '${1}', $p_string ); 100 | if( $t_wo_quotes !== $p_string ) 101 | $t_wo_quotes = str_replace( '""', '"', $t_wo_quotes ); 102 | return $t_wo_quotes; 103 | } 104 | 105 | # -------------------- 106 | function read_csv_file( $p_filename ) { 107 | $t_regexp = '/\G((?:[^"\r\n]+|"[^"]*")+)[\r|\n]*/sm'; 108 | 109 | $t_file_raw_content = file_get_contents( $p_filename ); 110 | 111 | # Convert special chars to html entities 112 | $t_file_content = mb_convert_encoding($t_file_raw_content, 'HTML-ENTITIES', "UTF-8"); 113 | 114 | preg_match_all($t_regexp, $t_file_content, $t_file_rows); 115 | return $t_file_rows[1]; 116 | } 117 | 118 | # -------------------- 119 | function read_csv_row( $p_file_row, $p_separator ) { 120 | $t_regexp = '/\G(?:\A|\\' . $p_separator . ')([^"\\' . $p_separator . ']+|(?:"[^"]*")*)/sm'; 121 | 122 | preg_match_all($t_regexp, $p_file_row, $t_row_element); 123 | 124 | # Return result 125 | return array_map( 'csv_string_unescape', $t_row_element[1] ); 126 | } 127 | 128 | function category_get_id_by_name_ne( $p_category_name, $p_project_id ) { 129 | # Don't cache categories as they can be added during the import process. 130 | $t_categories = category_get_all_rows( $p_project_id ); 131 | 132 | foreach ( $t_categories as $t_category ) { 133 | if( strcasecmp( $t_category['name'], $p_category_name ) == 0 ) { 134 | return (int)$t_category['id']; 135 | } 136 | } 137 | 138 | return false; 139 | } 140 | 141 | function prepare_output( $t_string , $t_encode_only = false ) { 142 | return string_html_specialchars( utf8_encode($t_string) ); 143 | } 144 | 145 | function get_csv_import_category_id( $p_project_id, $p_category_name ) { 146 | project_ensure_exists( $p_project_id ); 147 | 148 | $t_category_id = category_get_id_by_name_ne( $p_category_name, $p_project_id ); 149 | if( !$t_category_id ) 150 | { 151 | return category_add( $p_project_id, $p_category_name ); 152 | } 153 | 154 | return $t_category_id; 155 | } 156 | 157 | # -------------------- 158 | # Breaks up an enum string into num:value elements 159 | function explode_enum_string( $p_enum_string ) { 160 | return explode( ',', $p_enum_string ); 161 | } 162 | # -------------------- 163 | # Given one num:value pair it will return both in an array 164 | # num will be first (element 0) value second (element 1) 165 | function explode_enum_arr( $p_enum_elem ) { 166 | return explode( ':', $p_enum_elem ); 167 | } 168 | 169 | function array_isearch( $str , $array ) { 170 | foreach($array as $k => $v) { 171 | if(strcasecmp($str, $v) == 0) { 172 | return $k; 173 | } 174 | }; 175 | return false; 176 | } 177 | 178 | #----------------------- 179 | function get_enum_column_value( $p_name, $p_row, $p_default ) { 180 | $t_value = get_column_value( $p_name, $p_row ); 181 | if( is_blank( $t_value ) ) return $p_default; 182 | # First chance, search element in language enumeration string 183 | $t_element_enum_string = lang_get( $p_name . '_enum_string' ); 184 | $t_arr = explode_enum_string( $t_element_enum_string ); 185 | $t_arr_count = count( $t_arr ); 186 | for( $i = 0; $i < $t_arr_count; $i++ ) { 187 | $elem_arr = explode_enum_arr( $t_arr[$i] ); 188 | if( $elem_arr[1] == $t_value ) { 189 | return $elem_arr[0]; 190 | } elseif( $elem_arr[0] == $t_value ) { 191 | return $elem_arr[0]; 192 | }; 193 | }; 194 | 195 | # Second chance, search element in configuration enumeration string 196 | $t_element_enum_string = config_get( $p_name . '_enum_string' ); 197 | $t_arr = explode_enum_string( $t_element_enum_string ); 198 | $t_arr_count = count( $t_arr ); 199 | for( $i = 0; $i < $t_arr_count; $i++ ) { 200 | $elem_arr = explode_enum_arr( $t_arr[$i] ); 201 | if( $elem_arr[1] == $t_value ) { 202 | return $elem_arr[0]; 203 | } elseif( $elem_arr[0] == $t_value ) { 204 | return $elem_arr[0]; 205 | }; 206 | }; 207 | return $p_default; 208 | } 209 | 210 | #----------------------- 211 | function get_date_column_value( $p_name, $p_row, $p_default ) { 212 | $t_date = get_column_value( $p_name, $p_row ); 213 | 214 | if(!is_blank($t_date)) 215 | { 216 | return is_numeric($t_date) ? $t_date : strtotime( $t_date ); 217 | } 218 | 219 | return $p_default; 220 | } 221 | 222 | 223 | function string_MkPretty( $t_str ) { 224 | $t_str = utf8_encode(strtolower(trim(utf8_decode($t_str)))); 225 | $t_str = preg_replace('/\xfc/ui', 'ue', $t_str); 226 | $t_str = preg_replace('/\xf6/ui', 'oe', $t_str); 227 | $t_str = preg_replace('/\xe4/ui', 'ae', $t_str); 228 | $t_str = preg_replace('/\xdf/ui', 'ss', $t_str); 229 | return $t_str; 230 | } 231 | 232 | 233 | function get_user_column_value( $p_name, $p_row, $p_default ) { 234 | $t_username = get_column_value( $p_name, $p_row ); 235 | if( is_blank( $t_username ) ) { 236 | return $p_default; 237 | } 238 | 239 | if( ($t_user_id = user_get_id_by_name($t_username)) !== false ) { 240 | return $t_user_id; 241 | } 242 | 243 | $t_username_pretty = string_MkPretty( $t_username ); 244 | if ( $t_username_pretty !== $t_username ) { 245 | if ( $t_user_id = user_get_id_by_name( $t_username_pretty ) ) { 246 | return $t_user_id; 247 | } 248 | } 249 | 250 | if ( strstr( $t_username, '@' ) === false ) { 251 | # User name can contain invalid email characters, example spaces. 252 | # Since this is an invalid email address anyway and user is not enabled, use md5. 253 | $t_email = md5( $t_username ) . '@localhost'; 254 | } else { 255 | $t_email = $t_username; 256 | } 257 | 258 | $t_password = time() . rand( 1, 10000 ); 259 | 260 | if( user_create( 261 | $t_username, 262 | $t_password, # password 263 | $t_email, # email address 264 | null, # access_level 265 | false, # protected 266 | false) ) { # enabled - disable user - admin can reset password and enable. 267 | return user_get_id_by_name($t_username); 268 | } 269 | 270 | return $p_default; 271 | } 272 | 273 | #----------------------- 274 | function get_column_value( $p_name, $p_row, $p_default = '' ) { 275 | global $f_columns; 276 | $t_column = array_isearch( $p_name, $f_columns ); 277 | $t_value = ( ($t_column === false) || (!isset( $p_row[$t_column] )) ) ? $p_default : utf8_encode(trim( $p_row[$t_column] )); 278 | 279 | $t_value = str_replace( '\n', "\n", $t_value ); 280 | return $t_value; 281 | } 282 | 283 | #----------------------- 284 | function column_value_exists( $p_name, $p_row ) { 285 | global $f_columns; 286 | $t_column = array_isearch( $p_name, $f_columns ); 287 | return (($t_column !== false) && (isset( $p_row[$t_column] ))) ? true : false; 288 | } 289 | 290 | function get_category_column_value( $p_name, $p_row, $p_project, $p_default ) { 291 | $t_category_id = category_get_id_by_name_ne ( trim ( get_column_value( $p_name, $p_row ) ) , $p_project ); 292 | return (($t_category_id === false) ? $p_default : $t_category_id); 293 | } 294 | 295 | /** 296 | * A more readable var_dump 297 | * 298 | * @param mixed 299 | */ 300 | function hvar_dump() 301 | { 302 | $numargs = func_num_args(); 303 | $arg_list = func_get_args(); 304 | echo '
';
305 | 	for ($i = 0; $i < $numargs; $i++)
306 | 	{
307 | 		var_dump($arg_list[$i]);
308 | 	}
309 | 
310 | 	echo '
'; 311 | } 312 | 313 | if( !function_exists( 'helper_alternate_class' ) ) { 314 | function helper_alternate_class() { 315 | return ''; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /pages/import_issues_page_col_set.php: -------------------------------------------------------------------------------- 1 | 11 |
12 | &$t_file_line ) { 38 | $t_elements = read_csv_row( $t_file_line, $t_separator ); 39 | 40 | # First line 41 | if( $t_column_count < 0 ) { 42 | # If 0 or 1 column 43 | if( count( $t_elements ) <= 1 ) { 44 | error_parameters( sprintf( plugin_lang_get( 'error_noseparator' ), $t_separator) ); 45 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 46 | } 47 | elseif ( 48 | $t_trim_rows && (trim(implode(' ' , $t_elements)) == '') 49 | ) { 50 | if( $t_skip_first ) { 51 | error_parameters( plugin_lang_get('error_empty_header' ) ); 52 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 53 | } 54 | else { 55 | $t_file_line = null; 56 | } 57 | } 58 | 59 | if( $t_trim_columns ) { 60 | for( $i = 0 ; $i < count($t_elements) ; $i++ ) { 61 | if( trim($t_elements[$i]) == '' ) { 62 | $t_elements = array_slice( $t_elements , 0 , $i ); 63 | break 1; 64 | } 65 | } 66 | } 67 | $t_column_count = count( $t_elements ); 68 | $t_column_title = $t_elements; 69 | } 70 | 71 | # Other lines 72 | elseif( $t_column_count != count( $t_elements ) ) { 73 | if( $t_trim_columns ) { # @@@ u.sommer added 74 | $t_row = explode( $t_separator , $t_file_line ); 75 | $t_row = array_slice( $t_row , 0 , $t_column_count ); 76 | $t_file_line = implode( $t_separator , $t_row ); 77 | } 78 | else { 79 | error_parameters( sprintf( plugin_lang_get( 'error_col_count' ), $t_separator) ); 80 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 81 | } 82 | } 83 | 84 | if ( 85 | $t_trim_rows && trim(implode(' ' , $t_elements)) == '' 86 | ) { 87 | unset( $t_file_content[$t_key] ); 88 | $t_file_content = array_merge($t_file_content); 89 | } 90 | } 91 | 92 | if( is_writable( $f_import_file['tmp_name'] ) ) { 93 | if( $handle = fopen( $f_import_file['tmp_name'], "wb" ) ) { 94 | foreach( $t_file_content as &$t_file_line ) { 95 | $t_written = fwrite( $handle , $t_file_line . "\n" ); 96 | } 97 | fclose( $handle ); 98 | } 99 | else { 100 | error_parameters( plugin_lang_get( 'error_file_not_opened' ) ); 101 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 102 | } 103 | } 104 | else { 105 | error_parameters( plugin_lang_get( 'error_file_not_writable' ) ); 106 | plugin_error( 'ERROR_FILE_FORMAT', ERROR ); 107 | } 108 | 109 | # Move file 110 | $t_file_name = tempnam( dirname($f_import_file['tmp_name']), 'tmp' ); 111 | move_uploaded_file( $f_import_file['tmp_name'], $t_file_name ); 112 | ?> 113 | 114 | 115 |
116 |
117 |
118 |
119 |
120 |

121 | 122 |

123 |
124 |
125 |
126 |
127 |
128 | 129 |
130 |
131 | '; 135 | if( !$t_skip_first ) { 136 | echo sprintf( plugin_lang_get( 'column_number' ), $i + 1); 137 | } 138 | else { 139 | echo prepare_output($t_column_title[$i]); 140 | } 141 | echo ''; 142 | } 143 | ?> 144 | 145 | '; 158 | 159 | # Still more lines (add "...") 160 | if( --$t_display_max < 0 ) { 161 | echo str_repeat('', $t_column_count); 162 | echo ''; 163 | break; 164 | } 165 | else { 166 | # Write values 167 | foreach( read_csv_row( $t_file_line, $t_separator ) as $t_element ) { 168 | echo ''; 169 | } 170 | } 171 | echo ''; 172 | } 173 | ?> 174 | 175 |
' . prepare_output($t_element) . '
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | 185 |
186 | 187 | 188 |
189 |
190 |
191 |
192 |
193 |
194 |

195 | Column Mapping 196 |

197 |
198 |
199 |
200 |
201 |
202 | 203 |
204 |
205 | 208 | 211 | 214 | 215 | 238 | 239 | 249 | 254 | 257 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 |
206 | 207 | 209 | Matching Action 210 | 212 | Primary Key 213 |
240 | 248 | 250 | 253 | 255 | 256 |
268 |
269 |
270 |
271 |
272 | 273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | 281 | 304 | 305 | 11 |
12 | 18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 |

26 | 27 |

28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 | 39 | 43 | 44 | 45 | 46 | 49 | 52 | 53 | 54 | 55 | 58 | 61 | 62 | 63 | 64 | 67 | 70 | 71 | 72 | 73 | 76 | 79 | 80 | 81 | 82 | 86 | 90 | 91 | 92 |
37 | 38 | 40 | - 41 | [] 42 |
47 | 48 | 50 | 51 |
56 | 57 | 59 | 60 |
65 | 66 | 68 | 69 |
74 | 75 | 77 | 78 |
83 |
84 | (' . plugin_lang_get( 'max_file_size_label' ) . ': ' . number_format( $t_max_file_size/1000 ) . 'k)'?> 85 |
87 | 88 | 89 |
93 |
94 |
95 |
96 |
97 | 98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | 106 |