The plugin’s public extension surface, grouped by what you’d want to do with it.
Ground Rules #
Before writing a callback:
- Filters must return their filtered value on every path, including early bails. Returning nothing replaces the value with
nullfor every later callback. - Be defensive. Don’t assume a parameter’s type; validate at the top of the callback.
- Never log field values or full entry data. The plugin’s own records are redacted deliberately — don’t undo that in an extension.
Tuning Intervals #
| Filter | Default | Purpose |
|---|---|---|
rfsfgf_worker_interval |
900 |
Seconds between worker runs. One-minute floor. The health threshold (two intervals) follows it automatically. |
rfsfgf_failed_check_interval |
43200 |
Seconds between maintenance scans. |
rfsfgf_failed_check_first_run |
— | UTC timestamp anchoring the maintenance event’s first run, so it lands at a preferred time of day. |
rfsfgf_missed_run_grace |
2 × worker interval | How late an occurrence must be before a skipping feed treats it as missed. Never below one worker interval. |
// Poll every five minutes. Only worth doing if the host invokes WordPress that often.
add_filter( 'rfsfgf_worker_interval', function ( $seconds ) {
return 300;
} );
Interval changes are detected during registration, and an event registered at the wrong interval is repaired — with the previous timestamp and interval recorded.
Shaping Schedules #
| Filter | Receives | Purpose |
|---|---|---|
rfsfgf_schedule_created |
$schedule, $meta, $entry |
Adjust the normalized schedule as a series is created. |
rfsfgf_next_occurrence |
$target, $schedule, $after |
Adjust a calculated target before it is stored. |
rfsfgf_next_occurrence is the hook for calendar rules the settings don’t cover — a blackout window, a business-day offset, an organisation-specific holiday list.
add_filter( 'rfsfgf_next_occurrence', function ( $target, $schedule, $after ) {
if ( ! is_int( $target ) ) {
return $target;
}
// Push a target landing on a company holiday to the next day.
return my_is_holiday( $target ) ? $target + DAY_IN_SECONDS : $target;
}, 10, 3 );
Return a valid future timestamp. A filter that returns something unusable will produce a schedule you can’t explain from the UI.
Processing Events #
| Action | Receives | Fires |
|---|---|---|
rfsfgf_attempt_started |
$attempt, $id, $context |
As an attempt begins. |
rfsfgf_attempt_completed |
$result, $context |
When an attempt resolves. The context is redacted. |
rfsfgf_lock_recovered |
$series_id |
When a stale claim is recovered. |
Use these for structured monitoring — a metrics pipeline, an audit trail, a dashboard.
add_action( 'rfsfgf_attempt_completed', function ( $result, $context ) {
if ( ! is_array( $result ) ) {
return;
}
my_metrics_counter( 'rfsfgf.attempt.' . rgar( $result, 'outcome', 'unknown' ) );
}, 10, 2 );
Lifecycle and Transition Events #
| Action | Receives | Fires |
|---|---|---|
rfsfgf_series_pause |
$series |
A series is paused. |
rfsfgf_series_resume |
$series |
A series is resumed. |
rfsfgf_series_cancel |
$series |
A series is canceled. |
rfsfgf_series_first_failure |
$series |
The first failure in a new sequence. |
rfsfgf_series_failed |
$series |
The failure threshold was reached. |
rfsfgf_series_recovered |
$series |
A success resolved the issue. |
rfsfgf_parent_series_canceled |
$entry_id, $count, $reason |
A parent was trashed or deleted, cancelling its series. $reason distinguishes trashed from deleted. |
These are the right hooks for routing alerts somewhere other than the Admin Email — Slack, a helpdesk, a log.
add_action( 'rfsfgf_series_failed', function ( $series ) {
if ( ! is_array( $series ) ) {
return;
}
my_alerting_channel( sprintf(
'Recurring series #%d stopped after %d consecutive failures.',
(int) rgar( $series, 'id' ),
(int) rgar( $series, 'consecutive_failures' )
) );
} );
The historical
rfsfgf_auto_form_submissions_failed_entriesreport filter is superseded by these events. Periodic full-history email generation has been removed.
Schedule Propagation #
| Action | Receives | Fires |
|---|---|---|
rfsfgf_schedule_applied |
$series_id, $schedule, $source |
A schedule was applied to one series. |
rfsfgf_feed_schedule_applied |
$feed_id, $saved, $skipped |
A bulk feed application finished, with counts of applied and skipped series. |
rfsfgf_next_submission_changed |
$series_id, $target, $schedule |
A series’ next target was moved. |
Useful for auditing who changed what, and for reconciling a bulk application that skipped locked series.
Diagnostics #
| Filter | Receives | Purpose |
|---|---|---|
rfsfgf_diagnostic_context |
$context |
Adjust the diagnostic context before the report is produced. |
The plugin applies its own bounded allowlist after this filter, so you cannot use it to leak values into a report. Adding non-sensitive environment detail is the intended use.
Shortcode Visibility #
| Filter | Receives | Purpose |
|---|---|---|
rfsfgf_shortcode_can_view |
$can_view, $context, $args |
Decide whether a shortcode renders, before anything is output. |
$context is overview or entry_widget. For the entry widget, $args holds the entry and form.
add_filter( 'rfsfgf_shortcode_can_view', function ( $can_view, $context, $args ) {
if ( 'entry_widget' === $context && ! $can_view ) {
return get_current_user_id() && (int) rgar( $args['entry'], 'created_by' ) === get_current_user_id();
}
return $can_view;
}, 10, 3 );
Widening the read does not widen the write. The buttons and the handler behind them still require recurring_form_submissions_manage_resubmissions.
Capability #
recurring_form_submissions_manage_resubmissions
Granted to administrators automatically. Every operational surface and handler checks it; every request also verifies its nonce and that the parent, form and feed belong together.
Gravity Forms Integration Points #
The plugin registers ordinary Gravity Forms extension points you can use as usual:
| Point | Names |
|---|---|
| Notification events | auto_submit_success, auto_submit_fail, auto_submits_complete |
| Merge tags | {resubmission_progress}, {is_auto_submission}, {rfsfgf_is_parent_submission}, {total_resubmissions}, {rfsfgf_feed_label} |
| Entry meta | Feed Label, Is Parent Submission, Is Auto Submission, Total Resubmissions, Resubmissions Progress |
Child entries are created through normal Gravity Forms processing, so gform_after_submission and friends fire on them exactly as they would for a human submission. Use {is_auto_submission} or the entry meta to tell them apart.