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
invitedrole orinviteduser 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_ajaxfilter at a priority below 10, - act only when the subaction is
mam_api_picker_searchANDformidis 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()
Related articles
- 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 |
