PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 1.0.0
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v1.0.0
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
suredonation / inc / form-editor / assets.php

assets.php in SureDonation – Donation Forms, Fundraising Campaigns & Donor Management 1.0.0, at inc/form-editor/assets.php

459 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Form Editor Assets.
4 *
5 * Handles asset registration and enqueuing for the donation form editor.
6 *
7 * @package SureDonation
8 * @since 0.0.1
9 */
10
11 namespace SureDonation\Inc\FormEditor;
12
13 use SureDonation\Inc\Helper;
14 use SureDonation\Inc\Payments\Payment_Helper;
15 use SureDonation\Inc\Traits\Get_Instance;
16 use SureDonation\Inc\Post_Types\Donation_Form;
17
18 // Exit if accessed directly.
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Assets Class.
25 *
26 * @since 0.0.1
27 */
28 class Assets {
29 use Get_Instance;
30
31 /**
32 * Constructor.
33 *
34 * @since 0.0.1
35 */
36 public function __construct() {
37 add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_editor_assets' ] );
38 add_action( 'init', [ $this, 'register_form_settings_meta' ] );
39 add_action( 'init', [ $this, 'register_email_notifications_meta' ] );
40 }
41
42 /**
43 * Enqueue editor assets for the donation form editor.
44 *
45 * @return void
46 * @since 0.0.1
47 */
48 public function enqueue_editor_assets() {
49 $screen = get_current_screen();
50
51 // Only load on donation form editor.
52 if ( ! $screen || Donation_Form::POST_TYPE !== $screen->post_type ) {
53 return;
54 }
55
56 // Get the asset file for dependencies.
57 $editor_asset_file = SUREDONATION_DIR . 'assets/build/editor/editor.asset.php';
58 $editor_asset = file_exists( $editor_asset_file )
59 ? include $editor_asset_file
60 : [
61 'dependencies' => [
62 'wp-plugins',
63 'wp-editor',
64 'wp-components',
65 'wp-data',
66 'wp-element',
67 'wp-i18n',
68 ],
69 'version' => SUREDONATION_VER,
70 ];
71
72 // Editor plugin JS.
73 wp_enqueue_script(
74 'suredonation-form-editor',
75 SUREDONATION_URL . 'assets/build/editor/editor.js',
76 $editor_asset['dependencies'],
77 $editor_asset['version'],
78 true
79 );
80
81 // Editor styles.
82 wp_enqueue_style(
83 'suredonation-form-editor',
84 SUREDONATION_URL . 'assets/build/editor/editor.css',
85 [ 'wp-components' ],
86 $editor_asset['version']
87 );
88
89 // Localized data.
90 $global_currency = Payment_Helper::get_global_setting( 'currency', 'USD' );
91 $global_currency = is_string( $global_currency ) ? $global_currency : 'USD';
92
93 wp_localize_script(
94 'suredonation-form-editor',
95 'suredonationFormEditor',
96 [
97 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
98 'nonce' => wp_create_nonce( 'suredonation_editor_nonce' ),
99 'postType' => Donation_Form::POST_TYPE,
100 'smartTags' => Helper::get_smart_tags()['confirmation'],
101 'emailSmartTags' => Helper::get_smart_tags()['email_grouped'],
102 'defaultEmailNotifications' => $this->get_default_email_notifications(),
103 'currency' => $global_currency,
104 'currencySymbol' => Payment_Helper::get_currency_symbol( $global_currency ),
105 ]
106 );
107
108 // Set script translations.
109 wp_set_script_translations( 'suredonation-form-editor', 'suredonation' );
110 }
111
112 /**
113 * Register form settings meta fields.
114 *
115 * Stores form confirmation settings as a single JSON string.
116 *
117 * @return void
118 * @since 1.0.0
119 */
120 public function register_form_settings_meta() {
121 $post_type = Donation_Form::POST_TYPE;
122
123 // Default confirmation message HTML (receipt layout with smart tags).
124 $default_message = Helper::get_default_confirmation_message();
125
126 $default_confirmation = wp_json_encode(
127 [
128 'confirmation_type' => 'same page',
129 'message' => $default_message,
130 'submission_action' => 'hide form',
131 'custom_url' => '',
132 'page_url' => '',
133 ]
134 );
135
136 // Form confirmation settings (JSON string).
137 register_post_meta(
138 $post_type,
139 '_suredonation_form_confirmation',
140 [
141 'type' => 'string',
142 'description' => __( 'Form confirmation settings.', 'suredonation' ),
143 'single' => true,
144 'default' => $default_confirmation,
145 'show_in_rest' => [
146 'schema' => [
147 'type' => 'string',
148 'context' => [ 'edit' ],
149 ],
150 ],
151 'sanitize_callback' => [ $this, 'sanitize_confirmation_settings' ],
152 'auth_callback' => static function () {
153 return current_user_can( 'manage_options' );
154 },
155 ]
156 );
157 }
158
159 /**
160 * Email notification meta key.
161 *
162 * No migration from global `suredonation_options['email_notifications']` is needed:
163 * the plugin is pre-release (v0.0.1) with no production installs carrying customized
164 * global settings. New forms are seeded with defaults via the editor JS useEffect.
165 *
166 * @since 1.0.0
167 */
168 public const EMAIL_NOTIFICATIONS_META_KEY = '_suredonation_form_email_notifications';
169
170 /**
171 * Get default email notifications for new forms.
172 *
173 * Provides the initial set of notifications (donation receipt + admin) that
174 * are seeded when a form has no email notifications configured.
175 *
176 * @return array<int, array<string, mixed>> Default notifications array.
177 * @since 1.0.0
178 */
179 public function get_default_email_notifications() {
180 $sig = '<p>' . esc_html__( 'We truly appreciate your support', 'suredonation' ) . '</p>'
181 . '<p>— {site_title}</p>';
182
183 // phpcs:disable Generic.Strings.UnnecessaryStringConcat.Found -- Readability.
184 $defaults = [
185 // --- Donor Emails ---
186 [
187 'id' => 1,
188 'status' => true,
189 'name' => __( 'Donation Receipt', 'suredonation' ),
190 'email_to' => '{donor_email}',
191 'subject' => __( 'Thank you for your donation to {campaign_name}', 'suredonation' ),
192 'email_body' => '<p>' . esc_html__( 'Hi {donor_name},', 'suredonation' ) . '</p>'
193 . '<p>' . esc_html__( 'Thank you for supporting {campaign_name}. Your contribution means a lot.', 'suredonation' ) . '</p>'
194 . '<p><strong>' . esc_html__( 'Donation Details:', 'suredonation' ) . '</strong></p>'
195 . '<ul>'
196 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {amount}</li>'
197 . '<li>' . esc_html__( 'Date:', 'suredonation' ) . ' {donation_date}</li>'
198 . '<li>' . esc_html__( 'Transaction ID:', 'suredonation' ) . ' {transaction_id}</li>'
199 . '</ul>'
200 . $sig,
201 'from_name' => '{site_title}',
202 'from_email' => '{admin_email}',
203 'reply_to' => '',
204 'trigger' => 'donation_completed',
205 ],
206 [
207 'id' => 2,
208 'status' => true,
209 'name' => __( 'Donation Processing', 'suredonation' ),
210 'email_to' => '{donor_email}',
211 'subject' => __( 'Your donation is being processed', 'suredonation' ),
212 'email_body' => '<p>' . esc_html__( 'Hi {donor_name},', 'suredonation' ) . '</p>'
213 . '<p>' . esc_html__( 'Your donation to {campaign_name} is currently being processed.', 'suredonation' ) . '</p>'
214 . '<ul>'
215 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {amount}</li>'
216 . '<li>' . esc_html__( 'Date:', 'suredonation' ) . ' {donation_date}</li>'
217 . '</ul>'
218 . '<p>' . esc_html__( "We'll notify you once it's confirmed.", 'suredonation' ) . '</p>'
219 . '<p>— {site_title}</p>',
220 'from_name' => '{site_title}',
221 'from_email' => '{admin_email}',
222 'reply_to' => '',
223 'trigger' => 'donation_processing',
224 ],
225 [
226 'id' => 3,
227 'status' => true,
228 'name' => __( 'Donation Failed', 'suredonation' ),
229 'email_to' => '{donor_email}',
230 'subject' => __( "We couldn't process your donation", 'suredonation' ),
231 'email_body' => '<p>' . esc_html__( 'Hi {donor_name},', 'suredonation' ) . '</p>'
232 . '<p>' . esc_html__( 'Unfortunately, your donation to {campaign_name} could not be completed.', 'suredonation' ) . '</p>'
233 . '<p>' . esc_html__( 'If you need help, feel free to contact us.', 'suredonation' ) . '</p>'
234 . '<p>— {site_title}</p>',
235 'from_name' => '{site_title}',
236 'from_email' => '{admin_email}',
237 'reply_to' => '',
238 'trigger' => 'donation_failed',
239 ],
240 [
241 'id' => 4,
242 'status' => true,
243 'name' => __( 'Refund Processed', 'suredonation' ),
244 'email_to' => '{donor_email}',
245 'subject' => __( 'Your donation has been refunded', 'suredonation' ),
246 'email_body' => '<p>' . esc_html__( 'Hi {donor_name},', 'suredonation' ) . '</p>'
247 . '<p>' . esc_html__( 'Your donation has been refunded.', 'suredonation' ) . '</p>'
248 . '<ul>'
249 . '<li>' . esc_html__( 'Campaign:', 'suredonation' ) . ' {campaign_name}</li>'
250 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {refund_amount}</li>'
251 . '</ul>'
252 . '<p>' . esc_html__( 'If you have any questions, feel free to reach out.', 'suredonation' ) . '</p>'
253 . '<p>— {site_title}</p>',
254 'from_name' => '{site_title}',
255 'from_email' => '{admin_email}',
256 'reply_to' => '',
257 'trigger' => 'refund_processed',
258 ],
259
260 // --- Admin Emails ---
261 [
262 'id' => 9,
263 'status' => true,
264 'name' => __( 'New Donation (Admin)', 'suredonation' ),
265 'email_to' => '{admin_email}',
266 'subject' => __( 'New donation received', 'suredonation' ),
267 'email_body' => '<p>' . esc_html__( 'A new donation has been received.', 'suredonation' ) . '</p>'
268 . '<ul>'
269 . '<li>' . esc_html__( 'Donor:', 'suredonation' ) . ' {donor_name}</li>'
270 . '<li>' . esc_html__( 'Email:', 'suredonation' ) . ' {donor_email}</li>'
271 . '<li>' . esc_html__( 'Campaign:', 'suredonation' ) . ' {campaign_name}</li>'
272 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {amount}</li>'
273 . '<li>' . esc_html__( 'Date:', 'suredonation' ) . ' {donation_date}</li>'
274 . '</ul>'
275 . '<p>' . esc_html__( 'View details:', 'suredonation' ) . '<br />{admin_url}</p>',
276 'from_name' => '{site_title}',
277 'from_email' => '{admin_email}',
278 'reply_to' => '',
279 'trigger' => 'donation_completed',
280 ],
281 [
282 'id' => 10,
283 'status' => true,
284 'name' => __( 'Donation Failed (Admin)', 'suredonation' ),
285 'email_to' => '{admin_email}',
286 'subject' => __( 'Donation failed', 'suredonation' ),
287 'email_body' => '<p>' . esc_html__( 'A donation attempt has failed.', 'suredonation' ) . '</p>'
288 . '<ul>'
289 . '<li>' . esc_html__( 'Donor:', 'suredonation' ) . ' {donor_name}</li>'
290 . '<li>' . esc_html__( 'Campaign:', 'suredonation' ) . ' {campaign_name}</li>'
291 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {amount}</li>'
292 . '<li>' . esc_html__( 'Date:', 'suredonation' ) . ' {donation_date}</li>'
293 . '</ul>'
294 . '<p>' . esc_html__( 'Check details:', 'suredonation' ) . '<br />{admin_url}</p>',
295 'from_name' => '{site_title}',
296 'from_email' => '{admin_email}',
297 'reply_to' => '',
298 'trigger' => 'donation_failed',
299 ],
300 [
301 'id' => 11,
302 'status' => true,
303 'name' => __( 'Refund Processed (Admin)', 'suredonation' ),
304 'email_to' => '{admin_email}',
305 'subject' => __( 'Refund issued', 'suredonation' ),
306 'email_body' => '<p>' . esc_html__( 'A refund has been processed.', 'suredonation' ) . '</p>'
307 . '<ul>'
308 . '<li>' . esc_html__( 'Donor:', 'suredonation' ) . ' {donor_name}</li>'
309 . '<li>' . esc_html__( 'Campaign:', 'suredonation' ) . ' {campaign_name}</li>'
310 . '<li>' . esc_html__( 'Amount:', 'suredonation' ) . ' {refund_amount}</li>'
311 . '</ul>'
312 . '<p>' . esc_html__( 'View details:', 'suredonation' ) . '<br />{admin_url}</p>',
313 'from_name' => '{site_title}',
314 'from_email' => '{admin_email}',
315 'reply_to' => '',
316 'trigger' => 'refund_processed',
317 ],
318 ];
319 // phpcs:enable Generic.Strings.UnnecessaryStringConcat.Found
320
321 /**
322 * Filter default email notifications.
323 * Pro uses this to add subscription email notification templates.
324 *
325 * @param array<int, array<string, mixed>> $defaults Default notification configs.
326 * @since 1.0.0
327 */
328 return apply_filters( 'suredonation_default_email_notifications', $defaults );
329 }
330
331 /**
332 * Register email notification meta for donation forms.
333 *
334 * Stores per-form email notification settings as a JSON string.
335 *
336 * @return void
337 * @since 1.0.0
338 */
339 public function register_email_notifications_meta() {
340 register_post_meta(
341 Donation_Form::POST_TYPE,
342 self::EMAIL_NOTIFICATIONS_META_KEY,
343 [
344 'type' => 'string',
345 'description' => __( 'Form email notification settings.', 'suredonation' ),
346 'single' => true,
347 'default' => '',
348 'show_in_rest' => [
349 'schema' => [
350 'type' => 'string',
351 'context' => [ 'edit' ],
352 ],
353 ],
354 'sanitize_callback' => [ $this, 'sanitize_email_notifications' ],
355 'auth_callback' => static function () {
356 return current_user_can( 'manage_options' );
357 },
358 ]
359 );
360 }
361
362 /**
363 * Sanitize email notification settings.
364 *
365 * @param string $value JSON string of email notification settings.
366 * @return string Sanitized JSON string.
367 * @since 1.0.0
368 */
369 public function sanitize_email_notifications( $value ) {
370 if ( empty( $value ) || ! is_string( $value ) ) {
371 return '';
372 }
373
374 $data = json_decode( $value, true );
375
376 if ( ! is_array( $data ) ) {
377 return '';
378 }
379
380 $sanitized = [];
381 foreach ( $data as $notification ) {
382 if ( ! is_array( $notification ) ) {
383 continue;
384 }
385
386 $sanitized[] = [
387 'id' => isset( $notification['id'] ) ? absint( $notification['id'] ) : 0,
388 'status' => isset( $notification['status'] ) ? (bool) $notification['status'] : true,
389 'name' => isset( $notification['name'] ) ? sanitize_text_field( $notification['name'] ) : '',
390 'email_to' => isset( $notification['email_to'] ) ? sanitize_text_field( $notification['email_to'] ) : '',
391 'subject' => isset( $notification['subject'] ) ? sanitize_text_field( $notification['subject'] ) : '',
392 'email_body' => isset( $notification['email_body'] ) ? wp_kses_post( $notification['email_body'] ) : '',
393 'from_name' => isset( $notification['from_name'] ) ? sanitize_text_field( $notification['from_name'] ) : '',
394 'from_email' => isset( $notification['from_email'] ) ? sanitize_text_field( $notification['from_email'] ) : '',
395 'reply_to' => isset( $notification['reply_to'] ) ? sanitize_text_field( $notification['reply_to'] ) : '',
396 'trigger' => isset( $notification['trigger'] ) && in_array(
397 $notification['trigger'],
398 apply_filters(
399 'suredonation_email_notification_triggers',
400 [ 'all', 'donation_completed', 'donation_processing', 'donation_failed', 'refund_processed' ]
401 ),
402 true
403 ) ? $notification['trigger'] : 'all',
404 ];
405 }
406
407 $encoded = wp_json_encode( $sanitized );
408 return is_string( $encoded ) ? $encoded : '';
409 }
410
411 /**
412 * Sanitize form confirmation settings.
413 *
414 * @param string $value JSON string of confirmation settings.
415 * @return string Sanitized JSON string.
416 * @since 1.0.0
417 */
418 public function sanitize_confirmation_settings( $value ) {
419 $fallback_data = [
420 'confirmation_type' => 'same page',
421 'message' => '',
422 'submission_action' => 'hide form',
423 'custom_url' => '',
424 'page_url' => '',
425 ];
426 $fallback = (string) wp_json_encode( $fallback_data );
427
428 if ( empty( $value ) || ! is_string( $value ) ) {
429 return $fallback;
430 }
431
432 $data = json_decode( $value, true );
433
434 if ( ! is_array( $data ) ) {
435 return $fallback;
436 }
437
438 $allowed_types = [ 'same page', 'different page', 'custom url' ];
439 $allowed_actions = [ 'hide form', 'reset form' ];
440
441 $message = isset( $data['message'] ) ? wp_kses_post( $data['message'] ) : '';
442
443 $sanitized = [
444 'confirmation_type' => isset( $data['confirmation_type'] ) && in_array( $data['confirmation_type'], $allowed_types, true )
445 ? $data['confirmation_type']
446 : 'same page',
447 'message' => $message,
448 'submission_action' => isset( $data['submission_action'] ) && in_array( $data['submission_action'], $allowed_actions, true )
449 ? $data['submission_action']
450 : 'hide form',
451 'custom_url' => isset( $data['custom_url'] ) ? esc_url_raw( $data['custom_url'] ) : '',
452 'page_url' => isset( $data['page_url'] ) ? esc_url_raw( $data['page_url'] ) : '',
453 ];
454
455 $encoded = wp_json_encode( $sanitized );
456 return is_string( $encoded ) ? $encoded : $fallback;
457 }
458 }
459