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

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