BBP_Topics_Admin

Loads bbPress topics admin area.

Defined (1)

The class is defined in the following location(s).

/includes/admin/topics.php  
  1. class BBP_Topics_Admin { 
  2.  
  3. /** Variables *************************************************************/ 
  4.  
  5. /** 
  6. * @var The post type of this admin component 
  7. */ 
  8. private $post_type = ''; 
  9.  
  10. /** Functions *************************************************************/ 
  11.  
  12. /** 
  13. * The main bbPress topics admin loader 
  14. * @since bbPress (r2515) 
  15. * @uses BBP_Topics_Admin::setup_globals() Setup the globals needed 
  16. * @uses BBP_Topics_Admin::setup_actions() Setup the hooks and actions 
  17. * @uses BBP_Topics_Admin::setup_help() Setup the help text 
  18. */ 
  19. public function __construct() { 
  20. $this->setup_globals(); 
  21. $this->setup_actions(); 
  22.  
  23. /** 
  24. * Setup the admin hooks, actions and filters 
  25. * @since bbPress (r2646) 
  26. * @access private 
  27. * @uses add_action() To add various actions 
  28. * @uses add_filter() To add various filters 
  29. * @uses bbp_get_forum_post_type() To get the forum post type 
  30. * @uses bbp_get_topic_post_type() To get the topic post type 
  31. * @uses bbp_get_reply_post_type() To get the reply post type 
  32. */ 
  33. private function setup_actions() { 
  34.  
  35. // Add some general styling to the admin area 
  36. add_action( 'bbp_admin_head', array( $this, 'admin_head' ) ); 
  37.  
  38. // Messages 
  39. add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) ); 
  40.  
  41. // Topic column headers. 
  42. add_filter( 'manage_' . $this->post_type . '_posts_columns', array( $this, 'column_headers' ) ); 
  43.  
  44. // Topic columns (in post row) 
  45. add_action( 'manage_' . $this->post_type . '_posts_custom_column', array( $this, 'column_data' ), 10, 2 ); 
  46. add_filter( 'post_row_actions', array( $this, 'row_actions' ), 10, 2 ); 
  47.  
  48. // Topic metabox actions 
  49. add_action( 'add_meta_boxes', array( $this, 'attributes_metabox' ) ); 
  50. add_action( 'save_post', array( $this, 'attributes_metabox_save' ) ); 
  51.  
  52. // Check if there are any bbp_toggle_topic_* requests on admin_init, also have a message displayed 
  53. add_action( 'load-edit.php', array( $this, 'toggle_topic' ) ); 
  54. add_action( 'admin_notices', array( $this, 'toggle_topic_notice' ) ); 
  55.  
  56. // Anonymous metabox actions 
  57. add_action( 'add_meta_boxes', array( $this, 'author_metabox' ) ); 
  58.  
  59. // Add ability to filter topics and replies per forum 
  60. add_filter( 'restrict_manage_posts', array( $this, 'filter_dropdown' ) ); 
  61. add_filter( 'bbp_request', array( $this, 'filter_post_rows' ) ); 
  62.  
  63. // Contextual Help 
  64. add_action( 'load-edit.php', array( $this, 'edit_help' ) ); 
  65. add_action( 'load-post.php', array( $this, 'new_help' ) ); 
  66. add_action( 'load-post-new.php', array( $this, 'new_help' ) ); 
  67.  
  68. /** 
  69. * Should we bail out of this method? 
  70. * @since bbPress (r4067) 
  71. * @return boolean 
  72. */ 
  73. private function bail() { 
  74. if ( !isset( get_current_screen()->post_type ) || ( $this->post_type !== get_current_screen()->post_type ) ) 
  75. return true; 
  76.  
  77. return false; 
  78.  
  79. /** 
  80. * Admin globals 
  81. * @since bbPress (r2646) 
  82. * @access private 
  83. */ 
  84. private function setup_globals() { 
  85. $this->post_type = bbp_get_topic_post_type(); 
  86.  
  87. /** Contextual Help *******************************************************/ 
  88.  
  89. /** 
  90. * Contextual help for bbPress topic edit page 
  91. * @since bbPress (r3119) 
  92. * @uses get_current_screen() 
  93. */ 
  94. public function edit_help() { 
  95.  
  96. if ( $this->bail() ) return; 
  97.  
  98. // Overview 
  99. get_current_screen()->add_help_tab( array( 
  100. 'id' => 'overview',  
  101. 'title' => __( 'Overview', 'bbpress' ),  
  102. 'content' => 
  103. '<p>' . __( 'This screen displays the individual topics on your site. You can customize the display of this screen to suit your workflow.', 'bbpress' ) . '</p>' 
  104. ) ); 
  105.  
  106. // Screen Content 
  107. get_current_screen()->add_help_tab( array( 
  108. 'id' => 'screen-content',  
  109. 'title' => __( 'Screen Content', 'bbpress' ),  
  110. 'content' => 
  111. '<p>' . __( 'You can customize the display of this screen’s contents in a number of ways:', 'bbpress' ) . '</p>' . 
  112. '<ul>' . 
  113. '<li>' . __( 'You can hide/display columns based on your needs and decide how many topics to list per screen using the Screen Options tab.', 'bbpress' ) . '</li>' . 
  114. '<li>' . __( 'You can filter the list of topics by topic status using the text links in the upper left to show All, Published, or Trashed topics. The default view is to show all topics.', 'bbpress' ) . '</li>' . 
  115. '<li>' . __( 'You can refine the list to show only topics from a specific month by using the dropdown menus above the topics list. Click the Filter button after making your selection. You also can refine the list by clicking on the topic creator in the topics list.', 'bbpress' ) . '</li>' . 
  116. '</ul>' 
  117. ) ); 
  118.  
  119. // Available Actions 
  120. get_current_screen()->add_help_tab( array( 
  121. 'id' => 'action-links',  
  122. 'title' => __( 'Available Actions', 'bbpress' ),  
  123. 'content' => 
  124. '<p>' . __( 'Hovering over a row in the topics list will display action links that allow you to manage your topic. You can perform the following actions:', 'bbpress' ) . '</p>' . 
  125. '<ul>' . 
  126. '<li>' . __( '<strong>Edit</strong> takes you to the editing screen for that topic. You can also reach that screen by clicking on the topic title.', 'bbpress' ) . '</li>' . 
  127. '<li>' . __( '<strong>Trash</strong> removes your topic from this list and places it in the trash, from which you can permanently delete it.', 'bbpress' ) . '</li>' . 
  128. '<li>' . __( '<strong>Spam</strong> removes your topic from this list and places it in the spam queue, from which you can permanently delete it.', 'bbpress' ) . '</li>' . 
  129. '<li>' . __( '<strong>Preview</strong> will show you what your draft topic will look like if you publish it. View will take you to your live site to view the topic. Which link is available depends on your topic’s status.', 'bbpress' ) . '</li>' . 
  130. '<li>' . __( '<strong>Close</strong> will mark the selected topic as ’closed’ and disable the option to post new replies to the topic.', 'bbpress' ) . '</li>' . 
  131. '<li>' . __( '<strong>Stick</strong> will keep the selected topic ’pinned’ to the top the parent forum topic list.', 'bbpress' ) . '</li>' . 
  132. '<li>' . __( '<strong>Stick <em>(to front)</em></strong> will keep the selected topic ’pinned’ to the top of ALL forums and be visable in any forums topics list.', 'bbpress' ) . '</li>' . 
  133. '</ul>' 
  134. ) ); 
  135.  
  136. // Bulk Actions 
  137. get_current_screen()->add_help_tab( array( 
  138. 'id' => 'bulk-actions',  
  139. 'title' => __( 'Bulk Actions', 'bbpress' ),  
  140. 'content' => 
  141. '<p>' . __( 'You can also edit or move multiple topics to the trash at once. Select the topics you want to act on using the checkboxes, then select the action you want to take from the Bulk Actions menu and click Apply.', 'bbpress' ) . '</p>' . 
  142. '<p>' . __( 'When using Bulk Edit, you can change the metadata (categories, author, etc.) for all selected topics at once. To remove a topic from the grouping, just click the x next to its name in the Bulk Edit area that appears.', 'bbpress' ) . '</p>' 
  143. ) ); 
  144.  
  145. // Help Sidebar 
  146. get_current_screen()->set_help_sidebar( 
  147. '<p><strong>' . __( 'For more information:', 'bbpress' ) . '</strong></p>' . 
  148. '<p>' . __( '<a href="http://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' . 
  149. '<p>' . __( '<a href="http://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>' 
  150. ); 
  151.  
  152. /** 
  153. * Contextual help for bbPress topic edit page 
  154. * @since bbPress (r3119) 
  155. * @uses get_current_screen() 
  156. */ 
  157. public function new_help() { 
  158.  
  159. if ( $this->bail() ) return; 
  160.  
  161. $customize_display = '<p>' . __( 'The title field and the big topic editing Area are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to unhide more boxes (Excerpt, Send Trackbacks, Custom Fields, Discussion, Slug, Author) or to choose a 1- or 2-column layout for this screen.', 'bbpress' ) . '</p>'; 
  162.  
  163. get_current_screen()->add_help_tab( array( 
  164. 'id' => 'customize-display',  
  165. 'title' => __( 'Customizing This Display', 'bbpress' ),  
  166. 'content' => $customize_display,  
  167. ) ); 
  168.  
  169. get_current_screen()->add_help_tab( array( 
  170. 'id' => 'title-topic-editor',  
  171. 'title' => __( 'Title and Topic Editor', 'bbpress' ),  
  172. 'content' => 
  173. '<p>' . __( '<strong>Title</strong> - Enter a title for your topic. After you enter a title, you’ll see the permalink below, which you can edit.', 'bbpress' ) . '</p>' . 
  174. '<p>' . __( '<strong>Topic Editor</strong> - Enter the text for your topic. There are two modes of editing: Visual and HTML. Choose the mode by clicking on the appropriate tab. Visual mode gives you a WYSIWYG editor. Click the last icon in the row to get a second row of controls. The HTML mode allows you to enter raw HTML along with your topic text. You can insert media files by clicking the icons above the topic editor and following the directions. You can go to the distraction-free writing screen via the Fullscreen icon in Visual mode (second to last in the top row) or the Fullscreen button in HTML mode (last in the row). Once there, you can make buttons visible by hovering over the top area. Exit Fullscreen back to the regular topic editor.', 'bbpress' ) . '</p>' 
  175. ) ); 
  176.  
  177. $publish_box = '<p>' . __( '<strong>Publish</strong> - You can set the terms of publishing your topic in the Publish box. For Status, Visibility, and Publish (immediately), click on the Edit link to reveal more options. Visibility includes options for password-protecting a topic or making it stay at the top of your blog indefinitely (sticky). Publish (immediately) allows you to set a future or past date and time, so you can schedule a topic to be published in the future or backdate a topic.', 'bbpress' ) . '</p>'; 
  178.  
  179. if ( current_theme_supports( 'topic-thumbnails' ) && post_type_supports( 'topic', 'thumbnail' ) ) { 
  180. $publish_box .= '<p>' . __( '<strong>Featured Image</strong> - This allows you to associate an image with your topic without inserting it. This is usually useful only if your theme makes use of the featured image as a topic thumbnail on the home page, a custom header, etc.', 'bbpress' ) . '</p>'; 
  181.  
  182. get_current_screen()->add_help_tab( array( 
  183. 'id' => 'topic-attributes',  
  184. 'title' => __( 'Topic Attributes', 'bbpress' ),  
  185. 'content' => 
  186. '<p>' . __( 'Select the attributes that your topic should have:', 'bbpress' ) . '</p>' . 
  187. '<ul>' . 
  188. '<li>' . __( '<strong>Forum</strong> dropdown determines the parent forum that the topic belongs to. Select the forum or category from the dropdown, or leave the default (No Forum) to post the topic without an assigned forum.', 'bbpress' ) . '</li>' . 
  189. '<li>' . __( '<strong>Topic Type</strong> dropdown indicates the sticky status of the topic. Selecting the super sticky option would stick the topic to the front of your forums, i.e. the topic index, sticky option would stick the topic to its respective forum. Selecting normal would not stick the topic anywhere.', 'bbpress' ) . '</li>' . 
  190. '</ul>' 
  191. ) ); 
  192.  
  193. get_current_screen()->add_help_tab( array( 
  194. 'id' => 'publish-box',  
  195. 'title' => __( 'Publish Box', 'bbpress' ),  
  196. 'content' => $publish_box,  
  197. ) ); 
  198.  
  199. get_current_screen()->set_help_sidebar( 
  200. '<p><strong>' . __( 'For more information:', 'bbpress' ) . '</strong></p>' . 
  201. '<p>' . __( '<a href="http://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' . 
  202. '<p>' . __( '<a href="http://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>' 
  203. ); 
  204.  
  205. /** 
  206. * Add the topic attributes metabox 
  207. * @since bbPress (r2744) 
  208. * @uses bbp_get_topic_post_type() To get the topic post type 
  209. * @uses add_meta_box() To add the metabox 
  210. * @uses do_action() Calls 'bbp_topic_attributes_metabox' 
  211. */ 
  212. public function attributes_metabox() { 
  213.  
  214. if ( $this->bail() ) return; 
  215.  
  216. add_meta_box ( 
  217. 'bbp_topic_attributes',  
  218. __( 'Topic Attributes', 'bbpress' ),  
  219. 'bbp_topic_metabox',  
  220. $this->post_type,  
  221. 'side',  
  222. 'high' 
  223. ); 
  224.  
  225. do_action( 'bbp_topic_attributes_metabox' ); 
  226.  
  227. /** 
  228. * Pass the topic attributes for processing 
  229. * @since bbPress (r2746) 
  230. * @param int $topic_id Topic id 
  231. * @uses current_user_can() To check if the current user is capable of 
  232. * editing the topic 
  233. * @uses do_action() Calls 'bbp_topic_attributes_metabox_save' with the 
  234. * topic id and parent id 
  235. * @return int Parent id 
  236. */ 
  237. public function attributes_metabox_save( $topic_id ) { 
  238.  
  239. if ( $this->bail() ) return $topic_id; 
  240.  
  241. // Bail if doing an autosave 
  242. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
  243. return $topic_id; 
  244.  
  245. // Bail if not a post request 
  246. if ( ! bbp_is_post_request() ) 
  247. return $topic_id; 
  248.  
  249. // Nonce check 
  250. if ( empty( $_POST['bbp_topic_metabox'] ) || !wp_verify_nonce( $_POST['bbp_topic_metabox'], 'bbp_topic_metabox_save' ) ) 
  251. return $topic_id; 
  252.  
  253. // Bail if current user cannot edit this topic 
  254. if ( !current_user_can( 'edit_topic', $topic_id ) ) 
  255. return $topic_id; 
  256.  
  257. // Get the forum ID 
  258. $forum_id = !empty( $_POST['parent_id'] ) ? (int) $_POST['parent_id'] : 0; 
  259.  
  260. // Get topic author data 
  261. $anonymous_data = bbp_filter_anonymous_post_data(); 
  262. $author_id = bbp_get_topic_author_id( $topic_id ); 
  263. $is_edit = (bool) isset( $_POST['save'] ); 
  264.  
  265. // Formally update the topic 
  266. bbp_update_topic( $topic_id, $forum_id, $anonymous_data, $author_id, $is_edit ); 
  267.  
  268. // Stickies 
  269. if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) { 
  270.  
  271. // What's the haps? 
  272. switch ( $_POST['bbp_stick_topic'] ) { 
  273.  
  274. // Sticky in this forum 
  275. case 'stick' : 
  276. bbp_stick_topic( $topic_id ); 
  277. break; 
  278.  
  279. // Super sticky in all forums 
  280. case 'super' : 
  281. bbp_stick_topic( $topic_id, true ); 
  282. break; 
  283.  
  284. // Normal 
  285. case 'unstick' : 
  286. default : 
  287. bbp_unstick_topic( $topic_id ); 
  288. break; 
  289.  
  290. // Allow other fun things to happen 
  291. do_action( 'bbp_topic_attributes_metabox_save', $topic_id, $forum_id ); 
  292. do_action( 'bbp_author_metabox_save', $topic_id, $anonymous_data ); 
  293.  
  294. return $topic_id; 
  295.  
  296. /** 
  297. * Add the author info metabox 
  298. * @since bbPress (r2828) 
  299. * @uses bbp_get_topic() To get the topic 
  300. * @uses bbp_get_reply() To get the reply 
  301. * @uses bbp_get_topic_post_type() To get the topic post type 
  302. * @uses bbp_get_reply_post_type() To get the reply post type 
  303. * @uses add_meta_box() To add the metabox 
  304. * @uses do_action() Calls 'bbp_author_metabox' with the topic/reply 
  305. * id 
  306. */ 
  307. public function author_metabox() { 
  308.  
  309. if ( $this->bail() ) return; 
  310.  
  311. // Bail if post_type is not a topic 
  312. if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) 
  313. return; 
  314.  
  315. // Add the metabox 
  316. add_meta_box( 
  317. 'bbp_author_metabox',  
  318. __( 'Author Information', 'bbpress' ),  
  319. 'bbp_author_metabox',  
  320. $this->post_type,  
  321. 'side',  
  322. 'high' 
  323. ); 
  324.  
  325. do_action( 'bbp_author_metabox', get_the_ID() ); 
  326.  
  327. /** 
  328. * Add some general styling to the admin area 
  329. * @since bbPress (r2464) 
  330. * @uses bbp_get_forum_post_type() To get the forum post type 
  331. * @uses bbp_get_topic_post_type() To get the topic post type 
  332. * @uses bbp_get_reply_post_type() To get the reply post type 
  333. * @uses sanitize_html_class() To sanitize the classes 
  334. * @uses do_action() Calls 'bbp_admin_head' 
  335. */ 
  336. public function admin_head() { 
  337.  
  338. if ( $this->bail() ) return; 
  339.  
  340. ?> 
  341.  
  342. <style type="text/css" media="screen"> 
  343. /*<![CDATA[*/ 
  344.  
  345. strong.label { 
  346. display: inline-block; 
  347. width: 60px; 
  348.  
  349. .column-bbp_forum_topic_count,  
  350. .column-bbp_forum_reply_count,  
  351. .column-bbp_topic_reply_count,  
  352. .column-bbp_topic_voice_count { 
  353. width: 8% !important; 
  354.  
  355. .column-author,  
  356. .column-bbp_reply_author,  
  357. .column-bbp_topic_author { 
  358. width: 10% !important; 
  359.  
  360. .column-bbp_topic_forum,  
  361. .column-bbp_reply_forum,  
  362. .column-bbp_reply_topic { 
  363. width: 10% !important; 
  364.  
  365. .column-bbp_forum_freshness,  
  366. .column-bbp_topic_freshness { 
  367. width: 10% !important; 
  368.  
  369. .column-bbp_forum_created,  
  370. .column-bbp_topic_created,  
  371. .column-bbp_reply_created { 
  372. width: 15% !important; 
  373.  
  374. .status-closed { 
  375. background-color: #eaeaea; 
  376.  
  377. .status-spam { 
  378. background-color: #faeaea; 
  379.  
  380. /*]]>*/ 
  381. </style> 
  382.  
  383. <?php 
  384.  
  385. /** 
  386. * Toggle topic 
  387. * Handles the admin-side opening/closing, sticking/unsticking and 
  388. * spamming/unspamming of topics 
  389. * @since bbPress (r2727) 
  390. * @uses bbp_get_topic() To get the topic 
  391. * @uses current_user_can() To check if the user is capable of editing 
  392. * the topic 
  393. * @uses wp_die() To die if the user isn't capable or the post wasn't 
  394. * found 
  395. * @uses check_admin_referer() To verify the nonce and check referer 
  396. * @uses bbp_is_topic_open() To check if the topic is open 
  397. * @uses bbp_close_topic() To close the topic 
  398. * @uses bbp_open_topic() To open the topic 
  399. * @uses bbp_is_topic_sticky() To check if the topic is a sticky or 
  400. * super sticky 
  401. * @uses bbp_unstick_topic() To unstick the topic 
  402. * @uses bbp_stick_topic() To stick the topic 
  403. * @uses bbp_is_topic_spam() To check if the topic is marked as spam 
  404. * @uses bbp_unspam_topic() To unmark the topic as spam 
  405. * @uses bbp_spam_topic() To mark the topic as spam 
  406. * @uses do_action() Calls 'bbp_toggle_topic_admin' with success, post 
  407. * data, action and message 
  408. * @uses add_query_arg() To add custom args to the url 
  409. * @uses wp_safe_redirect() Redirect the page to custom url 
  410. */ 
  411. public function toggle_topic() { 
  412.  
  413. if ( $this->bail() ) return; 
  414.  
  415. // Only proceed if GET is a topic toggle action 
  416. if ( bbp_is_get_request() && !empty( $_GET['action'] ) && in_array( $_GET['action'], array( 'bbp_toggle_topic_close', 'bbp_toggle_topic_stick', 'bbp_toggle_topic_spam' ) ) && !empty( $_GET['topic_id'] ) ) { 
  417. $action = $_GET['action']; // What action is taking place? 
  418. $topic_id = (int) $_GET['topic_id']; // What's the topic id? 
  419. $success = false; // Flag 
  420. $post_data = array( 'ID' => $topic_id ); // Prelim array 
  421. $topic = bbp_get_topic( $topic_id ); 
  422.  
  423. // Bail if topic is missing 
  424. if ( empty( $topic ) ) 
  425. wp_die( __( 'The topic was not found!', 'bbpress' ) ); 
  426.  
  427. if ( !current_user_can( 'moderate', $topic->ID ) ) // What is the user doing here? 
  428. wp_die( __( 'You do not have the permission to do that!', 'bbpress' ) ); 
  429.  
  430. switch ( $action ) { 
  431. case 'bbp_toggle_topic_close' : 
  432. check_admin_referer( 'close-topic_' . $topic_id ); 
  433.  
  434. $is_open = bbp_is_topic_open( $topic_id ); 
  435. $message = true === $is_open ? 'closed' : 'opened'; 
  436. $success = true === $is_open ? bbp_close_topic( $topic_id ) : bbp_open_topic( $topic_id ); 
  437.  
  438. break; 
  439.  
  440. case 'bbp_toggle_topic_stick' : 
  441. check_admin_referer( 'stick-topic_' . $topic_id ); 
  442.  
  443. $is_sticky = bbp_is_topic_sticky( $topic_id ); 
  444. $is_super = false === $is_sticky && !empty( $_GET['super'] ) && ( "1" === $_GET['super'] ) ? true : false; 
  445. $message = true === $is_sticky ? 'unsticked' : 'sticked'; 
  446. $message = true === $is_super ? 'super_sticked' : $message; 
  447. $success = true === $is_sticky ? bbp_unstick_topic( $topic_id ) : bbp_stick_topic( $topic_id, $is_super ); 
  448.  
  449. break; 
  450.  
  451. case 'bbp_toggle_topic_spam' : 
  452. check_admin_referer( 'spam-topic_' . $topic_id ); 
  453.  
  454. $is_spam = bbp_is_topic_spam( $topic_id ); 
  455. $message = true === $is_spam ? 'unspammed' : 'spammed'; 
  456. $success = true === $is_spam ? bbp_unspam_topic( $topic_id ) : bbp_spam_topic( $topic_id ); 
  457.  
  458. break; 
  459.  
  460. $message = array( 'bbp_topic_toggle_notice' => $message, 'topic_id' => $topic->ID ); 
  461.  
  462. if ( false === $success || is_wp_error( $success ) ) 
  463. $message['failed'] = '1'; 
  464.  
  465. // Do additional topic toggle actions (admin side) 
  466. do_action( 'bbp_toggle_topic_admin', $success, $post_data, $action, $message ); 
  467.  
  468. // Redirect back to the topic 
  469. $redirect = add_query_arg( $message, remove_query_arg( array( 'action', 'topic_id' ) ) ); 
  470. wp_safe_redirect( $redirect ); 
  471.  
  472. // For good measure 
  473. exit(); 
  474.  
  475. /** 
  476. * Toggle topic notices 
  477. * Display the success/error notices from 
  478. * {@link BBP_Admin::toggle_topic()} 
  479. * @since bbPress (r2727) 
  480. * @uses bbp_get_topic() To get the topic 
  481. * @uses bbp_get_topic_title() To get the topic title of the topic 
  482. * @uses esc_html() To sanitize the topic title 
  483. * @uses apply_filters() Calls 'bbp_toggle_topic_notice_admin' with 
  484. * message, topic id, notice and is it a failure 
  485. */ 
  486. public function toggle_topic_notice() { 
  487.  
  488. if ( $this->bail() ) return; 
  489.  
  490. // Only proceed if GET is a topic toggle action 
  491. if ( bbp_is_get_request() && !empty( $_GET['bbp_topic_toggle_notice'] ) && in_array( $_GET['bbp_topic_toggle_notice'], array( 'opened', 'closed', 'super_sticked', 'sticked', 'unsticked', 'spammed', 'unspammed' ) ) && !empty( $_GET['topic_id'] ) ) { 
  492. $notice = $_GET['bbp_topic_toggle_notice']; // Which notice? 
  493. $topic_id = (int) $_GET['topic_id']; // What's the topic id? 
  494. $is_failure = !empty( $_GET['failed'] ) ? true : false; // Was that a failure? 
  495.  
  496. // Bais if no topic_id or notice 
  497. if ( empty( $notice ) || empty( $topic_id ) ) 
  498. return; 
  499.  
  500. // Bail if topic is missing 
  501. $topic = bbp_get_topic( $topic_id ); 
  502. if ( empty( $topic ) ) 
  503. return; 
  504.  
  505. $topic_title = bbp_get_topic_title( $topic->ID ); 
  506.  
  507. switch ( $notice ) { 
  508. case 'opened' : 
  509. $message = $is_failure === true ? sprintf( __( 'There was a problem opening the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully opened.', 'bbpress' ), $topic_title ); 
  510. break; 
  511.  
  512. case 'closed' : 
  513. $message = $is_failure === true ? sprintf( __( 'There was a problem closing the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully closed.', 'bbpress' ), $topic_title ); 
  514. break; 
  515.  
  516. case 'super_sticked' : 
  517. $message = $is_failure === true ? sprintf( __( 'There was a problem sticking the topic "%1$s" to front.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully sticked to front.', 'bbpress' ), $topic_title ); 
  518. break; 
  519.  
  520. case 'sticked' : 
  521. $message = $is_failure === true ? sprintf( __( 'There was a problem sticking the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully sticked.', 'bbpress' ), $topic_title ); 
  522. break; 
  523.  
  524. case 'unsticked' : 
  525. $message = $is_failure === true ? sprintf( __( 'There was a problem unsticking the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully unsticked.', 'bbpress' ), $topic_title ); 
  526. break; 
  527.  
  528. case 'spammed' : 
  529. $message = $is_failure === true ? sprintf( __( 'There was a problem marking the topic "%1$s" as spam.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully marked as spam.', 'bbpress' ), $topic_title ); 
  530. break; 
  531.  
  532. case 'unspammed' : 
  533. $message = $is_failure === true ? sprintf( __( 'There was a problem unmarking the topic "%1$s" as spam.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully unmarked as spam.', 'bbpress' ), $topic_title ); 
  534. break; 
  535.  
  536. // Do additional topic toggle notice filters (admin side) 
  537. $message = apply_filters( 'bbp_toggle_topic_notice_admin', $message, $topic->ID, $notice, $is_failure ); 
  538.  
  539. ?> 
  540.  
  541. <div id="message" class="<?php echo $is_failure === true ? 'error' : 'updated'; ?> fade"> 
  542. <p style="line-height: 150%"><?php echo esc_html( $message ); ?></p> 
  543. </div> 
  544.  
  545. <?php 
  546.  
  547. /** 
  548. * Manage the column headers for the topics page 
  549. * @since bbPress (r2485) 
  550. * @param array $columns The columns 
  551. * @uses apply_filters() Calls 'bbp_admin_topics_column_headers' with 
  552. * the columns 
  553. * @return array $columns bbPress topic columns 
  554. */ 
  555. public function column_headers( $columns ) { 
  556.  
  557. if ( $this->bail() ) return $columns; 
  558.  
  559. $columns = array( 
  560. 'cb' => '<input type="checkbox" />',  
  561. 'title' => __( 'Topics', 'bbpress' ),  
  562. 'bbp_topic_forum' => __( 'Forum', 'bbpress' ),  
  563. 'bbp_topic_reply_count' => __( 'Replies', 'bbpress' ),  
  564. 'bbp_topic_voice_count' => __( 'Voices', 'bbpress' ),  
  565. 'bbp_topic_author' => __( 'Author', 'bbpress' ),  
  566. 'bbp_topic_created' => __( 'Created', 'bbpress' ),  
  567. 'bbp_topic_freshness' => __( 'Freshness', 'bbpress' ) 
  568. ); 
  569.  
  570. return apply_filters( 'bbp_admin_topics_column_headers', $columns ); 
  571.  
  572. /** 
  573. * Print extra columns for the topics page 
  574. * @since bbPress (r2485) 
  575. * @param string $column Column 
  576. * @param int $topic_id Topic id 
  577. * @uses bbp_get_topic_forum_id() To get the forum id of the topic 
  578. * @uses bbp_forum_title() To output the topic's forum title 
  579. * @uses apply_filters() Calls 'topic_forum_row_actions' with an array 
  580. * of topic forum actions 
  581. * @uses bbp_get_forum_permalink() To get the forum permalink 
  582. * @uses admin_url() To get the admin url of post.php 
  583. * @uses bbp_topic_reply_count() To output the topic reply count 
  584. * @uses bbp_topic_voice_count() To output the topic voice count 
  585. * @uses bbp_topic_author_display_name() To output the topic author name 
  586. * @uses get_the_date() Get the topic creation date 
  587. * @uses get_the_time() Get the topic creation time 
  588. * @uses esc_attr() To sanitize the topic creation time 
  589. * @uses bbp_get_topic_last_active_time() To get the time when the topic was 
  590. * last active 
  591. * @uses do_action() Calls 'bbp_admin_topics_column_data' with the 
  592. * column and topic id 
  593. */ 
  594. public function column_data( $column, $topic_id ) { 
  595.  
  596. if ( $this->bail() ) return; 
  597.  
  598. // Get topic forum ID 
  599. $forum_id = bbp_get_topic_forum_id( $topic_id ); 
  600.  
  601. // Populate column data 
  602. switch ( $column ) { 
  603.  
  604. // Forum 
  605. case 'bbp_topic_forum' : 
  606.  
  607. // Output forum name 
  608. if ( !empty( $forum_id ) ) { 
  609.  
  610. // Forum Title 
  611. $forum_title = bbp_get_forum_title( $forum_id ); 
  612. if ( empty( $forum_title ) ) { 
  613. $forum_title = esc_html__( 'No Forum', 'bbpress' ); 
  614.  
  615. // Output the title 
  616. echo $forum_title; 
  617.  
  618. } else { 
  619. esc_html_e( '(No Forum)', 'bbpress' ); 
  620.  
  621. break; 
  622.  
  623. // Reply Count 
  624. case 'bbp_topic_reply_count' : 
  625. bbp_topic_reply_count( $topic_id ); 
  626. break; 
  627.  
  628. // Reply Count 
  629. case 'bbp_topic_voice_count' : 
  630. bbp_topic_voice_count( $topic_id ); 
  631. break; 
  632.  
  633. // Author 
  634. case 'bbp_topic_author' : 
  635. bbp_topic_author_display_name( $topic_id ); 
  636. break; 
  637.  
  638. // Freshness 
  639. case 'bbp_topic_created': 
  640. printf( '%1$s <br /> %2$s',  
  641. get_the_date(),  
  642. esc_attr( get_the_time() ) 
  643. ); 
  644.  
  645. break; 
  646.  
  647. // Freshness 
  648. case 'bbp_topic_freshness' : 
  649. $last_active = bbp_get_topic_last_active_time( $topic_id, false ); 
  650. if ( !empty( $last_active ) ) { 
  651. echo esc_html( $last_active ); 
  652. } else { 
  653. esc_html_e( 'No Replies', 'bbpress' ); // This should never happen 
  654.  
  655. break; 
  656.  
  657. // Do an action for anything else 
  658. default : 
  659. do_action( 'bbp_admin_topics_column_data', $column, $topic_id ); 
  660. break; 
  661.  
  662. /** 
  663. * Topic Row actions 
  664. * Remove the quick-edit action link under the topic title and add the 
  665. * content and close/stick/spam links 
  666. * @since bbPress (r2485) 
  667. * @param array $actions Actions 
  668. * @param array $topic Topic object 
  669. * @uses bbp_get_topic_post_type() To get the topic post type 
  670. * @uses bbp_topic_content() To output topic content 
  671. * @uses bbp_get_topic_permalink() To get the topic link 
  672. * @uses bbp_get_topic_title() To get the topic title 
  673. * @uses current_user_can() To check if the current user can edit or 
  674. * delete the topic 
  675. * @uses bbp_is_topic_open() To check if the topic is open 
  676. * @uses bbp_is_topic_spam() To check if the topic is marked as spam 
  677. * @uses bbp_is_topic_sticky() To check if the topic is a sticky or a 
  678. * super sticky 
  679. * @uses get_post_type_object() To get the topic post type object 
  680. * @uses add_query_arg() To add custom args to the url 
  681. * @uses remove_query_arg() To remove custom args from the url 
  682. * @uses wp_nonce_url() To nonce the url 
  683. * @uses get_delete_post_link() To get the delete post link of the topic 
  684. * @return array $actions Actions 
  685. */ 
  686. public function row_actions( $actions, $topic ) { 
  687.  
  688. if ( $this->bail() ) return $actions; 
  689.  
  690. unset( $actions['inline hide-if-no-js'] ); 
  691.  
  692. // Show view link if it's not set, the topic is trashed and the user can view trashed topics 
  693. if ( empty( $actions['view'] ) && ( bbp_get_trash_status_id() === $topic->post_status ) && current_user_can( 'view_trash' ) ) 
  694. $actions['view'] = '<a href="' . esc_url( bbp_get_topic_permalink( $topic->ID ) ) . '" title="' . esc_attr( sprintf( __( 'View “%s”', 'bbpress' ), bbp_get_topic_title( $topic->ID ) ) ) . '" rel="permalink">' . esc_html__( 'View', 'bbpress' ) . '</a>'; 
  695.  
  696. // Only show the actions if the user is capable of viewing them :) 
  697. if ( current_user_can( 'moderate', $topic->ID ) ) { 
  698.  
  699. // Close 
  700. // Show the 'close' and 'open' link on published and closed posts only 
  701. if ( in_array( $topic->post_status, array( bbp_get_public_status_id(), bbp_get_closed_status_id() ) ) ) { 
  702. $close_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_close' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'close-topic_' . $topic->ID ); 
  703. if ( bbp_is_topic_open( $topic->ID ) ) 
  704. $actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Close this topic', 'bbpress' ) . '">' . _x( 'Close', 'Close a Topic', 'bbpress' ) . '</a>'; 
  705. else 
  706. $actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Open this topic', 'bbpress' ) . '">' . _x( 'Open', 'Open a Topic', 'bbpress' ) . '</a>'; 
  707.  
  708. // Dont show sticky if topic links is spam or trash 
  709. if ( !bbp_is_topic_spam( $topic->ID ) && !bbp_is_topic_trash( $topic->ID ) ) { 
  710.  
  711. // Sticky 
  712. $stick_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_stick' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_' . $topic->ID ); 
  713. if ( bbp_is_topic_sticky( $topic->ID ) ) { 
  714. $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Unstick this topic', 'bbpress' ) . '">' . esc_html__( 'Unstick', 'bbpress' ) . '</a>'; 
  715. } else { 
  716. $super_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_stick', 'super' => '1' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_' . $topic->ID ); 
  717. $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Stick this topic to its forum', 'bbpress' ) . '">' . esc_html__( 'Stick', 'bbpress' ) . '</a> <a href="' . esc_url( $super_uri ) . '" title="' . esc_attr__( 'Stick this topic to front', 'bbpress' ) . '">' . esc_html__( '(to front)', 'bbpress' ) . '</a>'; 
  718.  
  719. // Spam 
  720. $spam_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_spam' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'spam-topic_' . $topic->ID ); 
  721. if ( bbp_is_topic_spam( $topic->ID ) ) 
  722. $actions['spam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark the topic as not spam', 'bbpress' ) . '">' . esc_html__( 'Not spam', 'bbpress' ) . '</a>'; 
  723. else 
  724. $actions['spam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark this topic as spam', 'bbpress' ) . '">' . esc_html__( 'Spam', 'bbpress' ) . '</a>'; 
  725.  
  726.  
  727. // Do not show trash links for spam topics, or spam links for trashed topics 
  728. if ( current_user_can( 'delete_topic', $topic->ID ) ) { 
  729. if ( bbp_get_trash_status_id() === $topic->post_status ) { 
  730. $post_type_object = get_post_type_object( bbp_get_topic_post_type() ); 
  731. $actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash', 'bbpress' ) . "' href='" . esc_url( wp_nonce_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $topic->ID ) ) ), 'untrash-' . $topic->post_type . '_' . $topic->ID ) ) . "'>" . esc_html__( 'Restore', 'bbpress' ) . "</a>"; 
  732. } elseif ( EMPTY_TRASH_DAYS ) { 
  733. $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash', 'bbpress' ) . "' href='" . esc_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), get_delete_post_link( $topic->ID ) ) ) . "'>" . esc_html__( 'Trash', 'bbpress' ) . "</a>"; 
  734.  
  735. if ( bbp_get_trash_status_id() === $topic->post_status || !EMPTY_TRASH_DAYS ) { 
  736. $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently', 'bbpress' ) . "' href='" . esc_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), get_delete_post_link( $topic->ID, '', true ) ) ) . "'>" . esc_html__( 'Delete Permanently', 'bbpress' ) . "</a>"; 
  737. } elseif ( bbp_get_spam_status_id() === $topic->post_status ) { 
  738. unset( $actions['trash'] ); 
  739.  
  740. return $actions; 
  741.  
  742. /** 
  743. * Add forum dropdown to topic and reply list table filters 
  744. * @since bbPress (r2991) 
  745. * @uses bbp_get_reply_post_type() To get the reply post type 
  746. * @uses bbp_get_topic_post_type() To get the topic post type 
  747. * @uses bbp_dropdown() To generate a forum dropdown 
  748. * @return bool False. If post type is not topic or reply 
  749. */ 
  750. public function filter_dropdown() { 
  751.  
  752. if ( $this->bail() ) return; 
  753.  
  754. // Add Empty Spam button 
  755. if ( !empty( $_GET['post_status'] ) && ( bbp_get_spam_status_id() === $_GET['post_status'] ) && current_user_can( 'moderate' ) ) { 
  756. wp_nonce_field( 'bulk-destroy', '_destroy_nonce' ); 
  757. $title = esc_attr__( 'Empty Spam', 'bbpress' ); 
  758. submit_button( $title, 'button-secondary apply', 'delete_all', false ); 
  759.  
  760. // Get which forum is selected 
  761. $selected = !empty( $_GET['bbp_forum_id'] ) ? $_GET['bbp_forum_id'] : ''; 
  762.  
  763. // Show the forums dropdown 
  764. bbp_dropdown( array( 
  765. 'selected' => $selected,  
  766. 'show_none' => __( 'In all forums', 'bbpress' ) 
  767. ) ); 
  768.  
  769. /** 
  770. * Adjust the request query and include the forum id 
  771. * @since bbPress (r2991) 
  772. * @param array $query_vars Query variables from {@link WP_Query} 
  773. * @uses is_admin() To check if it's the admin section 
  774. * @uses bbp_get_topic_post_type() To get the topic post type 
  775. * @uses bbp_get_reply_post_type() To get the reply post type 
  776. * @return array Processed Query Vars 
  777. */ 
  778. function filter_post_rows( $query_vars ) { 
  779.  
  780. if ( $this->bail() ) return $query_vars; 
  781.  
  782. // Add post_parent query_var if one is present 
  783. if ( !empty( $_GET['bbp_forum_id'] ) ) { 
  784. $query_vars['meta_key'] = '_bbp_forum_id'; 
  785. $query_vars['meta_value'] = $_GET['bbp_forum_id']; 
  786.  
  787. // Return manipulated query_vars 
  788. return $query_vars; 
  789.  
  790. /** 
  791. * Custom user feedback messages for topic post type 
  792. * @since bbPress (r3080) 
  793. * @global int $post_ID 
  794. * @uses bbp_get_topic_permalink() 
  795. * @uses wp_post_revision_title() 
  796. * @uses esc_url() 
  797. * @uses add_query_arg() 
  798. * @param array $messages 
  799. * @return array 
  800. */ 
  801. public function updated_messages( $messages ) { 
  802. global $post_ID; 
  803.  
  804. if ( $this->bail() ) return $messages; 
  805.  
  806. // URL for the current topic 
  807. $topic_url = bbp_get_topic_permalink( $post_ID ); 
  808.  
  809. // Current topic's post_date 
  810. $post_date = bbp_get_global_post_field( 'post_date', 'raw' ); 
  811.  
  812. // Messages array 
  813. $messages[$this->post_type] = array( 
  814. 0 => '', // Left empty on purpose 
  815.  
  816. // Updated 
  817. 1 => sprintf( __( 'Topic updated. <a href="%s">View topic</a>', 'bbpress' ), $topic_url ),  
  818.  
  819. // Custom field updated 
  820. 2 => __( 'Custom field updated.', 'bbpress' ),  
  821.  
  822. // Custom field deleted 
  823. 3 => __( 'Custom field deleted.', 'bbpress' ),  
  824.  
  825. // Topic updated 
  826. 4 => __( 'Topic updated.', 'bbpress' ),  
  827.  
  828. // Restored from revision 
  829. // translators: %s: date and time of the revision 
  830. 5 => isset( $_GET['revision'] ) 
  831. ? sprintf( __( 'Topic restored to revision from %s', 'bbpress' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) 
  832. : false,  
  833.  
  834. // Topic created 
  835. 6 => sprintf( __( 'Topic created. <a href="%s">View topic</a>', 'bbpress' ), $topic_url ),  
  836.  
  837. // Topic saved 
  838. 7 => __( 'Topic saved.', 'bbpress' ),  
  839.  
  840. // Topic submitted 
  841. 8 => sprintf( __( 'Topic submitted. <a target="_blank" href="%s">Preview topic</a>', 'bbpress' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),  
  842.  
  843. // Topic scheduled 
  844. 9 => sprintf( __( 'Topic scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview topic</a>', 'bbpress' ),  
  845. // translators: Publish box date format, see http://php.net/date 
  846. date_i18n( __( 'M j, Y @ G:i', 'bbpress' ),  
  847. strtotime( $post_date ) ),  
  848. $topic_url ),  
  849.  
  850. // Topic draft updated 
  851. 10 => sprintf( __( 'Topic draft updated. <a target="_blank" href="%s">Preview topic</a>', 'bbpress' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),  
  852. ); 
  853.  
  854. return $messages;