Skip to content

Hooks Reference

All actions and filters provided by Virtual Media Folders and its add-ons.


Filter the folder to assign when a new attachment is uploaded.

PropertyValue
Since1.8.1
Filesrc/Admin.php

Parameters:

ParamTypeDescription
$folder_idintDefault folder term ID (from settings, or 0).
$attachment_idintThe attachment post ID.
$metadataarrayAttachment metadata (dimensions, EXIF, etc.).

Return: int — Folder term ID. Return 0 to skip assignment.

Example — always assign to a specific folder:

add_filter( 'vmfo_upload_folder', function ( int $folder_id, int $attachment_id, array $metadata ): int {
return 42; // Always assign to folder term ID 42.
}, 10, 3 );

Example — route PDFs to a “Documents” folder:

add_filter( 'vmfo_upload_folder', function ( int $folder_id, int $attachment_id, array $metadata ): int {
$mime = get_post_mime_type( $attachment_id );
if ( $mime === 'application/pdf' ) {
$term = get_term_by( 'name', 'Documents', 'vmfo_folder' );
return $term ? $term->term_id : $folder_id;
}
return $folder_id;
}, 10, 3 );

Example — route images by EXIF date:

add_filter( 'vmfo_upload_folder', function ( int $folder_id, int $attachment_id, array $metadata ): int {
if ( ! empty( $metadata['image_meta']['created_timestamp'] ) ) {
$year = date( 'Y', $metadata['image_meta']['created_timestamp'] );
$term = get_term_by( 'name', $year, 'vmfo_folder' );
if ( $term ) {
return $term->term_id;
}
}
return $folder_id;
}, 10, 3 );

Control whether filtering by a folder also includes child-folder items.

PropertyValue
Since1.0.0
Filesrc/Editor.php

Parameters:

ParamTypeDescription
$include_childrenboolDefault false.
$folder_idintThe folder term ID being filtered.

Return: bool

Example:

// Always show child-folder media when a parent folder is selected.
add_filter( 'vmfo_include_child_folders', '__return_true' );

Override the default plugin settings before they are stored.

PropertyValue
Since1.0.5
Filesrc/Settings.php

Parameters:

ParamTypeDescription
$defaultsarrayDefault settings (default_folder, show_all_media, show_uncategorized, etc.).

Return: array

Example:

add_filter( 'vmfo_default_settings', function ( array $defaults ): array {
$defaults['show_uncategorized'] = false; // Hide "Uncategorized" by default.
return $defaults;
} );

Filter a single setting value at read-time. The dynamic portion is the setting key.

PropertyValue
Since1.0.5
Filesrc/Settings.php

Parameters:

ParamTypeDescription
$valuemixedThe setting value.
$keystringThe setting key.
$optionsarrayAll settings.

Return: mixed

Example:

// Force "jump to folder after move" on for editors+.
add_filter( 'vmfo_setting_jump_to_folder_after_move', function ( $value ): bool {
return current_user_can( 'edit_others_posts' ) ? true : $value;
} );

Filter all settings at once, after individual vmfo_setting_{$key} filters.

PropertyValue
Since1.0.5
Filesrc/Settings.php

Parameters:

ParamTypeDescription
$optionsarrayAll settings.

Return: array


Register add-on tabs on the Settings page. Used by all official add-ons.

PropertyValue
Since1.1.0
Filesrc/Settings.php

Parameters:

ParamTypeDescription
$tabsarray[ 'slug' => [ 'title' => string, 'callback' => callable, 'subtabs' => array ] ]

Return: array

Example:

add_filter( 'vmfo_settings_tabs', function ( array $tabs ): array {
$tabs['my-addon'] = [
'title' => __( 'My Add-on', 'my-addon' ),
'callback' => [ MyAddon\Settings::class, 'render' ],
];
return $tabs;
} );

Prevent a specific folder from being deleted. Return a WP_Error to block deletion with a message.

PropertyValue
Since1.6.5
Filesrc/RestApi.php

Parameters:

ParamTypeDescription
$can_deletebool|WP_ErrorDefault true.
$folder_idintFolder term ID.
$termobjectFolder term object.

