PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 1.2.2
Forumax – AI Powered Advanced Community Forum Plugin v1.2.2
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 2.0.0 2.1.0 All 29 releases
bbp-core / includes / features / bbp_voting / frontend.php

frontend.php in Forumax – AI Powered Advanced Community Forum Plugin 1.2.2, at includes/features/bbp_voting/frontend.php

349 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6 $opt = get_option( 'bbp_core_settings' );
7 $voting_position = $opt['voting_position'] ?? 'below_user';
8
9
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');
15
16 add_action( 'bbp_theme_before_topic_content', 'bbp_voting_buttons' );
17
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 }
23
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 );
27
28 function bbp_voting_buttons( $post_obj = false ) {
29 $opt = get_option( 'bbp_core_settings' );
30
31 $current_action = current_action();
32
33 if ( $current_action === 'bbp_voting_cpt' ) {
34
35 // Using a custom hook for a custom post type
36 if ( ! $post_obj ) {
37 return;
38 }
39
40 $post = $post_obj;
41
42 } else {
43 $topic_post_type = bbp_get_topic_post_type();
44 $reply_post_type = bbp_get_reply_post_type();
45
46 if ( in_array( $current_action, [ 'bbp_theme_before_topic_title', 'bbp_template_before_lead_topic', 'bbp_theme_before_topic_content' ] ) ) {
47
48 $this_post_type = $topic_post_type;
49 }
50
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();
53 }
54
55 // Get the post.
56 if ( $this_post_type == $topic_post_type ) {
57 $post = bbpress()->topic_query->post;
58 }
59
60 if ( $this_post_type == $reply_post_type ) {
61 $post = bbpress()->reply_query->post;
62 }
63 }
64
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';
152
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' : '' ) . '">';
159
160 // Adds the word 'helpful' in red above the arrow.
161 $is_label = $opt['is_label'] ?? true;
162
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>';
166 }
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 }
202 }
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>';
207 }
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 }
217 }
218
219 // Sort by Votes
220
221 add_filter( 'bbp_has_topics_query', 'sort_bbpress_posts_by_votes', 99 );
222 add_filter( 'bbp_has_replies_query', 'sort_bbpress_posts_by_votes', 99 );
223
224 function sort_bbpress_posts_by_votes( $args = [] ) {
225 $opt = get_option( 'bbp_core_settings' );
226
227 $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 $forum_post_type = bbp_get_forum_post_type();
232 $topic_post_type = bbp_get_topic_post_type();
233 switch ( current_filter() ) {
234 case 'bbp_has_topics_query':
235 $this_post_type = $forum_post_type;
236 $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;
238 break;
239 case 'bbp_has_replies_query':
240 $this_post_type = $topic_post_type;
241 $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;
243 break;
244 default:
245 return $args;
246 }
247 // Do "allowed" checks
248 if ( isset( $_GET['bbp-voting-sort'] ) ) {
249 // Sort dropdown used, skip the rest of the checks
250 if ( $_GET['bbp-voting-sort'] === 'best' ) {
251 // Proceed with score sorting
252 } elseif ( $_GET['bbp-voting-sort'] === 'default' || $_GET['bbp-voting-sort'] === '' ) {
253 // bbp default non-score sort
254 return $args;
255 }
256 } else {
257 // Sort dropdown not used... check the settings
258 if ( ! empty( $post_setting ) ) {
259 // Forum-specific override is set (not Default)
260 if ( $post_setting === 'false' ) {
261 return $args;
262 }
263 } else {
264 // Use broad disable settings
265 if ( $broad_enable === false ) {
266 return $args;
267 }
268 }
269 if ( ! apply_filters( 'bbp_voting_allowed_on_forum', true, $forum_id ) ) {
270 return $args;
271 }
272 }
273 // Done with "allowed" checks... let's do this
274 // Filter the sort meta key. Default = bbp_voting_score
275 $sort_meta_key = apply_filters( 'bbp_voting_sort_meta_key', 'bbp_voting_score' );
276
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 // -----------------------------------
284
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 );
298 }
299
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'] );
311 $args['meta_query'] = [
312 'relation' => 'AND',
313 'score_clause' => [
314 'key' => $sort_meta_key,
315 'compare' => 'EXISTS',
316 // 'type' => 'DECIMAL' // https://stackoverflow.com/questions/30018711/wordpress-meta-query-not-working-with-decimal-type
317 ],
318 ];
319 if ( $sort_meta_key == 'bbp_voting_score' ) {
320 $args['meta_query']['score_clause']['type'] = 'NUMERIC';
321 }
322 $args['orderby'] = [
323 'post_type' => 'DESC',
324 'score_clause' => 'DESC',
325 ];
326 if ( $this_post_type === $topic_post_type ) {
327 // Add Date as another orderby for topics on a forum
328 $args['orderby']['date'] = 'ASC';
329 }
330 if ( $this_post_type === $forum_post_type ) {
331 // Add Freshness as another orderby for topics on a forum
332 $args['meta_query']['orderby_freshness'] = [
333 'key' => '_bbp_last_active_time',
334 'type' => 'DATETIME',
335 ];
336 $args['orderby']['orderby_freshness'] = 'DESC';
337 }
338 return $args;
339 }
340
341 add_action( 'init', 'bbp_voting_lead_topic' );
342 function bbp_voting_lead_topic() {
343 $opt = get_option( 'bbp_core_settings' );
344
345 if ( $opt['is_lead_topic_broken'] ?? false ) {
346 add_filter( 'bbp_show_lead_topic', '__return_true' );
347 }
348 }
349