PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 0.0.1
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v0.0.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 / api / forms-api.php

forms-api.php in SureDonation – Donation Forms, Fundraising Campaigns & Donor Management 0.0.1, at inc/api/forms-api.php

404 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Forms REST API endpoints.
4 *
5 * @package SureDonation
6 */
7
8 namespace SureDonation\Inc\API;
9
10 use SureDonation\Inc\Duplicate_Form;
11 use SureDonation\Inc\Post_Types\Donation_Form;
12 use WP_Error;
13 use WP_REST_Request;
14 use WP_REST_Response;
15 use WP_REST_Server;
16
17 // Exit if accessed directly.
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Forms API class.
24 *
25 * @since 0.0.1
26 */
27 class Forms_API {
28 /**
29 * Get forms endpoints.
30 *
31 * @return array<string, mixed>
32 * @since 0.0.1
33 */
34 public function get_endpoints() {
35 return [
36 // Get forms list.
37 '/forms' => [
38 [
39 'methods' => WP_REST_Server::READABLE,
40 'callback' => [ $this, 'get_forms' ],
41 'permission_callback' => [ $this, 'check_permissions' ],
42 'args' => [
43 'campaign_id' => [
44 'type' => 'integer',
45 'sanitize_callback' => 'absint',
46 ],
47 'per_page' => [
48 'type' => 'integer',
49 'default' => 100,
50 'sanitize_callback' => 'absint',
51 ],
52 'status' => [
53 'type' => 'string',
54 'default' => 'any',
55 'sanitize_callback' => 'sanitize_text_field',
56 ],
57 ],
58 ],
59 ],
60
61 // Manage form lifecycle (trash/restore/delete).
62 '/forms/manage' => [
63 [
64 'methods' => WP_REST_Server::CREATABLE,
65 'callback' => [ $this, 'manage_form_lifecycle' ],
66 'permission_callback' => [ $this, 'check_permissions' ],
67 'args' => [
68 'form_ids' => [
69 'required' => true,
70 'type' => [ 'array', 'integer' ],
71 'sanitize_callback' => static function ( $value ) {
72 if ( is_array( $value ) ) {
73 return array_map( 'intval', $value );
74 }
75 return [ intval( $value ) ];
76 },
77 ],
78 'action' => [
79 'required' => true,
80 'type' => 'string',
81 'enum' => [ 'trash', 'restore', 'delete' ],
82 'sanitize_callback' => 'sanitize_text_field',
83 ],
84 ],
85 ],
86 ],
87
88 // Duplicate a form.
89 '/forms/duplicate' => [
90 [
91 'methods' => WP_REST_Server::CREATABLE,
92 'callback' => [ Duplicate_Form::get_instance(), 'handle_duplicate_form_rest' ],
93 'permission_callback' => [ $this, 'check_permissions' ],
94 'args' => [
95 'form_id' => [
96 'required' => true,
97 'type' => 'integer',
98 'sanitize_callback' => 'absint',
99 'validate_callback' => static function ( $value ) {
100 return $value > 0;
101 },
102 ],
103 'title_suffix' => [
104 'required' => false,
105 'type' => 'string',
106 'default' => __( ' (Copy)', 'suredonation' ),
107 'sanitize_callback' => 'sanitize_text_field',
108 ],
109 ],
110 ],
111 ],
112
113 // Get/update single form.
114 '/forms/(?P<id>\d+)' => [
115 [
116 'methods' => WP_REST_Server::READABLE,
117 'callback' => [ $this, 'get_form' ],
118 'permission_callback' => [ $this, 'check_permissions' ],
119 'args' => [
120 'id' => [
121 'required' => true,
122 'validate_callback' => static function ( $param ) {
123 return is_numeric( $param );
124 },
125 ],
126 ],
127 ],
128 [
129 'methods' => WP_REST_Server::EDITABLE,
130 'callback' => [ $this, 'update_form' ],
131 'permission_callback' => [ $this, 'check_permissions' ],
132 'args' => [
133 'id' => [
134 'required' => true,
135 'validate_callback' => static function ( $param ) {
136 return is_numeric( $param );
137 },
138 ],
139 'campaign_id' => [
140 'type' => 'integer',
141 'sanitize_callback' => 'absint',
142 ],
143 ],
144 ],
145 ],
146 ];
147 }
148
149 /**
150 * Get forms list.
151 *
152 * @param WP_REST_Request $request Request object.
153 * @return WP_REST_Response|WP_Error Response object.
154 * @since 0.0.1
155 */
156 public function get_forms( $request ) {
157 $campaign_id = $request->get_param( 'campaign_id' );
158 $per_page = $request->get_param( 'per_page' ) ?? 100;
159 $status = $request->get_param( 'status' ) ?? 'any';
160
161 // Map status parameter to post_status values.
162 $post_status = 'any' === $status ? [ 'publish', 'draft', 'trash' ] : $status;
163
164 $args = [
165 'posts_per_page' => $per_page,
166 'post_status' => $post_status,
167 ];
168
169 // Filter by campaign if provided.
170 if ( $campaign_id ) {
171 $args['meta_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
172 [
173 'key' => Donation_Form::META_CAMPAIGN_ID,
174 'value' => $campaign_id,
175 'compare' => '=',
176 'type' => 'NUMERIC',
177 ],
178 ];
179 }
180
181 $forms = Donation_Form::get_forms( $args );
182
183 $formatted_forms = [];
184 foreach ( $forms as $form ) {
185 $formatted_forms[] = $this->format_form( $form );
186 }
187
188 return new WP_REST_Response(
189 [
190 'success' => true,
191 'forms' => $formatted_forms,
192 ],
193 200
194 );
195 }
196
197 /**
198 * Get a single form.
199 *
200 * @param WP_REST_Request $request Request object.
201 * @return WP_REST_Response|WP_Error Response object.
202 * @since 0.0.1
203 */
204 public function get_form( $request ) {
205 $form_id = absint( $request->get_param( 'id' ) );
206 $form = get_post( $form_id );
207
208 if ( ! $form || Donation_Form::POST_TYPE !== $form->post_type ) {
209 return new WP_Error(
210 'form_not_found',
211 __( 'Form not found.', 'suredonation' ),
212 [ 'status' => 404 ]
213 );
214 }
215
216 return new WP_REST_Response(
217 [
218 'success' => true,
219 'form' => $this->format_form( $form, true ),
220 ],
221 200
222 );
223 }
224
225 /**
226 * Update form (primarily for updating campaign association).
227 *
228 * @param WP_REST_Request $request Request object.
229 * @return WP_REST_Response|WP_Error Response object.
230 * @since 0.0.1
231 */
232 public function update_form( $request ) {
233 $form_id = absint( $request->get_param( 'id' ) );
234 $campaign_id = $request->get_param( 'campaign_id' );
235
236 $form = get_post( $form_id );
237
238 if ( ! $form || Donation_Form::POST_TYPE !== $form->post_type ) {
239 return new WP_Error(
240 'form_not_found',
241 __( 'Form not found.', 'suredonation' ),
242 [ 'status' => 404 ]
243 );
244 }
245
246 // Update campaign association.
247 if ( ! is_null( $campaign_id ) ) {
248 Donation_Form::set_form_campaign_id( $form_id, $campaign_id );
249 }
250
251 return new WP_REST_Response(
252 [
253 'success' => true,
254 'message' => __( 'Form updated successfully.', 'suredonation' ),
255 'form' => $this->format_form( $form ),
256 ],
257 200
258 );
259 }
260
261 /**
262 * Manage form lifecycle (trash, restore, permanent delete).
263 *
264 * @param WP_REST_Request $request Request object.
265 * @return WP_REST_Response|WP_Error Response object.
266 * @since 0.0.1
267 */
268 public function manage_form_lifecycle( $request ) {
269 $form_ids = $request->get_param( 'form_ids' );
270 $action = $request->get_param( 'action' );
271
272 if ( empty( $form_ids ) || empty( $action ) ) {
273 return new WP_Error(
274 'missing_parameters',
275 __( 'Missing required parameters.', 'suredonation' ),
276 [ 'status' => 400 ]
277 );
278 }
279
280 $results = [];
281 $errors = [];
282
283 foreach ( $form_ids as $form_id ) {
284 $post = get_post( $form_id );
285
286 if ( ! $post || Donation_Form::POST_TYPE !== $post->post_type ) {
287 $errors[] = [
288 'form_id' => $form_id,
289 'error' => __( 'Form not found.', 'suredonation' ),
290 ];
291 continue;
292 }
293
294 $result = false;
295
296 switch ( $action ) {
297 case 'trash':
298 if ( 'trash' === $post->post_status ) {
299 $errors[] = [
300 'form_id' => $form_id,
301 'error' => __( 'Form is already in trash.', 'suredonation' ),
302 ];
303 continue 2;
304 }
305 $result = wp_trash_post( $form_id );
306 break;
307
308 case 'restore':
309 if ( 'trash' !== $post->post_status ) {
310 $errors[] = [
311 'form_id' => $form_id,
312 'error' => __( 'Form is not in trash.', 'suredonation' ),
313 ];
314 continue 2;
315 }
316 $result = wp_untrash_post( $form_id );
317 break;
318
319 case 'delete':
320 $result = wp_delete_post( $form_id, true );
321 break;
322 }
323
324 if ( $result ) {
325 $results[] = [
326 'form_id' => $form_id,
327 'action' => $action,
328 'success' => true,
329 ];
330 } else {
331 $errors[] = [
332 'form_id' => $form_id,
333 'error' => __( 'Operation failed.', 'suredonation' ),
334 ];
335 }
336 }
337
338 return new WP_REST_Response(
339 [
340 'success' => ! empty( $results ),
341 'action' => $action,
342 'processed_ids' => array_column( $results, 'form_id' ),
343 'success_count' => count( $results ),
344 'error_count' => count( $errors ),
345 'results' => $results,
346 'errors' => $errors,
347 ],
348 200
349 );
350 }
351
352 /**
353 * Check if user has read permissions.
354 *
355 * @return bool True if user has permission.
356 * @since 0.0.1
357 */
358 public function check_permissions() {
359 return current_user_can( 'manage_options' );
360 }
361
362 /**
363 * Format form data for API response.
364 *
365 * @param \WP_Post $form Form post object.
366 * @param bool $include_html Whether to include rendered HTML.
367 * @return array<string, mixed> Formatted form data.
368 * @since 0.0.1
369 */
370 private function format_form( $form, $include_html = false ) {
371 $campaign_id = Donation_Form::get_form_campaign_id( $form->ID );
372 $campaign = $campaign_id ? get_post( $campaign_id ) : null;
373
374 $data = [
375 'id' => $form->ID,
376 'title' => $form->post_title,
377 'status' => $form->post_status,
378 'campaign_id' => $campaign_id,
379 'campaign_name' => $campaign ? $campaign->post_title : '',
380 'created_at' => $form->post_date,
381 'modified_at' => $form->post_modified,
382 'edit_url' => admin_url( 'post.php?post=' . $form->ID . '&action=edit' ),
383 ];
384
385 if ( $include_html ) {
386 // Parse and render the form blocks.
387 $blocks = parse_blocks( $form->post_content );
388 $blocks_html = '';
389
390 foreach ( $blocks as $block ) {
391 if ( ! empty( $block['blockName'] ) ) {
392 $block['attrs']['formId'] = $form->ID;
393 $blocks_html .= render_block( $block );
394 }
395 }
396
397 $data['content'] = $form->post_content;
398 $data['rendered_html'] = $blocks_html;
399 }
400
401 return $data;
402 }
403 }
404