PluginProbe
wpForo Forum / 3.0.9
wpForo Forum v3.0.9
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.0.9, at widgets/RecentPosts.php

458 lines 27.4 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
205 wp_send_json_success( [ 'html' => $this->get_widget( $instance, $post_args ) ] );
206 }
207
208 public function widget( $args, $instance ) {
209 wp_enqueue_script( 'wpforo-widgets-js' );
210 $is_user_logged_in = (bool) WPF()->current_userid;
211 $instance = wpforo_parse_args( $instance, $this->default_instance );
212 if( $instance['display_only_unread'] ) {
213 $display_widget = $is_user_logged_in;
214 $display_widget = apply_filters( 'wpforo_widget_display_recent_posts', $display_widget );
215 } else {
216 $display_widget = true;
217 }
218 if( ! $display_widget ) return;
219
220 if( $instance['current_forumid_filter'] && $instance['boardid'] === WPF()->board->get_current( 'boardid' ) && $current_forumid = wpfval(
221 WPF()->current_object,
222 'forumid'
223 ) ) {
224 $instance['forumids'] = (array) $current_forumid;
225 }
226 $data = [
227 'boardid' => $instance['boardid'],
228 'action' => 'wpforo_load_ajax_widget_RecentPosts',
229 'instance' => $instance,
230 'post_args' => [
231 'forumids' => ( $instance['forumids'] ?: $this->default_instance['forumids'] ),
232 'orderby' => ( key_exists( $instance['orderby'], $this->orderby_fields ) ? $instance['orderby'] : $this->default_instance['orderby'] ),
233 'order' => ( key_exists( $instance['order'], $this->order_fields ) ? $instance['order'] : $this->default_instance['order'] ),
234 'row_count' => ( intval( $instance['count'] ) ?: $this->default_instance['count'] ),
235 'limit_per_topic' => ( intval( $instance['limit_per_topic'] ) ?: $this->default_instance['limit_per_topic'] ),
236 'is_first_post' => $instance['exclude_firstposts'] ? false : null,
237 'check_private' => true,
238 ],
239 ];
240 if( WPF()->board->get_current( 'boardid' ) === $instance['boardid'] ) {
241 $html = $this->get_widget( $data['instance'], $data['post_args'] );
242 $onload = false;
243 } else {
244 $html = '<div style="text-align: center; font-size: 20px;"><i class="fas fa-spinner fa-spin"></i></div>';
245 $onload = true;
246 $data['referer'] = home_url();
247 }
248
249 $json = wp_json_encode( $data );
250 echo $args['before_widget'] . '<div id="wpf-widget-recent-replies" class="wpforo-widget-wrap">';
251 if( ! empty( $instance['title'] ) ) echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
252 echo '<div class="wpforo-widget-content wpforo-ajax-widget ' . ( ! $onload ? 'wpforo-ajax-widget-onload-false' : '' ) . '" data-json="' . esc_attr(
253 $json
254 ) . '">' . $html . '</div></div>' . $args['after_widget'];
255 }
256
257 public function form( $instance ) {
258 $instance = wpforo_parse_args( $instance, $this->default_instance );
259 $title = (string) $instance['title'];
260 $boardid = (int) $instance['boardid'];
261 $selected = array_unique( array_filter( array_map( 'intval', (array) $instance['forumids'] ) ) );
262 $orderby = (string) $instance['orderby'];
263 $order = (string) $instance['order'];
264 $count = (int) $instance['count'];
265 $limit_per_topic = (int) $instance['limit_per_topic'];
266 $display_avatar = (bool) $instance['display_avatar'];
267 $forumids_filter = (bool) $instance['forumids_filter'];
268 $current_forumid_filter = (bool) $instance['current_forumid_filter'];
269 $exclude_firstposts = (bool) $instance['exclude_firstposts'];
270 $display_only_unread = (bool) $instance['display_only_unread'];
271 $display_new_indicator = (bool) $instance['display_new_indicator'];
272 $refresh_interval = (int) $instance['refresh_interval'];
273 $excerpt_length = (int) $instance['excerpt_length'];
274 WPF()->change_board( $boardid );
275 ?>
276 <style>
277 .wpf-wdg-wrapper .wpf_wdg_forumids_wrap {
278 display: none !important;
279 }
280
281 .wpf-wdg-wrapper input.wpf_wdg_forumids_filter_1:checked ~ .wpf_wdg_forumids_wrap {
282 display: block !important;
283 }
284
285 .wpf_wdg_limit_per_topic {
286 width: 53px;
287 }
288 </style>
289 <div class="wpf-wdg-wrapper">
290 <p>
291 <label for="<?php echo $this->get_field_id( 'title' ) ?>"><?php _e( 'Title', 'wpforo' ); ?>:</label>
292 <input id="<?php echo $this->get_field_id( 'title' ) ?>" class="widefat"
293 name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text"
294 value="<?php echo esc_attr( $title ); ?>">
295 </p>
296 <p>
297 <label for="<?php echo $this->get_field_id( 'boardid' ) ?>"></label>
298 <select id="<?php echo $this->get_field_id( 'boardid' ) ?>" class="wpf_wdg_boardid" name="<?php echo esc_attr( $this->get_field_name( 'boardid' ) ); ?>">
299 <?php echo WPF()->board->dropdown( $boardid ) ?>
300 </select>
301 </p>
302 <div>
303 <span><?php _e( 'Filter by forums', 'wpforo' ); ?> :</span>
304
305 <label for="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
306 <input id="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_1" value="1" class="wpf_wdg_forumids_filter_1"
307 name="<?php echo esc_attr( $this->get_field_name( 'forumids_filter' ) ); ?>" <?php checked( $forumids_filter ); ?> type="radio">
308
309 <label for="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
310 <input id="<?php echo $this->get_field_id( 'forumids_filter' ) ?>_0" value="0" class="wpf_wdg_forumids_filter_0"
311 name="<?php echo esc_attr( $this->get_field_name( 'forumids_filter' ) ); ?>" <?php checked( $forumids_filter, false ); ?> type="radio">
312
313 <div class="wpf_wdg_forumids_wrap">
314 <label for="<?php echo $this->get_field_id( 'forumids' ) ?>"></label>
315 <select id="<?php echo $this->get_field_id( 'forumids' ) ?>" class="wpf_wdg_forumids" name="<?php echo esc_attr( $this->get_field_name( 'forumids' ) ); ?>[]" multiple>
316 <?php WPF()->forum->tree( 'select_box', false, $selected ) ?>
317 </select>
318 </div>
319 </div>
320 <p>
321 <span><?php _e( 'Autofilter by current forum', 'wpforo' ); ?> : </span>
322
323 <label for="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
324 <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(
325 $current_forumid_filter
326 ); ?> type="radio">
327
328 <label for="<?php echo $this->get_field_id( 'current_forumid_filter' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
329 <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(
330 $current_forumid_filter,
331 false
332 ); ?> type="radio">
333 </p>
334 <p>
335 <label for="<?php echo $this->get_field_id( 'orderby' ) ?>"><?php _e( 'Order by', 'wpforo' ); ?>
336 :</label>
337 <select class="wpf_wdg_orderby" name="<?php echo esc_attr( $this->get_field_name( 'orderby' ) ); ?>"
338 id="<?php echo $this->get_field_id( 'orderby' ) ?>" <?php echo( $limit_per_topic ? 'disabled' : '' ) ?>>
339 <?php foreach( $this->orderby_fields as $orderby_key => $orderby_field ) : ?>
340 <option value="<?php echo $orderby_key; ?>"<?php echo( $orderby_key == $orderby ? ' selected' : '' ); ?>><?php echo $orderby_field; ?></option>
341 <?php endforeach; ?>
342 </select>
343 <label>
344 <select class="wpf_wdg_order"
345 name="<?php echo esc_attr( $this->get_field_name( 'order' ) ); ?>" <?php echo( $limit_per_topic ? 'disabled' : '' ) ?>>
346 <?php foreach( $this->order_fields as $order_key => $order_field ) : ?>
347 <option value="<?php echo $order_key; ?>"<?php echo( $order_key == $order ? ' selected' : '' ); ?>><?php echo $order_field; ?></option>
348 <?php endforeach; ?>
349 </select>
350 </label>
351 </p>
352 <p>
353 <label for="<?php echo $this->get_field_id( 'limit_per_topic' ) ?>"><?php _e( 'Limit Per Topic', 'wpforo' ); ?></label>&nbsp;
354 <input id="<?php echo $this->get_field_id( 'limit_per_topic' ) ?>" class="wpf_wdg_limit_per_topic"
355 type="number" min="0"
356 name="<?php echo esc_attr( $this->get_field_name( 'limit_per_topic' ) ); ?>"
357 value="<?php echo esc_attr( $limit_per_topic ); ?>">
358 <span style="color: #aaa;"><?php _e( 'set 0 to remove this limit', 'wpforo' ) ?></span>
359 </p>
360 <p>
361 <label for="<?php echo $this->get_field_id( 'count' ) ?>"><?php _e( 'Number of Items', 'wpforo' ); ?></label>&nbsp;
362 <input id="<?php echo $this->get_field_id( 'count' ) ?>" type="number" min="1" style="width: 53px;"
363 name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>"
364 value="<?php echo esc_attr( $count ); ?>">
365 </p>
366 <p>
367 <label for="<?php echo $this->get_field_id( 'excerpt_length' ) ?>"><?php _e( 'Excerpt Length', 'wpforo' ); ?></label>&nbsp;
368 <input id="<?php echo $this->get_field_id( 'excerpt_length' ) ?>" type="number" min="0" style="display: inline-block; width: 53px;"
369 name="<?php echo esc_attr( $this->get_field_name( 'excerpt_length' ) ); ?>" value="<?php echo esc_attr( $excerpt_length ); ?>">
370 <span style="color: #ccc"><?php _e( 'Set 0 to disable autorefresh', 'wpforo' ) ?></span>
371 </p>
372 <p>
373 <span><?php _e( 'Display with avatars', 'wpforo' ); ?> : </span>
374
375 <label for="<?php echo $this->get_field_id( 'display_avatar' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
376 <input id="<?php echo $this->get_field_id( 'display_avatar' ) ?>_1" value="1" <?php checked( $display_avatar ); ?> type="radio"
377 name="<?php echo esc_attr( $this->get_field_name( 'display_avatar' ) ); ?>">
378
379 <label for="<?php echo $this->get_field_id( 'display_avatar' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
380 <input id="<?php echo $this->get_field_id( 'display_avatar' ) ?>_0" value="0" <?php checked( $display_avatar, false ); ?> type="radio"
381 name="<?php echo esc_attr( $this->get_field_name( 'display_avatar' ) ); ?>">
382 </p>
383 <p>
384 <span><?php _e( 'Exclude First Posts', 'wpforo' ); ?></span>
385 <label for="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
386 <input id="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_1" value="1" <?php checked( $exclude_firstposts ); ?> type="radio"
387 name="<?php echo esc_attr( $this->get_field_name( 'exclude_firstposts' ) ); ?>">
388
389 <label for="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
390 <input id="<?php echo $this->get_field_id( 'exclude_firstposts' ) ?>_0" value="0" <?php checked( $exclude_firstposts, false ); ?> type="radio"
391 name="<?php echo esc_attr( $this->get_field_name( 'exclude_firstposts' ) ); ?>">
392 </p>
393 <p>
394 <span><?php _e( 'Display Only Unread Posts', 'wpforo' ); ?></span>
395 <label for="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
396 <input id="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_1" value="1" <?php checked( $display_only_unread ); ?> type="radio"
397 name="<?php echo esc_attr( $this->get_field_name( 'display_only_unread' ) ); ?>">
398
399 <label for="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
400 <input id="<?php echo $this->get_field_id( 'display_only_unread' ) ?>_0" value="0" <?php checked( $display_only_unread, false ); ?> type="radio"
401 name="<?php echo esc_attr( $this->get_field_name( 'display_only_unread' ) ); ?>">
402 </p>
403 <p>
404 <span><?php _e( 'Display [new] indicator', 'wpforo' ); ?> : </span>
405
406 <label for="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_1"><?php _e( 'Yes', 'wpforo' ); ?></label>
407 <input id="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_1" value="1" <?php checked( $display_new_indicator ); ?> type="radio"
408 name="<?php echo esc_attr( $this->get_field_name( 'display_new_indicator' ) ); ?>">
409
410 <label for="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_0"><?php _e( 'No', 'wpforo' ); ?></label>
411 <input id="<?php echo $this->get_field_id( 'display_new_indicator' ) ?>_0" value="0" <?php checked( $display_new_indicator, false ); ?> type="radio"
412 name="<?php echo esc_attr( $this->get_field_name( 'display_new_indicator' ) ); ?>">
413 </p>
414 <p>
415 <label for="<?php echo $this->get_field_id( 'refresh_interval' ) ?>"><?php _e( 'Auto Refresh Interval Seconds', 'wpforo' ); ?></label>&nbsp;
416 <input id="<?php echo $this->get_field_id( 'refresh_interval' ) ?>" type="number" min="0" style="display: inline-block; width: 53px;"
417 name="<?php echo esc_attr( $this->get_field_name( 'refresh_interval' ) ); ?>" value="<?php echo esc_attr( $refresh_interval ); ?>">
418 <span style="color: #ccc"><?php _e( 'Set 0 to disable autorefresh', 'wpforo' ) ?></span>
419 </p>
420 </div>
421 <?php
422 }
423
424 public function update( $new_instance, $old_instance ) {
425 $new_instance = wpforo_parse_args( $new_instance, $this->default_instance );
426 $instance = [];
427 $instance['title'] = strip_tags( (string) $new_instance['title'] );
428 $instance['boardid'] = (int) $new_instance['boardid'];
429 $instance['forumids_filter'] = (bool) (int) $new_instance['forumids_filter'];
430 $instance['forumids'] = array_unique( array_filter( array_map( 'intval', (array) $new_instance['forumids'] ) ) );
431 $instance['orderby'] = ( ! empty( $new_instance['orderby'] ) && key_exists(
432 $new_instance['orderby'],
433 $this->orderby_fields
434 ) ) ? $new_instance['orderby'] : $this->default_instance['orderby'];
435 $instance['order'] = ( ! empty( $new_instance['order'] ) && key_exists(
436 $new_instance['order'],
437 $this->order_fields
438 ) ) ? $new_instance['order'] : $this->default_instance['order'];
439 $instance['count'] = (int) $new_instance['count'];
440 $instance['display_avatar'] = (bool) (int) $new_instance['display_avatar'];
441 $instance['current_forumid_filter'] = (bool) (int) $new_instance['current_forumid_filter'];
442 $instance['limit_per_topic'] = (int) $new_instance['limit_per_topic'];
443 $instance['exclude_firstposts'] = (bool) (int) $new_instance['exclude_firstposts'];
444 $instance['display_only_unread'] = (bool) (int) $new_instance['display_only_unread'];
445 $instance['display_new_indicator'] = (bool) (int) $new_instance['display_new_indicator'];
446 $instance['refresh_interval'] = (int) $new_instance['refresh_interval'];
447 $instance['excerpt_length'] = (int) $new_instance['excerpt_length'];
448
449 return $instance;
450 }
451
452 public function get_forum_tree() {
453 ob_start();
454 WPF()->forum->tree( 'select_box', false, [] );
455 wp_send_json_success( [ 'html' => ob_get_clean() ] );
456 }
457 }
458