PluginProbe
Section Collection – Add Ready-made Sections to Design Modern Websites / trunk
Section Collection – Add Ready-made Sections to Design Modern Websites vtrunk
trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.3 All 43 releases
section-collection / includes / RestNewsletter.php

RestNewsletter.php in Section Collection – Add Ready-made Sections to Design Modern Websites trunk, at includes/RestNewsletter.php

149 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST endpoint for the Newsletter Section block.
4 *
5 * Route: POST bpsc/v1/newsletter-subscribe
6 * Accepts: { email, form_id, hp }
7 * Reads mail settings from a transient keyed bpsc_newsletter_{form_id}
8 * and sends a notification to the configured recipient via wp_mail().
9 */
10
11 // ABS PATH guard.
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 if ( ! class_exists( 'BPSCRestNewsletter' ) ) {
17 class BPSCRestNewsletter {
18
19 public function __construct() {
20 add_action( 'rest_api_init', [ $this, 'register_routes' ] );
21 }
22
23 /**
24 * Register the REST route.
25 */
26 public function register_routes() {
27 register_rest_route(
28 'bpsc/v1',
29 '/newsletter-subscribe',
30 [
31 'methods' => WP_REST_Server::CREATABLE,
32 'callback' => [ $this, 'handle_subscribe' ],
33 'permission_callback' => '__return_true',
34 'args' => [
35 'email' => [
36 'type' => 'string',
37 'required' => true,
38 'sanitize_callback' => function ( $val ) {
39 return sanitize_email( wp_unslash( $val ) );
40 },
41 ],
42 'form_id' => [
43 'type' => 'string',
44 'required' => true,
45 'sanitize_callback' => function ( $val ) {
46 return sanitize_text_field( wp_unslash( $val ) );
47 },
48 ],
49 'hp' => [
50 'type' => 'string',
51 'default' => '',
52 'sanitize_callback' => function ( $val ) {
53 return sanitize_text_field( wp_unslash( $val ) );
54 },
55 ],
56 ],
57 ]
58 );
59 }
60
61 /**
62 * Handle a newsletter subscription request.
63 *
64 * @param WP_REST_Request $request Full request object.
65 * @return WP_REST_Response|WP_Error
66 */
67 public function handle_subscribe( WP_REST_Request $request ) {
68 // --- Honeypot check ---
69 $hp = $request->get_param( 'hp' );
70 if ( '' !== $hp ) {
71 // Silent success — do not reveal the bot was detected.
72 return rest_ensure_response( [ 'success' => true ] );
73 }
74
75 // --- Email validation ---
76 $email = $request->get_param( 'email' );
77 if ( ! is_email( $email ) ) {
78 return new WP_Error(
79 'invalid_email',
80 __( 'Please enter a valid email address.', 'section-collection' ),
81 [ 'status' => 400 ]
82 );
83 }
84
85 // --- Load mail settings from transient ---
86 $form_id = $request->get_param( 'form_id' );
87 $settings = get_transient( 'bpsc_newsletter_' . $form_id );
88
89 if ( false === $settings || ! is_array( $settings ) ) {
90 return new WP_Error(
91 'form_expired',
92 __( 'This form has expired. Please refresh the page.', 'section-collection' ),
93 [ 'status' => 400 ]
94 );
95 }
96
97 // --- Resolve recipient ---
98 $recipient = isset( $settings['recipient'] ) ? trim( $settings['recipient'] ) : '';
99 if ( empty( $recipient ) || ! is_email( $recipient ) ) {
100 $recipient = get_option( 'admin_email' );
101 }
102
103 // --- Build message ---
104 $subject = isset( $settings['subject'] ) ? sanitize_text_field( $settings['subject'] ) : __( 'New newsletter subscriber', 'section-collection' );
105 $body_template = isset( $settings['body'] ) ? $settings['body'] : '{email} is subscribing to the newsletter.';
106 $body = str_replace( '{email}', $email, $body_template );
107
108 // --- Optional From Name via filters ---
109 $from_name = isset( $settings['fromName'] ) ? sanitize_text_field( $settings['fromName'] ) : '';
110 $headers = [];
111
112 if ( ! empty( $from_name ) ) {
113 $from_email = '';
114 $from_filter = function ( $email ) use ( &$from_email ) {
115 $from_email = $email;
116 return $email;
117 };
118 add_filter( 'wp_mail_from', $from_filter, 99 );
119 // Run once to capture the default from address.
120 $from_email = apply_filters( 'wp_mail_from', get_option( 'admin_email' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- core WordPress filter, read intentionally to capture the default from-address.
121 remove_filter( 'wp_mail_from', $from_filter, 99 );
122
123 $from_name_filter = function () use ( $from_name ) {
124 return $from_name;
125 };
126 add_filter( 'wp_mail_from_name', $from_name_filter, 99 );
127 wp_mail( $recipient, $subject, $body, $headers );
128 remove_filter( 'wp_mail_from_name', $from_name_filter, 99 );
129 } else {
130 wp_mail( $recipient, $subject, $body, $headers );
131 }
132
133 // --- Build success message ---
134 $success_message = isset( $settings['successMessage'] ) && '' !== $settings['successMessage']
135 ? $settings['successMessage']
136 : __( "Thanks! Check your inbox.", 'section-collection' );
137
138 return rest_ensure_response(
139 [
140 'success' => true,
141 'message' => $success_message,
142 ]
143 );
144 }
145 }
146
147 new BPSCRestNewsletter();
148 }
149