1

I have been working on this for hours and can't get it. In short, I want to be able to work with both $_FILES and $_POST in my PHP file that handles an AJAX request made through WordPress's API, because this is a file upload procedure that also needs to keep references to the file in the database. Every example I've seen on the internet either shows how to upload a file or use non-file inputs, but never both.

My PHP script which attempts to do both is

add_action( 'wp_ajax_member_update', 'member_update' );

function member_update ( )
{
    // there must be a more elegant way of getting those values out .... 
    $name = $_POST['postData'][0]['value'];
    $title = $_POST['postData'][1]['value'];
    $bio = $_POST['postData'][2]['value'];
    $sord = $_POST['postData'][3]['value'];
    $id = $_POST['postData'][4]['value'];

    $targetFileName = basename($_FILES['pic']['name']); // DOESN'T WORK! $_FILES is empty
    $targetFileNameAndPath = 'assets/' . $targetFileName;

    $message = "";

    $thisAction = $_POST['postData'][5]['value'];

    switch ($thisAction)
    {
        case 'add':
        {
            global $wpdb;
            $q = "INSERT INTO " . MySqlInfo::TEAMTABLENAME . " (name, title, bio, sord, picfn) VALUES (" . implode( ',', array("'$name'", "'$title'", "'$bio'", intval($sord), "'somepic.jpg'")) . ")";
            if($wpdb->query($q))
            {
                if (move_uploaded_file($_FILES['pic']['tmp_name'], $targetFileNameAndPath))
                {
                    $message .= "Successfully added " . $targetFileName . " to assets folder\n";        
                }
                else
                {
                    $message .= "Encountered problem when trying to add " . $targetFileName . " to assets folder\n";

                    // now delete member ...
                }            
            }
            else
            {
                $message .= 'Error when trying to run query ' . $wpdb->last_query;
            }
            break;
        }
        case 'update':
        {
            // ... 
            break;
        }
        case 'delete':
        {
            global $wpdb;
            $qresult = $wpdb->get_results('SELECT picfn FROM ' . MySqlInfo::TEAMTABLENAME . ' WHERE id=' . $id);
            if ($qresult) // if was able to retrieve pic file name from db
            {
                echo "qresult[0] = " . json_encode($qresult[0]);
                // try to delete profile picture from assets folder
                if (unlink(get_template_directory() . '/management/assets/' . $qresult[0]->picfn))
                {
                        // try to delete db info about member
                        if ($wpdb->query("DELETE FROM " . MySqlInfo::TEAMTABLENAME . " WHERE id=" . $id))
                        {
                            $message .= "Member successfully deleted!";
                        }
                        else
                        {
                            $message .= "Deleted profile image, but couldn't delete member from database, for some reason";
                        }
                }
                else
                {
                    $message .= 'Could not delete profile picture from assets folder, for some reason'; 
                }
            }
            else // was not able to retrive pic file name from db
            {
                $message .= "Couldn't select profile picture file name with query " . $wpdb->last_query . ", for some reason.";
            }
            break;
        }
        default:
        {
            $message .= 'Didn\'t recognize action.';
            break;
        }
    }

    echo json_encode($message);
    wp_die();

}

and I'm running into the problem of $_FILES not containing anything. My JavaScript that submits the request is

        jQuery('.member-update-button').click( function() {

            // change the value of the memberAction hidden input based on which member-update-button was clicked
            var memActionInput = jQuery('input[name="memberAction"');
            switch (jQuery(this).attr('id'))
            {

                case 'remv-btn':
                    memActionInput.val('delete');
                    break;
                case 'update-btn':
                    memActionInput.val('update');
                    break;
                case 'add-btn':
                    memActionInput.val('add');
                    break;
            }

            // Serialize form and post using WP hook method            
            var parentForm = jQuery(this).closest('form');
            var postData = parentForm.serializeArray();
            jQuery.post( ajaxurl,
                        {'action': 'member_update', 'postData' : postData},
                        function(response)
                        { 
                            jQuery('#member-modal').modal('hide');
                            alert(response); 

                        }
                       );
        });

and the HTML for the form is

    <form method="POST" action="member-update"  enctype="multipart/form-data" id="member-form">
        <div class="modal fade" id="member-modal">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <div class="row">
                            <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                                <h2></h2>
                            </div>
                        </div>
                    </div>
                    <div class="modal-body">
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                Full name:
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <input type="text" name="fullname" value=""> 
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                Title:
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <input type="text" name="title" value="">
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                Bio (approx 150 chars):
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <textarea rows="4" name="bio" form="member-form"></textarea> 
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                Sort order:
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <input type="text" name="sord" value=""> 
                            </div>                          
                        </div>
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                Pic: 
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <input type="file" name="pic" id="pic-input">
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <div class="row">
                            <div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
                                <!-- empty space -->
                            </div>
                            <div class="col-xs-12 col-sm-9 col-md-9 col-lg-9">
                                <button type="button" class="member-update-button wp-core-ui button-primary" id="remv-btn">Remove</button>
                                <button type="button" class="member-update-button wp-core-ui button-primary" id="update-btn">Update</button>
                                <button type="button" class="member-update-button wp-core-ui button-primary" id="add-btn">Add</button>
                            </div>
                        </div>
                    </div>
                    <input type="hidden" name="memberId" value="" />
                    <input type="hidden" name="memberAction" value="" />
                </div>
            </div>
        </div>
    </form>
  • you're not handling the file uploads properly, since you're serializing the file inputs along with the rest of the form. you can't do ajax file uploads that way... since they're not being handled properly, you're uploading a file, you're just posting a useless input field along with the rest of the form fields, and NOTHING will show up in $_FILES. – Marc B Jul 17 '15 at 21:55
  • @MarcB So I do I have to make 2 AJAX requests? Or what is the proper way? –  Jul 17 '15 at 22:03
  • no, you can do it in one, but you have to set up the uploads properly, and `.serialize()` on the form is NOT enough: http://stackoverflow.com/questions/2320069/jquery-ajax-file-upload – Marc B Jul 17 '15 at 22:04
  • @MarcB Thanks. The problem is that I can't follow the examples because I have to go through the WordPress hook ... –  Jul 17 '15 at 22:08
  • See [this answer](http://stackoverflow.com/questions/5392344/sending-multipart-formdata-with-jquery-ajax) also. I can't help you with Wordpress. – brian Jul 18 '15 at 00:21

0 Answers0