Developer Reference
Settings Keys
All plugin settings are individual WordPress options readable with get_option(). There is no single serialized array.
| Option Key | Type | Default | Description |
|---|---|---|---|
wcrda_sync_method | string | async | Active sync method: async (Background Process) or fly (On-the-Fly) |
wcrda_batch_size | int | 20 | Orders per background job (Background Process only) |
wcrda_force_reset | string | no | Delete existing permissions before re-creating: yes or no |
wcrda_disable_cache | string | no | Bypass on-the-fly scan cache: yes or no |
wcrda_cache_duration | int | 60 | On-the-fly scan cache window in minutes |
wcrda_order_statuses | array | ['wc-completed', 'wc-processing'] | Eligible order statuses (with wc- prefix) |
wcrda_date_from | string | '' | Orders from date (YYYY-MM-DD); empty = no lower limit |
wcrda_date_to | string | '' | Orders to date (YYYY-MM-DD); empty = no upper limit |
wcrda_expiry_handling | string | current | Expiry for new permissions: current or preserve |
wcrda_download_limit_handling | string | current | Download limit for new permissions: current or inherit |
wcrda_send_email | string | no | Send customer notification emails: yes or no |
wcrda_email_subject | string | [{site_name}] New downloads available for order #{order_number} | Email subject template |
wcrda_debug_mode | string | no | Enable debug logging: yes or no |
Example:
// Check active sync method.
$method = get_option( 'wcrda_sync_method', 'async' );
// Read eligible statuses.
$statuses = get_option( 'wcrda_order_statuses', array( 'wc-completed', 'wc-processing' ) );
Product Exclusion Meta
To check or set the per-product exclusion flag programmatically:
// Check if a product is excluded.
$excluded = 'yes' === get_post_meta( $product_id, '_wcrda_exclude', true );
// Exclude a product.
update_post_meta( $product_id, '_wcrda_exclude', 'yes' );
// Re-include a product.
update_post_meta( $product_id, '_wcrda_exclude', 'no' );
Hooks & Filters
The plugin exposes 20 hooks across four categories. See Hooks & Filters for the full reference with parameters and usage examples.
Hooks & Filters
All hooks were introduced in version 1.2.0.
Permission Grant Hooks
These hooks fire inside WCRDA_Grant_Helper::grant_permission(), which is called by both sync methods whenever a missing permission is detected.
wcrda_should_grant_permission
Type: Filter
Return: bool — return false to skip granting this file.
Fires before a download permission is created. Return false to prevent the grant for this specific file without affecting other files or orders in the same batch.
add_filter( 'wcrda_should_grant_permission', function( $should_grant, $download_id, $product, $order, $quantity ) {
// Skip a specific product category.
if ( has_term( 'restricted', 'product_cat', $product->get_id() ) ) {
return false;
}
return $should_grant;
}, 10, 5 );
Parameters:
| # | Type | Description |
|---|---|---|
| 1 | bool | Whether to proceed with the grant. |
| 2 | string | The WooCommerce download ID (file hash). |
| 3 | WC_Product | The product being granted. |
| 4 | WC_Order | The order receiving the permission. |
| 5 | int | Line item quantity. |
wcrda_before_grant_permission
Type: Action
Fires immediately before wc_downloadable_file_permission() is called. Use this to perform setup or logging before the permission row is written.
add_action( 'wcrda_before_grant_permission', function( $download_id, $product, $order, $quantity ) {
// Custom logging before the grant.
}, 10, 4 );
Parameters: string $download_id, WC_Product $product, WC_Order $order, int $quantity
wcrda_after_grant_permission
Type: Action
Fires immediately after the permission row has been created by WooCommerce. Use this to trigger integrations or record the grant in an external system.
add_action( 'wcrda_after_grant_permission', function( $download_id, $product, $order, $quantity ) {
// Notify an external service.
}, 10, 4 );
Parameters: string $download_id, WC_Product $product, WC_Order $order, int $quantity
wcrda_permission_expiry
Type: Filter
Return: WC_DateTime|null — the expiry date, or null for no expiry.
Filters the expiry date applied to a newly granted permission. The initial value passed to the filter reflects the wcrda_expiry_handling setting: preserve passes the expiry from the customer’s first existing permission on the order; current passes the product’s default expiry.
add_filter( 'wcrda_permission_expiry', function( $expires, $permission, $order, $product ) {
// Always set a 30-day expiry from today, regardless of settings.
return new WC_DateTime( '+30 days' );
}, 10, 4 );
Parameters:
| # | Type | Description | |
|---|---|---|---|
| 1 | WC_DateTime | null | Initial expiry date (from the wcrda_expiry_handling setting). |
| 2 | WC_Customer_Download | The newly created permission object. | |
| 3 | WC_Order | The order receiving the permission. | |
| 4 | WC_Product | The product being granted. |
wcrda_permission_download_limit
Type: Filter
Return: string — remaining downloads; '' means unlimited.
Filters the download limit applied to a newly granted permission. The initial value reflects the wcrda_download_limit_handling setting: inherit passes the remaining count from the customer’s first existing permission; current passes the product’s default limit.
add_filter( 'wcrda_permission_download_limit', function( $limit, $permission, $order, $product ) {
// Grant unlimited downloads for all retroactive permissions.
return '';
}, 10, 4 );
Parameters:
| # | Type | Description |
|---|---|---|
| 1 | string | Initial remaining downloads; '' = unlimited. |
| 2 | WC_Customer_Download | The newly created permission object. |
| 3 | WC_Order | The order receiving the permission. |
| 4 | WC_Product | The product being granted. |
wcrda_should_notify_customer
Type: Filter
Return: bool — return false to suppress the email for this order.
Fires after the global Notify Customers setting is confirmed enabled, allowing per-order suppression without disabling notifications globally.
add_filter( 'wcrda_should_notify_customer', function( $should_notify, $order ) {
// Suppress notifications for wholesale customers.
if ( $order->get_billing_email() === 'wholesale@example.com' ) {
return false;
}
return $should_notify;
}, 10, 2 );
Parameters: bool $should_notify, WC_Order $order
Eligibility Hooks
These hooks fire inside WCRDA_Grant_Helper helper methods used by both sync methods to determine whether an order or product is in scope.
wcrda_allowed_order_statuses
Type: Filter
Return: string[] — order statuses with the wc- prefix.
Filters the order statuses eligible for retroactive access. The initial value is the wcrda_order_statuses setting (or the default ['wc-completed', 'wc-processing'] if nothing is saved).
add_filter( 'wcrda_allowed_order_statuses', function( $statuses ) {
// Also include 'on-hold' orders.
$statuses[] = 'wc-on-hold';
return $statuses;
} );
Parameters: string[] $statuses
wcrda_is_product_excluded
Type: Filter
Return: bool — return true to exclude the product from all retroactive access.
Filters whether a product is excluded. The initial value is true if the _wcrda_exclude post meta is yes, false otherwise.
add_filter( 'wcrda_is_product_excluded', function( $excluded, $product_id ) {
// Exclude all variable products programmatically.
$product = wc_get_product( $product_id );
if ( $product && $product->is_type( 'variable' ) ) {
return true;
}
return $excluded;
}, 10, 2 );
Parameters: bool $excluded, int $product_id
wcrda_is_order_in_date_range
Type: Filter
Return: bool — return false to exclude the order from scope.
Filters whether an order passes the configured date range check.
add_filter( 'wcrda_is_order_in_date_range', function( $in_range, $order ) {
// Also exclude orders from a specific year.
if ( $order->get_date_created() && '2020' === $order->get_date_created()->format( 'Y' ) ) {
return false;
}
return $in_range;
}, 10, 2 );
Parameters: bool $in_range, WC_Order $order
Background Process Hooks
These hooks fire inside WCRDA_Background_Process and are only relevant when the Background Process sync method is active.
wcrda_file_changes_detected
Type: Action
Fires when new download file IDs are detected on a product save (before the regeneration job is scheduled).
add_action( 'wcrda_file_changes_detected', function( $product_id, $added_ids, $old_ids ) {
// Log the added file hashes.
}, 10, 3 );
Parameters: int $product_id, string[] $added_download_ids, string[] $previous_download_ids
wcrda_should_schedule_regeneration
Type: Filter
Return: bool — return false to prevent the Action Scheduler job from being queued.
Fires inside schedule_regeneration() after file changes are detected. Use this to suppress scheduling during bulk imports or to redirect to a custom processing queue.
add_filter( 'wcrda_should_schedule_regeneration', function( $should_schedule, $product_id ) {
// Skip scheduling during a WP-CLI import.
if ( defined( 'WP_CLI' ) && WP_CLI ) {
return false;
}
return $should_schedule;
}, 10, 2 );
Parameters: bool $should_schedule, int $product_id
wcrda_batch_order_ids
Type: Filter
Return: int[] — modified list of order IDs to process in this batch.
Filters the order IDs fetched from the database for a per-product batch. Use this to inject, remove, or reorder specific orders.
add_filter( 'wcrda_batch_order_ids', function( $order_ids, $product_id, $page ) {
// Prepend a specific order on the first page.
if ( 1 === $page ) {
array_unshift( $order_ids, 9999 );
}
return $order_ids;
}, 10, 3 );
Parameters: int[] $order_ids, int $product_id, int $page (1-based)
wcrda_skip_order
Type: Filter
Return: bool — return true to skip this order entirely.
Fires for each order before status and date range checks run. $product_id is 0 when called from a global scan.
add_filter( 'wcrda_skip_order', function( $skip, $order, $product_id ) {
// Skip orders placed by a specific customer.
if ( $order->get_customer_id() === 42 ) {
return true;
}
return $skip;
}, 10, 3 );
Parameters: bool $skip, WC_Order $order, int $product_id (0 in a global scan)
wcrda_before_process_order
Type: Action
Fires before the plugin evaluates the items of an order during batch processing.
add_action( 'wcrda_before_process_order', function( $order, $product_id ) {
// Set up per-order context.
}, 10, 2 );
Parameters: WC_Order $order, int $product_id (0 in a global scan)
wcrda_after_process_order
Type: Action
Fires after all items of an order have been evaluated.
add_action( 'wcrda_after_process_order', function( $order, $permissions_granted, $product_id ) {
if ( $permissions_granted ) {
// React to the fact that this order received new files.
}
}, 10, 3 );
Parameters: WC_Order $order, bool $permissions_granted, int $product_id (0 in a global scan)
wcrda_regeneration_complete
Type: Action
Fires when all batch pages for a per-product regeneration have finished processing.
add_action( 'wcrda_regeneration_complete', function( $product_id ) {
// All orders for this product have been processed.
} );
Parameters: int $product_id
On-the-Fly Hooks
These hooks fire inside WCRDA_On_The_Fly and are only relevant when the On-the-Fly sync method is active.
wcrda_on_the_fly_enabled
Type: Filter
Return: bool — return false to skip the scan for this user entirely.
Fires at the start of the on-the-fly check, before the cache is consulted. Use this to disable the feature for specific roles or during maintenance.
add_filter( 'wcrda_on_the_fly_enabled', function( $enabled, $user_id ) {
// Disable for administrators (they manage products, not customers).
if ( user_can( $user_id, 'manage_options' ) ) {
return false;
}
return $enabled;
}, 10, 2 );
Parameters: bool $enabled, int $user_id
wcrda_on_the_fly_cache_duration
Type: Filter
Return: int — throttle window in seconds; 0 disables the throttle for this user.
Filters the scan cache duration for a specific user, overriding the global Cache Duration setting.
add_filter( 'wcrda_on_the_fly_cache_duration', function( $duration, $user_id ) {
// VIP customers get a shorter cache (10 minutes).
if ( get_user_meta( $user_id, 'is_vip', true ) ) {
return 10 * 60;
}
return $duration;
}, 10, 2 );
Parameters: int $cache_duration_seconds, int $user_id
wcrda_on_the_fly_orders
Type: Filter
Return: WC_Order[] — modified list of orders to scan for this user.
Filters the orders retrieved for a user’s on-the-fly scan. Use this to add, remove, or reorder orders before the permission check loop runs.
add_filter( 'wcrda_on_the_fly_orders', function( $orders, $user_id ) {
// Remove a specific order from the scan.
return array_filter( $orders, function( $order ) {
return $order->get_id() !== 1234;
} );
}, 10, 2 );
Parameters: WC_Order[] $orders, int $user_id
wcrda_after_on_the_fly_processing
Type: Action
Fires after the on-the-fly scan has completed for a user, after the cache timestamp is updated.
add_action( 'wcrda_after_on_the_fly_processing', function( $user_id, $permissions_granted ) {
if ( $permissions_granted ) {
// New files were granted to this user on this visit.
}
}, 10, 2 );
Parameters: int $user_id, bool $permissions_granted