PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.7.1
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.7.1
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 / export.php
export.php
311 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Sureforms export.
4 *
5 * @package sureforms.
6 * @since 0.0.1
7 */
8
9 namespace SRFM\Inc;
10
11 use SRFM\Inc\Traits\Get_Instance;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly.
15 }
16
17 /**
18 * Load Defaults Class.
19 *
20 * @since 0.0.1
21 */
22 class Export {
23 use Get_Instance;
24
25 /**
26 * Unserialized post metas.
27 *
28 * @var array<string>
29 */
30 public $unserialized_post_metas = [
31 '_srfm_conditional_logic',
32 '_srfm_email_notification',
33 '_srfm_form_confirmation',
34 '_srfm_compliance',
35 '_srfm_forms_styling',
36 '_srfm_integrations_webhooks',
37 '_srfm_instant_form_settings',
38 '_srfm_page_break_settings',
39 '_srfm_conversational_form',
40 '_srfm_premium_common',
41 '_srfm_forms_styling_starter',
42 '_srfm_user_registration_settings',
43 ];
44
45 /**
46 * Constructor
47 *
48 * @since 0.0.1
49 */
50 public function __construct() {
51 // Modern REST API endpoints are registered in rest-api.php.
52 }
53
54 /**
55 * Get unserialized post meta keys.
56 *
57 * Retrieves the list of post meta keys that need to be unserialized during export.
58 * Allows filtering of meta keys via 'srfm_export_and_import_post_meta_keys' filter.
59 *
60 * @since 1.9.0
61 * @return array<string> Array of post meta keys to unserialize.
62 */
63 public function get_unserialized_post_metas() {
64 return Helper::apply_filters_as_array( 'srfm_export_and_import_post_meta_keys', $this->unserialized_post_metas );
65 }
66
67 /**
68 * Get forms with meta by post IDs.
69 * Uses:
70 * - On websitedemos.net, for exporting the Spectra Block Patterns & Pages with SureForms form.
71 *
72 * @since 1.13.0
73 * @param array<int,string>|array<int, int> $post_ids Array of post IDs to retrieve forms for.
74 * @return array Array of forms with their post data and meta data.
75 */
76 public function get_forms_with_meta( $post_ids = [] ) {
77 $posts = [];
78
79 foreach ( $post_ids as $post_id ) {
80 $post_id = intval( $post_id );
81 $post = get_post( $post_id );
82 $post_meta = get_post_meta( $post_id );
83 $posts[] = [
84 'post' => $post,
85 'post_meta' => $post_meta,
86 ];
87 }
88
89 // Unserialize the post metas that are serialized.
90 // This is needed because the post metas are serialized before saving.
91 foreach ( $posts as $key => $post ) {
92 $post_metas = isset( $post['post_meta'] ) && is_array( $post['post_meta'] ) ? $post['post_meta'] : [];
93
94 foreach ( $this->get_unserialized_post_metas() as $meta_key ) {
95 if ( isset( $post_metas[ $meta_key ] ) && is_array( $post_metas[ $meta_key ] ) ) {
96 $post_metas[ $meta_key ] = maybe_unserialize( $post_metas[ $meta_key ][0] );
97 }
98 }
99 $posts[ $key ]['post_meta'] = $post_metas;
100 }
101
102 return $posts;
103 }
104
105 /**
106 * Handle Export form via REST API
107 *
108 * @param \WP_REST_Request $request Full details about the request.
109 * @since 2.0.0
110 * @return \WP_REST_Response|\WP_Error
111 */
112 public function handle_export_form_rest( $request ) {
113 $nonce = sanitize_text_field( Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) ) );
114
115 if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
116 return new \WP_Error(
117 'invalid_nonce',
118 __( 'Nonce verification failed.', 'sureforms' ),
119 [ 'status' => 403 ]
120 );
121 }
122
123 $params = $request->get_params();
124 $post_ids = [];
125
126 // Handle post_ids parameter - can be array or comma-separated string.
127 if ( isset( $params['post_ids'] ) ) {
128 if ( is_array( $params['post_ids'] ) ) {
129 $post_ids = array_map( 'intval', $params['post_ids'] );
130 } else {
131 $post_ids = array_map( 'intval', explode( ',', sanitize_text_field( Helper::get_string_value( $params['post_ids'] ) ) ) );
132 }
133 }
134
135 // Validate that all post IDs are valid sureforms_form posts.
136 $validated_post_ids = [];
137 foreach ( $post_ids as $post_id ) {
138 $post = get_post( $post_id );
139 if ( $post && 'sureforms_form' === $post->post_type ) {
140 $validated_post_ids[] = $post_id;
141 }
142 }
143
144 if ( empty( $validated_post_ids ) ) {
145 return new \WP_Error(
146 'no_valid_forms',
147 __( 'No valid forms found for export.', 'sureforms' ),
148 [ 'status' => 400 ]
149 );
150 }
151
152 $posts = $this->get_forms_with_meta( $validated_post_ids );
153
154 return new \WP_REST_Response(
155 [
156 'success' => true,
157 'data' => $posts,
158 'count' => count( $posts ),
159 ]
160 );
161 }
162
163 /**
164 * Handle Import form via REST API
165 *
166 * @param \WP_REST_Request $request Full details about the request.
167 * @since 2.0.0
168 * @return \WP_REST_Response|\WP_Error
169 */
170 public function handle_import_form_rest( $request ) {
171 $nonce = sanitize_text_field( Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) ) );
172
173 if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
174 return new \WP_Error(
175 'invalid_nonce',
176 __( 'Nonce verification failed.', 'sureforms' ),
177 [ 'status' => 403 ]
178 );
179 }
180
181 $params = $request->get_params();
182
183 // Get forms data from the request.
184 $forms_data = isset( $params['forms_data'] ) && is_array( $params['forms_data'] ) ? $params['forms_data'] : [];
185 $default_status = isset( $params['default_status'] ) ? sanitize_text_field( Helper::get_string_value( $params['default_status'] ) ) : 'draft';
186
187 if ( empty( $forms_data ) ) {
188 return new \WP_Error(
189 'no_forms_data',
190 __( 'No forms data provided for import.', 'sureforms' ),
191 [ 'status' => 400 ]
192 );
193 }
194
195 // Validate forms data structure.
196 foreach ( $forms_data as $form_data ) {
197 if ( ! is_array( $form_data ) || ! isset( $form_data['post'] ) || ! isset( $form_data['post_meta'] ) ) {
198 return new \WP_Error(
199 'invalid_form_data',
200 __( 'Invalid form data structure provided.', 'sureforms' ),
201 [ 'status' => 400 ]
202 );
203 }
204 }
205
206 $result = $this->import_forms_with_meta( $forms_data, $default_status );
207
208 if ( is_wp_error( $result ) ) {
209 return $result;
210 }
211
212 return new \WP_REST_Response(
213 [
214 'success' => true,
215 'message' => __( 'Forms imported successfully!', 'sureforms' ),
216 'forms_mapping' => $result,
217 'imported_count' => count( $result ),
218 ]
219 );
220 }
221
222 /**
223 * Import Forms with Meta
224 * Uses:
225 * - In Design Library for importing the Spectra Block Patterns and Pages with SureForms form.
226 *
227 * @param array<array<array<string>>> $data Form data to import.
228 * @param string $default_status Default post status for imported forms. Default is 'draft'.
229 *
230 * @since 1.13.0
231 * @return array<int, int>|\WP_Error Returns mapping array on success, WP_Error on failure.
232 */
233 public function import_forms_with_meta( $data, $default_status = 'draft' ) {
234 $forms_mapping = [];
235 foreach ( $data as $form_data ) {
236 // sanitize the data before saving.
237 $old_id = intval( $form_data['post']['ID'] );
238 $post_content = wp_kses_post( $form_data['post']['post_content'] );
239 $post_title = sanitize_text_field( $form_data['post']['post_title'] );
240 $post_meta = $form_data['post_meta'];
241 $post_type = sanitize_text_field( $form_data['post']['post_type'] );
242
243 // Remove percent-encoded slugs from imported form content.
244 // Non-Latin labels produce broken slugs like %e3%83%95%e3%83%aa
245 // via sanitize_title(). Clearing them lets process_blocks()
246 // regenerate clean block-name-based slugs on save.
247 $cleaned_content = preg_replace(
248 '/"slug":"(%[a-fA-F0-9]{2}[^"]*)"/',
249 '"slug":""',
250 $post_content
251 );
252 if ( is_string( $cleaned_content ) ) {
253 $post_content = $cleaned_content;
254 }
255
256 $post_content = addslashes( $post_content );
257
258 // Check if sureforms/form exists in post_content.
259 if ( 'sureforms_form' === $post_type ) {
260 $new_post = [
261 'post_title' => $post_title,
262 'post_status' => $default_status,
263 'post_type' => 'sureforms_form',
264 ];
265
266 $post_id = wp_insert_post( $new_post );
267
268 // Update the post content formId to the new post id.
269 $post_content = str_replace(
270 '\"formId\":' . intval( $form_data['post']['ID'] ),
271 '\"formId\":' . intval( $post_id ),
272 $post_content
273 );
274
275 // update the post content.
276 wp_update_post(
277 [
278 'ID' => $post_id,
279 'post_content' => $post_content,
280 ]
281 );
282
283 if ( ! $post_id ) {
284 return new \WP_Error( 'import_forms_failed', __( 'Unable to import form.', 'sureforms' ) );
285 }
286
287 $forms_mapping[ $old_id ] = $post_id;
288
289 // Update post meta.
290 foreach ( $post_meta as $meta_key => $meta_value ) {
291 // Check if the meta key is one of the unserialized post metas then add it as is.
292 if ( in_array( $meta_key, $this->get_unserialized_post_metas(), true ) ) {
293 add_post_meta( $post_id, $meta_key, $meta_value );
294 } else {
295 if ( is_array( $meta_value ) && isset( $meta_value[0] ) ) {
296 add_post_meta( $post_id, $meta_key, $meta_value[0] );
297 } else {
298 add_post_meta( $post_id, $meta_key, $meta_value );
299 }
300 }
301 }
302 } else {
303 return new \WP_Error( 'import_forms_invalid_post_type', __( 'Unable to import form.', 'sureforms' ) );
304 }
305 }
306
307 return $forms_mapping;
308 }
309
310 }
311