Skip to content

Entries: make approval/denial email content customizable (EVF-2724) - #1632

Open
rajatgautam755421 wants to merge 4 commits into
pre-developfrom
fix/EVF-2724-customizable-entry-approval-emails
Open

Entries: make approval/denial email content customizable (EVF-2724)#1632
rajatgautam755421 wants to merge 4 commits into
pre-developfrom
fix/EVF-2724-customizable-entry-approval-emails

Conversation

@rajatgautam755421

Copy link
Copy Markdown
Contributor

Summary

  • The emails sent to a user when their entry is approved or denied were fully hardcoded (only customizable via PHP filters, no settings UI).
  • Added shared helpers on EVF_Admin_Entries (get_entry_status_email_subject(), get_entry_status_email_message(), is_entry_status_email_enabled()) that read from options, falling back to the original hardcoded copy as defaults.
  • Wired both the admin-UI approve/deny action (EVF_Admin_Entries::update_status()) and the token-link approve/deny flow (EVF_Form_Task::evf_admin_approve_entry()/evf_admin_deny_entry()) through these helpers, so both paths stay in sync.
  • All pre-existing filters (everest_forms_entry_submission_approval_subject, everest_forms_entry_approval_message, everest_forms_entry_submission_denial_subject, everest_forms_entry_denial_message) still fire with the same signature.
  • Fixed a pre-existing bug: the token-link deny handler filtered its subject through the approval filter name instead of the denial one.
  • Settings UI (Subject/Message/Enable toggle for both emails) is added in a companion PR on everest-forms-pro under Settings > Advanced > Entries Management, next to the existing admin-approval-entries settings.

Scope note: this ticket's "entry approval notification to admin" item turned out to be dead code on inspection — Pro already has Subject/Message/To-Address settings for it, but no code path anywhere actually sends that email (the approval token is generated but never emailed). Left untouched here; flagging as a separate follow-up rather than building a new send path under this ticket.

Test plan

  • Approve/deny an entry from the Entries list admin UI, confirm the customized subject/message is used
  • Click an approve/deny token link (from the admin's own entry-approval email, if the admin notification is separately configured) and confirm the same customized content is used
  • Toggle the enable switch off for one email type and confirm it stops sending while the other still works
  • Confirm a legacy everest_forms_entry_approval_message / everest_forms_entry_denial_message filter still fires and can alter the final message

Jira: EVF-2724
Companion PR (everest-forms-pro settings UI): link to follow

The emails sent to a user when their entry is approved or denied were
hardcoded, with no settings UI (only PHP filters). Both the admin-UI
approve/deny action and the token-link approve/deny flow now read
subject/message/enable from options that Pro exposes in Entries
Management settings, falling back to the original hardcoded copy as
defaults so existing sites see no change.

Also fixes the token-link deny handler firing the wrong ("approval")
subject filter instead of the denial one.

EVF-2724
@rajatgautam755421
rajatgautam755421 marked this pull request as ready for review August 6, 2026 11:34
@rajatgautam755421 rajatgautam755421 self-assigned this Aug 6, 2026
…n email suppression

Approve/deny links now use separate, entry-bound tokens (verified with
hash_equals) instead of a shared token checked with in_array() against
the whole option, which let one entry's link approve/deny another.
Tokens are invalidated after use and when an entry is deleted. Admin
redirects now exit properly and show a clear message on invalid/expired
links instead of silently falling through. update_status() now takes an
explicit is_bulk_action flag from the caller instead of trusting an
unverified $_GET param, and $subject/$message/name-matching are
consistent across all status-email code paths.

@deepench deepench left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rajatgautam755421 Please check the below comments:-

case 'approved':
foreach ( $entry_ids as $entry_id ) {
if ( EVF_Admin_Entries::update_status( $entry_id, $doaction ) ) {
if ( EVF_Admin_Entries::update_status( $entry_id, $doaction, true ) ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This true disables the feature. update_status() only sends when $is_bulk_action is false, so the new subject/message helpers never run. The email that goes out is the hardcoded block below, which ignores the new options and the Enable toggle.

Drop the third param and delete the hardcoded block, let update_status() send.

case 'denied':
foreach ( $entry_ids as $entry_id ) {
if ( EVF_Admin_Entries::update_status( $entry_id, $doaction ) ) {
if ( EVF_Admin_Entries::update_status( $entry_id, $doaction, true ) ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the denial email.

$email = $value;
}
$evf_denial_key = 'denial_token_' . $evf_admin_entry_id;
$evf_admin_expected_token = isset( $evf_admin_entry_saved_token[ $evf_denial_key ] ) ? $evf_admin_entry_saved_token[ $evf_denial_key ] : '';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaks deny links already sent out. Old entries only have approval_token_ saved, so this returns '' and we wp_die() with "invalid or has already been used".

Needs a fallback:

if ( '' === $evf_admin_expected_token ) {
	$legacy_key               = 'approval_token_' . $evf_admin_entry_id;
	$evf_admin_expected_token = isset( $evf_admin_entry_saved_token[ $legacy_key ] )
		? $evf_admin_entry_saved_token[ $legacy_key ]
		: '';
}

Comment thread includes/class-evf-form-task.php Outdated
$evf_approval_token = array(
$evf_approval_key => $token,
// Separate tokens for approve and deny so one link can't be used to perform the other action.
$evf_new_token = array_merge(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two tokens per entry now instead of one, on an autoloaded option.

The check above never returns. get_option() with a default always returns a value, so tokens get written for every submission even when admin approval is off. Fix it here:

if ( 'yes' !== $evf_admin_entry_enable ) {
	return;
}

$name = '';

foreach ( $entry_meta as $key => $value ) {
if ( preg_match( '/^name/', $key ) ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/^name/ is too loose. Meta keys come from the field label, so "Name of Business" gives name_of_business_4821 and matches. No break in the loop, so the last match wins and overwrites the first+last name built below.

Use /^name_/.

@deepench

Copy link
Copy Markdown
Contributor

@rajatgautam755421 Please check this while Enable admin approval entries setting is disable below settings are visible. The settings should be hidden.

image

- Bulk approve/deny passed is_bulk_action=true to update_status(), which
  suppresses its email send, then a separate hardcoded block sent an email
  anyway - bypassing the new subject/message options and Enable toggle
  entirely. Dropped the flag and deleted the dead hardcoded block so
  update_status() sends the customized email like the single-entry path.
- Deny-link handler only checked the new per-entry denial_token_<id> key,
  so deny links already sent before this change (which only ever had the
  old shared approval_token_<id>) would 403 as invalid. Added a fallback
  to the legacy key.
- evf_set_approval_status()'s enable check used isset() on an option that
  always has a default, so it was always true and tokens got written to an
  autoloaded option on every submission regardless of whether admin
  approval was even on. Check the actual 'yes'/'no' value instead.
- /^name/ matched any meta key starting with "name", not just the actual
  name field (e.g. a "Name of Business" field's meta key) and could
  overwrite the real name. Tightened to /^name_/ in all 4 places this
  pattern was copy-pasted.
@rajatgautam755421

Copy link
Copy Markdown
Contributor Author

@deepench issues fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants