Permalink
Browse files

Issue #12013: Improved ImportExportXml plugin

Improvements made to the importing and exporting features of this
plugin:
* Added support for custom fields, bugnotes and attachments
* Added support for dates (date submitted, last updated) - keep dates as
given in import file
* Added function to easily retrieve the contents of a file
(file_api.php)

Signed-off-by: David Hicks <hickseydr@optusnet.com.au>
  • Loading branch information...
dominik authored and davidhicks committed Jun 23, 2010
1 parent 3c6e93b commit 84017535f8718685d755d58af7a39d80f52ffca8
View
@@ -311,6 +311,7 @@
if ( $t_bug_note->note &&
config_get( 'reassign_on_feedback' ) &&
$t_existing_bug->status === config_get( 'bug_feedback_status' ) &&
$t_updated_bug->handler_id !== auth_get_current_user_id() &&
$t_updated_bug->reporter_id === auth_get_current_user_id() ) {
if ( $t_updated_bug->handler_id !== NO_USER ) {
$t_updated_bug->status = config_get( 'bug_assigned_status' );
View
@@ -108,7 +108,7 @@ class BugData {
# omitted:
# var $bug_text_id
protected $profile_id;
protected $profile_id = 0;
# extended info
protected $description = '';
@@ -310,7 +310,14 @@ function create() {
# check due_date format
if( is_blank( $this->due_date ) ) {
$this_due_date = date_get_null();
$this->due_date = date_get_null();
}
# check date submitted and last modified
if( is_blank( $this->date_submitted ) ) {
$this->date_submitted = db_now();
}
if( is_blank( $this->last_updated ) ) {
$this->last_updated = db_now();
}
$t_bug_table = db_get_table( 'bug' );
@@ -374,7 +381,8 @@ function create() {
" . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ",
" . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ')';
db_query_bound( $query, Array( $this->project_id, $this->reporter_id, $this->handler_id, $this->duplicate_id, $this->priority, $this->severity, $this->reproducibility, $t_status, $this->resolution, $this->projection, $this->category_id, db_now(), db_now(), $this->eta, $t_text_id, $this->os, $this->os_build, $this->platform, $this->version, $this->build, $this->profile_id, $this->summary, $this->view_state, $this->sponsorship_total, $this->sticky, $this->fixed_in_version, $this->target_version, $this->due_date ) );
db_query_bound( $query, Array( $this->project_id, $this->reporter_id, $this->handler_id, $this->duplicate_id, $this->priority, $this->severity, $this->reproducibility, $t_status, $this->resolution, $this->projection, $this->category_id, $this->date_submitted, $this->last_updated, $this->eta, $t_text_id, $this->os, $this->os_build, $this->platform, $this->version, $this->build, $this->profile_id, $this->summary, $this->view_state, $this->sponsorship_total, $this->sticky, $this->fixed_in_version, $this->target_version, $this->due_date ) );
$this->id = db_insert_id( $t_bug_table );
View
@@ -136,14 +136,19 @@ function bugnote_is_user_reporter( $p_bugnote_id, $p_user_id ) {
* @param string $p_attr
* @param int $p_user_id user id
* @param bool $p_send_email generate email?
* @param int $p_date_submitted date submitted (defaults to now())
* @param int $p_last_modified last modification date (defaults to now())
* @param bool $p_skip_bug_update skip bug last modification update (useful when importing bugs/bugnotes)
* @return false|int false or indicating bugnote id added
* @access public
*/
function bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_private = false, $p_type = 0, $p_attr = '', $p_user_id = null, $p_send_email = TRUE ) {
function bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_private = false, $p_type = 0, $p_attr = '', $p_user_id = null, $p_send_email = TRUE, $p_date_submitted = 0, $p_last_modified = 0, $p_skip_bug_update = FALSE ) {
$c_bug_id = db_prepare_int( $p_bug_id );
$c_time_tracking = helper_duration_to_minutes( $p_time_tracking );
$c_private = db_prepare_bool( $p_private );
$c_type = db_prepare_int( $p_type );
$c_date_submitted = $p_date_submitted <= 0 ? db_now() : db_prepare_int( $p_date_submitted );
$c_last_modified = $p_last_modified <= 0 ? db_now() : db_prepare_int( $p_last_modified );
$t_bugnote_text_table = db_get_table( 'bugnote_text' );
$t_bugnote_table = db_get_table( 'bugnote' );
@@ -181,7 +186,7 @@ function bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_
}
# Check for private bugnotes.
if( $p_private && access_has_bug_level( config_get( 'set_view_status_threshold' ), $p_bug_id, $c_user_id ) ) {
if( $c_private && access_has_bug_level( config_get( 'set_view_status_threshold' ), $p_bug_id, $c_user_id ) ) {
$t_view_state = VS_PRIVATE;
} else {
$t_view_state = VS_PUBLIC;
@@ -192,13 +197,15 @@ function bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_
(bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking )
VALUES
(" . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )';
db_query_bound( $query, Array( $c_bug_id, $c_user_id, $t_bugnote_text_id, $t_view_state, db_now(), db_now(), $c_type, $p_attr, $c_time_tracking ) );
db_query_bound( $query, Array( $c_bug_id, $c_user_id, $t_bugnote_text_id, $t_view_state, $c_date_submitted, $c_last_modified, $c_type, $p_attr, $c_time_tracking ) );
# get bugnote id
$t_bugnote_id = db_insert_id( $t_bugnote_table );
# update bug last updated
bug_update_date( $p_bug_id );
if ( !$p_skip_bug_update ) {
bug_update_date( $p_bug_id );
}
# log new bug
history_log_event_special( $p_bug_id, BUGNOTE_ADDED, bugnote_format_id( $t_bugnote_id ) );
View
@@ -302,6 +302,7 @@
define( 'ERROR_CUSTOM_FIELD_IN_USE', 1302 );
define( 'ERROR_CUSTOM_FIELD_INVALID_VALUE', 1303 );
define( 'ERROR_CUSTOM_FIELD_INVALID_DEFINITION', 1304 );
define( 'ERROR_CUSTOM_FIELD_NOT_LINKED_TO_PROJECT', 1305 );
# ERROR_LDAP_*
define( 'ERROR_LDAP_AUTH_FAILED', 1400 );
View
@@ -628,12 +628,19 @@ function file_is_name_unique( $p_name, $p_bug_id ) {
*
* @param integer $p_bug_id the bug id
* @param array $p_file the uploaded file info, as retrieved from gpc_get_file()
* @param string $p_table table ('bug' or 'doc')
* @param string $p_title file title
* @param string $p_desc file description
* @param int $p_user_id user id
* @param int $p_date_added date added
* @param bool $p_skip_bug_update skip bug last modification update (useful when importing bug attachments)
*/
function file_add( $p_bug_id, $p_file, $p_table = 'bug', $p_title = '', $p_desc = '', $p_user_id = null ) {
function file_add( $p_bug_id, $p_file, $p_table = 'bug', $p_title = '', $p_desc = '', $p_user_id = null, $p_date_added = 0, $p_skip_bug_update = false ) {
file_ensure_uploaded( $p_file );
$t_file_name = $p_file['name'];
$t_tmp_file = $p_file['tmp_name'];
$c_date_added = $p_date_added <= 0 ? db_now() : db_prepare_int( $p_date_added );
if( !file_type_check( $t_file_name ) ) {
trigger_error( ERROR_FILE_NOT_ALLOWED, ERROR );
@@ -728,13 +735,15 @@ function file_add( $p_bug_id, $p_file, $p_table = 'bug', $p_title = '', $p_desc
$query = "INSERT INTO $t_file_table
(" . $p_table . "_id, title, description, diskfile, filename, folder, filesize, file_type, date_added, content, user_id)
VALUES
($c_id, '$c_title', '$c_desc', '$c_unique_name', '$c_new_file_name', '$c_file_path', $c_file_size, '$c_file_type', '" . db_now() . "', $c_content, $c_user_id)";
($c_id, '$c_title', '$c_desc', '$c_unique_name', '$c_new_file_name', '$c_file_path', $c_file_size, '$c_file_type', '" . $c_date_added . "', $c_content, $c_user_id)";
db_query( $query );
if( 'bug' == $p_table ) {
# updated the last_updated date
$result = bug_update_date( $p_bug_id );
if ( !$p_skip_bug_update ) {
$result = bug_update_date( $p_bug_id );
}
# log new bug
history_log_event_special( $p_bug_id, FILE_ADDED, $t_file_name );
@@ -868,3 +877,103 @@ function file_get_extension( $p_filename ) {
}
return $t_extension;
}
/**
* Get file content
*
* @param int $p_file_id file id
* @param string $p_type file type (either 'bug' or 'doc')
* @return array|bool array containing file type and content or false on failure to retrieve file
*/
function file_get_content( $p_file_id, $p_type = 'bug' ) {
# we handle the case where the file is attached to a bug
# or attached to a project as a project doc.
$query = '';
switch ( $p_type ) {
case 'bug':
$t_bug_file_table = db_get_table( 'mantis_bug_file_table' );
$query = "SELECT *
FROM $t_bug_file_table
WHERE id=" . db_param();
break;
case 'doc':
$t_project_file_table = db_get_table( 'mantis_project_file_table' );
$query = "SELECT *
FROM $t_project_file_table
WHERE id=" . db_param();
break;
default:
return false;
}
$result = db_query_bound( $query, Array( $p_file_id ) );
$row = db_fetch_array( $result );
if ( $f_type == 'bug' ) {
$t_project_id = bug_get_field( $row['bug_id'], 'project_id' );
} else {
$t_project_id = $row['bug_id'];
}
# If finfo is available (always true for PHP >= 5.3.0) we can use it to determine the MIME type of files
$finfo_available = false;
if ( class_exists( 'finfo' ) ) {
$t_info_file = config_get( 'fileinfo_magic_db_file' );
if ( is_blank( $t_info_file ) ) {
$finfo = new finfo( FILEINFO_MIME );
} else {
$finfo = new finfo( FILEINFO_MIME, $t_info_file );
}
if ( $finfo ) {
$finfo_available = true;
}
}
$t_content_type = $row['file_type'];
switch ( config_get( 'file_upload_method' ) ) {
case DISK:
$t_local_disk_file = file_normalize_attachment_path( $row['diskfile'], $t_project_id );
if ( file_exists( $t_local_disk_file ) ) {
if ( $finfo_available ) {
$t_file_info_type = $finfo->file( $t_local_disk_file );
if ( $t_file_info_type !== false ) {
$t_content_type = $t_file_info_type;
}
}
return array( 'type' => $t_content_type, 'content' => file_get_contents( $t_local_disk_file ) );
}
break;
case FTP:
$t_local_disk_file = file_normalize_attachment_path( $row['diskfile'], $t_project_id );
if ( !file_exists( $t_local_disk_file ) ) {
$ftp = file_ftp_connect();
file_ftp_get ( $ftp, $t_local_disk_file, $row['diskfile'] );
file_ftp_disconnect( $ftp );
}
if ( $finfo_available ) {
$t_file_info_type = $finfo->file( $t_local_disk_file );
if ( $t_file_info_type !== false ) {
$t_content_type = $t_file_info_type;
}
}
return array( 'type' => $t_content_type, 'content' => file_get_contents( $t_local_disk_file ) );
break;
default:
if ( $finfo_available ) {
$t_file_info_type = $finfo->buffer( $row['content'] );
if ( $t_file_info_type !== false ) {
$t_content_type = $t_file_info_type;
}
}
return array( 'type' => $t_content_type, 'content' => $row['content'] );
break;
}
}
View
@@ -238,6 +238,7 @@ $MANTIS_ERROR[ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE] = 'This is a duplicate name.';
$MANTIS_ERROR[ERROR_CUSTOM_FIELD_IN_USE] = 'At least one project still uses this field.';
$MANTIS_ERROR[ERROR_CUSTOM_FIELD_INVALID_VALUE] = 'Invalid value for field "%1$s".';
$MANTIS_ERROR[ERROR_CUSTOM_FIELD_INVALID_DEFINITION] = 'Invalid custom field definition.';
$MANTIS_ERROR[ERROR_CUSTOM_FIELD_NOT_LINKED_TO_PROJECT] = 'Custom field "%1$s" (id %2$s) not linked to currently active project.';
$MANTIS_ERROR[ERROR_LDAP_AUTH_FAILED] = 'LDAP Authentication Failed.';
$MANTIS_ERROR[ERROR_LDAP_SERVER_CONNECT_FAILED] = 'LDAP Server Connection Failed.';
$MANTIS_ERROR[ERROR_LDAP_UPDATE_FAILED] = 'LDAP Record Update has failed.';
@@ -102,23 +102,42 @@ public function import( ) {
echo " Done\n";
// replace references in bug description and additional information
$importedIssues = $this->itemsMap_->getall( 'issue' );
printf( "Processing cross-references for %s issues...", count( $importedIssues ) );
foreach( $importedIssues as $oldId => $newId ) {
$bugData = bug_get( $newId, true );
$bugLinkRegexp = '/(^|[^\w])(' . preg_quote( $this->source_->issuelink, '/' ) . ')(\d+)\b/e';
$replacement = '"\\1" . $this->getReplacementString( "\\2", "\\3" )';
$bugData->description = preg_replace( $bugLinkRegexp, $replacement, $bugData->description );
bug_update( $newId, $bugData, true, true );
// replace links in description
preg_match_all( $bugLinkRegexp, $bugData->description, $matches );
if ( is_array( $matches[3] && count( $matches[3] ) > 0 ) ) {
$content_replaced = true;
foreach ( $matches[3] as $old_id ) {
$bugData->description = str_replace( $this->source_->issuelink . $old_id, $this->getReplacementString( $this->source_->issuelink, $old_id ), $bugData->description);
}
}
// replace links in additional information
preg_match_all( $bugLinkRegexp, $bugData->additional_information, $matches );
if ( is_array( $matches[3] && count( $matches[3] ) > 0 ) ) {
$content_replaced = true;
foreach ( $matches[3] as $old_id ) {
$bugData->additional_information = str_replace( $this->source_->issuelink . $old_id, $this->getReplacementString( $this->source_->issuelink, $old_id ), $bugData->additional_information);
}
}
if ( $content_replaced ) {
// only update bug if necessary (otherwise last update date would be unnecessarily overwritten)
$bugData->update( true );
}
}
// @todo: replace references within bugnotes
echo " Done\n";
}
/**
* Compute and return the new link
*
*
*/
private function getReplacementString( $oldLinkTag, $oldId ) {
$linkTag = config_get( 'bug_link_tag' );
Oops, something went wrong.

0 comments on commit 8401753

Please sign in to comment.