2

I allow uploading a selected few types of files from the frontend, e.g. .zip, .mp4, .jpeg and .pdf. Till now all these file types had no issues getting attached to the post it is uploaded to. However after upgrading to WordPress 4.0, I have not been able to upload specific .zip file type from the frontend, although it uploads well from the backend using media-upload interface. Please note that the other file types .mp4 and .pdf files still attach with no issues.

Given below is the entire code that performs the attachment function.

if ( isset( $_POST['upload_attachments'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce($_POST['secure_upload'], 'upload_attachments_nonce')) {

    //checking if upload is empty
    //checking if universal filesize is valid

    if ($_FILES) { //loop through multiple files.         
        $files = $_FILES['upload'];
        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]
                );

                $uploaded_file_type = $files['type'][$key];
                $allowed_file_types = array('image/jpg', 'image/jpeg', 'image/png', 'application/pdf', 'application/zip', 'video/mp4');
                $uploaded_file_size = $files['size'][$key];
                $size_in_kb = $uploaded_file_size / 1024;
                $file_size_limit = 10000; // Your Filesize in KB


                if(in_array($uploaded_file_type,  $allowed_file_types)) { 
                   if( $size_in_kb > $file_size_limit ) {
                   $upload_error .= 'Image files must be smaller than '.$file_size_limit.'KB';
                   return;
                   } else {
                   $_FILES = array("upload" => $file);
                   foreach ($_FILES as $file => $array) {
                   $newupload = insert_attachment($file,$post_id);
                   //return; this loop neds to run multiple times so no return here
                 }      
                 }
                 } else { $upload_error .= 'Invalid File type';
                         return;
                        }                                                              

                }
            }
        }                  

    header ('Location: ' . $_SERVER['REQUEST_URI']);//Post, redirect and get
    exit();
    }//end of nonce check 

Helper function insert_attachment by goldenapples

function insert_attachment($file_handler,$post_id,$setthumb='false') {

    // check to make sure its a successful upload
    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');

    $attach_id = media_handle_upload( $file_handler, $post_id );

    //if ($setthumb) update_post_meta($post_id,'_thumbnail_id',$attach_id);
    return $attach_id;
}

Form Html

<form method="post" id="frontend-attachment-upload-form" action="" enctype="multipart/form-data" >
<input type="file" multiple="true" name="upload[]">   

<?php wp_nonce_field('upload_attachments_nonce','secure_upload'); ?>
<input type="submit" id="upload_attachments_button" name="upload_attachments" value="UPLOAD">
<form>

The .zip file is not getting uploaded at all, otherwise I would find them in media-library ,even if unattached. When I try to upload a .zip file in the frontend, it simply returns the error invalid file type. As you can see this line clearly defines all file types:

$allowed_file_types = array('image/jpg', 'image/jpeg', 'image/png', 'application/pdf', 'application/zip', 'video/mp4');

So how come the .mp4, .pdf, .jpeg all other file types gets attached fine and .zip does not? Logically, If there was a mistake in the loop, no file-types would be uploaded at all. Also the fact is .zip files had been uploading fine till a few days ago. I am clueless to what is happening. A little help will be appreciated please.


Just in case I checked for allowed file types and it lists .zip file type as allowed. So, is it possible that wordpress might have made some changes in image.php or file.php or media.php that would block specific file types to be uploaded in the frontend ?

<?php $allowed_mimes = get_allowed_mime_types();
        echo '<pre>';
        print_r($allowed_mimes);
        echo '</pre>';
        ?>

UPDATE : This issue has been solved, kindly take a look at the accepted answer.

  • where does it fail? have you looked at the filetype to see that it matches what's in $appnvid_file_types? – Milo Sep 7 '14 at 17:37
  • 1
    well it's obviously failing somewhere if the file isn't uploaded. my point is you need to narrow it down to what step it fails on- does it enter the if(in_array) check? does it pass that test? does it enter the foreach to loop over the files, etc.. – Milo Sep 7 '14 at 17:49
  • 1
    You need to perform some debugging. What is the resulting return value from the media_handle_upload() call? If there was an error, it will return an error message. – Otto Sep 8 '14 at 1:25
  • How do I perform this check ? Is it possible that wordpress might have made some changes in image.php or file.php or media.php that would unintentionally block specific file types to be uploaded in the frontend ? – gurung Sep 8 '14 at 7:12
0

You need need to update the allowed mime-types that WordPress has in its settings.

For zip/rar files:

function my_modify_mimes( $mimes ) {

    $mimes['zip'] = 'application/zip';
    $mimes['rar'] = 'application/x-rar-compressed';

    return $mimes;
}

add_filter( 'upload_mimes', 'my_modify_mimes' );

Also, if you are uploading from the front-end you should filter who has access to certain mime-types by roles/capabilities.

Rar/zips are also identified with this mime-type: application/octet-stream if errors occur.

  • Sorry, This does not work. Also as suggested by @ialocin i think $allowed_file_types = get_allowed_mime_types(); gets all default allowed mime types which includes .zip as well so this solution has somehow already been covered. – gurung Sep 17 '14 at 6:31
  • Did you tried swapping application/zip to application/octet-stream ? – aifrim Sep 17 '14 at 8:10
0

*I thought I will write this as an update but then I thought it is better to provide the solution as an answer because someone may skip the solution in the question update.

There is no mistake in my code or in the loop for that matter. This is not a server misconfiguration either. As a part of debugging I was echoing back the uploaded filetypes and I realized that when I upload a .zip file it returns as application/x-zip-compressed instead of what I thought should be application/zip. So a small change in the code did the job.

$allowed_file_types = array('application/x-zip-compressed', 'other file types......');

Above works fine now, also to note the .rar file has to be application/x-rar-compressed. I wish it was mentioned on the relevant codex page. I am still sure that this is something that came along with wordpress 4.0. Thanks to @ialocin and @aifrim and others for help.

  • 1
    Funnily enough this should've been you very first step of debugging. Anyway, I'm deleting my answer as it is of no relevance now and after all you solved it. – Nicolai Sep 20 '14 at 12:01
  • Agreed. Nonetheless, many thanks for help, really appreciated. – gurung Sep 20 '14 at 12:05
  • My pleasure. Btw adding the solution as answer is totally compliant with the site rules, actually it's preferable and there is even at least one badge you can earn by answering your own question. – Nicolai Sep 20 '14 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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