Summary
Per-phase reference for the four pipeline phases. Each phase is a method on MAM_Phone_Data_Pipeline that mutates the MAM_Phone_Data_Context. Sibling plugins extend the pipeline through hooks fired at well-known points; the most-used hook (mam_get_phone_data_before_send) fires at the content-phase boundary.
phase_auth
Purpose: Resolve identity, hydrate MAM_Current_Request.
Reads:
$_REQUESTfor the auth nonce, user id, role hint- WP
wp_get_current_user() MAM_Current_Requestsetup
Writes to context:
user_id,user_role,is_cloning,is_app_request
Hooks fired: None at this phase boundary.
Default subscriber (priority 10 in the legacy filter, runs as part of this phase): mam_user_roles_manager::manage_phone_data.
After this phase the rest of the pipeline can rely on mam_current_request() being correctly populated.
phase_settings
Purpose: Load app settings, evaluate cache decisions, check the short-circuit hook.
Reads:
mam_app_settings_get_setting('no', $role, 'general-settings', 'tsl-setting-disable_caching')— controls cursor resetmam_main_allow_cache_json_elements— global cache flagmam_main_json_debug— debug enable
Writes to context:
bypass_cachingflag- Settings cache, theme/branding base data
Hooks fired:
mam_local_app_data(short-circuit) — if any subscriber returns a non-empty array, the pipeline returns it immediately. Frozen contract.
Default subscriber: mam_app_settings::manage_phone_data (priority 1) — base theme + branding settings.
phase_content
Purpose: Build page/button/section data; let sibling plugins inject; build navigation; resolve forms.
Sub-steps (in order):
- Button loop — for each button in the role’s button array, resolve the content class and call
get_data_for_app($category). The result is merged into the response. - Per-button enrichment —
apply_filters('mam_app_settings_get_buttons', ...)then per-buttonapply_filters('mam_tab_manager', $button)(~43 subscribers) andapply_filters('mam_final_button_settings', $button). - Tab-bar dispatch — for each tab-bar setting where
visible === 'on', firesmam_main_skip_tab_bar_buttonthenmam_main_add_tab_bar_item_{slug}then the same enrichment chain. - Form data — injects the cached form definitions, the
nonce, andsync_user_meta. - Left menu —
main_create_left_menu($button_array, $data_array). - AJAX URL — injects the admin-ajax URL for the app to POST to.
- Pre-send filter — fires the legacy
mam_get_phone_data_before_sendfilter with the assembled$data_array. ~70 subscribers. - Post-pre-send check —
mam_main_check_initial_form(form-state validation).
Writes to context:
- The full
$data_arrayshape
Hooks fired:
mam_app_settings_get_buttons(read)mam_tab_manager(per-button)mam_final_button_settings(per-button)mam_main_skip_tab_bar_buttonmam_main_add_tab_bar_item_{slug}(dynamic)mam_get_phone_data_before_send— the big onemam_main_check_initial_formmam_main_check_cache_for_main_json(cache-check side effects)mam_main_iap_subscription_has_changedmam_initial_phone_data(early)add_to_tracer(perf debug)
phase_finalize
Purpose: Inject home_cats, apply final-block overrides, output-shaping cleanup.
Sub-steps:
home_catsinjection —MAM_Main_Manager::manage_phone_data(priority 1000 in the legacy filter) builds the home-screen category structure. Critical contract: must run after every priority < 1000 subscriber.- Final-block overrides — use-case priority-9999 subscribers run here for total replacement of sections.
- Output shaping:
clean_notifications($data_array)— trim notification payload to active itemsmam_clean_subcategories($json_content)— strip empty subcategoriesmam_replace_null_with_empty_string($array)— replacenullwith""(older mobile parsers rejectnullin string fields)mam_add_pn_ids()— hydrate per-user push-notification idsmam_json_validate($data_array, $line)— validate JSON before send
Writes to context: Final array passed to wp_send_json($context->to_array()).
Hooks fired: Subscribers at priority 1000+ in the legacy filter run here.
Phase boundaries — for new pipeline subscribers
The pipeline also fires phase-tagged actions for new code that wants to opt into a specific phase rather than the legacy filter:
do_action( 'mam_phone_data_phase_auth', $context );
do_action( 'mam_phone_data_phase_settings', $context );
do_action( 'mam_phone_data_phase_content', $context );
do_action( 'mam_phone_data_phase_finalize', $context );
These pass the MAM_Phone_Data_Context object directly. New plugins should prefer phase-tagged hooks over the legacy filter; the legacy filter remains fired at the content-phase boundary indefinitely as a frozen contract.
When to hook which phase
| If you want to… | Hook this |
|---|---|
| Override identity for the whole pipeline | phase_auth |
| Short-circuit and return a complete response | mam_local_app_data |
| Inject content (the common case) | mam_get_phone_data_before_send at priority 10 |
Run after the default cohort but before home_cats |
mam_get_phone_data_before_send at priority 99 |
| Validate or clean the final structure | mam_get_phone_data_before_send at priority 1001+ |
| Modify a single button’s enrichment | mam_tab_manager or mam_final_button_settings |
| Add a tab-bar item dynamically | mam_main_add_tab_bar_item_{slug} |
Gotchas
phase_settingsshort-circuit returns early. Don’t put critical setup inphase_contentand rely on it always running.- The button loop is per-item. A list of 50 listings calls every per-button filter 50 times. Cache expensive lookups inside callbacks.
mam_get_phone_data_before_sendis fired ONCE per pipeline run with the full$data_array, not per button. Per-button hooks aremam_tab_managerand friends.- Output shaping happens last. A subscriber that adds a JSON-incompatible value (a closure, a resource) won’t fail until
wp_send_json()blows up.
Related articles
- Phone data pipeline overview
- Mobile JSON shape
- Cursor cache mechanism
- Priority conventions for phone-data subscribers
- Hook: mam_get_phone_data_before_send
- Hook: mam_local_app_data
- Hook: mam_main_check_initial_form
- Hook: mam_tab_manager
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 |
