Skip to content

Instantly share code, notes, and snippets.

@doiftrue
Last active March 16, 2024 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doiftrue/685dab3f398d1225b41a52d52a7e079a to your computer and use it in GitHub Desktop.
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
/**
* Предыдущие записи из рубрики (относительно текущей записи) +
* кольцевая перелинковка (можно указывать таксономию и тип записи).
*
* Кэширует результат в объектный кэш, если он включен.
*
* Вызываем функцию так:
*
* 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