Goal
Give the venue owner a self-service “Edit Deals” button inside the mobile app — tapping it lets them create, edit, or soft-delete special offers on their own listing without ever opening WordPress admin. After this recipe, an authenticated app user looking at a listing they own will see a tab bar button that opens an inline Gravity Form for offer management.
This is the path most production apps want for venues. The desk-side admin path in Recipe: Add a special offer to a listing is for staff filling in offers on behalf of venues; this recipe replaces that with an in-app self-service flow.
Prerequisites
- A working install per Recipe: Add a special offer to a listing
mam-gravity-forms-manageractivated alongsidemam-special-offers. Without it, the auto-registered Gravity Form is never built and the Edit Deals button silently returns empty.mam-main‘s app-user authentication wired up somam_user_id()resolves on form submission- A listing with an authenticated app user as the owner (so they have a context to edit from)
How it works
The plugin auto-registers a Gravity Form named Special Offers: Offers under mam_gf_get_form_settings. On first run after mam-gravity-forms-manager builds the form, the Gravity Form ID is stored in the WordPress option mam_special_offers_special_offers, and one option per field (mam_special_offers_special_offers_{slug}) records the field IDs. The plugin then:
- Listens on
mam_gravity_forms_after_form_processed_{form_id}for submissions of that specific form. - On submit, calls
mam_special_offers_form_manager::special_offers()which extractsoffer-title,description,subtitle,always-available,offer-start-date,offer-end-date,delete-offer,postid, andlistingidfrom the form values, then either creates a newspecial_offerspost or updates the existing one identified bypostid. - Populates the
mam_main_add_tab_bar_item_edit_dealsslot on the listing detail screen with one form entry per existing offer plus an “Add Offer” entry. Each entry pre-fills the form viacustom_form_valueswith the offer’s current state. - Caps the number of offers exposed by the button at 20 (configurable via Hook: mam_special_offers_deals_allowed).
The form fields are auto-generated. You don’t build them by hand. But you do need to confirm the Gravity Form actually got built before the button can render.
Steps
1. Confirm the Gravity Form was generated
After mam-gravity-forms-manager and mam-special-offers both load for the first time, the form should appear under Forms → Forms in WP admin with the title Special Offers: Offers. If it isn’t there:
- Make sure both plugins are activated and entitled.
- Visit any admin page that triggers the suite’s settings registration (e.g., Mobile App Manager → App Settings) — that’s where
mam_gf_get_form_settingsis run. - Check the option
mam_special_offers_special_offersfor a non-zero Gravity Form ID:
$form_id = get_option( 'mam_special_offers_special_offers' );
If the option exists but the form doesn’t, the GF builder has failed silently and you need to debug mam-gravity-forms-manager rather than this plugin.
2. Register the listing as the offer-management surface
The Edit Deals tab bar button is registered on the mam_main_add_tab_bar_item_edit_deals slot. The default theme exposes this slot on listing detail screens; depending on your app shell you may need to wire the slot into a tab bar position. In Mobile App Manager → App Settings → Tab Bar, confirm that the listing detail screen has an edit_deals slot enabled for the venue-owner role.
3. Resolve permissions
The plugin doesn’t gate the Edit Deals button by ownership — it builds and returns the button whenever a form has been generated and the listing has fewer than the allowed number of offers. Gating is your responsibility. The two common patterns:
Hide the button for non-owners. Subscribe to Hook: mam_special_offers_skip_tab_bar_button and return an empty array unless the current app user is the listing’s author (or matches whatever ownership scheme your app uses).
Hide the button entirely on the wrong screens. For a hard skip that doesn’t even build the offers list, subscribe to mam_special_offers_hard_skip_tab_bar_button and return true.
For a venue-owner-only app:
add_filter( 'mam_special_offers_skip_tab_bar_button', function ( $button, $data_array ) {
$listing_author = (int) get_post_field( 'post_author', $data_array['id'] );
if ( $listing_author !== mam_user_id() ) {
return array();
}
return $button;
}, 10, 2 );
4. Verify in the app
Sign into the app as a venue owner and navigate to their listing’s detail screen. You should see:
- An Edit Deals tab bar button (gift icon by default).
- Tapping it opens a list with one row per existing offer and an Add Offer row at the top (or bottom, depending on shell).
- Tapping Add Offer opens the auto-generated Gravity Form with
listingidpre-filled. - Submitting it creates a new offer and returns the user to the offers list (
'type' => 'refreshAndReturnToList'). - Tapping an existing offer opens the same form pre-filled with that offer’s current values; submitting updates the offer in place.
- Ticking Delete Offer before submitting flips the offer’s
post_statustodraftand hides it from subsequent loads.
If the button doesn’t appear at all, the form lookup probably failed — re-check step 1 and confirm apply_filters( 'mam_gf_get_form_from_cache', 0, $form_id ) returns a non-zero index.
How the form maps to meta
Form submissions go through mam_special_offers_form_manager::special_offers(). The mapping from form field slug to offer meta is:
| Form field slug | Offer meta / post field |
|---|---|
offer-title |
post_title |
description |
post_content (sanitized via wp_kses_post) and special-offer-details meta |
subtitle |
special-offer-subtitle |
always-available |
special-offer-no-dates |
offer-start-date |
special-offer-start-date |
offer-end-date |
special-offer-end-date |
delete-offer |
If YES, sets post_status = draft. Not stored as meta. |
postid |
Hidden. Empty creates a new offer; non-zero updates that offer. |
listingid |
Stored as special-offer-parent meta. |
Two date fields, offer-start-date and offer-end-date, are conditionally hidden when always-available is checked (Gravity Forms conditional logic, set up automatically by add_field_features()).
Common gotchas
- The button appears empty if no Gravity Form has been generated.
mam_app_settings_tab_bar_button_edit_deals()returns an empty array as soon asapply_filters( 'mam_gf_get_form_from_cache', 0, $form_id )is<= 0. There’s no admin warning. - Each form-edit entry resets the offer’s image. The in-app form has no image field, so re-saving an offer through this path doesn’t change the thumbnail — but neither does it clear it. If you need image upload from the app, extend the form via
mam_gf_get_custom_formand add image handling tospecial_offers(). - The handler does not enforce ownership. Anyone with a valid app user ID who can submit the form can edit any offer whose
postidthey pass in. The check ismam_user_id() > 0, not “current user owns this listing.” Pair this recipe with the Hook: mam_special_offers_skip_tab_bar_button gate and any permission check you bake into the form submission path. - The 20-offer cap controls the button only. Beyond 20 offers, the Add Offer row disappears from the tab bar entry list, but existing offers are still listed. See Hook: mam_special_offers_deals_allowed if you need a different cap.
Verification
This article was last verified against:
- Plugin:
mam-special-offersv2.1 - Source:
mam-special-offers/includes/mam_special_offers_form_manager.php - Source:
mam-special-offers/includes/mam_special_offers_tab_bar_manager.php mam-gravity-forms-manager(required dependency)
Re-verify whenever the auto-generated form’s field slugs change, the option key scheme (mam_special_offers_*) changes, the 20-offer default cap changes, or the mam_main_add_tab_bar_item_edit_deals slot is renamed.
Related articles
- Plugin: mam-special-offers
- Recipe: Add a special offer to a listing
- Recipe: Enable RSVP for a special offer
- Hook: mam_special_offers_deals_allowed
- Hook: mam_special_offers_skip_tab_bar_button
Metadata
| Field | Value |
|---|---|
| Article type | Recipe (Admin) |
| Plugin slug | mam-special-offers |
| Applies to plugin version | 2.1+ |
| Category | Building Your App |
| Audience | WordPress admin |
| Estimated time | 15 minutes |
| Prerequisites article | Recipe: Add a special offer to a listing |
| Last verified | 2026-05-01 |
