PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.0
Forumax – AI Powered Advanced Community Forum Plugin v2.5.0
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_voting/frontend.php +266 -248 1.2.2 → 2.5.0 View file →
@@ -2,221 +2,241 @@
2 2 if ( ! defined( 'ABSPATH' ) ) {
3 3 exit; // Exit if accessed directly.
4 4 }
5 5
6 -$opt = get_option( 'bbp_core_settings' );
7 -$voting_position = $opt['voting_position'] ?? 'below_user';
6 +// Vote Buttons and Score hooks.
7 +add_action( 'bbp_theme_after_topic_content', 'bbp_voting_buttons' );
8 +add_action( 'forumax_reply_avatar_voting', 'bbp_voting_buttons' );
9 +add_action( 'bbp_voting_cpt', 'bbp_voting_buttons', 10, 1 );
8 10
11 +function bbp_voting_buttons( $post_obj = false ) {
12 + // Don't show voting buttons on user profile pages
13 + if ( function_exists( 'bbp_is_single_user' ) && bbp_is_single_user() ) {
14 + return;
15 + }
9 16
10 -// Vote Buttons and Score hooks.
11 -// add_action('bbp_theme_before_topic_author_details', 'bbp_voting_buttons');
12 -// add_action('bbp_theme_before_reply_author_details', 'bbp_voting_buttons');
13 -add_action( 'bbp_theme_before_topic_title', 'bbp_voting_buttons' );
14 -// add_action('bbp_template_before_lead_topic', 'bbp_voting_buttons');
17 + $current_action = current_action();
18 + $topic_post_type = bbp_get_topic_post_type();
19 + $reply_post_type = bbp_get_reply_post_type();
20 + $this_post_type = '';
21 + $post = null;
15 22
16 -add_action( 'bbp_theme_before_topic_content', 'bbp_voting_buttons' );
23 + // Prefer explicitly passed post object (custom hooks/CPT usage).
24 + if ( $post_obj instanceof WP_Post ) {
25 + $post = $post_obj;
26 + $this_post_type = get_post_type( $post->ID );
27 + }
17 28
18 -if ( 'before_content' == $voting_position ) {
19 - add_action( 'bbp_theme_before_reply_content', 'bbp_voting_buttons' );
20 -} elseif ( 'below_user' == $voting_position ) {
21 - add_action( 'bbp_theme_after_reply_author_details', 'bbp_voting_buttons' );
22 -}
29 + // Fallback to action-based context detection.
30 + if ( empty( $post ) ) {
31 + if ( $current_action === 'bbp_voting_cpt' ) {
32 + if ( ! $post_obj ) return;
33 + $post = $post_obj;
34 + $this_post_type = get_post_type( $post->ID );
35 + } else {
36 + // Determine post type from current action
37 + if ( in_array( $current_action, [
38 + 'bbp_theme_before_topic_title',
39 + 'bbp_template_before_lead_topic',
40 + 'bbp_theme_after_topic_author_details',
41 + 'bbp_theme_after_topic_content',
42 + ] ) ) {
43 + $this_post_type = $topic_post_type;
44 + $post = bbpress()->topic_query->post;
45 + } elseif ( in_array( $current_action, [
46 + 'bbp_theme_before_reply_content',
47 + 'bbp_theme_after_reply_author_details',
48 + 'forumax_reply_avatar_voting',
49 + 'bbp_theme_after_reply_content',
50 + ] ) ) {
51 + $this_post_type = bbp_voting_get_current_post_type();
52 + $post = bbpress()->reply_query->post;
53 + }
54 + }
55 + }
23 56
24 -// add_filter('bbp_get_topic_author_link', 'bbp_voting_buttons', 9, 3);
25 -// add_filter('bbp_get_reply_author_link', 'bbp_voting_buttons', 9, 3);
26 -add_action( 'bbp_voting_cpt', 'bbp_voting_buttons', 10, 1 );
57 + // Exit if unknown context or no post
58 + if ( empty( $this_post_type ) || empty( $post ) ) return;
27 59
28 -function bbp_voting_buttons( $post_obj = false ) {
29 - $opt = get_option( 'bbp_core_settings' );
60 + // Check forum settings
61 + $forum_id = ($this_post_type === $topic_post_type)
62 + ? bbp_get_topic_forum_id( $post->ID )
63 + : bbp_get_reply_forum_id( $post->ID );
30 64
31 - $current_action = current_action();
65 + // Check if voting is allowed on this forum
66 + if ( ! apply_filters( 'bbp_voting_allowed_on_forum', true, $forum_id ) ) return;
32 67
33 - if ( $current_action === 'bbp_voting_cpt' ) {
68 + // Get post-specific settings
69 + $post_setting = ($this_post_type === $topic_post_type)
70 + ? get_post_meta( $forum_id, 'bbp_voting_forum_enable_topics', true )
71 + : get_post_meta( $forum_id, 'bbp_voting_forum_enable_replies', true );
34 72
35 - // Using a custom hook for a custom post type
36 - if ( ! $post_obj ) {
37 - return;
38 - }
73 + $broad_disable = ($this_post_type === $topic_post_type)
74 + ? forumax_get_opt( 'is_voting_disabled_topics', 0 )
75 + : forumax_get_opt( 'is_voting_disabled_replies', 0 );
39 76
40 - $post = $post_obj;
77 + // Check if voting is disabled
78 + if ( ! empty( $post_setting ) && $post_setting === 'false' ) return;
79 + if ( empty( $post_setting ) && $broad_disable === '0' ) return;
41 80
42 - } else {
43 - $topic_post_type = bbp_get_topic_post_type();
44 - $reply_post_type = bbp_get_reply_post_type();
81 + $post_id = $post->ID;
45 82
46 - if ( in_array( $current_action, [ 'bbp_theme_before_topic_title', 'bbp_template_before_lead_topic', 'bbp_theme_before_topic_content' ] ) ) {
83 + $score = (int) get_post_meta( $post_id, 'bbp_voting_score', true );
84 + $ups = (int) get_post_meta( $post_id, 'bbp_voting_ups', true );
85 + $downs = (int) get_post_meta( $post_id, 'bbp_voting_downs', true );
47 86
48 - $this_post_type = $topic_post_type;
87 + $calc_score = $ups + $downs;
88 + if ( $score > $calc_score ) {
89 + $diff = $score - $calc_score;
90 + $ups += $diff;
91 + update_post_meta( $post_id, 'bbp_voting_ups', $ups );
92 + }
93 +
94 + $voting_log = get_post_meta( $post_id, 'bbp_voting_log', true );
95 + $voting_log = is_array( $voting_log ) ? $voting_log : [];
96 + $client_ip = $_SERVER['REMOTE_ADDR'];
97 + $identifier = is_user_logged_in() ? get_current_user_id() : $client_ip;
98 + $existing_vote = $voting_log[ $identifier ] ?? 0;
99 +
100 + // Check if admin can bypass voting restrictions
101 + $admin_bypass = current_user_can( 'administrator' ) &&
102 + forumax_get_opt( 'is_admin_can_vote_unlimited', false );
103 +
104 + // Determine if this is view-only mode
105 + $view_only = ! is_user_logged_in() &&
106 + forumax_get_opt( 'is_disabled_voting_for_non_logged_users', false );
107 +
108 + // Additional view-only checks for regular context (not CPT)
109 + if ( ! $view_only && $current_action !== 'bbp_voting_cpt' ) {
110 + // Check if topic is closed and voting on closed topics is disabled
111 + $topic_id = ( $this_post_type === $topic_post_type ) ?
112 + $post_id : bbp_get_reply_topic_id( $post_id );
113 +
114 + if ( get_post_status( $topic_id ) === 'closed' &&
115 + forumax_get_opt( 'is_disabled_voting_closed_topics', false ) ) {
116 + $view_only = true;
49 117 }
50 118
51 - if ( in_array( $current_action, [ 'bbp_theme_before_reply_content', 'bbp_theme_after_reply_author_details' ] ) ) {
52 - $this_post_type = bbp_voting_get_current_post_type();
119 + // Check if voting on own posts is disabled
120 + if ( ! $view_only &&
121 + forumax_get_opt( 'is_disabled_voting_own_topic_reply', false ) &&
122 + $post->post_author == get_current_user_id() ) {
123 + $view_only = true;
53 124 }
125 + }
54 126
55 - // Get the post.
56 - if ( $this_post_type == $topic_post_type ) {
57 - $post = bbpress()->topic_query->post;
58 - }
127 + $disable_down = forumax_get_opt( 'is_down_votes_disabled', 0 );
128 + $vote_number_display = forumax_get_opt( 'vote_numbers_display', 'hover' );
129 + $display_vote_nums = 'num-' . $vote_number_display;
59 130
60 - if ( $this_post_type == $reply_post_type ) {
61 - $post = bbpress()->reply_query->post;
131 + // Determine if floating style should be applied
132 + $float = ( $current_action === 'bbp_voting_cpt' );
133 +
134 + // Build CSS classes for the voting container
135 + $vote_classes = [
136 + 'bbp-voting',
137 + 'bbp-voting-post-' . $post_id,
138 + get_post_type( $post_id )
139 + ];
140 +
141 + if ( $view_only ) {
142 + $vote_classes[] = 'view-only';
143 + } elseif ( $existing_vote == 1 ) {
144 + $vote_classes[] = 'voted-up';
145 + } elseif ( $existing_vote == -1 ) {
146 + $vote_classes[] = 'voted-down';
147 + }
148 +
149 + if ( $admin_bypass ) $vote_classes[] = 'admin-bypass';
150 + if ( $float ) $vote_classes[] = 'bbp-voting-float';
151 +
152 + // Start building HTML
153 + $html = '<div class="' . implode(' ', $vote_classes) . '">';
154 +
155 + // Add label if enabled
156 + $is_label = forumax_get_opt( 'is_label', true );
157 + if ( $is_label ) {
158 + $upvote_label = forumax_get_opt( 'upvote_label' );
159 + if ( $upvote_label ) {
160 + $html .= '<div class="bbp-voting-label helpful">' . esc_html( $upvote_label ) . '</div>';
62 161 }
63 162 }
64 163
65 - // Do we have a post?
66 - if ( ! empty( $post ) ) {
67 - $post_id = $post->ID;
68 - // Since we're using a filter on the author link, avoid duplicates
69 - // if($bbp_voting_last_author_link_post_id === $post_id) {
70 - // Duplicate
71 - // return $author_link;
72 - // } else {
73 - // New, continue, but set the global variable
74 - // $bbp_voting_last_author_link_post_id = $post_id;
75 - // }
76 - if ( $current_action === 'bbp_voting_cpt' ) {
77 - $post_setting = true;
78 - $broad_disable = false;
79 - } else {
80 - switch ( $this_post_type ) {
81 - case $topic_post_type:
82 - $forum_id = bbp_get_topic_forum_id( $post_id );
83 - $post_setting = get_post_meta( $forum_id, 'bbp_voting_forum_enable_topics', true );
84 - $broad_disable = $opt['is_voting_disabled_topics'] ?? false;
85 - break;
86 - case $reply_post_type:
87 - $forum_id = bbp_get_reply_forum_id( $post_id );
88 - $post_setting = get_post_meta( $forum_id, 'bbp_voting_forum_enable_replies', true );
89 - $broad_disable = $opt['is_voting_disabled_replies'] ?? false;
90 - break;
91 - }
92 - // Filter Hook: 'bbp_voting_allowed_on_forum'
93 - if ( ! apply_filters( 'bbp_voting_allowed_on_forum', true, $forum_id ) ) {
94 - return;
95 - }
96 - }
97 - if ( ! empty( $post_setting ) ) {
98 - // Forum-specific override is set (not Default)
99 - if ( $post_setting === 'false' ) {
100 - return;
101 - }
102 - } else {
103 - // Use broad disable settings
104 - if ( $broad_disable === true ) {
105 - return;
106 - }
107 - }
108 - // Done with "allowed" checks... let's do this
109 - $score = (int) get_post_meta( $post_id, 'bbp_voting_score', true );
110 - $ups = (int) get_post_meta( $post_id, 'bbp_voting_ups', true );
111 - $downs = (int) get_post_meta( $post_id, 'bbp_voting_downs', true );
112 - // Check for, and correct, discrepancies
113 - $calc_score = $ups + $downs;
114 - if ( $score > $calc_score ) {
115 - $diff = $score - $calc_score;
116 - $ups += $diff;
117 - update_post_meta( $post_id, 'bbp_voting_ups', $ups );
118 - }
119 - // Get the weighted score
120 - // $weighted_score = get_post_meta($post_id, 'bbp_voting_weighted_score', true);
121 - // Get user's vote by ID or IP
122 - $voting_log = get_post_meta( $post_id, 'bbp_voting_log', true );
123 - $voting_log = is_array( $voting_log ) ? $voting_log : []; // Set up new array
124 - $client_ip = $_SERVER['REMOTE_ADDR'];
125 - $identifier = is_user_logged_in() ? get_current_user_id() : $client_ip;
126 - $existing_vote = array_key_exists( $identifier, $voting_log ) ? $voting_log[ $identifier ] : 0;
127 - // Admin bypass?
128 - $is_admin_can_vote_unlimited = $opt['is_admin_can_vote_unlimited'] ?? false;
129 - $admin_bypass = current_user_can( 'administrator' ) && $is_admin_can_vote_unlimited;
130 - // View only score?
131 - // View only for visitors option
132 - $is_disabled_voting_non_logged = $opt['is_disabled_voting_for_non_logged_users'] ?? false;
133 - $view_only = ! is_user_logged_in() && $is_disabled_voting_non_logged;
134 - if ( ! $view_only ) {
135 - // View only for closed topic option.
136 - if ( $current_action !== 'bbp_voting_cpt' ) {
137 - $topic_id = $this_post_type == $topic_post_type ? $post_id : bbp_get_reply_topic_id( $post_id );
138 - $topic_status = get_post_status( $topic_id );
139 - $is_diabled_closed_topics = $opt['is_disabled_voting_closed_topics'] ?? false;
140 - $view_only = ( 'closed' == $topic_status && $is_diabled_closed_topics ) ? true : false;
141 - }
142 - if ( ! $view_only ) {
143 - // View only for author of post.
144 - $is_disabled_own_topic_reply = $opt['is_disabled_voting_own_topic_reply'] ?? false;
145 - $view_only = ( $is_disabled_own_topic_reply && $post->post_author == get_current_user_ID() ) ? true : false;
146 - }
147 - }
148 - // Show labels?
149 - // Disable down votes?
150 - $disable_down = $opt['is_down_votes_disabled'] ?? false;
151 - $vote_number_display = $opt['vote_numbers_display'] ?? 'hover';
164 + // Generate voting HTML based on whether we're in AMP mode or not
165 + if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
166 + // AMP version of voting buttons
167 + $post_url = admin_url( 'admin-ajax.php' );
168 + $plusups = $ups ? '+' . $ups : ' ';
152 169
153 - // How to display vote numbers?
154 - $display_vote_nums = 'num-' . $vote_number_display;
155 - // Start HTML
156 - $html = '';
157 - $float = in_array( current_action(), [ 'bbp_theme_before_reply_content', 'bbp_theme_before_topic_content', 'bbp_voting_cpt' ] );
158 - $html .= '<div class="bbp-voting bbp-voting-post-' . $post_id . ( $view_only ? ' view-only' : ( $existing_vote == 1 ? ' voted-up' : ( $existing_vote == -1 ? ' voted-down' : '' ) ) ) . ( $admin_bypass ? ' admin-bypass' : '' ) . ( $float ? ' bbp-voting-float' : '' ) . '">';
170 + // Upvote form
171 + $html .= sprintf(
172 + '<form name="amp-form%1$s" method="post" action-xhr="%2$s" target="_top" on="submit-success: AMP.setState({\'voteup%1$s\': %3$s})">
173 + <input type="hidden" name="action" value="bbpress_post_vote_link_clicked">
174 + <input type="hidden" name="post_id" value="%4$s" />
175 + <input type="hidden" name="direction" value="1" />
176 + <input type="submit" class="nobutton upvote-amp" value="🔺" />
177 + <span class="vote up" [text]="voteup%1$s ? \'+\' + voteup%1$s : \'%5$s\'">%5$s</span>
178 + </form>',
179 + $post_id,
180 + esc_url( $post_url ),
181 + ( $ups + 1 ),
182 + esc_attr( $post_id ),
183 + esc_html( $plusups )
184 + );
159 185
160 - // Adds the word 'helpful' in red above the arrow.
161 - $is_label = $opt['is_label'] ?? true;
162 186
163 - if ( $is_label ) {
164 - $upvote_label = ! empty( $opt['upvote_label'] ) ? $opt['upvote_label'] : '';
165 - $html .= '<div class="bbp-voting-label helpful">' . $upvote_label . '</div>';
187 + // Downvote form (if enabled)
188 + if ( $disable_down == 1 ) {
189 + $html .= sprintf(
190 + '<form name="amp-form%1$s" method="post" action-xhr="%2$s" target="_top" on="submit-success: AMP.setState({\'votedown%1$s\': %3$s})">
191 + <input type="hidden" name="action" value="bbpress_post_vote_link_clicked">
192 + <input type="hidden" name="post_id" value="%4$s" />
193 + <input type="hidden" name="direction" value="-1" />
194 + <input type="submit" class="nobutton downvote-amp" value="🔻" />
195 + <span class="vote down" [text]="votedown%1$s || \'%5$s\'">%6$s</span>
196 + </form>',
197 + $post_id,
198 + esc_url( $post_url ),
199 + ( $downs - 1 ),
200 + esc_attr( $post_id ),
201 + esc_html( $downs ? $downs : ' ' ),
202 + esc_html( $downs ? $downs : '' )
203 + );
166 204 }
167 - if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
168 - // AMP = No JS
169 - $post_url = admin_url( 'admin-ajax.php' );
170 - // Up vote
171 - $plusups = $ups ? '+' . $ups : ' ';
172 - $html .= '<form name="amp-form' . $post_id . '" method="post" action-xhr="' . $post_url . '" target="_top" on="submit-success: AMP.setState({\'voteup' . $post_id . '\': ' . ( $ups + 1 ) . '})">
173 - <input type="hidden" name="action" value="bbpress_post_vote_link_clicked">
174 - <input type="hidden" name="post_id" value="' . $post_id . '" />
175 - <input type="hidden" name="direction" value="1" />
176 - <input type="submit" class="nobutton upvote-amp" value="🔺" />
177 - <span class="vote up" [text]="voteup' . $post_id . ' ? \'+\' + voteup' . $post_id . ' : \'' . $plusups . '\'">' . $plusups . '</span>
178 - </form>';
179 - // Display current vote count for post
180 - // $html .= '<div class="score">'. $score. '</div>';
181 - // $html .= '<div class="score" style="background-color: rgb('. floor((1 - $score) * 255). ', '.floor($score * 255).', 0); width:'.floor($score * 100).'%;"></div>';
182 - // Down vote
183 - if ( ! $disable_down ) {
184 - $html .= '<form name="amp-form' . $post_id . '" method="post" action-xhr="' . $post_url . '" target="_top" on="submit-success: AMP.setState({\'votedown' . $post_id . '\': ' . ( $downs - 1 ) . '})">
185 - <input type="hidden" name="action" value="bbpress_post_vote_link_clicked">
186 - <input type="hidden" name="post_id" value="' . $post_id . '" />
187 - <input type="hidden" name="direction" value="-1" />
188 - <input type="submit" class="nobutton downvote-amp" value="🔻" />
189 - <span class="vote down" [text]="votedown' . $post_id . ' || \'' . ( $downs ? $downs : ' ' ) . '\'">' . ( $downs ? $downs : '' ) . '</span>
190 - </form>';
191 - }
192 - } else {
193 - // Normal JS AJAX version
194 - // Up vote
195 - $html .= '<a class="vote up ' . $display_vote_nums . '" data-votes="' . ( $ups ? '+' . $ups : '' ) . '" onclick="bbpress_post_vote_link_clicked(' . $post_id . ', 1); return false;">Up</a>';
196 - // Display current vote count for post
197 - $html .= '<div class="score">' . $score . '</div>';
198 - // Down vote
199 - if ( ! $disable_down ) {
200 - $html .= '<a class="vote down ' . $display_vote_nums . '" data-votes="' . ( $downs ? $downs : '' ) . '" onclick="bbpress_post_vote_link_clicked(' . $post_id . ', -1); return false;">Down</a>';
201 - }
205 + } else {
206 + // Standard version of voting buttons
207 + $html .= '<a class="vote up ' . esc_attr( $display_vote_nums ) . '" data-votes="' .
208 + ( $ups ? '+' . $ups : '' ) . '" onclick="bbpress_post_vote_link_clicked(' .
209 + $post_id . ', 1); return false;">Up</a>';
210 +
211 + $html .= '<div class="score">' . $score . '</div>';
212 +
213 + if ( $disable_down == 1 ) {
214 + $html .= '<a class="vote down ' . esc_attr( $display_vote_nums ) . '" data-votes="' .
215 + ( $downs ? $downs : '' ) . '" onclick="bbpress_post_vote_link_clicked(' .
216 + $post_id . ', -1); return false;">Down</a>';
202 217 }
203 - // adds the words 'not helpful' in red below the arrow
204 - if ( ! $disable_down && $is_label ) {
205 - $downvote_label = ! empty( $opt['downvote_label'] ) ? $opt['downvote_label'] : '';
206 - $html .= '<div class="bbp-voting-label not-helpful">' . $downvote_label . '</div>';
218 + }
219 +
220 + if ( $disable_down == 1 && $is_label ) {
221 + $downvote_label = forumax_get_opt( 'downvote_label' );
222 + if ( $downvote_label ) {
223 + $html .= '<div class="bbp-voting-label not-helpful">' . esc_html( $downvote_label ) . '</div>';
207 224 }
208 - if ( $this_post_type == $reply_post_type ) {
209 - $html = apply_filters( 'bbp_voting_after_reply_voting_buttons', $html, $post_id ); // TODO: take care
210 - }
211 - $html .= '</div>';
212 - // Special hidden mark after the voting buttons for using regex to strip them off of things that pull excerpts using jQuery text()
213 - $html .= '<span style="display:none;">::</span>';
214 - // return $html . $author_link;
215 - echo $html;
216 225 }
226 +
227 + // Apply filter for reply voting buttons
228 + if ( $this_post_type === $reply_post_type ) {
229 + $html = apply_filters( 'bbp_voting_after_reply_voting_buttons', $html, $post_id );
230 + }
231 +
232 + // Close the voting container
233 + $html .= '</div>';
234 +
235 + echo $html;
217 236 }
218 237
238 +
219 239 // Sort by Votes
220 240
221 241 add_filter( 'bbp_has_topics_query', 'sort_bbpress_posts_by_votes', 99 );
222 242 add_filter( 'bbp_has_replies_query', 'sort_bbpress_posts_by_votes', 99 );
@@ -221,128 +241,126 @@
221 241 add_filter( 'bbp_has_topics_query', 'sort_bbpress_posts_by_votes', 99 );
222 242 add_filter( 'bbp_has_replies_query', 'sort_bbpress_posts_by_votes', 99 );
223 243
224 244 function sort_bbpress_posts_by_votes( $args = [] ) {
225 - $opt = get_option( 'bbp_core_settings' );
226 -
227 245 $forum_id = bbp_get_forum_id();
228 - // if($forum_id === 0) return $args;
229 - // $this_post_type = isset($args['post_type']) ? $args['post_type'] : bbp_voting_get_current_post_type();
230 - // $this_post_type = bbp_voting_get_current_post_type();
231 246 $forum_post_type = bbp_get_forum_post_type();
232 247 $topic_post_type = bbp_get_topic_post_type();
233 - switch ( current_filter() ) {
248 +
249 + // Determine post type and settings based on current filter
250 + $current_filter = current_filter();
251 + switch ( $current_filter ) {
234 252 case 'bbp_has_topics_query':
235 253 $this_post_type = $forum_post_type;
236 254 $post_setting = get_post_meta( $forum_id, 'sort_bbpress_topics_by_votes_on_forum', true );
237 - $broad_enable = $opt['is_sort_topic_by_votes'] ?? false;
255 + $broad_enable = forumax_get_opt( 'is_sort_topic_by_votes', false );
238 256 break;
239 257 case 'bbp_has_replies_query':
240 258 $this_post_type = $topic_post_type;
241 259 $post_setting = get_post_meta( $forum_id, 'sort_bbpress_replies_by_votes_on_forum', true );
242 - $broad_enable = $opt['is_sort_reply_by_votes'] ?? false;
260 + $broad_enable = forumax_get_opt( 'is_sort_reply_by_votes', false );
243 261 break;
244 262 default:
245 263 return $args;
246 264 }
247 - // Do "allowed" checks
265 +
266 + // Check if we should apply vote sorting
267 + $apply_sorting = false;
268 +
269 + // Check URL parameter first
248 270 if ( isset( $_GET['bbp-voting-sort'] ) ) {
249 - // Sort dropdown used, skip the rest of the checks
250 271 if ( $_GET['bbp-voting-sort'] === 'best' ) {
251 - // Proceed with score sorting
272 + $apply_sorting = true;
252 273 } elseif ( $_GET['bbp-voting-sort'] === 'default' || $_GET['bbp-voting-sort'] === '' ) {
253 - // bbp default non-score sort
254 274 return $args;
255 275 }
256 276 } else {
257 - // Sort dropdown not used... check the settings
277 + // Check forum settings
258 278 if ( ! empty( $post_setting ) ) {
259 - // Forum-specific override is set (not Default)
260 - if ( $post_setting === 'false' ) {
261 - return $args;
279 + if ( $post_setting !== 'false' ) {
280 + $apply_sorting = true;
262 281 }
263 - } else {
264 - // Use broad disable settings
265 - if ( $broad_enable === false ) {
266 - return $args;
267 - }
282 + } elseif ( $broad_enable !== '1' ) {
283 + $apply_sorting = true;
268 284 }
285 +
286 + // Check if voting is allowed on this forum
269 287 if ( ! apply_filters( 'bbp_voting_allowed_on_forum', true, $forum_id ) ) {
270 - return $args;
288 + $apply_sorting = false;
271 289 }
272 290 }
273 - // Done with "allowed" checks... let's do this
274 - // Filter the sort meta key. Default = bbp_voting_score
291 +
292 + // Return original args if sorting should not be applied
293 + if ( ! $apply_sorting ) {
294 + return $args;
295 + }
296 +
297 + // Get the meta key to sort by
275 298 $sort_meta_key = apply_filters( 'bbp_voting_sort_meta_key', 'bbp_voting_score' );
276 299
277 - // Reset for testing only -------------------------------------
278 - // $argsreset = $args;
279 - // $query = new WP_Query($argsreset);
280 - // foreach($query->posts as $reply) {
281 - // delete_post_meta($reply->ID, $sort_meta_key);
282 - // }
283 - // -----------------------------------
300 + // Find and fill any posts missing the sort meta key
301 + $cache_key = 'frmx_vote_backfill_' . md5( serialize( $args ) );
302 + if ( false === get_transient( $cache_key ) ) {
303 + $missing_meta_query = [
304 + 'meta_query' => [
305 + [
306 + 'key' => $sort_meta_key,
307 + 'compare' => 'NOT EXISTS',
308 + 'value' => '',
309 + ],
310 + ],
311 + 'fields' => 'ids',
312 + ];
284 313
285 - // Find any replies that are missing the bbp_voting_score post meta and fill them with 0
286 - $args2 = $args;
287 - $args2['meta_query'] = [
288 - [
289 - 'key' => $sort_meta_key,
290 - 'compare' => 'NOT EXISTS',
291 - 'value' => '',
292 - ],
293 - ];
294 - $query = new WP_Query( $args2 );
295 - foreach ( $query->posts as $reply ) {
296 - $fill_in_default = apply_filters( 'bbp_voting_sort_meta_key_default_value', '0', $reply->ID );
297 - update_post_meta( $reply->ID, $sort_meta_key, $fill_in_default );
314 + $query = new WP_Query( array_merge( $args, $missing_meta_query ) );
315 + foreach ( $query->posts as $post_id ) {
316 + $default_value = apply_filters( 'bbp_voting_sort_meta_key_default_value', '0', $post_id );
317 + update_post_meta( $post_id, $sort_meta_key, $default_value );
318 + }
319 +
320 + // Cache for 24 hours to skip subsequent checks
321 + set_transient( $cache_key, 'done', DAY_IN_SECONDS );
298 322 }
299 323
300 - // Now that all missing scores are filled in, we can sort the original args by the score
301 - // $args['meta_key'] = 'bbp_voting_score';
302 - // $args['orderby'] = [
303 - // 'post_type' => 'DESC',
304 - // 'meta_value_num' => 'DESC',
305 - // 'date' => 'DESC'
306 - // ];
307 - unset( $args['meta_key'] );
308 - unset( $args['meta_type'] );
309 - unset( $args['orderby'] );
310 - unset( $args['order'] );
324 + // Clear existing sort parameters
325 + $args = array_diff_key( $args, array_flip( ['meta_key', 'meta_type', 'orderby', 'order'] ) );
326 +
327 + // Set up meta query for sorting
311 328 $args['meta_query'] = [
312 329 'relation' => 'AND',
313 330 'score_clause' => [
314 331 'key' => $sort_meta_key,
315 332 'compare' => 'EXISTS',
316 - // 'type' => 'DECIMAL' // https://stackoverflow.com/questions/30018711/wordpress-meta-query-not-working-with-decimal-type
317 333 ],
318 334 ];
319 - if ( $sort_meta_key == 'bbp_voting_score' ) {
335 +
336 + // Set numeric type for score meta if using the default key
337 + if ( $sort_meta_key === 'bbp_voting_score' ) {
320 338 $args['meta_query']['score_clause']['type'] = 'NUMERIC';
321 339 }
340 +
341 + // Set up orderby parameters
322 342 $args['orderby'] = [
323 343 'post_type' => 'DESC',
324 344 'score_clause' => 'DESC',
325 345 ];
346 +
347 + // Add additional sorting parameters based on post type
326 348 if ( $this_post_type === $topic_post_type ) {
327 - // Add Date as another orderby for topics on a forum
328 349 $args['orderby']['date'] = 'ASC';
329 - }
330 - if ( $this_post_type === $forum_post_type ) {
331 - // Add Freshness as another orderby for topics on a forum
350 + } elseif ( $this_post_type === $forum_post_type ) {
332 351 $args['meta_query']['orderby_freshness'] = [
333 352 'key' => '_bbp_last_active_time',
334 353 'type' => 'DATETIME',
335 354 ];
336 - $args['orderby']['orderby_freshness'] = 'DESC';
355 + $args['orderby']['orderby_freshness'] = 'DESC';
337 356 }
357 +
338 358 return $args;
339 359 }
340 360
341 361 add_action( 'init', 'bbp_voting_lead_topic' );
342 362 function bbp_voting_lead_topic() {
343 - $opt = get_option( 'bbp_core_settings' );
344 -
345 - if ( $opt['is_lead_topic_broken'] ?? false ) {
363 + if ( forumax_get_opt( 'is_lead_topic_broken', false ) ) {
346 364 add_filter( 'bbp_show_lead_topic', '__return_true' );
347 365 }
348 366 }