PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.7.5
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.7.5
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / admin / section / class-convertkit-admin-section-general.php

class-convertkit-admin-section-general.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.7.5, at admin/section/class-convertkit-admin-section-general.php

884 lines 27.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Settings General class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Registers General Settings that can be edited at Settings > Kit > General.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Admin_Section_General extends ConvertKit_Admin_Section_Base {
16
17 /**
18 * Holds the API instance.
19 *
20 * @since 1.9.6
21 *
22 * @var ConvertKit_API_V4
23 */
24 private $api;
25
26 /**
27 * Holds the ConvertKit Account Name.
28 *
29 * @since 1.9.6
30 *
31 * @var bool|WP_Error|array
32 */
33 private $account = false;
34
35 /**
36 * Holds the ConvertKit Forms Resource.
37 *
38 * @since 1.9.6
39 *
40 * @var bool|ConvertKit_Resource_Forms
41 */
42 private $forms = false;
43
44 /**
45 * Constructor.
46 */
47 public function __construct() {
48
49 // Define the class that reads/writes settings.
50 $this->settings = new ConvertKit_Settings();
51
52 // Define the settings key.
53 $this->settings_key = $this->settings::SETTINGS_NAME;
54
55 // Define the programmatic name, Title and Tab Text.
56 $this->name = 'general';
57 $this->title = __( 'General Settings', 'convertkit' );
58 $this->tab_text = __( 'General', 'convertkit' );
59
60 // Define settings sections.
61 $this->settings_sections = array(
62 'general' => array(
63 'title' => $this->title,
64 'callback' => array( $this, 'print_section_info' ),
65 'wrap' => true,
66 ),
67 'site-wide' => array(
68 'title' => __( 'Site Wide', 'convertkit' ),
69 'callback' => array( $this, 'print_section_info_site_wide' ),
70 'wrap' => true,
71 ),
72 'advanced' => array(
73 'title' => __( 'Advanced', 'convertkit' ),
74 'callback' => array( $this, 'print_section_info_advanced' ),
75 'wrap' => true,
76 ),
77 );
78
79 // Register and maybe output notices for this settings screen, and the Intercom messenger.
80 if ( $this->on_settings_screen( $this->name ) ) {
81 add_filter( 'convertkit_settings_base_register_notices', array( $this, 'register_notices' ) );
82 add_action( 'convertkit_settings_base_render_before', array( $this, 'maybe_output_notices' ) );
83 add_action( 'admin_footer', array( $this, 'output_intercom' ) );
84 }
85
86 // Enqueue scripts and CSS.
87 add_action( 'convertkit_admin_settings_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
88 add_action( 'convertkit_admin_settings_enqueue_styles', array( $this, 'enqueue_styles' ) );
89
90 parent::__construct();
91
92 $this->check_credentials();
93 $this->maybe_disconnect();
94
95 }
96
97 /**
98 * Registers success and error notices for the General screen, to be displayed
99 * depending on the action.
100 *
101 * @since 2.5.1
102 *
103 * @param array $notices Regsitered success and error notices.
104 * @return array
105 */
106 public function register_notices( $notices ) {
107
108 return array_merge(
109 $notices,
110 array(
111 'oauth2_success' => __( 'Successfully authorized with Kit.', 'convertkit' ),
112 )
113 );
114
115 }
116
117 /**
118 * Test the access token, if it exists.
119 * If the access token has been revoked or is invalid, remove it from the settings now.
120 *
121 * @since 2.5.0
122 */
123 private function check_credentials() {
124
125 // Bail if we're not on the settings screen.
126 if ( ! $this->on_settings_screen( $this->name ) ) {
127 return;
128 }
129
130 // Bail if no access and refresh token exist.
131 if ( ! $this->settings->has_access_and_refresh_token() ) {
132 return;
133 }
134
135 // Initialize the API.
136 $this->api = new ConvertKit_API_V4(
137 CONVERTKIT_OAUTH_CLIENT_ID,
138 CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI,
139 $this->settings->get_access_token(),
140 $this->settings->get_refresh_token(),
141 $this->settings->debug_enabled(),
142 'settings'
143 );
144
145 // Get Account Details, which we'll use in account_name_callback(), but also lets us test
146 // whether the API credentials are valid.
147 $this->account = $this->api->get_account();
148
149 // If the request succeeded, no need to perform further actions.
150 if ( ! is_wp_error( $this->account ) ) {
151 // Remove any existing persistent notice.
152 WP_ConvertKit()->get_class( 'admin_notices' )->delete( 'authorization_failed' );
153
154 return;
155 }
156
157 // Depending on the error code, maybe persist a notice in the WordPress Administration until the user
158 // fixes the problem.
159 switch ( $this->account->get_error_data( $this->account->get_error_code() ) ) {
160 case 401:
161 // Access token either expired or was revoked in ConvertKit.
162 // Remove from settings.
163 $this->settings->delete_credentials();
164
165 // Display a site wide notice.
166 WP_ConvertKit()->get_class( 'admin_notices' )->add( 'authorization_failed' );
167
168 // Redirect to General screen, which will now show the ConvertKit_Admin_Section_OAuth screen, because
169 // the Plugin has no access token.
170 wp_safe_redirect(
171 add_query_arg(
172 array(
173 'page' => $this->settings_key,
174 ),
175 'options-general.php'
176 )
177 );
178 exit();
179 }
180
181 // Output a non-401 error now.
182 $this->output_error( $this->account->get_error_message() );
183
184 }
185
186 /**
187 * Deletes the OAuth Access Token, Refresh Token and Expiry from the Plugin's settings, if the user
188 * clicked the Disconnect button.
189 *
190 * @since 2.5.0
191 */
192 private function maybe_disconnect() {
193
194 // Bail if we're not on the settings screen.
195 if ( ! $this->on_settings_screen( $this->name ) ) {
196 return;
197 }
198
199 // Bail if nonce verification fails.
200 if ( ! isset( $_REQUEST['_convertkit_settings_oauth_disconnect'] ) ) {
201 return;
202 }
203 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_oauth_disconnect'] ), 'convertkit-oauth-disconnect' ) ) {
204 return;
205 }
206
207 // Delete Access Token.
208 $settings = new ConvertKit_Settings();
209 $settings->delete_credentials();
210
211 // Delete cached resources.
212 $creator_network = new ConvertKit_Resource_Creator_Network_Recommendations();
213 $forms = new ConvertKit_Resource_Forms();
214 $landing_pages = new ConvertKit_Resource_Landing_Pages();
215 $posts = new ConvertKit_Resource_Posts();
216 $products = new ConvertKit_Resource_Products();
217 $tags = new ConvertKit_Resource_Tags();
218 $creator_network->delete();
219 $forms->delete();
220 $landing_pages->delete();
221 $posts->delete();
222 $products->delete();
223 $tags->delete();
224
225 // Redirect to General screen, which will now show the ConvertKit_Settings_OAuth screen, because
226 // the Plugin has no access token.
227 wp_safe_redirect(
228 add_query_arg(
229 array(
230 'page' => $this->settings_key,
231 ),
232 'options-general.php'
233 )
234 );
235 exit();
236
237 }
238
239 /**
240 * Enqueues scripts for the Settings > General screen.
241 *
242 * @since 2.2.4
243 *
244 * @param string $section Settings section / tab (general|tools|restrict-content).
245 */
246 public function enqueue_scripts( $section ) {
247
248 // Bail if we're not on the general section.
249 if ( $section !== $this->name ) {
250 return;
251 }
252
253 // Enqueue Select2 JS.
254 convertkit_select2_enqueue_scripts();
255
256 // Enqueue JS.
257 wp_enqueue_script( 'convertkit-admin-preview-output', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/preview-output.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
258 wp_enqueue_script( 'convertkit-admin-settings-conditional-display', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/settings-conditional-display.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
259
260 }
261
262 /**
263 * Enqueues styles for the Settings > General screen.
264 *
265 * @since 2.2.4
266 *
267 * @param string $section Settings section / tab (general|tools|restrict-content).
268 */
269 public function enqueue_styles( $section ) {
270
271 // Bail if we're not on the general section.
272 if ( $section !== $this->name ) {
273 return;
274 }
275
276 // Enqueue Select2 CSS.
277 convertkit_select2_enqueue_styles();
278
279 }
280
281 /**
282 * Registers settings fields for this section.
283 */
284 public function register_fields() {
285
286 // Initialize resource classes.
287 $this->maybe_initialize_and_refresh_resources();
288
289 add_settings_field(
290 'account_name',
291 __( 'Account Name', 'convertkit' ),
292 array( $this, 'account_name_callback' ),
293 $this->settings_key,
294 $this->name
295 );
296
297 // Initialize resource classes and perform a refresh if this hasn't yet been done.
298 foreach ( convertkit_get_supported_post_types() as $supported_post_type ) {
299 // Get Post Type's Label.
300 $post_type = get_post_type_object( $supported_post_type );
301
302 // Skip if the Post Type doesn't exist.
303 if ( ! $post_type ) {
304 continue;
305 }
306
307 // Add Settings Fields.
308 add_settings_field(
309 $supported_post_type . '_form',
310 sprintf(
311 /* translators: Post Type Name, plural */
312 __( 'Default Form (%s)', 'convertkit' ),
313 $post_type->label
314 ),
315 array( $this, 'default_form_callback' ),
316 $this->settings_key,
317 $this->name,
318 array(
319 'label_for' => '_wp_convertkit_settings_' . $supported_post_type . '_form',
320 'post_type' => $supported_post_type,
321 'post_type_object' => $post_type,
322 )
323 );
324
325 if ( $this->forms->exist() ) {
326 add_settings_field(
327 $supported_post_type . '_form_position',
328 sprintf(
329 /* translators: Post Type Name, plural */
330 __( 'Form Position (%s)', 'convertkit' ),
331 $post_type->label
332 ),
333 array( $this, 'default_form_position_callback' ),
334 $this->settings_key,
335 $this->name,
336 array(
337 'label_for' => '_wp_convertkit_settings_' . $supported_post_type . '_form_position',
338 'post_type' => $supported_post_type,
339 'post_type_object' => $post_type,
340 )
341 );
342
343 add_settings_field(
344 $supported_post_type . '_form_position_element',
345 '',
346 array( $this, 'default_form_position_element_callback' ),
347 $this->settings_key,
348 $this->name,
349 array(
350 'label_for' => '_wp_convertkit_settings_' . $supported_post_type . '_form_position_element',
351 'post_type' => $supported_post_type,
352 'post_type_object' => $post_type,
353 )
354 );
355 }
356 }
357
358 // Site Wide.
359 add_settings_field(
360 'non_inline_form',
361 __( 'Default Forms (Site Wide)', 'convertkit' ),
362 array( $this, 'non_inline_form_callback' ),
363 $this->settings_key,
364 $this->name . '-site-wide',
365 array(
366 'label_for' => 'non_inline_form',
367 )
368 );
369
370 add_settings_field(
371 'non_inline_form_honor_none_setting',
372 __( 'Behavior', 'convertkit' ),
373 array( $this, 'non_inline_form_honor_none_setting_callback' ),
374 $this->settings_key,
375 $this->name . '-site-wide',
376 array(
377 'label_for' => 'non_inline_form_honor_none_setting',
378 )
379 );
380
381 // Advanced.
382 add_settings_field(
383 'debug',
384 __( 'Debug', 'convertkit' ),
385 array( $this, 'debug_callback' ),
386 $this->settings_key,
387 $this->name . '-advanced',
388 array(
389 'label_for' => 'debug',
390 )
391 );
392
393 add_settings_field(
394 'no_scripts',
395 __( 'Disable JavaScript', 'convertkit' ),
396 array( $this, 'no_scripts_callback' ),
397 $this->settings_key,
398 $this->name . '-advanced',
399 array(
400 'label_for' => 'no_scripts',
401 )
402 );
403
404 add_settings_field(
405 'no_css',
406 __( 'Disable CSS', 'convertkit' ),
407 array( $this, 'no_css_callback' ),
408 $this->settings_key,
409 $this->name . '-advanced',
410 array(
411 'label_for' => 'no_css',
412 )
413 );
414
415 }
416
417 /**
418 * Prints help info for this section
419 */
420 public function print_section_info() {
421
422 ?>
423 <p><?php esc_html_e( 'Choosing a default form will embed it at the top, bottom or top and bottom of every post or page (in single view only) across your site.', 'convertkit' ); ?></p>
424 <p><?php esc_html_e( 'If you wish to turn off form embedding or select a different form for an individual post or page, you can do so using the Kit meta box on the edit page.', 'convertkit' ); ?></p>
425 <p>
426 <?php
427 printf(
428 /* translators: [convertkit] shortcode, wrapped in <code> tags */
429 esc_html__( 'The default form can be inserted into the middle of post or page content by using either the %s shortcode or block.', 'convertkit' ),
430 '<code>[convertkit]</code>'
431 );
432 ?>
433 </p>
434 <?php
435
436 }
437
438 /**
439 * Prints help info for the site wide section of the settings screen.
440 *
441 * @since 2.7.3
442 */
443 public function print_section_info_site_wide() {
444
445 ?>
446 <p class="description"><?php esc_html_e( 'Defines non-inline forms to display site wide, and if these forms should display on Pages / Posts that have the Kit Form setting = None.', 'convertkit' ); ?></p>
447 <?php
448
449 }
450
451 /**
452 * Prints help info for the advanced section of the settings screen.
453 *
454 * @since 2.7.1
455 */
456 public function print_section_info_advanced() {
457
458 ?>
459 <p class="description"><?php esc_html_e( 'Defines advanced configuration settings, usually when working with support or needing to disable JS or CSS.', 'convertkit' ); ?></p>
460 <?php
461
462 }
463
464 /**
465 * Returns the URL for the ConvertKit documentation for this setting section.
466 *
467 * @since 2.0.8
468 *
469 * @return string Documentation URL.
470 */
471 public function documentation_url() {
472
473 return 'https://help.kit.com/en/articles/2502591-the-convertkit-wordpress-plugin';
474
475 }
476
477 /**
478 * Outputs the Account Name
479 *
480 * @since 1.9.6
481 */
482 public function account_name_callback() {
483
484 // Output Account Name.
485 $html = sprintf(
486 '<p>%s</p>',
487 isset( $this->account['account']['name'] ) ? esc_attr( $this->account['account']['name'] ) : esc_html__( '(Not specified)', 'convertkit' )
488 );
489
490 // Display an option to disconnect.
491 $html .= sprintf(
492 '<p><a href="%1$s" class="button button-secondary">%2$s</a></p>',
493 esc_url(
494 add_query_arg(
495 array(
496 'page' => '_wp_convertkit_settings',
497 '_convertkit_settings_oauth_disconnect' => wp_create_nonce( 'convertkit-oauth-disconnect' ),
498 ),
499 'options-general.php'
500 )
501 ),
502 esc_html__( 'Disconnect', 'convertkit' )
503 );
504
505 // Output has already been run through escaping functions above.
506 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput
507 }
508
509 /**
510 * Initialize resource classes and perform a and refresh of resources,
511 * if initialization has not yet taken place.
512 *
513 * @since 2.5.9
514 */
515 public function maybe_initialize_and_refresh_resources() {
516
517 // If the Forms resource class is initialized, this has already been done.
518 if ( $this->forms !== false ) {
519 return;
520 }
521
522 // Initialize forms resource class.
523 $this->forms = new ConvertKit_Resource_Forms( 'settings' );
524
525 // Don't refresh resources if we're not on the settings screen, as
526 // it's a resource intense process that can take several seconds.
527 // We don't want to block other parts of the admin UI.
528 if ( ! $this->on_settings_screen( $this->name ) ) {
529 return;
530 }
531
532 // Refresh Forms.
533 $this->forms->refresh();
534
535 // Also refresh Landing Pages, Tags and Posts. Whilst not displayed in the Plugin Settings, this ensures up to date
536 // lists are stored for when editing e.g. Pages.
537 $landing_pages = new ConvertKit_Resource_Landing_Pages( 'settings' );
538 $landing_pages->refresh();
539
540 remove_all_actions( 'convertkit_resource_refreshed_posts' );
541 $posts = new ConvertKit_Resource_Posts( 'settings' );
542 $posts->refresh();
543
544 $products = new ConvertKit_Resource_Products( 'settings' );
545 $products->refresh();
546
547 $sequences = new ConvertKit_Resource_Sequences( 'settings' );
548 $sequences->refresh();
549
550 $tags = new ConvertKit_Resource_Tags( 'settings' );
551 $tags->refresh();
552 }
553
554 /**
555 * Renders the input for the Default Form setting for the given Post Type.
556 *
557 * @since 1.9.6
558 *
559 * @param array $args Field arguments.
560 */
561 public function default_form_callback( $args ) {
562
563 // Bail if no Forms exist.
564 if ( ! $this->forms->exist() ) {
565 esc_html_e( 'No Forms exist in Kit.', 'convertkit' );
566 echo '<br /><a href="' . esc_url( convertkit_get_new_form_url() ) . '" target="_blank">' . esc_html__( 'Click here to create your first form', 'convertkit' ) . '</a>';
567 return;
568 }
569
570 // Build description with preview link.
571 $description = false;
572 $preview_url = WP_ConvertKit()->get_class( 'preview_output' )->get_preview_form_url( $args['post_type'] );
573 if ( $preview_url ) {
574 // Include a preview link in the description.
575 $description = sprintf(
576 '%s %s %s',
577 sprintf(
578 /* translators: Post Type name, plural */
579 esc_html__( 'Select a form above to automatically output below all %s.', 'convertkit' ),
580 $args['post_type_object']->label
581 ),
582 '<a href="' . esc_url( $preview_url ) . '" id="convertkit-preview-form-' . esc_attr( $args['post_type'] ) . '" target="_blank">' . esc_html__( 'Click here', 'convertkit' ) . '</a>',
583 esc_html__( 'to preview how this will display.', 'convertkit' )
584 );
585 } else {
586 // Just output the field's description.
587 $description = sprintf(
588 /* translators: Post Type name, plural */
589 esc_html__( 'Select a form above to automatically output below all %s.', 'convertkit' ),
590 $args['post_type_object']->label
591 );
592 }
593
594 // Build field.
595 $select_field = $this->forms->get_select_field_all(
596 $this->settings_key . '[' . $args['post_type'] . '_form]',
597 $this->settings_key . '_' . $args['post_type'] . '_form',
598 array(
599 'convertkit-select2',
600 'convertkit-preview-output-link',
601 ),
602 $this->settings->get_default_form( $args['post_type'] ),
603 array(
604 'default' => esc_html__( 'None', 'convertkit' ),
605 ),
606 array(
607 'data-target' => '#convertkit-preview-form-' . esc_attr( $args['post_type'] ),
608 'data-link' => esc_attr( $preview_url ) . '&convertkit_form_id=',
609 ),
610 $description
611 );
612
613 // Output field.
614 echo '<div class="convertkit-select2-container">' . $select_field . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput
615
616 }
617
618 /**
619 * Renders the input for the Default Form Position setting for the given Post Type.
620 *
621 * @since 2.5.8
622 *
623 * @param array $args Field arguments.
624 */
625 public function default_form_position_callback( $args ) {
626
627 echo $this->get_select_field( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
628 $args['post_type'] . '_form_position',
629 esc_attr( $this->settings->get_default_form_position( $args['post_type'] ) ),
630 array(
631 'before_content' => sprintf(
632 /* translators: Post type singular name */
633 esc_attr__( 'Before %s content', 'convertkit' ),
634 esc_attr( $args['post_type_object']->labels->singular_name )
635 ),
636 'after_content' => sprintf(
637 /* translators: Post type singular name */
638 esc_attr__( 'After %s content', 'convertkit' ),
639 esc_attr( $args['post_type_object']->labels->singular_name )
640 ),
641 'before_after_content' => sprintf(
642 /* translators: Post type singular name */
643 esc_attr__( 'Before and after %s content', 'convertkit' ),
644 esc_attr( $args['post_type_object']->labels->singular_name )
645 ),
646 'after_element' => esc_html__( 'After element', 'convertkit' ),
647 ),
648 sprintf(
649 /* translators: Post Type name, plural */
650 esc_html__( 'Where forms should display relative to the %s content', 'convertkit' ),
651 esc_html( $args['post_type_object']->labels->singular_name )
652 ),
653 array( 'convertkit-conditional-display' ),
654 array(
655 'data-conditional-value' => 'after_element',
656 'data-conditional-element' => esc_attr( $args['post_type'] ) . '_form_position_element_index',
657 )
658 );
659
660 }
661
662 /**
663 * Renders the input for the Default Form Position Index setting for the given Post Type.
664 *
665 * @since 2.6.1
666 *
667 * @param array $args Field arguments.
668 */
669 public function default_form_position_element_callback( $args ) {
670
671 echo $this->get_number_field( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
672 $args['post_type'] . '_form_position_element_index',
673 esc_attr( (string) $this->settings->get_default_form_position_element_index( $args['post_type'] ) ),
674 1,
675 999,
676 1,
677 false,
678 array( 'after_element' )
679 );
680
681 echo $this->get_select_field( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
682 $args['post_type'] . '_form_position_element',
683 esc_attr( $this->settings->get_default_form_position_element( $args['post_type'] ) ),
684 array(
685 'p' => esc_html__( 'Paragraphs', 'convertkit' ),
686 'h2' => esc_html__( 'Headings <h2>', 'convertkit' ),
687 'h3' => esc_html__( 'Headings <h3>', 'convertkit' ),
688 'h4' => esc_html__( 'Headings <h4>', 'convertkit' ),
689 'h5' => esc_html__( 'Headings <h5>', 'convertkit' ),
690 'h6' => esc_html__( 'Headings <h6>', 'convertkit' ),
691 'img' => esc_html__( 'Images', 'convertkit' ),
692 ),
693 esc_html__( 'The number of elements before outputting the form.', 'convertkit' ),
694 array( 'after_element' )
695 );
696
697 }
698
699 /**
700 * Renders the input for the Non-inline Form setting.
701 *
702 * @since 2.2.3
703 *
704 * @param array $args Field arguments.
705 */
706 public function non_inline_form_callback( $args ) {
707
708 // Bail if no non-inline Forms exist.
709 if ( ! $this->forms->non_inline_exist() ) {
710 esc_html_e( 'No non-inline Forms exist in Kit.', 'convertkit' );
711 echo '<br /><a href="' . esc_url( convertkit_get_new_form_url() ) . '" target="_blank">' . esc_html__( 'Click here to create your first modal, slide in or sticky bar form', 'convertkit' ) . '</a>';
712 return;
713 }
714
715 // Build description with preview link.
716 $preview_url = WP_ConvertKit()->get_class( 'preview_output' )->get_preview_form_home_url();
717 $description = sprintf(
718 '%s %s %s',
719 esc_html__( 'Automatically display one or more modal, slide-in, or sticky bar forms across your site. This setting is overridden if a default non-inline form is set above, a specific non-inline form or "None" option is chosen for a post/page, or a non-inline form is specified in a block/shortcode.', 'convertkit' ),
720 '<a href="' . esc_url( $preview_url ) . '" id="convertkit-preview-non-inline-form" target="_blank">' . esc_html__( 'Click here', 'convertkit' ) . '</a>',
721 esc_html__( 'to preview how this will display.', 'convertkit' )
722 );
723
724 // Build field.
725 $select_field = $this->forms->get_select_field_non_inline(
726 $this->settings_key . '[non_inline_form]',
727 $this->settings_key . '_non_inline_form',
728 array(
729 'convertkit-select2',
730 'convertkit-preview-output-link',
731 ),
732 $this->settings->get_non_inline_form(),
733 false,
734 array(
735 'data-target' => '#convertkit-preview-non-inline-form',
736 'data-link' => esc_attr( $preview_url ) . '&convertkit_form_id=',
737 ),
738 $description
739 );
740
741 // Output field.
742 echo '<div class="convertkit-select2-container">' . $select_field . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput
743
744 }
745
746 /**
747 * Renders the input for the Non-inline Form override setting.
748 *
749 * @since 2.7.3
750 */
751 public function non_inline_form_honor_none_setting_callback() {
752
753 // Output field.
754 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
755 'non_inline_form_honor_none_setting',
756 'on',
757 $this->settings->non_inline_form_honor_none_setting(), // phpcs:ignore WordPress.Security.EscapeOutput
758 esc_html__( 'If checked, do not display the site wide form(s) above on Pages / Posts that have their Kit Form setting = None.', 'convertkit' )
759 );
760
761 }
762
763 /**
764 * Renders the input for the Debug setting.
765 *
766 * @since 1.9.6
767 */
768 public function debug_callback() {
769
770 // Output field.
771 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
772 'debug',
773 'on',
774 $this->settings->debug_enabled(), // phpcs:ignore WordPress.Security.EscapeOutput
775 esc_html__( 'Log requests to file and output browser console messages.', 'convertkit' ),
776 esc_html__( 'You can ignore this unless you\'re working with our support team to resolve an issue. Decheck this option to improve performance.', 'convertkit' )
777 );
778
779 }
780
781 /**
782 * Renders the input for the Disable Javascript setting.
783 *
784 * @since 1.9.6
785 */
786 public function no_scripts_callback() {
787
788 // Output field.
789 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
790 'no_scripts',
791 'on',
792 $this->settings->scripts_disabled(), // phpcs:ignore WordPress.Security.EscapeOutput
793 esc_html__( 'Prevent plugin from loading JavaScript files. This will disable the custom content and tagging features of the plugin. Does not apply to landing pages. Use with caution!', 'convertkit' )
794 );
795
796 }
797
798 /**
799 * Renders the input for the Disable CSS setting.
800 *
801 * @since 1.9.6.9
802 */
803 public function no_css_callback() {
804
805 // Output field.
806 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
807 'no_css',
808 'on',
809 $this->settings->css_disabled(), // phpcs:ignore WordPress.Security.EscapeOutput
810 esc_html__( 'Prevents loading plugin CSS files. This will disable styling on broadcasts, form trigger buttons, product buttons and member\'s content. Use with caution!', 'convertkit' ),
811 array(
812 sprintf(
813 '%s <a href="%s" target="_blank">%s</a>',
814 esc_html__( 'To customize forms and their styling, use the', 'convertkit' ),
815 esc_url( convertkit_get_form_editor_url() ),
816 esc_html__( 'Kit form editor', 'convertkit' )
817 ),
818 sprintf(
819 '%s <a href="https://wordpress.org/plugins/contact-form-7/" target="_blank">Contact Form 7</a>, <a href="https://wordpress.org/plugins/convertkit-gravity-forms/" target="_blank">Gravity Forms</a> %s <a href="https://wordpress.org/plugins/integrate-convertkit-wpforms/" target="_blank">WPForms</a> %s',
820 esc_html__( 'For developers who require custom form designs through use of CSS, consider using the', 'convertkit' ),
821 esc_html__( 'or', 'convertkit' ),
822 esc_html__( 'integrations.', 'convertkit' )
823 ),
824 )
825 );
826
827 }
828
829 /**
830 * Sanitizes the settings prior to being saved.
831 *
832 * @since 2.4.3
833 *
834 * @param null|array $settings Submitted Settings Fields.
835 * @return array Sanitized Settings with Defaults
836 */
837 public function sanitize_settings( $settings ) {
838
839 // If no Access Token, Refresh Token or Token Expiry keys were specified in the settings
840 // prior to save, don't overwrite them with the blank setting from get_defaults().
841 // This ensures we only blank these values if we explicitly do so via $settings,
842 // as they won't be included in the Settings screen for security.
843 if ( ! array_key_exists( 'disconnect', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
844 // If settings are null, no checkboxes were ticked and no other form elements
845 // were submitted i.e. the Kit account has no forms.
846 if ( is_null( $settings ) ) {
847 $settings = array();
848 }
849
850 if ( ! array_key_exists( 'access_token', $settings ) ) {
851 $settings['access_token'] = $this->settings->get_access_token();
852 }
853 if ( ! array_key_exists( 'refresh_token', $settings ) ) {
854 $settings['refresh_token'] = $this->settings->get_refresh_token();
855 }
856 if ( ! array_key_exists( 'token_expires', $settings ) ) {
857 $settings['token_expires'] = $this->settings->get_token_expiry();
858 }
859 }
860
861 // Call parent class to merge settings with defaults.
862 $settings = parent::sanitize_settings( $settings );
863
864 // If a Form or Landing Page was specified that isn't the default,
865 // request a review.
866 // Since switching to OAuth means the settings screen will only display
867 // settings if the access token is valid, the Default Forms options will
868 // always be submitted. Previously, if no API Key/Secret was specified,
869 // no Default Forms options would render.
870 // This can safely be called multiple times, as the review request
871 // class will ensure once a review request is dismissed by the user,
872 // it is never displayed again.
873 if ( ( isset( $settings['page_form'] ) && $settings['page_form'] !== 'default' ) ||
874 ( isset( $settings['post_form'] ) && $settings['post_form'] !== 'default' ) ) {
875 WP_ConvertKit()->get_class( 'review_request' )->request_review();
876 }
877
878 // Return settings to be saved.
879 return $settings;
880
881 }
882
883 }
884