'Your forum\'s recent posts.' ] ); $this->init_local_vars(); add_action( 'wp_ajax_wpforo_load_ajax_widget_RecentPosts', [ $this, 'load_ajax_widget' ] ); add_action( 'wp_ajax_nopriv_wpforo_load_ajax_widget_RecentPosts', [ $this, 'load_ajax_widget' ] ); if( is_admin() ) { add_action( 'wp_ajax_wpforo_get_forum_tree', [ $this, 'get_forum_tree' ] ); } } private function init_local_vars() { $this->default_instance = [ 'boardid' => 0, 'title' => 'Recent Posts', 'forumids' => [], 'orderby' => 'created', 'order' => 'DESC', 'count' => 9, 'limit_per_topic' => 0, 'display_avatar' => true, 'forumids_filter' => false, 'current_forumid_filter' => false, 'exclude_firstposts' => false, 'display_only_unread' => false, 'display_new_indicator' => false, 'refresh_interval' => 0, 'excerpt_length' => 55, ]; $this->orderby_fields = [ 'created' => __( 'Created Date', 'wpforo' ), 'modified' => __( 'Modified Date', 'wpforo' ), ]; $this->order_fields = [ 'DESC' => __( 'DESC', 'wpforo' ), 'ASC' => __( 'ASC', 'wpforo' ), 'RAND' => __( 'Random', 'wpforo' ), ]; } private function add_post_cache_filter( $post_args ) { if( $post_args['order'] === 'RAND' ) { add_filter( 'wpforo_cache_post', '__return_false' ); } } private function remove_post_cache_filter( $post_args ) { if( $post_args['order'] === 'RAND' ) { remove_filter( 'wpforo_cache_post', '__return_false' ); } } public function get_widget( $instance, $post_args ) { $this->add_post_cache_filter( $post_args ); $is_user_logged_in = (bool) WPF()->current_userid; $post_args['private'] = ( ! $is_user_logged_in || ! WPF()->usergroup->can( 'aum' ) ) ? 0 : null; $post_args['status'] = ( ! $is_user_logged_in || ! WPF()->usergroup->can( 'aum' ) ) ? 0 : null; $print_avatar = $instance['display_avatar'] && wpforo_setting( 'profiles', 'avatars' ) && WPF()->usergroup->can( 'va' ); ob_start(); if( $post_args['limit_per_topic'] ) { if( $instance['display_only_unread'] && $is_user_logged_in ) { $grouped_postids = WPF()->post->get_unread_posts( $post_args, $post_args['row_count'] ); } else { $grouped_postids = WPF()->post->get_posts( $post_args ); } if( ! empty( $grouped_postids ) ) { $grouped_postids = implode( ',', $grouped_postids ); $postids = array_filter( array_map( 'wpforo_bigintval', explode( ',', $grouped_postids ) ) ); rsort( $postids ); foreach( $postids as $postid ) { $class = ''; $post = wpforo_post( $postid ); if( ! wpfval( $post, 'forumid' ) ) continue; if( ! WPF()->post->view_access( $post ) ) continue; $current = $post['topicid'] == wpfval( WPF()->current_object, 'topicid' ); if( ! $current ) { $class = 'class="' . ( $instance['display_only_unread'] ? 'wpf-unread-post' : wpforo_unread( $post['topicid'], 'post', false, $post['postid'] ) ) . '"'; } $member = wpforo_member( $post ); ?>
  • >
    style="width: 100%">

    ,

  • ' . wpforo_phrase( $error_message, false ) . ''; } } else { if( $instance['display_only_unread'] && $is_user_logged_in ) { $recent_posts = WPF()->post->get_unread_posts( $post_args, $post_args['row_count'] ); } else { $recent_posts = WPF()->post->get_posts( $post_args ); } if( ! empty( $recent_posts ) ) { foreach( $recent_posts as $post ) { $class = ''; $post_url = wpforo_post( $post['postid'], 'url' ); $member = wpforo_member( $post ); $current = $post['topicid'] == wpfval( WPF()->current_object, 'topicid' ); if( ! $current ) { $class = 'class="' . ( $instance['display_only_unread'] ? 'wpf-unread-post' : wpforo_unread( $post['topicid'], 'post', false, $post['postid'] ) ) . '"'; } ?>
  • >
    style="width:100%">

    ,

  • ' . wpforo_phrase( $error_message, false ) . ''; } } $this->remove_post_cache_filter( $post_args ); return sprintf( '', ob_get_clean() ); } public function load_ajax_widget() { $_POST = wp_unslash( $_POST ); $instance = json_decode( (string) wpfval( $_POST, 'instance' ), true ); $post_args = json_decode( (string) wpfval( $_POST, 'post_args' ), true ); // SECURITY FIX: Sanitize and validate all user-controlled parameters if( is_array( $post_args ) ) { // Remove dangerous 'where' parameter unset( $post_args['where'] ); // Force permission checks — prevents check_private=false injection $post_args['check_private'] = true; // Validate 'orderby' parameter against whitelist if( isset( $post_args['orderby'] ) ) { if( ! key_exists( $post_args['orderby'], $this->orderby_fields ) ) { $post_args['orderby'] = $this->default_instance['orderby']; } } // Validate 'order' parameter against whitelist if( isset( $post_args['order'] ) ) { if( ! key_exists( $post_args['order'], $this->order_fields ) ) { $post_args['order'] = $this->default_instance['order']; } } // SECURITY: coerce id-list fields to integer arrays so a serialized // payload from an unauthenticated POST can never reach // wpforo_parse_args() / unserialize() downstream. Defense in depth // alongside the allowed_classes=>false hardening in wpforo_parse_args. foreach( [ 'forumids', 'include', 'exclude', 'postids' ] as $idfield ) { if( isset( $post_args[ $idfield ] ) ) { $post_args[ $idfield ] = is_array( $post_args[ $idfield ] ) ? array_map( 'intval', $post_args[ $idfield ] ) : []; } } } wp_send_json_success( [ 'html' => $this->get_widget( $instance, $post_args ) ] ); } public function widget( $args, $instance ) { wp_enqueue_script( 'wpforo-widgets-js' ); $is_user_logged_in = (bool) WPF()->current_userid; $instance = wpforo_parse_args( $instance, $this->default_instance ); if( $instance['display_only_unread'] ) { $display_widget = $is_user_logged_in; $display_widget = apply_filters( 'wpforo_widget_display_recent_posts', $display_widget ); } else { $display_widget = true; } if( ! $display_widget ) return; if( $instance['current_forumid_filter'] && $instance['boardid'] === WPF()->board->get_current( 'boardid' ) && $current_forumid = wpfval( WPF()->current_object, 'forumid' ) ) { $instance['forumids'] = (array) $current_forumid; } $data = [ 'boardid' => $instance['boardid'], 'action' => 'wpforo_load_ajax_widget_RecentPosts', 'instance' => $instance, 'post_args' => [ 'forumids' => ( $instance['forumids'] ?: $this->default_instance['forumids'] ), 'orderby' => ( key_exists( $instance['orderby'], $this->orderby_fields ) ? $instance['orderby'] : $this->default_instance['orderby'] ), 'order' => ( key_exists( $instance['order'], $this->order_fields ) ? $instance['order'] : $this->default_instance['order'] ), 'row_count' => ( intval( $instance['count'] ) ?: $this->default_instance['count'] ), 'limit_per_topic' => ( intval( $instance['limit_per_topic'] ) ?: $this->default_instance['limit_per_topic'] ), 'is_first_post' => $instance['exclude_firstposts'] ? false : null, 'check_private' => true, ], ]; if( WPF()->board->get_current( 'boardid' ) === $instance['boardid'] ) { $html = $this->get_widget( $data['instance'], $data['post_args'] ); $onload = false; } else { $html = '
    '; $onload = true; $data['referer'] = home_url(); } $json = wp_json_encode( $data ); echo $args['before_widget'] . '
    '; if( ! empty( $instance['title'] ) ) echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title']; echo '
    ' . $html . '
    ' . $args['after_widget']; } public function form( $instance ) { $instance = wpforo_parse_args( $instance, $this->default_instance ); $title = (string) $instance['title']; $boardid = (int) $instance['boardid']; $selected = array_unique( array_filter( array_map( 'intval', (array) $instance['forumids'] ) ) ); $orderby = (string) $instance['orderby']; $order = (string) $instance['order']; $count = (int) $instance['count']; $limit_per_topic = (int) $instance['limit_per_topic']; $display_avatar = (bool) $instance['display_avatar']; $forumids_filter = (bool) $instance['forumids_filter']; $current_forumid_filter = (bool) $instance['current_forumid_filter']; $exclude_firstposts = (bool) $instance['exclude_firstposts']; $display_only_unread = (bool) $instance['display_only_unread']; $display_new_indicator = (bool) $instance['display_new_indicator']; $refresh_interval = (int) $instance['refresh_interval']; $excerpt_length = (int) $instance['excerpt_length']; WPF()->change_board( $boardid ); ?>

    : type="radio"> type="radio">

    : type="radio"> type="radio">

     

     

     

    : type="radio" name="get_field_name( 'display_avatar' ) ); ?>"> type="radio" name="get_field_name( 'display_avatar' ) ); ?>">

    type="radio" name="get_field_name( 'exclude_firstposts' ) ); ?>"> type="radio" name="get_field_name( 'exclude_firstposts' ) ); ?>">

    type="radio" name="get_field_name( 'display_only_unread' ) ); ?>"> type="radio" name="get_field_name( 'display_only_unread' ) ); ?>">

    : type="radio" name="get_field_name( 'display_new_indicator' ) ); ?>"> type="radio" name="get_field_name( 'display_new_indicator' ) ); ?>">

     

    default_instance ); $instance = []; $instance['title'] = strip_tags( (string) $new_instance['title'] ); $instance['boardid'] = (int) $new_instance['boardid']; $instance['forumids_filter'] = (bool) (int) $new_instance['forumids_filter']; $instance['forumids'] = array_unique( array_filter( array_map( 'intval', (array) $new_instance['forumids'] ) ) ); $instance['orderby'] = ( ! empty( $new_instance['orderby'] ) && key_exists( $new_instance['orderby'], $this->orderby_fields ) ) ? $new_instance['orderby'] : $this->default_instance['orderby']; $instance['order'] = ( ! empty( $new_instance['order'] ) && key_exists( $new_instance['order'], $this->order_fields ) ) ? $new_instance['order'] : $this->default_instance['order']; $instance['count'] = (int) $new_instance['count']; $instance['display_avatar'] = (bool) (int) $new_instance['display_avatar']; $instance['current_forumid_filter'] = (bool) (int) $new_instance['current_forumid_filter']; $instance['limit_per_topic'] = (int) $new_instance['limit_per_topic']; $instance['exclude_firstposts'] = (bool) (int) $new_instance['exclude_firstposts']; $instance['display_only_unread'] = (bool) (int) $new_instance['display_only_unread']; $instance['display_new_indicator'] = (bool) (int) $new_instance['display_new_indicator']; $instance['refresh_interval'] = (int) $new_instance['refresh_interval']; $instance['excerpt_length'] = (int) $new_instance['excerpt_length']; return $instance; } public function get_forum_tree() { ob_start(); WPF()->forum->tree( 'select_box', false, [] ); wp_send_json_success( [ 'html' => ob_get_clean() ] ); } }