defaults = array(
'title' => __( 'Related Posts', 'advance-widget-pack' ),
'post_count' => '5',
'match_by' => 'category',
'show_image' => '0',
'show_date' => '0',
'show_author' => '0',
'show_category' => '0',
'show_comment_number' => '0',
'show_excerpt' => '0',
);
$widget_ops = array(
'classname' => 'awp_related_posts awp_widget',
'description' => __( 'Widget to display posts related to the current post.', 'advance-widget-pack' ),
);
$control_ops = array(
'id_base' => 'awp_related_posts',
'width' => 200,
'height' => 250,
);
parent::__construct( 'awp_related_posts', __( 'AWP Related Posts', 'advance-widget-pack' ), $widget_ops, $control_ops );
}
public function widget( $args, $instance ) {
$instance = wp_parse_args( (array) $instance, $this->defaults );
$title = apply_filters( 'widget_title', $instance['title'] );
$post_count = absint( $instance['post_count'] );
$match_by = 'tag' === $instance['match_by'] ? 'tag' : 'category';
$current_post_id = get_the_ID();
if ( ! $current_post_id ) {
return;
}
$post_ids = self::get_post_ids( $current_post_id, $match_by, $post_count );
if ( ! $post_ids ) {
return;
}
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sidebar-provided wrapper markup, trusted per WP core convention.
if ( ! empty( $title ) ) {
echo $args['before_title'] . esc_html( $title ) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- title text is esc_html()'d; before/after_title are sidebar-provided wrapper markup.
}
awp_is_rendering( true );
echo '
';
foreach ( $post_ids as $post_id ) {
Awp_Recent_Post::render_post( $post_id, $instance );
}
echo '
';
awp_is_rendering( false );
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sidebar-provided wrapper markup, trusted per WP core convention.
}
/**
* Fetches related-post IDs for a given post, matched by shared category
* or tag, using the shared transient cache. Used by both the widget and
* the Related Posts block.
*
* @param int $current_post_id The post to find related posts for.
* @param string $match_by 'category' or 'tag'.
* @param int $post_count Max number of related posts to fetch.
* @return int[] Post IDs.
*/
public static function get_post_ids( $current_post_id, $match_by, $post_count ) {
$match_by = 'tag' === $match_by ? 'tag' : 'category';
$post_count = absint( $post_count );
$taxonomy = 'tag' === $match_by ? 'post_tag' : 'category';
$term_ids = wp_get_post_terms( $current_post_id, $taxonomy, array( 'fields' => 'ids' ) );
if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) {
return array();
}
$cache_key = 'awp_related_posts_' . awp_cache_generation() . '_' . $current_post_id . '_' . $match_by . '_' . $post_count;
$post_ids = get_transient( $cache_key );
if ( false === $post_ids ) {
$query = new WP_Query(
array(
'posts_per_page' => $post_count,
'post_type' => 'post',
'post_status' => 'publish',
'post__not_in' => array( $current_post_id ), // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- always excludes exactly one ID (the current post), not an unbounded list; result is cached via the transient below.
'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- cached via transient below.
array(
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $term_ids,
),
),
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => true,
'update_post_term_cache' => false,
)
);
$post_ids = wp_list_pluck( $query->posts, 'ID' );
set_transient( $cache_key, $post_ids, 15 * MINUTE_IN_SECONDS );
}
return $post_ids;
}
public function form( $instance ) {
$instance = wp_parse_args( (array) $instance, $this->defaults );
$title = $instance['title'];
$post_count = $instance['post_count'];
?>
id="get_field_id( 'show_image' ) ); ?>" name="get_field_name( 'show_image' ) ); ?>" />
id="get_field_id( 'show_date' ) ); ?>" name="get_field_name( 'show_date' ) ); ?>" />
id="get_field_id( 'show_author' ) ); ?>" name="get_field_name( 'show_author' ) ); ?>" />
id="get_field_id( 'show_category' ) ); ?>" name="get_field_name( 'show_category' ) ); ?>" />
id="get_field_id( 'show_comment_number' ) ); ?>" name="get_field_name( 'show_comment_number' ) ); ?>" />
id="get_field_id( 'show_excerpt' ) ); ?>" name="get_field_name( 'show_excerpt' ) ); ?>" />