Attachment lookup hooks

GoDAM for WordPress v2.2.0 Updated: 2026-09-08

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_Queryget_postsget_children, or raw $wpdb queries against posts/postmeta).

HookFiresArgumentsSince
rtgodam_before_attachment_lookupImmediately before GoDAM touches attachment datanone2.2.0
rtgodam_after_attachment_lookupImmediately after GoDAM is donenone2.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_lookup reaches a matching rtgodam_after_attachment_lookup before its scope ends — including on early return/throw, where GoDAM wraps the work in try/finally so the after still 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' );
} );