Skip to:
Content

BuddyPress.org

Changeset 13196


Ignore:
Timestamp:
12/23/2021 08:07:07 PM (4 years ago)
Author:
imath
Message:

BP Messages: introduce a functionality to exit a messages thread

Exiting a messages thread is removing the user from the list of the recipients of the thread. The thread can carry on between the other recipients.

Props Oelita, vapvarun

Fixes #7540

Location:
trunk
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-messages/bp-messages-cache.php

    r13096 r13196  
    8888}
    8989add_action( 'messages_delete_thread', 'bp_messages_clear_cache_on_message_delete', 10, 2 );
     90add_action( 'bp_messages_exit_thread', 'bp_messages_clear_cache_on_message_delete', 10, 2 );
    9091
    9192/**
  • trunk/src/bp-messages/bp-messages-functions.php

    r13108 r13196  
    800800    return $retval;
    801801}
     802
     803/**
     804 * Exit one or more message thread(s) for a given user.
     805 *
     806 * @since 10.0.0
     807 *
     808 * @param int|array $thread_ids Thread ID or array of thread IDs.
     809 * @param int       $user_id    ID of the user to delete the threads for. Defaults
     810 *                              to the current logged-in user.
     811 * @return bool True on success, false on failure.
     812 */
     813function bp_messages_exit_thread( $thread_ids, $user_id = 0 ) {
     814
     815    if ( empty( $user_id ) ) {
     816        $user_id = bp_loggedin_user_id();
     817
     818        if ( bp_displayed_user_id() ) {
     819            $user_id = bp_displayed_user_id();
     820        }
     821    }
     822
     823    /**
     824     * Fires before a user exits specified thread IDs.
     825     *
     826     * @since 10.0.0
     827     *
     828     * @param int|array $thread_ids Thread ID or array of thread IDs to be deleted.
     829     * @param int       $user_id    ID of the user the threads are being deleted for.
     830     */
     831    do_action( 'bp_messages_before_exit_thread', $thread_ids, $user_id );
     832
     833    if ( is_array( $thread_ids ) ) {
     834        $error = 0;
     835        for ( $i = 0, $count = count( $thread_ids ); $i < $count; ++$i ) {
     836            if ( ! BP_Messages_Thread::exit_thread( $thread_ids[ $i ], $user_id ) ) {
     837                $error = 1;
     838            }
     839        }
     840
     841        if ( ! empty( $error ) ) {
     842            return false;
     843        }
     844
     845        /**
     846         * Fires after a user exited the specified thread IDs.
     847         *
     848         * @since 10.0.0
     849         *
     850         * @param int|array Thread ID or array of thread IDs that were deleted.
     851         * @param int       ID of the user that the threads were deleted for.
     852         */
     853        do_action( 'bp_messages_exit_thread', $thread_ids, $user_id );
     854
     855        return true;
     856    } else {
     857        if ( ! BP_Messages_Thread::exit_thread( $thread_ids, $user_id ) ) {
     858            return false;
     859        }
     860
     861        /** This action is documented in bp-messages/bp-messages-functions.php */
     862        do_action( 'bp_messages_exit_thread', $thread_ids, $user_id );
     863
     864        return true;
     865    }
     866}
  • trunk/src/bp-messages/bp-messages-template.php

    r13185 r13196  
    21902190
    21912191/**
     2192 * Output the URL to exit the current thread.
     2193 *
     2194 * @since 10.0.0
     2195 */
     2196function bp_the_thread_exit_link() {
     2197    echo esc_url( bp_get_the_thread_exit_link() );
     2198}
     2199    /**
     2200     * Get the URL to exit the current thread.
     2201     *
     2202     * @since 10.0.0
     2203     *
     2204     * @return string URL
     2205     */
     2206    function bp_get_the_thread_exit_link() {
     2207
     2208        /**
     2209         * Filters the URL to exit the current thread.
     2210         *
     2211         * @since 1.0.0
     2212         *
     2213         * @param string $value URL to exit the current thread.
     2214         * @param string $value Text indicating action being executed.
     2215         */
     2216        return apply_filters( 'bp_get_the_thread_exit_link', wp_nonce_url( bp_displayed_user_domain() . bp_get_messages_slug() . '/inbox/exit/' . bp_get_the_thread_id(), 'bp_messages_exit_thread' ) );
     2217    }
     2218
     2219/**
    21922220 * Output the 'Sent x hours ago' string for the current message.
    21932221 *
  • trunk/src/bp-messages/classes/class-bp-messages-component.php

    r13185 r13196  
    103103            // Authenticated action variables.
    104104            if ( is_user_logged_in() && bp_action_variable( 0 ) &&
    105                 in_array( bp_action_variable( 0 ), array( 'delete', 'read', 'unread', 'bulk-manage', 'bulk-delete' ), true )
     105                in_array( bp_action_variable( 0 ), array( 'delete', 'read', 'unread', 'bulk-manage', 'bulk-delete', 'exit' ), true )
    106106            ) {
    107107                require $this->path . 'bp-messages/actions/' . bp_action_variable( 0 ) . '.php';
  • trunk/src/bp-messages/classes/class-bp-messages-thread.php

    r13148 r13196  
    531531         */
    532532        do_action( 'bp_messages_thread_after_delete', $thread_id, $message_ids, $user_id );
     533
     534        return true;
     535    }
     536
     537    /**
     538     * Exit a user from a thread.
     539     *
     540     * @since 10.0.0
     541     *
     542     * @global wpdb $wpdb WordPress database object.
     543     *
     544     * @param int $thread_id The message thread ID.
     545     * @param int $user_id The ID of the user in the thread.
     546     *                     Defaults to the current logged-in user.
     547     *
     548     * @return bool
     549     */
     550    public static function exit_thread( $thread_id = 0, $user_id = 0 ) {
     551        global $wpdb;
     552
     553        $thread_id = (int) $thread_id;
     554        $user_id   = (int) $user_id;
     555
     556        if ( empty( $user_id ) ) {
     557            $user_id = bp_loggedin_user_id();
     558        }
     559
     560        // Check the user is a recipient of the thread and recipients count > 2.
     561        $recipients    = self::get_recipients_for_thread( $thread_id );
     562        $recipient_ids = wp_list_pluck( $recipients, 'user_id' );
     563
     564        if ( 2 >= count( $recipient_ids ) || ! in_array( $user_id, $recipient_ids, true ) ) {
     565            return false;
     566        }
     567
     568        /**
     569         * Fires before a user exits a thread.
     570         *
     571         * @since 10.0.0
     572         *
     573         * @param int $thread_id ID of the thread being deleted.
     574         * @param int $user_id   ID of the user that the thread is being deleted for.
     575         */
     576        do_action( 'bp_messages_thread_before_exit', $thread_id, $user_id );
     577
     578        $bp = buddypress();
     579
     580        // Delete the user from messages recipients
     581        $exited = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND user_id = %d", $thread_id, $user_id ) );
     582
     583        // Bail if the user wasn't removed from the recipients list.
     584        if ( empty( $exited ) ) {
     585            return false;
     586        }
     587
     588        /**
     589         * Fires after a user exits a thread.
     590         *
     591         * @since 10.0.0
     592         *
     593         * @param int   $thread_id ID of the thread being deleted.
     594         * @param int   $user_id   ID of the user the threads were deleted for.
     595         */
     596        do_action( 'bp_messages_thread_after_exit', $thread_id, $user_id );
    533597
    534598        return true;
  • trunk/src/bp-templates/bp-legacy/buddypress/members/single/messages/single.php

    r12595 r13196  
    55 * @package BuddyPress
    66 * @subpackage bp-legacy
    7  * @version 3.0.0
     7 * @version 10.0.0
    88 */
    99
     
    4949            </span>
    5050
    51             <a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>"><?php _e( 'Delete', 'buddypress' ); ?></a>
     51            <a class="button confirm" href="<?php bp_the_thread_delete_link(); ?>"><?php esc_html_e( 'Delete', 'buddypress' ); ?></a>
     52
     53            <?php if ( bp_get_thread_recipients_count() > 2 ) : ?>
     54
     55                <a class="button confirm" href="<?php bp_the_thread_exit_link(); ?>"><?php esc_html_e( 'Exit Conversation', 'buddypress' ); ?></a>
     56
     57            <?php endif; ?>
    5258
    5359            <?php
  • trunk/src/bp-templates/bp-nouveau/buddypress/common/js-templates/messages/index.php

    r13151 r13196  
    189189                        <span class="bp-screen-reader-text"><?php esc_html_e( 'Delete conversation.', 'buddypress' ); ?></span>
    190190                    </button>
     191
     192                    <# if ( undefined !== data.recipients && data.recipients.length > 2 ) { #>
     193                        <button type="button" class="message-action-exit bp-tooltip bp-icons" data-bp-action="exit" data-bp-tooltip="<?php esc_attr_e( 'Exit conversation.', 'buddypress' ); ?>">
     194                            <span class="bp-screen-reader-text"><?php esc_html_e( 'Exit conversation.', 'buddypress' ); ?></span>
     195                        </button>
     196                    <# } #>
    191197
    192198                    <# if ( undefined !== data.star_link ) { #>
     
    251257                <span class="bp-screen-reader-text"><?php esc_html_e( 'Delete conversation.', 'buddypress' ); ?></span>
    252258            </button>
     259
     260            <# if ( undefined !== data.recipients && data.recipients.length > 2 ) { #>
     261                <button type="button" class="message-action-exit bp-tooltip bp-icons" data-bp-action="exit" data-bp-tooltip="<?php esc_attr_e( 'Exit conversation.', 'buddypress' ); ?>">
     262                    <span class="bp-screen-reader-text"><?php esc_html_e( 'Exit conversation.', 'buddypress' ); ?></span>
     263                </button>
     264            <# } #>
    253265        </div>
    254266    </header>
  • trunk/src/bp-templates/bp-nouveau/css/buddypress-rtl.css

    r13182 r13196  
    30723072.message-action-unstar:before,
    30733073.message-action-view:before,
    3074 .message-action-delete:before {
     3074.message-action-delete:before,
     3075.message-action-exit:before {
    30753076    font-family: dashicons;
    30763077    font-size: 18px;
     
    30933094.message-action-delete:before {
    30943095    content: "\f153";
     3096}
     3097
     3098.message-action-exit:before {
     3099    content: "\f14a";
    30953100}
    30963101
  • trunk/src/bp-templates/bp-nouveau/css/buddypress.css

    r13182 r13196  
    30723072.message-action-unstar:before,
    30733073.message-action-view:before,
    3074 .message-action-delete:before {
     3074.message-action-delete:before,
     3075.message-action-exit:before {
    30753076    font-family: dashicons;
    30763077    font-size: 18px;
     
    30933094.message-action-delete:before {
    30943095    content: "\f153";
     3096}
     3097
     3098.message-action-exit:before {
     3099    content: "\f14a";
    30953100}
    30963101
  • trunk/src/bp-templates/bp-nouveau/css/twentytwentyone-rtl.css

    r12921 r13196  
    907907}
    908908
    909 #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:before {
     909#buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:before, #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-exit:before {
    910910    width: 32px;
    911911    height: 32px;
     
    914914}
    915915
    916 #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:hover:before {
     916#buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:hover:before, #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-exit:hover:before {
    917917    border-radius: 50%;
    918918    color: var(--global--color-background);
  • trunk/src/bp-templates/bp-nouveau/css/twentytwentyone.css

    r12921 r13196  
    907907}
    908908
    909 #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:before {
     909#buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:before, #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-exit:before {
    910910    width: 32px;
    911911    height: 32px;
     
    914914}
    915915
    916 #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:hover:before {
     916#buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-delete:hover:before, #buddypress.twentytwentyone .bp-messages-content .actions button.bp-tooltip.message-action-exit:hover:before {
    917917    border-radius: 50%;
    918918    color: var(--global--color-background);
  • trunk/src/bp-templates/bp-nouveau/includes/messages/ajax.php

    r12989 r13196  
    44 *
    55 * @since 3.0.0
    6  * @version 8.0.0
     6 * @version 10.0.0
    77 */
    88
     
    1212add_action( 'admin_init', function() {
    1313    $ajax_actions = array(
    14         array( 'messages_send_message'             => array( 'function' => 'bp_nouveau_ajax_messages_send_message', 'nopriv' => false ) ),
    15         array( 'messages_send_reply'               => array( 'function' => 'bp_nouveau_ajax_messages_send_reply', 'nopriv' => false ) ),
    16         array( 'messages_get_user_message_threads' => array( 'function' => 'bp_nouveau_ajax_get_user_message_threads', 'nopriv' => false ) ),
    17         array( 'messages_thread_read'              => array( 'function' => 'bp_nouveau_ajax_messages_thread_read', 'nopriv' => false ) ),
    18         array( 'messages_get_thread_messages'      => array( 'function' => 'bp_nouveau_ajax_get_thread_messages', 'nopriv' => false ) ),
    19         array( 'messages_delete'                   => array( 'function' => 'bp_nouveau_ajax_delete_thread_messages', 'nopriv' => false ) ),
    20         array( 'messages_unstar'                   => array( 'function' => 'bp_nouveau_ajax_star_thread_messages', 'nopriv' => false ) ),
    21         array( 'messages_star'                     => array( 'function' => 'bp_nouveau_ajax_star_thread_messages', 'nopriv' => false ) ),
    22         array( 'messages_unread'                   => array( 'function' => 'bp_nouveau_ajax_readunread_thread_messages', 'nopriv' => false ) ),
    23         array( 'messages_read'                     => array( 'function' => 'bp_nouveau_ajax_readunread_thread_messages', 'nopriv' => false ) ),
    24         array( 'messages_dismiss_sitewide_notice'  => array( 'function' => 'bp_nouveau_ajax_dismiss_sitewide_notice', 'nopriv' => false ) ),
     14        array(
     15            'messages_send_message' => array(
     16                'function' => 'bp_nouveau_ajax_messages_send_message',
     17                'nopriv'   => false,
     18            ),
     19        ),
     20        array(
     21            'messages_send_reply' => array(
     22                'function' => 'bp_nouveau_ajax_messages_send_reply',
     23                'nopriv'  => false,
     24            ),
     25        ),
     26        array(
     27            'messages_get_user_message_threads' => array(
     28                'function' => 'bp_nouveau_ajax_get_user_message_threads',
     29                'nopriv'   => false,
     30            ),
     31        ),
     32        array(
     33            'messages_thread_read' => array(
     34                'function' => 'bp_nouveau_ajax_messages_thread_read',
     35                'nopriv'   => false,
     36            ),
     37        ),
     38        array(
     39            'messages_get_thread_messages' => array(
     40                'function' => 'bp_nouveau_ajax_get_thread_messages',
     41                'nopriv'   => false,
     42            ),
     43        ),
     44        array(
     45            'messages_delete' => array(
     46                'function' => 'bp_nouveau_ajax_delete_thread_messages',
     47                'nopriv'   => false,
     48            ),
     49        ),
     50        array(
     51            'messages_exit' => array(
     52                'function' => 'bp_nouveau_ajax_exit_thread_messages',
     53                'nopriv'   => false,
     54            ),
     55        ),
     56        array(
     57            'messages_unstar' => array(
     58                'function' => 'bp_nouveau_ajax_star_thread_messages',
     59                'nopriv'   => false,
     60            ),
     61        ),
     62        array(
     63            'messages_star' => array(
     64                'function' => 'bp_nouveau_ajax_star_thread_messages',
     65                'nopriv'   => false,
     66            ),
     67        ),
     68        array(
     69            'messages_unread' => array(
     70                'function' => 'bp_nouveau_ajax_readunread_thread_messages',
     71                'nopriv'   => false,
     72            ),
     73        ),
     74        array(
     75            'messages_read' => array(
     76                'function' => 'bp_nouveau_ajax_readunread_thread_messages',
     77                'nopriv'   => false,
     78            ),
     79        ),
     80        array(
     81            'messages_dismiss_sitewide_notice'  => array(
     82                'function' => 'bp_nouveau_ajax_dismiss_sitewide_notice',
     83                'nopriv' => false,
     84            ),
     85        ),
    2586    );
    2687
     
    781842    }
    782843}
     844
     845/**
     846 * Ajax Handler of the exit action.
     847 *
     848 * @since 10.0.0
     849 */
     850function bp_nouveau_ajax_exit_thread_messages() {
     851    $response = array(
     852        'feedback' => __( 'There was a problem exiting the conversation. Please try again.', 'buddypress' ),
     853        'type'     => 'error',
     854    );
     855
     856    if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'bp_nouveau_messages' ) ) {
     857        wp_send_json_error( $response );
     858    }
     859
     860    if ( empty( $_POST['id'] ) ) {
     861        wp_send_json_error( $response );
     862    }
     863
     864    $thread_ids = wp_parse_id_list( $_POST['id'] );
     865
     866    foreach ( $thread_ids as $thread_id ) {
     867        if ( ! messages_check_thread_access( $thread_id ) && ! bp_current_user_can( 'bp_moderate' ) ) {
     868            wp_send_json_error( $response );
     869        }
     870
     871        bp_messages_exit_thread( $thread_id );
     872    }
     873
     874    wp_send_json_success( array(
     875        'feedback' => __( 'You have left the message thread.', 'buddypress' ),
     876        'type'     => 'success',
     877    ) );
     878}
  • trunk/src/bp-templates/bp-nouveau/js/buddypress-messages.js

    r12941 r13196  
    979979                bp.Nouveau.Messages.displayFeedback( response.feedback, response.type );
    980980
    981                 if ( 'delete' === action || ( 'starred' === self.collection.options.box && 'unstar' === action ) ) {
     981                if ( 'delete' === action || 'exit' === action || ( 'starred' === self.collection.options.box && 'unstar' === action ) ) {
    982982                    // Remove from the list of messages.
    983983                    self.collection.remove( model.get( 'id' ) );
     
    10901090                bp.Nouveau.Messages.displayFeedback( response.feedback, response.type );
    10911091
    1092                 if ( 'delete' === action || ( 'starred' === self.collection.options.box && 'unstar' === action ) ) {
     1092                if ( 'delete' === action || 'exit' === action || ( 'starred' === self.collection.options.box && 'unstar' === action ) ) {
    10931093                    // Remove from the list of messages.
    10941094                    self.collection.remove( thread_ids );
     
    12421242            bp.Nouveau.Messages.threads.doAction( action, this.model.get( 'id' ), options ).done( function( response ) {
    12431243                // Remove all views
    1244                 if ( 'delete' === action ) {
     1244                if ( 'delete' === action || 'exit' === action ) {
    12451245                    bp.Nouveau.Messages.clearViews();
    12461246                } else if ( response.messages ) {
  • trunk/src/bp-templates/bp-nouveau/sass/_nouveau_messages.scss

    r12398 r13196  
    88.message-action-unstar:before,
    99.message-action-view:before,
    10 .message-action-delete:before {
     10.message-action-delete:before,
     11.message-action-exit:before {
    1112    font-family: dashicons;
    1213    font-size: 18px;
     
    2930.message-action-delete:before {
    3031    content: "\f153";
     32}
     33
     34.message-action-exit:before {
     35    content: "\f14a";
    3136}
    3237
  • trunk/src/bp-templates/bp-nouveau/sass/twentytwentyone.scss

    r12921 r13196  
    12281228                background: none;
    12291229
    1230                 &.message-action-delete {
     1230                &.message-action-delete,
     1231                &.message-action-exit {
    12311232
    12321233                    &:before {
  • trunk/tests/phpunit/testcases/messages/class.bp-messages-thread.php

    r13148 r13196  
    672672        $this->assertEquals( 'Bar and baz.', $thread->last_message_content );
    673673    }
     674
     675    /**
     676     * @group exit
     677     * @ticket BP7540
     678     */
     679    public function test_bp_messages_thread_exit() {
     680        $u1 = self::factory()->user->create();
     681        $u2 = self::factory()->user->create();
     682        $u3 = self::factory()->user->create();
     683
     684        $message = self::factory()->message->create_and_get( array(
     685            'sender_id' => $u1,
     686            'recipients' => array( $u2, $u3 ),
     687            'subject' => 'Foo Bar',
     688            'date_sent' => bp_core_current_time(),
     689            'content' => 'Foo Bar is there.',
     690        ) );
     691
     692        $t1 = $message->thread_id;
     693
     694        $this->assertTrue( BP_Messages_Thread::exit_thread( $t1, $u3 ) );
     695    }
     696
     697    /**
     698     * @group exit
     699     * @ticket BP7540
     700     */
     701    public function test_bp_messages_thread_exit_not_enougth_recipients() {
     702        $u1 = self::factory()->user->create();
     703        $u2 = self::factory()->user->create();
     704
     705        $message = self::factory()->message->create_and_get( array(
     706            'sender_id' => $u1,
     707            'recipients' => array( $u2 ),
     708            'subject' => 'Bar Foo',
     709            'date_sent' => bp_core_current_time(),
     710            'content' => 'Bar Foo is also there.',
     711        ) );
     712
     713        $t1 = $message->thread_id;
     714
     715        $this->assertFalse( BP_Messages_Thread::exit_thread( $t1, $u2 ) );
     716    }
     717
     718    /**
     719     * @group exit
     720     * @ticket BP7540
     721     */
     722    public function test_bp_messages_thread_exit_not_one_of_recipients() {
     723        $u1 = self::factory()->user->create();
     724        $u2 = self::factory()->user->create();
     725        $u3 = self::factory()->user->create();
     726        $u4 = self::factory()->user->create();
     727
     728        $message = self::factory()->message->create_and_get( array(
     729            'sender_id' => $u1,
     730            'recipients' => array( $u2, $u3 ),
     731            'subject' => 'Taz',
     732            'date_sent' => bp_core_current_time(),
     733            'content' => 'Where is Taz?',
     734        ) );
     735
     736        $t1 = $message->thread_id;
     737
     738        $this->assertFalse( BP_Messages_Thread::exit_thread( $t1, $u4 ) );
     739    }
    674740}
Note: See TracChangeset for help on using the changeset viewer.