Hook: mam_user_directory_search (find an app user)

Purpose

Lets any MAM plugin offer a “find a person on the app” picker (add staff, invite a friend, share with someone) without writing its own user query. mam-main owns the privacy rules, so every feature that searches people follows the same ones.


Calling it

// Function form.
$items = mam_user_directory_search( $term, $context, $viewer_id );

// Filter form (use this from sibling plugins, it degrades to the default when mam-main is older).
$items = apply_filters( 'mam_user_directory_search', array(), $term, $context, $viewer_id );
Parameter Type Description
$term string What the person typed.
$context array Anything the caller wants passed to the filters, e.g. array( 'purpose' => 'gd_staff', 'post_id' => 123 ).
$viewer_id int WP user ID of the person searching. 0 or null means the current app user.

Returns a list of at most 20 items:

[ { "text": "Jane Doe", "value": "1134", "image": "https://.../avatar-150x150.png" } ]
Key Type Meaning
text string The person’s name (first + last, else display name, else nickname). Never an email address.
value string The person’s app_user post ID.
image string The app avatar (_user_avatar) URL, or "". Gravatar is not used.

This is the shape the app pickers read from a data array, so a picker endpoint can return array( 'data' => $items ) as is.


Matching rules

  • Name and login: prefix match on first name, last name, “first last”, display name, and login. At least 2 characters. Logins and display names that look like an email are never prefix matched.
  • Email: exact match only (case does not matter). Anything containing @ that is not a full, exact address returns nothing.
  • Phone: exact match on the last 10 digits of billing_phone, after removing spaces, dashes, dots, brackets, and +. Digits never prefix match names.

Always left out:

  • the viewer,
  • invited placeholder accounts (the invited role or invited user meta),
  • anyone the viewer has blocked in chat, or who has blocked the viewer (mam_chat_blocked_users),
  • on multisite, users who are not members of the current site,
  • any ID returned by mam_user_search_exclude.

Anonymous viewers get an empty list. Each viewer may run 30 searches per minute; past that the list is empty until the window passes.

Older accounts without an app_user record get one created on first match (through mam_get_user_post_id), so value is always a real app_user ID.


Filter: mam_user_search_exclude

Add WP user IDs that must never be found, for example people who opted out.

add_filter( 'mam_user_search_exclude', function ( array $ids, string $term, array $context, int $viewer_id ): array {
    $opted_out = get_users( array( 'meta_key' => 'my_plugin_hide_from_search', 'meta_value' => '1', 'fields' => 'ID' ) );
    return array_merge( $ids, array_map( 'intval', $opted_out ) );
}, 10, 4 );

Filter: mam_user_search_results

Change or trim the final list. Keep every value a string; the apps read these keys as strings.

add_filter( 'mam_user_search_results', function ( array $items, string $term, array $context, int $viewer_id ): array {
    if ( ( $context['purpose'] ?? '' ) !== 'my_feature' ) {
        return $items;
    }
    return array_slice( $items, 0, 10 );
}, 10, 4 );

Wiring a picker to it

Picker searches arrive at mam_main_ajax with subaction=mam_api_picker_search, formid, and search. Several plugins answer that subaction for their own forms, so:

  • hook the mam_main_ajax filter at a priority below 10,
  • act only when the subaction is mam_api_picker_search AND formid is your form,
  • send wp_send_json( array( 'data' => $items ) ) and stop; otherwise return the value untouched.

Never add_action( 'mam_api_picker_search', ... ): the hub then dispatches that action and skips the mam_main_ajax filter for every plugin’s picker. See Form: Add or remove staff and managers (mam-geodirectory) for a working example.


Verification

  • Source: includes/user-roles/class-mam-user-directory.php (MAM_User_Directory::search())
  • Registration: mam-main.php, register_app_users()

  • Hook: mam_app_user_invite_accepted (invite lifecycle)
  • Form: Add or remove staff and managers (mam-geodirectory)

Metadata

Field Value
Article type Hook Reference
Plugin slug mam-main
Applies to plugin version 26.40.6+
Category Extending MAM Suite
Hook type filter (plus a PHP function)
Audience PHP developer / integrator
Last verified 2026-10-01
Was this article helpful?
Contents

    Need Support?

    Can't find the answer you're looking for? Don't worry we're here to help!