Files
2026-07-02 15:54:39 -06:00

81 lines
3.2 KiB
PHP

<?php
/**
* Notifier - registers Gravity Forms notification events for entry-bound cases
* (success, resubmit) and sends wp_mail for validation-time failures and repeated
* 401s (cases with no entry). Every wp_mail is return-checked - a false is logged
* and escalated, never silently dropped.
*
* @package ESP\Instanda
*/
declare(strict_types=1);
namespace ESP\Instanda;
final class Notifier {
/** gform_notification_events - admins attach native Notifications to these. */
public function register_events(array $events, array $form): array {
$events['espinstanda_quote_success'] = 'INSTANDA - quote created';
$events['espinstanda_resubmit_success'] = 'INSTANDA - quote created on resubmit';
return $events;
}
public function validation_failure_alert(Transaction $tx, ?Api_Result $result = null): bool {
$recipients = $this->alert_recipients();
if (!$recipients) {
return false;
}
$error = $result !== null ? $result->error_string() : (string) $tx->error_detail;
$body = "A 'Start a Quote' submission failed before a Gravity Forms entry was created.\n\n"
. 'Environment: ' . strtoupper($tx->environment) . "\n"
. 'Customer: ' . $tx->customer_email . "\n"
. 'Role: ' . $tx->role_label . "\n"
. 'Error: ' . $error . "\n"
. 'Transaction: #' . $tx->id . "\n\n"
. 'Review and resubmit: ' . admin_url('admin.php?page=espinstanda-transactions&status=failed') . "\n";
return $this->send($recipients, '[ESP INSTANDA] Quote submission failed', $body);
}
public function credential_failure_alert(): bool {
$recipients = $this->alert_recipients();
if (!$recipients) {
return false;
}
return $this->send(
$recipients,
'[ESP INSTANDA] Repeated authentication failures (401)',
"INSTANDA returned repeated 401 Unauthorized responses. Check the API credentials on the INSTANDA settings screen.\n"
);
}
/** Option-B lead recovery: email the customer their freshly minted quote link. */
public function customer_quote_ready_email(Transaction $tx, string $fresh_url): bool {
if ($tx->customer_email === '' || $fresh_url === '') {
return false;
}
$body = "Thanks for starting a quote with ESP Specialty.\n\n"
. "Your quote is ready. Continue here:\n{$fresh_url}\n";
return $this->send([$tx->customer_email], 'Your ESP Specialty quote is ready', $body);
}
/** @return list<string> */
private function alert_recipients(): array {
$raw = (string) get_option('espinstanda_alert_emails', '');
$list = array_filter(array_map('trim', explode(',', $raw)), static fn ($e) => $e !== '' && is_email($e));
return array_values($list);
}
private function send(array $to, string $subject, string $body): bool {
$ok = wp_mail($to, $subject, $body);
if (!$ok) {
Logger::error('wp_mail failed for recipients: ' . implode(', ', $to));
if (function_exists('do_action')) {
do_action('esp_instanda_mail_failed', $to, $subject);
}
}
return (bool) $ok;
}
}