TABLE OF CONTENTS
Media Deduper Pro uses a set of filters to replace attachment references stored in post meta or in properties of WP_Post objects when a user performs a Smart Delete operation. Developers can extend the Smart Delete functionality by adding their own custom callbacks to these filters.
The mdd_get_reference_fields filter allows developers to define custom fields where Media Deduper Pro should look for attachment references, and the mdd_get_reference_post_types filter allows developers to control which post types should be checked for references (and, conversely, which should be ignored).
The mdd_detect_* and mdd_replace_* filters are used to detect (track) attachment references in field values while indexing, and to replace those values, respectively. The detection and replacement filters come in two flavors: type-specific and field-specific.
Type-specific filters apply to all fields of a given data type: for example, mdd_detect_type__int will apply to all fields whose corresponding array value in the array returned by the mdd_get_reference_fields filter is ‘int’.
Field-specific filters apply only to a specific field: a callback attached to the mdd_detect_field__prop:post_content will only be applied to post content.
mdd_get_reference_fields
Filter the list of post fields that may contain attachment references.
Parameters
$fields (array)
An array describing post fields. Keys start with either 'meta' or 'prop' (denoting a post meta field or post object property, respectively), followed by a colon character, followed by the field's name (e.g. '_thumbnail_id' or 'post_content'). Values are strings indicating the type of data stored in a field. Note that these data type values have no intrinsic meaning; they’re just a way of grouping multiple fields together for use with the mdd_detect_type__{$type} and mdd_replace_type__{$replace} hooks.
$post (int|WP_Post)
The post to return fields for.
Example
Let’s say you have a cheap social media plugin that implements a postmeta field called “fb_sharing_image,” which stores a post_id of an attachment, and you’d like Deduper to track those. You can tell Media Deduper to track that field in all posts like this:
function my_social_plugin_mdd_reference_fields( $fields ){
$fields['meta:fb_sharing_image'] = 'int';
return $fields;
}
add_filter( 'mdd_get_reference_fields', 'my_social_plugin_mdd_reference_fields' );
Or if you’re in the tragic situation of having two post types that each have a meta field named ‘_custom_image’, but for Posts, the field value is stored as an attachment ID, and on Pages, the field value is stored as a URL, you could do this:
function custom_image_mdd_reference_fields( $fields, $post ) {
if ( 'post' === $post->post_type ) {
$fields['meta:_custom_image'] = 'int';
} elseif ( 'page' === $post->post_type ) {
$fields['meta:_custom_image'] = 'url';
}
return $fields;
}
add_filter( 'mdd_get_reference_fields', 'custom_image_mdd_reference_fields', 10, 2 );
mdd_get_reference_post_types
Filter the list of post types that may contain attachment references.
Parameters
$types (array)
An array of post type slugs. Defaults to all public post types except ‘attachment’.
Example
If you’re using a custom post type named ‘my-custom-post-type’, but it’s registered with the ‘public’ argument set to false, then you can explicitly tell Media Deduper to track references to it like this:
function my_custom_mdd_post_type( $post_types ) {
$post_types[] = 'my-custom-post-type';
return $post_types;
}
add_filter( 'mdd_get_reference_post_types', 'my_custom_mdd_post_type' );
mdd_detect_type__{$type}
Filter the list of attachment IDs referenced by a field. The dynamic portion of the hook name, $type, refers to a field data type, i.e. a value in the array returned by the mdd_get_reference_fields filter, such as 'wysiwyg', 'int', or 'multi_int'.
Parameters
$refs (array)
An array of attachment IDs to filter.
$value (mixed)
The value of the field.
Example
Let’s say you’ve created a custom shortcode, [fancy_img id="10"], that outputs the image with the given ID and while adding extra markup around the image. You can tell MDD to look for that shortcode in WYSIWYG field content like this:
function fancy_img_mdd_detect( $refs, $value ) {
// Look for [fancy_img] shortcodes.
if ( preg_match_all( '/\[fancy_img[^\]]*id="(\d*)"/', $value, $matches ) ) {
foreach ( $matches[1] as $fancy_img_id ) {
// Add each matching ID to $refs, if it's not already present.
$fancy_img_id = intval( $fancy_img_id );
if ( ! in_array( $fancy_img_id, $refs, true ) ) {
$refs[] = $fancy_img_id;
}
}
}
return $refs;
}
add_filter( 'mdd_detect_type__wysiwyg', 'fancy_img_mdd_detect', 10, 2 );
mdd_replace_type__{$type}
Filter the value of a field, replacing references to one attachment with references to another. The dynamic portion of the hook name, $type, refers to a field data type, i.e. a value in the array returned by the mdd_get_reference_fields filter, such as 'wysiwyg', 'int', or 'multi_int'.
Parameters
$new_value (mixed)
The field value to filter.
$old_id (int)
The ID of the 'old' attachment, references to which should be replaced.
$new_id (int)
The ID of the 'new' attachment, which should replace the 'old' attachment wherever it's referenced.
Example
To replace [fancy_img] shortcodes as described in the previous example:
function fancy_img_mdd_replace( $new_value, $old_id, $new_id ) {
$new_value = preg_replace_all(
'/\[fancy_img ([^\]]*)id="' . $old_id . '"/',
'[fancy_img \1id="' . $new_id . '"',
$new_value
);
return $new_value;
}
add_filter( 'mdd_replace_type__wysiwyg', 'fancy_img_mdd_replace', 10, 3 );
mdd_detect_field__{$field}
Filter the list of attachment IDs referenced by a field. The dynamic portion of the hook name, $field, refers to a field descriptor, i.e. a key in the array returned by the mdd_get_reference_fields filter, such as 'prop:post_content' or 'meta:_thumbnail_id'.
Parameters
$refs (array)
An array of attachment IDs to filter.
$value (mixed)
The value of the field.
Example
Let’s say you have a gallery plugin that stores gallery data for posts as a serialized array in a meta field called _my_gallery, and the structure of that array looks something like this:
array(
array(
'image_id' => '123',
'caption' => 'This is an image',
),
array(
'image_id' => '456',
'caption' => 'This is another image',
),
// ...etc.
)
You can tell MDD how to detect references in this specific field using the mdd_detect_field__meta:_my_gallery hook like so:
function my_gallery_mdd_detect( $refs, $value ) {
foreach ( $value as $gallery_item ) {
$image_id = intval( $gallery_item['image_id'] );
if ( ! in_array( $image_id, $refs, true ) ) {
$refs[] = $image_id;
}
}
return $refs;
}
add_filter( 'mdd_detect_field__meta:_my_gallery', 'my_gallery_mdd_detect', 10, 2 );
mdd_replace_field__{$field}
Filter the value of a field, replacing references to one attachment with references to another. The dynamic portion of the hook name, $field, refers to a field descriptor, i.e. a key in the array returned by the mdd_get_reference_fields filter, such as 'prop:post_content' or ‘meta:_thumbnail_id'.
Parameters
$new_value (mixed)
The field value to filter.
$old_id (int)
The ID of the 'old' attachment, references to which should be replaced.
$new_id (int)
The ID of the 'new' attachment, which should replace the 'old' attachment wherever it's referenced.
Example
To replace images in the _my_gallery meta value described in the previous example:
function my_gallery_mdd_replace( $new_value, $old_id, $new_id ) {
foreach ( $new_value as $index => $gallery_item ) {
if ( $old_id === intval( $gallery_item['image_id'] ) ) {
$new_value[ $index ]['image_id'] = strval( $new_id );
}
}
return $new_value;
}
add_filter( 'mdd_replace_field__meta:_my_gallery', 'my_gallery_mdd_replace', 10, 3 );
mdd_pro_file_hash_maxlength
Filter the maximum number of bytes to read when hashing attachment files. When the "run partial hashes" plugin setting is enabled, Media Deduper Pro will read this many bytes of a file, calculate its hash based on that data, and ignore the rest of the file. The lower this value is, the faster indexing will be, but very low values will increase the risk that two files could be treated as duplicates when they aren't really identical beyond their first few bytes.
The default is 5242880 bytes (5 MB).
Note that this filter is only applied if "Run partial hashes" is enabled in the Media Deduper Pro plugin settings.
Parameters
$length (int)
The length to read in bytes.
$file (string)
The path to the file being hashed.
Example
Hash the first 8 MB of files instead of the first 5 MB:
function increase_mdd_hash_length( $length ) {
if ( $length < 8388608 ) { // Only change $length if it hasn't already been increased by another filter.
$length = 8388608;
}
return $length;
}
add_filter( 'mdd_pro_file_hash_maxlength', 'increase_mdd_hash_length' );