PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 1.6.4
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v1.6.4
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-custom-content.php

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

542 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class ConvertKit_Custom_Content
4 *
5 * @since 1.5.0
6 */
7 class ConvertKit_Custom_Content {
8
9 /**
10 * Name of the database table to store user visits
11 *
12 * @var string
13 */
14 public $table = 'convertkit_user_history';
15
16 /**
17 * Name of the cookie to store user visits
18 *
19 * @var string
20 */
21 public $cookie;
22
23 /**
24 * Version of the visits database
25 */
26 public $version = '1.0.0';
27
28 /**
29 * How long the cookie will last
30 *
31 * @var
32 */
33 public $cookie_life;
34
35 /**
36 * @var mixed|void
37 */
38 protected $options;
39
40 /**
41 * Constructor
42 */
43 public function __construct() {
44
45 $this->options = get_option( '_wp_convertkit_integration_custom_content_settings' );
46
47 $this->table = 'convertkit_user_history';
48 $this->cookie = 'convertkit_history';
49 $this->cookie_life = 21 * DAY_IN_SECONDS;
50
51 $this->add_actions();
52 $this->register_shortcodes();
53 }
54
55 /**
56 * Add actions related to user history
57 */
58 public function add_actions() {
59
60 add_action( 'wp_ajax_nopriv_ck_add_user_visit', array( $this, 'maybe_tag_subscriber_ajax' ) );
61 add_action( 'wp_ajax_ck_add_user_visit', array( $this, 'maybe_tag_subscriber_ajax' ) );
62 add_action( 'wp_ajax_nopriv_ck_get_subscriber', array( $this, 'get_subscriber' ) );
63 add_action( 'wp_ajax_ck_get_subscriber', array( $this, 'get_subscriber' ) );
64
65 if ( ! is_admin() ) {
66 add_action( 'the_post', array( $this, 'maybe_tag_subscriber' ), 50 );
67 }
68
69 }
70
71 /**
72 * This method is called by a javascript ajax call when a ck_subscriber_id was passed via the query args.
73 *
74 * @since 1.5.5
75 */
76 public function maybe_tag_subscriber_ajax(){
77
78 // get post_id from url
79 $url = isset( $_POST['url'] ) ? sanitize_text_field( $_POST['url'] ) : '';
80 $post_id = url_to_postid( $url );
81 $post = get_post( $post_id );
82
83 // set cookie
84 $subscriber_id = isset( $_POST['subscriber_id'] ) ? sanitize_text_field( $_POST['subscriber_id'] ) : 0;
85 $_COOKIE['ck_subscriber_id'] = absint( $subscriber_id );
86
87 if ( isset( $post ) ) {
88 ConvertKit_Custom_Content::maybe_tag_subscriber( $post );
89 }
90 echo json_encode(
91 array(
92 'subscriber_id' => $subscriber_id,
93 )
94 );
95 exit;
96 }
97
98 /**
99 * Track the visitor
100 *
101 * @since 1.5.0
102 */
103 public function add_user_history() {
104 /*
105 $subscriber_id = isset( $_POST['subscriber_id'] ) ? sanitize_text_field( $_POST['subscriber_id'] ): 0;
106
107 $visitor_cookie = isset( $_POST['user'] ) ? sanitize_text_field( $_POST['user'] ): 0;
108 $subscriber_id = isset( $_POST['subscriber_id'] ) ? sanitize_text_field( $_POST['subscriber_id'] ): 0;
109 $user_id = get_current_user_id();
110 $url = isset( $_POST['url'] ) ? sanitize_text_field( $_POST['url'] ): '';
111 $ip = $this->get_user_ip();
112 $date = date( 'Y-m-d H:i:s', time() );
113
114 if ( ! $subscriber_id && $user_id ) {
115 $api = WP_ConvertKit::get_api();
116 $user_info = get_userdata( $user_id );
117 WP_ConvertKit::log( 'Trying to get subscriber_id with email: ' . $user_info->user_email );
118 $subscriber_id = $api->get_subscriber_id( $user_info->user_email );
119 }
120
121 WP_ConvertKit::log( '-------- in add_history ---------' );
122 WP_ConvertKit::log( 'visitor_cookie: ' . $visitor_cookie );
123 WP_ConvertKit::log( 'subscriber_id: ' . $subscriber_id );
124 WP_ConvertKit::log( 'url: ' . $url );
125 WP_ConvertKit::log( 'user_id: ' . $user_id );
126
127 if ( empty( $visitor_cookie ) ) {
128 $visitor_cookie = md5( time() );
129 WP_ConvertKit::log( 'no user adding one: ' . $visitor_cookie );
130 }
131
132 $this->insert( array(
133 'visitor_cookie' => $visitor_cookie,
134 'user_id' => $user_id,
135 'subscriber_id' => $subscriber_id,
136 'url' => $url,
137 'ip' => $ip,
138 'date' => $date,
139 ) );
140
141
142 echo json_encode(
143 array(
144 'subscriber_id' => $subscriber_id,
145 )
146 );
147 exit;
148 */
149 }
150
151 /**
152 * Get ck_subscriber_id with email via AJAX
153 */
154 public function get_subscriber() {
155
156 $email = isset( $_POST['email'] ) ? sanitize_text_field( $_POST['email'] ): 0;
157
158 $api = WP_ConvertKit::get_api();
159 WP_ConvertKit::log( 'Trying to get subscriber_id with email: ' . $email );
160 $subscriber_id = $api->get_subscriber_id( $email );
161
162 WP_ConvertKit::log( 'In get_subscriber. email: ' . $email . ', subscriber_id: ' . $subscriber_id );
163
164 echo json_encode(
165 array(
166 'subscriber_id' => $subscriber_id,
167 )
168 );
169 exit;
170 }
171
172 /**
173 * Register shortcode
174 */
175 public function register_shortcodes() {
176 add_shortcode( 'convertkit_content', array( $this, 'shortcode' ) );
177 }
178
179 /**
180 * Shortcode callback
181 *
182 * @param array $attributes Shortcode attributes.
183 * @param string $content
184 * @return mixed|void
185 */
186 public static function shortcode( $attributes, $content ) {
187
188 // The 'tag' attribute is required.
189 if ( isset( $attributes['tag'] ) ) {
190 $tags = array();
191 $tag = $attributes['tag'];
192 $user_id = get_current_user_id();
193 $api = WP_ConvertKit::get_api();
194
195 if ( isset( $_COOKIE['ck_subscriber_id'] ) ) {
196 WP_ConvertKit::log( 'shortcode: cookie found, calling API' );
197 // get cookie and check API for customer tags.
198 $subscriber_id = absint( $_COOKIE['ck_subscriber_id'] );
199 if ( $subscriber_id ) {
200 $tags = $api->get_subscriber_tags( $subscriber_id );
201 }
202 } elseif ( isset( $_COOKIE['ck_subscriber_id'] ) ) {
203 WP_ConvertKit::log( 'shortcode: cookie param found, calling API' );
204 // get cookie and check API for customer tags.
205 $subscriber_id = absint( $_GET['ck_subscriber_id'] );
206 if ( $subscriber_id ) {
207 $tags = $api->get_subscriber_tags( $subscriber_id );
208 }
209 } elseif ( isset( $_GET['ck_subscriber_id'] ) ) {
210 WP_ConvertKit::log( 'shortcode: URL param found, calling API' );
211 // get cookie and check API for customer tags.
212 $subscriber_id = absint( $_GET['ck_subscriber_id'] );
213 if ( $subscriber_id ) {
214 $tags = $api->get_subscriber_tags( $subscriber_id );
215 }
216 }
217
218 if ( isset( $tags[ $tag ] ) ) {
219 return apply_filters( 'wp_convertkit_shortcode_custom_content', $content, $attributes );
220 }
221 }
222 return null;
223 }
224
225 /**
226 * If the user views page with a cookie 'ck_subscriber_id' then check if tags need to be applied based on visit.
227 *
228 * @see https://app.convertkit.com/account/edit#email_settings
229 * @param $post WP_Post
230 */
231 public static function maybe_tag_subscriber( $post ) {
232
233 if ( isset( $_COOKIE['ck_subscriber_id'] ) && absint( $_COOKIE['ck_subscriber_id'] ) ) {
234 $subscriber_id = absint( $_COOKIE['ck_subscriber_id'] );
235 $api = WP_ConvertKit::get_api();
236 $meta = get_post_meta( $post->ID, '_wp_convertkit_post_meta', true );
237 $tag = isset( $meta['tag'] ) ? $meta['tag'] : 0;
238
239 // get subscriber's email to add tag with
240 $subscriber = $api->get_subscriber( $subscriber_id );
241
242 if ( $subscriber ) {
243 // tag subscriber
244 $args = array(
245 'email' => $subscriber->email_address,
246 );
247
248 if ( $tag ) {
249 $api->add_tag( $tag, $args );
250 WP_ConvertKit::log( 'Tagging ' . $subscriber->email_address . ' (' . $subscriber_id . ')' . ' with tag (' . $tag . ')' );
251 } else {
252 WP_ConvertKit::log( 'post_id (' . $post->ID . ') post does not have tags defined.' );
253 }
254 }
255 }
256
257 }
258
259 /**
260 * Runs after the customer has been tagged and subscriber_id has been retrieved
261 *
262 * @param $user_login
263 * @param $user
264 */
265 public function login_action( $user_login, $user ) {
266
267 $user_email = $user->user_email;
268
269 $api = WP_ConvertKit::get_api();
270 WP_ConvertKit::log( '----login_action for user: ' . $user->ID );
271
272 // Get subscriber id from email and cookie
273 $subscriber_id = $api->get_subscriber_id( $user_email );
274 if ( $subscriber_id ) {
275 update_user_meta( $user->ID, 'convertkit_subscriber_id', $subscriber_id );
276 setcookie( 'convertkit_subscriber', $subscriber_id, time() + ( 21 * DAY_IN_SECONDS ), '/' );
277 // get tags and add to user meta
278 $tags = $api->get_subscriber_tags( $subscriber_id );
279 update_user_meta( $user->ID, 'convertkit_tags', json_encode( $tags ) );
280 }
281
282 if ( isset( $_COOKIE['ck_visit'] ) ) {
283 $user_cookie = sanitize_text_field( $_COOKIE['ck_visit'] );
284 $this->associate_history_with_user( $user_cookie, $subscriber_id, $user->ID );
285 }
286
287 if ( $subscriber_id ) {
288 $this->process_history( $subscriber_id, $user->ID, $user->user_email );
289 }
290
291 $tags = $api->get_subscriber_tags( $subscriber_id );
292 update_user_meta( $user->ID, 'convertkit_tags', json_encode( $tags ) );
293
294 }
295
296 /**
297 * @param string $cookie
298 * @param int $subscriber_id
299 * @param int $user_id
300 */
301 public function associate_history_with_user( $cookie, $subscriber_id = 0, $user_id = 0 ) {
302
303 if ( $user_id ) {
304 $this->update( 'user_id', strval( $user_id ), 'visitor_cookie', $cookie );
305 }
306
307 if ( $subscriber_id ) {
308 $this->update( 'subscriber_id', strval( $subscriber_id ), 'visitor_cookie', $cookie );
309 }
310 }
311
312 /**
313 * Remove rows in the convertkit_user_history table older than the Expire setting.
314 */
315 public function remove_expired_rows() {
316
317 $expire_months = isset( $this->options['expire'] ) ? absint( $this->options['expire'] ) : 4 ;
318 $expire_range = apply_filters( 'convertkit_user_history_expire', $expire_months );
319 $expire_date = date( 'Y-m-d H:i:s', strtotime( '-' . $expire_range . ' months' ) );
320 $rows = $this->delete( 'date', $expire_date, '<' );
321
322 }
323
324 /**
325 * Get IP of visitor
326 *
327 * @see https://stackoverflow.com/questions/13646690/how-to-get-real-ip-from-visitor
328 * @return mixed
329 */
330 public function get_user_ip() {
331 $client = @$_SERVER['HTTP_CLIENT_IP'];
332 $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
333 $remote = $_SERVER['REMOTE_ADDR'];
334
335 if ( filter_var( $client, FILTER_VALIDATE_IP ) ) {
336 $ip = $client;
337 } elseif ( filter_var( $forward, FILTER_VALIDATE_IP ) ) {
338 $ip = $forward;
339 } else {
340 $ip = $remote;
341 }
342
343 return $ip;
344 }
345
346 /**
347 * Process the rows collected in the history table
348 *
349 * @param int $subscriber_id
350 * @param int $user_id
351 * @param string $user_email
352 */
353 public function process_history( $subscriber_id = 0, $user_id = 0, $user_email ) {
354
355 // TODO this needs to work with batch processing for larger user history
356
357 $user_rows = array();
358 $sub_rows = array();
359
360 // get all rows
361 if ( $user_id ) {
362 $user_rows = $this->get( 'user_id', $user_id, '=' );
363 }
364 if ( $subscriber_id ) {
365 $sub_rows = $this->get( 'subscriber_id', $subscriber_id, '=' );
366 }
367
368 // get unique urls visited
369 $visits = array_merge( $user_rows, $sub_rows );
370 $urls = wp_list_pluck( $visits, 'url' );
371 $urls = array_unique( $urls );
372
373 // get post ids
374 $post_ids = $this->get_post_ids_from_url( $urls );
375
376 // for each matching post_id tag customer
377
378 $api = WP_ConvertKit::get_api(); // TODO remove when there is a general logger for plugin
379 $args = array(
380 'email' => $user_email,
381 );
382
383 foreach ( $post_ids as $post_id ) {
384 $meta = get_post_meta( $post_id, '_wp_convertkit_post_meta', true );
385 $tag = isset( $meta['tag'] ) ? $meta['tag'] : 0;
386 if ( $tag ) {
387 $api->add_tag( $tag, $args );
388 WP_ConvertKit::log( 'tagging user (' . $user_id . ')' . ' with tag (' . $tag . ')' );
389 } else {
390 WP_ConvertKit::log( 'post_id (' . $post_id . ') not found in user history' );
391 }
392 }
393
394 // delete all rows
395 $this->delete( 'user_id', $user_id, '=' );
396 $this->delete( 'subscriber_id', $subscriber_id, '=' );
397 }
398
399 /**
400 * Get post_id from a URL
401 *
402 * @param $urls
403 * @return array
404 */
405 public function get_post_ids_from_url( $urls ) {
406 $ids = array();
407
408 foreach ( $urls as $url ) {
409 $post_id = url_to_postid( $url );
410 if ( $post_id ) {
411 $ids[] = $post_id;
412 }
413 }
414
415 return $ids;
416 }
417
418 /**
419 * Database Helper functions
420 */
421
422 /**
423 * Insert table row
424 *
425 * @param $data
426 */
427 private function insert( $data ) {
428 global $wpdb;
429
430 do_action( 'ck_data_before_insert', $data );
431
432 $table_columns = array(
433 'visitor_cookie' => '%s',
434 'user_id' => '%d',
435 'url' => '%s',
436 'ip' => '%s',
437 'date' => '%s',
438 );
439
440 $wpdb->insert( $wpdb->prefix . $this->table, $data, $table_columns );
441
442 do_action( 'ck_data_after_insert', $data );
443
444 }
445
446 /**
447 * Get rows from the database
448 *
449 * @param $field
450 * @param $value
451 * @param $operator
452 *
453 * @return false|int
454 */
455 private function get( $field, $value, $operator ) {
456 global $wpdb;
457
458 $table_name = $wpdb->prefix . 'convertkit_user_history';
459 $sql = 'SELECT * from ' . $table_name . ' WHERE ' . $field . ' ' . $operator . ' \'' . $value . '\'';
460 $rows = $wpdb->get_results( $sql );
461
462 return $rows;
463 }
464
465 /**
466 * Update table row
467 *
468 * @param $column
469 * @param $value
470 * @param $compare
471 * @param $compare_value
472 *
473 * @return int
474 */
475 private function update( $column, $value, $compare, $compare_value ) {
476 global $wpdb;
477
478 $table_name = $wpdb->prefix . 'convertkit_user_history';
479 $data = array(
480 $column => $value,
481 );
482 $where = array(
483 $compare => $compare_value,
484 );
485
486 $rows = $wpdb->update( $table_name, $data, $where );
487
488 return $rows;
489 }
490
491 /**
492 * Delete table row
493 *
494 * @param string $column
495 * @param string $value
496 * @param string $operator
497 *
498 * @return false|int
499 */
500 private function delete( $column, $value, $operator ) {
501 global $wpdb;
502
503 $table_name = $wpdb->prefix . 'convertkit_user_history';
504 $sql = 'DELETE from ' . $table_name . ' WHERE ' . $column . ' ' . $operator . ' \'' . $value . '\'';
505 $rows = $wpdb->query( $sql );
506
507 return $rows;
508 }
509
510 /**
511 * Creates the table to track visits.
512 *
513 * @access public
514 *
515 * @see dbDelta()
516 */
517 static function create_table() {
518 global $wpdb;
519
520 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
521
522 $table_name = $wpdb->prefix . 'convertkit_user_history';
523 $sql = 'CREATE TABLE ' . $table_name . ' (
524 visit_id bigint(20) NOT NULL AUTO_INCREMENT,
525 visitor_cookie mediumtext NOT NULL,
526 user_id bigint(20) NOT NULL,
527 subscriber_id bigint(20) NOT NULL,
528 url mediumtext NOT NULL,
529 ip tinytext NOT NULL,
530 date datetime NOT NULL,
531 PRIMARY KEY (visit_id)
532 ) CHARACTER SET utf8 COLLATE utf8_general_ci;';
533
534 dbDelta( $sql );
535
536 update_option( 'convertkit_user_history_table' , '1.0.0' );
537 }
538
539 }
540
541 new ConvertKit_Custom_Content();
542