How do I make multiple image uploads with WordPress metabox?

12.3k views Asked by At

Hello

I created an Image upload with WordPress Meta-box, but it works only with "JPG" extension

By this code

function add_custom_meta_boxes() {

    // Define the custom attachment for posts
    add_meta_box(
        'wp_custom_attachment',
        'Product Images',
        'wp_custom_attachment',
        'post',
        'normal'
    );


} // end add_custom_meta_boxes
add_action('add_meta_boxes', 'add_custom_meta_boxes');

function wp_custom_attachment() {

    wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce');

    $html = '<p class="description">';
        $html .= 'Upload your Image here.';
    $html .= '</p>';
    $html .= '<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" />';

    echo $html;

} // end wp_custom_attachment

function save_custom_meta_data($id) {

    /* --- security verification --- */
    if(!wp_verify_nonce($_POST['wp_custom_attachment_nonce'], plugin_basename(__FILE__))) {
      return $id;
    } // end if

    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
      return $id;
    } // end if

    if('page' == $_POST['post_type']) {
      if(!current_user_can('edit_page', $id)) {
        return $id;
      } // end if
    } else {
        if(!current_user_can('edit_page', $id)) {
            return $id;
        } // end if
    } // end if
    /* - end security verification - */

    // 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 JPG.
        $supported_types = array('image/jpg', 'image/jpeg', 'image/pjpeg');

        // 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']) && $upload['error'] != 0) {
                wp_die('There was an error uploading your file. The error is: ' . $upload['error']);
            } else {
                add_post_meta($id, 'wp_custom_attachment', $upload);
                update_post_meta($id, 'wp_custom_attachment', $upload);
            } // end if/else

        } else {
            wp_die("The file type that you've uploaded is not a JPG.");
        } // end if/else

    } // end if

} // end save_custom_meta_data
add_action('save_post', 'save_custom_meta_data');

function update_edit_form() {
    echo ' enctype="multipart/form-data"';
} // end update_edit_form
add_action('post_edit_form_tag', 'update_edit_form');

