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_initor later. Registering a new inventory type is the main reason to usedms_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:
- Theme
functions.php/ child theme - quickest for site-specific tweaks. Lost if you switch themes. - mu-plugin (
wp-content/mu-plugins/your-file.php) - always active, survives theme changes. Best for a few site-specific customizations. - 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¶
- Listings API - the core
Listing/Typeobjects and query layer. - Filters Reference - change values before DMS uses them.
- Actions Reference - run code on lifecycle events.
- Building Extensions - package customizations as a plugin.
- Cookbook - copy-paste recipes.