Last active
March 16, 2024 16:04
-
-
Save doiftrue/685dab3f398d1225b41a52d52a7e079a to your computer and use it in GitHub Desktop.
[wp-kama embed] Interlinking posts in WordPress (previous posts from category). Function 2 -- https://wp-kama.com/2186
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Предыдущие записи из рубрики (относительно текущей записи) + | |
* кольцевая перелинковка (можно указывать таксономию и тип записи). | |
* | |
* Кэширует результат в объектный кэш, если он включен. | |
* | |
* Вызываем функцию так: | |
* | |
* echo kama_previous_posts_from_tax_lis( [ | |
* 'post_num' => 5, | |
* 'format' => '{date:j.M.Y} - {a}{title}{/a}', | |
* ] ); | |
* | |
* @param array|string $args { | |
* Parameters passed as array or query string. | |
* | |
* @type int $post_num Количество ссылок. | |
* @type string $format {thumb} {date:j.M.Y} - {a}{title}{/a} ({comments}) | |
* @type string $list_tag Тег-обертка каждой ссылки. | |
* @type string $tax Таксономия. Пр. category. | |
* @type string|array $exclude_terms Элементы таксономии посты из которых нужно исключить (через запятую или в массиве). | |
* Указываем term_id или term_slug. | |
* @type string $post_type Тип записи. пр. post. | |
* } | |
* | |
* @version 1.3 | |
*/ | |
function kama_previous_posts_from_tax_lis( $args = array() ){ | |
global $post, $wpdb; | |
$rg = (object) wp_parse_args( $args, [ | |
'post_num' => 5, | |
'format' => '', | |
'list_tag' => 'li', | |
'tax' => 'category', | |
'post_type' => 'post', | |
'exclude_terms' => '', | |
] ); | |
if( wp_using_ext_object_cache() ){ | |
$cache_key = md5( __FUNCTION__ . $post->ID ); | |
$cache_flag = __FUNCTION__; | |
if( $cache_out = wp_cache_get( $cache_key, $cache_flag ) ){ | |
return $cache_out; | |
} | |
} | |
// wp_parse_list() analog to work with WP < 5.1 | |
if ( is_string( $rg->exclude_terms ) ) { | |
$rg->exclude_terms = preg_split( '/[\s,]+/', $rg->exclude_terms, -1, PREG_SPLIT_NO_EMPTY ); | |
} | |
if( 'exclude_terms' ){ | |
$exclude_terms = $rg->exclude_terms; | |
foreach( $exclude_terms as & $term_id ){ | |
if( ! is_numeric( $term_id ) ){ | |
$term = get_term_by( 'slug', $term_id, $rg->tax ); | |
$term_id = $term ? $term->term_id : 0; | |
} | |
else { | |
$term_id = (int) $term_id; | |
} | |
} | |
unset( $term_id ); | |
$exclude_terms = array_map( 'intval', array_filter( $exclude_terms ) ); | |
$AND_NOT_IN = $exclude_terms ? sprintf( ' AND term_id NOT IN (%s)', implode( ',', $exclude_terms ) ) : ''; | |
} | |
$sub_query_term_id = $wpdb->prepare( | |
"(SELECT term_id FROM $wpdb->term_relationships rl | |
LEFT JOIN $wpdb->term_taxonomy tx ON (rl.term_taxonomy_id = tx.term_taxonomy_id) | |
WHERE object_id = %d AND tx.taxonomy = %s $AND_NOT_IN | |
LIMIT 1)", | |
$post->ID, $rg->tax | |
); | |
$WHERE_arr = [ | |
"p.post_status = 'publish'", | |
"tax.term_id = $sub_query_term_id", | |
$wpdb->prepare( 'p.post_date < %s', $post->post_date ), | |
$wpdb->prepare( 'tax.taxonomy = %s', $rg->tax ), | |
$wpdb->prepare( 'p.post_type = %s', $rg->post_type ), | |
]; | |
$SELECT = "SELECT ID, post_title, post_date, comment_count, guid | |
FROM $wpdb->posts p | |
LEFT JOIN $wpdb->term_relationships rel ON (p.ID = rel.object_id) | |
LEFT JOIN $wpdb->term_taxonomy tax ON (rel.term_taxonomy_id = tax.term_taxonomy_id)"; | |
$WHERE = implode( ' AND ', $WHERE_arr ); | |
$ORDER_BY = 'ORDER BY p.post_date DESC'; | |
$sql = "$SELECT WHERE $WHERE $ORDER_BY LIMIT " . (int) $rg->post_num; | |
$posts_data = $wpdb->get_results( $sql ); | |
$posts_count = count( $posts_data ); | |
// если количество меньше нужного, делаем 2-й запрос (кольцевая перелинковка) | |
if( ! $posts_data || $posts_count < $rg->post_num ){ | |
$NOT_IN = $post->ID; | |
foreach( $posts_data as $pdata ){ | |
$NOT_IN .= ",$pdata->ID"; | |
} | |
$WHERE_arr[] = "p.ID NOT IN ($NOT_IN)"; | |
$WHERE = implode( ' AND ', $WHERE_arr ); | |
$sql = "$SELECT WHERE $WHERE $ORDER_BY LIMIT " . (int) ( $rg->post_num - $posts_count ); | |
$res2 = $wpdb->get_results( $sql ); | |
$posts_data = array_merge( $posts_data, $res2 ); | |
} | |
if( ! $posts_data ){ | |
return ''; | |
} | |
// вывод | |
$date_match = false; | |
if( $rg->format ){ | |
preg_match( '!{date:(.*?)}!', $rg->format, $date_match ); | |
} | |
$add_thumb = false !== strpos( $rg->format, '{thumb}' ); | |
$out = ''; | |
foreach( $posts_data as $pdata ){ | |
$x = ( ( $x ?? '' ) === 'li1' ) ? 'li2' : 'li1'; | |
$a = sprintf( '<a href="%s" title="%s">', get_permalink( $pdata->ID ), esc_attr( $pdata->post_title ) ); | |
if( $rg->format ){ | |
$formated = strtr( $rg->format, [ | |
'{title}' => esc_html( $pdata->post_title ), | |
'{a}' => $a, | |
'{/a}' => '</a>', | |
'{comments}' => $pdata->comment_count ?: '', | |
] ); | |
if( $add_thumb ){ | |
$formated = str_replace( '{thumb}', get_the_post_thumbnail( $pdata->ID, 'thumbnail' ), $formated ); | |
} | |
// есть дата | |
if( $date_match ){ | |
$formated = str_replace( $date_match[0], apply_filters( 'the_time', mysql2date( $date_match[1], $pdata->post_date ) ), $formated ); | |
} | |
} | |
else{ | |
$formated = $a . esc_html( $pdata->post_title ) . '</a>'; | |
} | |
$out .= "\t<li class=\"$x\">$formated</li>\n"; | |
} | |
if( wp_using_ext_object_cache() ){ | |
wp_cache_add( $cache_key, $out, $cache_flag ); | |
} | |
return $out; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment