Featured_Replies

Based on Featured Comments by Pippin Williamson and Utkarsh Kukreti.

Defined (1)

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

/bbpress-featured-replies.php  
  1. final class Featured_Replies { 
  2.  
  3.  
  4. /** Singleton *************************************************************/ 
  5.  
  6. /** 
  7. * @var Featured_Replies 
  8. */ 
  9. private static $instance; 
  10.  
  11. /** 
  12. * @var array possible feature/bury actions 
  13. */ 
  14. private static $actions; 
  15.  
  16.  
  17. /** 
  18. * Main Featured_Replies Instance 
  19. * Ensures that only one instance of Featured_Replies exists in memory at any one 
  20. * time. Also prevents needing to define globals all over the place. 
  21. * @since v1.0 
  22. * @staticvar array $instance 
  23. * @see wp_featured_replies_load() 
  24. * @return The one true Featured_Replies 
  25. */ 
  26. public static function instance() { 
  27.  
  28. add_action( 'admin_init', array( 'Featured_Replies', 'check_for_bbpress' ) ); 
  29.  
  30. if ( ! self::is_bbpress_active() ) { 
  31. return; 
  32.  
  33. if ( ! isset( self::$instance ) ) { 
  34. self::$instance = new Featured_Replies; 
  35. self::$instance->includes(); 
  36. self::$instance->init(); 
  37. self::$instance->load_textdomain(); 
  38. return self::$instance; 
  39.  
  40.  
  41. private function includes() { 
  42.  
  43. include_once( dirname( __FILE__ ) . '/includes/widget.php' ); 
  44.  
  45.  
  46. /** Filters & Actions **/ 
  47. private function init() { 
  48.  
  49. self::$actions = array( 
  50. 'feature' => __( 'Feature', 'bbp-featured-replies' ),  
  51. 'unfeature' => __( 'Unfeature', 'bbp-featured-replies' ),  
  52. 'bury' => __( 'Bury', 'bbp-featured-replies' ),  
  53. 'unbury' => __( 'Unbury', 'bbp-featured-replies' ) 
  54. ); 
  55.  
  56. /** Backend */ 
  57. add_action( 'save_post', array( $this, 'save_meta_box_postdata' ) ); 
  58. add_action( 'add_meta_boxes', array( $this, 'add_reply_meta_box' ) ); 
  59. add_action( 'wp_ajax_featured_replies', array( $this, 'ajax' ) ); 
  60. add_filter( 'bbp_get_reply_content', array( $this, 'add_reply_actions' ), 10, 2 ); 
  61. add_filter( 'post_row_actions', array( $this, 'reply_row_actions' ), 10, 2 ); 
  62.  
  63. add_action( 'wp_enqueue_scripts', array( $this, 'maybe_print_scripts' ) ); 
  64. add_action( 'admin_print_scripts', array( $this, 'maybe_print_scripts' ) ); 
  65. add_action( 'wp_print_styles', array( $this, 'maybe_print_styles' ) ); 
  66. add_action( 'admin_print_styles', array( $this, 'maybe_print_styles' ) ); 
  67.  
  68. add_filter( 'user_has_cap', array( $this, 'map_feature_cap' ), 10, 4 ); 
  69.  
  70. /** Frontend */ 
  71. add_filter( 'bbp_get_reply_class', array( $this, 'reply_class' ), 10, 2 ); 
  72.  
  73.  
  74. public function load_textdomain() { 
  75.  
  76. // Set filter for plugin's languages directory 
  77. $lang_dir = dirname( plugin_basename( __FILE__ ) ) . '/languages/'; 
  78. $lang_dir = apply_filters( 'featured_replies_languages_directory', $lang_dir ); 
  79.  
  80.  
  81. // Traditional WordPress plugin locale filter 
  82. $locale = apply_filters( 'plugin_locale', get_locale(), 'bbp-featured-replies' ); 
  83. $mofile = sprintf( '%1$s-%2$s.mo', 'bbp-featured-replies', $locale ); 
  84.  
  85. // Setup paths to current locale file 
  86. $mofile_local = $lang_dir . $mofile; 
  87. $mofile_global = WP_LANG_DIR . '/bbp-featured-replies/' . $mofile; 
  88.  
  89. if ( file_exists( $mofile_global ) ) { 
  90. // Look in global /wp-content/languages/bbp-featured-replies folder 
  91. load_textdomain( 'bbp-featured-replies', $mofile_global ); 
  92. } elseif ( file_exists( $mofile_local ) ) { 
  93. // Look in local /wp-content/plugins/bbp-featured-replies/languages/ folder 
  94. load_textdomain( 'bbp-featured-replies', $mofile_local ); 
  95. } else { 
  96. // Load the default language files 
  97. load_plugin_textdomain( 'bbp-featured-replies', false, $lang_dir ); 
  98.  
  99.  
  100. private static function is_bbpress_active() { 
  101. return class_exists( 'bbPress' ); 
  102.  
  103. public static function activation_check() { 
  104. if ( ! self::is_bbpress_active() ) { 
  105. deactivate_plugins( plugin_basename( __FILE__ ) ); 
  106. wp_die( __( 'bbPress - Featured Replies requires bbPress to be activated.', 'bbp-featured-replies' ) ); 
  107.  
  108. public static function check_for_bbpress() { 
  109. if ( ! self::is_bbpress_active() ) { 
  110. if ( is_plugin_active( plugin_basename( __FILE__ ) ) ) { 
  111. deactivate_plugins( plugin_basename( __FILE__ ) ); 
  112.  
  113. add_action( 'admin_notices', array( 'Featured_Replies', 'disabled_notice' ) ); 
  114.  
  115. if ( isset( $_GET['activate'] ) ) { 
  116. unset( $_GET['activate'] ); 
  117.  
  118. public function disabled_notice() { 
  119. echo '<div class="updated"><p><strong>' . esc_html__( 'bbPress - Featured Replies was deactivated. This plugin requires bbPress to be activated.', 'bbp-featured-replies' ) . '</strong></p></div>'; 
  120.  
  121. // Scripts 
  122. public function maybe_print_scripts() { 
  123.  
  124. // Admin 
  125. if ( is_admin() ) { 
  126. if ( current_user_can( 'moderate' ) ) { 
  127. $this->enqueue_scripts(); 
  128.  
  129. return; 
  130.  
  131. // Front-end only 
  132. $post = get_post(); 
  133.  
  134. if ( current_user_can( 'feature_replies', $post->ID ) ) { 
  135. $this->enqueue_scripts(); 
  136.  
  137.  
  138. public function enqueue_scripts() { 
  139.  
  140. wp_enqueue_script( 'featured-replies', plugin_dir_url( __FILE__ ) . 'js/featured-replies.js', array( 'jquery' ), filemtime( dirname( __FILE__ ) . '/js/featured-replies.js' ) ); 
  141. wp_localize_script( 'featured-replies', 'Featured_Replies', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); 
  142.  
  143. // Styles 
  144. public function maybe_print_styles() { 
  145.  
  146. // Admin 
  147. if ( is_admin() ) { 
  148. if ( current_user_can( 'moderate' ) ) { 
  149. $this->print_styles(); 
  150.  
  151. return; 
  152.  
  153. // Front-end only 
  154. $post = get_post(); 
  155.  
  156. if ( current_user_can( 'feature_replies', $post->ID ) ) { 
  157. $this->print_styles(); 
  158.  
  159.  
  160. public function print_styles() { 
  161. ?> 
  162. <style> 
  163. #bbpress-forums .featured-replies.unfeature, #bbpress-forums .featured-replies.unbury, .featured-replies.unfeature, .featured-replies.unbury { display:none; } 
  164. #bbpress-forums .featured-replies, .featured-replies { cursor:pointer;} 
  165. #bbpress-forums .featured.featured-replies.feature, .featured.featured-replies.feature { display:none; } 
  166. #bbpress-forums .featured.featured-replies.unfeature, .featured.featured-replies.unfeature { display:inline; } 
  167. #bbpress-forums .buried.featured-replies.bury, .buried.featured-replies.bury { display:none; } 
  168. #bbpress-forums .buried.featured-replies.unbury, .buried.featured-replies.unbury { display:inline; } 
  169. .post-type-reply #the-list tr.featured { background-color: #dfd; } 
  170. .post-type-reply #the-list tr.buried { opacity: 0.5; } 
  171. </style> 
  172. <?php 
  173.  
  174.  
  175. public function ajax() { 
  176.  
  177. if ( ! isset( $_POST['do'] ) ) { 
  178. die(); 
  179.  
  180. $action = $_POST['do']; 
  181.  
  182. $actions = array_keys( self::$actions ); 
  183.  
  184. if ( in_array( $action, $actions ) ) { 
  185.  
  186. $reply_id = absint( $_POST['reply_id'] ); 
  187.  
  188. // Verify reply exists 
  189. if ( ! $reply = bbp_get_reply( $reply_id ) ) { 
  190. die(); 
  191.  
  192. // Verify whether user has the capability to moderate it 
  193. if ( ! current_user_can( 'feature_replies', $reply_id ) ) { 
  194. die(); 
  195.  
  196. // TAKE ACTION! 
  197. switch ( $action ) { 
  198.  
  199. case 'feature': 
  200. add_post_meta( $reply_id, 'featured', '1' ); 
  201. break; 
  202.  
  203. case 'unfeature': 
  204. delete_post_meta( $reply_id, 'featured' ); 
  205. break; 
  206.  
  207. case 'bury': 
  208. add_post_meta( $reply_id, 'buried', '1' ); 
  209. break; 
  210.  
  211. case 'unbury': 
  212. delete_post_meta( $reply_id, 'buried' ); 
  213. break; 
  214.  
  215.  
  216. die(); 
  217.  
  218.  
  219. public function add_reply_actions( $content, $reply_id ) { 
  220. if ( is_admin() || ! current_user_can( 'feature_replies', $reply_id ) ) { 
  221. return $content; 
  222.  
  223. $reply = bbp_get_reply( $reply_id ); 
  224.  
  225. // Check if reply exists, and verify that reply isn't the main topic 
  226. if ( ! $reply || $reply_id == $reply->post_parent ) { 
  227. return $content; 
  228.  
  229. $data_id = ' data-reply_id=' . $reply_id; 
  230.  
  231. $current_status = implode( ' ', $this->reply_class( array(), $reply_id ) ); 
  232.  
  233. $o = '<div class="feature-bury-replies">'; 
  234.  
  235. foreach ( self::$actions as $action => $label ) { 
  236. $o .= "<a class='featured-replies {$current_status} {$action}' data-do='{$action}' {$data_id} title='{$label}'>{$label}</a> "; 
  237.  
  238. $o .= '</div>'; 
  239.  
  240. return $content . $o; 
  241.  
  242.  
  243. /** 
  244. * Reply Row actions 
  245. * Add featured replies action links to replies 
  246. * @since 0.1.0 
  247. * @param array $actions Actions 
  248. * @param array $reply Reply object 
  249. * @return array $actions Actions 
  250. */ 
  251. public function reply_row_actions( $actions, $reply ) { 
  252.  
  253. // Bail if we're not editing replies 
  254. if ( bbp_get_reply_post_type() != get_current_screen()->post_type ) { 
  255. return $actions; 
  256.  
  257. // Only show the actions if the user is capable of viewing them :) 
  258. if ( current_user_can( 'feature_replies', $reply->ID ) ) { 
  259.  
  260. $data_id = ' data-reply_id=' . $reply->ID; 
  261.  
  262. $current_status = implode( ' ', self::reply_class( array(), $reply->ID ) ); 
  263.  
  264. $o = ''; 
  265. $o .= "<a data-do='unfeature' {$data_id} class='featured-replies unfeature {$current_status}' title='" . esc_attr__( 'Unfeature this comment', 'bbp-featured-replies' ) . "'>" . __( 'Unfeature', 'bbp-featured-replies' ) . '</a>'; 
  266. $o .= "<a data-do='feature' {$data_id} class='featured-replies feature {$current_status}' title='" . esc_attr__( 'Feature this comment', 'bbp-featured-replies' ) . "'>" . __( 'Feature', 'bbp-featured-replies' ) . '</a>'; 
  267. $o .= ' | '; 
  268. $o .= "<a data-do='unbury' {$data_id} class='featured-replies unbury {$current_status}' title='" . esc_attr__( 'Unbury this comment', 'bbp-featured-replies' ) . "'>" . __( 'Unbury', 'bbp-featured-replies' ) . '</a>'; 
  269. $o .= "<a data-do='bury' {$data_id} class='featured-replies bury {$current_status}' title='" . esc_attr__( 'Bury this comment', 'bbp-featured-replies' ) . "'>" . __( 'Bury', 'bbp-featured-replies' ) . '</a>'; 
  270.  
  271. $o = "<span class='$current_status'>$o</span>"; 
  272.  
  273. $actions['featured_replies'] = $o; 
  274.  
  275. return $actions; 
  276.  
  277.  
  278. public function add_reply_meta_box() { 
  279.  
  280. add_meta_box( 'reply_meta_box', __( 'Featured Replies', 'bbp-featured-replies' ), array( $this, 'reply_meta_box' ), bbp_get_reply_post_type(), 'normal' ); 
  281.  
  282. public function save_meta_box_postdata( $reply_id ) { 
  283.  
  284. if ( ! isset( $_POST['featured_replies_nonce'] ) || ! wp_verify_nonce( $_POST['featured_replies_nonce'], plugin_basename( __FILE__ ) ) ) { 
  285. return; 
  286.  
  287. if ( ! current_user_can( 'feature_replies', $reply_id ) ) { 
  288. wp_die( __( 'You are not allowed to moderate this reply.', 'bbp-featured-replies' ) ); 
  289.  
  290. // Handle feature 
  291. if ( isset( $_POST['featured'] ) ) { 
  292. update_post_meta( $reply_id, 'featured', '1' ); 
  293. } else { 
  294. delete_post_meta( $reply_id, 'featured' ); 
  295.  
  296. // Handle bury 
  297. if ( isset( $_POST['buried'] ) ) { 
  298. update_post_meta( $reply_id, 'buried', '1' ); 
  299. } else { 
  300. delete_post_meta( $reply_id, 'buried' ); 
  301.  
  302.  
  303. public function reply_meta_box( $post ) { 
  304.  
  305. // Bail if post isn't set 
  306. if ( ! $post ) { 
  307. return; 
  308.  
  309. // Non-moderator topic authors shouldn't be in the admin, so we only check for 'moderate' cap here 
  310. if ( ! current_user_can( 'moderate' ) ) { 
  311. return; 
  312.  
  313. echo '<p>'; 
  314. echo wp_nonce_field( plugin_basename( __FILE__ ), 'featured_replies_nonce' ); 
  315.  
  316. echo '<input id = "featured" type="checkbox" name="featured" value="true"' . checked( true, self::is_reply_featured( $post->ID ), false ) . '/>'; 
  317. echo ' <label for="featured">' . __( "Featured", 'bbp-featured-replies' ) . '</label> '; 
  318. echo '<input id = "buried" type="checkbox" name="buried" value="true"' . checked( true, self::is_reply_buried( $post->ID ), false ) . '/>'; 
  319. echo ' <label for="buried">' . __( "Buried", 'bbp-featured-replies' ) . '</label>'; 
  320. echo '</p>'; 
  321.  
  322.  
  323. public function reply_class( $classes = array(), $reply_id ) { 
  324.  
  325. if ( self::is_reply_featured( $reply_id ) ) { 
  326. $classes[] = 'featured'; 
  327.  
  328. if ( self::is_reply_buried( $reply_id ) ) { 
  329. $classes[] = 'buried'; 
  330.  
  331. return $classes; 
  332.  
  333.  
  334. private static function is_reply_featured( $reply_id ) { 
  335.  
  336. return '1' == get_post_meta( $reply_id, 'featured', true ); 
  337.  
  338. private static function is_reply_buried( $reply_id ) { 
  339.  
  340. return '1' == get_post_meta( $reply_id, 'buried', true ); 
  341.  
  342. public function map_feature_cap( $allcaps, $caps, $args, $user ) { 
  343.  
  344. if ( 'feature_replies' == $args[0] ) { 
  345.  
  346. // All moderators should have this cap 
  347. if ( isset( $allcaps['moderate'] ) ) { 
  348. $allcaps[ $caps[0] ] = true; 
  349.  
  350. // Get reply topic id 
  351. $topic_id = bbp_get_reply_topic_id( absint( $args[2] ) ); 
  352. $topic_author_id = bbp_get_topic_author_id( $topic_id ); 
  353.  
  354. // Check if the user authored the reply, and give them the cap if so 
  355. if ( $user->ID == $topic_author_id ) { 
  356. $allcaps[ $caps[0] ] = true; 
  357.  
  358.  
  359. return $allcaps; 
  360.