Return: bool|WP_Error

Example:

add_filter( 'vmfo_can_delete_folder', function ( $can_delete, int $folder_id, $term ) {
if ( $term->slug === 'important' ) {
return new WP_Error( 'protected', 'This folder cannot be deleted.' );
}
return $can_delete;
}, 10, 3 );

Fires after a media item is moved to a folder via drag-and-drop or AJAX.

PropertyValue
Since1.5.0
Filesrc/Admin.php

Parameters:

ParamTypeDescription
$media_idintAttachment ID.
$folder_idintFolder term ID.
$resultarrayResult from wp_set_object_terms().

Example:

add_action( 'vmfo_folder_assigned', function ( int $media_id, int $folder_id, array $result ): void {
error_log( "Attachment {$media_id} assigned to folder {$folder_id}" );
}, 10, 3 );

Fires when the settings page assets are loaded. Add-ons enqueue their tab scripts here.

PropertyValue
Since1.1.0
Filesrc/Settings.php

Parameters:

ParamTypeDescription
$active_tabstringCurrent tab slug.
$active_subtabstringCurrent subtab slug.

Example:

add_action( 'vmfo_settings_enqueue_scripts', function ( string $tab, string $subtab ): void {
if ( $tab === 'my-addon' ) {
wp_enqueue_script( 'my-addon-settings', plugins_url( 'build/settings.js', __FILE__ ) );
}
}, 10, 2 );

Plugin: vmfa-rules-engine

Register custom condition matchers for rule evaluation.

PropertyValue
Since1.0.0
Filesrc/php/Services/RuleEvaluator.php

Parameters:

ParamTypeDescription
$matchersarray<string, MatcherInterface>Keyed by matcher slug.

Return: array

Example:

add_filter( 'vmfa_rules_engine_matchers', function ( array $matchers ): array {
$matchers['custom_field'] = new MyPlugin\CustomFieldMatcher();
return $matchers;
} );

Control whether rule evaluation is skipped when the attachment already has a folder.

PropertyValue
Since1.3.0
Filesrc/php/Services/RuleEvaluator.php

Parameters:

ParamTypeDescription
$skipboolDefault true.
$attachment_idintAttachment ID.
$existing_termsarrayCurrently assigned folder terms.

Return: bool

Example:

// Always re-evaluate rules, even for already-assigned media.
add_filter( 'vmfa_rules_engine_skip_if_assigned', '__return_false' );

Fires after the Rules Engine assigns a folder to an attachment.

PropertyValue
Since1.0.0
Filesrc/php/Services/RuleEvaluator.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$folder_idintAssigned folder term ID.
$rulearrayThe matching rule.

Example:

add_action( 'vmfa_rules_engine_folder_assigned', function ( int $attachment_id, int $folder_id, array $rule ): void {
error_log( sprintf( 'Rule "%s" assigned attachment %d to folder %d', $rule['name'], $attachment_id, $folder_id ) );
}, 10, 3 );

Plugin: vmfa-ai-organizer

Fires when cached AI analysis results are applied to media.

PropertyValue
Filesrc/php/Services/MediaScannerService.php

Parameters:

ParamTypeDescription
$appliedintNumber of items successfully assigned.
$failedintNumber of items that failed.

Fires when an AI scan batch completes.

PropertyValue
Filesrc/php/Services/MediaScannerService.php

Parameters:

ParamTypeDescription
$progressarrayScan progress data.

Fires when AI Organizer assigns media to a folder. Uses the vmfo_ prefix for compatibility with core VMF folder-assignment hooks.

PropertyValue
Filesrc/php/Services/AIAnalysisService.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$folder_idintFolder term ID.
$resultarrayTerm IDs returned by wp_set_object_terms().

Example:

add_action( 'vmfo_media_moved', function ( int $attachment_id, int $folder_id, array $result ): void {
error_log( sprintf( 'AI Organizer moved attachment %d to folder %d', $attachment_id, $folder_id ) );
}, 10, 3 );

Plugin: vmfa-editorial-workflow

Fires after a new upload is assigned to a user’s inbox folder.

