GoDAM fires a pair of action hooks around every place it reads or writes attachment data directly, post meta, attachment URLs/paths, and attachment queries (WP_Query, get_posts, get_children, or raw $wpdb queries against posts/postmeta).
| Hook | Fires | Arguments | Since |
|---|---|---|---|
rtgodam_before_attachment_lookup | Immediately before GoDAM touches attachment data | none | 2.2.0 |
rtgodam_after_attachment_lookup | Immediately after GoDAM is done | none | 2.2.0 |
Both are plain do_action() calls with no parameters — they are context markers, not data filters.
Why they exist
GoDAM does not know where your attachments physically live. On a standard single site the answer is “right here,” and the hooks are no-ops. But if a plugin centralizes attachments onto one media site of a multisite network (for example, a DAM plugin such as wp-dam), then every attachment read GoDAM performs must happen in the context of that media site — otherwise get_post_meta(), wp_get_attachment_url(), and attachment queries run against the wrong blog and return nothing.
These hooks give that plugin exactly one job: switch to the media site on before, and switch back on after. GoDAM handles firing them around every attachment-access site in its own code.
Contract
- The two hooks are always fired as a balanced pair. Every
rtgodam_before_attachment_lookupreaches a matchingrtgodam_after_attachment_lookupbefore its scope ends — including on earlyreturn/throw, where GoDAM wraps the work intry/finallyso theafterstill runs. (This balance is enforced in CI.) - They wrap the smallest possible scope — often a single meta read. Keep your callbacks cheap; they may run many times per request.
- Do not assume they only fire once per request, and do not assume they never overlap across different code paths. Write your callbacks so a plain switch/restore pair is always correct, and guard against nesting if your switch is not intrinsically stackable (see the robust example below).
Example: route attachment lookups to a central media site
The simplest form. switch_to_blog() / restore_current_blog() maintain their own stack, so a matched pair is safe:
add_action( 'rtgodam_before_attachment_lookup', 'myplugin_switch_to_media_site' );
add_action( 'rtgodam_after_attachment_lookup', 'myplugin_restore_media_site' );
/**
* Switch to the site that stores the shared media library.
*/
function myplugin_switch_to_media_site() {
switch_to_blog( MYPLUGIN_MEDIA_SITE_ID );
}
/**
* Return to the original site once GoDAM is done reading attachment data.
*/
function myplugin_restore_media_site() {
restore_current_blog();
}
Example: nesting-safe version
If your context switch is not something you want to nest — or you want to be defensive about overlapping before/after pairs — track depth and only switch on the outermost before:
class MyPlugin_Media_Context {
/** @var int Number of open attachment-lookup scopes. */
private $depth = 0;
public function register() {
add_action( 'rtgodam_before_attachment_lookup', array( $this, 'enter' ) );
add_action( 'rtgodam_after_attachment_lookup', array( $this, 'leave' ) );
}
/**
* Enter media-site context. Only the outermost scope actually switches.
*/
public function enter() {
if ( 0 === $this->depth ) {
switch_to_blog( MYPLUGIN_MEDIA_SITE_ID );
}
$this->depth++;
}
/**
* Leave media-site context once the outermost scope closes.
*/
public function leave() {
if ( $this->depth > 0 ) {
$this->depth--;
}
if ( 0 === $this->depth ) {
restore_current_blog();
}
}
}
Example: any other per-lookup adjustment
The hooks are not limited to switch_to_blog(). Any state that must be in place only while GoDAM reads attachment data can hang off them — for instance short-circuiting an object-cache group, or toggling a filter:
add_action( 'rtgodam_before_attachment_lookup', function () {
add_filter( 'my_attachment_cache_bypass', '__return_true' );
} );
add_action( 'rtgodam_after_attachment_lookup', function () {
remove_filter( 'my_attachment_cache_bypass', '__return_true' );
} );