Handling front-end file uploads, considering safety and ease of use

I’m looking to adapt an existing forum-like plugin which has no facility for attaching media.

The plugin works as a Custom Post Type, so it would be as “simple” as attaching an image to a post.

Read More

I am only concerned about attaching images rather than any file type, but the plugin does use wp_editor and as such the solution should in some way integrate with that. I’m not overly fussed about creating a tinyMCE button, as long as the solution is capable of inserting a thumbnail of the image into the tinyMCE textarea.

Please note, I am referring to the front-end of my website rather than the admin area.

In an absolutely ideal situation, I would like this scenario to occur:

  • User clicks “Ask a question”
  • Use enters their post details
  • User clicks a button on the tinyMCE interface which, similar to StackExchange, asks the user to upload a file.
  • System then inserts the correctly-sized thumbnail into the tinyMCE textarea, having crunched the file into this thumbnail size
  • Clicking this image should offer the same functionality as an image attachment in a Post
  • User can then click again to insert a new image
  • User can also delete the image from the tinyMCE textarea as needed

However, I am happy for the tinyMCE button to be peripheral – if a “file upload” box is significantly easier, that’s fine.

I came across this link but I’m always apprehensive about reading WordPress articles on t’interwebs as I’m never too sure of how secure they are, nor am I a php security expert by any stretch of the imagination.

Thanks in advance,

Related posts

Leave a Reply

2 comments

  1. I think the easiest way, since you’re already using the wp_editor function is going to be to just include the media buttons in the WP_Editor instance – this way you’ll have the native functions, including the “Insert into post” button, built in for free.

    How you do this obviously depends on the plugin you’re trying to work with. However, this should get you started. Include code like this in a page template to display the editor, and you’ll get an editor on your page. Including this in a form and processing the results is another step not detailed here.

    // Define the global variable $post_id - this is used by the media uploader
    // to attach uploads to a specific post (so that the uploader can see uploads
    // attached to this post and not others)
    global $post_id;
    $post_id = $post->ID; // should be the ID of the new post created
    
    // Now filter the list of tabs available in the media editor.
    // Remove everything but the "From Computer" option.
    
    add_filter( 'media_upload_tabs', 'wpse42068_remove_additional_tabs' );
    
    function wpse42068_remove_additional_tabs( $_default_tabs ) {
        return array( 'type' => __('From Computer') );
    }
    
    // Now just include the WP_Editor. See
    // http://codex.wordpress.org/Function_Reference/wp_editor
    // for settings available
    wp_editor( '', 'posteditor', array( 'media_buttons' => true ) );
    

    Defining the post ID is probably the critical part, and how you do this is will depend on the logic of your functionality. I would suggest:

    • Creating an auto-draft on first visiting this page, and saving the post ID returned in the global $post_id variable.
    • Then saving the created post with that same ID when the form is submitted.
  2. Maybe this is not your ideal solution, but it worth a shot. Got it by googling but unfortunately I forgot the url. The attaching part is similar with the one on @goldenapples article.

    Here is the basic function.

    function attach_uploads($uploads,$post_id = 0){
        $files = rearrange($uploads);
        if($files[0]['name']==''){
            return false;   
        }
        foreach($files as $file){
            $upload_file = wp_handle_upload( $file, array('test_form' => false) );
            $attachment = array(
            'post_mime_type' => $upload_file['type'],
            'post_title' => preg_replace('/.[^.]+$/', '', basename($upload_file['file'])),
            'post_content' => '',
            'post_status' => 'inherit'
        );
            $attach_id = wp_insert_attachment( $attachment, $upload_file['file'], $post_id );
            $attach_array[] = $attach_id;
            require_once(ABSPATH . 'wp-admin/includes/image.php');
            $attach_data = wp_generate_attachment_metadata( $attach_id, $upload_file['file'] );
            wp_update_attachment_metadata( $attach_id, $attach_data );
        }
        return $attach_array;
    }
    

    The ajax function

    add_action('wp_ajax_attach_file', 'process_attach_file');
    function process_attach_file() {
    
        // add some filter and validation on the id and the files here
        $post_id = $_POST['post_id'];
        $files = $_FILES['profile-picture'];
    
        // insert attachment
        $attached_files = attach_uploads($files,$post_id);
    
        // set the first file as post thumbnail
        if($attached_files){
            set_post_thumbnail( $post_id, $attached_files[0] ); 
        }
    
        // now all you have to do is set the response data
    
    }
    

    The markup

    <form id="upload-form" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" class="form" enctype="multipart/form-data" >
        <label for="profile-picture">Foto Profil</label>
        <input type="file" id="profile-picture" name="profile-picture[]" size="40" multiple />
        <?php wp_nonce_field( // intention nonce); ?>
        <input name="action" value="attach_file" type="hidden">
        <input name="post_id" value="12" type="hidden">
    </form>
    

    Hope this help