1

I want start saying that I'm learning and I'm trying to understand the use of $_FILES and $file_handler which are making me crazy into this function to upload attachments from a frontend form.

What I've discovered into mine yesterday question was that using $_FILES into the same function makes it overwritten so some nice dude suggested to change this variable in something different like $whatever. Both files could be managed and uploaded then but of course this is not happening yet and only files are uploaded. Having 2 form inputs relatively named:

  • For images: name="moreimages"
  • For files: name="morefiles"

Basically I've arrived at this point in my php:

if ($_FILES)
    {
        // Get the upload attachment files
        $images = $_FILES['moreimages'];
        foreach ($images['name'] as $key => $value)
        {
            if ($images['name'][$key])
            {
                $image = array(
                    'name' => $images['name'][$key],
                    'type' => $images['type'][$key],
                    'tmp_name' => $images['tmp_name'][$key],
                    'error' => $images['error'][$key],
                    'size' => $images['size'][$key]
                );

                //here I've changed the $_FILES variable into something else
                $my_processed_images = array("moreimages" => $image);
                foreach ($my_processed_images as $image => $array)
                {
                    $newupload = project_images($image,$pid);
                }
            }
        }
        // Get the upload attachment files
        $files = $_FILES['morefiles'];
        foreach ($files['name'] as $key => $value)
        {
            if ($files['name'][$key])
            {
                $file = array(
                    'name' => $files['name'][$key],
                    'type' => $files['type'][$key],
                    'tmp_name' => $files['tmp_name'][$key],
                    'error' => $files['error'][$key],
                    'size' => $files['size'][$key],
                    'post_mime_type' => $files['type'][$key]
                );
                $_FILES = array("morefiles" => $file);
                foreach ($_FILES as $file => $array)
                {
                    $uploadfile = project_file($file,$pid);
                }
            }
        }
    }

and my functions look like

function project_images($file_handler, $pid)
    {
        if ($_FILES[$file_handler]['error'] !== UPLOAD_ERR_OK) __return_false();
        require_once(ABSPATH . "wp-admin" . '/includes/image.php');
        require_once(ABSPATH . "wp-admin" . '/includes/file.php');
        require_once(ABSPATH . "wp-admin" . '/includes/media.php');
        $image_id = media_handle_upload( $file_handler, $pid );
        return $image_id;
    }
function project_file($file_handler, $pid)
    {
        if ($_FILES[$file_handler]['error'] !== UPLOAD_ERR_OK) __return_false();
        require_once(ABSPATH . "wp-admin" . '/includes/image.php');
        require_once(ABSPATH . "wp-admin" . '/includes/file.php');
        require_once(ABSPATH . "wp-admin" . '/includes/media.php');
        $file_id = media_handle_upload( $file_handler, $pid );
        update_post_meta($file_id,'is_prj_file','1');
        return $file_id;
    }

I understand that there could be a problem with my $file_handler but I don't know how to manage it. What really is happening is that debugging the $more_images is null and not considered and $_FILES into the second loop is uploaded instead. Can you drive me?

EDIT

My HTML form fields are like these for entire:

<input id="moreimages" accept="image/png, image/jpeg, image/gif" type="file" name="moreimages[]" >

<input id="morefiles" accept=".zip,.pdf,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.psd,.ai" type="file" name="morefiles[]" >

Furthermore My AJAX POST STATUS is OK sending these parameters for moreimages:

Content-Disposition: form-data; name="moreimages[]"; filename="Screen Shot 2016-04-05 at 16.48.10.png"
Content-Type: image/png

PNG

and these parameters for morefiles:

Content-Disposition: form-data; name="morefiles[]"; filename="articolo-slow-food-ararat.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document

So I think the problem, once again, how these data are received into php.

1
  • @TwerkingN00b ok! But where do you mean? Because now I have alerady 2 different varibles with $_FILES = array("morefiles" => $file); and $my_processed_images = array("moreimages" => $image);. You mean in the project_images and project_files functions? Thanks.
    – Kleeia
    Commented May 5, 2016 at 12:44

2 Answers 2

0

I did override something. I did not validation and only build structured to validation and upload function. You can validate file as you needed.

if ($_FILES)
    {
        // Get the upload attachment files
        $images = $_FILES['moreimages'];
        $errors = '';
        foreach ($images['name'] as $key => $value)
        {
            if ($images['name'][$key])
            {
                $image = array(
                    'name' => $images['name'][$key],
                    'type' => $images['type'][$key],
                    'tmp_name' => $images['tmp_name'][$key],
                    'error' => $images['error'][$key],
                    'size' => $images['size'][$key]
                );

                //here I've changed the $_FILES variable into something else
                $_FILES['moreimages'] = $image;
                if( is_wp_error( $moreimages = project_media_handle_upload('moreimages',$pid) ) )
                $errors .= $moreimages->get_error_message();

            }
        }
        // Get the upload attachment files
        $files = $_FILES['morefiles'];
        foreach ($files['name'] as $key => $value)
        {
            if ($files['name'][$key])
            {
                $file = array(
                    'name' => $files['name'][$key],
                    'type' => $files['type'][$key],
                    'tmp_name' => $files['tmp_name'][$key],
                    'error' => $files['error'][$key],
                    'size' => $files['size'][$key],
                    'post_mime_type' => $files['type'][$key]
                );
                $_FILES['morefiles'] = $file;
                if( is_wp_error( $morefiles = project_media_handle_upload( 'morefiles', $pid, 'file' ) ) )
                $errors .= $morefiles->get_error_message();
            }
        }

        if( ! empty( $errors) )
        echo $errors;
    }

