Get attachment ID of author_meta image – Attachment Metadata

I’ve created a custom field in user profile where upload a profile image. It’s very simple.

To create fields I’ve used:

add_action( 'show_user_profile', 'cover_image_function' );
add_action( 'edit_user_profile', 'cover_image_function' );
function cover_image_function( $user ) 
{
   <h3>Cover Image</h3>
    <style type="text/css">
    .fh-profile-upload-options th,
    .fh-profile-upload-options td,
    .fh-profile-upload-options input {
        vertical-align: top;
    }
    .user-preview-image {
        display: block;
        height: auto;
        width: 300px;
    }
    </style>
    <table class="form-table fh-profile-upload-options">
        <tr>
            <th>
                <label for="image">Cover Image</label>
            </th>
            <td>
                <img class="user-preview-image" src="<?php echo esc_attr( get_the_author_meta( 'mycoverimage', $user->ID ) ); ?>">
                <input type="text" name="mycoverimage" id="mycoverimage" value="<?php echo esc_attr( get_the_author_meta( 'mycoverimage', $user->ID ) ); ?>" class="regular-text" />
                <input type='button' class="button-primary" value="Upload Image" id="coverimage"/><br />
                <span class="description">Please upload your cover image.</span>
            </td>
        </tr>
    </table>
    <script type="text/javascript">
    (function( $ ) {
        $( 'input#coverimage' ).on('click', function() {
            tb_show('', 'media-upload.php?type=image&TB_iframe=true');

            window.send_to_editor = function( html ) 
            {
                imgurl = $( 'img', html ).attr( 'src' );
                $( '#mycoverimage' ).val(imgurl);
                tb_remove();
            }

            return false;
        });
    })(jQuery);
    </script>
}

To save my image:
add_action( 'personal_options_update', 'save_cover_image' );
add_action( 'edit_user_profile_update', 'save_cover_image' );
function save_cover_image( $user_id ) {
    if ( !current_user_can( 'edit_user', $user_id ) )
    {
        return false;
    }

    update_user_meta( $user_id, 'mycoverimage', $_POST[ 'mycoverimage' ] );
}

Everything works fine but I can’t retrieve the attachment ID for generating the thumbnails and smaller sizes. For now I can just get the url like:
echo esc_attr( get_the_author_meta( 'mycoverimage', $user->ID ) );

I’ve even used the known method like in other questions:
function get_attachment_id($image_url) {
    global $wpdb;
    $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url )); 
    return $attachment[0]; 
}

But It doesn’t work. Is it possible that the image doesn’t generate any attachment metadata, while uploading? And how Can I do it? Even suggestions, articles or questions already answered would be appreciated. Everything but a plugin, I want build a custom code. Thanks!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I suggest you to use the more newer media manager dialog; WordPress will hanlde all the image upload stuff, including generating intermediate sizes and attachement metadata.

Here a working example (it is a quick example built from a previous code, it may needs some tweaks to be used on production):

add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
function load_wp_media_files( $page ) {
  if( $page == 'profile.php' || $page == 'user-edit.php' ) {
    wp_enqueue_media();
    wp_enqueue_script( 'my_custom_script', plugins_url( '/js/myscript.js' , __FILE__ ), array('jquery'), '0.1' );
  }
}

add_action( 'show_user_profile', 'cover_image_function' );
add_action( 'edit_user_profile', 'cover_image_function' );
function cover_image_function( $user ) 
{
    $image_id = get_user_meta( $user->ID, 'mycoverimage', true );
    if( intval( $image_id ) > 0 ) {
        // Change with the image size you want to use
        $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'id' => 'user-preview-image' ) );
    } else {
        $image = '<img id="user-preview-image" src="https://some.default.image.jpg" />';
    }
    ?>
   <h3>Cover Image</h3>
   <style type="text/css">
    .fh-profile-upload-options th,
    .fh-profile-upload-options td,
    .fh-profile-upload-options input {
        vertical-align: top;
    }
    .user-preview-image {
        display: block;
        height: auto;
        width: 300px;
    }
    </style>
    <table class="form-table fh-profile-upload-options">
        <tr>
            <th>
                <label for="image">Cover Image</label>
            </th>
            <td>
                <?php echo $image; ?>
                <input type="hidden" name="mycoverimage" id="mycoverimage" value="<?php echo esc_attr( get_the_author_meta( 'mycoverimage', $user->ID ) ); ?>" class="regular-text" />
                <input type='button' class="button-primary" value="Upload Image" id="coverimage"/><br />
                <span class="description">Please upload your cover image.</span>
            </td>
        </tr>
    </table>
    <?php
}

add_action( 'personal_options_update', 'save_cover_image' );
add_action( 'edit_user_profile_update', 'save_cover_image' );
function save_cover_image( $user_id ) {
    if ( ! current_user_can( 'edit_user', $user_id ) )
    {
        return false;
    }

    update_user_meta( $user_id, 'mycoverimage', $_POST[ 'mycoverimage' ] );
}  


