PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.5.2
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.5.2
2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 All 96 releases
sureforms / inc / abilities / forms / update-form.php
update-form.php
291 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Update Form Ability.
4 *
5 * @package sureforms
6 * @since 2.5.2
7 */
8
9 namespace SRFM\Inc\Abilities\Forms;
10
11 use SRFM\Inc\Abilities\Abstract_Ability;
12 use SRFM\Inc\AI_Form_Builder\Field_Mapping;
13 use SRFM\Inc\Create_New_Form;
14 use SRFM\Inc\Helper;
15 use WP_REST_Request;
16
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit; // Exit if accessed directly.
19 }
20
21 /**
22 * Update_Form ability class.
23 *
24 * Updates an existing SureForms form's title, status, fields, and/or metadata.
25 *
26 * @since 2.5.2
27 */
28 class Update_Form extends Abstract_Ability {
29 use Form_Field_Schema;
30 use Form_Metadata;
31
32 /**
33 * Constructor.
34 *
35 * @since 2.5.2
36 */
37 public function __construct() {
38 $this->id = 'sureforms/update-form';
39 $this->label = __( 'Update SureForms Form', 'sureforms' );
40 $this->description = __( 'Update an existing SureForms form title, status (publish/draft/private/trash), fields, and/or metadata settings. Use status "trash" to trash a form, or change from "trash" to another status to restore it. Providing formFields replaces all existing fields.', 'sureforms' );
41 $this->capability = 'manage_options';
42 }
43
44 /**
45 * {@inheritDoc}
46 *
47 * @since 2.5.2
48 */
49 public function get_annotations() {
50 return [
51 'readonly' => false,
52 'destructive' => false,
53 'idempotent' => true,
54 ];
55 }
56
57 /**
58 * {@inheritDoc}
59 *
60 * @since 2.5.2
61 */
62 public function get_input_schema() {
63 $field_properties = $this->get_form_field_schema();
64
65 return [
66 'type' => 'object',
67 'properties' => [
68 'form_id' => [
69 'type' => 'integer',
70 'description' => __( 'The ID of the form to update.', 'sureforms' ),
71 ],
72 'title' => [
73 'type' => 'string',
74 'description' => __( 'New title for the form.', 'sureforms' ),
75 ],
76 'status' => [
77 'type' => 'string',
78 'description' => __( 'New status for the form.', 'sureforms' ),
79 'enum' => [ 'publish', 'draft', 'private', 'trash' ],
80 ],
81 'formFields' => [
82 'type' => 'array',
83 'description' => __( 'Array of form field definitions. Providing this replaces all existing fields.', 'sureforms' ),
84 'items' => [
85 'type' => 'object',
86 'properties' => $field_properties,
87 'required' => [ 'label', 'fieldType' ],
88 ],
89 ],
90 'formMetaData' => [
91 'type' => 'object',
92 'description' => __( 'Optional form metadata including confirmation, compliance, and styling settings. Same schema as create-form.', 'sureforms' ),
93 'properties' => [
94 'formConfirmation' => [
95 'type' => 'object',
96 'properties' => [
97 'confirmationMessage' => [
98 'type' => 'string',
99 'description' => __( 'Message displayed after successful submission.', 'sureforms' ),
100 ],
101 ],
102 ],
103 'compliance' => [
104 'type' => 'object',
105 'properties' => [
106 'enableCompliance' => [ 'type' => 'boolean' ],
107 'neverStoreEntries' => [ 'type' => 'boolean' ],
108 'autoDeleteEntries' => [ 'type' => 'boolean' ],
109 'autoDeleteEntriesDays' => [ 'type' => 'string' ],
110 ],
111 ],
112 'instantForm' => [
113 'type' => 'object',
114 'properties' => [
115 'instantForm' => [ 'type' => 'boolean' ],
116 'showTitle' => [ 'type' => 'boolean' ],
117 'formBackgroundColor' => [ 'type' => 'string' ],
118 'formWidth' => [ 'type' => 'integer' ],
119 ],
120 ],
121 'general' => [
122 'type' => 'object',
123 'properties' => [
124 'useLabelAsPlaceholder' => [ 'type' => 'boolean' ],
125 'submitText' => [ 'type' => 'string' ],
126 ],
127 ],
128 'styling' => [
129 'type' => 'object',
130 'properties' => [
131 'submitAlignment' => [ 'type' => 'string' ],
132 ],
133 ],
134 ],
135 ],
136 ],
137 'required' => [ 'form_id' ],
138 ];
139 }
140
141 /**
142 * {@inheritDoc}
143 *
144 * @since 2.5.2
145 */
146 public function get_output_schema() {
147 return [
148 'type' => 'object',
149 'properties' => [
150 'form_id' => [ 'type' => 'integer' ],
151 'title' => [ 'type' => 'string' ],
152 'status' => [ 'type' => 'string' ],
153 'previous_status' => [ 'type' => 'string' ],
154 'edit_url' => [ 'type' => 'string' ],
155 'updated_fields' => [
156 'type' => 'array',
157 'items' => [ 'type' => 'string' ],
158 ],
159 ],
160 ];
161 }
162
163 /**
164 * Execute the update-form ability.
165 *
166 * @param array<string,mixed> $input Validated input data.
167 * @since 2.5.2
168 * @return array<string,mixed>|\WP_Error
169 */
170 public function execute( $input ) {
171 $form_id = Helper::get_integer_value( $input['form_id'] ?? 0 );
172 $post = get_post( $form_id );
173
174 if ( ! $post || SRFM_FORMS_POST_TYPE !== $post->post_type ) {
175 return new \WP_Error(
176 'srfm_form_not_found',
177 __( 'Form not found.', 'sureforms' ),
178 [ 'status' => 404 ]
179 );
180 }
181
182 $previous_status = $post->post_status;
183 $updated_fields = [];
184
185 // Handle status changes.
186 if ( ! empty( $input['status'] ) ) {
187 $new_status = sanitize_text_field( Helper::get_string_value( $input['status'] ) );
188 $allowed_status = [ 'publish', 'draft', 'private', 'trash' ];
189
190 if ( in_array( $new_status, $allowed_status, true ) ) {
191 if ( 'trash' === $new_status && 'trash' !== $previous_status ) {
192 wp_trash_post( $form_id );
193 $updated_fields[] = 'status';
194 } elseif ( 'trash' !== $new_status && 'trash' === $previous_status ) {
195 wp_untrash_post( $form_id );
196 // After untrash, set the desired status.
197 wp_update_post(
198 [
199 'ID' => $form_id,
200 'post_status' => $new_status,
201 ]
202 );
203 $updated_fields[] = 'status';
204 } elseif ( $new_status !== $previous_status ) {
205 wp_update_post(
206 [
207 'ID' => $form_id,
208 'post_status' => $new_status,
209 ]
210 );
211 $updated_fields[] = 'status';
212 }
213 }
214 }
215
216 // Handle title changes.
217 if ( ! empty( $input['title'] ) ) {
218 $new_title = sanitize_text_field( Helper::get_string_value( $input['title'] ) );
219
220 if ( $new_title !== $post->post_title ) {
221 wp_update_post(
222 [
223 'ID' => $form_id,
224 'post_title' => $new_title,
225 ]
226 );
227 $updated_fields[] = 'title';
228 }
229 }
230
231 // Handle metadata changes.
232 if ( ! empty( $input['formMetaData'] ) && is_array( $input['formMetaData'] ) ) {
233 $current_metas = [];
234 $meta_keys = Create_New_Form::get_default_meta_keys();
235
236 foreach ( array_keys( $meta_keys ) as $meta_key ) {
237 $current_metas[ $meta_key ] = get_post_meta( $form_id, $meta_key, true );
238 }
239
240 $updated_metas = $this->apply_metadata_overrides( $current_metas, $input['formMetaData'] );
241
242 foreach ( $updated_metas as $meta_key => $meta_value ) {
243 if ( isset( $current_metas[ $meta_key ] ) && $current_metas[ $meta_key ] === $meta_value ) {
244 continue;
245 }
246 update_post_meta( $form_id, $meta_key, $meta_value );
247 }
248
249 $updated_fields[] = 'metadata';
250 }
251
252 // Handle field changes.
253 if ( ! empty( $input['formFields'] ) && is_array( $input['formFields'] ) ) {
254 // Sanitize form fields before passing to Field_Mapping.
255 $form_fields = $this->sanitize_form_fields( $input['formFields'] );
256
257 $request = new WP_REST_Request( 'POST' );
258 $request->set_param(
259 'form_data',
260 [
261 'form' => [ 'formFields' => $form_fields ],
262 ]
263 );
264
265 $post_content = Field_Mapping::generate_gutenberg_fields_from_questions( $request );
266
267 if ( ! empty( $post_content ) ) {
268 wp_update_post(
269 [
270 'ID' => $form_id,
271 'post_content' => $post_content,
272 ]
273 );
274 $updated_fields[] = 'fields';
275 }
276 }
277
278 // Re-fetch post to get the current state.
279 $updated_post = get_post( $form_id );
280
281 return [
282 'form_id' => $form_id,
283 'title' => $updated_post ? $updated_post->post_title : $post->post_title,
284 'status' => $updated_post ? $updated_post->post_status : $post->post_status,
285 'previous_status' => $previous_status,
286 'edit_url' => admin_url( 'post.php?post=' . $form_id . '&action=edit' ),
287 'updated_fields' => $updated_fields,
288 ];
289 }
290 }
291