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

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