PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 1.12.3
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v1.12.3
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 / admin-ajax.php
admin-ajax.php
371 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Sureforms Admin Ajax Class.
4 *
5 * Class file for public functions.
6 *
7 * @package sureforms
8 */
9
10 namespace SRFM\Inc;
11
12 use BSF_UTM_Analytics;
13 use SRFM\Inc\Traits\Get_Instance;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 if ( ! function_exists( 'get_plugins' ) ) {
20 require_once ABSPATH . 'wp-admin/includes/plugin.php';
21 }
22
23 /**
24 * Public Class
25 *
26 * @since 0.0.1
27 */
28 class Admin_Ajax {
29 use Get_Instance;
30
31 /**
32 * Constructor
33 *
34 * @since 0.0.1
35 */
36 public function __construct() {
37 add_action( 'wp_ajax_sureforms_recommended_plugin_activate', [ $this, 'required_plugin_activate' ] );
38 add_action( 'wp_ajax_sureforms_recommended_plugin_install', 'wp_ajax_install_plugin' );
39 add_action( 'wp_ajax_sureforms_integration', [ $this, 'generate_data_for_suretriggers_integration' ] );
40
41 add_filter( SRFM_SLUG . '_admin_filter', [ $this, 'localize_script_integration' ] );
42
43 // adding support for rest-nonce endpoint. To regenerate latest nonce incase of form submission failure.
44 add_action( 'wp_ajax_rest-nonce', [ $this, 'print_rest_nonce' ], 999 );
45 add_action( 'wp_ajax_nopriv_rest-nonce', [ $this, 'print_rest_nonce' ], 999 );
46 }
47
48 /**
49 * Required Plugin Activate
50 *
51 * @return void
52 * @since 0.0.1
53 */
54 public function required_plugin_activate() {
55
56 $response_data = [ 'message' => $this->get_error_msg( 'permission' ) ];
57
58 if ( ! Helper::current_user_can() ) {
59 wp_send_json_error( $response_data );
60 }
61
62 if ( empty( $_POST ) ) {
63 $response_data = [ 'message' => $this->get_error_msg( 'invalid' ) ];
64 wp_send_json_error( $response_data );
65 }
66
67 /**
68 * Nonce verification.
69 */
70 if ( ! check_ajax_referer( 'sf_plugin_manager_nonce', 'security', false ) ) {
71 $response_data = [ 'message' => $this->get_error_msg( 'nonce' ) ];
72 wp_send_json_error( $response_data );
73 }
74
75 if ( ! isset( $_POST['init'] ) || ! sanitize_text_field( wp_unslash( $_POST['init'] ) ) ) {
76 wp_send_json_error(
77 [
78 'success' => false,
79 'message' => __( 'No plugin specified', 'sureforms' ),
80 ]
81 );
82 }
83
84 $plugin_init = isset( $_POST['init'] ) ? sanitize_text_field( wp_unslash( $_POST['init'] ) ) : '';
85
86 $plugin_slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
87
88 $activate = activate_plugin( $plugin_init, '', false, true );
89
90 if ( is_wp_error( $activate ) ) {
91 wp_send_json_error(
92 [
93 'success' => false,
94 'message' => $activate->get_error_message(),
95 ]
96 );
97 }
98
99 if ( class_exists( 'BSF_UTM_Analytics' ) && is_callable( 'BSF_UTM_Analytics::update_referer' ) ) {
100 $plugin_slug = pathinfo( $plugin_slug, PATHINFO_FILENAME );
101 BSF_UTM_Analytics::update_referer( 'sureforms', $plugin_slug );
102 }
103
104 wp_send_json_success(
105 [
106 'success' => true,
107 'message' => __( 'Plugin Successfully Activated', 'sureforms' ),
108 ]
109 );
110 }
111
112 /**
113 * Get ajax error message.
114 *
115 * @param string $type Message type.
116 * @return string
117 * @since 0.0.2
118 */
119 public function get_error_msg( $type ) {
120
121 if ( ! isset( $this->errors[ $type ] ) ) {
122 $type = 'default';
123 }
124 if ( ! isset( $this->errors ) ) {
125 return '';
126 }
127 return $this->errors[ $type ];
128 }
129
130 /**
131 * Localize the variables required for integration plugins.
132 *
133 * @param array<mixed> $values localized values.
134 * @return array<mixed>
135 * @since 0.0.1
136 */
137 public function localize_script_integration( $values ) {
138 $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' );
139 return array_merge(
140 $values,
141 [
142 'ajax_url' => admin_url( 'admin-ajax.php' ),
143 'sfPluginManagerNonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
144 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
145 'isRTL' => is_rtl(),
146 'current_screen_id' => $is_screen_sureforms_menu ? 'sureforms_menu' : '',
147 'form_id' => get_post() ? get_post()->ID : '',
148 'suretriggers_nonce' => wp_create_nonce( 'suretriggers_nonce' ),
149 ]
150 );
151 }
152
153 /**
154 * Generates data required for suretriggers integration
155 *
156 * @since 0.0.8
157 * @return void
158 */
159 public function generate_data_for_suretriggers_integration() {
160 if ( ! Helper::current_user_can() ) {
161 wp_send_json_error( [ 'message' => __( 'You do not have permission to access this page.', 'sureforms' ) ] );
162 }
163
164 if ( ! check_ajax_referer( 'suretriggers_nonce', 'security', false ) ) {
165 wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ] );
166 }
167
168 if ( empty( $_POST['formId'] ) ) {
169 wp_send_json_error( [ 'message' => __( 'Form ID is required.', 'sureforms' ) ] );
170 }
171
172 if ( ! Helper::is_suretriggers_ready() ) {
173 wp_send_json_error(
174 [
175 'code' => 'invalid_secret_key',
176 'message' => __( 'OttoKit is not configured properly.', 'sureforms' ),
177 ]
178 );
179 }
180
181 $form_id = Helper::get_integer_value( sanitize_text_field( wp_unslash( $_POST['formId'] ) ) );
182 $form = get_post( $form_id );
183
184 if ( is_null( $form ) || SRFM_FORMS_POST_TYPE !== $form->post_type ) {
185 wp_send_json_error( [ 'message' => __( 'Invalid form ID.', 'sureforms' ) ] );
186 }
187
188 // Translators: %s: Form ID.
189 $form_name = ! empty( $form->post_title ) ? $form->post_title : sprintf( __( 'SureForms id: %s', 'sureforms' ), $form_id );
190 $api_url = apply_filters( 'suretriggers_get_iframe_url', SRFM_SURETRIGGERS_INTEGRATION_BASE_URL );
191
192 // This is the format of data required by SureTriggers for adding iframe in target id.
193 $body = [
194 'client_id' => 'SureForms',
195 'st_embed_url' => $api_url,
196 'embedded_identifier' => $form_id,
197 'target' => 'suretriggers-iframe-wrapper', // div where we want SureTriggers to add iframe should have this target id.
198 'event' => [
199 'label' => __( 'Form Submitted', 'sureforms' ),
200 'value' => 'sureforms_form_submitted',
201 'description' => __( 'Runs when a form is submitted', 'sureforms' ),
202 ],
203 'summary' => $form_name,
204 'selected_options' => [
205 'form_id' => [
206 'value' => $form_id,
207 'label' => $form_name,
208 ],
209 ],
210 'integration' => 'SureForms',
211 'sample_response' => [
212 'form_id' => $form_id,
213 'to_emails' => [
214 'dev-email@wpengine.local',
215 ],
216 'form_name' => $form_name,
217 'data' => $this->get_form_fields( $form_id ),
218 ],
219 ];
220
221 // Adding entry_id in body sample response if do_not_store_entries is not enabled.
222 $compliance = get_post_meta( $form_id, '_srfm_compliance', true );
223 $do_not_store_entries = is_array( $compliance ) && isset( $compliance[0]['do_not_store_entries'] )
224 ? $compliance[0]['do_not_store_entries']
225 : null;
226
227 if ( ! $do_not_store_entries ) {
228 $body['sample_response']['entry_id'] = 12;
229 }
230
231 wp_send_json_success(
232 [
233 'message' => 'success',
234 'data' => apply_filters( 'srfm_suretriggers_integration_data_filter', $body, $form_id ),
235 ]
236 );
237 }
238
239 /**
240 * This function populates data for particular form.
241 *
242 * @param int $form_id Form ID.
243 * @since 0.0.8
244 * @return array<mixed>
245 */
246 public function get_form_fields( $form_id ) {
247 if ( empty( $form_id ) || ! is_int( $form_id ) ) {
248 return [];
249 }
250
251 if ( SRFM_FORMS_POST_TYPE !== get_post_type( $form_id ) ) {
252 return [];
253 }
254
255 $post = get_post( $form_id );
256
257 if ( is_null( $post ) ) {
258 return [];
259 }
260
261 $blocks = parse_blocks( $post->post_content );
262
263 $blocks = array_filter(
264 $blocks,
265 static function( $block ) {
266 if ( 'srfm/html' === $block['blockName'] ) {
267 return false;
268 }
269 return true;
270 }
271 );
272
273 $blocks = array_values( $blocks );
274
275 if ( empty( $blocks ) ) {
276 return [];
277 }
278
279 $data = [];
280
281 foreach ( $blocks as $block ) {
282 if ( ! empty( $block['blockName'] ) && 0 === strpos( $block['blockName'], 'srfm/' ) ) {
283 if ( ! empty( $block['attrs']['slug'] ) ) {
284 $data[ $block['attrs']['slug'] ] = $this->get_sample_data( $block['blockName'] );
285 }
286 }
287 }
288
289 if ( empty( $data ) ) {
290 return [];
291 }
292
293 return $data;
294 }
295
296 /**
297 * Returns sample data for a block.
298 *
299 * @param string $block_name Block name.
300 * @since 0.0.8
301 * @return mixed
302 */
303 public function get_sample_data( $block_name ) {
304 if ( empty( $block_name ) ) {
305 return __( 'Sample data', 'sureforms' );
306 }
307
308 $dummy_data = [
309 'srfm/input' => __( 'Sample input data', 'sureforms' ),
310 'srfm/email' => 'noreply@sureforms.com',
311 'srfm/textarea' => __( 'Sample textarea data', 'sureforms' ),
312 'srfm/number' => 123,
313 'srfm/checkbox' => 'checkbox value',
314 'srfm/gdpr' => 'GDPR value',
315 'srfm/phone' => '1234567890',
316 'srfm/address' => __( 'Address data', 'sureforms' ),
317 'srfm/address-compact' => __( 'Address data', 'sureforms' ),
318 'srfm/dropdown' => __( 'Selected dropdown option', 'sureforms' ),
319 'srfm/multi-choice' => __( 'Selected Multichoice option', 'sureforms' ),
320 'srfm/radio' => __( 'Selected radio option', 'sureforms' ),
321 'srfm/submit' => __( 'Submit', 'sureforms' ),
322 'srfm/url' => 'https://example.com',
323 'srfm/date-time-picker' => '2022-01-01 12:00:00',
324 'srfm/hidden' => __( 'Hidden Value', 'sureforms' ),
325 'srfm/slider' => 50,
326 'srfm/password' => 'DummyPassword123',
327 'srfm/rating' => 4,
328 'srfm/upload' => 'https://example.com/uploads/file.pdf',
329 ];
330
331 /**
332 * Filter the sample data for specific block types.
333 *
334 * Allows plugins and themes to add custom sample data for their block types
335 * or modify existing sample data. This is particularly useful for dynamic
336 * block types that require complex sample data structures.
337 *
338 * @since 0.0.8
339 *
340 * @param array $dummy_data {
341 * Array of sample data keyed by block name.
342 *
343 * @type string|array $block_name Sample data for the block.
344 * }
345 * @param array $filter_args {
346 * Additional filter arguments.
347 *
348 * @type string $block_name The name of the block being processed.
349 * }
350 */
351 $dummy_data = Helper::apply_filters_as_array( 'srfm_sample_data_filter', $dummy_data, [ 'block_name' => $block_name ] );
352
353 if ( ! empty( $dummy_data[ $block_name ] ) ) {
354 return $dummy_data[ $block_name ];
355 }
356 return __( 'Sample data', 'sureforms' );
357 }
358
359 /**
360 * This function will echo wp_rest nonce
361 * was required to provide nonce for fallback of wp.apiFetch
362 *
363 * @since 1.2.4
364 * @return void
365 */
366 public function print_rest_nonce() {
367 echo esc_js( wp_create_nonce( 'wp_rest' ) );
368 exit;
369 }
370 }
371