PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.0
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
← All changes | includes/functions.php +418 -36 2.3.33.4.0 View file →
@@ -16,8 +16,9 @@
16 16 function convertkit_plugin_activate( $network_wide ) {
17 17
18 18 // Initialise Plugin.
19 19 $convertkit = WP_ConvertKit();
20 + $convertkit->initialize();
20 21
21 22 // Check if we are on a multisite install, activating network wide, or a single install.
22 23 if ( ! is_multisite() || ! $network_wide ) {
23 24 // Single Site activation.
@@ -57,8 +58,9 @@
57 58 }
58 59
59 60 // Initialise Plugin.
60 61 $convertkit = WP_ConvertKit();
62 + $convertkit->initialize();
61 63
62 64 // Run installation routine.
63 65 switch_to_blog( $site_or_blog_id );
64 66 $convertkit->get_class( 'setup' )->activate();
@@ -76,8 +78,9 @@
76 78 function convertkit_plugin_deactivate( $network_wide ) {
77 79
78 80 // Initialise Plugin.
79 81 $convertkit = WP_ConvertKit();
82 + $convertkit->initialize();
80 83
81 84 // Check if we are on a multisite install, activating network wide, or a single install.
82 85 if ( ! is_multisite() || ! $network_wide ) {
83 86 // Single Site activation.
@@ -106,13 +109,32 @@
106 109 * @return array Post Types
107 110 */
108 111 function convertkit_get_supported_post_types() {
109 112
113 + // Define supported Post Types.
110 114 $post_types = array(
111 115 'page',
112 116 'post',
113 117 );
114 118
119 + // If public Custom Post Types can be fetched, include them now.
120 + if ( function_exists( 'get_post_types' ) ) {
121 + // Get public Custom Post Types.
122 + $custom_post_types = (array) get_post_types(
123 + array(
124 + 'public' => true,
125 +
126 + // Don't include WordPress' built in Post Types, such as attachment, revisino and nav_menu_item.
127 + '_builtin' => false,
128 + )
129 + );
130 +
131 + $post_types = array_merge(
132 + $post_types,
133 + array_keys( $custom_post_types )
134 + );
135 + }
136 +
115 137 /**
116 138 * Defines the Post Types that support ConvertKit Forms.
117 139 *
118 140 * @since 1.9.6
@@ -125,32 +147,40 @@
125 147
126 148 }
127 149
128 150 /**
151 + * Determines whether the current user can create and publish the given Post Type.
152 + *
153 + * @since 3.3.9
154 + *
155 + * @param string $post_type Post Type.
156 + * @return bool User can create and publish Post Type.
157 + */
158 +function convertkit_user_can_create_published_post_type( $post_type ) {
159 +
160 + $post_type_object = get_post_type_object( $post_type );
161 +
162 + if ( ! $post_type_object ) {
163 + return false;
164 + }
165 +
166 + return current_user_can( $post_type_object->cap->create_posts ) && current_user_can( $post_type_object->cap->publish_posts );
167 +
168 +}
169 +
170 +/**
129 171 * Helper method to get supported Post Types for Restricted Content (Member's Content)
130 172 *
131 173 * @since 2.1.0
132 174 *
175 + * @deprecated 2.4.3 No longer used by internal code and not recommended. Use `convertkit_get_supported_post_types` instead.
176 + *
133 177 * @return array Post Types
134 178 */
135 179 function convertkit_get_supported_restrict_content_post_types() {
136 180
137 - $post_types = array(
138 - 'page',
139 - 'post',
140 - );
181 + return convertkit_get_supported_post_types();
141 182
142 - /**
143 - * Defines the Post Types that support Restricted Content / Members Content functionality.
144 - *
145 - * @since 2.0.0
146 - *
147 - * @param array $post_types Post Types
148 - */
149 - $post_types = apply_filters( 'convertkit_get_supported_restrict_content_post_types', $post_types );
150 -
151 - return $post_types;
152 -
153 183 }
154 184
155 185 /**
156 186 * Helper method to get registered Shortcodes.
@@ -224,8 +254,32 @@
224 254
225 255 }
226 256
227 257 /**
258 + * Helper method to get registered plugin sidebars.
259 + *
260 + * @since 3.3.0
261 + *
262 + * @return array Plugin sidebars
263 + */
264 +function convertkit_get_plugin_sidebars() {
265 +
266 + $plugin_sidebars = array();
267 +
268 + /**
269 + * Registers plugin sidebars for the WordPress block editor.
270 + *
271 + * @since 3.3.0
272 + *
273 + * @param array $plugin_sidebars Plugin sidebars.
274 + */
275 + $plugin_sidebars = apply_filters( 'convertkit_plugin_sidebars', $plugin_sidebars );
276 +
277 + return $plugin_sidebars;
278 +
279 +}
280 +
281 +/**
228 282 * Helper method to get registered pre-publish actions.
229 283 *
230 284 * @since 2.4.0
231 285 *
@@ -248,8 +302,57 @@
248 302
249 303 }
250 304
251 305 /**
306 + * Helper method to get registered importers that can replace third party
307 + * form shortcodes and blocks with Kit form shortcodes and blocks.
308 + *
309 + * @since 3.1.7
310 + *
311 + * @return array Importers.
312 + */
313 +function convertkit_get_form_importers() {
314 +
315 + $importers = array();
316 +
317 + /**
318 + * Registers form importers for the ConvertKit Plugin.
319 + *
320 + * @since 3.1.7
321 + *
322 + * @param array $importers Importers.
323 + */
324 + $importers = apply_filters( 'convertkit_get_form_importers', $importers );
325 +
326 + return $importers;
327 +
328 +}
329 +
330 +/**
331 + * Helper method to get registered abilities.
332 + *
333 + * @since 3.4.0
334 + *
335 + * @return array Abilities.
336 + */
337 +function convertkit_get_abilities() {
338 +
339 + $abilities = array();
340 +
341 + /**
342 + * Registers abilities for the Kit Plugin.
343 + *
344 + * @since 3.4.0
345 + *
346 + * @param array $abilities Abilities.
347 + */
348 + $abilities = apply_filters( 'convertkit_abilities', $abilities );
349 +
350 + return $abilities;
351 +
352 +}
353 +
354 +/**
252 355 * Helper method to return the Plugin Settings Link
253 356 *
254 357 * @since 1.9.6
255 358 *
@@ -304,9 +407,9 @@
304 407 'utm_source' => 'wordpress',
305 408 'utm_term' => get_locale(),
306 409 'utm_content' => 'convertkit',
307 410 ),
308 - 'https://app.convertkit.com/users/signup'
411 + 'https://app.kit.com/users/signup'
309 412 );
310 413
311 414 }
312 415
@@ -324,9 +427,9 @@
324 427 'utm_source' => 'wordpress',
325 428 'utm_term' => get_locale(),
326 429 'utm_content' => 'convertkit',
327 430 ),
328 - 'https://app.convertkit.com/'
431 + 'https://app.kit.com/'
329 432 );
330 433
331 434 }
332 435
@@ -344,21 +447,21 @@
344 447 'utm_source' => 'wordpress',
345 448 'utm_term' => get_locale(),
346 449 'utm_content' => 'convertkit',
347 450 ),
348 - 'https://app.convertkit.com/account_settings/billing/'
451 + 'https://app.kit.com/account_settings/billing/'
349 452 );
350 453
351 454 }
352 455
353 456 /**
354 - * Helper method to return the URL the user needs to visit on the ConvertKit app to obtain their API Key and Secret.
457 + * Helper method to return the URL the user needs to visit on the ConvertKit app to create a new Form or Landing Page.
355 458 *
356 - * @since 1.9.6.1
459 + * @since 2.2.3
357 460 *
358 - * @return string ConvertKit App URL.
461 + * @return string ConvertKit App URL
359 462 */
360 -function convertkit_get_api_key_url() {
463 +function convertkit_get_new_form_url() {
361 464
362 465 return add_query_arg(
363 466 array(
364 467 'utm_source' => 'wordpress',
@@ -364,21 +467,21 @@
364 467 'utm_source' => 'wordpress',
365 468 'utm_term' => get_locale(),
366 469 'utm_content' => 'convertkit',
367 470 ),
368 - 'https://app.convertkit.com/account_settings/advanced_settings/'
471 + 'https://app.kit.com/forms/new/'
369 472 );
370 473
371 474 }
372 475
373 476 /**
374 - * Helper method to return the URL the user needs to visit on the ConvertKit app to create a new Form or Landing Page.
477 + * Helper method to return the URL the user needs to visit to edit ConvertKit forms.
375 478 *
376 479 * @since 2.2.3
377 480 *
378 - * @return string ConvertKit App URL
481 + * @return string ConvertKit Form Editor URL.
379 482 */
380 -function convertkit_get_new_form_url() {
483 +function convertkit_get_form_editor_url() {
381 484
382 485 return add_query_arg(
383 486 array(
384 487 'utm_source' => 'wordpress',
@@ -384,21 +487,21 @@
384 487 'utm_source' => 'wordpress',
385 488 'utm_term' => get_locale(),
386 489 'utm_content' => 'convertkit',
387 490 ),
388 - 'https://app.convertkit.com/forms/new/'
491 + 'https://app.kit.com/forms'
389 492 );
390 493
391 494 }
392 495
393 496 /**
394 - * Helper method to return the URL the user needs to visit to edit ConvertKit forms.
497 + * Helper method to return the URL the user needs to visit on the ConvertKit app to create a new Landing Page.
395 498 *
396 - * @since 2.2.3
499 + * @since 2.5.5
397 500 *
398 - * @return string ConvertKit Form Editor URL.
501 + * @return string ConvertKit App URL
399 502 */
400 -function convertkit_get_form_editor_url() {
503 +function convertkit_get_new_landing_page_url() {
401 504
402 505 return add_query_arg(
403 506 array(
404 507 'utm_source' => 'wordpress',
@@ -404,9 +507,9 @@
404 507 'utm_source' => 'wordpress',
405 508 'utm_term' => get_locale(),
406 509 'utm_content' => 'convertkit',
407 510 ),
408 - 'https://app.convertkit.com/forms'
511 + 'https://app.kit.com/pages/new/'
409 512 );
410 513
411 514 }
412 515
@@ -424,9 +527,9 @@
424 527 'utm_source' => 'wordpress',
425 528 'utm_term' => get_locale(),
426 529 'utm_content' => 'convertkit',
427 530 ),
428 - 'https://app.convertkit.com/subscribers/'
531 + 'https://app.kit.com/subscribers/'
429 532 );
430 533
431 534 }
432 535
@@ -444,9 +547,9 @@
444 547 'utm_source' => 'wordpress',
445 548 'utm_term' => get_locale(),
446 549 'utm_content' => 'convertkit',
447 550 ),
448 - 'https://app.convertkit.com/campaigns/'
551 + 'https://app.kit.com/campaigns/'
449 552 );
450 553
451 554 }
452 555
@@ -466,9 +569,9 @@
466 569 'utm_term' => get_locale(),
467 570 'utm_content' => 'convertkit',
468 571 ),
469 572 sprintf(
470 - 'https://app.convertkit.com/campaigns/%s/draft',
573 + 'https://app.kit.com/campaigns/%s/draft',
471 574 $broadcast_id
472 575 )
473 576 );
474 577
@@ -488,14 +591,42 @@
488 591 'utm_source' => 'wordpress',
489 592 'utm_term' => get_locale(),
490 593 'utm_content' => 'convertkit',
491 594 ),
492 - 'https://app.convertkit.com/products/new/'
595 + 'https://app.kit.com/products/new/'
493 596 );
494 597
495 598 }
496 599
497 600 /**
601 + * Helper method to enqueue the frontend CSS file.
602 + *
603 + * @since 3.2.0
604 + */
605 +function convertkit_enqueue_frontend_css() {
606 +
607 + wp_enqueue_style( 'convertkit-frontend', CONVERTKIT_PLUGIN_URL . 'resources/frontend/css/frontend.css', array(), CONVERTKIT_PLUGIN_VERSION );
608 +
609 +}
610 +
611 +/**
612 + * Helper method to enqueue the frontend JS file.
613 + *
614 + * @since 3.2.0
615 + */
616 +function convertkit_enqueue_frontend_js() {
617 +
618 + wp_enqueue_script(
619 + 'convertkit-js',
620 + CONVERTKIT_PLUGIN_URL . 'resources/frontend/js/dist/frontend.min.js',
621 + array(),
622 + CONVERTKIT_PLUGIN_VERSION,
623 + true
624 + );
625 +
626 +}
627 +
628 +/**
498 629 * Helper method to enqueue Select2 scripts for use within the ConvertKit Plugin.
499 630 *
500 631 * @since 1.9.6.4
501 632 */
@@ -544,4 +675,255 @@
544 675 // Return file's contents.
545 676 return $contents;
546 677
547 678 }
679 +
680 +/**
681 + * Returns a dropdown field commonly used for settings, comprising of:
682 + * - Do not subscribe
683 + * - Subscribe
684 + * - Subscribe to Form
685 + *
686 + * @since 2.5.2
687 + *
688 + * @param string $name Field name.
689 + * @param string $value Field value.
690 + * @param string $id Field ID attribute.
691 + * @param string $css_class Field CSS class(es).
692 + * @param string $context Resource context.
693 + * @param bool|array $additional_options Additional <option> key/value pairs.
694 + */
695 +function convertkit_get_subscription_dropdown_field( $name, $value, $id, $css_class = '', $context = '', $additional_options = false ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
696 +
697 + // Load resource classes.
698 + $forms = new ConvertKit_Resource_Forms( $context );
699 + $tags = new ConvertKit_Resource_Tags( $context );
700 + $sequences = new ConvertKit_Resource_Sequences( $context );
701 +
702 + ob_start();
703 + include CONVERTKIT_PLUGIN_PATH . '/views/backend/subscription-dropdown-field.php';
704 + $output = trim( ob_get_clean() );
705 +
706 + // Return output.
707 + return $output;
708 +
709 +}
710 +
711 +/**
712 + * Helper method to safely call get_current_screen(), returning false
713 + * if the function is not available or returns null.
714 + *
715 + * Otherwise returns the given WP_Screen property.
716 + *
717 + * @since 2.5.9
718 + *
719 + * @param string $property WP_Screen property to return.
720 + * @return bool|string
721 + */
722 +function convertkit_get_current_screen( $property ) {
723 +
724 + // Bail if we cannot determine the screen.
725 + if ( ! function_exists( 'get_current_screen' ) ) {
726 + return false;
727 + }
728 +
729 + // Get screen.
730 + $screen = get_current_screen();
731 +
732 + // Bail if the screen couldn't be determined.
733 + if ( is_null( $screen ) ) {
734 + return false;
735 + }
736 +
737 + // Return property.
738 + return $screen->$property;
739 +
740 +}
741 +
742 +/**
743 + * Outputs the Intercom help widget script.
744 + *
745 + * @since 2.7.2
746 + */
747 +function convertkit_output_intercom_messenger() {
748 +
749 + ?>
750 + <script>
751 + const KIT_INTERCOM_APP_ID = 'e4n3xtxz';
752 + window.intercomSettings = {
753 + api_base: 'https://api-iam.intercom.io',
754 + app_id: KIT_INTERCOM_APP_ID
755 + };
756 + </script>
757 +
758 + <script>
759 + (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/' + KIT_INTERCOM_APP_ID;var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
760 + </script>
761 + <?php
762 +
763 +}
764 +
765 +/**
766 + * Checks if the given Theme is active.
767 + *
768 + * @since 3.1.4
769 + *
770 + * @param string $theme_name Theme name.
771 + * @return bool
772 + */
773 +function convertkit_is_theme_active( $theme_name ) {
774 +
775 + // Assume Theme isn't active if we can't detect it.
776 + if ( ! function_exists( 'wp_get_theme' ) ) {
777 + return false;
778 + }
779 +
780 + // Check the Parent Theme if we're on a Child Theme.
781 + if ( wp_get_theme()->parent() ) {
782 + $theme = wp_get_theme()->parent();
783 + } else {
784 + $theme = wp_get_theme();
785 + }
786 +
787 + return strtolower( $theme->get( 'Name' ) ) === strtolower( $theme_name );
788 +
789 +}
790 +
791 +/**
792 + * Returns permitted HTML output when using wp_kses( ..., convertkit_kses_allowed_html()).
793 + *
794 + * @since 2.8.5
795 + */
796 +function convertkit_kses_allowed_html() {
797 +
798 + // Get WordPress' permitted HTML elements.
799 + $elements = wp_kses_allowed_html( 'post' );
800 +
801 + // Add form elements.
802 + $form_elements = array(
803 + 'input' => array(
804 + 'type' => true,
805 + 'id' => true,
806 + 'name' => true,
807 + 'class' => true,
808 + 'value' => true,
809 + 'checked' => true,
810 + 'min' => true,
811 + 'max' => true,
812 + 'step' => true,
813 + 'data-*' => true,
814 + ),
815 + 'select' => array(
816 + 'id' => true,
817 + 'name' => true,
818 + 'class' => true,
819 + 'size' => true,
820 + 'multiple' => true,
821 + 'data-*' => true,
822 + ),
823 + 'option' => array(
824 + 'value' => true,
825 + 'selected' => true,
826 + 'data-*' => true,
827 + ),
828 + 'optgroup' => array(
829 + 'label' => true,
830 + 'data-*' => true,
831 + ),
832 + 'label' => array(
833 + 'for' => true,
834 + ),
835 + );
836 +
837 + return array_merge( $elements, $form_elements );
838 +
839 +}
840 +
841 +/**
842 + * Saves the new access token, refresh token and its expiry, and schedules
843 + * a WordPress Cron event to refresh the token on expiry.
844 + *
845 + * @since 3.1.1
846 + *
847 + * @param array $result New Access Token, Refresh Token and Expiry.
848 + * @param string $client_id OAuth Client ID used for the Access and Refresh Tokens.
849 + */
850 +function convertkit_maybe_update_credentials( $result, $client_id ) {
851 +
852 + // Don't save these credentials if they're not for this Client ID.
853 + // They're for another Kit Plugin that uses OAuth.
854 + if ( $client_id !== CONVERTKIT_OAUTH_CLIENT_ID ) {
855 + return;
856 + }
857 +
858 + $settings = new ConvertKit_Settings();
859 + $settings->update_credentials( $result );
860 +
861 +}
862 +
863 +/**
864 + * Deletes the stored access token, refresh token and its expiry from the Plugin settings,
865 + * and clears any existing scheduled WordPress Cron event to refresh the token on expiry,
866 + * when the user revokes the access token.
867 + *
868 + * @since 3.2.4
869 + *
870 + * @param string $client_id OAuth Client ID used for the Access and Refresh Tokens.
871 + */
872 +function convertkit_delete_credentials( $client_id ) {
873 +
874 + // Don't delete these credentials if they're not for this Client ID.
875 + // They're for another Kit Plugin that uses OAuth.
876 + if ( $client_id !== CONVERTKIT_OAUTH_CLIENT_ID ) {
877 + return;
878 + }
879 +
880 + // Delete Access and Refresh Tokens.
881 + $settings = new ConvertKit_Settings();
882 + $settings->delete_credentials();
883 +
884 +}
885 +
886 +/**
887 + * Deletes the stored access token, refresh token and its expiry from the Plugin settings,
888 + * and clears any existing scheduled WordPress Cron event to refresh the token on expiry,
889 + * when either:
890 + * - The access token is invalid
891 + * - The access token expired, and refreshing failed
892 + *
893 + * @since 3.1.1
894 + *
895 + * @param WP_Error $result Error result.
896 + * @param string $client_id OAuth Client ID used for the Access and Refresh Tokens.
897 + */
898 +function convertkit_maybe_delete_credentials( $result, $client_id ) {
899 +
900 + // Don't save these credentials if they're not for this Client ID.
901 + // They're for another Kit Plugin that uses OAuth.
902 + if ( $client_id !== CONVERTKIT_OAUTH_CLIENT_ID ) {
903 + return;
904 + }
905 +
906 + // If the error isn't a 401, don't delete credentials.
907 + // This could be e.g. a temporary network error, rate limit or similar.
908 + if ( $result->get_error_data( 'convertkit_api_error' ) !== 401 ) {
909 + return;
910 + }
911 +
912 + // Persist an error notice in the WordPress Administration until the user fixes the problem.
913 + WP_ConvertKit()->get_class( 'admin_notices' )->add( 'authorization_failed' );
914 +
915 + $settings = new ConvertKit_Settings();
916 + $settings->delete_credentials();
917 +
918 +}
919 +
920 +// Update Access Token when refreshed by the API class.
921 +add_action( 'convertkit_api_get_access_token', 'convertkit_maybe_update_credentials', 10, 2 );
922 +add_action( 'convertkit_api_refresh_token', 'convertkit_maybe_update_credentials', 10, 2 );
923 +
924 +// Delete credentials when the user revokes the access and refresh tokens.
925 +add_action( 'convertkit_api_revoke_tokens', 'convertkit_delete_credentials', 10, 1 );
926 +
927 +// Delete credentials if the API class uses a invalid access token.
928 +// This prevents the Plugin making repetitive API requests that will 401.
929 +add_action( 'convertkit_api_access_token_invalid', 'convertkit_maybe_delete_credentials', 10, 2 );