I am coding my first WordPress plugin that handles some data for a custom (shop-like) post type. It also has an image uploader within a metabox, where you simply drag in your images and it automatically handles the uploads, filename and media-library integration without reloading the page. (AJAX)

To do this I use Javascript for drag and drop and an AJAX submit to send the images to a wp-function in the backend. I use the media_handle_upload() that wordpress offers. It creates my thumbnails and does the upload process using wp_handle_upload() it also does the db-part for me which is pretty comfortable.

Code for this Part:

//// WP AJAX: UPLOAD FILES ////
add_action('wp_ajax_save_attachments', function ($post) {
    $file = $_FILES['file'];

    if(!empty($file) && $file['size'] > 0) {

        if(isset($_POST['apt_post_id'])) {
            $post_id = $_POST['apt_post_id'];
            // retrieve the filetype & check if is allowed for upload
            $filetype = wp_check_filetype(basename($file['name']));
            $allowed_filetypes = array(
                'image/jpeg',
                'image/png',
                'image/gif',
            );
            if(in_array($filetype['type'], $allowed_filetypes)) {
                // Set up options array to add this file as an attachment
                $post_data = array(
                    "post_title"        => 'Testimage',
                    "post_content"      => "",
                    "post_status"       => "inherit",
                );
                $overrides = array( 'test_form' => false );

                if( $attachment_id = media_handle_upload('file', $post_id, $post_data, $overrides) ) {
                    $attachments = get_attached_media('image', $post_id);
                    $attachment = get_object_vars($attachments[$attachment_id]);
                    $data = array(
                        'ID'        => $attachment['ID'],
                        'thumbnail' => wp_get_attachment_thumb_url($attachment['ID']),
                        'name'      => $attachment['post_title'],
                    );
                    echo json_encode(array(
                        'success'       => true,
                        'message'       => 'Image successfully uploaded!',
                        'attachment'    => $data,
                    ));
                    die;
                }
            } else {
                // errorhandling
            }
        } else {
                // errorhandling
    } else {
                // errorhandling
    }
});

Now I want to upload the images to a specific folder like /wp-root/wp-content/uploads/apartments/ to do this I found out that one can set a filter: add_filter( 'upload_dir', array($this, 'wpUploadDir') );which I did and tested with the “normal” (non-ajax) upload and it worked fine.

But doing the same with an AJAX upload has no effect at all. It always loads the images to the ../2014/07/ folder. Is there any way to change this? I tried to put the filter-call in the ‘admin_init’ or ‘init’ or even before, but nothing seems to work.

I can’t find anything on google that could solve my question, so I am here. Thank you for any hint and solution!

EDIT: The way how I integrated the filter call:
At this state my class is pretty chaotic, but works fine so far… (the cleanup will follow). I try to only show necessary code because it would be more than 1000 lines of code if I’d post it all.

As I already mentioned, I tried 3 calls of the filter. Here you can see them all as comments.

new Zap('zap_apartments');


class Zap
{
    // some privates...

    /**
     *  Stores the upload folder for this post type
     */
    private $_upload_dir="/apartments";

    public function __construct($post_type_id)
    {
        // set post_type_id by argument
        $this->post_type_id = $post_type_id;

        // set post_type as a new object from Fixture
        $this->post_type = new wpObjectsData($this->post_type_id);

        // ONE TRY TO ADD THE FILTER CALL:
        //add_filter( 'upload_dir', array($this, 'wpUploadDir') );

        // runs on plugin activation
        $this->wpPluginActivation();

        // run global wp init
        $this->wpInit();

        // run wp admin init
        $this->wpAdminInit();
    }


    public function wpInit($post)
    {       
        add_action('init', function($post) {

            // register post-type to wordpress
            $this->post_type->registerPostType();

            // register taxonomies to wordpress
            $this->post_type->registerAllTaxonomies();

            // ANOTHER TRY TO ADD THE FILTER CALL:
            //add_filter( 'upload_dir', array($this, 'wpUploadDir') );
        });
    }


    public function wpAdminInit()
    {
        add_action('admin_init', function() {

            // ANOTHER TRY TO ADD THE FILTER CALL:
            //add_filter( 'upload_dir', array($this, 'wpUploadDir') );

            // register wp scripts
            add_action( 'admin_enqueue_scripts', array($this, 'wpRegisterScripts') );

            // call the metaboxes
            $this->metaboxes();
        });
    }


    /**
     *  Set new wp upload directory for custom post type
     *  
     *  @param  []  (required) array with _FILE structure
     *  @return []  array with new _FILE structure
     */
    public function wpUploadDir($param)
    {
        global $post;

        if($post->post_type == $this->post_type_id) {
            $param['path'] = $param['basedir'] . $this->_upload_dir;
            $param['url']  = $param['baseurl'] . $this->_upload_dir;
        }

        return $param;
    }


    /**
     *  Register all metaboxes for the plugin
     */
    public function metaboxes()
    {
        add_action('add_meta_boxes', function() {
                    //   $id (css),      $title,        $callback,              $post_type,         $context,   $priority,  $callback_args
            add_meta_box('zap_coredata', 'Stammdaten',  'apt_coredata',         'zap_apartments',   'normal',   'high');
            add_meta_box('zap_features', 'Merkmale',    'apartment_features',   'zap_apartments',   'normal',   'high');
            add_meta_box('zap_images',   'Bilder',      'apt_images',           'zap_apartments',   'normal',   'high');
        });

        // tons of code here

        //// WP AJAX: UPLOAD FILES
        add_action('wp_ajax_save_attachments', function () {

            // THE CODE YOU CAN INSPECT ABOVE

        });

        // tons of code here... yes i need to clean up soon, I know! ;-)
    }
}

Here's a Picture of the callback right after the dropped image has uploaded

0

Leave a Reply

Your email address will not be published. Required fields are marked *