// Ajax action to refresh the user image
add_action( 'wp_ajax_cyb_get_image_url', 'cyb_get_image_url'   );
function cyb_get_image_url() {
    if(isset($_GET['id']) ){
        $image = wp_get_attachment_image( filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ), 'medium', false, array( 'id' => 'user-preview-image' ) );
        $data = array(
            'image'    => $image,
        );
        wp_send_json_success( $data );
    } else {
        wp_send_json_error();
    }
}

And myscript.js file:
jQuery(document).ready( function($) {

      jQuery('input#coverimage').click(function(e) {

             e.preventDefault();
             var image_frame;
             if(image_frame){
                 image_frame.open();
             }
             image_frame = wp.media({
                           title: 'Select Media',
                           multiple : false,
                           library : {
                                type : 'image',
                            }
                       });

                       image_frame.on('close',function() {
                          // get selections and save to hidden input plus other AJAX stuff etc.
                          var selection =  image_frame.state().get('selection');
                          var gallery_ids = new Array();
                          var my_index = 0;
                          selection.each(function(attachment) {
                             gallery_ids[my_index] = attachment['id'];
                             my_index++;
                          });
                          var ids = gallery_ids.join(",");
                          jQuery('input#mycoverimage').val(ids);
                          Refresh_Image(ids);
                       });

                      image_frame.on('open',function() {
                        var selection =  image_frame.state().get('selection');
                        ids = jQuery('input#mycoverimage').val().split(',');
                        ids.forEach(function(id) {
                          attachment = wp.media.attachment(id);
                          attachment.fetch();
                          selection.add( attachment ? [ attachment ] : [] );
                        });

                      });

                    image_frame.on('toolbar:create:select',function() {

                        image_frame.state().set('filterable', 'uploaded');

                    });

                    image_frame.open();
     });

});

function Refresh_Image(the_id){
        var data = {
            action: 'cyb_get_image_url',
            id: the_id
        };

        jQuery.get(ajaxurl, data, function(response) {

            if(response.success === true) {
                jQuery('#user-preview-image').replaceWith( response.data.image );
            }
        });
}

Note that this code stores image id on user meta field instead of full size image url as you was doing before, so you can get any image size form the user meta field:
$image_id = get_user_meta( $user->ID, 'mycoverimage', true );
$fulle_user_image = wp_get_attachment_image( $image_id, 'full' );

Method 2

I’ve finally solved! The problem was that simply using

update_user_meta( $user_id, 'mycoverimage', $_POST[ 'mycoverimage' ] );

The image was saved without generating attachment metadata. In fact, checking my table, it got only usermeta id which is not the attachment id. So I had to change a bit my uploading function according to codex with the use of wp_insert_attachment like:
add_action( 'personal_options_update', 'save_cover_image' );
add_action( 'edit_user_profile_update', 'save_cover_image' );
function save_cover_image( $user_id ) {
    if ( !current_user_can( 'edit_user', $user_id ) )
    {
        return false;
    }
    $filename = $_POST['mycoverimage'];
    $parent_post_id = 0;
    $filetype = wp_check_filetype( basename( $filename ), null );
    $wp_upload_dir = wp_upload_dir();
    $attachment = array(
        'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ), 
        'post_mime_type' => $filetype['type'],
        'post_title'     => preg_replace( '/.[^.]+$/', '', basename( $filename ) ),
        'post_content'   => '',
        'post_status'    => 'inherit',
        'post_author'    => $uid
    );
    $attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id, $attach_data );
    update_user_meta( $user_id, 'mycoverimage', $_POST[ 'mycoverimage' ] );
}

At this point I have a usermeta id and an attachment id which I can easily retrieve for thumbs and other operations. Thanks to @majick anyway.

Method 3

Not sure it will make a difference, but as you just want one value you can get get_var instead of get_col. I tweaked the query slightly to what I know works:

function get_attachment_id($image_url) {
    global $wpdb;
    $attachment = $wpdb->get_var($wpdb->prepare("SELECT ID FROM ".$wpdb->prefix."posts WHERE post_type='attachment' AND guid='%s'", $image_url )); 
    return $attachment; 
}

And making use you are not doing esc_attr on the URL value before sending it to the function or it won’t match to it.

EDIT You could try this to (less strictly) just match the URL path to the guid instead of the full URL:

function get_attachment_id($image_url) {
    $parseurl = parse_url($image_url);
    $path = $parseurl['path'];

    global $wpdb;
    $attachments = $wpdb->get_results("SELECT ID,guid FROM ".$wpdb->prefix."posts WHERE post_type='attachment'");
    foreach ($attachments as $attachment) {
        if (strstr($attachment->guid,$path)) {return $attachment->ID;}
    }
    echo "<!-- All Attachments "; print_r($attachments); echo "-->"; // debug output
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments