PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 1.7.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v1.7.0
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 2.3.1 2.3.2 All 195 releases
convertkit / includes / class-convertkit.php

class-convertkit.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 1.7.0, at includes/class-convertkit.php

665 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class WP_ConvertKit
5 */
6 class WP_ConvertKit {
7
8 const POST_META_KEY = '_wp_convertkit_post_meta';
9
10 const SETTINGS_NAME = '_wp_convertkit_settings';
11
12 const SETTINGS_PAGE_SLUG = '_wp_convertkit_settings';
13
14 /**
15 * @var ConvertKit_API
16 */
17 private static $api;
18
19 /**
20 * @var int Data Caching
21 */
22 private static $cache_period = 0;
23
24 /**
25 * @var null
26 */
27 private static $meta_defaults = null;
28
29 /**
30 * @var array
31 */
32 private static $settings_defaults = array(
33 'api_key' => '',
34 'api_secret' => '',
35 'default_form' => 0,
36 'debug' => false,
37 'no_scripts' => false,
38 );
39
40 /**
41 * @var array
42 */
43 private static $forms_markup = array();
44
45 /** @var array */
46 private static $landing_pages_markup = array();
47
48 /** @var string */
49 private static $forms_version = '6';
50
51 /**
52 * Initialize the class
53 */
54 public static function init() {
55 self::add_actions();
56 self::add_filters();
57 self::register_shortcodes();
58
59 self::$cache_period = MINUTE_IN_SECONDS * 10;
60
61 self::_api_connect();
62 }
63
64 /**
65 * Add WP Actions
66 */
67 private static function add_actions() {
68 add_action( 'plugins_loaded', array( __CLASS__, 'load_textdomain' ) );
69 if ( is_admin() ) {
70 add_action( 'add_meta_boxes_page', array( __CLASS__, 'add_meta_boxes' ) );
71 add_action( 'add_meta_boxes_post', array( __CLASS__, 'add_meta_boxes' ) );
72 } else {
73 add_action( 'template_redirect', array( __CLASS__, 'page_takeover' ) );
74 add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
75 }
76
77 add_action( 'widgets_init', array( __CLASS__, 'ck_register_widgets' ) );
78
79 add_action( 'save_post', array( __CLASS__, 'save_post_meta' ), 10, 2 );
80
81 add_action( 'init', array( __CLASS__, 'upgrade' ) , 10 );
82 }
83
84 /**
85 * Load plugin textdomain
86 */
87 public static function load_textdomain() {
88 load_plugin_textdomain( 'convertkit', false, basename( dirname( __FILE__ ) ) . '/languages/' );
89 }
90
91 /**
92 * Add WP Filters
93 */
94 private static function add_filters() {
95 if ( ! is_admin() ) {
96 add_filter( 'the_content', array( __CLASS__, 'append_form' ) );
97 }
98
99 add_filter( 'plugin_action_links_' . CONVERTKIT_PLUGIN_FILE, array( __CLASS__, 'add_settings_page_link' ) );
100 }
101
102 /**
103 * Register ConvertKit shortcodes
104 */
105 private static function register_shortcodes() {
106 add_shortcode( 'convertkit', array( __CLASS__, 'shortcode' ) );
107 }
108
109 /**
110 * Plugin action links callback
111 *
112 * @param $links
113 * @return array
114 */
115 public static function add_settings_page_link( $links ) {
116 $settings_link = sprintf( '<a href="%s">%s</a>', self::_get_settings_page_link(), __( 'Settings', 'convertkit' ) );
117
118 return array(
119 'settings' => $settings_link,
120 ) + $links;
121 }
122
123 /**
124 * Add Meta Boxes callback
125 *
126 * @param WP_Post $post The current post.
127 */
128 public static function add_meta_boxes( $post ) {
129 add_meta_box( 'wp-convertkit-meta-box', __( 'ConvertKit', 'convertkit' ), array( __CLASS__, 'display_meta_box' ), $post->post_type, 'normal' );
130 }
131
132 /**
133 * Metabox callback
134 *
135 * @param $post
136 */
137 public static function display_meta_box( $post ) {
138
139 $forms = get_option( 'convertkit_forms' );
140 $landing_pages = get_option( 'convertkit_landing_pages' );
141 $tags = get_option( 'convertkit_tags' );
142
143 $meta = self::_get_meta( $post->ID );
144 $settings_link = self::_get_settings_page_link();
145
146 include( CONVERTKIT_PLUGIN_PATH . '/views/backend/meta-boxes/meta-box.php' );
147 }
148
149 /**
150 * Save post meta callback
151 *
152 * @param int $post_id Post id.
153 * @param WP_Post $post The post.
154 */
155 public static function save_post_meta( $post_id, $post ) {
156 if ( wp_is_post_autosave( $post_id )
157 || wp_is_post_revision( $post_id )
158 || ! isset( $_POST['wp-convertkit-save-meta-nonce'] ) // WPCS input var okay.
159 || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wp-convertkit-save-meta-nonce'] ) ), 'wp-convertkit-save-meta' ) ) { // WPCS input var okay.
160 return;
161 }
162 if ( isset( $_POST['wp-convertkit'] ) ) { // WPCS input var okay.
163 $form = '';
164 if ( isset( $_POST['wp-convertkit']['form'] ) ) { // WPCS input var okay.
165 $form = sanitize_text_field( wp_unslash( $_POST['wp-convertkit']['form'] ) ); // WPCS input var okay.
166 }
167 $landing_page = '';
168 if ( isset( $_POST['wp-convertkit']['landing_page'] ) ) { // WPCS input var okay.
169 $landing_page = sanitize_text_field( wp_unslash( $_POST['wp-convertkit']['landing_page'] ) ); // WPCS input var okay.
170 }
171 $tag = '';
172 if ( isset( $_POST['wp-convertkit']['tag'] ) ) { // WPCS input var okay.
173 $tag = sanitize_text_field( wp_unslash( $_POST['wp-convertkit']['tag'] ) ); // WPCS input var okay.
174 }
175
176 $meta = array(
177 'form' => $form,
178 'landing_page' => $landing_page,
179 'tag' => $tag,
180 );
181 update_post_meta( $post_id, self::POST_META_KEY, $meta );
182 }
183 }
184
185 /**
186 * Page/Post display callback
187 *
188 * @param string $content The post content.
189 * @return string
190 */
191 public static function append_form( $content ) {
192
193 if ( is_singular( array( 'post' ) ) || is_page() ) {
194
195 $attributes = self::_get_meta( get_the_ID() );
196
197 // Get post/page form setting
198 if ( isset( $attributes['form'] ) && ( 0 < $attributes['form'] ) ) {
199 $form_id = $attributes['form'];
200 } else {
201 // Get category form
202 $form_id = self::get_category_form( get_the_ID() );
203
204 if ( 0 === $form_id ) {
205 // Get global default form
206 if ( '-1' === $attributes['form'] ) {
207 $form_id = self::_get_settings( 'default_form' );
208 }
209 }
210 }
211
212 if ( 0 < $form_id ) {
213
214 $forms = get_option( 'convertkit_forms' );
215
216 if ( isset( $forms[ $form_id ]['uid'] ) ) {
217 // new form
218 $tag = '<script async data-uid="' . $forms[ $form_id ]['uid'] . '" src="' . $forms[ $form_id ]['embed_js'] . '"></script>';
219 $content .= $tag;
220
221 } else {
222 // old form
223 $url = add_query_arg(
224 array(
225 'api_key' => self::_get_settings( 'api_key' ),
226 'v' => self::$forms_version,
227 ),
228 'https://forms.convertkit.com/' . $form_id . '.html'
229 );
230
231 $form_markup = self::$api->get_resource( $url );
232 $content .= $form_markup;
233 }
234 }
235 }
236
237 return $content;
238 }
239
240 /**
241 * Replace page content if a landing_page is set
242 */
243 public static function page_takeover() {
244 $queried_object = get_queried_object();
245 if ( isset( $queried_object->post_type )
246 && 'page' === $queried_object->post_type ) {
247
248 $landing_page_id = self::_get_meta( $queried_object->ID, 'landing_page' );
249
250 if ( '0' === $landing_page_id || empty( $landing_page_id ) ) {
251 // Set to None
252 return;
253 }
254
255 if ( strstr( $landing_page_id, 'http') ) {
256 // Old landing page
257 $landing_page = self::$api->get_resource( $landing_page_id );
258 if ( ! empty( $landing_page ) ) {
259 $script = WP_ConvertKit::get_ck_script();
260 $script .= "</head>";
261 $landing_page = str_replace( '</head>', $script, $landing_page );
262 echo $landing_page; // WPCS: XSS ok.
263 exit;
264 }
265 } else {
266 // New landing page
267 $landing_pages = get_option( 'convertkit_landing_pages' );
268 $landing_page = self::$api->get_resource( $landing_pages[$landing_page_id]['embed_url'] );
269 if ( ! empty( $landing_page ) ) {
270 $script = WP_ConvertKit::get_ck_script( true );
271 $script .= "</head>";
272 $landing_page = str_replace( '</head>', $script, $landing_page );
273 echo $landing_page; // WPCS: XSS ok.
274 exit;
275 }
276 }
277 }
278 }
279
280 /**
281 * Generate HTML for including ConvertKit JS in a landing page.
282 *
283 * During the landing page takeover the normal WordPress enqueue routine is not run so we need to add these
284 * javascript if we want subscribers tagged correctly.
285 *
286 * @since 1.5.2
287 * @param bool $include_jquery
288 * @return string
289 */
290 public static function get_ck_script( $include_jquery = false) {
291 $script = '';
292 if ( $include_jquery ) {
293 $scripts = new WP_Scripts();
294 $script .= "<script type='text/javascript' src='" . trailingslashit( $scripts->base_url ) . "wp-includes/js/jquery/jquery.js?ver=1.4.0'></script>";
295 }
296 $script .= "<script type='text/javascript' src='" . CONVERTKIT_PLUGIN_URL . "resources/frontend/jquery.cookie.min.js?ver=1.4.0'></script>";
297 $script .= "<script type='text/javascript' src='" . CONVERTKIT_PLUGIN_URL . 'resources/frontend/wp-convertkit.js?ver=' . CONVERTKIT_PLUGIN_VERSION . "'></script>";
298 $script .= "<script type='text/javascript'>/* <![CDATA[ */var ck_data = {\"ajaxurl\":\"" . admin_url( 'admin-ajax.php' ) . '"};/* ]]> */</script>';
299 return $script;
300 }
301
302 /**
303 * Enqueue scripts
304 */
305 public static function enqueue_scripts() {
306
307 // Only check for tags if we're on a singular post; otherwise, no tags
308 $has_tag = is_singular() ? self::post_has_tag( get_post() ) : false;
309
310 // Only load scripts if no scripts setting is not checked
311 $no_scripts = self::_get_settings( 'no_scripts' );
312 if ( ! $no_scripts ) {
313 wp_register_script(
314 'jquery-cookie',
315 CONVERTKIT_PLUGIN_URL . 'resources/frontend/jquery.cookie.min.js',
316 array( 'jquery' ),
317 '1.4.0'
318 );
319
320 wp_register_script(
321 'convertkit-js',
322 CONVERTKIT_PLUGIN_URL . 'resources/frontend/wp-convertkit.js',
323 array( 'jquery-cookie' ),
324 CONVERTKIT_PLUGIN_VERSION
325 );
326
327 wp_localize_script(
328 'convertkit-js',
329 'ck_data',
330 array(
331 'ajaxurl' => admin_url( 'admin-ajax.php' ),
332 'post_has_tag' => $has_tag,
333 )
334 );
335
336 wp_enqueue_script( 'convertkit-js' );
337 }
338 }
339
340 /**
341 * Register widget.
342 */
343 public static function ck_register_widgets() {
344 register_widget( 'CK_Widget_Form' );
345 }
346
347 /**
348 * Shortcode callback
349 *
350 * @param array $attributes Shortcode attributes.
351 * @param null $content
352 * @return string
353 */
354 public static function shortcode( $attributes, $content = null ) {
355
356 if ( isset( $attributes['id'] ) ) {
357 $form_id = $attributes['id'];
358 $forms = get_option( 'convertkit_forms' );
359
360 if ( isset( $forms[ $form_id ]['uid'] ) ) {
361 // new form
362 $form_markup = '<script async data-uid="' . $forms[ $form_id ]['uid'] . '" src="' . $forms[ $form_id ]['embed_js'] . '"></script>';
363 return apply_filters( 'wp_convertkit_get_form_embed', $form_markup, $attributes );
364 } else {
365 // old form
366 $url = add_query_arg(
367 array(
368 'api_key' => self::_get_settings( 'api_key' ),
369 'v' => self::$forms_version,
370 ),
371 'https://forms.convertkit.com/' . $form_id . '.html'
372 );
373 }
374 } elseif ( isset( $attributes['form'] ) ) {
375 $form_id = $attributes['form'];
376 $forms = get_option( 'convertkit_forms' );
377
378 if ( isset( $forms[ $form_id ]['uid'] ) ) {
379 // new form
380 $form_markup = '<script async data-uid="' . $forms[ $form_id ]['uid'] . '" src="' . $forms[ $form_id ]['embed_js'] . '"></script>';
381 return apply_filters( 'wp_convertkit_get_form_embed', $form_markup, $attributes );
382 } else {
383 $url = add_query_arg(
384 array(
385 'k' => self::_get_settings( 'api_key' ),
386 'v' => '2',
387 ),
388 'https://api.convertkit.com/forms/' . $form_id . '/embed'
389 );
390 }
391 } else {
392 $form_id = self::_get_settings( 'default_form' );
393 $url = add_query_arg(
394 array(
395 'api_key' => self::_get_settings( 'api_key' ),
396 'v' => self::$forms_version,
397 ),
398 'https://forms.convertkit.com/' . $form_id . '.html'
399 );
400 }
401
402 if ( 0 < $form_id ) {
403 $form_markup = self::$api->get_resource( $url );
404 } else {
405 $form_markup = '';
406 }
407
408 return apply_filters( 'wp_convertkit_get_form_embed', $form_markup, $attributes );
409 }
410
411 /**
412 * Retrieve meta
413 *
414 * @return array|null
415 */
416 private static function _get_meta_defaults() {
417 if ( is_null( self::$meta_defaults ) ) {
418 self::$meta_defaults = array(
419 'form' => '-1',
420 'landing_page' => '',
421 'tag' => '',
422 );
423 }
424
425 return self::$meta_defaults;
426 }
427
428 /**
429 * Get selected post meta
430 *
431 * @param int $post_id Post ID.
432 * @param null $meta_key Key string to get.
433 *
434 * @return array|bool
435 */
436 private static function _get_meta( $post_id, $meta_key = null ) {
437 $post_id = empty( $post_id ) ? get_the_ID() : $post_id;
438
439 $meta = get_post_meta( $post_id, self::POST_META_KEY, true );
440 $meta_defaults = self::_get_meta_defaults();
441
442 if ( empty( $meta ) ) {
443 $meta = $meta_defaults;
444
445 $old_value = intval( get_post_meta( $post_id, '_convertkit_convertkit_form', true ) );
446 if ( 0 !== $old_value ) {
447 $meta['form'] = $old_value;
448 }
449 }
450
451 $meta = shortcode_atts( $meta_defaults, $meta );
452
453 return is_null( $meta_key ) ? $meta : ( isset( $meta[ $meta_key ] ) ? $meta[ $meta_key ] : false );
454 }
455
456 /**
457 * Get plugin settings
458 *
459 * @param null $settings_key
460 * @return mixed|null
461 */
462 public static function _get_settings( $settings_key = null ) {
463 $settings = get_option( self::SETTINGS_NAME, self::$settings_defaults );
464
465 return is_null( $settings_key ) ? $settings : ( isset( $settings[ $settings_key ] ) ? $settings[ $settings_key ] : null);
466 }
467
468 /**
469 * Get instance of ConvertKitAPI
470 */
471 private static function _api_connect() {
472 $api_key = self::_get_settings( 'api_key' );
473 $api_secret = self::_get_settings( 'api_secret' );
474 $debug = self::_get_settings( 'debug' );
475
476 self::$api = new ConvertKit_API( $api_key, $api_secret, $debug );
477 }
478
479 /**
480 * Get instance of the CK API
481 *
482 * @return ConvertKit_API
483 */
484 public static function get_api() {
485 return self::$api;
486 }
487
488 /**
489 * Get ConvertKit API key
490 *
491 * @return mixed|null|void
492 */
493 public static function get_api_key() {
494 return self::_get_settings( 'api_key' );
495 }
496
497 /**
498 * Get ConvertKit API secret
499 *
500 * @return mixed|null|void
501 */
502 public static function get_api_secret() {
503 return self::_get_settings( 'api_secret' );
504 }
505
506 /**
507 * @return string
508 */
509 public static function get_forms_version() {
510 return self::$forms_version;
511 }
512
513 /**
514 * Get link to the plugin settings page
515 *
516 * @param array $query_args Args to add to URL.
517 * @return string
518 */
519 private static function _get_settings_page_link( $query_args = array() ) {
520 $query_args = array(
521 'page' => self::SETTINGS_PAGE_SLUG,
522 ) + $query_args;
523
524 return add_query_arg( $query_args, admin_url( 'options-general.php' ) );
525 }
526
527 /**
528 * Get default form for the post's categories.
529 * If there are multiple set the last one found will be returned.
530 *
531 * @param int $id
532 * @return int $form_id
533 */
534 private static function get_category_form( $id ) {
535 $categories = wp_get_post_categories( $id );
536
537 $form_id = 0;
538 foreach ( $categories as $category ) {
539
540 $id = get_term_meta( $category, 'ck_default_form', true );
541 if ( $id ) {
542 $form_id = $id;
543 }
544 }
545
546 return $form_id;
547 }
548
549 /**
550 * Output data to log file
551 *
552 * @param string $message String to add to log.
553 */
554 static function log( $message ) {
555
556 if ( 'on' === self::_get_settings( 'debug' ) ) {
557 $dir = CONVERTKIT_PLUGIN_PATH;
558 $handle = fopen( trailingslashit( $dir ) . 'log.txt', 'a' );
559 if ( $handle ) {
560 $time = date_i18n( 'm-d-Y @ H:i:s -' );
561 fwrite( $handle, $time . ' ' . $message . "\n" );
562 fclose( $handle );
563 }
564 }
565
566 }
567
568 /**
569 * Run version specific upgrade.
570 */
571 public static function upgrade() {
572
573 $current_version = get_option( 'convertkit_version' );
574 $convertkit_user_history_table = get_option( 'convertkit_user_history_table' );
575
576 if ( ! $current_version ) {
577 // Run 1.4.1 upgrade.
578 $settings = self::_get_settings();
579
580 if ( isset( $settings['api_key'] ) ) {
581 // Get all posts and pages to track what has been updated.
582 $posts = get_option( '_wp_convertkit_upgrade_posts' );
583
584 if ( ! $posts ) {
585
586 $args = array(
587 'post_type' => array( 'post', 'page' ),
588 'fields' => 'ids',
589 );
590
591 $result = new WP_Query( $args );
592 if ( ! is_wp_error( $result ) ) {
593 $posts = $result->posts;
594 update_option( '_wp_convertkit_upgrade_posts', $posts );
595 }
596 }
597
598 // Get form mappings.
599 $mappings = self::$api->get_resources( 'subscription_forms' );
600
601 // 1. Update global form. Set 'api_version' so this is only done once.
602 if ( ! isset( $settings['api_version'] ) ) {
603 $old_form_id = $settings['default_form'];
604 $settings['default_form'] = isset( $mappings[ $old_form_id ] ) ? $mappings[ $old_form_id ] : 0;
605 $settings['api_version'] = 'v3';
606 update_option( self::SETTINGS_NAME, $settings );
607 }
608
609 // 2. Scan posts/pages for _wp_convertkit_post_meta and update IDs
610 // Scan content for shortcode and update
611 // Remove page_id from posts array after page is updated.
612 foreach ( $posts as $key => $post_id ) {
613 $post_settings = get_post_meta( $post_id, '_wp_convertkit_post_meta', true );
614
615 if ( isset( $post_settings['form'] ) && ( 0 < $post_settings['form'] ) ) {
616 $post_settings['form'] = isset( $mappings[ $post_settings['form'] ] ) ? $mappings[ $post_settings['form'] ] : 0;
617 }
618 if ( isset( $post_settings['landing_page'] ) && ( 0 < $post_settings['landing_page'] ) ) {
619 $post_settings['landing_page'] = isset( $mappings[ $post_settings['landing_page'] ] ) ? $mappings[ $post_settings['landing_page'] ] : 0;
620 }
621 update_post_meta( $post_id, '_wp_convertkit_post_meta', $post_settings );
622 unset( $posts[ $key ] );
623 update_option( '_wp_convertkit_upgrade_posts', $posts );
624 }
625
626 // Done scanning posts, upgrade complete.
627 if ( empty( $posts ) ) {
628 update_option( 'convertkit_version', CONVERTKIT_PLUGIN_VERSION );
629 delete_option( '_wp_convertkit_upgrade_posts' );
630 }
631 } else {
632 update_option( 'convertkit_version', CONVERTKIT_PLUGIN_VERSION );
633 } // End if().
634 } elseif ( version_compare( $current_version, '1.5.0', '<' ) || ! $convertkit_user_history_table ) {
635
636 // Create User History table
637 ConvertKit_Custom_Content::create_table();
638 update_option( 'convertkit_version', CONVERTKIT_PLUGIN_VERSION );
639
640 } elseif ( version_compare( $current_version, '1.6.1', '<' ) ) {
641 // Refresh the forms meta to get new forms builder settings
642 $api_key = self::_get_settings( 'api_key' );
643 if ( ! empty( $api_key ) ) {
644 self::$api->update_resources( $api_key );
645 }
646 update_option( 'convertkit_version', CONVERTKIT_PLUGIN_VERSION );
647 }// End if().
648 }
649
650
651 /**
652 * @param $post WP_Post
653 *
654 * @return boolean
655 */
656 public static function post_has_tag( $post ) {
657 $meta = get_post_meta( $post->ID, '_wp_convertkit_post_meta', true );
658
659 if ( isset( $meta['tag'] ) ) {
660 return ( $meta['tag'] == 0 ) ? false : true;
661 }
662 return false;
663 }
664 }
665