Ask your WordPress questions! Pay money and get answers fast! (more info)

how can i check if an uploaded image have a certain size WordPress

  • SOLVED

Hi, That's my first question to this site, I am going to try making it as clear as i can

I am using Advanced custom field, with a flexible content field that contain various "templates"

-flexible content field
-template1
-text field (name of the field txt_field)
... some other fields
-image field (name of the field name img)
-template2
-text field (name of the field name txt_field)
... some other fields
-image field (name of the field name img)
-template3
-text field (name of the field name txt_field)
... some other fields
-image field (name of the field name img)
....

as you notice the text and image field have the same name (that makes it easyer to handle the output on front end).

so what I want to do is on the edit page, when the user try to upload an image via the image custom field on one of these template, check (if possible before uploading) if the image size is a certain size and if it's not prevent the image from uploading and tell the user to upload the good size (or delet the image that has been uploaded and tell the user to upload the good size


for example the image of template 1 should be 100x300px the one of template2 200x450px ...

please let me know if it is unclear

Answers (3)

2014-05-11

Arnav Joy answers:

please try this in your functions.php file of the theme


add_filter('wp_handle_upload_prefilter','aj_handle_upload_prefilter');
function aj_handle_upload_prefilter($file)
{

$img=getimagesize($file['tmp_name']);
$minimum = array('width' => '640', 'height' => '480');
$width= $img[0];
$height =$img[1];

if ($width < $minimum['width'] )
return array("error"=>"Image dimensions are too small. Minimum width is {$minimum['width']}px. Uploaded image width is $width px");

elseif ($height < $minimum['height'])
return array("error"=>"Image dimensions are too small. Minimum height is {$minimum['height']}px. Uploaded image height is $height px");
else
return $file;
}


l.pirondini comments:

Hi, Thanks for this greate answer, the checking of image size is working good.
I still have a problem that I can't figure out:

How can I pass my own width / height parameters depending on the image field that is used.