PropertyValue
Filesrc/php/Services/InboxService.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$inbox_folder_idintInbox folder term ID.
$user_idintWordPress user ID.

Example:

add_action( 'vmfa_inbox_assigned', function ( int $attachment_id, int $inbox_folder_id, int $user_id ): void {
// Send notification when new media arrives in a user's inbox.
$user = get_userdata( $user_id );
wp_mail( $user->user_email, 'New media in your inbox', 'A new file was uploaded to your inbox folder.' );
}, 10, 3 );

Fires after an attachment is marked for editorial review.

PropertyValue
Filesrc/php/WorkflowState.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$folder_idintReview folder term ID.

Fires after an attachment is approved in the editorial workflow.

PropertyValue
Filesrc/php/WorkflowState.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$folder_idintDestination folder term ID.

Plugin: vmfa-media-cleanup

Override whether an attachment is considered unused. Useful for excluding media referenced by third-party plugins (WooCommerce galleries, ACF fields, etc.).

PropertyValue
Filesrc/php/Detectors/UnusedDetector.php

Parameters:

ParamTypeDescription
$is_unusedboolWhether the attachment is unused.
$attachment_idintAttachment ID.

Return: bool

Example:

// Never flag WooCommerce product gallery images as unused.
add_filter( 'vmfa_cleanup_is_unused', function ( bool $is_unused, int $attachment_id ): bool {
if ( ! $is_unused ) {
return false;
}
global $wpdb;
$in_gallery = $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_product_image_gallery' AND meta_value LIKE %s",
'%' . $wpdb->esc_like( (string) $attachment_id ) . '%'
) );
return $in_gallery ? false : $is_unused;
}, 10, 2 );

Customize the dimension thresholds for detecting oversized images.

PropertyValue
Filesrc/php/Detectors/OversizedDetector.php

Parameters:

ParamTypeDescription
$thresholdsarray<string, int>[ 'width' => int, 'height' => int ].

Return: array

Example:

add_filter( 'vmfa_cleanup_oversized_thresholds', function ( array $thresholds ): array {
$thresholds['width'] = 3840; // Flag images wider than 4K.
$thresholds['height'] = 2160;
return $thresholds;
} );

Customize the name of the folder created when archiving media.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$folder_namestringDefault folder name.

Return: string


Control how many attachments are processed per scan batch.

PropertyValue
Filesrc/php/Services/ScanService.php

Parameters:

ParamTypeDescription
$batch_sizeintBatch size.

Return: int


Extend the list of postmeta keys scanned for attachment references.

PropertyValue
Filesrc/php/Services/ReferenceIndex.php

Parameters:

ParamTypeDescription
$meta_keysstring[]Meta keys to scan.

Return: string[]

Example:

add_filter( 'vmfa_cleanup_reference_meta_keys', function ( array $keys ): array {
$keys[] = '_my_plugin_gallery'; // Also scan this meta key for image IDs.
return $keys;
} );

Register custom reference-detection callbacks beyond postmeta scanning.

PropertyValue
Filesrc/php/Services/ReferenceIndex.php

Parameters:

ParamTypeDescription
$sourcesarray[ [ 'type' => string, 'callback' => callable(int $post_id): int[] ] ]

Return: array


Change the hashing algorithm for duplicate detection.

PropertyValue
Filesrc/php/Services/HashService.php

Parameters:

ParamTypeDescription
$algorithmstringDefault sha256.

Return: string


Fires before a bulk cleanup action (archive, trash, delete) is processed.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$actionstringAction name: archive, trash, or delete.
$idsint[]Attachment IDs.

Fires after a media item is archived to a cleanup folder.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.
$folder_idintArchive folder term ID.

Fires after a media item is moved to the trash.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.

Fires after a media item is restored from trash.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.

Fires after a media item is permanently deleted.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.

Fires after a media item is flagged for review.

PropertyValue
Filesrc/php/REST/ActionsController.php

Parameters:

ParamTypeDescription
$attachment_idintAttachment ID.

Fires after cleanup settings are saved.

PropertyValue
Filesrc/php/REST/SettingsController.php

Parameters:

ParamTypeDescription
$updatedarrayNew settings.
$currentarrayPrevious settings.

