Skip to:
Content

BuddyPress.org

Ticket #6331: 6331.01.patch

File 6331.01.patch, 19.5 KB (added by r-a-y, 6 years ago)

Refreshed for trunk and fixes an issue with AJAX mass unstarring.

  • 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
     385/**
     386 * Is the 'Starred' private messages feature enabled?
     387 *
     388 * @since BuddyPress (2.3.0)
     389 *
     390 * @return bool
     391 */
     392function bp_messages_is_starred_enabled() {
     393        return (bool) apply_filters( 'bp_messages_enable_starred', true );
     394}
     395
    369396/** Messages Meta *******************************************************/
    370397
    371398/**
  • src/bp-messages/bp-messages-loader.php

     
    6767                );
    6868
    6969                parent::includes( $includes );
     70
     71                // Conditional includes
     72                if ( bp_messages_is_starred_enabled() ) {
     73                        require $this->path . 'bp-messages/bp-messages-starred.php';
     74                }
    7075        }
    7176
    7277        /**
     
    164169                        'user_has_access' => bp_core_can_edit_settings()
    165170                );
    166171
     172                if ( bp_messages_is_starred_enabled() ) {
     173                        $sub_nav[] = array(
     174                                'name'            => __( 'Starred', 'buddypress' ),
     175                                'slug'            => bp_get_messages_starred_slug(),
     176                                'parent_url'      => $messages_link,
     177                                'parent_slug'     => $this->slug,
     178                                'screen_function' => 'bp_messages_starred_screen',
     179                                'position'        => 11,
     180                                'user_has_access' => bp_core_can_edit_settings()
     181                        );
     182                }
     183
    167184                $sub_nav[] = array(
    168185                        'name'            => __( 'Sent', 'buddypress' ),
    169186                        'slug'            => 'sentbox',
     
    241258                                'href'   => trailingslashit( $messages_link . 'inbox' )
    242259                        );
    243260
     261                        // Starred
     262                        if ( bp_messages_is_starred_enabled() ) {
     263                                $wp_admin_nav[] = array(
     264                                        'parent' => 'my-account-' . $this->id,
     265                                        'id'     => 'my-account-' . $this->id . '-starred',
     266                                        'title'  => __( 'Starred', 'buddypress' ),
     267                                        'href'   => trailingslashit( $messages_link . bp_get_messages_starred_slug() )
     268                                );
     269                        }
     270
    244271                        // Sent Messages
    245272                        $wp_admin_nav[] = array(
    246273                                'parent' => 'my-account-' . $this->id,
  • new file src/bp-messages/bp-messages-starred.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 * Function to determine if a message ID is starred.
     12 *
     13 * @since BuddyPress (2.3.0)
     14 *
     15 * @param  int $mid     The message ID
     16 * @param  int $user_id The user ID
     17 * @return bool
     18 */
     19function bp_messages_is_message_starred( $mid = 0, $user_id = 0 ) {
     20        if ( empty( $user_id ) ) {
     21                $user_id = bp_loggedin_user_id();
     22        }
     23
     24        if ( empty( $mid ) ) {
     25                return false;
     26        }
     27
     28        $starred = array_flip( (array) bp_messages_get_meta( $mid, 'starred_by_user', false ) );
     29
     30        if ( isset( $starred[$user_id] ) ) {
     31                return true;
     32        } else {
     33                return false;
     34        }
     35}
     36
     37/**
     38 * Return the starred messages slug. Defaults to 'starred'.
     39 *
     40 * @since BuddyPress (2.3.0)
     41 *
     42 * @return string
     43 */
     44function bp_get_messages_starred_slug() {
     45        /**
     46         * Filters the starred message slug.
     47         *
     48         * @since BuddyPress (2.3.0)
     49         *
     50         * @param string
     51         */
     52        return sanitize_title( apply_filters( 'bp_get_messages_starred_slug', 'starred' ) );
     53}
     54
     55/**
     56 * Output the URL for deleting the current thread.
     57 */
     58function bp_messages_starred_action_link( $args = array() ) {
     59        echo bp_get_messages_starred_action_link( $args );
     60}
     61        /**
     62         * Return the URL for deleting the current thread.
     63         *
     64         * @param array $args {
     65         *     Array of arguments.
     66         *     @type int    $user_id       The user ID. Defaults to the logged-in user ID.
     67         *     @type int    $thread_id     The message thread ID. Default: 0. If not zero, this takes precedence over
     68         *                                 $message_id.
     69         *     @type int    $message_id    The individual message ID. If on a single thread page, defaults to the
     70         *                                 current message ID in the message loop.
     71         *     @type bool   $link_only     Whether to return the link only. If false, returns link with markup.
     72         *                                 Default: false.
     73         *     @type string $string_unstar Link text for the 'unstar' action. Only applicable if $link_only is false.
     74         *     @type string $string_star   Link text for the 'star' action. Only applicable if $link_only is false.
     75         }
     76         * @return string
     77         */
     78        function bp_get_messages_starred_action_link( $args = array() ) {
     79                $r = bp_parse_args( $args, array(
     80                        'user_id'       => bp_loggedin_user_id(),
     81                        'thread_id'     => 0,
     82                        'message_id'    => (int) bp_get_the_thread_message_id(),
     83                        'link_only'     => false,
     84                        'string_unstar' => __( 'Unstar', 'buddypress' ),
     85                        'string_star'   => __( 'Star', 'buddypress' ),                 
     86                ), 'messages_starred_action_link' );
     87
     88                $retval = $bulk_attr = '';
     89
     90                if ( 0 === $r['user_id'] ) {
     91                        return $retval;
     92                }
     93
     94                // get user domain
     95                if ( $r['user_id'] == bp_loggedin_user_id() ) {
     96                        $user_domain = bp_loggedin_user_domain();
     97                } elseif ( $r['user_id'] == bp_displayed_user_domain() ) {
     98                        $user_domain = bp_displayed_user_domain();
     99                } else {
     100                        $user_domain = bp_core_get_user_domain( $user_id );
     101                }
     102
     103                // thread ID
     104                if ( (int) $r['thread_id'] > 0 ) {
     105                        // see if we're in the loop
     106                        if ( bp_get_message_thread_id() == $r['thread_id'] ) {
     107                                // grab all message ids
     108                                $mids = wp_list_pluck( $GLOBALS['messages_template']->thread->messages, 'id' );
     109
     110                                // make sure order is ASC
     111                                // order is DESC when used in the thread loop by default
     112                                $mids = array_reverse( $mids );
     113
     114                        // pull up the thread
     115                        } else {
     116                                $thread = new BP_Messages_thread( $r['thread_id'] );
     117                                $mids = wp_list_pluck( $thread->messages, 'id' );
     118                        }
     119
     120                        $is_starred = false;
     121                        $message_id = 0;
     122                        foreach ( $mids as $mid ) {
     123                                // try to find the first msg that is starred in a thread
     124                                if ( true === bp_messages_is_message_starred( $mid ) ) {
     125                                        $is_starred = true;
     126                                        $message_id = $mid;
     127                                        break;
     128                                }
     129                        }
     130
     131                        // no star, so default to first message in thread
     132                        if ( empty( $message_id ) ) {
     133                                $message_id = $mids[0];
     134                        }
     135
     136                        // nonce
     137                        $nonce = wp_create_nonce( "bp-messages-star-{$message_id}" );
     138
     139                        if ( $is_starred ) {
     140                                $action = 'unstar';
     141                                $bulk_attr = ' data-star-bulk="1"';
     142                                $retval = $user_domain . bp_get_messages_slug() . '/unstar/' . $message_id . '/' . $nonce . '/all/';
     143                        } else {
     144                                $action = 'star';
     145                                $retval = $user_domain . bp_get_messages_slug() . '/star/' . $message_id . '/' . $nonce . '/';
     146                        }
     147
     148                // message ID
     149                } else {
     150                        $message_id = (int) $r['message_id'];
     151                        $is_starred = bp_messages_is_message_starred( $message_id );
     152                        $nonce      = wp_create_nonce( "bp-messages-star-{$message_id}" );
     153
     154                        if ( $is_starred ) {
     155                                $action = 'unstar';
     156                                $retval = $user_domain . bp_get_messages_slug() . '/unstar/' . $message_id . '/' . $nonce . '/';
     157                        } else {
     158                                $action = 'star';
     159                                $retval = $user_domain . bp_get_messages_slug() . '/star/' . $message_id . '/' . $nonce . '/';
     160                        }
     161                }
     162
     163                /**
     164                 * Filters the starred action URL for starring / unstarring a message.
     165                 *
     166                 * @since BuddyPress (2.3.0)
     167                 *
     168                 * @param string $retval URL for starring / unstarring a message.
     169                 * @param array  $r      Parsed link arguments. See $args in bp_get_messages_starred_action_link().
     170                 */
     171                $retval = esc_url( apply_filters( 'bp_get_messages_starred_action_linkonly', $retval, $r ) );
     172                if ( true === (bool) $r['link_only'] ) {
     173                        return $retval;
     174                }
     175
     176                /**
     177                 * Filters the starred action link, including markup.
     178                 *
     179                 * @since BuddyPress (2.3.0)
     180                 *
     181                 * @param string $retval Link for starring / unstarring a message, including markup.
     182                 * @param array  $r      Parsed link arguments. See $args in bp_get_messages_starred_action_link().
     183                 */
     184                return apply_filters( 'bp_get_messages_starred_action_link', '<a 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="screen-reader-text">' . $r['string_' . $action] . '</span></a>', $r );
     185        }
     186
     187/**
     188 * Save or delete message meta according to a message star's status.
     189 *
     190 * @since BuddyPress (2.3.0)
     191 *
     192 * @param  array $args {
     193 *     Array of arguments.
     194 *     @type string $action     The star action. Either 'star' or 'unstar'. Default: 'star'.
     195 *     @type int    $message_id The message ID to star or unstar.  Default: 0.
     196 *     @type int    $user_id    The user ID. Defaults to the logged-in user ID.
     197 *     @type bool   $bulk       Whether to mark all messages in a thread as a certain action. Only relevant
     198 *                              when $action is 'unstar' at the moment. Default: false.
     199 * }
     200 * @return bool
     201 */
     202function bp_messages_starred_set_action( $args = array() ) {
     203        $r = wp_parse_args( $args, array(
     204                'action'     => 'star',
     205                'message_id' => 0,
     206                'user_id'    => bp_loggedin_user_id(),
     207                'bulk'       => false
     208        ) );
     209
     210        $thread_id = messages_get_message_thread_id( $r['message_id'] );
     211        if ( empty( $thread_id ) ) {
     212                return false;
     213        }
     214
     215        if( ! messages_check_thread_access( $thread_id ) ) {
     216                return false;
     217        }
     218
     219        $is_starred = bp_messages_is_message_starred( $r['message_id'] );
     220
     221        // star
     222        if ( 'star' == $r['action'] ) {
     223                if ( true === $is_starred ) {
     224                        return true;
     225                } else {
     226                        bp_messages_add_meta( $r['message_id'], 'starred_by_user', $r['user_id'] );
     227                        return true;
     228                }
     229        // unstar
     230        } else {
     231                // unstar one message
     232                if ( false === $r['bulk'] ) {
     233                        if ( false === $is_starred ) {
     234                                return true;
     235                        } else {
     236                                bp_messages_delete_meta( $r['message_id'], 'starred_by_user', $r['user_id'] );
     237                                return true;
     238                        }
     239
     240                // unstar all messages in a thread
     241                } else {
     242                        $thread = new BP_Messages_Thread( $thread_id );
     243                        $mids = wp_list_pluck( $thread->messages, 'id' );
     244
     245                        foreach ( $mids as $mid ) {
     246                                if ( true === bp_messages_is_message_starred( $mid ) ) {
     247                                        bp_messages_delete_meta( $mid, 'starred_by_user', $r['user_id'] );
     248                                }
     249                        }
     250
     251                        return true;
     252                }
     253        }
     254}
     255
     256/** SCREENS **************************************************************/
     257
     258/**
     259 * Screen handler to display a user's "Starred" private messages page.
     260 *
     261 * @since BuddyPress (2.3.0)
     262 */
     263function bp_messages_starred_screen() {
     264        add_action( 'bp_template_content', 'bp_messages_starred_content' );
     265
     266        /**
     267         * Fires right before the loading of the "Starred" messages box.
     268         *
     269         * @since BuddyPress (2.3.0)
     270         */
     271        do_action( 'bp_messages_screen_starred' );
     272
     273        bp_core_load_template( 'members/single/plugins' );
     274}
     275
     276/**
     277 * Screen content callback to display a user's "Starred" messages page.
     278 *
     279 * @since BuddyPress (2.3.0)
     280 */
     281function bp_messages_starred_content() {
     282        // add our message thread filter
     283        add_filter( 'bp_after_has_message_threads_parse_args', 'bp_messages_filter_starred_message_threads' );
     284
     285        // load the message loop template part
     286        bp_get_template_part( 'members/single/messages/messages-loop' );
     287
     288        // remove our filter
     289        remove_filter( 'bp_after_has_message_threads_parse_args', 'bp_messages_filter_starred_message_threads' );
     290}
     291
     292/**
     293 * Filter message threads by those starred by the logged-in user.
     294 *
     295 * @since BuddyPress (2.3.0)
     296 *
     297 * @param  array $r Current message thread arguments.
     298 * @return array
     299 */
     300function bp_messages_filter_starred_message_threads( $r = array() ) {
     301        $r['user_id'] = 0;
     302        $r['meta_query'] = array( array(
     303                'key'   => 'starred_by_user',
     304                'value' => bp_loggedin_user_id()
     305        ) );
     306
     307        return $r;
     308}
     309
     310/** ACTIONS **************************************************************/
     311
     312/**
     313 * Action handler to set a message's star status for those not using JS.
     314 *
     315 * @since BuddyPress (2.3.0)
     316 */
     317function bp_messages_starred_action_handler() {
     318        if ( ! bp_is_user_messages() ) {
     319                return;
     320        }
     321
     322        if ( false === ( bp_is_current_action( 'unstar' ) || bp_is_current_action( 'star' ) ) ) {
     323                return;
     324        }
     325
     326        if ( ! wp_verify_nonce( bp_action_variable( 1 ), 'bp-messages-star-' . bp_action_variable( 0 ) ) ) {
     327                wp_die( "Oops!  That's a no-no!" );
     328        }
     329
     330        // mark the star
     331        $set = bp_messages_starred_set_action( array(
     332                'action'     => bp_current_action(),
     333                'message_id' => bp_action_variable(),
     334                'bulk'       => (bool) bp_action_variable( 2 )
     335        ) );
     336
     337        // redirect back to previous screen
     338        $redirect = wp_get_referer() ? wp_get_referer() : bp_loggedin_user_domain() . bp_get_messages_slug();
     339        bp_core_redirect( $redirect );
     340        die();
     341}
     342add_action( 'bp_actions', 'bp_messages_starred_action_handler' );
     343
     344/**
     345 * AJAX callback to set a message's star status.
     346 *
     347 * @since BuddyPress (2.3.0)
     348 */
     349function bp_messages_starred_ajax_handler() {
     350        if ( empty( $_POST['message_id'] ) ) {
     351                return;
     352        }
     353
     354        check_ajax_referer( 'bp-messages-star-' . (int) $_POST['message_id'], 'nonce' );
     355
     356        $bulk = ! empty( $_POST['bulk'] ) ? true : false;
     357
     358        if ( true === bp_messages_starred_set_action( array(
     359                'action'     => $_POST['star_status'],
     360                'message_id' => (int) $_POST['message_id'],
     361                'bulk'       => $bulk
     362         ) ) ) {
     363                echo '1';
     364                die();
     365        }
     366
     367        echo '-1';
     368        die();
     369}
     370add_action( 'wp_ajax_messages_starred', 'bp_messages_starred_ajax_handler' );
     371
     372
     373/** HOOKS ****************************************************************/
     374
     375/**
     376 * Enqueues the dashicons font on user private message pages.
     377 *
     378 * The dashicons font is used for the star / unstar icon.
     379 *
     380 * @since BuddyPress (2.3.0)
     381 */
     382function bp_messages_starred_enqueue_styles() {
     383        if ( ! bp_is_user_messages() ) {
     384                return;
     385        }
     386
     387        wp_enqueue_style( 'dashicons' );
     388}
     389add_action( 'wp_enqueue_scripts', 'bp_messages_starred_enqueue_styles' );
     390
     391/**
     392 * Add CSS class for the current message depending on starred status.
     393 *
     394 * @since BuddyPress (2.3.0)
     395 *
     396 * @param  array $retval Current CSS classes
     397 * @return array
     398 */
     399function bp_messages_starred_message_css_class( $retval = array() ) {
     400        if ( true === bp_messages_is_message_starred( bp_get_the_thread_message_id() ) ) {
     401                $status = 'starred';
     402        } else {
     403                $status = 'not-starred';
     404        }
     405
     406        // add css class based on star status for the current message
     407        $retval[] = "message-{$status}";
     408
     409        return $retval;
     410}
     411add_filter( 'bp_get_the_thread_message_css_class', 'bp_messages_starred_message_css_class' );
  • src/bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php

     
    4848                                        <th scope="col" class="thread-checkbox bulk-select-all"><label class="bp-screen-reader-text" for="select-all-messages"><?php _e( 'Select all', 'buddypress' ); ?></label><input id="select-all-messages" type="checkbox"></th>
    4949                                        <th scope="col" class="thread-from"><?php _e( 'From', 'buddypress' ); ?></th>
    5050                                        <th scope="col" class="thread-info"><?php _e( 'Subject', 'buddypress' ); ?></th>
     51
     52                                        <?php if ( bp_messages_is_starred_enabled() ) : ?>
     53                                                <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>
     54                                        <?php endif; ?>
     55
    5156                                        <th scope="col" class="thread-options"><?php _e( 'Actions', 'buddypress' ); ?></th>
    5257                                </tr>
    5358                        </thead>
     
    9196                                                 */
    9297                                                do_action( 'bp_messages_inbox_list_item' ); ?>
    9398
     99                                                <?php if ( bp_messages_is_starred_enabled() ) : ?>
     100                                                        <td class="thread-star">
     101                                                                <?php bp_messages_starred_action_link( array( 'thread_id' => bp_get_message_thread_id() ) ); ?>
     102                                                        </td>
     103                                                <?php endif; ?>
     104
    94105                                                <td class="thread-options">
    95106                                                        <?php if ( bp_message_thread_has_unread() ) : ?>
    96107                                                                <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_messages_is_starred_enabled() ) : ?>
     73                                                <div class="message-star-actions">
     74                                                        <?php bp_messages_starred_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

     
    14451445        margin: 0 20px;
    14461446}
    14471447
     1448.message-metadata {
     1449        position: relative;
     1450}
     1451.message-star-actions {
     1452        position: absolute;
     1453        right: 0;
     1454        top: 0;
     1455}
     1456a.message-action-star,
     1457a.message-action-unstar {
     1458        text-decoration: none;
     1459        outline: none;
     1460}
     1461a.message-action-star {
     1462        opacity: .7;
     1463}
     1464a.message-action-star:hover {
     1465        opacity: 1;
     1466}
     1467.message-action-star span.icon:before,
     1468.message-action-unstar span.icon:before {
     1469        font-family: dashicons;
     1470        font-size: 18px;
     1471}
     1472.message-action-star span.icon:before {
     1473        color: #aaa;
     1474        content: "\f154";
     1475}
     1476.message-action-unstar span.icon:before {
     1477        color: #FCDD77;
     1478        content: "\f155";
     1479}
     1480
    14481481/*--------------------------------------------------------------
    144914823.10 - Extended Profiles
    14501483--------------------------------------------------------------*/
  • 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_starred',
     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 ( 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                                } else {
     1598                                        link.data('star-status', 'unstar');
     1599                                        link.removeClass('message-action-star').addClass('message-action-unstar');
     1600                                }
     1601                        }
     1602                });
     1603                return false;
     1604        }
     1605
     1606        /* Star actions */
     1607        jq('#message-threads').on('click', 'td.thread-star a', starAction );
     1608        jq('#message-thread').on('click', '.message-star-actions a', starAction );
     1609
     1610        /** Notifications **********************************************/
     1611
    15811612        /* Selecting/Deselecting all notifications */
    15821613        jq('#select-all-notifications').click(function(event) {
    15831614                if( this.checked ) {