PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 1.6.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v1.6.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 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.3, at includes/class-convertkit-custom-content.php

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