HubSpot – Free Marketing Plugin for WordPress - Version 2.0.1

Version Description

(2014.09.01) =

Download this release

Release Info

Developer AndyGCook
Plugin Icon 128x128 HubSpot – Free Marketing Plugin for WordPress
Version 2.0.1
Comparing to
See all releases

Code changes from version 2.0.0 to 2.0.1

admin/inc/class-leadin-contact.php CHANGED
@@ -266,12 +266,12 @@ class LI_Contact {
266
  global $wpdb;
267
 
268
  $esp_power_ups = array(
269
- 'MailChimp' => 'mailchimp_list_sync',
270
- 'Constant Contact' => 'constant_contact_list_sync',
271
- 'AWeber' => 'aweber_list_sync',
272
- 'GetResponse' => 'getresponse_list_sync',
273
- 'MailPoet' => 'mailpoet_list_sync',
274
- 'Campaign Monitor' => 'campaign_monitor_list_sync'
275
  );
276
 
277
  $safe_tags = $tags_to_update = '';
@@ -337,7 +337,7 @@ class LI_Contact {
337
  if ( in_array($list['list_id'], $synced_lists) )
338
  continue;
339
 
340
- $power_up_global = 'leadin_' . $list['esp'] . '_list_sync' . '_wp';
341
  if ( array_key_exists($power_up_global, $GLOBALS) )
342
  {
343
  global ${$power_up_global};
@@ -351,29 +351,6 @@ class LI_Contact {
351
  array_push($synced_lists, $list['list_id']);
352
  }
353
  }
354
-
355
- /*else if ( $tag->tag_synced_lists && ! $update_tag && ! $tag->tag_relationship_deleted )
356
- {
357
- foreach ( unserialize($tag->tag_synced_lists) as $list )
358
- {
359
- // Skip removing contact form list if it has already happened or the contact was previoulsy synced
360
- if ( in_array($list['list_id'], $removed_lists) || in_array($list['list_id'], $synced_lists) )
361
- continue;
362
-
363
- $power_up_global = 'leadin_' . $list['esp'] . '_list_sync' . '_wp';
364
- if ( array_key_exists($power_up_global, $GLOBALS) )
365
- {
366
- global ${$power_up_global};
367
-
368
- if ( ! ${$power_up_global}->activated )
369
- continue;
370
-
371
- ${$power_up_global}->remove_contact_from_list($list['list_id'], $this->history->lead->lead_email);
372
- }
373
-
374
- array_push($synced_lists, $list['list_id']);
375
- }
376
- }*/
377
  }
378
 
379
  if ( $tags_to_update )
266
  global $wpdb;
267
 
268
  $esp_power_ups = array(
269
+ 'MailChimp' => 'mailchimp_connect',
270
+ 'Constant Contact' => 'constant_contact_connect',
271
+ 'AWeber' => 'aweber_connect',
272
+ 'GetResponse' => 'getresponse_connect',
273
+ 'MailPoet' => 'mailpoet_connect',
274
+ 'Campaign Monitor' => 'campaign_monitor_connect'
275
  );
276
 
277
  $safe_tags = $tags_to_update = '';
337
  if ( in_array($list['list_id'], $synced_lists) )
338
  continue;
339
 
340
+ $power_up_global = 'leadin_' . $list['esp'] . '_connect' . '_wp';
341
  if ( array_key_exists($power_up_global, $GLOBALS) )
342
  {
343
  global ${$power_up_global};
351
  array_push($synced_lists, $list['list_id']);
352
  }
353
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  }
355
 
356
  if ( $tags_to_update )
admin/inc/class-leadin-list-table.php CHANGED
@@ -253,26 +253,26 @@ class LI_List_Table extends WP_List_Table {
253
 
254
  $q = $wpdb->prepare("
255
  SELECT
256
- l.hashkey, l.lead_id,
257
  ( SELECT ltr.tag_id FROM $wpdb->li_tag_relationships ltr WHERE ltr.tag_id = %d AND ltr.contact_hashkey = l.hashkey GROUP BY ltr.contact_hashkey ) AS tag_set
258
  FROM
259
  $wpdb->li_leads l
260
  WHERE
261
  l.lead_id IN ( " . $ids_for_action . " ) AND l.lead_deleted = 0 GROUP BY l.lead_id", $tag_id);
262
 
263
- $hashes = $wpdb->get_results($q);
264
 
265
- $insert_values = '';
266
- $hashes_to_update = '';
267
 
268
- if ( count($hashes) )
269
  {
270
- foreach ( $hashes as $hash )
271
  {
272
- if ( $hash->tag_set === NULL )
273
- $insert_values .= '(' . $tag_id . ', "' . $hash->hashkey . '"),';
274
  else
275
- $hashes_to_update .= "'" . $hash->hashkey . "',";
276
  }
277
  }
278
 
@@ -284,19 +284,23 @@ class LI_List_Table extends WP_List_Table {
284
  $wpdb->query($q);
285
  }
286
 
287
- if ( $hashes_to_update )
288
  {
289
- // update the relationships for the contacts that exist already
290
- $q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 0 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($hashes_to_update, ',') . ") ", $tag_id);
291
  $wpdb->query($q);
292
  }
 
 
 
 
293
  }
294
  else
295
  {
296
- if ( $hashes_to_update )
297
  {
298
- // Update the existing tags only
299
- $q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($hashes_to_update, ',') . ") ", $tag_id);
300
  $wpdb->query($q);
301
  }
302
  }
