PluginProbe
wpForo Forum / 3.1.1
wpForo Forum v3.1.1
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / widgets / RecentPosts.php

RecentPosts.php in wpForo Forum 3.1.1, at widgets/RecentPosts.php

470 lines 28.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace wpforo\widgets;
4
5 use WP_Widget;
6
7 class RecentPosts extends WP_Widget {
8 private $default_instance = [];
9 private $orderby_fields = [];
10 private $order_fields = [];
11
12 function __construct() {
13 parent::__construct( 'wpforo_recent_posts', 'wpForo Recent Posts', [ 'description' => 'Your forum\'s recent posts.' ] );
14 $this->init_local_vars();
15 add_action( 'wp_ajax_wpforo_load_ajax_widget_RecentPosts', [ $this, 'load_ajax_widget' ] );
16 add_action( 'wp_ajax_nopriv_wpforo_load_ajax_widget_RecentPosts', [ $this, 'load_ajax_widget' ] );
17 if( is_admin() ) {
18 add_action( 'wp_ajax_wpforo_get_forum_tree', [ $this, 'get_forum_tree' ] );
19 }
20 }
21
22 private function init_local_vars() {
23 $this->default_instance = [
24 'boardid' => 0,
25 'title' => 'Recent Posts',
26 'forumids' => [],
27 'orderby' => 'created',
28 'order' => 'DESC',
29 'count' => 9,
30 'limit_per_topic' => 0,
31 'display_avatar' => true,
32 'forumids_filter' => false,
33 'current_forumid_filter' => false,
34 'exclude_firstposts' => false,
35 'display_only_unread' => false,
36 'display_new_indicator' => false,
37 'refresh_interval' => 0,
38 'excerpt_length' => 55,
39 ];
40 $this->orderby_fields = [
41 'created' => __( 'Created Date', 'wpforo' ),
42 'modified' => __( 'Modified Date', 'wpforo' ),
43 ];
44 $this->order_fields = [
45 'DESC' => __( 'DESC', 'wpforo' ),
46 'ASC' => __( 'ASC', 'wpforo' ),
47 'RAND' => __( 'Random', 'wpforo' ),
48 ];
49 }
50
51 private function add_post_cache_filter( $post_args ) {
52 if( $post_args['order'] === 'RAND' ) {
53 add_filter( 'wpforo_cache_post', '__return_false' );
54 }
55 }
56
57 private function remove_post_cache_filter( $post_args ) {
58 if( $post_args['order'] === 'RAND' ) {
59 remove_filter( 'wpforo_cache_post', '__return_false' );
60 }
61 }
62
63 public function get_widget( $instance, $post_args ) {
64 $this->add_post_cache_filter( $post_args );
65 $is_user_logged_in = (bool) WPF()->current_userid;
66 $post_args['private'] = ( ! $is_user_logged_in || ! WPF()->usergroup->can( 'aum' ) ) ? 0 : null;
67 $post_args['status'] = ( ! $is_user_logged_in || ! WPF()->usergroup->can( 'aum' ) ) ? 0 : null;
68 $print_avatar = $instance['display_avatar'] && wpforo_setting( 'profiles', 'avatars' ) && WPF()->usergroup->can( 'va' );
69
70 ob_start();
71 if( $post_args['limit_per_topic'] ) {
72 if( $instance['display_only_unread'] && $is_user_logged_in ) {
73 $grouped_postids = WPF()->post->get_unread_posts( $post_args, $post_args['row_count'] );
74 } else {
75 $grouped_postids = WPF()->post->get_posts( $post_args );
76 }
77 if( ! empty( $grouped_postids ) ) {
78 $grouped_postids = implode( ',', $grouped_postids );
79 $postids = array_filter( array_map( 'wpforo_bigintval', explode( ',', $grouped_postids ) ) );
80 rsort( $postids );
81 foreach( $postids as $postid ) {
82 $class = '';
83 $post = wpforo_post( $postid );
84 if( ! wpfval( $post, 'forumid' ) ) continue;
85 if( ! WPF()->post->view_access( $post ) ) continue;
86 $current = $post['topicid'] == wpfval( WPF()->current_object, 'topicid' );
87 if( ! $current ) {
88 $class = 'class="' . ( $instance['display_only_unread'] ? 'wpf-unread-post' : wpforo_unread( $post['topicid'], 'post', false, $post['postid'] ) ) . '"';
89 }
90 $member = wpforo_member( $post );
91 ?>
92 <li <?php echo $class; ?>>
93 <div class="wpforo-list-item ">
94 <?php if( $print_avatar ): ?>
95 <div class="wpforo-list-item-left">
96 <?php echo wpforo_user_avatar( $member ); ?>
97 </div>
98 <?php endif; ?>
99 <div class="wpforo-list-item-right" <?php if( ! $print_avatar ): ?> style="width: 100%"<?php endif; ?>>
100 <p class="posttitle">
101 <a href="<?php echo esc_url( (string) $post['url'] ) ?>"><?php
102 if( $t = esc_html( trim( (string) $post['title'] ) ) ) {
103 echo $t;
104 } else {
105 echo wpforo_phrase( 'RE', false, 'default' ) . ': ' . esc_html( trim( (string) wpforo_topic( $post['topicid'], 'title' ) ) );
106 } ?>
107 </a>
108 <?php if( ! $current && $instance['display_new_indicator'] ) wpforo_unread_button( $post['topicid'], '', true, $post['postid'] ) ?>
109 </p>
110 <p class="posttext"><?php echo esc_html( wpforo_text( $post['body'], $instance['excerpt_length'], false ) ); ?></p>
111 <p class="postuser"><?php wpforo_phrase( 'by' ) ?> <?php wpforo_member_link( $member ) ?>
112 , <span style="white-space: nowrap;"><?php wpforo_date( $post['created'] ) ?></span></p>
113 </div>
114 <div class="wpf-clear"></div>
115 </div>
116 </li>
117 <?php
118 }
119 } else {
120 $error_message = ( $instance['display_only_unread'] ) ? 'No new posts found' : 'No posts found';
121 echo '<li class="wpf-no-post-found">' . wpforo_phrase( $error_message, false ) . '</li>';
122 }
123 } else {
124 if( $instance['display_only_unread'] && $is_user_logged_in ) {
125 $recent_posts = WPF()->post->get_unread_posts( $post_args, $post_args['row_count'] );
126 } else {
127 $recent_posts = WPF()->post->get_posts( $post_args );
128 }
129 if( ! empty( $recent_posts ) ) {
130 foreach( $recent_posts as $post ) {
131 $class = '';
132 $post_url = wpforo_post( $post['postid'], 'url' );
133 $member = wpforo_member( $post );
134 $current = $post['topicid'] == wpfval( WPF()->current_object, 'topicid' );
135 if( ! $current ) {
136 $class = 'class="' . ( $instance['display_only_unread'] ? 'wpf-unread-post' : wpforo_unread( $post['topicid'], 'post', false, $post['postid'] ) ) . '"';
137 }
138 ?>
139 <li <?php echo $class; ?>>
140 <div class="wpforo-list-item">
141 <?php if( $print_avatar ): ?>
142 <div class="wpforo-list-item-left">
143 <?php echo wpforo_user_avatar( $member ); ?>
144 </div>
145 <?php endif; ?>
146 <div class="wpforo-list-item-right" <?php if( ! $print_avatar ): ?> style="width:100%"<?php endif; ?>>
147 <p class="posttitle">
148 <a href="<?php echo esc_url( (string) $post_url ) ?>"><?php
149 if( $t = esc_html( trim( (string) $post['title'] ) ) ) {
150 echo $t;
151 } else {
152 echo wpforo_phrase( 'RE', false, 'default' ) . ': ' . esc_html( trim( (string) wpforo_topic( $post['topicid'], 'title' ) ) );
153 } ?>
154 </a>
155 <?php if( ! $current && $instance['display_new_indicator'] ) wpforo_unread_button( $post['topicid'], '', true, $post['postid'] ) ?>
156 </p>
157 <p class="posttext"><?php echo esc_html( wpforo_text( $post['body'], $instance['excerpt_length'], false ) ); ?></p>
158 <p class="postuser"><?php wpforo_phrase( 'by' ) ?> <?php wpforo_member_link( $member ) ?>
159 , <span style="white-space: nowrap;"><?php wpforo_date( $post['created'] ) ?></span></p>
160 </div>
161 <div class="wpf-clear"></div>
162 </div>
163 </li>
164 <?php
165 }
166 } else {
167 $error_message = ( $instance['display_only_unread'] ) ? 'No new posts found' : 'No posts found';
168 echo '<li class="wpf-no-post-found">' . wpforo_phrase( $error_message, false ) . '</li>';
169 }
170 }
171
172 $this->remove_post_cache_filter( $post_args );
173
174 return sprintf( '<ul>%1$s</ul>', ob_get_clean() );
175 }
176
177 public function load_ajax_widget() {
178 $_POST = wp_unslash( $_POST );
179 $instance = json_decode( (string) wpfval( $_POST, 'instance' ), true );
180 $post_args = json_decode( (string) wpfval( $_POST, 'post_args' ), true );
181
182 // SECURITY FIX: Sanitize and validate all user-controlled parameters
183 if( is_array( $post_args ) ) {
184 // Remove dangerous 'where' parameter
185 unset( $post_args['where'] );
186
187 // Force permission checks — prevents check_private=false injection
188 $post_args['check_private'] = true;
189
190 // Validate 'orderby' parameter against whitelist
191 if( isset( $post_args['orderby'] ) ) {
192 if( ! key_exists( $post_args['orderby'], $this->orderby_fields ) ) {
193 $post_args['orderby'] = $this->default_instance['orderby'];
194 }
195 }
196
197 // Validate 'order' parameter against whitelist
198 if( isset( $post_args['order'] ) ) {
199 if( ! key_exists( $post_args['order'], $this->order_fields ) ) {
200 $post_args['order'] = $this->default_instance['order'];
201 }
202 }
203
204 // SECURITY: coerce id-list fields to integer arrays so a serialized
205 // payload from an unauthenticated POST can never reach
206 // wpforo_parse_args() / unserialize() downstream. Defense in depth
207 // alongside the allowed_classes=>false hardening in wpforo_parse_args.
208 foreach( [ 'forumids', 'include', 'exclude', 'postids' ] as $idfield ) {
209 if( isset( $post_args[ $idfield ] ) ) {
210 $post_args[ $idfield ] = is_array( $post_args[ $idfield ] )
211 ? array_map( 'intval', $post_args[ $idfield ] )
212 : [];
213 }
214 }
215 }
216
217 wp_send_json_success( [ 'html' => $this->get_widget( $instance, $post_args ) ] );
218 }
219
220 public function widget( $args, $instance ) {
221 wp_enqueue_script( 'wpforo-widgets-js' );
222 $is_user_logged_in = (bool) WPF()->current_userid;
223 $instance = wpforo_parse_args( $instance, $this->default_instance );
224 if( $instance['display_only_unread'] ) {
225 $display_widget = $is_user_logged_in;
226 $display_widget = apply_filters( 'wpforo_widget_display_recent_posts', $display_widget );
227 } else {
228 $display_widget = true;
229 }
230 if( ! $display_widget ) return;
231
232 if( $instance['current_forumid_filter'] && $instance['boardid'] === WPF()->board->get_current( 'boardid' ) && $current_forumid = wpfval(
233 WPF()->current_object,
234 'forumid'
235 ) ) {
236 $instance['forumids'] = (array) $current_forumid;
237 }
238 $data = [
239 'boardid' => $instance['boardid'],
240 'action' => 'wpforo_load_ajax_widget_RecentPosts',
241 'instance' => $instance,
242 'post_args' => [
243 'forumids' => ( $instance['forumids'] ?: $this->default_instance['forumids'] ),
244 'orderby' => ( key_exists( $instance['orderby'], $this->orderby_fields ) ? $instance['orderby'] : $this->default_instance['orderby'] ),
245 'order' => ( key_exists( $instance['order'], $this->order_fields ) ? $instance['order'] : $this->default_instance['order'] ),
246 'row_count' => ( intval( $instance['count'] ) ?: $this->default_instance['count'] ),
247 'limit_per_topic' => ( intval( $instance['limit_per_topic'] ) ?: $this->default_instance['limit_per_topic'] ),
248 'is_first_post' => $instance['exclude_firstposts'] ? false : null,
249 'check_private' => true,
250 ],
251 ];
252 if( WPF()->board->get_current( 'boardid' ) === $instance['boardid'] ) {
253 $html = $this->get_widget( $data['instance'], $data['post_args'] );
254 $onload = false;
255 } else {
256 $html = '<div style="text-align: center; font-size: 20px;"><i class="fas fa-spinner fa-spin"></i></div>';
257 $onload = true;
258 $data['referer'] = home_url();
259 }
260
261 $json = wp_json_encode( $data );
262 echo $args['before_widget'] . '<div id="wpf-widget-recent-replies" class="wpforo-widget-wrap">';
263 if( ! empty( $instance['title'] ) ) echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
264 echo '<div class="wpforo-widget-content wpforo-ajax-widget ' . ( ! $onload ? 'wpforo-ajax-widget-onload-false' : '' ) . '" data-json="' . esc_attr(
265 $json
266 ) . '">' . $html . '</div></div>' . $args['after_widget'];
267 }
268
269 public function form( $instance ) {
270 $instance = wpforo_parse_args( $instance, $this->default_instance );
271 $title = (string) $instance['title'];
272 $boardid = (int) $instance['boardid'];
273 $selected = array_unique( array_filter( array_map( 'intval', (array) $instance['forumids'] ) ) );
274 $orderby = (string) $instance['orderby'];
275 $order = (string) $instance['order'];
276 $count = (int) $instance['count'];
277 $limit_per_topic = (int) $instance['limit_per_topic'];
278 $display_avatar = (bool) $instance['display_avatar'];
279 $forumids_filter = (bool) $instance['forumids_filter'];
280 $current_forumid_filter = (bool) $instance['current_forumid_filter'];
281 $exclude_firstposts = (bool) $instance['exclude_firstposts'];
282 $display_only_unread = (bool) $instance['display_only_unread'];
283 $display_new_indicator = (bool) $instance['display_new_indicator'];
284 $refresh_interval = (int) $instance['refresh_interval'];
285 $excerpt_length = (int) $instance['excerpt_length'];
286 WPF()->change_board( $boardid );
287 ?>
288 <style>
289 .wpf-wdg-wrapper .wpf_wdg_forumids_wrap {
290 display: none !important;
291 }
292
293 .wpf-wdg-wrapper input.wpf_wdg_forumids_filter_1:checked ~ .wpf_wdg_forumids_wrap {
294 display: block !important;
295 }
296
297 .wpf_wdg_limit_per_topic {
298 width: 53px;
299 }
300 </style>
301 <div class="wpf-wdg-wrapper">
302 <p>
303 <label for="<?php echo $this->get_field_id( 'title' ) ?>"><?php _e( 'Title', 'wpforo' ); ?>:</label>
304 <input id="<?php echo $this->get_field_id( 'title' ) ?>" class="widefat"
305 name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text"
306 value="<?php echo esc_attr( $title ); ?>">
307 </p>
308 <p>
309 <label for="<?php echo $this->get_field_id( 'boardid' ) ?>"></label>
310 <select id="<?php echo $this->get_field_id( 'boardid' ) ?>" class="wpf_wdg_boardid" name="<?php echo esc_attr( $this->get_field_name( 'boardid' ) ); ?>">
311 <?php echo WPF()->board->dropdown( $boardid ) ?>
312 </select>
313 </p>
314 <div>
315 <span><?php _e( 'Filter by forums', 'wpforo' ); ?> :</span>
316
317 <label for="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
318 <input id="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_1" value="1" class="wpf_wdg_forumids_filter_1"
319 name="<?php echo esc_attr( $this->get_field_name( 'forumids_filter' ) ); ?>" <?php checked( $forumids_filter ); ?> type="radio">
320
321 <label for="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
322 <input id="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_0" value="0" class="wpf_wdg_forumids_filter_0"
323 name="<?php echo esc_attr( $this->get_field_name( 'forumids_filter' ) ); ?>" <?php checked( $forumids_filter, false ); ?> type="radio">
324
325 <div class="wpf_wdg_forumids_wrap">
326 <label for="<?php echo $this->get_field_id( 'forumids' ) ?>"></label>
327 <select id="<?php echo $this->get_field_id( 'forumids' ) ?>" class="wpf_wdg_forumids" name="<?php echo esc_attr( $this->get_field_name( 'forumids' ) ); ?>[]" multiple>
328 <?php WPF()->forum->tree( 'select_box', false, $selected ) ?>
329 </select>
330 </div>
331 </div>
332 <p>
333 <span><?php _e( 'Autofilter by current forum', 'wpforo' ); ?> : </span>
334
335 <label for="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
336 <input id="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_1" name="<?php echo esc_attr( $this->get_field_name( 'current_forumid_filter' ) ); ?>" value="1" <?php checked(
337 $current_forumid_filter
338 ); ?> type="radio">
339
340 <label for="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
341 <input id="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_0" name="<?php echo esc_attr( $this->get_field_name( 'current_forumid_filter' ) ); ?>" value="0" <?php checked(
342 $current_forumid_filter,
343 false
344 ); ?> type="radio">
345 </p>
346 <p>
347 <label for="<?php echo $this->get_field_id( 'orderby' ) ?>"><?php _e( 'Order by', 'wpforo' ); ?>
348 :</label>
349 <select class="wpf_wdg_orderby" name="<?php echo esc_attr( $this->get_field_name( 'orderby' ) ); ?>"
350 id="<?php echo $this->get_field_id( 'orderby' ) ?>" <?php echo( $limit_per_topic ? 'disabled' : '' ) ?>>
351 <?php foreach( $this->orderby_fields as $orderby_key => $orderby_field ) : ?>
352 <option value="<?php echo $orderby_key; ?>"<?php echo( $orderby_key == $orderby ? ' selected' : '' ); ?>><?php echo $orderby_field; ?></option>
353 <?php endforeach; ?>
354 </select>
355 <label>
356 <select class="wpf_wdg_order"
357 name="<?php echo esc_attr( $this->get_field_name( 'order' ) ); ?>" <?php echo( $limit_per_topic ? 'disabled' : '' ) ?>>
358 <?php foreach( $this->order_fields as $order_key => $order_field ) : ?>
359 <option value="<?php echo $order_key; ?>"<?php echo( $order_key == $order ? ' selected' : '' ); ?>><?php echo $order_field; ?></option>
360 <?php endforeach; ?>
361 </select>
362 </label>
363 </p>
364 <p>
365 <label for="<?php echo $this->get_field_id( 'limit_per_topic' ) ?>"><?php _e( 'Limit Per Topic', 'wpforo' ); ?></label>&nbsp;
366 <input id="<?php echo $this->get_field_id( 'limit_per_topic' ) ?>" class="wpf_wdg_limit_per_topic"
367 type="number" min="0"
368 name="<?php echo esc_attr( $this->get_field_name( 'limit_per_topic' ) ); ?>"
369 value="<?php echo esc_attr( $limit_per_topic ); ?>">
370 <span style="color: #aaa;"><?php _e( 'set 0 to remove this limit', 'wpforo' ) ?></span>
371 </p>
372 <p>
373 <label for="<?php echo $this->get_field_id( 'count' ) ?>"><?php _e( 'Number of Items', 'wpforo' ); ?></label>&nbsp;
374 <input id="<?php echo $this->get_field_id( 'count' ) ?>" type="number" min="1" style="width: 53px;"
375 name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>"
376 value="<?php echo esc_attr( $count ); ?>">
377 </p>
378 <p>
379 <label for="<?php echo $this->get_field_id( 'excerpt_length' ) ?>"><?php _e( 'Excerpt Length', 'wpforo' ); ?></label>&nbsp;
380 <input id="<?php echo $this->get_field_id( 'excerpt_length' ) ?>" type="number" min="0" style="display: inline-block; width: 53px;"
381 name="<?php echo esc_attr( $this->get_field_name( 'excerpt_length' ) ); ?>" value="<?php echo esc_attr( $excerpt_length ); ?>">
382 <span style="color: #ccc"><?php _e( 'Set 0 to disable autorefresh', 'wpforo' ) ?></span>
383 </p>
384 <p>
385 <span><?php _e( 'Display with avatars', 'wpforo' ); ?> : </span>
386
387 <label for="<?php echo $this->get_field_id( 'display_avatar' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
388 <input id="<?php echo $this->get_field_id( 'display_avatar' ) ?>_1" value="1" <?php checked( $display_avatar ); ?> type="radio"
389 name="<?php echo esc_attr( $this->get_field_name( 'display_avatar' ) ); ?>">
390
391 <label for="<?php echo $this->get_field_id( 'display_avatar' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
392 <input id="<?php echo $this->get_field_id( 'display_avatar' ) ?>_0" value="0" <?php checked( $display_avatar, false ); ?> type="radio"
393 name="<?php echo esc_attr( $this->get_field_name( 'display_avatar' ) ); ?>">
394 </p>
395 <p>
396 <span><?php _e( 'Exclude First Posts', 'wpforo' ); ?></span>
397 <label for="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
398 <input id="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_1" value="1" <?php checked( $exclude_firstposts ); ?> type="radio"
399 name="<?php echo esc_attr( $this->get_field_name( 'exclude_firstposts' ) ); ?>">
400
401 <label for="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
402 <input id="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_0" value="0" <?php checked( $exclude_firstposts, false ); ?> type="radio"
403 name="<?php echo esc_attr( $this->get_field_name( 'exclude_firstposts' ) ); ?>">
404 </p>
405 <p>
406 <span><?php _e( 'Display Only Unread Posts', 'wpforo' ); ?></span>
407 <label for="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
408 <input id="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_1" value="1" <?php checked( $display_only_unread ); ?> type="radio"
409 name="<?php echo esc_attr( $this->get_field_name( 'display_only_unread' ) ); ?>">
410
411 <label for="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
412 <input id="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_0" value="0" <?php checked( $display_only_unread, false ); ?> type="radio"
413 name="<?php echo esc_attr( $this->get_field_name( 'display_only_unread' ) ); ?>">
414 </p>
415 <p>
416 <span><?php _e( 'Display [new] indicator', 'wpforo' ); ?> : </span>
417
418 <label for="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
419 <input id="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_1" value="1" <?php checked( $display_new_indicator ); ?> type="radio"
420 name="<?php echo esc_attr( $this->get_field_name( 'display_new_indicator' ) ); ?>">
421
422 <label for="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
423 <input id="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_0" value="0" <?php checked( $display_new_indicator, false ); ?> type="radio"
424 name="<?php echo esc_attr( $this->get_field_name( 'display_new_indicator' ) ); ?>">
425 </p>
426 <p>
427 <label for="<?php echo $this->get_field_id( 'refresh_interval' ) ?>"><?php _e( 'Auto Refresh Interval Seconds', 'wpforo' ); ?></label>&nbsp;
428 <input id="<?php echo $this->get_field_id( 'refresh_interval' ) ?>" type="number" min="0" style="display: inline-block; width: 53px;"
429 name="<?php echo esc_attr( $this->get_field_name( 'refresh_interval' ) ); ?>" value="<?php echo esc_attr( $refresh_interval ); ?>">
430 <span style="color: #ccc"><?php _e( 'Set 0 to disable autorefresh', 'wpforo' ) ?></span>
431 </p>
432 </div>
433 <?php
434 }
435
436 public function update( $new_instance, $old_instance ) {
437 $new_instance = wpforo_parse_args( $new_instance, $this->default_instance );
438 $instance = [];
439 $instance['title'] = strip_tags( (string) $new_instance['title'] );
440 $instance['boardid'] = (int) $new_instance['boardid'];
441 $instance['forumids_filter'] = (bool) (int) $new_instance['forumids_filter'];
442 $instance['forumids'] = array_unique( array_filter( array_map( 'intval', (array) $new_instance['forumids'] ) ) );
443 $instance['orderby'] = ( ! empty( $new_instance['orderby'] ) && key_exists(
444 $new_instance['orderby'],
445 $this->orderby_fields
446 ) ) ? $new_instance['orderby'] : $this->default_instance['orderby'];
447 $instance['order'] = ( ! empty( $new_instance['order'] ) && key_exists(
448 $new_instance['order'],
449 $this->order_fields
450 ) ) ? $new_instance['order'] : $this->default_instance['order'];
451 $instance['count'] = (int) $new_instance['count'];
452 $instance['display_avatar'] = (bool) (int) $new_instance['display_avatar'];
453 $instance['current_forumid_filter'] = (bool) (int) $new_instance['current_forumid_filter'];
454 $instance['limit_per_topic'] = (int) $new_instance['limit_per_topic'];
455 $instance['exclude_firstposts'] = (bool) (int) $new_instance['exclude_firstposts'];
456 $instance['display_only_unread'] = (bool) (int) $new_instance['display_only_unread'];
457 $instance['display_new_indicator'] = (bool) (int) $new_instance['display_new_indicator'];
458 $instance['refresh_interval'] = (int) $new_instance['refresh_interval'];
459 $instance['excerpt_length'] = (int) $new_instance['excerpt_length'];
460
461 return $instance;
462 }
463
464 public function get_forum_tree() {
465 ob_start();
466 WPF()->forum->tree( 'select_box', false, [] );
467 wp_send_json_success( [ 'html' => ob_get_clean() ] );
468 }
469 }
470