PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 1.6.1
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v1.6.1
1.6.1 1.6.0 1.5.1 1.5.0 1.4.0 1.3.0 trunk 0.0.1 1.0.0 1.1.0 1.1.1 1.1.2 1.2.0
← All changes | inc/api/settings-api.php +165 -20 1.5.0 → 1.6.1 View file →
@@ -6,8 +6,9 @@
6 6 */
7 7
8 8 namespace SureDonation\Inc\API;
9 9
10 +use SureDonation\Inc\Emails\Email_Reports;
10 11 use SureDonation\Inc\Helper;
11 12 use SureDonation\Inc\Payments\Payment_Helper;
12 13 use WP_Error;
13 14 use WP_REST_Request;
@@ -61,9 +62,9 @@
61 62 */
62 63 public function get_endpoints() {
63 64 return [
64 65 // Get currency data for block editor (public endpoint).
65 - '/settings' => [
66 + '/settings' => [
66 67 'methods' => WP_REST_Server::READABLE,
67 68 'callback' => [ $this, 'get_currency_settings' ],
68 69 'permission_callback' => '__return_true',
69 70 ],
@@ -68,9 +69,9 @@
68 69 'permission_callback' => '__return_true',
69 70 ],
70 71
71 72 // Get and update general settings.
72 - '/settings/general' => [
73 + '/settings/general' => [
73 74 [
74 75 'methods' => WP_REST_Server::READABLE,
75 76 'callback' => [ $this, 'get_settings' ],
76 77 'permission_callback' => [ $this, 'check_permissions' ],
@@ -82,9 +83,9 @@
82 83 ],
83 84 ],
84 85
85 86 // Get available currencies.
86 - '/settings/currencies' => [
87 + '/settings/currencies' => [
87 88 'methods' => WP_REST_Server::READABLE,
88 89 'callback' => [ $this, 'get_currencies' ],
89 90 'permission_callback' => [ $this, 'check_permissions' ],
90 91 ],
@@ -91,9 +92,9 @@
91 92
92 93 // Email notifications are managed per-form via post meta.
93 94 // See inc/form-editor/assets.php for the form-level email system.
94 95 // AI settings.
95 - '/settings/ai' => [
96 + '/settings/ai' => [
96 97 [
97 98 'methods' => WP_REST_Server::READABLE,
98 99 'callback' => [ $this, 'get_ai_settings' ],
99 100 'permission_callback' => [ $this, 'check_permissions' ],
@@ -105,9 +106,9 @@
105 106 ],
106 107 ],
107 108
108 109 // Spam protection settings.
109 - '/settings/spam-protection' => [
110 + '/settings/spam-protection' => [
110 111 [
111 112 'methods' => WP_REST_Server::READABLE,
112 113 'callback' => [ $this, 'get_spam_protection_settings' ],
113 114 'permission_callback' => [ $this, 'check_permissions' ],
@@ -119,9 +120,9 @@
119 120 ],
120 121 ],
121 122
122 123 // Miscellaneous settings (usage tracking, etc.).
123 - '/settings/misc' => [
124 + '/settings/misc' => [
124 125 [
125 126 'methods' => WP_REST_Server::READABLE,
126 127 'callback' => [ $this, 'get_misc_settings' ],
127 128 'permission_callback' => [ $this, 'check_permissions' ],
@@ -139,9 +140,9 @@
139 140 ],
140 141 ],
141 142
142 143 // Donor management settings.
143 - '/settings/donor' => [
144 + '/settings/donor' => [
144 145 [
145 146 'methods' => WP_REST_Server::READABLE,
146 147 'callback' => [ $this, 'get_donor_settings' ],
147 148 'permission_callback' => [ $this, 'check_permissions' ],
@@ -150,18 +151,25 @@
150 151 'methods' => WP_REST_Server::EDITABLE,
151 152 'callback' => [ $this, 'update_donor_settings' ],
152 153 'permission_callback' => [ $this, 'check_permissions' ],
153 154 'args' => [
154 - 'create_wp_user' => [
155 + 'create_wp_user' => [
155 156 'type' => 'boolean',
156 157 'sanitize_callback' => 'rest_sanitize_boolean',
157 158 ],
159 + // Registered so the handler's (bool) cast receives a real
160 + // boolean: a form-encoded "false" would otherwise cast to true
161 + // and switch moderation ON when the admin asked for OFF.
162 + 'hold_donor_comments' => [
163 + 'type' => 'boolean',
164 + 'sanitize_callback' => 'rest_sanitize_boolean',
165 + ],
158 166 ],
159 167 ],
160 168 ],
161 169
162 170 // Form validation default messages.
163 - '/settings/validation' => [
171 + '/settings/validation' => [
164 172 [
165 173 'methods' => WP_REST_Server::READABLE,
166 174 'callback' => [ $this, 'get_validation_settings' ],
167 175 'permission_callback' => [ $this, 'check_permissions' ],
@@ -173,9 +181,9 @@
173 181 ],
174 182 ],
175 183
176 184 // Privacy settings (data retention, consent, privacy/terms fields).
177 - '/settings/privacy' => [
185 + '/settings/privacy' => [
178 186 [
179 187 'methods' => WP_REST_Server::READABLE,
180 188 'callback' => [ $this, 'get_privacy_settings' ],
181 189 'permission_callback' => [ $this, 'check_permissions' ],
@@ -186,12 +194,26 @@
186 194 'permission_callback' => [ $this, 'check_permissions' ],
187 195 ],
188 196 ],
189 197
190 - // Send test email.
191 - '/settings/email/test' => [
198 + // Email Reports (weekly donation digest).
199 + '/settings/email-reports' => [
200 + [
201 + 'methods' => WP_REST_Server::READABLE,
202 + 'callback' => [ $this, 'get_email_reports_settings' ],
203 + 'permission_callback' => [ $this, 'check_permissions' ],
204 + ],
205 + [
206 + 'methods' => WP_REST_Server::EDITABLE,
207 + 'callback' => [ $this, 'update_email_reports_settings' ],
208 + 'permission_callback' => [ $this, 'check_permissions' ],
209 + ],
210 + ],
211 +
212 + // Send this week's report now, to the addresses in the request.
213 + '/settings/email-reports/test' => [
192 214 'methods' => WP_REST_Server::CREATABLE,
193 - 'callback' => [ $this, 'send_test_email' ],
215 + 'callback' => [ $this, 'send_test_email_report' ],
194 216 'permission_callback' => [ $this, 'check_permissions' ],
195 217 ],
196 218 ];
197 219 }
@@ -196,8 +218,119 @@
196 218 ];
197 219 }
198 220
199 221 /**
222 + * Get the Email Reports settings (stored values merged over the defaults).
223 + *
224 + * @param WP_REST_Request $request Request object.
225 + * @return WP_REST_Response
226 + * @since 1.6.1
227 + */
228 + public function get_email_reports_settings( $request ) {
229 + unset( $request ); // Unused parameter.
230 +
231 + return new WP_REST_Response( self::email_reports_payload( Email_Reports::get_settings() ), 200 );
232 + }
233 +
234 + /**
235 + * Update the Email Reports settings and (re)schedule the weekly send.
236 + *
237 + * Turning the report on with no deliverable address is refused with a
238 + * 400 rather than quietly stored as off: the client's address check is
239 + * looser than is_email(), and a success response would leave the screen
240 + * showing the report as on while nothing is scheduled.
241 + *
242 + * @param WP_REST_Request $request Request object.
243 + * @return WP_REST_Response
244 + * @since 1.6.1
245 + */
246 + public function update_email_reports_settings( $request ) {
247 + $params = $request->get_json_params();
248 + $params = is_array( $params ) ? $params : [];
249 +
250 + $wants_on = filter_var( $params['enabled'] ?? false, FILTER_VALIDATE_BOOLEAN );
251 + $sanitized = Email_Reports::sanitize( $params );
252 +
253 + if ( $wants_on && ! $sanitized['enabled'] ) {
254 + return new WP_REST_Response(
255 + [
256 + 'success' => false,
257 + 'code' => 'no_valid_recipient',
258 + 'message' => __( 'Enter at least one valid email address to turn on email reports.', 'suredonation' ),
259 + ],
260 + 400
261 + );
262 + }
263 +
264 + return new WP_REST_Response( self::email_reports_payload( Email_Reports::save( $params ) ), 200 );
265 + }
266 +
267 + /**
268 + * The Email Reports response body: the stored settings plus the schedule
269 + * state, so the screen can show when the next report goes out, or that
270 + * none is queued.
271 + *
272 + * @param array<string, mixed> $settings Stored settings.
273 + * @return array<string, mixed>
274 + * @since 1.6.1
275 + */
276 + private static function email_reports_payload( $settings ) {
277 + $next_run = Email_Reports::next_run();
278 +
279 + return [
280 + 'success' => true,
281 + 'settings' => $settings,
282 + 'next_run' => $next_run,
283 + 'next_run_label' => null === $next_run
284 + ? ''
285 + : Helper::get_string_value( wp_date( Helper::get_string_value( get_option( 'date_format' ) ) . ' ' . Helper::get_string_value( get_option( 'time_format' ) ), $next_run ) ),
286 + ];
287 + }
288 +
289 + /**
290 + * Send this week's report immediately to the addresses in the request.
291 + *
292 + * Reads recipients from the request, not the stored settings, so an admin
293 + * can preview before saving. Sends even when the week has no donations.
294 + *
295 + * @param WP_REST_Request $request Request object.
296 + * @return WP_REST_Response
297 + * @since 1.6.1
298 + */
299 + public function send_test_email_report( $request ) {
300 + $params = $request->get_json_params();
301 + $recipients = Email_Reports::parse_recipients( is_array( $params ) ? ( $params['recipients'] ?? '' ) : '' );
302 +
303 + if ( [] === $recipients ) {
304 + return new WP_REST_Response(
305 + [
306 + 'success' => false,
307 + 'message' => __( 'Enter at least one valid email address.', 'suredonation' ),
308 + ],
309 + 400
310 + );
311 + }
312 +
313 + if ( ! Email_Reports::send_report( $recipients, true ) ) {
314 + return new WP_REST_Response(
315 + [
316 + 'success' => false,
317 + 'message' => __( 'The report could not be sent. Check your site’s email configuration.', 'suredonation' ),
318 + ],
319 + 500
320 + );
321 + }
322 +
323 + return new WP_REST_Response(
324 + [
325 + 'success' => true,
326 + 'message' => __( 'Test report sent.', 'suredonation' ),
327 + ],
328 + 200
329 + );
330 + }
331 +
332 + /**
200 333 * Get the Privacy settings (stored values merged over the defaults).
201 334 *
202 335 * @param WP_REST_Request $request Request object.
203 336 * @return WP_REST_Response
@@ -646,9 +779,13 @@
646 779 [
647 780 'success' => true,
648 781 'settings' => [
649 782 // Off by default: guest donations never auto-create WP user accounts.
650 - 'create_wp_user' => ! empty( $donor_settings['create_wp_user'] ),
783 + 'create_wp_user' => ! empty( $donor_settings['create_wp_user'] ),
784 + // Off by default: donor comments publish as soon as the donation
785 + // completes, matching GiveWP and Charitable out of the box. Turning
786 + // it on holds new comments as `pending` for review instead.
787 + 'hold_donor_comments' => ! empty( $donor_settings['hold_donor_comments'] ),
651 788 ],
652 789 ],
653 790 200
654 791 );
@@ -661,17 +798,25 @@
661 798 * @return WP_REST_Response Response object.
662 799 * @since 1.0.0
663 800 */
664 801 public function update_donor_settings( $request ) {
665 - $create_wp_user = $request->get_param( 'create_wp_user' );
802 + $donor_settings = Helper::get_suredonation_option( self::DONOR_OPTION_KEY, [] );
803 + if ( ! is_array( $donor_settings ) ) {
804 + $donor_settings = [];
805 + }
666 806
667 - if ( null !== $create_wp_user ) {
668 - $donor_settings = Helper::get_suredonation_option( self::DONOR_OPTION_KEY, [] );
669 - if ( ! is_array( $donor_settings ) ) {
670 - $donor_settings = [];
807 + // Read each setting via get_param() so the endpoint accepts JSON, body,
808 + // or query params (matches the sibling /settings/* update handlers).
809 + $changed = false;
810 + foreach ( [ 'create_wp_user', 'hold_donor_comments' ] as $key ) {
811 + $value = $request->get_param( $key );
812 + if ( null !== $value ) {
813 + $donor_settings[ $key ] = (bool) $value;
814 + $changed = true;
671 815 }
816 + }
672 817
673 - $donor_settings['create_wp_user'] = (bool) $create_wp_user;
818 + if ( $changed ) {
674 819 Helper::update_suredonation_option( self::DONOR_OPTION_KEY, $donor_settings );
675 820 }
676 821
677 822 return new WP_REST_Response(