PageRenderTime 37ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/bbpress/includes/topics/functions.php

https://bitbucket.org/Thane2376/death-edge.ru
PHP | 3538 lines | 1450 code | 715 blank | 1373 comment | 337 complexity | a8562137e608af5585f62a76307183a0 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-3.0, AGPL-1.0
  1. <?php
  2. /**
  3. * bbPress Topic Functions
  4. *
  5. * @package bbPress
  6. * @subpackage Functions
  7. */
  8. // Exit if accessed directly
  9. if ( !defined( 'ABSPATH' ) ) exit;
  10. /** Insert ********************************************************************/
  11. /**
  12. * A wrapper for wp_insert_post() that also includes the necessary meta values
  13. * for the topic to function properly.
  14. *
  15. * @since bbPress (r3349)
  16. *
  17. * @uses bbp_parse_args()
  18. * @uses bbp_get_topic_post_type()
  19. * @uses wp_insert_post()
  20. * @uses update_post_meta()
  21. *
  22. * @param array $topic_data Forum post data
  23. * @param arrap $topic_meta Forum meta data
  24. */
  25. function bbp_insert_topic( $topic_data = array(), $topic_meta = array() ) {
  26. // Parse arguments against default values
  27. $topic_data = bbp_parse_args( $topic_data, array(
  28. 'post_parent' => 0, // forum ID
  29. 'post_status' => bbp_get_public_status_id(),
  30. 'post_type' => bbp_get_topic_post_type(),
  31. 'post_author' => bbp_get_current_user_id(),
  32. 'post_password' => '',
  33. 'post_content' => '',
  34. 'post_title' => '',
  35. 'comment_status' => 'closed',
  36. 'menu_order' => 0,
  37. ), 'insert_topic' );
  38. // Insert topic
  39. $topic_id = wp_insert_post( $topic_data );
  40. // Bail if no topic was added
  41. if ( empty( $topic_id ) )
  42. return false;
  43. // Parse arguments against default values
  44. $topic_meta = bbp_parse_args( $topic_meta, array(
  45. 'author_ip' => bbp_current_author_ip(),
  46. 'forum_id' => 0,
  47. 'topic_id' => $topic_id,
  48. 'voice_count' => 1,
  49. 'reply_count' => 0,
  50. 'reply_count_hidden' => 0,
  51. 'last_reply_id' => 0,
  52. 'last_active_id' => $topic_id,
  53. 'last_active_time' => get_post_field( 'post_date', $topic_id, 'db' ),
  54. ), 'insert_topic_meta' );
  55. // Insert topic meta
  56. foreach ( $topic_meta as $meta_key => $meta_value ) {
  57. update_post_meta( $topic_id, '_bbp_' . $meta_key, $meta_value );
  58. }
  59. // Update the forum
  60. $forum_id = bbp_get_topic_forum_id( $topic_id );
  61. if ( !empty( $forum_id ) ) {
  62. bbp_update_forum( array( 'forum_id' => $forum_id ) );
  63. }
  64. // Return new topic ID
  65. return $topic_id;
  66. }
  67. /** Post Form Handlers ********************************************************/
  68. /**
  69. * Handles the front end topic submission
  70. *
  71. * @param string $action The requested action to compare this function to
  72. * @uses bbp_add_error() To add an error message
  73. * @uses bbp_verify_nonce_request() To verify the nonce and check the referer
  74. * @uses bbp_is_anonymous() To check if an anonymous post is being made
  75. * @uses current_user_can() To check if the current user can publish topic
  76. * @uses bbp_get_current_user_id() To get the current user id
  77. * @uses bbp_filter_anonymous_post_data() To filter anonymous data
  78. * @uses bbp_set_current_anonymous_user_data() To set the anonymous user cookies
  79. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
  80. * @uses esc_attr() For sanitization
  81. * @uses bbp_is_forum_category() To check if the forum is a category
  82. * @uses bbp_is_forum_closed() To check if the forum is closed
  83. * @uses bbp_is_forum_private() To check if the forum is private
  84. * @uses bbp_check_for_flood() To check for flooding
  85. * @uses bbp_check_for_duplicate() To check for duplicates
  86. * @uses bbp_get_topic_post_type() To get the topic post type
  87. * @uses remove_filter() To remove kses filters if needed
  88. * @uses apply_filters() Calls 'bbp_new_topic_pre_title' with the content
  89. * @uses apply_filters() Calls 'bbp_new_topic_pre_content' with the content
  90. * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors
  91. * @uses wp_insert_post() To insert the topic
  92. * @uses do_action() Calls 'bbp_new_topic' with the topic id, forum id,
  93. * anonymous data and reply author
  94. * @uses bbp_stick_topic() To stick or super stick the topic
  95. * @uses bbp_unstick_topic() To unstick the topic
  96. * @uses bbp_get_topic_permalink() To get the topic permalink
  97. * @uses wp_safe_redirect() To redirect to the topic link
  98. * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error
  99. * messages
  100. */
  101. function bbp_new_topic_handler( $action = '' ) {
  102. // Bail if action is not bbp-new-topic
  103. if ( 'bbp-new-topic' !== $action )
  104. return;
  105. // Nonce check
  106. if ( ! bbp_verify_nonce_request( 'bbp-new-topic' ) ) {
  107. bbp_add_error( 'bbp_new_topic_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  108. return;
  109. }
  110. // Define local variable(s)
  111. $view_all = false;
  112. $forum_id = $topic_author = $anonymous_data = 0;
  113. $topic_title = $topic_content = '';
  114. $terms = array( bbp_get_topic_tag_tax_id() => array() );
  115. /** Topic Author **********************************************************/
  116. // User is anonymous
  117. if ( bbp_is_anonymous() ) {
  118. // Filter anonymous data
  119. $anonymous_data = bbp_filter_anonymous_post_data();
  120. // Anonymous data checks out, so set cookies, etc...
  121. if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
  122. bbp_set_current_anonymous_user_data( $anonymous_data );
  123. }
  124. // User is logged in
  125. } else {
  126. // User cannot create topics
  127. if ( !current_user_can( 'publish_topics' ) ) {
  128. bbp_add_error( 'bbp_topic_permissions', __( '<strong>ERROR</strong>: You do not have permission to create new topics.', 'bbpress' ) );
  129. return;
  130. }
  131. // Topic author is current user
  132. $topic_author = bbp_get_current_user_id();
  133. }
  134. // Remove kses filters from title and content for capable users and if the nonce is verified
  135. if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_topic'] ) && wp_create_nonce( 'bbp-unfiltered-html-topic_new' ) === $_POST['_bbp_unfiltered_html_topic'] ) {
  136. remove_filter( 'bbp_new_topic_pre_title', 'wp_filter_kses' );
  137. remove_filter( 'bbp_new_topic_pre_content', 'bbp_encode_bad', 10 );
  138. remove_filter( 'bbp_new_topic_pre_content', 'bbp_filter_kses', 30 );
  139. }
  140. /** Topic Title ***********************************************************/
  141. if ( !empty( $_POST['bbp_topic_title'] ) )
  142. $topic_title = esc_attr( strip_tags( $_POST['bbp_topic_title'] ) );
  143. // Filter and sanitize
  144. $topic_title = apply_filters( 'bbp_new_topic_pre_title', $topic_title );
  145. // No topic title
  146. if ( empty( $topic_title ) )
  147. bbp_add_error( 'bbp_topic_title', __( '<strong>ERROR</strong>: Your topic needs a title.', 'bbpress' ) );
  148. /** Topic Content *********************************************************/
  149. if ( !empty( $_POST['bbp_topic_content'] ) )
  150. $topic_content = $_POST['bbp_topic_content'];
  151. // Filter and sanitize
  152. $topic_content = apply_filters( 'bbp_new_topic_pre_content', $topic_content );
  153. // No topic content
  154. if ( empty( $topic_content ) )
  155. bbp_add_error( 'bbp_topic_content', __( '<strong>ERROR</strong>: Your topic cannot be empty.', 'bbpress' ) );
  156. /** Topic Forum ***********************************************************/
  157. // Error check the POST'ed topic id
  158. if ( isset( $_POST['bbp_forum_id'] ) ) {
  159. // Empty Forum id was passed
  160. if ( empty( $_POST['bbp_forum_id'] ) ) {
  161. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
  162. // Forum id is not a number
  163. } elseif ( ! is_numeric( $_POST['bbp_forum_id'] ) ) {
  164. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID must be a number.', 'bbpress' ) );
  165. // Forum id might be valid
  166. } else {
  167. // Get the forum id
  168. $posted_forum_id = intval( $_POST['bbp_forum_id'] );
  169. // Forum id is empty
  170. if ( 0 === $posted_forum_id ) {
  171. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
  172. // Forum id is a negative number
  173. } elseif ( 0 > $posted_forum_id ) {
  174. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID cannot be a negative number.', 'bbpress' ) );
  175. // Forum does not exist
  176. } elseif ( ! bbp_get_forum( $posted_forum_id ) ) {
  177. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum does not exist.', 'bbpress' ) );
  178. // Use the POST'ed forum id
  179. } else {
  180. $forum_id = $posted_forum_id;
  181. }
  182. }
  183. }
  184. // Forum exists
  185. if ( !empty( $forum_id ) ) {
  186. // Forum is a category
  187. if ( bbp_is_forum_category( $forum_id ) ) {
  188. bbp_add_error( 'bbp_new_topic_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No topics can be created in this forum.', 'bbpress' ) );
  189. // Forum is not a category
  190. } else {
  191. // Forum is closed and user cannot access
  192. if ( bbp_is_forum_closed( $forum_id ) && !current_user_can( 'edit_forum', $forum_id ) ) {
  193. bbp_add_error( 'bbp_new_topic_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new topics.', 'bbpress' ) );
  194. }
  195. // Forum is private and user cannot access
  196. if ( bbp_is_forum_private( $forum_id ) ) {
  197. if ( !current_user_can( 'read_private_forums' ) ) {
  198. bbp_add_error( 'bbp_new_topic_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
  199. }
  200. // Forum is hidden and user cannot access
  201. } elseif ( bbp_is_forum_hidden( $forum_id ) ) {
  202. if ( !current_user_can( 'read_hidden_forums' ) ) {
  203. bbp_add_error( 'bbp_new_topic_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
  204. }
  205. }
  206. }
  207. }
  208. /** Topic Flooding ********************************************************/
  209. if ( !bbp_check_for_flood( $anonymous_data, $topic_author ) )
  210. bbp_add_error( 'bbp_topic_flood', __( '<strong>ERROR</strong>: Slow down; you move too fast.', 'bbpress' ) );
  211. /** Topic Duplicate *******************************************************/
  212. if ( !bbp_check_for_duplicate( array( 'post_type' => bbp_get_topic_post_type(), 'post_author' => $topic_author, 'post_content' => $topic_content, 'anonymous_data' => $anonymous_data ) ) )
  213. bbp_add_error( 'bbp_topic_duplicate', __( '<strong>ERROR</strong>: Duplicate topic detected; it looks as though you&#8217;ve already said that!', 'bbpress' ) );
  214. /** Topic Blacklist *******************************************************/
  215. if ( !bbp_check_for_blacklist( $anonymous_data, $topic_author, $topic_title, $topic_content ) )
  216. bbp_add_error( 'bbp_topic_blacklist', __( '<strong>ERROR</strong>: Your topic cannot be created at this time.', 'bbpress' ) );
  217. /** Topic Status **********************************************************/
  218. // Maybe put into moderation
  219. if ( !bbp_check_for_moderation( $anonymous_data, $topic_author, $topic_title, $topic_content ) ) {
  220. $topic_status = bbp_get_pending_status_id();
  221. // Check a whitelist of possible topic status ID's
  222. } elseif ( !empty( $_POST['bbp_topic_status'] ) && in_array( $_POST['bbp_topic_status'], array_keys( bbp_get_topic_statuses() ) ) ) {
  223. $topic_status = $_POST['bbp_topic_status'];
  224. // Default to published if nothing else
  225. } else {
  226. $topic_status = bbp_get_public_status_id();
  227. }
  228. /** Topic Tags ************************************************************/
  229. if ( bbp_allow_topic_tags() && !empty( $_POST['bbp_topic_tags'] ) ) {
  230. // Escape tag input
  231. $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
  232. // Explode by comma
  233. if ( strstr( $terms, ',' ) ) {
  234. $terms = explode( ',', $terms );
  235. }
  236. // Add topic tag ID as main key
  237. $terms = array( bbp_get_topic_tag_tax_id() => $terms );
  238. }
  239. /** Additional Actions (Before Save) **************************************/
  240. do_action( 'bbp_new_topic_pre_extras', $forum_id );
  241. // Bail if errors
  242. if ( bbp_has_errors() )
  243. return;
  244. /** No Errors *************************************************************/
  245. // Add the content of the form to $topic_data as an array.
  246. // Just in time manipulation of topic data before being created
  247. $topic_data = apply_filters( 'bbp_new_topic_pre_insert', array(
  248. 'post_author' => $topic_author,
  249. 'post_title' => $topic_title,
  250. 'post_content' => $topic_content,
  251. 'post_status' => $topic_status,
  252. 'post_parent' => $forum_id,
  253. 'post_type' => bbp_get_topic_post_type(),
  254. 'tax_input' => $terms,
  255. 'comment_status' => 'closed'
  256. ) );
  257. // Insert topic
  258. $topic_id = wp_insert_post( $topic_data );
  259. /** No Errors *************************************************************/
  260. if ( !empty( $topic_id ) && !is_wp_error( $topic_id ) ) {
  261. /** Trash Check *******************************************************/
  262. // If the forum is trash, or the topic_status is switched to
  263. // trash, trash it properly
  264. if ( ( get_post_field( 'post_status', $forum_id ) === bbp_get_trash_status_id() ) || ( $topic_data['post_status'] === bbp_get_trash_status_id() ) ) {
  265. // Trash the reply
  266. wp_trash_post( $topic_id );
  267. // Force view=all
  268. $view_all = true;
  269. }
  270. /** Spam Check ********************************************************/
  271. // If reply or topic are spam, officially spam this reply
  272. if ( $topic_data['post_status'] === bbp_get_spam_status_id() ) {
  273. add_post_meta( $topic_id, '_bbp_spam_meta_status', bbp_get_public_status_id() );
  274. // Force view=all
  275. $view_all = true;
  276. }
  277. /** Update counts, etc... *********************************************/
  278. do_action( 'bbp_new_topic', $topic_id, $forum_id, $anonymous_data, $topic_author );
  279. /** Stickies **********************************************************/
  280. // Sticky check after 'bbp_new_topic' action so forum ID meta is set
  281. if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) {
  282. // What's the caps?
  283. if ( current_user_can( 'moderate' ) ) {
  284. // What's the haps?
  285. switch ( $_POST['bbp_stick_topic'] ) {
  286. // Sticky in this forum
  287. case 'stick' :
  288. bbp_stick_topic( $topic_id );
  289. break;
  290. // Super sticky in all forums
  291. case 'super' :
  292. bbp_stick_topic( $topic_id, true );
  293. break;
  294. // We can avoid this as it is a new topic
  295. case 'unstick' :
  296. default :
  297. break;
  298. }
  299. }
  300. }
  301. /** Additional Actions (After Save) ***********************************/
  302. do_action( 'bbp_new_topic_post_extras', $topic_id );
  303. /** Redirect **********************************************************/
  304. // Redirect to
  305. $redirect_to = bbp_get_redirect_to();
  306. // Get the topic URL
  307. $redirect_url = bbp_get_topic_permalink( $topic_id, $redirect_to );
  308. // Add view all?
  309. if ( bbp_get_view_all() || !empty( $view_all ) ) {
  310. // User can moderate, so redirect to topic with view all set
  311. if ( current_user_can( 'moderate' ) ) {
  312. $redirect_url = bbp_add_view_all( $redirect_url );
  313. // User cannot moderate, so redirect to forum
  314. } else {
  315. $redirect_url = bbp_get_forum_permalink( $forum_id );
  316. }
  317. }
  318. // Allow to be filtered
  319. $redirect_url = apply_filters( 'bbp_new_topic_redirect_to', $redirect_url, $redirect_to, $topic_id );
  320. /** Successful Save ***************************************************/
  321. // Redirect back to new topic
  322. wp_safe_redirect( $redirect_url );
  323. // For good measure
  324. exit();
  325. // Errors
  326. } else {
  327. $append_error = ( is_wp_error( $topic_id ) && $topic_id->get_error_message() ) ? $topic_id->get_error_message() . ' ' : '';
  328. bbp_add_error( 'bbp_topic_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your topic:' . $append_error, 'bbpress' ) );
  329. }
  330. }
  331. /**
  332. * Handles the front end edit topic submission
  333. *
  334. * @param string $action The requested action to compare this function to
  335. * @uses bbp_add_error() To add an error message
  336. * @uses bbp_get_topic() To get the topic
  337. * @uses bbp_verify_nonce_request() To verify the nonce and check the request
  338. * @uses bbp_is_topic_anonymous() To check if topic is by an anonymous user
  339. * @uses current_user_can() To check if the current user can edit the topic
  340. * @uses bbp_filter_anonymous_post_data() To filter anonymous data
  341. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
  342. * @uses esc_attr() For sanitization
  343. * @uses bbp_is_forum_category() To check if the forum is a category
  344. * @uses bbp_is_forum_closed() To check if the forum is closed
  345. * @uses bbp_is_forum_private() To check if the forum is private
  346. * @uses remove_filter() To remove kses filters if needed
  347. * @uses apply_filters() Calls 'bbp_edit_topic_pre_title' with the title and
  348. * topic id
  349. * @uses apply_filters() Calls 'bbp_edit_topic_pre_content' with the content
  350. * and topic id
  351. * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors
  352. * @uses wp_save_post_revision() To save a topic revision
  353. * @uses bbp_update_topic_revision_log() To update the topic revision log
  354. * @uses bbp_stick_topic() To stick or super stick the topic
  355. * @uses bbp_unstick_topic() To unstick the topic
  356. * @uses wp_update_post() To update the topic
  357. * @uses do_action() Calls 'bbp_edit_topic' with the topic id, forum id,
  358. * anonymous data and reply author
  359. * @uses bbp_move_topic_handler() To handle movement of a topic from one forum
  360. * to another
  361. * @uses bbp_get_topic_permalink() To get the topic permalink
  362. * @uses wp_safe_redirect() To redirect to the topic link
  363. * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error
  364. * messages
  365. */
  366. function bbp_edit_topic_handler( $action = '' ) {
  367. // Bail if action is not bbp-edit-topic
  368. if ( 'bbp-edit-topic' !== $action )
  369. return;
  370. // Define local variable(s)
  371. $revisions_removed = false;
  372. $topic = $topic_id = $topic_author = $forum_id = $anonymous_data = 0;
  373. $topic_title = $topic_content = $topic_edit_reason = '';
  374. /** Topic *****************************************************************/
  375. // Topic id was not passed
  376. if ( empty( $_POST['bbp_topic_id'] ) ) {
  377. bbp_add_error( 'bbp_edit_topic_id', __( '<strong>ERROR</strong>: Topic ID not found.', 'bbpress' ) );
  378. return;
  379. // Topic id was passed
  380. } elseif ( is_numeric( $_POST['bbp_topic_id'] ) ) {
  381. $topic_id = (int) $_POST['bbp_topic_id'];
  382. $topic = bbp_get_topic( $topic_id );
  383. }
  384. // Topic does not exist
  385. if ( empty( $topic ) ) {
  386. bbp_add_error( 'bbp_edit_topic_not_found', __( '<strong>ERROR</strong>: The topic you want to edit was not found.', 'bbpress' ) );
  387. return;
  388. // Topic exists
  389. } else {
  390. // Check users ability to create new topic
  391. if ( ! bbp_is_topic_anonymous( $topic_id ) ) {
  392. // User cannot edit this topic
  393. if ( !current_user_can( 'edit_topic', $topic_id ) ) {
  394. bbp_add_error( 'bbp_edit_topic_permissions', __( '<strong>ERROR</strong>: You do not have permission to edit that topic.', 'bbpress' ) );
  395. }
  396. // Set topic author
  397. $topic_author = bbp_get_topic_author_id( $topic_id );
  398. // It is an anonymous post
  399. } else {
  400. // Filter anonymous data
  401. $anonymous_data = bbp_filter_anonymous_post_data( array(), true );
  402. }
  403. }
  404. // Nonce check
  405. if ( ! bbp_verify_nonce_request( 'bbp-edit-topic_' . $topic_id ) ) {
  406. bbp_add_error( 'bbp_edit_topic_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  407. return;
  408. }
  409. // Remove kses filters from title and content for capable users and if the nonce is verified
  410. if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_topic'] ) && ( wp_create_nonce( 'bbp-unfiltered-html-topic_' . $topic_id ) === $_POST['_bbp_unfiltered_html_topic'] ) ) {
  411. remove_filter( 'bbp_edit_topic_pre_title', 'wp_filter_kses' );
  412. remove_filter( 'bbp_edit_topic_pre_content', 'bbp_encode_bad', 10 );
  413. remove_filter( 'bbp_edit_topic_pre_content', 'bbp_filter_kses', 30 );
  414. }
  415. /** Topic Forum ***********************************************************/
  416. // Forum id was not passed
  417. if ( empty( $_POST['bbp_forum_id'] ) ) {
  418. bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
  419. // Forum id was passed
  420. } elseif ( is_numeric( $_POST['bbp_forum_id'] ) ) {
  421. $forum_id = (int) $_POST['bbp_forum_id'];
  422. }
  423. // Current forum this topic is in
  424. $current_forum_id = bbp_get_topic_forum_id( $topic_id );
  425. // Forum exists
  426. if ( !empty( $forum_id ) && ( $forum_id !== $current_forum_id ) ) {
  427. // Forum is a category
  428. if ( bbp_is_forum_category( $forum_id ) ) {
  429. bbp_add_error( 'bbp_edit_topic_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No topics can be created in it.', 'bbpress' ) );
  430. // Forum is not a category
  431. } else {
  432. // Forum is closed and user cannot access
  433. if ( bbp_is_forum_closed( $forum_id ) && !current_user_can( 'edit_forum', $forum_id ) ) {
  434. bbp_add_error( 'bbp_edit_topic_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new topics.', 'bbpress' ) );
  435. }
  436. // Forum is private and user cannot access
  437. if ( bbp_is_forum_private( $forum_id ) ) {
  438. if ( !current_user_can( 'read_private_forums' ) ) {
  439. bbp_add_error( 'bbp_edit_topic_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
  440. }
  441. // Forum is hidden and user cannot access
  442. } elseif ( bbp_is_forum_hidden( $forum_id ) ) {
  443. if ( !current_user_can( 'read_hidden_forums' ) ) {
  444. bbp_add_error( 'bbp_edit_topic_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
  445. }
  446. }
  447. }
  448. }
  449. /** Topic Title ***********************************************************/
  450. if ( !empty( $_POST['bbp_topic_title'] ) )
  451. $topic_title = esc_attr( strip_tags( $_POST['bbp_topic_title'] ) );
  452. // Filter and sanitize
  453. $topic_title = apply_filters( 'bbp_edit_topic_pre_title', $topic_title, $topic_id );
  454. // No topic title
  455. if ( empty( $topic_title ) )
  456. bbp_add_error( 'bbp_edit_topic_title', __( '<strong>ERROR</strong>: Your topic needs a title.', 'bbpress' ) );
  457. /** Topic Content *********************************************************/
  458. if ( !empty( $_POST['bbp_topic_content'] ) )
  459. $topic_content = $_POST['bbp_topic_content'];
  460. // Filter and sanitize
  461. $topic_content = apply_filters( 'bbp_edit_topic_pre_content', $topic_content, $topic_id );
  462. // No topic content
  463. if ( empty( $topic_content ) )
  464. bbp_add_error( 'bbp_edit_topic_content', __( '<strong>ERROR</strong>: Your topic cannot be empty.', 'bbpress' ) );
  465. /** Topic Blacklist *******************************************************/
  466. if ( !bbp_check_for_blacklist( $anonymous_data, $topic_author, $topic_title, $topic_content ) )
  467. bbp_add_error( 'bbp_topic_blacklist', __( '<strong>ERROR</strong>: Your topic cannot be edited at this time.', 'bbpress' ) );
  468. /** Topic Status **********************************************************/
  469. // Maybe put into moderation
  470. if ( !bbp_check_for_moderation( $anonymous_data, $topic_author, $topic_title, $topic_content ) ) {
  471. // Set post status to pending if public or closed
  472. if ( in_array( $topic->post_status, array( bbp_get_public_status_id(), bbp_get_closed_status_id() ) ) ) {
  473. $topic_status = bbp_get_pending_status_id();
  474. }
  475. // Check a whitelist of possible topic status ID's
  476. } elseif ( !empty( $_POST['bbp_topic_status'] ) && in_array( $_POST['bbp_topic_status'], array_keys( bbp_get_topic_statuses() ) ) ) {
  477. $topic_status = $_POST['bbp_topic_status'];
  478. // Use existing post_status
  479. } else {
  480. $topic_status = $topic->post_status;
  481. }
  482. /** Topic Tags ************************************************************/
  483. // Either replace terms
  484. if ( bbp_allow_topic_tags() && current_user_can( 'assign_topic_tags' ) && ! empty( $_POST['bbp_topic_tags'] ) ) {
  485. // Escape tag input
  486. $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
  487. // Explode by comma
  488. if ( strstr( $terms, ',' ) )
  489. $terms = explode( ',', $terms );
  490. // Add topic tag ID as main key
  491. $terms = array( bbp_get_topic_tag_tax_id() => $terms );
  492. // ...or remove them.
  493. } elseif ( isset( $_POST['bbp_topic_tags'] ) ) {
  494. $terms = array( bbp_get_topic_tag_tax_id() => array() );
  495. // Existing terms
  496. } else {
  497. $terms = array( bbp_get_topic_tag_tax_id() => explode( ',', bbp_get_topic_tag_names( $topic_id, ',' ) ) );
  498. }
  499. /** Additional Actions (Before Save) **************************************/
  500. do_action( 'bbp_edit_topic_pre_extras', $topic_id );
  501. // Bail if errors
  502. if ( bbp_has_errors() )
  503. return;
  504. /** No Errors *************************************************************/
  505. // Add the content of the form to $topic_data as an array
  506. // Just in time manipulation of topic data before being edited
  507. $topic_data = apply_filters( 'bbp_edit_topic_pre_insert', array(
  508. 'ID' => $topic_id,
  509. 'post_title' => $topic_title,
  510. 'post_content' => $topic_content,
  511. 'post_status' => $topic_status,
  512. 'post_parent' => $forum_id,
  513. 'post_author' => $topic_author,
  514. 'post_type' => bbp_get_topic_post_type(),
  515. 'tax_input' => $terms,
  516. ) );
  517. // Toggle revisions to avoid duplicates
  518. if ( post_type_supports( bbp_get_topic_post_type(), 'revisions' ) ) {
  519. $revisions_removed = true;
  520. remove_post_type_support( bbp_get_topic_post_type(), 'revisions' );
  521. }
  522. // Insert topic
  523. $topic_id = wp_update_post( $topic_data );
  524. // Toggle revisions back on
  525. if ( true === $revisions_removed ) {
  526. $revisions_removed = false;
  527. add_post_type_support( bbp_get_topic_post_type(), 'revisions' );
  528. }
  529. /** No Errors *************************************************************/
  530. if ( !empty( $topic_id ) && !is_wp_error( $topic_id ) ) {
  531. // Update counts, etc...
  532. do_action( 'bbp_edit_topic', $topic_id, $forum_id, $anonymous_data, $topic_author , true /* Is edit */ );
  533. /** Revisions *********************************************************/
  534. // Revision Reason
  535. if ( !empty( $_POST['bbp_topic_edit_reason'] ) ) {
  536. $topic_edit_reason = esc_attr( strip_tags( $_POST['bbp_topic_edit_reason'] ) );
  537. }
  538. // Update revision log
  539. if ( !empty( $_POST['bbp_log_topic_edit'] ) && ( "1" === $_POST['bbp_log_topic_edit'] ) ) {
  540. $revision_id = wp_save_post_revision( $topic_id );
  541. if ( ! empty( $revision_id ) ) {
  542. bbp_update_topic_revision_log( array(
  543. 'topic_id' => $topic_id,
  544. 'revision_id' => $revision_id,
  545. 'author_id' => bbp_get_current_user_id(),
  546. 'reason' => $topic_edit_reason
  547. ) );
  548. }
  549. }
  550. /** Move Topic ********************************************************/
  551. // If the new forum id is not equal to the old forum id, run the
  552. // bbp_move_topic action and pass the topic's forum id as the
  553. // first arg and topic id as the second to update counts.
  554. if ( $forum_id !== $topic->post_parent ) {
  555. bbp_move_topic_handler( $topic_id, $topic->post_parent, $forum_id );
  556. }
  557. /** Stickies **********************************************************/
  558. if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array_keys( bbp_get_topic_types() ) ) ) {
  559. // What's the caps?
  560. if ( current_user_can( 'moderate' ) ) {
  561. // What's the haps?
  562. switch ( $_POST['bbp_stick_topic'] ) {
  563. // Sticky in forum
  564. case 'stick' :
  565. bbp_stick_topic( $topic_id );
  566. break;
  567. // Sticky in all forums
  568. case 'super' :
  569. bbp_stick_topic( $topic_id, true );
  570. break;
  571. // Normal
  572. case 'unstick' :
  573. default :
  574. bbp_unstick_topic( $topic_id );
  575. break;
  576. }
  577. }
  578. }
  579. /** Additional Actions (After Save) ***********************************/
  580. do_action( 'bbp_edit_topic_post_extras', $topic_id );
  581. /** Redirect **********************************************************/
  582. // Redirect to
  583. $redirect_to = bbp_get_redirect_to();
  584. // View all?
  585. $view_all = bbp_get_view_all();
  586. // Get the topic URL
  587. $topic_url = bbp_get_topic_permalink( $topic_id, $redirect_to );
  588. // Add view all?
  589. if ( !empty( $view_all ) )
  590. $topic_url = bbp_add_view_all( $topic_url );
  591. // Allow to be filtered
  592. $topic_url = apply_filters( 'bbp_edit_topic_redirect_to', $topic_url, $view_all, $redirect_to );
  593. /** Successful Edit ***************************************************/
  594. // Redirect back to new topic
  595. wp_safe_redirect( $topic_url );
  596. // For good measure
  597. exit();
  598. /** Errors ****************************************************************/
  599. } else {
  600. $append_error = ( is_wp_error( $topic_id ) && $topic_id->get_error_message() ) ? $topic_id->get_error_message() . ' ' : '';
  601. bbp_add_error( 'bbp_topic_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your topic:' . $append_error . 'Please try again.', 'bbpress' ) );
  602. }
  603. }
  604. /**
  605. * Handle all the extra meta stuff from posting a new topic
  606. *
  607. * @param int $topic_id Optional. Topic id
  608. * @param int $forum_id Optional. Forum id
  609. * @param bool|array $anonymous_data Optional logged-out user data.
  610. * @param int $author_id Author id
  611. * @param bool $is_edit Optional. Is the post being edited? Defaults to false.
  612. * @uses bbp_get_topic_id() To get the topic id
  613. * @uses bbp_get_forum_id() To get the forum id
  614. * @uses bbp_get_current_user_id() To get the current user id
  615. * @yses bbp_get_topic_forum_id() To get the topic forum id
  616. * @uses update_post_meta() To update the topic metas
  617. * @uses set_transient() To update the flood check transient for the ip
  618. * @uses bbp_update_user_last_posted() To update the users last posted time
  619. * @uses bbp_is_subscriptions_active() To check if the subscriptions feature is
  620. * activated or not
  621. * @uses bbp_is_user_subscribed() To check if the user is subscribed
  622. * @uses bbp_remove_user_subscription() To remove the user's subscription
  623. * @uses bbp_add_user_subscription() To add the user's subscription
  624. * @uses bbp_update_topic_forum_id() To update the topic's forum id
  625. * @uses bbp_update_topic_topic_id() To update the topic's topic id
  626. * @uses bbp_update_topic_last_reply_id() To update the last reply id topic meta
  627. * @uses bbp_update_topic_last_active_id() To update the topic last active id
  628. * @uses bbp_update_topic_last_active_time() To update the last active topic meta
  629. * @uses bbp_update_topic_reply_count() To update the topic reply count
  630. * @uses bbp_update_topic_reply_count_hidden() To udpate the topic hidden reply count
  631. * @uses bbp_update_topic_voice_count() To update the topic voice count
  632. * @uses bbp_update_topic_walker() To udpate the topic's ancestors
  633. */
  634. function bbp_update_topic( $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false ) {
  635. // Validate the ID's passed from 'bbp_new_topic' action
  636. $topic_id = bbp_get_topic_id( $topic_id );
  637. $forum_id = bbp_get_forum_id( $forum_id );
  638. // Bail if there is no topic
  639. if ( empty( $topic_id ) )
  640. return;
  641. // Check author_id
  642. if ( empty( $author_id ) )
  643. $author_id = bbp_get_current_user_id();
  644. // Check forum_id
  645. if ( empty( $forum_id ) )
  646. $forum_id = bbp_get_topic_forum_id( $topic_id );
  647. // If anonymous post, store name, email, website and ip in post_meta.
  648. // It expects anonymous_data to be sanitized.
  649. // Check bbp_filter_anonymous_post_data() for sanitization.
  650. if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
  651. // Parse arguments against default values
  652. $r = bbp_parse_args( $anonymous_data, array(
  653. 'bbp_anonymous_name' => '',
  654. 'bbp_anonymous_email' => '',
  655. 'bbp_anonymous_website' => '',
  656. ), 'update_topic' );
  657. // Update all anonymous metas
  658. foreach ( $r as $anon_key => $anon_value ) {
  659. update_post_meta( $topic_id, '_' . $anon_key, (string) $anon_value, false );
  660. }
  661. // Set transient for throttle check (only on new, not edit)
  662. if ( empty( $is_edit ) ) {
  663. set_transient( '_bbp_' . bbp_current_author_ip() . '_last_posted', time() );
  664. }
  665. } else {
  666. if ( empty( $is_edit ) && !current_user_can( 'throttle' ) ) {
  667. bbp_update_user_last_posted( $author_id );
  668. }
  669. }
  670. // Handle Subscription Checkbox
  671. if ( bbp_is_subscriptions_active() && !empty( $author_id ) ) {
  672. $subscribed = bbp_is_user_subscribed( $author_id, $topic_id );
  673. $subscheck = ( !empty( $_POST['bbp_topic_subscription'] ) && ( 'bbp_subscribe' === $_POST['bbp_topic_subscription'] ) ) ? true : false;
  674. // Subscribed and unsubscribing
  675. if ( true === $subscribed && false === $subscheck ) {
  676. bbp_remove_user_subscription( $author_id, $topic_id );
  677. // Subscribing
  678. } elseif ( false === $subscribed && true === $subscheck ) {
  679. bbp_add_user_subscription( $author_id, $topic_id );
  680. }
  681. }
  682. // Forum topic meta
  683. bbp_update_topic_forum_id( $topic_id, $forum_id );
  684. bbp_update_topic_topic_id( $topic_id, $topic_id );
  685. // Update associated topic values if this is a new topic
  686. if ( empty( $is_edit ) ) {
  687. // Update poster IP if not editing
  688. update_post_meta( $topic_id, '_bbp_author_ip', bbp_current_author_ip(), false );
  689. // Last active time
  690. $last_active = current_time( 'mysql' );
  691. // Reply topic meta
  692. bbp_update_topic_last_reply_id ( $topic_id, 0 );
  693. bbp_update_topic_last_active_id ( $topic_id, $topic_id );
  694. bbp_update_topic_last_active_time ( $topic_id, $last_active );
  695. bbp_update_topic_reply_count ( $topic_id, 0 );
  696. bbp_update_topic_reply_count_hidden ( $topic_id, 0 );
  697. bbp_update_topic_voice_count ( $topic_id );
  698. // Walk up ancestors and do the dirty work
  699. bbp_update_topic_walker( $topic_id, $last_active, $forum_id, 0, false );
  700. }
  701. }
  702. /**
  703. * Walks up the post_parent tree from the current topic_id, and updates the
  704. * counts of forums above it. This calls a few internal functions that all run
  705. * manual queries against the database to get their results. As such, this
  706. * function can be costly to run but is necessary to keep everything accurate.
  707. *
  708. * @since bbPress (r2800)
  709. * @param int $topic_id Topic id
  710. * @param string $last_active_time Optional. Last active time
  711. * @param int $forum_id Optional. Forum id
  712. * @param int $reply_id Optional. Reply id
  713. * @param bool $refresh Reset all the previous parameters? Defaults to true.
  714. * @uses bbp_get_topic_id() To get the topic id
  715. * @uses bbp_get_topic_forum_id() To get the topic forum id
  716. * @uses get_post_ancestors() To get the topic's ancestors
  717. * @uses bbp_is_forum() To check if the ancestor is a forum
  718. * @uses bbp_update_forum() To update the forum
  719. */
  720. function bbp_update_topic_walker( $topic_id, $last_active_time = '', $forum_id = 0, $reply_id = 0, $refresh = true ) {
  721. // Validate topic_id
  722. $topic_id = bbp_get_topic_id( $topic_id );
  723. // Define local variable(s)
  724. $active_id = 0;
  725. // Topic was passed
  726. if ( !empty( $topic_id ) ) {
  727. // Get the forum ID if none was passed
  728. if ( empty( $forum_id ) ) {
  729. $forum_id = bbp_get_topic_forum_id( $topic_id );
  730. }
  731. // Set the active_id based on topic_id/reply_id
  732. $active_id = empty( $reply_id ) ? $topic_id : $reply_id;
  733. }
  734. // Get topic ancestors
  735. $ancestors = array_values( array_unique( array_merge( array( $forum_id ), (array) get_post_ancestors( $topic_id ) ) ) );
  736. // Topic status
  737. $topic_status = get_post_status( $topic_id );
  738. // If we want a full refresh, unset any of the possibly passed variables
  739. if ( true === $refresh ) {
  740. $forum_id = $topic_id = $reply_id = $active_id = $last_active_time = 0;
  741. $topic_status = bbp_get_public_status_id();
  742. }
  743. // Loop through ancestors
  744. if ( !empty( $ancestors ) ) {
  745. foreach ( $ancestors as $ancestor ) {
  746. // If ancestor is a forum, update counts
  747. if ( bbp_is_forum( $ancestor ) ) {
  748. // Update the forum
  749. bbp_update_forum( array(
  750. 'forum_id' => $ancestor,
  751. 'last_topic_id' => $topic_id,
  752. 'last_reply_id' => $reply_id,
  753. 'last_active_id' => $active_id,
  754. 'last_active_time' => 0,
  755. 'last_active_status' => $topic_status
  756. ) );
  757. }
  758. }
  759. }
  760. }
  761. /**
  762. * Handle the moving of a topic from one forum to another. This includes walking
  763. * up the old and new branches and updating the counts.
  764. *
  765. * @param int $topic_id Topic id
  766. * @param int $old_forum_id Old forum id
  767. * @param int $new_forum_id New forum id
  768. * @uses bbp_get_topic_id() To get the topic id
  769. * @uses bbp_get_forum_id() To get the forum id
  770. * @uses bbp_get_stickies() To get the old forums sticky topics
  771. * @uses delete_post_meta() To delete the forum sticky meta
  772. * @uses update_post_meta() To update the old forum sticky meta
  773. * @uses bbp_stick_topic() To stick the topic in the new forum
  774. * @uses bbp_get_reply_post_type() To get the reply post type
  775. * @uses bbp_get_all_child_ids() To get the public child ids
  776. * @uses bbp_update_reply_forum_id() To update the reply forum id
  777. * @uses bbp_update_topic_forum_id() To update the topic forum id
  778. * @uses get_post_ancestors() To get the topic's ancestors
  779. * @uses bbp_is_forum() To check if the ancestor is a forum
  780. * @uses bbp_update_forum() To update the forum
  781. */
  782. function bbp_move_topic_handler( $topic_id, $old_forum_id, $new_forum_id ) {
  783. // Validate parameters
  784. $topic_id = bbp_get_topic_id( $topic_id );
  785. $old_forum_id = bbp_get_forum_id( $old_forum_id );
  786. $new_forum_id = bbp_get_forum_id( $new_forum_id );
  787. // Update topic forum's ID
  788. bbp_update_topic_forum_id( $topic_id, $new_forum_id );
  789. /** Stickies **************************************************************/
  790. // Get forum stickies
  791. $old_stickies = bbp_get_stickies( $old_forum_id );
  792. // Only proceed if stickies are found
  793. if ( !empty( $old_stickies ) ) {
  794. // Define local variables
  795. $updated_stickies = array();
  796. // Loop through stickies of forum and add misses to the updated array
  797. foreach ( (array) $old_stickies as $sticky_topic_id ) {
  798. if ( $topic_id !== $sticky_topic_id ) {
  799. $updated_stickies[] = $sticky_topic_id;
  800. }
  801. }
  802. // If stickies are different, update or delete them
  803. if ( $updated_stickies !== $old_stickies ) {
  804. // No more stickies so delete the meta
  805. if ( empty( $updated_stickies ) ) {
  806. delete_post_meta( $old_forum_id, '_bbp_sticky_topics' );
  807. // Still stickies so update the meta
  808. } else {
  809. update_post_meta( $old_forum_id, '_bbp_sticky_topics', $updated_stickies );
  810. }
  811. // Topic was sticky, so restick in new forum
  812. bbp_stick_topic( $topic_id );
  813. }
  814. }
  815. /** Topic Replies *********************************************************/
  816. // Get the topics replies
  817. $replies = bbp_get_all_child_ids( $topic_id, bbp_get_reply_post_type() );
  818. // Update the forum_id of all replies in the topic
  819. foreach ( $replies as $reply_id ) {
  820. bbp_update_reply_forum_id( $reply_id, $new_forum_id );
  821. }
  822. /** Old forum_id **********************************************************/
  823. // Get topic ancestors
  824. $old_forum_ancestors = array_values( array_unique( array_merge( array( $old_forum_id ), (array) get_post_ancestors( $old_forum_id ) ) ) );
  825. // Loop through ancestors and update them
  826. if ( !empty( $old_forum_ancestors ) ) {
  827. foreach ( $old_forum_ancestors as $ancestor ) {
  828. if ( bbp_is_forum( $ancestor ) ) {
  829. bbp_update_forum( array(
  830. 'forum_id' => $ancestor,
  831. ) );
  832. }
  833. }
  834. }
  835. /** New forum_id **********************************************************/
  836. // Make sure we're not walking twice
  837. if ( !in_array( $new_forum_id, $old_forum_ancestors ) ) {
  838. // Get topic ancestors
  839. $new_forum_ancestors = array_values( array_unique( array_merge( array( $new_forum_id ), (array) get_post_ancestors( $new_forum_id ) ) ) );
  840. // Make sure we're not walking twice
  841. $new_forum_ancestors = array_diff( $new_forum_ancestors, $old_forum_ancestors );
  842. // Loop through ancestors and update them
  843. if ( !empty( $new_forum_ancestors ) ) {
  844. foreach ( $new_forum_ancestors as $ancestor ) {
  845. if ( bbp_is_forum( $ancestor ) ) {
  846. bbp_update_forum( array(
  847. 'forum_id' => $ancestor,
  848. ) );
  849. }
  850. }
  851. }
  852. }
  853. }
  854. /**
  855. * Merge topic handler
  856. *
  857. * Handles the front end merge topic submission
  858. *
  859. * @since bbPress (r2756)
  860. *
  861. * @param string $action The requested action to compare this function to
  862. * @uses bbp_add_error() To add an error message
  863. * @uses bbp_get_topic() To get the topics
  864. * @uses bbp_verify_nonce_request() To verify the nonce and check the request
  865. * @uses current_user_can() To check if the current user can edit the topics
  866. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
  867. * @uses do_action() Calls 'bbp_merge_topic' with the destination and source
  868. * topic ids
  869. * @uses bbp_get_topic_subscribers() To get the source topic subscribers
  870. * @uses bbp_add_user_subscription() To add the user subscription
  871. * @uses bbp_remove_user_subscription() To remove the user subscription
  872. * @uses bbp_get_topic_favoriters() To get the source topic favoriters
  873. * @uses bbp_add_user_favorite() To add the user favorite
  874. * @uses bbp_remove_user_favorite() To remove the user favorite
  875. * @uses wp_get_post_terms() To get the source topic tags
  876. * @uses wp_set_post_terms() To set the topic tags
  877. * @uses wp_delete_object_term_relationships() To delete the topic tags
  878. * @uses bbp_open_topic() To open the topic
  879. * @uses bbp_unstick_topic() To unstick the topic
  880. * @uses bbp_get_reply_post_type() To get the reply post type
  881. * @uses get_posts() To get the replies
  882. * @uses wp_update_post() To update the topic
  883. * @uses bbp_update_reply_topic_id() To update the reply topic id
  884. * @uses bbp_get_topic_forum_id() To get the topic forum id
  885. * @uses bbp_update_reply_forum_id() To update the reply forum id
  886. * @uses do_action() Calls 'bbp_merged_topic_reply' with the reply id and
  887. * destination topic id
  888. * @uses do_action() Calls 'bbp_merged_topic' with the destination and source
  889. * topic ids and source topic's forum id
  890. * @uses bbp_get_topic_permalink() To get the topic permalink
  891. * @uses wp_safe_redirect() To redirect to the topic link
  892. */
  893. function bbp_merge_topic_handler( $action = '' ) {
  894. // Bail if action is not bbp-merge-topic
  895. if ( 'bbp-merge-topic' !== $action )
  896. return;
  897. // Define local variable(s)
  898. $source_topic_id = $destination_topic_id = 0;
  899. $source_topic = $destination_topic = 0;
  900. $subscribers = $favoriters = $replies = array();
  901. /** Source Topic **********************************************************/
  902. // Topic id
  903. if ( empty( $_POST['bbp_topic_id'] ) ) {
  904. bbp_add_error( 'bbp_merge_topic_source_id', __( '<strong>ERROR</strong>: Topic ID not found.', 'bbpress' ) );
  905. } else {
  906. $source_topic_id = (int) $_POST['bbp_topic_id'];
  907. }
  908. // Nonce check
  909. if ( ! bbp_verify_nonce_request( 'bbp-merge-topic_' . $source_topic_id ) ) {
  910. bbp_add_error( 'bbp_merge_topic_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  911. return;
  912. // Source topic not found
  913. } elseif ( !$source_topic = bbp_get_topic( $source_topic_id ) ) {
  914. bbp_add_error( 'bbp_merge_topic_source_not_found', __( '<strong>ERROR</strong>: The topic you want to merge was not found.', 'bbpress' ) );
  915. return;
  916. }
  917. // Cannot edit source topic
  918. if ( !current_user_can( 'edit_topic', $source_topic->ID ) ) {
  919. bbp_add_error( 'bbp_merge_topic_source_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress' ) );
  920. return;
  921. }
  922. /** Destination Topic *****************************************************/
  923. // Topic id
  924. if ( empty( $_POST['bbp_destination_topic'] ) )
  925. bbp_add_error( 'bbp_merge_topic_destination_id', __( '<strong>ERROR</strong>: Destination topic ID not found.', 'bbpress' ) );
  926. else
  927. $destination_topic_id = (int) $_POST['bbp_destination_topic'];
  928. // Destination topic not found
  929. if ( !$destination_topic = bbp_get_topic( $destination_topic_id ) )
  930. bbp_add_error( 'bbp_merge_topic_destination_not_found', __( '<strong>ERROR</strong>: The topic you want to merge to was not found.', 'bbpress' ) );
  931. // Cannot edit destination topic
  932. if ( !current_user_can( 'edit_topic', $destination_topic->ID ) )
  933. bbp_add_error( 'bbp_merge_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the destination topic.', 'bbpress' ) );
  934. // Bail if errors
  935. if ( bbp_has_errors() )
  936. return;
  937. /** No Errors *************************************************************/
  938. // Update counts, etc...
  939. do_action( 'bbp_merge_topic', $destination_topic->ID, $source_topic->ID );
  940. /** Date Check ************************************************************/
  941. // Check if the destination topic is older than the source topic
  942. if ( strtotime( $source_topic->post_date ) < strtotime( $destination_topic->post_date ) ) {
  943. // Set destination topic post_date to 1 second before source topic
  944. $destination_post_date = date( 'Y-m-d H:i:s', strtotime( $source_topic->post_date ) - 1 );
  945. // Update destination topic
  946. wp_update_post( array(
  947. 'ID' => $destination_topic_id,
  948. 'post_date' => $destination_post_date,
  949. 'post_date_gmt' => get_gmt_from_date( $destination_post_date )
  950. ) );
  951. }
  952. /** Subscriptions *********************************************************/
  953. // Get subscribers from source topic
  954. $subscribers = bbp_get_topic_subscribers( $source_topic->ID );
  955. // Remove the topic from everybody's subscriptions
  956. if ( !empty( $subscribers ) ) {
  957. // Loop through each user
  958. foreach ( (array) $subscribers as $subscriber ) {
  959. // Shift the subscriber if told to
  960. if ( !empty( $_POST['bbp_topic_subscribers'] ) && ( "1" === $_POST['bbp_topic_subscribers'] ) && bbp_is_subscriptions_active() )
  961. bbp_add_user_subscription( $subscriber, $destination_topic->ID );
  962. // Remove old subscription
  963. bbp_remove_user_subscription( $subscriber, $source_topic->ID );
  964. }
  965. }
  966. /** Favorites *************************************************************/
  967. // Get favoriters from source topic
  968. $favoriters = bbp_get_topic_favoriters( $source_topic->ID );
  969. // Remove the topic from everybody's favorites
  970. if ( !empty( $favoriters ) ) {
  971. // Loop through each user
  972. foreach ( (array) $favoriters as $favoriter ) {
  973. // Shift the favoriter if told to
  974. if ( !empty( $_POST['bbp_topic_favoriters'] ) && "1" === $_POST['bbp_topic_favoriters'] )
  975. bbp_add_user_favorite( $favoriter, $destination_topic->ID );
  976. // Remove old favorite
  977. bbp_remove_user_favorite( $favoriter, $source_topic->ID );
  978. }
  979. }
  980. /** Tags ******************************************************************/
  981. // Get the source topic tags
  982. $source_topic_tags = wp_get_post_terms( $source_topic->ID, bbp_get_topic_tag_tax_id(), array( 'fields' => 'names' ) );
  983. // Tags to possibly merge
  984. if ( !empty( $source_topic_tags ) && !is_wp_error( $source_topic_tags ) ) {
  985. // Shift the tags if told to
  986. if ( !empty( $_POST['bbp_topic_tags'] ) && ( "1" === $_POST['bbp_topic_tags'] ) )
  987. wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
  988. // Delete the tags from the source topic
  989. wp_delete_object_term_relationships( $source_topic->ID, bbp_get_topic_tag_tax_id() );
  990. }
  991. /** Source Topic **********************************************************/
  992. // Status
  993. bbp_open_topic( $source_topic->ID );
  994. // Sticky
  995. bbp_unstick_topic( $source_topic->ID );
  996. // Get the replies of the source topic
  997. $replies = (array) get_posts( array(
  998. 'post_parent' => $source_topic->ID,
  999. 'post_type' => bbp_get_reply_post_type(),
  1000. 'posts_per_page' => -1,
  1001. 'order' => 'ASC'
  1002. ) );
  1003. // Prepend the source topic to its replies array for processing
  1004. array_unshift( $replies, $source_topic );
  1005. if ( !empty( $replies ) ) {
  1006. /** Merge Replies *****************************************************/
  1007. // Change the post_parent of each reply to the destination topic id
  1008. foreach ( $replies as $reply ) {
  1009. // Update the reply
  1010. wp_update_post( array(
  1011. 'ID' => $reply->ID,
  1012. 'post_title' => sprintf( __( 'Reply To: %s', 'bbpress' ), $destination_topic->post_title ),
  1013. 'post_name' => false,
  1014. 'post_type' => bbp_get_reply_post_type(),
  1015. 'post_parent' => $destination_topic->ID,
  1016. 'guid' => ''
  1017. ) );
  1018. // Adjust reply meta values
  1019. bbp_update_reply_topic_id( $reply->ID, $destination_topic->ID );
  1020. bbp_update_reply_forum_id( $reply->ID, bbp_get_topic_forum_id( $destination_topic->ID ) );
  1021. // Adjust reply to values
  1022. $reply_to = bbp_get_reply_to( $reply->ID );
  1023. if ( empty( $reply_to ) ) {
  1024. bbp_update_reply_to( $reply->ID, $source_topic->ID );
  1025. }
  1026. // Do additional actions per merged reply
  1027. do_action( 'bbp_merged_topic_reply', $reply->ID, $destination_topic->ID );
  1028. }
  1029. }
  1030. /** Successful Merge ******************************************************/
  1031. // Update topic's last meta data
  1032. bbp_update_topic_last_reply_id ( $destination_topic->ID );
  1033. bbp_update_topic_last_active_id ( $destination_topic->ID );
  1034. bbp_update_topic_last_active_time( $destination_topic->ID );
  1035. // Send the post parent of the source topic as it has been shifted
  1036. // (possibly to a new forum) so we need to update the counts of the
  1037. // old forum as well as the new one
  1038. do_action( 'bbp_merged_topic', $destination_topic->ID, $source_topic->ID, $source_topic->post_parent );
  1039. // Redirect back to new topic
  1040. wp_safe_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );
  1041. // For good measure
  1042. exit();
  1043. }
  1044. /**
  1045. * Fix counts on topic merge
  1046. *
  1047. * When a topic is merged, update the counts of source and destination topic
  1048. * and their forums.
  1049. *
  1050. * @since bbPress (r2756)
  1051. *
  1052. * @param int $destination_topic_id Destination topic id
  1053. * @param int $source_topic_id Source topic id
  1054. * @param int $source_topic_forum Source topic's forum id
  1055. * @uses bbp_update_forum_topic_count() To update the forum topic counts
  1056. * @uses bbp_update_forum_reply_count() To update the forum reply counts
  1057. * @uses bbp_update_topic_reply_count() To update the topic reply counts
  1058. * @uses bbp_update_topic_voice_count() To update the topic voice counts
  1059. * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
  1060. * count
  1061. * @uses do_action() Calls 'bbp_merge_topic_count' with the destination topic
  1062. * id, source topic id & source topic forum id
  1063. */
  1064. function bbp_merge_topic_count( $destination_topic_id, $source_topic_id, $source_topic_forum_id ) {
  1065. /** Source Topic **********************************************************/
  1066. // Forum Topic Counts
  1067. bbp_update_forum_topic_count( $source_topic_forum_id );
  1068. // Forum Reply Counts
  1069. bbp_update_forum_reply_count( $source_topic_forum_id );
  1070. /** Destination Topic *****************************************************/
  1071. // Topic Reply Counts
  1072. bbp_update_topic_reply_count( $destination_topic_id );
  1073. // Topic Hidden Reply Counts
  1074. bbp_update_topic_reply_count_hidden( $destination_topic_id );
  1075. // Topic Voice Counts
  1076. bbp_update_topic_voice_count( $destination_topic_id );
  1077. do_action( 'bbp_merge_topic_count', $destination_topic_id, $source_topic_id, $source_topic_forum_id );
  1078. }
  1079. /**
  1080. * Split topic handler
  1081. *
  1082. * Handles the front end split topic submission
  1083. *
  1084. * @since bbPress (r2756)
  1085. *
  1086. * @param string $action The requested action to compare this function to
  1087. * @uses bbp_add_error() To add an error message
  1088. * @uses bbp_get_reply() To get the reply
  1089. * @uses bbp_get_topic() To get the topics
  1090. * @uses bbp_verify_nonce_request() To verify the nonce and check the request
  1091. * @uses current_user_can() To check if the current user can edit the topics
  1092. * @uses bbp_get_topic_post_type() To get the topic post type
  1093. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
  1094. * @uses do_action() Calls 'bbp_pre_split_topic' with the from reply id, source
  1095. * and destination topic ids
  1096. * @uses bbp_get_topic_subscribers() To get the source topic subscribers
  1097. * @uses bbp_add_user_subscription() To add the user subscription
  1098. * @uses bbp_get_topic_favoriters() To get the source topic favoriters
  1099. * @uses bbp_add_user_favorite() To add the user favorite
  1100. * @uses wp_get_post_terms() To get the source topic tags
  1101. * @uses wp_set_post_terms() To set the topic tags
  1102. * @uses bbp_get_reply_post_type() To get the reply post type
  1103. * @uses wpdb::prepare() To prepare our sql query
  1104. * @uses wpdb::get_results() To execute the sql query and get results
  1105. * @uses wp_update_post() To update the replies
  1106. * @uses bbp_update_reply_topic_id() To update the reply topic id
  1107. * @uses bbp_get_topic_forum_id() To get the topic forum id
  1108. * @uses bbp_update_reply_forum_id() To update the reply forum id
  1109. * @uses do_action() Calls 'bbp_split_topic_reply' with the reply id and
  1110. * destination topic id
  1111. * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
  1112. * @uses bbp_update_topic_last_active_time() To update the topic last active meta
  1113. * @uses do_action() Calls 'bbp_post_split_topic' with the destination and
  1114. * source topic ids and source topic's forum id
  1115. * @uses bbp_get_topic_permalink() To get the topic permalink
  1116. * @uses wp_safe_redirect() To redirect to the topic link
  1117. */
  1118. function bbp_split_topic_handler( $action = '' ) {
  1119. // Bail if action is not 'bbp-split-topic'
  1120. if ( 'bbp-split-topic' !== $action )
  1121. return;
  1122. global $wpdb;
  1123. // Prevent debug notices
  1124. $from_reply_id = $destination_topic_id = 0;
  1125. $destination_topic_title = '';
  1126. $destination_topic = $from_reply = $source_topic = '';
  1127. $split_option = false;
  1128. /** Split Reply ***********************************************************/
  1129. if ( empty( $_POST['bbp_reply_id'] ) )
  1130. bbp_add_error( 'bbp_split_topic_reply_id', __( '<strong>ERROR</strong>: Reply ID to split the topic from not found!', 'bbpress' ) );
  1131. else
  1132. $from_reply_id = (int) $_POST['bbp_reply_id'];
  1133. $from_reply = bbp_get_reply( $from_reply_id );
  1134. // Reply exists
  1135. if ( empty( $from_reply ) )
  1136. bbp_add_error( 'bbp_split_topic_r_not_found', __( '<strong>ERROR</strong>: The reply you want to split from was not found.', 'bbpress' ) );
  1137. /** Topic to Split ********************************************************/
  1138. // Get the topic being split
  1139. $source_topic = bbp_get_topic( $from_reply->post_parent );
  1140. // No topic
  1141. if ( empty( $source_topic ) )
  1142. bbp_add_error( 'bbp_split_topic_source_not_found', __( '<strong>ERROR</strong>: The topic you want to split was not found.', 'bbpress' ) );
  1143. // Nonce check failed
  1144. if ( ! bbp_verify_nonce_request( 'bbp-split-topic_' . $source_topic->ID ) ) {
  1145. bbp_add_error( 'bbp_split_topic_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  1146. return;
  1147. }
  1148. // Use cannot edit topic
  1149. if ( !current_user_can( 'edit_topic', $source_topic->ID ) )
  1150. bbp_add_error( 'bbp_split_topic_source_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress' ) );
  1151. // How to Split
  1152. if ( !empty( $_POST['bbp_topic_split_option'] ) )
  1153. $split_option = (string) trim( $_POST['bbp_topic_split_option'] );
  1154. // Invalid split option
  1155. if ( empty( $split_option ) || !in_array( $split_option, array( 'existing', 'reply' ) ) ) {
  1156. bbp_add_error( 'bbp_split_topic_option', __( '<strong>ERROR</strong>: You need to choose a valid split option.', 'bbpress' ) );
  1157. // Valid Split Option
  1158. } else {
  1159. // What kind of split
  1160. switch ( $split_option ) {
  1161. // Into an existing topic
  1162. case 'existing' :
  1163. // Get destination topic id
  1164. if ( empty( $_POST['bbp_destination_topic'] ) )
  1165. bbp_add_error( 'bbp_split_topic_destination_id', __( '<strong>ERROR</strong>: Destination topic ID not found!', 'bbpress' ) );
  1166. else
  1167. $destination_topic_id = (int) $_POST['bbp_destination_topic'];
  1168. // Get the destination topic
  1169. $destination_topic = bbp_get_topic( $destination_topic_id );
  1170. // No destination topic
  1171. if ( empty( $destination_topic ) )
  1172. bbp_add_error( 'bbp_split_topic_destination_not_found', __( '<strong>ERROR</strong>: The topic you want to split to was not found!', 'bbpress' ) );
  1173. // User cannot edit the destination topic
  1174. if ( !current_user_can( 'edit_topic', $destination_topic->ID ) )
  1175. bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the destination topic!', 'bbpress' ) );
  1176. break;
  1177. // Split at reply into a new topic
  1178. case 'reply' :
  1179. default :
  1180. // User needs to be able to publish topics
  1181. if ( current_user_can( 'publish_topics' ) ) {
  1182. // Use the new title that was passed
  1183. if ( !empty( $_POST['bbp_topic_split_destination_title'] ) ) {
  1184. $destination_topic_title = esc_attr( strip_tags( $_POST['bbp_topic_split_destination_title'] ) );
  1185. // Use the source topic title
  1186. } else {
  1187. $destination_topic_title = $source_topic->post_title;
  1188. }
  1189. // Update the topic
  1190. $destination_topic_id = wp_update_post( array(
  1191. 'ID' => $from_reply->ID,
  1192. 'post_title' => $destination_topic_title,
  1193. 'post_name' => false,
  1194. 'post_type' => bbp_get_topic_post_type(),
  1195. 'post_parent' => $source_topic->post_parent,
  1196. 'menu_order' => 0,
  1197. 'guid' => ''
  1198. ) );
  1199. $destination_topic = bbp_get_topic( $destination_topic_id );
  1200. // Make sure the new topic knows its a topic
  1201. bbp_update_topic_topic_id( $from_reply->ID );
  1202. // Shouldn't happen
  1203. if ( false === $destination_topic_id || is_wp_error( $destination_topic_id ) || empty( $destination_topic ) ) {
  1204. bbp_add_error( 'bbp_split_topic_destination_reply', __( '<strong>ERROR</strong>: There was a problem converting the reply into the topic. Please try again.', 'bbpress' ) );
  1205. }
  1206. // User cannot publish posts
  1207. } else {
  1208. bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to create new topics. The reply could not be converted into a topic.', 'bbpress' ) );
  1209. }
  1210. break;
  1211. }
  1212. }
  1213. // Bail if there are errors
  1214. if ( bbp_has_errors() )
  1215. return;
  1216. /** No Errors - Do the Spit ***********************************************/
  1217. // Update counts, etc...
  1218. do_action( 'bbp_pre_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
  1219. /** Date Check ************************************************************/
  1220. // Check if the destination topic is older than the from reply
  1221. if ( strtotime( $from_reply->post_date ) < strtotime( $destination_topic->post_date ) ) {
  1222. // Set destination topic post_date to 1 second before from reply
  1223. $destination_post_date = date( 'Y-m-d H:i:s', strtotime( $from_reply->post_date ) - 1 );
  1224. // Update destination topic
  1225. wp_update_post( array(
  1226. 'ID' => $destination_topic_id,
  1227. 'post_date' => $destination_post_date,
  1228. 'post_date_gmt' => get_gmt_from_date( $destination_post_date )
  1229. ) );
  1230. }
  1231. /** Subscriptions *********************************************************/
  1232. // Copy the subscribers
  1233. if ( !empty( $_POST['bbp_topic_subscribers'] ) && "1" === $_POST['bbp_topic_subscribers'] && bbp_is_subscriptions_active() ) {
  1234. // Get the subscribers
  1235. $subscribers = bbp_get_topic_subscribers( $source_topic->ID );
  1236. if ( !empty( $subscribers ) ) {
  1237. // Add subscribers to new topic
  1238. foreach ( (array) $subscribers as $subscriber ) {
  1239. bbp_add_user_subscription( $subscriber, $destination_topic->ID );
  1240. }
  1241. }
  1242. }
  1243. /** Favorites *************************************************************/
  1244. // Copy the favoriters if told to
  1245. if ( !empty( $_POST['bbp_topic_favoriters'] ) && ( "1" === $_POST['bbp_topic_favoriters'] ) ) {
  1246. // Get the favoriters
  1247. $favoriters = bbp_get_topic_favoriters( $source_topic->ID );
  1248. if ( !empty( $favoriters ) ) {
  1249. // Add the favoriters to new topic
  1250. foreach ( (array) $favoriters as $favoriter ) {
  1251. bbp_add_user_favorite( $favoriter, $destination_topic->ID );
  1252. }
  1253. }
  1254. }
  1255. /** Tags ******************************************************************/
  1256. // Copy the tags if told to
  1257. if ( !empty( $_POST['bbp_topic_tags'] ) && ( "1" === $_POST['bbp_topic_tags'] ) ) {
  1258. // Get the source topic tags
  1259. $source_topic_tags = wp_get_post_terms( $source_topic->ID, bbp_get_topic_tag_tax_id(), array( 'fields' => 'names' ) );
  1260. if ( !empty( $source_topic_tags ) ) {
  1261. wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
  1262. }
  1263. }
  1264. /** Split Replies *********************************************************/
  1265. // get_posts() is not used because it doesn't allow us to use '>='
  1266. // comparision without a filter.
  1267. $replies = (array) $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_date >= %s AND {$wpdb->posts}.post_parent = %d AND {$wpdb->posts}.post_type = %s ORDER BY {$wpdb->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type() ) );
  1268. // Make sure there are replies to loop through
  1269. if ( !empty( $replies ) && !is_wp_error( $replies ) ) {
  1270. // Calculate starting point for reply positions
  1271. switch ( $split_option ) {
  1272. // Get topic reply count for existing topic
  1273. case 'existing' :
  1274. $reply_position = bbp_get_topic_reply_count( $destination_topic->ID );
  1275. break;
  1276. // Account for new lead topic
  1277. case 'reply' :
  1278. $reply_position = 1;
  1279. break;
  1280. }
  1281. // Save reply ids
  1282. $reply_ids = array();
  1283. // Change the post_parent of each reply to the destination topic id
  1284. foreach ( $replies as $reply ) {
  1285. // Bump the reply position each iteration through the loop
  1286. $reply_position++;
  1287. // Update the reply
  1288. wp_update_post( array(
  1289. 'ID' => $reply->ID,
  1290. 'post_title' => sprintf( __( 'Reply To: %s', 'bbpress' ), $destination_topic->post_title ),
  1291. 'post_name' => false, // will be automatically generated
  1292. 'post_parent' => $destination_topic->ID,
  1293. 'menu_order' => $reply_position,
  1294. 'guid' => ''
  1295. ) );
  1296. // Gather reply ids
  1297. $reply_ids[] = $reply->ID;
  1298. // Adjust reply meta values
  1299. bbp_update_reply_topic_id( $reply->ID, $destination_topic->ID );
  1300. bbp_update_reply_forum_id( $reply->ID, bbp_get_topic_forum_id( $destination_topic->ID ) );
  1301. // Adjust reply to values
  1302. $reply_to = bbp_get_reply_to( $reply->ID );
  1303. // Not a reply to a reply that moved over
  1304. if ( !in_array( $reply_to, $reply_ids ) ) {
  1305. bbp_update_reply_to( $reply->ID, 0 );
  1306. }
  1307. // New topic from reply can't be a reply to
  1308. if ( ( $from_reply->ID === $destination_topic->ID ) && ( $from_reply->ID === $reply_to ) ) {
  1309. bbp_update_reply_to( $reply->ID, 0 );
  1310. }
  1311. // Do additional actions per split reply
  1312. do_action( 'bbp_split_topic_reply', $reply->ID, $destination_topic->ID );
  1313. }
  1314. // Remove reply to from new topic
  1315. if ( $from_reply->ID === $destination_topic->ID ) {
  1316. delete_post_meta( $from_reply->ID, '_bbp_reply_to' );
  1317. }
  1318. // Set the last reply ID and freshness
  1319. $last_reply_id = $reply->ID;
  1320. $freshness = $reply->post_date;
  1321. // Set the last reply ID and freshness to the from_reply
  1322. } else {
  1323. $last_reply_id = $from_reply->ID;
  1324. $freshness = $from_reply->post_date;
  1325. }
  1326. // It is a new topic and we need to set some default metas to make
  1327. // the topic display in bbp_has_topics() list
  1328. if ( 'reply' === $split_option ) {
  1329. bbp_update_topic_last_reply_id ( $destination_topic->ID, $last_reply_id );
  1330. bbp_update_topic_last_active_id ( $destination_topic->ID, $last_reply_id );
  1331. bbp_update_topic_last_active_time( $destination_topic->ID, $freshness );
  1332. }
  1333. // Update source topic ID last active
  1334. bbp_update_topic_last_reply_id ( $source_topic->ID );
  1335. bbp_update_topic_last_active_id ( $source_topic->ID );
  1336. bbp_update_topic_last_active_time( $source_topic->ID );
  1337. /** Successful Split ******************************************************/
  1338. // Update counts, etc...
  1339. do_action( 'bbp_post_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
  1340. // Redirect back to the topic
  1341. wp_safe_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );
  1342. // For good measure
  1343. exit();
  1344. }
  1345. /**
  1346. * Fix counts on topic split
  1347. *
  1348. * When a topic is split, update the counts of source and destination topic
  1349. * and their forums.
  1350. *
  1351. * @since bbPress (r2756)
  1352. *
  1353. * @param int $from_reply_id From reply id
  1354. * @param int $source_topic_id Source topic id
  1355. * @param int $destination_topic_id Destination topic id
  1356. * @uses bbp_update_forum_topic_count() To update the forum topic counts
  1357. * @uses bbp_update_forum_reply_count() To update the forum reply counts
  1358. * @uses bbp_update_topic_reply_count() To update the topic reply counts
  1359. * @uses bbp_update_topic_voice_count() To update the topic voice counts
  1360. * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
  1361. * count
  1362. * @uses do_action() Calls 'bbp_split_topic_count' with the from reply id,
  1363. * source topic id & destination topic id
  1364. */
  1365. function bbp_split_topic_count( $from_reply_id, $source_topic_id, $destination_topic_id ) {
  1366. // Forum Topic Counts
  1367. bbp_update_forum_topic_count( bbp_get_topic_forum_id( $destination_topic_id ) );
  1368. // Forum Reply Counts
  1369. bbp_update_forum_reply_count( bbp_get_topic_forum_id( $destination_topic_id ) );
  1370. // Topic Reply Counts
  1371. bbp_update_topic_reply_count( $source_topic_id );
  1372. bbp_update_topic_reply_count( $destination_topic_id );
  1373. // Topic Hidden Reply Counts
  1374. bbp_update_topic_reply_count_hidden( $source_topic_id );
  1375. bbp_update_topic_reply_count_hidden( $destination_topic_id );
  1376. // Topic Voice Counts
  1377. bbp_update_topic_voice_count( $source_topic_id );
  1378. bbp_update_topic_voice_count( $destination_topic_id );
  1379. do_action( 'bbp_split_topic_count', $from_reply_id, $source_topic_id, $destination_topic_id );
  1380. }
  1381. /**
  1382. * Handles the front end tag management (renaming, merging, destroying)
  1383. *
  1384. * @since bbPress (r2768)
  1385. *
  1386. * @param string $action The requested action to compare this function to
  1387. * @uses bbp_verify_nonce_request() To verify the nonce and check the request
  1388. * @uses current_user_can() To check if the current user can edit/delete tags
  1389. * @uses bbp_add_error() To add an error message
  1390. * @uses wp_update_term() To update the topic tag
  1391. * @uses get_term_link() To get the topic tag url
  1392. * @uses term_exists() To check if the topic tag already exists
  1393. * @uses wp_insert_term() To insert a topic tag
  1394. * @uses wp_delete_term() To delete the topic tag
  1395. * @uses home_url() To get the blog's home page url
  1396. * @uses do_action() Calls actions based on the actions with associated args
  1397. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
  1398. * @uses wp_safe_redirect() To redirect to the url
  1399. */
  1400. function bbp_edit_topic_tag_handler( $action = '' ) {
  1401. // Bail if required POST actions aren't passed
  1402. if ( empty( $_POST['tag-id'] ) )
  1403. return;
  1404. // Setup possible get actions
  1405. $possible_actions = array(
  1406. 'bbp-update-topic-tag',
  1407. 'bbp-merge-topic-tag',
  1408. 'bbp-delete-topic-tag'
  1409. );
  1410. // Bail if actions aren't meant for this function
  1411. if ( !in_array( $action, $possible_actions ) )
  1412. return;
  1413. // Setup vars
  1414. $tag_id = (int) $_POST['tag-id'];
  1415. $tag = get_term( $tag_id, bbp_get_topic_tag_tax_id() );
  1416. // Tag does not exist
  1417. if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1418. bbp_add_error( 'bbp_manage_topic_invalid_tag', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while getting the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
  1419. return;
  1420. }
  1421. // What action are we trying to perform?
  1422. switch ( $action ) {
  1423. // Update tag
  1424. case 'bbp-update-topic-tag' :
  1425. // Nonce check
  1426. if ( ! bbp_verify_nonce_request( 'update-tag_' . $tag_id ) ) {
  1427. bbp_add_error( 'bbp_manage_topic_tag_update_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  1428. return;
  1429. }
  1430. // Can user edit topic tags?
  1431. if ( !current_user_can( 'edit_topic_tags' ) ) {
  1432. bbp_add_error( 'bbp_manage_topic_tag_update_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to edit the topic tags.', 'bbpress' ) );
  1433. return;
  1434. }
  1435. // No tag name was provided
  1436. if ( empty( $_POST['tag-name'] ) || !$name = $_POST['tag-name'] ) {
  1437. bbp_add_error( 'bbp_manage_topic_tag_update_name', __( '<strong>ERROR</strong>: You need to enter a tag name.', 'bbpress' ) );
  1438. return;
  1439. }
  1440. // Attempt to update the tag
  1441. $slug = !empty( $_POST['tag-slug'] ) ? $_POST['tag-slug'] : '';
  1442. $tag = wp_update_term( $tag_id, bbp_get_topic_tag_tax_id(), array( 'name' => $name, 'slug' => $slug ) );
  1443. // Cannot update tag
  1444. if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1445. bbp_add_error( 'bbp_manage_topic_tag_update_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while updating the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
  1446. return;
  1447. }
  1448. // Redirect
  1449. $redirect = get_term_link( $tag_id, bbp_get_topic_tag_tax_id() );
  1450. // Update counts, etc...
  1451. do_action( 'bbp_update_topic_tag', $tag_id, $tag, $name, $slug );
  1452. break;
  1453. // Merge two tags
  1454. case 'bbp-merge-topic-tag' :
  1455. // Nonce check
  1456. if ( ! bbp_verify_nonce_request( 'merge-tag_' . $tag_id ) ) {
  1457. bbp_add_error( 'bbp_manage_topic_tag_merge_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  1458. return;
  1459. }
  1460. // Can user edit topic tags?
  1461. if ( !current_user_can( 'edit_topic_tags' ) ) {
  1462. bbp_add_error( 'bbp_manage_topic_tag_merge_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to edit the topic tags.', 'bbpress' ) );
  1463. return;
  1464. }
  1465. // No tag name was provided
  1466. if ( empty( $_POST['tag-existing-name'] ) || !$name = $_POST['tag-existing-name'] ) {
  1467. bbp_add_error( 'bbp_manage_topic_tag_merge_name', __( '<strong>ERROR</strong>: You need to enter a tag name.', 'bbpress' ) );
  1468. return;
  1469. }
  1470. // If term does not exist, create it
  1471. if ( !$tag = term_exists( $name, bbp_get_topic_tag_tax_id() ) )
  1472. $tag = wp_insert_term( $name, bbp_get_topic_tag_tax_id() );
  1473. // Problem inserting the new term
  1474. if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1475. bbp_add_error( 'bbp_manage_topic_tag_merge_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while merging the tags: %s', 'bbpress' ), $tag->get_error_message() ) );
  1476. return;
  1477. }
  1478. // Merging in to...
  1479. $to_tag = $tag['term_id'];
  1480. // Attempting to merge a tag into itself
  1481. if ( $tag_id === $to_tag ) {
  1482. bbp_add_error( 'bbp_manage_topic_tag_merge_same', __( '<strong>ERROR</strong>: The tags which are being merged can not be the same.', 'bbpress' ) );
  1483. return;
  1484. }
  1485. // Delete the old term
  1486. $tag = wp_delete_term( $tag_id, bbp_get_topic_tag_tax_id(), array( 'default' => $to_tag, 'force_default' => true ) );
  1487. // Error merging the terms
  1488. if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1489. bbp_add_error( 'bbp_manage_topic_tag_merge_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while merging the tags: %s', 'bbpress' ), $tag->get_error_message() ) );
  1490. return;
  1491. }
  1492. // Redirect
  1493. $redirect = get_term_link( (int) $to_tag, bbp_get_topic_tag_tax_id() );
  1494. // Update counts, etc...
  1495. do_action( 'bbp_merge_topic_tag', $tag_id, $to_tag, $tag );
  1496. break;
  1497. // Delete tag
  1498. case 'bbp-delete-topic-tag' :
  1499. // Nonce check
  1500. if ( ! bbp_verify_nonce_request( 'delete-tag_' . $tag_id ) ) {
  1501. bbp_add_error( 'bbp_manage_topic_tag_delete_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
  1502. return;
  1503. }
  1504. // Can user delete topic tags?
  1505. if ( !current_user_can( 'delete_topic_tags' ) ) {
  1506. bbp_add_error( 'bbp_manage_topic_tag_delete_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to delete the topic tags.', 'bbpress' ) );
  1507. return;
  1508. }
  1509. // Attempt to delete term
  1510. $tag = wp_delete_term( $tag_id, bbp_get_topic_tag_tax_id() );
  1511. // Error deleting term
  1512. if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1513. bbp_add_error( 'bbp_manage_topic_tag_delete_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while deleting the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
  1514. return;
  1515. }
  1516. // We don't have any other place to go other than home! Or we may die because of the 404 disease
  1517. $redirect = home_url();
  1518. // Update counts, etc...
  1519. do_action( 'bbp_delete_topic_tag', $tag_id, $tag );
  1520. break;
  1521. }
  1522. /** Successful Moderation *************************************************/
  1523. // Redirect back
  1524. $redirect = ( !empty( $redirect ) && !is_wp_error( $redirect ) ) ? $redirect : home_url();
  1525. wp_safe_redirect( $redirect );
  1526. // For good measure
  1527. exit();
  1528. }
  1529. /** Helpers *******************************************************************/
  1530. /**
  1531. * Return an associative array of available topic statuses
  1532. *
  1533. * @since bbPress (r5059)
  1534. *
  1535. * @return array
  1536. */
  1537. function bbp_get_topic_statuses() {
  1538. return apply_filters( 'bbp_get_topic_statuses', array(
  1539. bbp_get_public_status_id() => _x( 'Open', 'Open the topic', 'bbpress' ),
  1540. bbp_get_closed_status_id() => _x( 'Closed', 'Close the topic', 'bbpress' ),
  1541. bbp_get_spam_status_id() => _x( 'Spam', 'Spam the topic', 'bbpress' ),
  1542. bbp_get_trash_status_id() => _x( 'Trash', 'Trash the topic', 'bbpress' ),
  1543. bbp_get_pending_status_id() => _x( 'Pending', 'Mark topic as pending', 'bbpress' ),
  1544. ) );
  1545. }
  1546. /**
  1547. * Return an associative array of topic sticky types
  1548. *
  1549. * @since bbPress (r5059)
  1550. *
  1551. * @return array
  1552. */
  1553. function bbp_get_topic_types() {
  1554. return apply_filters( 'bbp_get_topic_types', array(
  1555. 'unstick' => _x( 'Normal', 'Unstick a topic', 'bbpress' ),
  1556. 'stick' => _x( 'Sticky', 'Make topic sticky', 'bbpress' ),
  1557. 'super' => _x( 'Super Sticky', 'Make topic super sticky', 'bbpress' )
  1558. ) );
  1559. }
  1560. /** Stickies ******************************************************************/
  1561. /**
  1562. * Return sticky topics of a forum
  1563. *
  1564. * @since bbPress (r2592)
  1565. *
  1566. * @param int $forum_id Optional. If not passed, super stickies are returned.
  1567. * @uses bbp_get_super_stickies() To get the super stickies
  1568. * @uses get_post_meta() To get the forum stickies
  1569. * @uses apply_filters() Calls 'bbp_get_stickies' with the stickies and forum id
  1570. * @return array IDs of sticky topics of a forum or super stickies
  1571. */
  1572. function bbp_get_stickies( $forum_id = 0 ) {
  1573. $stickies = empty( $forum_id ) ? bbp_get_super_stickies() : get_post_meta( $forum_id, '_bbp_sticky_topics', true );
  1574. $stickies = ( empty( $stickies ) || !is_array( $stickies ) ) ? array() : $stickies;
  1575. return apply_filters( 'bbp_get_stickies', $stickies, (int) $forum_id );
  1576. }
  1577. /**
  1578. * Return topics stuck to front page of the forums
  1579. *
  1580. * @since bbPress (r2592)
  1581. *
  1582. * @uses get_option() To get super sticky topics
  1583. * @uses apply_filters() Calls 'bbp_get_super_stickies' with the stickies
  1584. * @return array IDs of super sticky topics
  1585. */
  1586. function bbp_get_super_stickies() {
  1587. $stickies = get_option( '_bbp_super_sticky_topics', array() );
  1588. $stickies = ( empty( $stickies ) || !is_array( $stickies ) ) ? array() : $stickies;
  1589. return apply_filters( 'bbp_get_super_stickies', $stickies );
  1590. }
  1591. /** Topics Actions ************************************************************/
  1592. /**
  1593. * Handles the front end opening/closing, spamming/unspamming,
  1594. * sticking/unsticking and trashing/untrashing/deleting of topics
  1595. *
  1596. * @since bbPress (r2727)
  1597. *
  1598. * @param string $action The requested action to compare this function to
  1599. * @uses bbp_get_topic() To get the topic
  1600. * @uses current_user_can() To check if the user is capable of editing or
  1601. * deleting the topic
  1602. * @uses bbp_get_topic_post_type() To get the topic post type
  1603. * @uses check_ajax_referer() To verify the nonce and check the referer
  1604. * @uses bbp_is_topic_open() To check if the topic is open
  1605. * @uses bbp_close_topic() To close the topic
  1606. * @uses bbp_open_topic() To open the topic
  1607. * @uses bbp_is_topic_sticky() To check if the topic is a sticky
  1608. * @uses bbp_unstick_topic() To unstick the topic
  1609. * @uses bbp_stick_topic() To stick the topic
  1610. * @uses bbp_is_topic_spam() To check if the topic is marked as spam
  1611. * @uses bbp_spam_topic() To make the topic as spam
  1612. * @uses bbp_unspam_topic() To unmark the topic as spam
  1613. * @uses wp_trash_post() To trash the topic
  1614. * @uses wp_untrash_post() To untrash the topic
  1615. * @uses wp_delete_post() To delete the topic
  1616. * @uses do_action() Calls 'bbp_toggle_topic_handler' with success, post data
  1617. * and action
  1618. * @uses bbp_get_forum_permalink() To get the forum link
  1619. * @uses bbp_get_topic_permalink() To get the topic link
  1620. * @uses add_query_arg() To add args to the url
  1621. * @uses wp_safe_redirect() To redirect to the topic
  1622. * @uses bbPress::errors:add() To log the error messages
  1623. */
  1624. function bbp_toggle_topic_handler( $action = '' ) {
  1625. // Bail if required GET actions aren't passed
  1626. if ( empty( $_GET['topic_id'] ) )
  1627. return;
  1628. // Setup possible get actions
  1629. $possible_actions = array(
  1630. 'bbp_toggle_topic_close',
  1631. 'bbp_toggle_topic_stick',
  1632. 'bbp_toggle_topic_spam',
  1633. 'bbp_toggle_topic_trash'
  1634. );
  1635. // Bail if actions aren't meant for this function
  1636. if ( !in_array( $action, $possible_actions ) )
  1637. return;
  1638. $failure = ''; // Empty failure string
  1639. $view_all = false; // Assume not viewing all
  1640. $topic_id = (int) $_GET['topic_id']; // What's the topic id?
  1641. $success = false; // Flag
  1642. $post_data = array( 'ID' => $topic_id ); // Prelim array
  1643. $redirect = ''; // Empty redirect URL
  1644. // Make sure topic exists
  1645. $topic = bbp_get_topic( $topic_id );
  1646. if ( empty( $topic ) )
  1647. return;
  1648. // What is the user doing here?
  1649. if ( !current_user_can( 'edit_topic', $topic->ID ) || ( 'bbp_toggle_topic_trash' === $action && !current_user_can( 'delete_topic', $topic->ID ) ) ) {
  1650. bbp_add_error( 'bbp_toggle_topic_permission', __( '<strong>ERROR:</strong> You do not have the permission to do that.', 'bbpress' ) );
  1651. return;
  1652. }
  1653. // What action are we trying to perform?
  1654. switch ( $action ) {
  1655. // Toggle open/close
  1656. case 'bbp_toggle_topic_close' :
  1657. check_ajax_referer( 'close-topic_' . $topic_id );
  1658. $is_open = bbp_is_topic_open( $topic_id );
  1659. $success = true === $is_open ? bbp_close_topic( $topic_id ) : bbp_open_topic( $topic_id );
  1660. $failure = true === $is_open ? __( '<strong>ERROR</strong>: There was a problem closing the topic.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem opening the topic.', 'bbpress' );
  1661. break;
  1662. // Toggle sticky/super-sticky/unstick
  1663. case 'bbp_toggle_topic_stick' :
  1664. check_ajax_referer( 'stick-topic_' . $topic_id );
  1665. $is_sticky = bbp_is_topic_sticky( $topic_id );
  1666. $is_super = false === $is_sticky && !empty( $_GET['super'] ) && ( "1" === $_GET['super'] ) ? true : false;
  1667. $success = true === $is_sticky ? bbp_unstick_topic( $topic_id ) : bbp_stick_topic( $topic_id, $is_super );
  1668. $failure = true === $is_sticky ? __( '<strong>ERROR</strong>: There was a problem unsticking the topic.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem sticking the topic.', 'bbpress' );
  1669. break;
  1670. // Toggle spam
  1671. case 'bbp_toggle_topic_spam' :
  1672. check_ajax_referer( 'spam-topic_' . $topic_id );
  1673. $is_spam = bbp_is_topic_spam( $topic_id );
  1674. $success = true === $is_spam ? bbp_unspam_topic( $topic_id ) : bbp_spam_topic( $topic_id );
  1675. $failure = true === $is_spam ? __( '<strong>ERROR</strong>: There was a problem unmarking the topic as spam.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem marking the topic as spam.', 'bbpress' );
  1676. $view_all = !$is_spam;
  1677. break;
  1678. // Toggle trash
  1679. case 'bbp_toggle_topic_trash' :
  1680. $sub_action = !empty( $_GET['sub_action'] ) && in_array( $_GET['sub_action'], array( 'trash', 'untrash', 'delete' ) ) ? $_GET['sub_action'] : false;
  1681. if ( empty( $sub_action ) )
  1682. break;
  1683. switch ( $sub_action ) {
  1684. case 'trash':
  1685. check_ajax_referer( 'trash-' . bbp_get_topic_post_type() . '_' . $topic_id );
  1686. $view_all = true;
  1687. $success = wp_trash_post( $topic_id );
  1688. $failure = __( '<strong>ERROR</strong>: There was a problem trashing the topic.', 'bbpress' );
  1689. break;
  1690. case 'untrash':
  1691. check_ajax_referer( 'untrash-' . bbp_get_topic_post_type() . '_' . $topic_id );
  1692. $success = wp_untrash_post( $topic_id );
  1693. $failure = __( '<strong>ERROR</strong>: There was a problem untrashing the topic.', 'bbpress' );
  1694. break;
  1695. case 'delete':
  1696. check_ajax_referer( 'delete-' . bbp_get_topic_post_type() . '_' . $topic_id );
  1697. $success = wp_delete_post( $topic_id );
  1698. $failure = __( '<strong>ERROR</strong>: There was a problem deleting the topic.', 'bbpress' );
  1699. break;
  1700. }
  1701. break;
  1702. }
  1703. // Do additional topic toggle actions
  1704. do_action( 'bbp_toggle_topic_handler', $success, $post_data, $action );
  1705. // No errors
  1706. if ( false !== $success && !is_wp_error( $success ) ) {
  1707. // Redirect back to the topic's forum
  1708. if ( isset( $sub_action ) && ( 'delete' === $sub_action ) ) {
  1709. $redirect = bbp_get_forum_permalink( $success->post_parent );
  1710. // Redirect back to the topic
  1711. } else {
  1712. // Get the redirect detination
  1713. $permalink = bbp_get_topic_permalink( $topic_id );
  1714. $redirect = bbp_add_view_all( $permalink, $view_all );
  1715. }
  1716. wp_safe_redirect( $redirect );
  1717. // For good measure
  1718. exit();
  1719. // Handle errors
  1720. } else {
  1721. bbp_add_error( 'bbp_toggle_topic', $failure );
  1722. }
  1723. }
  1724. /** Favorites & Subscriptions *************************************************/
  1725. /**
  1726. * Remove a deleted topic from all users' favorites
  1727. *
  1728. * @since bbPress (r2652)
  1729. *
  1730. * @param int $topic_id Get the topic id to remove
  1731. * @uses bbp_get_topic_id To get the topic id
  1732. * @uses bbp_get_topic_favoriters() To get the topic's favoriters
  1733. * @uses bbp_remove_user_favorite() To remove the topic from user's favorites
  1734. */
  1735. function bbp_remove_topic_from_all_favorites( $topic_id = 0 ) {
  1736. $topic_id = bbp_get_topic_id( $topic_id );
  1737. // Bail if no topic
  1738. if ( empty( $topic_id ) )
  1739. return;
  1740. // Get users
  1741. $users = (array) bbp_get_topic_favoriters( $topic_id );
  1742. // Users exist
  1743. if ( !empty( $users ) ) {
  1744. // Loop through users
  1745. foreach ( $users as $user ) {
  1746. // Remove each user
  1747. bbp_remove_user_favorite( $user, $topic_id );
  1748. }
  1749. }
  1750. }
  1751. /**
  1752. * Remove a deleted topic from all users' subscriptions
  1753. *
  1754. * @since bbPress (r2652)
  1755. *
  1756. * @param int $topic_id Get the topic id to remove
  1757. * @uses bbp_is_subscriptions_active() To check if the subscriptions are active
  1758. * @uses bbp_get_topic_id To get the topic id
  1759. * @uses bbp_get_topic_subscribers() To get the topic subscribers
  1760. * @uses bbp_remove_user_subscription() To remove the user subscription
  1761. */
  1762. function bbp_remove_topic_from_all_subscriptions( $topic_id = 0 ) {
  1763. // Subscriptions are not active
  1764. if ( !bbp_is_subscriptions_active() )
  1765. return;
  1766. $topic_id = bbp_get_topic_id( $topic_id );
  1767. // Bail if no topic
  1768. if ( empty( $topic_id ) )
  1769. return;
  1770. // Get users
  1771. $users = (array) bbp_get_topic_subscribers( $topic_id );
  1772. // Users exist
  1773. if ( !empty( $users ) ) {
  1774. // Loop through users
  1775. foreach ( $users as $user ) {
  1776. // Remove each user
  1777. bbp_remove_user_subscription( $user, $topic_id );
  1778. }
  1779. }
  1780. }
  1781. /** Count Bumpers *************************************************************/
  1782. /**
  1783. * Bump the total reply count of a topic
  1784. *
  1785. * @since bbPress (r3825)
  1786. *
  1787. * @param int $topic_id Optional. Forum id.
  1788. * @param int $difference Optional. Default 1
  1789. * @param bool $update_ancestors Optional. Default true
  1790. * @uses bbp_get_topic_id() To get the topic id
  1791. * @uses update_post_meta() To update the topic's reply count meta
  1792. * @uses apply_filters() Calls 'bbp_bump_topic_reply_count' with the reply
  1793. * count, topic id, and difference
  1794. * @return int Forum reply count
  1795. */
  1796. function bbp_bump_topic_reply_count( $topic_id = 0, $difference = 1 ) {
  1797. // Get counts
  1798. $topic_id = bbp_get_topic_id( $topic_id );
  1799. $reply_count = bbp_get_topic_reply_count( $topic_id, true );
  1800. $new_count = (int) $reply_count + (int) $difference;
  1801. // Update this topic id's reply count
  1802. update_post_meta( $topic_id, '_bbp_reply_count', (int) $new_count );
  1803. return (int) apply_filters( 'bbp_bump_topic_reply_count', (int) $new_count, $topic_id, (int) $difference );
  1804. }
  1805. /**
  1806. * Bump the total hidden reply count of a topic
  1807. *
  1808. * @since bbPress (r3825)
  1809. *
  1810. * @param int $topic_id Optional. Forum id.
  1811. * @param int $difference Optional. Default 1
  1812. * @uses bbp_get_topic_id() To get the topic id
  1813. * @uses update_post_meta() To update the topic's reply count meta
  1814. * @uses apply_filters() Calls 'bbp_bump_topic_reply_count_hidden' with the
  1815. * reply count, topic id, and difference
  1816. * @return int Forum hidden reply count
  1817. */
  1818. function bbp_bump_topic_reply_count_hidden( $topic_id = 0, $difference = 1 ) {
  1819. // Get counts
  1820. $topic_id = bbp_get_topic_id( $topic_id );
  1821. $reply_count = bbp_get_topic_reply_count_hidden( $topic_id, true );
  1822. $new_count = (int) $reply_count + (int) $difference;
  1823. // Update this topic id's hidder reply count
  1824. update_post_meta( $topic_id, '_bbp_reply_count_hidden', (int) $new_count );
  1825. return (int) apply_filters( 'bbp_bump_topic_reply_count_hidden', (int) $new_count, $topic_id, (int) $difference );
  1826. }
  1827. /** Topic Updaters ************************************************************/
  1828. /**
  1829. * Update the topic's forum id
  1830. *
  1831. * @since bbPress (r2855)
  1832. *
  1833. * @param int $topic_id Optional. Topic id to update
  1834. * @param int $forum_id Optional. Forum id
  1835. * @uses bbp_is_reply() TO check if the passed topic id is a reply
  1836. * @uses bbp_get_reply_topic_id() To get the reply topic id
  1837. * @uses bbp_get_topic_id() To get the topic id
  1838. * @uses get_post_field() To get the post parent of the topic id
  1839. * @uses bbp_get_forum_id() To get the forum id
  1840. * @uses update_post_meta() To update the topic forum id meta
  1841. * @uses apply_filters() Calls 'bbp_update_topic_forum_id' with the forum id
  1842. * and topic id
  1843. * @return int Forum id
  1844. */
  1845. function bbp_update_topic_forum_id( $topic_id = 0, $forum_id = 0 ) {
  1846. // If it's a reply, then get the parent (topic id)
  1847. if ( bbp_is_reply( $topic_id ) ) {
  1848. $topic_id = bbp_get_reply_topic_id( $topic_id );
  1849. } else {
  1850. $topic_id = bbp_get_topic_id( $topic_id );
  1851. }
  1852. if ( empty( $forum_id ) ) {
  1853. $forum_id = get_post_field( 'post_parent', $topic_id );
  1854. }
  1855. update_post_meta( $topic_id, '_bbp_forum_id', (int) $forum_id );
  1856. return apply_filters( 'bbp_update_topic_forum_id', (int) $forum_id, $topic_id );
  1857. }
  1858. /**
  1859. * Update the topic's topic id
  1860. *
  1861. * @since bbPress (r2954)
  1862. *
  1863. * @param int $topic_id Optional. Topic id to update
  1864. * @uses bbp_get_topic_id() To get the topic id
  1865. * @uses update_post_meta() To update the topic's topic id meta
  1866. * @uses apply_filters() Calls 'bbp_update_topic_topic_id' with the topic id
  1867. * @return int Topic id
  1868. */
  1869. function bbp_update_topic_topic_id( $topic_id = 0 ) {
  1870. $topic_id = bbp_get_topic_id( $topic_id );
  1871. update_post_meta( $topic_id, '_bbp_topic_id', (int) $topic_id );
  1872. return apply_filters( 'bbp_update_topic_topic_id', (int) $topic_id );
  1873. }
  1874. /**
  1875. * Adjust the total reply count of a topic
  1876. *
  1877. * @since bbPress (r2467)
  1878. *
  1879. * @param int $topic_id Optional. Topic id to update
  1880. * @param int $reply_count Optional. Set the reply count manually.
  1881. * @uses bbp_is_reply() To check if the passed topic id is a reply
  1882. * @uses bbp_get_reply_topic_id() To get the reply topic id
  1883. * @uses bbp_get_topic_id() To get the topic id
  1884. * @uses bbp_get_reply_post_type() To get the reply post type
  1885. * @uses bbp_get_public_child_count() To get the reply count
  1886. * @uses update_post_meta() To update the topic reply count meta
  1887. * @uses apply_filters() Calls 'bbp_update_topic_reply_count' with the reply
  1888. * count and topic id
  1889. * @return int Topic reply count
  1890. */
  1891. function bbp_update_topic_reply_count( $topic_id = 0, $reply_count = 0 ) {
  1892. // If it's a reply, then get the parent (topic id)
  1893. if ( bbp_is_reply( $topic_id ) ) {
  1894. $topic_id = bbp_get_reply_topic_id( $topic_id );
  1895. } else {
  1896. $topic_id = bbp_get_topic_id( $topic_id );
  1897. }
  1898. // Get replies of topic if not passed
  1899. if ( empty( $reply_count ) ) {
  1900. $reply_count = bbp_get_public_child_count( $topic_id, bbp_get_reply_post_type() );
  1901. }
  1902. update_post_meta( $topic_id, '_bbp_reply_count', (int) $reply_count );
  1903. return apply_filters( 'bbp_update_topic_reply_count', (int) $reply_count, $topic_id );
  1904. }
  1905. /**
  1906. * Adjust the total hidden reply count of a topic (hidden includes trashed and spammed replies)
  1907. *
  1908. * @since bbPress (r2740)
  1909. *
  1910. * @param int $topic_id Optional. Topic id to update
  1911. * @param int $reply_count Optional. Set the reply count manually
  1912. * @uses bbp_is_reply() To check if the passed topic id is a reply
  1913. * @uses bbp_get_reply_topic_id() To get the reply topic id
  1914. * @uses bbp_get_topic_id() To get the topic id
  1915. * @uses bbp_get_reply_post_type() To get the reply post type
  1916. * @uses wpdb::prepare() To prepare our sql query
  1917. * @uses wpdb::get_var() To execute our query and get the var back
  1918. * @uses update_post_meta() To update the topic hidden reply count meta
  1919. * @uses apply_filters() Calls 'bbp_update_topic_reply_count_hidden' with the
  1920. * hidden reply count and topic id
  1921. * @return int Topic hidden reply count
  1922. */
  1923. function bbp_update_topic_reply_count_hidden( $topic_id = 0, $reply_count = 0 ) {
  1924. global $wpdb;
  1925. // If it's a reply, then get the parent (topic id)
  1926. if ( bbp_is_reply( $topic_id ) ) {
  1927. $topic_id = bbp_get_reply_topic_id( $topic_id );
  1928. } else {
  1929. $topic_id = bbp_get_topic_id( $topic_id );
  1930. }
  1931. // Get replies of topic
  1932. if ( empty( $reply_count ) ) {
  1933. $post_status = "'" . implode( "','", array( bbp_get_trash_status_id(), bbp_get_spam_status_id() ) ) . "'";
  1934. $reply_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent = %d AND post_status IN ( {$post_status} ) AND post_type = '%s';", $topic_id, bbp_get_reply_post_type() ) );
  1935. }
  1936. update_post_meta( $topic_id, '_bbp_reply_count_hidden', (int) $reply_count );
  1937. return apply_filters( 'bbp_update_topic_reply_count_hidden', (int) $reply_count, $topic_id );
  1938. }
  1939. /**
  1940. * Update the topic with the last active post ID
  1941. *
  1942. * @since bbPress (r2888)
  1943. *
  1944. * @param int $topic_id Optional. Topic id to update
  1945. * @param int $active_id Optional. active id
  1946. * @uses bbp_is_reply() To check if the passed topic id is a reply
  1947. * @uses bbp_get_reply_topic_id() To get the reply topic id
  1948. * @uses bbp_get_topic_id() To get the topic id
  1949. * @uses bbp_get_reply_post_type() To get the reply post type
  1950. * @uses bbp_get_public_child_last_id() To get the last public reply id
  1951. * @uses bbp_get_active_id() To get the active id
  1952. * @uses update_post_meta() To update the topic last active id meta
  1953. * @uses apply_filters() Calls 'bbp_update_topic_last_active_id' with the active
  1954. * id and topic id
  1955. * @return int Active id
  1956. */
  1957. function bbp_update_topic_last_active_id( $topic_id = 0, $active_id = 0 ) {
  1958. // If it's a reply, then get the parent (topic id)
  1959. if ( bbp_is_reply( $topic_id ) ) {
  1960. $topic_id = bbp_get_reply_topic_id( $topic_id );
  1961. } else {
  1962. $topic_id = bbp_get_topic_id( $topic_id );
  1963. }
  1964. if ( empty( $active_id ) ) {
  1965. $active_id = bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() );
  1966. }
  1967. // Adjust last_id's based on last_reply post_type
  1968. if ( empty( $active_id ) || !bbp_is_reply( $active_id ) ) {
  1969. $active_id = $topic_id;
  1970. }
  1971. // Update only if published
  1972. if ( bbp_get_public_status_id() === get_post_status( $active_id ) ) {
  1973. update_post_meta( $topic_id, '_bbp_last_active_id', (int) $active_id );
  1974. }
  1975. return apply_filters( 'bbp_update_topic_last_active_id', (int) $active_id, $topic_id );
  1976. }
  1977. /**
  1978. * Update the topics last active date/time (aka freshness)
  1979. *
  1980. * @since bbPress (r2680)
  1981. *
  1982. * @param int $topic_id Optional. Topic id
  1983. * @param string $new_time Optional. New time in mysql format
  1984. * @uses bbp_get_topic_id() To get the topic id
  1985. * @uses bbp_get_reply_topic_id() To get the reply topic id
  1986. * @uses current_time() To get the current time
  1987. * @uses update_post_meta() To update the topic last active meta
  1988. * @return bool True on success, false on failure
  1989. */
  1990. function bbp_update_topic_last_active_time( $topic_id = 0, $new_time = '' ) {
  1991. // If it's a reply, then get the parent (topic id)
  1992. if ( bbp_is_reply( $topic_id ) ) {
  1993. $topic_id = bbp_get_reply_topic_id( $topic_id );
  1994. } else {
  1995. $topic_id = bbp_get_topic_id( $topic_id );
  1996. }
  1997. // Check time and use current if empty
  1998. if ( empty( $new_time ) ) {
  1999. $new_time = get_post_field( 'post_date', bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() ) );
  2000. }
  2001. // Update only if published
  2002. if ( !empty( $new_time ) ) {
  2003. update_post_meta( $topic_id, '_bbp_last_active_time', $new_time );
  2004. }
  2005. return apply_filters( 'bbp_update_topic_last_active_time', $new_time, $topic_id );
  2006. }
  2007. /**
  2008. * Update the topic with the most recent reply ID
  2009. *
  2010. * @since bbPress (r2625)
  2011. *
  2012. * @param int $topic_id Optional. Topic id to update
  2013. * @param int $reply_id Optional. Reply id
  2014. * @uses bbp_is_reply() To check if the passed topic id is a reply
  2015. * @uses bbp_get_reply_id() To get the reply id
  2016. * @uses bbp_get_reply_topic_id() To get the reply topic id
  2017. * @uses bbp_get_topic_id() To get the topic id
  2018. * @uses bbp_get_reply_post_type() To get the reply post type
  2019. * @uses bbp_get_public_child_last_id() To get the last public reply id
  2020. * @uses update_post_meta() To update the topic last reply id meta
  2021. * @uses apply_filters() Calls 'bbp_update_topic_last_reply_id' with the reply
  2022. * id and topic id
  2023. * @return int Reply id
  2024. */
  2025. function bbp_update_topic_last_reply_id( $topic_id = 0, $reply_id = 0 ) {
  2026. // If it's a reply, then get the parent (topic id)
  2027. if ( empty( $reply_id ) && bbp_is_reply( $topic_id ) ) {
  2028. $reply_id = bbp_get_reply_id( $topic_id );
  2029. $topic_id = bbp_get_reply_topic_id( $reply_id );
  2030. } else {
  2031. $reply_id = bbp_get_reply_id( $reply_id );
  2032. $topic_id = bbp_get_topic_id( $topic_id );
  2033. }
  2034. if ( empty( $reply_id ) ) {
  2035. $reply_id = bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() );
  2036. }
  2037. // Adjust last_id's based on last_reply post_type
  2038. if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) ) {
  2039. $reply_id = 0;
  2040. }
  2041. // Update if reply is published
  2042. if ( bbp_is_reply_published( $reply_id ) ) {
  2043. update_post_meta( $topic_id, '_bbp_last_reply_id', (int) $reply_id );
  2044. }
  2045. return apply_filters( 'bbp_update_topic_last_reply_id', (int) $reply_id, $topic_id );
  2046. }
  2047. /**
  2048. * Adjust the total voice count of a topic
  2049. *
  2050. * @since bbPress (r2567)
  2051. *
  2052. * @param int $topic_id Optional. Topic id to update
  2053. * @uses bbp_is_reply() To check if the passed topic id is a reply
  2054. * @uses bbp_get_reply_topic_id() To get the reply topic id
  2055. * @uses bbp_get_topic_id() To get the topic id
  2056. * @uses bbp_get_reply_topic_id() To get the reply topic id
  2057. * @uses bbp_get_reply_post_type() To get the reply post type
  2058. * @uses bbp_get_topic_post_type() To get the topic post type
  2059. * @uses wpdb::prepare() To prepare our sql query
  2060. * @uses wpdb::get_col() To execute our query and get the column back
  2061. * @uses update_post_meta() To update the topic voice count meta
  2062. * @uses apply_filters() Calls 'bbp_update_topic_voice_count' with the voice
  2063. * count and topic id
  2064. * @return int Voice count
  2065. */
  2066. function bbp_update_topic_voice_count( $topic_id = 0 ) {
  2067. global $wpdb;
  2068. // If it's a reply, then get the parent (topic id)
  2069. if ( bbp_is_reply( $topic_id ) ) {
  2070. $topic_id = bbp_get_reply_topic_id( $topic_id );
  2071. } elseif ( bbp_is_topic( $topic_id ) ) {
  2072. $topic_id = bbp_get_topic_id( $topic_id );
  2073. } else {
  2074. return;
  2075. }
  2076. // Query the DB to get voices in this topic
  2077. $voices = $wpdb->get_col( $wpdb->prepare( "SELECT COUNT( DISTINCT post_author ) FROM {$wpdb->posts} WHERE ( post_parent = %d AND post_status = '%s' AND post_type = '%s' ) OR ( ID = %d AND post_type = '%s' );", $topic_id, bbp_get_public_status_id(), bbp_get_reply_post_type(), $topic_id, bbp_get_topic_post_type() ) );
  2078. // If there's an error, make sure we have at least have 1 voice
  2079. $voices = ( empty( $voices ) || is_wp_error( $voices ) ) ? 1 : $voices[0];
  2080. // Update the voice count for this topic id
  2081. update_post_meta( $topic_id, '_bbp_voice_count', (int) $voices );
  2082. return apply_filters( 'bbp_update_topic_voice_count', (int) $voices, $topic_id );
  2083. }
  2084. /**
  2085. * Adjust the total anonymous reply count of a topic
  2086. *
  2087. * @since bbPress (r2567)
  2088. *
  2089. * @param int $topic_id Optional. Topic id to update
  2090. * @uses bbp_is_reply() To check if the passed topic id is a reply
  2091. * @uses bbp_get_reply_topic_id() To get the reply topic id
  2092. * @uses bbp_get_topic_id() To get the topic id
  2093. * @uses bbp_get_reply_topic_id() To get the reply topic id
  2094. * @uses bbp_get_reply_post_type() To get the reply post type
  2095. * @uses bbp_get_topic_post_type() To get the topic post type
  2096. * @uses wpdb::prepare() To prepare our sql query
  2097. * @uses wpdb::get_col() To execute our query and get the column back
  2098. * @uses update_post_meta() To update the topic anonymous reply count meta
  2099. * @uses apply_filters() Calls 'bbp_update_topic_anonymous_reply_count' with the
  2100. * anonymous reply count and topic id
  2101. * @return int Anonymous reply count
  2102. */
  2103. function bbp_update_topic_anonymous_reply_count( $topic_id = 0 ) {
  2104. global $wpdb;
  2105. // If it's a reply, then get the parent (topic id)
  2106. if ( bbp_is_reply( $topic_id ) ) {
  2107. $topic_id = bbp_get_reply_topic_id( $topic_id );
  2108. } elseif ( bbp_is_topic( $topic_id ) ) {
  2109. $topic_id = bbp_get_topic_id( $topic_id );
  2110. } else {
  2111. return;
  2112. }
  2113. $anonymous_replies = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( ID ) FROM {$wpdb->posts} WHERE ( post_parent = %d AND post_status = '%s' AND post_type = '%s' AND post_author = 0 ) OR ( ID = %d AND post_type = '%s' AND post_author = 0 );", $topic_id, bbp_get_public_status_id(), bbp_get_reply_post_type(), $topic_id, bbp_get_topic_post_type() ) );
  2114. update_post_meta( $topic_id, '_bbp_anonymous_reply_count', (int) $anonymous_replies );
  2115. return apply_filters( 'bbp_update_topic_anonymous_reply_count', (int) $anonymous_replies, $topic_id );
  2116. }
  2117. /**
  2118. * Update the revision log of the topic
  2119. *
  2120. * @since bbPress (r2782)
  2121. *
  2122. * @param mixed $args Supports these args:
  2123. * - topic_id: Topic id
  2124. * - author_id: Author id
  2125. * - reason: Reason for editing
  2126. * - revision_id: Revision id
  2127. * @uses bbp_get_topic_id() To get the topic id
  2128. * @uses bbp_format_revision_reason() To format the reason
  2129. * @uses bbp_get_topic_raw_revision_log() To get the raw topic revision log
  2130. * @uses update_post_meta() To update the topic revision log meta
  2131. * @return mixed False on failure, true on success
  2132. */
  2133. function bbp_update_topic_revision_log( $args = '' ) {
  2134. // Parse arguments against default values
  2135. $r = bbp_parse_args( $args, array(
  2136. 'reason' => '',
  2137. 'topic_id' => 0,
  2138. 'author_id' => 0,
  2139. 'revision_id' => 0
  2140. ), 'update_topic_revision_log' );
  2141. // Populate the variables
  2142. $r['reason'] = bbp_format_revision_reason( $r['reason'] );
  2143. $r['topic_id'] = bbp_get_topic_id( $r['topic_id'] );
  2144. $r['author_id'] = bbp_get_user_id ( $r['author_id'], false, true );
  2145. $r['revision_id'] = (int) $r['revision_id'];
  2146. // Get the logs and append the new one to those
  2147. $revision_log = bbp_get_topic_raw_revision_log( $r['topic_id'] );
  2148. $revision_log[ $r['revision_id'] ] = array( 'author' => $r['author_id'], 'reason' => $r['reason'] );
  2149. // Finally, update
  2150. return update_post_meta( $r['topic_id'], '_bbp_revision_log', $revision_log );
  2151. }
  2152. /** Topic Actions *************************************************************/
  2153. /**
  2154. * Closes a topic
  2155. *
  2156. * @since bbPress (r2740)
  2157. *
  2158. * @param int $topic_id Topic id
  2159. * @uses bbp_get_topic() To get the topic
  2160. * @uses do_action() Calls 'bbp_close_topic' with the topic id
  2161. * @uses add_post_meta() To add the previous status to a meta
  2162. * @uses wp_update_post() To update the topic with the new status
  2163. * @uses do_action() Calls 'bbp_opened_topic' with the topic id
  2164. * @return mixed False or {@link WP_Error} on failure, topic id on success
  2165. */
  2166. function bbp_close_topic( $topic_id = 0 ) {
  2167. // Get topic
  2168. $topic = bbp_get_topic( $topic_id );
  2169. if ( empty( $topic ) )
  2170. return $topic;
  2171. // Bail if already closed
  2172. if ( bbp_get_closed_status_id() === $topic->post_status )
  2173. return false;
  2174. // Execute pre close code
  2175. do_action( 'bbp_close_topic', $topic_id );
  2176. // Add pre close status
  2177. add_post_meta( $topic_id, '_bbp_status', $topic->post_status );
  2178. // Set closed status
  2179. $topic->post_status = bbp_get_closed_status_id();
  2180. // No revisions
  2181. remove_action( 'pre_post_update', 'wp_save_post_revision' );
  2182. // Update topic
  2183. $topic_id = wp_update_post( $topic );
  2184. // Execute post close code
  2185. do_action( 'bbp_closed_topic', $topic_id );
  2186. // Return topic_id
  2187. return $topic_id;
  2188. }
  2189. /**
  2190. * Opens a topic
  2191. *
  2192. * @since bbPress (r2740)
  2193. *
  2194. * @param int $topic_id Topic id
  2195. * @uses bbp_get_topic() To get the topic
  2196. * @uses do_action() Calls 'bbp_open_topic' with the topic id
  2197. * @uses get_post_meta() To get the previous status
  2198. * @uses delete_post_meta() To delete the previous status meta
  2199. * @uses wp_update_post() To update the topic with the new status
  2200. * @uses do_action() Calls 'bbp_opened_topic' with the topic id
  2201. * @return mixed False or {@link WP_Error} on failure, topic id on success
  2202. */
  2203. function bbp_open_topic( $topic_id = 0 ) {
  2204. // Get topic
  2205. $topic = bbp_get_topic( $topic_id );
  2206. if ( empty( $topic ) )
  2207. return $topic;
  2208. // Bail if already open
  2209. if ( bbp_get_closed_status_id() !== $topic->post_status )
  2210. return false;
  2211. // Execute pre open code
  2212. do_action( 'bbp_open_topic', $topic_id );
  2213. // Get previous status
  2214. $topic_status = get_post_meta( $topic_id, '_bbp_status', true );
  2215. // Set previous status
  2216. $topic->post_status = $topic_status;
  2217. // Remove old status meta
  2218. delete_post_meta( $topic_id, '_bbp_status' );
  2219. // No revisions
  2220. remove_action( 'pre_post_update', 'wp_save_post_revision' );
  2221. // Update topic
  2222. $topic_id = wp_update_post( $topic );
  2223. // Execute post open code
  2224. do_action( 'bbp_opened_topic', $topic_id );
  2225. // Return topic_id
  2226. return $topic_id;
  2227. }
  2228. /**
  2229. * Marks a topic as spam
  2230. *
  2231. * @since bbPress (r2740)
  2232. *
  2233. * @param int $topic_id Topic id
  2234. * @uses bbp_get_topic() To get the topic
  2235. * @uses do_action() Calls 'bbp_spam_topic' with the topic id
  2236. * @uses add_post_meta() To add the previous status to a meta
  2237. * @uses wp_update_post() To update the topic with the new status
  2238. * @uses do_action() Calls 'bbp_spammed_topic' with the topic id
  2239. * @return mixed False or {@link WP_Error} on failure, topic id on success
  2240. */
  2241. function bbp_spam_topic( $topic_id = 0 ) {
  2242. // Get the topic
  2243. $topic = bbp_get_topic( $topic_id );
  2244. if ( empty( $topic ) )
  2245. return $topic;
  2246. // Bail if topic is spam
  2247. if ( bbp_get_spam_status_id() === $topic->post_status )
  2248. return false;
  2249. // Execute pre spam code
  2250. do_action( 'bbp_spam_topic', $topic_id );
  2251. /** Trash Replies *********************************************************/
  2252. // Topic is being spammed, so its replies are trashed
  2253. $replies = new WP_Query( array(
  2254. 'suppress_filters' => true,
  2255. 'post_type' => bbp_get_reply_post_type(),
  2256. 'post_status' => bbp_get_public_status_id(),
  2257. 'post_parent' => $topic_id,
  2258. 'posts_per_page' => -1,
  2259. 'nopaging' => true,
  2260. 'fields' => 'id=>parent'
  2261. ) );
  2262. if ( !empty( $replies->posts ) ) {
  2263. // Prevent debug notices
  2264. $pre_spammed_replies = array();
  2265. // Loop through replies, trash them, and add them to array
  2266. foreach ( $replies->posts as $reply ) {
  2267. wp_trash_post( $reply->ID );
  2268. $pre_spammed_replies[] = $reply->ID;
  2269. }
  2270. // Set a post_meta entry of the replies that were trashed by this action.
  2271. // This is so we can possibly untrash them, without untrashing replies
  2272. // that were purposefully trashed before.
  2273. update_post_meta( $topic_id, '_bbp_pre_spammed_replies', $pre_spammed_replies );
  2274. // Reset the $post global
  2275. wp_reset_postdata();
  2276. }
  2277. // Cleanup
  2278. unset( $replies );
  2279. /** Topic Tags ************************************************************/
  2280. // Add the original post status as post meta for future restoration
  2281. add_post_meta( $topic_id, '_bbp_spam_meta_status', $topic->post_status );
  2282. // Get topic tags
  2283. $terms = get_the_terms( $topic_id, bbp_get_topic_tag_tax_id() );
  2284. // Define local variable(s)
  2285. $term_names = array();
  2286. // Topic has tags
  2287. if ( !empty( $terms ) ) {
  2288. // Loop through and collect term names
  2289. foreach ( $terms as $term ) {
  2290. $term_names[] = $term->name;
  2291. }
  2292. // Topic terms have slugs
  2293. if ( !empty( $term_names ) ) {
  2294. // Add the original post status as post meta for future restoration
  2295. add_post_meta( $topic_id, '_bbp_spam_topic_tags', $term_names );
  2296. // Empty the topic of its tags
  2297. $topic->tax_input = array( bbp_get_topic_tag_tax_id() => '' );
  2298. }
  2299. }
  2300. // Set post status to spam
  2301. $topic->post_status = bbp_get_spam_status_id();
  2302. // No revisions
  2303. remove_action( 'pre_post_update', 'wp_save_post_revision' );
  2304. // Update the topic
  2305. $topic_id = wp_update_post( $topic );
  2306. // Execute post spam code
  2307. do_action( 'bbp_spammed_topic', $topic_id );
  2308. // Return topic_id
  2309. return $topic_id;
  2310. }
  2311. /**
  2312. * Unspams a topic
  2313. *
  2314. * @since bbPress (r2740)
  2315. *
  2316. * @param int $topic_id Topic id
  2317. * @uses bbp_get_topic() To get the topic
  2318. * @uses do_action() Calls 'bbp_unspam_topic' with the topic id
  2319. * @uses get_post_meta() To get the previous status
  2320. * @uses delete_post_meta() To delete the previous status meta
  2321. * @uses wp_update_post() To update the topic with the new status
  2322. * @uses do_action() Calls 'bbp_unspammed_topic' with the topic id
  2323. * @return mixed False or {@link WP_Error} on failure, topic id on success
  2324. */
  2325. function bbp_unspam_topic( $topic_id = 0 ) {
  2326. // Get the topic
  2327. $topic = bbp_get_topic( $topic_id );
  2328. if ( empty( $topic ) )
  2329. return $topic;
  2330. // Bail if already not spam
  2331. if ( bbp_get_spam_status_id() !== $topic->post_status )
  2332. return false;
  2333. // Execute pre unspam code
  2334. do_action( 'bbp_unspam_topic', $topic_id );
  2335. /** Untrash Replies *******************************************************/
  2336. // Get the replies that were not previously trashed
  2337. $pre_spammed_replies = get_post_meta( $topic_id, '_bbp_pre_spammed_replies', true );
  2338. // There are replies to untrash
  2339. if ( !empty( $pre_spammed_replies ) ) {
  2340. // Maybe reverse the trashed replies array
  2341. if ( is_array( $pre_spammed_replies ) )
  2342. $pre_spammed_replies = array_reverse( $pre_spammed_replies );
  2343. // Loop through replies
  2344. foreach ( (array) $pre_spammed_replies as $reply ) {
  2345. wp_untrash_post( $reply );
  2346. }
  2347. }
  2348. /** Topic Tags ************************************************************/
  2349. // Get pre-spam topic tags
  2350. $terms = get_post_meta( $topic_id, '_bbp_spam_topic_tags', true );
  2351. // Topic had tags before it was spammed
  2352. if ( !empty( $terms ) ) {
  2353. // Set the tax_input of the topic
  2354. $topic->tax_input = array( bbp_get_topic_tag_tax_id() => $terms );
  2355. // Delete pre-spam topic tag meta
  2356. delete_post_meta( $topic_id, '_bbp_spam_topic_tags' );
  2357. }
  2358. /** Topic Status **********************************************************/
  2359. // Get pre spam status
  2360. $topic_status = get_post_meta( $topic_id, '_bbp_spam_meta_status', true );
  2361. // If no previous status, default to publish
  2362. if ( empty( $topic_status ) ) {
  2363. $topic_status = bbp_get_public_status_id();
  2364. }
  2365. // Set post status to pre spam
  2366. $topic->post_status = $topic_status;
  2367. // Delete pre spam meta
  2368. delete_post_meta( $topic_id, '_bbp_spam_meta_status' );
  2369. // No revisions
  2370. remove_action( 'pre_post_update', 'wp_save_post_revision' );
  2371. // Update the topic
  2372. $topic_id = wp_update_post( $topic );
  2373. // Execute post unspam code
  2374. do_action( 'bbp_unspammed_topic', $topic_id );
  2375. // Return topic_id
  2376. return $topic_id;
  2377. }
  2378. /**
  2379. * Sticks a topic to a forum or front
  2380. *
  2381. * @since bbPress (r2754)
  2382. *
  2383. * @param int $topic_id Optional. Topic id
  2384. * @param int $super Should we make the topic a super sticky?
  2385. * @uses bbp_get_topic_id() To get the topic id
  2386. * @uses bbp_unstick_topic() To unstick the topic
  2387. * @uses bbp_get_topic_forum_id() To get the topic forum id
  2388. * @uses bbp_get_stickies() To get the stickies
  2389. * @uses do_action() 'bbp_stick_topic' with topic id and bool super
  2390. * @uses update_option() To update the super stickies option
  2391. * @uses update_post_meta() To update the forum stickies meta
  2392. * @uses do_action() Calls 'bbp_sticked_topic' with the topic id, bool super
  2393. * and success
  2394. * @return bool True on success, false on failure
  2395. */
  2396. function bbp_stick_topic( $topic_id = 0, $super = false ) {
  2397. $topic_id = bbp_get_topic_id( $topic_id );
  2398. // Bail if a topic is not a topic (prevents revisions as stickies)
  2399. if ( ! bbp_is_topic( $topic_id ) )
  2400. return false;
  2401. // We may have a super sticky to which we want to convert into a normal
  2402. // sticky and vice versa; unstick the topic first to avoid any possible error.
  2403. bbp_unstick_topic( $topic_id );
  2404. $forum_id = empty( $super ) ? bbp_get_topic_forum_id( $topic_id ) : 0;
  2405. $stickies = bbp_get_stickies( $forum_id );
  2406. do_action( 'bbp_stick_topic', $topic_id, $super );
  2407. if ( !is_array( $stickies ) ) {
  2408. $stickies = array( $topic_id );
  2409. } else {
  2410. $stickies[] = $topic_id;
  2411. }
  2412. // Pull out duplicates and empties
  2413. $stickies = array_unique( array_filter( $stickies ) );
  2414. // Unset incorrectly stuck revisions
  2415. foreach ( (array) $stickies as $key => $id ) {
  2416. if ( ! bbp_is_topic( $id ) ) {
  2417. unset( $stickies[$key] );
  2418. }
  2419. }
  2420. // Reset keys
  2421. $stickies = array_values( $stickies );
  2422. $success = !empty( $super ) ? update_option( '_bbp_super_sticky_topics', $stickies ) : update_post_meta( $forum_id, '_bbp_sticky_topics', $stickies );
  2423. do_action( 'bbp_sticked_topic', $topic_id, $super, $success );
  2424. return (bool) $success;
  2425. }
  2426. /**
  2427. * Unsticks a topic both from front and it's forum
  2428. *
  2429. * @since bbPress (r2754)
  2430. *
  2431. * @param int $topic_id Optional. Topic id
  2432. * @uses bbp_get_topic_id() To get the topic id
  2433. * @uses bbp_is_topic_super_sticky() To check if the topic is a super sticky
  2434. * @uses bbp_get_topic_forum_id() To get the topic forum id
  2435. * @uses bbp_get_stickies() To get the forum stickies
  2436. * @uses do_action() Calls 'bbp_unstick_topic' with the topic id
  2437. * @uses delete_option() To delete the super stickies option
  2438. * @uses update_option() To update the super stickies option
  2439. * @uses delete_post_meta() To delete the forum stickies meta
  2440. * @uses update_post_meta() To update the forum stickies meta
  2441. * @uses do_action() Calls 'bbp_unsticked_topic' with the topic id and success
  2442. * @return bool Always true.
  2443. */
  2444. function bbp_unstick_topic( $topic_id = 0 ) {
  2445. $topic_id = bbp_get_topic_id( $topic_id );
  2446. $super = bbp_is_topic_super_sticky( $topic_id );
  2447. $forum_id = empty( $super ) ? bbp_get_topic_forum_id( $topic_id ) : 0;
  2448. $stickies = bbp_get_stickies( $forum_id );
  2449. $offset = array_search( $topic_id, $stickies );
  2450. do_action( 'bbp_unstick_topic', $topic_id );
  2451. if ( empty( $stickies ) ) {
  2452. $success = true;
  2453. } elseif ( !in_array( $topic_id, $stickies ) ) {
  2454. $success = true;
  2455. } elseif ( false === $offset ) {
  2456. $success = true;
  2457. } else {
  2458. array_splice( $stickies, $offset, 1 );
  2459. if ( empty( $stickies ) ) {
  2460. $success = !empty( $super ) ? delete_option( '_bbp_super_sticky_topics' ) : delete_post_meta( $forum_id, '_bbp_sticky_topics' );
  2461. } else {
  2462. $success = !empty( $super ) ? update_option( '_bbp_super_sticky_topics', $stickies ) : update_post_meta( $forum_id, '_bbp_sticky_topics', $stickies );
  2463. }
  2464. }
  2465. do_action( 'bbp_unsticked_topic', $topic_id, $success );
  2466. return (bool) $success;
  2467. }
  2468. /** Before Delete/Trash/Untrash ***********************************************/
  2469. /**
  2470. * Called before deleting a topic.
  2471. *
  2472. * This function is supplemental to the actual topic deletion which is
  2473. * handled by WordPress core API functions. It is used to clean up after
  2474. * a topic that is being deleted.
  2475. *
  2476. * @uses bbp_get_topic_id() To get the topic id
  2477. * @uses bbp_is_topic() To check if the passed id is a topic
  2478. * @uses do_action() Calls 'bbp_delete_topic' with the topic id
  2479. * @uses bbp_has_replies() To check if the topic has replies
  2480. * @uses bbp_replies() To loop through the replies
  2481. * @uses bbp_the_reply() To set a reply as the current reply in the loop
  2482. * @uses bbp_get_reply_id() To get the reply id
  2483. * @uses wp_delete_post() To delete the reply
  2484. */
  2485. function bbp_delete_topic( $topic_id = 0 ) {
  2486. // Validate topic ID
  2487. $topic_id = bbp_get_topic_id( $topic_id );
  2488. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2489. return false;
  2490. do_action( 'bbp_delete_topic', $topic_id );
  2491. // Topic is being permanently deleted, so its replies gotta go too
  2492. // Note that we get all post statuses here
  2493. $replies = new WP_Query( array(
  2494. 'suppress_filters' => true,
  2495. 'post_type' => bbp_get_reply_post_type(),
  2496. 'post_status' => array_keys( get_post_stati() ),
  2497. 'post_parent' => $topic_id,
  2498. 'posts_per_page' => -1,
  2499. 'nopaging' => true,
  2500. 'fields' => 'id=>parent'
  2501. ) );
  2502. // Loop through and delete child replies
  2503. if ( ! empty( $replies->posts ) ) {
  2504. foreach ( $replies->posts as $reply ) {
  2505. wp_delete_post( $reply->ID, true );
  2506. }
  2507. // Reset the $post global
  2508. wp_reset_postdata();
  2509. }
  2510. // Cleanup
  2511. unset( $replies );
  2512. }
  2513. /**
  2514. * Called before trashing a topic
  2515. *
  2516. * This function is supplemental to the actual topic being trashed which is
  2517. * handled by WordPress core API functions. It is used to clean up after
  2518. * a topic that is being trashed.
  2519. *
  2520. * @uses bbp_get_topic_id() To get the topic id
  2521. * @uses bbp_is_topic() To check if the passed id is a topic
  2522. * @uses do_action() Calls 'bbp_trash_topic' with the topic id
  2523. * @uses wp_trash_post() To trash the reply
  2524. * @uses update_post_meta() To save a list of just trashed replies for future use
  2525. */
  2526. function bbp_trash_topic( $topic_id = 0 ) {
  2527. // Validate topic ID
  2528. $topic_id = bbp_get_topic_id( $topic_id );
  2529. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2530. return false;
  2531. do_action( 'bbp_trash_topic', $topic_id );
  2532. // Topic is being trashed, so its replies are trashed too
  2533. $replies = new WP_Query( array(
  2534. 'suppress_filters' => true,
  2535. 'post_type' => bbp_get_reply_post_type(),
  2536. 'post_status' => bbp_get_public_status_id(),
  2537. 'post_parent' => $topic_id,
  2538. 'posts_per_page' => -1,
  2539. 'nopaging' => true,
  2540. 'fields' => 'id=>parent'
  2541. ) );
  2542. if ( !empty( $replies->posts ) ) {
  2543. // Prevent debug notices
  2544. $pre_trashed_replies = array();
  2545. // Loop through replies, trash them, and add them to array
  2546. foreach ( $replies->posts as $reply ) {
  2547. wp_trash_post( $reply->ID );
  2548. $pre_trashed_replies[] = $reply->ID;
  2549. }
  2550. // Set a post_meta entry of the replies that were trashed by this action.
  2551. // This is so we can possibly untrash them, without untrashing replies
  2552. // that were purposefully trashed before.
  2553. update_post_meta( $topic_id, '_bbp_pre_trashed_replies', $pre_trashed_replies );
  2554. // Reset the $post global
  2555. wp_reset_postdata();
  2556. }
  2557. // Cleanup
  2558. unset( $replies );
  2559. }
  2560. /**
  2561. * Called before untrashing a topic
  2562. *
  2563. * @uses bbp_get_topic_id() To get the topic id
  2564. * @uses bbp_is_topic() To check if the passed id is a topic
  2565. * @uses do_action() Calls 'bbp_untrash_topic' with the topic id
  2566. * @uses get_post_meta() To get the list of replies which were trashed with the
  2567. * topic
  2568. * @uses wp_untrash_post() To untrash the reply
  2569. */
  2570. function bbp_untrash_topic( $topic_id = 0 ) {
  2571. $topic_id = bbp_get_topic_id( $topic_id );
  2572. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2573. return false;
  2574. do_action( 'bbp_untrash_topic', $topic_id );
  2575. // Get the replies that were not previously trashed
  2576. $pre_trashed_replies = get_post_meta( $topic_id, '_bbp_pre_trashed_replies', true );
  2577. // There are replies to untrash
  2578. if ( !empty( $pre_trashed_replies ) ) {
  2579. // Maybe reverse the trashed replies array
  2580. if ( is_array( $pre_trashed_replies ) )
  2581. $pre_trashed_replies = array_reverse( $pre_trashed_replies );
  2582. // Loop through replies
  2583. foreach ( (array) $pre_trashed_replies as $reply ) {
  2584. wp_untrash_post( $reply );
  2585. }
  2586. }
  2587. }
  2588. /** After Delete/Trash/Untrash ************************************************/
  2589. /**
  2590. * Called after deleting a topic
  2591. *
  2592. * @uses bbp_get_topic_id() To get the topic id
  2593. * @uses bbp_is_topic() To check if the passed id is a topic
  2594. * @uses do_action() Calls 'bbp_deleted_topic' with the topic id
  2595. */
  2596. function bbp_deleted_topic( $topic_id = 0 ) {
  2597. $topic_id = bbp_get_topic_id( $topic_id );
  2598. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2599. return false;
  2600. do_action( 'bbp_deleted_topic', $topic_id );
  2601. }
  2602. /**
  2603. * Called after trashing a topic
  2604. *
  2605. * @uses bbp_get_topic_id() To get the topic id
  2606. * @uses bbp_is_topic() To check if the passed id is a topic
  2607. * @uses do_action() Calls 'bbp_trashed_topic' with the topic id
  2608. */
  2609. function bbp_trashed_topic( $topic_id = 0 ) {
  2610. $topic_id = bbp_get_topic_id( $topic_id );
  2611. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2612. return false;
  2613. do_action( 'bbp_trashed_topic', $topic_id );
  2614. }
  2615. /**
  2616. * Called after untrashing a topic
  2617. *
  2618. * @uses bbp_get_topic_id() To get the topic id
  2619. * @uses bbp_is_topic() To check if the passed id is a topic
  2620. * @uses do_action() Calls 'bbp_untrashed_topic' with the topic id
  2621. */
  2622. function bbp_untrashed_topic( $topic_id = 0 ) {
  2623. $topic_id = bbp_get_topic_id( $topic_id );
  2624. if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
  2625. return false;
  2626. do_action( 'bbp_untrashed_topic', $topic_id );
  2627. }
  2628. /** Settings ******************************************************************/
  2629. /**
  2630. * Return the topics per page setting
  2631. *
  2632. * @since bbPress (r3540)
  2633. *
  2634. * @param int $default Default replies per page (15)
  2635. * @uses get_option() To get the setting
  2636. * @uses apply_filters() To allow the return value to be manipulated
  2637. * @return int
  2638. */
  2639. function bbp_get_topics_per_page( $default = 15 ) {
  2640. // Get database option and cast as integer
  2641. $retval = get_option( '_bbp_topics_per_page', $default );
  2642. // If return val is empty, set it to default
  2643. if ( empty( $retval ) )
  2644. $retval = $default;
  2645. // Filter and return
  2646. return (int) apply_filters( 'bbp_get_topics_per_page', $retval, $default );
  2647. }
  2648. /**
  2649. * Return the topics per RSS page setting
  2650. *
  2651. * @since bbPress (r3540)
  2652. *
  2653. * @param int $default Default replies per page (25)
  2654. * @uses get_option() To get the setting
  2655. * @uses apply_filters() To allow the return value to be manipulated
  2656. * @return int
  2657. */
  2658. function bbp_get_topics_per_rss_page( $default = 25 ) {
  2659. // Get database option and cast as integer
  2660. $retval = get_option( '_bbp_topics_per_rss_page', $default );
  2661. // If return val is empty, set it to default
  2662. if ( empty( $retval ) )
  2663. $retval = $default;
  2664. // Filter and return
  2665. return (int) apply_filters( 'bbp_get_topics_per_rss_page', $retval, $default );
  2666. }
  2667. /** Topic Tags ****************************************************************/
  2668. /**
  2669. * Get topic tags for a specific topic ID
  2670. *
  2671. * @since bbPress (r4165)
  2672. *
  2673. * @param int $topic_id
  2674. * @param string $sep
  2675. * @return string
  2676. */
  2677. function bbp_get_topic_tag_names( $topic_id = 0, $sep = ', ' ) {
  2678. $topic_id = bbp_get_topic_id( $topic_id );
  2679. $topic_tags = array_filter( (array) get_the_terms( $topic_id, bbp_get_topic_tag_tax_id() ) );
  2680. $terms = array();
  2681. foreach ( $topic_tags as $term ) {
  2682. $terms[] = $term->name;
  2683. }
  2684. $terms = !empty( $terms ) ? implode( $sep, $terms ) : '';
  2685. return apply_filters( 'bbp_get_topic_tags', $terms, $topic_id );
  2686. }
  2687. /** Autoembed *****************************************************************/
  2688. /**
  2689. * Check if autoembeds are enabled and hook them in if so
  2690. *
  2691. * @since bbPress (r3752)
  2692. * @global WP_Embed $wp_embed
  2693. */
  2694. function bbp_topic_content_autoembed() {
  2695. global $wp_embed;
  2696. if ( bbp_use_autoembed() && is_a( $wp_embed, 'WP_Embed' ) ) {
  2697. add_filter( 'bbp_get_topic_content', array( $wp_embed, 'autoembed' ), 2 );
  2698. }
  2699. }
  2700. /** Feeds *********************************************************************/
  2701. /**
  2702. * Output an RSS2 feed of topics, based on the query passed.
  2703. *
  2704. * @since bbPress (r3171)
  2705. *
  2706. * @uses bbp_version()
  2707. * @uses bbp_is_single_topic()
  2708. * @uses bbp_user_can_view_forum()
  2709. * @uses bbp_get_topic_forum_id()
  2710. * @uses bbp_show_load_topic()
  2711. * @uses bbp_topic_permalink()
  2712. * @uses bbp_topic_title()
  2713. * @uses bbp_get_topic_reply_count()
  2714. * @uses bbp_topic_content()
  2715. * @uses bbp_has_topics()
  2716. * @uses bbp_topics()
  2717. * @uses bbp_the_topic()
  2718. * @uses get_wp_title_rss()
  2719. * @uses get_option()
  2720. * @uses bloginfo_rss
  2721. * @uses self_link()
  2722. * @uses the_author()
  2723. * @uses get_post_time()
  2724. * @uses rss_enclosure()
  2725. * @uses do_action()
  2726. * @uses apply_filters()
  2727. *
  2728. * @param array $topics_query
  2729. */
  2730. function bbp_display_topics_feed_rss2( $topics_query = array() ) {
  2731. // User cannot access this forum
  2732. if ( bbp_is_single_forum() && !bbp_user_can_view_forum( array( 'forum_id' => bbp_get_forum_id() ) ) )
  2733. return;
  2734. // Display the feed
  2735. header( 'Content-Type: ' . feed_content_type( 'rss-http' ) . '; charset=' . get_option( 'blog_charset' ), true );
  2736. header( 'Status: 200 OK' );
  2737. echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?' . '>'; ?>
  2738. <rss version="2.0"
  2739. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  2740. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  2741. xmlns:dc="http://purl.org/dc/elements/1.1/"
  2742. xmlns:atom="http://www.w3.org/2005/Atom"
  2743. <?php do_action( 'bbp_feed' ); ?>
  2744. >
  2745. <channel>
  2746. <title><?php bloginfo_rss( 'name' ); ?> &#187; <?php _e( 'All Topics', 'bbpress' ); ?></title>
  2747. <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
  2748. <link><?php self_link(); ?></link>
  2749. <description><?php //?></description>
  2750. <pubDate><?php echo mysql2date( 'D, d M Y H:i:s O', current_time( 'mysql' ), false ); ?></pubDate>
  2751. <generator>http://bbpress.org/?v=<?php bbp_version(); ?></generator>
  2752. <language><?php bloginfo_rss( 'language' ); ?></language>
  2753. <?php do_action( 'bbp_feed_head' ); ?>
  2754. <?php if ( bbp_has_topics( $topics_query ) ) : ?>
  2755. <?php while ( bbp_topics() ) : bbp_the_topic(); ?>
  2756. <item>
  2757. <guid><?php bbp_topic_permalink(); ?></guid>
  2758. <title><![CDATA[<?php bbp_topic_title(); ?>]]></title>
  2759. <link><?php bbp_topic_permalink(); ?></link>
  2760. <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_meta( bbp_get_topic_id(), '_bbp_last_active_time', true ) ); ?></pubDate>
  2761. <dc:creator><?php the_author() ?></dc:creator>
  2762. <?php if ( !post_password_required() ) : ?>
  2763. <description>
  2764. <![CDATA[
  2765. <p><?php printf( esc_html__( 'Replies: %s', 'bbpress' ), bbp_get_topic_reply_count() ); ?></p>
  2766. <?php bbp_topic_content(); ?>
  2767. ]]>
  2768. </description>
  2769. <?php rss_enclosure(); ?>
  2770. <?php endif; ?>
  2771. <?php do_action( 'bbp_feed_item' ); ?>
  2772. </item>
  2773. <?php endwhile; ?>
  2774. <?php endif; ?>
  2775. <?php do_action( 'bbp_feed_footer' ); ?>
  2776. </channel>
  2777. </rss>
  2778. <?php
  2779. exit();
  2780. }
  2781. /** Permissions ***************************************************************/
  2782. /**
  2783. * Redirect if unathorized user is attempting to edit a topic
  2784. *
  2785. * @since bbPress (r3605)
  2786. *
  2787. * @uses bbp_is_topic_edit()
  2788. * @uses current_user_can()
  2789. * @uses bbp_get_topic_id()
  2790. * @uses wp_safe_redirect()
  2791. * @uses bbp_get_topic_permalink()
  2792. */
  2793. function bbp_check_topic_edit() {
  2794. // Bail if not editing a topic
  2795. if ( !bbp_is_topic_edit() )
  2796. return;
  2797. // User cannot edit topic, so redirect back to topic
  2798. if ( !current_user_can( 'edit_topic', bbp_get_topic_id() ) ) {
  2799. wp_safe_redirect( bbp_get_topic_permalink() );
  2800. exit();
  2801. }
  2802. }
  2803. /**
  2804. * Redirect if unathorized user is attempting to edit a topic tag
  2805. *
  2806. * @since bbPress (r3605)
  2807. *
  2808. * @uses bbp_is_topic_tag_edit()
  2809. * @uses current_user_can()
  2810. * @uses bbp_get_topic_tag_id()
  2811. * @uses wp_safe_redirect()
  2812. * @uses bbp_get_topic_tag_link()
  2813. */
  2814. function bbp_check_topic_tag_edit() {
  2815. // Bail if not editing a topic tag
  2816. if ( !bbp_is_topic_tag_edit() )
  2817. return;
  2818. // Bail if current user cannot edit topic tags
  2819. if ( !current_user_can( 'edit_topic_tags', bbp_get_topic_tag_id() ) ) {
  2820. wp_safe_redirect( bbp_get_topic_tag_link() );
  2821. exit();
  2822. }
  2823. }