@@ -22,7 +22,9 @@ discard block |
||
| 22 | 22 | * @todo Throw away spechial chars and trim() entries ? |
| 23 | 23 | * @todo Check for XSS like userinput! (see common_functions) |
| 24 | 24 | */ |
| 25 | -class importexport_import_csv implements importexport_iface_import_record { //, Iterator { |
|
| 25 | +class importexport_import_csv implements importexport_iface_import_record |
|
| 26 | +{ |
|
| 27 | +//, Iterator { |
|
| 26 | 28 | |
| 27 | 29 | const csv_max_linelength = 8000; |
| 28 | 30 | |
@@ -83,10 +85,14 @@ discard block |
||
| 83 | 85 | * @param string $_resource resource containing data. May be each valid php-stream |
| 84 | 86 | * @param array $_options options for the resource array with keys: charset and fieldsep |
| 85 | 87 | */ |
| 86 | - public function __construct( $_resource, array $_options ) { |
|
| 88 | + public function __construct( $_resource, array $_options ) |
|
| 89 | + { |
|
| 87 | 90 | $this->resource = $_resource; |
| 88 | 91 | $this->csv_fieldsep = $_options['fieldsep']; |
| 89 | - if($_options['charset'] == 'user') $_options['charset'] = $GLOBALS['egw_info']['user']['preferences']['common']['csv_charset']; |
|
| 92 | + if($_options['charset'] == 'user') |
|
| 93 | + { |
|
| 94 | + $_options['charset'] = $GLOBALS['egw_info']['user']['preferences']['common']['csv_charset']; |
|
| 95 | + } |
|
| 90 | 96 | $this->csv_charset = $_options['charset']; |
| 91 | 97 | return; |
| 92 | 98 | } // end of member function __construct |
@@ -94,7 +100,8 @@ discard block |
||
| 94 | 100 | /** |
| 95 | 101 | * cleanup |
| 96 | 102 | */ |
| 97 | - public function __destruct( ) { |
|
| 103 | + public function __destruct( ) |
|
| 104 | + { |
|
| 98 | 105 | } // end of member function __destruct |
| 99 | 106 | |
| 100 | 107 | /** |
@@ -103,20 +110,27 @@ discard block |
||
| 103 | 110 | * @param mixed _position may be: {current|first|last|next|previous|somenumber} |
| 104 | 111 | * @return mixed array with data / false if no furtor records |
| 105 | 112 | */ |
| 106 | - public function get_record( $_position = 'next' ) { |
|
| 113 | + public function get_record( $_position = 'next' ) |
|
| 114 | + { |
|
| 107 | 115 | |
| 108 | - if ($this->get_raw_record( $_position ) === false) { |
|
| 116 | + if ($this->get_raw_record( $_position ) === false) |
|
| 117 | + { |
|
| 109 | 118 | return false; |
| 110 | 119 | } |
| 111 | 120 | |
| 112 | 121 | // skip empty records |
| 113 | - if( count( array_unique( $this->record ) ) < 2 ) return $this->get_record( $_position ); |
|
| 122 | + if( count( array_unique( $this->record ) ) < 2 ) |
|
| 123 | + { |
|
| 124 | + return $this->get_record( $_position ); |
|
| 125 | + } |
|
| 114 | 126 | |
| 115 | - if ( !empty( $this->conversion ) ) { |
|
| 127 | + if ( !empty( $this->conversion ) ) |
|
| 128 | + { |
|
| 116 | 129 | $this->do_conversions(); |
| 117 | 130 | } |
| 118 | 131 | |
| 119 | - if ( !empty( $this->mapping ) ) { |
|
| 132 | + if ( !empty( $this->mapping ) ) |
|
| 133 | + { |
|
| 120 | 134 | $this->do_fieldmapping(); |
| 121 | 135 | } |
| 122 | 136 | |
@@ -128,8 +142,10 @@ discard block |
||
| 128 | 142 | * |
| 129 | 143 | * @param int $_numToSkip |
| 130 | 144 | */ |
| 131 | - public function skip_records( $_numToSkip ) { |
|
| 132 | - while ( (int)$_numToSkip-- !== 0 ) { |
|
| 145 | + public function skip_records( $_numToSkip ) |
|
| 146 | + { |
|
| 147 | + while ( (int)$_numToSkip-- !== 0 ) |
|
| 148 | + { |
|
| 133 | 149 | fgetcsv( $this->resource, self::csv_max_linelength, $this->csv_fieldsep); |
| 134 | 150 | } |
| 135 | 151 | } |
@@ -140,22 +156,27 @@ discard block |
||
| 140 | 156 | * @param mixed $_position |
| 141 | 157 | * @return bool |
| 142 | 158 | */ |
| 143 | - private function get_raw_record( $_position = 'next' ) { |
|
| 144 | - switch ($_position) { |
|
| 159 | + private function get_raw_record( $_position = 'next' ) |
|
| 160 | + { |
|
| 161 | + switch ($_position) |
|
| 162 | + { |
|
| 145 | 163 | case 'current' : |
| 146 | - if ($this->current_position == 0) { |
|
| 164 | + if ($this->current_position == 0) |
|
| 165 | + { |
|
| 147 | 166 | return; |
| 148 | 167 | } |
| 149 | 168 | break; |
| 150 | 169 | case 'first' : |
| 151 | - if (!$this->current_position == 0) { |
|
| 170 | + if (!$this->current_position == 0) |
|
| 171 | + { |
|
| 152 | 172 | $this->current_position = 0; |
| 153 | 173 | rewind($this->resource); |
| 154 | 174 | } |
| 155 | 175 | |
| 156 | 176 | case 'next' : |
| 157 | 177 | $csv_data = fgetcsv( $this->resource, self::csv_max_linelength, $this->csv_fieldsep); |
| 158 | - if (!is_array($csv_data)) { |
|
| 178 | + if (!is_array($csv_data)) |
|
| 179 | + { |
|
| 159 | 180 | return false; |
| 160 | 181 | } |
| 161 | 182 | $this->current_position++; |
@@ -163,33 +184,41 @@ discard block |
||
| 163 | 184 | break; |
| 164 | 185 | |
| 165 | 186 | case 'previous' : |
| 166 | - if ($this->current_position < 2) { |
|
| 187 | + if ($this->current_position < 2) |
|
| 188 | + { |
|
| 167 | 189 | throw new Exception('Error: There is no previous record!'); |
| 168 | 190 | } |
| 169 | 191 | $final_position = --$this->current_position; |
| 170 | 192 | $this->current_position = 0; |
| 171 | 193 | rewind($this->resource); |
| 172 | - while ($this->current_position !== $final_position) { |
|
| 194 | + while ($this->current_position !== $final_position) |
|
| 195 | + { |
|
| 173 | 196 | $this->get_raw_record(); |
| 174 | 197 | } |
| 175 | 198 | break; |
| 176 | 199 | |
| 177 | 200 | case 'last' : |
| 178 | - while ($this->get_raw_record()) {} |
|
| 201 | + while ($this->get_raw_record()) |
|
| 202 | + { |
|
| 203 | +} |
|
| 179 | 204 | break; |
| 180 | 205 | |
| 181 | 206 | default: //somenumber |
| 182 | - if (!is_int($_position)) { |
|
| 207 | + if (!is_int($_position)) |
|
| 208 | + { |
|
| 183 | 209 | throw new Exception('Error: $position must be one of {current|first|last|next|previous} or an integer value'); |
| 184 | 210 | } |
| 185 | - if ($_position == $this->current_position) { |
|
| 211 | + if ($_position == $this->current_position) |
|
| 212 | + { |
|
| 186 | 213 | break; |
| 187 | 214 | } |
| 188 | - elseif ($_position < $this->current_position) { |
|
| 215 | + elseif ($_position < $this->current_position) |
|
| 216 | + { |
|
| 189 | 217 | $this->current_position = 0; |
| 190 | 218 | rewind($this->resource); |
| 191 | 219 | } |
| 192 | - while ($this->current_position !== $_position) { |
|
| 220 | + while ($this->current_position !== $_position) |
|
| 221 | + { |
|
| 193 | 222 | $this->get_raw_record(); |
| 194 | 223 | } |
| 195 | 224 | break; |
@@ -202,12 +231,16 @@ discard block |
||
| 202 | 231 | * |
| 203 | 232 | * @return int |
| 204 | 233 | */ |
| 205 | - public function get_num_of_records( ) { |
|
| 206 | - if ($this->num_of_records > 0) { |
|
| 234 | + public function get_num_of_records( ) |
|
| 235 | + { |
|
| 236 | + if ($this->num_of_records > 0) |
|
| 237 | + { |
|
| 207 | 238 | return $this->num_of_records; |
| 208 | 239 | } |
| 209 | 240 | $current_position = $this->current_position; |
| 210 | - while ($this->get_raw_record()) {} |
|
| 241 | + while ($this->get_raw_record()) |
|
| 242 | + { |
|
| 243 | +} |
|
| 211 | 244 | $this->num_of_records = $this->current_position; |
| 212 | 245 | $this->get_record($current_position); |
| 213 | 246 | return $this->num_of_records; |
@@ -218,7 +251,8 @@ discard block |
||
| 218 | 251 | * |
| 219 | 252 | * @return int |
| 220 | 253 | */ |
| 221 | - public function get_current_position( ) { |
|
| 254 | + public function get_current_position( ) |
|
| 255 | + { |
|
| 222 | 256 | |
| 223 | 257 | return $this->current_position; |
| 224 | 258 | |
@@ -230,12 +264,16 @@ discard block |
||
| 230 | 264 | * |
| 231 | 265 | * @return |
| 232 | 266 | */ |
| 233 | - protected function do_fieldmapping( ) { |
|
| 267 | + protected function do_fieldmapping( ) |
|
| 268 | + { |
|
| 234 | 269 | $record = $this->record; |
| 235 | 270 | $this->record = array(); |
| 236 | 271 | foreach ($this->mapping as $cvs_idx => $new_idx) |
| 237 | 272 | { |
| 238 | - if( $new_idx == '' ) continue; |
|
| 273 | + if( $new_idx == '' ) |
|
| 274 | + { |
|
| 275 | + continue; |
|
| 276 | + } |
|
| 239 | 277 | $this->record[$new_idx] = $record[$cvs_idx]; |
| 240 | 278 | } |
| 241 | 279 | return true; |
@@ -246,8 +284,10 @@ discard block |
||
| 246 | 284 | * |
| 247 | 285 | * @return bool |
| 248 | 286 | */ |
| 249 | - protected function do_conversions() { |
|
| 250 | - if ( $record = importexport_helper_functions::conversion( $this->record, $this->conversion, $this->conversion_class )) { |
|
| 287 | + protected function do_conversions() |
|
| 288 | + { |
|
| 289 | + if ( $record = importexport_helper_functions::conversion( $this->record, $this->conversion, $this->conversion_class )) |
|
| 290 | + { |
|
| 251 | 291 | $this->record = $record; |
| 252 | 292 | return; |
| 253 | 293 | } |
@@ -264,16 +304,19 @@ discard block |
||
| 264 | 304 | * |
| 265 | 305 | * @return string warnings, if any |
| 266 | 306 | */ |
| 267 | - public static function convert(Array &$record, Array $fields = array(), $appname = null, Array $selects = array(), $format=0) { |
|
| 307 | + public static function convert(Array &$record, Array $fields = array(), $appname = null, Array $selects = array(), $format=0) |
|
| 308 | + { |
|
| 268 | 309 | $warnings = array(); |
| 269 | 310 | |
| 270 | 311 | // Automatic conversions |
| 271 | - if($appname) { |
|
| 312 | + if($appname) |
|
| 313 | + { |
|
| 272 | 314 | |
| 273 | 315 | // Load translations |
| 274 | 316 | Api\Translation::add_app($appname); |
| 275 | 317 | |
| 276 | - if(!self::$cf_parse_cache[$appname]) { |
|
| 318 | + if(!self::$cf_parse_cache[$appname]) |
|
| 319 | + { |
|
| 277 | 320 | $c_fields = importexport_export_csv::convert_parse_custom_fields($appname, $selects, $links, $methods); |
| 278 | 321 | self::$cf_parse_cache[$appname] = array($c_fields, $selects, $links, $methods); |
| 279 | 322 | } |
@@ -282,7 +325,10 @@ discard block |
||
| 282 | 325 | // Add in any fields that are keys to another app |
| 283 | 326 | foreach((array)$fields['links'] as $link_field => $app) |
| 284 | 327 | { |
| 285 | - if(is_numeric($link_field)) continue; |
|
| 328 | + if(is_numeric($link_field)) |
|
| 329 | + { |
|
| 330 | + continue; |
|
| 331 | + } |
|
| 286 | 332 | $links[$link_field] = $app; |
| 287 | 333 | // Set it as a normal link field |
| 288 | 334 | $fields['links'][] = $link_field; |
@@ -292,7 +338,8 @@ discard block |
||
| 292 | 338 | // Not quite a recursive merge, since only one level |
| 293 | 339 | foreach($fields as $type => &$list) |
| 294 | 340 | { |
| 295 | - if($c_fields[$type]) { |
|
| 341 | + if($c_fields[$type]) |
|
| 342 | + { |
|
| 296 | 343 | $list = array_merge($c_fields[$type], $list); |
| 297 | 344 | unset($c_fields[$type]); |
| 298 | 345 | } |
@@ -300,12 +347,15 @@ discard block |
||
| 300 | 347 | $fields += $c_fields; |
| 301 | 348 | $selects += $c_selects; |
| 302 | 349 | } |
| 303 | - if($fields) { |
|
| 304 | - foreach((array)$fields['select'] as $name) { |
|
| 350 | + if($fields) |
|
| 351 | + { |
|
| 352 | + foreach((array)$fields['select'] as $name) |
|
| 353 | + { |
|
| 305 | 354 | $record[$name] = static::find_select_key($record[$name], $selects[$name]); |
| 306 | 355 | } |
| 307 | 356 | |
| 308 | - foreach((array)$fields['links'] as $name) { |
|
| 357 | + foreach((array)$fields['links'] as $name) |
|
| 358 | + { |
|
| 309 | 359 | if($record[$name] && $links[$name]) |
| 310 | 360 | { |
| 311 | 361 | // Primary key to another app, not a link |
@@ -347,15 +397,19 @@ discard block |
||
| 347 | 397 | lang($links[$name]), $record[$name]). |
| 348 | 398 | ' - ' . lang('no matches'); |
| 349 | 399 | continue; |
| 350 | - } else { |
|
| 400 | + } |
|
| 401 | + else |
|
| 402 | + { |
|
| 351 | 403 | $record[$name] = key($results); |
| 352 | 404 | } |
| 353 | 405 | } |
| 354 | 406 | } |
| 355 | 407 | } |
| 356 | - foreach((array)$fields['select-account'] as $name) { |
|
| 408 | + foreach((array)$fields['select-account'] as $name) |
|
| 409 | + { |
|
| 357 | 410 | // Compare against null to deal with empty arrays |
| 358 | - if ($record[$name]) { |
|
| 411 | + if ($record[$name]) |
|
| 412 | + { |
|
| 359 | 413 | // Automatically handle text owner without explicit translation |
| 360 | 414 | $new_owner = importexport_helper_functions::account_name2id($record[$name]); |
| 361 | 415 | if(count($new_owner) != count(explode(',',$record[$name]))) |
@@ -363,20 +417,26 @@ discard block |
||
| 363 | 417 | // Unable to parse value into account |
| 364 | 418 | $warnings[] = $name . ': ' .lang('%1 is not a known user or group', $record[$name]); |
| 365 | 419 | } |
| 366 | - if($new_owner != '') { |
|
| 420 | + if($new_owner != '') |
|
| 421 | + { |
|
| 367 | 422 | $record[$name] = $new_owner; |
| 368 | - } else { |
|
| 423 | + } |
|
| 424 | + else |
|
| 425 | + { |
|
| 369 | 426 | // Clear it to prevent trouble later on |
| 370 | 427 | $record[$name] = ''; |
| 371 | 428 | } |
| 372 | 429 | } |
| 373 | 430 | } |
| 374 | - foreach((array)$fields['select-bool'] as $name) { |
|
| 375 | - if($record[$name] != null && $record[$name] != '') { |
|
| 431 | + foreach((array)$fields['select-bool'] as $name) |
|
| 432 | + { |
|
| 433 | + if($record[$name] != null && $record[$name] != '') |
|
| 434 | + { |
|
| 376 | 435 | $record[$name] = ($record[$name] == lang('Yes') || $record[$name] == '1' ? 1 : 0); |
| 377 | 436 | } |
| 378 | 437 | } |
| 379 | - foreach((array)$fields['date-time'] as $name) { |
|
| 438 | + foreach((array)$fields['date-time'] as $name) |
|
| 439 | + { |
|
| 380 | 440 | if (isset($record[$name]) && !is_numeric($record[$name]) && strlen(trim($record[$name])) > 0) |
| 381 | 441 | { |
| 382 | 442 | // Need to handle format first |
@@ -402,7 +462,8 @@ discard block |
||
| 402 | 462 | // Try again, anything goes |
| 403 | 463 | try { |
| 404 | 464 | $formatted = new Api\DateTime($record[$name]); |
| 405 | - } catch (Exception $e) { |
|
| 465 | + } |
|
| 466 | + catch (Exception $e) { |
|
| 406 | 467 | $warnings[] = $name.': ' . $e->getMessage() . "\n" . |
| 407 | 468 | 'Format: '.'!'.Api\DateTime::$user_dateformat . ' ' .Api\DateTime::$user_timeformat; |
| 408 | 469 | continue; |
@@ -424,7 +485,8 @@ discard block |
||
| 424 | 485 | } |
| 425 | 486 | |
| 426 | 487 | if(is_array(self::$cf_parse_cache[$appname][0]['date-time']) && |
| 427 | - in_array($name, self::$cf_parse_cache[$appname][0]['date-time'])) { |
|
| 488 | + in_array($name, self::$cf_parse_cache[$appname][0]['date-time'])) |
|
| 489 | + { |
|
| 428 | 490 | // Custom fields stored in a particular format (from customfields_widget) |
| 429 | 491 | $record[$name] = date('Y-m-d H:i:s', $record[$name]); |
| 430 | 492 | } |
@@ -434,7 +496,8 @@ discard block |
||
| 434 | 496 | $record[$name] = null; |
| 435 | 497 | } |
| 436 | 498 | } |
| 437 | - foreach((array)$fields['date'] as $name) { |
|
| 499 | + foreach((array)$fields['date'] as $name) |
|
| 500 | + { |
|
| 438 | 501 | if (isset($record[$name]) && !is_numeric($record[$name]) && strlen(trim($record[$name])) > 0) |
| 439 | 502 | { |
| 440 | 503 | // Need to handle format first |
@@ -448,7 +511,8 @@ discard block |
||
| 448 | 511 | } |
| 449 | 512 | $record[$name] = Api\DateTime::server2user($record[$name],'ts'); |
| 450 | 513 | if(is_array(self::$cf_parse_cache[$appname][0]['date']) && |
| 451 | - in_array($name, self::$cf_parse_cache[$appname][0]['date'])) { |
|
| 514 | + in_array($name, self::$cf_parse_cache[$appname][0]['date'])) |
|
| 515 | + { |
|
| 452 | 516 | // Custom fields stored in a particular format (from customfields_widget) |
| 453 | 517 | $record[$name] = date('Y-m-d', $record[$name]); |
| 454 | 518 | } |
@@ -460,26 +524,37 @@ discard block |
||
| 460 | 524 | } |
| 461 | 525 | foreach((array)$fields['float'] as $name) |
| 462 | 526 | { |
| 463 | - if($record[$name] != null && $record[$name] != '') { |
|
| 527 | + if($record[$name] != null && $record[$name] != '') |
|
| 528 | + { |
|
| 464 | 529 | $dec_point = $GLOBALS['egw_info']['user']['preferences']['common']['number_format'][0]; |
| 465 | - if (empty($dec_point)) $dec_point = '.'; |
|
| 530 | + if (empty($dec_point)) |
|
| 531 | + { |
|
| 532 | + $dec_point = '.'; |
|
| 533 | + } |
|
| 466 | 534 | $record[$name] = floatval(str_replace($dec_point, '.', preg_replace('/[^\d'.preg_quote($dec_point).']/', '', $record[$name]))); |
| 467 | 535 | } |
| 468 | 536 | } |
| 469 | 537 | |
| 470 | 538 | // Some custom methods for conversion |
| 471 | - foreach((array)$methods as $name => $method) { |
|
| 472 | - if($record[$name]) $record[$name] = ExecMethod($method, $record[$name]); |
|
| 539 | + foreach((array)$methods as $name => $method) |
|
| 540 | + { |
|
| 541 | + if($record[$name]) |
|
| 542 | + { |
|
| 543 | + $record[$name] = ExecMethod($method, $record[$name]); |
|
| 544 | + } |
|
| 473 | 545 | } |
| 474 | 546 | |
| 475 | 547 | // cat_name2id will use currentapp to create new categories |
| 476 | 548 | $current_app = $GLOBALS['egw_info']['flags']['currentapp']; |
| 477 | - if($appname) { |
|
| 549 | + if($appname) |
|
| 550 | + { |
|
| 478 | 551 | $GLOBALS['egw_info']['flags']['currentapp'] = $appname; |
| 479 | 552 | } |
| 480 | 553 | $categories = new Api\Categories('',$appname); |
| 481 | - foreach((array)$fields['select-cat'] as $name) { |
|
| 482 | - if($record[$name]) { |
|
| 554 | + foreach((array)$fields['select-cat'] as $name) |
|
| 555 | + { |
|
| 556 | + if($record[$name]) |
|
| 557 | + { |
|
| 483 | 558 | // Only parse name if it needs it |
| 484 | 559 | if($format == 1) |
| 485 | 560 | { |
@@ -493,7 +568,10 @@ discard block |
||
| 493 | 568 | $cat_id = importexport_helper_functions::cat_name2id($record[$name]); |
| 494 | 569 | } |
| 495 | 570 | // Don't clear it if it wasn't found |
| 496 | - if($cat_id) $record[$name] = $cat_id; |
|
| 571 | + if($cat_id) |
|
| 572 | + { |
|
| 573 | + $record[$name] = $cat_id; |
|
| 574 | + } |
|
| 497 | 575 | } |
| 498 | 576 | } |
| 499 | 577 | } |
@@ -514,7 +592,8 @@ discard block |
||
| 514 | 592 | */ |
| 515 | 593 | protected static function find_select_key($record_value, $selects) |
| 516 | 594 | { |
| 517 | - if($record_value != null && is_array($selects)) { |
|
| 595 | + if($record_value != null && is_array($selects)) |
|
| 596 | + { |
|
| 518 | 597 | if(is_array($record_value) || is_string($record_value) && strpos($record_value, ',') !== FALSE) |
| 519 | 598 | { |
| 520 | 599 | // Array, or CSV |
@@ -526,7 +605,10 @@ discard block |
||
| 526 | 605 | if(!$sub_key) |
| 527 | 606 | { |
| 528 | 607 | $sub_key = static::find_select_key($subs[$sub_index].','.$subs[$sub_index+1], $selects); |
| 529 | - if($sub_key) $sub_index++; |
|
| 608 | + if($sub_key) |
|
| 609 | + { |
|
| 610 | + $sub_index++; |
|
| 611 | + } |
|
| 530 | 612 | } |
| 531 | 613 | if($sub_key) |
| 532 | 614 | { |
@@ -543,7 +625,10 @@ discard block |
||
| 543 | 625 | else |
| 544 | 626 | { |
| 545 | 627 | $key = array_search(strtolower($record_value), array_map('strtolower',array_map('lang',$selects))); |
| 546 | - if($key !== false) $record_value = $key; |
|
| 628 | + if($key !== false) |
|
| 629 | + { |
|
| 630 | + $record_value = $key; |
|
| 631 | + } |
|
| 547 | 632 | } |
| 548 | 633 | } |
| 549 | 634 | |