Created
January 23, 2025 22:14
-
-
Save chrisegg/dd020a24c84b5cef3984024a592ad318 to your computer and use it in GitHub Desktop.
Adds a unread indicator to Gravity Forms entries menu in the WordPress admin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Gravity Forms Unread Entries Indicator | |
* Description: Adds an indicator to the Gravity Forms Entries menu showing the number of unread entries. | |
* Version: 1.0 | |
* Author: Chris Egglelston | |
* Website: https://gravityranger.com | |
*/ | |
if (!defined('ABSPATH')) { | |
exit; // Exit if accessed directly | |
} | |
// Add unread entries indicator to the Entries submenu | |
add_action('admin_menu', 'add_unread_entries_indicator_to_entries', 999); | |
function add_unread_entries_indicator_to_entries() { | |
// Get all forms | |
$forms = GFAPI::get_forms(); | |
// Initialize unread count | |
$unread_count = 0; | |
// Loop through all forms and count unread entries | |
foreach ($forms as $form) { | |
$entries = GFAPI::get_entries($form['id'], array(), null, array('status' => 'active')); | |
foreach ($entries as $entry) { | |
if (!gform_get_meta($entry['id'], 'is_read')) { | |
$unread_count++; | |
} | |
} | |
} | |
// Add the bubble to the Entries submenu | |
global $submenu; | |
if (isset($submenu['gf_edit_forms'])) { | |
foreach ($submenu['gf_edit_forms'] as $key => $item) { | |
if ($item[2] === 'gf_entries') { // "Entries" submenu slug | |
$submenu['gf_edit_forms'][$key][0] .= " <span class='update-plugins count-$unread_count' style='margin-left: 5px;'> | |
<span class='plugin-count'>$unread_count</span> | |
</span>"; | |
break; | |
} | |
} | |
} | |
} | |
// Mark entries as read/unread when toggled via AJAX | |
add_action('wp_ajax_gf_toggle_entry_read', 'update_unread_count'); | |
function update_unread_count() { | |
// Get entry ID and action from the AJAX request | |
$entry_id = isset($_POST['entryId']) ? absint($_POST['entryId']) : null; | |
$mark_as_read = isset($_POST['markAsRead']) ? filter_var($_POST['markAsRead'], FILTER_VALIDATE_BOOLEAN) : true; | |
if (!$entry_id) { | |
wp_send_json_error('No entry ID provided.'); | |
return; | |
} | |
// Update the entry's read status | |
gform_update_meta($entry_id, 'is_read', $mark_as_read); | |
// Recalculate unread count | |
$unread_count = 0; | |
$forms = GFAPI::get_forms(); | |
foreach ($forms as $form) { | |
$entries = GFAPI::get_entries($form['id'], array(), null, array('status' => 'active')); | |
foreach ($entries as $entry) { | |
if (!gform_get_meta($entry['id'], 'is_read')) { | |
$unread_count++; | |
} | |
} | |
} | |
// Send back the new unread count | |
wp_send_json_success(array('unread_count' => $unread_count)); | |
} | |
// Enqueue inline JavaScript | |
add_action('admin_enqueue_scripts', 'add_inline_unread_entries_script'); | |
function add_inline_unread_entries_script() { | |
// Enqueue jQuery as a dependency | |
wp_enqueue_script('jquery'); | |
// Add inline JavaScript | |
$inline_script = <<<EOT | |
jQuery(document).on('click', 'a[id^="mark_read_"], a[id^="mark_unread_"]', function (e) { | |
e.preventDefault(); | |
// Extract the entry ID from the link ID | |
const entryId = jQuery(this).attr('id').split('_')[2]; | |
const isMarkingAsRead = jQuery(this).attr('id').startsWith('mark_read'); | |
// Perform the AJAX request to mark the entry as read/unread | |
jQuery.post(ajaxurl, { | |
action: 'gf_toggle_entry_read', | |
entryId: entryId, | |
markAsRead: isMarkingAsRead // Pass whether we're marking it as read | |
}).done(function (response) { | |
if (response.success) { | |
const unreadCount = response.data.unread_count; | |
// Update the bubble in the menu | |
const menuItem = jQuery('#toplevel_page_gf_edit_forms .plugin-count'); | |
if (menuItem.length) { | |
menuItem.text(unreadCount); | |
// Hide the bubble if there are no unread entries | |
if (unreadCount === 0) { | |
menuItem.parent().hide(); | |
} else { | |
menuItem.parent().show(); | |
} | |
} | |
// Let Gravity Forms handle the DOM toggle for read/unread | |
ToggleRead(entryId, ''); | |
} else { | |
console.error('Error:', response.data); | |
} | |
}).fail(function () { | |
console.error('Failed to toggle read/unread status.'); | |
}); | |
}); | |
EOT; | |
wp_add_inline_script('jquery', $inline_script); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment