0

I have a custom form that allows users to make posts and also upload images with it. The images are saved in wp_posts as post_type = attachment with a guid to show the image.

Now I have created a grid created with php which shows all main pictures of my posts. However, since I call the guid's of the images it loads very slow when the pictures are large.

I know that there is some smaller thumbnail that should get saved with each image upload, but I cannot find these files in the database.

I tried showing them with all of the following ways:

//test with ID of the post:
get_the_post_thumbnail('17547');
get_the_post_thumbnail(17547, 'thumbnail');
get_the_post_thumbnail(17547, 'medium');

//test with ID of the attachment:
wp_get_attachment_image(17548, 'medium' );
wp_get_attachment_image_src(17548, 'medium' );

The two different numbers are because i tried the post ID and the attachement ID. But all of the above functions don't show me anything in the DOM...

I think that maybe the way I save the pictures doesn't allows me to use this function. But I don't know what I'm doing wrong! Does anyone know where I can look or how I can show these thumbnails?

This is how my photo grid is made:
 First I get a list of ID's based on what the user searches:

$allluca01 = $wpdb->get_results("
    SELECT wpp.ID, post_title
    FROM wp_posts AS wpp
    WHERE post_type = 'post' 
    ".$plus_other_search_conditions."
    GROUP BY wpp.ID
");

 Then I get the guid of the image. I have the attachment id saved as metavalue to a metakey called image01 (linked to post_id).

foreach($sqlsearchquery as $results){
        $resultid = $results->ID;
        $getpicture = $wpdb->get_results("
            SELECT guid AS pic 
            FROM wp_posts
            LEFT JOIN wp_postmeta ON ID = meta_value
            WHERE post_id = '$resultid' AND meta_key = 'item_image01'
        ");

            <div class="grid_item_img" style="background-image:url('<? echo $getpicture[0]->pic; ?>')">

As you can see I attain the guid and then I use it in my grid. I just want to obtain a guid of a smaller size of my media so I can have the grid load faster. Does anyone know how to do that?

  • I've been rereading your question, and I think we all missed something here. How are you querying your images at this stage. – Pieter Goosen Mar 3 '16 at 9:33
  • I'd like to show you but what do you mean by querying? – mesqueeb Mar 3 '16 at 10:15
  • Show us what you explained here: However, since I call the guid's of the images it loads very slow – Pieter Goosen Mar 3 '16 at 10:25
  • Dear pieter i updated the question with the query how i create the grid – mesqueeb Mar 3 '16 at 10:36
  • Updated the sqlsearchquery – mesqueeb Mar 3 '16 at 10:53
0

You can use several functions to get the URL of a image of any of the intermediate sizes created by WordPress (thumbnail, medium, large, full, or any other custom size).

You can use get_the_post_thumbnail()/the_post_thumbnail(): use this function if you want to get a <img> element of the featured image of a post (aka "post thumbnail"). For example, to get the featured image, medium szie, of the post with ID 78:

$featured_image = get_the_post_thumbanil( 78, 'medium' );
echo $featured_image;

If you are within the loop, you can display the post thumbnail, medium size, of the current post as follow:

// Don't need echo
the_post_thumbnail( 'medium' );

If no image size is set, get_the_post_thumbanil()/the_post_thumbnail() use post-thumbnail, which is the size registered for the post thumbanil (featured image).

If you want to get a <img> element of any image, not the post thumbnail (featured image), use wp_get_attachment_image(). For example, if the attachement has ID of 7898 and you want to get medium size <img>:

echo wp_get_attachment_image( 7898, 'medium' );

You can also use wp_get_attachment_image_src() if you only want to get the URL of any image (but not a <img> element):

$image_url = wp_get_attachment_image_src( $id_of_the_attachment, $size );

For example, if the attachement has ID of 7898 and you want to get medium size URL:

$image_url = wp_get_attachment_image_src( 7898, 'medium' );

In you custom query, you could select the attachment ID instead of the guid and use this attachment ID with wp_get_attachment_image() and wp_get_attachment_image_src().

Anyway, you should avoid that custom SQL queries. You are missing important WordPress hooks and several functions, template tags, filters on content, embeds, etc, won't wrok. If you want to work with WordPress posts within WordPress, the best choice is to use get_posts() o or a new instance of WP_Query.

Now, to directly answer your question: the attachment files, including the intermediate sizes of images, are stored in wp-content/uploads folder. The database keeps information of the attachement post type, but the files are not in database.

  • cybmeta, I tried this but it wouldn't work! I have updated my question. Do you have any advice? – mesqueeb Mar 3 '16 at 11:12
  • What exactly have you tried and doesn't work? Can you add it to the question? If you use, for exmaple, wp_get_attachment_image( 7898, 'medium' );, you will get the medium size image of the attachment with ID 7898. I that doesn't work, you are using a incorrect attachment Id, a incorrect size parameter or both. Can you add to the question what you have tried exactly? – cybmeta Mar 3 '16 at 14:33
  • I updated the answer. The id with the 48 at the end is the attachment. – mesqueeb Mar 3 '16 at 14:40
  • If you read the answer carefully, get_the_post_thumbnail( 7898, 'medium' ) would get the featured image, medium size, of the post with ID 7898, no the attachment with ID 7898. The featured image is a image (attachment) associated with a post, like a representative image of the post. To get images by their IDs, use the other functions included in the answer, like wp_get_attachment_image(). – cybmeta Mar 3 '16 at 17:39
  • But i already tried wp_get_attachement_image. And this also wont show anything. Do you know why my images are not properly regocnized? – mesqueeb Mar 3 '16 at 23:47
0

I am not sure how you have implemented the image upload in custom form. If you have followed standard way then you shall be able to get thumbnails using either of following:

get_the_post_thumbnail( $post_id, 'thumbnail' ); get_the_post_thumbnail( $post_id, 'medium' );

If above does not work then you can give specific image size, through second argument. Simply pass size as below, and WordPress will return the image with specified size on the fly:

get_the_post_thumbnail( $post_id, array(300, 300))

Let me know how it goes :-)

  • It seems that you and me post the answer almost at the same time. – cybmeta Mar 3 '16 at 8:57
  • I tried but nothing. :( i updated the question – mesqueeb Mar 3 '16 at 10:22
0

By default the thumbnail (attachment) ID is stored in the post's meta_key of _thumbnail_id, so if that is not set (eg. by adding the image to the post via the post writing screen) then get_the_post_thumbnail and the_post_thumbnail will not do anything, as you pass them the $post_id they will check and find that _thumbnail_id is not set for that $post_id and return nothing.

wp_get_attachment and wp_get_attachment_src will do something however, but only if you pass the Attachment ID and not the Post ID. You say you have saved the attachment ID to meta_key of item_image01 (or image01?) but in your current SQL query you are not actually retrieving this value, just checking it has been set. So you should be able to just do this instead:

foreach ($sqlsearchquery as $results) {
    $post_id = $results->ID;
    $attachment_id = get_post_meta($post_id,'item_image01',true);
    $source_url = wp_get_attachment_src($attachment_id,'medium');
    ?>

        <div class="grid_item_img" style="background-image:url('<? echo $source_url; ?>')">

So it also seems you are using some other method to set the attachment ID to this meta_key, again, if you did want to simply use get_the_post_thumbnail you would set the attachment ID to the post's _thumbnail_id meta_key instead.

  • Dear Majick, Thanks for helping me! But unfortunately still everything I try shows nothing. I tried adding _thumbnail_id to the main post's postmeta with the ID of the image. I've also tried wp_get_attachment with the id of the image. But just nothing appears. Do you know what could be conflicting? – mesqueeb Mar 4 '16 at 2:12
  • try adding an image to the the post the standard way - from the post writing screen - and compare the result of doing that with what you are doing. – majick Mar 4 '16 at 2:20
  • Good idea! I'll do that and report back! – mesqueeb Mar 4 '16 at 2:21
  • That also didn't work. I cannot use any of the following wordpress functions, they are all broken: get_media_item, wp_get_attachment_image, wp_get_attachment_image_src, get_the_post_thumbnail ... I'm not sure why... – mesqueeb Mar 4 '16 at 2:28
  • did the database key appear for _thumbnail_id? also you could reinstall your wp-includes it may be something is corrupt (but normally this would cause a crash.) – majick Mar 4 '16 at 2:38
0

I wonder if you aren't looking for something different than I have originally answered. After rereading your post trying to make proper sense, I think your images are actually attachments and not thumbnails, if I read this correctly. If, so, these attachments are still not saved in db, only the info about the attachment as you correctly pointed out

In this case, loading attachment can be very expensive if not done correctly. It is quite frustrating that WordPress does not allow you to directly query attachments without passing a post parent ID.

To get attached images for your posts, you can try the following, it will be a bit faster doing it this way

/**
 * Because we really just need post ID's and nothing more like
 * custom fields, postdata, and post terms, we will not be updating
 * the post cache. This saves a lot of time and resources. If you are 
 * going to need custom fields or post data or terms, then you should remove
 * cache_results because this will cause huge increase in db queries when you
 * try to get post terms or custom fields
 *
 * Also, we will only get post ID's as we do not need anything else
 */
$args = [
    'fields'        => 'ids', // Get only post ID's
    'cache_results' => false, // Do not update post caches
    // Add any extra arguments
];
$q = get_posts( $args );

if ( $q ) {
    foreach ( $q as $id ) {
        /**
         * Get all attached images
         * 
         * We will be doing what get_attached_media does, but because we only
         * have post ID's and have not updated the post cache, we will not be 
         * using get_attached_media() as it will lead to a large number of db hits
         * because get_attached_media() will use get_post() to get the complete post object
         */
        $image_args = [
            'post_parent'    => $id,
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'posts_per_page' => -1,
            'orderby'        => 'menu_order',
            'order'          => 'ASC',
        ];
        $images = get_children( $image_args );

        if ( !$images )
            continue;

        // Loop throught the images
        foreach ( $images as $image ) {
            // Output the images as needed

            // For debugging, see the var_dump for values
            var_dump( $image );

        }
    }
}

ORIGINAL ANSWER

Post thumbnails aren't explicitely saved in the db, only the ID of that particular thumbnail is saved as post meta in the wp_postmeta table. The particular meta key is _thumbnail_id.

You can specifiy which thumbnail size to return for each post via the second parameter of the get_the_post_thumbnail() function. You can alternatively set a string or an array of custom attributes as third parameter

It should be noted, get_the_post_thumbnail() does not display the thumbnail, but simply returns it. Inside the loop, you would want to use the_post_thumbnail() to display the thumbnail, in which case the parameters as discussed above will be the first and second parameters respectively.

Loading thumbnails in a custom loop is expensive as thumbnails aren't cached for custom queries. Only the main query is covered. You need to explicitely set caching for thumbnails in a custom loop.

You can try the following as a probable solution: (NOTE: Everything is untested and might be buggy)

(Lets say you want to use the medium size thumbnail and only want to display thumbnails, nothing else, if need any other post properties, remove the filter)

Lets first look at the filter which should go into functions.php

/**
 * Custom filter to retrieve only post ID's.
 *
 * We cannot set the fields arguments to ID in our query because
 * we need to update the thumbnail cache, and if you look at 
 * update_post_thumbnail_cache(), we need the post as an object
 * so we can use $post->ID, if we set the fields parameter, we only
 * get an array of ID's, not post objects with only ID's
 */
add_filter( 'posts_fields', function ( $fields, \WP_Query $q ) use ( &$wpdb )
{
    remove_filter( current_filter(), __FUNCTION__ );

    // Only target a query where the new wpse_fields parameter is set with a value of ID
    if ( 'ID' === $q->get( 'wpse_fields' ) ) {
        // Only get the post ID field to reduce server load
        $fields = "$wpdb->posts.ID";
    }

    return $fields;
}, 10, 2);

This filter will reduce server load by a big margin as we only get post ID's, but still maintain the post object.

Your custom query can look something like the following:

/** 
 * Because we only need to display the post thumbnails, we will not be
 * updating the term cache. If you need post term info, remove the 
 * update_post_term_cache argument. This will increase performance if you
 * do not need post term info
 */
$args = [
    'meta_key'               => '_thumbnail_id', // Only get posts with thumbnails
    'wpse_fields'            => 'ID',            // Our custom argument to get only post ID's
    'update_post_term_cache' => false,           // Do not update the post caches to make the query faster
    // Any other arguments
];
$q = new WP_Query( $args );

if ( $q->have_posts() ) {

    // Update the post thumbnail cache
    update_post_thumbnail_cache( $q );

    while ( $q->have_posts() ) {
        $q->the_post();

        // Display the post thumbnail, medium size
        if ( has_post_thumbnail() ) // Not really necessary in current context
            the_post_thumbnail( 'medium' ); // Get medium size post thumbnail

    }
    wp_reset_postdata();
}

EDIT

VERY IMPORTANT NOTE

The use of short PHP tags are highly discouraged, it is actually not allowed in WordPress. It is really bad coding practice. You should make a habit of it to use proper PHP tags (*<?php and ?>

  • I have just update my answer. Test the code in my my edit above. I think you might be looking for this – Pieter Goosen Mar 3 '16 at 10:24
  • Dear pieter. I also think they are just attachements and i manually set the parent id to the post i add with the form. But how do i know for sure? – mesqueeb Mar 3 '16 at 10:25
  • Try my answer in the edit first and see if it works – Pieter Goosen Mar 3 '16 at 10:27
-1

The answer is simple:

Don't forget to write echo in front of all of these functions.

echo wp_get_attachment_image($attachment_id, 'medium' );
echo wp_get_attachment_image_src($attachment_id, 'medium' );

echo get_the_post_thumbnail($post_id, 'thumbnail');
echo get_the_post_thumbnail($post_id, 'medium');
//note this only works if you have _thumbnail_id set to the postmeta of the post.

This all works fine and the problem is solved.

  • All of that is already explained in my answer. – cybmeta Mar 4 '16 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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