我已经使用此查询随机选择了总共$limit
个图片(附件),每个图片来自一个唯一且随机选择的父级。
$query="SELECT {$wpdb->posts}.post_parent, {$wpdb->posts}.ID
FROM {$wpdb->posts}
INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.post_parent = {$wpdb->term_relationships}.object_id)
INNER JOIN {$wpdb->term_taxonomy} ON ({$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id)
WHERE {$wpdb->posts}.post_type = 'attachment'
AND {$wpdb->term_taxonomy}.taxonomy = 'category' AND {$wpdb->term_taxonomy}.term_id IN ('{$wpdb->escape($category_filter)}')
AND {$wpdb->posts}.post_password = ''
AND {$wpdb->posts}.post_mime_type IN ('image/jpeg', 'image/gif', 'image/png')
GROUP BY {$wpdb->posts}.post_parent
ORDER BY {$order_by}
LIMIT {$limit};";
不幸的是它有三个错误:
我认为密码检查不正确,因为它测试附件而不是parent_post,对吧? (WordPress甚至支持受密码保护的图库附件吗?)
它肯定不会检查post_status = "publish"
它正确选择随机帖子,但总是在其中相同的图片(第一个)。
所以 - 我谦卑地问你的SQL-fu。一个两者如何选择随机父级(首先检查已发布状态),然后选择该父级拥有的随机图像ID,所有这些都在一个查询中?
(我可以选择所有附件,随机排序并循环浏览所有附件,然后从独特的父母那里抓取第一个$limit
。但这也会导致父母也有很多图像被选中常。)
“当答案逃脱时,请更改问题......”
我刚刚发布了a plugin,可以直接从媒体库批量选择“精选帖子图片”。我的功能核心从~45行到此;
foreach($potential_parents as $parent){
if(has_post_thumbnail($parent->ID)) {
$image = get_post_thumbnail_id($parent->ID);
}
}
这不是随机的,但网站看起来更好,访问者现在可以更轻松地浏览内容,因为缩略图是一致的。
答案 0 :(得分:0)
好。所以这是使用WordPress的API实现它的一种方法。它非常笨拙而且很慢,但看起来很正确。我当然更愿意让MySQL完成所有这些工作。
$count = $limit;
$parent_posts = get_posts(array(
'post_type' => 'post',
'numberposts' => $limit,
'post_status' => 'publish',
'category' => $category_filter,
'orderby' => $order_by
));
foreach ($parent_posts as $parent_post) {
$attachments = get_posts(array(
'post_parent' => $parent_post->ID,
'post_mime_type' => '"image/jpeg", "image/gif", "image/png"', //Not sure if this is functional http://wordpress.org/support/topic/361633
'post_type' => 'attachment',
'numberposts' => 1,
'post_status' => 'inherit',
'orderby' => 'rand'
));
foreach($attachments as $attachment){ //NOTE: $attachments might be empty
$imgurl = wp_get_attachment_image_src($attachment->ID, $size);
if($imgurl === false){continue;} //bail, don't add to selection, don't decrease $count
/*[... do whatever with the image, add it to $selection ...]*/
if(--$count < 1){return $selection;}
}
}
请注意,您必须将此包装在while循环中以确保填充$selection
。一些潜在的$parent_posts
可能没有任何孩子。
答案 1 :(得分:0)
这不是一个查询,但它比我之前发布的WordPress-hackery快得多,而且非常比原来慢得多。我认为这是付出正确性的代价,同时又是SQL无知的代价。 :P
$potential_parents = $wpdb->get_results(
"SELECT DISTINCT {$wpdb->posts}.ID, {$wpdb->posts}.post_title
FROM {$wpdb->posts}
LEFT JOIN $wpdb->postmeta wpostmeta ON ({$wpdb->posts}.ID = wpostmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON ({$wpdb->posts}.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id IN({$wpdb->escape($category_filter)})
AND {$wpdb->posts}.post_type = 'post'
AND {$wpdb->posts}.post_status LIKE 'publish'
AND {$wpdb->posts}.post_password = ''
ORDER BY {$order_by};");
$imglists = array();
$parent_titles = array();
$count = $limit;
foreach($potential_parents as $parent){
$images = $wpdb->get_results(
"SELECT {$wpdb->posts}.ID
FROM {$wpdb->posts}
WHERE {$wpdb->posts}.post_parent = {$parent->ID}
AND {$wpdb->posts}.post_type = 'attachment'
AND {$wpdb->posts}.post_mime_type IN ('image/jpeg', 'image/gif', 'image/png')
ORDER BY {$order_by}
LIMIT 1;");
if($images){
$imglists[$parent->ID] = $images;
$parent_titles[$parent->ID] = $parent->post_title;
if(--$count < 1){break;}
}
}
foreach($imglists as $parent_id => $imagelist){
$imgurl = wp_get_attachment_image_src($imagelist[0]->ID, $size);
if($imgurl === false){continue;} //the image doesn't exist?
$img_width = $imgurl[1];
$img_height = $imgurl[2];
$imgurl = $imgurl[0];
$selection[] = array('post_url'=>get_permalink( $parent_id ), 'post_title' => wp_specialchars($parent_titles[$parent_id]),'post_id'=>$parent_id, 'img_src'=>$imgurl, 'width'=>$img_width, 'height'=>$img_height);
}
return $selection;
基本上,首先抓住一个较大的结果集,并在类别中发布所有已发布的帖子。然后是一堆较小的查询,每个循环都会获取一个附件ID,直到$limit
被填充。
如果你在这些类别中有很多帖子没有附件,你会在这里浪费一些时间。但在我们的情况下,它似乎是可控的。
仍在寻找有效的单一查询解决方案。 :)
答案 2 :(得分:0)
我解决了!今天重新发现了子查询和IN关键字。 :)看起来足够快速和正确启动。
$images = $wpdb->get_results(
"SELECT SQL_SMALL_RESULT DISTINCT wp_posts.post_parent, wp_posts.ID
FROM wp_posts
WHERE wp_posts.post_parent IN (
SELECT SQL_SMALL_RESULT DISTINCT wp_posts.ID
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
WHERE
wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN({$wpdb->escape($category_filter)})
AND wp_posts.post_type = 'post'
AND wp_posts.post_status = 'publish'
AND wp_posts.post_password = ''
ORDER BY {$order_by}
)
AND wp_posts.post_type = 'attachment'
AND wp_posts.post_mime_type IN ('image/jpeg', 'image/gif', 'image/png')
ORDER BY {$order_by}
LIMIT {$limit};"
);
$selection = array();
foreach($images as $img){
$imgurl = wp_get_attachment_image_src($img->ID, $size);
if($imgurl === false){continue;} //the image doesn't exist?
$img_width = $imgurl[1];
$img_height = $imgurl[2];
$imgurl = $imgurl[0];
$selection[] = array(
'post_url' => get_permalink($img->post_parent),
'post_title' => wp_specialchars(get_the_title($img->post_parent)),
'post_id' => $img->post_parent,
'img_id' => $img->ID,
'img_src' => $imgurl,
'width' => $img_width,
'height' => $img_height
);
}
return $selection;