PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.2.13
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.2.13
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Admin / EntriesMailReceiver.php

EntriesMailReceiver.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.2.13, at includes/Admin/EntriesMailReceiver.php

208 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Entries Mail Receiver
4 *
5 * Sends an email notification to configured receivers each time a new
6 * NotificationX entry is inserted (e.g. a form submission).
7 *
8 * @package NotificationX\Admin
9 */
10
11 namespace NotificationX\Admin;
12
13 use NotificationX\GetInstance;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * @method static EntriesMailReceiver get_instance($args = null)
21 */
22 class EntriesMailReceiver {
23
24 use GetInstance;
25
26 public function __construct() {
27 if ( Settings::get_instance()->get( 'settings.enable_entries_mail', false ) ) {
28 add_action( 'nx_after_entry_inserted', [ $this, 'notify_on_entry' ] );
29 }
30 }
31
32 /**
33 * Triggered after every new entry insert.
34 *
35 * @param array $entry
36 */
37 public function notify_on_entry( $entry ) {
38 $emails = $this->receiver_emails();
39 $subject = $this->email_subject();
40
41 if ( empty( $emails ) ) {
42 return;
43 }
44
45 $body = $this->build_email_body( $entry );
46 $headers = [
47 'Content-Type: text/html; charset=UTF-8',
48 'From: NotificationX <support@wpdeveloper.com>',
49 ];
50
51 wp_mail( $emails, $subject, $body, $headers );
52 }
53
54 /**
55 * REST handler for the "Send Test Email" button.
56 *
57 * @param \WP_REST_Request $request
58 * @return array|\WP_Error
59 */
60 public function send_test( $request ) {
61 $raw_email = $request->get_param( 'entries_mail_email' );
62 $subject = $request->get_param( 'entries_mail_subject' );
63
64 $emails = $this->receiver_emails( ! empty( $raw_email ) ? $raw_email : null );
65 if ( empty( $emails ) ) {
66 return new \WP_Error( 'nx_invalid_email', __( 'Please provide a valid email address.', 'notificationx' ) );
67 }
68
69 if ( empty( $subject ) ) {
70 $subject = $this->email_subject();
71 }
72
73 $dummy_entry = [
74 'source' => 'test',
75 'entry_key' => 'test_entry',
76 'data' => [
77 'name' => 'John Doe',
78 'email' => 'johndoe@example.com',
79 'message' => 'This is a test entry notification from NotificationX.',
80 ],
81 ];
82
83 $body = $this->build_email_body( $dummy_entry );
84 $headers = [
85 'Content-Type: text/html; charset=UTF-8',
86 'From: NotificationX <support@wpdeveloper.com>',
87 ];
88
89 $sent = wp_mail( $emails, $subject, $body, $headers );
90
91 if ( $sent ) {
92 return [ 'message' => __( 'Test email sent successfully.', 'notificationx' ) ];
93 }
94
95 return new \WP_Error( 'nx_mail_failed', __( 'Failed to send the test email. Please check your mail configuration.', 'notificationx' ) );
96 }
97
98 /**
99 * Return receiver emails from settings.
100 * Handles the simple-repeater array format: [['title' => 'email', ...], ...]
101 *
102 * @param mixed $raw Optional override value (e.g. from REST request).
103 * @return array
104 */
105 public function receiver_emails( $raw = null ) {
106 if ( is_null( $raw ) ) {
107 $raw = Settings::get_instance()->get( 'settings.entries_mail_email', [] );
108 }
109 $emails = $this->extract_emails( $raw );
110 if ( empty( $emails ) ) {
111 $emails = [ get_option( 'admin_email' ) ];
112 }
113 return $emails;
114 }
115
116 /**
117 * Extract a clean array of validated email strings.
118 * Handles simple-repeater format [['title' => 'email@...'], ...] and
119 * plain comma/newline-separated strings as a legacy fallback.
120 *
121 * @param mixed $value
122 * @return array
123 */
124 private function extract_emails( $value ) {
125 if ( is_array( $value ) ) {
126 $emails = [];
127 foreach ( $value as $item ) {
128 if ( is_array( $item ) && ! empty( $item['title'] ) ) {
129 $email = trim( $item['title'] );
130 if ( is_email( $email ) ) {
131 $emails[] = $email;
132 }
133 }
134 }
135 return $emails;
136 }
137
138 // Legacy plain-string fallback
139 $parts = preg_split( '/[\s,]+/', trim( (string) $value ), -1, PREG_SPLIT_NO_EMPTY );
140 return array_values( array_filter( $parts, 'is_email' ) );
141 }
142
143 /**
144 * Return configured subject or a sensible default.
145 *
146 * @return string
147 */
148 public function email_subject() {
149 $subject = Settings::get_instance()->get( 'settings.entries_mail_subject', '' );
150 if ( empty( $subject ) ) {
151 $site_name = get_bloginfo( 'name' );
152 /* translators: %s: site name */
153 $subject = sprintf( __( 'New Entry Received on "%s"', 'notificationx' ), $site_name );
154 }
155 return stripcslashes( $subject );
156 }
157
158 /**
159 * Build the HTML email body for a given entry.
160 *
161 * @param array $entry
162 * @return string
163 */
164 private function build_email_body( $entry ) {
165 $source = ! empty( $entry['source'] ) ? esc_html( $entry['source'] ) : __( 'Unknown', 'notificationx' );
166 $site_name = get_bloginfo( 'name' );
167 $site_url = get_bloginfo( 'url' );
168 $date = current_time( 'Y-m-d H:i:s' );
169
170 $data_rows = '';
171 $data = ! empty( $entry['data'] ) && is_array( $entry['data'] ) ? $entry['data'] : [];
172 foreach ( $data as $key => $value ) {
173 if ( is_array( $value ) ) {
174 $value = implode( ', ', $value );
175 }
176 $data_rows .= '<tr>'
177 . '<td style="padding:8px 12px;font-weight:600;border-bottom:1px solid #eee;white-space:nowrap;">'
178 . esc_html( ucwords( str_replace( '_', ' ', $key ) ) )
179 . '</td>'
180 . '<td style="padding:8px 12px;border-bottom:1px solid #eee;">'
181 . esc_html( (string) $value )
182 . '</td>'
183 . '</tr>';
184 }
185
186 $table = $data_rows
187 ? '<table style="width:100%;border-collapse:collapse;margin-top:16px;">' . $data_rows . '</table>'
188 : '<p style="color:#888;">' . __( 'No entry data available.', 'notificationx' ) . '</p>';
189
190 return '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body style="margin:0;padding:20px;background:#f4f4f4;font-family:Arial,sans-serif;">
191 <div style="max-width:600px;margin:0 auto;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.08);">
192 <div style="background:#7c3aed;padding:24px;">
193 <h2 style="color:#fff;margin:0;font-size:20px;">New Entry Notification</h2>
194 <p style="color:#ede9fe;margin:4px 0 0;font-size:13px;">' . esc_html( $site_name ) . '</p>
195 </div>
196 <div style="padding:24px;">
197 <p style="margin:0 0 8px;"><strong>Source:</strong> ' . $source . '</p>
198 <p style="margin:0 0 16px;"><strong>Date:</strong> ' . esc_html( $date ) . '</p>
199 ' . $table . '
200 </div>
201 <div style="background:#f9f9f9;padding:12px 24px;font-size:12px;color:#999;text-align:center;">
202 Sent by <a href="' . esc_url( $site_url ) . '" style="color:#7c3aed;text-decoration:none;">NotificationX</a>
203 </div>
204 </div>
205 </body></html>';
206 }
207 }
208