Skip to content

Instantly share code, notes, and snippets.

@chrisegg
Created January 23, 2025 22:14
Show Gist options
  • Save chrisegg/dd020a24c84b5cef3984024a592ad318 to your computer and use it in GitHub Desktop.
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.
<?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