17

I have finally!! got this thing I've tried about 12 times to make and 12 different ways, but finally got it to work,... sort of.

I made a custom metabox for uploading and attaching images to posts, and it doesn't require you to use the horrible thickbox media uploader built into WP. I hate that thing. No, what I've done is just a group of inputs (title, description, file), which you can also duplicate, to add additional attachments if you want. So you fill in the fields, select an image to upload, and save draft or publish the post. Once there are attachments added to a post, the metabox will display the input fields, along with a preview image of the attached image for each attachment you added. The title and description fields are used to generate the file meta data, nothing is saved as the post_meta, that I know of. That's currently all that I have gotten working so far.

I need to make it so that when you save/publish a post, inturn upload/create the attachment files, it will create the three image sizes as the default wp uploader would, thumbnail, medium, large, and keeping the full size image too. If that's possible somehow. If not, I would like to otherwise use add_image_size() to create/define new custom sizes, and generate them that way instead, upon uploading.

I'm not sure which function is the most ideal to use in this case, maybe the image_make_intermediate_size() function would be better, or wp_create_thumbnail() or wp_crop_image()... who knows!!

I cannot figure out how to go about doing that, if I need to run the wp_handle_upload() function for each one, or maybe something involving the wp_generate_attachment_metadata() function. It's confusing to me since the 3 image sizes are to be associated as variants of the same attachment, and how to go about doing that.

I have scoured the web, read the source of every wp media/upload/image related file, and played with just about every function there is for the media upload stuff and cannot find how WP creates the 3 image sizes anywhere, or how to do it myself.

In wp-includes/media.php the image_resize() function looks like it would be best since it's exactly what it should be. I just can't figure out for the life of me what the hell I'm missing or have tried doing but did wrong to make the image thumbnails.

Here's my working function that does the wp_handle_upload() stuff and things, but it also needs to create the 100px thumb, and make a resize version of the image that is max-width like 500px, and saved as new files of the uploaded one.

function update_attachment(){
  global $post;

  wp_update_attachment_metadata( $post->ID, $_POST['a_image'] );

  if( !empty( $_FILES['a_image']['name'] )) { //New upload
    require_once( ABSPATH . 'wp-admin/includes/file.php' );

    $override['action'] = 'editpost';
    $url = wp_handle_upload( $_FILES['a_image'], $override );

    // $medium = image_make_intermediate_size( $uploaded_file['url'], 500, 400, true );
    // $thumb = = image_make_intermediate_size( $uploaded_file['url'], 100, 100, true );

    if ( isset( $file['error'] )) {
      return new WP_Error( 'upload_error', $file['error'] );
    }

    $array_type = wp_check_filetype
    $allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png');

    $name_parts = pathinfo( $name );
    $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] )) ));

    $type = $file['type'];
    $file = $file['file'];
    $title = $_POST['a_title'] ? $_POST['a_title'] : $name;
    $content = $_POST['a_desc']

    $post_id = $post->ID;
    $attachment = array(
      'post_title' => $title,
      'post_type' => 'attachment',
      'post_content' => $content,
      'post_parent' => $post_id,
      'post_mime_type' => $type,
      'guid' => $url['url']
    );


    // Save the data
    $id = wp_insert_attachment( $attachment, $_FILES['a_image'][ 'file' ]/*, $post_id - for post_thumbnails*/);

    if ( !is_wp_error( $id )) {
      $attach_meta = wp_generate_attachment_metadata( $id, $uploaded_file['url'] );
      wp_update_attachment_metadata( $attach_id, $attach_meta );
    }
    update_post_meta( $post->ID, 'a_image', $uploaded_file['url'] );
  }
}

Anyone able to help me finally fix this so it works proper would be loved. I've spent so many ridiculous countless hours numerous different times trying to develop this thing and the documentation sucks, and there's not really any good posts anywhere on how to do it.

Thanks

2
  • Check the comments on the various answers below and I think either I or @בניית אתרים or both of us are confused on what you need. Jan 30, 2011 at 1:10
  • Has anyone solved this?? Having a similar problem, have been scowering the web for ages on this one.
    – user3599
    Mar 1, 2011 at 6:53

2 Answers 2

6

Hi @jaredwilli:

Dude! Valiant effort, and nice work. All-in-all it could be a great addition to WordPress.

You were so close, but you had somewhere between 5 and 10 little failed assumptions or code that looks like you started it but didn't get back to it because it wasn't working. I reworked your function only as much as I needed to correct it. The solution follows, and I'll leave the side-by-side comparison to your or someone less burned-out. :)

