defaults = array( 'title' => __( 'Random Posts', 'advance-widget-pack' ), 'post_count' => '5', 'show_image' => '0', 'show_date' => '0', 'show_author' => '0', 'show_category' => '0', 'show_comment_number' => '0', 'show_excerpt' => '0', ); $widget_ops = array( 'classname' => 'awp_random_posts awp_widget', 'description' => __( 'Widget to display random posts.', 'advance-widget-pack' ), ); $control_ops = array( 'id_base' => 'awp_random_posts', 'width' => 200, 'height' => 250, ); parent::__construct( 'awp_random_posts', __( 'AWP Random 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'] ); // update() already clamps to 1-50 and there is no Random Posts block, // so this is defence in depth: it keeps the cache key below bounded for // a hand-crafted or migrated instance that never passed through update(). $post_count = max( 1, min( 50, absint( $instance['post_count'] ) ) ); 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. } // Deliberately short-lived: this keeps the "random" feel (reshuffles // often) while still absorbing bursts of concurrent requests instead // of running ORDER BY RAND() — a full table scan — on every single one. $cache_key = 'awp_random_posts_' . awp_cache_generation() . '_' . $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', 'orderby' => 'rand', 'no_found_rows' => true, 'update_post_term_cache' => false, ) ); $post_ids = wp_list_pluck( $query->posts, 'ID' ); set_transient( $cache_key, $post_ids, 30 ); } if ( $post_ids ) { awp_is_rendering( true ); echo ''; awp_is_rendering( false ); } echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sidebar-provided wrapper markup, trusted per WP core convention. } /** * Renders a single post row inside the widget's