From 66bf62296c075da741877e54efba4ab63633a0fc Mon Sep 17 00:00:00 2001 From: Jacob Hoover Date: Mon, 3 May 2010 23:45:42 -0500 Subject: [PATCH] Fix #11687: Bugs with attachments that are moved will lose attachments --- bug_actiongroup.php | 2 + core/file_api.php | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 0 deletions(-) diff --git a/bug_actiongroup.php b/bug_actiongroup.php index 7d72793..fb68327 100644 --- a/bug_actiongroup.php +++ b/bug_actiongroup.php @@ -101,7 +101,9 @@ if ( access_has_bug_level( config_get( 'move_bug_threshold' ), $t_bug_id ) ) { /** @todo we need to issue a helper_call_custom_function( 'issue_update_validate', array( $t_bug_id, $t_bug_data, $f_bugnote_text ) ); */ $f_project_id = gpc_get_int( 'project_id' ); + $t_origional_bug_project = bug_get_field( $t_bug_id, 'project_id' ); bug_set_field( $t_bug_id, 'project_id', $f_project_id ); + file_move_bug_attachments( $t_bug_id, $t_origional_bug_project, $f_project_id ); helper_call_custom_function( 'issue_update_notify', array( $t_bug_id ) ); } else { $t_failed_ids[$t_bug_id] = lang_get( 'bug_actiongroup_access' ); diff --git a/core/file_api.php b/core/file_api.php index 4729d4d..6973245 100644 --- a/core/file_api.php +++ b/core/file_api.php @@ -855,3 +855,82 @@ function file_get_extension( $p_filename ) { } return $t_extension; } + +/** + * Move any attachements as needed when a bug is moved from project to project + * + * @param integer $p_bug_id the bug id + * @param integer $p_project_id_from the project id the bug was in + * @param integer $p_project_id_to the project id the bug was moved to + */ +function file_move_bug_attachments( $p_bug_id, $p_project_id_from, $p_project_id_to ) { + if ( $p_project_id_from == $p_project_id_to ) { + return true; + } + + $t_method = config_get( 'file_upload_method' ); + + # Optimization here, as DB atachments don't need to be moved. + if ( file_bug_has_attachments($p_bug_id) == true && $t_method != DATABASE ){ + $t_path_from = project_get_field( $p_project_id_from, 'file_path' ); + if ( is_blank( $t_path_from ) ) { + $t_path_from = config_get( 'absolute_path_default_upload_folder' ); + } + $t_path_to = project_get_field( $p_project_id_to, 'file_path' ); + if ( is_blank( $t_path_to ) ) { + $t_path_to = config_get( 'absolute_path_default_upload_folder' ); + } + if ( $t_path_from == $t_path_to ) { + return true; + } + + $t_attachment_rows = bug_get_attachments( $p_bug_id ); + $t_attachments_count = count( $t_attachment_rows ); + $t_bug_file_table = db_get_table( 'bug_file' ); + $c_bug_id = db_prepare_int( $p_bug_id ); + + # Initialize the update query to update a single row + $query_disk_attachment_update = "UPDATE $t_bug_file_table + SET folder=" . db_param() . " + WHERE bug_id=" . db_param() . " + AND id =" . db_param(); + + file_ensure_valid_upload_path( $t_path_from ); + file_ensure_valid_upload_path( $t_path_to ); + + for( $i = 0;$i < $t_attachments_count;$i++ ) { + $t_row = $t_attachment_rows[$i]; + $t_basename = basename( $t_row['diskfile'] ); + + $t_disk_file_name_from = file_path_combine( $t_path_from, $t_basename ); + $t_disk_file_name_to = file_path_combine( $t_path_to, $t_basename ); + + switch( $t_method ) { + case FTP: + case DISK: + # In the case of FTP storage, it's my understanding that all the files are stored + # in a single folder, so we don't need to do anything with the remote ftp backup + if( !file_exists( $t_disk_file_name_to ) ) { + chmod( $t_disk_file_name_from, 0775 ); + if ( !rename( $t_disk_file_name_from, $t_disk_file_name_to ) ) { + if ( !copy( $t_disk_file_name_from, $t_disk_file_name_to ) ) { + trigger_error( FILE_MOVE_FAILED, ERROR ); + } + file_delete_local( $t_disk_file_name_from ); + } + chmod( $t_disk_file_name_to, config_get( 'attachments_file_permissions' ) ); + db_query_bound( $query_disk_attachment_update, Array( db_prepare_string( $t_path_to ), $c_bug_id, db_prepare_int( $t_row['id'] ) ) ); + } else { + trigger_error( ERROR_FILE_DUPLICATE, ERROR ); + } + break; + case DATABASE: + # Nothing to do with DB storage, but if we needed to update any meta data, we would remove the upper + # optimization, and then update here + break; + default: + trigger_error( ERROR_GENERIC, ERROR ); + } + } + } +} \ No newline at end of file -- 1.7.0.2.msysgit.0