PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.5.5
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.5.5
3.4.4 3.4.3 3.4.2 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 All 197 releases
← All changes | includes/class-convertkit-settings.php +34 -537 3.4.12.5.5 View file →
@@ -44,8 +44,11 @@
44 44 } else {
45 45 $this->settings = array_merge( $this->get_defaults(), $settings );
46 46 }
47 47
48 + // Update Access Token when refreshed by the API class.
49 + add_action( 'convertkit_api_refresh_token', array( $this, 'update_credentials' ), 10, 2 );
50 +
48 51 }
49 52
50 53 /**
51 54 * Returns Plugin settings.
@@ -158,13 +161,10 @@
158 161 * @return bool
159 162 */
160 163 public function has_api_key_and_secret() {
161 164
162 - _deprecated_function( __FUNCTION__, '2.6.3', 'has_access_and_refresh_token()' );
165 + return $this->has_api_key() && $this->has_api_secret();
163 166
164 - // Use check for access and refresh token.
165 - return $this->has_access_and_refresh_token();
166 -
167 167 }
168 168
169 169 /**
170 170 * Returns the Access Token Plugin setting.
@@ -174,11 +174,8 @@
174 174 * @return string
175 175 */
176 176 public function get_access_token() {
177 177
178 - // Reload settings from options table, to ensure we have the latest tokens.
179 - $this->refresh_settings();
180 -
181 178 // Return Access Token from settings.
182 179 return $this->settings['access_token'];
183 180
184 181 }
@@ -204,11 +201,8 @@
204 201 * @return string
205 202 */
206 203 public function get_refresh_token() {
207 204
208 - // Reload settings from options table, to ensure we have the latest tokens.
209 - $this->refresh_settings();
210 -
211 205 // Return Refresh Token from settings.
212 206 return $this->settings['refresh_token'];
213 207
214 208 }
@@ -294,86 +288,23 @@
294 288
295 289 }
296 290
297 291 /**
298 - * Returns the Default Form Position Plugin setting.
299 - *
300 - * @since 2.5.8
301 - *
302 - * @param string $post_type Post Type.
303 - * @return string|int Default Form (default|form id)
304 - */
305 - public function get_default_form_position( $post_type ) {
306 -
307 - // Return after_content if this Post Type's position doesn't exist as a setting.
308 - if ( ! array_key_exists( $post_type . '_form_position', $this->settings ) ) {
309 - return 'after_content';
310 - }
311 -
312 - return $this->settings[ $post_type . '_form_position' ];
313 -
314 - }
315 -
316 - /**
317 - * Returns the Default Form Position Element Plugin setting.
318 - *
319 - * @since 2.6.1
320 - *
321 - * @param string $post_type Post Type.
322 - * @return string Element to insert form after
323 - */
324 - public function get_default_form_position_element( $post_type ) {
325 -
326 - // Return after_content if this Post Type's position doesn't exist as a setting.
327 - if ( ! array_key_exists( $post_type . '_form_position_element', $this->settings ) ) {
328 - return 'p';
329 - }
330 -
331 - return $this->settings[ $post_type . '_form_position_element' ];
332 -
333 - }
334 -
335 - /**
336 - * Returns the Default Form Position Index Plugin setting.
337 - *
338 - * @since 2.6.1
339 - *
340 - * @param string $post_type Post Type.
341 - * @return int Number of elements before inserting form
342 - */
343 - public function get_default_form_position_element_index( $post_type ) {
344 -
345 - // Return 1 if this Post Type's position index doesn't exist as a setting.
346 - if ( ! array_key_exists( $post_type . '_form_position_element_index', $this->settings ) ) {
347 - return 1;
348 - }
349 -
350 - return (int) $this->settings[ $post_type . '_form_position_element_index' ];
351 -
352 - }
353 -
354 - /**
355 292 * Returns the Global non-inline Form Plugin setting.
356 293 *
357 294 * @since 2.3.3
358 295 *
359 - * @return array
296 + * @return string|int Non-inline Form (blank string|form id)
360 297 */
361 298 public function get_non_inline_form() {
362 299
363 - // Return blank array if no inline form is specified.
300 + // Return blank string if no inline form is specified.
364 301 if ( ! $this->has_non_inline_form() ) {
365 - return array();
302 + return '';
366 303 }
367 304
368 - // 2.6.8 and earlier stored a single Form ID in a string.
369 - if ( is_string( $this->settings['non_inline_form'] ) ) {
370 - return array( (int) $this->settings['non_inline_form'] );
371 - }
305 + return $this->settings['non_inline_form'];
372 306
373 - // Cast values to integers and return.
374 - return array_map( 'intval', $this->settings['non_inline_form'] );
375 -
376 307 }
377 308
378 309 /**
379 310 * Returns whether the Global non-inline Form has been set in the Plugin settings.
@@ -383,207 +314,13 @@
383 314 * @return bool Global non-inline Form setting specified in Plugin Settings.
384 315 */
385 316 public function has_non_inline_form() {
386 317
387 - // 2.6.8 and earlier stored a single Form ID in a string.
388 - if ( is_string( $this->settings['non_inline_form'] ) ) {
389 - if ( ! empty( $this->settings['non_inline_form'] ) ) {
390 - return true;
391 - }
318 + return ( ! empty( $this->settings['non_inline_form'] ) ? true : false );
392 319
393 - return false;
394 - }
395 -
396 - return ( count( $this->settings['non_inline_form'] ) > 0 ? true : false );
397 -
398 320 }
399 321
400 322 /**
401 - * Returns whether the Global non-inline Form setting should honor the Page / Post
402 - * None setting.
403 - *
404 - * @since 2.7.3
405 - *
406 - * @return bool
407 - */
408 - public function non_inline_form_honor_none_setting() {
409 -
410 - return ( $this->settings['non_inline_form_honor_none_setting'] === 'on' ? true : false );
411 -
412 - }
413 -
414 - /**
415 - * Returns whether the Non-inline Form Limit per Session setting has been set in the Plugin settings.
416 - *
417 - * @since 3.0.0
418 - *
419 - * @return bool
420 - */
421 - public function non_inline_form_limit_per_session() {
422 -
423 - return ( $this->settings['non_inline_form_limit_per_session'] === 'on' ? true : false );
424 -
425 - }
426 -
427 - /**
428 - * Returns the active spam protection provider Plugin setting.
429 - *
430 - * @since 3.3.7
431 - *
432 - * @return string none|recaptcha|turnstile
433 - */
434 - public function spam_protection_provider() {
435 -
436 - return $this->settings['spam_protection_provider'];
437 -
438 - }
439 -
440 - /**
441 - * Returns the reCAPTCHA Site Key Plugin setting.
442 - *
443 - * @since 3.0.0
444 - *
445 - * @return string
446 - */
447 - public function recaptcha_site_key() {
448 -
449 - return $this->settings['recaptcha_site_key'];
450 -
451 - }
452 -
453 - /**
454 - * Returns whether the reCAPTCHA Site Key has been set in the Plugin settings.
455 - *
456 - * @since 3.0.0
457 - *
458 - * @return bool
459 - */
460 - public function has_recaptcha_site_key() {
461 -
462 - return ! empty( $this->recaptcha_site_key() );
463 -
464 - }
465 -
466 - /**
467 - * Returns the reCAPTCHA Secret Key Plugin setting.
468 - *
469 - * @since 3.0.0
470 - *
471 - * @return string
472 - */
473 - public function recaptcha_secret_key() {
474 -
475 - return $this->settings['recaptcha_secret_key'];
476 -
477 - }
478 -
479 - /**
480 - * Returns whether the reCAPTCHA Secret Key has been set in the Plugin settings.
481 - *
482 - * @since 3.0.0
483 - *
484 - * @return bool
485 - */
486 - public function has_recaptcha_secret_key() {
487 -
488 - return ! empty( $this->recaptcha_secret_key() );
489 -
490 - }
491 -
492 - /**
493 - * Returns whether the reCAPTCH Site Key and Secret Key are defined
494 - * in the Plugin settings.
495 - *
496 - * @since 3.0.0
497 - *
498 - * @return bool
499 - */
500 - public function has_recaptcha_site_and_secret_keys() {
501 -
502 - return $this->has_recaptcha_site_key() && $this->has_recaptcha_secret_key();
503 -
504 - }
505 -
506 - /**
507 - * Returns the reCAPTCHA minimum score Plugin setting.
508 - *
509 - * @since 3.0.0
510 - *
511 - * @return float
512 - */
513 - public function recaptcha_minimum_score() {
514 -
515 - return (float) $this->settings['recaptcha_minimum_score'];
516 -
517 - }
518 -
519 - /**
520 - * Returns the Cloudflare Turnstile Site Key Plugin setting.
521 - *
522 - * @since 3.3.7
523 - *
524 - * @return string
525 - */
526 - public function cloudflare_turnstile_site_key() {
527 -
528 - return $this->settings['cloudflare_turnstile_site_key'];
529 -
530 - }
531 -
532 - /**
533 - * Returns whether the Cloudflare Turnstile Site Key has been set in the Plugin settings.
534 - *
535 - * @since 3.3.7
536 - *
537 - * @return bool
538 - */
539 - public function has_cloudflare_turnstile_site_key() {
540 -
541 - return ! empty( $this->cloudflare_turnstile_site_key() );
542 -
543 - }
544 -
545 - /**
546 - * Returns the Cloudflare Turnstile Secret Key Plugin setting.
547 - *
548 - * @since 3.3.7
549 - *
550 - * @return string
551 - */
552 - public function cloudflare_turnstile_secret_key() {
553 -
554 - return $this->settings['cloudflare_turnstile_secret_key'];
555 -
556 - }
557 -
558 - /**
559 - * Returns whether the Cloudflare Turnstile Secret Key has been set in the Plugin settings.
560 - *
561 - * @since 3.3.7
562 - *
563 - * @return bool
564 - */
565 - public function has_cloudflare_turnstile_secret_key() {
566 -
567 - return ! empty( $this->cloudflare_turnstile_secret_key() );
568 -
569 - }
570 -
571 - /**
572 - * Returns whether the Cloudflare Turnstile Site Key and Secret Key are defined
573 - * in the Plugin settings.
574 - *
575 - * @since 3.3.7
576 - *
577 - * @return bool
578 - */
579 - public function has_cloudflare_turnstile_site_and_secret_keys() {
580 -
581 - return $this->has_cloudflare_turnstile_site_key() && $this->has_cloudflare_turnstile_secret_key();
582 -
583 - }
584 -
585 - /**
586 323 * Returns whether debugging is enabled in the Plugin settings.
587 324 *
588 325 * @since 1.9.6
589 326 *
@@ -621,198 +358,8 @@
621 358
622 359 }
623 360
624 361 /**
625 - * Returns whether the Add New Landing Page / Member Content button is disabled in the Plugin settings.
626 - *
627 - * @since 3.2.0
628 - *
629 - * @return bool
630 - */
631 - public function add_new_button_disabled() {
632 -
633 - return ( $this->settings['no_add_new_button'] === 'on' ? true : false );
634 -
635 - }
636 -
637 - /**
638 - * Returns whether usage tracking is enabled in the Plugin settings.
639 - *
640 - * @since 3.0.4
641 - *
642 - * @return bool
643 - */
644 - public function usage_tracking() {
645 -
646 - return ( $this->settings['usage_tracking'] === 'on' ? true : false );
647 -
648 - }
649 -
650 - /**
651 - * Returns this settings group's programmatic name.
652 - *
653 - * @since 3.4.0
654 - *
655 - * @return string
656 - */
657 - public function get_name() {
658 -
659 - return 'general';
660 -
661 - }
662 -
663 - /**
664 - * Returns the title of this settings group.
665 - *
666 - * @since 3.4.0
667 - *
668 - * @return string
669 - */
670 - public function get_title() {
671 -
672 - return __( 'General Settings', 'convertkit' );
673 -
674 - }
675 -
676 - /**
677 - * Returns the keys in this settings group that hold credentials or other
678 - * sensitive values.
679 - *
680 - * @since 3.4.0
681 - *
682 - * @return string[]
683 - */
684 - public function get_secret_keys() {
685 -
686 - return array(
687 - 'access_token',
688 - 'refresh_token',
689 - 'token_expires',
690 - 'api_key',
691 - 'api_secret',
692 - 'recaptcha_secret_key',
693 - );
694 -
695 - }
696 -
697 - /**
698 - * Returns the JSON Schema describing this settings group, in the shape
699 - * stored by save() / returned by get(), excluding secret keys.
700 - *
701 - * @since 3.4.0
702 - *
703 - * @return array
704 - */
705 - public function get_schema() {
706 -
707 - $properties = array(
708 - 'non_inline_form' => array(
709 - 'type' => 'array',
710 - 'items' => array( 'type' => 'integer' ),
711 - 'description' => __( 'IDs of non-inline Forms to display site-wide.', 'convertkit' ),
712 - ),
713 - 'non_inline_form_honor_none_setting' => array(
714 - 'type' => 'string',
715 - 'enum' => array( '', 'on' ),
716 - 'description' => __( 'Whether the site-wide non-inline Form honors a per-Page / per-Post "None" Form setting.', 'convertkit' ),
717 - ),
718 - 'non_inline_form_limit_per_session' => array(
719 - 'type' => 'string',
720 - 'enum' => array( '', 'on' ),
721 - 'description' => __( 'Whether to limit non-inline Form display to once per session.', 'convertkit' ),
722 - ),
723 - 'recaptcha_site_key' => array(
724 - 'type' => 'string',
725 - 'description' => __( 'Google reCAPTCHA v3 site key.', 'convertkit' ),
726 - ),
727 - 'recaptcha_minimum_score' => array(
728 - 'type' => 'number',
729 - 'minimum' => 0,
730 - 'maximum' => 1,
731 - 'description' => __( 'Minimum Google reCAPTCHA v3 score (0.0 - 1.0) below which a request is treated as spam.', 'convertkit' ),
732 - ),
733 - 'debug' => array(
734 - 'type' => 'string',
735 - 'enum' => array( '', 'on' ),
736 - 'description' => __( 'Whether debug logging is enabled.', 'convertkit' ),
737 - ),
738 - 'no_scripts' => array(
739 - 'type' => 'string',
740 - 'enum' => array( '', 'on' ),
741 - 'description' => __( 'Whether the Plugin\'s frontend JavaScript is disabled.', 'convertkit' ),
742 - ),
743 - 'no_css' => array(
744 - 'type' => 'string',
745 - 'enum' => array( '', 'on' ),
746 - 'description' => __( 'Whether the Plugin\'s frontend CSS is disabled.', 'convertkit' ),
747 - ),
748 - 'no_add_new_button' => array(
749 - 'type' => 'string',
750 - 'enum' => array( '', 'on' ),
751 - 'description' => __( 'Whether the "Add New" button for Landing Pages / Member Content is hidden in the WordPress Admin.', 'convertkit' ),
752 - ),
753 - 'usage_tracking' => array(
754 - 'type' => 'string',
755 - 'enum' => array( '', 'on' ),
756 - 'description' => __( 'Whether anonymous usage tracking is enabled.', 'convertkit' ),
757 - ),
758 - );
759 -
760 - // Per-post-type Default Form settings, mirroring get_defaults().
761 - foreach ( convertkit_get_supported_post_types() as $post_type ) {
762 - $properties[ $post_type . '_form' ] = array(
763 - 'type' => 'integer',
764 - 'minimum' => -1,
765 - 'description' => sprintf(
766 - /* translators: Post type slug. */
767 - __( 'Default Form ID to display on %s. `-1` = Plugin Default; `0` = None; positive integer = specific Kit Form ID.', 'convertkit' ),
768 - $post_type
769 - ),
770 - );
771 -
772 - $properties[ $post_type . '_form_position' ] = array(
773 - 'type' => 'string',
774 - 'enum' => array( 'before_content', 'after_content', 'before_after_content', 'after_element' ),
775 - 'description' => sprintf(
776 - /* translators: Post type slug. */
777 - __( 'Where the Default Form displays relative to the %s content.', 'convertkit' ),
778 - $post_type
779 - ),
780 - );
781 -
782 - $properties[ $post_type . '_form_position_element' ] = array(
783 - 'type' => 'string',
784 - 'enum' => array( 'p', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
785 - 'description' => sprintf(
786 - /* translators: 1: Post type slug, 2: Post type slug. */
787 - __( 'HTML element after which to display the Default Form on %1$s. Only used when `%2$s_form_position` is `after_element`.', 'convertkit' ),
788 - $post_type,
789 - $post_type
790 - ),
791 - );
792 -
793 - $properties[ $post_type . '_form_position_element_index' ] = array(
794 - 'type' => 'integer',
795 - 'minimum' => 1,
796 - 'maximum' => 999,
797 - 'description' => sprintf(
798 - /* translators: 1: Post type slug, 2: Post type slug. */
799 - __( 'Nth occurrence of the element after which to display the Default Form on %1$s. Only used when `%2$s_form_position` is `after_element`.', 'convertkit' ),
800 - $post_type,
801 - $post_type
802 - ),
803 - );
804 - }
805 -
806 - return array(
807 - 'type' => 'object',
808 - 'additionalProperties' => false,
809 - 'properties' => $properties,
810 - );
811 -
812 - }
813 -
814 - /**
815 362 * The default settings, used when the ConvertKit Plugin Settings haven't been saved
816 363 * e.g. on a new installation.
817 364 *
818 365 * @since 1.9.6
@@ -822,47 +369,26 @@
822 369 public function get_defaults() {
823 370
824 371 $defaults = array(
825 372 // OAuth.
826 - 'access_token' => '', // string.
827 - 'refresh_token' => '', // string.
828 - 'token_expires' => '', // integer.
373 + 'access_token' => '', // string.
374 + 'refresh_token' => '', // string.
375 + 'token_expires' => '', // integer.
829 376
830 377 // API Key. Retained if needed for backward compat.
831 - 'api_key' => '', // string.
832 - 'api_secret' => '', // string.
378 + 'api_key' => '', // string.
379 + 'api_secret' => '', // string.
833 380
834 - // Site Wide.
835 - 'non_inline_form' => array(), // array.
836 - 'non_inline_form_honor_none_setting' => '', // blank|on.
837 - 'non_inline_form_limit_per_session' => '', // blank|on.
838 -
839 - // Spam Protection.
840 - 'spam_protection_provider' => 'recaptcha', // recaptcha|turnstile.
841 -
842 - // reCAPTCHA.
843 - 'recaptcha_site_key' => '', // string.
844 - 'recaptcha_secret_key' => '', // string.
845 - 'recaptcha_minimum_score' => 0.5, // float.
846 -
847 - // Cloudflare Turnstile.
848 - 'cloudflare_turnstile_site_key' => '', // string.
849 - 'cloudflare_turnstile_secret_key' => '', // string.
850 -
851 - // Advanced.
852 - 'debug' => '', // blank|on.
853 - 'no_scripts' => '', // blank|on.
854 - 'no_css' => '', // blank|on.
855 - 'no_add_new_button' => '', // blank|on.
856 - 'usage_tracking' => '', // blank|on.
381 + // Settings.
382 + 'non_inline_form' => '', // string.
383 + 'debug' => '', // blank|on.
384 + 'no_scripts' => '', // blank|on.
385 + 'no_css' => '', // blank|on.
857 386 );
858 387
859 388 // Add Post Type Default Forms.
860 389 foreach ( convertkit_get_supported_post_types() as $post_type ) {
861 - $defaults[ $post_type . '_form' ] = 0; // -1, 0 or Form ID.
862 - $defaults[ $post_type . '_form_position' ] = 'after_content'; // before_content,after_content,before_after_content,element.
863 - $defaults[ $post_type . '_form_position_element' ] = 'p';
864 - $defaults[ $post_type . '_form_position_element_index' ] = 1;
390 + $defaults[ $post_type . '_form' ] = 0; // -1, 0 or Form ID.
865 391 }
866 392
867 393 /**
868 394 * The default settings, used when the ConvertKit Plugin Settings haven't been saved
@@ -878,39 +404,36 @@
878 404
879 405 }
880 406
881 407 /**
882 - * Saves the new access token, refresh token and its expiry, and schedules
883 - * a WordPress Cron event to refresh the token on expiry.
408 + * Saves the new access token, refresh token and its expiry when the API
409 + * class automatically refreshes an outdated access token.
884 410 *
885 - * @since 2.8.3
411 + * @since 2.5.0
886 412 *
887 - * @param array $result New Access Token, Refresh Token and Expiry.
413 + * @param array $result New Access Token, Refresh Token and Expiry.
414 + * @param string $client_id OAuth Client ID used for the Access and Refresh Tokens.
888 415 */
889 - public function update_credentials( $result ) {
416 + public function update_credentials( $result, $client_id ) {
890 417
891 - // Remove any existing persistent notice.
892 - WP_ConvertKit()->get_class( 'admin_notices' )->delete( 'authorization_failed' );
418 + // Don't save these credentials if they're not for this Client ID.
419 + // They're for another ConvertKit Plugin that uses OAuth.
420 + if ( $client_id !== CONVERTKIT_OAUTH_CLIENT_ID ) {
421 + return;
422 + }
893 423
894 424 $this->save(
895 425 array(
896 426 'access_token' => $result['access_token'],
897 427 'refresh_token' => $result['refresh_token'],
898 - 'token_expires' => ( time() + $result['expires_in'] ),
428 + 'token_expires' => ( $result['created_at'] + $result['expires_in'] ),
899 429 )
900 430 );
901 431
902 - // Clear any existing scheduled WordPress Cron event.
903 - wp_clear_scheduled_hook( 'convertkit_refresh_token' );
904 -
905 - // Schedule a WordPress Cron event to refresh the token on expiry.
906 - wp_schedule_single_event( ( time() + $result['expires_in'] ), 'convertkit_refresh_token' );
907 -
908 432 }
909 433
910 434 /**
911 - * Deletes any existing access token, refresh token and its expiry from the Plugin settings,
912 - * and clears any existing scheduled WordPress Cron event to refresh the token on expiry.
435 + * Deletes any existing access token, refresh token and its expiry from the Plugin settings.
913 436 *
914 437 * @since 2.5.0
915 438 */
916 439 public function delete_credentials() {
@@ -916,22 +439,14 @@
916 439 public function delete_credentials() {
917 440
918 441 $this->save(
919 442 array(
920 - // OAuth.
921 443 'access_token' => '',
922 444 'refresh_token' => '',
923 445 'token_expires' => '',
924 -
925 - // API Key.
926 - 'api_key' => '',
927 - 'api_secret' => '',
928 446 )
929 447 );
930 448
931 - // Clear any existing scheduled WordPress Cron event.
932 - wp_clear_scheduled_hook( 'convertkit_refresh_token' );
933 -
934 449 }
935 450
936 451 /**
937 452 * Saves the given array of settings to the WordPress options table.
@@ -944,27 +459,9 @@
944 459
945 460 update_option( self::SETTINGS_NAME, array_merge( $this->get(), $settings ) );
946 461
947 462 // Reload settings in class, to reflect changes.
948 - $this->refresh_settings();
949 -
950 - }
951 -
952 - /**
953 - * Reloads settings from the options table so this instance has the latest values.
954 - *
955 - * @since 3.1.1
956 - */
957 - private function refresh_settings() {
958 -
959 - $settings = get_option( self::SETTINGS_NAME );
960 -
961 - if ( ! $settings ) {
962 - $this->settings = $this->get_defaults();
963 - return;
964 - }
965 -
966 - $this->settings = array_merge( $this->get_defaults(), $settings );
463 + $this->settings = get_option( self::SETTINGS_NAME );
967 464
968 465 }
969 466
970 467 }