Ticket #6331: 6331.03.patch
File 6331.03.patch, 39.8 KB (added by , 10 years ago) |
---|
-
src/bp-core/bp-core-component.php
131 131 * Component loader. 132 132 * 133 133 * @since BuddyPress (1.5.0) 134 * 135 * @uses BP_Component::setup_actions() Set up the hooks and actions. 136 * 137 * @param string $id Unique ID (for internal identification). Letters, 138 * numbers, and underscores only. 139 * @param string $name Unique name. This should be a translatable name, 140 * eg __( 'Groups', 'buddypress' ). 141 * @param string $path The file path for the component's files. Used by 142 * {@link BP_Component::includes()}. 143 * @param array $params Additional parameters used by the component. 144 * The config array supports the following values: 145 * - 'adminbar_myaccount_order' Sets the position for our 146 * component menu under the WP Toolbar's "My Account" menu. 134 * @since BuddyPress (1.9.0) Added $params as a parameter. 135 * @since BuddyPress (2.3.0) Added $params['features'] as a configurable value. 136 * 137 * @param string $id Unique ID. Letters, numbers, and underscores only. 138 * @param string $name Unique name. This should be a translatable name, eg. 139 * __( 'Groups', 'buddypress' ). 140 * @param string $path The file path for the component's files. Used by {@link BP_Component::includes()}. 141 * @param array $params { 142 * Additional parameters used by the component. 143 * @type int $adminbar_myaccount_order Set the position for our menu under the WP Toolbar's "My Account menu" 144 * @type array $features An array of feature names. This is used to load additional files from your 145 * component directory and for feature active checks. eg. array( 'awesome' ) 146 * would look for a file called "bp-{$this->id}-awesome.php" and you could use 147 * bp_is_active( $this->id, 'awesome' ) to determine if the feature is active. 148 * } 147 149 */ 148 150 public function start( $id = '', $name = '', $path = '', $params = array() ) { 149 151 … … 163 165 $this->adminbar_myaccount_order = (int) $params['adminbar_myaccount_order']; 164 166 } 165 167 168 // Register features 169 if ( ! empty( $params['features'] ) ) { 170 $this->features = array_map( 'sanitize_title', (array) $params['features'] ); 171 } 172 166 173 // Set defaults if not passed 167 174 } else { 168 175 // new component menus are added before the settings menu if not set … … 183 190 * 184 191 * @param array $args { 185 192 * All values are optional. 186 * @type string $slug The component slug. Used to construct certain 187 * URLs, such as 'friends' in http://example.com/members/joe/friends/ 188 * Default: the value of $this->id. 189 * @type string $root_slug The component root slug. Note that this 190 * value is generally unused if the component has a root 191 * directory (the slug will be overridden by the post_name of 192 * the directory page). Default: the slug of the directory 193 * page if one is found, otherwise an empty string. 194 * @type bool $has_directory Set to true if the component requires 195 * an associated WordPress page. 196 * @type callable $notification_callback Optional. The callable 197 * function that formats the component's notifications. 198 * @type string $search_term Optional. The placeholder text in the 199 * component directory search box. Eg, 'Search Groups...'. 200 * @type array $global_tables Optional. An array of database table 201 * names. 202 * @type array $meta_tables Optional. An array of metadata table 203 * names. 193 * @type string $slug The component slug. Used to construct certain URLs, such as 'friends' in 194 * http://example.com/members/joe/friends/. Default: the value of $this->id. 195 * @type string $root_slug The component root slug. Note that this value is generally unused if the 196 * component has a root directory (the slug will be overridden by the 197 * post_name of the directory page). Default: the slug of the directory page 198 * if one is found, otherwise an empty string. 199 * @type bool $has_directory Set to true if the component requires an associated WordPress page. 200 * @type callable $notification_callback Optional. The callable function that formats the component's notifications. 201 * @type string $search_term Optional. The placeholder text in the component directory search box. Eg, 202 * 'Search Groups...'. 203 * @type array $global_tables Optional. An array of database table names. 204 * @type array $meta_tables Optional. An array of metadata table names. 204 205 * } 205 206 */ 206 207 public function setup_globals( $args = array() ) { -
src/bp-core/bp-core-template.php
1845 1845 /** Components ****************************************************************/ 1846 1846 1847 1847 /** 1848 * Check whether a given component has been activated by the admin. 1848 * Check whether a given component (or feature of a component) is active. 1849 * 1850 * @since BuddyPress (1.2.0) See r2539. 1851 * @since BuddyPress (2.3.0) Added $feature as a parameter. 1849 1852 * 1850 1853 * @param string $component The component name. 1851 * @return bool True if the component is active, otherwise false. 1854 * @param string $feature The feature name. 1855 * @return bool 1852 1856 */ 1853 function bp_is_active( $component = '' ) {1857 function bp_is_active( $component = '', $feature = '' ) { 1854 1858 $retval = false; 1855 1859 1856 1860 // Default to the current component if none is passed … … 1861 1865 // Is component in either the active or required components arrays 1862 1866 if ( isset( buddypress()->active_components[ $component ] ) || isset( buddypress()->required_components[ $component ] ) ) { 1863 1867 $retval = true; 1868 1869 // Is feature active? 1870 if ( ! empty( $feature ) ) { 1871 if ( empty( buddypress()->$component->features ) || false === in_array( $feature, buddypress()->$component->features, true ) ) { 1872 $retval = false; 1873 } 1874 1875 /** 1876 * Filters whether or not a given feature for a component is active. 1877 * 1878 * @since BuddyPress (2.3.0) 1879 * 1880 * @param bool $retval 1881 */ 1882 $retval = apply_filters( "bp_is_{$component}_{$feature}_active", $retval ); 1883 } 1864 1884 } 1865 1885 1866 1886 /** -
src/bp-messages/bp-messages-functions.php
366 366 return BP_Messages_Thread::is_valid( $thread_id ); 367 367 } 368 368 369 /** 370 * Get the thread ID from a message ID. 371 * 372 * @since BuddyPress (2.3.0) 373 * 374 * @param int $message_id ID of the message. 375 * @return int The ID of the thread if found, otherwise 0. 376 */ 377 function messages_get_message_thread_id( $message_id = 0 ) { 378 global $wpdb; 379 380 $bp = buddypress(); 381 382 return (int) $wpdb->get_var( $wpdb->prepare( "SELECT thread_id FROM {$bp->messages->table_name_messages} WHERE id = %d", $message_id ) ); 383 } 384 369 385 /** Messages Meta *******************************************************/ 370 386 371 387 /** -
src/bp-messages/bp-messages-loader.php
39 39 __( 'Private Messages', 'buddypress' ), 40 40 buddypress()->plugin_dir, 41 41 array( 42 'adminbar_myaccount_order' => 50 42 'adminbar_myaccount_order' => 50, 43 'features' => array( 'star' ) 43 44 ) 44 45 ); 45 46 } … … 67 68 'widgets', 68 69 ); 69 70 71 // Conditional includes 72 if ( bp_is_active( $this->id, 'star' ) ) { 73 $includes[] = 'star'; 74 } 75 70 76 parent::includes( $includes ); 71 77 } 72 78 … … 166 172 'user_has_access' => bp_core_can_edit_settings() 167 173 ); 168 174 175 if ( bp_is_active( $this->id, 'star' ) ) { 176 $sub_nav[] = array( 177 'name' => __( 'Starred', 'buddypress' ), 178 'slug' => bp_get_messages_starred_slug(), 179 'parent_url' => $messages_link, 180 'parent_slug' => $this->slug, 181 'screen_function' => 'bp_messages_star_screen', 182 'position' => 11, 183 'user_has_access' => bp_core_can_edit_settings() 184 ); 185 } 186 169 187 $sub_nav[] = array( 170 188 'name' => __( 'Sent', 'buddypress' ), 171 189 'slug' => 'sentbox', … … 243 261 'href' => trailingslashit( $messages_link . 'inbox' ) 244 262 ); 245 263 264 // Starred 265 if ( bp_is_active( $this->id, 'star' ) ) { 266 $wp_admin_nav[] = array( 267 'parent' => 'my-account-' . $this->id, 268 'id' => 'my-account-' . $this->id . '-starred', 269 'title' => __( 'Starred', 'buddypress' ), 270 'href' => trailingslashit( $messages_link . bp_get_messages_starred_slug() ) 271 ); 272 } 273 246 274 // Sent Messages 247 275 $wp_admin_nav[] = array( 248 276 'parent' => 'my-account-' . $this->id, -
new file src/bp-messages/bp-messages-star.php
new file mode 100644
- + 1 <?php 2 /** 3 * Functions related to starring private messages. 4 * 5 * @since BuddyPress (2.3.0) 6 */ 7 8 /** UTILITY **************************************************************/ 9 10 /** 11 * Return the starred messages slug. Defaults to 'starred'. 12 * 13 * @since BuddyPress (2.3.0) 14 * 15 * @return string 16 */ 17 function bp_get_messages_starred_slug() { 18 /** 19 * Filters the starred message slug. 20 * 21 * @since BuddyPress (2.3.0) 22 * 23 * @param string 24 */ 25 return sanitize_title( apply_filters( 'bp_get_messages_starred_slug', 'starred' ) ); 26 } 27 28 /** 29 * Function to determine if a message ID is starred. 30 * 31 * @since BuddyPress (2.3.0) 32 * 33 * @param int $mid The message ID. Please note that this isn't the message thread ID. 34 * @param int $user_id The user ID 35 * @return bool 36 */ 37 function bp_messages_is_message_starred( $mid = 0, $user_id = 0 ) { 38 if ( empty( $user_id ) ) { 39 $user_id = bp_loggedin_user_id(); 40 } 41 42 if ( empty( $mid ) ) { 43 return false; 44 } 45 46 $starred = array_flip( (array) bp_messages_get_meta( $mid, 'starred_by_user', false ) ); 47 48 if ( isset( $starred[$user_id] ) ) { 49 return true; 50 } else { 51 return false; 52 } 53 } 54 55 /** 56 * Output the link or raw URL for starring or unstarring a message. 57 * 58 * @since BuddyPress (2.3.0) 59 * 60 * @param array $args See bp_get_the_message_star_action_link() for full documentation. 61 */ 62 function bp_the_message_star_action_link( $args = array() ) { 63 echo bp_get_the_message_star_action_link( $args ); 64 } 65 /** 66 * Return the link or raw URL for starring or unstarring a message. 67 * 68 * @since BuddyPress (2.3.0) 69 * 70 * @param array $args { 71 * Array of arguments. 72 * @type int $user_id The user ID. Defaults to the logged-in user ID. 73 * @type int $thread_id The message thread ID. Default: 0. If not zero, this takes precedence over 74 * $message_id. 75 * @type int $message_id The individual message ID. If on a single thread page, defaults to the 76 * current message ID in the message loop. 77 * @type bool $url_only Whether to return the URL only. If false, returns link with markup. 78 * Default: false. 79 * @type string $text_unstar Link text for the 'unstar' action. Only applicable if $url_only is false. 80 * @type string $text_star Link text for the 'star' action. Only applicable if $url_only is false. 81 * @type string $title_unstar Link title for the 'unstar' action. Only applicable if $url_only is false. 82 * @type string $title_star Link title for the 'star' action. Only applicable if $url_only is false. 83 * @type string $title_unstar_thread Link title for the 'unstar' action when displayed in a thread loop. 84 * Only applicable if $message_id is set and if $url_only is false. 85 * @type string $title_star_thread Link title for the 'star' action when displayed in a thread loop. 86 * Only applicable if $message_id is set and if $url_only is false. 87 * } 88 * @return string 89 */ 90 function bp_get_the_message_star_action_link( $args = array() ) { 91 $r = bp_parse_args( $args, array( 92 'user_id' => bp_loggedin_user_id(), 93 'thread_id' => 0, 94 'message_id' => (int) bp_get_the_thread_message_id(), 95 'url_only' => false, 96 'text_unstar' => __( 'Unstar', 'buddypress' ), 97 'text_star' => __( 'Star', 'buddypress' ), 98 'title_unstar' => __( 'Starred', 'buddypress' ), 99 'title_star' => __( 'Not starred', 'buddypress' ), 100 'title_unstar_thread' => __( 'Remove all starred messages in this thread', 'buddypress' ), 101 'title_star_thread' => __( 'Star the first message in this thread', 'buddypress' ), 102 ), 'messages_star_action_link' ); 103 104 $retval = $bulk_attr = ''; 105 106 if ( 0 === $r['user_id'] ) { 107 return $retval; 108 } 109 110 // get user domain 111 if ( $r['user_id'] == bp_loggedin_user_id() ) { 112 $user_domain = bp_loggedin_user_domain(); 113 } elseif ( $r['user_id'] == bp_displayed_user_domain() ) { 114 $user_domain = bp_displayed_user_domain(); 115 } else { 116 $user_domain = bp_core_get_user_domain( $user_id ); 117 } 118 119 // thread ID 120 if ( (int) $r['thread_id'] > 0 ) { 121 // see if we're in the loop 122 if ( bp_get_message_thread_id() == $r['thread_id'] ) { 123 // grab all message ids 124 $mids = wp_list_pluck( $GLOBALS['messages_template']->thread->messages, 'id' ); 125 126 // make sure order is ASC 127 // order is DESC when used in the thread loop by default 128 $mids = array_reverse( $mids ); 129 130 // pull up the thread 131 } else { 132 $thread = new BP_Messages_thread( $r['thread_id'] ); 133 $mids = wp_list_pluck( $thread->messages, 'id' ); 134 } 135 136 $is_starred = false; 137 $message_id = 0; 138 foreach ( $mids as $mid ) { 139 // try to find the first msg that is starred in a thread 140 if ( true === bp_messages_is_message_starred( $mid ) ) { 141 $is_starred = true; 142 $message_id = $mid; 143 break; 144 } 145 } 146 147 // no star, so default to first message in thread 148 if ( empty( $message_id ) ) { 149 $message_id = $mids[0]; 150 } 151 152 // nonce 153 $nonce = wp_create_nonce( "bp-messages-star-{$message_id}" ); 154 155 if ( $is_starred ) { 156 $action = 'unstar'; 157 $bulk_attr = ' data-star-bulk="1"'; 158 $retval = $user_domain . bp_get_messages_slug() . '/unstar/' . $message_id . '/' . $nonce . '/all/'; 159 } else { 160 $action = 'star'; 161 $retval = $user_domain . bp_get_messages_slug() . '/star/' . $message_id . '/' . $nonce . '/'; 162 } 163 164 $title = $r["title_{$action}_thread"]; 165 166 // message ID 167 } else { 168 $message_id = (int) $r['message_id']; 169 $is_starred = bp_messages_is_message_starred( $message_id ); 170 $nonce = wp_create_nonce( "bp-messages-star-{$message_id}" ); 171 172 if ( $is_starred ) { 173 $action = 'unstar'; 174 $retval = $user_domain . bp_get_messages_slug() . '/unstar/' . $message_id . '/' . $nonce . '/'; 175 } else { 176 $action = 'star'; 177 $retval = $user_domain . bp_get_messages_slug() . '/star/' . $message_id . '/' . $nonce . '/'; 178 } 179 180 $title = $r["title_{$action}"]; 181 } 182 183 /** 184 * Filters the star action URL for starring / unstarring a message. 185 * 186 * @since BuddyPress (2.3.0) 187 * 188 * @param string $retval URL for starring / unstarring a message. 189 * @param array $r Parsed link arguments. See $args in bp_get_the_message_star_action_link(). 190 */ 191 $retval = esc_url( apply_filters( 'bp_get_the_message_star_action_urlonly', $retval, $r ) ); 192 if ( true === (bool) $r['url_only'] ) { 193 return $retval; 194 } 195 196 /** 197 * Filters the star action link, including markup. 198 * 199 * @since BuddyPress (2.3.0) 200 * 201 * @param string $retval Link for starring / unstarring a message, including markup. 202 * @param array $r Parsed link arguments. See $args in bp_get_the_message_star_action_link(). 203 */ 204 return apply_filters( 'bp_get_the_message_star_action_link', '<a title="' . esc_attr( $title ) . '" class="message-action-' . $action . '" data-star-status="' . $action .'" data-star-nonce="' . $nonce . '"' . $bulk_attr . ' data-message-id="' . esc_attr( (int) $message_id ) . '" href="' . $retval . '"><span class="icon"></span> <span class="bp-screen-reader-text">' . $r['text_' . $action] . '</span></a>', $r ); 205 } 206 207 /** 208 * Save or delete star message meta according to a message's star status. 209 * 210 * @since BuddyPress (2.3.0) 211 * 212 * @param array $args { 213 * Array of arguments. 214 * @type string $action The star action. Either 'star' or 'unstar'. Default: 'star'. 215 * @type int $thread_id The message thread ID. Default: 0. If not zero, this takes precedence over 216 * $message_id. 217 * @type int $message_id The indivudal message ID to star or unstar. Default: 0. 218 * @type int $user_id The user ID. Defaults to the logged-in user ID. 219 * @type bool $bulk Whether to mark all messages in a thread as a certain action. Only relevant 220 * when $action is 'unstar' at the moment. Default: false. 221 * } 222 * @return bool 223 */ 224 function bp_messages_star_set_action( $args = array() ) { 225 $r = wp_parse_args( $args, array( 226 'action' => 'star', 227 'thread_id' => 0, 228 'message_id' => 0, 229 'user_id' => bp_loggedin_user_id(), 230 'bulk' => false 231 ) ); 232 233 // Set thread ID 234 if ( ! empty( $r['thread_id'] ) ) { 235 $thread_id = (int) $r['thread_id']; 236 } else { 237 $thread_id = messages_get_message_thread_id( $r['message_id'] ); 238 } 239 if ( empty( $thread_id ) ) { 240 return false; 241 } 242 243 // Check if user has access to thread 244 if( ! messages_check_thread_access( $thread_id, $r['user_id'] ) ) { 245 return false; 246 } 247 248 $is_starred = bp_messages_is_message_starred( $r['message_id'], $r['user_id'] ); 249 250 // star 251 if ( 'star' == $r['action'] ) { 252 if ( true === $is_starred ) { 253 return true; 254 } else { 255 bp_messages_add_meta( $r['message_id'], 'starred_by_user', $r['user_id'] ); 256 return true; 257 } 258 // unstar 259 } else { 260 // unstar one message 261 if ( false === $r['bulk'] ) { 262 if ( false === $is_starred ) { 263 return true; 264 } else { 265 bp_messages_delete_meta( $r['message_id'], 'starred_by_user', $r['user_id'] ); 266 return true; 267 } 268 269 // unstar all messages in a thread 270 } else { 271 $thread = new BP_Messages_Thread( $thread_id ); 272 $mids = wp_list_pluck( $thread->messages, 'id' ); 273 274 foreach ( $mids as $mid ) { 275 if ( true === bp_messages_is_message_starred( $mid, $r['user_id'] ) ) { 276 bp_messages_delete_meta( $mid, 'starred_by_user', $r['user_id'] ); 277 } 278 } 279 280 return true; 281 } 282 } 283 } 284 285 /** SCREENS **************************************************************/ 286 287 /** 288 * Screen handler to display a user's "Starred" private messages page. 289 * 290 * @since BuddyPress (2.3.0) 291 */ 292 function bp_messages_star_screen() { 293 add_action( 'bp_template_content', 'bp_messages_star_content' ); 294 295 /** 296 * Fires right before the loading of the "Starred" messages box. 297 * 298 * @since BuddyPress (2.3.0) 299 */ 300 do_action( 'bp_messages_screen_star' ); 301 302 bp_core_load_template( 'members/single/plugins' ); 303 } 304 305 /** 306 * Screen content callback to display a user's "Starred" messages page. 307 * 308 * @since BuddyPress (2.3.0) 309 */ 310 function bp_messages_star_content() { 311 // add our message thread filter 312 add_filter( 'bp_after_has_message_threads_parse_args', 'bp_messages_filter_starred_message_threads' ); 313 314 // load the message loop template part 315 bp_get_template_part( 'members/single/messages/messages-loop' ); 316 317 // remove our filter 318 remove_filter( 'bp_after_has_message_threads_parse_args', 'bp_messages_filter_starred_message_threads' ); 319 } 320 321 /** 322 * Filter message threads by those starred by the logged-in user. 323 * 324 * @since BuddyPress (2.3.0) 325 * 326 * @param array $r Current message thread arguments. 327 * @return array 328 */ 329 function bp_messages_filter_starred_message_threads( $r = array() ) { 330 $r['user_id'] = 0; 331 $r['meta_query'] = array( array( 332 'key' => 'starred_by_user', 333 'value' => bp_loggedin_user_id() 334 ) ); 335 336 return $r; 337 } 338 339 /** ACTIONS **************************************************************/ 340 341 /** 342 * Action handler to set a message's star status for those not using JS. 343 * 344 * @since BuddyPress (2.3.0) 345 */ 346 function bp_messages_star_action_handler() { 347 if ( ! bp_is_user_messages() ) { 348 return; 349 } 350 351 if ( false === ( bp_is_current_action( 'unstar' ) || bp_is_current_action( 'star' ) ) ) { 352 return; 353 } 354 355 if ( ! wp_verify_nonce( bp_action_variable( 1 ), 'bp-messages-star-' . bp_action_variable( 0 ) ) ) { 356 wp_die( "Oops! That's a no-no!" ); 357 } 358 359 // Check capability 360 if ( ! is_user_logged_in() || ! bp_core_can_edit_settings() ) { 361 return; 362 } 363 364 // mark the star 365 bp_messages_star_set_action( array( 366 'action' => bp_current_action(), 367 'message_id' => bp_action_variable(), 368 'bulk' => (bool) bp_action_variable( 2 ) 369 ) ); 370 371 // redirect back to previous screen 372 $redirect = wp_get_referer() ? wp_get_referer() : bp_loggedin_user_domain() . bp_get_messages_slug(); 373 bp_core_redirect( $redirect ); 374 die(); 375 } 376 add_action( 'bp_actions', 'bp_messages_star_action_handler' ); 377 378 /** 379 * Bulk manage handler to set the star status for multiple messages. 380 * 381 * @since BuddyPress (2.3.0) 382 */ 383 function bp_messages_star_bulk_manage_handler() { 384 if ( empty( $_POST['messages_bulk_nonce' ] ) ) { 385 return; 386 } 387 388 // Check the nonce. 389 if ( ! wp_verify_nonce( $_POST['messages_bulk_nonce'], 'messages_bulk_nonce' ) ) { 390 return; 391 } 392 393 // Check capability 394 if ( ! is_user_logged_in() || ! bp_core_can_edit_settings() ) { 395 return; 396 } 397 398 $action = ! empty( $_POST['messages_bulk_action'] ) ? $_POST['messages_bulk_action'] : ''; 399 $threads = ! empty( $_POST['message_ids'] ) ? $_POST['message_ids'] : ''; 400 $threads = wp_parse_id_list( $threads ); 401 402 // Bail if action doesn't match our star actions or no IDs. 403 if ( false === in_array( $action, array( 'star', 'unstar' ), true ) || empty( $threads ) ) { 404 return; 405 } 406 407 // It's star time! 408 switch ( $action ) { 409 case 'star' : 410 $count = count( $threads ); 411 412 // if we're starring a thread, we only star the first message in the thread 413 foreach ( $threads as $thread ) { 414 $thread = new BP_Messages_thread( $thread ); 415 $mids = wp_list_pluck( $thread->messages, 'id' ); 416 417 bp_messages_star_set_action( array( 418 'action' => 'star', 419 'message_id' => $mids[0], 420 ) ); 421 } 422 423 bp_core_add_message( sprintf( _n( '1 message was successfully starred', '%s messages were successfully starred', $count, 'buddypress' ), $count ) ); 424 break; 425 426 case 'unstar' : 427 $count = count( $threads ); 428 429 foreach ( $threads as $thread ) { 430 bp_messages_star_set_action( array( 431 'action' => 'unstar', 432 'thread_id' => $thread, 433 'bulk' => true 434 ) ); 435 } 436 437 bp_core_add_message( sprintf( _n( '1 message was successfully unstarred', '%s messages were successfully unstarred', $count, 'buddypress' ), $count ) ); 438 break; 439 } 440 441 // Redirect back to message box. 442 bp_core_redirect( bp_displayed_user_domain() . bp_get_messages_slug() . '/' . bp_current_action() . '/' ); 443 die(); 444 } 445 add_action( 'bp_actions', 'bp_messages_star_bulk_manage_handler', 5 ); 446 447 /** HOOKS ****************************************************************/ 448 449 /** 450 * Enqueues the dashicons font. 451 * 452 * The dashicons font is used for the star / unstar icon. 453 * 454 * @since BuddyPress (2.3.0) 455 */ 456 function bp_messages_star_enqueue_scripts() { 457 if ( ! bp_is_user_messages() ) { 458 return; 459 } 460 461 wp_enqueue_style( 'dashicons' ); 462 } 463 add_action( 'bp_enqueue_scripts', 'bp_messages_star_enqueue_scripts' ); 464 465 /** 466 * Add the "Add star" and "Remove star" options to the bulk management list. 467 * 468 * @since BuddyPress (2.3.0) 469 */ 470 function bp_messages_star_bulk_management_dropdown() { 471 ?> 472 473 <option value="star"><?php _e( 'Add star', 'buddypress' ); ?></option> 474 <option value="unstar"><?php _e( 'Remove star', 'buddypress' ); ?></option> 475 476 <?php 477 } 478 add_action( 'bp_messages_bulk_management_dropdown', 'bp_messages_star_bulk_management_dropdown', 1 ); 479 480 /** 481 * Add CSS class for the current message depending on starred status. 482 * 483 * @since BuddyPress (2.3.0) 484 * 485 * @param array $retval Current CSS classes 486 * @return array 487 */ 488 function bp_messages_star_message_css_class( $retval = array() ) { 489 if ( true === bp_messages_is_message_starred( bp_get_the_thread_message_id() ) ) { 490 $status = 'starred'; 491 } else { 492 $status = 'not-starred'; 493 } 494 495 // add css class based on star status for the current message 496 $retval[] = "message-{$status}"; 497 498 return $retval; 499 } 500 add_filter( 'bp_get_the_thread_message_css_class', 'bp_messages_star_message_css_class' ); -
src/bp-messages/bp-messages-template.php
1290 1290 <option value="read"><?php _e( 'Mark read', 'buddypress' ); ?></option> 1291 1291 <option value="unread"><?php _e( 'Mark unread', 'buddypress' ); ?></option> 1292 1292 <option value="delete"><?php _e( 'Delete', 'buddypress' ); ?></option> 1293 <?php 1294 /** 1295 * Action to add additional options to the messages bulk management dropdown. 1296 * 1297 * @since BuddyPress (2.3.0) 1298 */ 1299 do_action( 'bp_messages_bulk_management_dropdown' ); 1300 ?> 1293 1301 </select> 1294 1302 <input type="submit" id="messages-bulk-manage" class="button action" value="<?php esc_attr_e( 'Apply', 'buddypress' ); ?>"> 1295 1303 <?php -
src/bp-templates/bp-legacy/buddypress-functions.php
177 177 'messages_send_reply' => 'bp_legacy_theme_ajax_messages_send_reply', 178 178 ); 179 179 180 // Conditional actions 181 if ( bp_is_active( 'messages', 'star' ) ) { 182 $actions['messages_star'] = 'bp_legacy_theme_ajax_messages_star_handler'; 183 } 184 180 185 /** 181 186 * Register all of these AJAX handlers 182 187 * … … 307 312 // Enqueue script 308 313 wp_enqueue_script( $asset['handle'] . '-password-verify', $asset['location'], $dependencies, $this->version); 309 314 } 315 316 // Star private messages 317 if ( bp_is_active( 'messages', 'star' ) && bp_is_user_messages() ) { 318 wp_localize_script( $asset['handle'], 'BP_PM_Star', array( 319 'strings' => array( 320 'text_unstar' => __( 'Unstar', 'buddypress' ), 321 'text_star' => __( 'Star', 'buddypress' ), 322 'title_unstar' => __( 'Starred', 'buddypress' ), 323 'title_star' => __( 'Not starred', 'buddypress' ), 324 'title_unstar_thread' => __( 'Remove all starred messages in this thread', 'buddypress' ), 325 'title_star_thread' => __( 'Star the first message in this thread', 'buddypress' ), 326 ), 327 'is_single_thread' => (int) bp_is_messages_conversation(), 328 'star_counter' => 0, 329 'unstar_counter' => 0 330 ) ); 331 } 310 332 } 311 333 312 334 /** … … 1687 1709 1688 1710 exit; 1689 1711 } 1712 1713 /** 1714 * AJAX callback to set a message's star status. 1715 * 1716 * @since BuddyPress (2.3.0) 1717 */ 1718 function bp_legacy_theme_ajax_messages_star_handler() { 1719 if ( false === bp_is_active( 'messages', 'star' ) || empty( $_POST['message_id'] ) ) { 1720 return; 1721 } 1722 1723 // Check nonce 1724 check_ajax_referer( 'bp-messages-star-' . (int) $_POST['message_id'], 'nonce' ); 1725 1726 // Check capability 1727 if ( ! is_user_logged_in() || ( ! bp_is_my_profile() && ! bp_current_user_can( 'bp_moderate' ) ) ) { 1728 return; 1729 } 1730 1731 if ( true === bp_messages_star_set_action( array( 1732 'action' => $_POST['star_status'], 1733 'message_id' => (int) $_POST['message_id'], 1734 'bulk' => ! empty( $_POST['bulk'] ) ? true : false 1735 ) ) ) { 1736 echo '1'; 1737 die(); 1738 } 1739 1740 echo '-1'; 1741 die(); 1742 } -
src/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php
61 61 */ 62 62 do_action( 'bp_messages_inbox_list_header' ); ?> 63 63 64 <?php if ( bp_is_active( 'messages', 'star' ) ) : ?> 65 <th scope="col" class="thread-star"><span class="message-action-star"><span class="icon"></span> <span class="screen-reader-text"><?php _e( 'Star', 'buddypress' ); ?></span></span></th> 66 <?php endif; ?> 67 64 68 <th scope="col" class="thread-options"><?php _e( 'Actions', 'buddypress' ); ?></th> 65 69 </tr> 66 70 </thead> … … 107 111 */ 108 112 do_action( 'bp_messages_inbox_list_item' ); ?> 109 113 114 <?php if ( bp_is_active( 'messages', 'star' ) ) : ?> 115 <td class="thread-star"> 116 <?php bp_the_message_star_action_link( array( 'thread_id' => bp_get_message_thread_id() ) ); ?> 117 </td> 118 <?php endif; ?> 119 110 120 <td class="thread-options"> 111 121 <?php if ( bp_message_thread_has_unread() ) : ?> 112 122 <a class="read" href="<?php bp_the_message_thread_mark_read_url();?>"><?php _e( 'Read', 'buddypress' ); ?></a> -
src/bp-templates/bp-legacy/buddypress/members/single/messages/single.php
69 69 70 70 <span class="activity"><?php bp_the_thread_message_time_since(); ?></span> 71 71 72 <?php if ( bp_is_active( 'messages', 'star' ) ) : ?> 73 <div class="message-star-actions"> 74 <?php bp_the_message_star_action_link(); ?> 75 </div> 76 <?php endif; ?> 77 72 78 <?php 73 79 74 80 /** This action is documented in bp-templates/bp-legacy/buddypress-functions.php */ -
src/bp-templates/bp-legacy/css/buddypress.css
1448 1448 margin: 0 20px; 1449 1449 } 1450 1450 1451 .message-metadata { 1452 position: relative; 1453 } 1454 .message-star-actions { 1455 position: absolute; 1456 right: 0; 1457 top: 0; 1458 } 1459 a.message-action-star, 1460 a.message-action-unstar { 1461 text-decoration: none; 1462 outline: none; 1463 } 1464 a.message-action-star { 1465 opacity: .7; 1466 } 1467 a.message-action-star:hover { 1468 opacity: 1; 1469 } 1470 .message-action-star span.icon:before, 1471 .message-action-unstar span.icon:before { 1472 font-family: dashicons; 1473 font-size: 18px; 1474 } 1475 .message-action-star span.icon:before { 1476 color: #aaa; 1477 content: "\f154"; 1478 } 1479 .message-action-unstar span.icon:before { 1480 color: #FCDD77; 1481 content: "\f155"; 1482 } 1483 1451 1484 /*-------------------------------------------------------------- 1452 1485 3.10 - Extended Profiles 1453 1486 --------------------------------------------------------------*/ -
src/bp-templates/bp-legacy/js/buddypress.js
1578 1578 jq('#messages-bulk-manage').attr('disabled', jq(this).val().length <= 0); 1579 1579 }); 1580 1580 1581 /* Star action function */ 1582 starAction = function() { 1583 var link = jq(this); 1584 1585 jq.post( ajaxurl, { 1586 action: 'messages_star', 1587 'message_id': link.data('message-id'), 1588 'star_status': link.data('star-status'), 1589 'nonce': link.data('star-nonce'), 1590 'bulk': link.data('star-bulk') 1591 }, 1592 function(response) { 1593 if ( 1 == response ) { 1594 if ( 'unstar' === link.data('star-status') ) { 1595 link.data('star-status', 'star'); 1596 link.removeClass('message-action-unstar').addClass('message-action-star'); 1597 link.find('.bp-screen-reader-text').text( BP_PM_Star.strings.text_star ); 1598 1599 if ( 1 == BP_PM_Star.is_single_thread ) { 1600 link.prop('title', BP_PM_Star.strings.title_star ); 1601 } else { 1602 link.prop('title', BP_PM_Star.strings.title_star_thread ); 1603 } 1604 1605 } else { 1606 link.data('star-status', 'unstar'); 1607 link.removeClass('message-action-star').addClass('message-action-unstar'); 1608 link.find('.bp-screen-reader-text').text(BP_PM_Star.strings.text_unstar); 1609 1610 if ( 1 == BP_PM_Star.is_single_thread ) { 1611 link.prop('title', BP_PM_Star.strings.title_unstar ); 1612 } else { 1613 link.prop('title', BP_PM_Star.strings.title_unstar_thread ); 1614 } 1615 } 1616 } 1617 }); 1618 return false; 1619 } 1620 1621 /* Star actions */ 1622 jq('#message-threads').on('click', 'td.thread-star a', starAction ); 1623 jq('#message-thread').on('click', '.message-star-actions a', starAction ); 1624 1625 /* Star bulk manage - Show only the valid action based on the starred item. */ 1626 jq('#message-threads td.bulk-select-check :checkbox').on('change', function() { 1627 var box = jq(this), 1628 star = box.closest('tr').find('.thread-star a'); 1629 1630 if ( box.prop("checked") ) { 1631 if( 'unstar' == star.data('star-status') ) { 1632 BP_PM_Star.star_counter++; 1633 } else { 1634 BP_PM_Star.unstar_counter++; 1635 } 1636 } else { 1637 if( 'unstar' == star.data('star-status') ) { 1638 BP_PM_Star.star_counter--; 1639 } else { 1640 BP_PM_Star.unstar_counter--; 1641 } 1642 } 1643 1644 if ( BP_PM_Star.star_counter > 0 && BP_PM_Star.unstar_counter == 0 ) { 1645 jq('option[value="star"]').hide(); 1646 } else { 1647 jq('option[value="star"]').show(); 1648 } 1649 1650 if ( BP_PM_Star.unstar_counter > 0 && BP_PM_Star.star_counter == 0 ) { 1651 jq('option[value="unstar"]').hide(); 1652 } else { 1653 jq('option[value="unstar"]').show(); 1654 } 1655 }); 1656 1657 /** Notifications **********************************************/ 1658 1581 1659 /* Selecting/Deselecting all notifications */ 1582 1660 jq('#select-all-notifications').click(function(event) { 1583 1661 if( this.checked ) { -
tests/phpunit/testcases/core/functions.php
620 620 621 621 $this->assertSame( $expected_upload_dir, $tested_upload_dir ); 622 622 } 623 624 /** 625 * @group bp_is_active 626 */ 627 public function test_bp_is_active_component() { 628 $bp = buddypress(); 629 $reset_active_components = $bp->active_components; 630 631 $this->assertTrue( bp_is_active( 'members' ) ); 632 633 $this->assertFalse( bp_is_active( 'foo' ) ); 634 635 // Create and activate the foo component 636 $bp->foo = new BP_Component; 637 $bp->foo->id = 'foo'; 638 $bp->foo->slug = 'foo'; 639 $bp->foo->name = 'Foo'; 640 $bp->active_components[ $bp->foo->id ] = 1; 641 642 $this->assertTrue( bp_is_active( 'foo' ) ); 643 644 add_filter( 'bp_is_active', '__return_false' ); 645 646 $this->assertFalse( bp_is_active( 'foo' ) ); 647 648 remove_filter( 'bp_is_active', '__return_false' ); 649 650 // Reset buddypress() vars 651 $bp->active_components = $reset_active_components; 652 } 653 654 /** 655 * @group bp_is_active 656 */ 657 public function test_bp_is_active_feature() { 658 $bp = buddypress(); 659 $reset_active_components = $bp->active_components; 660 661 // star feature for messages component is active by default 662 $this->assertTrue( bp_is_active( 'messages', 'star' ) ); 663 664 // test the feature filter 665 add_filter( 'bp_is_messages_star_active', '__return_false' ); 666 $this->assertFalse( bp_is_active( 'messages', 'star' ) ); 667 remove_filter( 'bp_is_messages_star_active', '__return_false' ); 668 669 // test the main component filter 670 add_filter( 'bp_is_active', '__return_false' ); 671 $this->assertFalse( bp_is_active( 'messages', 'star' ) ); 672 remove_filter( 'bp_is_active', '__return_false' ); 673 674 // Create and activate the foo component 675 $bp->foo = new BP_Component; 676 $bp->foo->id = 'foo'; 677 $bp->foo->slug = 'foo'; 678 $bp->foo->name = 'Foo'; 679 $bp->active_components[ $bp->foo->id ] = 1; 680 681 // foo did not register 'bar' as a feature 682 $this->assertFalse( bp_is_active( 'foo', 'bar' ) ); 683 684 // fake registering the 'bar' feature 685 $bp->foo->features = array( 'bar' ); 686 $this->assertTrue( bp_is_active( 'foo', 'bar' ) ); 687 688 // test the feature filter 689 add_filter( 'bp_is_foo_bar_active', '__return_false' ); 690 $this->assertFalse( bp_is_active( 'foo', 'bar' ) ); 691 remove_filter( 'bp_is_foo_bar_active', '__return_false' ); 692 693 // test the main component filter 694 add_filter( 'bp_is_active', '__return_false' ); 695 $this->assertFalse( bp_is_active( 'foo', 'bar' ) ); 696 remove_filter( 'bp_is_active', '__return_false' ); 697 698 // Reset buddypress() vars 699 $bp->active_components = $reset_active_components; 700 } 623 701 } -
new file tests/phpunit/testcases/messages/star.php
new file mode 100644
- + 1 <?php 2 /** 3 * @group messages 4 * @group star 5 */ 6 class BP_Tests_Messages_Star_ extends BP_UnitTestCase { 7 8 /** 9 * @group bp_messages_is_message_starred 10 * @group bp_messages_star_set_action 11 */ 12 public function test_is_message_starred() { 13 $u1 = $this->factory->user->create(); 14 $u2 = $this->factory->user->create(); 15 16 // create the thread 17 $t1 = $this->factory->message->create( array( 18 'sender_id' => $u1, 19 'recipients' => array( $u2 ), 20 'subject' => 'This is a knive', 21 ) ); 22 23 // create a reply 24 $this->factory->message->create( array( 25 'thread_id' => $t1, 26 'sender_id' => $u2, 27 'recipients' => array( $u1 ), 28 'content' => "That's a spoon", 29 ) ); 30 31 // grab the message ids as individual variables 32 list( $m1, $m2 ) = $this->get_message_ids( $t1 ); 33 34 // star the second message 35 $star = bp_messages_star_set_action( array( 36 'user_id' => $u1, 37 'message_id' => $m2, 38 ) ); 39 40 // assert that star is set 41 $this->assertTrue( $star ); 42 $this->assertTrue( bp_messages_is_message_starred( $m2, $u1 ) ); 43 44 // unstar the second message 45 $unstar = bp_messages_star_set_action( array( 46 'user_id' => $u1, 47 'message_id' => $m2, 48 'action' => 'unstar' 49 ) ); 50 51 // assert that star is removed 52 $this->assertTrue( $unstar ); 53 $this->assertFalse( bp_messages_is_message_starred( $m2, $u1 ) ); 54 } 55 56 /** 57 * @group bp_messages_star_set_action 58 * @group bulk 59 */ 60 public function test_star_set_action_bulk_unstar() { 61 $u1 = $this->factory->user->create(); 62 $u2 = $this->factory->user->create(); 63 64 // create the thread 65 $t1 = $this->factory->message->create( array( 66 'sender_id' => $u1, 67 'recipients' => array( $u2 ), 68 'subject' => 'This is a knive', 69 ) ); 70 71 // create a reply 72 $this->factory->message->create( array( 73 'thread_id' => $t1, 74 'sender_id' => $u2, 75 'recipients' => array( $u1 ), 76 'content' => "That's a spoon", 77 ) ); 78 79 // grab the message ids as individual variables 80 list( $m1, $m2 ) = $this->get_message_ids( $t1 ); 81 82 // star all messages 83 bp_messages_star_set_action( array( 84 'user_id' => $u1, 85 'message_id' => $m1, 86 ) ); 87 bp_messages_star_set_action( array( 88 'user_id' => $u1, 89 'message_id' => $m2, 90 ) ); 91 92 // assert that stars are set 93 $this->assertTrue( bp_messages_is_message_starred( $m1, $u1 ) ); 94 $this->assertTrue( bp_messages_is_message_starred( $m2, $u1 ) ); 95 96 // unstar all messages 97 bp_messages_star_set_action( array( 98 'user_id' => $u1, 99 'thread_id' => $t1, 100 'action' => 'unstar', 101 'bulk' => true 102 ) ); 103 104 // assert that star is removed 105 $this->assertFalse( bp_messages_is_message_starred( $m1, $u1 ) ); 106 $this->assertFalse( bp_messages_is_message_starred( $m2, $u1 ) ); 107 } 108 109 /** 110 * Helper method to grab the message IDs from a message thread. 111 * 112 * @param int $thread_id The message thread ID 113 * @return array 114 */ 115 protected function get_message_ids( $thread_id = 0 ) { 116 $thread = new BP_Messages_Thread( $thread_id ); 117 return wp_list_pluck( $thread->messages, 'id' ); 118 } 119 } 120 No newline at end of file