1

I have a form that allows users to upload an image. I'm using the code below (which currently doesn't work) to ensure what a user uploads is valid.

Can someone help me out and either update my code or point me in the right direction as to how I can use as many of the built-in WordPress functions (wp_check_filetype_and_ext()), or anything else that would be well-suited, to handle the validation as possible? It also must be secure to prevent any malicious files, attacks, etc.

if ( $_FILES ) {
  foreach ($_FILES as $file => $array) {
    //Check if the $_FILES is set and if the size is > 0 (if =0 it's empty)
    if ( isset( $_FILES[$file]) && ($_FILES[$file]['size'] > 0 ) ) {
      $tmpName = $_FILES[$file]['tmp_name'];
      list($width, $height, $type, $attr) = @getimagesize($tmpName);

      if ($width != 500 || $height != 500) {
        $error .= "Image is to small<br />";
        unlink($_FILES[$file]['tmp_name']);
      }

      // Get the type of the uploaded file. This is returned as "type/extension"
      $arr_file_type = wp_check_filetype(basename($_FILES[$file]['name']));
      $uploaded_file_type = $arr_file_type['type'];

      // Set an array containing a list of acceptable formats
      $allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png');

      // If the uploaded file is the right format
      if (in_array($uploaded_file_type, $allowed_file_types)) {
      } else { // wrong file type
        $error .= "Please upload a JPG, GIF, or PNG file<br />";
      }
    }
  }
}
4
  • 1
  • Thanks for the reply. I'm not really familiar with it, nor am I a PHP developer. The only part I need is file validation. I have functionality in place to handle the image uploading, saving, etc. What do you recommend?
    – user1462
    Commented Dec 12, 2014 at 0:55
  • I'd recommend using the WordPress APIs for as much of it as possible. That way your using tried and tested code, maintained by people whose job it is to make it work
    – Tom J Nowell
    Commented Dec 12, 2014 at 0:56
  • The image is uploaded using BuddyPress, along with the BuddyPress XProfile Image Field plug-in. It just doesn't have any validation so users can upload whatever they want!
    – user1462
    Commented Dec 12, 2014 at 0:58

1 Answer 1

3

All of the code in your question can be replaced with:

require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
if ( $_FILES ) {
  foreach ($_FILES as $file => $array) {
    $image_post_id = media_handler_upload( $file );
    if ( is_wp_error( $image_post_id ) ) {
      $error .= $image_post_id->get_error_message();
    } else {
      // $image_post_id now holds the post ID of an attachment that is your uploaded file
    }
  }
}

The power of media_handle_upload means that now you have now completely outsourced your security, checking, and uploading to WordPress Core. media_handle_upload will be maintained long after you've finished your project, by people who are far smarter than either of us, and other people with a vested interest in keeping WordPress secure.

media_handle_upload will do all of the checking you get when you upload things via the dashboard, and will create attachment posts to represent these uploaded files in the database. It will also handle the creation of different image sizes, and compatibility with plugins, and respect the security settings specified in the dashboard.

If successful, it will return the ID of the attachment post it created. If unsuccessful, it will return a WP_Error object with an error message.

You can then use wp_get_attachment_url if you need the full URL of the attachment, or wp_get_attachment_image_src if you need to get a particular size for the image, e.g.:

$image = wp_get_attachment_image_src( $image_post_id, 'thumbnail' );
if ( $image != false ) {
    echo $image[0];
}
8
  • The form is actually located on the front-end. Would this solution still work there as well? All I really need it to do is just flag an error if it's: an invalid file, not the exact dimensions, and over a specified file size. If it passes all these requirements, then the functionality is in place to handle the image (uploading, store the info in the database, etc.)
    – user1462
    Commented Dec 12, 2014 at 1:15
  • This code is for the handling of the form once it's submitted, and it will give you an attachment post. What you do with that attachment post is up to you, without knowing anything more about how the values are stored or what you then do with them, I can't comment. However, checking the size, file type, etc, is all handled by media_handle_upload. What I have in my answer should function in place of what you posted in your question
    – Tom J Nowell
    Commented Dec 12, 2014 at 1:17
  • I'm getting Warning: Missing argument 2 for media_handle_upload()... Any ideas how to get it to work without a $post_id? A post ID doesn't exist for the page that contains the form.
    – user1462
    Commented Dec 12, 2014 at 1:30
  • Ah yes, you can pass a 0 according to the documentation if you don't want to attach it to anything
    – Tom J Nowell
    Commented Dec 12, 2014 at 1:39
  • I added includes to media.php and async-upload.php, but it's prompting me to log into the WP Admin. This has to work on the front-end for logged in users. Is there anyway to get media_handle_upload to work there and not in the WP Admin?
    – user1462
    Commented Dec 12, 2014 at 2:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.