Skip to:
Content

BuddyPress.org

Ticket #6331: 6331.03.patch

File 6331.03.patch, 39.8 KB (added by r-a-y, 6 years ago)
  • src/bp-core/bp-core-component.php

     
    131131         * Component loader.
    132132         *
    133133         * @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         * }
    147149         */
    148150        public function start( $id = '', $name = '', $path = '', $params = array() ) {
    149151
     
    163165                                $this->adminbar_myaccount_order = (int) $params['adminbar_myaccount_order'];
    164166                        }
    165167
     168                        // Register features
     169                        if ( ! empty( $params['features'] ) ) {
     170                                $this->features = array_map( 'sanitize_title', (array) $params['features'] );
     171                        }
     172
    166173                // Set defaults if not passed
    167174                } else {
    168175                        // new component menus are added before the settings menu if not set
     
    183190         *
    184191         * @param array $args {
    185192         *     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.
    204205         * }
    205206         */
    206207        public function setup_globals( $args = array() ) {
  • src/bp-core/bp-core-template.php

     
    18451845/** Components ****************************************************************/
    18461846
    18471847/**
    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.
    18491852 *
    18501853 * @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
    18521856 */
    1853 function bp_is_active( $component = '' ) {
     1857function bp_is_active( $component = '', $feature = '' ) {
    18541858        $retval = false;
    18551859
    18561860        // Default to the current component if none is passed
     
    18611865        // Is component in either the active or required components arrays
    18621866        if ( isset( buddypress()->active_components[ $component ] ) || isset( buddypress()->required_components[ $component ] ) ) {
    18631867                $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                }
    18641884        }
    18651885
    18661886        /**
  • src/bp-messages/bp-messages-functions.php

     
    366366        return BP_Messages_Thread::is_valid( $thread_id );
    367367}
    368368
     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 */
     377function 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
    369385/** Messages Meta *******************************************************/
    370386
    371387/**
  • src/bp-messages/bp-messages-loader.php

     
    3939                        __( 'Private Messages', 'buddypress' ),
    4040                        buddypress()->plugin_dir,
    4141                        array(
    42                                 'adminbar_myaccount_order' => 50
     42                                'adminbar_myaccount_order' => 50,
     43                                'features'                 => array( 'star' )
    4344                        )
    4445                );
    4546        }
     
    6768                        'widgets',
    6869                );
    6970
     71                // Conditional includes
     72                if ( bp_is_active( $this->id, 'star' ) ) {
     73                        $includes[] = 'star';
     74                }
     75
    7076                parent::includes( $includes );
    7177        }
    7278
     
    166172                        'user_has_access' => bp_core_can_edit_settings()
    167173                );
    168174
     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
    169187                $sub_nav[] = array(
    170188                        'name'            => __( 'Sent', 'buddypress' ),
    171189                        'slug'            => 'sentbox',
     
    243261                                'href'   => trailingslashit( $messages_link . 'inbox' )
    244262                        );
    245263
     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
    246274                        // Sent Messages
    247275                        $wp_admin_nav[] = array(
    248276                                '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 */
     17function 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 */
     37function 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 */
     62function 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 */
     224function 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 */
     292function 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 */
     310function 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 */
     329function 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 */
     346function 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}
     376add_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 */
     383function 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}
     445add_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 */
     456function bp_messages_star_enqueue_scripts() {
     457        if ( ! bp_is_user_messages() ) {
     458                return;
     459        }
     460
     461        wp_enqueue_style( 'dashicons' );
     462}
     463add_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 */
     470function 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}
     478add_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 */
     488function 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}
     500add_filter( 'bp_get_the_thread_message_css_class', 'bp_messages_star_message_css_class' );
  • src/bp-messages/bp-messages-template.php

     
    12901290                <option value="read"><?php _e( 'Mark read', 'buddypress' ); ?></option>
    12911291                <option value="unread"><?php _e( 'Mark unread', 'buddypress' ); ?></option>
    12921292                <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                ?>
    12931301        </select>
    12941302        <input type="submit" id="messages-bulk-manage" class="button action" value="<?php esc_attr_e( 'Apply', 'buddypress' ); ?>">
    12951303        <?php
  • src/bp-templates/bp-legacy/buddypress-functions.php

     
    177177                        'messages_send_reply'           => 'bp_legacy_theme_ajax_messages_send_reply',
    178178                );
    179179
     180                // Conditional actions
     181                if ( bp_is_active( 'messages', 'star' ) ) {
     182                        $actions['messages_star'] = 'bp_legacy_theme_ajax_messages_star_handler';
     183                }
     184
    180185                /**
    181186                 * Register all of these AJAX handlers
    182187                 *
     
    307312                        // Enqueue script
    308313                        wp_enqueue_script( $asset['handle'] . '-password-verify', $asset['location'], $dependencies, $this->version);
    309314                }
     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                }
    310332        }
    311333
    312334        /**
     
    16871709
    16881710        exit;
    16891711}
     1712
     1713/**
     1714 * AJAX callback to set a message's star status.
     1715 *
     1716 * @since BuddyPress (2.3.0)
     1717 */
     1718function 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

     
    6161                                         */
    6262                                        do_action( 'bp_messages_inbox_list_header' ); ?>
    6363
     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
    6468                                        <th scope="col" class="thread-options"><?php _e( 'Actions', 'buddypress' ); ?></th>
    6569                                </tr>
    6670                        </thead>
     
    107111                                                 */
    108112                                                do_action( 'bp_messages_inbox_list_item' ); ?>
    109113
     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
    110120                                                <td class="thread-options">
    111121                                                        <?php if ( bp_message_thread_has_unread() ) : ?>
    112122                                                                <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

     
    6969
    7070                                        <span class="activity"><?php bp_the_thread_message_time_since(); ?></span>
    7171
     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
    7278                                        <?php
    7379
    7480                                        /** This action is documented in bp-templates/bp-legacy/buddypress-functions.php */
  • src/bp-templates/bp-legacy/css/buddypress.css

     
    14481448        margin: 0 20px;
    14491449}
    14501450
     1451.message-metadata {
     1452        position: relative;
     1453}
     1454.message-star-actions {
     1455        position: absolute;
     1456        right: 0;
     1457        top: 0;
     1458}
     1459a.message-action-star,
     1460a.message-action-unstar {
     1461        text-decoration: none;
     1462        outline: none;
     1463}
     1464a.message-action-star {
     1465        opacity: .7;
     1466}
     1467a.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
    14511484/*--------------------------------------------------------------
    145214853.10 - Extended Profiles
    14531486--------------------------------------------------------------*/
  • src/bp-templates/bp-legacy/js/buddypress.js

     
    15781578                jq('#messages-bulk-manage').attr('disabled', jq(this).val().length <= 0);
    15791579        });
    15801580
     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
    15811659        /* Selecting/Deselecting all notifications */
    15821660        jq('#select-all-notifications').click(function(event) {
    15831661                if( this.checked ) {
  • tests/phpunit/testcases/core/functions.php

     
    620620
    621621                $this->assertSame( $expected_upload_dir, $tested_upload_dir );
    622622        }
     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        }
    623701}
  • new file tests/phpunit/testcases/messages/star.php

    new file mode 100644
    - +  
     1<?php
     2/**
     3 * @group messages
     4 * @group star
     5 */
     6class 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