Hook: mam_app_settings_set_setting

Purpose

The settings-cascade write filter. Mirror of mam_app_settings_get_setting. Persists a value to the appropriate scope.


Signature

$status = apply_filters(
    'mam_app_settings_set_setting',
    $status,         // pass-through status value (returned unchanged)
    $role,           // role scope ('mam-all' for global)
    $button_id,      // button-id namespace for the setting
    $key,            // setting key
    $value           // value to persist
);

Registered by the data manager at priority 10, 5 (five args).

Parameter Type Description
$status mixed Pass-through status — returned unchanged (this filter’s “value” slot is not the written value)
$role string Role scope. Empty falls back to 'mam-all' (global).
$button_id string Button-id namespace the setting is stored under (a real button id, or a namespace sentinel like 'general-settings')
$key string Setting key
$value mixed The value to persist (the last argument, not the first)

Returns: mixed — $status echoed back unchanged. The write is a side effect; the return value is not the persisted value.


Per-scope persistence

$role value Persisted to
'' (empty) → 'mam-all' Global row (role mam-all) in the wp_mam_app_settings_options table
'subscriber', 'admin', etc. Per-role row (role column = the role)

The $button_id argument selects the button-id namespace column; every row is keyed by (button_id, role, setting_key, acct_code).


Example: write a per-role value

apply_filters(
    'mam_app_settings_set_setting',
    '',                              // status (pass-through)
    'subscriber',                    // role
    'general-settings',              // button-id namespace
    'tsl-setting-geofilter_radius',  // key
    'new value'                      // value (last arg)
);

Example: subscriber-side write hook

add_filter( 'mam_app_settings_set_setting', function ( $status, $role, $button_id, $key, $value ) {

    if ( $key !== 'my_plugin_special_value' ) {
        return $status;
    }

    // Persist to my plugin's own store.
    update_option( 'my_plugin_special_value_' . $role, $value );

    // Also invalidate a cache.
    wp_cache_delete( 'my_plugin_settings', 'mam' );

    return $status;
}, 10, 5 );

Cache invalidation responsibility

If the setting being written affects what the mobile app sees, you may need to invalidate the cursor cache:

JSON_Cursor_Manager::reset_cursor();

Or, more surgically, bump a section-specific timestamp:

update_option( 'my_plugin_data_changed_at', time() );

For form-affecting settings, also invalidate the form cache:

mam_form_manager_cache_manager::invalidate( $form_id );

Gotchas

  • Cache invalidation is your responsibility. A subscriber that persists a setting affecting mobile output must invalidate the appropriate cache.
  • Per-button writes need a button context. The data manager looks up the active button id from the request; if no button context is set, the write goes per-role or global.
  • Frozen contract. Many call sites assume the existing signature.
  • Don’t bypass with direct update_option. The filter runs the data manager’s validation + side-effect chain.

  • Settings cascade overview
  • Per-button and per-role settings
  • Cursor cache mechanism
  • Hook: mam_app_settings_get_setting
  • Frozen public contracts reference

Metadata

Field Value
Article type Hook Reference
Plugin slug mam-main
Applies to plugin version 2.1.11+
Hook type filter
Audience PHP developer
Frozen contract yes
Last verified 2026-05-02
Was this article helpful?
Contents

    Need Support?

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