Skip to content

Developer Reference

Filters

Notifications

voxel_adrotate_sync/milestone_email

Replace the milestone email wholesale — recipient, subject, body, headers. Return the modified array.

php
add_filter( 'voxel_adrotate_sync/milestone_email', function ( $email, $post_id, $threshold, $type ) {
    $email['subject'] = sprintf( 'Your ad just passed %d %s', $threshold, $type );
    $email['headers'][] = 'Bcc: [email protected]';
    return $email;
}, 10, 4 );

Targeting

voxel_adrotate_sync/visitor_location (default null)

Override geo detection entirely. Return a location array, or a bare two-letter country string. Useful for testing, or for driving geo from a source of your own.

php
add_filter( 'voxel_adrotate_sync/visitor_location', fn() => [
    'country'     => 'US',
    'region'      => 'California',
    'region_code' => 'CA',
    'city'        => 'Los Angeles',
] );

voxel_adrotate_sync/geo_lookup

Used by the Custom geo provider. Receives the IP; return a location array.

voxel_adrotate_sync/geo_country_aliases

Extend the country name → ISO-2 map used by geo= rules.

php
add_filter( 'voxel_adrotate_sync/geo_country_aliases', function ( $map ) {
    $map['HOLLAND'] = 'NL';
    return $map;
} );

voxel_adrotate_sync/has_consent

Override the GDPR consent decision — for integrating a consent-management platform server-side.

Assets

voxel_adrotate_sync_chartjs_src

Chart.js is bundled locally by default, so there's no third-party request. Filter the URL to point at a CDN or your own copy, or return false to skip it entirely if your theme already ships Chart.js.

php
add_filter( 'voxel_adrotate_sync_chartjs_src', '__return_false' );

voxel_adrotate_sync/preload_ad_assets (default false)

By default the ad CSS and responsive script load only where an ad can appear. Enable this to force them everywhere — needed if you place ads through AdRotate's own sidebar widgets or post injection, which the plugin can't detect server-side.

voxel_adrotate_sync/preload_stats_css (default true)

The stats widget enqueues its own CSS where placed, but Voxel's My Listings cards are built outside Elementor's enqueue cycle, so the CSS is forced site-wide by default. Return false to stop that and save a few KB per page, if you don't show banner stats inside My Listings cards.

Maintenance

voxel_adrotate_sync/bulk_resync_batch_size

Tune the bulk re-sync chunk size. Accepts 50 to 1000; defaults to 200.

Helper functions

Available once the plugin is active. Each defaults to the current post.

php
get_adrotate_banner_stats( $post_id = null, $period = 'all' );
get_adrotate_banner_schedule( $post_id = null );
get_adrotate_daily_stats( $post_id = null, $days = 30 );
get_adrotate_banner_revenue( $post_id = null );

$period accepts today, week, month, year or all.

php
$stats = get_adrotate_banner_stats( get_the_ID(), 'month' );
printf( '%d impressions, %d clicks', $stats['impressions'], $stats['clicks'] );

Shortcodes

ShortcodePurpose
[adrotate_banner_stats]Renders stats for the current banner.
[vas_ad]Targeting and consent wrapper — see Targeting.

Scheduled action

voxel_adrotate_sync/daily_expiry_scan runs daily. It demotes schedule-expired adverts to disabled and sends expiry warnings. Hook it to run your own daily work against banner data, or trigger it manually with WP-CLI:

bash
wp cron event run voxel_adrotate_sync/daily_expiry_scan

Notes on internals

  • Every database query uses prepare() with placeholders, or binds only internally-cast integers.
  • Statistics and schedule reads are cached as transients, with the TTL configurable in settings. The cache is invalidated the moment AdRotate records an impression or click, so figures never lag.
  • Dynamic-tag statistics are memoised per request: multiple tags on one card cost one stats query and one schedule query.
  • Text domain is voxel-adrotate-sync, with a .pot in /languages/. This is unchanged from before the plugin was renamed to Voxel Ads — the domain keys existing translations and stored settings.

Built by Code Wattz.