PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.1
Forumax – AI Powered Advanced Community Forum Plugin v2.5.1
2.5.1 2.5.0 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 All 31 releases
← All changes | includes/features/bbp_solved_topic.php +70 -27 1.2.3 → 2.5.1 View file →
@@ -1,8 +1,8 @@
1 1 <?php
2 2 namespace features;
3 3
4 -class bbp_solved_topic {
4 +class forumax_solve_topic {
5 5
6 6 /**
7 7 * The capability required to view private posts.
8 8 *
@@ -41,13 +41,42 @@
41 41
42 42 add_filter( 'bbp_theme_before_topic_title', [ $this, 'solved_badge' ], 999, 2 );
43 43 add_filter( 'bbp_topic_admin_links', [ $this, 'add_topic_admin_link' ], 10, 2 );
44 44
45 + add_action( 'template_redirect', [ $this, 'handle_solve_action' ] );
46 +
45 47 // add a class name indicating the read status
46 48 add_filter( 'post_class', [ $this, 'reply_post_class' ] );
47 49 }
48 50
49 51 /**
52 + * Handle the solve/unsolve action via GET request
53 + *
54 + * @since 2.2.0
55 + */
56 + public function handle_solve_action() {
57 + if ( ! isset( $_GET['solve_topic'] ) && ! isset( $_GET['unsolve_topic'] ) ) {
58 + return;
59 + }
60 +
61 + $topic_id = bbp_get_topic_id();
62 + $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
63 +
64 + if ( isset( $_GET['solve_topic'] ) ) {
65 + // Verify nonce
66 + if ( ! wp_verify_nonce( $nonce, 'forumax_solve_topic_' . $topic_id ) ) {
67 + wp_die( esc_html__( 'Security check failed.', 'forumax' ) );
68 + }
69 + $this->solve_topic( $topic_id );
70 + } elseif ( isset( $_GET['unsolve_topic'] ) ) {
71 + if ( ! wp_verify_nonce( $nonce, 'forumax_unsolve_topic_' . $topic_id ) ) {
72 + wp_die( esc_html__( 'Security check failed.', 'forumax' ) );
73 + }
74 + $this->unsolve_topic( $topic_id );
75 + }
76 + }
77 +
78 + /**
50 79 * Admin links
51 80 */
52 81 public function add_topic_admin_link( $links, $topic_id ) {
53 82
@@ -52,20 +81,18 @@
52 81 public function add_topic_admin_link( $links, $topic_id ) {
53 82
54 83 $topic_author = bbp_get_topic_author_id( bbp_get_topic_id() );
55 84 if ( ( current_user_can( $this->capability ) ) || ( $topic_author == get_current_user_id() ) ) {
56 - if ( isset( $_GET['unsolve_topic'] ) ) {
57 - $this->unsolve_topic( bbp_get_topic_id() );
58 - $links['solved'] = '<a href="' . bbp_get_topic_permalink() . '?solve_topic">' . esc_html__( 'Mark as solved', 'ama-core' ) . '</a>';
59 - } elseif ( isset( $_GET['solve_topic'] ) ) {
60 - $this->solve_topic( bbp_get_topic_id() );
61 - $links['unsolved'] = '<a href="' . bbp_get_topic_permalink() . '?unsolve_topic">' . esc_html__( 'Mark as unsolved', 'ama-core' ) . '</a>';
85 + if ( $this->is_solved( bbp_get_topic_id() ) ) {
86 + $links['unsolved'] = '<a href="' . wp_nonce_url(
87 + add_query_arg( 'unsolve_topic', '1', bbp_get_topic_permalink() ),
88 + 'forumax_unsolve_topic_' . bbp_get_topic_id()
89 + ) . '">' . esc_html__( 'Mark as unsolved', 'forumax' ) . '</a>';
62 90 } else {
63 - if ( $this->is_solved( bbp_get_topic_id() ) ) {
64 - $links['unsolved'] = '<a href="' . bbp_get_topic_permalink() . '?unsolve_topic">' . esc_html__( 'Mark as unsolved', 'ama-core' ) . '</a>';
65 - } else {
66 - $links['solved'] = '<a href="' . bbp_get_topic_permalink() . '?solve_topic">' . esc_html__( 'Mark as solved', 'ama-core' ) . '</a>';
67 - }
91 + $links['solved'] = '<a href="' . wp_nonce_url(
92 + add_query_arg( 'solve_topic', '1', bbp_get_topic_permalink() ),
93 + 'forumax_solve_topic_' . bbp_get_topic_id()
94 + ) . '">' . esc_html__( 'Mark as solved', 'forumax' ) . '</a>';
68 95 }
69 96 }
70 97 return $links;
71 98 }
@@ -73,12 +100,13 @@
73 100 public function solve_topic( $topic_id = 0 ) {
74 101 $topic_author = bbp_get_topic_author_id( $topic_id );
75 102 if ( ( current_user_can( $this->capability ) ) || ( $topic_author == get_current_user_id() ) ) {
76 103 update_post_meta( $topic_id, '_bbp_topic_is_solved', '1' );
77 - $redirect = remove_query_arg( [ 'solve_topic' ] );
104 + $redirect = remove_query_arg( [ 'solve_topic', '_wpnonce' ] );
78 105 wp_safe_redirect( $redirect );
106 + exit;
79 107 } else {
80 - wp_die( esc_html__( 'You do not have the permission to do that!', 'ama-core' ) );
108 + wp_die( esc_html__( 'You do not have the permission to do that!', 'forumax' ) );
81 109 }
82 110
83 111 }
84 112
@@ -85,12 +113,13 @@
85 113 public function unsolve_topic( $topic_id = 0 ) {
86 114 $topic_author = bbp_get_topic_author_id( $topic_id );
87 115 if ( ( current_user_can( $this->capability ) ) || ( $topic_author == get_current_user_id() ) ) {
88 116 delete_post_meta( $topic_id, '_bbp_topic_is_solved' );
89 - $redirect = remove_query_arg( [ 'unsolve_topic' ] );
117 + $redirect = remove_query_arg( [ 'unsolve_topic', '_wpnonce' ] );
90 118 wp_safe_redirect( $redirect );
119 + exit;
91 120 } else {
92 - wp_die( esc_html__( 'You do not have the permission to do that!', 'ama-core' ) );
121 + wp_die( esc_html__( 'You do not have the permission to do that!', 'forumax' ) );
93 122 }
94 123 }
95 124
96 125 /**
@@ -101,9 +130,9 @@
101 130 *
102 131 * @return void
103 132 */
104 133 public function filter_capability() {
105 - $this->capability = apply_filters( 'bbp_solved_topic_capability', $this->capability );
134 + $this->capability = apply_filters( 'forumax_solve_topic_capability', $this->capability );
106 135 }
107 136
108 137 /**
109 138 * Solved topic badge
@@ -133,9 +162,9 @@
133 162 if ( ( ! $has_best_answer ) || ( $is_best_answer ) ) {
134 163 ?>
135 164 <p>
136 165 <input name="bbp_best_answer" id="bbp_best_answer" type="checkbox"<?php checked( '1', $is_best_answer ); ?> value="1" tabindex="<?php bbp_tab_index(); ?>" />
137 - <label for="bbp_best_answer"><?php esc_html_e( 'Set this reply as Best Answer.', 'ama-core' ); ?></label>
166 + <label for="bbp_best_answer"><?php esc_html_e( 'Set this reply as Best Answer.', 'forumax' ); ?></label>
138 167 </p>
139 168 <?php
140 169 }
141 170 }
@@ -152,10 +181,10 @@
152 181 $topic_author = bbp_get_topic_author_id( bbp_get_topic_id() );
153 182 if ( bbp_is_topic_edit() && ( ( current_user_can( $this->capability ) ) || ( $topic_author == get_current_user_id() ) ) ) {
154 183 ?>
155 184 <p>
156 - <input name="bbp_solved_topic" id="bbp_solved_topic" type="checkbox"<?php checked( '1', $this->is_solved( bbp_get_topic_id() ) ); ?> value="1" tabindex="<?php bbp_tab_index(); ?>" />
157 - <label for="bbp_solved_topic"><?php esc_html_e( 'Set this post as solved.', 'ama-core' ); ?></label>
185 + <input name="forumax_solve_topic" id="forumax_solve_topic" type="checkbox"<?php checked( '1', $this->is_solved( bbp_get_topic_id() ) ); ?> value="1" tabindex="<?php bbp_tab_index(); ?>" />
186 + <label for="forumax_solve_topic"><?php esc_html_e( 'Set this post as solved.', 'forumax' ); ?></label>
158 187 </p>
159 188 <?php
160 189 }
161 190
@@ -182,9 +211,11 @@
182 211 if ( ! $get_topic_meta ) {
183 212 update_post_meta( $topic_id, '_bbp_topic_has_best_answer', '1' );
184 213 }
185 214 update_post_meta( $reply_id, '_bbp_reply_is_best_answer', '1' );
186 - } else {
215 + } elseif ( get_post_meta( $reply_id, '_bbp_reply_is_best_answer', true ) ) {
216 + // Only clear the topic flag when this reply was the best answer;
217 + // saving any other reply must not wipe it.
187 218 delete_post_meta( $reply_id, '_bbp_reply_is_best_answer' );
188 219 delete_post_meta( $topic_id, '_bbp_topic_has_best_answer' );
189 220 }
190 221
@@ -201,9 +232,9 @@
201 232 * @return void
202 233 */
203 234 public function update_topic( $topic_id = 0, $is_edit = false ) {
204 235
205 - if ( isset( $_POST['bbp_solved_topic'] ) ) {
236 + if ( isset( $_POST['forumax_solve_topic'] ) ) {
206 237 update_post_meta( $topic_id, '_bbp_topic_is_solved', '1' );
207 238 } else {
208 239 delete_post_meta( $topic_id, '_bbp_topic_is_solved' );
209 240 }
@@ -338,9 +369,9 @@
338 369
339 370 $topic_id = bbp_get_topic_id();
340 371
341 372 if ( $this->is_best_answer( $reply_id ) ) {
342 - $content = '<div class="solved-topic-bar" id="best-answer"><span class="badge"><i class="icon_check"></i> ' . esc_html__( 'Best Answer', 'ama-core' ) . '</span></div>' . $content;
373 + $content = '<div class="solved-topic-bar" id="best-answer"><span class="badge"><i class="icon_check"></i> ' . esc_html__( 'Best Answer', 'forumax' ) . '</span></div>' . $content;
343 374 }
344 375
345 376 return $content;
346 377 }
@@ -371,9 +402,9 @@
371 402 $close = '</div>';
372 403 }
373 404
374 405 if ( $this->is_solved( $topic_id ) ) {
375 - $resolved = '<span class="accepted-ans-mark"><i class="icon_check_alt"></i> ' . esc_html__( 'Resolved', 'ama-core' ) . '</span>';
406 + $resolved = '<span class="accepted-ans-mark badge"><i class="icon_check_alt"></i> ' . esc_html__( 'Resolved', 'forumax' ) . '</span>';
376 407 }
377 408
378 409 $content = $content . $open . $resolved . $has_best_answer . $close;
379 410
@@ -411,9 +442,21 @@
411 442 }
412 443 }
413 444
414 445 // Instantiate the class.
415 -$GLOBALS['bbp_solved_topic'] = new bbp_solved_topic();
446 +$GLOBALS['forumax_solve_topic'] = new forumax_solve_topic();
416 447
417 -function bbp_solved_topic(): bbp_solved_topic {
418 - return new bbp_solved_topic();
448 +/**
449 + * Shared solved-topic instance.
450 + *
451 + * Constructing a new instance re-registers every hook, so repeated calls
452 + * (once per topic in a loop) duplicated badges and filters.
453 + *
454 + * @return forumax_solve_topic
455 + */
456 +function forumax_solve_topic(): forumax_solve_topic {
457 + if ( ! ( $GLOBALS['forumax_solve_topic'] ?? null ) instanceof forumax_solve_topic ) {
458 + $GLOBALS['forumax_solve_topic'] = new forumax_solve_topic();
459 + }
460 +
461 + return $GLOBALS['forumax_solve_topic'];
419 462 }