I have a working multisite, using the webhooks plugin and of course GravityForms, both latest versions. The site is in production and has been working flawlessly. However, we want to do an audit of the Webhooks and some forms have multiple “conditional” webhooks attached. So, the easiest I came up with was a wp-cli command, but I am only getting: “Unnamed Webhook”,N/A,“No mappings found”, even though each webhook is named and there are fields mapped.
This is the script:
<?php
if (defined('WP_CLI') && WP_CLI) {
class GF_Multisite_CLI {
public function list_forms($args, $assoc_args) {
if (!is_multisite()) {
WP_CLI::error('This command is intended for multisite setups.');
}
$sites = get_sites();
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
$site_name = sanitize_title(get_bloginfo('name'));
$site_id = $site->blog_id;
WP_CLI::log("\n--- Processing Site: {$site_name} (ID: {$site_id}) ---\n");
// Force unlock Webhook feeds for testing purposes
$this->unlock_webhook_feeds();
if (!class_exists('GFAPI')) {
WP_CLI::warning("Gravity Forms is not active on this site.");
restore_current_blog();
continue;
}
$forms = \GFAPI::get_forms();
if (empty($forms)) {
WP_CLI::log("No forms found on this site.");
restore_current_blog();
continue;
}
foreach ($forms as $form) {
$form_name = sanitize_title($form['title']);
$form_id = $form['id'];
WP_CLI::log("Processing Form: {$form['title']} (ID: {$form_id})");
if (class_exists('GF_Webhooks')) {
$webhook_addon = \GF_Webhooks::get_instance();
$webhook_feeds = $webhook_addon->get_feeds($form_id);
if (!empty($webhook_feeds)) {
$this->export_webhook_data_to_csv($site_name, $site_id, $form_name, $form_id, $webhook_feeds, $form['fields']);
} else {
WP_CLI::log("No webhooks found for Form: {$form['title']}");
}
} else {
WP_CLI::warning("Webhooks Add-On is not active for Form: {$form['title']}");
}
}
restore_current_blog();
}
}
private function unlock_webhook_feeds() {
global $wpdb;
$result = $wpdb->update(
"{$wpdb->prefix}gf_addon_feed",
['is_active' => 1], // Unlock the feed
['addon_slug' => 'gravityformswebhooks'] // Target the Webhooks Add-On
);
if ($result !== false) {
WP_CLI::log("Successfully unlocked Webhook feeds. Rows affected: {$result}");
} else {
WP_CLI::warning("Failed to unlock Webhook feeds.");
}
}
private function export_webhook_data_to_csv($site_name, $site_id, $form_name, $form_id, $webhook_feeds, $form_fields) {
$script_dir = __DIR__;
$site_dir = $script_dir . "/gravity-forms-reports/{$site_name}_{$site_id}";
if (!file_exists($site_dir)) {
if (!mkdir($site_dir, 0755, true)) {
WP_CLI::error("Unable to create directory {$site_dir}");
return;
}
}
$file_path = "{$site_dir}/form-{$form_name}_{$form_id}.csv";
$file = fopen($file_path, 'w');
if (!$file) {
WP_CLI::error("Unable to create CSV file at {$file_path}");
return;
}
// Write UTF-8 BOM
fwrite($file, "\xEF\xBB\xBF");
// Write CSV headers
fputcsv($file, ['Webhook Name', 'Webhook URL', 'Field Mappings'], ';');
// Write data for each webhook
foreach ($webhook_feeds as $feed) {
$webhook_name = $feed['meta']['name'] ?? 'Unnamed Webhook';
$webhook_url = $feed['meta']['request_url'] ?? 'N/A';
// Process mappings
$mappings = $this->get_field_mappings($feed, $form_fields);
$formatted_mappings = implode(' | ', $mappings);
fputcsv($file, [
$webhook_name,
$webhook_url,
$formatted_mappings,
], ';');
}
fclose($file);
WP_CLI::success("Webhook data exported: {$file_path}");
}
private function get_field_mappings($feed, $form_fields) {
$mappings = [];
if (isset($feed['meta']['mappings']) && is_array($feed['meta']['mappings'])) {
foreach ($feed['meta']['mappings'] as $webhook_field => $form_field_id) {
$form_field_label = $this->get_field_label_by_id($form_fields, $form_field_id);
$mappings[] = "{$webhook_field} => {$form_field_label}";
}
} else {
$mappings[] = 'No mappings found';
}
return $mappings;
}
private function get_field_label_by_id($fields, $field_id) {
foreach ($fields as $field) {
if ($field->id == $field_id) {
return $field->label;
}
}
return 'Unknown Field';
}
}
WP_CLI::add_command('gf_multisite', 'GF_Multisite_CLI');
}
I would expect an output like:
|Webhook Name|Webhook URL|Field Mappings|
| --- | --- | --- |
|CRM Integration|https://api.example.com/crm|email => Email Address
name => Full Name|
|Support Notification|https://api.example.com/support|message => Feedback|
But I am only getting ‘“Unnamed Webhook”,N/A,“No mappings found”’. I am pretty sure it has something to do, how I query the mappings, but I am at the end of my knowledge, if anyone can point me into the right direction.
Thank you