function image_and_files_validate_handle( $file ){
    // $file provide all values size, name etc
    // conditional statement here and return every time fixed key with message
    $file['error'] =  'File is invalid';
    return $file;
}

function file_upload_validate_handle( $file ){
    // $file provide all values size, name etc
    // conditional statement here and return every time fixed key with message
    $file['error'] =  $file['name']. ' is invalid format.';
    return $file;
}

add_action( 'project_media_handle_upload', 'save_file_meta_content_id', 10, 2 );

function save_file_meta_content_id( $fid, $type ){
  if( $type == 'file')
  update_post_meta($fid,'is_prj_file','1'); 
}


function project_media_handle_upload( $file_id, $pid, $type= "image" ){

  $action = 'image_upload_action'; //  change custom action name easy to understand

  if( $type !== 'image')
  $action = 'file_upload_action'; 

  if( function_exists('check_upload_size') )
  add_filter(  "{$action}_prefilter", 'check_upload_size'); // wordpress default filter to check upload size

  add_filter(  "{$action}_prefilter", 'image_and_files_validate_handle'); // both conditional validation for images and files
  add_filter(  "file_upload_action_prefilter", 'file_upload_validate_handle');

  require_once(ABSPATH . "wp-admin" . '/includes/image.php');
  require_once(ABSPATH . "wp-admin" . '/includes/file.php');
  require_once(ABSPATH . "wp-admin" . '/includes/media.php');
  $result =  media_handle_upload( $file_id, $pid, array(), array( 
    'test_form' => false,
    'action' => $action
  ));

  if( ! is_wp_error($result) )
  do_action( 'project_media_handle_upload', $result, $type );   

  return $result;
}
1
  • Thank you man for your help! It has been precious for me. However I've solved in another way, implementing the code I already had. Thanks again.
    – Kleeia
    Commented May 5, 2016 at 16:20
0

Everybody has been very useful and I say THANK YOU guys for having helped me out. The problem seems really to be into $_FILES variable which overwrite itself throughout 2 loops. After several tries I've found this solution that works for me and allows to upload both images and files.

if ($_FILES)
    {
        // I've firstly declared main variables
        $images = $_FILES['moreimages'];
        $files = $_FILES['morefiles'];

        //then I check for both if they're empty. That was just it.
        if(!empty($images)) {
            foreach ($images['name'] as $key => $value)
            {
                if ($images['name'][$key])
                {
                    $image = array(
                        'name' => $images['name'][$key],
                        'type' => $images['type'][$key],
                        'tmp_name' => $images['tmp_name'][$key],
                        'error' => $images['error'][$key],
                        'size' => $images['size'][$key]
                    );
                    $_FILES = array("moreimages" => $image);
                    foreach ( $_FILES as $image => $array ) {
                        if ( $_FILES[$image]['error'] !== UPLOAD_ERR_OK ) __return_false();
                        require_once( ABSPATH . "wp-admin" . '/includes/image.php' );
                        require_once( ABSPATH . "wp-admin" . '/includes/file.php' );
                        require_once( ABSPATH . "wp-admin" . '/includes/media.php' );
                        $image_id = media_handle_upload( $image, $pid );
                        update_post_meta( $pid, 'project_image',$image_id);
                    }
                }

            }
        }
        if(!empty($files)) {
            foreach ($files['name'] as $key => $value)
            {
                if ($files['name'][$key])
                {
                    $file = array(
                        'name' => $files['name'][$key],
                        'type' => $files['type'][$key],
                        'tmp_name' => $files['tmp_name'][$key],
                        'error' => $files['error'][$key],
                        'size' => $files['size'][$key]
                    );
                    $_FILES = array("morefiles" => $file);
                    foreach ( $_FILES as $file => $array ) {
                        if ( $_FILES[$file]['error'] !== UPLOAD_ERR_OK ) __return_false();
                        require_once( ABSPATH . "wp-admin" . '/includes/image.php' );
                        require_once( ABSPATH . "wp-admin" . '/includes/file.php' );
                        require_once( ABSPATH . "wp-admin" . '/includes/media.php' );
                        $file_id = media_handle_upload( $file, $pid );
                        update_post_meta( $file_id, 'is_prj_file', '1');
                    }
                } 
            }
        }
    }

Maybe this code is not really efficient and perfect but it does the job. Furthemore it's still without file validation server-side which I'm going to implement later as suggested before.

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.