---
title: Actions and filters
description: "GOCSM exposes WordPress actions for observing completed operations and filters for changing policy or values. Register callbacks with `add_action()` or `add_filter()`, including the accepted argument count. Filters must return the filtered value on every path. Register early enough for the…"
url: "https://brightleafdigital.io/docs/actions-and-filters/"
updated: "2026-10-20"
category: GravityOps Code Snippet Manager / Advanced
---

# Actions and filters

GOCSM exposes WordPress actions for observing completed operations and filters for changing policy or values. Register callbacks with `add_action()` or `add_filter()`, including the accepted argument count. Filters must return the filtered value on every path.

Register early enough for the event you need. A small custom plugin or MU plugin can observe PHP loading from the start of a request. A managed snippet can register callbacks for later events, but cannot observe its own earlier loading events.

Snippet and collection objects supplied to these hooks are snapshots. Changing an action argument does not save a change. Action callbacks should finish without throwing exceptions and should avoid recursively starting the same operation.

## Snippet lifecycle

| Action | Arguments, in order | Timing |
| --- | --- | --- |
| `gocsm_snippet_created` | `int $id`, `Snippet $snippet`, `string $origin` | After a new snippet's source and related data have been saved. |
| `gocsm_snippet_saved` | `int $id`, `Snippet $snippet`, `Snippet\|null $previous`, `string $origin` | After source, configuration, tags where applicable, and revision capture. Also fires for creation. |
| `gocsm_snippet_status_changed` | `int $id`, `string $status`, `string $old_status`, `string $origin`, `Snippet $snippet` | After an actual persisted status change. Includes automatic error disabling and orphan detection. |
| `gocsm_snippet_activated` | `int $id`, `Snippet $snippet`, `string $origin` | After a transition to Active, following generation and path/hash persistence. |
| `gocsm_snippet_deactivated` | `int $id`, `Snippet $snippet`, `string $origin` | After a transition to Inactive, including run-once completion and overwriting an active snippet during import. Error/orphan transitions use the status-changed action instead. |
| `gocsm_before_delete_snippet` | `int $id`, `Snippet $snippet`, `string $origin` | Before deleting the snippet's database row and associated data; generated-file cleanup may already have happened. |
| `gocsm_snippet_deleted` | `int $id`, `Snippet $snippet`, `string $origin` | After the snippet row has been deleted. Also fires for each member of a deleted collection, after the collection transaction commits. |

Completed save events cover editor and Abilities API saves/patches (`save`), JSON import (`import`), Code Snippets migration (`code_snippets_import`), initial GitHub discovery (`sync`), automatic standalone adoption (`collection_adoption`), manual updates (`manual_update`), inline automatic updates (`sync_update`), cron updates (`cron_update`), and revision restoration (`restore`). `$previous` is null for creation. Skipped imports and unchanged sync entries do not emit save events. Imports can report configuration warnings; inspect their batch report when those details matter.

Additional status origins are `activate`, `deactivate`, `run_once`, `execution`, `fatal`, `render`, and `status` for other direct status writes. Deletion origins are `delete` and `collection_delete`. Direct low-level repository saves are persistence helpers and do not emit completed-operation save events.

`gocsm_snippet_validation_errors` filters an initially empty `string[] $errors`, with `Snippet $proposed`, `SnippetConfig[] $configs`, and `string $origin`. Return additional errors to refuse a save, activation, import, update, or restore. This does not replace built-in validation. The configuration array is empty for imports and initial GitHub discovery, which run this policy before parsing their configurations. Return an array of string messages; malformed returns also block the operation.

```
add_filter( 'gocsm_snippet_validation_errors', function ( $errors, $snippet, $configs, $origin ) {
    if ( 'activate' === $origin && str_contains( $snippet->name, '[draft]' ) ) {
        $errors[] = 'Remove the draft marker before activating this snippet.';
    }
    return $errors;
}, 10, 4 );
```

`gocsm_snippet_adopted` receives `int $snippet_id`, `int $collection_id`, and `int $original_id` (the Code Snippets ID, or zero). It fires after a successful collection handoff, source/config persistence, revision capture and generated-file cleanup. Adoption also emits the normal completed save event with origin `collection_adoption`; failed or ambiguous matches emit neither completed event.

## PHP execution

| Hook | Arguments, in order | Behavior |
| --- | --- | --- |
| Filter: `gocsm_should_execute_snippet` | `bool $execute`, `Snippet $snippet` | Starts as true for an eligible PHP snippet, immediately before its execution attempt. Returning false skips this attempt without changing status or consuming run-once behavior. Existing scope and safe mode still apply. |
| Filter: `gocsm_safe_mode_duration` | `int $duration` | Seconds safe mode stays on in the browser after the safe-mode URL is opened. Default one hour; `0` limits it to that single request. Register it outside a snippet, since snippets do not run in safe mode. |
| Action: `gocsm_before_execute_snippet` | `int $id`, `Snippet $snippet` | Before the execution attempt, including attempts that later fail integrity checking. |
| Action: `gocsm_snippet_executed` | `int $id`, `Snippet $snippet` | After successful file/eval execution and run-once processing. The snapshot describes the execution input; query the repository for the resulting status. |
| Action: `gocsm_snippet_execution_failed` | `int $id`, `string $message`, `Snippet $snippet` | After disabling and logging a failed attempt, or an attributed shutdown fatal from a snippet callback. |

