How to Allow People Upload Photo Wordpress
Read Fourth dimension: 13 mins Languages:
In this tutorial, you lot'll acquire how to create a plugin that allows users to submit images and upload them to the WordPress media library. You'll too learn how to correctly delete images from the WordPress media library as well as do some basic validation on uploaded images.
Previously...
This tutorial is by request from some users who found my quotes plugin tutorial interesting but were specially keen to find out how the aforementioned technique could be used to upload images from the frontend. And so hither's a reiteration of that tutorial that does just that. For detailed info about plugin setup, shortcodes and nonces, see the previous tutorial.
The plugin volition:
- display an image upload grade using a shortcode
- have simply images of a certain type and maximum size
- add a custom post type for user images
- add images to the WordPress media library with a proper attachment caption
- display unpublished images
- allow users to delete their unpublished images
We will use the congenital-in WordPress post thumbnail (aka Featured Epitome) meta field to hold the prototype for each post. This also makes it easier to brandish and work with our image as we can use the post_thumbnail functions.
Here's what nosotros're aiming for:
All code is available in the plugin source at the superlative of this tutorial.
Step 1 Ready-Upwards the Plugin
Create a plugin file named submit_user_images.php in the wp-content/plugins/submit-user-images directory.
Refer to the plugin source for plugin header info.
Stride 2 Plugin Initialization Function
Nosotros're going to create a custom postal service type named user_images to hold our user images and a custom taxonomy named user_image_category. This will enable cleaner administration of the images than but assigning them to normal posts and categories.
The Init Hook and Function
We'll utilise the following initialization lawmaking to create our custom postal service blazon and custom taxonomy:
add_action('init', 'sui_plugin_init'); function sui_plugin_init(){ $image_type_labels = array( 'name' => _x('User images', 'mail service type full general name'), 'singular_name' => _x('User Image', 'post type singular name'), 'add_new' => _x('Add New User Epitome', 'image'), 'add_new_item' => __('Add New User Image'), 'edit_item' => __('Edit User Image'), 'new_item' => __('Add New User Image'), 'all_items' => __('View User Images'), 'view_item' => __('View User Prototype'), 'search_items' => __('Search User Images'), 'not_found' => __('No User Images found'), 'not_found_in_trash' => __('No User Images found in Trash'), 'parent_item_colon' => '', 'menu_name' => 'User Images' ); $image_type_args = array( 'labels' => $image_type_labels, 'public' => true, 'query_var' => truthful, 'rewrite' => truthful, 'capability_type' => 'post', 'has_archive' => truthful, 'hierarchical' => false, 'map_meta_cap' => true, 'menu_position' => null, 'supports' => array('title', 'editor', 'author', 'thumbnail') ); register_post_type('user_images', $image_type_args); $image_category_labels = array( 'proper noun' => _x( 'User Image Categories', 'taxonomy general name' ), 'singular_name' => _x( 'User Image', 'taxonomy singular name' ), 'search_items' => __( 'Search User Image Categories' ), 'all_items' => __( 'All User Image Categories' ), 'parent_item' => __( 'Parent User Image Category' ), 'parent_item_colon' => __( 'Parent User Image Category:' ), 'edit_item' => __( 'Edit User Paradigm Category' ), 'update_item' => __( 'Update User Image Category' ), 'add_new_item' => __( 'Add New User Image Category' ), 'new_item_name' => __( 'New User Image Name' ), 'menu_name' => __( 'User Epitome Categories' ), ); $image_category_args = array( 'hierarchical' => true, 'labels' => $image_category_labels, 'show_ui' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'user_image_category' ), ); register_taxonomy('sui_image_category', array('user_images'), $image_category_args); $default_image_cats = assortment('humor', 'landscapes', 'sport', 'people'); foreach($default_image_cats as $true cat){ if(!term_exists($true cat, 'sui_image_category')) wp_insert_term($cat, 'sui_image_category'); } } What this code does:
- uses the WordPress init activity claw to call a plugin initialization function
- registers a custom post type named user_images
- registers a custom taxonomy named user_image_category and assigns information technology to the user_images mail blazon
- adds some default categories to the user_image_category taxonomy if they don't already exist
We volition at present accept a User Images menu in our admin dashboard and a way to administer user images and their categories.
Step 3 Gear up Some Defaults
We'll need to exercise some bones validation so let'southward define two constants for later employ:
ascertain('MAX_UPLOAD_SIZE', 200000); define('TYPE_WHITELIST', serialize(array( 'image/jpeg', 'paradigm/png', 'image/gif' ))); Step 4 Define A Shortcode
We'll define a shortcode that will allow usa to brandish (and procedure) the user images submission form in a postal service or page:
add_shortcode('sui_form', 'sui_form_shortcode'); Security
Considering our plugin accepts data from the user, we implement the following security mechanisms:
- only logged-in users have access to the image submission class
- we utilise nonces to verify that the forms were generated by our plugin
- images are submitted using wp_insert_post which sanitizes the data earlier saving it to the database
- users can simply view their own images, and nonces preclude them from deleting any other user's image posts
Stride five The Main Function
This is the function chosen by our shortcode. Information technology displays and processes the epitome submission form and the epitome list/deletion form. We'll take it in seize with teeth-sized pieces and in Step 6 we'll look at the helper functions.
part sui_form_shortcode(){ if(!is_user_logged_in()){ return '<p>You need to exist logged in to submit an image.</p>'; } global $current_user; - bank check to see if the user is logged in
- take hold of the WordPress $current_user variable which we'll need to get our user ID
if(isset( $_POST['sui_upload_image_form_submitted'] ) && wp_verify_nonce($_POST['sui_upload_image_form_submitted'], 'sui_upload_image_form') ){ $issue = sui_parse_file_errors($_FILES['sui_image_file'], $_POST['sui_image_caption']); if($upshot['error']){ echo '<p>Mistake: ' . $result['error'] . '</p>'; }else{ $user_image_data = array( 'post_title' => $result['explanation'], 'post_status' => 'awaiting', 'post_author' => $current_user->ID, 'post_type' => 'user_images' ); if($post_id = wp_insert_post($user_image_data)){ sui_process_image('sui_image_file', $post_id, $issue['caption']); wp_set_object_terms($post_id, (int)$_POST['sui_image_category'], 'sui_image_category'); } } } - if the image form has been submitted, there'll exist a sui_upload_image_form_submitted field which was generated by our wp_nonce_field function. We tin can and then verify the nonce and proceed to procedure the submitted image
- practice some validation by passing the file input (where the uploaded image information is stored) and explanation input data to a validation function, sui_parse_file_errors, and display any returned errors
- construct an array setting the post status to pending (the admin volition now have to corroborate information technology for publication), setting the post type to user_images (our custom post type), and setting the author of the paradigm post to the currently logged-in user
- if the image post was successfully inserted, save the prototype in the WordPress media library (sui_process_image) and finally set the category for the image post and display a success message
if (isset( $_POST['sui_form_delete_submitted'] ) && wp_verify_nonce($_POST['sui_form_delete_submitted'], 'sui_form_delete')){ if(isset($_POST['sui_image_delete_id'])){ if($user_images_deleted = sui_delete_user_images($_POST['sui_image_delete_id'])){ echo '<p>' . $user_images_deleted . ' images(south) deleted!</p>'; } } } - if the image delete class has been submitted, in that location'll be a sui_form_delete_submitted field which was generated by our wp_nonce_field role. We can and then verify the nonce and proceed to process the array of images checked for deletion
- nosotros check that we really accept some images checked for deletion by testing $_POST['sui_image_delete_id']. If so, we hand them off to the sui_delete_user_images office (run into Stride half dozen)
- if images were deleted, we brandish a success message
echo sui_get_upload_image_form($sui_image_caption = $_POST['sui_image_caption'], $sui_image_category = $_POST['sui_image_category']); if($user_images_table = sui_get_user_images_table($current_user->ID)){ echo $user_images_table; } - nosotros output the image upload course
- finally, we output the images listing/deletion class by passing the user ID to the sui_get_user_images_table function (see Step half-dozen)
Step vi Helper Functions
Here we'll look at the functions that generate the forms, add the images to the media library and the role that deletes the selected images.
function sui_get_upload_image_form($sui_image_caption = '', $sui_image_category = 0){ $out = ''; $out .= '<grade id="sui_upload_image_form" method="postal service" activity="" enctype="multipart/form-data">'; $out .= wp_nonce_field('sui_upload_image_form', 'sui_upload_image_form_submitted'); $out .= '<characterization for="sui_image_caption">Image Caption - Letters, Numbers and Spaces</label><br/>'; $out .= '<input type="text" id="sui_image_caption" proper name="sui_image_caption" value="' . $sui_image_caption . '"/><br/>'; $out .= '<label for="sui_image_category">Epitome Category</label><br/>'; $out .= sui_get_image_categories_dropdown('sui_image_category', $sui_image_category) . '<br/>'; $out .= '<label for="sui_image_file">Select Your Epitome - ' . MAX_UPLOAD_SIZE . ' bytes maximum</label><br/>'; $out .= '<input type="file" size="60" name="sui_image_file" id="sui_image_file"><br/>'; $out .= '<input type="submit" id="sui_submit" proper name="sui_submit" value="Upload Image">'; $out .= '</form>'; return $out; } - the office accepts 2 optional arguments for repopulating the course fields. This is a convenience for the user.
- a nonce field is output which nosotros check when the form is submitted
- we output a dropdown for the image categories by calling sui_get_image_categories_dropdown (run across next office)
part sui_get_image_categories_dropdown($taxonomy, $selected){ return wp_dropdown_categories(assortment('taxonomy' => $taxonomy, 'name' => 'sui_image_category', 'selected' => $selected, 'hide_empty' => 0, 'echo' => 0)); } - the part accepts two arguments including the element ID of the currently selected category
- we utilise the WordPress wp_dropdown_categories function to create a dropdown that lists the user image categories from the user_image_category taxonomy (our custom taxonomy)
function sui_get_user_images_table($user_id){ $args = array( 'author' => $user_id, 'post_type' => 'user_images', 'post_status' => 'pending' ); $user_images = new WP_Query($args); if(!$user_images->post_count) return 0; $out = ''; $out .= '<p>Your unpublished images - Click to see full size</p>'; $out .= '<class method="post" action="">'; $out .= wp_nonce_field('sui_form_delete', 'sui_form_delete_submitted'); $out .= '<tabular array id="user_images">'; $out .= '<thead><th>Epitome</th><th>Caption</thursday><th>Category</th><th>Delete</th></thead>'; foreach($user_images->posts every bit $user_image){ $user_image_cats = get_the_terms($user_image->ID, 'sui_image_category'); foreach($user_image_cats every bit $cat){ $user_image_cat = $cat->proper noun; } $post_thumbnail_id = get_post_thumbnail_id($user_image->ID); $out .= wp_nonce_field('sui_image_delete_' . $user_image->ID, 'sui_image_delete_id_' . $user_image->ID, false); $out .= '<tr>'; $out .= '<td>' . wp_get_attachment_link($post_thumbnail_id, 'thumbnail') . '</td>'; $out .= '<td>' . $user_image->post_title . '</td>'; $out .= '<td>' . $user_image_cat . '</td>'; $out .= '<td><input type="checkbox" name="sui_image_delete_id[]" value="' . $user_image->ID . '" /></td>'; $out .= '</tr>'; } $out .= '</table>'; $out .= '<input type="submit" name="sui_delete" value="Delete Selected Images" />'; $out .= '</form>'; return $out; } - have the user ID because we demand to get a listing of user images for the current user just
- create $args to specify our user, the mail service type of user_images and user images that are pending (not yet published by the admin)
- execute a custom query using WP_Query
- render false if our query returns no user images
- start a grade and generate a nonce for the class
- loop through the images posts making certain we also grab the category of the image post
- generate a nonce for the image delete checkbox, assigning a unique name for the nonce by concatenating the user image post ID
- output a tabular array row containing the image post info also as a delete checkbox
Why add a nonce for each image post?
Forms can exist manipulated in the browser to mail back unexpected information. In our instance, each delete checkbox is assigned the value of a mail. Only what if a malicious user altered that value and acquired our delete function to remove a post that was not actually listed?
One way to avoid this, is to utilize nonces for each row of post data, ensuring that the nonces are uniquely named with the post value to be deleted. We so verify the nonce upon form submission to make certain information technology'due south a genuine return value.
function sui_delete_user_images($images_to_delete){ $images_deleted = 0; foreach($images_to_delete as $user_image){ if (isset($_POST['sui_image_delete_id_' . $user_image]) && wp_verify_nonce($_POST['sui_image_delete_id_' . $user_image], 'sui_image_delete_' . $user_image)){ if($post_thumbnail_id = get_post_thumbnail_id($user_image)){ wp_delete_attachment($post_thumbnail_id); } wp_trash_post($user_image); $images_deleted ++; } } return $images_deleted; } - the office accepts an array of image post IDs to delete
- each image postal service ID is checked to run across if a nonce was generated for it
- if the nonce verifies, we delete the image attachment that exists in the media library by passing the id of the epitome mail thumbnail to the WordPress role wp_delete_attachment
- we also trash the image post using the WordPress office wp_trash_post
Just doesn't the thumbnail attachment go deleted when the post is trashed?
No and that'southward because WordPress stores attachments every bit regular posts in the posts database table. Have a look yourself: all attachments are stored in the posts table with a post_type of zipper. Simply deleting a postal service of type user_images doesn't delete its thumbnail attachment. It remains in the media library for futurity use unless we specifically delete information technology with wp_delete_attachment. For our purposes, I idea it was best to remove the attachment when the user's post was deleted.
Footstep vii The Paradigm Handling Functions
Let's remind ourselves of what the output of an html file input looks like when information technology posts an paradigm to your script:
Assortment ( [name] => ref_blind.jpg [blazon] => image/jpeg [tmp_name] => /tmp/php79xI4e [error] => 0 [size] => 106290 )
We pass that array to the sui_process_image function forth with the id of the saved user image post and the santized image explanation.
function sui_process_image($file, $post_id, $caption){ require_once(ABSPATH . "wp-admin" . '/includes/image.php'); require_once(ABSPATH . "wp-admin" . '/includes/file.php'); require_once(ABSPATH . "wp-admin" . '/includes/media.php'); $attachment_id = media_handle_upload($file, $post_id); update_post_meta($post_id, '_thumbnail_id', $attachment_id); $attachment_data = assortment( 'ID' => $attachment_id, 'post_excerpt' => $caption ); wp_update_post($attachment_data); return $attachment_id; } - we need to include the WordPress admin scripts that handle image uploads behind the scenes
- nosotros call the media_handle_upload part (which is part of media.php), passing it the uploaded file array and the post id
- now nosotros have an attachment id which nosotros can use with update_post_meta to assign the attachment to the postal service equally its thumbnail. Notation: "_thumbnail_id" refers to the internal thumbnail (Featured Image) meta field. Internal Wordpress fields begin with an underscore.
- we next use the attachment id to update the caption of the zipper using the wp_update_post function
Because attachments are just regular posts, if we update the post_excerpt field for the attachment, we are actually updating the attachment'southward caption field every bit seen in the media library edit screen.
The validation role
We likewise validate the file array and the user-provided paradigm explanation with the sui_parse_file_errors role.
function sui_parse_file_errors($file = '', $image_caption){ $result = array(); $result['error'] = 0; if($file['mistake']){ $result['fault'] = "No file uploaded or there was an upload error!"; return $result; } $image_caption = trim(preg_replace('/[^a-zA-Z0-9\s]+/', ' ', $image_caption)); if($image_caption == ''){ $result['error'] = "Your caption may only contain letters, numbers and spaces!"; return $result; } $upshot['caption'] = $image_caption; $image_data = getimagesize($file['tmp_name']); if(!in_array($image_data['mime'], unserialize(TYPE_WHITELIST))){ $result['fault'] = 'Your paradigm must be a jpeg, png or gif!'; }elseif(($file['size'] > MAX_UPLOAD_SIZE)){ $issue['error'] = 'Your image was ' . $file['size'] . ' bytes! It must not exceed ' . MAX_UPLOAD_SIZE . ' bytes.'; } return $result; } - check the error chemical element of the files array for an html upload mistake, if found return a result array with error
- run some regex on the paradigm caption to remove everything merely alphanumeric data and spaces, replacing with spaces for readability
- if we end upwards with an empty caption after sanitizing it, nosotros return an mistake
- check the internal image blazon (don't trust the file extension) using the PHP getimagesize office confronting the TYPE_WHITELIST constant
- check the paradigm size against the MAX_UPLOAD_SIZE abiding
Step 8 Some Styling
But drib this style info into the style.css file in your theme folder:
#sui_upload_image_form #sui_image_caption{ width:500px; } #user_images{ font-size:12px; } #user_images th{ text-align:left; } #user_images td{ vertical-align:heart; } #user_images td input{ margin:0px; } Pace 9 Endeavour Information technology Out
Activate the plugin, pop the shortcode onto a folio, log into your site, and test it out. When you upload an image yous'll run across a new mail service appear under the User Images admin menu. It will be pending publication. You'll likewise see a new prototype listed in your media library, attached to your new mail service and with the explanation equally provided.
The full plugin code source and a demo site link is listed at the pinnacle of this tutorial.
The source folder likewise contains a Wordpress folio template with a custom loop that displays published images for all users.
Concluding Thoughts
You may wish to place more stringent validation on your image uploads. Recall, you lot're accepting data from users who may accidentally or maliciously upload inappropriate files. Checking the file type and size is a skillful start.
Also, nosotros created the attachment caption by updating the attachment's post_excerpt field. You tin can also set an attachment description by using the attachment'southward post_content field.
Did you find this post useful?
Source: https://code.tutsplus.com/articles/allow-users-to-submit-images-to-your-wordpress-site--wp-22601
0 Response to "How to Allow People Upload Photo Wordpress"
Post a Comment