BP Events bp-events invites broken, workaround

bp-events version 1.1 on top of buddypress 1.1.3 isn’t working for invites, it’s broken. After hours and hours of combing the web looking for a solution, I couldn’t find one. I figured out a workaround.

There were several other places online that I found other complain about this same problem. As far as I can tell, nobody has published any solution or workaround. Until now. I have a workaround – more like a hack, but it works!

I don’t know the WordPress/BuddyPress framework, but I’m pretty skilled at PHP, and can debug by following the HTTP request, and walk through the codebase. I used tcpflow to watch the HTTP requests and responses, and walked the codebase by dropping print lines in appropriate places to see how the request traversed the code.

Here’s what I found out. When bp-events gets to the “Send Invites” section, when you check a checkbox of a friend, it invokes an AJAX call, via JavaScript, to wp-load.php. Well, what it sends to the server is action=groups_invite_user, friend_id=. Everything else is hogwash. There is nothing in the request to tell you what event it’s for!

Ok, so the reason for this is that bp-events uses the same api as bp groups. It borrows from bp groups to draw your “Select Friends” widget. I have not found the real root cause. What it’s supposed to do is send an action=events_invite_user and should also send the event_id, I speculate. I haven’t been able to figure out how to craft an HTTP request to wp-load.php that will perform the intended behavior. I do, however, have a workaround that fixes the problem. Keep reading if you want a workaround hack that fixes this problem.

Open this file wp-content/themes/bp-sn-parent/_inc/ajax.php and find the bp_dtheme_ajax_invite_user function and edit it like so:

function bp_dtheme_ajax_invite_user() {
        global $bp;

#dkhack_block - to make the bp-events invite work, get the event_id:
if ( $_COOKIE['bp_new_event_id'] && ereg("/events/create/step/event-invites", $_SERVER['HTTP_REFERER']) )
  $event_id = (int) $_COOKIE['bp_new_event_id'];
else if ( ereg("/events/", $_SERVER['HTTP_REFERER']) )
{
  $event_slug = ereg_replace(".*/events/", "", $_SERVER['HTTP_REFERER']);
  $event_slug = ereg_replace("/.*$", "", $event_slug);

  # The idea here is that I can lookup the event_id based on the slug
  # .   If I have an event_id, then I can override the group invite
  # and make this work.  Very hacki hacki
  $conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
  mysql_select_db(DB_NAME, $conn);
  $sql = "SELECT id FROM wp_bp_events WHERE slug='".mysql_escape_string($event_slug)."' LIMIT 1";
  $result = mysql_query($sql, $conn);
  $row = mysql_fetch_assoc($result);
  $event_id = $row['id'];
}
# END dkhack_block

#dkhack - added !$event_id &&
        !$event_id && check_ajax_referer( 'groups_invite_uninvite_user' );
        if ( !$_POST['friend_id'] || !$_POST['friend_action'] || !$_POST['group_id'] )
                return false;
#dkhack - added !$event_id &&
        if ( !$event_id && !groups_is_user_admin( $bp->loggedin_user->id, $_POST['group_id'] ) )
                return false;
        if ( !friends_check_friendship( $bp->loggedin_user->id, $_POST['friend_id'] ) )
                return false;
        if ( 'invite' == $_POST['friend_action'] ) {
#dkhack - do not do the invite:
# instead of:
#               if ( !groups_invite_user( array( 'user_id' => $_POST['friend_id'], 'group_id' => $_POST['group_id'] ) ) )
#                       return false;
# do this:
                if ( $event_id && !events_invite_user( array( 'user_id' => $_POST['friend_id'], 'event_id' => $event_id ) ) )
                        return false;
                else if ( !$event_id && !groups_invite_user( array( 'user_id' => $_POST['friend_id'], 'group_id' => $_POST['group_id'] ) ) )
                        return false;

                $user = new BP_Core_User( $_POST['friend_id'] );

                echo '<li id="uid-' . $user->id . '">';
                echo $user->avatar_thumb;
                echo '<h4>' . $user->user_link . '</h4>';
                echo '<span class="activity">' . attribute_escape( $user->last_active ) . '</span>';
                echo '<div class="action">
                                <a class="remove" href="' . wp_nonce_url( $bp->loggedin_user->domain . $bp->groups->slug . '/' . $_POST['group_id'] . '/invites/remove/' . $user->id, 'groups_invite_uninvite_user' ) . '" id="uid-' . attribute_escape( $user->id ) . '">' . __( 'Remove Invite', 'buddypress' ) . '</a>
                          </div>';
                echo '</li>';

        } else if ( 'uninvite' == $_POST['friend_action'] ) {
#dkhack - instead of:
#               if ( !groups_uninvite_user( $_POST['friend_id'], $_POST['group_id'] ) )
#                       return false;
# do this:
                if ( $event_id && !events_uninvite_user( $_POST['friend_id'], $event_id ) )
                        return false;
                else if ( !$event_id && !groups_uninvite_user( $_POST['friend_id'], $_POST['group_id'] ) )
                        return false;

                return true;

        } else {
                return false;
        }
}

To conclude, what’s going on here, is we’re taking over the AJAX handler for groups_invite_user and using some fuzzy logic to determine if this is really an event invite, or a group invite. If we determine that it’s an event invite, we get the event_id and then call the events_invite_user function.

This workaround does not break Group invites. It’s especially messy, because I don’t know the WP/BP framework, so I’m using mysql native functions to do a query. I’m also hard coding the wp prefix, which I know isn’t great. I’m a little embarrassed to share the solution, because it’s a hack. But, it worked in pinch, and I figured I should share and help the next guy that’s stuck struggling with this.

DaveK

1,169 thoughts on “BP Events bp-events invites broken, workaround

  1. I’m a lil embarrassed using a hack too but man, this really helped me out for the time being – thanks!

    • Glad it helped, I’ve since figured out how to use the db object so don’t have to drop in a new mysql connection. I’ll post it soon.

Comments are closed.