@@ -390,7 +394,7 @@ class LI_List_Table extends WP_List_Table {
390
  $mysql_action_filter = ( $filtered_hashkeys ? " AND l.hashkey IN ( " . $filtered_hashkeys . " ) " : '' ); // If a filter action isn't set, use the filtered hashkeys if they exist, else, don't include the statement
391
 
392
  // There's a filter and leads are in it
393
- if ( ( isset($_GET['contact_type']) && $num_contacts ) || ! isset($_GET['contact_type']) )
394
  {
395
  $q = $wpdb->prepare("
396
  SELECT
@@ -438,7 +442,7 @@ class LI_List_Table extends WP_List_Table {
438
  $lead_array = array(
439
  'ID' => $lead->lead_id,
440
  'hashkey' => $lead->hashkey,
441
- 'email' => sprintf('<a href="?page=%s&action=%s&lead=%s">' . "<img class='pull-left leadin-contact-avatar leadin-dynamic-avatar_" . substr($lead->lead_id, -1) . "' src='https://app.getsignals.com/avatar/image/?emails=" . $lead->lead_email . "' width='35' height='35'/> " . '</a>', $_REQUEST['page'], 'view', $lead->lead_id) . sprintf('<a href="?page=%s&action=%s&lead=%s"><b>' . $lead->lead_email . '</b></a>', $_REQUEST['page'], 'view', $lead->lead_id),
442
  'visits' => ( !isset($lead->visits) ? 1 : $lead->visits ),
443
  'submissions' => $lead->lead_form_submissions,
444
  'pageviews' => $lead->lead_pageviews,
@@ -513,7 +517,7 @@ class LI_List_Table extends WP_List_Table {
513
  {
514
  global $wpdb;
515
 
516
- $q = $wpdb->prepare("
517
  SELECT
518
  lt.tag_text, lt.tag_slug, lt.tag_synced_lists, lt.tag_form_selectors, lt.tag_order, lt.tag_id,
519
  ( SELECT COUNT(DISTINCT contact_hashkey) FROM $wpdb->li_tag_relationships, $wpdb->li_leads WHERE tag_id = lt.tag_id AND tag_relationship_deleted = 0 AND contact_hashkey != '' AND $wpdb->li_leads.hashkey = $wpdb->li_tag_relationships.contact_hashkey GROUP BY tag_id ) AS tag_count
@@ -521,7 +525,7 @@ class LI_List_Table extends WP_List_Table {
521
  $wpdb->li_tags lt
522
  WHERE
523
  lt.tag_deleted = 0
524
- ORDER BY lt.tag_order ASC", "");
525
 
526
  return $wpdb->get_results($q);
527
  }
@@ -532,11 +536,16 @@ class LI_List_Table extends WP_List_Table {
532
  function views ()
533
  {
534
  $this->tags = stripslashes_deep($this->get_tags());
 
535
  $current = ( !empty($_GET['contact_type']) ? html_entity_decode($_GET['contact_type']) : 'all' );
536
  $all_params = array( 'contact_type', 's', 'paged', '_wpnonce', '_wpreferrer', '_wp_http_referer', 'action', 'action2', 'filter_form', 'filter_action', 'filter_content', 'contact');
 
537
  $all_url = remove_query_arg($all_params);
 
538
  $this->total_contacts = $this->get_total_contacts();
539
 
 
 
540
  echo "<ul class='leadin-contacts__type-picker'>";
541
  echo "<li><a href='$all_url' class='" . ( $current == 'all' ? 'current' :'' ) . "'><span class='icon-user'></span>" . $this->total_contacts . " Total</a></li>";
542
  echo "</ul>";
253
 
254
  $q = $wpdb->prepare("
255
  SELECT
256
+ l.hashkey, l.lead_email,
257
  ( SELECT ltr.tag_id FROM $wpdb->li_tag_relationships ltr WHERE ltr.tag_id = %d AND ltr.contact_hashkey = l.hashkey GROUP BY ltr.contact_hashkey ) AS tag_set
258
  FROM
259
  $wpdb->li_leads l
260
  WHERE
261
  l.lead_id IN ( " . $ids_for_action . " ) AND l.lead_deleted = 0 GROUP BY l.lead_id", $tag_id);
262
 
263
+ $contacts = $wpdb->get_results($q);
264
 
265
+ $insert_values = '';
266
+ $contacts_to_update = '';
267
 
268
+ if ( count($contacts) )
269
  {
270
+ foreach ( $contacts as $contact )
271
  {
272
+ if ( $contact->tag_set === NULL )
273
+ $insert_values .= '(' . $tag_id . ', "' . $contact->hashkey . '"),';
274
  else
275
+ $contacts_to_update .= "'" . $contact->hashkey . "',";
276
  }
277
  }
278
 
284
  $wpdb->query($q);
285
  }
286
 
287
+ if ( $contacts_to_update )
288
  {
289
+ // update the relationships for the contacts that exist already making sure to set all the tag_relationship_deleted = 0
290
+ $q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 0 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($contacts_to_update, ',') . ") ", $tag_id);
291
  $wpdb->query($q);
292
  }
293
+
294
+ // Bulk push all the email addresses for the tag to the MailChimp API
295
+ $tagger = new LI_Tag_Editor($tag_id);
296
+ $tagger->push_contacts_to_tagged_list($tag_id);
297
  }
298
  else
299
  {
300
+ if ( $contacts_to_update )
301
  {
302
+ // "Delete" the existing tags only
303
+ $q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($contacts_to_update, ',') . ") ", $tag_id);
304
  $wpdb->query($q);
305
  }
306
  }
394
  $mysql_action_filter = ( $filtered_hashkeys ? " AND l.hashkey IN ( " . $filtered_hashkeys . " ) " : '' ); // If a filter action isn't set, use the filtered hashkeys if they exist, else, don't include the statement
395
 
396
  // There's a filter and leads are in it
397
+ if ( ( isset($_GET['contact_type']) && ( $num_contacts || ! $_GET['contact_type'] ) ) || ! isset($_GET['contact_type']) )
398
  {
399
  $q = $wpdb->prepare("
400
  SELECT
442
  $lead_array = array(
443
  'ID' => $lead->lead_id,
444
  'hashkey' => $lead->hashkey,
445
+ 'email' => sprintf('<a href="?page=%s&action=%s&lead=%s">' . "<img class='pull-left leadin-contact-avatar leadin-dynamic-avatar_" . substr($lead->lead_id, -1) . "' src='https://api.hubapi.com/socialintel/v1/avatars?email=" . $lead->lead_email . "' width='35' height='35'/> " . '</a>', $_REQUEST['page'], 'view', $lead->lead_id) . sprintf('<a href="?page=%s&action=%s&lead=%s"><b>' . $lead->lead_email . '</b></a>', $_REQUEST['page'], 'view', $lead->lead_id),
446
  'visits' => ( !isset($lead->visits) ? 1 : $lead->visits ),
447
  'submissions' => $lead->lead_form_submissions,
448
  'pageviews' => $lead->lead_pageviews,
517
  {
518
  global $wpdb;
519
 
520
+ $q = "
521
  SELECT
522
  lt.tag_text, lt.tag_slug, lt.tag_synced_lists, lt.tag_form_selectors, lt.tag_order, lt.tag_id,
523
  ( SELECT COUNT(DISTINCT contact_hashkey) FROM $wpdb->li_tag_relationships, $wpdb->li_leads WHERE tag_id = lt.tag_id AND tag_relationship_deleted = 0 AND contact_hashkey != '' AND $wpdb->li_leads.hashkey = $wpdb->li_tag_relationships.contact_hashkey GROUP BY tag_id ) AS tag_count
525
  $wpdb->li_tags lt
526
  WHERE
527
  lt.tag_deleted = 0
528
+ ORDER BY lt.tag_order ASC";
529
 
530
  return $wpdb->get_results($q);
531
  }
536
  function views ()
537
  {
538
  $this->tags = stripslashes_deep($this->get_tags());
539
+
540
  $current = ( !empty($_GET['contact_type']) ? html_entity_decode($_GET['contact_type']) : 'all' );
541
  $all_params = array( 'contact_type', 's', 'paged', '_wpnonce', '_wpreferrer', '_wp_http_referer', 'action', 'action2', 'filter_form', 'filter_action', 'filter_content', 'contact');
542
+
543
  $all_url = remove_query_arg($all_params);
544
+
545
  $this->total_contacts = $this->get_total_contacts();
546
 
547
+
548
+
549
  echo "<ul class='leadin-contacts__type-picker'>";
550
  echo "<li><a href='$all_url' class='" . ( $current == 'all' ? 'current' :'' ) . "'><span class='icon-user'></span>" . $this->total_contacts . " Total</a></li>";
551
  echo "</ul>";
admin/inc/class-leadin-tag-editor.php CHANGED
@@ -14,7 +14,7 @@ class LI_Tag_Editor {
14
  /**
15
  * Class constructor
16
  */
17
- function __construct ( $tag_id )
18
  {
19
  if ( $tag_id )
20
  $this->tag_id = $tag_id;
@@ -113,15 +113,20 @@ class LI_Tag_Editor {
113
  function save_tag ( $tag_id, $tag_text, $tag_form_selectors, $tag_synced_lists )
114
  {
115
  global $wpdb;
 
116
 
117
  $tag_slug = $this->generate_slug($tag_text, $tag_id);
118
 
 
 
119
  $q = $wpdb->prepare("
120
  UPDATE $wpdb->li_tags
121
  SET tag_text = %s, tag_slug = %s, tag_form_selectors = %s, tag_synced_lists = %s
122
  WHERE tag_id = %d", $tag_text, $tag_slug, $tag_form_selectors, $tag_synced_lists, $tag_id);
123
  $result = $wpdb->query($q);
124
 
 
 
125
  return $result;
126
  }
127
 
@@ -150,9 +155,10 @@ class LI_Tag_Editor {
150
  * Generates a slug based off a string. If slug exists, then appends -N until the slug is free
151
  *
152
  * @param string
 
153
  * @return string
154
  */
155
- function generate_slug ( $tag_text, $tag_id = FALSE )
156
  {
157
  global $wpdb;
158
 
@@ -180,5 +186,57 @@ class LI_Tag_Editor {
180
 
181
  return $tag_slug;
182
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  }
184
  ?>
14
  /**
15
  * Class constructor
16
  */
17
+ function __construct ( $tag_id = FALSE )
18
  {
19
  if ( $tag_id )
20
  $this->tag_id = $tag_id;
113
  function save_tag ( $tag_id, $tag_text, $tag_form_selectors, $tag_synced_lists )
114
  {
115
  global $wpdb;
116
+ global $leadin_mailchimp_connect_wp;
117
 
118
  $tag_slug = $this->generate_slug($tag_text, $tag_id);
119
 
120
+ $this->push_contacts_to_tagged_list($tag_id, $tag_synced_lists);
121
+
122
  $q = $wpdb->prepare("
123
  UPDATE $wpdb->li_tags
124
  SET tag_text = %s, tag_slug = %s, tag_form_selectors = %s, tag_synced_lists = %s
125
  WHERE tag_id = %d", $tag_text, $tag_slug, $tag_form_selectors, $tag_synced_lists, $tag_id);
126
  $result = $wpdb->query($q);
127
 
128
+ // Add a method to loop through all the lists here and
129
+
130
  return $result;
131
  }
132
 
155
  * Generates a slug based off a string. If slug exists, then appends -N until the slug is free
156
  *
157
  * @param string
158
+ * @param int
159
  * @return string
160
  */
161
+ function generate_slug ( $tag_text, $tag_id = 0 )
162
  {
163
  global $wpdb;
164
 
186
 
187
  return $tag_slug;
188
  }
189
+
190
+ /**
191
+ * Gets all the contacts in a list given a tag_id
192
+ *
193
+ * @param int
194
+ * @return object
195
+ */
196
+ function get_contacts_in_tagged_list ( $tag_id = 0 )
197
+ {
198
+ global $wpdb;
199
+ $q = $wpdb->prepare("SELECT contact_hashkey, lead_email FROM $wpdb->li_tag_relationships ltr, $wpdb->li_leads ll WHERE ltr.contact_hashkey = ll.hashkey AND ltr.tag_id = %d", $tag_id);
200
+ $contacts = $wpdb->get_results($q);
201
+ return $contacts;
202
+ }
203
+
204
+ /**
205
+ * Gets all the contacts in a list given a tag_id
206
+ *
207
+ * @param int
208
+ * @param string serialized array
209
+ * @return object
210
+ */
211
+ function push_contacts_to_tagged_list ( $tag_id = 0, $tag_synced_lists = '' )
212
+ {
213
+ global $wpdb;
214
+
215
+ if ( ! $tag_synced_lists )
216
+ {
217
+ $this->get_tag_details($tag_id);
218
+ $tag_synced_lists = $this->details->tag_synced_lists;
219
+ }
220
+
221
+ $contacts = $this->get_contacts_in_tagged_list($tag_id);
222
+
223
+ if ( count($contacts) && $tag_synced_lists )
224
+ {
225
+ $synced_lists = unserialize($tag_synced_lists);
226
+
227
+ if ( count($synced_lists) )
228
+ {
229
+ foreach ( $synced_lists as $synced_list )
230
+ {
231
+ $power_up_slug = $synced_list['esp'] . '_connect'; // e.g leadin_mailchimp_connect_wp
232
+ if ( WPLeadIn::is_power_up_active($power_up_slug) )
233
+ {
234
+ global ${'leadin_' . $power_up_slug . '_wp'}; // e.g leadin_mailchimp_connect_wp
235
+ ${'leadin_' . $power_up_slug . '_wp'}->bulk_push_contact_to_list($synced_list['list_id'], $contacts);
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
241
  }
242
  ?>
admin/inc/class-stats-dashboard.php CHANGED
@@ -125,6 +125,7 @@ class LI_StatsDashboard {
125
  FROM
126
  $wpdb->li_leads ll, $wpdb->li_pageviews lpv
127
  WHERE
 
128
  pageview_date >= CURRENT_DATE() AND
129
  ll.hashkey = lpv.lead_hashkey AND
130
  pageview_deleted = 0 AND lead_email != '' AND lead_deleted = 0 ";
@@ -162,7 +163,7 @@ class LI_StatsDashboard {
162
  $wpdb->li_leads
163
  WHERE
164
  lead_date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() AND lead_email != ''";
165
-
166
  $contacts = $wpdb->get_results($q);
167
 
168
  foreach ( $contacts as $contact )
@@ -204,10 +205,12 @@ class LI_StatsDashboard {
204
  {
205
  if ( $source )
206
  {
207
- if ( strstr(urldecode($source), 'utm_medium=cpc') || strstr(urldecode($source), 'utm_medium=ppc') )
 
 
208
  return 'paid';
209
 
210
- if ( strstr($source, 'utm_') )
211
  {
212
  $url = $source;
213
  $url_parts = parse_url($url);
@@ -230,7 +233,7 @@ class LI_StatsDashboard {
230
 
231
  if ( isset($path_parts['utm_source']) )
232
  {
233
- if ( strstr($path_parts['utm_source'], 'email') )
234
  return 'email';
235
  }
236
  }
125
  FROM
126
  $wpdb->li_leads ll, $wpdb->li_pageviews lpv
127
  WHERE
128
+ ll.lead_date < CURRENT_DATE() AND
129
  pageview_date >= CURRENT_DATE() AND
130
  ll.hashkey = lpv.lead_hashkey AND
131
  pageview_deleted = 0 AND lead_email != '' AND lead_deleted = 0 ";
163
  $wpdb->li_leads
164
  WHERE
165
  lead_date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() AND lead_email != ''";
166
+
167
  $contacts = $wpdb->get_results($q);
168
 
169
  foreach ( $contacts as $contact )
205
  {
206
  if ( $source )
207
  {
208
+ $decoded_source = urldecode($source);
209
+
210
+ if ( stristr($decoded_source, 'utm_medium=cpc') || stristr($decoded_source, 'utm_medium=ppc') || stristr($decoded_source, 'aclk') || stristr($decoded_source, 'gclid') )
211
  return 'paid';
212
 
213
+ if ( stristr($source, 'utm_') )
214
  {
215
  $url = $source;
216
  $url_parts = parse_url($url);
233
 
234
  if ( isset($path_parts['utm_source']) )
235
  {
236
+ if ( stristr($path_parts['utm_source'], 'email') )
237
  return 'email';
238
  }
239
  }
admin/leadin-admin.php CHANGED
@@ -59,22 +59,120 @@ class WPLeadInAdmin {
59
  // Hooks & Filters
60
  //=============================================
61
 
 
 
 
 
 
 
62
  $this->admin_power_ups = $power_ups;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- if( is_admin() )
 
 
 
 
 
 
 
65
  {
66
- add_action('admin_menu', array(&$this, 'leadin_add_menu_items'));
67
- add_action('admin_init', array(&$this, 'leadin_build_settings_page'));
68
- add_action('admin_print_styles', array(&$this, 'add_leadin_admin_styles'));
69
- add_action('add_meta_boxes', array(&$this, 'add_li_analytics_meta_box' ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- if ( isset($_GET['page']) && $_GET['page'] == 'leadin_stats' )
 
 
72
  {
73
- add_action('admin_footer', array($this, 'build_contacts_chart'));
 
74
  }
 
 
 
 
 
 
 
 
 
75
  }
76
 
77
- //print_r($_POST);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
 
80
  //=============================================
@@ -86,6 +184,8 @@ class WPLeadInAdmin {
86
  */
87
  function leadin_add_menu_items ()
88
  {
 
 
89
  global $submenu;
90
  global $wp_version;
91
 
@@ -112,9 +212,11 @@ class WPLeadInAdmin {
112
  if ( !isset($_GET['page']) || $_GET['page'] != 'leadin_settings' )
113
  {
114
  $options = get_option('leadin_options');
115
- if ( !isset($options['ignore_settings_popup']) || !$options['ignore_settings_popup'] )
116
- $li_pointers = new LI_Pointers();
117
  }
 
 
118
  }
119
 
120
  //=============================================
@@ -129,10 +231,10 @@ class WPLeadInAdmin {
129
  */
130
  function leadin_plugin_settings_link ( $links )
131
  {
132
- $url = get_admin_url() . 'admin.php?page=leadin_settings';
133
- $settings_link = '<a href="' . $url . '">Settings</a>';
134
- array_unshift($links, $settings_link);
135
- return $links;
136
  }
137
 
138
  /**
@@ -142,7 +244,7 @@ class WPLeadInAdmin {
142
  {
143
  global $wp_version;
144
  $this->stats_dashboard = new LI_StatsDashboard();
145
-
146
  leadin_track_plugin_activity("Loaded Stats Page");
147
 
148
  if ( !current_user_can( 'manage_categories' ) )
@@ -229,7 +331,7 @@ class WPLeadInAdmin {
229
  {
230
  $new_contacts_postbox .= '<tr>';
231
  $new_contacts_postbox .= '<td class="">';
232
- $new_contacts_postbox .= '<a href="?page=leadin_contacts&action=view&lead=' . $contact->lead_id . '&stats_dashboard=1"><img class="lazy pull-left leadin-contact-avatar leadin-dynamic-avatar_' . substr($contact->lead_id, -1) .'" src="https://app.getsignals.com/avatar/image/?emails=' . $contact->lead_email . '" width="35" height="35"><b>' . $contact->lead_email . '</b></a>';
233
  $new_contacts_postbox .= '</td>';
234
  $new_contacts_postbox .= '<td class="">' . $contact->pageviews . '</td>';
235
  $new_contacts_postbox .= '<td class="">' . $this->stats_dashboard->print_readable_source($this->stats_dashboard->check_lead_source($contact->lead_source)) . '</td>';
@@ -264,7 +366,7 @@ class WPLeadInAdmin {
264
  {
265
  $returning_contacts_postbox .= '<tr>';
266
  $returning_contacts_postbox .= '<td class="">';
267
- $returning_contacts_postbox .= '<a href="?page=leadin_contacts&action=view&lead=' . $contact->lead_id . '&stats_dashboard=1"><img class="lazy pull-left leadin-contact-avatar leadin-dynamic-avatar_' . substr($contact->lead_id, -1) .'" src="https://app.getsignals.com/avatar/image/?emails=' . $contact->lead_email . '" width="35" height="35"><b>' . $contact->lead_email . '</b></a>';
268
  $returning_contacts_postbox .= '</td>';
269
  $returning_contacts_postbox .= '<td class="">' . $contact->pageviews . '</td>';
270
  $returning_contacts_postbox .= '<td class="">' . $this->stats_dashboard->print_readable_source($this->stats_dashboard->check_lead_source($contact->lead_source)) . '</td>';
@@ -377,12 +479,15 @@ class WPLeadInAdmin {
377
  {
378
  // Hacky solution to solve the Settings API overwriting the default values
379
  $options = get_option('leadin_options');
380
- $li_installed = ( $options['li_installed'] ? $options['li_installed'] : 1 );
381
- $li_db_version = ( $options['li_db_version'] ? $options['li_db_version'] : LEADIN_DB_VERSION );
382
- $ignore_settings_popup = ( $options['ignore_settings_popup'] ? $options['ignore_settings_popup'] : 0 );
383
- $onboarding_complete = ( $options['onboarding_complete'] ? $options['onboarding_complete'] : 0 );
384
- $data_recovered = ( $options['data_recovered'] ? $options['data_recovered'] : 0 );
385
- $delete_flags_fixed = ( $options['delete_flags_fixed'] ? $options['delete_flags_fixed'] : 0 );
 
 
 
386
 
387
  printf(
388
  '<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
@@ -413,6 +518,11 @@ class WPLeadInAdmin {
413
  '<input id="delete_flags_fixed" type="hidden" name="leadin_options[delete_flags_fixed]" value="%d"/>',
414
  $delete_flags_fixed
415
  );
 
 
 
 
 
416
  }
417
 
418
  function tracking_code_installed_message ( )
@@ -538,6 +648,18 @@ class WPLeadInAdmin {
538
  if( isset( $input['ignore_settings_popup'] ) )
539
  $new_input['ignore_settings_popup'] = $input['ignore_settings_popup'];
540
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  if( isset( $input['beta_tester'] ) )
542
  {
543
  $new_input['beta_tester'] = sanitize_text_field($input['beta_tester']);
@@ -796,88 +918,6 @@ class WPLeadInAdmin {
796
  <?php
797
  }
798
 
799
- /**
800
- * Adds the analytics meta box in the post editor
801
- */
802
- function add_li_analytics_meta_box ()
803
- {
804
- global $post;
805
- if ( ! in_array(get_post_status($post->ID), array('publish', 'private')) )
806
- return false;
807
-
808
- $post_types = get_post_types( array( 'public' => true ) );
809
-
810
- $permalink = get_permalink($post->ID);
811
- $this->li_viewers = new LI_Viewers();
812
- $this->li_viewers->get_identified_viewers($permalink);
813
- $this->li_viewers->get_submissions($permalink);
814
-
815
- if ( is_array( $post_types ) && $post_types !== array() ) {
816
- foreach ( $post_types as $post_type ) {
817
- add_meta_box( 'li_analytics-meta', 'LeadIn Analytics', array( $this, 'li_analytics_meta_box' ), $post_type, 'normal', 'high');
818
- }
819
- }
820
- }
821
-
822
- /**
823
- * Output the LeadIn Analytics meta box
824
- */
825
- function li_analytics_meta_box ()
826
- {
827
- global $post;
828
- $view_count = 0;
829
- $submission_count = 0;
830
- $max_faces = 10;
831
- ?>
832
- <table class="form-table"><tbody>
833
- <tr>
834
- <th scope="row">
835
- <?php echo count($this->li_viewers->viewers) . ' ' . ( count($this->li_viewers->viewers) != 1 ? 'identified viewers:' : 'identified viewer:' ); ?>
836
- </th>
837
- <td>
838
- <?php
839
- if ( count($this->li_viewers->viewers) )
840
- {
841
- foreach ( $this->li_viewers->viewers as $viewer )
842
- {
843
- $view_count++;
844
- $contact_view_url = get_bloginfo('wpurl') . "/wp-admin/admin.php?page=leadin_contacts&action=view&lead=" . $viewer->lead_id . '&post_id=' . $post->ID;
845
- echo '<a class="li-analytics-link ' . ( $view_count > $max_faces ? 'hidden_face' : '' ) . '" href="' . $contact_view_url . '" title="' . $viewer->lead_email . '"><img height="35px" width="35px" data-original="https://app.getsignals.com/avatar/image/?emails=' . $viewer->lead_email . '" class="lazy li-analytics__face leadin-dynamic-avatar_' . substr($viewer->lead_id, -1) . '"/></a>';
846
- }
847
- }
848
-
849
- if ( $view_count > $max_faces )
850
- {
851
- echo '<div class="show-all-faces-container"><a class="show_all_faces" href="javascript:void(0)">+ Show ' . ( $view_count - $max_faces ) . ' more</a></div>';
852
- }
853
- ?>
854
- </td>
855
- </tr>
856
- <tr>
857
- <th scope="row">
858
- <?php echo count($this->li_viewers->submissions) . ' ' . ( count($this->li_viewers->submissions) != 1 ? 'form submissions:' : 'form submission:' ); ?>
859
- </th>
860
- <td>
861
- <?php
862
- foreach ( $this->li_viewers->submissions as $submission )
863
- {
864
- $submission_count++;
865
- $contact_view_url = get_bloginfo('wpurl') . "/wp-admin/admin.php?page=leadin_contacts&action=view&lead=" . $submission->lead_id . '&post_id=' . $post->ID;
866
- echo '<a class="li-analytics-link ' . ( $submission_count > $max_faces ? 'hidden_face' : '' ) . '" href="' . $contact_view_url . '" title="' . $submission->lead_email . '"><img height="35px" width="35px" data-original="https://app.getsignals.com/avatar/image/?emails=' . $submission->lead_email . '" class="lazy li-analytics__face leadin-dynamic-avatar_' . substr($submission->lead_id, -1) . '"/></a>';
867
- }
868
-
869
- if ( $submission_count > $max_faces )
870
- {
871
- echo '<div class="show-all-faces-container"><a class="show_all_faces" href="javascript:void(0)">+ Show ' . ( $submission_count - $max_faces ) . ' more</a></div>';
872
- }
873
- ?>
874
- </td>
875
- </tr>
876
- </tbody></table>
877
- <?php
878
- }
879
-
880
-
881
  function build_contacts_chart ( )
882
  {
883
  ?>
@@ -1068,7 +1108,7 @@ class WPLeadInAdmin {
1068
 
1069
  </script>
1070
  <?php
1071
- }
1072
  }
1073
 
1074
  ?>
59
  // Hooks & Filters
60
  //=============================================
61
 
62
+ $options = get_option('leadin_options');
63
+
64
+ // If the plugin version matches the latest version escape the update function
65
+ //if ( $options['leadin_version'] != LEADIN_PLUGIN_VERSION )
66
+ self::leadin_update_check();
67
+
68
  $this->admin_power_ups = $power_ups;
69
+
70
+ add_action('admin_menu', array(&$this, 'leadin_add_menu_items'));
71
+ add_action('admin_init', array(&$this, 'leadin_build_settings_page'));
72
+ add_action('admin_print_styles', array(&$this, 'add_leadin_admin_styles'));
73
+ add_filter('plugin_action_links_' . 'leadin/leadin.php', array($this, 'leadin_plugin_settings_link'));
74
+
75
+ if ( isset($_GET['page']) && $_GET['page'] == 'leadin_stats' )
76
+ {
77
+ add_action('admin_footer', array($this, 'build_contacts_chart'));
78
+ }
79
+
80
+ if ( isset($options['beta_tester']) && $options['beta_tester'] )
81
+ $li_wp_updater = new WPLeadInUpdater();
82
+
83
+ //print_r($_POST);
84
+ }
85
 
86
+ function leadin_update_check ( )
87
+ {
88
+ $options = get_option('leadin_options');
89
+
90
+ // 0.5.1 upgrade - Create active power-ups option if it doesn't exist
91
+ $leadin_active_power_ups = get_option('leadin_active_power_ups');
92
+
93
+ if ( !$leadin_active_power_ups )
94
  {
95
+ $auto_activate = array(
96
+ 'contacts',
97
+ 'beta_program'
98
+ );
99
+
100
+ update_option('leadin_active_power_ups', serialize($auto_activate));
101
+ }
102
+ else
103
+ {
104
+ // 0.9.2 upgrade - set beta program power-up to auto-activate
105
+ $activated_power_ups = unserialize($leadin_active_power_ups);
106
+
107
+ // 0.9.3 bug fix for duplicate beta_program values being stored in the active power-ups array
108
+ if ( !in_array('beta_program', $activated_power_ups) )
109
+ {
110
+ $activated_power_ups[] = 'beta_program';
111
+ update_option('leadin_active_power_ups', serialize($activated_power_ups));
112
+ }
113
+ else
114
+ {
115
+ $tmp = array_count_values($activated_power_ups);
116
+ $count = $tmp['beta_program'];
117
+
118
+ if ( $count > 1 )
119
+ {
120
+ $activated_power_ups = array_unique($activated_power_ups);
121
+ update_option('leadin_active_power_ups', serialize($activated_power_ups));
122
+ }
123
+ }
124
 
125
+ // 2.0.1 upgrade - [plugin_slug]_list_sync changed to [plugin_slug]_connect
126
+ $mailchimp_list_sync_key = array_search('mailchimp_list_sync', $activated_power_ups);
127
+ if ( $mailchimp_list_sync_key !== FALSE )
128
  {
129
+ unset($activated_power_ups[$mailchimp_list_sync_key]);
130
+ $activated_power_ups[] = 'mailchimp_connect';
131
  }
132
+
133
+ $constant_contact_list_sync_key = array_search('constant_contact_list_sync', $activated_power_ups);
134
+ if ( $constant_contact_list_sync_key !== FALSE )
135
+ {
136
+ unset($activated_power_ups[$constant_contact_list_sync_key]);
137
+ $activated_power_ups[] = 'constant_contact_connect';
138
+ }
139
+
140
+ update_option('leadin_active_power_ups', serialize($activated_power_ups));
141
  }
142
 
143
+ // 0.7.2 bug fix - data recovery algorithm for deleted contacts
144
+ if ( ! isset($options['data_recovered']) )
145
+ {
146
+ leadin_recover_contact_data();
147
+ }
148
+
149
+ // Set the database version if it doesn't exist
150
+ if ( isset($options['li_db_version']) )
151
+ {
152
+ if ( $options['li_db_version'] != LEADIN_DB_VERSION )
153
+ {
154
+ leadin_db_install();
155
+
156
+ // 2.0.0 upgrade
157
+ if ( ! isset($options['converted_to_tags']) )
158
+ {
159
+ leadin_convert_statuses_to_tags();
160
+ }
161
+ }
162
+ }
163
+ else
164
+ {
165
+ leadin_db_install();
166
+ }
167
+
168
+ // 0.8.3 bug fix - bug fix for duplicated contacts that should be merged
169
+ if ( ! isset($options['delete_flags_fixed']) )
170
+ {
171
+ leadin_delete_flag_fix();
172
+ }
173
+
174
+ // Set the plugin version
175
+ leadin_update_option('leadin_options', 'leadin_version', LEADIN_PLUGIN_VERSION);
176
  }
177
 
178
  //=============================================
184
  */
185
  function leadin_add_menu_items ()
186
  {
187
+ $options = get_option('leadin_options');
188
+
189
  global $submenu;
190
  global $wp_version;
191
 
212
  if ( !isset($_GET['page']) || $_GET['page'] != 'leadin_settings' )
213
  {
214
  $options = get_option('leadin_options');
215
+ //if ( !isset($options['ignore_settings_popup']) || !$options['ignore_settings_popup'] )
216
+
217
  }
218
+
219
+ $li_pointers = new LI_Pointers();
220
  }
221
 
222
  //=============================================
231
  */
232
  function leadin_plugin_settings_link ( $links )
233
  {
234
+ $url = get_admin_url() . 'admin.php?page=leadin_settings';
235
+ $settings_link = '<a href="' . $url . '">Settings</a>';
236
+ array_unshift($links, $settings_link);
237
+ return $links;
238
  }
239
 
240
  /**
244
  {
245
  global $wp_version;
246
  $this->stats_dashboard = new LI_StatsDashboard();
247
+
248
  leadin_track_plugin_activity("Loaded Stats Page");
249
 
250
  if ( !current_user_can( 'manage_categories' ) )
331
  {
332
  $new_contacts_postbox .= '<tr>';
333
  $new_contacts_postbox .= '<td class="">';
334
+ $new_contacts_postbox .= '<a href="?page=leadin_contacts&action=view&lead=' . $contact->lead_id . '&stats_dashboard=1"><img class="lazy pull-left leadin-contact-avatar leadin-dynamic-avatar_' . substr($contact->lead_id, -1) .'" src="https://api.hubapi.com/socialintel/v1/avatars?email=' . $contact->lead_email . '" width="35" height="35"><b>' . $contact->lead_email . '</b></a>';
335
  $new_contacts_postbox .= '</td>';
336
  $new_contacts_postbox .= '<td class="">' . $contact->pageviews . '</td>';
337
  $new_contacts_postbox .= '<td class="">' . $this->stats_dashboard->print_readable_source($this->stats_dashboard->check_lead_source($contact->lead_source)) . '</td>';
366
  {
367
  $returning_contacts_postbox .= '<tr>';
368
  $returning_contacts_postbox .= '<td class="">';
369
+ $returning_contacts_postbox .= '<a href="?page=leadin_contacts&action=view&lead=' . $contact->lead_id . '&stats_dashboard=1"><img class="lazy pull-left leadin-contact-avatar leadin-dynamic-avatar_' . substr($contact->lead_id, -1) .'" src="https://api.hubapi.com/socialintel/v1/avatars?email=' . $contact->lead_email . '" width="35" height="35"><b>' . $contact->lead_email . '</b></a>';
370
  $returning_contacts_postbox .= '</td>';
371
  $returning_contacts_postbox .= '<td class="">' . $contact->pageviews . '</td>';
372
  $returning_contacts_postbox .= '<td class="">' . $this->stats_dashboard->print_readable_source($this->stats_dashboard->check_lead_source($contact->lead_source)) . '</td>';
479
  {
480
  // Hacky solution to solve the Settings API overwriting the default values
481
  $options = get_option('leadin_options');
482
+
483
+ $li_installed = ( isset($options['li_installed']) ? $options['li_installed'] : 1 );
484
+ $li_db_version = ( isset($options['li_db_version']) ? $options['li_db_version'] : LEADIN_DB_VERSION );
485
+ $ignore_settings_popup = ( isset($options['ignore_settings_popup']) ? $options['ignore_settings_popup'] : 0 );
486
+ $onboarding_complete = ( isset($options['onboarding_complete']) ? $options['onboarding_complete'] : 0 );
487
+ $data_recovered = ( isset($options['data_recovered']) ? $options['data_recovered'] : 0 );
488
+ $delete_flags_fixed = ( isset($options['delete_flags_fixed']) ? $options['delete_flags_fixed'] : 0 );
489
+ $converted_to_tags = ( isset($options['converted_to_tags']) ? $options['converted_to_tags'] : 0 );
490
+ $leadin_version = ( isset($options['leadin_version']) ? $options['leadin_version'] : LEADIN_PLUGIN_VERSION );
491
 
492
  printf(
493
  '<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
518
  '<input id="delete_flags_fixed" type="hidden" name="leadin_options[delete_flags_fixed]" value="%d"/>',
519
  $delete_flags_fixed
520
  );
521
+
522
+ printf(
523
+ '<input id="converted_to_tags" type="hidden" name="leadin_options[converted_to_tags]" value="%d"/>',
524
+ $converted_to_tags
525
+ );
526
  }
527
 
528
  function tracking_code_installed_message ( )
648
  if( isset( $input['ignore_settings_popup'] ) )
649
  $new_input['ignore_settings_popup'] = $input['ignore_settings_popup'];
650
 
651
+ if( isset( $input['data_recovered'] ) )
652
+ $new_input['data_recovered'] = $input['data_recovered'];
653
+
654
+ if( isset( $input['converted_to_tags'] ) )
655
+ $new_input['converted_to_tags'] = $input['converted_to_tags'];
656
+
657
+ if( isset( $input['delete_flags_fixed'] ) )
658
+ $new_input['delete_flags_fixed'] = $input['delete_flags_fixed'];
659
+
660
+ if( isset( $input['leadin_version'] ) )
661
+ $new_input['leadin_version'] = $input['leadin_version'];
662
+
663
  if( isset( $input['beta_tester'] ) )
664
  {
665
  $new_input['beta_tester'] = sanitize_text_field($input['beta_tester']);
918
  <?php
919
  }
920
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
  function build_contacts_chart ( )
922
  {
923
  ?>
1108
 
1109
  </script>
1110
  <?php
1111
+ }
1112
  }
1113
 
1114
  ?>
assets/js/build/leadin-tracking.js CHANGED
@@ -115,6 +115,7 @@ var page_title = jQuery(document).find("title").text();
115
  var page_url = window.location.href;
116
  var page_referrer = document.referrer;
117
  var form_saved = false;
 
118
 
119
  jQuery(document).ready( function ( $ ) {
120
 
@@ -194,7 +195,6 @@ function leadin_submit_form ( $form, $ )
194
  var lead_first_name = '';
195
  var lead_last_name = '';
196
  var lead_phone = '';
197
- var ignore_form = false;
198
  var form_selector_id = ( $form.attr('id') ? $form.attr('id') : '' );
199
  var form_selector_classes = ( $form.classes() ? $form.classes().join(',') : '' );
200
 
@@ -293,10 +293,11 @@ function leadin_submit_form ( $form, $ )
293
 
294
  var $label_text = $.trim($label.replaceArray(["(", ")", "required", "Required", "*", ":"], [""]));
295
 
296
- if ( $label_text.toLowerCase().indexOf('credit card') != -1 || $label_text.toLowerCase().indexOf('card number') != -1 )
297
- ignore_form = true;
298
 
299
- push_form_field($label_text, $value, form_fields);
 
300
 
301
  if ( $value.indexOf('@') != -1 && $value.indexOf('.') != -1 && !lead_email )
302
  lead_email = $value;
@@ -342,7 +343,8 @@ function leadin_submit_form ( $form, $ )
342
 
343
  var rgb_selected = ( !$("input:radio[name='" + radio_groups[i] + "']:checked").val() ) ? 'not selected' : $("input:radio[name='" + radio_groups[i] + "']:checked").val();
344
 
345
- push_form_field($rbg_label, rgb_selected, form_fields);
 
346
  }
347
 
348
  $this.find('select').each( function ( ) {
@@ -390,14 +392,20 @@ function leadin_submit_form ( $form, $ )
390
  select_value = $select.val();
391
  }
392
 
393
- push_form_field($select_label, select_value, form_fields);
 
394
  });
395
 
396
  $this.find('.li_used').removeClass('li_used'); // Clean up added classes
397
 
398
  // Save submission into database if email is present and form is not ignore, send LeadIn email, and submit form as usual
399
- if ( lead_email && ! ignore_form )
400
  {
 
 
 
 
 
401
  var submission_hash = Math.random().toString(36).slice(2);
402
  var hashkey = $.cookie("li_hash");
403
  var json_form_fields = JSON.stringify(form_fields);
@@ -565,6 +573,47 @@ function push_form_field ( label, value, form_fields )
565
  form_fields.push(field);
566
  }
567
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  String.prototype.replaceArray = function(find, replace) {
569
  var replaceString = this;
570
  for (var i = 0; i < find.length; i++) {
@@ -634,4 +683,8 @@ String.prototype.replaceArray = function(find, replace) {
634
  }
635
  return classes;
636
  };
637
- })(jQuery);
 
 
 
 
115
  var page_url = window.location.href;
116
  var page_referrer = document.referrer;
117
  var form_saved = false;
118
+ var ignore_form = false;
119
 
120
  jQuery(document).ready( function ( $ ) {
121
 
195
  var lead_first_name = '';
196
  var lead_last_name = '';
197
  var lead_phone = '';
 
198
  var form_selector_id = ( $form.attr('id') ? $form.attr('id') : '' );
199
  var form_selector_classes = ( $form.classes() ? $form.classes().join(',') : '' );
200
 
293
 
294
  var $label_text = $.trim($label.replaceArray(["(", ")", "required", "Required", "*", ":"], [""]));
295
 
296
+ /*if ( $label_text.toLowerCase().indexOf('credit card') != -1 || $label_text.toLowerCase().indexOf('card number') != -1 )
297
+ ignore_form = true;*/
298
 
299
+ if ( ! ignore_field($label_text, $value) )
300
+ push_form_field($label_text, $value, form_fields);
301
 
302
  if ( $value.indexOf('@') != -1 && $value.indexOf('.') != -1 && !lead_email )
303
  lead_email = $value;
343
 
344
  var rgb_selected = ( !$("input:radio[name='" + radio_groups[i] + "']:checked").val() ) ? 'not selected' : $("input:radio[name='" + radio_groups[i] + "']:checked").val();
345
 
346
+ if ( ! ignore_field($rbg_label, rgb_selected) )
347
+ push_form_field($rbg_label, rgb_selected, form_fields);
348
  }
349
 
350
  $this.find('select').each( function ( ) {
392
  select_value = $select.val();
393
  }
394
 
395
+ if ( ! ignore_field($select_label, select_value) )
396
+ push_form_field($select_label, select_value, form_fields);
397
  });
398
 
399
  $this.find('.li_used').removeClass('li_used'); // Clean up added classes
400
 
401
  // Save submission into database if email is present and form is not ignore, send LeadIn email, and submit form as usual
402
+ if ( lead_email )
403
  {
404
+ if ( ignore_form )
405
+ {
406
+ push_form_field('Credit card form submitted', 'Payment fields not collected for security', form_fields);
407
+ }
408
+
409
  var submission_hash = Math.random().toString(36).slice(2);
410
  var hashkey = $.cookie("li_hash");
411
  var json_form_fields = JSON.stringify(form_fields);
573
  form_fields.push(field);
574
  }
575
 
576
+ function ignore_field ( label, value )
577
+ {
578
+ var bool_ignore_field = false;
579
+
580
+ // Ignore any fields with labels that indicate a credit card field
581
+ if ( label.toLowerCase().indexOf('credit card') != -1 || label.toLowerCase().indexOf('card number') != -1 )
582
+ bool_ignore_field = true;
583
+
584
+ if ( label.toLowerCase().indexOf('expiration') != -1 || label.toLowerCase().indexOf('expiry') != -1)
585
+ bool_ignore_field = true;
586
+
587
+ if ( label.toLowerCase().indexOf('month') != -1 || label.toLowerCase().indexOf('mm') != -1 || label.toLowerCase().indexOf('yy') != -1 || label.toLowerCase().indexOf('year') != -1 )
588
+ bool_ignore_field = true;
589
+
590
+ if ( label.toLowerCase().indexOf('cvv') != -1 || label.toLowerCase().indexOf('cvc') != -1 || label.toLowerCase().indexOf('secure code') != -1 || label.toLowerCase().indexOf('security code') != -1 )
591
+ bool_ignore_field = true;
592
+
593
+ if ( value.toLowerCase().indexOf('visa') != -1 || value.toLowerCase().indexOf('mastercard') != -1 || value.toLowerCase().indexOf('american express') != -1 || value.toLowerCase().indexOf('amex') != -1 || value.toLowerCase().indexOf('discover') != -1 )
594
+ bool_ignore_field = true;
595
+
596
+ // Check if value has integers, strip out spaces, then ignore anything with a credit card length (>16) or an expiration/cvv length (<5)
597
+ var int_regex = new RegExp("/^[0-9]+$/");
598
+ if ( int_regex.test(value) )
599
+ {
600
+ var value_no_spaces = value.replace(' ', '');
601
+
602
+ if ( isInt(value_no_spaces) && value_no_spaces.length >= 16 )
603
+ bool_ignore_field = true;
604
+ }
605
+
606
+ if ( bool_ignore_field )
607
+ {
608
+ if ( ! ignore_form )
609
+ ignore_form = true;
610
+
611
+ return true;
612
+ }
613
+ else
614
+ return false;
615
+ }
616
+
617
  String.prototype.replaceArray = function(find, replace) {
618
  var replaceString = this;
619
  for (var i = 0; i < find.length; i++) {
683
  }
684
  return classes;
685
  };
686
+ })(jQuery);
687
+
688
+ function isInt ( n ) {
689
+ return typeof n== "number" && isFinite(n) && n%1===0;
690
+ }
assets/js/build/leadin-tracking.min.js CHANGED
@@ -1 +1 @@
1
- function leadin_submit_form($form,$){var $this=$form,form_fields=[],lead_email="",lead_first_name="",lead_last_name="",lead_phone="",ignore_form=!1,form_selector_id=$form.attr("id")?$form.attr("id"):"",form_selector_classes=$form.classes()?$form.classes().join(","):"";$this.find('input[type!="submit"], textarea').not('input[type="hidden"], input[type="radio"], input[type="password"]').each(function(){var $element=$(this),$value=$element.val();if(!$element.is(":visible"))return!0;var $label=$("label[for='"+$element.attr("id")+"']").text();0==$label.length&&($label=$element.prev("label").not(".li_used").addClass("li_used").first().text(),$label.length||($label=$element.prevAll("b, strong, span").text())),0==$label.length&&($label=$element.next("label").not(".li_used").addClass("li_used").first().text(),$label.length||($label=$element.nextAll("b, strong, span").text())),0==$label.length&&($label=$element.parent().find("label, b, strong").not(".li_used").first().text()),0==$label.length&&$.contains($this,$element.parent().parent())&&($label=$element.parent().parent().find("label, b, strong").first().text()),0==$label.length&&($p=$element.closest("p").not(".li_used").addClass("li_used"),$p.length&&($label=$p.text(),$label=$.trim($label.replace($value,"")))),0==$label.length&&void 0!==$element.attr("placeholder")&&($label=$element.attr("placeholder").toString()),0==$label.length&&void 0!==$element.attr("name")&&($label=$element.attr("name").toString()),$element.is(":checkbox")&&($value=$element.is(":checked")?"Checked":"Not checked"),$value=$value.replace("C:\\fakepath\\","");var $label_text=$.trim($label.replaceArray(["(",")","required","Required","*",":"],[""]));(-1!=$label_text.toLowerCase().indexOf("credit card")||-1!=$label_text.toLowerCase().indexOf("card number"))&&(ignore_form=!0),push_form_field($label_text,$value,form_fields),-1==$value.indexOf("@")||-1==$value.indexOf(".")||lead_email||(lead_email=$value),"leadin-subscribe-fname"==$element.attr("id")&&(lead_first_name=$value),"leadin-subscribe-lname"==$element.attr("id")&&(lead_last_name=$value),"leadin-subscribe-phone"==$element.attr("id")&&(lead_phone=$value)});var radio_groups=[],rbg_label_values=[];$this.find(":radio").each(function(){-1==$.inArray(this.name,radio_groups)&&radio_groups.push(this.name),rbg_label_values.push($(this).val())});for(var i=0;i<radio_groups.length;i++){{var $rbg=$("input:radio[name='"+radio_groups[i]+"']");$("input:radio[name='"+radio_groups[i]+"']:checked").val()}$p=$this.find(".gfield").length?$rbg.closest(".gfield").not(".li_used").addClass("li_used"):$this.find(".frm_form_field").length?$rbg.closest(".frm_form_field").not(".li_used").addClass("li_used"):$rbg.closest("div, p").not(".li_used").addClass("li_used"),$p.length&&($rbg_label=$p.text(),$rbg_label=$.trim($rbg_label.replaceArray(rbg_label_values,[""]).replace($p.find(".gfield_description").text(),"")));var rgb_selected=$("input:radio[name='"+radio_groups[i]+"']:checked").val()?$("input:radio[name='"+radio_groups[i]+"']:checked").val():"not selected";push_form_field($rbg_label,rgb_selected,form_fields)}if($this.find("select").each(function(){var $select=$(this),$select_label=$("label[for='"+$select.attr("id")+"']").text();if(!$select_label.length){var select_values=[];$select.find("option").each(function(){-1==$.inArray($(this).val(),select_values)&&select_values.push($(this).val())}),$p=$select.closest("div, p").not(".li_used").addClass("li_used"),$p=$this.find(".gfield").length?$select.closest(".gfield").not(".li_used").addClass("li_used"):$select.closest("div, p").addClass("li_used"),$p.length&&($select_label=$p.text(),$select_label=$.trim($select_label.replaceArray(select_values,[""]).replace($p.find(".gfield_description").text(),"")))}var select_value="";if($select.val()instanceof Array){var select_vals=$select.val();for(i=0;i<select_vals.length;i++)select_value+=select_vals[i],i!=select_vals.length-1&&(select_value+=", ")}else select_value=$select.val();push_form_field($select_label,select_value,form_fields)}),$this.find(".li_used").removeClass("li_used"),lead_email&&!ignore_form){var submission_hash=Math.random().toString(36).slice(2),hashkey=$.cookie("li_hash"),json_form_fields=JSON.stringify(form_fields),form_submission={};form_submission={submission_hash:submission_hash,hashkey:hashkey,lead_email:lead_email,lead_first_name:lead_first_name,lead_last_name:lead_last_name,lead_phone:lead_phone,page_title:page_title,page_url:page_url,json_form_fields:json_form_fields,form_selector_id:form_selector_id,form_selector_classes:form_selector_classes},$.cookie("li_submission",JSON.stringify(form_submission),{path:"/",domain:""}),leadin_insert_form_submission(submission_hash,hashkey,page_title,page_url,json_form_fields,lead_email,lead_first_name,lead_last_name,lead_phone,form_selector_id,form_selector_classes,function(){$.removeCookie("li_submission",{path:"/",domain:""})})}else form_saved=!0}function leadin_check_merged_contact(hashkey){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_check_merged_contact",li_id:hashkey},success:function(data){var json_data=jQuery.parseJSON(data);json_data&&jQuery.cookie("li_hash",json_data,{path:"/",domain:""})},error:function(){}})}function leadin_check_visitor_status(hashkey,callback){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_check_visitor_status",li_id:hashkey},success:function(data){var json_data=jQuery.parseJSON(data);callback&&callback(json_data)},error:function(){}})}function leadin_log_pageview(hashkey,page_title,page_url,page_referrer,last_visit){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_log_pageview",li_id:hashkey,li_title:page_title,li_url:page_url,li_referrer:page_referrer,li_last_visit:last_visit},success:function(){},error:function(){}})}function leadin_insert_lead(hashkey,page_referrer){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_insert_lead",li_id:hashkey,li_referrer:page_referrer},success:function(){},error:function(){}})}function leadin_insert_form_submission(submission_haskey,hashkey,page_title,page_url,json_fields,lead_email,lead_first_name,lead_last_name,lead_phone,form_selector_id,form_selector_classes,Callback){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_insert_form_submission",li_submission_id:submission_haskey,li_id:hashkey,li_title:page_title,li_url:page_url,li_fields:json_fields,li_email:lead_email,li_first_name:lead_first_name,li_last_name:lead_last_name,li_phone:lead_phone,li_form_selector_id:form_selector_id,li_form_selector_classes:form_selector_classes},success:function(data){Callback&&Callback(data)},error:function(){}})}function push_form_field(label,value,form_fields){var field={label:label,value:value};form_fields.push(field)}!function(factory){"function"==typeof define&&define.amd?define(["jquery"],factory):factory(jQuery)}(function($){function encode(s){return config.raw?s:encodeURIComponent(s)}function decode(s){return config.raw?s:decodeURIComponent(s)}function stringifyCookieValue(value){return encode(config.json?JSON.stringify(value):String(value))}function parseCookieValue(s){0===s.indexOf('"')&&(s=s.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return s=decodeURIComponent(s.replace(pluses," ")),config.json?JSON.parse(s):s}catch(e){}}function read(s,converter){var value=config.raw?s:parseCookieValue(s);return $.isFunction(converter)?converter(value):value}var pluses=/\+/g,config=$.cookie=function(key,value,options){if(void 0!==value&&!$.isFunction(value)){if(options=$.extend({},config.defaults,options),"number"==typeof options.expires){var days=options.expires,t=options.expires=new Date;t.setDate(t.getDate()+days)}return document.cookie=[encode(key),"=",stringifyCookieValue(value),options.expires?"; expires="+options.expires.toUTCString():"",options.path?"; path="+options.path:"",options.domain?"; domain="+options.domain:"",options.secure?"; secure":""].join("")}for(var result=key?void 0:{},cookies=document.cookie?document.cookie.split("; "):[],i=0,l=cookies.length;l>i;i++){var parts=cookies[i].split("="),name=decode(parts.shift()),cookie=parts.join("=");if(key&&key===name){result=read(cookie,value);break}key||void 0===(cookie=read(cookie))||(result[name]=cookie)}return result};config.defaults={},$.removeCookie=function(key,options){return void 0===$.cookie(key)?!1:($.cookie(key,"",$.extend({},options,{expires:-1})),!$.cookie(key))}});var page_title=jQuery(document).find("title").text(),page_url=window.location.href,page_referrer=document.referrer,form_saved=!1;jQuery(document).ready(function($){var hashkey=$.cookie("li_hash"),li_submission_cookie=$.cookie("li_submission");if(li_submission_cookie){var submission_data=JSON.parse(li_submission_cookie);leadin_insert_form_submission(submission_data.submission_hash,submission_data.hashkey,submission_data.page_title,submission_data.page_url,submission_data.json_form_fields,submission_data.lead_email,submission_data.lead_first_name,submission_data.lead_last_name,submission_data.lead_phone,submission_data.form_selector_id,submission_data.form_selector_classes,function(){$.removeCookie("li_submission",{path:"/",domain:""})})}hashkey||(hashkey=Math.random().toString(36).slice(2),$.cookie("li_hash",hashkey,{path:"/",domain:""}),leadin_insert_lead(hashkey,page_referrer)),leadin_log_pageview(hashkey,page_title,page_url,page_referrer,$.cookie("li_last_visit"));var date=new Date,current_time=date.getTime();date.setTime(date.getTime()+36e5),$.cookie("li_last_visit")||leadin_check_merged_contact(hashkey),$.cookie("li_last_visit",current_time,{path:"/",domain:"",expires:date})}),jQuery(function($){-1!=$.versioncompare($.fn.jquery,"1.7.0")?$(document).on("submit","form",function(){var $form=$(this).closest("form");leadin_submit_form($form,$)}):$(document).bind("submit","form",function(){var $form=$(this).closest("form");leadin_submit_form($form,$)})}),String.prototype.replaceArray=function(find,replace){for(var replaceString=this,i=0;i<find.length;i++)replaceString=1!=replace.length?replaceString.replace(find[i],replace[i]):replaceString.replace(find[i],replace[0]);return replaceString},function($){function normalize(version){return $.map(version.split("."),function(value){return parseInt(value,10)})}$.versioncompare=function(version1,version2){if("undefined"==typeof version1)throw new Error("$.versioncompare needs at least one parameter.");if(version2=version2||$.fn.jquery,version1==version2)return 0;for(var v1=normalize(version1),v2=normalize(version2),len=Math.max(v1.length,v2.length),i=0;len>i;i++)if(v1[i]=v1[i]||0,v2[i]=v2[i]||0,v1[i]!=v2[i])return v1[i]>v2[i]?1:-1;return 0}}(jQuery),function($){$.fn.classes=function(callback){var classes=[];if($.each(this,function(i,v){var splitClassName=v.className.split(/\s+/);for(var j in splitClassName){var className=splitClassName[j];-1===classes.indexOf(className)&&classes.push(className)}}),"function"==typeof callback)for(var i in classes)callback(classes[i]);return classes}}(jQuery);
1
+ function leadin_submit_form($form,$){var $this=$form,form_fields=[],lead_email="",lead_first_name="",lead_last_name="",lead_phone="",form_selector_id=$form.attr("id")?$form.attr("id"):"",form_selector_classes=$form.classes()?$form.classes().join(","):"";$this.find('input[type!="submit"], textarea').not('input[type="hidden"], input[type="radio"], input[type="password"]').each(function(){var $element=$(this),$value=$element.val();if(!$element.is(":visible"))return!0;var $label=$("label[for='"+$element.attr("id")+"']").text();0==$label.length&&($label=$element.prev("label").not(".li_used").addClass("li_used").first().text(),$label.length||($label=$element.prevAll("b, strong, span").text())),0==$label.length&&($label=$element.next("label").not(".li_used").addClass("li_used").first().text(),$label.length||($label=$element.nextAll("b, strong, span").text())),0==$label.length&&($label=$element.parent().find("label, b, strong").not(".li_used").first().text()),0==$label.length&&$.contains($this,$element.parent().parent())&&($label=$element.parent().parent().find("label, b, strong").first().text()),0==$label.length&&($p=$element.closest("p").not(".li_used").addClass("li_used"),$p.length&&($label=$p.text(),$label=$.trim($label.replace($value,"")))),0==$label.length&&void 0!==$element.attr("placeholder")&&($label=$element.attr("placeholder").toString()),0==$label.length&&void 0!==$element.attr("name")&&($label=$element.attr("name").toString()),$element.is(":checkbox")&&($value=$element.is(":checked")?"Checked":"Not checked"),$value=$value.replace("C:\\fakepath\\","");var $label_text=$.trim($label.replaceArray(["(",")","required","Required","*",":"],[""]));ignore_field($label_text,$value)||push_form_field($label_text,$value,form_fields),-1==$value.indexOf("@")||-1==$value.indexOf(".")||lead_email||(lead_email=$value),"leadin-subscribe-fname"==$element.attr("id")&&(lead_first_name=$value),"leadin-subscribe-lname"==$element.attr("id")&&(lead_last_name=$value),"leadin-subscribe-phone"==$element.attr("id")&&(lead_phone=$value)});var radio_groups=[],rbg_label_values=[];$this.find(":radio").each(function(){-1==$.inArray(this.name,radio_groups)&&radio_groups.push(this.name),rbg_label_values.push($(this).val())});for(var i=0;i<radio_groups.length;i++){{var $rbg=$("input:radio[name='"+radio_groups[i]+"']");$("input:radio[name='"+radio_groups[i]+"']:checked").val()}$p=$this.find(".gfield").length?$rbg.closest(".gfield").not(".li_used").addClass("li_used"):$this.find(".frm_form_field").length?$rbg.closest(".frm_form_field").not(".li_used").addClass("li_used"):$rbg.closest("div, p").not(".li_used").addClass("li_used"),$p.length&&($rbg_label=$p.text(),$rbg_label=$.trim($rbg_label.replaceArray(rbg_label_values,[""]).replace($p.find(".gfield_description").text(),"")));var rgb_selected=$("input:radio[name='"+radio_groups[i]+"']:checked").val()?$("input:radio[name='"+radio_groups[i]+"']:checked").val():"not selected";ignore_field($rbg_label,rgb_selected)||push_form_field($rbg_label,rgb_selected,form_fields)}if($this.find("select").each(function(){var $select=$(this),$select_label=$("label[for='"+$select.attr("id")+"']").text();if(!$select_label.length){var select_values=[];$select.find("option").each(function(){-1==$.inArray($(this).val(),select_values)&&select_values.push($(this).val())}),$p=$select.closest("div, p").not(".li_used").addClass("li_used"),$p=$this.find(".gfield").length?$select.closest(".gfield").not(".li_used").addClass("li_used"):$select.closest("div, p").addClass("li_used"),$p.length&&($select_label=$p.text(),$select_label=$.trim($select_label.replaceArray(select_values,[""]).replace($p.find(".gfield_description").text(),"")))}var select_value="";if($select.val()instanceof Array){var select_vals=$select.val();for(i=0;i<select_vals.length;i++)select_value+=select_vals[i],i!=select_vals.length-1&&(select_value+=", ")}else select_value=$select.val();ignore_field($select_label,select_value)||push_form_field($select_label,select_value,form_fields)}),$this.find(".li_used").removeClass("li_used"),lead_email){ignore_form&&push_form_field("Credit card form submitted","Payment fields not collected for security",form_fields);var submission_hash=Math.random().toString(36).slice(2),hashkey=$.cookie("li_hash"),json_form_fields=JSON.stringify(form_fields),form_submission={};form_submission={submission_hash:submission_hash,hashkey:hashkey,lead_email:lead_email,lead_first_name:lead_first_name,lead_last_name:lead_last_name,lead_phone:lead_phone,page_title:page_title,page_url:page_url,json_form_fields:json_form_fields,form_selector_id:form_selector_id,form_selector_classes:form_selector_classes},$.cookie("li_submission",JSON.stringify(form_submission),{path:"/",domain:""}),leadin_insert_form_submission(submission_hash,hashkey,page_title,page_url,json_form_fields,lead_email,lead_first_name,lead_last_name,lead_phone,form_selector_id,form_selector_classes,function(){$.removeCookie("li_submission",{path:"/",domain:""})})}else form_saved=!0}function leadin_check_merged_contact(hashkey){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_check_merged_contact",li_id:hashkey},success:function(data){var json_data=jQuery.parseJSON(data);json_data&&jQuery.cookie("li_hash",json_data,{path:"/",domain:""})},error:function(){}})}function leadin_check_visitor_status(hashkey,callback){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_check_visitor_status",li_id:hashkey},success:function(data){var json_data=jQuery.parseJSON(data);callback&&callback(json_data)},error:function(){}})}function leadin_log_pageview(hashkey,page_title,page_url,page_referrer,last_visit){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_log_pageview",li_id:hashkey,li_title:page_title,li_url:page_url,li_referrer:page_referrer,li_last_visit:last_visit},success:function(){},error:function(){}})}function leadin_insert_lead(hashkey,page_referrer){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_insert_lead",li_id:hashkey,li_referrer:page_referrer},success:function(){},error:function(){}})}function leadin_insert_form_submission(submission_haskey,hashkey,page_title,page_url,json_fields,lead_email,lead_first_name,lead_last_name,lead_phone,form_selector_id,form_selector_classes,Callback){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_insert_form_submission",li_submission_id:submission_haskey,li_id:hashkey,li_title:page_title,li_url:page_url,li_fields:json_fields,li_email:lead_email,li_first_name:lead_first_name,li_last_name:lead_last_name,li_phone:lead_phone,li_form_selector_id:form_selector_id,li_form_selector_classes:form_selector_classes},success:function(data){Callback&&Callback(data)},error:function(){}})}function push_form_field(label,value,form_fields){var field={label:label,value:value};form_fields.push(field)}function ignore_field(label,value){var bool_ignore_field=!1;(-1!=label.toLowerCase().indexOf("credit card")||-1!=label.toLowerCase().indexOf("card number"))&&(bool_ignore_field=!0),(-1!=label.toLowerCase().indexOf("expiration")||-1!=label.toLowerCase().indexOf("expiry"))&&(bool_ignore_field=!0),(-1!=label.toLowerCase().indexOf("month")||-1!=label.toLowerCase().indexOf("mm")||-1!=label.toLowerCase().indexOf("yy")||-1!=label.toLowerCase().indexOf("year"))&&(bool_ignore_field=!0),(-1!=label.toLowerCase().indexOf("cvv")||-1!=label.toLowerCase().indexOf("cvc")||-1!=label.toLowerCase().indexOf("secure code")||-1!=label.toLowerCase().indexOf("security code"))&&(bool_ignore_field=!0),(-1!=value.toLowerCase().indexOf("visa")||-1!=value.toLowerCase().indexOf("mastercard")||-1!=value.toLowerCase().indexOf("american express")||-1!=value.toLowerCase().indexOf("amex")||-1!=value.toLowerCase().indexOf("discover"))&&(bool_ignore_field=!0);var int_regex=new RegExp("/^[0-9]+$/");if(int_regex.test(value)){var value_no_spaces=value.replace(" ","");isInt(value_no_spaces)&&value_no_spaces.length>=16&&(bool_ignore_field=!0)}return bool_ignore_field?(ignore_form||(ignore_form=!0),!0):!1}function isInt(n){return"number"==typeof n&&isFinite(n)&&n%1===0}!function(factory){"function"==typeof define&&define.amd?define(["jquery"],factory):factory(jQuery)}(function($){function encode(s){return config.raw?s:encodeURIComponent(s)}function decode(s){return config.raw?s:decodeURIComponent(s)}function stringifyCookieValue(value){return encode(config.json?JSON.stringify(value):String(value))}function parseCookieValue(s){0===s.indexOf('"')&&(s=s.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return s=decodeURIComponent(s.replace(pluses," ")),config.json?JSON.parse(s):s}catch(e){}}function read(s,converter){var value=config.raw?s:parseCookieValue(s);return $.isFunction(converter)?converter(value):value}var pluses=/\+/g,config=$.cookie=function(key,value,options){if(void 0!==value&&!$.isFunction(value)){if(options=$.extend({},config.defaults,options),"number"==typeof options.expires){var days=options.expires,t=options.expires=new Date;t.setDate(t.getDate()+days)}return document.cookie=[encode(key),"=",stringifyCookieValue(value),options.expires?"; expires="+options.expires.toUTCString():"",options.path?"; path="+options.path:"",options.domain?"; domain="+options.domain:"",options.secure?"; secure":""].join("")}for(var result=key?void 0:{},cookies=document.cookie?document.cookie.split("; "):[],i=0,l=cookies.length;l>i;i++){var parts=cookies[i].split("="),name=decode(parts.shift()),cookie=parts.join("=");if(key&&key===name){result=read(cookie,value);break}key||void 0===(cookie=read(cookie))||(result[name]=cookie)}return result};config.defaults={},$.removeCookie=function(key,options){return void 0===$.cookie(key)?!1:($.cookie(key,"",$.extend({},options,{expires:-1})),!$.cookie(key))}});var page_title=jQuery(document).find("title").text(),page_url=window.location.href,page_referrer=document.referrer,form_saved=!1,ignore_form=!1;jQuery(document).ready(function($){var hashkey=$.cookie("li_hash"),li_submission_cookie=$.cookie("li_submission");if(li_submission_cookie){var submission_data=JSON.parse(li_submission_cookie);leadin_insert_form_submission(submission_data.submission_hash,submission_data.hashkey,submission_data.page_title,submission_data.page_url,submission_data.json_form_fields,submission_data.lead_email,submission_data.lead_first_name,submission_data.lead_last_name,submission_data.lead_phone,submission_data.form_selector_id,submission_data.form_selector_classes,function(){$.removeCookie("li_submission",{path:"/",domain:""})})}hashkey||(hashkey=Math.random().toString(36).slice(2),$.cookie("li_hash",hashkey,{path:"/",domain:""}),leadin_insert_lead(hashkey,page_referrer)),leadin_log_pageview(hashkey,page_title,page_url,page_referrer,$.cookie("li_last_visit"));var date=new Date,current_time=date.getTime();date.setTime(date.getTime()+36e5),$.cookie("li_last_visit")||leadin_check_merged_contact(hashkey),$.cookie("li_last_visit",current_time,{path:"/",domain:"",expires:date})}),jQuery(function($){-1!=$.versioncompare($.fn.jquery,"1.7.0")?$(document).on("submit","form",function(){var $form=$(this).closest("form");leadin_submit_form($form,$)}):$(document).bind("submit","form",function(){var $form=$(this).closest("form");leadin_submit_form($form,$)})}),String.prototype.replaceArray=function(find,replace){for(var replaceString=this,i=0;i<find.length;i++)replaceString=1!=replace.length?replaceString.replace(find[i],replace[i]):replaceString.replace(find[i],replace[0]);return replaceString},function($){function normalize(version){return $.map(version.split("."),function(value){return parseInt(value,10)})}$.versioncompare=function(version1,version2){if("undefined"==typeof version1)throw new Error("$.versioncompare needs at least one parameter.");if(version2=version2||$.fn.jquery,version1==version2)return 0;for(var v1=normalize(version1),v2=normalize(version2),len=Math.max(v1.length,v2.length),i=0;len>i;i++)if(v1[i]=v1[i]||0,v2[i]=v2[i]||0,v1[i]!=v2[i])return v1[i]>v2[i]?1:-1;return 0}}(jQuery),function($){$.fn.classes=function(callback){var classes=[];if($.each(this,function(i,v){var splitClassName=v.className.split(/\s+/);for(var j in splitClassName){var className=splitClassName[j];-1===classes.indexOf(className)&&classes.push(className)}}),"function"==typeof callback)for(var i in classes)callback(classes[i]);return classes}}(jQuery);
images/{power-up-icon-constant-contact-list-sync.png → power-up-icon-constant-contact-connect.png} RENAMED
File without changes
images/power-up-icon-constant-contact-connect@2x.png ADDED
Binary file
images/power-up-icon-constant-contact-connect_small.png ADDED
Binary file
images/power-up-icon-constant-contact-connect_small@2x.png ADDED
Binary file
images/power-up-icon-mailchimp-connect.png ADDED
Binary file
images/power-up-icon-mailchimp-connect@2x.png ADDED
Binary file
images/power-up-icon-mailchimp-connect_small.png ADDED
Binary file
images/power-up-icon-mailchimp-connect_small@2x.png ADDED
Binary file
inc/class-emailer.php CHANGED
@@ -70,7 +70,7 @@ class LI_Emailer {
70
  * @return string concatenated string - New submission on [Site Name](linked to site URL)
71
  */
72
  function build_submission_details ( $url ) {
73
- $format = '<table class="row submission-detail" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 style="color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 18px;">New submission on <a href="%s" style="color: #2ba6cb;text-decoration: none;">%s</a></h3></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>';
74
  $built_submission_details = sprintf($format, $url, get_bloginfo('name'));
75
 
76
  return $built_submission_details;
@@ -83,10 +83,10 @@ class LI_Emailer {
83
  * @return string concatenated string with avatar + linked email address
84
  */
85
  function build_contact_identity ( $email ) {
86
- $avatar_img = "https://app.getsignals.com/avatar/image/?emails=" . $email;
87
 
88
- $format = '<table class="row lead-identity" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="two columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 80px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><img height="60" width="60" src="%s" style="background-color:#F6601D;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;width: auto;max-width: 100%%;float: left;clear: both;display: block;"/></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="ten columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 480px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h1 style="color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 60px;word-break: normal;font-size: 26px;">%s</h1></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>';
89
- $built_identity = sprintf($format, $avatar_img, $email);
90
 
91
  return $built_identity;
92
  }
70
  * @return string concatenated string - New submission on [Site Name](linked to site URL)
71
  */
72
  function build_submission_details ( $url ) {
73
+ $format = '<table class="row submission-detail" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 style="color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 18px;">New submission on <a href="%s" style="color: #2ba6cb;text-decoration: none;">%s</a></h3></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>' . "\r\n";
74
  $built_submission_details = sprintf($format, $url, get_bloginfo('name'));
75
 
76
  return $built_submission_details;
83
  * @return string concatenated string with avatar + linked email address
84
  */
85
  function build_contact_identity ( $email ) {
86
+ $avatar_img = "https://api.hubapi.com/socialintel/v1/avatars?email=" . $email;
87
 
88
+ $format = '<table class="row lead-identity" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="two columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 80px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><img height="60" width="60" src="%s" style="background-color:#F6601D;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;width: auto;max-width: 100%%;float: left;clear: both;display: block;"/></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="ten columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 480px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><a style="color: #2ba6cb;text-decoration: none;" href="mailto:%s"><h1 style="font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 60px;word-break: normal;font-size: 26px;">%s</h1></a></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>';
89
+ $built_identity = sprintf($format, $avatar_img, $email, $email);
90
 
91
  return $built_identity;
92
  }
inc/class-leadin.php CHANGED
@@ -4,34 +4,32 @@
4
  // WPLeadIn Class
5
  //=============================================
6
  class WPLeadIn {
7
-
8
- var $power_ups;
9
- var $options;
10
 
 
11
  /**
12
  * Class constructor
13
  */
14
  function __construct ()
15
  {
16
- global $wpdb;
17
-
18
  leadin_set_wpdb_tables();
19
-
20
- //=============================================
21
- // Hooks & Filters
22
- //=============================================
23
 
24
- $this->power_ups = $this->get_available_power_ups();
25
- $this->options = get_option('leadin_options');
26
- $this->add_leadin_frontend_scripts();
27
 
28
- add_action('admin_bar_menu', array($this, 'add_leadin_link_to_admin_bar'), 999);
29
-
30
- $li_wp_admin = new WPLeadInAdmin($this->power_ups);
31
- add_filter('plugin_action_links_' . plugin_basename(__FILE__), array(&$li_wp_admin, 'leadin_plugin_settings_link'));
 
 
 
 
 
 
32
 
33
- if ( isset($this->options['beta_tester']) && $this->options['beta_tester'] )
34
- $li_wp_updater = new WPLeadInUpdater();
 
35
  }
36
 
37
  //=============================================
@@ -43,14 +41,12 @@ class WPLeadIn {
43
  */
44
  function add_leadin_frontend_scripts ()
45
  {
46
- if ( !is_admin() )
47
- {
48
- wp_register_script('leadin-tracking', LEADIN_PATH . '/assets/js/build/leadin-tracking.min.js', array ('jquery'), FALSE, TRUE);
49
- wp_enqueue_script('leadin-tracking');
50
 
51
- // replace https with http for admin-ajax calls for SSLed backends
52
- wp_localize_script('leadin-tracking', 'li_ajax', array('ajax_url' => str_replace('https:', 'http:', admin_url('admin-ajax.php'))));
53
- }
54
  }
55
 
56
  /**
@@ -73,40 +69,40 @@ class WPLeadIn {
73
  /**
74
  * List available power-ups
75
  */
76
- public static function get_available_power_ups( $min_version = FALSE, $max_version = FALSE ) {
77
  static $power_ups = null;
78
 
79
  if ( ! isset( $power_ups ) ) {
80
- $files = WPLeadIn::glob_php( LEADIN_PLUGIN_DIR . '/power-ups' );
81
 
82
  $power_ups = array();
83
 
84
  foreach ( $files as $file ) {
85
 
86
- if ( ! $headers = WPLeadIn::get_power_up($file) ) {
87
- continue;
88
- }
89
-
90
- $power_up = new $headers['class']($headers['activated']);
91
- $power_up->power_up_name = $headers['name'];
92
- $power_up->menu_text = $headers['menu_text'];
93
- $power_up->menu_link = $headers['menu_link'];
94
- $power_up->slug = $headers['slug'];
95
- $power_up->link_uri = $headers['uri'];
96
- $power_up->description = $headers['description'];
97
- $power_up->icon = $headers['icon'];
98
- $power_up->permanent = ( $headers['permanent'] == 'Yes' ? 1 : 0 );
99
- $power_up->auto_activate = ( $headers['auto_activate'] == 'Yes' ? 1 : 0 );
100
- $power_up->hidden = ( $headers['hidden'] == 'Yes' ? 1 : 0 );
101
- $power_up->activated = $headers['activated'];
102
-
103
- // Set the small icons HTML for the settings page
104
- if ( strstr($headers['icon_small'], 'dashicons') )
105
- $power_up->icon_small = '<span class="dashicons ' . $headers['icon_small'] . '"></span>';
106
- else
107
- $power_up->icon_small = '<img src="' . LEADIN_PATH . '/images/' . $headers['icon_small'] . '.png" class="power-up-settings-icon"/>';
108
-
109
- array_push($power_ups, $power_up);
110
  }
111
  }
112
 
@@ -114,59 +110,59 @@ class WPLeadIn {
114
  }
115
 
116
  /**
117
- * Extract a power-up's slug from its full path.
118
- */
119
- public static function get_power_up_slug ( $file ) {
120
- return str_replace( '.php', '', basename( $file ) );
121
- }
122
-
123
- /**
124
- * Generate a power-up's path from its slug.
125
- */
126
- public static function get_power_up_path ( $slug ) {
127
- return LEADIN_PLUGIN_DIR . "/power-ups/$slug.php";
128
- }
129
 
130
  /**
131
- * Load power-up data from power-up file. Headers differ from WordPress
132
- * plugin headers to avoid them being identified as standalone
133
- * plugins on the WordPress plugins page.
134
- *
135
- * @param $power_up The file path for the power-up
136
- * @return $pu array of power-up attributes
137
- */
138
- public static function get_power_up ( $power_up )
139
- {
140
- $headers = array(
141
- 'name' => 'Power-up Name',
142
- 'class' => 'Power-up Class',
143
- 'menu_text' => 'Power-up Menu Text',
144
- 'menu_link' => 'Power-up Menu Link',
145
- 'slug' => 'Power-up Slug',
146
- 'uri' => 'Power-up URI',
147
- 'description' => 'Power-up Description',
148
- 'icon' => 'Power-up Icon',
149
- 'icon_small' => 'Power-up Icon Small',
150
- 'introduced' => 'First Introduced',
151
- 'auto_activate' => 'Auto Activate',
152
- 'permanent' => 'Permanently Enabled',
153
- 'power_up_tags' => 'Power-up Tags',
154
- 'hidden' => 'Hidden'
155
- );
156
-
157
- $file = WPLeadIn::get_power_up_path( WPLeadIn::get_power_up_slug( $power_up ) );
158
- if ( ! file_exists( $file ) )
159
- return FALSE;
160
-
161
- $pu = get_file_data( $file, $headers );
162
-
163
- if ( empty( $pu['name'] ) )
164
- return FALSE;
165
-
166
- $pu['activated'] = self::is_power_up_active($pu['slug']);
167
 
168
- return $pu;
169
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  /**
172
  * Returns an array of all PHP files in the specified absolute path.
@@ -197,11 +193,11 @@ class WPLeadIn {
197
  }
198
 
199
  $files = leadin_sort_power_ups($files, array(
200
- LEADIN_PLUGIN_DIR . '/power-ups/contacts.php',
201
- LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php',
202
- LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-list-sync.php',
203
- LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-list-sync.php',
204
- LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php'
205
  ));
206
 
207
  closedir( $dir );
@@ -210,83 +206,82 @@ class WPLeadIn {
210
  }
211
 
212
  /**
213
- * Check whether or not a LeadIn power-up is active.
214
- *
215
- * @param string $power_up The slug of a power-up
216
- * @return bool
217
- *
218
- * @static
219
- */
220
- public static function is_power_up_active( $power_up_slug )
221
- {
222
- return in_array($power_up_slug, self::get_active_power_ups());
223
- }
224
-
225
- /**
226
- * Get a list of activated modules as an array of module slugs.
227
- */
228
- public static function get_active_power_ups ()
229
- {
230
- $activated_power_ups = get_option('leadin_active_power_ups');
231
- if ( $activated_power_ups )
232
- return array_unique(unserialize($activated_power_ups));
233
- else
234
- return array();
235
- }
236
-
237
- public static function activate_power_up( $power_up_slug, $exit = TRUE )
238
- {
239
- if ( ! strlen( $power_up_slug ) )
240
- return FALSE;
241
-
242
- // If it's already active, then don't do it again
243
- $active = self::is_power_up_active($power_up_slug);
244
- if ( $active )
245
- return TRUE;
246
-
247
- $activated_power_ups = get_option('leadin_active_power_ups');
248
-
249
- if ( $activated_power_ups )
250
- {
251
- $activated_power_ups = unserialize($activated_power_ups);
252
- $activated_power_ups[] = $power_up_slug;
253
- }
254
- else
255
- {
256
- $activated_power_ups = array($power_up_slug);
257
- }
258
-
259
- update_option('leadin_active_power_ups', serialize($activated_power_ups));
260
 
 
 
 
 
 
 
 
 
 
 
 
261
 
262
- if ( $exit )
263
- {
264
- exit;
265
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
 
267
- }
268
 
269
- public static function deactivate_power_up( $power_up_slug, $exit = TRUE )
270
- {
271
- if ( ! strlen( $power_up_slug ) )
272
- return FALSE;
273
 
274
- // If it's already active, then don't do it again
275
- $active = self::is_power_up_active($power_up_slug);
276
- if ( ! $active )
277
- return TRUE;
 
278
 
279
- $activated_power_ups = get_option('leadin_active_power_ups');
280
-
281
- $power_ups_left = leadin_array_delete(unserialize($activated_power_ups), $power_up_slug);
282
- update_option('leadin_active_power_ups', serialize($power_ups_left));
283
-
284
- if ( $exit )
285
- {
286
- exit;
287
- }
 
 
 
 
 
 
 
 
 
 
288
 
289
- }
290
  }
291
 
292
  //=============================================
4
  // WPLeadIn Class
5
  //=============================================
6
  class WPLeadIn {
 
 
 
7
 
8
+ var $power_ups;
9
  /**
10
  * Class constructor
11
  */
12
  function __construct ()
13
  {
 
 
14
  leadin_set_wpdb_tables();
 
 
 
 
15
 
16
+ $this->power_ups = self::get_available_power_ups();
17
+ add_action('admin_bar_menu', array($this, 'add_leadin_link_to_admin_bar'), 999);
 
18
 
19
+ if ( is_admin() )
20
+ {
21
+ if ( ! defined('DOING_AJAX') || ! DOING_AJAX )
22
+ {
23
+ if ( current_user_can('manage_options') )
24
+ $li_wp_admin = new WPLeadInAdmin($this->power_ups);
25
+ }
26
+ }
27
+ else
28
+ {
29
 
30
+ add_action('wp_enqueue_scripts', array($this, 'add_leadin_frontend_scripts'));
31
+ // Get all the power-ups and instantiate them
32
+ }
33
  }
34
 
35
  //=============================================
41
  */
42
  function add_leadin_frontend_scripts ()
43
  {
44
+ wp_register_script('leadin-tracking', LEADIN_PATH . '/assets/js/build/leadin-tracking.min.js', array ('jquery'), FALSE, TRUE);
45
+ wp_enqueue_script('leadin-tracking');
 
 
46
 
47
+ // replace https with http for admin-ajax calls for SSLed backends
48
+ //wp_localize_script('leadin-tracking', 'li_ajax', array('ajax_url' => str_replace('https:', 'http:', admin_url('admin-ajax.php'))));
49
+ wp_localize_script('leadin-tracking', 'li_ajax', array('ajax_url' => get_admin_url(NULL,'') . '/admin-ajax.php'));
50
  }
51
 
52
  /**
69
  /**
70
  * List available power-ups
71
  */
72
+ public static function get_available_power_ups ( $min_version = FALSE, $max_version = FALSE ) {
73
  static $power_ups = null;
74
 
75
  if ( ! isset( $power_ups ) ) {
76
+ $files = self::glob_php( LEADIN_PLUGIN_DIR . '/power-ups' );
77
 
78
  $power_ups = array();
79
 
80
  foreach ( $files as $file ) {
81
 
82
+ if ( ! $headers = self::get_power_up($file) ) {
83
+ continue;
84
+ }
85
+
86
+ $power_up = new $headers['class']($headers['activated']);
87
+ $power_up->power_up_name = $headers['name'];
88
+ $power_up->menu_text = $headers['menu_text'];
89
+ $power_up->menu_link = $headers['menu_link'];
90
+ $power_up->slug = $headers['slug'];
91
+ $power_up->link_uri = $headers['uri'];
92
+ $power_up->description = $headers['description'];
93
+ $power_up->icon = $headers['icon'];
94
+ $power_up->permanent = ( $headers['permanent'] == 'Yes' ? 1 : 0 );
95
+ $power_up->auto_activate = ( $headers['auto_activate'] == 'Yes' ? 1 : 0 );
96
+ $power_up->hidden = ( $headers['hidden'] == 'Yes' ? 1 : 0 );
97
+ $power_up->activated = $headers['activated'];
98
+
99
+ // Set the small icons HTML for the settings page
100
+ if ( strstr($headers['icon_small'], 'dashicons') )
101
+ $power_up->icon_small = '<span class="dashicons ' . $headers['icon_small'] . '"></span>';
102
+ else
103
+ $power_up->icon_small = '<img src="' . LEADIN_PATH . '/images/' . $headers['icon_small'] . '.png" class="power-up-settings-icon"/>';
104
+
105
+ array_push($power_ups, $power_up);
106
  }
107
  }
108
 
110
  }
111
 
112
  /**
113
+ * Extract a power-up's slug from its full path.
114
+ */
115
+ public static function get_power_up_slug ( $file ) {
116
+ return str_replace( '.php', '', basename( $file ) );
117
+ }
 
 
 
 
 
 
 
118
 
119
  /**
120
+ * Generate a power-up's path from its slug.
121
+ */
122
+ public static function get_power_up_path ( $slug ) {
123
+ return LEADIN_PLUGIN_DIR . "/power-ups/$slug.php";
124
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
+ /**
127
+ * Load power-up data from power-up file. Headers differ from WordPress
128
+ * plugin headers to avoid them being identified as standalone
129
+ * plugins on the WordPress plugins page.
130
+ *
131
+ * @param $power_up The file path for the power-up
132
+ * @return $pu array of power-up attributes
133
+ */
134
+ public static function get_power_up ( $power_up )
135
+ {
136
+ $headers = array(
137
+ 'name' => 'Power-up Name',
138
+ 'class' => 'Power-up Class',
139
+ 'menu_text' => 'Power-up Menu Text',
140
+ 'menu_link' => 'Power-up Menu Link',
141
+ 'slug' => 'Power-up Slug',
142
+ 'uri' => 'Power-up URI',
143
+ 'description' => 'Power-up Description',
144
+ 'icon' => 'Power-up Icon',
145
+ 'icon_small' => 'Power-up Icon Small',
146
+ 'introduced' => 'First Introduced',
147
+ 'auto_activate' => 'Auto Activate',
148
+ 'permanent' => 'Permanently Enabled',
149
+ 'power_up_tags' => 'Power-up Tags',
150
+ 'hidden' => 'Hidden'
151
+ );
152
+
153
+ $file = self::get_power_up_path( self::get_power_up_slug( $power_up ) );
154
+ if ( ! file_exists( $file ) )
155
+ return FALSE;
156
+
157
+ $pu = get_file_data( $file, $headers );
158
+
159
+ if ( empty( $pu['name'] ) )
160
+ return FALSE;
161
+
162
+ $pu['activated'] = self::is_power_up_active($pu['slug']);
163
+
164
+ return $pu;
165
+ }
166
 
167
  /**
168
  * Returns an array of all PHP files in the specified absolute path.
193
  }
194
 
195
  $files = leadin_sort_power_ups($files, array(
196
+ LEADIN_PLUGIN_DIR . '/power-ups/contacts.php',
197
+ LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php',
198
+ LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php',
199
+ LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php',
200
+ LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php'
201
  ));
202
 
203
  closedir( $dir );
206
  }
207
 
208
  /**
209
+ * Check whether or not a LeadIn power-up is active.
210
+ *
211
+ * @param string $power_up The slug of a power-up
212
+ * @return bool
213
+ *
214
+ * @static
215
+ */
216
+ public static function is_power_up_active ( $power_up_slug )
217
+ {
218
+ return in_array($power_up_slug, self::get_active_power_ups());
219
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
+ /**
222
+ * Get a list of activated modules as an array of module slugs.
223
+ */
224
+ public static function get_active_power_ups ()
225
+ {
226
+ $activated_power_ups = get_option('leadin_active_power_ups');
227
+ if ( $activated_power_ups )
228
+ return array_unique(unserialize($activated_power_ups));
229
+ else
230
+ return array();
231
+ }
232
 
233
+ public static function activate_power_up( $power_up_slug, $exit = TRUE )
234
+ {
235
+ if ( ! strlen( $power_up_slug ) )
236
+ return FALSE;
237
+
238
+ // If it's already active, then don't do it again
239
+ $active = self::is_power_up_active($power_up_slug);
240
+ if ( $active )
241
+ return TRUE;
242
+
243
+ $activated_power_ups = get_option('leadin_active_power_ups');
244
+
245
+ if ( $activated_power_ups )
246
+ {
247
+ $activated_power_ups = unserialize($activated_power_ups);
248
+ $activated_power_ups[] = $power_up_slug;
249
+ }
250
+ else
251
+ {
252
+ $activated_power_ups = array($power_up_slug);
253
+ }
254
 
255
+ update_option('leadin_active_power_ups', serialize($activated_power_ups));
256
 
 
 
 
 
257
 
258
+ if ( $exit )
259
+ {
260
+ exit;
261
+ }
262
+ }
263
 
264
+ public static function deactivate_power_up( $power_up_slug, $exit = TRUE )
265
+ {
266
+ if ( ! strlen( $power_up_slug ) )
267
+ return FALSE;
268
+
269
+ // If it's already active, then don't do it again
270
+ $active = self::is_power_up_active($power_up_slug);
271
+ if ( ! $active )
272
+ return TRUE;
273
+
274
+ $activated_power_ups = get_option('leadin_active_power_ups');
275
+
276
+ $power_ups_left = leadin_array_delete(unserialize($activated_power_ups), $power_up_slug);
277
+ update_option('leadin_active_power_ups', serialize($power_ups_left));
278
+
279
+ if ( $exit )
280
+ {
281
+ exit;
282
+ }
283
 
284
+ }
285
  }
286
 
287
  //=============================================
inc/leadin-ajax-functions.php CHANGED
@@ -249,8 +249,8 @@ function leadin_insert_form_submission ()
249
  {
250
  foreach ( unserialize($list->tag_synced_lists) as $synced_list )
251
  {
252
- // e.g. leadin_constant_contact_list_sync_wp
253
- $leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_list_sync_wp';
254
  global ${$leadin_esp_wp};
255
 
256
  if ( ${$leadin_esp_wp}->activated )
@@ -280,8 +280,8 @@ function leadin_insert_form_submission ()
280
  {
281
  foreach ( unserialize($list->tag_synced_lists) as $synced_list )
282
  {
283
- // e.g. leadin_constant_contact_list_sync_wp
284
- $leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_list_sync_wp';
285
  global ${$leadin_esp_wp};
286
 
287
  if ( ${$leadin_esp_wp}->activated )
249
  {
250
  foreach ( unserialize($list->tag_synced_lists) as $synced_list )
251
  {
252
+ // e.g. leadin_constant_contact_connect_wp
253
+ $leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
254
  global ${$leadin_esp_wp};
255
 
256
  if ( ${$leadin_esp_wp}->activated )
280
  {
281
  foreach ( unserialize($list->tag_synced_lists) as $synced_list )
282
  {
283
+ // e.g. leadin_constant_contact_connect_wp
284
+ $leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
285
  global ${$leadin_esp_wp};
286
 
287
  if ( ${$leadin_esp_wp}->activated )
inc/leadin-functions.php CHANGED
@@ -51,7 +51,9 @@ function leadin_update_option ( $option, $option_key, $new_value )
51
  }
52
 
53
  $options_array[$option_key] = $new_value;
 
54
 
 
55
  return update_option($option, $options_array);
56
  }
57
 
@@ -461,7 +463,7 @@ function leadin_convert_statuses_to_tags ( )
461
  $mailchimp_options = get_option('leadin_mls_options');
462
  if ( $mailchimp_options['li_mls_subscribers_to_list'] )
463
  {
464
- $leadin_mailchimp = new WPMailChimpListSync(TRUE);
465
  $leadin_mailchimp->admin_init();
466
  $lists = $leadin_mailchimp->admin->li_get_lists();
467
 
@@ -489,7 +491,7 @@ function leadin_convert_statuses_to_tags ( )
489
  $constant_contact_options = get_option('leadin_cc_options');
490
  if ( $constant_contact_options['li_cc_subscribers_to_list'] )
491
  {
492
- $leadin_constant_contact = new WPConstantContactListSync(TRUE);
493
  $leadin_constant_contact->admin_init();
494
  $lists = $leadin_constant_contact->admin->li_get_lists();
495
 
@@ -578,7 +580,7 @@ function leadin_convert_statuses_to_tags ( )
578
  }
579
  }
580
 
581
- leadin_update_option('leadin_options', 'converted_to_tags', '1');
582
  }
583
 
584
  /**
@@ -638,10 +640,13 @@ function leadin_strip_params_from_url ( $url )
638
  $url_parts = parse_url($url);
639
  $base_url = ( isset($url_parts['host']) ? 'http://' . rtrim($url_parts['host'], '/') : '' );
640
  $base_url .= ( isset($url_parts['path']) ? '/' . ltrim($url_parts['path'], '/') : '' );
641
- ltrim($url_parts['path'], '/');
 
 
 
642
  $base_url = urldecode(ltrim($base_url, '/'));
643
 
644
- return $base_url;
645
  }
646
 
647
  /**
51
  }
52
 
53
  $options_array[$option_key] = $new_value;
54
+ update_option($option, $options_array);
55
 
56
+ $options_array = get_option($option);
57
  return update_option($option, $options_array);
58
  }
59
 
463
  $mailchimp_options = get_option('leadin_mls_options');
464
  if ( $mailchimp_options['li_mls_subscribers_to_list'] )
465
  {
466
+ $leadin_mailchimp = new WPMailChimpConnect(TRUE);
467
  $leadin_mailchimp->admin_init();
468
  $lists = $leadin_mailchimp->admin->li_get_lists();
469
 
491
  $constant_contact_options = get_option('leadin_cc_options');
492
  if ( $constant_contact_options['li_cc_subscribers_to_list'] )
493
  {
494
+ $leadin_constant_contact = new WPConstantContactConnect(TRUE);
495
  $leadin_constant_contact->admin_init();
496
  $lists = $leadin_constant_contact->admin->li_get_lists();
497
 
580
  }
581
  }
582
 
583
+ leadin_update_option('leadin_options', 'converted_to_tags', 1);
584
  }
585
 
586
  /**
640
  $url_parts = parse_url($url);
641
  $base_url = ( isset($url_parts['host']) ? 'http://' . rtrim($url_parts['host'], '/') : '' );
642
  $base_url .= ( isset($url_parts['path']) ? '/' . ltrim($url_parts['path'], '/') : '' );
643
+
644
+ if ( isset($url_parts['path'] ) )
645
+ ltrim($url_parts['path'], '/');
646
+
647
  $base_url = urldecode(ltrim($base_url, '/'));
648
 
649
+ return strtolower($base_url);
650
  }
651
 
652
  /**
leadin.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: LeadIn
4
  Plugin URI: http://leadin.com
5
  Description: LeadIn is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
6
- Version: 2.0.0
7
  Author: Andy Cook, Nelson Joyce
8
  Author URI: http://leadin.com
9
  License: GPL2
@@ -26,7 +26,7 @@ if ( !defined('LEADIN_DB_VERSION') )
26
  define('LEADIN_DB_VERSION', '2.0.0');
27
 
28
  if ( !defined('LEADIN_PLUGIN_VERSION') )
29
- define('LEADIN_PLUGIN_VERSION', '2.0.0');
30
 
31
  if ( !defined('MIXPANEL_PROJECT_TOKEN') )
32
  define('MIXPANEL_PROJECT_TOKEN', 'a9615503ec58a6bce2c646a58390eac1');
@@ -41,33 +41,19 @@ require_once(LEADIN_PLUGIN_DIR . '/inc/class-emailer.php');
41
  require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin-updater.php');
42
  require_once(LEADIN_PLUGIN_DIR . '/admin/leadin-admin.php');
43
 
44
-
45
  require_once(LEADIN_PLUGIN_DIR . '/lib/mixpanel/LI_Mixpanel.php');
46
  require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin.php');
47
 
48
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
49
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
50
- require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-list-sync.php');
51
- require_once(LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-list-sync.php');
52
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php');
53
 
54
  //=============================================
55
  // Hooks & Filters
56
  //=============================================
57
 
58
-
59
-
60
-
61
- // Pretty sure this hook is being run
62
-
63
- if ( ! defined( 'WP_INSTALLING' ) || WP_INSTALLING === false )
64
- {
65
- if ( ! has_action('init', 'leadin_update_check') )
66
- {
67
- add_action('init', 'leadin_update_check', 9);
68
- }
69
- }
70
-
71
  // Activate + install LeadIn
72
  register_activation_hook( __FILE__, 'activate_leadin');
73
 
@@ -131,7 +117,8 @@ function add_leadin_defaults ( )
131
  'ignore_settings_popup' => 0,
132
  'data_recovered' => 1,
133
  'delete_flags_fixed' => 1,
134
- 'beta_tester' => 0
 
135
  );
136
 
137
  update_option('leadin_options', $opt);
@@ -207,90 +194,9 @@ function activate_leadin_on_new_blog ( $blog_id, $user_id, $domain, $path, $site
207
  /**
208
  * Checks the stored database version against the current data version + updates if needed
209
  */
210
- function leadin_update_check ()
211
  {
212
- global $wpdb;
213
-
214
  $leadin_wp = new WPLeadIn();
215
-
216
- if ( defined('DOING_AJAX') && DOING_AJAX )
217
- return;
218
-
219
- $options = get_option('leadin_options');
220
-
221
- // If the plugin version matches the latest version escape the update function
222
- if ( isset ($options['leadin_version']) && $options['leadin_version'] == LEADIN_PLUGIN_VERSION )
223
- return FALSE;
224
-
225
- // 0.5.1 upgrade - Create active power-ups option if it doesn't exist
226
- $leadin_active_power_ups = get_option('leadin_active_power_ups');
227
-
228
- if ( !$leadin_active_power_ups )
229
- {
230
- $auto_activate = array(
231
- 'contacts',
232
- 'beta_program'
233
- );
234
-
235
- update_option('leadin_active_power_ups', serialize($auto_activate));
236
- }
237
- else
238
- {
239
- // 0.9.2 upgrade - set beta program power-up to auto-activate
240
- $activated_power_ups = unserialize($leadin_active_power_ups);
241
-
242
- // 0.9.3 bug fix for dupliate beta_program values being stored in the active power-ups array
243
- if ( !in_array('beta_program', $activated_power_ups) )
244
- {
245
- $activated_power_ups[] = 'beta_program';
246
- update_option('leadin_active_power_ups', serialize($activated_power_ups));
247
- }
248
- else
249
- {
250
- $tmp = array_count_values($activated_power_ups);
251
- $count = $tmp['beta_program'];
252
-
253
- if ( $count > 1 )
254
- {
255
- $activated_power_ups = array_unique($activated_power_ups);
256
- update_option('leadin_active_power_ups', serialize($activated_power_ups));
257
- }
258
- }
259
-
260
- update_option('leadin_active_power_ups', serialize($activated_power_ups));
261
- }
262
-
263
- // 0.7.2 bug fix - data recovery algorithm for deleted contacts
264
- if ( ! isset($options['data_recovered']) )
265
- {
266
- leadin_recover_contact_data();
267
- }
268
-
269
- // Set the database version if it doesn't exist
270
- if ( isset($options['li_db_version']) )
271
- {
272
- if ( $options['li_db_version'] != LEADIN_DB_VERSION )
273
- {
274
- leadin_db_install();
275
-
276
- // 2.0.0 upgrade
277
- if ( ! isset($options['converted_to_tags']) )
278
- leadin_convert_statuses_to_tags();
279
- }
280
- }
281
- else
282
- {
283
- leadin_db_install();
284
- }
285
-
286
- // 0.8.3 bug fix - bug fix for duplicated contacts that should be merged
287
- if ( ! isset($options['delete_flags_fixed']) )
288
- {
289
- leadin_delete_flag_fix();
290
- }
291
-
292
- // Set the plugin version
293
- leadin_update_option('leadin_options', 'leadin_version', LEADIN_PLUGIN_VERSION);
294
  }
295
 
296
  //=============================================
@@ -380,4 +286,18 @@ function leadin_db_install ()
380
  leadin_update_option('leadin_options', 'li_db_version', LEADIN_DB_VERSION);
381
  }
382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  ?>
3
  Plugin Name: LeadIn
4
  Plugin URI: http://leadin.com
5
  Description: LeadIn is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
6
+ Version: 2.0.1
7
  Author: Andy Cook, Nelson Joyce
8
  Author URI: http://leadin.com
9
  License: GPL2
26
  define('LEADIN_DB_VERSION', '2.0.0');
27
 
28
  if ( !defined('LEADIN_PLUGIN_VERSION') )
29
+ define('LEADIN_PLUGIN_VERSION', '2.0.1');
30
 
31
  if ( !defined('MIXPANEL_PROJECT_TOKEN') )
32
  define('MIXPANEL_PROJECT_TOKEN', 'a9615503ec58a6bce2c646a58390eac1');
41
  require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin-updater.php');
42
  require_once(LEADIN_PLUGIN_DIR . '/admin/leadin-admin.php');
43
 
 
44
  require_once(LEADIN_PLUGIN_DIR . '/lib/mixpanel/LI_Mixpanel.php');
45
  require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin.php');
46
 
47
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
48
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
49
+ require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php');
50
+ require_once(LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php');
51
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php');
52
 
53
  //=============================================
54
  // Hooks & Filters
55
  //=============================================
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  // Activate + install LeadIn
58
  register_activation_hook( __FILE__, 'activate_leadin');
59
 
117
  'ignore_settings_popup' => 0,
118
  'data_recovered' => 1,
119
  'delete_flags_fixed' => 1,
120
+ 'beta_tester' => 0,
121
+ 'converted_to_tags' => 1
122
  );
123
 
124
  update_option('leadin_options', $opt);
194
  /**
195
  * Checks the stored database version against the current data version + updates if needed
196
  */
197
+ function leadin_init ()
198
  {
 
 
199
  $leadin_wp = new WPLeadIn();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
  //=============================================
286
  leadin_update_option('leadin_options', 'li_db_version', LEADIN_DB_VERSION);
287
  }
288
 
289
+ add_action( 'plugins_loaded', 'leadin_init', 14 );
290
+
291
+ if ( is_admin() )
292
+ {
293
+ // Activate + install LeadIn
294
+ register_activation_hook( __FILE__, 'activate_leadin');
295
+
296
+ // Deactivate LeadIn
297
+ register_deactivation_hook( __FILE__, 'deactivate_leadin');
298
+
299
+ // Activate on newly created wpmu blog
300
+ add_action('wpmu_new_blog', 'activate_leadin_on_new_blog', 10, 6);
301
+ }
302
+
303
  ?>
power-ups/constant-contact-connect.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Power-up Name: Contact Connect
4
+ * Power-up Class: WPConstantContactConnect
5
+ * Power-up Menu Text:
6
+ * Power-up Slug: constant_contact_connect
7
+ * Power-up Menu Link: settings
8
+ * Power-up URI: http://leadin.com/mailchimp-list-sync
9
+ * Power-up Description: Push your contacts to Constant Contact email lists.
10
+ * Power-up Icon: power-up-icon-constant-contact-connect
11
+ * Power-up Icon Small: power-up-icon-constant-contact-connect_small
12
+ * First Introduced: 0.8.0
13
+ * Power-up Tags: Newsletter, Email
14
+ * Auto Activate: No
15
+ * Permanently Enabled: No
16
+ * Hidden: No
17
+ */
18
+
19
+ //=============================================
20
+ // Define Constants
21
+ //=============================================
22
+
23
+ if ( !defined('LEADIN_CONSTANT_CONTACT_CONNECT_PATH') )
24
+ define('LEADIN_CONSTANT_CONTACT_CONNECT_PATH', LEADIN_PATH . '/power-ups/constant-contact-connect');
25
+
26
+ if ( !defined('LEADIN_CONSTANT_CONTACT_CONNECT_PLUGIN_DIR') )
27
+ define('LEADIN_CONSTANT_CONTACT_CONNECT_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect');
28
+
29
+ if ( !defined('LEADIN_CONSTANT_CONTACT_CONNECT_PLUGIN_SLUG') )
30
+ define('LEADIN_CONSTANT_CONTACT_CONNECT_SLUG', basename(dirname(__FILE__)));
31
+
32
+ if ( !defined('LEADIN_CONSTANT_CONTACT_API_KEY') )
33
+ define('LEADIN_CONSTANT_CONTACT_API_KEY', 'p5hrzdhe2zrwbm76r2u7pvtc');
34
+
35
+
36
+
37
+ //=============================================
38
+ // Include Needed Files
39
+ //=============================================
40
+ require_once(LEADIN_CONSTANT_CONTACT_CONNECT_PLUGIN_DIR . '/admin/constant-contact-connect-admin.php');
41
+ require_once(LEADIN_CONSTANT_CONTACT_CONNECT_PLUGIN_DIR . '/inc/li_constant_contact.php');
42
+
43
+ //=============================================
44
+ // WPLeadIn Class
45
+ //=============================================
46
+ class WPConstantContactConnect extends WPLeadIn {
47
+
48
+ var $admin;
49
+ var $options;
50
+ var $constant_contact;
51
+ var $cc_id;
52
+
53
+ /**
54
+ * Class constructor
55
+ */
56
+ function __construct ( $activated )
57
+ {
58
+ //=============================================
59
+ // Hooks & Filters
60
+ //=============================================
61
+
62
+ if ( ! $activated )
63
+ return false;
64
+
65
+ global $leadin_constant_contact_connect_wp;
66
+ $leadin_constant_contact_connect_wp = $this;
67
+ $this->options = get_option('leadin_cc_options');
68
+ }
69
+
70
+ public function admin_init ( )
71
+ {
72
+ $admin_class = get_class($this) . 'Admin';
73
+ $this->admin = new $admin_class($this->icon_small);
74
+ }
75
+
76
+ function power_up_setup_callback ( )
77
+ {
78
+ $this->admin->power_up_setup_callback();
79
+ }
80
+
81
+ /**
82
+ * Activate the power-up and add the defaults
83
+ */
84
+ function add_defaults ()
85
+ {
86
+
87
+ }
88
+
89
+ /**
90
+ * Adds a subcsriber to a specific list
91
+ *
92
+ * @param string
93
+ * @param string
94
+ * @param string
95
+ * @param string
96
+ * @param string
97
+ * @return int ContactID for the new entry
98
+ */
99
+ function push_contact_to_list ( $list_id = '', $email = '', $first_name = '', $last_name = '', $phone = '' )
100
+ {
101
+ if ( isset($this->options['li_cc_email']) && isset($this->options['li_cc_password']) && $this->options['li_cc_email'] && $this->options['li_cc_password'] )
102
+ {
103
+ // Convert the stored list id integer into the accepted constant contact list id format
104
+ $list_id = 'http://api.constantcontact.com/ws/customers/' . str_replace('@', '%40', $this->options['li_cc_email']) . '/lists/' . $list_id;
105
+
106
+ $this->constant_contact = new LI_ConstantContact($this->options['li_cc_email'], $this->options['li_cc_password'], LEADIN_CONSTANT_CONTACT_API_KEY, FALSE);
107
+
108
+ if ( ! isset($this->cc_id) )
109
+ {
110
+ $this->cc_id = $this->constant_contact->search_contact_by_email($email);
111
+ }
112
+
113
+ if ( $this->cc_id )
114
+ return $this->constant_contact->add_subscription($this->cc_id, $list_id, 'ACTION_BY_CLIENT');
115
+ else
116
+ {
117
+ $contact = array();
118
+ if ( $email )
119
+ $contact['EmailAddress'] = $email;
120
+
121
+ if ( $first_name )
122
+ $contact['FirstName'] = $first_name;
123
+
124
+ if ( $last_name )
125
+ $contact['LastName'] = $last_name;
126
+
127
+ if ( $phone )
128
+ $contact['HomePhone'] = $phone;
129
+
130
+ if ( $phone )
131
+ $contact['WorkPhone'] = $phone;
132
+
133
+ return $this->constant_contact->add_contact($contact, array($list_id));
134
+ }
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Removes an email address from a specific list
140
+ *
141
+ * @param string
142
+ * @param string
143
+ * @return bool
144
+ */
145
+ function remove_contact_from_list ( $list_id = '', $email = '' )
146
+ {
147
+ if ( isset($this->options['li_cc_email']) && isset($this->options['li_cc_password']) && $this->options['li_cc_email'] && $this->options['li_cc_password'] )
148
+ {
149
+ // Convert the stored list id integer into the accepted constant contact list id format
150
+ $list_id = 'http://api.constantcontact.com/ws/customers/' . str_replace('@', '%40', $this->options['li_cc_email']) . '/lists/' . $list_id;
151
+
152
+ $this->constant_contact = new LI_ConstantContact($this->options['li_cc_email'], $this->options['li_cc_password'], LEADIN_CONSTANT_CONTACT_API_KEY, FALSE);
153
+ $cc_id = $this->constant_contact->search_contact_by_email($email);
154
+
155
+ if ( $cc_id )
156
+ return $this->constant_contact->remove_subscription($cc_id, $list_id);
157
+ else
158
+ return FALSE;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Adds a subcsriber to a specific list
164
+ *
165
+ * @param string
166
+ * @param array
167
+ * @return int/bool API status code OR false if api key not set
168
+ */
169
+ function bulk_push_contact_to_list ( $list_id = '', $contacts = '' )
170
+ {
171
+ /*
172
+ The majority of our user base doesn't use Constant Contact, so we decided not to retroactively sync contacts to the list.
173
+ If people complain, we will respond with a support ticket and ask them to export/import manually.
174
+ */
175
+
176
+ return FALSE;
177
+ }
178
+ }
179
+
180
+ //=============================================
181
+ // Subscribe Widget Init
182
+ //=============================================
183
+
184
+ global $leadin_constant_contact_connect_wp;
185
+
186
+ ?>
power-ups/constant-contact-connect/admin/constant-contact-connect-admin.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //=============================================
3
+ // WPLeadInAdmin Class
4
+ //=============================================
5
+ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
6
+
7
+ var $power_up_settings_section = 'leadin_cc_options_section';
8
+ var $power_up_icon;
9
+ var $bad_api_call;
10
+ var $constant_contact;
11
+ var $lists;
12
+ var $options;
13
+ var $authed = FALSE;
14
+
15
+ /**
16
+ * Class constructor
17
+ */
18
+ function __construct ( $power_up_icon_small )
19
+ {
20
+ global $pagenow;
21
+
22
+ //=============================================
23
+ // Hooks & Filters
24
+ //=============================================
25
+
26
+ if ( is_admin() )
27
+ {
28
+ $this->power_up_icon = $power_up_icon_small;
29
+ add_action('admin_init', array($this, 'leadin_cc_build_settings_page'));
30
+ $this->options = get_option('leadin_cc_options');
31
+ if ( isset($this->options['li_cc_email']) && isset($this->options['li_cc_password']) && $this->options['li_cc_email'] && $this->options['li_cc_password'] )
32
+ $this->authed = TRUE;
33
+ }
34
+ }
35
+
36
+ //=============================================
37
+ // Settings Page
38
+ //=============================================
39
+
40
+ /**
41
+ * Creates settings options
42
+ */
43
+ function leadin_cc_build_settings_page ()
44
+ {
45
+ global $leadin_constant_contact_connect_wp;
46
+
47
+ register_setting('leadin_settings_options', 'leadin_cc_options', array($this, 'sanitize'));
48
+
49
+ // If the creds are set, check if they are any good by hitting the API
50
+ if ( $this->authed )
51
+ {
52
+ // Try to make a request using the authentication credentials
53
+ $this->lists = $this->li_cc_get_email_lists(LEADIN_CONSTANT_CONTACT_API_KEY, $this->options['li_cc_email'], $this->options['li_cc_password']);
54
+
55
+ if ( $this->constant_contact->cc_exception )
56
+ {
57
+ $this->bad_api_call = TRUE;
58
+ }
59
+ }
60
+
61
+ add_settings_section($this->power_up_settings_section, $this->power_up_icon . "Constant Contact", array($this, 'cc_section_callback'), LEADIN_ADMIN_PATH);
62
+
63
+ if ( $this->authed && ! $this->bad_api_call )
64
+ add_settings_field('li_print_synced_lists', 'Synced tags', array($this, 'li_print_synced_lists'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
65
+ else
66
+ {
67
+ add_settings_field('li_cc_email', 'Email', array($this, 'li_cc_email_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
68
+ add_settings_field('li_cc_password', 'Password', array($this, 'li_cc_password_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
69
+ }
70
+ }
71
+
72
+ function cc_section_callback ( )
73
+ {
74
+ if ( ! $this->authed )
75
+ echo '<div class="leadin-section">Sign into your Constant Contact account below to setup Contact Sync</div>';
76
+ else if ( $this->bad_api_call )
77
+ echo '<div class="leadin-section"><p style="color: #f33f33; font-weight: bold;">' . $this->constant_contact->cc_exception . '</p></div>';
78
+
79
+ $this->print_hidden_settings_fields();
80
+ }
81
+
82
+ function print_hidden_settings_fields ()
83
+ {
84
+ // Hacky solution to solve the Settings API overwriting the default values
85
+ $li_cc_email = ( $this->options['li_cc_email'] ? $this->options['li_cc_email'] : '' );
86
+ $li_cc_password = ( $this->options['li_cc_password'] ? $this->options['li_cc_password'] : '' );
87
+
88
+ if ( $li_cc_email )
89
+ {
90
+ printf(
91
+ '<input id="li_cc_email" type="hidden" name="leadin_cc_options[li_cc_email]" value="%s"/>',
92
+ $li_cc_email
93
+ );
94
+ }
95
+
96
+ if ( $li_cc_password )
97
+ {
98
+ printf(
99
+ '<input id="li_cc_password" type="hidden" name="leadin_cc_options[li_cc_password]" value="%s"/>',
100
+ $li_cc_password
101
+ );
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Sanitize each setting field as needed
107
+ *
108
+ * @param array $input Contains all settings fields as array keys
109
+ */
110
+ public function sanitize ( $input )
111
+ {
112
+ $new_input = array();
113
+
114
+ if( isset( $input['li_cc_email'] ) )
115
+ $new_input['li_cc_email'] = sanitize_text_field( $input['li_cc_email'] );
116
+
117
+ if( isset( $input['li_cc_password'] ) )
118
+ $new_input['li_cc_password'] = sanitize_text_field( $input['li_cc_password'] );
119
+
120
+ if( isset( $input['li_cc_subscribers_to_list'] ) )
121
+ $new_input['li_cc_subscribers_to_list'] = sanitize_text_field( $input['li_cc_subscribers_to_list'] );
122
+
123
+ return $new_input;
124
+ }
125
+
126
+ /**
127
+ * Prints email input for settings page
128
+ */
129
+ function li_cc_email_callback ()
130
+ {
131
+ $li_cc_email = ( $this->options['li_cc_email'] ? $this->options['li_cc_email'] : '' ); // Get header from options, or show default
132
+
133
+ printf(
134
+ '<input id="li_cc_email" type="text" id="title" name="leadin_cc_options[li_cc_email]" value="%s" size="50"/>',
135
+ $li_cc_email
136
+ );
137
+ }
138
+
139
+ /**
140
+ * Prints password input for settings page
141
+ */
142
+ function li_cc_password_callback ()
143
+ {
144
+ $li_cc_password = ( $this->options['li_cc_password'] ? $this->options['li_cc_password'] : '' ); // Get header from options, or show default
145
+
146
+ printf(
147
+ '<input id="li_cc_password" type="password" id="title" name="leadin_cc_options[li_cc_password]" value="%s" size="50"/>',
148
+ $li_cc_password
149
+ );
150
+ }
151
+
152
+ /**
153
+ * Prints email input for settings page
154
+ */
155
+ function li_cc_subscribers_to_list_callback ()
156
+ {
157
+ $li_cc_subscribers_to_list = ( isset($this->options['li_cc_subscribers_to_list']) ? $this->options['li_cc_subscribers_to_list'] : '' ); // Get header from options, or show default
158
+
159
+ echo '<select id="li_cc_subscribers_to_list" name="leadin_cc_options[li_cc_subscribers_to_list]" ' . ( ! count($this->lists) ? 'disabled' : '' ) . '>';
160
+
161
+ if ( count($this->lists) )
162
+ {
163
+ $list_set = FALSE;
164
+
165
+ foreach ( $this->lists as $list )
166
+ {
167
+ // Skip over default lists
168
+ if ( $list['Name'] == 'Active' || $list['Name'] == 'Do Not Mail' || $list['Name'] == 'Removed' )
169
+ continue;
170
+
171
+ if ( urldecode($list['ListID']) == $li_cc_subscribers_to_list && !$list_set )
172
+ $list_set = TRUE;
173
+
174
+ echo '<option ' . ( urldecode($list['ListID']) == $li_cc_subscribers_to_list ? 'selected' : '' ) . ' value="' . urldecode($list['ListID']) . '">' . $list['Name'] . '</option>';
175
+ }
176
+
177
+ if ( !$list_set )
178
+ echo '<option selected value="">No list set...</option>';
179
+ }
180
+ else
181
+ {
182
+ echo '<option value="No lists...">No lists...</option>';
183
+ }
184
+
185
+ echo '</select>';
186
+ echo '<p><a href="https://login.constantcontact.com/login/login.sdo?goto=https://ui.constantcontact.com/rnavmap/distui/contacts" target="_blank">Create a new list on ConstantContact.com</a></p>';
187
+ }
188
+
189
+ function li_cc_get_email_lists ( $api_key, $username, $password )
190
+ {
191
+ $this->constant_contact = new LI_ConstantContact($username, $password, $api_key, FALSE);
192
+ $lists = $this->constant_contact->get_lists();
193
+
194
+ if ( count($lists) )
195
+ return $lists;
196
+ else
197
+ return FALSE;
198
+ }
199
+
200
+ /**
201
+ * Prints synced lists with tag name
202
+ */
203
+ function li_print_synced_lists ()
204
+ {
205
+ $synced_lists = $this->li_get_synced_list_for_esp('constant_contact');
206
+ $list_value_pairs = array();
207
+ $synced_list_count = 0;
208
+
209
+ echo '<table>';
210
+ foreach ( $synced_lists as $synced_list )
211
+ {
212
+ foreach ( stripslashes_deep(unserialize($synced_list->tag_synced_lists)) as $tag_synced_list )
213
+ {
214
+ if ( $tag_synced_list['esp'] == 'constant_contact' )
215
+ {
216
+ echo '<tr class="synced-list-row">';
217
+ echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
218
+ echo '<td class="synced-list-cell"><span class="synced-list-arrow">&#8594;</span></td>';
219
+ echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
220
+ echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts&action=edit_tag&tag=' . $synced_list->tag_id . '">edit</a></td>';
221
+ echo '</tr>';
222
+
223
+ $synced_list_count++;
224
+ }
225
+ }
226
+ }
227
+ echo '</table>';
228
+
229
+ if ( ! $synced_list_count )
230
+ echo "<p>You don't have any Constant Contact lists synced with LeadIn yet...</p>";
231
+
232
+ echo '<p><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts&action=manage_tags' . '">Manage tags</a></p>';
233
+
234
+ echo '<p style="padding-top: 10px;"><a href="https://login.constantcontact.com/login/login.sdo?goto=https://ui.constantcontact.com/rnavmap/distui/contacts" target="_blank">Create a new list on ConstantContact.com</a></p>';
235
+ }
236
+
237
+ function li_get_synced_list_for_esp ( $esp_name, $output_type = 'OBJECT' )
238
+ {
239
+ global $wpdb;
240
+
241
+ $q = $wpdb->prepare("SELECT * FROM $wpdb->li_tags WHERE tag_synced_lists LIKE '%%%s%%' AND tag_deleted = 0", $esp_name);
242
+ $synced_lists = $wpdb->get_results($q, $output_type);
243
+
244
+ return $synced_lists;
245
+ }
246
+
247
+ function li_get_lists ( )
248
+ {
249
+ $lists = $this->li_cc_get_email_lists(LEADIN_CONSTANT_CONTACT_API_KEY, $this->options['li_cc_email'], $this->options['li_cc_password']);
250
+
251
+ $sanitized_lists = array();
252
+ if ( count($lists) )
253
+ {
254
+ foreach ( $lists as $list )
255
+ {
256
+ $list_obj = (Object)NULL;
257
+ $list_obj->id = $list['ListID'];
258
+ $list_obj->name = $list['Name'];
259
+
260
+ array_push($sanitized_lists, $list_obj);;
261
+ }
262
+ }
263
+
264
+ return $sanitized_lists;
265
+ }
266
+ }
267
+
268
+ ?>
power-ups/constant-contact-connect/inc/li_constant_contact.php ADDED
@@ -0,0 +1,1123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ global $cc_exception;
4
+
5
+ class LI_ConstantContact
6
+ {
7
+ var $auth;
8
+ var $api;
9
+ var $debug;
10
+ var $cc_exception;
11
+
12
+ /**
13
+ * The ConstantContact contructor
14
+ *
15
+ * @param String $username - Your username
16
+ * @param String $password - Your password
17
+ * @param String $api_key - Your API Key
18
+ * @param Boolean $debug - Whether or not debugging output is displayed
19
+ * @param String $debug_style - Options are "cli" or "html". All it does is print "\n" or "<br>" for debugging output.
20
+ */
21
+
22
+ public function __construct ( $username = '', $password = '', $api_key = '', $debug_enabled = FALSE, $debug_style = 'html' )
23
+ {
24
+ $this->debug['enabled'] = $debug_enabled;
25
+ $this->debug['style'] = $debug_style;
26
+ $this->debug['last_response'] = 0;
27
+ $this->auth['username'] = $username;
28
+ $this->auth['password'] = $password;
29
+ $this->auth['api_key'] = $api_key;
30
+ $this->api['url'] = 'https://api.constantcontact.com/ws/customers/'.$username.'/';
31
+ $this->api['inner_url'] = 'http://api.constantcontact.com/ws/customers/'.$username.'/';
32
+ $this->api['relative_url'] = '/ws/customers/'.$username.'/';
33
+ }
34
+
35
+ //Main Functions
36
+
37
+ /**
38
+ * Print debugging output
39
+ *
40
+ * @param String $string - String to print
41
+ */
42
+ private function debug_print($string)
43
+ {
44
+ if($this->debug['enabled'])
45
+ {
46
+ $line_end = "\n";
47
+ if ($this->debug['style'] == 'html')
48
+ $line_end = "<br>";
49
+ print "ConstantContact Debug: $string{$line_end}";
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Fetch a URI from ConstantContact
55
+ *
56
+ * @param String $url - URL to connect to
57
+ * @param String $post - POST data to include
58
+ * @param String $fetch_as - Either array or xml for the return object
59
+ * @param String $call_type - NORMAL,PUT,DELETE
60
+ * @return Respose
61
+ */
62
+ private function fetch($url,$post,$fetch_as='array',$call_type='NORMAL')
63
+ {
64
+ $this->debug_print("------------------ fetch ------------------");
65
+
66
+ $credentials=$this->auth['api_key'].'%'.$this->auth['username'].':'.$this->auth['password'];
67
+
68
+ $this->debug_print("Connecting to '".$url."'");
69
+ $this->debug_print("With Credentials '".$credentials."'");
70
+
71
+ $ch=curl_init();
72
+
73
+ curl_setopt($ch, CURLOPT_URL, $url);
74
+ curl_setopt($ch, CURLOPT_USERPWD, $credentials);
75
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
76
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
77
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
78
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
79
+
80
+ if(strlen(trim($post))>0)
81
+ {
82
+ if ($this->debug['style'] == 'cli')
83
+ $this->debug_print("And Posting:\n\n---START---\n".$post."\n---END---\n\n");
84
+ elseif ($this->debug['style'] == 'html')
85
+ $this->debug_print("And Posting:<pre>\n\n---START---\n".htmlspecialchars($post)."\n---END---\n\n</pre>");
86
+ if ($call_type == 'PUT')
87
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
88
+ elseif ($call_type == 'DELETE')
89
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
90
+ else
91
+ curl_setopt($ch, CURLOPT_POST, 1);
92
+
93
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
94
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/atom+xml'));
95
+ }
96
+ else
97
+ {
98
+ $this->debug_print("Not posting");
99
+ curl_setopt($ch, CURLOPT_POST, 0);
100
+ if ($call_type == 'PUT')
101
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
102
+ elseif ($call_type == 'DELETE')
103
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
104
+ }
105
+
106
+ curl_setopt($ch, CURLOPT_HEADER, 0);
107
+
108
+
109
+
110
+ $response = curl_exec($ch);
111
+ $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
112
+ $this->debug_print("HTTP Response Code '".$response_code."'");
113
+
114
+ if ( ! in_array($response_code, array('201', '200', '204')) )
115
+ {
116
+ if ( $response_code == 401 )
117
+ {
118
+ $this->cc_exception = "Sorry, that username and password combination isn't right";
119
+ }
120
+ else if ( $response_code == 403 )
121
+ {
122
+ $this->cc_exception = "Your account is locked due to too many bad logins. You can try <a href='https://login.constantcontact.com/login/pwreset.sdo' target='_blank'>resetting your Constant Contact password</a> to unlock your account";
123
+ }
124
+ }
125
+
126
+ $this->debug['last_response'] = $response_code;
127
+
128
+ if ($this->debug['style'] == 'cli')
129
+ $this->debug_print("Received:\n\n---START---\n".$response."\n---END---\n\n");
130
+ elseif ($this->debug['style'] == 'html')
131
+ $this->debug_print("Received:<pre>\n\n---START---\n".htmlspecialchars($response)."\n---END---\n\n</pre>");
132
+
133
+ curl_close($ch);
134
+
135
+ if ($fetch_as == 'array')
136
+ return $this->xml_to_array($response);
137
+ else
138
+ return $response;
139
+ }
140
+
141
+ /**
142
+ * Converts XML data into a nested array
143
+ *
144
+ * @param String $contents - XML string
145
+ * @param Integers $get_attributes - Include attributes (default 1)
146
+ * @return Nested associative array
147
+ */
148
+ public function xml_to_array($contents, $get_attributes=1)
149
+ {
150
+ if (!$contents)
151
+ return array();
152
+
153
+ if (!function_exists('xml_parser_create'))
154
+ {
155
+ $this->debug_print("ERROR: xml_parser_create function doesn't exist!");
156
+ return array();
157
+ }
158
+
159
+ $parser = xml_parser_create();
160
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
161
+ xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
162
+ xml_parse_into_struct( $parser, $contents, $xml_values );
163
+ xml_parser_free( $parser );
164
+
165
+ if (!$xml_values)
166
+ {
167
+ $this->debug_print("WARN: Could not parse xml_values!");
168
+ return;
169
+ }
170
+
171
+ $xml_array = array();
172
+ $parents = array();
173
+ $opened_tags = array();
174
+ $arr = array();
175
+
176
+ $current = &$xml_array;
177
+
178
+ foreach( $xml_values as $data)
179
+ {
180
+ unset($attributes,$value);
181
+ extract($data);
182
+
183
+ $result = '';
184
+ if ($get_attributes)
185
+ {
186
+ $result = array();
187
+ if (isset($value))
188
+ $result['value'] = $value;
189
+ if (isset($attributes))
190
+ {
191
+ foreach ($attributes as $attr => $val)
192
+ {
193
+ if ($get_attributes == 1)
194
+ $result['attr'][$attr] = $val;
195
+ }
196
+ }
197
+ }
198
+ elseif (isset($value))
199
+ $result = $value;
200
+
201
+ if ($type == "open")
202
+ {
203
+ $parent[$level-1] = &$current;
204
+ if (!is_array($current) || !in_array($tag, array_keys($current)))
205
+ {
206
+ $current[$tag] = $result;
207
+ $current = &$current[$tag];
208
+ }
209
+ else
210
+ {
211
+ if (isset($current[$tag][0]))
212
+ array_push($current[$tag], $result);
213
+ else
214
+ $current[$tag] = array($current[$tag],$result);
215
+
216
+ $last = count($current[$tag]) - 1;
217
+ $current = &$current[$tag][$last];
218
+ }
219
+ }
220
+ elseif ($type == "complete")
221
+ {
222
+ if (!isset($current[$tag]))
223
+ $current[$tag] = $result;
224
+ else
225
+ {
226
+ if ((is_array($current[$tag]) and $get_attributes == 0) || (isset($current[$tag][0]) and is_array($current[$tag][0]) and $get_attributes == 1))
227
+ array_push($current[$tag],$result);
228
+ else
229
+ $current[$tag] = array($current[$tag],$result);
230
+ }
231
+ }
232
+ elseif ($type == 'close')
233
+ $current = &$parent[$level-1];
234
+ }
235
+ return($xml_array);
236
+ }
237
+
238
+ /**
239
+ * Converts id URL to numeric id
240
+ *
241
+ * @param String $url - ID URL
242
+ * @return Numeric ID
243
+ */
244
+ public function id_from_url($url)
245
+ {
246
+ $temp = Array();
247
+ $temp = explode('/',trim($url));
248
+ return trim($temp[count($temp)-1]);
249
+ }
250
+
251
+ /**
252
+ * Retrieves the XML service document
253
+ *
254
+ * @return XML service document
255
+ */
256
+ public function get_service_doc_xml()
257
+ {
258
+ $url=$this->api_url;
259
+ $post='';
260
+ $response=$this->fetch($url,$post,'xml');
261
+ return $response;
262
+ }
263
+
264
+
265
+ //Contact Functions
266
+
267
+ /**
268
+ * Formats a contact array into the format we always return as
269
+ * Note:
270
+ * I like to do this because the atom specification has so much extraneous data
271
+ * that I just don't care about. This makes a sane array out of what is
272
+ * incredibly overcomplicated in my opinion.
273
+ *
274
+ * @param Array - Contact array as returned from fetch/xml_to_array
275
+ * @return Associative array in the format returned by this api
276
+ */
277
+ public function format_contact($response)
278
+ {
279
+ $my_data = Array();
280
+ $my_data = $response['entry']['content']['Contact'];
281
+ $d = Array();
282
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
283
+ unset($my_data['attr']);
284
+ foreach ($my_data as $dkey => $dval)
285
+ {
286
+ if ($dkey != 'ContactLists')
287
+ $d[$dkey] = $dval['value'];
288
+ else
289
+ {
290
+ $entries = Array();
291
+ if (isset($dval['ContactList']['link']))
292
+ $entries[] = $dval['ContactList'];
293
+ else
294
+ $entries = $dval['ContactList'];
295
+
296
+ foreach ($entries as $entry)
297
+ {
298
+ $e = Array();
299
+ $e['ListID'] = $this->id_from_url($entry['attr']['id']);
300
+ unset($entry['attr']);
301
+ unset($entry['link']);
302
+ foreach ($entry as $ekey => $eval)
303
+ $e[$ekey] = $eval['value'];
304
+ $d[$dkey][] = $e;
305
+ }
306
+ }
307
+ }
308
+ return $d;
309
+ }
310
+
311
+ /**
312
+ * Return your list of contacts.
313
+ *
314
+ * @param String $key - Optionally specify a key to use for the array
315
+ * @param Boolean $unique - Whether the key you specified is unique
316
+ * @return Associative array containing your contacts indexed by whatever key specified.
317
+ */
318
+ public function get_contacts($key='',$unique=true)
319
+ {
320
+ $ret = Array();
321
+
322
+ $url = $this->api['url'].'contacts';
323
+ $post = '';
324
+ $response = Array();
325
+ $response = $this->fetch($url,$post);
326
+
327
+ $entries = Array();
328
+ if (isset($response['feed']['entry']['link']))
329
+ $entries[] = $response['feed']['entry'];
330
+ else
331
+ $entries = $response['feed']['entry'];
332
+ foreach ($entries as $data)
333
+ {
334
+ $my_data = Array();
335
+ $my_data = $data['content']['Contact'];
336
+ $d = Array();
337
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
338
+ unset($my_data['attr']);
339
+ foreach ($my_data as $dkey => $dval)
340
+ $d[$dkey] = $dval['value'];
341
+
342
+ if ($key)
343
+ {
344
+ if ($unique)
345
+ $ret[$d[$key]] = $d;
346
+ else
347
+ $ret[$d[$key]][] = $d;
348
+ }
349
+ else
350
+ $ret[] = $d;
351
+ }
352
+ return $ret;
353
+ }
354
+
355
+ /**
356
+ * Add a contact
357
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
358
+ *
359
+ * @param Array $data - An associative array containing all the contact data to add
360
+ * @param Array $lists - An array of list_ids to add this contact to
361
+ * @return Integer - ContactID for the new entry
362
+ */
363
+ public function add_contact($data,$lists)
364
+ {
365
+
366
+ $updated = date('Y-m-d\TH:i:s\Z');
367
+ $xml_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><entry xmlns='http://www.w3.org/2005/Atom'></entry>";
368
+ $xml_object = simplexml_load_string($xml_string);
369
+ $xml_object->addChild("title");
370
+ $xml_object->addChild("updated",$updated);
371
+ $author_node = $xml_object->addChild("author");
372
+ $author_node->addChild("name", ("CTCT Samples"));
373
+ $xml_object->addChild("id", 'data:,none');
374
+ $summary_node = $xml_object->addChild("summary");
375
+ $summary_node->addAttribute("type", "text");
376
+ $content_node = $xml_object->addChild("content");
377
+ $content_node->addAttribute("type", "application/vnd.ctct+xml");
378
+ $contact_node = $content_node->addChild("Contact");
379
+ $contact_node->addAttribute("xmlns", "http://ws.constantcontact.com/ns/1.0/");
380
+ $contact_node->addChild("OptInSource", 'ACTION_BY_CUSTOMER');
381
+
382
+ foreach ( $data as $key => $val )
383
+ {
384
+ $contact_node->addChild($key, $val);
385
+ }
386
+
387
+ $contactlists_node = $contact_node->addChild("ContactLists");
388
+ foreach ( $lists as $list )
389
+ {
390
+ $listNode = $contactlists_node->addChild("ContactList");
391
+ $listNode->addAttribute("id", $list);
392
+ }
393
+
394
+ $entry = $xml_object->asXML();
395
+
396
+ $url= $this->api['url'].'contacts';
397
+
398
+ $response = Array();
399
+ $response = $this->fetch($url, $entry);
400
+ if ( $this->debug['last_response'] <= 204 )
401
+ return $this->id_from_url($response['entry']['id']['value']);
402
+ else
403
+ return false;
404
+ }
405
+
406
+ /**
407
+ * Returns detailed info for a particular contact.
408
+ *
409
+ * @param Integer $id - Contact ID of the contact requested.
410
+ * @return Associative array containing the contact's details
411
+ */
412
+ public function get_contact($id)
413
+ {
414
+ $url = $this->api['url'].'contacts/'.$id;
415
+ $post = '';
416
+ $contact = Array();
417
+ $contact = $this->format_contact($this->fetch($url,$post));
418
+
419
+ if ($this->debug['last_response'] <= 204)
420
+ return $contact;
421
+ else
422
+ return false;
423
+ }
424
+
425
+ /**
426
+ * Edit a contact
427
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
428
+ *
429
+ * @param Integer $id - Contact ID of the contact to edit
430
+ * @param Array $data - An associative array containing all the contact data to edit
431
+ * @return Boolean - True on success and false on failure
432
+ */
433
+ public function edit_contact($id,$data)
434
+ {
435
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
436
+ $url = $this->api['url'].'contacts/'.$id;
437
+ $post = '';
438
+ $post = $this->fetch($url,$post,'xml');
439
+
440
+ foreach ($data as $key => $val)
441
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
442
+
443
+ $this->fetch($url,$post,'array','PUT');
444
+
445
+ if ($this->debug['last_response'] <= 204)
446
+ return true;
447
+ else
448
+ return false;
449
+ }
450
+
451
+ /**
452
+ * Delete a contact
453
+ *
454
+ * @param Integer $id - Contact ID of the contact to delete
455
+ * @return Boolean - True on success and false on failure
456
+ */
457
+ public function delete_contact($id)
458
+ {
459
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
460
+ $url = $this->api['url'].'contacts/'.$id;
461
+ $post = '';
462
+ $this->fetch($url,$post,'array','DELETE');
463
+
464
+ if ($this->debug['last_response'] <= 204)
465
+ return true;
466
+ else
467
+ return false;
468
+ }
469
+
470
+
471
+ /**
472
+ * Search for a contact by email
473
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
474
+ *
475
+ * @param String $email - Email address of the contact to search for
476
+ * @param Boolean $id_only - If true will return ContactID found otherwise will return all contact info
477
+ * @return Integer of found ContactID or Associative Array of contact info for found contact
478
+ */
479
+ public function search_contact_by_email($email,$id_only=true)
480
+ {
481
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
482
+ $url = $this->api['url'].'contacts?email='.urlencode(strtolower($email));
483
+ $post = '';
484
+ $response = Array();
485
+ $response = $this->fetch($url,$post);
486
+
487
+ if ($this->debug['last_response'] <= 204)
488
+ {
489
+ if ($id_only)
490
+ {
491
+ return $this->id_from_url($response['feed']['entry']['id']['value']);
492
+ }
493
+ else
494
+ {
495
+ return $this->get_contact($this->id_from_url($response['feed']['entry']['id']['value']));
496
+ }
497
+ }
498
+ else
499
+ return false;
500
+ }
501
+
502
+ /**
503
+ * Returns contacts updated since date your list of contacts.
504
+ *
505
+ * @param Date $date - Date should be in the format "Y-m-d H:i:s" (this is the datetime mysql spec)
506
+ * @param String $list_type - Type of contact to query for: active,removed,do-not-mail
507
+ * @param String $key - Optionally specify a key to use for the array
508
+ * @param Boolean $unique - Whether the key you specified is unique
509
+ * @return Associative array containing your contacts indexed by whatever key specified.
510
+ */
511
+ public function search_contacts_by_date($date,$list_type='active',$key='',$unique=true)
512
+ {
513
+ //Format date to UTC atom spec
514
+ $atom_date = date('Y-m-d\TH:i:s\Z',strtotime($date)+date("Z"));
515
+
516
+ $ret = Array();
517
+
518
+ $url = $this->api['url'].'contacts?updatedsince='.$atom_date.'&listtype='.$list_type;
519
+ $post = '';
520
+ $response = Array();
521
+ $response = $this->fetch($url,$post);
522
+
523
+ $entries = Array();
524
+ if (isset($response['feed']['entry']['link']))
525
+ $entries[] = $response['feed']['entry'];
526
+ else
527
+ $entries = $response['feed']['entry'];
528
+ foreach ($entries as $data)
529
+ {
530
+ $my_data = Array();
531
+ $my_data = $data['content']['Contact'];
532
+ $d = Array();
533
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
534
+ unset($my_data['attr']);
535
+ foreach ($my_data as $dkey => $dval)
536
+ $d[$dkey] = $dval['value'];
537
+
538
+ if ($key)
539
+ {
540
+ if ($unique)
541
+ $ret[$d[$key]] = $d;
542
+ else
543
+ $ret[$d[$key]][] = $d;
544
+ }
545
+ else
546
+ $ret[] = $d;
547
+ }
548
+ return $ret;
549
+ }
550
+
551
+ //List Functions
552
+
553
+ /**
554
+ * Formats a list array into the format we always return as
555
+ * Note:
556
+ * I like to do this because the atom specification has so much extraneous data
557
+ * that I just don't care about it. This makes a sane array out of what is
558
+ * incredibly overcomplicated in my opinion.
559
+ *
560
+ * @param Array - Contact array as returned from fetch/xml_to_array
561
+ * @return Associative array in the format returned by this api
562
+ */
563
+ public function format_list($response)
564
+ {
565
+ $my_data = Array();
566
+ $my_data = $response['entry']['content']['ContactList'];
567
+ $d = Array();
568
+ $d['ListID'] = $this->id_from_url($my_data['attr']['id']);
569
+ unset($my_data['attr']);
570
+ unset($my_data['Members']);
571
+ foreach ($my_data as $key => $val)
572
+ $d[$key] = $val['value'];
573
+ return $d;
574
+ }
575
+
576
+ /**
577
+ * Add a list
578
+ * See List Data Format at http://developer.constantcontact.com/doc/contactLists for all fields
579
+ *
580
+ * @param Array $data - An associative array containing all the contact data to add
581
+ * @return Integer - ListID for the new entry
582
+ */
583
+ public function add_list($data)
584
+ {
585
+ $updated = date('Y-m-d\TH:i:s\Z');
586
+ $post = <<<end
587
+ <entry xmlns="http://www.w3.org/2005/Atom">
588
+ <title type="text"> </title>
589
+ <updated>{$updated}</updated>
590
+ <author></author>
591
+ <id>data:,none</id>
592
+ <summary type="text">Contact</summary>
593
+ <content type="application/vnd.ctct+xml">
594
+ <ContactList xmlns="http://ws.constantcontact.com/ns/1.0/">
595
+
596
+ end;
597
+
598
+ foreach ($data as $key => $val)
599
+ $post .= "\t\t\t<$key>{$val}</$key>\n";
600
+
601
+ $post .= <<<end
602
+ </ContactList>
603
+ </content>
604
+ </entry>
605
+ end;
606
+
607
+
608
+ $url= $this->api['url'].'lists';
609
+
610
+ $response = Array();
611
+ $response = $this->fetch($url,$post);
612
+ if ($this->debug['last_response'] <= 204)
613
+ return $this->id_from_url($response['entry']['id']['value']);
614
+ else
615
+ return false;
616
+ }
617
+
618
+ /**
619
+ * Returns detailed info for a particular list.
620
+ *
621
+ * @param Integer $id - ListID of the list requested.
622
+ * @return Associative array containing the list's details
623
+ */
624
+ public function get_list($id)
625
+ {
626
+ $url = $this->api['url'].'lists/'.$id;
627
+ $post = '';
628
+ $list = Array();
629
+ $list = $this->format_list($this->fetch($url,$post));
630
+
631
+ if ($this->debug['last_response'] <= 204)
632
+ return $list;
633
+ else
634
+ return false;
635
+ }
636
+
637
+ /**
638
+ * Edit a list
639
+ * See List Data Format at http://developer.constantcontact.com/doc/contactLists for all fields
640
+ *
641
+ * @param Integer $id - List ID of the list to edit
642
+ * @param Array $data - An associative array containing all the list data to edit
643
+ * @return Boolean - True on success and false on failure
644
+ */
645
+ public function edit_list($id,$data)
646
+ {
647
+ //Get the old xml from get_list() and then post after replacing values that need replacing
648
+ $url = $this->api['url'].'lists/'.$id;
649
+ $post = '';
650
+ $post = $this->fetch($url,$post,'xml');
651
+
652
+ foreach ($data as $key => $val)
653
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
654
+
655
+ $this->fetch($url,$post,'array','PUT');
656
+
657
+ if ($this->debug['last_response'] <= 204)
658
+ return true;
659
+ else
660
+ return false;
661
+ }
662
+
663
+ /**
664
+ * Return your lists.
665
+ *
666
+ * @param String $key - Optionally specify a key to use for the array
667
+ * @param Boolean $unique - Whether the key you specified is unique
668
+ * @return Associative array containing your lists indexed by whatever key specified.
669
+ */
670
+ public function get_lists($key='',$unique=true)
671
+ {
672
+ $ret = Array();
673
+
674
+ $url = $this->api['url'].'lists';
675
+ $post = '';
676
+ $response = Array();
677
+ $response = $this->fetch($url,$post);
678
+
679
+ $entries = Array();
680
+ if (isset($response['feed']['entry']['link']))
681
+ $entries[] = $response['feed']['entry'];
682
+ else
683
+ $entries = $response['feed']['entry'];
684
+ foreach ($entries as $data)
685
+ {
686
+ $my_data = Array();
687
+ $my_data = $data['content']['ContactList'];
688
+ $d = Array();
689
+ //$d['ListID'] = $this->id_from_url($my_data['attr']['id']);
690
+ $d['ListID'] = $my_data['attr']['id'];
691
+
692
+ // Exclude the default lists like active, do-not-mail and removed
693
+ if ( ! is_numeric($this->id_from_url($my_data['attr']['id'])) )
694
+ continue;
695
+
696
+ unset($my_data['attr']);
697
+ foreach ($my_data as $dkey => $dval)
698
+ {
699
+ if ( isset($dval['value']) )
700
+ $d[$dkey] = $dval['value'];
701
+ }
702
+
703
+ if ($key)
704
+ {
705
+ if ($unique)
706
+ $ret[$d[$key]] = $d;
707
+ else
708
+ $ret[$d[$key]][] = $d;
709
+ }
710
+ else
711
+ $ret[] = $d;
712
+ }
713
+ return $ret;
714
+ }
715
+
716
+ /**
717
+ * Delete a list
718
+ *
719
+ * @param Integer $id - ListID of the list to delete
720
+ * @return Boolean - True on success and false on failure
721
+ */
722
+ public function delete_list($id)
723
+ {
724
+ //Get the old xml from get_list() and then post after replacing values that need replacing
725
+ $url = $this->api['url'].'lists/'.$id;
726
+ $post = '';
727
+ $this->fetch($url,$post,'array','DELETE');
728
+
729
+ if ($this->debug['last_response'] <= 204)
730
+ return true;
731
+ else
732
+ return false;
733
+ }
734
+
735
+ //Subscription Functions
736
+
737
+ /**
738
+ * Add a subscription for an existing contact to a list
739
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
740
+ *
741
+ * @param Integer $contact_id - Contact ID of the contact to use
742
+ * @param Integer $list_id - List ID of the list to add the contact to
743
+ * @param String $optin_source - ACTION_BY_CUSTOMER or ACTION_BY_CLIENT depending on if this person is filling out a form for subscription in realtime
744
+ * @return Boolean - True on success and false on failure
745
+ */
746
+ public function add_subscription($contact_id,$list_id,$optin_source='ACTION_BY_CUSTOMER')
747
+ {
748
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
749
+ $url = $this->api['url'].'contacts/'.$contact_id;
750
+ $post = '';
751
+ $post = $this->fetch($url,$post,'xml');
752
+
753
+ if (!strstr($post,'</ContactLists>'))
754
+ $post = str_replace('</Contact>',"<ContactLists></ContactLists></Contact>",$post);
755
+
756
+ if (!strstr($post,'<OptInSource>'))
757
+ $post = str_replace('</Confirmed>',"</Confirmed>\n<OptInSource>$optin_source</OptInSource>",$post);
758
+
759
+ if (!strstr($post,'<ContactList id="'.$this->api['inner_url'].'lists/'.$list_id.'">'))
760
+ $post = str_replace('</ContactLists>','<ContactList id="'.$this->api['inner_url'].'lists/'.$list_id.'"></ContactList></ContactLists>',$post);
761
+
762
+ $this->fetch($url,$post,'array','PUT');
763
+
764
+ if ($this->debug['last_response'] <= 204)
765
+ return true;
766
+ else
767
+ return false;
768
+ }
769
+
770
+ /**
771
+ * Remove a subscription for an existing contact to a list
772
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
773
+ *
774
+ * @param Integer $contact_id - Contact ID of the contact to use
775
+ * @param Integer $list_id - List ID of the list to add the contact to
776
+ * @return Boolean - True on success and false on failure
777
+ */
778
+ public function remove_subscription($contact_id,$list_id)
779
+ {
780
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
781
+ $url = $this->api['url'].'contacts/'.$contact_id;
782
+ $post = '';
783
+ $post = $this->fetch($url,$post,'xml');
784
+
785
+ $post = preg_replace('/<ContactList id="'.str_replace('/','\/',$this->api['inner_url']).'lists\/'.$list_id.'">.*?<\/ContactList>/s','',$post);
786
+
787
+ $this->fetch($url,$post,'array','PUT');
788
+
789
+ if ($this->debug['last_response'] <= 204)
790
+ return true;
791
+ else
792
+ return false;
793
+ }
794
+
795
+ //Campaign Functions
796
+
797
+ /**
798
+ * Formats a campaign array into the format we always return as
799
+ * Note:
800
+ * I like to do this because the atom specification has so much extraneous data
801
+ * that I just don't care about it. This makes a sane array out of what is
802
+ * incredibly overcomplicated in my opinion.
803
+ *
804
+ * @param Array - Contact array as returned from fetch/xml_to_array
805
+ * @return Associative array in the format returned by this api
806
+ */
807
+ public function format_campaign($response)
808
+ {
809
+ $my_data = Array();
810
+ $my_data = $response['entry']['content']['Campaign'];
811
+ $d = Array();
812
+ $d['CampaignID'] = $this->id_from_url($my_data['attr']['id']);
813
+ $d['FromID'] = $this->id_from_url($my_data['FromEmail']['Email']['attr']['id']);
814
+ $d['FromEmail'] = $my_data['FromEmail']['EmailAddress']['value'];
815
+ unset($my_data['FromEmail']);
816
+ unset($my_data['ReplyToEmail']);
817
+
818
+ unset($my_data['attr']);
819
+ foreach ($my_data as $dkey => $dval)
820
+ {
821
+ if ($dkey != 'ContactLists')
822
+ $d[$dkey] = $dval['value'];
823
+ else
824
+ {
825
+ $entries = Array();
826
+ if (isset($dval['ContactList']['link']))
827
+ $entries[] = $dval['ContactList'];
828
+ else
829
+ $entries = $dval['ContactList'];
830
+
831
+ foreach ($entries as $entry)
832
+ {
833
+ $e = Array();
834
+ $e['ListID'] = $this->id_from_url($entry['attr']['id']);
835
+ unset($entry['attr']);
836
+ unset($entry['link']);
837
+ foreach ($entry as $ekey => $eval)
838
+ $e[$ekey] = $eval['value'];
839
+ $d[$dkey][] = $e;
840
+ }
841
+ }
842
+ }
843
+ return $d;
844
+ }
845
+
846
+ /**
847
+ * Return your campaigns.
848
+ *
849
+ * @param String $key - Optionally specify a key to use for the array
850
+ * @param Boolean $unique - Whether the key you specified is unique
851
+ * @return Associative array containing your lists indexed by whatever key specified.
852
+ */
853
+ public function get_campaigns($key='',$unique=true)
854
+ {
855
+ $ret = Array();
856
+
857
+ $url = $this->api['url'].'campaigns';
858
+ $post = '';
859
+ $response = Array();
860
+ $response = $this->fetch($url,$post);
861
+
862
+ $entries = Array();
863
+ if (isset($response['feed']['entry']['link']))
864
+ $entries[] = $response['feed']['entry'];
865
+ else
866
+ $entries = $response['feed']['entry'];
867
+ foreach ($entries as $data)
868
+ {
869
+ $my_data = Array();
870
+ $my_data = $data['content']['Campaign'];
871
+ $d = Array();
872
+ $d['CampaignID'] = $this->id_from_url($my_data['attr']['id']);
873
+ unset($my_data['attr']);
874
+ foreach ($my_data as $dkey => $dval)
875
+ $d[$dkey] = $dval['value'];
876
+
877
+ if ($key)
878
+ {
879
+ if ($unique)
880
+ $ret[$d[$key]] = $d;
881
+ else
882
+ $ret[$d[$key]][] = $d;
883
+ }
884
+ else
885
+ $ret[] = $d;
886
+ }
887
+ return $ret;
888
+ }
889
+
890
+ /**
891
+ * Add a campaign
892
+ * See Campaign Data Format at http://developer.constantcontact.com/doc/manageCampaigns for all fields
893
+ *
894
+ * @param Array $data - An associative array containing all the campaign data to add
895
+ * @param Array $lists - An array of ListIDs to have this campaign send to
896
+ * @param Array $from_id - FromID to use as the from email address
897
+ * @return Integer - CampaignID for the new entry
898
+ */
899
+ public function add_campaign($data,$lists,$from_id)
900
+ {
901
+ $updated = date('Y-m-d\TH:i:s\Z');
902
+ $post = <<<end
903
+ <entry xmlns="http://www.w3.org/2005/Atom">
904
+ <link href="{$this->api['relative_url']}campaigns" rel="edit" />
905
+ <id>{$this->api['inner_url']}campaigns</id>
906
+ <title type="text">{$data['Name']}</title>
907
+ <updated>{$updated}</updated>
908
+ <author>
909
+ <name>Constant Contact</name>
910
+ </author>
911
+ <content type="application/vnd.ctct+xml">
912
+ <Campaign xmlns="http://ws.constantcontact.com/ns/1.0/" id="{$this->api['inner_url']}campaigns/">
913
+
914
+ end;
915
+
916
+ foreach ($data as $key => $val)
917
+ {
918
+ if ($key == 'Date')
919
+ $val = date('Y-m-d\TH:i:s\Z',strtotime($val)+date("Z"));
920
+ elseif ($key == 'EmailContent' || $key == 'StyleSheet' || $key == 'PermissionReminderText')
921
+ $val = urlencode($val);
922
+ elseif ($key == 'TextContent')
923
+ $val = urlencode('<Text>'.$val.'</Text>');
924
+
925
+ $post .= "\t\t\t<$key>{$val}</$key>\n";
926
+ }
927
+
928
+ $post .= "\t\t\t<ContactLists>\n";
929
+ foreach ($lists as $list_id)
930
+ $post .= "\t\t\t\t<ContactList id=\"{$this->api['inner_url']}lists/{$list_id}\" />\n";
931
+
932
+ $temp = Array();
933
+ $temp = get_from($from_id);
934
+ $email = $temp['EmailAddress'];
935
+
936
+ $post .= <<<end
937
+ </ContactLists>
938
+ <FromEmail>
939
+ <Email id="{$this->api['inner_url']}emailaddresses/$from_id">
940
+ <link xmlns="http://www.w3.org/2005/Atom" href="{$this->api['inner_url']}emailaddresses/$from_id" rel="self" />
941
+ </Email>
942
+ <EmailAddress>$email</EmailAddress>
943
+ </FromEmail>
944
+ <ReplyToEmail>
945
+ <Email id="{$this->api['inner_url']}emailaddresses/$from_id">
946
+ <link xmlns="http://www.w3.org/2005/Atom" href="{$this->api['inner_url']}emailaddresses/$from_id" rel="self" />
947
+ </Email>
948
+ <EmailAddress>$email</EmailAddress>
949
+ </ReplyToEmail>
950
+
951
+ end;
952
+
953
+ $post .= <<<end
954
+ </Campaign>
955
+ </content>
956
+ </entry>
957
+ end;
958
+
959
+
960
+ $url= $this->api['url'].'contacts';
961
+
962
+ $response = Array();
963
+ $response = $this->fetch($url,$post);
964
+ if ($this->debug['last_response'] <= 204)
965
+ return $this->id_from_url($response['entry']['id']['value']);
966
+ else
967
+ return false;
968
+ }
969
+
970
+ /**
971
+ * Returns detailed info for a particular campaign.
972
+ *
973
+ * @param Integer $id - Campaign ID of the campaign requested.
974
+ * @return Associative array containing the campaign's details
975
+ */
976
+ public function get_campaign($id)
977
+ {
978
+ $url = $this->api['url'].'campaigns/'.$id;
979
+ $post = '';
980
+ $campaign = Array();
981
+ $campaign = $this->format_campaign($this->fetch($url,$post));
982
+
983
+ if ($this->debug['last_response'] <= 204)
984
+ return $campaign;
985
+ else
986
+ return false;
987
+ }
988
+
989
+ /**
990
+ * Edit a campaign
991
+ * See Campaign Data Format at http://developer.constantcontact.com/doc/manageCampaigns for all fields
992
+ *
993
+ * @param Integer $id - Campaign ID of the list to edit
994
+ * @param Array $data - An associative array containing all the campaign data to edit
995
+ * @return Boolean - True on success and false on failure
996
+ */
997
+ public function edit_campaign($id,$data)
998
+ {
999
+ //Get the old xml from get_campaign() and then post after replacing values that need replacing
1000
+ $url = $this->api['url'].'campaigns/'.$id;
1001
+ $post = '';
1002
+ $post = $this->fetch($url,$post,'xml');
1003
+
1004
+ foreach ($data as $key => $val)
1005
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
1006
+
1007
+ $this->fetch($url,$post,'array','PUT');
1008
+
1009
+ if ($this->debug['last_response'] <= 204)
1010
+ return true;
1011
+ else
1012
+ return false;
1013
+ }
1014
+
1015
+ /**
1016
+ * Delete a campaign
1017
+ *
1018
+ * @param Integer $id - CampaignID of the list to delete
1019
+ * @return Boolean - True on success and false on failure
1020
+ */
1021
+ public function delete_campaign($id)
1022
+ {
1023
+ //Get the old xml from get_campaign() and then post after replacing values that need replacing
1024
+ $url = $this->api['url'].'campaigns/'.$id;
1025
+ $post = '';
1026
+ $this->fetch($url,$post,'array','DELETE');
1027
+
1028
+ if ($this->debug['last_response'] <= 204)
1029
+ return true;
1030
+ else
1031
+ return false;
1032
+ }
1033
+
1034
+ //From Functions
1035
+
1036
+ /**
1037
+ * Formats a list array into the format we always return as
1038
+ * Note:
1039
+ * I like to do this because the atom specification has so much extraneous data
1040
+ * that I just don't care about. This makes a sane array out of what is
1041
+ * incredibly overcomplicated in my opinion.
1042
+ *
1043
+ * @param Array - Contact array as returned from fetch/xml_to_array
1044
+ * @return Associative array in the format returned by this api
1045
+ */
1046
+ public function format_from($response)
1047
+ {
1048
+ $my_data = Array();
1049
+ $my_data = $response['entry']['content']['Email'];
1050
+ $d = Array();
1051
+ $d['FromID'] = $this->id_from_url($my_data['attr']['id']);
1052
+ unset($my_data['attr']);
1053
+ foreach ($my_data as $key => $val)
1054
+ $d[$key] = $val['value'];
1055
+ return $d;
1056
+ }
1057
+
1058
+ /**
1059
+ * Returns detailed info for a particular list.
1060
+ *
1061
+ * @param Integer $id - FromID of the from email requested.
1062
+ * @return Associative array containing the from's details
1063
+ */
1064
+ public function get_from($id)
1065
+ {
1066
+ $url = $this->api['url'].'settings/emailaddresses/'.$id;
1067
+ $post = '';
1068
+ $from = Array();
1069
+ $from = $this->format_from($this->fetch($url,$post));
1070
+
1071
+ if ($this->debug['last_response'] <= 204)
1072
+ return $from;
1073
+ else
1074
+ return false;
1075
+ }
1076
+
1077
+ /**
1078
+ * Return your from email addresses.
1079
+ *
1080
+ * @param String $key - Optionally specify a key to use for the array
1081
+ * @param Boolean $unique - Whether the key you specified is unique
1082
+ * @return Associative array containing your lists indexed by whatever key specified.
1083
+ */
1084
+ public function get_froms($key='',$unique=true)
1085
+ {
1086
+ $ret = Array();
1087
+
1088
+ $url = $this->api['url'].'settings/emailaddresses';
1089
+ $post = '';
1090
+ $response = Array();
1091
+ $response = $this->fetch($url,$post);
1092
+
1093
+ $entries = Array();
1094
+ if (isset($response['feed']['entry']['link']))
1095
+ $entries[] = $response['feed']['entry'];
1096
+ else
1097
+ $entries = $response['feed']['entry'];
1098
+ foreach ($entries as $data)
1099
+ {
1100
+ $my_data = Array();
1101
+ $my_data = $data['content']['Email'];
1102
+ $d = Array();
1103
+ $d['FromID'] = $this->id_from_url($my_data['attr']['id']);
1104
+ unset($my_data['attr']);
1105
+ foreach ($my_data as $dkey => $dval)
1106
+ $d[$dkey] = $dval['value'];
1107
+
1108
+ if ($key)
1109
+ {
1110
+ if ($unique)
1111
+ $ret[$d[$key]] = $d;
1112
+ else
1113
+ $ret[$d[$key]][] = $d;
1114
+ }
1115
+ else
1116
+ $ret[] = $d;
1117
+ }
1118
+ return $ret;
1119
+ }
1120
+
1121
+ }
1122
+
1123
+ ?>
power-ups/contacts/admin/contacts-admin.php CHANGED
@@ -68,6 +68,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
68
 
69
  foreach ( $_POST as $name => $value )
70
  {
 
71
  if ( strstr($name, 'email_form_tags_') )
72
  {
73
  $tag_selector = '';
@@ -81,14 +82,14 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
81
  if ( ! strstr($tag_form_selectors, $tag_selector) )
82
  $tag_form_selectors .= $tag_selector . ',';
83
  }
84
- }
85
- else if ( strstr($name, 'email_list_sync_') )
86
  {
87
  $synced_list = '';
88
  if ( strstr($name, '_mailchimp') )
89
- $synced_list = array('esp' => 'mailchimp', 'list_id' => str_replace('email_list_sync_mailchimp_', '', $name), 'list_name' => $value);
90
  else if ( strstr($name, '_constant_contact') )
91
- $synced_list = array('esp' => 'constant_contact', 'list_id' => str_replace('email_list_sync_constant_contact_', '', $name), 'list_name' => $value);
92
 
93
  array_push($tag_synced_lists, $synced_list);
94
  }
@@ -210,7 +211,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
210
  echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts">&larr; All Contacts</a>';
211
 
212
  echo '<div class="contact-header-wrap">';
213
- echo '<img class="contact-header-avatar leadin-dynamic-avatar_' . substr($lead_id, -1) . '" height="76px" width="76px" src="https://app.getsignals.com/avatar/image/?emails=' . $lead_email . '"/>';
214
  echo '<div class="contact-header-info">';
215
  echo '<h1 class="contact-name">' . $lead_email . '</h1>';
216
  echo '<div class="contact-tags">';
@@ -422,20 +423,20 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
422
 
423
  <?php
424
  $esp_power_ups = array(
425
- 'MailChimp' => 'mailchimp_list_sync',
426
- 'Constant Contact' => 'constant_contact_list_sync',
427
- 'AWeber' => 'aweber_list_sync',
428
- 'GetResponse' => 'getresponse_list_sync',
429
- 'MailPoet' => 'mailpoet_list_sync',
430
- 'Campaign Monitor' => 'campaign_monitor_list_sync'
431
  );
432
 
433
  foreach ( $esp_power_ups as $power_up_name => $power_up_slug )
434
  {
435
  if ( WPLeadIn::is_power_up_active($power_up_slug) )
436
  {
437
- global ${'leadin_' . $power_up_slug . '_wp'}; // e.g leadin_mailchimp_list_sync_wp
438
- $esp_name = strtolower(str_replace('_list_sync', '', $power_up_slug)); // e.g. mailchimp
439
  $lists = ${'leadin_' . $power_up_slug . '_wp'}->admin->li_get_lists();
440
  $synced_lists = ( isset($tagger->details->tag_synced_lists) ? unserialize($tagger->details->tag_synced_lists) : '' );
441
 
@@ -481,7 +482,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
481
  if ( $power_up_name == 'Constant Contact' )
482
  $list_id = end(explode('/', $list_id));
483
 
484
- $html_id = 'email_list_sync_' . $esp_name . '_' . $list_id;
485
  $synced = FALSE;
486
 
487
  if ( $synced_lists )
@@ -739,7 +740,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
739
  {
740
  wp_register_script('leadin-admin-js', LEADIN_PATH . '/assets/js/build/leadin-admin.min.js', array ( 'jquery' ), FALSE, TRUE);
741
  wp_enqueue_script('leadin-admin-js');
742
- wp_localize_script('leadin-admin-js', 'li_admin_ajax', array('ajax_url' => admin_url('admin-ajax.php')));
743
  }
744
 
745
  if ( $pagenow == 'post.php' && isset($_GET['post']) && isset($_GET['action']) && strstr($_GET['action'], 'edit') )
@@ -765,6 +766,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
765
  if ( isset($_POST['export-all']) || isset($_POST['export-selected']) )
766
  {
767
  global $wpdb;
 
768
 
769
  $sitename = sanitize_key(get_bloginfo('name'));
770
 
68
 
69
  foreach ( $_POST as $name => $value )
70
  {
71
+ // Create a comma deliniated list of selectors for tag_form_selectors
72
  if ( strstr($name, 'email_form_tags_') )
73
  {
74
  $tag_selector = '';
82
  if ( ! strstr($tag_form_selectors, $tag_selector) )
83
  $tag_form_selectors .= $tag_selector . ',';
84
  }
85
+ } // Create a comma deliniated list of synced lists for tag_synced_lists
86
+ else if ( strstr($name, 'email_connect_') )
87
  {
88
  $synced_list = '';
89
  if ( strstr($name, '_mailchimp') )
90
+ $synced_list = array('esp' => 'mailchimp', 'list_id' => str_replace('email_connect_mailchimp_', '', $name), 'list_name' => $value);
91
  else if ( strstr($name, '_constant_contact') )
92
+ $synced_list = array('esp' => 'constant_contact', 'list_id' => str_replace('email_connect_constant_contact_', '', $name), 'list_name' => $value);
93
 
94
  array_push($tag_synced_lists, $synced_list);
95
  }
211
  echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts">&larr; All Contacts</a>';
212
 
213
  echo '<div class="contact-header-wrap">';
214
+ echo '<img class="contact-header-avatar leadin-dynamic-avatar_' . substr($lead_id, -1) . '" height="76px" width="76px" src="https://api.hubapi.com/socialintel/v1/avatars?email=' . $lead_email . '"/>';
215
  echo '<div class="contact-header-info">';
216
  echo '<h1 class="contact-name">' . $lead_email . '</h1>';
217
  echo '<div class="contact-tags">';
423
 
424
  <?php
425
  $esp_power_ups = array(
426
+ 'MailChimp' => 'mailchimp_connect',
427
+ 'Constant Contact' => 'constant_contact_connect',
428
+ 'AWeber' => 'aweber_connect',
429
+ 'GetResponse' => 'getresponse_connect',
430
+ 'MailPoet' => 'mailpoet_connect',
431
+ 'Campaign Monitor' => 'campaign_monitor_connect'
432
  );
433
 
434
  foreach ( $esp_power_ups as $power_up_name => $power_up_slug )
435
  {
436
  if ( WPLeadIn::is_power_up_active($power_up_slug) )
437
  {
438
+ global ${'leadin_' . $power_up_slug . '_wp'}; // e.g leadin_mailchimp_connect_wp
439
+ $esp_name = strtolower(str_replace('_connect', '', $power_up_slug)); // e.g. mailchimp
440
  $lists = ${'leadin_' . $power_up_slug . '_wp'}->admin->li_get_lists();
441
  $synced_lists = ( isset($tagger->details->tag_synced_lists) ? unserialize($tagger->details->tag_synced_lists) : '' );
442
 
482
  if ( $power_up_name == 'Constant Contact' )
483
  $list_id = end(explode('/', $list_id));
484
 
485
+ $html_id = 'email_connect_' . $esp_name . '_' . $list_id;
486
  $synced = FALSE;
487
 
488
  if ( $synced_lists )
740
  {
741
  wp_register_script('leadin-admin-js', LEADIN_PATH . '/assets/js/build/leadin-admin.min.js', array ( 'jquery' ), FALSE, TRUE);
742
  wp_enqueue_script('leadin-admin-js');
743
+ wp_localize_script('leadin-admin-js', 'li_admin_ajax', array('ajax_url' => get_admin_url(NULL,'') . '/admin-ajax.php'));
744
  }
745
 
746
  if ( $pagenow == 'post.php' && isset($_GET['post']) && isset($_GET['action']) && strstr($_GET['action'], 'edit') )
766
  if ( isset($_POST['export-all']) || isset($_POST['export-selected']) )
767
  {
768
  global $wpdb;
769
+ leadin_set_wpdb_tables();
770
 
771
  $sitename = sanitize_key(get_bloginfo('name'));
772
 
power-ups/mailchimp-connect.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Power-up Name: MailChimp Connect
4
+ * Power-up Class: WPMailChimpConnect
5
+ * Power-up Menu Text:
6
+ * Power-up Slug: mailchimp_connect
7
+ * Power-up Menu Link: settings
8
+ * Power-up URI: http://leadin.com/mailchimp-connect
9
+ * Power-up Description: Push your contacts to MailChimp email lists.
10
+ * Power-up Icon: power-up-icon-mailchimp-connect
11
+ * Power-up Icon Small: power-up-icon-mailchimp-connect_small
12
+ * First Introduced: 0.7.0
13
+ * Power-up Tags: Newsletter, Email
14
+ * Auto Activate: No
15
+ * Permanently Enabled: No
16
+ * Hidden: No
17
+ */
18
+
19
+ //=============================================
20
+ // Define Constants
21
+ //=============================================
22
+
23
+ if ( !defined('LEADIN_MAILCHIMP_CONNECT_PATH') )
24
+ define('LEADIN_MAILCHIMP_CONNECT_PATH', LEADIN_PATH . '/power-ups/mailchimp-connect');
25
+
26
+ if ( !defined('LEADIN_MAILCHIMP_CONNECT_PLUGIN_DIR') )
27
+ define('LEADIN_MAILCHIMP_CONNECT_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect');
28
+
29
+ if ( !defined('LEADIN_MAILCHIMP_CONNECT_PLUGIN_SLUG') )
30
+ define('LEADIN_MAILCHIMP_CONNECT_SLUG', basename(dirname(__FILE__)));
31
+
32
+ //=============================================
33
+ // Include Needed Files
34
+ //=============================================
35
+ require_once(LEADIN_MAILCHIMP_CONNECT_PLUGIN_DIR . '/admin/mailchimp-connect-admin.php');
36
+ require_once(LEADIN_MAILCHIMP_CONNECT_PLUGIN_DIR . '/inc/MailChimp-API.php');
37
+
38
+ //=============================================
39
+ // WPLeadIn Class
40
+ //=============================================
41
+ class WPMailChimpConnect extends WPLeadIn {
42
+
43
+ var $admin;
44
+ var $options;
45
+
46
+ /**
47
+ * Class constructor
48
+ */
49
+ function __construct ( $activated )
50
+ {
51
+ //=============================================
52
+ // Hooks & Filters
53
+ //=============================================
54
+
55
+ if ( ! $activated )
56
+ return false;
57
+
58
+ global $leadin_mailchimp_connect_wp;
59
+ $leadin_mailchimp_connect_wp = $this;
60
+ $this->options = get_option('leadin_mls_options');
61
+ }
62
+
63
+ public function admin_init ( )
64
+ {
65
+ $admin_class = get_class($this) . 'Admin';
66
+ $this->admin = new $admin_class($this->icon_small);
67
+ }
68
+
69
+ function power_up_setup_callback ( )
70
+ {
71
+ $this->admin->power_up_setup_callback();
72
+ }
73
+
74
+ /**
75
+ * Activate the power-up and add the defaults
76
+ */
77
+ function add_defaults ()
78
+ {
79
+
80
+ }
81
+
82
+ /**
83
+ * Adds a subcsriber to a specific list
84
+ *
85
+ * @param string
86
+ * @param string
87
+ * @param string
88
+ * @param string
89
+ * @param string
90
+ * @return int/bool API status code OR false if api key not set
91
+ */
92
+ function push_contact_to_list ( $list_id = '', $email = '', $first_name = '', $last_name = '', $phone = '' )
93
+ {
94
+ if ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] && $list_id )
95
+ {
96
+ $MailChimp = new LI_MailChimp($this->options['li_mls_api_key']);
97
+ $contact_synced = $MailChimp->call("lists/subscribe", array(
98
+ "id" => $list_id,
99
+ "email" => array('email' => $email),
100
+ "send_welcome" => FALSE,
101
+ "email_type" => 'html',
102
+ "update_existing" => TRUE,
103
+ 'replace_interests' => FALSE,
104
+ 'double_optin' => FALSE,
105
+ "merge_vars" => array(
106
+ 'EMAIL' => $email,
107
+ 'FNAME' => $first_name,
108
+ 'LNAME' => $last_name,
109
+ 'PHONE' => $phone
110
+ )
111
+ ));
112
+
113
+ return $contact_synced;
114
+ }
115
+
116
+ return FALSE;
117
+ }
118
+
119
+ /**
120
+ * Removes an email address from a specific list
121
+ *
122
+ * @param string
123
+ * @param string
124
+ * @return int/bool API status code OR false if api key not set
125
+ */
126
+ function remove_contact_from_list ( $list_id = '', $email = '' )
127
+ {
128
+ if ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] && $list_id )
129
+ {
130
+ $MailChimp = new LI_MailChimp($this->options['li_mls_api_key']);
131
+ $contact_removed = $MailChimp->call("lists/unsubscribe ", array(
132
+ "id" => $list_id,
133
+ "email" => array('email' => $email),
134
+ "delete_member" => TRUE,
135
+ "send_goodbye" => FALSE,
136
+ "send_notify" => FALSE
137
+ ));
138
+
139
+ return $contact_removed;
140
+ }
141
+
142
+ return FALSE;
143
+ }
144
+
145
+ /**
146
+ * Adds a subcsriber to a specific list
147
+ *
148
+ * @param string
149
+ * @param array
150
+ * @return int/bool API status code OR false if api key not set
151
+ */
152
+ function bulk_push_contact_to_list ( $list_id = '', $contacts = '' )
153
+ {
154
+ if ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] && $list_id )
155
+ {
156
+ $MailChimp = new LI_MailChimp($this->options['li_mls_api_key']);
157
+
158
+ $batch_contacts = array();
159
+ foreach ( $contacts as $contact )
160
+ array_push($batch_contacts, array('email' => array('email' => $contact->lead_email)));
161
+
162
+ $list_updated = $MailChimp->call("lists/batch-subscribe", array(
163
+ "id" => $list_id,
164
+ "send_welcome" => FALSE,
165
+ "email_type" => 'html',
166
+ "update_existing" => TRUE,
167
+ 'replace_interests' => FALSE,
168
+ 'double_optin' => FALSE,
169
+ "batch" => $batch_contacts
170
+ ));
171
+
172
+ return $list_updated;
173
+ }
174
+
175
+ return FALSE;
176
+ }
177
+ }
178
+
179
+ //=============================================
180
+ // Subscribe Widget Init
181
+ //=============================================
182
+
183
+ global $leadin_mailchimp_connect_wp;
184
+
185
+ ?>
power-ups/mailchimp-connect/admin/mailchimp-connect-admin.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //=============================================
3
+ // WPLeadInAdmin Class
4
+ //=============================================
5
+ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
6
+
7
+ var $power_up_settings_section = 'leadin_mls_options_section';
8
+ var $power_up_icon;
9
+ var $options;
10
+ var $authed = FALSE;
11
+
12
+ /**
13
+ * Class constructor
14
+ */
15
+ function __construct ( $power_up_icon_small )
16
+ {
17
+ //=============================================
18
+ // Hooks & Filters
19
+ //=============================================
20
+
21
+ if ( is_admin() )
22
+ {
23
+ $this->power_up_icon = $power_up_icon_small;
24
+ add_action('admin_init', array($this, 'leadin_mls_build_settings_page'));
25
+ $this->options = get_option('leadin_mls_options');
26
+ $this->authed = ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] ? TRUE : FALSE );
27
+ }
28
+ }
29
+
30
+ //=============================================
31
+ // Settings Page
32
+ //=============================================
33
+
34
+ /**
35
+ * Creates settings options
36
+ */
37
+ function leadin_mls_build_settings_page ()
38
+ {
39
+ register_setting('leadin_settings_options', 'leadin_mls_options', array($this, 'sanitize'));
40
+ add_settings_section($this->power_up_settings_section, $this->power_up_icon . "MailChimp", '', LEADIN_ADMIN_PATH);
41
+ add_settings_field('li_mls_api_key', 'API key', array($this, 'li_mls_api_key_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
42
+
43
+ if ( isset($this->options['li_mls_api_key']) )
44
+ {
45
+ if ( $this->options['li_mls_api_key'] )
46
+ add_settings_field('li_print_synced_lists', 'Synced tags', array($this, 'li_print_synced_lists'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Sanitize each setting field as needed
52
+ *
53
+ * @param array $input Contains all settings fields as array keys
54
+ */
55
+ public function sanitize ( $input )
56
+ {
57
+ $new_input = array();
58
+
59
+ if( isset( $input['li_mls_api_key'] ) )
60
+ $new_input['li_mls_api_key'] = sanitize_text_field( $input['li_mls_api_key'] );
61
+
62
+ if( isset( $input['li_mls_subscribers_to_list'] ) )
63
+ $new_input['li_mls_subscribers_to_list'] = sanitize_text_field( $input['li_mls_subscribers_to_list'] );
64
+
65
+ return $new_input;
66
+ }
67
+
68
+ /**
69
+ * Prints email input for settings page
70
+ */
71
+ function li_mls_api_key_callback ()
72
+ {
73
+ $li_mls_api_key = ( $this->options['li_mls_api_key'] ? $this->options['li_mls_api_key'] : '' ); // Get header from options, or show default
74
+
75
+ printf(
76
+ '<input id="li_mls_api_key" type="text" id="title" name="leadin_mls_options[li_mls_api_key]" value="%s" size="50"/>',
77
+ $li_mls_api_key
78
+ );
79
+
80
+ if ( ! isset($li_mls_api_key) || ! $li_mls_api_key )
81
+ echo '<p><a href="http://admin.mailchimp.com/account/api/" target="_blank">Get an API key from MailChimp.com</a></p>';
82
+ }
83
+
84
+ /**
85
+ * Prints email input for settings page
86
+ */
87
+ function li_print_synced_lists ()
88
+ {
89
+ $li_mls_api_key = ( $this->options['li_mls_api_key'] ? $this->options['li_mls_api_key'] : '' ); // Get header from options, or show default
90
+
91
+ if ( isset($li_mls_api_key ) )
92
+ {
93
+ $synced_lists = $this->li_get_synced_list_for_esp('mailchimp');
94
+ $list_value_pairs = array();
95
+ $synced_list_count = 0;
96
+
97
+ echo '<table>';
98
+ foreach ( $synced_lists as $synced_list )
99
+ {
100
+ foreach ( stripslashes_deep(unserialize($synced_list->tag_synced_lists)) as $tag_synced_list )
101
+ {
102
+ if ( $tag_synced_list['esp'] == 'mailchimp' )
103
+ {
104
+ echo '<tr class="synced-list-row">';
105
+ echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
106
+ echo '<td class="synced-list-cell"><span class="synced-list-arrow">&#8594;</span></td>';
107
+ echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
108
+ echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts&action=edit_tag&tag=' . $synced_list->tag_id . '">edit</a></td>';
109
+ echo '</tr>';
110
+
111
+ $synced_list_count++;
112
+ }
113
+ }
114
+ }
115
+ echo '</table>';
116
+
117
+ if ( ! $synced_list_count )
118
+ echo "<p>You don't have any MailChimp lists synced with LeadIn yet...</p>";
119
+
120
+ echo '<p><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts&action=manage_tags' . '">Manage tags</a></p>';
121
+ }
122
+
123
+ if ( $li_mls_api_key )
124
+ echo '<p style="padding-top: 10px;"><a href="http://admin.mailchimp.com/lists/new-list/" target="_blank">Create a new list on MailChimp.com</a></p>';
125
+ }
126
+
127
+ function li_get_synced_list_for_esp ( $esp_name, $output_type = 'OBJECT' )
128
+ {
129
+ global $wpdb;
130
+
131
+ $q = $wpdb->prepare("SELECT * FROM $wpdb->li_tags WHERE tag_synced_lists LIKE '%%%s%%' AND tag_deleted = 0", $esp_name);
132
+ $synced_lists = $wpdb->get_results($q, $output_type);
133
+
134
+ return $synced_lists;
135
+ }
136
+
137
+ /**
138
+ * Prints email input for settings page
139
+ */
140
+ function li_mls_subscribers_to_list_callback ()
141
+ {
142
+ $li_mls_subscribers_to_list = ( isset($this->options['li_mls_subscribers_to_list']) ? $this->options['li_mls_subscribers_to_list'] : '' );
143
+
144
+ $lists = $this->li_mls_get_mailchimp_lists($this->options['li_mls_api_key']);
145
+
146
+ echo '<select id="li_mls_subscribers_to_list" name="leadin_mls_options[li_mls_subscribers_to_list]" ' . ( ! count($lists['data']) ? 'disabled' : '' ) . '>';
147
+
148
+ if ( count($lists['data']) )
149
+ {
150
+ $list_set = FALSE;
151
+
152
+ foreach ( $lists['data'] as $list )
153
+ {
154
+ if ( $list['id'] == $li_mls_subscribers_to_list && !$list_set )
155
+ $list_set = TRUE;
156
+
157
+ echo '<option ' . ( $list['id'] == $li_mls_subscribers_to_list ? 'selected' : '' ) . ' value="' . $list['id'] . '">' . $list['name'] . '</option>';
158
+ }
159
+
160
+ if ( !$list_set )
161
+ echo '<option selected value="">No list set...</option>';
162
+ }
163
+ else
164
+ {
165
+ echo '<option value="No lists...">No lists...</option>';
166
+ }
167
+
168
+ echo '</select>';
169
+
170
+ echo '<p><a href="http://admin.mailchimp.com/lists/new-list/" target="_blank">Create a new list on MailChimp.com</a></p>';
171
+ }
172
+
173
+ function li_get_lists ( )
174
+ {
175
+ $lists = $this->li_mls_get_mailchimp_lists($this->options['li_mls_api_key']);
176
+
177
+ $sanitized_lists = array();
178
+ foreach ( $lists['data'] as $list )
179
+ {
180
+ $list_obj = (Object)NULL;
181
+ $list_obj->id = $list['id'];
182
+ $list_obj->name = $list['name'];
183
+
184
+ array_push($sanitized_lists, $list_obj);;
185
+ }
186
+
187
+ return $sanitized_lists;
188
+ }
189
+
190
+ function li_mls_get_mailchimp_lists ( $api_key )
191
+ {
192
+ $MailChimp = new LI_MailChimp($api_key);
193
+
194
+ $lists = $MailChimp->call("lists/list", array(
195
+ "start" => 0, // optional, control paging of lists, start results at this list #, defaults to 1st page of data (page 0)
196
+ "limit" => 25, // optional, control paging of lists, number of lists to return with each call, defaults to 25 (max=100)
197
+ "sort_field" => "created", // optional, "created" (the created date, default) or "web" (the display order in the web app). Invalid values will fall back on "created" - case insensitive.
198
+ "sort_dir" => "DESC" // optional, "DESC" for descending (default), "ASC" for Ascending. Invalid values will fall back on "created" - case insensitive. Note: to get the exact display order as the web app you'd use "web" and "ASC"
199
+ ));
200
+
201
+ return $lists;
202
+ }
203
+ }
204
+
205
+ ?>
power-ups/mailchimp-connect/inc/MailChimp-API.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Super-simple, minimum abstraction MailChimp API v2 wrapper
6
+ *
7
+ * Uses curl if available, falls back to file_get_contents and HTTP stream.
8
+ * This probably has more comments than code.
9
+ *
10
+ * Contributors:
11
+ * Michael Minor <me@pixelbacon.com>
12
+ * Lorna Jane Mitchell, github.com/lornajane
13
+ *
14
+ * @author Drew McLellan <drew.mclellan@gmail.com>
15
+ * @version 1.1.1
16
+ */
17
+ class LI_MailChimp
18
+ {
19
+ private $api_key;
20
+ private $api_endpoint = 'https://<dc>.api.mailchimp.com/2.0';
21
+ private $verify_ssl = false;
22
+
23
+ /**
24
+ * Create a new instance
25
+ * @param string $api_key Your MailChimp API key
26
+ */
27
+ function __construct($api_key)
28
+ {
29
+ $this->api_key = $api_key;
30
+ if ( !strstr($this->api_key, '-') )
31
+ return FALSE;
32
+
33
+ list(, $datacentre) = explode('-', $this->api_key);
34
+ $this->api_endpoint = str_replace('<dc>', $datacentre, $this->api_endpoint);
35
+ }
36
+
37
+ /**
38
+ * Call an API method. Every request needs the API key, so that is added automatically -- you don't need to pass it in.
39
+ * @param string $method The API method to call, e.g. 'lists/list'
40
+ * @param array $args An array of arguments to pass to the method. Will be json-encoded for you.
41
+ * @return array Associative array of json decoded API response.
42
+ */
43
+ public function call($method, $args=array())
44
+ {
45
+ return $this->makeRequest($method, $args);
46
+ }
47
+
48
+ /**
49
+ * Performs the underlying HTTP request. Not very exciting
50
+ * @param string $method The API method to be called
51
+ * @param array $args Assoc array of parameters to be passed
52
+ * @return array Assoc array of decoded result
53
+ */
54
+ private function makeRequest($method, $args=array())
55
+ {
56
+ $args['apikey'] = $this->api_key;
57
+
58
+ $url = $this->api_endpoint.'/'.$method.'.json';
59
+
60
+ if (function_exists('curl_init') && function_exists('curl_setopt')){
61
+ $ch = curl_init();
62
+ curl_setopt($ch, CURLOPT_URL, $url);
63
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
64
+ curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
65
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
66
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
67
+ curl_setopt($ch, CURLOPT_POST, true);
68
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl);
69
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args));
70
+ curl_setopt($ch, CURLOPT_HEADER, false);
71
+ $result = curl_exec($ch);
72
+ curl_close($ch);
73
+
74
+
75
+ } else {
76
+ $json_data = json_encode($args);
77
+ $result = file_get_contents($url, null, stream_context_create(array(
78
+ 'http' => array(
79
+ 'protocol_version' => 1.1,
80
+ 'user_agent' => 'PHP-MCAPI/2.0',
81
+ 'method' => 'POST',
82
+ 'header' => "Content-type: application/json\r\n".
83
+ "Connection: close\r\n" .
84
+ "Content-length: " . strlen($json_data) . "\r\n",
85
+ 'content' => $json_data,
86
+ ),
87
+ )));
88
+ }
89
+
90
+ return $result ? json_decode($result, true) : false;
91
+ }
92
+ }
power-ups/subscribe-widget.php CHANGED
@@ -55,8 +55,13 @@ class WPLeadInSubscribe extends WPLeadIn {
55
  return false;
56
 
57
  $this->options = get_option('leadin_subscribe_options');
58
- add_action('get_footer', array(&$this, 'append_leadin_subscribe_settings'));
59
-
 
 
 
 
 
60
  if ( ($this->options['li_susbscibe_installed'] != 1) || (!is_array($this->options)) )
61
  {
62
  $this->add_defaults();
@@ -131,8 +136,6 @@ class WPLeadInSubscribe extends WPLeadIn {
131
 
132
  // Div checked by media query for mobile
133
  echo '<span id="leadin-subscribe-mobile-check"></span>';
134
-
135
- $this->add_leadin_subscribe_frontend_scripts_and_styles();
136
  }
137
 
138
  //=============================================
55
  return false;
56
 
57
  $this->options = get_option('leadin_subscribe_options');
58
+
59
+ if ( ! is_admin() )
60
+ {
61
+ add_action('get_footer', array(&$this, 'append_leadin_subscribe_settings'));
62
+ add_action('wp_enqueue_scripts', array($this, 'add_leadin_subscribe_frontend_scripts_and_styles'));
63
+ }
64
+
65
  if ( ($this->options['li_susbscibe_installed'] != 1) || (!is_array($this->options)) )
66
  {
67
  $this->add_defaults();
136
 
137
  // Div checked by media query for mobile
138
  echo '<span id="leadin-subscribe-mobile-check"></span>';
 
 
139
  }
140
 
141
  //=============================================
readme.txt CHANGED
@@ -1,64 +1,68 @@
1
- === LeadIn ===
2
  Contributors: andygcook, nelsonjoyce
3
  Tags: crm, contacts, lead tracking, click tracking, visitor tracking, analytics, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp, constant contact, newsletter, popup, popover, email list, email, contacts database, contact form, forms, form widget, popup form
4
  Requires at least: 3.7
5
- Tested up to: 3.9.2
6
- Stable tag: 2.0.0
7
 
8
- LeadIn is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
9
 
10
  == Description ==
11
 
12
  = Get personal with your leads =
13
 
14
- <a href="http://leadin.com" alt="WordPress marketing automation and lead tracking plugin">LeadIn</a> is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
15
 
16
  When a person submits a form on your WordPress site, you want to know more about them. What pages they've visited, when they return, and what social networks they’re on. Our WordPress marketing automation and lead tracking plugin gives you the details you need to make your next move. Because business isn’t business unless it’s personal.
17
 
18
  = How does it work? =
19
 
20
- 1. When you activate the WordPress plugin, LeadIn will track each anonymous visitor to your site with a cookie. If someone closes the pop-up or subscribes, we won't show them the pop-up again.
21
- 2. Once someone fills out the subscribe form or any other other form on your site, LeadIn will identify that person with their email address.
22
- 3. You'll receive an email with a link to the new contact record with all of their visit history.
 
23
 
24
- = Who's using LeadIn? =
25
 
 
26
 
27
- **Alan Perlman**: *“I can use LeadIn to get a sense of how engaged certain contacts are, and I can learn more about their behavior on my website to better drive the conversation and understand what they’re interested in or looking for.”*
 
 
28
 
29
  <a href="http://www.extremeinbound.com/leadin-wordpress-crm-inbound-plugin/">Read more from Alan</a>
30
 
31
 
32
- **Adam W. Warner**: *“…the LeadIn plugin has been very useful so far in giving us an idea of the actual visitor paths to our contact forms vs. the paths we’ve intended.”*
33
 
34
  <a href="http://thewpvalet.com/wordpress-lead-tracking/">Read more from Adam</a>
35
 
36
 
37
  = Note: =
38
 
39
- LeadIn collects usage information about this plugin so that we can better serve our customers and know what features to add. By installing and activating the LeadIn for WordPress plugin you agree to these terms.
40
 
41
  == Installation ==
42
 
43
  1. Upload the 'leadin' folder to the '/wp-content/plugins/' directory
44
  2. Activate the plugin through the 'Plugins' menu in WordPress
45
- 3. Add an email address under 'LeadIn' in your settings panel
46
 
47
  == Frequently Asked Questions ==
48
 
49
- = How does LeadIn integrate with my forms? =
50
 
51
- LeadIn automatically integrates with your contact and comment forms that contain an email address field on your web site. There's no setup required.
52
 
53
  = Where are my contact submission stored? =
54
 
55
- LeadIn creates a new contact in your Contacts Tabke whenever an email address is detected in your visitor's form submission.
56
 
57
  There is no limit to the number of contacts you can store in your Contacts Table.
58
 
59
  = Which contact form building plugins are supported? =
60
 
61
- LeadIn is intended to work with any HTML form out of the box, but does not support forms created by Javascript or loaded through an iFrame.
62
 
63
  To ensure quality we've tested the most popular WordPress form builder plugins.
64
 
@@ -72,27 +76,55 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
72
  - Formidable
73
  - Ninja Forms
74
  - Contact Form Clean and Simple
 
 
 
 
75
 
76
  = Tested + unsupported: =
77
 
78
  - Wufoo
79
- - HubSpot
80
  - Easy Contact Forms
81
  - Disqus comments
 
 
 
 
 
82
 
83
  == Screenshots ==
84
 
85
  1. See the visit history of each contact.
86
  2. Get an email notification for every new lead.
87
- 3. LeadIn stats show you where your leads are coming from.
88
  4. Segment your contact list based on page views and submissinos.
89
  5. Collect more contacts with the pop-up subscribe widget.
90
  6. Create custom tagged lists, choose the form triggers to add contacts and sync your contacts to third-party email services
91
 
92
  == Changelog ==
93
 
94
- - Current version: 2.0.0
95
- - Current version release: 2014-08-14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  = 2.0.0 (2014.08.11) =
98
  = Enhancements =
@@ -112,11 +144,11 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
112
  = 1.2.0 (2014.06.25) =
113
  - Bug fixes
114
  - Contacts with default "contact status" were not showing up in the contact list
115
- - WordPress admin backends secured with SSL can now be used with LeadIn
116
  - Namespaced the referrer parsing library for the Sources widget
117
 
118
  = Enhancements =
119
- - LeadIn VIP program
120
 
121
  = 1.1.1 (2014.06.20) =
122
  - Bug fixes
@@ -124,7 +156,7 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
124
 
125
  = 1.1.0 (2014.06.20) =
126
  - Bug fixes
127
- - LeadIn subscriber email confirmations were not sending
128
  - Removed smart contact segmenting for leads
129
 
130
  = Enhancements =
@@ -164,7 +196,7 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
164
 
165
  = Enhancements =
166
  - Overhaul of settings page to make it easier to see which settings go with each power-up
167
- - Launched LeadIn Beta Program
168
 
169
  = 0.9.1 (2014.05.14) =
170
  - Bug fixes
@@ -267,7 +299,7 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
267
 
268
  = Enhancements =
269
  - Improved readability on new lead notification emails
270
- - Confirmation email added for new subscribers to the LeadIn Subscribe Pop-up
271
  - Updated screenshots
272
  - Improved onboarding flow
273
  - Deleted unused and deprecated files
@@ -281,16 +313,16 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
281
  - Add (blank page title tag) to emails and contact timeline for blank page titles
282
  - Fix link on admin nav menu bar to link to contact list
283
  - Ignore lead notifications and subscribe popup on login page
284
- - Saving an email no longer overwrites all the LeadIn options
285
  - Added live chat support
286
 
287
  = Enhancements =
288
  - New power-ups page
289
- - LeadIn Subscribe integrated into plugin as a power-up
290
  - Improved contact history styling + interface
291
  - Added visit, pageview and submission stats to the contact view
292
- - Added Live Chat into the LeadIn WordPress admin screens
293
- - New LeadIn icons for WordPres sidebar and admin nav menu
294
 
295
  = 0.4.6 (2013.02.11) =
296
  - Bug fixes
@@ -299,14 +331,14 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
299
  - Bug fix "Select All" export
300
  - Bug fix for CSS "page views" hover triangle breaking to next line
301
  - Backwards compability for < jQuery 1.7.0
302
- - Add LeadIn link to admin bar
303
 
304
  = Enhancements =
305
  - New onboarding flow
306
 
307
  = 0.4.5 (2013.01.30) =
308
  = Enhancements =
309
- - Integration with LeadIn Subscribe
310
 
311
  = 0.4.4 (2013.01.24) =
312
  - Bug fixes
@@ -317,9 +349,9 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
317
 
318
  = 0.4.3 (2013.01.13) =
319
  - Bug fixes
320
- - Fixed LeadIn form submission inserts for comments
321
  - Resolved various silent PHP warnings in administrative dashboard
322
- - Fixed LeadIn updater class to be compatible with WP3.8
323
  - Improved contact merging logic to be more reliable
324
 
325
  = Enhancements =
@@ -338,11 +370,11 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
338
  - Added url for each page views in the contact timeline
339
  - Added source for each visit event
340
  - Tweak colors for contact timeline
341
- - Default the LeadIn menu to the contacts page
342
 
343
  = 0.4.1 (2013.12.18) =
344
  - Bug fixes
345
- - Removed LeadIn header from the contact timeline view
346
  - Updated the wording on the menu view picker above contacts list
347
  - Remove pre-mp6 styles if MP6 plugin is activated
348
  - Default totals leads/comments = 0 when leads table is empty instead of printing blank integer
@@ -368,10 +400,10 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
368
  - Strip slashes from page titles in emails
369
 
370
  = Enhancements =
371
- - Created separate LeadIn menu in WordPress admin
372
  - CRM list of all contacts
373
  - Added ability to export list of contacts
374
- - LeadIn now distinguishes between a contact requests and comment submissions
375
  - Added link to CRM list inside each contact/comment email
376
 
377
  = 0.2.0 (2013.11.26) =
1
+ === Leadin ===
2
  Contributors: andygcook, nelsonjoyce
3
  Tags: crm, contacts, lead tracking, click tracking, visitor tracking, analytics, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp, constant contact, newsletter, popup, popover, email list, email, contacts database, contact form, forms, form widget, popup form
4
  Requires at least: 3.7
5
+ Tested up to: 4.0-RC1
6
+ Stable tag: 2.0.1
7
 
8
+ Leadin is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
9
 
10
  == Description ==
11
 
12
  = Get personal with your leads =
13
 
14
+ <a href="http://leadin.com" alt="WordPress marketing automation and lead tracking plugin">Leadin</a> is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
15
 
16
  When a person submits a form on your WordPress site, you want to know more about them. What pages they've visited, when they return, and what social networks they’re on. Our WordPress marketing automation and lead tracking plugin gives you the details you need to make your next move. Because business isn’t business unless it’s personal.
17
 
18
  = How does it work? =
19
 
20
+ -1. When you activate the WordPress plugin, Leadin will track each anonymous visitor to your site with a cookie.
21
+ -2. Leadin automatically identifies and watches each existing form on your site for submissions.
22
+ -3. Once someone fills out any other form on your site, Leadin will identify that person with their email address. and add them to your contact list.
23
+ -4. You'll also receive an email with a link to the new contact record with all of their visit history.
24
 
25
+ = Multisite Compatible =
26
 
27
+ Leadin is fully Multisite compatible. The plugin will all data to each site's installaion just fine without requiring any additional setup.
28
 
29
+ = Who's using Leadin? =
30
+
31
+ **Alan Perlman**: *“I can use Leadin to get a sense of how engaged certain contacts are, and I can learn more about their behavior on my website to better drive the conversation and understand what they’re interested in or looking for.”*
32
 
33
  <a href="http://www.extremeinbound.com/leadin-wordpress-crm-inbound-plugin/">Read more from Alan</a>
34
 
35
 
36
+ **Adam W. Warner**: *“…the Leadin plugin has been very useful so far in giving us an idea of the actual visitor paths to our contact forms vs. the paths we’ve intended.”*
37
 
38
  <a href="http://thewpvalet.com/wordpress-lead-tracking/">Read more from Adam</a>
39
 
40
 
41
  = Note: =
42
 
43
+ Leadin collects usage information about this plugin so that we can better serve our customers and know what features to add. By installing and activating the Leadin for WordPress plugin you agree to these terms.
44
 
45
  == Installation ==
46
 
47
  1. Upload the 'leadin' folder to the '/wp-content/plugins/' directory
48
  2. Activate the plugin through the 'Plugins' menu in WordPress
49
+ 3. Add an email address under 'Leadin' in your settings panel
50
 
51
  == Frequently Asked Questions ==
52
 
53
+ = How does Leadin integrate with my forms? =
54
 
55
+ Leadin automatically integrates with your contact and comment forms that contain an email address field on your web site. There's no setup required.
56
 
57
  = Where are my contact submission stored? =
58
 
59
+ Leadin creates a new contact in your Contacts Tabke whenever an email address is detected in your visitor's form submission.
60
 
61
  There is no limit to the number of contacts you can store in your Contacts Table.
62
 
63
  = Which contact form building plugins are supported? =
64
 
65
+ Leadin is intended to work with any HTML form out of the box, but does not support forms created by Javascript or loaded through an iFrame.
66
 
67
  To ensure quality we've tested the most popular WordPress form builder plugins.
68
 
76
  - Formidable
77
  - Ninja Forms
78
  - Contact Form Clean and Simple
79
+ - SumoMe
80
+ - HubSpot
81
+ - Native WordPress comment forms
82
+ - Most custom forms
83
 
84
  = Tested + unsupported: =
85
 
86
  - Wufoo
 
87
  - Easy Contact Forms
88
  - Disqus comments
89
+ - Forms contained in an iFrame
90
+
91
+ = Does Leadin work on Multisite? =
92
+
93
+ You betcha! Leadin should work just fine on Multisite right out-of-the-box without requiring any additional setup.
94
 
95
  == Screenshots ==
96
 
97
  1. See the visit history of each contact.
98
  2. Get an email notification for every new lead.
99
+ 3. Leadin stats show you where your leads are coming from.
100
  4. Segment your contact list based on page views and submissinos.
101
  5. Collect more contacts with the pop-up subscribe widget.
102
  6. Create custom tagged lists, choose the form triggers to add contacts and sync your contacts to third-party email services
103
 
104
  == Changelog ==
105
 
106
+ - Current version: 2.0.1
107
+ - Current version release: 2014-09-01
108
+
109
+ = 2.0.1 (2014.09.01) =
110
+ = Enhancements =
111
+ - Removed "Who read my post" widget analytics from the post editor
112
+ - Separated backend from frontend code to speed up ajax calls on both sides
113
+
114
+ - Bug fixes
115
+ - Fixed bug when deleting specifically selected contacts looked like all the contacts were deleted on the page refresh
116
+ - Organic traffic and paid traffic sources are now parsing more accurately
117
+ - Credit card forms will add to the timeline now but will block all credit card information
118
+ - Bulk edited tags now push contacts to ESP lists when added
119
+ - Lists with existing contacts retroactively push email addresses to corresponding ESP list
120
+ - Renamed MailChimp Contact Sync + Constant Contact Sync to MailChimp Connect + Constant Contact Connect
121
+ - Fixed returning contacts vs. new contacts in dashboard widget
122
+ - Contact export works again
123
+ - Fixed insecure content warning on SSL
124
+ - Non-administrators no longer can see the Leadin menu links or pages
125
+ - Settings link missing from plugins list page
126
+ - Line break contact notifications previews
127
+ - Setup a mailto link on the contact notification email in the details header
128
 
129
  = 2.0.0 (2014.08.11) =
130
  = Enhancements =
144
  = 1.2.0 (2014.06.25) =
145
  - Bug fixes
146
  - Contacts with default "contact status" were not showing up in the contact list
147
+ - WordPress admin backends secured with SSL can now be used with Leadin
148
  - Namespaced the referrer parsing library for the Sources widget
149
 
150
  = Enhancements =
151
+ - Leadin VIP program
152
 
153
  = 1.1.1 (2014.06.20) =
154
  - Bug fixes
156
 
157
  = 1.1.0 (2014.06.20) =
158
  - Bug fixes
159
+ - Leadin subscriber email confirmations were not sending
160
  - Removed smart contact segmenting for leads
161
 
162
  = Enhancements =
196
 
197
  = Enhancements =
198
  - Overhaul of settings page to make it easier to see which settings go with each power-up
199
+ - Launched Leadin Beta Program
200
 
201
  = 0.9.1 (2014.05.14) =
202
  - Bug fixes
299
 
300
  = Enhancements =
301
  - Improved readability on new lead notification emails
302
+ - Confirmation email added for new subscribers to the Leadin Subscribe Pop-up
303
  - Updated screenshots
304
  - Improved onboarding flow
305
  - Deleted unused and deprecated files
313
  - Add (blank page title tag) to emails and contact timeline for blank page titles
314
  - Fix link on admin nav menu bar to link to contact list
315
  - Ignore lead notifications and subscribe popup on login page
316
+ - Saving an email no longer overwrites all the Leadin options
317
  - Added live chat support
318
 
319
  = Enhancements =
320
  - New power-ups page
321
+ - Leadin Subscribe integrated into plugin as a power-up
322
  - Improved contact history styling + interface
323
  - Added visit, pageview and submission stats to the contact view
324
+ - Added Live Chat into the Leadin WordPress admin screens
325
+ - New Leadin icons for WordPres sidebar and admin nav menu
326
 
327
  = 0.4.6 (2013.02.11) =
328
  - Bug fixes
331
  - Bug fix "Select All" export
332
  - Bug fix for CSS "page views" hover triangle breaking to next line
333
  - Backwards compability for < jQuery 1.7.0
334
+ - Add Leadin link to admin bar
335
 
336
  = Enhancements =
337
  - New onboarding flow
338
 
339
  = 0.4.5 (2013.01.30) =
340
  = Enhancements =
341
+ - Integration with Leadin Subscribe
342
 
343
  = 0.4.4 (2013.01.24) =
344
  - Bug fixes
349
 
350
  = 0.4.3 (2013.01.13) =
351
  - Bug fixes
352
+ - Fixed Leadin form submission inserts for comments
353
  - Resolved various silent PHP warnings in administrative dashboard
354
+ - Fixed Leadin updater class to be compatible with WP3.8
355
  - Improved contact merging logic to be more reliable
356
 
357
  = Enhancements =
370
  - Added url for each page views in the contact timeline
371
  - Added source for each visit event
372
  - Tweak colors for contact timeline
373
+ - Default the Leadin menu to the contacts page
374
 
375
  = 0.4.1 (2013.12.18) =
376
  - Bug fixes
377
+ - Removed Leadin header from the contact timeline view
378
  - Updated the wording on the menu view picker above contacts list
379
  - Remove pre-mp6 styles if MP6 plugin is activated
380
  - Default totals leads/comments = 0 when leads table is empty instead of printing blank integer
400
  - Strip slashes from page titles in emails
401
 
402
  = Enhancements =
403
+ - Created separate Leadin menu in WordPress admin
404
  - CRM list of all contacts
405
  - Added ability to export list of contacts
406
+ - Leadin now distinguishes between a contact requests and comment submissions
407
  - Added link to CRM list inside each contact/comment email
408
 
409
  = 0.2.0 (2013.11.26) =