PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.8.14
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.8.14
7.8.14 7.8.14.1 7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / provider / class-hustle-provider-admin-ajax.php
wordpress-popup / inc / provider Last commit date
class-hustle-provider-abstract.php 5 months ago class-hustle-provider-admin-ajax.php 1 month ago class-hustle-provider-autoload.php 5 months ago class-hustle-provider-container.php 3 years ago class-hustle-provider-form-hooks-abstract.php 5 months ago class-hustle-provider-form-settings-abstract.php 1 month ago class-hustle-provider-interface.php 5 months ago class-hustle-provider-utils.php 1 month ago
class-hustle-provider-admin-ajax.php
822 lines
1 <?php
2 /**
3 * File for Hustle_Provider_Admin_Ajax class.
4 *
5 * @package Hustle
6 * @since 3.0.5
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 die();
11 }
12
13 /**
14 * Class Hustle_Provider_Admin_Ajax.
15 * Handles the AJAX actions for providers.
16 *
17 * @since 4.0.0
18 */
19 class Hustle_Provider_Admin_Ajax {
20
21 /**
22 * Default nonce action.
23 *
24 * @since 4.0.0
25 * @var string
26 */
27 private static $nonce_action = 'hustle_provider_action';
28
29 /**
30 * Instance of this class.
31 *
32 * @since 4.2.0
33 * @var Hustle_Provider_Admin_Ajax
34 */
35 private static $instance = null;
36
37 /**
38 * Instance of Hustle_Layout_Helper.
39 *
40 * @since 4.2.0
41 * @var Hustle_Layout_Helper
42 */
43 private $renderer = null;
44
45 /**
46 * Returns an instance of this class.
47 *
48 * @since 4.2.0
49 * @return Hustle_Provider_Admin_Ajax
50 */
51 public static function get_instance() {
52 if ( is_null( self::$instance ) ) {
53 self::$instance = new self();
54 }
55
56 return self::$instance;
57 }
58
59 /**
60 * Class constructor.
61 *
62 * @since 4.0.0
63 */
64 public function __construct() {
65
66 $this->renderer = new Hustle_Layout_Helper();
67
68 add_action( 'wp_ajax_hustle_provider_get_providers', array( $this, 'get_addons' ) );
69 add_action( 'wp_ajax_hustle_provider_get_form_providers', array( $this, 'get_form_addons' ) );
70 add_action( 'wp_ajax_hustle_provider_deactivate', array( $this, 'deactivate' ) );
71 add_action( 'wp_ajax_hustle_provider_is_on_module', array( $this, 'is_on_module' ) );
72 add_action( 'wp_ajax_hustle_provider_settings', array( $this, 'settings' ) );
73 add_action( 'wp_ajax_hustle_provider_form_settings', array( $this, 'form_settings' ) );
74 add_action( 'wp_ajax_hustle_provider_form_deactivate', array( $this, 'form_deactivate' ) );
75 add_action( 'wp_ajax_hustle_refresh_email_lists', array( $this, 'refresh_email_lists' ) );
76 add_action( 'wp_ajax_hustle_provider_insert_local_list', array( $this, 'insert_local_list' ) );
77 add_action( 'wp_ajax_hustle_provider_migrate_aweber', array( $this, 'migrate_aweber' ) );
78 add_action( 'wp_ajax_hustle_provider_migrate_constantcontact', array( $this, 'migrate_constantcontact' ) );
79 add_action( 'wp_ajax_hustle_provider_migrate_infusionsoft', array( $this, 'migrate_infusionsoft' ) );
80 add_action( 'wp_ajax_hustle_provider_migrate_convertkit', array( $this, 'migrate_convertkit' ) );
81 add_action( 'wp_ajax_hustle_provider_migrate_hubspot', array( $this, 'migrate_hubspot' ) );
82 }
83
84 /**
85 * Validates the Ajax request.
86 *
87 * @since 4.0.0
88 */
89 private function validate_ajax() {
90 Opt_In_Utils::validate_ajax_call( self::$nonce_action );
91 }
92
93 /**
94 * Executes the deactivation of the global instance of a provider.
95 *
96 * @since 4.0.0
97 */
98 public function deactivate() {
99 $this->validate_ajax();
100 Opt_In_Utils::is_user_allowed_ajax( 'hustle_edit_integrations' );
101
102 $post_data = ! empty( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
103
104 $data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug' ) );
105 $slug = $data['slug'];
106 $addon = Hustle_Provider_Utils::get_provider_by_slug( $slug );
107
108 // . Hustle_Provider_Utils::maybe_attach_addon_hook( $addon ).
109 $title = $addon->get_title();
110
111 // Handling multi_id.
112 if ( isset( $data['global_multi_id'] ) ) {
113
114 $multi_id_label = '';
115 $multi_ids = $addon->get_global_multi_ids();
116 foreach ( $multi_ids as $key => $multi_id ) {
117 if ( isset( $multi_id['id'] ) && $multi_id['label'] ) {
118 if ( $multi_id['id'] === $data['global_multi_id'] ) {
119 $multi_id_label = $multi_id['label'];
120 break;
121 }
122 }
123 }
124
125 if ( ! empty( $multi_id_label ) ) {
126 $title .= ' - ' . $multi_id_label;
127 }
128 }
129
130 $deactivated = Hustle_Providers::get_instance()->deactivate_addon( $slug, $data );
131
132 if ( ! $deactivated ) {
133 wp_send_json_error(
134 array(
135 'message' => Hustle_Providers::get_instance()->get_last_error_message(),
136 'data' => array(
137 'notification' => array(
138 'type' => 'error',
139 'text' => Hustle_Providers::get_instance()->get_last_error_message(),
140 ),
141 ),
142 )
143 );
144 }
145
146 wp_send_json_success(
147 array(
148 'message' => __( 'Addon Deactivated', 'hustle' ),
149 'data' => array(
150 'notification' => array(
151 'type' => 'success',
152 'text' => '<strong>' . $title . '</strong> ' . __( 'Successfully disconnected' ),
153 ),
154 ),
155 )
156 );
157 }
158
159
160 /**
161 * Get Addons list, grouped by connected status
162 *
163 * @since 4.0
164 */
165 public function get_addons() {
166 $this->validate_ajax();
167
168 $providers = Hustle_Provider_Utils::get_registered_addons_grouped_by_connected();
169 $connected_html = $this->renderer->render( 'admin/integrations/page-table-connected', array( 'providers' => $providers['connected'] ), true );
170 $not_connected_html = $this->renderer->render( 'admin/integrations/page-table-not-connected', array( 'providers' => $providers['not_connected'] ), true );
171
172 wp_send_json_success(
173 array(
174 'connected' => $connected_html,
175 'not_connected' => $not_connected_html,
176 )
177 );
178 }
179
180 /**
181 * Refresh email lists
182 *
183 * @since 4.0.2
184 */
185 public function refresh_email_lists() {
186 $this->validate_ajax();
187
188 $module_id = filter_input( INPUT_POST, 'id', FILTER_VALIDATE_INT );
189 $slug = filter_input( INPUT_POST, 'slug', FILTER_SANITIZE_SPECIAL_CHARS );
190 $type = filter_input( INPUT_POST, 'type', FILTER_SANITIZE_SPECIAL_CHARS );
191
192 $provider = Hustle_Provider_Utils::get_provider_by_slug( $slug );
193
194 if ( ! $provider ) {
195 wp_send_json_error( esc_html__( 'Provider not found', 'hustle' ) );
196 }
197
198 $class_name = $provider->get_form_settings_class_name();
199 if ( empty( $class_name ) || ! class_exists( $class_name ) ) {
200 wp_send_json_error( esc_html__( 'Settings class not found', 'hustle' ) );
201 }
202 $form_settings_instance = new $class_name( $provider, $module_id );
203 $lists = $form_settings_instance->get_global_multi_lists( true, $module_id, $type );
204
205 $list_id = empty( $type ) || 'forms' !== $type ? 'list_id' : 'form_id';
206 $options = array(
207 'list' => array(
208 'id' => $list_id,
209 'type' => 'select',
210 'name' => $list_id,
211 'default' => '',
212 'options' => $lists,
213 'value' => '',
214 'selected' => '',
215 'class' => 'sui-select',
216 ),
217 );
218 $select = Hustle_Provider_Utils::get_html_for_options( $options );
219
220 wp_send_json_success(
221 array(
222 'select' => $select,
223 )
224 );
225 }
226
227 /**
228 * Get providers list, grouped by connected status with module
229 *
230 * @since 4.0.0
231 */
232 public function get_form_addons() {
233 $this->validate_ajax();
234
235 $post_data = ! empty( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
236
237 $sanitized_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'moduleId' => 'moduleId' ) );
238 $module_id = isset( $sanitized_data['moduleId'] ) ? $sanitized_data['moduleId'] : '';
239 $providers = Hustle_Provider_Utils::get_registered_addons_grouped_by_form_connected( $module_id );
240 $connected_html = $this->renderer->render(
241 'admin/integrations/wizard-table-connected',
242 array(
243 'providers' => $providers['connected'],
244 'module_id' => $module_id,
245 ),
246 true
247 );
248 $not_connected_html = $this->renderer->render(
249 'admin/integrations/wizard-table-not-connected',
250 array(
251 'providers' => $providers['not_connected'],
252 'module_id' => $module_id,
253 ),
254 true
255 );
256
257 $list_connected = array();
258
259 if ( ! empty( $providers ) && isset( $providers['connected'] ) ) {
260 foreach ( $providers['connected'] as $key => $value ) {
261 $list_connected[] = $value['slug'];
262 }
263 }
264
265 wp_send_json_success(
266 array(
267 'connected' => $connected_html,
268 'not_connected' => $not_connected_html,
269 'list_connected' => implode( ',', $list_connected ),
270 'list_connected_total' => count( $list_connected ),
271 )
272 );
273 }
274
275 /**
276 * Handles the provider's wizard for the global configuration.
277 *
278 * @since 4.0.0
279 */
280 public function settings() {
281 $this->validate_ajax();
282 Opt_In_Utils::is_user_allowed_ajax( 'hustle_edit_integrations' );
283
284 $sanitized_post_data = $this->get_sanitized_submitted_data();
285
286 $check_required_fields_missing = $this->check_required_fields( $sanitized_post_data, array( 'slug', 'step', 'current_step' ) );
287
288 if ( ! empty( $check_required_fields_missing ) ) {
289 wp_send_json_error(
290 array(
291 'message' => __( 'Please check the required fields.', 'hustle' ),
292 'errors' => $check_required_fields_missing,
293 )
294 );
295 }
296
297 $slug = $sanitized_post_data['slug'];
298 $step = $sanitized_post_data['step'];
299 $current_step = $sanitized_post_data['current_step'];
300 $module_id = 0;
301 if ( isset( $sanitized_post_data['module_id'] ) ) {
302 $module_id = $sanitized_post_data['module_id'];
303 // Module_id could be unset from $sanitized_post_data when the providers don't expect it anymore within they params.
304 }
305
306 $provider = Hustle_Provider_Utils::get_provider_by_slug( $slug );
307
308 if ( ! $provider ) {
309 wp_send_json_error( __( 'Provider not found', 'hustle' ) );
310 }
311
312 if ( ! $provider->is_settings_available() ) {
313 wp_send_json_error(
314 array(
315 'data' => $provider->get_empty_wizard( __( 'This provider does not have settings available', 'hustle' ) ),
316 )
317 );
318 }
319
320 Hustle_Provider_Utils::maybe_attach_addon_hook( $provider );
321
322 unset( $sanitized_post_data['slug'] );
323 unset( $sanitized_post_data['current_step'] );
324 unset( $sanitized_post_data['step'] );
325
326 $wizard = $provider->get_settings_wizard( $sanitized_post_data, $module_id, $current_step, $step, true );
327
328 wp_send_json_success(
329 array(
330 'data' => $wizard,
331 )
332 );
333 }
334
335 /**
336 * Handles the provider's wizard for the per module configuration.
337 *
338 * @since 4.0.0
339 */
340 public function form_settings() {
341 $this->validate_ajax();
342
343 $sanitized_post_data = $this->get_sanitized_submitted_data( array( 'module_id' => FILTER_VALIDATE_INT ) );
344
345 $check_required_fields_missing = $this->check_required_fields( $sanitized_post_data, array( 'slug', 'step', 'current_step', 'module_id' ) );
346
347 if ( ! empty( $check_required_fields_missing ) ) {
348 wp_send_json_error(
349 array(
350 'message' => __( 'Please check the required fields.', 'hustle' ),
351 'errors' => $check_required_fields_missing,
352 )
353 );
354 }
355
356 $slug = $sanitized_post_data['slug'];
357 $step = (int) $sanitized_post_data['step'];
358 $current_step = (int) $sanitized_post_data['current_step'];
359 $module_id = $sanitized_post_data['module_id'];
360
361 $provider = Hustle_Provider_Utils::get_provider_by_slug( $slug );
362
363 if ( ! $provider ) {
364 wp_send_json_error( __( 'Provider not found', 'hustle' ) );
365 }
366
367 if ( ! $provider->is_form_settings_available( $module_id ) ) {
368 wp_send_json_success(
369 array(
370 'data' => $provider->get_empty_wizard( __( 'This provider does not have form settings available', 'hustle' ) ),
371 )
372 );
373 }
374
375 Hustle_Provider_Utils::maybe_attach_addon_hook( $provider );
376
377 unset( $sanitized_post_data['slug'] );
378 unset( $sanitized_post_data['current_step'] );
379 unset( $sanitized_post_data['step'] );
380 unset( $sanitized_post_data['module_id'] );
381
382 $wizard = $provider->get_form_settings_wizard( $sanitized_post_data, $module_id, $current_step, $step );
383
384 if ( ! $wizard['opt_in_provider_has_next_step'] ) {
385 $module = Hustle_Module_Model::new_instance( $module_id );
386 if ( ! is_wp_error( $module ) ) {
387 $module->connect_integration( $slug );
388 }
389 }
390
391 wp_send_json_success(
392 array(
393 'data' => $wizard,
394 )
395 );
396 }
397
398 /**
399 * Handles the provider's deactivation from modules.
400 *
401 * @since 4.0.0
402 */
403 public function form_deactivate() {
404 $this->validate_ajax();
405
406 $sanitized_data = Opt_In_Utils::validate_and_sanitize_fields( $_POST['data'], array( 'slug', 'module_id' ) );// phpcs:ignore
407 $slug = $sanitized_data['slug'];
408 $module_id = $sanitized_data['module_id'];
409
410 $provider = Hustle_Provider_Utils::get_provider_by_slug( $slug );
411 $provider_title = $provider->get_title();
412
413 if ( ! $provider ) {
414 $response = array(
415 'message' => __( 'Addon not found', 'hustle' ),
416 'data' => array(
417 'notification' => array(
418 'type' => 'error',
419 'text' => '<strong>' . $slug . '</strong> ' . __( 'integration not found', 'hustle' ),
420 ),
421 ),
422 );
423 wp_send_json_error( $response );
424 }
425
426 $form_settings = $provider->get_provider_form_settings( $module_id );
427 if ( $form_settings instanceof Hustle_Provider_Form_Settings_Abstract ) {
428 unset( $sanitized_data['slug'] );
429 unset( $sanitized_data['module_id'] );
430
431 // Handling multi_id.
432 if ( isset( $sanitized_data['multi_id'] ) ) {
433 $multi_id_label = '';
434 $multi_ids = $form_settings->get_multi_ids();
435 foreach ( $multi_ids as $key => $multi_id ) {
436 if ( isset( $multi_id['id'] ) && $multi_id['label'] ) {
437 if ( $multi_id['id'] === $sanitized_data['multi_id'] ) {
438 $multi_id_label = $multi_id['label'];
439 break;
440 }
441 }
442 }
443
444 if ( ! empty( $multi_id_label ) ) {
445 $provider_title .= ' [' . $multi_id_label . '] ';
446 }
447 }
448
449 $form_settings->disconnect_form( $sanitized_data );
450
451 $response = array(
452 'message' => /* translators: provider title */ sprintf( __( 'Successfully disconnected %s from this form', 'hustle' ), $provider_title ),
453 'data' => array(
454 'notification' => array(
455 'type' => 'success',
456 'text' => '<strong>' . $provider_title . '</strong> ' . __( 'successfully disconnected from this form', 'hustle' ),
457 ),
458 ),
459 );
460 wp_send_json_success( $response );
461 } else {
462 $response = array(
463 /* translators: provider title */
464 'message' => sprintf( __( 'Failed to disconnect %1$s from this form', 'hustle' ), $provider_title ),
465 'data' => array(
466 'notification' => array(
467 'type' => 'error',
468 'text' => '<strong>' . $provider->get_title() . '</strong> ' . __( 'Failed to disconnected from this form', 'hustle' ),
469 ),
470 ),
471 );
472 wp_send_json_error( $response );
473 }
474 }
475
476 /**
477 * Insert local list into module
478 *
479 * @since 4.0.1
480 */
481 public function insert_local_list() {
482 $this->validate_ajax();
483
484 $id = filter_input( INPUT_POST, 'id', FILTER_VALIDATE_INT );
485 $module = Hustle_Module_Model::new_instance( $id );
486
487 if ( 0 < $id && ! is_wp_error( $module ) ) {
488 $module->update_meta( 'local_list_provider_settings', array( 'local_list_name' => 'hustle-' . wp_rand() ) );
489
490 $integrations_settings = $module->get_integrations_settings()->to_array();
491 $integrations_settings['active_integrations'] = 'local_list';
492 $module->update_meta( Hustle_Module_Model::KEY_INTEGRATIONS_SETTINGS, $integrations_settings );
493
494 wp_send_json_success();
495 }
496
497 if ( is_wp_error( $module ) ) {
498 wp_send_json_error( sprintf( __( 'Invalid module!', 'hustle' ) ) );
499 }
500
501 wp_send_json_error();
502 }
503
504 /**
505 * Migrate aweber integration from oAuth1 to oAuth2
506 *
507 * @since 4.1.1
508 */
509 public function migrate_aweber() {
510 $this->validate_ajax();
511
512 if ( isset( $_POST['data'] ) && is_array( $_POST['data'] ) ) {// phpcs:ignore
513 $post_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
514 } else {
515 $post_data = filter_input( INPUT_POST, 'data' );
516 }
517 $sanitized_post_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug', 'api_key', 'global_multi_id' ) );
518
519 $aweber = Hustle_Aweber::get_instance()->configure_migrated_api_key( $sanitized_post_data );
520
521 if ( $aweber ) {
522 wp_send_json_error();
523 }
524
525 wp_send_json_success();
526 }
527
528 /**
529 * Migrate constant contact integration from oAuth1 to oAuth2
530 *
531 * @since 4.1.1
532 */
533 public function migrate_constantcontact() {
534 $this->validate_ajax();
535
536 // Check if site connected to Hub.
537 if ( Opt_In_Utils::get_hub_api_key() ) {
538 wp_send_json_success();
539 }
540
541 if ( isset( $_POST['data'] ) && is_array( $_POST['data'] ) ) {// phpcs:ignore
542 $post_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
543 } else {
544 $post_data = filter_input( INPUT_POST, 'data' );
545 }
546 $sanitized_post_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug', 'api_key', 'global_multi_id' ) );
547
548 if ( isset( $sanitized_post_data['errors'] ) ) {
549 wp_send_json_error();
550 }
551
552 $instance = Hustle_ConstantContact::get_instance();
553 // Update API key and enable migration mode.
554 $instance->update_api_key( $sanitized_post_data['api_key'] );
555
556 $result = array(
557 'next_step' => array(
558 'nonce' => wp_create_nonce( 'hustle_provider_action' ),
559 'module_id' => 0,
560 'multi_id' => 0,
561 'action' => 'hustle_provider_settings',
562 'global_multi_id' => 0,
563 'slug' => 'constantcontact',
564 'step' => 2,
565 ),
566 );
567
568 wp_send_json_success( $result );
569 }
570
571 /**
572 * Migrate Infusionsoft integration from to OAuth2
573 *
574 * @since 7.8.9
575 */
576 public function migrate_infusionsoft() {
577 // Validate the AJAX request.
578 $this->validate_ajax();
579
580 if ( isset( $_POST['data'] ) && is_array( $_POST['data'] ) ) {// phpcs:ignore
581 $post_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
582 } else {
583 $post_data = filter_input( INPUT_POST, 'data' );
584 }
585 $sanitized_post_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug', 'api_key', 'private_key', 'global_multi_id' ) );
586
587 if ( isset( $sanitized_post_data['errors'] ) ) {
588 wp_send_json_error();
589 }
590
591 $instance = Hustle_Infusion_Soft::get_instance();
592 // Update API key.
593 $instance->configure_migrated_api_keys( $sanitized_post_data );
594
595 $redirect_url = $instance
596 ->get_oauth()
597 ->get_authorization_uri( 0, true, Hustle_Data::INTEGRATIONS_PAGE );
598 $result = array(
599 'redirect' => $redirect_url,
600 );
601
602 wp_send_json_success( $result );
603 }
604
605 /**
606 * Migrate ConvertKit integration to V4
607 *
608 * @since 7.8.11
609 */
610 public function migrate_convertkit() {
611 $this->validate_ajax();
612
613 if ( isset( $_POST['data'] ) && is_array( $_POST['data'] ) ) {// phpcs:ignore
614 $post_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
615 } else {
616 $post_data = filter_input( INPUT_POST, 'data' );
617 }
618 $sanitized_post_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug', 'api_key', 'global_multi_id' ) );
619
620 $convertkit = Hustle_ConvertKit::get_instance()->configure_api_key(
621 $sanitized_post_data
622 );
623
624 if ( ! empty( $convertkit['errors'] ) ) {
625 wp_send_json_error();
626 }
627
628 $integration_id = filter_var( $sanitized_post_data['global_multi_id'], FILTER_SANITIZE_SPECIAL_CHARS );
629
630 wp_send_json_success(
631 array(
632 'redirect' => add_query_arg(
633 array(
634 'page' => Hustle_Data::INTEGRATIONS_PAGE,
635 'migration' => true,
636 'slug' => 'convertkit',
637 'nonce' => wp_create_nonce( 'hustle_provider_external_redirect' ),
638 'action' => 'external-redirect',
639 'integration_id' => $integration_id,
640 ),
641 admin_url( 'admin.php' )
642 ),
643 )
644 );
645 }
646
647 /**
648 * Configure HubSpot integration with the new API key and enable migration mode.
649 *
650 * @since 7.8.13
651 */
652 public function migrate_hubspot() {
653 $this->validate_ajax();
654
655 if ( isset( $_POST['data'] ) && is_array( $_POST['data'] ) ) {// phpcs:ignore
656 $post_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
657 } else {
658 $post_data = filter_input( INPUT_POST, 'data' );
659 }
660 $sanitized_post_data = Opt_In_Utils::validate_and_sanitize_fields( $post_data, array( 'slug', 'api_key', 'global_multi_id' ) );
661
662 if ( isset( $sanitized_post_data['errors'] ) ) {
663 wp_send_json_error();
664 }
665
666 $instance = Hustle_HubSpot::get_instance();
667 $instance->remove_wp_options();
668 // Update API key.
669 $instance->configure_migrated_api_keys( $sanitized_post_data );
670
671 wp_send_json_success(
672 array(
673 'next_step' => array(
674 'slug' => 'hubspot',
675 ),
676 )
677 );
678 }
679
680 /**
681 * Check if is active on module
682 *
683 * @since 4.0.1
684 */
685 public function is_on_module() {
686 $this->validate_ajax();
687
688 $data = Opt_In_Utils::validate_and_sanitize_fields( $_POST['data'], array( 'slug' ) );// phpcs:ignore
689 $slug = $data['slug'];
690
691 $provider = Hustle_Provider_Utils::get_provider_by_slug( $slug );
692 $is_multi_on_global = $provider->is_allow_multi_on_global();
693 $is_multi_on_form = $provider->is_allow_multi_on_form();
694
695 $global_multi_id = filter_var( $_POST['data']['globalMultiId'], FILTER_SANITIZE_SPECIAL_CHARS );// phpcs:ignore
696 $global_multi_id = ( $is_multi_on_global && ! $is_multi_on_form && ! empty( $global_multi_id ) ) ? $global_multi_id : false;
697
698 $modules = Hustle_Provider_Utils::get_modules_by_active_provider( $slug, $global_multi_id );
699
700 $module_data = array();
701 foreach ( $modules as $module ) {
702
703 $meta = $module->get_meta( 'integrations_settings' );
704
705 $module_data[ $module->module_id ] = array(
706 'edit_url' => esc_url_raw( $module->get_edit_url( 'integrations' ) ),
707 'name' => $module->module_name,
708 'type' => $module->module_type,
709 'active' => json_decode( $meta ),
710 );
711 }
712 if ( ! empty( $module_data ) ) {
713 wp_send_json_success( $module_data );
714 }
715
716 if ( is_wp_error( $modules ) ) {
717 wp_send_json_error( sprintf( __( 'Invalid module!', 'hustle' ) ) );
718 }
719
720 wp_send_json_error();
721 }
722
723 /**
724 * Sanitizes the incoming $_POST['data'].
725 *
726 * It uses FILTER_SANITIZE_SPECIAL_CHARS for all keys except the predefined ones.
727 *
728 * @since 4.1.0
729 *
730 * @param array $extra_base_filters Additional default filters to be used.
731 *
732 * @return array
733 */
734 private function get_sanitized_submitted_data( $extra_base_filters = array() ) {
735
736 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
737 if ( ! empty( $_POST ) && ! is_array( $_POST['data'] ) ) {
738 $string_data = filter_input( INPUT_POST, 'data' );
739 parse_str( $string_data, $data );
740
741 } else {
742 $data = filter_input( INPUT_POST, 'data', FILTER_SANITIZE_SPECIAL_CHARS, FILTER_REQUIRE_ARRAY );
743 }
744
745 // Required and shared fields along all providers' requests.
746 $base_filters = array_merge(
747 array(
748 'slug' => FILTER_SANITIZE_SPECIAL_CHARS,
749 'step' => FILTER_VALIDATE_INT,
750 'current_step' => FILTER_VALIDATE_INT,
751 ),
752 $extra_base_filters
753 );
754
755 // Let's not kill submitted arrays.
756 $arrays_filters = array();
757 $submitted_arrays = array_filter( $data, 'is_array' );
758 if ( ! empty( $submitted_arrays ) ) {
759
760 $array_args = array(
761 'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
762 'flags' => FILTER_REQUIRE_ARRAY,
763 );
764
765 $arrays_filters = array_fill_keys( array_keys( $submitted_arrays ), $array_args );
766 }
767
768 // Implement trim for all incoming fields.
769 foreach ( $data as $data_key => $data_value ) {
770 // Check we are not trimming array value.
771 if ( is_array( $data_value ) ) {
772 continue;
773 }
774
775 $data[ $data_key ] = trim( $data_value );
776 }
777
778 // Implement FILTER_SANITIZE_SPECIAL_CHARS for all the other incoming fields.
779 $generic_filters = array_fill_keys( array_keys( $data ), FILTER_SANITIZE_SPECIAL_CHARS );
780
781 // Merge both generic filters with the pre-defined and arrays ones.
782 $filters = array_merge( $generic_filters, $arrays_filters, $base_filters );
783
784 // Aand filter.
785 $sanitized_data = filter_var_array( $data, $filters );
786
787 if ( ! empty( $sanitized_data['name'] ) ) {
788 $sanitized_data['name'] = wp_strip_all_tags( $sanitized_data['name'] );
789 }
790
791 return $sanitized_data;
792 }
793
794 /**
795 * Check that the required fields are set and not empty.
796 *
797 * @since 4.1.0
798 *
799 * @param array $data Data to check.
800 * @param array $required_fields Key of the required fields to look for.
801 *
802 * @return array|bool Array on missing required fields. False otherwise.
803 */
804 private function check_required_fields( $data, $required_fields ) {
805
806 $errors = array();
807 foreach ( $required_fields as $required_field ) {
808 if ( ! isset( $data[ $required_field ] ) || ( empty( trim( $data[ $required_field ] ) ) && 0 !== $data[ $required_field ] ) ) {
809 /* translators: required field name */
810 $errors[ $required_field ] = sprintf( __( 'Field %s is required.', 'hustle' ), $required_field );
811 continue;
812 }
813 }
814
815 if ( ! empty( $errors ) ) {
816 return $errors;
817 }
818
819 return false;
820 }
821 }
822