The before/success actions run outside the loader's current-snippet attribution window. Integrity failures, missing files without eval fallback, and thrown exceptions never emit the success action or complete a run-once snippet. A success action reports successful top-level loading, not that every callback registered by the snippet will succeed later. Shutdown failure observers should do minimal work.

```
add_filter( 'gocsm_should_execute_snippet', function ( $execute, $snippet ) {
    if ( 'maintenance-task' === $snippet->manifest_id && wp_doing_ajax() ) {
        return false;
    }
    return $execute;
}, 10, 2 );
```

## Configuration and generated files

| Hook | Arguments, in order | Behavior |
| --- | --- | --- |
| Filter: `gocsm_config_value` | `string $value`, `SnippetConfig $config` | Submitted expression before save/import/restore validation. Invalid expressions block application. |
| Filter: `gocsm_injected_config_value` | `string $value`, `SnippetConfig $config` | Stored expression before injection revalidation. Invalid expressions fall back to the source default. |
| Action: `gocsm_configs_synchronized` | `int $id`, `SnippetConfig[] $configs` | After synchronized configuration rows are persisted. Cached source-block and other snippet data may be written afterward; use `gocsm_snippet_saved` for a completed operation. |
| Filter: `gocsm_generated_content` | `string $content`, `Snippet $snippet`, `SnippetConfig[] $configs` | Content before syntax validation, writing, and hashing. PHP/JS/CSS include any generated header; HTML supplies only markup and adds its protected guard afterward. Eval preparation applies the same filter to injected source without a generated header, then validates it. |
| Action: `gocsm_snippet_generated` | `Snippet $snippet`, `GenerationResult $result` | Successful file generation or validated eval preparation, before the caller saves status/path/hash. |
| Action: `gocsm_snippet_generation_failed` | `Snippet $snippet`, `string[] $errors` | Generation failed; the caller determines how to handle it. |

Config values are source-language expressions, not evaluated PHP values: return `'42'`, not integer `42`, for a numeric expression. Generated content must be a string. A non-string result fails generation. Keep generation/configuration filters deterministic: file-based snippets use the filtered content until regenerated, while eval prepares it on each execution. Re-activate or save active snippets after changing a generation filter.

## GitHub synchronization and updates

These hooks belong to tracked GitHub collections, which need the Premium or Agency plan. The plan is checked before any of them runs, so returning true from a filter cannot enable a feature the license does not include.

| Hook | Arguments, in order | Behavior |
| --- | --- | --- |
| Filter: `gocsm_should_sync_collection` | `bool $sync`, `Collection $collection` | Starts true for an existing GitHub collection. False avoids network/reconciliation work. |
| Action: `gocsm_before_sync_collection` | `int $collection_id`, `Collection\|null $collection` | Before an attempted sync; omitted for a policy skip. |
| Action: `gocsm_collection_sync_failed` | `int $collection_id`, `array $result` | A sync returned a failed result with errors. |
| Action: `gocsm_collection_sync_completed` | `int $collection_id`, `array $result` | A sync returned, including failures, HTTP 304, and policy skips. A policy skip adds `skipped => true`. |
| Filter: `gocsm_should_auto_update_snippet` | `bool $allow`, `Snippet $snippet`, `Collection $collection`, `string $severity`, `string $origin` | Starts true for an eligible update. Runs for both inline sync and cron. Can veto; cannot enable collection auto-update or override warning-severity review. |
| Action: `gocsm_snippet_update_pending` | `int $id`, `string $severity` | An incoming update has been staged for later application. |
| Action: `gocsm_snippet_update_applied` | `int $id`, `Snippet $previous`, `string $origin` | After a manual, inline sync, or cron update is saved and pending fields are cleared. |
| Action: `gocsm_snippet_orphaned` | `int $id`, `Snippet $snippet`, `string $origin` | After a snippet missing from its collection manifest becomes Orphaned. |

The auto-update origins are `sync_update` and `cron_update`; manual application uses `manual_update`. A successful collection result can include per-snippet fetch/reconciliation failures in its sync log. Completion reflects the collection result, not a promise that every member updated.

## Rendering and assets

| Filter | Arguments, in order | Behavior |
| --- | --- | --- |
| `gocsm_should_run_on_page` | `bool $should_run`, `Snippet $snippet` | Built-in page-targeting result for JS, CSS, and HTML location output. Can add custom targeting. HTML shortcodes and blocks intentionally bypass page targeting. |
| `gocsm_script_enqueue_args` | `array $enqueue`, `Snippet $snippet`, `string $context` | Keys: `src`, `dependencies`, `version`, `args` (`in_footer`, optional `strategy`). |
| `gocsm_style_enqueue_args` | `array $enqueue`, `Snippet $snippet`, `string $context` | Keys: `src`, `dependencies`, `version`, `media`. |
| `gocsm_html_output` | `string $markup`, `Snippet $snippet`, `string $context` | Verified markup for each rendering. Context is `location`, `shortcode` or `block`. Never runs for missing files or failed integrity checks. |