(if it's on the flexible content field "template1" i would like a certain size, on the flexible content field "template2" another one,
and if that's even possible I have on a third flexible content field "template3" two image fields, they should have different size check)

Idealy I would like to do something like aj_handle_upload_prefilter($file, $reqSize) (where $reqSize is an array with width / height) but i don't know how to pass these param along.

Thanks for your help


l.pirondini comments:

is it possible to set add_filter('wp_handle_upload_prefilter','aj_handle_upload_prefilter');
with an ajax call or it can only be done in function.php?


l.pirondini comments:

Hi again,
your code alone worked on function.php but as I want to set the value of min width and height dynamicly I tryed the following with no luck so far:

on functions.php:

function my_acf_field_group_admin_enqueue_scripts(){

wp_enqueue_script( 'custom_admin_ACF_script', get_template_directory_uri() . '/_/js/ACF_admin.js', array('jquery'));

wp_localize_script( 'custom_admin_ACF_script', 'MyACF', array(
'ajaxurl' => admin_url('admin-ajax.php')
)
);
}

add_action('acf/input/admin_enqueue_scripts', 'my_acf_field_group_admin_enqueue_scripts');

add_action( 'wp_ajax_myaction', 'img_ajax_function' );

function img_ajax_function(){

function aj_handle_upload_prefilter($file) {

$img=getimagesize($file['tmp_name']);

$minimum = array('width' => '640', 'height' => '480');

$width= $img[0];

$height =$img[1];



if ($width < $minimum['width'] )

return array("error"=>"Image dimensions are too small. Minimum width is {$minimum['width']}px. Uploaded image width is $width px");



elseif ($height < $minimum['height'])

return array("error"=>"Image dimensions are too small. Minimum height is {$minimum['height']}px. Uploaded image height is $height px");

else

return $file;

}

add_filter('wp_handle_upload_prefilter','aj_handle_upload_prefilter',1);

}



and here is what I have on my ACF_admin.js :

// JavaScript Document
var $ = jQuery;

$(document).ready(function(e) {

function ajaxImgCall(width, height){

$.ajax({
type : "POST",
action: 'myaction',
data : {width: width, height: height},
url : MyACF.ajaxurl,
beforeSend : function(){
},
success : function(data){

alert("success");


},
error : function(jqXHR, textStatus, errorThrown) {
return;
}
});


}


$(document).on("click", '.field_type-image .acf-input p .acf-button', function(){

template = $(this).closest('.layout').attr('data-layout');
min_width = 400;
min_height = 300;
ajaxImgCall(min_width, min_height);
});

});



so at that point when I click on .acf-button the ajax call alert "sucess".
at the moment I am no using the "min_width" and "min_height" values that I pass trough the ajax function to " img_ajax_function" in the index.php but I was planning to pass them directly like that
$minimum = array('width' => $_POST['width'], 'height' => $_POST['height']);

but as it is now id dosen't work even with static values.

any ideas on that one?

2014-05-12

Dbranes answers:

I'm not sure if I understand your setup or why you need these different restrictions, instead of serving the correct image sizes registered with <em>add_image_size()</em> or through dynamic image resizers.

---

You can try this workaround idea to get the current ACF button template/field ID to the <em>wp_handle_upload_prefilter</em> action callback :

When the user clicks on the "Add Image" button, you can register it with Ajax into the user meta table. Then you can check it within the <em>wp_handle_upload_prefilter</em> action callback. You would then have to register the clicks on the main upload button as well. For example:

function img_ajax_function()
{
$pid = filter_input( INPUT_POST, 'pid', FILTER_SANITIZE_NUMBER_INT);
$field_key = filter_input( INPUT_POST, 'field_key', FILTER_SANITIZE_STRING);


if( 0 < ( $uid = get_current_user_id() ) )
update_user_meta( $uid, 'my_last_acf_field', array( 'pid' => $pid, 'field_key' => $field_key ) );

die();
}


if you send the following via POST Ajax request:

data : {pid: pid, field_key:field_key },


where the <em>pid</em> is the current post id and <em>field_key</em> is the current template/field ID (for examle field_536fa8c89be14 )

Then you can use <em>get_user_meta()</em> within the action callback to check it.

<strong>PS:</strong> Here's a less preferred idea, but you could also try to modify the current url via Javascript when the ACF "Add Image" button is clicked, and then use the <em>HTTP_REFERER</em> within the <em>wp_handle_upload_prefilter</em> hook to get the clicked button ID.


l.pirondini comments:

Hi thanks for this answer looks like a good work around.
I know my setup is quiet wierd I actualy cant use add_image_size(); as the image sizes are very specific to the templates and as I belive uploading a smaller image then the "add_image_size()" will result in no croping ? (not sure if that's right).

I had a look at wp-thumb as a dynamic resizer but if the image is too small same problem again.

so in your example the field key of the clicked image field button gets registred inside the user_meta then in my function.php I could have Arnav Joy's filter code and depending on the field key that is returned set the
$minimum = array('width' => '640', 'height' => '480');
to what I want.

Did I understand it well? I am giving it a try as soon as I have time.

Thanks alot


Dbranes comments:

Hi l.pirondini

ok, so you want the correct image <em>ratio</em>, and avoid users from adding <em>too small images</em>, so the images won't be stretched on your site?

Yes that's the idea, you should be able to use the filter code above, with an additional <em>field key</em> check and perhaps a <em>post id</em> check.


l.pirondini comments:

Hi Dbranes,

Yeah I have to get the images in an exact ratio, as in this website the posts are used in front end to generate a pdf .

At first I was thinking of just displaying a message with the minimu size on each field by field_key, but then that same client proved a total lack of reading and respecting these type of advices. I thought it would be easyer to hook on the media uploader.

but I can't relay on field_key as this is used on a multi site network so i'am implementing your solution retriving the field name from the field key with get_field_object().

so far the solution I got from here is the best I tryed, I think it will do the trick.


Dbranes comments:

But what about the case when the user adds images from the Media Library?

I wonder if you could instead try to stop an image from being selected if it doesn't have the correct ratio and size?


l.pirondini comments:

they can't I will hide the media library in the admin and there is no "add media" button on any Wysiwyg editor as every input is handel by ACF, the templates (flexible content) are all defined in advanced. the output is not much of a website it's more like an anual report/website, every year they create a new post and in that post every flexible custom field (the templates) they create will create a new "page" to that report. then on the front end the pages are put together on a 1 page scroll and the content can be output as a pdf from the front end.

I thing you can trigger a check on select but it wont prevent them to upload various bad sizes before getting it right and then leave them there instead of deleting them.


Dbranes comments:

ok, I was just wondering about that loop hole, looks like you got that covered ;-)

ps:

Just to give you another idea:

Since you can access the the <em>post_id</em> in the <em>wp_handle_upload_prefilter</em> hook, you might have width/height constraints on uploads <strong>per post type</strong>.

Then you could have one custom post type called 'annual' and other extra custom post types called <em>uploads-small</em>,<em>uploads-medium</em>,<em>uploads-large</em>, etc....

Then these extra cpt would use the featured images to store the uploaded photo.

Then one could use the nav-menu admin system to drag/drop the relevant uploads cpt to each annual year cpt.

;-)


l.pirondini comments:

Well I finished integrating the two sampel of code and everything is working greate I dont need post id but I am restricting by template name and for templates that have more than one image by template name + img field name.

Thanks alot guys for helping I actualy learned a lot.

about that work around, is it good practice to store data in user table and use them to dinamicaly change some functions.php functions, or should I avoid doing that on the future for some reasons?


l.pirondini comments:

yeah i thouth about different CPT but on template basis, but it ended up being to complicated to mantain for the user.
in my scenario when they create a new yearly raport they can save it as draft and see the result on front end under a "draft" page only active for loged in users. once they are happy with it they update the post an it gets displayed on the index page replacing the old one. ACF image field is great because I can limit the images avaliable to the ones uploaded to the current post.

I didn't think of that before but then they could select an image with the wrong size if they go in the select tab instead of uploading one, as subjects are different on every page trough the raport they will realy have to mean to select a wrong image size.

2014-05-11

jefrey landicho answers:

if (move_uploaded_file($_FILES['file']['tmp_name'], $file)) {
# ok so check the height and width
# if it is not the width and height assigned delete image and folder
$size = getimagesize($files);
$maxWidth = 500;
$maxHeight = 500;
if ($size[0] > $maxWidth || $size[1] > $maxHeight)
{
unlink($file);
rmdir("./uploads/temp/".$user."/".$mx."/".$hash."/");
rmdir("./uploads/temp/".$user."/".$mx."/");
rmdir("./uploads/temp/".$user."/");
}
else
$result=1;
end if
} else {
# error uploading
$result=$errormsg;
}

just change the variable


l.pirondini comments:

Hi,

Thanks for the quick answer, whis what hook can i use that function so that it triggers on my "image" custom field?