function update_attachment() {
  global $post;
  wp_update_attachment_metadata( $post->ID, $_POST['a_image'] );
  if( !empty( $_FILES['a_image']['name'] )) { //New upload
    require_once( ABSPATH . 'wp-admin/includes/file.php' );

    $override['action'] = 'editpost';
    $file = wp_handle_upload( $_FILES['a_image'], $override );

    if ( isset( $file['error'] )) {
      return new WP_Error( 'upload_error', $file['error'] );
    }

    $file_type = wp_check_filetype($_FILES['a_image']['name'], array(
      'jpg|jpeg' => 'image/jpeg',
      'gif' => 'image/gif',
      'png' => 'image/png',
    ));
    if ($file_type['type']) {
      $name_parts = pathinfo( $file['file'] );
      $name = $file['filename'];
      $type = $file['type'];
      $title = $_POST['a_title'] ? $_POST['a_title'] : $name;
      $content = $_POST['a_desc'];

      $post_id = $post->ID;
      $attachment = array(
        'post_title' => $title,
        'post_type' => 'attachment',
        'post_content' => $content,
        'post_parent' => $post_id,
        'post_mime_type' => $type,
        'guid' => $file['url'],
      );

      foreach( get_intermediate_image_sizes() as $s ) {
        $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => true );
        $sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
        $sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
        $sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
      }

      $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );

      foreach( $sizes as $size => $size_data ) {
        $resized = image_make_intermediate_size( $file['file'], $size_data['width'], $size_data['height'], $size_data['crop'] );
        if ( $resized )
          $metadata['sizes'][$size] = $resized;
      }

      $attach_id = wp_insert_attachment( $attachment, $file['file'] /*, $post_id - for post_thumbnails*/);

      if ( !is_wp_error( $id )) {
        $attach_meta = wp_generate_attachment_metadata( $attach_id, $file['file'] );
        wp_update_attachment_metadata( $attach_id, $attach_meta );
      }
      update_post_meta( $post->ID, 'a_image', $file['url'] );
    }
  }
}

Hey, why not splurge and get yourself a copy of PhpStorm? You could have easily solved this yourself, you were sooo close, if you could have just traced through the code like I now can. If you do, don't waste your time on the very buggy XDEBUG and instead download Zend Debugger.

P.S. This is my former answer. I posted this before I realized what exactly Jared was asking. It is correct, but not related to his question. :)


I think what you are looking for is add_image_size():

add_image_size( $size_id, $width, $height, $crop );

For example:

add_image_size('headshot', 130, 150);
add_image_size('large-headshot', 260, 300);

By setting this WordPress will create those sizes automatically. What that what you needed?

24
  • I'm not sure about that, he is asking for the creation of the default media sizes.
    – Bainternet
    Jan 30, 2011 at 0:23
  • Hmm. The function wp_generate_attachment_metadata() does that if add_image_size() is set. Maybe he just didn't try using add_image_size() to set the image sizes? Jan 30, 2011 at 0:41
  • yea but, jaredwilli is saying that the default WordPress built-in sizes (large,medium,thumbnail) are no being created then surly the extra added sizes using add_image_size() wont be created either.
    – Bainternet
    Jan 30, 2011 at 0:48
  • or maybe I'm not getting the question at all :)
    – Bainternet
    Jan 30, 2011 at 0:49
  • @בניית אתרים - I'm getting confused now too. I think we need to wait to here clarification from @jaredwilli. Jan 30, 2011 at 1:09
1

if i understand you question you need to get the list of sizes first like this:

$image_sizes = get_intermediate_image_sizes();

this returns an array of all image sizes registered (defaults: large, medium, thumbnail , any custom size registered using "add_image_size()" then all you have to do is loop trough each one of the sizes and create an image for that size like this:

$foreach ($image_sizes as $size){
    images[] = image_make_intermediate_size($file, $size['width'], $size['height'], $crop); 
}

replace $file with the uploaded file path and $crop with true or false if you want to crop the image to the new dimensions or false to resize.

5
  • @בניית אתרים - If you take a look at the code for wp_generate_attachment_metadata() in /wp-admin/includes/image.php you will see it does exactly what you posted above, and he is already called that. So if those are not being created then maybe he's got a plugin that filters them using the 'intermediate_image_sizes_advanced' hook? Jan 30, 2011 at 1:08
  • I actually hadnt tried using get_intermediate_image_sizes(); I wasn't aware that it got all the registered sizes. Which is nice to know now. I still don't quite understand how the generated image sizes are associated with a particular attachment though, like if i were to look in the media library, you see the 3 size options, when selecting one of those, it knows which image to grab. Idk, that's not as important. Unless it is. After doing that foreach loop what variable would i use to add the attachment though? $images['thumb'] or something (whatever size i want)?
    – jaredwilli
    Jan 30, 2011 at 1:52
  • @בניית אתרים - Both of us missed the real problem at first. The real problem was about about 7 or 8 code errors in the original example. See my updated answer. Jan 30, 2011 at 3:54
  • Yea it was late here and i was brain dead.
    – Bainternet
    Jan 30, 2011 at 6:50
  • @בניית אתרים - Same. :) Jan 30, 2011 at 7:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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