Skip to content

Getting Started (Developers)

How to extend DMS safely. The plugin's PHP is distributed encoded - you never edit it directly. All customization goes through hooks, filters, and helper functions, placed in your theme's functions.php, a child theme, or a small mu-plugin.

Ground Rules

  • Never edit encoded plugin files. They can't be read, and any change is lost on update. Use hooks and helpers instead.
  • Extensions must be independently activatable. Don't hard-depend on another add-on being present - guard for it (function_exists(), class_exists()).
  • Prefer documented helper functions over reaching into internal classes. Helpers are the stable public surface; internal class methods are not.
  • All AJAX endpoints require nonce validation. If you add your own, validate a nonce.

Boot Phases

DMS fires ordered action hooks during load. Hook your code to the earliest phase where the data you need is ready:

Hook When Use for
dms_before_init CPTs/taxonomies are being registered Register custom listing types/taxonomies
dms_init Options/settings loaded (priority 15) Anything needing settings, types, or the query layer
dms_after_init Types & options fully loaded Code needing full type/option state
dms_init_extension On plugins_loaded Extension entry point (see Building Extensions)
// Runs once DMS options and types are available.
add_action( 'dms_init', function () {
    // your setup here
} );

dms_init (and the other dms_* boot hooks) only fire when DMS is active, so code hooked here never needs a "is DMS active?" guard - if the plugin is off, the hook simply never runs.

Most integration code belongs on dms_init or later. Registering a new inventory type is the main reason to use dms_before_init.


The Accessor Pattern

Core systems are singletons, each reached through a global dms_*() function. Call the accessor rather than instantiating the class.

Accessor System
dms_options() Global settings store
dms_types() Inventory types
dms_badges() Badges
dms_cache() Object cache wrapper
dms_mail() Mail/notifications
dms_listing_query() The SRP listing query
dms_dashboard() Admin dashboard widgets

Reading & writing settings

Helper Returns Purpose
dms_get_option( string $name, mixed $default_value = false ) mixed Read a global DMS setting.
dms_is_option_on( $option ) bool Normalize a CMB2 switch value ('on', 1, true…) to a boolean.
dms_format_price( string\|float $price = 0, bool $is_tax_amount = false ) string Format a number using the site's currency settings.
$phone = dms_get_option( 'dealer_phone' );

if ( dms_is_option_on( dms_get_option( 'show_prices' ) ) ) {
    echo dms_format_price( 24995 ); // "$24,995"
}

Resolving Objects by ID or Slug

These return the DMS object for a given identifier. Each returns an empty object (never null) for an unknown identifier - always check ->exists().

Helper Returns
dms_get_listing( int $id ) Listing
dms_get_type( string\|int $id ) Type
dms_get_category( int\|string $category, int $type_id = 0 ) Category
dms_get_term( int\|string $term, string $search_value = 'slug', int $category_id = 0 ) Term
dms_get_badge( int\|string $id ) Badge
dms_category_meta_key( int\|string $category_id ) string - the post-meta key backing a category

See Listings API for what to do with a Listing or Type.


Where to Put Your Code

Three options, in increasing order of isolation:

  1. Theme functions.php / child theme - quickest for site-specific tweaks. Lost if you switch themes.
  2. mu-plugin (wp-content/mu-plugins/your-file.php) - always active, survives theme changes. Best for a few site-specific customizations.
  3. A standalone extension plugin - for reusable, distributable features. See Building Extensions.

Minimal working example (mu-plugin)

<?php
/**
 * Plugin Name: My DMS Customizations
 */

// Add a note to every VDP footer.
add_action( 'wp_footer', function () {
    if ( ! function_exists( 'dms_is_vdp' ) || ! dms_is_vdp() ) {
        return;
    }

    $listing = dms_get_current_listing();

    if ( $listing && $listing->exists() ) {
        printf(
            '<p class="my-note">Call about the %s today!</p>',
            esc_html( $listing->get_title() )
        );
    }
} );

Every DMS helper is namespaced dms_* and guarded behind function_exists() in the example so the code fails safe if DMS is deactivated.


Next Steps