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
suredonation / inc / blocks / donation-form / block.php

block.php in SureDonation – Donation Forms, Fundraising Campaigns & Donor Management 1.6.1, at inc/blocks/donation-form/block.php

182 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * PHP render for Donation Form Block.
4 *
5 * @package SureDonation
6 * @since 0.0.1
7 */
8
9 namespace SureDonation\Inc\Blocks\Donation_Form;
10
11 use SureDonation\Inc\Blocks\Base;
12 use SureDonation\Inc\Campaigns\Campaign_Page;
13 use SureDonation\Inc\Fields\Form_Renderer;
14 use SureDonation\Inc\Fields\Form_Styling;
15 use SureDonation\Inc\Helper;
16 use SureDonation\Inc\Post_Types\Donation_Form;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit; // Exit if accessed directly.
20 }
21
22 /**
23 * Donation Form Block.
24 *
25 * @since 0.0.1
26 */
27 class Block extends Base {
28 /**
29 * Render the block
30 *
31 * @param array<string, mixed> $attributes Block attributes.
32 * @param string $content Block content.
33 * @return string
34 * @since 0.0.1
35 */
36 public function render( $attributes, $content = '' ) {
37 unset( $content ); // Unused parameter.
38
39 if ( empty( $attributes ) ) {
40 return '';
41 }
42
43 // A custom form is required.
44 $form_id = isset( $attributes['formId'] ) ? absint( Helper::get_string_value( $attributes['formId'] ) ) : 0;
45
46 if ( ! $form_id ) {
47 // Show message only to users who can edit posts.
48 if ( current_user_can( 'edit_posts' ) ) {
49 return '<div class="suredonation-notice">' . esc_html__( 'Please select a donation form in the block settings.', 'suredonation' ) . '</div>';
50 }
51 return '';
52 }
53
54 return $this->render_custom_form( $form_id, $attributes );
55 }
56
57 /**
58 * Render a custom donation form.
59 *
60 * @param int $form_id Form post ID.
61 * @param array<string, mixed> $attributes Block attributes.
62 * @return string
63 * @since 0.0.1
64 */
65 private function render_custom_form( $form_id, $attributes ) {
66 // Get the form post.
67 $form = get_post( $form_id );
68 if ( ! $form instanceof \WP_Post || Donation_Form::POST_TYPE !== $form->post_type ) {
69 return '<div class="suredonation-notice">' . esc_html__( 'Invalid form selected.', 'suredonation' ) . '</div>';
70 }
71
72 // Check if form is published.
73 if ( 'publish' !== $form->post_status ) {
74 return '<div class="suredonation-notice">' . esc_html__( 'This form is not available.', 'suredonation' ) . '</div>';
75 }
76
77 // Get the campaign ID from block attributes or form meta.
78 $campaign_id = isset( $attributes['campaignId'] ) ? absint( Helper::get_string_value( $attributes['campaignId'] ) ) : 0;
79 if ( ! $campaign_id ) {
80 $campaign_id = Donation_Form::get_form_campaign_id( $form_id );
81 }
82
83 // Validate campaign if set.
84 if ( $campaign_id ) {
85 $campaign = get_post( $campaign_id );
86 if ( ! $campaign instanceof \WP_Post || SUREDONATION_POST_TYPE !== $campaign->post_type ) {
87 return '<div class="suredonation-notice">' . esc_html__( 'Invalid campaign selected.', 'suredonation' ) . '</div>';
88 }
89
90 // Only reflect published campaigns (mirrors the form publish check
91 // above) so a draft/private campaign's details can't surface in the
92 // preview via a passed campaign ID.
93 if ( 'publish' !== $campaign->post_status ) {
94 return '<div class="suredonation-notice">' . esc_html__( 'This campaign is not available.', 'suredonation' ) . '</div>';
95 }
96
97 // Check campaign status.
98 $campaign_status = Helper::get_campaign_meta_value( $campaign_id, 'campaign_status', 'active' );
99 if ( 'paused' === $campaign_status || 'completed' === $campaign_status ) {
100 return '<div class="suredonation-notice">' . esc_html__( 'This campaign is not currently accepting donations.', 'suredonation' ) . '</div>';
101 }
102 }
103
104 // Enqueue frontend styles for custom form blocks. Skipped when the form
105 // has default styling disabled — the site's own CSS then controls the
106 // appearance (scripts always load so payment/validation keep working).
107 // Note: Frontend JS is handled by the payment block (form-frontend.js).
108 if ( ! Form_Styling::is_default_styling_disabled( $form_id ) ) {
109 wp_enqueue_style( 'suredonation-donation-form' );
110 }
111
112 // Enqueue form frontend script.
113 wp_enqueue_script( 'suredonation-form-frontend' );
114
115 /**
116 * Fires when a donation form is rendered on the frontend.
117 *
118 * Allows payment gateway extensions to enqueue their scripts and localize
119 * their frontend configuration. Gateway SDKs whose URL depends on the
120 * payment mode are loaded by the form script at runtime instead.
121 *
122 * @param int $form_id The donation form post ID.
123 * @param string $form_content The form post content (blocks).
124 * @since 1.0.0
125 */
126 do_action( 'suredonation_enqueue_form_frontend_scripts', $form_id, $form->post_content );
127
128 // Pass form settings to frontend (wp_localize_script handles script-context escaping).
129 wp_localize_script(
130 'suredonation-form-frontend',
131 'suredonationPayment',
132 Helper::get_form_payment_settings( $form_id )
133 );
134
135 // Expose the resolved validation messages so client-side validation
136 // mirrors the server's configured messages.
137 wp_localize_script(
138 'suredonation-form-frontend',
139 'suredonationValidationMessages',
140 \SureDonation\Inc\Field_Validation::get_resolved_validation_messages()
141 );
142
143 // Shared markup (also used by the [suredonation_form] shortcode).
144 $form_html = Form_Renderer::render( $form, $campaign_id );
145
146 return $this->maybe_anchor_form( $form_html );
147 }
148
149 /**
150 * Wrap the first donation form rendered on the page in the campaign form
151 * anchor.
152 *
153 * The Campaign Donate Button links to `#suredonation-donation-form`. Owning
154 * that anchor here (rather than relying on a wrapping group set up by the
155 * page seeder) keeps the scroll target alive wherever the form block is
156 * placed — including after a user removes and manually re-adds it. Only the
157 * first instance per request is anchored so the id stays unique on the page.
158 *
159 * "First" means first in PHP render order for the request, not first in the
160 * visible page. On the campaign page that is the only/intended form. The
161 * known trade-offs of that scope: a form rendered earlier in the request
162 * (e.g. a sidebar/widget form) would claim the anchor instead, and
163 * ServerSideRender emits the anchored wrapper into the block's editor
164 * preview too. Both are acceptable for the campaign-page use case.
165 *
166 * @param string $form_html Rendered form markup.
167 * @return string
168 * @since 1.1.0
169 */
170 private function maybe_anchor_form( $form_html ) {
171 static $anchored = false;
172
173 if ( $anchored || '' === $form_html ) {
174 return $form_html;
175 }
176
177 $anchored = true;
178
179 return '<div id="' . esc_attr( Campaign_Page::FORM_ANCHOR ) . '" class="suredonation-donation-form-anchor">' . $form_html . '</div>';
180 }
181 }
182