PluginProbe
wpForo Forum / 3.1.6
wpForo Forum v3.1.6
3.1.6 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 All 138 releases
← All changes | includes/hooks.php +199 -140 3.1.13.1.6 View file →
@@ -16,9 +16,9 @@
16 16 'Boards',
17 17 'wpforo'
18 18 ) . '</a>';
19 19 array_unshift( $links, $settings_link );
20 -
20 +
21 21 return $links;
22 22 } );
23 23
24 24 function wpforo_notice_show() {
@@ -36,9 +36,9 @@
36 36 (array) WPF()->current_user_groupids,
37 37 (array) wpforo_setting( 'general', 'admin_bar' )
38 38 );
39 39 }
40 -
40 +
41 41 return $show_admin_bar;
42 42 } );
43 43
44 44 add_action( 'admin_notices', function() {
@@ -76,15 +76,15 @@
76 76 } );
77 77
78 78 add_filter( 'comments_open', function( $open ) {
79 79 if( is_wpforo_page() ) $open = false;
80 -
80 +
81 81 return $open;
82 82 } );
83 83
84 84 add_filter( 'comments_array', function( $comments ) {
85 85 if( is_wpforo_page() ) $comments = [];
86 -
86 +
87 87 return $comments;
88 88 }, 10, 2 );
89 89
90 90 add_action( 'wpforo_actions_end', function() {
@@ -106,24 +106,24 @@
106 106 'is_404' => false,
107 107 'is_page' => true,
108 108 'is_singular' => true,
109 109 ];
110 -
110 +
111 111 $target_post = get_post( $pageid );
112 112 if( ! is_a( $target_post, 'WP_Post' ) ) {
113 113 return;
114 114 }
115 -
115 +
116 116 $post = $target_post;
117 -
117 +
118 118 $wp_query->posts = [ $post ];
119 119 $wp_query->queried_object_id = $post->ID;
120 120 $wp_query->queried_object = $post;
121 -
121 +
122 122 foreach( $args as $key => $value ) {
123 123 $wp_query->$key = $value;
124 124 }
125 -
125 +
126 126 setup_postdata( $post );
127 127 }
128 128 }
129 129 } );
@@ -129,9 +129,9 @@
129 129 } );
130 130
131 131 add_filter( 'author_link', function( $link, $author_id ) {
132 132 if( wpforo_setting( 'profiles', 'profile' ) === 'wpforo' ) return WPF()->member->get_profile_url( $author_id );
133 -
133 +
134 134 return $link;
135 135 }, 10, 2 );
136 136
137 137 add_filter( 'get_comment_author_url', function( $link, $ID = 0, $object = null ) {
@@ -142,15 +142,15 @@
142 142 return WPF()->member->get_profile_url(
143 143 $object->user_id
144 144 );
145 145 }
146 -
146 +
147 147 return $link;
148 148 }, 10, 3 );
149 149
150 150 add_filter( 'register_url', function( $register_url ) {
151 151 if( wpforo_setting( 'authorization', 'use_our_register_url' ) ) $register_url = wpforo_register_url();
152 -
152 +
153 153 return $register_url;
154 154 } );
155 155
156 156 add_filter( 'login_url', function( $login_url ) {
@@ -162,15 +162,15 @@
162 162 'wp_auth_check_html, wp_login_url,'
163 163 ) === false ) {
164 164 $login_url = wpforo_login_url();
165 165 }
166 -
166 +
167 167 return $login_url;
168 168 } );
169 169
170 170 add_filter( 'logout_url', function( $logout_url ) {
171 171 if( wpforo_setting( 'authorization', 'use_our_login_url' ) ) $logout_url = wpforo_logout_url();
172 -
172 +
173 173 return $logout_url;
174 174 } );
175 175
176 176 add_filter( 'pre_trash_post', function( $check, $post ) {
@@ -177,9 +177,9 @@
177 177 if( in_array( $post->ID, WPF()->board->get_boards_pageids(), true ) ) {
178 178 $check = false;
179 179 WPF()->notice->add( 'DO NOT DELETE WPFORO PAGE!!!', 'error' );
180 180 }
181 -
181 +
182 182 return $check;
183 183 }, 10, 2 );
184 184
185 185 add_filter( 'wp_dropdown_pages', function( $output, $r ) {
@@ -192,9 +192,9 @@
192 192 $pageids
193 193 ) . ')[\'"][^<>]*?>[^<>]*?</option>#isu';
194 194 $output = preg_replace( $pattern, '', (string) $output );
195 195 }
196 -
196 +
197 197 return $output;
198 198 }, 10, 2 );
199 199
200 200 add_filter( 'pre_update_option', function( $value, $option, $old_value ) {
@@ -222,9 +222,9 @@
222 222 }
223 223 $value = ( $page_id && ! is_wp_error( $page_id ) ? $page_id : $old_value );
224 224 }
225 225 }
226 -
226 +
227 227 return $value;
228 228 }, 10, 3 );
229 229
230 230 function wpftpl_url( $filename ) {
@@ -234,9 +234,9 @@
234 234 $tpl_url = get_template_directory_uri() . '/wpforo/' . $filename;
235 235 }
236 236 if( ! $tpl_url ) $tpl_url = WPF()->tpl->template_url . '/' . $filename;
237 237 }
238 -
238 +
239 239 return apply_filters( 'wpforo_wpftpl_url', $tpl_url, $filename );
240 240 }
241 241
242 242 function wpftpl( $filename ) {
@@ -244,9 +244,9 @@
244 244 if( $filename ) {
245 245 $tpl = locate_template( 'wpforo/' . $filename );
246 246 if( ! $tpl ) $tpl = WPF()->tpl->template_dir . '/' . $filename;
247 247 }
248 -
248 +
249 249 return apply_filters( 'wpforo_wpftpl', $tpl, $filename );
250 250 }
251 251
252 252 add_shortcode( 'wpforo', function( $atts ) {
@@ -260,9 +260,9 @@
260 260 }
261 261 if( apply_filters( 'on_wpforo_load_remove_the_content_all_filters', false ) ) {
262 262 remove_all_filters( 'the_content' );
263 263 }
264 -
264 +
265 265 ob_start();
266 266 if( wpforo_current_user_is( 'admin' ) || ! wpforo_setting( 'board', 'under_construction' ) ) {
267 267 include( wpftpl( 'index.php' ) );
268 268 } else {
@@ -270,15 +270,15 @@
270 270 }
271 271 $output = ob_get_clean();
272 272 $output = trim( (string) $output );
273 273 if( ! $output ) $output = wpforo_hook_usage( 'the_content' );
274 -
274 +
275 275 return $output;
276 276 } );
277 277
278 278 function wpforo_hook_usage( $hook = '' ) {
279 279 global $wp_filter;
280 -
280 +
281 281 $output = '<div style="color: #990000; font-size: 16px;">Notice: a plugin conflict has been detected. wpForo forums are affected by other plugin errors.
282 282 Please deactivate all plugins, delete all caches and test again.
283 283 Then activate all plugins back one by one and find the conflict maker plugin.</div>
284 284 <pre style="display: none;">' . ( empty( $hook ) || ! isset( $wp_filter[ $hook ] ) ? 'No hook usage' : print_r(
@@ -284,9 +284,9 @@
284 284 <pre style="display: none;">' . ( empty( $hook ) || ! isset( $wp_filter[ $hook ] ) ? 'No hook usage' : print_r(
285 285 $wp_filter[ $hook ],
286 286 true
287 287 ) ) . '</pre>';
288 -
288 +
289 289 return $output;
290 290 }
291 291
292 292 add_action( 'wpforo_actions_end', 'wpforo_set_header_status' );
@@ -292,9 +292,9 @@
292 292 add_action( 'wpforo_actions_end', 'wpforo_set_header_status' );
293 293 function wpforo_set_header_status() {
294 294 if( is_wpforo_page() ) {
295 295 global $wp_query;
296 -
296 +
297 297 $status = ( WPF()->current_object['is_404'] ? 404 : 200 );
298 298 status_header( $status );
299 299 if( $status === 404 ) nocache_headers();
300 300 $wp_query->is_404 = false;
@@ -302,9 +302,9 @@
302 302 }
303 303
304 304 add_filter( 'pre_handle_404', function( $bypass ) {
305 305 if( is_wpforo_page() ) return true;
306 -
306 +
307 307 return $bypass;
308 308 } );
309 309
310 310 add_action( 'wpforo_actions_end', function() {
@@ -315,9 +315,9 @@
315 315 'index.php'
316 316 ) ) ) {
317 317 return $wpforo_template;
318 318 }
319 -
319 +
320 320 return $template;
321 321 } );
322 322 }
323 323 } );
@@ -329,9 +329,9 @@
329 329 '|',
330 330 pll_languages_list()
331 331 ) . ')/)?';
332 332 }
333 -
333 +
334 334 if( ! WPF()->board->get_current( 'is_standalone' ) ) {
335 335 $pageid = 0;
336 336 $boards = WPF()->board->get_boards( [ 'status' => true ] );
337 337 foreach( $boards as $board ) {
@@ -342,9 +342,9 @@
342 342 $pattern = $rewrite_prefix . preg_quote( $route ) . '(?:/|$).*$';
343 343 $to_url = 'index.php?lang=$matches[1]&page_id=' . $board['pageid'];
344 344 if( ! array_key_exists( $pattern, $rules ) ) $rules = array_merge( [ $pattern => $to_url ], $rules );
345 345 }
346 -
346 +
347 347 if( ! $pageid ) $pageid = wpforo_get_option( 'wpforo_pageid', 0 );
348 348 foreach( WPF()->board->routes as $route ) {
349 349 // $route = utf8_uri_encode( urldecode( (string) $route ) );
350 350 $route = urldecode( (string) $route );
@@ -354,9 +354,9 @@
354 354 $to_url = 'index.php?lang=$matches[1]&page_id=' . $pageid;
355 355 if( ! array_key_exists( $pattern, $rules ) ) $rules = array_merge( [ $pattern => $to_url ], $rules );
356 356 }
357 357 }
358 -
358 +
359 359 return $rules;
360 360 } );
361 361
362 362 add_action( 'wpforo_actions_end', function() {
@@ -369,9 +369,9 @@
369 369
370 370 function wpforo_include_once_theme_functions() {
371 371 $path = wpftpl( 'functions.php' );
372 372 if( file_exists( $path ) ) include_once( $path );
373 -
373 +
374 374 $path = wpftpl( 'functions-wp.php' );
375 375 if( file_exists( $path ) ) include_once( $path );
376 376 }
377 377
@@ -378,11 +378,11 @@
378 378 add_action( 'wpforo_after_init', 'wpforo_include_once_theme_functions' );
379 379
380 380 function wpforo_meta_title( $title ) {
381 381 $meta_title = [];
382 -
382 +
383 383 if( ! wpforo_setting( 'seo', 'seo_title' ) ) return $title;
384 -
384 +
385 385 if( is_wpforo_page() ) {
386 386 $template = WPF()->current_object['template'];
387 387 if( ! WPF()->current_object['is_404'] ) {
388 388 $paged = ( WPF()->current_object['paged'] > 1 ) ? wpforo_phrase( 'page', false ) . ' ' . WPF()->current_object['paged'] . ' ' : '';
@@ -529,9 +529,9 @@
529 529 $meta_title = wpforo_meta_title( $title );
530 530 if( is_array( $meta_title ) && ! empty( $meta_title ) ) {
531 531 $title = implode( ' &#8211; ', $meta_title );
532 532 }
533 -
533 +
534 534 return $title;
535 535 }
536 536
537 537 add_filter( 'wp_title', 'wpforo_meta_wp_title', 100 );
@@ -539,9 +539,9 @@
539 539 function wpforo_add_meta_tags() {
540 540 if( ! wpforo_setting( 'seo', 'seo_meta' ) ) {
541 541 return;
542 542 }
543 -
543 +
544 544 if( is_wpforo_page() && ! is_wpforo_shortcode_page() ) {
545 545 $title = '';
546 546 $og_img = '';
547 547 $tw_img = '';
@@ -791,22 +791,22 @@
791 791 if( ! is_user_logged_in() ) {
792 792 WPF()->notice->add( wpforo_get_login_or_register_notice_text() );
793 793 wp_send_json_error( WPF()->notice->get_notices() );
794 794 }
795 -
795 +
796 796 if( ! isset( $_POST['reportmsg'] ) || ! $_POST['reportmsg'] || ! isset( $_POST['postid'] ) || ! $_POST['postid'] ) {
797 797 WPF()->notice->add( 'Error: please insert some text to report.', 'error' );
798 798 wp_send_json_error( WPF()->notice->get_notices() );
799 799 }
800 -
800 +
801 801 $postid = intval( $_POST['postid'] );
802 802 $forumid = wpforo_post( $postid, 'forumid' );
803 -
803 +
804 804 if( ! WPF()->perm->can_report( $forumid ) ) {
805 805 WPF()->notice->add( 'You are not allowed to report.', 'error' );
806 806 wp_send_json_error( WPF()->notice->get_notices() );
807 807 }
808 -
808 +
809 809 ############### Sending Email ##################
810 810 $report_text = substr( strip_tags( (string) $_POST['reportmsg'] ), 0, 1000 );
811 811 $reporter = '<a href="' . WPF()->current_user['profile_url'] . '">' . ( WPF()->current_user['display_name'] ? WPF()->current_user['display_name'] : urldecode(
812 812 (string) WPF()->current_user['user_nicename']
@@ -812,12 +812,12 @@
812 812 (string) WPF()->current_user['user_nicename']
813 813 ) ) . '</a>';
814 814 $reportmsg = wpforo_kses( $report_text, 'email' );
815 815 $post_url = WPF()->post->get_url( $postid );
816 -
816 +
817 817 $subject = wpforo_setting( 'email', 'report_email_subject' );
818 818 $message = wpforo_setting( 'email', 'report_email_message' );
819 -
819 +
820 820 $from_tags = [ "[reporter]", "[message]", "[post_url]" ];
821 821 $to_words = [
822 822 sanitize_text_field( $reporter ),
823 823 $reportmsg,
@@ -822,16 +822,16 @@
822 822 sanitize_text_field( $reporter ),
823 823 $reportmsg,
824 824 '<a target="_blank" href="' . esc_url( (string) $post_url ) . '">' . esc_url( (string) $post_url ) . '</a>',
825 825 ];
826 -
826 +
827 827 $subject = stripslashes( strip_tags( str_replace( $from_tags, $to_words, (string) $subject ) ) );
828 828 $message = stripslashes( str_replace( $from_tags, $to_words, (string) $message ) );
829 -
829 +
830 830 $admin_emails = wpforo_setting( 'email', 'admin_emails' );
831 831 $admin_email = wpfval( $admin_emails, 0 );
832 832 $headers = wpforo_admin_mail_headers();
833 -
833 +
834 834 add_filter( 'wp_mail_content_type', 'wpforo_set_html_content_type', 999 );
835 835 if( ! @wp_mail( $admin_email, $subject, $message, $headers ) ) {
836 836 WPF()->notice->add( 'Can\'t send report email', 'error' );
837 837 wp_send_json_error( WPF()->notice->get_notices() );
@@ -836,9 +836,9 @@
836 836 WPF()->notice->add( 'Can\'t send report email', 'error' );
837 837 wp_send_json_error( WPF()->notice->get_notices() );
838 838 }
839 839 remove_filter( 'wp_mail_content_type', 'wpforo_set_html_content_type' );
840 -
840 +
841 841 ############### Sending Email end ##############
842 842 do_action( 'wpforo_after_post_report', $postid, $forumid, $_POST['reportmsg'] );
843 843 WPF()->notice->add( 'Message has been sent', 'success' );
844 844 wp_send_json_success( WPF()->notice->get_notices() );
@@ -852,9 +852,9 @@
852 852 $response = [ 'notice' => WPF()->notice->get_notices() ];
853 853 if( ! $topicid = wpforo_bigintval( wpfval( $_POST, 'topicid' ) ) ) {
854 854 wp_send_json_error( $response );
855 855 }
856 -
856 +
857 857 $sql = "SELECT `forumid` FROM `" . WPF()->tables->topics . "` WHERE `topicid` = $topicid";
858 858 $forumid = WPF()->db->get_var( $sql );
859 859 if( ! WPF()->perm->forum_can( 's', $forumid ) ) {
860 860 WPF()->notice->add( 'You don\'t have permission to do this action from this forum', 'error' );
@@ -1005,8 +1005,14 @@
1005 1005 wpforo_verify_nonce( 'wpforo_post_edit' );
1006 1006 $r = [ 'html' => '' ];
1007 1007 if( $postid = wpforo_bigintval( wpfval( $_POST, 'postid' ) ) ) {
1008 1008 if( $post = WPF()->post->get_post( $postid, false ) ) {
1009 + // forum_can() is a usergroup-level check and takes no post id, so for
1010 + // guests it cannot prove ownership of THIS post. Without this gate the
1011 + // edit form (post body + a valid form nonce) is handed to any visitor.
1012 + if( ! is_user_logged_in() && ! wpforo_guest_owns_post( $postid ) ) {
1013 + wp_send_json_error( $r );
1014 + }
1009 1015 if( WPF()->perm->forum_can( 'eor', $post['forumid'] ) || WPF()->perm->forum_can(
1010 1016 'eot',
1011 1017 $post['forumid']
1012 1018 ) ) {
@@ -1063,9 +1069,9 @@
1063 1069 $resp['notice'] = WPF()->notice->get_notices();
1064 1070 wp_send_json_success( $resp );
1065 1071 }
1066 1072 }
1067 -
1073 +
1068 1074 $resp['notice'] = WPF()->notice->get_notices();
1069 1075 wp_send_json_error( $resp );
1070 1076 }
1071 1077
@@ -1081,9 +1087,9 @@
1081 1087 'filter' => 'newest',
1082 1088 'paged' => 1,
1083 1089 ];
1084 1090 $request = array_merge( $request, $_POST );
1085 -
1091 +
1086 1092 if( $forumid = intval( $request['forumid'] ) ) {
1087 1093 $items_count = 0;
1088 1094 $childs = WPF()->forum->get_childs( $forumid );
1089 1095 $childs[] = $forumid;
@@ -1093,9 +1099,9 @@
1093 1099 'forumids' => $childs,
1094 1100 'orderby' => 'type, modified',
1095 1101 'order' => 'DESC',
1096 1102 ];
1097 -
1103 +
1098 1104 switch( $request['filter'] ) {
1099 1105 case 'solved':
1100 1106 $args['solved'] = 1;
1101 1107 $args['type'] = 0;
@@ -1108,9 +1114,9 @@
1108 1114 case 'hottest':
1109 1115 $args['orderby'] = 'posts';
1110 1116 break;
1111 1117 }
1112 -
1118 +
1113 1119 $topics = WPF()->topic->get_topics( $args, $items_count );
1114 1120 if( $topics ) {
1115 1121 ob_start();
1116 1122 if( function_exists( 'wpforo_thread_forum_template' ) ) {
@@ -1126,15 +1132,15 @@
1126 1132 }
1127 1133 } else {
1128 1134 $response['no_more'] = 1;
1129 1135 }
1130 -
1136 +
1131 1137 if( $response['no_more'] ) {
1132 1138 WPF()->notice->add( 'all topics has been loaded in this list', 'success' );
1133 1139 $response['notice'] = WPF()->notice->get_notices();
1134 1140 }
1135 1141 }
1136 -
1142 +
1137 1143 if( $success ) {
1138 1144 wp_send_json_success( $response );
1139 1145 } else {
1140 1146 wp_send_json_error( $response );
@@ -1338,13 +1344,13 @@
1338 1344 if( $comments = WPF()->post->get_posts( $args ) ) {
1339 1345 ob_start();
1340 1346 include_once( wpftpl( 'layouts/3/comment.php' ) );
1341 1347 ob_clean();
1342 -
1348 +
1343 1349 foreach( $comments as $comment ) {
1344 1350 wpforo_qa_comment_template( $comment );
1345 1351 }
1346 -
1352 +
1347 1353 $response['output_html'] = ob_get_clean();
1348 1354 $response['notice'] = '';
1349 1355 wp_send_json_success( $response );
1350 1356 }
@@ -1421,9 +1427,9 @@
1421 1427 $b = sanitize_email( $b );
1422 1428 $H[] = 'BCC: ' . $b;
1423 1429 }
1424 1430 }
1425 -
1431 +
1426 1432 return $H;
1427 1433 }
1428 1434
1429 1435 function wpforo_admin_mail_headers( $from_name = '', $from_email = '', $cc = [], $bcc = [] ) {
@@ -1447,9 +1453,9 @@
1447 1453 $b = sanitize_email( $b );
1448 1454 $H[] = 'BCC: ' . $b;
1449 1455 }
1450 1456 }
1451 -
1457 +
1452 1458 return $H;
1453 1459 }
1454 1460
1455 1461 function wpforo_get_login_or_register_notice_text() {
@@ -1466,9 +1472,9 @@
1466 1472 false
1467 1473 ) . '</a>'
1468 1474 );
1469 1475 }
1470 -
1476 +
1471 1477 return apply_filters( 'wpforo_login_or_register_popup_message', $popup_html );
1472 1478 }
1473 1479
1474 1480 function wpforo_dynamic_phrases_register() {
@@ -1475,9 +1481,9 @@
1475 1481 if( ! $js = WPF()->phrase->get_wpforo_phrases_inline_js() ) {
1476 1482 return;
1477 1483 }
1478 1484 $md5_js = md5( $js );
1479 -
1485 +
1480 1486 $inline = false;
1481 1487 $dynamic_js_file = WPF()->folders['assets']['dir'] . DIRECTORY_SEPARATOR . 'phrases.js';
1482 1488 if( ! file_exists( $dynamic_js_file ) || $md5_js !== md5_file( $dynamic_js_file ) ) {
1483 1489 $result = wpforo_write_file( $dynamic_js_file, $js );
@@ -1484,9 +1490,9 @@
1484 1490 if( wpfval( $result, 'error' ) ) {
1485 1491 $inline = true;
1486 1492 }
1487 1493 }
1488 -
1494 +
1489 1495 wp_register_script(
1490 1496 'wpforo-dynamic-phrases',
1491 1497 WPF()->folders['assets']['url'] . '/phrases.js',
1492 1498 false,
@@ -1502,9 +1508,9 @@
1502 1508 if( ! $css = WPF()->tpl->generate_dynamic_css() ) {
1503 1509 return;
1504 1510 }
1505 1511 $md5_css = md5( $css );
1506 -
1512 +
1507 1513 $inline = false;
1508 1514 $dynamic_css_file = WPF()->folders['assets']['dir'] . DIRECTORY_SEPARATOR . 'colors.css';
1509 1515 if( ! file_exists( $dynamic_css_file ) || $md5_css !== md5_file( $dynamic_css_file ) ) {
1510 1516 $result = wpforo_write_file( $dynamic_css_file, $css );
@@ -1511,9 +1517,9 @@
1511 1517 if( wpfval( $result, 'error' ) ) {
1512 1518 $inline = true;
1513 1519 }
1514 1520 }
1515 -
1521 +
1516 1522 wp_register_style(
1517 1523 'wpforo-dynamic-style',
1518 1524 WPF()->folders['assets']['url'] . '/colors.css',
1519 1525 false,
@@ -1522,9 +1528,9 @@
1522 1528 if( $inline ) {
1523 1529 $css = preg_replace( '|[\r\n\t]+|', '', $css );
1524 1530 wp_add_inline_style( 'wpforo-dynamic-style', $css );
1525 1531 }
1526 -
1532 +
1527 1533 wp_enqueue_style( 'wpforo-dynamic-style' );
1528 1534 }
1529 1535
1530 1536 add_action( 'wp_enqueue_scripts', 'wpforo_dynamic_style_enqueue', 999 );
@@ -1616,9 +1622,9 @@
1616 1622 $wpforo_widgets['live_notifications_start'] = $start;
1617 1623 $wpforo_widgets['live_notifications_interval'] = $interval;
1618 1624 }
1619 1625 wp_localize_script( 'wpforo-widgets-js', 'wpforo_widgets', $wpforo_widgets );
1620 -
1626 +
1621 1627 if( ! WPF()->perm->forum_can( 'va' ) || ! WPF()->usergroup->can( 'caa' ) ) {
1622 1628 wp_add_inline_script(
1623 1629 'wpforo-frontend-js',
1624 1630 "jQuery(document).ready(function($){
@@ -1634,11 +1640,11 @@
1634 1640 });
1635 1641 })"
1636 1642 );
1637 1643 }
1638 -
1644 +
1639 1645 do_action( 'wpforo_frontend_register_scripts' );
1640 -
1646 +
1641 1647 wpforo_frontend_enqueue_scripts();
1642 1648 }
1643 1649
1644 1650 add_action( 'wp_enqueue_scripts', 'wpforo_frontend_register_scripts' );
@@ -1648,9 +1654,9 @@
1648 1654 if( $fontawesome === 'sitewide' || ( $fontawesome === 'forum' && is_wpforo_page() ) ) {
1649 1655 wp_enqueue_style( 'wpforo-font-awesome' );
1650 1656 //if( is_rtl() ) wp_enqueue_style( 'wpforo-font-awesome-rtl' );
1651 1657 }
1652 -
1658 +
1653 1659 if( is_wpforo_page() ) {
1654 1660 wp_enqueue_script( 'wpforo-dynamic-phrases' );
1655 1661 wp_enqueue_script( 'wpforo-frontend-js' );
1656 1662 // Enqueue AI features script if AI service is available and any frontend AI feature is enabled
@@ -1673,15 +1679,15 @@
1673 1679 } else {
1674 1680 wp_enqueue_style( 'wpforo-style' );
1675 1681 }
1676 1682 }
1677 -
1683 +
1678 1684 if( is_rtl() ) {
1679 1685 wp_enqueue_style( 'wpforo-widgets-rtl' );
1680 1686 } else {
1681 1687 wp_enqueue_style( 'wpforo-widgets' );
1682 1688 }
1683 -
1689 +
1684 1690 do_action( 'wpforo_frontend_enqueue_scripts' );
1685 1691 }
1686 1692
1687 1693 function wpforo_style_options( $css ) {
@@ -1699,9 +1705,9 @@
1699 1705 ) . "px!important;}\r\n#wpforo-wrap .wpforo-post .wpf-right .wpforo-post-content p {font-size: " . wpforo_setting(
1700 1706 'styles',
1701 1707 'font_size_post_content'
1702 1708 ) . "px;}";
1703 -
1709 +
1704 1710 if( 'bottom' === wpforo_setting( 'posting', 'topic_editor_toolbar_location' ) ) {
1705 1711 $css .= "\r\n
1706 1712 #wpforo #wpforo-wrap .wpf-topic-create .mce-container-body{display: flex; flex-direction: column;}
1707 1713 #wpforo #wpforo-wrap .wpf-topic-create .mce-top-part{order: 1}
@@ -1826,9 +1832,9 @@
1826 1832 'jquery-ui-draggable',
1827 1833 'jquery-ui-slider',
1828 1834 'jquery-touch-punch',
1829 1835 ], false, true );
1830 -
1836 +
1831 1837 // Register AI Features admin assets
1832 1838 wp_register_style(
1833 1839 'wpforo-ai-features',
1834 1840 WPFORO_URL . '/admin/assets/css/ai-features.css',
@@ -1903,18 +1909,18 @@
1903 1909 ) !== false ) ) {
1904 1910 wp_enqueue_style( 'wpforo-deactivation-css' );
1905 1911 wp_enqueue_script( 'wpforo-deactivation-js' );
1906 1912 }
1907 -
1913 +
1908 1914 $screen = get_current_screen();
1909 1915 if( ( 'user-edit' === $screen->id || 'profile' === $screen->id ) ) {
1910 1916 wp_enqueue_style( 'wpforo-font-awesome' );
1911 1917 }
1912 -
1918 +
1913 1919 if( $screen->id === 'widgets' ) {
1914 1920 wp_enqueue_script( 'wpforo-backend-widgets-js' );
1915 1921 }
1916 -
1922 +
1917 1923 do_action( 'wpforo_admin_enqueue_scripts' );
1918 1924 }
1919 1925
1920 1926 add_action( 'admin_enqueue_scripts', 'wpforo_admin_enqueue' );
@@ -2211,8 +2217,11 @@
2211 2217 'user_login',
2212 2218 'user_email',
2213 2219 'user_pass1',
2214 2220 'user_pass2',
2221 + 'first_name',
2222 + 'last_name',
2223 + 'user_url',
2215 2224 ] ) );
2216 2225 $data['wpfreg']['userid'] = (int) $userid;
2217 2226
2218 2227 // SECURITY: strip reserved wp_users column names from custom-field
@@ -2263,14 +2272,14 @@
2263 2272 if( wpforo_is_owner( $userid ) ) {
2264 2273 $can_change_own_rating = false;
2265 2274 }
2266 2275 }
2267 -
2276 +
2268 2277 $custom_points = ( $can_change_own_rating && wpfval(
2269 2278 $_POST,
2270 2279 'wpforo_use_member_custom_points'
2271 2280 ) ) ? (int) wpfval( $_POST, 'wpforo_member_custom_points' ) : 0;
2272 -
2281 +
2273 2282 $args = [
2274 2283 'groupid' => intval( $groupid ),
2275 2284 'about' => wpforo_kses( $_POST['description'], 'user_description' ),
2276 2285 'timezone' => ( isset( $_POST['wpforo_usertimezone'] ) ? sanitize_text_field(
@@ -2279,9 +2288,9 @@
2279 2288 'secondary_groupids' => $secondary_groupids,
2280 2289 'custom_points' => $custom_points,
2281 2290 ];
2282 2291 WPF()->member->update_profile_fields( $userid, $args, false );
2283 -
2292 +
2284 2293 if( ! wpforo_is_owner( $userid ) ) {
2285 2294 WPF()->member->inactive_to_active( $userid );
2286 2295 }
2287 2296 }
@@ -2311,9 +2320,9 @@
2311 2320 }
2312 2321 } else {
2313 2322 $user = get_user_by( 'email', $id_or_email );
2314 2323 }
2315 -
2324 +
2316 2325 if( $user && is_object( $user ) ) {
2317 2326 if( $src = WPF()->member->get_avatar_url( $user->data->ID ) ) {
2318 2327 $avatar = "<img alt='" . esc_attr( $alt ) . "' src='" . esc_url(
2319 2328 (string) $src
@@ -2321,9 +2330,9 @@
2321 2330 $size
2322 2331 ) . "' width='" . esc_attr( $size ) . "' />";
2323 2332 }
2324 2333 }
2325 -
2334 +
2326 2335 return $avatar;
2327 2336 }
2328 2337
2329 2338 add_filter( 'get_avatar', 'wpforo_avatar', 10, 5 );
@@ -2360,9 +2369,9 @@
2360 2369 $user = get_user_by( 'email', $id_or_email->comment_author_email );
2361 2370 }
2362 2371 }
2363 2372 }
2364 -
2373 +
2365 2374 if( $user && is_object( $user ) ) {
2366 2375 if( $avatar_url = WPF()->member->get_avatar_url( $user->data->ID ) ) {
2367 2376 WPF()->ram_cache->set( $key, $avatar_url );
2368 2377 $args['url'] = $avatar_url;
@@ -2369,9 +2378,9 @@
2369 2378 }
2370 2379 }
2371 2380 }
2372 2381 }
2373 -
2382 +
2374 2383 return $args;
2375 2384 }
2376 2385
2377 2386 add_filter( 'pre_get_avatar_data', 'wpforo_pre_get_avatar_data', 10, 2 );
@@ -2382,9 +2391,9 @@
2382 2391 $type = sanitize_mime_type( $_FILES[ $argname ]['type'] ); //image/png
2383 2392 $tmp_name = sanitize_text_field( $_FILES[ $argname ]['tmp_name'] ); //D:\wamp\tmp\php986B.tmp
2384 2393 $error = intval( $_FILES[ $argname ]['error'] ); //0
2385 2394 $size = intval( $_FILES[ $argname ]['size'] ); //6112
2386 -
2395 +
2387 2396 $phpFileUploadErrors = [
2388 2397 0 => 'There is no error, the file uploaded with success',
2389 2398 1 => 'The uploaded file size is too big',
2390 2399 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
@@ -2393,19 +2402,19 @@
2393 2402 6 => 'Missing a temporary folder',
2394 2403 7 => 'Failed to write file to disk.',
2395 2404 8 => 'A PHP extension stopped the file upload.',
2396 2405 ];
2397 -
2406 +
2398 2407 if( $error ) {
2399 2408 WPF()->notice->add( $phpFileUploadErrors[ $error ], 'error' );
2400 -
2409 +
2401 2410 return '';
2402 2411 } elseif( $size > wpforo_setting( 'posting', 'max_upload_size' ) ) {
2403 2412 WPF()->notice->add( 'The uploaded file size is too big', 'error' );
2404 -
2413 +
2405 2414 return '';
2406 2415 }
2407 -
2416 +
2408 2417 if( function_exists( 'pathinfo' ) ) {
2409 2418 $ext = pathinfo( $name, PATHINFO_EXTENSION );
2410 2419 } else {
2411 2420 $ext = substr( strrchr( (string) $name, '.' ), 1 );
@@ -2417,22 +2426,22 @@
2417 2426 $allowed_types = implode( '|', $mime_types );
2418 2427 $expld = explode( '|', $allowed_types );
2419 2428 if( ! in_array( $ext, $expld ) ) {
2420 2429 WPF()->notice->add( 'File type is not allowed', 'error' );
2421 -
2430 +
2422 2431 return '';
2423 2432 }
2424 2433 if( ! WPF()->perm->can_attach_file_type( $ext ) ) {
2425 2434 WPF()->notice->add( 'You are not allowed to attach this file type', 'error' );
2426 -
2435 +
2427 2436 return '';
2428 2437 }
2429 2438 }
2430 -
2439 +
2431 2440 $attach_dir = WPF()->folders['default_attachments']['dir'];
2432 2441 $attach_url = WPF()->folders['default_attachments']['url//'];
2433 2442 if( ! is_dir( $attach_dir ) ) wp_mkdir_p( $attach_dir );
2434 -
2443 +
2435 2444 $fnm = pathinfo( $name, PATHINFO_FILENAME );
2436 2445 $fnm = str_replace( ' ', '-', $fnm );
2437 2446 while( strpos( (string) $fnm, '--' ) !== false ) {
2438 2447 $fnm = str_replace( '--', '-', $fnm );
@@ -2439,14 +2448,14 @@
2439 2448 }
2440 2449 $fnm = preg_replace( "/[^-a-zA-Z0-9_]/", "", (string) $fnm );
2441 2450 $fnm = trim( (string) $fnm, "-" );
2442 2451 $fnm_empty = ! $fnm;
2443 -
2452 +
2444 2453 $file_name = $fnm . "." . $ext;
2445 -
2454 +
2446 2455 $attach_fname = time() . ( ! $fnm_empty ? '-' : '' ) . $file_name;
2447 2456 $attach_path = $attach_dir . DIRECTORY_SEPARATOR . $attach_fname;
2448 -
2457 +
2449 2458 if( is_dir( $attach_dir ) && move_uploaded_file( $tmp_name, $attach_path ) ) {
2450 2459 $attach_id = wpforo_insert_to_media_library( $attach_path, $fnm );
2451 2460 if( $return === 'html' ) {
2452 2461 return "\r\n" . '<div id="wpfa-' . $attach_id . '" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="' . esc_url(
@@ -2466,9 +2475,9 @@
2466 2475 } else {
2467 2476 WPF()->notice->add( 'Can\'t upload file', 'error' );
2468 2477 }
2469 2478 }
2470 -
2479 +
2471 2480 return '';
2472 2481 }
2473 2482
2474 2483 function wpforo_add_default_attachment( $args ) {
@@ -2479,9 +2488,9 @@
2479 2488 $args['has_attach'] = 1;
2480 2489 }
2481 2490 }
2482 2491 }
2483 -
2492 +
2484 2493 return $args;
2485 2494 }
2486 2495
2487 2496 function wpforo_delete_attachment( $attach_post_id ) {
@@ -2537,9 +2546,9 @@
2537 2546 $text = str_replace( $match[0], $attach_html, $text );
2538 2547 }
2539 2548 }
2540 2549 }
2541 -
2550 +
2542 2551 return $text;
2543 2552 }
2544 2553
2545 2554 function wpforo_content_enable_do_shortcode() {
@@ -2561,9 +2570,9 @@
2561 2570 '<span style="color: red; font-weight: bold;">$1</span>',
2562 2571 (string) $text
2563 2572 );
2564 2573 }
2565 -
2574 +
2566 2575 return $text;
2567 2576 } );
2568 2577
2569 2578 add_action( 'wp_footer', function() { WPF()->cache->create(); } );
@@ -2577,9 +2586,9 @@
2577 2586 } else {
2578 2587 $reset_password_url = $match[0];
2579 2588 }
2580 2589 }
2581 -
2590 +
2582 2591 if( wpforo_setting( 'email', 'overwrite_reset_password_email' ) && $reset_password_url ) {
2583 2592 $message = str_replace(
2584 2593 [ '[user_login]', '[reset_password_url]' ],
2585 2594 [ $user_login, $reset_password_url, ],
@@ -2587,15 +2596,15 @@
2587 2596 );
2588 2597 $message = _wpforo_apply_email_shortcodes( $message, [ 'user' => [ 'userid' => $user_data->ID ] ] );
2589 2598 add_filter( 'wp_mail_content_type', '__wpforo_set_html_content_type', 999 );
2590 2599 }
2591 -
2600 +
2592 2601 return $message;
2593 2602 }, 999, 4 );
2594 2603
2595 2604 function wpforo_user_field_shortcode_to_value( $shortcode, $userid = null, $implode = true, $separator = ',' ) {
2596 2605 $value = null;
2597 -
2606 +
2598 2607 if( $shortcode && ( $field = preg_replace(
2599 2608 '#^\s*\[?\s*(?:user_|owner_)?(?:fields_)?([^\[\]]+?)\s*]?\s*$#iu',
2600 2609 '$1',
2601 2610 (string) $shortcode
@@ -2610,15 +2619,15 @@
2610 2619 }
2611 2620 $value = wpforo_member( $userid, $field );
2612 2621 if( $implode && wpforo_is_array_of_scalars( $value ) ) $value = implode( $separator, $value );
2613 2622 }
2614 -
2623 +
2615 2624 return $value;
2616 2625 }
2617 2626
2618 2627 function wpforo_forum_field_shortcode_to_value( $shortcode, $forumid, $implode = true, $separator = ',' ) {
2619 2628 $value = null;
2620 -
2629 +
2621 2630 if( $forumid ) {
2622 2631 if( $shortcode && ( $field = preg_replace(
2623 2632 '#^\s*\[?\s*(?:forum_)?(?:fields_)?([^\[\]]+?)\s*]?\s*$#iu',
2624 2633 '$1',
@@ -2636,15 +2645,15 @@
2636 2645 if( $implode && wpforo_is_array_of_scalars( $value ) ) $value = implode( $separator, $value );
2637 2646 }
2638 2647 }
2639 2648 }
2640 -
2649 +
2641 2650 return $value;
2642 2651 }
2643 2652
2644 2653 function wpforo_topic_field_shortcode_to_value( $shortcode, $topicid, $implode = true, $separator = ',' ) {
2645 2654 $value = null;
2646 -
2655 +
2647 2656 if( $topicid ) {
2648 2657 if( $shortcode && ( $field = preg_replace(
2649 2658 '#^\s*\[?\s*(?:topic_)?(?:fields_)?([^\[\]]+?)\s*]?\s*$#iu',
2650 2659 '$1',
@@ -2662,15 +2671,15 @@
2662 2671 if( $implode && wpforo_is_array_of_scalars( $value ) ) $value = implode( $separator, $value );
2663 2672 }
2664 2673 }
2665 2674 }
2666 -
2675 +
2667 2676 return $value;
2668 2677 }
2669 2678
2670 2679 function wpforo_post_field_shortcode_to_value( $shortcode, $postid, $implode = true, $separator = ',' ) {
2671 2680 $value = null;
2672 -
2681 +
2673 2682 if( $postid ) {
2674 2683 if( $shortcode && ( $field = preg_replace(
2675 2684 '#^\s*\[?\s*(?:post_)?(?:fields_)?([^\[\]]+?)\s*]?\s*$#iu',
2676 2685 '$1',
@@ -2688,9 +2697,9 @@
2688 2697 if( $implode && wpforo_is_array_of_scalars( $value ) ) $value = implode( $separator, $value );
2689 2698 }
2690 2699 }
2691 2700 }
2692 -
2701 +
2693 2702 return $value;
2694 2703 }
2695 2704
2696 2705 function wpforo_new_user_notification_email_admin( $wp_new_user_notification_email_admin, $user, $blogname ) {
@@ -2718,14 +2727,14 @@
2718 2727 '#\[[^\[\]]+?]#isu',
2719 2728 function( $match ) use ( $userid ) {
2720 2729 $value = wpforo_user_field_shortcode_to_value( $match[0], $userid );
2721 2730 if( ! $value || ! ( is_string( $value ) || is_numeric( $value ) ) ) $value = '';
2722 -
2731 +
2723 2732 return $value;
2724 2733 },
2725 2734 (string) $wp_new_user_notification_email_admin['message']
2726 2735 );
2727 -
2736 +
2728 2737 return $wp_new_user_notification_email_admin;
2729 2738 }
2730 2739
2731 2740 add_filter( 'wp_new_user_notification_email_admin', 'wpforo_new_user_notification_email_admin', 999, 3 );
@@ -2743,9 +2752,9 @@
2743 2752 } else {
2744 2753 $set_password_url = $match[0];
2745 2754 }
2746 2755 }
2747 -
2756 +
2748 2757 if( wpforo_setting( 'email', 'overwrite_new_user_notification' ) && $set_password_url ) {
2749 2758 $wp_new_user_notification_email['subject'] = str_replace(
2750 2759 '[blogname]',
2751 2760 '[' . $blogname . ']',
@@ -2760,9 +2769,9 @@
2760 2769 wpforo_setting( 'email', 'wp_new_user_notification_email_message' )
2761 2770 );
2762 2771 add_filter( 'wp_mail_content_type', '__wpforo_set_html_content_type', 999 );
2763 2772 }
2764 -
2773 +
2765 2774 return $wp_new_user_notification_email;
2766 2775 }
2767 2776
2768 2777 add_filter( 'wp_new_user_notification_email', 'wpforo_new_user_notification_email', 999, 3 );
@@ -2771,18 +2780,18 @@
2771 2780 return '#(?:<\s*)?https?://\S+?wp-login\.php(?:[?&]action=rp|[?&]login=[^?&=\s]+)?[?&]key=(?<key>[^?&=\s]+)(?:[?&]action=rp|[?&]login=[^?&=\s]+)?(?:\s*>)?#isu';
2772 2781 }
2773 2782
2774 2783 function wpforo_synch_user_roles( $userid ) {
2775 -
2784 +
2776 2785 $user = get_userdata( $userid );
2777 -
2786 +
2778 2787 if( ! empty( $user ) && ! empty( $user->roles ) ) {
2779 2788 $role_usergroups = WPF()->usergroup->get_role_usergroup_relation();
2780 -
2789 +
2781 2790 if( ! empty( $role_usergroups ) ) {
2782 2791 $append_second_groups = apply_filters( 'wpforo_synch_user_roles_append_secondary_groups', false );
2783 2792 $ug_users_array = WPF()->usergroup->build_users_groupid_array( $role_usergroups, [ $user ] );
2784 -
2793 +
2785 2794 if( wpfval( $ug_users_array, 'user_prime_group' ) ) {
2786 2795 $userid_groupids = current( $ug_users_array['user_prime_group'] );
2787 2796 if( ! empty( $userid_groupids ) ) {
2788 2797 $groupid = current( $userid_groupids );
@@ -2788,9 +2797,9 @@
2788 2797 $groupid = current( $userid_groupids );
2789 2798 if( $groupid ) WPF()->member->set_groupid( $userid, $groupid );
2790 2799 }
2791 2800 }
2792 -
2801 +
2793 2802 if( wpfval( $ug_users_array, 'user_second_groups' ) ) {
2794 2803 foreach( $ug_users_array['user_second_groups'] as $userid => $secondary_usergroups ) {
2795 2804 if( ! empty( $secondary_usergroups ) ) {
2796 2805 if( $append_second_groups ) {
@@ -2804,9 +2813,9 @@
2804 2813 }
2805 2814 } elseif( ! $append_second_groups && ! wpfval( $ug_users_array, 'user_second_groups' ) ) {
2806 2815 WPF()->member->set_secondary_groupids( $userid, [] );
2807 2816 }
2808 -
2817 +
2809 2818 delete_user_meta( intval( $userid ), '_wpf_member_obj' );
2810 2819 }
2811 2820 }
2812 2821 }
@@ -2827,9 +2836,9 @@
2827 2836 'id' => 0,
2828 2837 ];
2829 2838
2830 2839 $wpforo_synch_roles_data = isset( $_POST['wpforo_synch_roles_data'] ) ? $_POST['wpforo_synch_roles_data'] : '';
2831 -
2840 +
2832 2841 if( $wpforo_synch_roles_data ) {
2833 2842 parse_str( $wpforo_synch_roles_data, $data );
2834 2843 check_ajax_referer( 'wpforo_synch_roles', 'checkthis' );
2835 2844 $limit = apply_filters( 'wpforo_synch_roles_step_limit', 20 );
@@ -2919,13 +2928,13 @@
2919 2928 wpforo_delete_option( 'synch_roles' );
2920 2929 }
2921 2930 }
2922 2931 }
2923 -
2932 +
2924 2933 if( intval( wpfval( $status, 'progress' ) ) === 100 ) {
2925 2934 WPF()->notice->add( 'Role-Usergroup synchronization is complete!', 'success' );
2926 2935 }
2927 -
2936 +
2928 2937 wp_die( wp_json_encode( $status ) );
2929 2938 }
2930 2939
2931 2940 add_action( 'wp_ajax_wpforo_synch_roles', 'wpforo_synch_roles' );
@@ -2948,27 +2957,28 @@
2948 2957 '<div class="wp-core-ui wp-ui-notification wpforo-menu-notification-counter">%1$d</div>',
2949 2958 $number
2950 2959 );
2951 2960 }
2952 -
2961 +
2953 2962 return '';
2954 2963 }
2955 2964
2956 2965 function wpforo_get_memb_attention_count(): int {
2966 + if( is_null( WPF()->member ) ) return 0;
2957 2967 return WPF()->member->get_count( [ 'p.status' => [ 'banned', 'inactive' ] ] );
2958 2968 }
2959 2969
2960 2970 function wpforo_get_admin_bar_numbers(): array {
2961 2971 $all_count = 0;
2962 - $mod_count = WPF()->post->unapproved_count();
2972 + $mod_count = is_null( WPF()->post ) ? 0 : WPF()->post->unapproved_count();
2963 2973 $all_count += $mod_count;
2964 -
2974 +
2965 2975 return compact( 'all_count', 'mod_count' );
2966 2976 }
2967 2977
2968 2978 function wpforo_admin_bar_menu( $wp_admin_bar ) {
2969 2979 $admin_bar_numbers = wpforo_get_admin_bar_numbers();
2970 -
2980 +
2971 2981 if( wpforo_current_user_is( 'admin' ) ) {
2972 2982 $args = [
2973 2983 'id' => 'new-forum',
2974 2984 'title' => '&#43;&nbsp;&nbsp;' . __( 'Add New Forum', 'wpforo' ),
@@ -2992,9 +3002,9 @@
2992 3002 'parent' => 'new-content',
2993 3003 ];
2994 3004 $wp_admin_bar->add_node( $args );
2995 3005 }
2996 -
3006 +
2997 3007 $args = [
2998 3008 'id' => 'wpforo-home',
2999 3009 'title' => __( 'Visit Forum', 'wpforo' ),
3000 3010 'href' => wpforo_home_url(),
@@ -3001,9 +3011,9 @@
3001 3011 'parent' => 'wpf-community',
3002 3012 // 'meta' => [ 'target' => '_blank' ]
3003 3013 ];
3004 3014 $wp_admin_bar->add_node( $args );
3005 -
3015 +
3006 3016 if( wpforo_current_user_is( 'admin' ) || WPF()->usergroup->can( 'mf' ) || WPF()->usergroup->can( 'ms' ) || WPF()->usergroup->can( 'vm' ) || WPF()->usergroup->can( 'mp' ) || WPF()->usergroup->can(
3007 3017 'aum'
3008 3018 ) || WPF()->usergroup->can( 'vmg' ) || WPF()->usergroup->can( 'mth' ) ) {
3009 3019 $args = [
@@ -3159,15 +3169,15 @@
3159 3169 'href' => admin_url( 'admin.php?page=wpforo-overview' ),
3160 3170 'parent' => 'new-content',
3161 3171 ];
3162 3172 $wp_admin_bar->add_node( $args );
3163 -
3173 +
3164 3174 if( $boardids = WPF()->board->get_active_boardids() ) {
3165 3175 foreach( $boardids as $boardid ) {
3166 3176 WPF()->change_board( $boardid );
3167 3177 $current = WPF()->board->get_current();
3168 3178 $bds_bar_numbers[ $boardid ] = wpforo_get_admin_bar_numbers();
3169 -
3179 +
3170 3180 $menuid = 'wpforo-new-content-' . $current['slug'];
3171 3181 $args = [
3172 3182 'id' => $menuid,
3173 3183 'title' => $current['title'],
@@ -3200,13 +3210,13 @@
3200 3210 ),
3201 3211 'parent' => $menuid,
3202 3212 ];
3203 3213 $wp_admin_bar->add_node( $args );
3204 -
3214 +
3205 3215 }
3206 3216 }
3207 3217 }
3208 -
3218 +
3209 3219 if( wpforo_current_user_is( 'admin' ) || WPF()->usergroup->can( 'mf' ) || WPF()->usergroup->can( 'ms' ) || WPF()->usergroup->can( 'vm' ) || WPF()->usergroup->can( 'mp' ) || WPF()->usergroup->can(
3210 3220 'aum'
3211 3221 ) || WPF()->usergroup->can( 'vmg' ) || WPF()->usergroup->can( 'mth' ) ) {
3212 3222 $bds_bar_all = 0;
@@ -3216,15 +3226,15 @@
3216 3226 'title' => 'wpForo' . wpforo_wp_admin_bar_red_circle_number( $bds_bar_all ),
3217 3227 'href' => admin_url( 'admin.php?page=wpforo-overview' ),
3218 3228 ];
3219 3229 $wp_admin_bar->add_node( $args );
3220 -
3221 -
3230 +
3231 +
3222 3232 if( $boardids = WPF()->board->get_active_boardids() ) {
3223 3233 foreach( $boardids as $boardid ) {
3224 3234 WPF()->change_board( $boardid );
3225 3235 $current = WPF()->board->get_current();
3226 -
3236 +
3227 3237 $menuid = 'wpforo-' . $current['slug'];
3228 3238 $args = [
3229 3239 'id' => $menuid,
3230 3240 'title' => '' . $current['title'] . ' (' . strtok(
@@ -3234,11 +3244,11 @@
3234 3244 'href' => admin_url( 'admin.php?page=' . wpforo_prefix_slug( 'dashboard' ) ),
3235 3245 'parent' => 'wpforo',
3236 3246 ];
3237 3247 $wp_admin_bar->add_node( $args );
3238 -
3248 +
3239 3249 ## ---------------------------------------------------------------------------------- ####
3240 -
3250 +
3241 3251 $args = [
3242 3252 'id' => $menuid . '-home',
3243 3253 'title' => '' . __( 'Visit Forum', 'wpforo' ),
3244 3254 'href' => wpforo_home_url(),
@@ -3245,9 +3255,9 @@
3245 3255 'parent' => $menuid,
3246 3256 // 'meta' => [ 'target' => '_blank' ]
3247 3257 ];
3248 3258 $wp_admin_bar->add_node( $args );
3249 -
3259 +
3250 3260 if( WPF()->usergroup->can( 'mf' ) || wpforo_current_user_is( 'admin' ) ) {
3251 3261 $args = [
3252 3262 'id' => $menuid . '-forums',
3253 3263 'title' => '' . __( 'Forums', 'wpforo' ),
@@ -3312,11 +3322,11 @@
3312 3322 $wp_admin_bar->add_node( $args );
3313 3323 }
3314 3324 }
3315 3325 }
3316 -
3326 +
3317 3327 ##### -- ##### ----- $ ----- ###
3318 -
3328 +
3319 3329 if( WPF()->usergroup->can( 'ms' ) || wpforo_current_user_is( 'admin' ) ) {
3320 3330 $args = [
3321 3331 'id' => 'wpforo-boards',
3322 3332 'title' => '' . __( 'Boards', 'wpforo' ),
@@ -3491,9 +3501,9 @@
3491 3501 add_action( 'wp_ajax_wpforo_notifications', 'wpforo_check_notifications' );
3492 3502
3493 3503 function wpforo_can_display_recaptcha_note() {
3494 3504 $d = wpforo_is_admin() ? 'recaptcha_backend_note' : 'recaptcha_note';
3495 -
3505 +
3496 3506 return ! WPF()->dissmissed[ $d ] && current_user_can( 'administrator' ) && ! wp_is_mobile() && wpforo_setting(
3497 3507 'authorization',
3498 3508 'user_register'
3499 3509 ) && ! wpforo_setting( 'authorization', 'register_url' ) && ! wpforo_is_recaptcha_configured();
@@ -3643,9 +3653,9 @@
3643 3653 $var = esc_html( $var );
3644 3654 } else {
3645 3655 $var = wpforo_esc_html( $var );
3646 3656 }
3647 -
3657 +
3648 3658 return $var;
3649 3659 }
3650 3660
3651 3661 add_action( 'wpforo_bottom_hook', 'wpforo_debug' );
@@ -3678,9 +3688,9 @@
3678 3688 $forumids = WPF()->forum->get_forumid_and_childids( $forumid );
3679 3689 unset( $args['forumid'] );
3680 3690 $args['forumids'] = $forumids;
3681 3691 }
3682 -
3692 +
3683 3693 return $args;
3684 3694 } );
3685 3695
3686 3696 function wpf_body_wp_encode_emoji( $post ) {
@@ -3685,9 +3695,9 @@
3685 3695
3686 3696 function wpf_body_wp_encode_emoji( $post ) {
3687 3697 if( wpfkey( $post, 'title' ) ) $post['title'] = wp_encode_emoji( $post['title'] );
3688 3698 if( wpfkey( $post, 'body' ) ) $post['body'] = wp_encode_emoji( $post['body'] );
3689 -
3699 +
3690 3700 return $post;
3691 3701 }
3692 3702
3693 3703 add_filter( 'wpforo_add_post_data_filter', 'wpf_body_wp_encode_emoji' );
@@ -3718,4 +3728,53 @@
3718 3728 wp_safe_redirect( admin_url( 'admin.php?page=wpforo-overview' ) );
3719 3729 exit;
3720 3730 }
3721 3731 }, 1 );
3732 +
3733 +// AI Pricing Promo Notice - shows to users without active AI subscription
3734 +add_action( 'admin_notices', function() {
3735 + if( ! current_user_can( 'manage_options' ) ) return;
3736 +
3737 + // Check if dismissed
3738 + $dismissed = get_option( 'wpforo_ai_pricing_promo_dismissed' );
3739 + if( $dismissed === '2026-08' ) return;
3740 +
3741 + // Check if user has active paid subscription - don't show to them
3742 + if( function_exists( 'WPF' ) && WPF()->ai_client ) {
3743 + $status = WPF()->ai_client->get_subscription_status();
3744 + $plan = WPF()->ai_client->get_subscription_plan();
3745 + $paid_plans = [ 'starter', 'professional', 'business', 'enterprise' ];
3746 + if( $status === 'active' && in_array( $plan, $paid_plans, true ) ) return;
3747 + }
3748 +
3749 + $ai_url = admin_url( 'admin.php?page=wpforo-ai' );
3750 + ?>
3751 + <div class="notice notice-info is-dismissible wpforo-ai-pricing-notice" style="border-left-color: #43a6df; padding: 15px 20px; display: flex; align-items: center;">
3752 + <svg class="wpf-ai-sparkle-icon" xmlns="http://www.w3.org/2000/svg" height="55px" viewBox="0 0 24 24" fill="none" stroke="#43a6df" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink: 0; margin-right: 20px;"><path d="M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3z"></path><path d="M5 3v4"></path><path d="M3 5h4"></path><path d="M19 17v4"></path><path d="M17 19h4"></path></svg>
3753 + <div>
3754 + <p style="margin: 0 0 4px 0; font-size: 17px; font-weight: 600; color: #1d2327;">
3755 + wpForo AI Features — Free Month with 500 Credits and Subscription Starting at Just <span style="font-size: 17px;">&cuepr; <span style="color: #DA5800;">$9</span> &cuesc; !</span>
3756 + </p>
3757 + <p style="margin: 0 0 8px 0; font-size: 16px; color: #50575e;">
3758 + Unlock AI-powered smart search, spam protection, content moderation, topic summarization, topic suggestions, translation, and more...
3759 + </p>
3760 + <style>
3761 + .button.button-primary.wpforo-ai-get-started{background-color: #43a6df; border-color: #43a6df;}
3762 + .button.button-primary.wpforo-ai-get-started:hover{background-color: #178ac6; border-color: #178ac6;}
3763 + </style>
3764 + <p style="margin: 5px 0 0;">
3765 + <a href="<?php echo esc_url( $ai_url ); ?>" class="button button-primary wpforo-ai-get-started" style=" padding: 0 20px !important; min-height: 10px; height: 34px; line-height: 31px;">Get Started</a>
3766 + </p>
3767 + </div>
3768 + </div>
3769 + <script>
3770 + jQuery(document).on('click', '.wpforo-ai-pricing-notice .notice-dismiss', function() {
3771 + jQuery.post(ajaxurl, { action: 'wpforo_dismiss_ai_pricing_promo' });
3772 + });
3773 + </script>
3774 + <?php
3775 +} );
3776 +
3777 +add_action( 'wp_ajax_wpforo_dismiss_ai_pricing_promo', function() {
3778 + update_option( 'wpforo_ai_pricing_promo_dismissed', '2026-08' );
3779 + wp_die();
3780 +} );