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
bbp-core / includes / features / bbp-private-replies.php

bbp-private-replies.php in Forumax – AI Powered Advanced Community Forum Plugin 2.5.1, at includes/features/bbp-private-replies.php

359 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace features;
3
4 class Forumax_Private_Replies {
5
6 /**
7 * The capability required to view private posts.
8 *
9 * @since 1.3.3
10 *
11 * @var string $capability
12 */
13 public $capability = 'moderate';
14
15 /*
16 --------------------------------------------*
17 * Constructor
18 *--------------------------------------------*/
19
20 /**
21 * Initializes the plugin by setting filters, and administration functions.
22 */
23 function __construct() {
24
25 // Allow others to change the capability required to view private posts.
26 add_action( 'plugins_loaded', [ $this, 'filter_capability' ] );
27
28 // show the "Private Reply?" checkbox
29 add_action( 'frmx_reply_options', [ $this, 'checkbox' ] );
30
31 // save the private reply state
32 add_action( 'bbp_new_reply', [ $this, 'update_reply' ], 0, 6 );
33 add_action( 'bbp_edit_reply', [ $this, 'update_reply' ], 0, 6 );
34
35 // hide reply content
36 add_filter( 'bbp_get_reply_excerpt', [ $this, 'hide_reply' ], 999, 2 );
37 add_filter( 'bbp_get_reply_content', [ $this, 'hide_reply' ], 999, 2 );
38 add_filter( 'the_content', [ $this, 'hide_reply' ], 999 );
39 add_filter( 'the_excerpt', [ $this, 'hide_reply' ], 999 );
40
41 // prevent private replies from being sent in email subscriptions
42 add_filter( 'bbp_subscription_mail_message', [ $this, 'prevent_subscription_email' ], 999999, 3 );
43
44 // add a class name indicating the read status
45 add_filter( 'post_class', [ $this, 'reply_post_class' ] );
46
47 } // end constructor
48
49 /**
50 * Called during the plugins_loaded action to filter the capability
51 * required to view private replies.
52 *
53 * @since 1.3.3
54 *
55 * @return void
56 */
57 public function filter_capability() {
58 $this->capability = apply_filters( 'bbp_private_replies_capability', $this->capability );
59 }
60
61 /**
62 * Retrieves the no reply address.
63 *
64 * @since 1.3.3
65 *
66 * @return string
67 */
68 public function get_no_reply() {
69 return apply_filters( 'bbp_private_replies_no_reply_address', bbp_get_do_not_reply_address() );
70 }
71
72 /**
73 * Outputs the "Set as private reply" checkbox
74 *
75 * @since 1.0
76 *
77 * @return void
78 */
79 public function checkbox() {
80
81 ?>
82 <div class="frmx-option-row">
83 <div class="frmx-option-icon frmx-option-icon--private">
84 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
85 </div>
86 <label for="bbp_private_reply" class="frmx-option-label">
87 <?php if ( bbp_is_reply_edit() && ( get_the_author_meta( 'ID' ) != bbp_get_current_user_id() ) ) : ?>
88 <span class="frmx-option-title"><?php esc_html_e( 'Private reply', 'forumax' ); ?></span>
89 <span class="frmx-option-desc"><?php esc_html_e( "Set author's post as private", 'forumax' ); ?></span>
90 <?php else : ?>
91 <span class="frmx-option-title"><?php esc_html_e( 'Set as private reply', 'forumax' ); ?></span>
92 <span class="frmx-option-desc"><?php esc_html_e( 'Only visible to moderators and topic author', 'forumax' ); ?></span>
93 <?php endif; ?>
94 </label>
95 <label class="frmx-toggle" for="bbp_private_reply">
96 <input name="bbp_private_reply" id="bbp_private_reply" type="checkbox"<?php checked( '1', $this->is_private( bbp_get_reply_id() ) ); ?> value="1" tabindex="<?php bbp_tab_index(); ?>" />
97 <span class="frmx-toggle-slider"></span>
98 </label>
99 </div>
100 <?php
101
102 }
103
104
105 /**
106 * Stores the private state on reply creation and edit
107 *
108 * @since 1.0
109 *
110 * @param $reply_id int The ID of the reply
111 * @param $topic_id int The ID of the topic the reply belongs to
112 * @param $forum_id int The ID of the forum the topic belongs to
113 * @param $anonymous_data bool Are we posting as an anonymous user?
114 * @param $author_id int The ID of user creating the reply, or the ID of the replie's author during edit
115 * @param $is_edit bool Are we editing a reply?
116 *
117 * @return void
118 */
119 public function update_reply( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false ) {
120
121 if ( isset( $_POST['bbp_private_reply'] ) ) {
122 update_post_meta( $reply_id, '_bbp_reply_is_private', '1' );
123 } else {
124 delete_post_meta( $reply_id, '_bbp_reply_is_private' );
125 }
126
127 }
128
129
130 /**
131 * Determines if a reply is marked as private
132 *
133 * @since 1.0
134 *
135 * @param $reply_id int The ID of the reply
136 *
137 * @return bool
138 */
139 public function is_private( $reply_id = 0 ) {
140
141 $retval = false;
142
143 // Checking a specific reply id
144 if ( ! empty( $reply_id ) ) {
145 $reply = bbp_get_reply( $reply_id );
146 $reply_id = ! empty( $reply ) ? $reply->ID : 0;
147
148 // Using the global reply id
149 } elseif ( bbp_get_reply_id() ) {
150 $reply_id = bbp_get_reply_id();
151
152 // Use the current post id
153 } elseif ( ! bbp_get_reply_id() ) {
154 $reply_id = get_the_ID();
155 }
156
157 if ( ! empty( $reply_id ) ) {
158 $retval = get_post_meta( $reply_id, '_bbp_reply_is_private', true );
159 }
160
161 return (bool) apply_filters( 'bbp_reply_is_private', (bool) $retval, $reply_id );
162 }
163
164
165 /**
166 * Determines if the current user can view a private reply.
167 *
168 * @since 1.0
169 *
170 * @param int $reply_id The ID of the reply.
171 * @return bool
172 */
173 public function can_view_private_reply( $reply_id = 0 ) {
174
175 if ( empty( $reply_id ) ) {
176 $reply_id = bbp_get_reply_id( $reply_id );
177 }
178
179 $current_user = is_user_logged_in() ? wp_get_current_user() : false;
180 $topic_author = bbp_get_topic_author_id( bbp_get_reply_topic_id( $reply_id ) );
181 $reply_author = bbp_get_reply_author_id( $reply_id );
182
183 if ( ! empty( $current_user ) && $topic_author === $current_user->ID && user_can( $reply_author, $this->capability ) ) {
184 // Let the thread author view replies if the reply author is from a moderator.
185 return true;
186 }
187
188 if ( ! empty( $current_user ) && $reply_author === $current_user->ID ) {
189 // Let the reply author view their own reply.
190 return true;
191 }
192
193 if ( current_user_can( $this->capability ) ) {
194 // Let moderators view all replies.
195 return true;
196 }
197
198 return false;
199 }
200
201
202 /**
203 * Hides the reply content for users that do not have permission to view it
204 *
205 * @since 1.0
206 *
207 * @param $content string The content of the reply
208 * @param $reply_id int The ID of the reply
209 *
210 * @return string
211 */
212 public function hide_reply( $content = '', $reply_id = 0 ) {
213
214 // if bbPress isn't active, bail
215 if ( ! function_exists( 'bbp_get_reply_id' ) ) {
216 return $content;
217 }
218
219 if ( empty( $reply_id ) ) {
220 $reply_id = bbp_get_reply_id( $reply_id );
221 }
222
223 // the_content/the_excerpt run for every post; only replies can be private.
224 if ( empty( $reply_id ) ) {
225 return $content;
226 }
227
228 if ( $this->is_private( $reply_id ) ) {
229 if ( ! $this->can_view_private_reply( $reply_id ) ) {
230 $content = '<div class="alert alert-danger">' . esc_html__( 'This reply has been marked as private.', 'forumax' ) . '</div>';
231 }
232 }
233
234 return $content;
235 }
236
237
238 /**
239 * Prevents a New Reply notification from being sent if the user doesn't have permission to view it
240 *
241 * @since 1.0
242 *
243 * @param $message string The email message
244 * @param $reply_id int The ID of the reply
245 * @param $topic_id int The ID of the reply's topic
246 *
247 * @return mixed
248 */
249 public function prevent_subscription_email( $message, $reply_id, $topic_id ) {
250
251 if ( $this->is_private( $reply_id ) ) {
252 $this->subscription_email( $message, $reply_id, $topic_id );
253 return false;
254 }
255
256 return $message; // message unchanged
257 }
258
259
260 /**
261 * Sends the new reply notification email to moderators on private replies
262 *
263 * @since 1.2
264 *
265 * @param $message string The email message
266 * @param $reply_id int The ID of the reply
267 * @param $topic_id int The ID of the reply's topic
268 *
269 * @return void
270 */
271 public function subscription_email( $message, $reply_id, $topic_id ) {
272
273 if ( ! $this->is_private( $reply_id ) ) {
274
275 return false; // reply isn't private so do nothing
276
277 }
278
279 $topic_author = bbp_get_topic_author_id( $topic_id );
280 $reply_author = bbp_get_reply_author_id( $reply_id );
281 $reply_author_name = bbp_get_reply_author_display_name( $reply_id );
282
283 // Strip tags from text and setup mail data
284 $topic_title = wp_strip_all_tags( bbp_get_topic_title( $topic_id ) );
285 $reply_content = wp_strip_all_tags( bbp_get_reply_content( $reply_id ) );
286 $reply_url = bbp_get_reply_url( $reply_id );
287 $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
288 $subject = apply_filters( 'bbp_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $reply_id, $topic_id );
289
290 // Array to hold BCC's
291 $headers = [];
292
293 // Setup the From header
294 $headers[] = 'From: ' . get_bloginfo( 'name' ) . ' <' . $this->get_no_reply() . '>';
295
296 // Get topic subscribers and bail if empty
297 $user_ids = bbp_get_topic_subscribers( $topic_id, true );
298 if ( empty( $user_ids ) ) {
299 return false;
300 }
301
302 // Loop through users
303 foreach ( (array) $user_ids as $user_id ) {
304
305 // Don't send notifications to the person who made the post
306 if ( ! empty( $reply_author ) && (int) $user_id === (int) $reply_author ) {
307 continue;
308 }
309
310 $should_notify_op = user_can( $reply_author, $this->capability ) && (int) $topic_author === (int) $user_id;
311
312 if ( user_can( $user_id, $this->capability ) || $should_notify_op ) {
313
314 // Get email address of subscribed user
315 $headers[] = 'Bcc: ' . get_userdata( $user_id )->user_email;
316
317 }
318 }
319
320 wp_mail( $this->get_no_reply(), $subject, $message, $headers );
321 }
322
323
324 /**
325 * Adds a new class to replies that are marked as private
326 *
327 * @since 1.0
328 *
329 * @param $classes array An array of current class names
330 *
331 * @return bool
332 */
333 public function reply_post_class( $classes ) {
334
335 // if bbPress isn't active, bail
336 if ( ! function_exists( 'bbp_get_reply_id' ) ) {
337 return $classes;
338 }
339
340 $reply_id = bbp_get_reply_id();
341
342 // only apply the class to replies
343 if ( bbp_get_reply_post_type() != get_post_type( $reply_id ) ) {
344 return $classes;
345 }
346
347 if ( $this->is_private( $reply_id ) ) {
348 $classes[] = 'bbp-private-reply';
349 }
350
351 return $classes;
352 }
353
354 } // end class
355
356 // instantiate our plugin's class.
357 $GLOBALS['bbp_private_replies'] = new Forumax_Private_Replies();
358 ?>
359