Asset context is `frontend`, `admin`, or `login`. Asset filters run after context, page targeting, and file-existence checks. Return the argument array; omitted keys keep their defaults, while malformed values skip enqueueing. Handles remain `gocsm-snippet-{id}`. An invalid HTML output return produces an empty string. Escape any dynamic data inserted into HTML by your callback.

## Import, export, revisions, and organization

| Hook | Arguments, in order | Behavior |
| --- | --- | --- |
| Filter: `gocsm_import_snippet_data` | `array $snippet_data`, `int $collection_id` | Portable JSON snippet before validation and conflict detection, during both preview and import. Collection ID is 0 for standalone snippets or a preview of a collection that does not yet exist. |
| Filter: `gocsm_code_snippets_mapping` | `array $mapping`, `array $row` | Code Snippets mapping during preview and import. Return `ok` (bool), `type`, `scope` (array), `notes` (array), and `reason` (string). Supported types and nonempty source are still checked. |
| Action: `gocsm_snippet_imported` | `int $id`, `string $origin`, `bool $overwriting` | After an imported snippet is saved, before optional activation. Skips/rejections do not emit this event. |
| Action: `gocsm_import_completed` | `array $report`, `string $origin` | Batch finished, including partial failures. Origins are `import` (JSON files and Import from GitHub) and `code_snippets_import`. |
| Filter: `gocsm_export_snippet_data` | `array $payload`, `Snippet $snippet` | One snippet's portable JSON object. |
| Filter: `gocsm_export_payload` | `array $payload`, `int[] $snippet_ids` | Complete JSON export envelope. Retain required format/version/collection fields for round-tripping. |
| Action: `gocsm_revision_created` | `int $id`, `Revision $revision` | After a new revision is inserted and retention applied. Unchanged snapshots do not create an event. |
| Filter: `gocsm_revisions_to_keep` | `int $keep`, `int $id` | Existing retention filter; minimum two revisions. |
| Action: `gocsm_revision_restored` | `int $id`, `Revision $revision` | Existing event after successful restoration. Also emits the completed save event with origin `restore`. |
| Action: `gocsm_folder_created` | `int $folder_id`, `array $folder` | A new folder was created. Reusing an existing folder emits no event. |
| Action: `gocsm_folder_renamed` | `int $folder_id`, `array $folder`, `array $previous` | An existing folder's row changed. |
| Action: `gocsm_folder_deleted` | `int $folder_id`, `array $previous` | An empty folder was deleted. |
| Action: `gocsm_snippet_folder_changed` | `int $id`, `int\|null $folder_id`, `int\|null $previous`, `string $origin` | Folder changed through a save or bulk move (`move`). Null means no folder. |
| Action: `gocsm_snippet_tags_changed` | `int $id`, `array $tags`, `array $previous` | Tags changed through editing, import, or sync. Both arrays contain tag rows. |

Export filters affect JSON; portable/runnable source-file exports retain their existing format. Configuration injection filters also apply when generating runnable exports.

## Security scan

| Hook | Arguments, in order | Behavior |
| --- | --- | --- |
| Filter: `gocsm_security_scan_findings` | `array $findings`, `string $source`, `string $type` | Findings for a snippet's source, each with `severity` (`high`, `medium` or `low`), `line` and `message`. Add your own checks or remove ones you have reviewed. Findings are advisory and never block saving or activation. |

## Admin extension points and existing WordPress hooks

`gocsm_snippet_row_actions` filters the action HTML array, keyed by action name, with a `Snippet $snippet` second argument. Escape added markup. Navigation links use `target="_blank" rel="noopener noreferrer"`; AJAX controls should be buttons. Register your own authorized handler for any added operation.

Four editor actions receive a `Snippet $snippet`: `gocsm_before_snippet_editor` (before the form), `gocsm_snippet_editor_main` (end of the main column), `gocsm_snippet_editor_sidebar` (before save controls), and `gocsm_after_snippet_editor` (after the form). Escape your output. Rendering fields does not automatically persist them; integrations own their request handling and permission/nonce checks.

The existing cron entry points are `gocsm_check_collections`, `gocsm_apply_auto_updates`, and `gocsm_prune_sync_log`. `gocsm_fs_loaded` fires when Freemius initializes. WordPress's option filters/actions cover GOCSM settings (`gocsm_default_auto_update`, `gocsm_sync_log_retention_days`, `gocsm_eval_fallback_mode`, `gocsm_opcache_invalidation_mode`, `gocsm_performance_tracking`); its HTTP and cron hooks cover request customization and scheduling. Standard list-table column hooks remain available. Capability, API code-write, safe-mode, SSL, hash, and syntax checks retain their existing rules.