Fires when a full cleanup scan finishes.

PropertyValue
Filesrc/php/Services/ScanService.php

Parameters:

ParamTypeDescription
$resultsarrayScan results summary.

Plugin: vmfa-folder-exporter

Override the directory where export ZIP files are stored.

PropertyValue
Filesrc/php/Services/ExportService.php

Parameters:

ParamTypeDescription
$export_dirstringDefault export directory path.

Return: string


Customize the CSV manifest column headers.

PropertyValue
Filesrc/php/Services/ManifestService.php

Parameters:

ParamTypeDescription
$columnsarrayColumn headers.

Return: array

Example:

add_filter( 'vmfa_export_manifest_columns', function ( array $columns ): array {
$columns[] = 'alt_text'; // Add alt text column to the CSV export.
return $columns;
} );

Plugin: vmfa-migrate

Filter the list of migration driver classes. Add custom drivers to support additional media folder plugins.

PropertyValue
Since0.1.0
Filesrc/php/Services/DetectorService.php

Parameters:

ParamTypeDescription
$driver_classesarray<int, class-string<DriverInterface>>List of driver class names.

Return: array

Example — add a custom driver:

add_filter( 'vmfa_migrate_drivers', function ( array $drivers ): array {
$drivers[] = MyPlugin\Drivers\CustomFolderDriver::class;
return $drivers;
} );

Scheduled via Action Scheduler to process migration assignments in batches. Each invocation processes one batch and re-schedules itself until all assignments are migrated.

PropertyValue
Since0.1.0
Filesrc/php/Services/MigrationService.php

Parameters:

ParamTypeDescription
$job_idstringUnique migration job identifier.
$offsetintCurrent batch offset.

Example — log batch progress:

add_action( 'vmfa_migrate_process_batch', function ( string $job_id, int $offset ): void {
error_log( sprintf( 'Migration %s processing batch at offset %d', $job_id, $offset ) );
}, 5, 2 );

HookTypePlugin
vmfo_upload_folderfilterCore
vmfo_include_child_foldersfilterCore
vmfo_default_settingsfilterCore
vmfo_setting_{$key}filterCore
vmfo_settingsfilterCore
vmfo_settings_tabsfilterCore
vmfo_can_delete_folderfilterCore
vmfo_folder_assignedactionCore
vmfo_settings_enqueue_scriptsactionCore
vmfa_rules_engine_matchersfilterRules Engine
vmfa_rules_engine_skip_if_assignedfilterRules Engine
vmfa_rules_engine_folder_assignedactionRules Engine
vmfa_cached_results_appliedactionAI Organizer
vmfa_scan_completedactionAI Organizer
vmfo_media_movedactionAI Organizer
vmfa_inbox_assignedactionEditorial Workflow
vmfa_marked_needs_reviewactionEditorial Workflow
vmfa_approvedactionEditorial Workflow
vmfa_cleanup_is_unusedfilterMedia Cleanup
vmfa_cleanup_oversized_thresholdsfilterMedia Cleanup
vmfa_cleanup_archive_folder_namefilterMedia Cleanup
vmfa_cleanup_scan_batch_sizefilterMedia Cleanup
vmfa_cleanup_reference_meta_keysfilterMedia Cleanup
vmfa_cleanup_reference_sourcesfilterMedia Cleanup
vmfa_cleanup_hash_algorithmfilterMedia Cleanup
vmfa_cleanup_before_bulk_actionactionMedia Cleanup
vmfa_cleanup_media_archivedactionMedia Cleanup
vmfa_cleanup_media_trashedactionMedia Cleanup
vmfa_cleanup_media_restoredactionMedia Cleanup
vmfa_cleanup_media_deletedactionMedia Cleanup
vmfa_cleanup_media_flaggedactionMedia Cleanup
vmfa_cleanup_settings_updatedactionMedia Cleanup
vmfa_cleanup_scan_completeactionMedia Cleanup
vmfa_export_dirfilterFolder Exporter
vmfa_export_manifest_columnsfilterFolder Exporter
vmfa_migrate_driversfilterMigrate
vmfa_migrate_process_batchactionMigrate