/** * Searches through the content of an activity item to locate usernames, * designated by an @ sign. * * @since BuddyPress (1.5) * * @param string $content The content of the activity, usually found in $activity->content. * @return mixed Associative array with user ID as key and username as value. Boolean false if no mentions found. */ function bp_activity_find_mentions($content) { $pattern = '/[@]+([A-Za-z0-9-_\\.@]+)\\b/'; preg_match_all($pattern, $content, $usernames); // Make sure there's only one instance of each username if (!($usernames = array_unique($usernames[1]))) { return false; } $mentioned_users = array(); // We've found some mentions! Check to see if users exist foreach ((array) $usernames as $key => $username) { if (bp_is_username_compatibility_mode()) { $user_id = username_exists($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } // user ID exists, so let's add it to our array if (!empty($user_id)) { $mentioned_users[$user_id] = $username; } } if (empty($mentioned_users)) { return false; } return $mentioned_users; }
/** * Adjusts new mention count for mentioned users when activity items are deleted or created * * @since 1.5.0 * * @param int $activity_id The unique id for the activity item * @param string $action Can be 'delete' or 'add'. Defaults to 'add' * * @uses BP_Activity_Activity() {@link BP_Activity_Activity} * @uses bp_activity_find_mentions() * @uses bp_is_username_compatibility_mode() * @uses bp_core_get_userid_from_nicename() * @uses bp_get_user_meta() * @uses bp_update_user_meta() */ function bp_activity_adjust_mention_count($activity_id, $action = 'add') { $activity = new BP_Activity_Activity($activity_id); if ($usernames = bp_activity_find_mentions(strip_tags($activity->content))) { foreach ((array) $usernames as $username) { if (bp_is_username_compatibility_mode()) { $user_id = username_exists($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } if (empty($user_id)) { continue; } // Adjust the mention list and count for the member $new_mention_count = (int) bp_get_user_meta($user_id, 'bp_new_mention_count', true); if (!($new_mentions = bp_get_user_meta($user_id, 'bp_new_mentions', true))) { $new_mentions = array(); } switch ($action) { case 'delete': $key = array_search($activity_id, $new_mentions); if ($key !== false) { unset($new_mentions[$key]); } break; case 'add': default: if (!in_array($activity_id, $new_mentions)) { $new_mentions[] = (int) $activity_id; } break; } // Get an updated mention count $new_mention_count = count($new_mentions); // Resave the user_meta bp_update_user_meta($user_id, 'bp_new_mention_count', $new_mention_count); bp_update_user_meta($user_id, 'bp_new_mentions', $new_mentions); } } }
/** * Finds and links @-mentioned users in the contents of activity items * * @since 1.2.0 * * @param string $content The activity content * @param int $activity_id The activity id * * @uses bp_activity_find_mentions() * @uses bp_is_username_compatibility_mode() * @uses bp_core_get_userid_from_nicename() * @uses bp_activity_at_message_notification() * @uses bp_core_get_user_domain() * @uses bp_activity_adjust_mention_count() * * @return string $content Content filtered for mentions */ function bp_activity_at_name_filter($content, $activity_id = 0) { if ($activity_id & bp_is_active('activity')) { $activity = new BP_Activity_Activity($activity_id); // If this activity has been marked as spam, don't do anything. This prevents @notifications being sent. if (!empty($activity) && $activity->is_spam) { return $content; } } $usernames = bp_activity_find_mentions($content); foreach ((array) $usernames as $username) { if (bp_is_username_compatibility_mode()) { $user_id = username_exists($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } if (empty($user_id)) { continue; } // If an activity_id is provided, we can send email and BP notifications if ($activity_id) { bp_activity_at_message_notification($activity_id, $user_id); } $content = preg_replace('/(@' . $username . '\\b)/', "<a href='" . bp_core_get_user_domain($user_id) . "' rel='nofollow'>@{$username}</a>", $content); } // Adjust the activity count for this item if ($activity_id) { bp_activity_adjust_mention_count($activity_id, 'add'); } return $content; }
/** * Create a new message. * * @since 2.4.0 Added 'error_type' as an additional $args parameter. * * @param array|string $args { * Array of arguments. * @type int $sender_id Optional. ID of the user who is sending the * message. Default: ID of the logged-in user. * @type int $thread_id Optional. ID of the parent thread. Leave blank to * create a new thread for the message. * @type array $recipients IDs or usernames of message recipients. If this * is an existing thread, it is unnecessary to pass a $recipients * argument - existing thread recipients will be assumed. * @type string $subject Optional. Subject line for the message. For * existing threads, the existing subject will be used. For new * threads, 'No Subject' will be used if no $subject is provided. * @type string $content Content of the message. Cannot be empty. * @type string $date_sent Date sent, in 'Y-m-d H:i:s' format. Default: current date/time. * @type string $error_type Optional. Error type. Either 'bool' or 'wp_error'. Default: 'bool'. * } * @return int|bool ID of the message thread on success, false on failure. */ function messages_new_message($args = '') { // Parse the default arguments. $r = bp_parse_args($args, array('sender_id' => bp_loggedin_user_id(), 'thread_id' => false, 'recipients' => array(), 'subject' => false, 'content' => false, 'date_sent' => bp_core_current_time(), 'error_type' => 'bool'), 'messages_new_message'); // Bail if no sender or no content. if (empty($r['sender_id']) || empty($r['content'])) { if ('wp_error' === $r['error_type']) { if (empty($r['sender_id'])) { $error_code = 'messages_empty_sender'; $feedback = __('Your message was not sent. Please use a valid sender.', 'buddypress'); } else { $error_code = 'messages_empty_content'; $feedback = __('Your message was not sent. Please enter some content.', 'buddypress'); } return new WP_Error($error_code, $feedback); } else { return false; } } // Create a new message object. $message = new BP_Messages_Message(); $message->thread_id = $r['thread_id']; $message->sender_id = $r['sender_id']; $message->subject = $r['subject']; $message->message = $r['content']; $message->date_sent = $r['date_sent']; // If we have a thread ID... if (!empty($r['thread_id'])) { // ...use the existing recipients $thread = new BP_Messages_Thread($r['thread_id']); $message->recipients = $thread->get_recipients(); // Strip the sender from the recipient list, and unset them if they are // not alone. If they are alone, let them talk to themselves. if (isset($message->recipients[$r['sender_id']]) && count($message->recipients) > 1) { unset($message->recipients[$r['sender_id']]); } // Set a default reply subject if none was sent. if (empty($message->subject)) { $message->subject = sprintf(__('Re: %s', 'buddypress'), $thread->messages[0]->subject); } // ...otherwise use the recipients passed } else { // Bail if no recipients. if (empty($r['recipients'])) { if ('wp_error' === $r['error_type']) { return new WP_Error('message_empty_recipients', __('Message could not be sent. Please enter a recipient.', 'buddypress')); } else { return false; } } // Set a default subject if none exists. if (empty($message->subject)) { $message->subject = __('No Subject', 'buddypress'); } // Setup the recipients array. $recipient_ids = array(); // Invalid recipients are added to an array, for future enhancements. $invalid_recipients = array(); // Loop the recipients and convert all usernames to user_ids where needed. foreach ((array) $r['recipients'] as $recipient) { // Trim spaces and skip if empty. $recipient = trim($recipient); if (empty($recipient)) { continue; } // Check user_login / nicename columns first // @see http://buddypress.trac.wordpress.org/ticket/5151. if (bp_is_username_compatibility_mode()) { $recipient_id = bp_core_get_userid(urldecode($recipient)); } else { $recipient_id = bp_core_get_userid_from_nicename($recipient); } // Check against user ID column if no match and if passed recipient is numeric. if (empty($recipient_id) && is_numeric($recipient)) { if (bp_core_get_core_userdata((int) $recipient)) { $recipient_id = (int) $recipient; } } // Decide which group to add this recipient to. if (empty($recipient_id)) { $invalid_recipients[] = $recipient; } else { $recipient_ids[] = (int) $recipient_id; } } // Strip the sender from the recipient list, and unset them if they are // not alone. If they are alone, let them talk to themselves. $self_send = array_search($r['sender_id'], $recipient_ids); if (!empty($self_send) && count($recipient_ids) > 1) { unset($recipient_ids[$self_send]); } // Remove duplicates & bail if no recipients. $recipient_ids = array_unique($recipient_ids); if (empty($recipient_ids)) { if ('wp_error' === $r['error_type']) { return new WP_Error('message_invalid_recipients', __('Message could not be sent because you have entered an invalid username. Please try again.', 'buddypress')); } else { return false; } } // Format this to match existing recipients. foreach ((array) $recipient_ids as $i => $recipient_id) { $message->recipients[$i] = new stdClass(); $message->recipients[$i]->user_id = $recipient_id; } } // Bail if message failed to send. $send = $message->send(); if (false === is_int($send)) { if ('wp_error' === $r['error_type']) { if (is_wp_error($send)) { return $send; } else { return new WP_Error('message_generic_error', __('Message was not sent. Please try again.', 'buddypress')); } } return false; } /** * Fires after a message has been successfully sent. * * @since 1.1.0 * * @param BP_Messages_Message $message Message object. Passed by reference. */ do_action_ref_array('messages_message_sent', array(&$message)); // Return the thread ID. return $message->thread_id; }
function sp_build_profile_formlink($userid) { global $spThisUser; $sfprofile = sp_get_option('sfprofile'); $mode = $sfprofile['formmode']; # if profile mode is BP or Mingle but they are not active, switch back to popup profile include_once ABSPATH . 'wp-admin/includes/plugin.php'; if ($mode == 3 && !is_plugin_active('buddypress/bp-loader.php') || $mode == 5 && !is_plugin_active('mingle/mingle.php')) { $mode = 1; } switch ($mode) { case 1: # SPF form $edit = ''; if ($userid != $spThisUser->ID) { $user = new WP_User($userid); $edit = $user->ID . '/edit'; } $site = sp_url('profile/' . $edit); return $site; case 2: # WordPress form return SFHOMEURL . 'wp-admin/user-edit.php?user_id=' . $userid; case 3: # BuddyPress profile page $user = new WP_User($userid); # try to handle BP switches between username and login ussge $username = bp_is_username_compatibility_mode() ? $user->user_login : $user->user_nicename; if (strstr($username, ' ')) { $username = $user->user_nicename; } else { $username = urlencode($username); } # build BP user profile based on bp options $bp = get_option('bp-pages'); $baseurl = get_permalink($bp['members']); $site = user_trailingslashit($baseurl . str_replace(' ', '', $username) . '/profile'); $site = apply_filters('sph_buddypress_profile', $site, $user); return $site; case 4: # Handoff to user specified form if ($sfprofile['formpage']) { $out = $sfprofile['formpage']; if ($sfprofile['formquery']) { $out .= '?' . sp_filter_title_display($sfprofile['formquery']) . '=' . $userid; } } else { $out = ''; } return $out; case 5: # Mingle account page $user = new WP_User($userid); $site = SFSITEURL . user_trailingslashit('account'); $site = apply_filters('sph_mingle_profile', $site, $user); return $site; } }
/** * Return the user link for the user based on the supplied identifier. * * @param string $username If BP_ENABLE_USERNAME_COMPATIBILITY_MODE is set, * this should be user_login, otherwise it should be user_nicename. * @return string|bool The link to the user's domain, false on no match. */ function bp_core_get_userlink_by_username($username) { if (bp_is_username_compatibility_mode()) { $user_id = bp_core_get_userid($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } return apply_filters('bp_core_get_userlink_by_username', bp_core_get_userlink($user_id, false, false, true)); }
/** * Used in the bbPress plugin * * @since 0.6 */ function ray_get_the_author_display_name($name, $user_id) { // test to see if we're on a BP group forum page or on any bbPress page if (bp_is_group_forum() || function_exists('bbpress') && is_bbpress()) { // cache username queries with static variable // // tried stuffing in $bp global but didn't work properly // probably due to object buffering in bbP static $bp_uso_data = array(); $name = false; // try to get locally-cached value first if (!empty($bp_uso_data[$user_id])) { $name = $bp_uso_data[$user_id]; } // no cached value, so query for it if ($name === false) { $field = bp_is_username_compatibility_mode() ? 'user_login' : 'user_nicename'; $name = get_the_author_meta($field, $user_id); // cache it for later use in the loop $bp_uso_data[$user_id] = $name; } } return $name; }
/** * AJAX handler for group member autocomplete requests. * * @since BuddyPress (1.7.0) */ function bp_groups_admin_autocomplete_handler() { // Bail if user user shouldn't be here, or is a large network if (!current_user_can('bp_moderate') || is_multisite() && wp_is_large_network('users')) { wp_die(-1); } $return = array(); // Exclude current group members $group_id = isset($_GET['group_id']) ? wp_parse_id_list($_GET['group_id']) : array(); $group_member_query = new BP_Group_Member_Query(array('group_id' => $group_id, 'per_page' => 0, 'group_role' => array('member', 'mod', 'admin'), 'populate_extras' => false, 'count_total' => false)); $group_members = !empty($group_member_query->results) ? wp_list_pluck($group_member_query->results, 'ID') : array(); $terms = isset($_GET['term']) ? $_GET['term'] : ''; $users = bp_core_get_users(array('type' => 'alphabetical', 'search_terms' => $terms, 'exclude' => $group_members, 'per_page' => 10, 'populate_extras' => false)); foreach ((array) $users['users'] as $user) { $return[] = array('label' => sprintf(__('%1$s (%2$s)', 'buddypress'), bp_is_username_compatibility_mode() ? $user->user_login : $user->user_nicename, $user->user_email), 'value' => $user->user_nicename); } wp_die(json_encode($return)); }
function sp_build_profile_formlink($userid) { global $spThisUser; $sfprofile = sp_get_option('sfprofile'); switch ($sfprofile['formmode']) { case 1: # SPF form $edit = ''; if ($userid != $spThisUser->ID) { $user = new WP_User($userid); $edit = $user->ID . '/edit'; } $site = sp_url('profile/' . $edit); return $site; case 2: # WordPress form return SFHOMEURL . 'wp-admin/user-edit.php?user_id=' . $userid; case 3: # BuddyPress profile page $user = new WP_User($userid); # try to handle BP switches between username and login ussge $username = bp_is_username_compatibility_mode() ? $user->user_login : $user->user_nicename; if (strstr($username, ' ')) { $username = $user->user_nicename; } else { $username = urlencode($username); } $site = SFSITEURL . 'members/' . str_replace(' ', '', $username) . '/profile/edit/'; $site = apply_filters('sph_buddypress_profile', $site, $user); return $site; case 4: # Handoff to user specified form if ($sfprofile['formpage']) { $out = $sfprofile['formpage']; if ($sfprofile['formquery']) { $out .= '?' . sp_filter_title_display($sfprofile['formquery']) . '=' . $userid; } } else { $out = ''; } return $out; case 5: # Mingle account page $user = new WP_User($userid); $site = SFSITEURL . user_trailingslashit('account'); $site = apply_filters('sph_mingle_profile', $site, $user); return $site; } }
/** * AJAX receiver for the @mention autosuggest jQuery library. Performs a search on the string provided and returns matches. * * @global object $bp BuddyPress global settings * @return mixed Either HTML or JSON. If error, "-1" for missing parameters, "0" for no matches. * @see bp-labs/beakers/js/jquery.mentions.dev.js * @since 1.0 */ public function mention_autosuggest() { global $bp; if (empty($_POST['limit']) || empty($_POST['search'])) { exit('-1'); } // Sanitise input $search_query = implode('', (array) preg_replace(array('|^https?://|i', '|\\*|', '|@|'), '', $_POST['search'])); if (empty($search_query)) { exit('-1'); } $args = array('count_total' => false, 'number' => (int) $_POST['limit'], 'search' => "{$search_query}*"); if (!empty($bp->loggedin_user->id)) { $args['exclude'] = array($bp->loggedin_user->id); } if (bp_is_username_compatibility_mode()) { $args['fields'] = array('ID', 'user_login'); $args['orderby'] = 'login'; } else { $args['fields'] = array('ID', 'user_nicename'); $args['orderby'] = 'nicename'; } $args = apply_filters('bpl_mention_autosuggest_args', $args); // Search users $user_search_results = get_users($args); if (empty($user_search_results)) { // Return JSON if (!empty($_POST['format']) && 'json' == $_POST['format']) { exit(json_encode(false)); // Return HTML } else { printf('<li class="section error"><p><span>%s</span> %s</p></li>', _x('No matches found.', 'no search results', 'bpl'), _x('Please check your spelling.', 'no search results', 'bpl')); exit; } } // If logged in, get user's friends $friend_ids = array(); if (!empty($bp->loggedin_user->id) && bp_is_active('friends')) { $friend_ids = friends_get_friend_user_ids($bp->loggedin_user->id); } $search_results = array('friends' => array(), 'others' => array()); // Build results foreach ((array) $user_search_results as $user) { $result = new stdClass(); $result->avatar = bp_core_fetch_avatar(array('item_id' => $user->ID, 'width' => 30, 'height' => 30, 'type' => 'thumb', 'alt' => __('Profile picture of %s', 'bpl'))); $result->name = bp_core_get_user_displayname($user->ID); if (bp_is_username_compatibility_mode()) { $result->id = $user->user_login; } else { $result->id = $user->user_nicename; } if (in_array($user->ID, (array) $friend_ids)) { $search_results['friends'][] = $result; } else { $search_results['others'][] = $result; } } apply_filters_ref_array('bpl_mention_autosuggest', array(&$search_results, $args)); // Return JSON if (!empty($_POST['format']) && 'json' == $_POST['format']) { exit(json_encode($search_results)); // Return HTML } else { $html = array(); foreach ($search_results as $section => $items) { if (empty($items)) { continue; } // Friends and other users if ('friends' == $section || 'others' == $section) { if ('friends' == $section) { $html[] = sprintf('<li class="section friends"><p>%s</p></li>', __('Your friends', 'bpl')); } elseif ('others' == $section) { if (!empty($search_results['friends'])) { $html[] = sprintf('<li class="section other"><p>%s</p></li>', sprintf(__('Other people on %s', 'bpl'), get_bloginfo('name', 'display'))); } else { $html[] = sprintf('<li class="section other"><p>%s</p></li>', sprintf(__('People on %s', 'bpl'), get_bloginfo('name', 'display'))); } } foreach ($items as $item) { $html[] = sprintf('<li class=%s><p>%s</p></li>', esc_attr($item->id), $item->avatar . esc_html($item->name)); } // For third-party extensions } else { $custom_section = apply_filters('bpl_mention_autosuggest_custom_section', false, $section, $items); if (!empty($custom_section)) { $html = array_merge($html, (array) $custom_section); } } } // Safety net if (empty($html)) { $html[] = sprintf('<li class="section error"><p><span>%s</span> %s</p></li>', _x('No matches found.', 'no search results', 'bpl'), _x('Please check your spelling.', 'no search results', 'bpl')); } exit(apply_filters('bpl_mention_autosuggest_html', implode(PHP_EOL, $html), $html)); } }
/** * Create a new message. * * @param array $args { * Array of arguments. * @type int $sender_id Optional. ID of the user who is sending the * message. Default: ID of the logged-in user. * @type int $thread_id Optional. ID of the parent thread. Leave blank to * create a new thread for the message. * @type array $recipients IDs or usernames of message recipients. If this * is an existing thread, it is unnecessary to pass a $recipients * argument - existing thread recipients will be assumed. * @type string $subject Optional. Subject line for the message. For * existing threads, the existing subject will be used. For new * threads, 'No Subject' will be used if no $subject is provided. * @type string $content Content of the message. Cannot be empty. * @type string $date_sent Date sent, in 'Y-m-d H:i:s' format. Default: * current date/time. * } * @return int|bool ID of the message thread on success, false on failure. */ function messages_new_message( $args = '' ) { // Parse the default arguments $r = bp_parse_args( $args, array( 'sender_id' => bp_loggedin_user_id(), 'thread_id' => false, // false for a new message, thread id for a reply to a thread. 'recipients' => array(), // Can be an array of usernames, user_ids or mixed. 'subject' => false, 'content' => false, 'date_sent' => bp_core_current_time() ), 'messages_new_message' ); // Bail if no sender or no content if ( empty( $r['sender_id'] ) || empty( $r['content'] ) ) { return false; } // Create a new message object $message = new BP_Messages_Message; $message->thread_id = $r['thread_id']; $message->sender_id = $r['sender_id']; $message->subject = $r['subject']; $message->message = $r['content']; $message->date_sent = $r['date_sent']; // If we have a thread ID... if ( ! empty( $r['thread_id'] ) ) { // ...use the existing recipients $thread = new BP_Messages_Thread( $r['thread_id'] ); $message->recipients = $thread->get_recipients(); // Strip the sender from the recipient list, and unset them if they are // not alone. If they are alone, let them talk to themselves. if ( isset( $message->recipients[ $r['sender_id'] ] ) && ( count( $message->recipients ) > 1 ) ) { unset( $message->recipients[ $r['sender_id'] ] ); } // Set a default reply subject if none was sent if ( empty( $message->subject ) ) { $message->subject = sprintf( __( 'Re: %s', 'buddypress' ), $thread->messages[0]->subject ); } // ...otherwise use the recipients passed } else { // Bail if no recipients if ( empty( $r['recipients'] ) ) { return false; } // Set a default subject if none exists if ( empty( $message->subject ) ) { $message->subject = __( 'No Subject', 'buddypress' ); } // Setup the recipients array $recipient_ids = array(); // Invalid recipients are added to an array, for future enhancements $invalid_recipients = array(); // Loop the recipients and convert all usernames to user_ids where needed foreach( (array) $r['recipients'] as $recipient ) { // Trim spaces and skip if empty $recipient = trim( $recipient ); if ( empty( $recipient ) ) { continue; } // Check user_login / nicename columns first // @see http://buddypress.trac.wordpress.org/ticket/5151 if ( bp_is_username_compatibility_mode() ) { $recipient_id = bp_core_get_userid( urldecode( $recipient ) ); } else { $recipient_id = bp_core_get_userid_from_nicename( $recipient ); } // Check against user ID column if no match and if passed recipient is numeric if ( empty( $recipient_id ) && is_numeric( $recipient ) ) { if ( bp_core_get_core_userdata( (int) $recipient ) ) { $recipient_id = (int) $recipient; } } // Decide which group to add this recipient to if ( empty( $recipient_id ) ) { $invalid_recipients[] = $recipient; } else { $recipient_ids[] = (int) $recipient_id; } } // Strip the sender from the recipient list, and unset them if they are // not alone. If they are alone, let them talk to themselves. $self_send = array_search( $r['sender_id'], $recipient_ids ); if ( ! empty( $self_send ) && ( count( $recipient_ids ) > 1 ) ) { unset( $recipient_ids[ $self_send ] ); } // Remove duplicates & bail if no recipients $recipient_ids = array_unique( $recipient_ids ); if ( empty( $recipient_ids ) ) { return false; } // Format this to match existing recipients foreach( (array) $recipient_ids as $i => $recipient_id ) { $message->recipients[$i] = new stdClass; $message->recipients[$i]->user_id = $recipient_id; } } // Bail if message failed to send if ( ! $message->send() ) { return false; } /** * Fires after a message has been successfully sent. * * @since BuddyPress (1.1.0) * * @param BP_Messages_Message $message Message object. Passed by reference. */ do_action_ref_array( 'messages_message_sent', array( &$message ) ); // Return the thread ID return $message->thread_id; }
function messages_new_message($args = '') { $defaults = array('sender_id' => bp_loggedin_user_id(), 'thread_id' => false, 'recipients' => false, 'subject' => false, 'content' => false, 'date_sent' => bp_core_current_time()); $r = wp_parse_args($args, $defaults); extract($r, EXTR_SKIP); if (empty($sender_id) || empty($content)) { return false; } // Create a new message object $message = new BP_Messages_Message(); $message->thread_id = $thread_id; $message->sender_id = $sender_id; $message->subject = $subject; $message->message = $content; $message->date_sent = $date_sent; // If we have a thread ID, use the existing recipients, otherwise use the recipients passed if (!empty($thread_id)) { $thread = new BP_Messages_Thread($thread_id); $message->recipients = $thread->get_recipients(); // Strip the sender from the recipient list if they exist if (isset($message->recipients[$sender_id])) { unset($message->recipients[$sender_id]); } if (empty($message->subject)) { $message->subject = sprintf(__('Re: %s', 'buddypress'), $thread->messages[0]->subject); } // No thread ID, so make some adjustments } else { if (empty($recipients)) { return false; } if (empty($message->subject)) { $message->subject = __('No Subject', 'buddypress'); } $recipient_ids = array(); // Invalid recipients are added to an array, for future enhancements $invalid_recipients = array(); // Loop the recipients and convert all usernames to user_ids where needed foreach ((array) $recipients as $recipient) { $recipient = trim($recipient); if (empty($recipient)) { continue; } $recipient_id = false; // input was numeric if (is_numeric($recipient)) { // do a check against the user ID column first if (bp_core_get_core_userdata((int) $recipient)) { $recipient_id = (int) $recipient; } else { if (bp_is_username_compatibility_mode()) { $recipient_id = bp_core_get_userid((int) $recipient); } else { $recipient_id = bp_core_get_userid_from_nicename((int) $recipient); } } } else { if (bp_is_username_compatibility_mode()) { $recipient_id = bp_core_get_userid($recipient); } else { $recipient_id = bp_core_get_userid_from_nicename($recipient); } } if (!$recipient_id) { $invalid_recipients[] = $recipient; } else { $recipient_ids[] = (int) $recipient_id; } } // Strip the sender from the recipient list if they exist if ($key = array_search($sender_id, (array) $recipient_ids)) { unset($recipient_ids[$key]); } // Remove duplicates $recipient_ids = array_unique((array) $recipient_ids); if (empty($recipient_ids)) { return false; } // Format this to match existing recipients foreach ((array) $recipient_ids as $i => $recipient_id) { $message->recipients[$i] = new stdClass(); $message->recipients[$i]->user_id = $recipient_id; } } if ($message->send()) { // Send screen notifications to the recipients foreach ((array) $message->recipients as $recipient) { bp_core_add_notification($message->id, $recipient->user_id, 'messages', 'new_message'); } // Send email notifications to the recipients messages_notification_new_message(array('message_id' => $message->id, 'sender_id' => $message->sender_id, 'subject' => $message->subject, 'content' => $message->message, 'recipients' => $message->recipients, 'thread_id' => $message->thread_id)); do_action_ref_array('messages_message_sent', array(&$message)); return $message->thread_id; } return false; }
/** * Finds and links @-mentioned users in the contents of activity items * * @since 1.2.0 * * @param string $content The activity content * @param int $activity_id The activity id * * @uses bp_activity_find_mentions() * @uses bp_is_username_compatibility_mode() * @uses bp_core_get_userid_from_nicename() * @uses bp_activity_at_message_notification() * @uses bp_core_get_user_domain() * @uses bp_activity_adjust_mention_count() * * @return string $content Content filtered for mentions */ function bp_activity_at_name_filter($content, $activity_id = 0) { $usernames = bp_activity_find_mentions($content); foreach ((array) $usernames as $username) { if (bp_is_username_compatibility_mode()) { $user_id = username_exists($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } if (empty($user_id)) { continue; } // If an activity_id is provided, we can send email and BP notifications if ($activity_id) { bp_activity_at_message_notification($activity_id, $user_id); } $content = preg_replace('/(@' . $username . '\\b)/', "<a href='" . bp_core_get_user_domain($user_id) . "' rel='nofollow'>@{$username}</a>", $content); } // Adjust the activity count for this item if ($activity_id) { bp_activity_adjust_mention_count($activity_id, 'add'); } return $content; }
/** * bp_dtheme_ajax_messages_autocomplete_results() * * AJAX handler for autocomplete. Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined * * @global object object $bp Global BuddyPress settings object * @return none */ function bp_dtheme_ajax_messages_autocomplete_results() { global $bp; // Include everyone in the autocomplete, or just friends? if ($bp->messages->slug == $bp->current_component) { $autocomplete_all = $bp->messages->autocomplete_all; } $friends = false; $pag_page = 1; $limit = $_GET['limit'] ? $_GET['limit'] : apply_filters('bp_autocomplete_max_results', 10); // Get the user ids based on the search terms if (!empty($autocomplete_all)) { $users = BP_Core_User::search_users($_GET['q'], $limit, $pag_page); if (!empty($users['users'])) { // Build an array with the correct format $user_ids = array(); foreach ($users['users'] as $user) { if ($user->id != $bp->loggedin_user->id) { $user_ids[] = $user->id; } } $user_ids = apply_filters('bp_core_autocomplete_ids', $user_ids, $_GET['q'], $limit); } } else { if (bp_is_active('friends')) { $users = friends_search_friends($_GET['q'], $bp->loggedin_user->id, $limit, 1); // Keeping the bp_friends_autocomplete_list filter for backward compatibility $users = apply_filters('bp_friends_autocomplete_list', $users, $_GET['q'], $limit); if (!empty($users['friends'])) { $user_ids = apply_filters('bp_friends_autocomplete_ids', $users['friends'], $_GET['q'], $limit); } } } if (!empty($user_ids)) { foreach ($user_ids as $user_id) { $ud = get_userdata($user_id); if (!$ud) { continue; } if (bp_is_username_compatibility_mode()) { $username = $ud->user_login; } else { $username = $ud->user_nicename; } echo '<span id="link-' . $username . '" href="' . bp_core_get_user_domain($user_id) . '"></span>' . bp_core_fetch_avatar(array('item_id' => $user_id, 'type' => 'thumb', 'width' => 15, 'height' => 15)) . ' ' . bp_core_get_user_displayname($user_id) . ' (' . $username . ') '; } } }
/** * Return the user link for the user based on the supplied identifier. * * @since 1.0.0 * * @param string $username If BP_ENABLE_USERNAME_COMPATIBILITY_MODE is set, * this should be user_login, otherwise it should * be user_nicename. * @return string|bool The link to the user's domain, false on no match. */ function bp_core_get_userlink_by_username($username) { if (bp_is_username_compatibility_mode()) { $user_id = bp_core_get_userid($username); } else { $user_id = bp_core_get_userid_from_nicename($username); } /** * Filters the user link for the user based on username. * * @since 1.0.1 * * @param string|bool $value URL for the user if found, otherwise false. */ return apply_filters('bp_core_get_userlink_by_username', bp_core_get_userlink($user_id, false, false, true)); }
/** * Determine which BP component (if any) matches a given transect * * @link http://en.wikipedia.org/wiki/Cycle_(graph_theory) * @link http://en.wikipedia.org/wiki/Cycle_detection * @version 1.0 * @since 1.0 * @param array $intersect | Intersect array * @param array $status | Reason no match was found * @return bool $result | Exception on failure. True on match. False on no match. */ public function matchComponent($intersect, &$status) { $transect = $intersect["transect"]; $route_found = false; // CASE 1: Front-page component // ==================================================================== if ($intersect["endpoint_id"] === null) { // If a component is set to the front page, and the user is not requesting // a specific post via a URL parameter, we have a match $not_preview_mode = empty($_GET['p']) && empty($_GET['page_id']); if ($not_preview_mode) { $show_page_on_front = get_option('show_on_front') == 'page'; // Note comparison operator $post_id = get_option('page_on_front'); if ($show_page_on_front && $post_id) { $post = get_post($post_id); if (!empty($post)) { $this->bp->current_component = (string) $post->post_name; $status = array('numeric' => 1, 'text' => "Successful match on front-page component.", 'data' => array('current_component' => $this->bp->current_component, 'post_id' => $post_id, 'post' => $post), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; } else { throw new FOX_exception(array('numeric' => 1, 'text' => "Site front page set to component, but component's post was empty", 'data' => array("post_id" => $post_id), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } } } if (!$route_found) { $status = array('numeric' => 2, 'text' => "Site front page with no components active on front page.", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); return false; } } // CASE 2: Any non-nested component // ==================================================================== if (!$this->bp->current_component) { try { $this->bp->current_component = self::getPrimaryComponentName($intersect["endpoint_name"]); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error fetching primary component name", 'data' => array("endpoint_name" => $intersect["endpoint_name"]), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($this->bp->current_component) { $status = array('numeric' => 3, 'text' => "Successful match on primary component", 'data' => array('current_component' => $this->bp->current_component), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; } } // CASE 3: Root profile // ==================================================================== if (!$this->bp->current_component && !empty($transect) && !empty($this->bp->pages->members) && defined('BP_ENABLE_ROOT_PROFILES') && BP_ENABLE_ROOT_PROFILES) { // Shift the user name off the transect $user_name = array_shift($transect); // Switch the user_id based on compatibility mode if (bp_is_username_compatibility_mode()) { $user_id = (int) bp_core_get_userid(urldecode($user_name)); } else { $user_id = (int) bp_core_get_userid_from_nicename(urldecode($user_name)); } if ($user_id) { $this->bp->current_component = "members"; $this->bp->displayed_user->id = $user_id; $status = array('numeric' => 4, 'text' => "Successful match on root profile", 'data' => array('current_component' => $this->bp->current_component), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; // Without the 'members' URL chunk, WordPress won't know which page to load, // so this filter intercepts the WP query and tells it to load the members page $function_string = '$query_args["pagename"] = "'; $function_string .= $this->bp->pages->members->name; $function_string .= '"; return $query_args;'; add_filter('request', create_function('$query_args', $function_string)); } else { $status = array('numeric' => 5, 'text' => "Root profiles enabled. No matching user.", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); return false; } } // CASE 4: No match // ==================================================================== if (!$this->bp->current_component) { $status = array('numeric' => 6, 'text' => "No matching components", 'data' => array('intersect' => $this->intersect, 'walk' => $this->walk), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); return false; } // Members Component secondary processing // ==================================================================== if ($this->bp->current_component == "members" && !empty($transect)) { // If the component is "members", the transect must either contain no tokens (show all users on site), // or the first token in the transect must be a valid user name (show single user) $user_name = array_shift($transect); // Switch the user_id based on compatibility mode if (bp_is_username_compatibility_mode()) { $user_id = (int) bp_core_get_userid(urldecode($user_name)); } else { $user_id = (int) bp_core_get_userid_from_nicename(urldecode($user_name)); } // CASE 1: Token in first transect position isn't a valid user_id // --------------------------------------------------------------------------------------- if (empty($user_id)) { $this->bp->current_component = null; // Prevent components from loading their templates bp_do_404(); $status = array('numeric' => 7, 'text' => "Match on members component, but user_id is not valid.", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); return false; } elseif (!empty($user_id)) { $this->bp->displayed_user->id = $user_id; // CASE 2: Token in first transect position matches a user_id that // has been marked as a spammer // --------------------------------------------------------------------------------------- if (bp_core_is_user_spammer($user_id)) { if (is_super_admin()) { bp_core_add_message(__('This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress'), 'error'); } else { // If the user viewing the profile is not a super-admin, hide the page bp_do_404(); $status = array('numeric' => 8, 'text' => "Match on members component, but user_id is marked as a spammer and viewer is not a super-admin.", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); return false; } } elseif (count($transect) > 0) { $current_component_slug = array_shift($transect); // CASE 3A: Match against the "primary" components that can exist both as a top-level // page and a secondary page nested beneath the "members" component. External plugins // following the "BuddyPress Example Component" pattern will appear in this array. // // TODO: This creates a cardinality problem. Primary components will appear at // both "example.com/members/membername/slug_name" and "example.com/slug_name". This // is further complicated by the fact that some components use the alias location as a // *context*, for example, "activity" at the root node shows activity for all users on // the site, but "activity" nested in the "members" component shows activity for a user. // There needs to be a set of configuration options on the admin back-end to specify // which location to use for a given component. Note that this is a legacy problem with // the original BP router design and we have emulated it for compatibility. // --------------------------------------------------------------------------------------- try { $this->bp->current_component = self::getPrimaryComponentName($current_component_slug); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Error fetching primary component name", 'data' => array("current_component_slug" => $current_component_slug), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($this->bp->current_component != null) { $status = array('numeric' => 9, 'text' => "Match on members component with primary nested component", 'data' => array('bp_pages' => $this->bp->pages, 'active_components' => $this->bp->active_components, 'current_component_slug' => $current_component_slug, "component" => $this->bp->current_component), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; } else { // CASE 3B: Match against the "secondary" components that can only exist as a secondary // page nested beneath the "members" component. Matching is determined by the component's // action functions, which hook on the 'bp_init' action. Action functions are located // in "/component_name/bp-component_name-actions.php". // --------------------------------------------------------------------------------------- $this->bp->current_component = $current_component_slug; $status = array('numeric' => 10, 'text' => "Match on members component, with possible match on secondary nested component", 'data' => array('bp_pages' => $this->bp->pages, 'active_components' => $this->bp->active_components, 'current_component_slug' => $current_component_slug), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; } } else { $this->bp->current_component = $this->bp->default_component; $status = array('numeric' => 11, 'text' => "Match on members component with no nested component", 'data' => array("component" => $this->bp->current_component), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__); $route_found = true; } } } // Set BP's global variables // ==================================================================== if (isset($transect[0])) { $this->bp->current_action = array_shift($transect); if (count($transect) > 0) { $this->bp->action_variables = $transect; } } // Set WP's global variables // ==================================================================== // Set WP's internal query variables to the same state they would be in if // WP had loaded the page itself instead of BP intercepting the page load // and replacing it with our own content // TODO: We've emulated this for compatibility. BP should try to avoid // doing this unless actually necessary, because it costs an extra query on // each page load. $this->wp_query->queried_object_id = $this->intersect["endpoint_id"]; $this->wp_query->queried_object =& get_post($this->intersect["endpoint_id"]); return true; }
/** * Output the markup for the message recipient tabs. */ function bp_message_get_recipient_tabs() { $recipients = explode(' ', bp_get_message_get_recipient_usernames()); foreach ($recipients as $recipient) { $user_id = bp_is_username_compatibility_mode() ? bp_core_get_userid($recipient) : bp_core_get_userid_from_nicename($recipient); if (!empty($user_id)) { ?> <li id="un-<?php echo esc_attr($recipient); ?> " class="friend-tab"> <span><?php echo bp_core_fetch_avatar(array('item_id' => $user_id, 'type' => 'thumb', 'width' => 15, 'height' => 15)); echo bp_core_get_userlink($user_id); ?> </span> </li> <?php } } }
/** * Analyze the URI and break it down into BuddyPress-usable chunks. * * BuddyPress can use complete custom friendly URIs without the user having to * add new rewrite rules. Custom components are able to use their own custom * URI structures with very little work. * * The URIs are broken down as follows: * - http:// example.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * - OUTSIDE ROOT: http:// example.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * * Example: * - http://example.com/members/andy/profile/edit/group/5/ * - $bp->current_component: string 'xprofile' * - $bp->current_action: string 'edit' * - $bp->action_variables: array ['group', 5] * * @since 1.0.0 */ function bp_core_set_uri_globals() { global $current_blog, $wp_rewrite; // Don't catch URIs on non-root blogs unless multiblog mode is on. if (!bp_is_root_blog() && !bp_is_multiblog_mode()) { return false; } $bp = buddypress(); // Define local variables. $root_profile = $match = false; $key_slugs = $matches = $uri_chunks = array(); // Fetch all the WP page names for each component. if (empty($bp->pages)) { $bp->pages = bp_core_get_directory_pages(); } // Ajax or not? if (defined('DOING_AJAX') && DOING_AJAX || strpos($_SERVER['REQUEST_URI'], 'wp-load.php')) { $path = bp_get_referer_path(); } else { $path = esc_url($_SERVER['REQUEST_URI']); } /** * Filters the BuddyPress global URI path. * * @since 1.0.0 * * @param string $path Path to set. */ $path = apply_filters('bp_uri', $path); // Take GET variables off the URL to avoid problems. $path = strtok($path, '?'); // Fetch current URI and explode each part separated by '/' into an array. $bp_uri = explode('/', $path); // Loop and remove empties. foreach ((array) $bp_uri as $key => $uri_chunk) { if (empty($bp_uri[$key])) { unset($bp_uri[$key]); } } // If running off blog other than root, any subdirectory names must be // removed from $bp_uri. This includes two cases: // // 1. when WP is installed in a subdirectory, // 2. when BP is running on secondary blog of a subdirectory // multisite installation. Phew! if (is_multisite() && !is_subdomain_install() && (bp_is_multiblog_mode() || 1 != bp_get_root_blog_id())) { // Blow chunks. $chunks = explode('/', $current_blog->path); // If chunks exist... if (!empty($chunks)) { // ...loop through them... foreach ($chunks as $key => $chunk) { $bkey = array_search($chunk, $bp_uri); // ...and unset offending keys if (false !== $bkey) { unset($bp_uri[$bkey]); } $bp_uri = array_values($bp_uri); } } } // Get site path items. $paths = explode('/', bp_core_get_site_path()); // Take empties off the end of path. if (empty($paths[count($paths) - 1])) { array_pop($paths); } // Take empties off the start of path. if (empty($paths[0])) { array_shift($paths); } // Reset indexes. $bp_uri = array_values($bp_uri); $paths = array_values($paths); // Unset URI indices if they intersect with the paths. foreach ((array) $bp_uri as $key => $uri_chunk) { if (isset($paths[$key]) && $uri_chunk == $paths[$key]) { unset($bp_uri[$key]); } } // Reset the keys by merging with an empty array. $bp_uri = array_merge(array(), $bp_uri); // If a component is set to the front page, force its name into $bp_uri // so that $current_component is populated (unless a specific WP post is being requested // via a URL parameter, usually signifying Preview mode). if ('page' == get_option('show_on_front') && get_option('page_on_front') && empty($bp_uri) && empty($_GET['p']) && empty($_GET['page_id'])) { $post = get_post(get_option('page_on_front')); if (!empty($post)) { $bp_uri[0] = $post->post_name; } } // Keep the unfiltered URI safe. $bp->unfiltered_uri = $bp_uri; // Don't use $bp_unfiltered_uri, this is only for backpat with old plugins. Use $bp->unfiltered_uri. $GLOBALS['bp_unfiltered_uri'] =& $bp->unfiltered_uri; // Get slugs of pages into array. foreach ((array) $bp->pages as $page_key => $bp_page) { $key_slugs[$page_key] = trailingslashit('/' . $bp_page->slug); } // Bail if keyslugs are empty, as BP is not setup correct. if (empty($key_slugs)) { return; } // Loop through page slugs and look for exact match to path. foreach ($key_slugs as $key => $slug) { if ($slug == $path) { $match = $bp->pages->{$key}; $match->key = $key; $matches[] = 1; break; } } // No exact match, so look for partials. if (empty($match)) { // Loop through each page in the $bp->pages global. foreach ((array) $bp->pages as $page_key => $bp_page) { // Look for a match (check members first). if (in_array($bp_page->name, (array) $bp_uri)) { // Match found, now match the slug to make sure. $uri_chunks = explode('/', $bp_page->slug); // Loop through uri_chunks. foreach ((array) $uri_chunks as $key => $uri_chunk) { // Make sure chunk is in the correct position. if (!empty($bp_uri[$key]) && $bp_uri[$key] == $uri_chunk) { $matches[] = 1; // No match. } else { $matches[] = 0; } } // Have a match. if (!in_array(0, (array) $matches)) { $match = $bp_page; $match->key = $page_key; break; } // Unset matches. unset($matches); } // Unset uri chunks. unset($uri_chunks); } } // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above. if (empty($matches) && bp_core_enable_root_profiles()) { // Switch field based on compat. $field = bp_is_username_compatibility_mode() ? 'login' : 'slug'; // Make sure there's a user corresponding to $bp_uri[0]. if (!empty($bp->pages->members) && !empty($bp_uri[0]) && ($root_profile = get_user_by($field, $bp_uri[0]))) { // Force BP to recognize that this is a members page. $matches[] = 1; $match = $bp->pages->members; $match->key = 'members'; } } // Search doesn't have an associated page, so we check for it separately. if (!empty($bp_uri[0]) && bp_get_search_slug() == $bp_uri[0]) { $matches[] = 1; $match = new stdClass(); $match->key = 'search'; $match->slug = bp_get_search_slug(); } // This is not a BuddyPress page, so just return. if (empty($matches)) { return false; } $wp_rewrite->use_verbose_page_rules = false; // Find the offset. With $root_profile set, we fudge the offset down so later parsing works. $slug = !empty($match) ? explode('/', $match->slug) : ''; $uri_offset = empty($root_profile) ? 0 : -1; // Rejig the offset. if (!empty($slug) && 1 < count($slug)) { // Only offset if not on a root profile. Fixes issue when Members page is nested. if (false === $root_profile) { array_pop($slug); $uri_offset = count($slug); } } // Global the unfiltered offset to use in bp_core_load_template(). // To avoid PHP warnings in bp_core_load_template(), it must always be >= 0. $bp->unfiltered_uri_offset = $uri_offset >= 0 ? $uri_offset : 0; // We have an exact match. if (isset($match->key)) { // Set current component to matched key. $bp->current_component = $match->key; // If members component, do more work to find the actual component. if ('members' == $match->key) { $after_member_slug = false; if (!empty($bp_uri[$uri_offset + 1])) { $after_member_slug = $bp_uri[$uri_offset + 1]; } // Are we viewing a specific user? if ($after_member_slug) { // If root profile, we've already queried for the user. if ($root_profile instanceof WP_User) { $bp->displayed_user->id = $root_profile->ID; // Switch the displayed_user based on compatibility mode. } elseif (bp_is_username_compatibility_mode()) { $bp->displayed_user->id = (int) bp_core_get_userid(urldecode($after_member_slug)); } else { $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename($after_member_slug); } } // Is this a member type directory? if (!bp_displayed_user_id() && $after_member_slug === apply_filters('bp_members_member_type_base', _x('type', 'member type URL base', 'buddypress')) && !empty($bp_uri[$uri_offset + 2])) { $matched_types = bp_get_member_types(array('has_directory' => true, 'directory_slug' => $bp_uri[$uri_offset + 2])); if (!empty($matched_types)) { $bp->current_member_type = reset($matched_types); unset($bp_uri[$uri_offset + 1]); } } // If the slug matches neither a member type nor a specific member, 404. if (!bp_displayed_user_id() && !bp_get_current_member_type() && $after_member_slug) { // Prevent components from loading their templates. $bp->current_component = ''; bp_do_404(); return; } // If the displayed user is marked as a spammer, 404 (unless logged-in user is a super admin). if (bp_displayed_user_id() && bp_is_user_spammer(bp_displayed_user_id())) { if (bp_current_user_can('bp_moderate')) { bp_core_add_message(__('This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress'), 'warning'); } else { bp_do_404(); return; } } // Bump the offset. if (bp_displayed_user_id()) { if (isset($bp_uri[$uri_offset + 2])) { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = $bp_uri[0]; // No component, so default will be picked later. } else { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = ''; } // Reset the offset. $uri_offset = 0; } } } // Determine the current action. $current_action = isset($bp_uri[$uri_offset + 1]) ? $bp_uri[$uri_offset + 1] : ''; /* * If a BuddyPress directory is set to the WP front page, URLs like example.com/members/?s=foo * shouldn't interfere with blog searches. */ if (empty($current_action) && !empty($_GET['s']) && 'page' == get_option('show_on_front') && !empty($match->id)) { $page_on_front = (int) get_option('page_on_front'); if ((int) $match->id === $page_on_front) { $bp->current_component = ''; return false; } } $bp->current_action = $current_action; // Slice the rest of the $bp_uri array and reset offset. $bp_uri = array_slice($bp_uri, $uri_offset + 2); $uri_offset = 0; // Set the entire URI as the action variables, we will unset the current_component and action in a second. $bp->action_variables = $bp_uri; // Reset the keys by merging with an empty array. $bp->action_variables = array_merge(array(), $bp->action_variables); }
/** * Analyzes the URI structure and breaks it down into parts for use in code. * The idea is that BuddyPress can use complete custom friendly URI's without the * user having to add new re-write rules. * * Future custom components would then be able to use their own custom URI structure. * * @package BuddyPress Core * @since BuddyPress (r100) * * The URI's are broken down as follows: * - http:// domain.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * - OUTSIDE ROOT: http:// domain.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * * Example: * - http://domain.com/members/andy/profile/edit/group/5/ * - $bp->current_component: string 'xprofile' * - $bp->current_action: string 'edit' * - $bp->action_variables: array ['group', 5] * */ function bp_core_set_uri_globals() { global $bp, $bp_unfiltered_uri, $bp_unfiltered_uri_offset; global $current_blog, $nxtdb; // Create global component, action, and item variables $bp->current_component = $bp->current_action = $bp->current_item = ''; $bp->action_variables = $bp->displayed_user->id = ''; // Don't catch URIs on non-root blogs unless multiblog mode is on if (!bp_is_root_blog() && !bp_is_multiblog_mode()) { return false; } // Fetch all the nxt page names for each component if (empty($bp->pages)) { $bp->pages = bp_core_get_directory_pages(); } // Ajax or not? if (strpos($_SERVER['REQUEST_URI'], 'nxt-load.php')) { $path = bp_core_referrer(); } else { $path = esc_url($_SERVER['REQUEST_URI']); } // Filter the path $path = apply_filters('bp_uri', $path); // Take GET variables off the URL to avoid problems, // they are still registered in the global $_GET variable if ($noget = substr($path, 0, strpos($path, '?'))) { $path = $noget; } // Fetch the current URI and explode each part separated by '/' into an array $bp_uri = explode('/', $path); // Loop and remove empties foreach ((array) $bp_uri as $key => $uri_chunk) { if (empty($bp_uri[$key])) { unset($bp_uri[$key]); } } // Running off blog other than root if (is_multisite() && !is_subdomain_install() && (bp_is_multiblog_mode() || 1 != bp_get_root_blog_id())) { // Any subdirectory names must be removed from $bp_uri. // This includes two cases: (1) when nxt is installed in a subdirectory, // and (2) when BP is running on secondary blog of a subdirectory // multisite installation. Phew! if ($chunks = explode('/', $current_blog->path)) { foreach ($chunks as $key => $chunk) { $bkey = array_search($chunk, $bp_uri); if ($bkey !== false) { unset($bp_uri[$bkey]); } $bp_uri = array_values($bp_uri); } } } // Set the indexes, these are incresed by one if we are not on a VHOST install $component_index = 0; $action_index = $component_index + 1; // Get site path items $paths = explode('/', bp_core_get_site_path()); // Take empties off the end of path if (empty($paths[count($paths) - 1])) { array_pop($paths); } // Take empties off the start of path if (empty($paths[0])) { array_shift($paths); } // Unset URI indices if they intersect with the paths foreach ((array) $bp_uri as $key => $uri_chunk) { if (in_array($uri_chunk, $paths)) { unset($bp_uri[$key]); } } // Reset the keys by merging with an empty array $bp_uri = array_merge(array(), $bp_uri); // If a component is set to the front page, force its name into $bp_uri // so that $current_component is populated (unless a specific nxt post is being requested // via a URL parameter, usually signifying Preview mode) if ('page' == get_option('show_on_front') && get_option('page_on_front') && empty($bp_uri) && empty($_GET['p']) && empty($_GET['page_id'])) { $post = get_post(get_option('page_on_front')); if (!empty($post)) { $bp_uri[0] = $post->post_name; } } // Keep the unfiltered URI safe $bp_unfiltered_uri = $bp_uri; // Get slugs of pages into array foreach ((array) $bp->pages as $page_key => $bp_page) { $key_slugs[$page_key] = trailingslashit('/' . $bp_page->slug); } // Bail if keyslugs are empty, as BP is not setup correct if (empty($key_slugs)) { return; } // Loop through page slugs and look for exact match to path foreach ($key_slugs as $key => $slug) { if ($slug == $path) { $match = $bp->pages->{$key}; $match->key = $key; $matches[] = 1; break; } } // No exact match, so look for partials if (empty($match)) { // Loop through each page in the $bp->pages global foreach ((array) $bp->pages as $page_key => $bp_page) { // Look for a match (check members first) if (in_array($bp_page->name, (array) $bp_uri)) { // Match found, now match the slug to make sure. $uri_chunks = explode('/', $bp_page->slug); // Loop through uri_chunks foreach ((array) $uri_chunks as $key => $uri_chunk) { // Make sure chunk is in the correct position if (!empty($bp_uri[$key]) && $bp_uri[$key] == $uri_chunk) { $matches[] = 1; // No match } else { $matches[] = 0; } } // Have a match if (!in_array(0, (array) $matches)) { $match = $bp_page; $match->key = $page_key; break; } // Unset matches unset($matches); } // Unset uri chunks unset($uri_chunks); } } // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above if (empty($matches) && defined('BP_ENABLE_ROOT_PROFILES') && BP_ENABLE_ROOT_PROFILES) { // Make sure there's a user corresponding to $bp_uri[0] if (!empty($bp->pages->members) && !empty($bp_uri[0]) && ($root_profile = get_user_by('login', $bp_uri[0]))) { // Force BP to recognize that this is a members page $matches[] = 1; $match = $bp->pages->members; $match->key = 'members'; // Without the 'members' URL chunk, NXTClass won't know which page to load // This filter intercepts the nxt query and tells it to load the members page add_filter('request', create_function('$query_args', '$query_args["pagename"] = "' . $match->name . '"; return $query_args;')); } } // Search doesn't have an associated page, so we check for it separately if (!empty($bp_uri[0]) && bp_get_search_slug() == $bp_uri[0]) { $matches[] = 1; $match = new stdClass(); $match->key = 'search'; $match->slug = bp_get_search_slug(); } // This is not a BuddyPress page, so just return. if (!isset($matches)) { return false; } // Find the offset. With $root_profile set, we fudge the offset down so later parsing works $slug = !empty($match) ? explode('/', $match->slug) : ''; $uri_offset = empty($root_profile) ? 0 : -1; // Rejig the offset if (!empty($slug) && 1 < count($slug)) { array_pop($slug); $uri_offset = count($slug); } // Global the unfiltered offset to use in bp_core_load_template(). // To avoid PHP warnings in bp_core_load_template(), it must always be >= 0 $bp_unfiltered_uri_offset = $uri_offset >= 0 ? $uri_offset : 0; // We have an exact match if (isset($match->key)) { // Set current component to matched key $bp->current_component = $match->key; // If members component, do more work to find the actual component if ('members' == $match->key) { // Viewing a specific user if (!empty($bp_uri[$uri_offset + 1])) { // Switch the displayed_user based on compatbility mode if (bp_is_username_compatibility_mode()) { $bp->displayed_user->id = (int) bp_core_get_userid(urldecode($bp_uri[$uri_offset + 1])); } else { $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename(urldecode($bp_uri[$uri_offset + 1])); } if (empty($bp->displayed_user->id)) { // Prevent components from loading their templates $bp->current_component = ''; bp_do_404(); return; } // If the displayed user is marked as a spammer, 404 (unless logged- // in user is a super admin) if (!empty($bp->displayed_user->id) && bp_core_is_user_spammer($bp->displayed_user->id)) { if (is_super_admin()) { bp_core_add_message(__('This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress'), 'error'); } else { bp_do_404(); return; } } // Bump the offset if (isset($bp_uri[$uri_offset + 2])) { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = $bp_uri[0]; // No component, so default will be picked later } else { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = ''; } // Reset the offset $uri_offset = 0; } } } // Set the current action $bp->current_action = isset($bp_uri[$uri_offset + 1]) ? $bp_uri[$uri_offset + 1] : ''; // Slice the rest of the $bp_uri array and reset offset $bp_uri = array_slice($bp_uri, $uri_offset + 2); $uri_offset = 0; // Set the entire URI as the action variables, we will unset the current_component and action in a second $bp->action_variables = $bp_uri; // Remove the username from action variables if this is not a VHOST install // @todo - move or remove this all together if (defined('VHOST') && 'no' == VHOST && empty($bp->current_component)) { array_shift($bp_uri); } // Reset the keys by merging with an empty array $bp->action_variables = array_merge(array(), $bp->action_variables); }
/** * Get a user ID from a "mentionname", the name used for a user in @-mentions. * * @since BuddyPress (1.9.0) * * @return int|bool ID of the user, if one is found. Otherwise false. */ function bp_activity_get_userid_from_mentionname($mentionname) { $user_id = false; // In username compatibility mode, hyphens are ambiguous between // actual hyphens and converted spaces. // // @todo There is the potential for username clashes between 'foo bar' // and 'foo-bar' in compatibility mode. Come up with a system for // unique mentionnames. if (bp_is_username_compatibility_mode()) { // First, try the raw username $userdata = get_user_by('login', $mentionname); // Doing a direct query to use proper regex. Necessary to // account for hyphens + spaces in the same user_login. if (empty($userdata) || !is_a($userdata, 'WP_User')) { global $wpdb; $regex = esc_sql(str_replace('-', '[ \\-]', $mentionname)); $user_id = $wpdb->get_var("SELECT ID FROM {$wpdb->users} WHERE user_login REGEXP '{$regex}'"); } else { $user_id = $userdata->ID; } // When username compatibility mode is disabled, the mentionname is // the same as the nicename } else { $user_id = bp_core_get_userid_from_nicename($mentionname); } return $user_id; }
/** * AJAX handler for autocomplete. * * Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined. * * @since BuddyPress (1.2.0) * * @return string HTML. */ function bp_legacy_theme_ajax_messages_autocomplete_results() { // Include everyone in the autocomplete, or just friends? if (bp_is_current_component(bp_get_messages_slug())) { $autocomplete_all = buddypress()->messages->autocomplete_all; } $pag_page = 1; $limit = (int) $_GET['limit'] ? $_GET['limit'] : apply_filters('bp_autocomplete_max_results', 10); $search_terms = isset($_GET['q']) ? $_GET['q'] : ''; $user_query_args = array('search_terms' => $search_terms, 'page' => intval($pag_page), 'per_page' => intval($limit)); // If only matching against friends, get an $include param for // BP_User_Query if (!$autocomplete_all && bp_is_active('friends')) { $include = BP_Friends_Friendship::get_friend_user_ids(bp_loggedin_user_id()); // Ensure zero matches if no friends are found if (empty($include)) { $include = array(0); } $user_query_args['include'] = $include; } $user_query = new BP_User_Query($user_query_args); // Backward compatibility - if a plugin is expecting a legacy // filter, pass the IDs through the filter and requery (groan) if (has_filter('bp_core_autocomplete_ids') || has_filter('bp_friends_autocomplete_ids')) { $found_user_ids = wp_list_pluck($user_query->results, 'ID'); if ($autocomplete_all) { $found_user_ids = apply_filters('bp_core_autocomplete_ids', $found_user_ids); } else { $found_user_ids = apply_filters('bp_friends_autocomplete_ids', $found_user_ids); } if (empty($found_user_ids)) { $found_user_ids = array(0); } // Repopulate the $user_query variable $user_query = new BP_User_Query(array('include' => $found_user_ids)); } if (!empty($user_query->results)) { foreach ($user_query->results as $user) { if (bp_is_username_compatibility_mode()) { // Sanitize for spaces. Use urlencode() rather // than rawurlencode() because %20 breaks JS $username = urlencode($user->user_login); } else { $username = $user->user_nicename; } // Note that the final line break acts as a delimiter for the // autocomplete javascript and thus should not be removed echo '<span id="link-' . esc_attr($username) . '" href="' . bp_core_get_user_domain($user->ID) . '"></span>' . bp_core_fetch_avatar(array('item_id' => $user->ID, 'type' => 'thumb', 'width' => 15, 'height' => 15, 'alt' => $user->display_name)) . ' ' . bp_core_get_user_displayname($user->ID) . ' (' . esc_html($username) . ')' . "\n"; } } exit; }
/** * Get user domain. * * Do not use this outside of digests! * * This is almost a duplicate of bp_core_get_user_domain(), but references * our already-fetched mass-userdata array to avoid pinging the DB over and * over again in a foreach loop. */ function ass_digest_get_user_domain($user_id) { global $bp; if (empty($bp->ass->massdata)) { return false; } $mass_userdata = $bp->ass->massdata; $username = bp_is_username_compatibility_mode() ? $mass_userdata[$user_id]['user_login'] : $mass_userdata[$user_id]['user_nicename']; if (bp_core_enable_root_profiles()) { $after_domain = $username; } else { $after_domain = bp_get_members_root_slug() . '/'; $after_domain .= bp_is_username_compatibility_mode() ? rawurlencode($username) : $username; } $domain = trailingslashit(bp_get_root_domain() . '/' . $after_domain); $domain = apply_filters('bp_core_get_user_domain_pre_cache', $domain, $user_id, $mass_userdata[$user_id]['user_nicename'], $mass_userdata[$user_id]['user_login']); return apply_filters('bp_core_get_user_domain', $domain, $user_id, $mass_userdata[$user_id]['user_nicename'], $mass_userdata[$user_id]['user_login']); }
/** * Strips spaces from usernames that are created using add_user() and wp_insert_user() * * @package BuddyPress Core */ function bp_core_strip_username_spaces($username) { // Don't alter the user_login of existing users, as it causes user_nicename problems. // See http://trac.buddypress.org/ticket/2642 if (username_exists($username) && !bp_is_username_compatibility_mode()) { return $username; } return str_replace(' ', '-', $username); }
/** * AJAX handler for autocomplete. Displays friends only, unless BP_MESSAGES_AUTOCOMPLETE_ALL is defined. * * @return string HTML * @since BuddyPress (1.2) */ function bp_dtheme_ajax_messages_autocomplete_results() { // Include everyone in the autocomplete, or just friends? if (bp_is_current_component(bp_get_messages_slug())) { $autocomplete_all = buddypress()->messages->autocomplete_all; } $pag_page = 1; $limit = (int) $_GET['limit'] ? $_GET['limit'] : apply_filters('bp_autocomplete_max_results', 10); // Get the user ids based on the search terms if (!empty($autocomplete_all)) { $users = BP_Core_User::search_users($_GET['q'], $limit, $pag_page); if (!empty($users['users'])) { // Build an array with the correct format $user_ids = array(); foreach ($users['users'] as $user) { if ($user->id != bp_loggedin_user_id()) { $user_ids[] = $user->id; } } $user_ids = apply_filters('bp_core_autocomplete_ids', $user_ids, $_GET['q'], $limit); } } else { if (bp_is_active('friends')) { $users = friends_search_friends($_GET['q'], bp_loggedin_user_id(), $limit, 1); // Keeping the bp_friends_autocomplete_list filter for backward compatibility $users = apply_filters('bp_friends_autocomplete_list', $users, $_GET['q'], $limit); if (!empty($users['friends'])) { $user_ids = apply_filters('bp_friends_autocomplete_ids', $users['friends'], $_GET['q'], $limit); } } } if (!empty($user_ids)) { foreach ($user_ids as $user_id) { $ud = get_userdata($user_id); if (!$ud) { continue; } if (bp_is_username_compatibility_mode()) { $username = $ud->user_login; } else { $username = $ud->user_nicename; } // Note that the final line break acts as a delimiter for the // autocomplete javascript and thus should not be removed echo '<span id="link-' . esc_attr($username) . '" href="' . bp_core_get_user_domain($user_id) . '"></span>' . bp_core_fetch_avatar(array('item_id' => $user_id, 'type' => 'thumb', 'width' => 15, 'height' => 15, 'alt' => $ud->display_name)) . ' ' . bp_core_get_user_displayname($user_id) . ' (' . esc_html($username) . ')' . "\n"; } } exit; }
/** * This will save wall related data to the activity meta table when a new wall post happens * * @since BuddyBoss 2.0 */ function wall_input_filter(&$activity) { global $bp, $buddy_boss_wall; $user = $bp->loggedin_user; $tgt = $bp->displayed_user; $new_action = false; // If we're on an activity page (user's own profile or a friends), check for a target ID if ($bp->current_action == 'just-me' && (!isset($tgt->id) || $tgt->id == 0)) { return; } // It's either an @ mention, status update, or forum post. if ($bp->current_action == 'just-me' && $user->id == $tgt->id || $bp->current_action == 'forum') { if (!empty($activity->content)) { $mentioned = bp_activity_find_mentions($activity->content); $uids = array(); $usernames = array(); // Get all the mentions and store valid usernames in a new array foreach ((array) $mentioned as $mention) { if (bp_is_username_compatibility_mode()) { $user_id = username_exists($mention); } else { $user_id = bp_core_get_userid_from_nicename($mention); } if (empty($user_id)) { continue; } $uids[] = $user_id; $usernames[] = $mention; } $len = count($uids); $mentions_action = ''; // It's mentioning one person if ($len == 1) { $user_id = $tgt = bp_core_get_core_userdata((int) $uids[0]); $user_url = '<a href="' . $user->domain . '">' . $user->fullname . '</a>'; $tgt_url = '<a href="' . bp_core_get_userlink($uids[0], false, true) . '">@' . $tgt->user_login . '</a>'; $mentions_action = " " . __('mentioned', 'buddyboss') . " " . $tgt_url; } elseif ($len > 1) { $user_url = '<a href="' . $user->domain . '">' . $user->fullname . '</a>'; $un = '@' . join(',@', $usernames); $mentions_action = $user_url . " " . __('mentioned', 'buddyboss') . " " . $len . " " . __('people', 'buddyboss'); } // If it's a forum post let's define some forum topic text if ($bp->current_action == 'forum') { $new_action = str_replace(' replied to the forum topic', $mentions_action . ' in the forum topic', $activity->action); } elseif ($len > 0) { $new_action = $user_url . " " . $mentions_action . ' ' . __('in a public message', 'buddyboss'); } else { $new_action = false; } } } elseif ($bp->current_action == 'just-me' && $user->id != $tgt->id) { $user_url = '<a href="' . $user->domain . '">' . $user->fullname . '</a>'; $tgt_url = '<a href="' . $tgt->domain . '">' . $tgt->fullname . '\'s</a>'; // if a user is on his own page it is an update $new_action = sprintf(__('%s wrote on %s Wall', 'buddyboss'), $user_url, $tgt_url); } if ($new_action) { bp_activity_update_meta($activity->id, 'bboss_wall_action', $new_action); } }