Summary
mam_forms_manager_phone_manager (includes/forms-manager/phone-manager.php) handles phone-number normalization and SMS-code-based validation. It’s nominally part of forms-manager because GF phone fields are the most common entry point, but it’s used elsewhere too — notably by mam_validate_phone_code (includes/user-roles/phone-code-validation.php) for phone-code login.
Two distinct flows
| Flow | Use case | Notification type |
|---|---|---|
| One-shot validation | Validating a phone number during form submission (registration, “verify your number”) | gf-phone-number-validation |
| Phone-code login | Authenticating a returning user via SMS code instead of password | (Issued through mam_notification_send_message with the user-roles handler) |
Both share the same SMS dispatch path through the notification dispatcher.
How one-shot validation works
User enters phone in form field
│
▼
Field is configured with validation = phone_code (per-field special handling)
│
▼
Submission triggers mam_forms_manager_phone_manager::issue_code()
│ ├─ Normalize the input (strip spaces, parens, etc.)
│ ├─ Generate a 6-digit code
│ └─ Persist (code, phone, expiry) in a transient
▼
do_action('mam_notification_send_message', [
'message_type' => 'gf-phone-number-validation',
'phone' => $normalized_phone,
'message' => '[passwordcode]', ← gets replaced with the 6-digit code
])
▼
SMS sent via MAM_Sms_Sender → Twilio (or configured provider)
▼
User enters the code in the next form step
▼
mam_forms_manager_phone_manager::verify_code() compares input to transient
Normalization
The phone manager normalizes:
- Strips non-digits except a leading
+ - Defaults to E.164 (
+15551234567) where the country code can be inferred - Uses the per-site default country (configurable in Mobile App Manager → Forms → Phone settings) when the user enters a national number with no country prefix
⚠️ International apps with mixed-locale users should explicitly require the country code in the form’s UI — auto-inference only works reliably when most submissions come from one locale.
Phone-code login
mam_validate_phone_code (includes/user-roles/phone-code-validation.php) extends the same pattern:
- User enters phone number on the login screen
- Server issues a code, persists in transient, fires
mam_notification_send_message - User enters code;
mam_validate_phone_code::verify()compares - On success, the user is logged in (or, if the phone is unrecognized, the registration flow starts)
This is enabled by the Login content class’s phone_code_enabled setting.
Hooks involved
| Hook | Type | Role |
|---|---|---|
mam_notification_send_message |
Action | Fires the SMS code |
mam_form_manager_process_field_type_phone |
Filter | Standard phone-field processor (build-time) |
SMS dispatch dependencies
- A working SMS provider configured (typically Twilio via the global
$smsobject) - A populated
tsl_notification_text_status_*(ormam_notification_text_status_*) for the notification type to enable SMS routing - The recipient must have a phone number in
usermetabilling_phone(or supplied in the request)
⚠️ Legacy global $sms. The SMS handler depends on a global Twilio object. If absent, SMS silently fails. The notification dispatcher should null-check; it currently doesn’t (tracked as a hardening item).
Gotchas
- Codes expire. The default expiry is short (a few minutes) — verify timing in the implementation if you need to extend.
- One code per phone at a time. Re-issuing a code overwrites the transient; the previous code becomes invalid.
- Don’t bypass normalization. Storing un-normalized phone numbers in
usermetacauses mismatches at lookup. - STOP-to-opt-out copy is appended automatically by the SMS sender. Don’t duplicate it in your message body.
Related articles
- Forms manager overview
- Notifications overview
- Notification channels: email, SMS, push
- Hook: mam_notification_send_message
Metadata
| Field | Value |
|---|---|
| Article type | Plugin Overview |
| Plugin slug | mam-main |
| Applies to plugin version | 2.1.11+ |
| Category | Plugin Reference |
| Audience | PHP developer |
| Last verified | 2026-05-02 |
