Как получить все элементы таксономии записей, которые находятся в других указанных элементах таксономии?
Приветствую, Друзья!
Застрял я на одном моменте, а именно у меня есть custom posts type и к ним привязаны 3 вида таксономий.
Так вот, если я вывожу для первого вида таксономии все записи (т.е. для определенного term), мне необходимо получить список, всех terms второго вида таксономии, связанных с записями выводимыми для определенного term первой таксономии.
Ранее я это пытался делать перебором всех posts, получая у каждого связанную с ним term, затем array unique и выводил. Но сейчас, записей много, а перед основным циклом вывода (который может иметь разные условия), мне всё еще приходится перебирать все записи одним разом, что бы получить все terms и вывести их и это все создает большую нагрузку на сервер.
Может у кого есть идеи, как это сделать проще или с меньшей нагрузкой на хостинг?
Заранее, Спасибо!
Основной код того как делаешь скинь, может чего и придумается... А вообще, мне представляется это сделать отдельным запросом. Получили все записи термина, как обычно, взяли их ID и отдельным запросом нашли все термины этих записей из другой таксы. Если я правильно понял вообще, что нужно.
/* Как вариант: */
$posts = get_posts(array('category' => 'ID категории для которой делаем выборку брендов', 'numberposts' => -1));
$brendsarray = array();
foreach($posts as $post){
$brends = get_the_terms($post->ID, 'brends');
if(!empty($brends)) {
foreach($brends as $brend) {
$brendsarray[] = $brend->term_id;
}
}
}
$brendsarray = array_unique($brendsarray); asort($brendsarray);
/* Далее, обрабатываю $brendsarray; */
Просто, при такой схеме у меня получается, вначале этот цикл перебора записей, а затем уже основной и нагрузка получается большая, когда записей много...
Еще я находил подобный код, если попытаться искать примерно по такому запросу - "вывод меток для конкретной рубрики", что бы хоть с чем-то связать поиски моего вопроса:
function get_category_tags($cats) {
global $wpdb;
$tags = $wpdb->get_results
("
SELECT DISTINCT terms2.term_id as tag_id, terms2.name as tag_name, t2.count as posts_count, null as tag_link
FROM
wp_posts as p1
LEFT JOIN wp_term_relationships as r1 ON p1.ID = r1.object_ID
LEFT JOIN wp_term_taxonomy as t1 ON r1.term_taxonomy_id = t1.term_taxonomy_id
LEFT JOIN wp_terms as terms1 ON t1.term_id = terms1.term_id,
wp_posts as p2
LEFT JOIN wp_term_relationships as r2 ON p2.ID = r2.object_ID
LEFT JOIN wp_term_taxonomy as t2 ON r2.term_taxonomy_id = t2.term_taxonomy_id
LEFT JOIN wp_terms as terms2 ON t2.term_id = terms2.term_id
WHERE
t1.taxonomy = 'category' AND p1.post_status = 'publish' AND terms1.term_id IN (". $cats .") AND
t2.taxonomy = 'post_tag' AND p2.post_status = 'publish'
AND p1.ID = p2.ID
ORDER by tag_name
");
foreach($tags as $tag)
$out .= '<a href="'. get_tag_link($tag->tag_id) .'">'. $tag->tag_name .'<sub>'. $tag->posts_count .'</sub></a>, ';
return rtrim($out, ', ');
}
echo get_category_tags('Тут ID рубрики');
Я пробовал заменять "t2.taxonomy = 'post_tag'" на "t2.taxonomy = 'brends'", т.е. на ту таксономию, что мне необходима, но ничего данный код мне не выдал, точнее выдал пусто 
А так, как я ничего не понимаю в SQL запросах, я этот код пропустил и забыл о нем...
Написал вот функцию. Попробуй ка, я на этом блоге тестанул, вроде все работает как надо:
/** * Получает все элементы таксономии, в которых находятся записи из других элементов таксономии * @param array|int $terms ID элементов таксономии, в которых находятся записи * @param string [$taxname = 'category'] Название таксономии элементов указанных в $terms * @param string [$post_type = 'post'] Название типа записи * @param string [$taxname2 = 'post_tag'] Название таксономии элементы которой нужно получить * @return array Массив элементов таксономии (объектов WP_Term) из таксономии $taxname2 */ function get_terms_of_posts_in_terms( $terms, $taxname = 'category', $post_type = 'post', $taxname2 = 'post_tag' ) { global $wpdb; $terms = (array) $terms; // записи из терминов $_term_posts_ids_query = "SELECT ID FROM $wpdb->posts p LEFT JOIN $wpdb->term_relationships rel ON (ID = rel.object_id) LEFT JOIN $wpdb->term_taxonomy tt ON (tt.term_taxonomy_id = rel.term_taxonomy_id) LEFT JOIN $wpdb->terms tm ON (tt.term_id = tm.term_id) WHERE tt.taxonomy = ". $wpdb->prepare('%s', $taxname) ." AND tm.term_id IN (". implode(',', array_map('absint', $terms) ) .") AND post_type = ". $wpdb->prepare('%s', $post_type) ." AND post_status = 'publish'"; // // термины другой таксономии $_sql = "SELECT DISTINCT tt_.term_id FROM $wpdb->term_relationships rel_ LEFT JOIN $wpdb->term_taxonomy tt_ ON (tt_.term_taxonomy_id = rel_.term_taxonomy_id) WHERE tt_.taxonomy = ". $wpdb->prepare('%s', $taxname2) ." AND rel_.object_id IN ($_term_posts_ids_query)"; $term_ids = $wpdb->get_col( $_sql ); // соберем объекты терминов $terms = get_terms( array('include'=>$term_ids) ); return $terms ?: array(); } // пример использования функции --------- // получим все термины $terms = get_terms_of_posts_in_terms( array(154, 52), 'wpfunccat', 'func', 'wpfunctag'); // вывод if( $terms ){ $array = array(); foreach( $terms as $term ){ /* WP_Term Object ( [term_id] => 244 [name] => path путь directory папка [slug] => path-put-puti-directory [term_group] => 0 [term_taxonomy_id] => 257 [taxonomy] => wpfunctag [description] => [parent] => 0 [count] => 8 [filter] => raw ) */ $array[] = '<a href="'. get_term_link($term) .'">'. $term->name .' <sup>'. $term->count .'</sup></a>'; } $out = ' <ol> <li>'. implode("</li>\n<li>", $array ) .'</li> </ol>'; } else $out = 'Терминов не найдено...'; echo $out;Судя по
Это на php7 написано, кто в 5.6 заюзает, тот выхватит ошибку скорее всего.
Это PHP 5.3
Снимаю шляпу! Был не прав.
Да ну брось, в шляпах уже никто не ходит...
Я Вам очень признателен, Kama.
Большое спасибо за помощь!
Приветствую.
Спасибо за ваш код.
У меня что-то не правильно подсчитывает количество записей. Показывает количество записей в категории, без учета фильтрации.
Точнее говоря, например есть категории "телевизоры" и "телефоны"
у телевизоров есть две записи с меткой самсунг,
а у телефонов есть только одна запись с меткой самсунг,
теперь когда я указываю сюда get_terms_of_posts_in_terms(ид категории телевизоры); , то мне показывает, что у метки самсунг есть 3 записи, хотя должно отображаться только две.
Подскажите, что не так делаю?
Может кому пригодится, (нарыл там же, что и пример выше)
<?php $tags = $wpdb->get_results (" SELECT DISTINCT terms2.name as name, terms2.slug as slug, COUNT(terms2.slug) as numposts FROM wp_posts as p1 LEFT JOIN wp_term_relationships as r1 ON p1.ID = r1.object_ID LEFT JOIN wp_term_taxonomy as t1 ON r1.term_taxonomy_id = t1.term_taxonomy_id LEFT JOIN wp_terms as terms1 ON t1.term_id = terms1.term_id, wp_posts as p2 LEFT JOIN wp_term_relationships as r2 ON p2.ID = r2.object_ID LEFT JOIN wp_term_taxonomy as t2 ON r2.term_taxonomy_id = t2.term_taxonomy_id LEFT JOIN wp_terms as terms2 ON t2.term_id = terms2.term_id WHERE t1.taxonomy = 'catalog' AND p1.post_status = 'publish' AND terms1.slug = '$termpf->slug' AND t2.taxonomy = 'brand' AND p2.post_status = 'publish' AND p1.ID = p2.ID GROUP BY terms2.slug ORDER BY numposts DESC "); foreach ($tags as $tag) { echo '<a href="http://example.com/brand/'. $tag->slug.'/">'. $tag->name .' <sup>'. $tag->numposts .'</sup></a>'; } ?>catalog - таксономия рубрик
brand - таксономия метки