Hook: mam_geodirectory_explcit_listings

Signature

apply_filters( 'mam_geodirectory_explcit_listings', array $dir_data );
Parameter Type Description
$dir_data array Empty array — the plugin passes [].

Returns: array — the listing rows you want the directory pipeline to use instead of the GD query result. You must return an array.


Purpose

Bypasses the GeoDirectory directory-table query in mam_geodirectory_content::get_data_for_app(). When this filter has any subscriber, the plugin uses your returned array instead of querying the GD detail table — and also skips the geofilter / city-list resolution earlier in the request.

Use cases:

  • Source listings from an external database, REST API, or in-memory cache.
  • Show a curated subset of listings on a special-purpose screen.
  • Replace the live directory with seed/demo data during a launch dry-run.

Hook name preserves a typo. The original hook was named mam_geodirectory_explcit_listings (missing the i in “explicit”). The typo is now part of the public contract; renaming would break existing subscribers. Use it as written.


When it runs

Inside mam_geodirectory_content::get_data_for_app():

if ( has_filter( 'mam_geodirectory_explcit_listings' ) ) {
    $dir_data = apply_filters( 'mam_geodirectory_explcit_listings', array() );
}

Earlier in the same method, resolve_user_location_and_filters() also gates city resolution on ! has_filter('mam_geodirectory_explcit_listings') — i.e., when this filter has subscribers, the plugin does not scan tsl_gd_map_manager_cities to match the user’s coordinates to a configured city. Your returned array is used as-is.


Returned row shape

Your returned rows must look like the rows the plugin would have read from the GD detail table — at minimum:

Key Type Notes
post_id int Used to set id after rename.
latitude, longitude float Used to set lat, lon.
post_title string Used to set title.
post_status string Used by should_include_listing.
post_modified string Optional.
post_category string Comma-separated term IDs, used by category filtering.
business_hours, business_hours_for_app, default_category, etc. various All the GD detail-table columns that downstream finalisers expect.

The plugin’s per-listing finalisers (categories, marker icons, images, social platforms, claim status, chat) all run on your rows. The expected fields are documented in Mobile listing data shape.


Example: hand-built listings from a static config

add_filter( 'mam_geodirectory_explcit_listings', 'my_app_static_directory' );

function my_app_static_directory( $dir_data ) {
    return [
        [
            'post_id'      => 1001,
            'post_title'   => 'Joe's Coffee',
            'post_status'  => 'publish',
            'post_modified' => current_time( 'mysql' ),
            'latitude'     => 37.7749,
            'longitude'    => -122.4194,
            'post_category' => '5',
            'business_hours' => '',
            'default_category' => 5,
            // ...other detail-table columns...
        ],
    ];
}

Gotchas

  • Spelling is part of the contract. Use mam_geodirectory_explcit_listings, not mam_geodirectory_explicit_listings.
  • Returned rows must satisfy the finalisers. Missing keys lead to PHP notices and missing data on the app side. Return the same column set the GD detail tables produce, or stub empty values.
  • Geofiltering is bypassed. When this filter is active, the user’s lat/lon are not matched against the configured cities, and is_geofilter_neighborhood stays false. If you need geofiltering, do it inside your callback.
  • Admin approvals are not bypassed. manage_admin_approvals() and manage_user_drafts() still run on your returned array. They drop or include rows based on post_status and the request context.
  • mam_geodirectory_final_listings still runs. Your rows go through the per-listing finalisers, then through mam_geodirectory_final_listings, before being returned.

Verification

This article was last verified against:

  • Plugin: mam-geodirectory v2.1.5
  • Source: content-classes/local-app-geodirectory-v2-class.php (line 528 and line 974)

Re-verify whenever the conditional gate (has_filter check) is moved or replaced, the rename of the field map in get_directory_data() changes, or the resolve_user_location_and_filters short-circuit changes.


  • Plugin: mam-geodirectory
  • Content type: GeoDirectory list and map
  • Mobile listing data shape
  • Hook: mam_geodirectory_final_listings
  • Hook: mam_geodirectory_skip_record

Metadata

Field Value
Article type Hook Reference
Plugin slug mam-geodirectory
Applies to plugin version 2.1.5+
Category Extending MAM Suite
Hook type filter
Audience PHP developer
Last verified 2026-05-01
Contents

    Need Support?

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