WordPress как на ладони
wordpress jino

Как получить все элементы таксономии записей, которые находятся в других указанных элементах таксономии?

Приветствую, Друзья!

Застрял я на одном моменте, а именно у меня есть custom posts type и к ним привязаны 3 вида таксономий.

Так вот, если я вывожу для первого вида таксономии все записи (т.е. для определенного term), мне необходимо получить список, всех terms второго вида таксономии, связанных с записями выводимыми для определенного term первой таксономии.

Ранее я это пытался делать перебором всех posts, получая у каждого связанную с ним term, затем array unique и выводил. Но сейчас, записей много, а перед основным циклом вывода (который может иметь разные условия), мне всё еще приходится перебирать все записи одним разом, что бы получить все terms и вывести их и это все создает большую нагрузку на сервер.

Может у кого есть идеи, как это сделать проще или с меньшей нагрузкой на хостинг?

Заранее, Спасибо!

Kama 1.4 года назад

Основной код того как делаешь скинь, может чего и придумается... А вообще, мне представляется это сделать отдельным запросом. Получили все записи термина, как обычно, взяли их ID и отдельным запросом нашли все термины этих записей из другой таксы. Если я правильно понял вообще, что нужно.

kecapb 1.4 года назад
    /* Как вариант: */
	$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; */

Просто, при такой схеме у меня получается, вначале этот цикл перебора записей, а затем уже основной и нагрузка получается большая, когда записей много...

kecapb 1.4 года назад

Еще я находил подобный код, если попытаться искать примерно по такому запросу - "вывод меток для конкретной рубрики", что бы хоть с чем-то связать поиски моего вопроса:

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'", т.е. на ту таксономию, что мне необходима, но ничего данный код мне не выдал, точнее выдал пусто smile
А так, как я ничего не понимаю в SQL запросах, я этот код пропустил и забыл о нем...

1
Гость 1.4 года назад
  • 1
    Kama4697

    Написал вот функцию. Попробуй ка, я на этом блоге тестанул, вроде все работает как надо:

    /**
     * Получает все элементы таксономии, в которых находятся записи из других элементов таксономии
     * @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;
    campusboy 1.4 года назад

    Судя по

    return $terms ?: array();

    Это на php7 написано, кто в 5.6 заюзает, тот выхватит ошибку скорее всего.

    Kama 1.4 года назад
    campusboy 1.4 года назад

    Снимаю шляпу! Был не прав.

    Kama 1.4 года назад

    Да ну брось, в шляпах уже никто не ходит... smile

    Комментировать
  • 0

    Я Вам очень признателен, Kama.
    Большое спасибо за помощь!

    Комментировать
  • 0

    Приветствую.
    Спасибо за ваш код.

    У меня что-то не правильно подсчитывает количество записей. Показывает количество записей в категории, без учета фильтрации.

    Точнее говоря, например есть категории "телевизоры" и "телефоны"
    у телевизоров есть две записи с меткой самсунг,
    а у телефонов есть только одна запись с меткой самсунг,

    теперь когда я указываю сюда get_terms_of_posts_in_terms(ид категории телевизоры); , то мне показывает, что у метки самсунг есть 3 записи, хотя должно отображаться только две.

    Подскажите, что не так делаю?

    qwert555 1.2 года назад

    Может кому пригодится, (нарыл там же, что и пример выше)

    <?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://site.ru/brand/'. $tag->slug.'/">'. $tag->name .' <sup>'. $tag->numposts .'</sup></a>'; 
    	}
    ?>
    

    catalog - таксономия рубрик
    brand - таксономия метки

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.