Skip to:
Content

BuddyPress.org

Changeset 14075


Ignore:
Timestamp:
11/03/2024 07:16:26 PM (16 months ago)
Author:
espellcaste
Message:

Messages: Use a mysql subquery to insert the thread_id while inserting a new thread message.

By moving the thread_id insertion into a subquery, we can avoid race conditions where two messages are sent at the same time and both use the same thread_id.

Props imath and petersmithrestless.

Closes https://github.com/buddypress/buddypress/pull/399
Fixes #8544

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-messages/classes/class-bp-messages-message.php

    r13414 r14075  
    140140        // If we have no thread_id then this is the first message of a new thread.
    141141        if ( empty( $this->thread_id ) ) {
    142             $this->thread_id = (int) $wpdb->get_var( "SELECT MAX(thread_id) FROM {$bp->messages->table_name_messages}" ) + 1;
    143             $new_thread      = true;
     142            $new_thread           = true;
     143            $insert_message_query = $wpdb->prepare(
     144                "INSERT INTO {$bp->messages->table_name_messages} "
     145                . "( thread_id, sender_id, subject, message, date_sent ) "
     146                . "VALUES ( " . "( SELECT IFNULL(MAX(m.thread_id), 0) FROM {$bp->messages->table_name_messages} m ) + 1, " . "%d, %s, %s, %s )",
     147                $this->sender_id,
     148                $this->subject,
     149                $this->message,
     150                $this->date_sent
     151            );
     152        } else { // Add a new message to an existing thread.
     153            $insert_message_query = $wpdb->prepare(
     154                "INSERT INTO {$bp->messages->table_name_messages} "
     155                . "( thread_id, sender_id, subject, message, date_sent ) "
     156                . "VALUES ( %d, %d, %s, %s, %s )",
     157                $this->thread_id,
     158                $this->sender_id,
     159                $this->subject,
     160                $this->message,
     161                $this->date_sent
     162            );
    144163        }
    145164
    146165        // First insert the message into the messages table.
    147         if ( ! $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->messages->table_name_messages} ( thread_id, sender_id, subject, message, date_sent ) VALUES ( %d, %d, %s, %s, %s )", $this->thread_id, $this->sender_id, $this->subject, $this->message, $this->date_sent ) ) ) {
     166        if ( ! $wpdb->query( $insert_message_query ) ) {
    148167            return false;
    149168        }
    150169
    151170        $this->id = $wpdb->insert_id;
     171
     172        // For new threads fetch the thread_id that was generated during the insert query
     173        if ( $new_thread ) {
     174            $this->thread_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT thread_id FROM {$bp->messages->table_name_messages} WHERE id=%d", $this->id ) );
     175        }
    152176
    153177        $recipient_ids = array();
Note: See TracChangeset for help on using the changeset viewer.