Maybe this tutorial will help you.
EDIT: some code in case the original source gets lost.
1st) Add the meta box to all the post types we need
function wpse31877_add_custom_meta_boxes()
{
foreach ( array( 'post', 'page' ) as $post_type )
{
add_meta_box(
'wp_custom_attachment'
,'Custom Attachment'
,'wpse31877_custom_attachment'
,$post_type
,'side'
);
}
}
add_action( 'add_meta_boxes', 'wpse31877_add_custom_meta_boxes' );
2nd) Set up our callback (the content of the meta box)
function wpse31877_custom_attachment()
{
// validate and secure our upload
wp_nonce_field( plugin_basename(__FILE__), 'wpse31877_custom_attachment_nonce' );
printf(
'<p class="description">%s</p>%s'
,__( 'Upload your PDF here.', 'your_custom_textdomain' )
,'<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25">'
);
}
3rd) Save our data
function wpse31977_save_custom_meta_data( $id )
{
// security verification
if ( ! wp_verify_nonce( $_POST['wpse31977_custom_attachment_nonce'], plugin_basename( __FILE__ ) ) )
{
return $id;
}
if ( defined( 'DOING_AUTOSAVE' ) AND DOING_AUTOSAVE )
{
return $id;
}
if ( 'page' === $_POST['post_type'] )
{
if ( ! current_user_can( 'edit_page', $id ) )
{
return $id;
}
}
else
{
if ( ! current_user_can( 'edit_post', $id ) )
{
return $id;
}
}
// Make sure the file array isn't empty
if ( ! empty( $_FILES['wp_custom_attachment']['name'] ) )
{
// Setup the array of supported file types. In this case, it's just PDF.
$supported_types = array( 'application/pdf' );
// Get the file type of the upload
$arr_file_type = wp_check_filetype( basename( $_FILES['wp_custom_attachment']['name'] ) );
$uploaded_type = $arr_file_type['type'];
// Check if the type is supported. If not, throw an error.
if ( in_array( $uploaded_type, $supported_types ) )
{
// Use the WordPress API to upload the file
$upload = wp_upload_bits( $_FILES['wp_custom_attachment']['name'], null, file_get_contents( $_FILES['wp_custom_attachment']['tmp_name'] ) );
if ( isset( $upload['error'] ) AND 0 != $upload['error'] )
{
wp_die( sprintf( __( 'There was an error uploading your file. The error is: %s', 'your_textdomain' ), $upload['error'] ) );
}
else
{
add_post_meta( $id, 'wp_custom_attachment', $upload );
update_post_meta( $id, 'wp_custom_attachment', $upload );
}
}
else
{
wp_die( __( "The file type that you've uploaded is not a PDF.", 'your_textdomain' );
}
}
} // end save_custom_meta_data
add_action( 'save_post', 'wpse31877_save_custom_meta_data' );
4th) Display the data from the meta box.
echo get_post_meta( get_the_ID(), 'wp_custom_attachment', true );