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! ;-)
}
}