and it`s work good.

My question now is "How do I create a multiple image uploads and give it more supported_types?"

Thank you

4

There are 4 answers

6
Nisarg Thakkar On BEST ANSWER

i find that code in site and did some modification on it

//***************************** Start banner images metabox in page page ***********************



function call_Multi_Image_Uploader()
{
    new Multi_Image_Uploader();
}
function get_images($post_id=null)
{
    global $post;

    if ($post_id == null)
    {
        $post_id = $post->ID;
    }

    $value = get_post_meta($post_id, 'images', true);
    $images = unserialize($value);
    $result = array();
    if (!empty($images))
    {
        foreach ($images as $image)
        {
            $image = str_replace('.jpg', '-1903x428.jpg' , $image);
            $result[] = $image;
        }
    }
    return $result;
}

if (is_admin())
{
    add_action('load-post.php', 'call_Multi_Image_Uploader');
    add_action('load-post-new.php', 'call_Multi_Image_Uploader');
}
/**
 * Multi_Image_Uploader
 */
class Multi_Image_Uploader
{
    var $post_types = array();

    /**
     * Initialize Multi_Image_Uploader
     */
    public function __construct()
    {
        $this->post_types = array('page');     //limit meta box to certain post types
        add_action('add_meta_boxes', array($this, 'add_meta_box'));
        add_action('save_post', array($this, 'save'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
    }

    /**
     * Adds the meta box container.
     */
    public function add_meta_box($post_type)
    {
        if (in_array($post_type, $this->post_types))
        {
            add_meta_box(
                    'multi_image_upload_meta_box'
                    , __('Banner Image Upload', 'textdomain')
                    , array($this, 'render_meta_box_content')
                    , $post_type
                    , 'advanced'
                    , 'high'
            );
        }
    }
    /**
     * Save the images when the post is saved.
     *
     * @param int $post_id The ID of the post being saved.
     */
    public function save($post_id)
    {    /*
         * We need to verify this came from the our screen and with proper authorization,
         * because save_post can be triggered at other times.
         */

        // Check if our nonce is set.
        if (!isset($_POST['inner_custom_box_nonce']))
            return $post_id;

        $nonce = $_POST['inner_custom_box_nonce'];

        // Verify that the nonce is valid.
        if (!wp_verify_nonce($nonce, 'inner_custom_box'))
            return $post_id;

        // If this is an autosave, our form has not been submitted,
        //     so we don't want to do anything.
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
            return $post_id;

        // Check the user's permissions.
        if ('page' == $_POST['post_type'])
        {
            if (!current_user_can('edit_page', $post_id))
                return $post_id;
        } else
        {
            if (!current_user_can('edit_post', $post_id))
                return $post_id;
        }

        /* OK, its safe for us to save the data now. */
        // Validate user input.
        $posted_images = $_POST['images'];
        $images = array();
        if (!empty($posted_images))
        {
            foreach ($posted_images as $image_url)
            {
                if (!empty($image_url))
                    $images[] = esc_url_raw($image_url);
            }
        }

        // Update the images meta field.
        update_post_meta($post_id, 'images', serialize($images));
    }

    /**
     * Render Meta Box content.
     *
     * @param WP_Post $post The post object.
     */
    public function render_meta_box_content($post)
    {

        // Add an nonce field so we can check for it later.
        wp_nonce_field('inner_custom_box', 'inner_custom_box_nonce');

        // Use get_post_meta to retrieve an existing value from the database.
        $value = get_post_meta($post->ID, 'images', true);

        $metabox_content = '<div id="images"></div><input type="button" onClick="addRow()" value="Add Image" class="button" />';
        echo $metabox_content;

        $images = unserialize($value);

        $script = "<script>
            itemsCount= 0;";
        if (!empty($images))
        {
            foreach ($images as $image)
            {
                $script.="addRow('{$image}');";
            }
        }
        $script .="</script>";
        echo $script;
    }

    function enqueue_scripts($hook)
    {
        if ('post.php' != $hook && 'post-edit.php' != $hook && 'post-new.php' != $hook)
            return;
        wp_enqueue_script('banner_uploader',  get_template_directory_uri()."/js/banner_uploader.js", array('jquery'));
    }

}


//***************************** END banner images metabox in page page ***********************
2
Mangesh Parte On

There is a quick and good way/practice to achieve this.

http://metabox.io/meta-box/

0
Floris On

I know you did not ask for a plugin but for multiple image uploads I stumbled upon this free plugin that fits all needs: ACF Photo Gallery Field. Simple add this gallery field to the post type you want and you can easily attach as many images as you want. Also fetching the images can be done with a few lines of code.

0
svelandiag On

Here's is my working solution, Im making the use of basic HTML multiple upload form, you just need to give different treatment to $_FILES, here you can find the documentation.

// 3. Save the order invoices
add_action('save_post', 'save_order_invoice_meta');
function save_order_invoice_meta($id) {
 
    /* --- security verification --- */
    if(!wp_verify_nonce($_POST['order_invoice_nonce'], plugin_basename(__FILE__))) {
      return $id;
    } // end if
       
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
      return $id;
    } // end if

    if('page' == $_POST['post_type']) {
      if(!current_user_can('edit_page', $id)) {
        return $id;
      } // end if
    } else {
        if(!current_user_can('edit_page', $id)) {
            return $id;
        } // end if
    } // end if
    /* - end security verification - */
    
    $invoices = $_FILES['order_invoice'];
    
    // Make sure the file array isn't empty
    if(!empty($invoices)) {
        
        $invoices_cleaned = reArrayFiles($invoices);
        
        // Setup the array of supported file types. In this case, it's just PDF.
        $supported_types = array('application/pdf');
        
        $metadata_index = 1;
        
        foreach( $invoices_cleaned as $invoice ) {
         
            // Get the file type of the upload
            $arr_file_type = wp_check_filetype(basename($invoice['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($invoice['name'], null, file_get_contents($invoice['tmp_name']));
         
                if(isset($upload['error']) && $upload['error'] != 0) {
                    wp_die('There was an error uploading your file. The error is: ' . $upload['error']);
                } else {
                    add_post_meta($id, "order_invoice_$metadata_index", $upload);
                    update_post_meta($id, "order_invoice_$metadata_index", $upload);
                    $metadata_index++;
                } // end if/else
     
            } else {
                wp_die("The file type that you've uploaded is not a PDF.");
            } // end if/else
        }
         
    } // end if
     
} // end save_custom_meta_data

// 4. Adding extra markup to the form tag of the order edit form in order to accept images and multiple file upload
add_action('post_edit_form_tag', 'update_order_edit_form');
function update_order_edit_form() {
    echo 'multipart="" enctype="multipart/form-data"';
} // end update_order_edit_form

// Helper function to re-order multiple uploaded files array to something more cleaner
function reArrayFiles(&$file_post) {

    $file_ary = array();
    $file_count = count($file_post['name']);
    $file_keys = array_keys($file_post);

    for ($i=0; $i<$file_count; $i++) {
        foreach ($file_keys as $key) {
            $file_ary[$i][$key] = $file_post[$key][$i];
        }
    }

    return $file_ary;
}

With this, you will generate different metadata for each image uploaded, now the next thing you need to do is to properly set up your metabox callback, the input field should be something like this:

<input type="file" id="order_invoice_attachment" name="order_invoice[]" value="" size="25" multiple/>

Then you will need to properly display the files, I will let that up to you, but with this implementation, the files are saved properly as metadata fields on the order.