HubSpot – Free Marketing Plugin for WordPress - Version 0.9.0

Version Description

(2014.05.12) = - Bug fixes - Remove leadin-css file enqueue call

Download this release

Release Info

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

Code changes from version 0.7.2 to 0.9.0

Files changed (124) hide show
  1. admin/css/leadin-admin.css +137 -42
  2. admin/inc/class-leadin-contact.php +3 -1
  3. admin/inc/class-leadin-list-table.php +32 -28
  4. admin/inc/class-leadin-viewers.php +72 -0
  5. admin/js/jquery.lazyload.min.js +2 -0
  6. admin/js/leadin-admin.js +10 -1
  7. admin/leadin-admin.php +108 -9
  8. admin/sass/.sass-cache/0c3aa292b717031700a0344f604e0b99b479fc79/_susy.scssc +0 -0
  9. admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_container.scssc +0 -0
  10. admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_end.scssc +0 -0
  11. admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_isolate.scssc +0 -0
  12. admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_span.scssc +0 -0
  13. admin/sass/.sass-cache/52467c9ff883780d88c16e980bb8d43c6f3f113f/_susy.scssc +0 -0
  14. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_background.scssc +0 -0
  15. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_box-sizing.scssc +0 -0
  16. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_clearfix.scssc +0 -0
  17. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_prefix.scssc +0 -0
  18. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_rem.scssc +0 -0
  19. admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_support.scssc +0 -0
  20. admin/sass/.sass-cache/5cb96857c5f923ac31761ca34fd727781525b482/_math.scssc +0 -0
  21. admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_float.scssc +0 -0
  22. admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_shared.scssc +0 -0
  23. admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_support.scssc +0 -0
  24. admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_contact_detail_page.sassc +0 -0
  25. admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_grid.sassc +0 -0
  26. admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_metabox.sassc +0 -0
  27. admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_tables.sassc +0 -0
  28. admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/leadin-admin.sassc +0 -0
  29. admin/sass/.sass-cache/a1d71d7b609c5e9852c5bfc005fe6aac02f7590f/_support.scssc +0 -0
  30. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_appearance.scssc +0 -0
  31. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-clip.scssc +0 -0
  32. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-origin.scssc +0 -0
  33. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-size.scssc +0 -0
  34. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_border-radius.scssc +0 -0
  35. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box-shadow.scssc +0 -0
  36. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box-sizing.scssc +0 -0
  37. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box.scssc +0 -0
  38. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_columns.scssc +0 -0
  39. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_filter.scssc +0 -0
  40. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_font-face.scssc +0 -0
  41. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_hyphenation.scssc +0 -0
  42. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_images.scssc +0 -0
  43. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_inline-block.scssc +0 -0
  44. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_opacity.scssc +0 -0
  45. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_regions.scssc +0 -0
  46. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_shared.scssc +0 -0
  47. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_text-shadow.scssc +0 -0
  48. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_transform.scssc +0 -0
  49. admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_transition.scssc +0 -0
  50. admin/sass/.sass-cache/a3876a0695ee0091b635892c2b539b865026ee33/_settings.scssc +0 -0
  51. admin/sass/.sass-cache/a9f64e5d5dd6c28c118d0281ab7b3986e2729ea7/_grid-background.scssc +0 -0
  52. admin/sass/.sass-cache/aa1b4daeb1aa66522abf94710543639284144823/_clearfix.scssc +0 -0
  53. admin/sass/.sass-cache/aa1b4daeb1aa66522abf94710543639284144823/_hacks.scssc +0 -0
  54. admin/sass/.sass-cache/ba1a1c8b7407a74496e0f1bb0af5e060acd9c6b4/_css3.scssc +0 -0
  55. admin/sass/.sass-cache/ba1a1c8b7407a74496e0f1bb0af5e060acd9c6b4/_support.scssc +0 -0
  56. admin/sass/.sass-cache/e4b1f93193ae29c5c808f60975dad0a21092da77/_units.scssc +0 -0
  57. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_background.scssc +0 -0
  58. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_container.scssc +0 -0
  59. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_direction.scssc +0 -0
  60. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_margins.scssc +0 -0
  61. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_output.scssc +0 -0
  62. admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_padding.scssc +0 -0
  63. admin/sass/.sass-cache/eba4af504693c8b2c03a74241844b1c5ab414495/_su.scssc +0 -0
  64. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_contact_detail_page.sassc +0 -0
  65. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_contacts_list_page.sassc +0 -0
  66. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_settings_page.sassc +0 -0
  67. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_tables.sassc +0 -0
  68. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_variables.sassc +0 -0
  69. admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/leadin-admin.sassc +0 -0
  70. admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_grid.scssc +0 -0
  71. admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_maps.scssc +0 -0
  72. admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_settings.scssc +0 -0
  73. admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_validation.scssc +0 -0
  74. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_background.scssc +0 -0
  75. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_bleed.scssc +0 -0
  76. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_box-sizing.scssc +0 -0
  77. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_breakpoint-plugin.scssc +0 -0
  78. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_container.scssc +0 -0
  79. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_context.scssc +0 -0
  80. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_gallery.scssc +0 -0
  81. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_grids.scssc +0 -0
  82. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_gutters.scssc +0 -0
  83. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_isolate.scssc +0 -0
  84. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_margins.scssc +0 -0
  85. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_padding.scssc +0 -0
  86. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_rows.scssc +0 -0
  87. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_settings.scssc +0 -0
  88. admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_span.scssc +0 -0
  89. admin/sass/_contact_detail_page.sass +2 -0
  90. admin/sass/_grid.sass +3 -2
  91. admin/sass/_metabox.sass +16 -0
  92. admin/sass/_tables.sass +15 -2
  93. admin/sass/leadin-admin.sass +31 -0
  94. frontend/js/leadin.js +27 -3
  95. images/power-up-icon-constant-contact-list-sync.png +0 -0
  96. images/power-up-icon-constant-contact-list-sync@2x.png +0 -0
  97. images/power-up-icon-constant-contact-list-sync_small.png +0 -0
  98. images/power-up-icon-constant-contact-list-sync_small@2x.png +0 -0
  99. inc/class-emailer.php +11 -16
  100. inc/leadin-ajax-functions.php +43 -36
  101. inc/leadin-functions.php +153 -30
  102. leadin.php +33 -15
  103. lib/mixpanel/Base/{MixpanelBase.php → LI_MixpanelBase.php} +4 -1
  104. lib/mixpanel/ConsumerStrategies/{AbstractConsumer.php → LI_AbstractConsumer.php} +3 -2
  105. lib/mixpanel/ConsumerStrategies/{CurlConsumer.php → LI_CurlConsumer.php} +4 -3
  106. lib/mixpanel/ConsumerStrategies/{FileConsumer.php → LI_FileConsumer.php} +4 -3
  107. lib/mixpanel/ConsumerStrategies/{SocketConsumer.php → LI_SocketConsumer.php} +3 -2
  108. lib/mixpanel/{Mixpanel.php → LI_Mixpanel.php} +17 -14
  109. lib/mixpanel/Producers/{MixpanelBaseProducer.php → LI_MixpanelBaseProducer.php} +11 -10
  110. lib/mixpanel/Producers/{MixpanelEvents.php → LI_MixpanelEvents.php} +7 -6
  111. lib/mixpanel/Producers/{MixpanelPeople.php → LI_MixpanelPeople.php} +3 -2
  112. power-ups/constant-contact-list-sync.php +123 -0
  113. power-ups/constant-contact-list-sync/admin/constant-contact-list-sync-admin.php +205 -0
  114. power-ups/constant-contact-list-sync/inc/li_constant_contact.php +1114 -0
  115. power-ups/contacts.php +1 -0
  116. power-ups/contacts/admin/contacts-admin.php +16 -7
  117. power-ups/mailchimp-list-sync.php +6 -15
  118. power-ups/mailchimp-list-sync/admin/mailchimp-list-sync-admin.php +8 -7
  119. power-ups/mailchimp-list-sync/inc/MailChimp-API.php +1 -1
  120. power-ups/subscribe-widget.php +53 -22
  121. power-ups/subscribe-widget/admin/subscribe-widget-admin.php +140 -12
  122. power-ups/subscribe-widget/frontend/js/leadin-subscribe.js +6 -5
  123. readme.txt +58 -6
  124. screenshot-4.png +0 -0
admin/css/leadin-admin.css CHANGED
@@ -10,10 +10,10 @@
10
  padding-right: 1.25rem;
11
  margin-left: auto;
12
  margin-right: auto;
13
- margin: 0;
14
  padding: 0;
15
  }
16
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
17
  #leadin:after {
18
  content: "";
19
  display: table;
@@ -32,7 +32,7 @@
32
  margin-left: auto;
33
  margin-right: auto;
34
  }
35
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
36
  #leadin:after {
37
  content: "";
38
  display: table;
@@ -46,7 +46,8 @@
46
  @media (min-width: 782px) {
47
  /* line 12, ../sass/_grid.sass */
48
  #leadin {
49
- margin: 0;
 
50
  }
51
  }
52
 
@@ -57,7 +58,7 @@
57
  margin-bottom: 16px;
58
  *zoom: 1;
59
  }
60
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
61
  #leadin .top_table_controls:after {
62
  content: "";
63
  display: table;
@@ -83,67 +84,87 @@
83
  padding: 12px 0;
84
  line-height: 24px;
85
  font-weight: 300;
86
- font-size: 20px;
87
  text-decoration: none;
88
  }
89
- /* line 30, ../sass/_tables.sass */
 
 
 
 
 
 
90
  #leadin .table_segment_picker li a.current {
91
  margin-bottom: -2px;
92
  font-weight: 400;
93
  border-bottom: 2px solid #f66000;
94
  }
95
- /* line 35, ../sass/_tables.sass */
96
  #leadin .table_segment_picker li a.current, #leadin .table_segment_picker li a:hover, #leadin .table_segment_picker li a:active {
97
  color: #f66000;
98
  }
99
- /* line 38, ../sass/_tables.sass */
100
  #leadin .table_search {
101
  float: right;
102
  padding: 10px 0;
103
  padding-bottom: 9px;
104
  }
105
- /* line 44, ../sass/_tables.sass */
106
  #leadin table .leadin-contact-avatar {
107
  float: left;
108
  }
109
- /* line 48, ../sass/_tables.sass */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  #leadin.pre-mp6 .table_search {
111
  float: right;
112
  padding: 12px 0;
113
  padding-bottom: 11px;
114
  }
115
- /* line 53, ../sass/_tables.sass */
116
  #leadin.pre-mp6 table {
117
  background-color: white;
118
  border-color: #dedede;
119
  }
120
- /* line 59, ../sass/_tables.sass */
121
  #leadin.pre-mp6 table tr.alternate {
122
  background-color: white;
123
  }
124
- /* line 62, ../sass/_tables.sass */
125
  #leadin.pre-mp6 table th, #leadin.pre-mp6 table td {
126
  border-top: 0;
127
  padding: 12px 6px 11px;
128
  }
129
- /* line 66, ../sass/_tables.sass */
130
  #leadin.pre-mp6 table th a, #leadin.pre-mp6 table td a {
131
  padding: 0;
132
  }
133
- /* line 69, ../sass/_tables.sass */
134
  #leadin.pre-mp6 table th[scope="col"] {
135
  background: #eeeeee;
136
  font-family: sans-serif;
137
  font-size: 12px;
138
  text-shadow: none;
139
  }
140
- /* line 75, ../sass/_tables.sass */
141
  #leadin.pre-mp6 table td {
142
  border-color: #dedede;
143
  line-height: 18px;
144
  font-size: 14px;
145
  }
146
- /* line 80, ../sass/_tables.sass */
147
  #leadin.pre-mp6 table td .row-actions {
148
  float: left;
149
  }
@@ -170,7 +191,7 @@
170
  #leadin .metabox-holder {
171
  *zoom: 1;
172
  }
173
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
174
  #leadin .metabox-holder:after {
175
  content: "";
176
  display: table;
@@ -184,7 +205,7 @@
184
  color: #999999;
185
  border-top: 1px solid #dedede;
186
  }
187
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
188
  #leadin #leadin-footer:after {
189
  content: "";
190
  display: table;
@@ -214,6 +235,56 @@
214
  opacity: 0.6;
215
  }
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  /* line 1, ../sass/_settings_page.sass */
218
  #icon-leadin {
219
  background: url("../../images/leadin-icon-32x32.png") top center no-repeat;
@@ -270,7 +341,7 @@
270
  margin: 0;
271
  *zoom: 1;
272
  }
273
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
274
  .steps .step-names:after {
275
  content: "";
276
  display: table;
@@ -374,7 +445,7 @@
374
  *zoom: 1;
375
  padding: 9px 15px 4px 0;
376
  }
377
- /* line 38, ../../../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
378
  #leadin .header-wrap:after {
379
  content: "";
380
  display: table;
@@ -393,27 +464,31 @@
393
  #leadin .contact-name {
394
  line-height: 40px;
395
  }
396
- /* line 19, ../sass/_contact_detail_page.sass */
 
 
 
 
397
  #leadin .contact-info label {
398
  font-weight: bold;
399
  line-height: 1;
400
  cursor: default;
401
  }
402
- /* line 24, ../sass/_contact_detail_page.sass */
403
  #leadin .contact-history {
404
  padding-left: 20px;
405
  margin-left: 20px;
406
  border-left: 2px solid #dedede;
407
  }
408
- /* line 31, ../sass/_contact_detail_page.sass */
409
  #leadin .contact-history .session + .session {
410
  margin-top: 30px;
411
  }
412
- /* line 34, ../sass/_contact_detail_page.sass */
413
  #leadin .contact-history .session-date {
414
  position: relative;
415
  }
416
- /* line 37, ../sass/_contact_detail_page.sass */
417
  #leadin .contact-history .session-date:before {
418
  content: "\2022";
419
  font-size: 32px;
@@ -425,7 +500,7 @@
425
  top: 9px;
426
  color: #dedede;
427
  }
428
- /* line 48, ../sass/_contact_detail_page.sass */
429
  #leadin .contact-history .events {
430
  background-color: white;
431
  border: 1px solid #dedede;
@@ -433,66 +508,66 @@
433
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
434
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
435
  }
436
- /* line 53, ../sass/_contact_detail_page.sass */
437
  #leadin .contact-history .event {
438
  margin: 0;
439
  padding: 10px 20px;
440
  border-bottom: 1px solid #dedede;
441
  border-left: 4px solid;
442
  }
443
- /* line 60, ../sass/_contact_detail_page.sass */
444
  #leadin .contact-history .event:first-child {
445
  border-top: 0;
446
  }
447
- /* line 63, ../sass/_contact_detail_page.sass */
448
  #leadin .contact-history .event.pageview {
449
  border-left-color: #2288cc;
450
  color: #2288cc;
451
  }
452
- /* line 67, ../sass/_contact_detail_page.sass */
453
  #leadin .contact-history .event.form-submission {
454
  border-left-color: #f66000;
455
  color: #f66000;
456
  }
457
- /* line 71, ../sass/_contact_detail_page.sass */
458
  #leadin .contact-history .event.source {
459
  border-left-color: #99aa1f;
460
  color: #99aa1f;
461
  }
462
- /* line 75, ../sass/_contact_detail_page.sass */
463
  #leadin .contact-history .event-title {
464
  margin: 0;
465
  font-size: 13px;
466
  font-weight: 600;
467
  }
468
- /* line 80, ../sass/_contact_detail_page.sass */
469
  #leadin .contact-history .event-time-range {
470
  float: right;
471
  font-weight: 400;
472
  font-size: 0.85em;
473
  color: #999999;
474
  }
475
- /* line 86, ../sass/_contact_detail_page.sass */
476
  #leadin .contact-history .event-detail {
477
  margin-top: 20px;
478
  color: #444444;
479
  }
480
- /* line 90, ../sass/_contact_detail_page.sass */
481
  #leadin .contact-history .event-detail li + li {
482
  padding-top: 6px;
483
  border-top: 1px solid #eeeeee;
484
  }
485
- /* line 95, ../sass/_contact_detail_page.sass */
486
  #leadin .contact-history .visit-source p {
487
  margin: 0;
488
  color: #1f6696;
489
  }
490
- /* line 99, ../sass/_contact_detail_page.sass */
491
  #leadin .contact-history .pageview-url {
492
  margin: 0;
493
  color: #cccccc;
494
  }
495
- /* line 103, ../sass/_contact_detail_page.sass */
496
  #leadin .contact-history .field-label {
497
  text-transform: uppercase;
498
  letter-spacing: 0.05em;
@@ -500,11 +575,11 @@
500
  margin-bottom: 6px;
501
  font-size: 0.9em;
502
  }
503
- /* line 110, ../sass/_contact_detail_page.sass */
504
  #leadin .contact-history .field-value {
505
  margin: 0;
506
  }
507
- /* line 115, ../sass/_contact_detail_page.sass */
508
  #leadin.pre-mp6 .events {
509
  background-color: #f9f9f9;
510
  }
@@ -544,3 +619,23 @@
544
  .powerup-list .powerup.activated h2, .powerup-list .powerup.activated p {
545
  color: #1f7d71;
546
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  padding-right: 1.25rem;
11
  margin-left: auto;
12
  margin-right: auto;
13
+ margin: 10px 0 0;
14
  padding: 0;
15
  }
16
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
17
  #leadin:after {
18
  content: "";
19
  display: table;
32
  margin-left: auto;
33
  margin-right: auto;
34
  }
35
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
36
  #leadin:after {
37
  content: "";
38
  display: table;
46
  @media (min-width: 782px) {
47
  /* line 12, ../sass/_grid.sass */
48
  #leadin {
49
+ margin: 10px 0 0;
50
+ padding: 0;
51
  }
52
  }
53
 
58
  margin-bottom: 16px;
59
  *zoom: 1;
60
  }
61
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
62
  #leadin .top_table_controls:after {
63
  content: "";
64
  display: table;
84
  padding: 12px 0;
85
  line-height: 24px;
86
  font-weight: 300;
87
+ font-size: 16px;
88
  text-decoration: none;
89
  }
90
+ @media (min-width: 782px) {
91
+ /* line 22, ../sass/_tables.sass */
92
+ #leadin .table_segment_picker li a {
93
+ font-size: 20px;
94
+ }
95
+ }
96
+ /* line 33, ../sass/_tables.sass */
97
  #leadin .table_segment_picker li a.current {
98
  margin-bottom: -2px;
99
  font-weight: 400;
100
  border-bottom: 2px solid #f66000;
101
  }
102
+ /* line 38, ../sass/_tables.sass */
103
  #leadin .table_segment_picker li a.current, #leadin .table_segment_picker li a:hover, #leadin .table_segment_picker li a:active {
104
  color: #f66000;
105
  }
106
+ /* line 41, ../sass/_tables.sass */
107
  #leadin .table_search {
108
  float: right;
109
  padding: 10px 0;
110
  padding-bottom: 9px;
111
  }
112
+ /* line 47, ../sass/_tables.sass */
113
  #leadin table .leadin-contact-avatar {
114
  float: left;
115
  }
116
+ /* line 50, ../sass/_tables.sass */
117
+ #leadin table th, #leadin table td {
118
+ display: none;
119
+ }
120
+ /* line 53, ../sass/_tables.sass */
121
+ #leadin table th:nth-child(-n+3), #leadin table td:nth-child(-n+3) {
122
+ display: table-cell;
123
+ }
124
+ @media (min-width: 782px) {
125
+ /* line 50, ../sass/_tables.sass */
126
+ #leadin table th, #leadin table td {
127
+ display: table-cell;
128
+ }
129
+ }
130
+ /* line 60, ../sass/_tables.sass */
131
  #leadin.pre-mp6 .table_search {
132
  float: right;
133
  padding: 12px 0;
134
  padding-bottom: 11px;
135
  }
136
+ /* line 65, ../sass/_tables.sass */
137
  #leadin.pre-mp6 table {
138
  background-color: white;
139
  border-color: #dedede;
140
  }
141
+ /* line 71, ../sass/_tables.sass */
142
  #leadin.pre-mp6 table tr.alternate {
143
  background-color: white;
144
  }
145
+ /* line 74, ../sass/_tables.sass */
146
  #leadin.pre-mp6 table th, #leadin.pre-mp6 table td {
147
  border-top: 0;
148
  padding: 12px 6px 11px;
149
  }
150
+ /* line 78, ../sass/_tables.sass */
151
  #leadin.pre-mp6 table th a, #leadin.pre-mp6 table td a {
152
  padding: 0;
153
  }
154
+ /* line 81, ../sass/_tables.sass */
155
  #leadin.pre-mp6 table th[scope="col"] {
156
  background: #eeeeee;
157
  font-family: sans-serif;
158
  font-size: 12px;
159
  text-shadow: none;
160
  }
161
+ /* line 87, ../sass/_tables.sass */
162
  #leadin.pre-mp6 table td {
163
  border-color: #dedede;
164
  line-height: 18px;
165
  font-size: 14px;
166
  }
167
+ /* line 92, ../sass/_tables.sass */
168
  #leadin.pre-mp6 table td .row-actions {
169
  float: left;
170
  }
191
  #leadin .metabox-holder {
192
  *zoom: 1;
193
  }
194
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
195
  #leadin .metabox-holder:after {
196
  content: "";
197
  display: table;
205
  color: #999999;
206
  border-top: 1px solid #dedede;
207
  }
208
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
209
  #leadin #leadin-footer:after {
210
  content: "";
211
  display: table;
235
  opacity: 0.6;
236
  }
237
 
238
+ /* line 50, ../sass/leadin-admin.sass */
239
+ .leadin-dynamic-avatar_0 {
240
+ background-color: #f88e4b;
241
+ }
242
+
243
+ /* line 53, ../sass/leadin-admin.sass */
244
+ .leadin-dynamic-avatar_1 {
245
+ background-color: #64aada;
246
+ }
247
+
248
+ /* line 56, ../sass/leadin-admin.sass */
249
+ .leadin-dynamic-avatar_2 {
250
+ background-color: #64c2b6;
251
+ }
252
+
253
+ /* line 59, ../sass/leadin-admin.sass */
254
+ .leadin-dynamic-avatar_3 {
255
+ background-color: #cf7baa;
256
+ }
257
+
258
+ /* line 62, ../sass/leadin-admin.sass */
259
+ .leadin-dynamic-avatar_4 {
260
+ background-color: #e7c24b;
261
+ }
262
+
263
+ /* line 65, ../sass/leadin-admin.sass */
264
+ .leadin-dynamic-avatar_5 {
265
+ background-color: #9387da;
266
+ }
267
+
268
+ /* line 68, ../sass/leadin-admin.sass */
269
+ .leadin-dynamic-avatar_6 {
270
+ background-color: #d6dd99;
271
+ }
272
+
273
+ /* line 71, ../sass/leadin-admin.sass */
274
+ .leadin-dynamic-avatar_7 {
275
+ background-color: #ff4c4c;
276
+ }
277
+
278
+ /* line 74, ../sass/leadin-admin.sass */
279
+ .leadin-dynamic-avatar_8 {
280
+ background-color: #99583d;
281
+ }
282
+
283
+ /* line 77, ../sass/leadin-admin.sass */
284
+ .leadin-dynamic-avatar_9 {
285
+ background-color: #54cc14;
286
+ }
287
+
288
  /* line 1, ../sass/_settings_page.sass */
289
  #icon-leadin {
290
  background: url("../../images/leadin-icon-32x32.png") top center no-repeat;
341
  margin: 0;
342
  *zoom: 1;
343
  }
344
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
345
  .steps .step-names:after {
346
  content: "";
347
  display: table;
445
  *zoom: 1;
446
  padding: 9px 15px 4px 0;
447
  }
448
+ /* line 38, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-core-1.0.0.alpha.19/stylesheets/compass/utilities/general/_clearfix.scss */
449
  #leadin .header-wrap:after {
450
  content: "";
451
  display: table;
464
  #leadin .contact-name {
465
  line-height: 40px;
466
  }
467
+ /* line 18, ../sass/_contact_detail_page.sass */
468
+ #leadin .contact-info h3 {
469
+ margin: 0;
470
+ }
471
+ /* line 21, ../sass/_contact_detail_page.sass */
472
  #leadin .contact-info label {
473
  font-weight: bold;
474
  line-height: 1;
475
  cursor: default;
476
  }
477
+ /* line 26, ../sass/_contact_detail_page.sass */
478
  #leadin .contact-history {
479
  padding-left: 20px;
480
  margin-left: 20px;
481
  border-left: 2px solid #dedede;
482
  }
483
+ /* line 33, ../sass/_contact_detail_page.sass */
484
  #leadin .contact-history .session + .session {
485
  margin-top: 30px;
486
  }
487
+ /* line 36, ../sass/_contact_detail_page.sass */
488
  #leadin .contact-history .session-date {
489
  position: relative;
490
  }
491
+ /* line 39, ../sass/_contact_detail_page.sass */
492
  #leadin .contact-history .session-date:before {
493
  content: "\2022";
494
  font-size: 32px;
500
  top: 9px;
501
  color: #dedede;
502
  }
503
+ /* line 50, ../sass/_contact_detail_page.sass */
504
  #leadin .contact-history .events {
505
  background-color: white;
506
  border: 1px solid #dedede;
508
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
509
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
510
  }
511
+ /* line 55, ../sass/_contact_detail_page.sass */
512
  #leadin .contact-history .event {
513
  margin: 0;
514
  padding: 10px 20px;
515
  border-bottom: 1px solid #dedede;
516
  border-left: 4px solid;
517
  }
518
+ /* line 62, ../sass/_contact_detail_page.sass */
519
  #leadin .contact-history .event:first-child {
520
  border-top: 0;
521
  }
522
+ /* line 65, ../sass/_contact_detail_page.sass */
523
  #leadin .contact-history .event.pageview {
524
  border-left-color: #2288cc;
525
  color: #2288cc;
526
  }
527
+ /* line 69, ../sass/_contact_detail_page.sass */
528
  #leadin .contact-history .event.form-submission {
529
  border-left-color: #f66000;
530
  color: #f66000;
531
  }
532
+ /* line 73, ../sass/_contact_detail_page.sass */
533
  #leadin .contact-history .event.source {
534
  border-left-color: #99aa1f;
535
  color: #99aa1f;
536
  }
537
+ /* line 77, ../sass/_contact_detail_page.sass */
538
  #leadin .contact-history .event-title {
539
  margin: 0;
540
  font-size: 13px;
541
  font-weight: 600;
542
  }
543
+ /* line 82, ../sass/_contact_detail_page.sass */
544
  #leadin .contact-history .event-time-range {
545
  float: right;
546
  font-weight: 400;
547
  font-size: 0.85em;
548
  color: #999999;
549
  }
550
+ /* line 88, ../sass/_contact_detail_page.sass */
551
  #leadin .contact-history .event-detail {
552
  margin-top: 20px;
553
  color: #444444;
554
  }
555
+ /* line 92, ../sass/_contact_detail_page.sass */
556
  #leadin .contact-history .event-detail li + li {
557
  padding-top: 6px;
558
  border-top: 1px solid #eeeeee;
559
  }
560
+ /* line 97, ../sass/_contact_detail_page.sass */
561
  #leadin .contact-history .visit-source p {
562
  margin: 0;
563
  color: #1f6696;
564
  }
565
+ /* line 101, ../sass/_contact_detail_page.sass */
566
  #leadin .contact-history .pageview-url {
567
  margin: 0;
568
  color: #cccccc;
569
  }
570
+ /* line 105, ../sass/_contact_detail_page.sass */
571
  #leadin .contact-history .field-label {
572
  text-transform: uppercase;
573
  letter-spacing: 0.05em;
575
  margin-bottom: 6px;
576
  font-size: 0.9em;
577
  }
578
+ /* line 112, ../sass/_contact_detail_page.sass */
579
  #leadin .contact-history .field-value {
580
  margin: 0;
581
  }
582
+ /* line 117, ../sass/_contact_detail_page.sass */
583
  #leadin.pre-mp6 .events {
584
  background-color: #f9f9f9;
585
  }
619
  .powerup-list .powerup.activated h2, .powerup-list .powerup.activated p {
620
  color: #1f7d71;
621
  }
622
+
623
+ /* line 3, ../sass/_metabox.sass */
624
+ #li_analytics-meta .li-analytics-link {
625
+ float: left;
626
+ }
627
+ /* line 6, ../sass/_metabox.sass */
628
+ #li_analytics-meta .li-analytics-link .li-analytics__face {
629
+ height: 35px;
630
+ width: 35px;
631
+ margin-right: 5px;
632
+ margin-bottom: 5px;
633
+ }
634
+ /* line 12, ../sass/_metabox.sass */
635
+ #li_analytics-meta .hidden_face {
636
+ display: none;
637
+ }
638
+ /* line 15, ../sass/_metabox.sass */
639
+ #li_analytics-meta .show-all-faces-container {
640
+ clear: both;
641
+ }
admin/inc/class-leadin-contact.php CHANGED
@@ -13,7 +13,7 @@ class LI_Contact {
13
  /**
14
  * Class constructor
15
  */
16
- function LI_Contact () {
17
 
18
  }
19
 
@@ -65,6 +65,7 @@ class LI_Contact {
65
  FROM
66
  li_pageviews
67
  WHERE
 
68
  lead_hashkey LIKE %s ORDER BY event_date DESC", '%b %D', '%b %D %l:%i%p', $this->hashkey);
69
 
70
  $pageviews = $wpdb->get_results($q, ARRAY_A);
@@ -81,6 +82,7 @@ class LI_Contact {
81
  FROM
82
  li_submissions
83
  WHERE
 
84
  lead_hashkey = '%s' ORDER BY event_date DESC", '%b %D %l:%i%p', $this->hashkey);
85
 
86
  $submissions = $wpdb->get_results($q, ARRAY_A);
13
  /**
14
  * Class constructor
15
  */
16
+ function __construct () {
17
 
18
  }
19
 
65
  FROM
66
  li_pageviews
67
  WHERE
68
+ pageview_deleted = 0 AND
69
  lead_hashkey LIKE %s ORDER BY event_date DESC", '%b %D', '%b %D %l:%i%p', $this->hashkey);
70
 
71
  $pageviews = $wpdb->get_results($q, ARRAY_A);
82
  FROM
83
  li_submissions
84
  WHERE
85
+ form_deleted = 0 AND
86
  lead_hashkey = '%s' ORDER BY event_date DESC", '%b %D %l:%i%p', $this->hashkey);
87
 
88
  $submissions = $wpdb->get_results($q, ARRAY_A);
admin/inc/class-leadin-list-table.php CHANGED
@@ -187,32 +187,33 @@ class LI_List_Table extends WP_List_Table {
187
  $ids_to_delete .= ',';
188
  }
189
 
190
- $q = $wpdb->prepare("SELECT hashkey FROM li_leads WHERE lead_id IN ( " . $ids_to_delete . " )", $ids_to_delete);
191
- $hashes = $wpdb->get_results($q);
192
 
193
- for ( $i = 0; $i < count($hashes); $i++ )
194
  {
 
 
 
195
 
196
- $hashes_to_delete .= "'". $hashes[$i]->hashkey. "'";
197
-
198
- if ( $i != (count($hashes)-1) )
199
- $hashes_to_delete .= ",";
200
- }
201
 
202
- //Detect when a bulk action is being triggered...
203
- if( 'delete' === $this->current_action() )
204
- {
205
- $q = $wpdb->prepare("DELETE FROM li_pageviews WHERE lead_hashkey IN (" . $hashes_to_delete . ")", "");
206
- $delete_pageviews = $wpdb->query($q);
207
 
208
- $q = $wpdb->prepare("DELETE FROM li_submissions WHERE lead_hashkey IN (" . $hashes_to_delete . ")", "");
209
- $delete_submissions = $wpdb->query($q);
210
 
211
- $q = $wpdb->prepare("DELETE FROM li_leads WHERE lead_id IN (" . $ids_to_delete . ")", "");
212
- $delete_leads = $wpdb->query($q);
 
213
  }
214
  }
215
-
216
  }
217
 
218
  /**
@@ -252,7 +253,7 @@ class LI_List_Table extends WP_List_Table {
252
  li_leads l
253
  LEFT JOIN li_submissions s ON l.hashkey = s.lead_hashkey
254
  LEFT JOIN li_pageviews p ON l.hashkey = p.lead_hashkey
255
- WHERE l.lead_email != ''", '%Y/%m/%d %l:%i%p', '%Y/%m/%d %l:%i%p');
256
 
257
  $q .= $mysql_contact_type_filter;
258
  $q .= ( $mysql_search_filter ? $mysql_search_filter : "" );
@@ -264,7 +265,7 @@ class LI_List_Table extends WP_List_Table {
264
 
265
  foreach ( $leads as $lead )
266
  {
267
- $q = $wpdb->prepare("SELECT COUNT(DISTINCT pageview_id) FROM li_pageviews WHERE lead_hashkey = %s AND pageview_session_start = 1", $lead->hashkey);
268
  $pageviews = $wpdb->get_var($q);
269
  $lead->lead_visits = $pageviews;
270
 
@@ -275,16 +276,19 @@ class LI_List_Table extends WP_List_Table {
275
  else if ( $lead->lead_status == 'comment' )
276
  $lead_status = 'Commenter';
277
 
 
 
 
278
  $lead_array = array(
279
  'ID' => $lead->lead_id,
280
- 'email' => sprintf('<a href="?page=%s&action=%s&lead=%s">' . "<img class='pull-left leadin-contact-avatar' 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),
281
  'status' => $lead_status,
282
  'visits' => ( !$lead->lead_visits ? 1 : $lead->lead_visits ),
283
  'submissions' => $lead->lead_form_submissions,
284
  'pageviews' => $lead->lead_pageviews,
285
  'date' => $lead->lead_date,
286
  'last_visit' => $lead->last_visit,
287
- 'source' => ( $lead->lead_source ? "<a title='Visit page' href='" . $lead->lead_source . "' target='_blank'>" . $lead->lead_source . "</a>" : 'Direct' )
288
  );
289
 
290
  array_push($all_leads, $lead_array);
@@ -303,13 +307,13 @@ class LI_List_Table extends WP_List_Table {
303
  $q = $wpdb->prepare("
304
  SELECT
305
  COUNT(DISTINCT lead_email) AS total_contacts,
306
- ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'lead' AND lead_email != '' ) AS total_leads,
307
- ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'comment' AND lead_email != '' ) AS total_comments,
308
- ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'subscribe' AND lead_email != '' ) AS total_subscribes
309
  FROM
310
  li_leads
311
  WHERE
312
- lead_email != ''", "");
313
 
314
  $totals = $wpdb->get_row($q);
315
  return $totals;
@@ -420,12 +424,12 @@ class LI_List_Table extends WP_List_Table {
420
  $this->process_bulk_action();
421
  $this->data = $this->get_leads();;
422
 
423
- $orderby = ( !empty($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'date' );
424
  $order = ( !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'desc' );
425
 
426
  function usort_reorder($a,$b)
427
  {
428
- $orderby = ( !empty($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'date' );
429
  $order = ( !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'desc' );
430
 
431
  if ( $a[$orderby] == $b[$orderby] )
187
  $ids_to_delete .= ',';
188
  }
189
 
190
+ $q = $wpdb->prepare("SELECT hashkey FROM li_leads WHERE lead_id IN ( " . $ids_to_delete . " )", "");
191
+ $hashes = $wpdb->get_results($q);
192
 
193
+ if ( count($hashes) )
194
  {
195
+ for ( $i = 0; $i < count($hashes); $i++ )
196
+ {
197
+ $hashes_to_delete .= "'". $hashes[$i]->hashkey. "'";
198
 
199
+ if ( $i != (count($hashes)-1) )
200
+ $hashes_to_delete .= ",";
201
+ }
 
 
202
 
203
+ //Detect when a bulk action is being triggered...
204
+ if( 'delete' === $this->current_action() )
205
+ {
206
+ $q = $wpdb->prepare("UPDATE li_pageviews SET pageview_deleted = 1 WHERE lead_hashkey IN (" . $hashes_to_delete . ")", "");
207
+ $delete_pageviews = $wpdb->query($q);
208
 
209
+ $q = $wpdb->prepare("UPDATE li_submissions SET form_deleted = 1 WHERE lead_hashkey IN (" . $hashes_to_delete . ")", "");
210
+ $delete_submissions = $wpdb->query($q);
211
 
212
+ $q = $wpdb->prepare("UPDATE li_leads SET lead_deleted = 1 WHERE lead_id IN (" . $ids_to_delete . ")", "");
213
+ $delete_leads = $wpdb->query($q);
214
+ }
215
  }
216
  }
 
217
  }
218
 
219
  /**
253
  li_leads l
254
  LEFT JOIN li_submissions s ON l.hashkey = s.lead_hashkey
255
  LEFT JOIN li_pageviews p ON l.hashkey = p.lead_hashkey
256
+ WHERE l.lead_email != '' AND l.lead_deleted = 0 ", '%Y/%m/%d %l:%i%p', '%Y/%m/%d %l:%i%p');
257
 
258
  $q .= $mysql_contact_type_filter;
259
  $q .= ( $mysql_search_filter ? $mysql_search_filter : "" );
265
 
266
  foreach ( $leads as $lead )
267
  {
268
+ $q = $wpdb->prepare("SELECT COUNT(DISTINCT pageview_id) FROM li_pageviews WHERE lead_hashkey = %s AND pageview_session_start = 1 AND pageview_deleted = 0", $lead->hashkey);
269
  $pageviews = $wpdb->get_var($q);
270
  $lead->lead_visits = $pageviews;
271
 
276
  else if ( $lead->lead_status == 'comment' )
277
  $lead_status = 'Commenter';
278
 
279
+ $url_parts = parse_url($lead->lead_source);
280
+ $url = urldecode(rtrim($url_parts['host'] . '/' . $url_parts['path'], '/'));
281
+
282
  $lead_array = array(
283
  'ID' => $lead->lead_id,
284
+ '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),
285
  'status' => $lead_status,
286
  'visits' => ( !$lead->lead_visits ? 1 : $lead->lead_visits ),
287
  'submissions' => $lead->lead_form_submissions,
288
  'pageviews' => $lead->lead_pageviews,
289
  'date' => $lead->lead_date,
290
  'last_visit' => $lead->last_visit,
291
+ 'source' => ( $lead->lead_source ? "<a title='Visit page' href='" . $lead->lead_source . "' target='_blank'>" . $url . "</a>" : 'Direct' )
292
  );
293
 
294
  array_push($all_leads, $lead_array);
307
  $q = $wpdb->prepare("
308
  SELECT
309
  COUNT(DISTINCT lead_email) AS total_contacts,
310
+ ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'lead' AND lead_email != '' AND lead_deleted = 0 ) AS total_leads,
311
+ ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'comment' AND lead_email != '' AND lead_deleted = 0 ) AS total_comments,
312
+ ( SELECT COUNT(DISTINCT lead_email) FROM li_leads WHERE lead_status = 'subscribe' AND lead_email != '' AND lead_deleted = 0 ) AS total_subscribes
313
  FROM
314
  li_leads
315
  WHERE
316
+ lead_email != '' AND lead_deleted = 0", "");
317
 
318
  $totals = $wpdb->get_row($q);
319
  return $totals;
424
  $this->process_bulk_action();
425
  $this->data = $this->get_leads();;
426
 
427
+ $orderby = ( !empty($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'last_visit' );
428
  $order = ( !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'desc' );
429
 
430
  function usort_reorder($a,$b)
431
  {
432
+ $orderby = ( !empty($_REQUEST['orderby']) ? $_REQUEST['orderby'] : 'last_visit' );
433
  $order = ( !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'desc' );
434
 
435
  if ( $a[$orderby] == $b[$orderby] )
admin/inc/class-leadin-viewers.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //=============================================
3
+ // LI_Viewers Class
4
+ //=============================================
5
+ class LI_Viewers {
6
+
7
+ /**
8
+ * Variables
9
+ */
10
+ var $viewers;
11
+ var $submissions;
12
+
13
+ /**
14
+ * Class constructor
15
+ */
16
+ function __construct ()
17
+ {
18
+
19
+ }
20
+
21
+ /**
22
+ * Get identified readers from a url
23
+ * @param string
24
+ * @return array
25
+ */
26
+ function get_identified_viewers ( $pageview_url )
27
+ {
28
+ global $wpdb;
29
+ $q = $wpdb->prepare(
30
+ "SELECT
31
+ li_leads.lead_email, li_leads.lead_id, MAX(li_pageviews.pageview_date) AS pageview_date
32
+ FROM
33
+ li_leads, li_pageviews
34
+ WHERE
35
+ li_pageviews.pageview_url = %s AND
36
+ li_pageviews.lead_hashkey = li_leads.hashkey AND
37
+ li_leads.lead_deleted = 0 AND
38
+ li_leads.lead_email != ''
39
+ GROUP BY
40
+ li_leads.lead_id
41
+ ORDER BY
42
+ pageview_date DESC", $pageview_url);
43
+ $this->viewers = $wpdb->get_results($q);
44
+ return $this->viewers;
45
+ }
46
+
47
+ /**
48
+ * Get identified readers from a url
49
+ * @param string
50
+ * @return array
51
+ */
52
+ function get_submissions ( $pageview_url )
53
+ {
54
+ global $wpdb;
55
+ $q = $wpdb->prepare(
56
+ "SELECT
57
+ li_leads.lead_email, li_leads.lead_id, MAX(li_submissions.form_date) AS form_date
58
+ FROM
59
+ li_leads, li_submissions
60
+ WHERE
61
+ li_submissions.form_page_url = %s AND
62
+ li_submissions.lead_hashkey = li_leads.hashkey AND
63
+ li_leads.lead_deleted = 0 AND
64
+ li_submissions.form_deleted = 0
65
+ GROUP BY
66
+ li_leads.lead_id
67
+ ORDER BY
68
+ form_date DESC", $pageview_url);
69
+ $this->submissions = $wpdb->get_results($q);
70
+ return $this->submissions;
71
+ }
72
+ }
admin/js/jquery.lazyload.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */
2
+ !function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document);
admin/js/leadin-admin.js CHANGED
@@ -1,3 +1,12 @@
1
  jQuery(document).ready( function ( $ ) {
2
-
 
 
 
 
 
 
 
 
 
3
  });
1
  jQuery(document).ready( function ( $ ) {
2
+ $('.show_all_faces').on('click', function ( e ) {
3
+ var $this = $(this);
4
+ $this.closest('td').find('.hidden_face').removeClass('hidden_face');
5
+ $this.remove();
6
+ $("html,body").trigger("scroll");
7
+ });
8
+
9
+ $("img.lazy").lazyload({
10
+ effect : "fadeIn"
11
+ });
12
  });
admin/leadin-admin.php CHANGED
@@ -26,6 +26,9 @@ if ( !class_exists('LI_Contact') )
26
  if ( !class_exists('LI_Pointers') )
27
  require_once LEADIN_PLUGIN_DIR . '/admin/inc/class-leadin-pointers.php';
28
 
 
 
 
29
  include_once(ABSPATH . 'wp-admin/includes/plugin.php');
30
 
31
  //=============================================
@@ -34,6 +37,7 @@ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
34
  class WPLeadInAdmin {
35
 
36
  var $admin_power_ups;
 
37
 
38
  /**
39
  * Class constructor
@@ -51,6 +55,7 @@ class WPLeadInAdmin {
51
  add_action('admin_menu', array(&$this, 'leadin_add_menu_items'));
52
  add_action('admin_init', array(&$this, 'leadin_build_settings_page'));
53
  add_action('admin_print_styles', array(&$this, 'add_leadin_admin_styles'));
 
54
  }
55
  }
56
 
@@ -74,6 +79,7 @@ class WPLeadInAdmin {
74
  {
75
  $power_up->admin_init();
76
 
 
77
  if ( $power_up->menu_text == 'Contacts' )
78
  add_menu_page('LeadIn', 'LeadIn', 'manage_categories', 'leadin_contacts', array($power_up, 'power_up_setup_callback'), LEADIN_PATH . '/images/' . ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'leadin-icon-32x32.png' : 'leadin-svg-icon.svg'));
79
  else if ( $power_up->menu_text )
@@ -138,11 +144,8 @@ class WPLeadInAdmin {
138
  function leadin_options_section_heading ( )
139
  {
140
  ?>
141
- <div id="message" class="updated below-h2">
142
- <p>Visitor tracking is <span style='color: #090; font-weight: bold;'>installed and tracking visitors</span>.</p>
143
- <p>The next time a visitor fills out a form on your WordPress site with an email address, LeadIn will send you an email with the contact's referral source and page view history.</p>
144
- <p>All of your visitor's form submissions are stored in your <a href='<?php echo get_bloginfo('wpurl');?>/wp-admin/admin.php?page=leadin_contacts'>LeadIn Contacts</a>.</p>
145
- </div>
146
  <?php
147
 
148
  $this->print_hidden_settings_fields();
@@ -156,6 +159,10 @@ class WPLeadInAdmin {
156
  $li_db_version = ( $options['li_db_version'] ? $options['li_db_version'] : LEADIN_DB_VERSION );
157
  $ignore_settings_popup = ( $options['ignore_settings_popup'] ? $options['ignore_settings_popup'] : 0 );
158
  $onboarding_complete = ( $options['onboarding_complete'] ? $options['onboarding_complete'] : 0 );
 
 
 
 
159
 
160
  printf(
161
  '<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
@@ -176,6 +183,16 @@ class WPLeadInAdmin {
176
  '<input id="onboarding_complete" type="hidden" name="leadin_options[onboarding_complete]" value="%d"/>',
177
  $onboarding_complete
178
  );
 
 
 
 
 
 
 
 
 
 
179
  }
180
 
181
  function update_option_leadin_options_callback ( $old_value, $new_value )
@@ -303,12 +320,12 @@ class WPLeadInAdmin {
303
  function li_email_callback ()
304
  {
305
  $options = get_option('leadin_options');
306
- $li_email = ( $options['li_email'] ? $options['li_email'] : get_bloginfo('admin_email') ); // Get email from plugin settings, if none set, use admin email
307
-
308
  printf(
309
- '<input id="li_email" type="text" id="title" name="leadin_options[li_email]" value="%s" size="50"/><br/><span class="description">Separate multiple emails with commas</span>',
310
  $li_email
311
- );
312
  }
313
 
314
  /**
@@ -503,6 +520,88 @@ class WPLeadInAdmin {
503
  <!-- end SnapEngage code -->
504
  <?php
505
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  }
507
 
508
  ?>
26
  if ( !class_exists('LI_Pointers') )
27
  require_once LEADIN_PLUGIN_DIR . '/admin/inc/class-leadin-pointers.php';
28
 
29
+ if ( !class_exists('LI_Viewers') )
30
+ require_once LEADIN_PLUGIN_DIR . '/admin/inc/class-leadin-viewers.php';
31
+
32
  include_once(ABSPATH . 'wp-admin/includes/plugin.php');
33
 
34
  //=============================================
37
  class WPLeadInAdmin {
38
 
39
  var $admin_power_ups;
40
+ var $li_viewers;
41
 
42
  /**
43
  * Class constructor
55
  add_action('admin_menu', array(&$this, 'leadin_add_menu_items'));
56
  add_action('admin_init', array(&$this, 'leadin_build_settings_page'));
57
  add_action('admin_print_styles', array(&$this, 'add_leadin_admin_styles'));
58
+ add_action('add_meta_boxes', array(&$this, 'add_li_analytics_meta_box' ));
59
  }
60
  }
61
 
79
  {
80
  $power_up->admin_init();
81
 
82
+ // Creates the menu icon for power-up if it's set. Overrides the main LeadIn menu to hit the contacts power-up
83
  if ( $power_up->menu_text == 'Contacts' )
84
  add_menu_page('LeadIn', 'LeadIn', 'manage_categories', 'leadin_contacts', array($power_up, 'power_up_setup_callback'), LEADIN_PATH . '/images/' . ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'leadin-icon-32x32.png' : 'leadin-svg-icon.svg'));
85
  else if ( $power_up->menu_text )
144
  function leadin_options_section_heading ( )
145
  {
146
  ?>
147
+ <p style='color: #090; font-weight: bold;'>Visitor tracking is installed and tracking visitors.</p>
148
+ <p>The next time a visitor fills out a form on your WordPress site with an email address, LeadIn will send you an email with the contact's referral source and page view history.</p>
 
 
 
149
  <?php
150
 
151
  $this->print_hidden_settings_fields();
159
  $li_db_version = ( $options['li_db_version'] ? $options['li_db_version'] : LEADIN_DB_VERSION );
160
  $ignore_settings_popup = ( $options['ignore_settings_popup'] ? $options['ignore_settings_popup'] : 0 );
161
  $onboarding_complete = ( $options['onboarding_complete'] ? $options['onboarding_complete'] : 0 );
162
+ $data_recovered = ( $options['data_recovered'] ? $options['data_recovered'] : 0 );
163
+ $delete_flags_fixed = ( $options['delete_flags_fixed'] ? $options['delete_flags_fixed'] : 0 );
164
+
165
+
166
 
167
  printf(
168
  '<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
183
  '<input id="onboarding_complete" type="hidden" name="leadin_options[onboarding_complete]" value="%d"/>',
184
  $onboarding_complete
185
  );
186
+
187
+ printf(
188
+ '<input id="data_recovered" type="hidden" name="leadin_options[data_recovered]" value="%d"/>',
189
+ $data_recovered
190
+ );
191
+
192
+ printf(
193
+ '<input id="delete_flags_fixed" type="hidden" name="leadin_options[delete_flags_fixed]" value="%d"/>',
194
+ $delete_flags_fixed
195
+ );
196
  }
197
 
198
  function update_option_leadin_options_callback ( $old_value, $new_value )
320
  function li_email_callback ()
321
  {
322
  $options = get_option('leadin_options');
323
+ $li_email = ( isset($options['li_email']) && $options['li_email'] ? $options['li_email'] : '' ); // Get email from plugin settings, if none set, use admin email
324
+
325
  printf(
326
+ '<input id="li_email" type="text" id="title" name="leadin_options[li_email]" value="%s" size="50"/><br/><span class="description">Separate multiple emails with commas. Leave blank to disable email notifications.</span>',
327
  $li_email
328
+ );
329
  }
330
 
331
  /**
520
  <!-- end SnapEngage code -->
521
  <?php
522
  }
523
+
524
+ /**
525
+ * Adds the analytics meta box in the post editor
526
+ */
527
+ function add_li_analytics_meta_box ()
528
+ {
529
+ global $post;
530
+ if ( ! in_array(get_post_status($post->ID), array('publish', 'private')) )
531
+ return false;
532
+
533
+ $post_types = get_post_types( array( 'public' => true ) );
534
+
535
+ $permalink = get_permalink($post->ID);
536
+ $this->li_viewers = new LI_Viewers();
537
+ $this->li_viewers->get_identified_viewers($permalink);
538
+ $this->li_viewers->get_submissions($permalink);
539
+
540
+ if ( is_array( $post_types ) && $post_types !== array() ) {
541
+ foreach ( $post_types as $post_type ) {
542
+ add_meta_box( 'li_analytics-meta', 'LeadIn Analytics', array( $this, 'li_analytics_meta_box' ), $post_type, 'normal', 'high');
543
+ }
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Output the LeadIn Analytics meta box
549
+ */
550
+ function li_analytics_meta_box ()
551
+ {
552
+ global $post;
553
+ $view_count = 0;
554
+ $submission_count = 0;
555
+ $max_faces = 10;
556
+ ?>
557
+ <table class="form-table"><tbody>
558
+ <tr>
559
+ <th scope="row">
560
+ <?php echo count($this->li_viewers->viewers) . ' ' . ( count($this->li_viewers->viewers) != 1 ? 'identified viewers:' : 'identified viewer:' ); ?>
561
+ </th>
562
+ <td>
563
+ <?php
564
+ if ( count($this->li_viewers->viewers) )
565
+ {
566
+ foreach ( $this->li_viewers->viewers as $viewer )
567
+ {
568
+ $view_count++;
569
+ $contact_view_url = get_bloginfo('wpurl') . "/wp-admin/admin.php?page=leadin_contacts&action=view&lead=" . $viewer->lead_id . '&post_id=' . $post->ID;
570
+ 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>';
571
+ }
572
+ }
573
+
574
+ if ( $view_count > $max_faces )
575
+ {
576
+ echo '<div class="show-all-faces-container"><a class="show_all_faces" href="javascript:void(0)">+ Show ' . ( $view_count - $max_faces ) . ' more</a></div>';
577
+ }
578
+ ?>
579
+ </td>
580
+ </tr>
581
+ <tr>
582
+ <th scope="row">
583
+ <?php echo count($this->li_viewers->submissions) . ' ' . ( count($this->li_viewers->submissions) != 1 ? 'form submissions:' : 'form submission:' ); ?>
584
+ </th>
585
+ <td>
586
+ <?php
587
+ foreach ( $this->li_viewers->submissions as $submission )
588
+ {
589
+ $submission_count++;
590
+ $contact_view_url = get_bloginfo('wpurl') . "/wp-admin/admin.php?page=leadin_contacts&action=view&lead=" . $submission->lead_id . '&post_id=' . $post->ID;
591
+ 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>';
592
+ }
593
+
594
+ if ( $submission_count > $max_faces )
595
+ {
596
+ echo '<div class="show-all-faces-container"><a class="show_all_faces" href="javascript:void(0)">+ Show ' . ( $submission_count - $max_faces ) . ' more</a></div>';
597
+ }
598
+ ?>
599
+ </td>
600
+ </tr>
601
+ </tbody></table>
602
+ <?php
603
+ }
604
+
605
  }
606
 
607
  ?>
admin/sass/.sass-cache/0c3aa292b717031700a0344f604e0b99b479fc79/_susy.scssc DELETED
Binary file
admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_container.scssc DELETED
Binary file
admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_end.scssc DELETED
Binary file
admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_isolate.scssc DELETED
Binary file
admin/sass/.sass-cache/38f6ef42965a6f3d0db78c73e0225721577524c6/_span.scssc DELETED
Binary file
admin/sass/.sass-cache/52467c9ff883780d88c16e980bb8d43c6f3f113f/_susy.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_background.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_box-sizing.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_clearfix.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_prefix.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_rem.scssc DELETED
Binary file
admin/sass/.sass-cache/5b0ded2c21a8382c081077cb9f130cd662c5ce8e/_support.scssc DELETED
Binary file
admin/sass/.sass-cache/5cb96857c5f923ac31761ca34fd727781525b482/_math.scssc DELETED
Binary file
admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_float.scssc DELETED
Binary file
admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_shared.scssc DELETED
Binary file
admin/sass/.sass-cache/797a4968f0b8e5805efbffb5db3326f524464ef6/_support.scssc DELETED
Binary file
admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_contact_detail_page.sassc CHANGED
Binary file
admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_grid.sassc CHANGED
Binary file
admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_metabox.sassc ADDED
Binary file
admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/_tables.sassc CHANGED
Binary file
admin/sass/.sass-cache/7feb88049015a4dff396a24786f85814ae06425c/leadin-admin.sassc CHANGED
Binary file
admin/sass/.sass-cache/a1d71d7b609c5e9852c5bfc005fe6aac02f7590f/_support.scssc CHANGED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_appearance.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-clip.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-origin.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_background-size.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_border-radius.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box-shadow.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box-sizing.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_box.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_columns.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_filter.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_font-face.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_hyphenation.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_images.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_inline-block.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_opacity.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_regions.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_shared.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_text-shadow.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_transform.scssc DELETED
Binary file
admin/sass/.sass-cache/a2b7e568cca225148f3e4dc8c9c0bdfe1174b763/_transition.scssc DELETED
Binary file
admin/sass/.sass-cache/a3876a0695ee0091b635892c2b539b865026ee33/_settings.scssc CHANGED
Binary file
admin/sass/.sass-cache/a9f64e5d5dd6c28c118d0281ab7b3986e2729ea7/_grid-background.scssc CHANGED
Binary file
admin/sass/.sass-cache/aa1b4daeb1aa66522abf94710543639284144823/_clearfix.scssc DELETED
Binary file
admin/sass/.sass-cache/aa1b4daeb1aa66522abf94710543639284144823/_hacks.scssc DELETED
Binary file
admin/sass/.sass-cache/ba1a1c8b7407a74496e0f1bb0af5e060acd9c6b4/_css3.scssc DELETED
Binary file
admin/sass/.sass-cache/ba1a1c8b7407a74496e0f1bb0af5e060acd9c6b4/_support.scssc DELETED
Binary file
admin/sass/.sass-cache/e4b1f93193ae29c5c808f60975dad0a21092da77/_units.scssc CHANGED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_background.scssc DELETED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_container.scssc DELETED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_direction.scssc DELETED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_margins.scssc DELETED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_output.scssc DELETED
Binary file
admin/sass/.sass-cache/e84f61336d179205ae6530d80482c1682976ab4e/_padding.scssc DELETED
Binary file
admin/sass/.sass-cache/eba4af504693c8b2c03a74241844b1c5ab414495/_su.scssc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_contact_detail_page.sassc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_contacts_list_page.sassc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_settings_page.sassc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_tables.sassc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/_variables.sassc DELETED
Binary file
admin/sass/.sass-cache/f44f973eb6f81b0c357f9f23e88bc1c2233de3b4/leadin-admin.sassc DELETED
Binary file
admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_grid.scssc DELETED
Binary file
admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_maps.scssc DELETED
Binary file
admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_settings.scssc DELETED
Binary file
admin/sass/.sass-cache/fc4f4268225416ca556db305ea34784cf502478b/_validation.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_background.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_bleed.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_box-sizing.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_breakpoint-plugin.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_container.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_context.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_gallery.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_grids.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_gutters.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_isolate.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_margins.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_padding.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_rows.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_settings.scssc DELETED
Binary file
admin/sass/.sass-cache/fd9de46f5118e2ba495163d7bc711998018af17d/_span.scssc DELETED
Binary file
admin/sass/_contact_detail_page.sass CHANGED
@@ -15,6 +15,8 @@
15
  line-height: 40px
16
 
17
  .contact-info
 
 
18
 
19
  label
20
  font-weight: bold
15
  line-height: 40px
16
 
17
  .contact-info
18
+ h3
19
+ margin: 0
20
 
21
  label
22
  font-weight: bold
admin/sass/_grid.sass CHANGED
@@ -11,14 +11,15 @@ $grid-padding: 20px
11
 
12
  #leadin
13
  @include container($total-columns, $break)
14
- margin: 0
15
  padding: 0
16
 
17
  *
18
  box-sizing: border-box
19
 
20
  @include at-breakpoint($break)
21
- margin: 0
 
22
 
23
  // Layout
24
 
11
 
12
  #leadin
13
  @include container($total-columns, $break)
14
+ margin: 10px 0 0
15
  padding: 0
16
 
17
  *
18
  box-sizing: border-box
19
 
20
  @include at-breakpoint($break)
21
+ margin: 10px 0 0
22
+ padding: 0
23
 
24
  // Layout
25
 
admin/sass/_metabox.sass ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #li_analytics-meta
2
+
3
+ .li-analytics-link
4
+ float: left
5
+
6
+ .li-analytics__face
7
+ height: 35px
8
+ width: 35px
9
+ margin-right: 5px
10
+ margin-bottom: 5px
11
+
12
+ .hidden_face
13
+ display: none
14
+
15
+ .show-all-faces-container
16
+ clear: both
admin/sass/_tables.sass CHANGED
@@ -24,9 +24,12 @@ $table-controls-border-size: 2px
24
  padding: $table-controls-pading 0
25
  line-height: $base-vertical-unit*4
26
  font-weight: 300
27
- font-size: 20px
28
  text-decoration: none
29
 
 
 
 
30
  &.current
31
  margin-bottom: -2px
32
  font-weight: 400
@@ -44,6 +47,15 @@ $table-controls-border-size: 2px
44
  .leadin-contact-avatar
45
  float: left
46
 
 
 
 
 
 
 
 
 
 
47
  &.pre-mp6
48
  .table_search
49
  float: right
@@ -78,4 +90,5 @@ $table-controls-border-size: 2px
78
  font-size: 14px
79
 
80
  .row-actions
81
- float: left
 
24
  padding: $table-controls-pading 0
25
  line-height: $base-vertical-unit*4
26
  font-weight: 300
27
+ font-size: 16px
28
  text-decoration: none
29
 
30
+ @include at-breakpoint($break)
31
+ font-size: 20px
32
+
33
  &.current
34
  margin-bottom: -2px
35
  font-weight: 400
47
  .leadin-contact-avatar
48
  float: left
49
 
50
+ th, td
51
+ display: none
52
+
53
+ &:nth-child(-n+3)
54
+ display: table-cell
55
+
56
+ @include at-breakpoint($break)
57
+ display: table-cell
58
+
59
  &.pre-mp6
60
  .table_search
61
  float: right
90
  font-size: 14px
91
 
92
  .row-actions
93
+ float: left
94
+
admin/sass/leadin-admin.sass CHANGED
@@ -47,9 +47,40 @@
47
  width: 16px
48
  opacity: 0.6
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  // Pages
51
  @import settings_page.sass
52
  @import contacts_list_page.sass
53
  @import contact_detail_page.sass
54
  @import powerups_page.sass
 
55
 
47
  width: 16px
48
  opacity: 0.6
49
 
50
+ .leadin-dynamic-avatar_0
51
+ background-color: #F88E4B
52
+
53
+ .leadin-dynamic-avatar_1
54
+ background-color: #64AADA
55
+
56
+ .leadin-dynamic-avatar_2
57
+ background-color: #64C2B6
58
+
59
+ .leadin-dynamic-avatar_3
60
+ background-color: #CF7BAA
61
+
62
+ .leadin-dynamic-avatar_4
63
+ background-color: #E7C24B
64
+
65
+ .leadin-dynamic-avatar_5
66
+ background-color: #9387DA
67
+
68
+ .leadin-dynamic-avatar_6
69
+ background-color: #D6DD99
70
+
71
+ .leadin-dynamic-avatar_7
72
+ background-color: #FF4C4C
73
+
74
+ .leadin-dynamic-avatar_8
75
+ background-color: #99583D
76
+
77
+ .leadin-dynamic-avatar_9
78
+ background-color: #54CC14
79
+
80
  // Pages
81
  @import settings_page.sass
82
  @import contacts_list_page.sass
83
  @import contact_detail_page.sass
84
  @import powerups_page.sass
85
+ @import metabox.sass
86
 
frontend/js/leadin.js CHANGED
@@ -19,6 +19,9 @@ jQuery(document).ready( function ( $ ) {
19
  submission_data.page_url,
20
  submission_data.json_form_fields,
21
  submission_data.lead_email,
 
 
 
22
  submission_data.form_submission_type,
23
  function ( data ) {
24
  // Form was submitted successfully before page reload. Delete cookie for this submission
@@ -72,8 +75,11 @@ function leadin_submit_form ( $form, $, form_type )
72
  {
73
  var $this = $form;
74
 
75
- var form_fields = [];
76
- var lead_email = '';
 
 
 
77
  var form_submission_type = ( form_type ? form_type : 'lead' );
78
 
79
  // Excludes hidden input fields + submit inputs
@@ -172,6 +178,15 @@ function leadin_submit_form ( $form, $, form_type )
172
 
173
  if ( $value.indexOf('@') != -1 && $value.indexOf('.') != -1 && !lead_email )
174
  lead_email = $value;
 
 
 
 
 
 
 
 
 
175
  });
176
 
177
  var radio_groups = [];
@@ -258,6 +273,9 @@ function leadin_submit_form ( $form, $, form_type )
258
  "submission_hash": submission_hash,
259
  "hashkey": hashkey,
260
  "lead_email": lead_email,
 
 
 
261
  "page_title": page_title,
262
  "page_url": page_url,
263
  "json_form_fields": json_form_fields,
@@ -273,6 +291,9 @@ function leadin_submit_form ( $form, $, form_type )
273
  page_url,
274
  json_form_fields,
275
  lead_email,
 
 
 
276
  form_submission_type,
277
  function ( data ) {
278
  // Form was executed 100% successfully before page reload. Delete cookie for this submission
@@ -367,7 +388,7 @@ function leadin_insert_lead ( hashkey, page_referrer ) {
367
  });
368
  }
369
 
370
- function leadin_insert_form_submission ( submission_haskey, hashkey, page_title, page_url, json_fields, lead_email, form_submission_type, Callback )
371
  {
372
  jQuery.ajax({
373
  type: 'POST',
@@ -380,6 +401,9 @@ function leadin_insert_form_submission ( submission_haskey, hashkey, page_title,
380
  "li_url": page_url,
381
  "li_fields": json_fields,
382
  "li_email": lead_email,
 
 
 
383
  "li_submission_type": form_submission_type
384
  },
385
  success: function(data){
19
  submission_data.page_url,
20
  submission_data.json_form_fields,
21
  submission_data.lead_email,
22
+ submission_data.lead_first_name,
23
+ submission_data.lead_last_name,
24
+ submission_data.lead_phone,
25
  submission_data.form_submission_type,
26
  function ( data ) {
27
  // Form was submitted successfully before page reload. Delete cookie for this submission
75
  {
76
  var $this = $form;
77
 
78
+ var form_fields = [];
79
+ var lead_email = '';
80
+ var lead_first_name = '';
81
+ var lead_last_name = '';
82
+ var lead_phone = '';
83
  var form_submission_type = ( form_type ? form_type : 'lead' );
84
 
85
  // Excludes hidden input fields + submit inputs
178
 
179
  if ( $value.indexOf('@') != -1 && $value.indexOf('.') != -1 && !lead_email )
180
  lead_email = $value;
181
+
182
+ if ( $element.attr('id') == 'leadin-subscribe-fname')
183
+ lead_first_name = $value;
184
+
185
+ if ( $element.attr('id') == 'leadin-subscribe-lname')
186
+ lead_last_name = $value;
187
+
188
+ if ( $element.attr('id') == 'leadin-subscribe-phone')
189
+ lead_phone = $value;
190
  });
191
 
192
  var radio_groups = [];
273
  "submission_hash": submission_hash,
274
  "hashkey": hashkey,
275
  "lead_email": lead_email,
276
+ "lead_first_name": lead_first_name,
277
+ "lead_last_name": lead_last_name,
278
+ "lead_phone": lead_phone,
279
  "page_title": page_title,
280
  "page_url": page_url,
281
  "json_form_fields": json_form_fields,
291
  page_url,
292
  json_form_fields,
293
  lead_email,
294
+ lead_first_name,
295
+ lead_last_name,
296
+ lead_phone,
297
  form_submission_type,
298
  function ( data ) {
299
  // Form was executed 100% successfully before page reload. Delete cookie for this submission
388
  });
389
  }
390
 
391
+ 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_submission_type, Callback )
392
  {
393
  jQuery.ajax({
394
  type: 'POST',
401
  "li_url": page_url,
402
  "li_fields": json_fields,
403
  "li_email": lead_email,
404
+ "li_first_name": lead_first_name,
405
+ "li_last_name": lead_last_name,
406
+ "li_phone": lead_phone,
407
  "li_submission_type": form_submission_type
408
  },
409
  success: function(data){
images/power-up-icon-constant-contact-list-sync.png ADDED
Binary file
images/power-up-icon-constant-contact-list-sync@2x.png ADDED
Binary file
images/power-up-icon-constant-contact-list-sync_small.png ADDED
Binary file
images/power-up-icon-constant-contact-list-sync_small@2x.png ADDED
Binary file
inc/class-emailer.php CHANGED
@@ -7,7 +7,7 @@ class LI_Emailer {
7
  /**
8
  * Class constructor
9
  */
10
- function LI_Emailer ()
11
  {
12
 
13
  }
@@ -95,9 +95,10 @@ class LI_Emailer {
95
  // Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
96
  $body = wordwrap($body, 900, "\r\n");
97
 
 
98
  $headers = "From: LeadIn <team@leadin.com>\r\n";
99
- $headers.= "Reply-To: LeadIn <team@leadin.com>\r\n";
100
- $headers.= "X-Mailer: PHP/" . phpversion()."\r\n";
101
  $headers.= "MIME-Version: 1.0\r\n";
102
  $headers.= "Content-type: text/html; charset=utf-8\r\n";
103
 
@@ -108,27 +109,19 @@ class LI_Emailer {
108
  if ( $history->submission->form_type == "comment" )
109
  {
110
  $subject = "New comment posted on " . $history->submission->form_page_title;
111
- leadin_track_plugin_activity("New comment");
112
  $subject .= " by " . $history->lead->lead_email;
113
  }
114
  else if ( $history->submission->form_type == "subscribe" )
115
  {
116
  $subject = "New subscriber from " . $history->submission->form_page_title;
117
- leadin_track_plugin_activity("New subscriber");
118
  $this->send_subscriber_confirmation_email($history);
119
  }
120
  else
121
  {
122
  if ( $history->new_contact )
123
- {
124
  $subject = "New lead from " . get_bloginfo('name') . " - Say hello to " . $history->lead->lead_email;
125
- leadin_track_plugin_activity("New lead");
126
- }
127
  else
128
- {
129
  $subject = "Lead from " . get_bloginfo('name') . " - Say hello again to " . $history->lead->lead_email;
130
- leadin_track_plugin_activity("Returning lead");
131
- }
132
  }
133
 
134
  $email_sent = wp_mail($to, $subject, $body, $headers);
@@ -154,6 +147,7 @@ class LI_Emailer {
154
  FROM
155
  li_pageviews
156
  WHERE
 
157
  lead_hashkey LIKE %s ORDER BY pageview_date ASC", '%b %e', '%b %e %l:%i%p', $hashkey);
158
 
159
  $pageviews = $wpdb->get_results($q);
@@ -173,10 +167,10 @@ class LI_Emailer {
173
  $count++;
174
  }
175
 
176
- $q = $wpdb->prepare("SELECT form_date AS form_datetime, DATE_FORMAT(form_date, %s) AS form_date, form_page_title, form_page_url, form_fields, form_type FROM li_submissions WHERE lead_hashkey = '%s' ORDER BY form_datetime DESC", '%b %e %l:%i%p', $hashkey);
177
  $submissions = $wpdb->get_results($q);
178
 
179
- $q = $wpdb->prepare("SELECT lead_id, lead_date, lead_ip, lead_source, lead_email, lead_status FROM li_leads WHERE hashkey LIKE %s AND lead_email != ''", $hashkey);
180
  $lead = $wpdb->get_row($q);
181
 
182
  $history = (object)NULL;
@@ -409,20 +403,21 @@ class LI_Emailer {
409
 
410
  // Build Powered by LeadIn row
411
  $body .= "<table class='row section' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;position: relative;display: block;margin-top: 20px;padding: 0px;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td class='wrapper last' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;position: relative;padding: 0 0px 0 0;' align='left' valign='top'><table class='twelve columns' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 580px;margin: 0 auto;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='padding: 10px 20px;' align='left' valign='top'><table style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;overflow: hidden;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: center;display: block;width: auto !important;font-size: 16px;padding: 10px 20px;' align='center' valign='top'>";
412
- $body .="<div style='font-size: 11px; color: #888; padding: 0 0 5px 0;'>Powered by</div><a href='http://leadin.com/wordpress-subscribe-widget/?utm_campaign=subscribe_widget&utm_medium=email&utm_source=" . $site_url . "'><img alt='LeadIn' height='20px' width='99px' src='http://leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png' alt='leadin.com'/></a>";
413
  $body .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
414
 
415
  // @EMAIL - end form section
416
 
417
  // Email Base close
418
  $body .= '</center></td></tr></table></body></html>';
 
419
 
420
  // Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
421
  $body = wordwrap($body, 900, "\r\n");
422
 
423
  $headers = "From: LeadIn <team@leadin.com>\r\n";
424
- $headers.= "Reply-To: LeadIn <team@leadin.com>\r\n";
425
- $headers.= "X-Mailer: PHP/" . phpversion()."\r\n";
426
  $headers.= "MIME-Version: 1.0\r\n";
427
  $headers.= "Content-type: text/html; charset=utf-8\r\n";
428
 
7
  /**
8
  * Class constructor
9
  */
10
+ function __construct ()
11
  {
12
 
13
  }
95
  // Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
96
  $body = wordwrap($body, 900, "\r\n");
97
 
98
+ $from = $history->lead->lead_email;
99
  $headers = "From: LeadIn <team@leadin.com>\r\n";
100
+ $headers.= "Reply-To: LeadIn <" . $from . ">\r\n";
101
+ $headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
102
  $headers.= "MIME-Version: 1.0\r\n";
103
  $headers.= "Content-type: text/html; charset=utf-8\r\n";
104
 
109
  if ( $history->submission->form_type == "comment" )
110
  {
111
  $subject = "New comment posted on " . $history->submission->form_page_title;
 
112
  $subject .= " by " . $history->lead->lead_email;
113
  }
114
  else if ( $history->submission->form_type == "subscribe" )
115
  {
116
  $subject = "New subscriber from " . $history->submission->form_page_title;
 
117
  $this->send_subscriber_confirmation_email($history);
118
  }
119
  else
120
  {
121
  if ( $history->new_contact )
 
122
  $subject = "New lead from " . get_bloginfo('name') . " - Say hello to " . $history->lead->lead_email;
 
 
123
  else
 
124
  $subject = "Lead from " . get_bloginfo('name') . " - Say hello again to " . $history->lead->lead_email;
 
 
125
  }
126
 
127
  $email_sent = wp_mail($to, $subject, $body, $headers);
147
  FROM
148
  li_pageviews
149
  WHERE
150
+ pageview_deleted = 0 AND
151
  lead_hashkey LIKE %s ORDER BY pageview_date ASC", '%b %e', '%b %e %l:%i%p', $hashkey);
152
 
153
  $pageviews = $wpdb->get_results($q);
167
  $count++;
168
  }
169
 
170
+ $q = $wpdb->prepare("SELECT form_date AS form_datetime, DATE_FORMAT(form_date, %s) AS form_date, form_page_title, form_page_url, form_fields, form_type FROM li_submissions WHERE lead_hashkey = '%s' AND form_deleted = 0 ORDER BY form_datetime DESC", '%b %e %l:%i%p', $hashkey);
171
  $submissions = $wpdb->get_results($q);
172
 
173
+ $q = $wpdb->prepare("SELECT lead_id, lead_date, lead_ip, lead_source, lead_email, lead_status FROM li_leads WHERE hashkey LIKE %s AND lead_email != '' AND lead_deleted = 0", $hashkey);
174
  $lead = $wpdb->get_row($q);
175
 
176
  $history = (object)NULL;
403
 
404
  // Build Powered by LeadIn row
405
  $body .= "<table class='row section' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;position: relative;display: block;margin-top: 20px;padding: 0px;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td class='wrapper last' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;position: relative;padding: 0 0px 0 0;' align='left' valign='top'><table class='twelve columns' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 580px;margin: 0 auto;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='padding: 10px 20px;' align='left' valign='top'><table style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;overflow: hidden;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: center;display: block;width: auto !important;font-size: 16px;padding: 10px 20px;' align='center' valign='top'>";
406
+ $body .="<div style='font-size: 11px; color: #888; padding: 0 0 5px 0;'>Powered by</div><a href='http://leadin.com/wordpress-subscribe-widget/?utm_campaign=subscribe_widget&utm_medium=email&utm_source=" . $site_url . "'><img alt='LeadIn' height='20px' width='99px' src='http://leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/leadin_logo_small_grey.png' alt='leadin.com'/></a>";
407
  $body .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
408
 
409
  // @EMAIL - end form section
410
 
411
  // Email Base close
412
  $body .= '</center></td></tr></table></body></html>';
413
+ $from = apply_filters( 'li_subscribe_from', $leadin_email );
414
 
415
  // Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
416
  $body = wordwrap($body, 900, "\r\n");
417
 
418
  $headers = "From: LeadIn <team@leadin.com>\r\n";
419
+ $headers.= "Reply-To: LeadIn <" . $from . ">\r\n";
420
+ $headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
421
  $headers.= "MIME-Version: 1.0\r\n";
422
  $headers.= "Content-type: text/html; charset=utf-8\r\n";
423
 
inc/leadin-ajax-functions.php CHANGED
@@ -7,7 +7,7 @@ if ( !defined('LEADIN_PLUGIN_VERSION') )
7
  }
8
 
9
  /**
10
- * Check if the cookied hashkey has been merged with another contact
11
  *
12
  * @echo Hashkey from a merged_hashkeys row, FALSE if hashkey does not exist in a merged_hashkeys row
13
  */
@@ -17,6 +17,7 @@ function leadin_check_merged_contact ()
17
 
18
  $stale_hash = $_POST['li_id'];
19
 
 
20
  $q = $wpdb->prepare("SELECT hashkey, merged_hashkeys FROM li_leads WHERE merged_hashkeys LIKE '%%%s%%'", like_escape($stale_hash));
21
  $row = $wpdb->get_row($q);
22
 
@@ -39,9 +40,6 @@ function leadin_check_merged_contact ()
39
  $q = $wpdb->prepare("UPDATE li_leads SET merged_hashkeys = %s WHERE hashkey = %s", rtrim(implode(',', $merged_hashkeys), ','), $row->hashkey);
40
  $wpdb->query($q);
41
 
42
- $q = $wpdb->prepare("DELETE FROM li_leads WHERE hashkey LIKE '%%%s%%'", like_escape($stale_hash));
43
- $wpdb->query($q);
44
-
45
  echo json_encode($row->hashkey);
46
  die();
47
  }
@@ -65,7 +63,7 @@ function leadin_log_pageview ()
65
  global $wpdb;
66
 
67
  $hash = $_POST['li_id'];
68
- $title = htmlentities($_POST['li_title']);
69
  $url = $_POST['li_url'];
70
  $source = ( isset($_POST['li_referrer']) ? $_POST['li_referrer'] : '' );
71
  $last_visit = ( isset($_POST['li_last_visit']) ? $_POST['li_last_visit'] : 0 );
@@ -132,21 +130,24 @@ function leadin_insert_form_submission ()
132
 
133
  $submission_hash = $_POST['li_submission_id'];
134
  $hashkey = $_POST['li_id'];
135
- $page_title = htmlentities($_POST['li_title']);
136
  $page_url = $_POST['li_url'];
137
  $form_json = $_POST['li_fields'];
138
  $email = $_POST['li_email'];
 
 
 
139
  $submission_type = $_POST['li_submission_type'];
140
  $options = get_option('leadin_options');
141
- $li_admin_email = ( $options['li_email'] ) ? $options['li_email'] : get_bloginfo('admin_email');
142
 
143
  // Check to see if the form_hashkey exists, and if it does, don't run the insert or send the email
144
- $q = $wpdb->prepare("SELECT form_hashkey FROM li_submissions WHERE form_hashkey = %s", $submission_hash);
145
  $submission_hash_exists = $wpdb->get_var($q);
146
 
147
  if ( $submission_hash_exists )
148
  {
149
- // The form has been inserted successful so send back a trigger to clear the cache cooke on the front end
150
  return 1;
151
  exit;
152
  }
@@ -155,11 +156,11 @@ function leadin_insert_form_submission ()
155
  if ( !(current_user_can('administrator') && $submission_type == 'comment') && !(strstr($li_admin_email, $email) && $submission_type == 'comment') )
156
  {
157
  // Get the contact row tied to hashkey
158
- $q = $wpdb->prepare("SELECT * FROM li_leads WHERE hashkey = %s", $hashkey);
159
  $contact = $wpdb->get_row($q);
160
 
161
  // Check for existing contacts based on whether the email is present in the contacts table
162
- $q = $wpdb->prepare("SELECT lead_email, hashkey, merged_hashkeys, lead_status FROM li_leads WHERE lead_email = %s AND hashkey != %s", $email, $hashkey);
163
  $existing_contacts = $wpdb->get_results($q);
164
 
165
  // Set the default contact life cycle status to lead
@@ -208,10 +209,14 @@ function leadin_insert_form_submission ()
208
  // Update all the previous submissions to the new hashkey
209
  $q = $wpdb->prepare("UPDATE li_submissions SET lead_hashkey = %s WHERE lead_hashkey IN ( $existing_contact_hashkeys )", $hashkey);
210
  $wpdb->query($q);
 
 
 
 
211
  }
212
 
213
  // Prevent duplicate form submission entries by deleting existing submissions if it didn't finish the process before the web page refreshed
214
- $q = $wpdb->prepare("DELETE FROM li_submissions WHERE form_hashkey = %s", $submission_hash);
215
  $wpdb->query($q);
216
 
217
  // Insert the form fields and hash into the submissions table
@@ -257,13 +262,35 @@ function leadin_insert_form_submission ()
257
  if ( in_array('mailchimp_list_sync', $active_power_ups) )
258
  {
259
  global $leadin_mailchimp_list_sync_wp;
260
- $leadin_mailchimp_list_sync_wp->push_mailchimp_subscriber_to_list($email);
 
 
 
 
 
 
261
  }
262
  }
263
 
264
- // Send the contact email
265
  $li_emailer = new LI_Emailer();
266
- $li_emailer->send_new_lead_email($hashkey);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
  return $rows_updated;
269
  }
@@ -283,7 +310,7 @@ function leadin_check_visitor_status ()
283
 
284
  $hash = $_POST['li_id'];
285
 
286
- $q = $wpdb->prepare("SELECT lead_status FROM li_leads WHERE hashkey = %s", $hash);
287
  $lead_status = $wpdb->get_var($q);
288
 
289
  if ( isset($lead_status) )
@@ -310,26 +337,6 @@ function leadin_subscribe_show ()
310
  {
311
  leadin_track_plugin_activity('widget shown');
312
  die();
313
-
314
- /*global $wpdb;
315
-
316
- $hash = $_POST['li_id'];
317
-
318
- $q = $wpdb->prepare("SELECT lead_status FROM li_leads WHERE hashkey = %s", $hash);
319
- $lead_status = $wpdb->get_var($q);
320
-
321
- if ( isset($lead_status) )
322
- {
323
- echo json_encode($lead_status);
324
- die();
325
- }
326
- else
327
- {
328
- echo json_encode(FALSE);
329
- die();
330
- }*/
331
-
332
-
333
  }
334
 
335
  add_action('wp_ajax_leadin_subscribe_show', 'leadin_subscribe_show'); // Call when user logged in
7
  }
8
 
9
  /**
10
+ * Check if the cookied hashkey has been merged with another contact. If it is, set visitor's cookie to new hashkey
11
  *
12
  * @echo Hashkey from a merged_hashkeys row, FALSE if hashkey does not exist in a merged_hashkeys row
13
  */
17
 
18
  $stale_hash = $_POST['li_id'];
19
 
20
+ // Check if hashkey is in a merged contact
21
  $q = $wpdb->prepare("SELECT hashkey, merged_hashkeys FROM li_leads WHERE merged_hashkeys LIKE '%%%s%%'", like_escape($stale_hash));
22
  $row = $wpdb->get_row($q);
23
 
40
  $q = $wpdb->prepare("UPDATE li_leads SET merged_hashkeys = %s WHERE hashkey = %s", rtrim(implode(',', $merged_hashkeys), ','), $row->hashkey);
41
  $wpdb->query($q);
42
 
 
 
 
43
  echo json_encode($row->hashkey);
44
  die();
45
  }
63
  global $wpdb;
64
 
65
  $hash = $_POST['li_id'];
66
+ $title = $_POST['li_title'];
67
  $url = $_POST['li_url'];
68
  $source = ( isset($_POST['li_referrer']) ? $_POST['li_referrer'] : '' );
69
  $last_visit = ( isset($_POST['li_last_visit']) ? $_POST['li_last_visit'] : 0 );
130
 
131
  $submission_hash = $_POST['li_submission_id'];
132
  $hashkey = $_POST['li_id'];
133
+ $page_title = $_POST['li_title'];
134
  $page_url = $_POST['li_url'];
135
  $form_json = $_POST['li_fields'];
136
  $email = $_POST['li_email'];
137
+ $first_name = $_POST['li_first_name'];
138
+ $last_name = $_POST['li_last_name'];
139
+ $phone = $_POST['li_phone'];
140
  $submission_type = $_POST['li_submission_type'];
141
  $options = get_option('leadin_options');
142
+ $li_admin_email = ( isset($options['li_email']) ) ? $options['li_email'] : '';
143
 
144
  // Check to see if the form_hashkey exists, and if it does, don't run the insert or send the email
145
+ $q = $wpdb->prepare("SELECT form_hashkey FROM li_submissions WHERE form_hashkey = %s AND form_deleted = 0", $submission_hash);
146
  $submission_hash_exists = $wpdb->get_var($q);
147
 
148
  if ( $submission_hash_exists )
149
  {
150
+ // The form has been inserted successful so send back a trigger to clear the cached submission cookie on the front end
151
  return 1;
152
  exit;
153
  }
156
  if ( !(current_user_can('administrator') && $submission_type == 'comment') && !(strstr($li_admin_email, $email) && $submission_type == 'comment') )
157
  {
158
  // Get the contact row tied to hashkey
159
+ $q = $wpdb->prepare("SELECT * FROM li_leads WHERE hashkey = %s AND lead_deleted = 0", $hashkey);
160
  $contact = $wpdb->get_row($q);
161
 
162
  // Check for existing contacts based on whether the email is present in the contacts table
163
+ $q = $wpdb->prepare("SELECT lead_email, hashkey, merged_hashkeys, lead_status FROM li_leads WHERE lead_email = %s AND hashkey != %s AND lead_deleted = 0", $email, $hashkey);
164
  $existing_contacts = $wpdb->get_results($q);
165
 
166
  // Set the default contact life cycle status to lead
209
  // Update all the previous submissions to the new hashkey
210
  $q = $wpdb->prepare("UPDATE li_submissions SET lead_hashkey = %s WHERE lead_hashkey IN ( $existing_contact_hashkeys )", $hashkey);
211
  $wpdb->query($q);
212
+
213
+ // "Delete" all the old leads from the leads table
214
+ $q = $wpdb->prepare("UPDATE li_leads SET lead_deleted = 1 WHERE hashkey IN ( $existing_contact_hashkeys )", "");
215
+ $wpdb->query($q);
216
  }
217
 
218
  // Prevent duplicate form submission entries by deleting existing submissions if it didn't finish the process before the web page refreshed
219
+ $q = $wpdb->prepare("UPDATE li_submissions SET form_deleted = 1 WHERE form_hashkey = %s", $submission_hash);
220
  $wpdb->query($q);
221
 
222
  // Insert the form fields and hash into the submissions table
262
  if ( in_array('mailchimp_list_sync', $active_power_ups) )
263
  {
264
  global $leadin_mailchimp_list_sync_wp;
265
+ $leadin_mailchimp_list_sync_wp->push_mailchimp_subscriber_to_list($email, $first_name, $last_name, $phone);
266
+ }
267
+
268
+ if ( in_array('constant_contact_list_sync', $active_power_ups) )
269
+ {
270
+ global $leadin_constant_contact_list_sync_wp;
271
+ $leadin_constant_contact_list_sync_wp->push_constant_contact_subscriber_to_list($email, $first_name, $last_name, $phone);
272
  }
273
  }
274
 
 
275
  $li_emailer = new LI_Emailer();
276
+ if ( $li_admin_email )
277
+ {
278
+ // Send the contact email
279
+ $li_emailer->send_new_lead_email($hashkey);
280
+ }
281
+
282
+ if ( $contact_status == "comment" )
283
+ leadin_track_plugin_activity("New comment");
284
+ else if ( $contact_status == "subscribe" )
285
+ leadin_track_plugin_activity("New subscriber");
286
+ else
287
+ {
288
+ $history = $li_emailer->get_lead_history($hashkey);
289
+ if ( $history->new_contact )
290
+ leadin_track_plugin_activity("New lead");
291
+ else
292
+ leadin_track_plugin_activity("Returning lead");
293
+ }
294
 
295
  return $rows_updated;
296
  }
310
 
311
  $hash = $_POST['li_id'];
312
 
313
+ $q = $wpdb->prepare("SELECT lead_status FROM li_leads WHERE hashkey = %s AND lead_deleted = 0", $hash);
314
  $lead_status = $wpdb->get_var($q);
315
 
316
  if ( isset($lead_status) )
337
  {
338
  leadin_track_plugin_activity('widget shown');
339
  die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  }
341
 
342
  add_action('wp_ajax_leadin_subscribe_show', 'leadin_subscribe_show'); // Call when user logged in
inc/leadin-functions.php CHANGED
@@ -113,7 +113,7 @@ function leadin_get_current_user ()
113
  function leadin_register_user ()
114
  {
115
  $leadin_user = leadin_get_current_user();
116
- $mp = Mixpanel::getInstance(MIXPANEL_PROJECT_TOKEN);
117
 
118
  // @push mixpanel event for updated email
119
  $mp->identify($leadin_user['user_id']);
@@ -154,7 +154,7 @@ function leadin_register_user ()
154
  @curl_close($ch);
155
  echo $response;
156
 
157
- return true;
158
  }
159
 
160
  /**
@@ -166,15 +166,17 @@ function leadin_register_user ()
166
  */
167
  function leadin_track_plugin_registration_hook ( $activated )
168
  {
169
- if ($activated) {
 
170
  leadin_register_user();
171
  leadin_track_plugin_activity("Activated Plugin");
172
  }
173
- else {
 
174
  leadin_track_plugin_activity("Deactivated Plugin");
175
  }
176
 
177
- return true;
178
  }
179
 
180
  /**
@@ -193,7 +195,7 @@ function leadin_track_plugin_activity ( $activity_desc )
193
  get_currentuserinfo();
194
  $user_id = md5(get_bloginfo('wpurl'));
195
 
196
- $mp = Mixpanel::getInstance(MIXPANEL_PROJECT_TOKEN);
197
  $mp->track($activity_desc, array("distinct_id" => $user_id, '$wp-url' => get_bloginfo('wpurl'), '$wp-version' => $wp_version, '$li-version' => LEADIN_PLUGIN_VERSION));
198
 
199
  return true;
@@ -256,7 +258,7 @@ function leadin_recover_contact_data ()
256
  {
257
  global $wpdb;
258
 
259
- $q = $wpdb->prepare("SELECT * FROM li_submissions WHERE form_fields LIKE '%%%s%%' AND form_fields LIKE '%%%s%%'", '@', '.');
260
  $submissions = $wpdb->get_results($q);
261
 
262
  if ( count($submissions) )
@@ -265,31 +267,34 @@ function leadin_recover_contact_data ()
265
  {
266
  $json = json_decode(stripslashes($submission->form_fields), TRUE);
267
 
268
- foreach ( $json as $object )
269
  {
270
- if ( strstr($object['value'], '@') && strstr($object['value'], '@') && strlen($object['value']) <= 254 )
271
  {
272
- // check to see if the contact exists and if it does, skip the data recovery
273
- $q = $wpdb->prepare("SELECT lead_email FROM li_leads WHERE lead_email = %s", $object['value']);
274
- $exists = $wpdb->get_var($q);
275
-
276
- if ( $exists )
277
- continue;
278
-
279
- // get the original data
280
- $q = $wpdb->prepare("SELECT pageview_date, pageview_source FROM li_pageviews WHERE lead_hashkey = %s ORDER BY pageview_date ASC LIMIT 1", $submission->lead_hashkey);
281
- $first_pageview = $wpdb->get_row($q);
282
-
283
- // recreate the contact
284
- $q = $wpdb->prepare("INSERT INTO li_leads ( lead_date, hashkey, lead_source, lead_email, lead_status ) VALUES ( %s, %s, %s, %s, %s )",
285
- ( $first_pageview->pageview_date ? $first_pageview->pageview_date : $submission->form_date),
286
- $submission->lead_hashkey,
287
- ( $first_pageview->pageview_source ? $first_pageview->pageview_source : ''),
288
- $object['value'],
289
- $submission->form_type
290
- );
291
-
292
- $wpdb->query($q);
 
 
 
293
  }
294
  }
295
  }
@@ -297,4 +302,122 @@ function leadin_recover_contact_data ()
297
 
298
  leadin_update_option('leadin_options', 'data_recovered', 1);
299
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  ?>
113
  function leadin_register_user ()
114
  {
115
  $leadin_user = leadin_get_current_user();
116
+ $mp = new LI_Mixpanel(MIXPANEL_PROJECT_TOKEN);
117
 
118
  // @push mixpanel event for updated email
119
  $mp->identify($leadin_user['user_id']);
154
  @curl_close($ch);
155
  echo $response;
156
 
157
+ return TRUE;
158
  }
159
 
160
  /**
166
  */
167
  function leadin_track_plugin_registration_hook ( $activated )
168
  {
169
+ if ( $activated )
170
+ {
171
  leadin_register_user();
172
  leadin_track_plugin_activity("Activated Plugin");
173
  }
174
+ else
175
+ {
176
  leadin_track_plugin_activity("Deactivated Plugin");
177
  }
178
 
179
+ return TRUE;
180
  }
181
 
182
  /**
195
  get_currentuserinfo();
196
  $user_id = md5(get_bloginfo('wpurl'));
197
 
198
+ $mp = new LI_Mixpanel(MIXPANEL_PROJECT_TOKEN);
199
  $mp->track($activity_desc, array("distinct_id" => $user_id, '$wp-url' => get_bloginfo('wpurl'), '$wp-version' => $wp_version, '$li-version' => LEADIN_PLUGIN_VERSION));
200
 
201
  return true;
258
  {
259
  global $wpdb;
260
 
261
+ $q = $wpdb->prepare("SELECT * FROM li_submissions AS s LEFT JOIN li_leads AS l ON s.lead_hashkey = l.hashkey WHERE l.hashkey IS NULL AND s.form_fields LIKE '%%%s%%' AND s.form_fields LIKE '%%%s%%' AND form_deleted = 0", '@', '.');
262
  $submissions = $wpdb->get_results($q);
263
 
264
  if ( count($submissions) )
267
  {
268
  $json = json_decode(stripslashes($submission->form_fields), TRUE);
269
 
270
+ if ( count($json) )
271
  {
272
+ foreach ( $json as $object )
273
  {
274
+ if ( strstr($object['value'], '@') && strstr($object['value'], '@') && strlen($object['value']) <= 254 )
275
+ {
276
+ // check to see if the contact exists and if it does, skip the data recovery
277
+ $q = $wpdb->prepare("SELECT lead_email FROM li_leads WHERE lead_email = %s AND lead_deleted = 0", $object['value']);
278
+ $exists = $wpdb->get_var($q);
279
+
280
+ if ( $exists )
281
+ continue;
282
+
283
+ // get the original data
284
+ $q = $wpdb->prepare("SELECT pageview_date, pageview_source FROM li_pageviews WHERE lead_hashkey = %s AND pageview_deleted = 0 ORDER BY pageview_date ASC LIMIT 1", $submission->lead_hashkey);
285
+ $first_pageview = $wpdb->get_row($q);
286
+
287
+ // recreate the contact
288
+ $q = $wpdb->prepare("INSERT INTO li_leads ( lead_date, hashkey, lead_source, lead_email, lead_status ) VALUES ( %s, %s, %s, %s, %s )",
289
+ ( $first_pageview->pageview_date ? $first_pageview->pageview_date : $submission->form_date),
290
+ $submission->lead_hashkey,
291
+ ( $first_pageview->pageview_source ? $first_pageview->pageview_source : ''),
292
+ $object['value'],
293
+ $submission->form_type
294
+ );
295
+
296
+ $wpdb->query($q);
297
+ }
298
  }
299
  }
300
  }
302
 
303
  leadin_update_option('leadin_options', 'data_recovered', 1);
304
  }
305
+
306
+ /**
307
+ * Algorithm to set deleted contacts flag for 0.8.3 upgrade
308
+ *
309
+ */
310
+ function leadin_delete_flag_fix ()
311
+ {
312
+ global $wpdb;
313
+
314
+ $q = $wpdb->prepare("SELECT lead_email, COUNT(hashkey) c FROM li_leads WHERE lead_email != '' AND lead_deleted = 0 GROUP BY lead_email HAVING c > 1", '');
315
+ $duplicates = $wpdb->get_results($q);
316
+
317
+ if ( count($duplicates) )
318
+ {
319
+ foreach ( $duplicates as $duplicate )
320
+ {
321
+ $existing_contact_status = 'lead';
322
+
323
+ $q = $wpdb->prepare("SELECT lead_email, hashkey, merged_hashkeys, lead_status FROM li_leads WHERE lead_email = %s AND lead_deleted = 0 ORDER BY lead_date DESC", $duplicate->lead_email);
324
+ $existing_contacts = $wpdb->get_results($q);
325
+
326
+ $newest = $existing_contacts[0];
327
+
328
+ // Setup the string for the existing hashkeys
329
+ $existing_contact_hashkeys = $newest->merged_hashkeys;
330
+ if ( $newest->merged_hashkeys && count($existing_contacts) )
331
+ $existing_contact_hashkeys .= ',';
332
+
333
+ // Do some merging if the email exists already in the contact table
334
+ if ( count($existing_contacts) )
335
+ {
336
+ for ( $i = 0; $i < count($existing_contacts); $i++ )
337
+ {
338
+ // Start with the existing contact's hashkeys and create a string containg comma-deliminated hashes
339
+ $existing_contact_hashkeys .= "'" . $existing_contacts[$i]->hashkey . "'";
340
+
341
+ // Add any of those existing contact row's merged hashkeys
342
+ if ( $existing_contacts[$i]->merged_hashkeys )
343
+ $existing_contact_hashkeys .= "," . $existing_contacts[$i]->merged_hashkeys;
344
+
345
+ // Add a comma delimiter
346
+ if ( $i != count($existing_contacts)-1 )
347
+ $existing_contact_hashkeys .= ",";
348
+
349
+ // Check on each existing lead if the lead_status is comment. If it is, save the status to override the new lead's status
350
+ if ( $existing_contacts[$i]->lead_status == 'comment' && $existing_contact_status == 'lead' )
351
+ $existing_contact_status = 'comment';
352
+
353
+ // Check on each existing lead if the lead_status is subscribe. If it is, save the status to override the new lead's status
354
+ if ( $existing_contacts[$i]->lead_status == 'subscribe' && ($existing_contact_status == 'lead' || $existing_contact_status == 'comment') )
355
+ $existing_contact_status = 'subscribe';
356
+ }
357
+ }
358
+
359
+ // Remove duplicates from the array and original hashkey just in case
360
+ $existing_contact_hashkeys = leadin_array_delete(array_unique(explode(',', $existing_contact_hashkeys)), "'" . $newest->hashkey . "'");
361
+
362
+ // Safety precaution - trim any trailing commas
363
+ $existing_contact_hashkey_string = rtrim(implode(',', $existing_contact_hashkeys), ',');
364
+
365
+ if ( $existing_contact_hashkey_string )
366
+ {
367
+ // Set the merged hashkeys with the fixed merged hashkey values
368
+ $q = $wpdb->prepare("UPDATE li_leads SET merged_hashkeys = %s, lead_status = %s WHERE hashkey = %s", $existing_contact_hashkey_string, $existing_contact_status, $newest->hashkey);
369
+ $wpdb->query($q);
370
+
371
+ // "Delete" all the old contacts
372
+ $q = $wpdb->prepare("UPDATE li_leads SET merged_hashkeys = '', lead_deleted = 1 WHERE hashkey IN ( $existing_contact_hashkey_string )", '');
373
+ $wpdb->query($q);
374
+
375
+ // Set all the pageviews and submissions to the new hashkey just in case
376
+ $q = $wpdb->prepare("UPDATE li_pageviews SET lead_hashkey = %s WHERE lead_hashkey IN ( $existing_contact_hashkey_string )", $newest->hashkey);
377
+ $wpdb->query($q);
378
+
379
+ // Update all the previous submissions to the new hashkey just in case
380
+ $q = $wpdb->prepare("UPDATE li_submissions SET lead_hashkey = %s WHERE lead_hashkey IN ( $existing_contact_hashkey_string )", $newest->hashkey);
381
+ $wpdb->query($q);
382
+ }
383
+ }
384
+ }
385
+
386
+ leadin_update_option('leadin_options', 'delete_flags_fixed', 1);
387
+ }
388
+
389
+ /**
390
+ * Sorts the powerups into a predefined order in leadin.php line 416
391
+ *
392
+ * @param array
393
+ * @param array
394
+ * @return array
395
+ */
396
+ function leadin_sort_power_ups ( $power_ups, $ordered_power_ups )
397
+ {
398
+ $ordered = array();
399
+ $i = 0;
400
+ foreach ( $ordered_power_ups as $key )
401
+ {
402
+ if ( in_array($key, $power_ups) )
403
+ {
404
+ array_push($ordered, $key);
405
+ $i++;
406
+ }
407
+ }
408
+
409
+ return $ordered;
410
+ }
411
+
412
+ /**
413
+ * Encodes special HTML quote characters into utf-8 safe entities
414
+ *
415
+ * @param string
416
+ * @return string
417
+ */
418
+ function leadin_encode_quotes ( $string )
419
+ {
420
+ $string = str_replace(array("’", "‘", '&#039;', '“', '”'), array("'", "'", "'", '"', '"'), $string);
421
+ return $string;
422
+ }
423
  ?>
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: 0.7.2
7
  Author: Andy Cook, Nelson Joyce
8
  Author URI: http://leadin.com
9
  License: GPL2
@@ -23,10 +23,10 @@ if ( !defined('LEADIN_PLUGIN_SLUG') )
23
  define('LEADIN_PLUGIN_SLUG', basename(dirname(__FILE__)));
24
 
25
  if ( !defined('LEADIN_DB_VERSION') )
26
- define('LEADIN_DB_VERSION', '0.6.2');
27
 
28
  if ( !defined('LEADIN_PLUGIN_VERSION') )
29
- define('LEADIN_PLUGIN_VERSION', '0.7.2');
30
 
31
  if ( !defined('MIXPANEL_PROJECT_TOKEN') )
32
  define('MIXPANEL_PROJECT_TOKEN', 'a9615503ec58a6bce2c646a58390eac1');
@@ -43,7 +43,8 @@ require_once(LEADIN_PLUGIN_DIR . '/inc/leadin-functions.php');
43
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
44
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
45
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-list-sync.php');
46
- require_once(LEADIN_PLUGIN_DIR . '/lib/mixpanel/Mixpanel.php');
 
47
 
48
  //=============================================
49
  // WPLeadIn Class
@@ -76,6 +77,9 @@ class WPLeadIn {
76
  add_action( 'admin_bar_menu', array($this, 'add_leadin_link_to_admin_bar'), 999 );
77
 
78
  $li_wp_admin = new WPLeadInAdmin($this->power_ups);
 
 
 
79
  }
80
 
81
  /**
@@ -88,12 +92,13 @@ class WPLeadIn {
88
  if ( ($li_options['li_installed'] != 1) || (!is_array($li_options)) )
89
  {
90
  $opt = array(
91
- 'li_installed' => 1,
92
- 'li_db_version' => LEADIN_DB_VERSION,
93
- 'li_email' => get_bloginfo('admin_email'),
94
- 'onboarding_complete' => 0,
95
- 'ignore_settings_popup' => 0,
96
- 'data_recovered' => 1
 
97
  );
98
 
99
  update_option('leadin_options', $opt);
@@ -154,9 +159,10 @@ class WPLeadIn {
154
  `lead_email` varchar(255) DEFAULT NULL,
155
  `lead_status` set('lead','comment','subscribe') NOT NULL DEFAULT 'lead',
156
  `merged_hashkeys` text,
 
157
  PRIMARY KEY (`lead_id`),
158
  KEY `hashkey` (`hashkey`)
159
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;
160
 
161
  CREATE TABLE `li_pageviews` (
162
  `pageview_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -166,9 +172,10 @@ class WPLeadIn {
166
  `pageview_url` text NOT NULL,
167
  `pageview_source` text NOT NULL,
168
  `pageview_session_start` int(1) NOT NULL,
 
169
  PRIMARY KEY (`pageview_id`),
170
  KEY `lead_hashkey` (`lead_hashkey`)
171
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=692 ;
172
 
173
  CREATE TABLE `li_submissions` (
174
  `form_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -179,9 +186,10 @@ class WPLeadIn {
179
  `form_fields` text NOT NULL,
180
  `form_type` set('lead','comment','subscribe') NOT NULL DEFAULT 'lead',
181
  `form_hashkey` varchar(16) NOT NULL,
 
182
  PRIMARY KEY (`form_id`),
183
  KEY `lead_hashkey` (`lead_hashkey`)
184
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=85 ;";
185
 
186
  dbDelta($sql);
187
 
@@ -244,6 +252,12 @@ class WPLeadIn {
244
  {
245
  $this->leadin_db_install();
246
  }
 
 
 
 
 
 
247
  }
248
 
249
  //=============================================
@@ -398,6 +412,10 @@ class WPLeadIn {
398
  $files[] = $file;
399
  }
400
 
 
 
 
 
401
  closedir( $dir );
402
 
403
  return $files;
@@ -431,12 +449,12 @@ class WPLeadIn {
431
  public static function activate_power_up( $power_up_slug, $exit = TRUE )
432
  {
433
  if ( ! strlen( $power_up_slug ) )
434
- return false;
435
 
436
  // If it's already active, then don't do it again
437
  $active = self::is_power_up_active($power_up_slug);
438
  if ( $active )
439
- return true;
440
 
441
  $activated_power_ups = get_option('leadin_active_power_ups');
442
 
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: 0.9.0
7
  Author: Andy Cook, Nelson Joyce
8
  Author URI: http://leadin.com
9
  License: GPL2
23
  define('LEADIN_PLUGIN_SLUG', basename(dirname(__FILE__)));
24
 
25
  if ( !defined('LEADIN_DB_VERSION') )
26
+ define('LEADIN_DB_VERSION', '0.8.3');
27
 
28
  if ( !defined('LEADIN_PLUGIN_VERSION') )
29
+ define('LEADIN_PLUGIN_VERSION', '0.9.0');
30
 
31
  if ( !defined('MIXPANEL_PROJECT_TOKEN') )
32
  define('MIXPANEL_PROJECT_TOKEN', 'a9615503ec58a6bce2c646a58390eac1');
43
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
44
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
45
  require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-list-sync.php');
46
+ require_once(LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-list-sync.php');
47
+ require_once(LEADIN_PLUGIN_DIR . '/lib/mixpanel/LI_Mixpanel.php');
48
 
49
  //=============================================
50
  // WPLeadIn Class
77
  add_action( 'admin_bar_menu', array($this, 'add_leadin_link_to_admin_bar'), 999 );
78
 
79
  $li_wp_admin = new WPLeadInAdmin($this->power_ups);
80
+
81
+ if ( is_single() )
82
+ echo 'leadin single';
83
  }
84
 
85
  /**
92
  if ( ($li_options['li_installed'] != 1) || (!is_array($li_options)) )
93
  {
94
  $opt = array(
95
+ 'li_installed' => 1,
96
+ 'li_db_version' => LEADIN_DB_VERSION,
97
+ 'li_email' => get_bloginfo('admin_email'),
98
+ 'onboarding_complete' => 0,
99
+ 'ignore_settings_popup' => 0,
100
+ 'data_recovered' => 1,
101
+ 'delete_flags_fixed' => 1
102
  );
103
 
104
  update_option('leadin_options', $opt);
159
  `lead_email` varchar(255) DEFAULT NULL,
160
  `lead_status` set('lead','comment','subscribe') NOT NULL DEFAULT 'lead',
161
  `merged_hashkeys` text,
162
+ `lead_deleted` int(1) NOT NULL DEFAULT '0',
163
  PRIMARY KEY (`lead_id`),
164
  KEY `hashkey` (`hashkey`)
165
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
166
 
167
  CREATE TABLE `li_pageviews` (
168
  `pageview_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
172
  `pageview_url` text NOT NULL,
173
  `pageview_source` text NOT NULL,
174
  `pageview_session_start` int(1) NOT NULL,
175
+ `pageview_deleted` int(1) NOT NULL DEFAULT '0',
176
  PRIMARY KEY (`pageview_id`),
177
  KEY `lead_hashkey` (`lead_hashkey`)
178
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
179
 
180
  CREATE TABLE `li_submissions` (
181
  `form_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
186
  `form_fields` text NOT NULL,
187
  `form_type` set('lead','comment','subscribe') NOT NULL DEFAULT 'lead',
188
  `form_hashkey` varchar(16) NOT NULL,
189
+ `form_deleted` int(1) NOT NULL DEFAULT '0',
190
  PRIMARY KEY (`form_id`),
191
  KEY `lead_hashkey` (`lead_hashkey`)
192
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;";
193
 
194
  dbDelta($sql);
195
 
252
  {
253
  $this->leadin_db_install();
254
  }
255
+
256
+ // 0.8.3 bug fix - bug fix for duplicated contacts that should be merged
257
+ if ( ! isset($li_options['delete_flags_fixed']) )
258
+ {
259
+ leadin_delete_flag_fix();
260
+ }
261
  }
262
 
263
  //=============================================
412
  $files[] = $file;
413
  }
414
 
415
+ $files = leadin_sort_power_ups($files, array(
416
+ LEADIN_PLUGIN_DIR . '/power-ups/contacts' . '.php', LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget' . '.php', LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-list-sync' . '.php', LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-list-sync' . '.php'
417
+ ));
418
+
419
  closedir( $dir );
420
 
421
  return $files;
449
  public static function activate_power_up( $power_up_slug, $exit = TRUE )
450
  {
451
  if ( ! strlen( $power_up_slug ) )
452
+ return FALSE;
453
 
454
  // If it's already active, then don't do it again
455
  $active = self::is_power_up_active($power_up_slug);
456
  if ( $active )
457
+ return TRUE;
458
 
459
  $activated_power_ups = get_option('leadin_active_power_ups');
460
 
lib/mixpanel/Base/{MixpanelBase.php → LI_MixpanelBase.php} RENAMED
@@ -5,7 +5,10 @@
5
  * debugging and logging functionality. It also serves to persist $_options across the library.
6
  *
7
  */
8
- class Base_MixpanelBase {
 
 
 
9
 
10
 
11
  /**
5
  * debugging and logging functionality. It also serves to persist $_options across the library.
6
  *
7
  */
8
+
9
+
10
+
11
+ class LI_Base_MixpanelBase {
12
 
13
 
14
  /**
lib/mixpanel/ConsumerStrategies/{AbstractConsumer.php → LI_AbstractConsumer.php} RENAMED
@@ -1,10 +1,11 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
 
3
 
4
  /**
5
  * Provides some base methods for use by a Consumer implementation
6
  */
7
- abstract class ConsumerStrategies_AbstractConsumer extends Base_MixpanelBase {
8
 
9
  /**
10
  * Creates a new AbstractConsumer
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/../Base/LI_MixpanelBase.php");
4
 
5
  /**
6
  * Provides some base methods for use by a Consumer implementation
7
  */
8
+ abstract class LI_ConsumerStrategies_AbstractConsumer extends LI_Base_MixpanelBase {
9
 
10
  /**
11
  * Creates a new AbstractConsumer
lib/mixpanel/ConsumerStrategies/{CurlConsumer.php → LI_CurlConsumer.php} RENAMED
@@ -1,10 +1,11 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
 
3
 
4
  /**
5
  * Consumes messages and sends them to a host/endpoint using cURL
6
  */
7
- class ConsumerStrategies_CurlConsumer extends ConsumerStrategies_AbstractConsumer {
8
 
9
  /**
10
  * @var string the host to connect to (e.g. api.mixpanel.com)
@@ -43,7 +44,7 @@ class ConsumerStrategies_CurlConsumer extends ConsumerStrategies_AbstractConsume
43
 
44
 
45
  /**
46
- * Creates a new CurlConsumer and assigns properties from the $options array
47
  * @param array $options
48
  * @throws Exception
49
  */
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
4
 
5
  /**
6
  * Consumes messages and sends them to a host/endpoint using cURL
7
  */
8
+ class LI_ConsumerStrategies_CurlConsumer extends LI_ConsumerStrategies_AbstractConsumer {
9
 
10
  /**
11
  * @var string the host to connect to (e.g. api.mixpanel.com)
44
 
45
 
46
  /**
47
+ * Creates a new LI_CurlConsumer and assigns properties from the $options array
48
  * @param array $options
49
  * @throws Exception
50
  */
lib/mixpanel/ConsumerStrategies/{FileConsumer.php → LI_FileConsumer.php} RENAMED
@@ -1,9 +1,10 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
 
3
  /**
4
  * Consumes messages and writes them to a file
5
  */
6
- class ConsumerStrategies_FileConsumer extends ConsumerStrategies_AbstractConsumer {
7
 
8
  /**
9
  * @var string path to a file that we want to write the messages to
@@ -12,7 +13,7 @@ class ConsumerStrategies_FileConsumer extends ConsumerStrategies_AbstractConsume
12
 
13
 
14
  /**
15
- * Creates a new FileConsumer and assigns properties from the $options array
16
  * @param array $options
17
  */
18
  function __construct($options) {
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
4
  /**
5
  * Consumes messages and writes them to a file
6
  */
7
+ class ConsumerStrategies_LI_FileConsumer extends LI_ConsumerStrategies_AbstractConsumer {
8
 
9
  /**
10
  * @var string path to a file that we want to write the messages to
13
 
14
 
15
  /**
16
+ * Creates a new LI_FileConsumer and assigns properties from the $options array
17
  * @param array $options
18
  */
19
  function __construct($options) {
lib/mixpanel/ConsumerStrategies/{SocketConsumer.php → LI_SocketConsumer.php} RENAMED
@@ -31,12 +31,13 @@
31
  * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
32
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
  */
34
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
 
35
 
36
  /**
37
  * Consumes messages and writes them to host/endpoint using a persistent socket
38
  */
39
- class ConsumerStrategies_SocketConsumer extends ConsumerStrategies_AbstractConsumer {
40
 
41
  /**
42
  * @var string the host to connect to (e.g. api.mixpanel.com)
31
  * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
32
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
  */
34
+
35
+ require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
36
 
37
  /**
38
  * Consumes messages and writes them to host/endpoint using a persistent socket
39
  */
40
+ class LI_ConsumerStrategies_SocketConsumer extends LI_ConsumerStrategies_AbstractConsumer {
41
 
42
  /**
43
  * @var string the host to connect to (e.g. api.mixpanel.com)
lib/mixpanel/{Mixpanel.php → LI_Mixpanel.php} RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- require_once(dirname(__FILE__) . "/Base/MixpanelBase.php");
4
- require_once(dirname(__FILE__) . "/Producers/MixpanelPeople.php");
5
- require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
6
 
7
  /**
8
  * This is the main class for the Mixpanel PHP Library which provides all of the methods you need to track events and
@@ -14,7 +14,7 @@ require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
14
  * This library is built such that all messages are buffered in an in-memory "queue"
15
  * The queue will be automatically flushed at the end of every request. Alternatively, you can call "flush()" manually
16
  * at any time. Flushed messages will be passed to a Consumer's "persist" method. The library comes with a handful of
17
- * Consumers. The "CurlConsumer" is used by default which will send the messages to Mixpanel using forked cURL processes.
18
  * You can implement your own custom Consumer to customize how a message is sent to Mixpanel. This can be useful when
19
  * you want to put messages onto a distributed queue (such as ActiveMQ or Kestrel) instead of writing to Mixpanel in
20
  * the user thread.
@@ -75,12 +75,12 @@ require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
75
  * </tr>
76
  * <tr>
77
  * <td>connect_timeout</td>
78
- * <td>In both the SocketConsumer and CurlConsumer, this is used for the connection timeout (i.e. How long it has take to actually make a connection).
79
  * <td>5</td>
80
  * </tr>
81
  * <tr>
82
  * <td>timeout</td>
83
- * <td>In the CurlConsumer (non-forked), it is used to determine how long the cURL call has to execute.
84
  * <td>30</td>
85
  * </tr>
86
  * </table>
@@ -106,7 +106,7 @@ require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
106
  * ));
107
  *
108
  */
109
- class Mixpanel extends Base_MixpanelBase {
110
 
111
 
112
  /**
@@ -127,7 +127,7 @@ class Mixpanel extends Base_MixpanelBase {
127
  * An instance of the Mixpanel class (for singleton use)
128
  * @var Mixpanel
129
  */
130
- private static $_instance;
131
 
132
 
133
  /**
@@ -137,8 +137,8 @@ class Mixpanel extends Base_MixpanelBase {
137
  */
138
  public function __construct($token, $options = array()) {
139
  parent::__construct($options);
140
- $this->people = new Producers_MixpanelPeople($token, $options);
141
- $this->_events = new Producers_MixpanelEvents($token, $options);
142
  }
143
 
144
 
@@ -149,10 +149,13 @@ class Mixpanel extends Base_MixpanelBase {
149
  * @return Mixpanel
150
  */
151
  public static function getInstance($token, $options = array()) {
152
- if(!isset(self::$_instance)) {
153
- self::$_instance = new Mixpanel($token, $options);
154
- }
155
- return self::$_instance;
 
 
 
156
  }
157
 
158
 
1
  <?php
2
 
3
+ require_once(dirname(__FILE__) . "/Base/LI_MixpanelBase.php");
4
+ require_once(dirname(__FILE__) . "/Producers/LI_MixpanelPeople.php");
5
+ require_once(dirname(__FILE__) . "/Producers/LI_MixpanelEvents.php");
6
 
7
  /**
8
  * This is the main class for the Mixpanel PHP Library which provides all of the methods you need to track events and
14
  * This library is built such that all messages are buffered in an in-memory "queue"
15
  * The queue will be automatically flushed at the end of every request. Alternatively, you can call "flush()" manually
16
  * at any time. Flushed messages will be passed to a Consumer's "persist" method. The library comes with a handful of
17
+ * Consumers. The "LI_CurlConsumer" is used by default which will send the messages to Mixpanel using forked cURL processes.
18
  * You can implement your own custom Consumer to customize how a message is sent to Mixpanel. This can be useful when
19
  * you want to put messages onto a distributed queue (such as ActiveMQ or Kestrel) instead of writing to Mixpanel in
20
  * the user thread.
75
  * </tr>
76
  * <tr>
77
  * <td>connect_timeout</td>
78
+ * <td>In both the SocketConsumer and LI_CurlConsumer, this is used for the connection timeout (i.e. How long it has take to actually make a connection).
79
  * <td>5</td>
80
  * </tr>
81
  * <tr>
82
  * <td>timeout</td>
83
+ * <td>In the LI_CurlConsumer (non-forked), it is used to determine how long the cURL call has to execute.
84
  * <td>30</td>
85
  * </tr>
86
  * </table>
106
  * ));
107
  *
108
  */
109
+ class LI_Mixpanel extends LI_Base_MixpanelBase {
110
 
111
 
112
  /**
127
  * An instance of the Mixpanel class (for singleton use)
128
  * @var Mixpanel
129
  */
130
+ public $instance;
131
 
132
 
133
  /**
137
  */
138
  public function __construct($token, $options = array()) {
139
  parent::__construct($options);
140
+ $this->people = new LI_Producers_MixpanelPeople($token, $options);
141
+ $this->_events = new LI_Producers_MixpanelEvents($token, $options);
142
  }
143
 
144
 
149
  * @return Mixpanel
150
  */
151
  public static function getInstance($token, $options = array()) {
152
+
153
+
154
+
155
+
156
+ $this->instance = new LI_Mixpanel($token, $options);
157
+
158
+
159
  }
160
 
161
 
lib/mixpanel/Producers/{MixpanelBaseProducer.php → LI_MixpanelBaseProducer.php} RENAMED
@@ -1,8 +1,9 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
3
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/FileConsumer.php");
4
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
5
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/SocketConsumer.php");
 
6
 
7
  if (!function_exists('json_encode')) {
8
  throw new Exception('The JSON PHP extension is required.');
@@ -11,7 +12,7 @@ if (!function_exists('json_encode')) {
11
  /**
12
  * Provides some base methods for use by a message Producer
13
  */
14
- abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
15
 
16
 
17
  /**
@@ -27,7 +28,7 @@ abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
27
 
28
 
29
  /**
30
- * @var ConsumerStrategies_AbstractConsumer the consumer to use when flushing messages
31
  */
32
  private $_consumer = null;
33
 
@@ -36,9 +37,9 @@ abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
36
  * @var array The list of available consumers
37
  */
38
  private $_consumers = array(
39
- "file" => "ConsumerStrategies_FileConsumer",
40
- "curl" => "ConsumerStrategies_CurlConsumer",
41
- "socket" => "ConsumerStrategies_SocketConsumer"
42
  );
43
 
44
 
@@ -164,7 +165,7 @@ abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
164
 
165
  /**
166
  * Given a strategy type, return a new PersistenceStrategy object
167
- * @return ConsumerStrategies_AbstractConsumer
168
  */
169
  protected function _getConsumer() {
170
  $key = $this->_options['consumer'];
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/../Base/LI_MixpanelBase.php");
4
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_FileConsumer.php");
5
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_CurlConsumer.php");
6
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_SocketConsumer.php");
7
 
8
  if (!function_exists('json_encode')) {
9
  throw new Exception('The JSON PHP extension is required.');
12
  /**
13
  * Provides some base methods for use by a message Producer
14
  */
15
+ abstract class LI_Producers_MixpanelBaseProducer extends LI_Base_MixpanelBase {
16
 
17
 
18
  /**
28
 
29
 
30
  /**
31
+ * @var LI_ConsumerStrategies_AbstractConsumer the consumer to use when flushing messages
32
  */
33
  private $_consumer = null;
34
 
37
  * @var array The list of available consumers
38
  */
39
  private $_consumers = array(
40
+ "file" => "LI_ConsumerStrategies_FileConsumer",
41
+ "curl" => "LI_ConsumerStrategies_CurlConsumer",
42
+ "socket" => "LI_ConsumerStrategies_SocketConsumer"
43
  );
44
 
45
 
165
 
166
  /**
167
  * Given a strategy type, return a new PersistenceStrategy object
168
+ * @return LI_ConsumerStrategies_AbstractConsumer
169
  */
170
  protected function _getConsumer() {
171
  $key = $this->_options['consumer'];
lib/mixpanel/Producers/{MixpanelEvents.php → LI_MixpanelEvents.php} RENAMED
@@ -1,12 +1,13 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
3
- require_once(dirname(__FILE__) . "/MixpanelPeople.php");
4
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
 
5
 
6
  /**
7
  * Provides an API to track events on Mixpanel
8
  */
9
- class Producers_MixpanelEvents extends Producers_MixpanelBaseProducer {
10
 
11
  /**
12
  * An array of properties to attach to every tracked event
@@ -143,8 +144,8 @@ class Producers_MixpanelEvents extends Producers_MixpanelBaseProducer {
143
  );
144
 
145
  $options = array_merge($this->_options, array("endpoint" => $this->_getEndpoint(), "fork" => false));
146
- $curlConsumer = new ConsumerStrategies_CurlConsumer($options);
147
- $success = $curlConsumer->persist(array($msg));
148
  if (!$success) {
149
  //error_log("Creating Mixpanel Alias (original id: $original_id, new id: $new_id) failed");
150
  //throw new Exception("Tried to create an alias but the call was not successful");
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/LI_MixpanelBaseProducer.php");
4
+ require_once(dirname(__FILE__) . "/LI_MixpanelPeople.php");
5
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_CurlConsumer.php");
6
 
7
  /**
8
  * Provides an API to track events on Mixpanel
9
  */
10
+ class LI_Producers_MixpanelEvents extends LI_Producers_MixpanelBaseProducer {
11
 
12
  /**
13
  * An array of properties to attach to every tracked event
144
  );
145
 
146
  $options = array_merge($this->_options, array("endpoint" => $this->_getEndpoint(), "fork" => false));
147
+ $LI_CurlConsumer = new LI_ConsumerStrategies_CurlConsumer($options);
148
+ $success = $LI_CurlConsumer->persist(array($msg));
149
  if (!$success) {
150
  //error_log("Creating Mixpanel Alias (original id: $original_id, new id: $new_id) failed");
151
  //throw new Exception("Tried to create an alias but the call was not successful");
lib/mixpanel/Producers/{MixpanelPeople.php → LI_MixpanelPeople.php} RENAMED
@@ -1,10 +1,11 @@
1
  <?php
2
- require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
 
3
 
4
  /**
5
  * Provides an API to create/update profiles on Mixpanel
6
  */
7
- class Producers_MixpanelPeople extends Producers_MixpanelBaseProducer {
8
 
9
  /**
10
  * Internal method to prepare a message given the message data
1
  <?php
2
+
3
+ require_once(dirname(__FILE__) . "/LI_MixpanelBaseProducer.php");
4
 
5
  /**
6
  * Provides an API to create/update profiles on Mixpanel
7
  */
8
+ class LI_Producers_MixpanelPeople extends LI_Producers_MixpanelBaseProducer {
9
 
10
  /**
11
  * Internal method to prepare a message given the message data
power-ups/constant-contact-list-sync.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Power-up Name: Contact Sync
4
+ * Power-up Class: WPConstantContactListSync
5
+ * Power-up Menu Text:
6
+ * Power-up Slug: constant_contact_list_sync
7
+ * Power-up Menu Link: settings
8
+ * Power-up URI: http://leadin.com/constant-contact-list-sync
9
+ * Power-up Description: Sync your subscribers to a Constant Contact email list.
10
+ * Power-up Icon: power-up-icon-constant-contact-list-sync
11
+ * Power-up Icon Small: power-up-icon-constant-contact-list-sync_small
12
+ * First Introduced: 0.8.0
13
+ * Power-up Tags: Newsletter, Email
14
+ * Auto Activate: No
15
+ */
16
+
17
+ //=============================================
18
+ // Define Constants
19
+ //=============================================
20
+
21
+ if ( !defined('LEADIN_CONSTANT_CONTACT_LIST_SYNC_PATH') )
22
+ define('LEADIN_CONSTANT_CONTACT_LIST_SYNC_PATH', LEADIN_PATH . '/power-ups/constant-contact-list-sync');
23
+
24
+ if ( !defined('LEADIN_CONSTANT_CONTACT_LIST_SYNC_PLUGIN_DIR') )
25
+ define('LEADIN_CONSTANT_CONTACT_LIST_SYNC_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-list-sync');
26
+
27
+ if ( !defined('LEADIN_CONSTANT_CONTACT_LIST_SYNC_PLUGIN_SLUG') )
28
+ define('LEADIN_CONSTANT_CONTACT_LIST_SYNC_SLUG', basename(dirname(__FILE__)));
29
+
30
+ if ( !defined('LEADIN_CONSTANT_CONTACT_API_KEY') )
31
+ define('LEADIN_CONSTANT_CONTACT_API_KEY', 'p5hrzdhe2zrwbm76r2u7pvtc');
32
+
33
+
34
+
35
+ //=============================================
36
+ // Include Needed Files
37
+ //=============================================
38
+ require_once(LEADIN_CONSTANT_CONTACT_LIST_SYNC_PLUGIN_DIR . '/admin/constant-contact-list-sync-admin.php');
39
+ require_once(LEADIN_CONSTANT_CONTACT_LIST_SYNC_PLUGIN_DIR . '/inc/li_constant_contact.php');
40
+
41
+ //=============================================
42
+ // WPLeadIn Class
43
+ //=============================================
44
+ class WPConstantContactListSync extends WPLeadIn {
45
+
46
+ var $admin;
47
+ var $options;
48
+
49
+ /**
50
+ * Class constructor
51
+ */
52
+ function __construct ( $activated )
53
+ {
54
+ //=============================================
55
+ // Hooks & Filters
56
+ //=============================================
57
+
58
+ if ( ! $activated )
59
+ return false;
60
+
61
+ global $leadin_constant_contact_list_sync_wp;
62
+ $leadin_constant_contact_list_sync_wp = $this;
63
+ $this->options = get_option('leadin_cc_options');
64
+ }
65
+
66
+ public function admin_init ( )
67
+ {
68
+ $admin_class = get_class($this) . 'Admin';
69
+ $this->admin = new $admin_class($this->icon_small);
70
+ }
71
+
72
+ function power_up_setup_callback ( )
73
+ {
74
+ $this->admin->power_up_setup_callback();
75
+ }
76
+
77
+ /**
78
+ * Activate the power-up and add the defaults
79
+ */
80
+ function add_defaults ()
81
+ {
82
+
83
+ }
84
+
85
+ function push_constant_contact_subscriber_to_list ( $email = '', $first_name = '', $last_name = '', $phone = '' )
86
+ {
87
+ $options = $this->options;
88
+
89
+ $li_cc_subscribers_to_list = ( isset($options['li_cc_subscribers_to_list']) ? $options['li_cc_subscribers_to_list'] : '' );
90
+
91
+ if ( isset($options['li_cc_email']) && isset($options['li_cc_password']) && $options['li_cc_email'] && $options['li_cc_password'] && $li_cc_subscribers_to_list )
92
+ {
93
+ $this->constant_contact = new LI_ConstantContact($options['li_cc_email'], $options['li_cc_password'], LEADIN_CONSTANT_CONTACT_API_KEY, TRUE);
94
+
95
+ $contact = array();
96
+
97
+ if ( $email )
98
+ $contact['EmailAddress'] = $email;
99
+
100
+ if ( $first_name )
101
+ $contact['FirstName'] = $first_name;
102
+
103
+ if ( $last_name )
104
+ $contact['LastName'] = $last_name;
105
+
106
+ if ( $phone )
107
+ $contact['HomePhone'] = $phone;
108
+
109
+ if ( $phone )
110
+ $contact['WorkPhone'] = $phone;
111
+
112
+ $this->constant_contact->add_contact($contact, array($li_cc_subscribers_to_list));
113
+ }
114
+ }
115
+ }
116
+
117
+ //=============================================
118
+ // Subscribe Widget Init
119
+ //=============================================
120
+
121
+ global $leadin_constant_contact_list_sync_wp;
122
+
123
+ ?>
power-ups/constant-contact-list-sync/admin/constant-contact-list-sync-admin.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //=============================================
3
+ // WPLeadInAdmin Class
4
+ //=============================================
5
+ class WPConstantContactListSyncAdmin extends WPLeadInAdmin {
6
+
7
+ var $power_up_settings_section = 'leadin_cc_options_section';
8
+ var $power_up_icon;
9
+ var $auth_set;
10
+ var $bad_api_call;
11
+ var $constant_contact;
12
+ var $lists;
13
+
14
+ /**
15
+ * Class constructor
16
+ */
17
+ function __construct ( $small_icon )
18
+ {
19
+ //=============================================
20
+ // Hooks & Filters
21
+ //=============================================
22
+
23
+ if ( is_admin() )
24
+ {
25
+ $this->power_up_icon = '<img src="' . LEADIN_PATH . '/images/' . $small_icon . '.png" class="power-up-settings-icon"/>';
26
+ add_action('admin_init', array($this, 'leadin_cc_build_settings_page'));
27
+ }
28
+ }
29
+
30
+ //=============================================
31
+ // Settings Page
32
+ //=============================================
33
+
34
+ /**
35
+ * Creates settings options
36
+ */
37
+ function leadin_cc_build_settings_page ()
38
+ {
39
+ global $leadin_constant_contact_list_sync_wp;
40
+
41
+ $options = get_option('leadin_cc_options');
42
+
43
+ register_setting('leadin_settings_options', 'leadin_cc_options', array($this, 'sanitize'));
44
+
45
+ // If the creds are set, check if they are any good by hitting the API
46
+ if ( isset($options['li_cc_email']) && isset($options['li_cc_password']) && $options['li_cc_email'] && $options['li_cc_password'] )
47
+ {
48
+ $this->auth_set = TRUE;
49
+
50
+ // Try to make a request using the authentication credentials
51
+ $this->lists = $this->li_cc_get_email_lists(LEADIN_CONSTANT_CONTACT_API_KEY, $options['li_cc_email'], $options['li_cc_password']);
52
+
53
+ if ( $this->constant_contact->cc_exception )
54
+ {
55
+ $this->bad_api_call = TRUE;
56
+ }
57
+ }
58
+
59
+ add_settings_section($this->power_up_settings_section, $this->power_up_icon . "Constant Contact", array($this, 'cc_section_callback'), LEADIN_ADMIN_PATH);
60
+
61
+ if ( $this->auth_set && ! $this->bad_api_call )
62
+ {
63
+ add_settings_field('li_cc_subscribers_to_list', 'Add subscribers to list', array($this, 'li_cc_subscribers_to_list_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
64
+ }
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->auth_set )
75
+ echo 'Sign into your Constant Contact account below to setup Contact Sync';
76
+ else if ( $this->bad_api_call )
77
+ echo '<div id="message" class="updated below-h2 error"><p>' . $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
+ $options = get_option('leadin_cc_options');
86
+ $li_cc_email = ( $options['li_cc_email'] ? $options['li_cc_email'] : '' );
87
+ $li_cc_password = ( $options['li_cc_password'] ? $options['li_cc_password'] : '' );
88
+
89
+ if ( $li_cc_email )
90
+ {
91
+ printf(
92
+ '<input id="li_cc_email" type="hidden" name="leadin_cc_options[li_cc_email]" value="%s"/>',
93
+ $li_cc_email
94
+ );
95
+ }
96
+
97
+ if ( $li_cc_password )
98
+ {
99
+ printf(
100
+ '<input id="li_cc_password" type="hidden" name="leadin_cc_options[li_cc_password]" value="%s"/>',
101
+ $li_cc_password
102
+ );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Sanitize each setting field as needed
108
+ *
109
+ * @param array $input Contains all settings fields as array keys
110
+ */
111
+ public function sanitize ( $input )
112
+ {
113
+ $new_input = array();
114
+
115
+ if( isset( $input['li_cc_email'] ) )
116
+ $new_input['li_cc_email'] = sanitize_text_field( $input['li_cc_email'] );
117
+
118
+ if( isset( $input['li_cc_password'] ) )
119
+ $new_input['li_cc_password'] = sanitize_text_field( $input['li_cc_password'] );
120
+
121
+ if( isset( $input['li_cc_subscribers_to_list'] ) )
122
+ $new_input['li_cc_subscribers_to_list'] = sanitize_text_field( $input['li_cc_subscribers_to_list'] );
123
+
124
+ return $new_input;
125
+ }
126
+
127
+ /**
128
+ * Prints email input for settings page
129
+ */
130
+ function li_cc_email_callback ()
131
+ {
132
+ $options = get_option('leadin_cc_options');
133
+ $li_cc_email = ( $options['li_cc_email'] ? $options['li_cc_email'] : '' ); // Get header from options, or show default
134
+
135
+ printf(
136
+ '<input id="li_cc_email" type="text" id="title" name="leadin_cc_options[li_cc_email]" value="%s" size="50"/>',
137
+ $li_cc_email
138
+ );
139
+ }
140
+
141
+ /**
142
+ * Prints password input for settings page
143
+ */
144
+ function li_cc_password_callback ()
145
+ {
146
+ $options = get_option('leadin_cc_options');
147
+ $li_cc_password = ( $options['li_cc_password'] ? $options['li_cc_password'] : '' ); // Get header from options, or show default
148
+
149
+ printf(
150
+ '<input id="li_cc_password" type="password" id="title" name="leadin_cc_options[li_cc_password]" value="%s" size="50"/>',
151
+ $li_cc_password
152
+ );
153
+ }
154
+
155
+ /**
156
+ * Prints email input for settings page
157
+ */
158
+ function li_cc_subscribers_to_list_callback ()
159
+ {
160
+ $options = get_option('leadin_cc_options');
161
+ $li_cc_subscribers_to_list = ( isset($options['li_cc_subscribers_to_list']) ? $options['li_cc_subscribers_to_list'] : '' ); // Get header from options, or show default
162
+
163
+ echo '<select id="li_cc_subscribers_to_list" name="leadin_cc_options[li_cc_subscribers_to_list]" ' . ( ! count($this->lists) ? 'disabled' : '' ) . '>';
164
+
165
+ if ( count($this->lists) )
166
+ {
167
+ $list_set = FALSE;
168
+
169
+ foreach ( $this->lists as $list )
170
+ {
171
+ // Skip over default lists
172
+ if ( $list['Name'] == 'Active' || $list['Name'] == 'Do Not Mail' || $list['Name'] == 'Removed' )
173
+ continue;
174
+
175
+ if ( urldecode($list['ListID']) == $li_cc_subscribers_to_list && !$list_set )
176
+ $list_set = TRUE;
177
+
178
+ echo '<option ' . ( urldecode($list['ListID']) == $li_cc_subscribers_to_list ? 'selected' : '' ) . ' value="' . urldecode($list['ListID']) . '">' . $list['Name'] . '</option>';
179
+ }
180
+
181
+ if ( !$list_set )
182
+ echo '<option selected value="">No list set...</option>';
183
+ }
184
+ else
185
+ {
186
+ echo '<option value="No lists...">No lists...</option>';
187
+ }
188
+
189
+ echo '</select>';
190
+ 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>';
191
+ }
192
+
193
+ function li_cc_get_email_lists ( $api_key, $username, $password )
194
+ {
195
+ $this->constant_contact = new LI_ConstantContact($username, $password, $api_key, FALSE);
196
+ $lists = $this->constant_contact->get_lists();
197
+
198
+ if ( count($lists) )
199
+ return $lists;
200
+ else
201
+ return FALSE;
202
+ }
203
+ }
204
+
205
+ ?>
power-ups/constant-contact-list-sync/inc/li_constant_contact.php ADDED
@@ -0,0 +1,1114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 = 'cli' )
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
+ if(strlen(trim($post))>0)
80
+ {
81
+ if ($this->debug['style'] == 'cli')
82
+ $this->debug_print("And Posting:\n\n---START---\n".$post."\n---END---\n\n");
83
+ elseif ($this->debug['style'] == 'html')
84
+ $this->debug_print("And Posting:<pre>\n\n---START---\n".htmlspecialchars($post)."\n---END---\n\n</pre>");
85
+ if ($call_type == 'PUT')
86
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
87
+ elseif ($call_type == 'DELETE')
88
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
89
+ else
90
+ curl_setopt($ch, CURLOPT_POST, 1);
91
+
92
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
93
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/atom+xml'));
94
+ }
95
+ else
96
+ {
97
+ $this->debug_print("Not posting");
98
+ curl_setopt($ch, CURLOPT_POST, 0);
99
+ if ($call_type == 'PUT')
100
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
101
+ elseif ($call_type == 'DELETE')
102
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
103
+ }
104
+
105
+ curl_setopt($ch, CURLOPT_HEADER, 0);
106
+
107
+ $response = curl_exec($ch);
108
+ $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
109
+ $this->debug_print("HTTP Response Code '".$response_code."'");
110
+
111
+ if ( ! in_array($response_code, array('201', '200', '204')) )
112
+ {
113
+ if ( $response_code == 401 )
114
+ {
115
+ $this->cc_exception = "Sorry, that username and password combination isn't right";
116
+ }
117
+ else if ( $response_code == 403 )
118
+ {
119
+ $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";
120
+ }
121
+ }
122
+
123
+ $this->debug['last_response'] = $response_code;
124
+
125
+ if ($this->debug['style'] == 'cli')
126
+ $this->debug_print("Received:\n\n---START---\n".$response."\n---END---\n\n");
127
+ elseif ($this->debug['style'] == 'html')
128
+ $this->debug_print("Received:<pre>\n\n---START---\n".htmlspecialchars($response)."\n---END---\n\n</pre>");
129
+
130
+ curl_close($ch);
131
+ if ($fetch_as == 'array')
132
+ return $this->xml_to_array($response);
133
+ else
134
+ return $response;
135
+ }
136
+
137
+ /**
138
+ * Converts XML data into a nested array
139
+ *
140
+ * @param String $contents - XML string
141
+ * @param Integers $get_attributes - Include attributes (default 1)
142
+ * @return Nested associative array
143
+ */
144
+ public function xml_to_array($contents, $get_attributes=1)
145
+ {
146
+ if (!$contents)
147
+ return array();
148
+
149
+ if (!function_exists('xml_parser_create'))
150
+ {
151
+ $this->debug_print("ERROR: xml_parser_create function doesn't exist!");
152
+ return array();
153
+ }
154
+
155
+ $parser = xml_parser_create();
156
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
157
+ xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
158
+ xml_parse_into_struct( $parser, $contents, $xml_values );
159
+ xml_parser_free( $parser );
160
+
161
+ if (!$xml_values)
162
+ {
163
+ $this->debug_print("WARN: Could not parse xml_values!");
164
+ return;
165
+ }
166
+
167
+ $xml_array = array();
168
+ $parents = array();
169
+ $opened_tags = array();
170
+ $arr = array();
171
+
172
+ $current = &$xml_array;
173
+
174
+ foreach( $xml_values as $data)
175
+ {
176
+ unset($attributes,$value);
177
+ extract($data);
178
+
179
+ $result = '';
180
+ if ($get_attributes)
181
+ {
182
+ $result = array();
183
+ if (isset($value))
184
+ $result['value'] = $value;
185
+ if (isset($attributes))
186
+ {
187
+ foreach ($attributes as $attr => $val)
188
+ {
189
+ if ($get_attributes == 1)
190
+ $result['attr'][$attr] = $val;
191
+ }
192
+ }
193
+ }
194
+ elseif (isset($value))
195
+ $result = $value;
196
+
197
+ if ($type == "open")
198
+ {
199
+ $parent[$level-1] = &$current;
200
+ if (!is_array($current) || !in_array($tag, array_keys($current)))
201
+ {
202
+ $current[$tag] = $result;
203
+ $current = &$current[$tag];
204
+ }
205
+ else
206
+ {
207
+ if (isset($current[$tag][0]))
208
+ array_push($current[$tag], $result);
209
+ else
210
+ $current[$tag] = array($current[$tag],$result);
211
+
212
+ $last = count($current[$tag]) - 1;
213
+ $current = &$current[$tag][$last];
214
+ }
215
+ }
216
+ elseif ($type == "complete")
217
+ {
218
+ if (!isset($current[$tag]))
219
+ $current[$tag] = $result;
220
+ else
221
+ {
222
+ if ((is_array($current[$tag]) and $get_attributes == 0) || (isset($current[$tag][0]) and is_array($current[$tag][0]) and $get_attributes == 1))
223
+ array_push($current[$tag],$result);
224
+ else
225
+ $current[$tag] = array($current[$tag],$result);
226
+ }
227
+ }
228
+ elseif ($type == 'close')
229
+ $current = &$parent[$level-1];
230
+ }
231
+ return($xml_array);
232
+ }
233
+
234
+ /**
235
+ * Converts id URL to numeric id
236
+ *
237
+ * @param String $url - ID URL
238
+ * @return Numeric ID
239
+ */
240
+ public function id_from_url($url)
241
+ {
242
+ $temp = Array();
243
+ $temp = explode('/',trim($url));
244
+ return trim($temp[count($temp)-1]);
245
+ }
246
+
247
+ /**
248
+ * Retrieves the XML service document
249
+ *
250
+ * @return XML service document
251
+ */
252
+ public function get_service_doc_xml()
253
+ {
254
+ $url=$this->api_url;
255
+ $post='';
256
+ $response=$this->fetch($url,$post,'xml');
257
+ return $response;
258
+ }
259
+
260
+
261
+ //Contact Functions
262
+
263
+ /**
264
+ * Formats a contact array into the format we always return as
265
+ * Note:
266
+ * I like to do this because the atom specification has so much extraneous data
267
+ * that I just don't care about. This makes a sane array out of what is
268
+ * incredibly overcomplicated in my opinion.
269
+ *
270
+ * @param Array - Contact array as returned from fetch/xml_to_array
271
+ * @return Associative array in the format returned by this api
272
+ */
273
+ public function format_contact($response)
274
+ {
275
+ $my_data = Array();
276
+ $my_data = $response['entry']['content']['Contact'];
277
+ $d = Array();
278
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
279
+ unset($my_data['attr']);
280
+ foreach ($my_data as $dkey => $dval)
281
+ {
282
+ if ($dkey != 'ContactLists')
283
+ $d[$dkey] = $dval['value'];
284
+ else
285
+ {
286
+ $entries = Array();
287
+ if (isset($dval['ContactList']['link']))
288
+ $entries[] = $dval['ContactList'];
289
+ else
290
+ $entries = $dval['ContactList'];
291
+
292
+ foreach ($entries as $entry)
293
+ {
294
+ $e = Array();
295
+ $e['ListID'] = $this->id_from_url($entry['attr']['id']);
296
+ unset($entry['attr']);
297
+ unset($entry['link']);
298
+ foreach ($entry as $ekey => $eval)
299
+ $e[$ekey] = $eval['value'];
300
+ $d[$dkey][] = $e;
301
+ }
302
+ }
303
+ }
304
+ return $d;
305
+ }
306
+
307
+ /**
308
+ * Return your list of contacts.
309
+ *
310
+ * @param String $key - Optionally specify a key to use for the array
311
+ * @param Boolean $unique - Whether the key you specified is unique
312
+ * @return Associative array containing your contacts indexed by whatever key specified.
313
+ */
314
+ public function get_contacts($key='',$unique=true)
315
+ {
316
+ $ret = Array();
317
+
318
+ $url = $this->api['url'].'contacts';
319
+ $post = '';
320
+ $response = Array();
321
+ $response = $this->fetch($url,$post);
322
+
323
+ $entries = Array();
324
+ if (isset($response['feed']['entry']['link']))
325
+ $entries[] = $response['feed']['entry'];
326
+ else
327
+ $entries = $response['feed']['entry'];
328
+ foreach ($entries as $data)
329
+ {
330
+ $my_data = Array();
331
+ $my_data = $data['content']['Contact'];
332
+ $d = Array();
333
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
334
+ unset($my_data['attr']);
335
+ foreach ($my_data as $dkey => $dval)
336
+ $d[$dkey] = $dval['value'];
337
+
338
+ if ($key)
339
+ {
340
+ if ($unique)
341
+ $ret[$d[$key]] = $d;
342
+ else
343
+ $ret[$d[$key]][] = $d;
344
+ }
345
+ else
346
+ $ret[] = $d;
347
+ }
348
+ return $ret;
349
+ }
350
+
351
+ /**
352
+ * Add a contact
353
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
354
+ *
355
+ * @param Array $data - An associative array containing all the contact data to add
356
+ * @param Array $lists - An array of list_ids to add this contact to
357
+ * @return Integer - ContactID for the new entry
358
+ */
359
+ public function add_contact($data,$lists)
360
+ {
361
+
362
+ $updated = date('Y-m-d\TH:i:s\Z');
363
+ $xml_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><entry xmlns='http://www.w3.org/2005/Atom'></entry>";
364
+ $xml_object = simplexml_load_string($xml_string);
365
+ $xml_object->addChild("title");
366
+ $xml_object->addChild("updated",$updated);
367
+ $author_node = $xml_object->addChild("author");
368
+ $author_node->addChild("name", ("CTCT Samples"));
369
+ $xml_object->addChild("id", 'data:,none');
370
+ $summary_node = $xml_object->addChild("summary");
371
+ $summary_node->addAttribute("type", "text");
372
+ $content_node = $xml_object->addChild("content");
373
+ $content_node->addAttribute("type", "application/vnd.ctct+xml");
374
+ $contact_node = $content_node->addChild("Contact");
375
+ $contact_node->addAttribute("xmlns", "http://ws.constantcontact.com/ns/1.0/");
376
+ $contact_node->addChild("OptInSource", 'ACTION_BY_CUSTOMER');
377
+
378
+ foreach ( $data as $key => $val )
379
+ {
380
+ $contact_node->addChild($key, $val);
381
+ }
382
+
383
+ $contactlists_node = $contact_node->addChild("ContactLists");
384
+ foreach ( $lists as $list )
385
+ {
386
+ $listNode = $contactlists_node->addChild("ContactList");
387
+ $listNode->addAttribute("id", $list);
388
+ }
389
+
390
+ $entry = $xml_object->asXML();
391
+
392
+ $url= $this->api['url'].'contacts';
393
+
394
+ $response = Array();
395
+ $response = $this->fetch($url, $entry);
396
+ if ( $this->debug['last_response'] <= 204 )
397
+ return $this->id_from_url($response['entry']['id']['value']);
398
+ else
399
+ return false;
400
+ }
401
+
402
+ /**
403
+ * Returns detailed info for a particular contact.
404
+ *
405
+ * @param Integer $id - Contact ID of the contact requested.
406
+ * @return Associative array containing the contact's details
407
+ */
408
+ public function get_contact($id)
409
+ {
410
+ $url = $this->api['url'].'contacts/'.$id;
411
+ $post = '';
412
+ $contact = Array();
413
+ $contact = $this->format_contact($this->fetch($url,$post));
414
+
415
+ if ($this->debug['last_response'] <= 204)
416
+ return $contact;
417
+ else
418
+ return false;
419
+ }
420
+
421
+ /**
422
+ * Edit a contact
423
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
424
+ *
425
+ * @param Integer $id - Contact ID of the contact to edit
426
+ * @param Array $data - An associative array containing all the contact data to edit
427
+ * @return Boolean - True on success and false on failure
428
+ */
429
+ public function edit_contact($id,$data)
430
+ {
431
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
432
+ $url = $this->api['url'].'contacts/'.$id;
433
+ $post = '';
434
+ $post = $this->fetch($url,$post,'xml');
435
+
436
+ foreach ($data as $key => $val)
437
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
438
+
439
+ $this->fetch($url,$post,'array','PUT');
440
+
441
+ if ($this->debug['last_response'] <= 204)
442
+ return true;
443
+ else
444
+ return false;
445
+ }
446
+
447
+ /**
448
+ * Delete a contact
449
+ *
450
+ * @param Integer $id - Contact ID of the contact to delete
451
+ * @return Boolean - True on success and false on failure
452
+ */
453
+ public function delete_contact($id)
454
+ {
455
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
456
+ $url = $this->api['url'].'contacts/'.$id;
457
+ $post = '';
458
+ $this->fetch($url,$post,'array','DELETE');
459
+
460
+ if ($this->debug['last_response'] <= 204)
461
+ return true;
462
+ else
463
+ return false;
464
+ }
465
+
466
+
467
+ /**
468
+ * Search for a contact by email
469
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
470
+ *
471
+ * @param String $email - Email address of the contact to search for
472
+ * @param Boolean $id_only - If true will return ContactID found otherwise will return all contact info
473
+ * @return Integer of found ContactID or Associative Array of contact info for found contact
474
+ */
475
+ public function search_contact_by_email($email,$id_only=true)
476
+ {
477
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
478
+ $url = $this->api['url'].'contacts?email='.urlencode(strtolower($email));
479
+ $response = Array();
480
+ $response = $this->fetch($url,$post);
481
+
482
+ if ($this->debug['last_response'] <= 204)
483
+ {
484
+ if ($id_only)
485
+ return $this->id_from_url($response['feed']['entry']['id']['value']);
486
+ else
487
+ return $this->get_contact($this->id_from_url($response['feed']['entry']['id']['value']));
488
+ }
489
+ else
490
+ return false;
491
+ }
492
+
493
+ /**
494
+ * Returns contacts updated since date your list of contacts.
495
+ *
496
+ * @param Date $date - Date should be in the format "Y-m-d H:i:s" (this is the datetime mysql spec)
497
+ * @param String $list_type - Type of contact to query for: active,removed,do-not-mail
498
+ * @param String $key - Optionally specify a key to use for the array
499
+ * @param Boolean $unique - Whether the key you specified is unique
500
+ * @return Associative array containing your contacts indexed by whatever key specified.
501
+ */
502
+ public function search_contacts_by_date($date,$list_type='active',$key='',$unique=true)
503
+ {
504
+ //Format date to UTC atom spec
505
+ $atom_date = date('Y-m-d\TH:i:s\Z',strtotime($date)+date("Z"));
506
+
507
+ $ret = Array();
508
+
509
+ $url = $this->api['url'].'contacts?updatedsince='.$atom_date.'&listtype='.$list_type;
510
+ $post = '';
511
+ $response = Array();
512
+ $response = $this->fetch($url,$post);
513
+
514
+ $entries = Array();
515
+ if (isset($response['feed']['entry']['link']))
516
+ $entries[] = $response['feed']['entry'];
517
+ else
518
+ $entries = $response['feed']['entry'];
519
+ foreach ($entries as $data)
520
+ {
521
+ $my_data = Array();
522
+ $my_data = $data['content']['Contact'];
523
+ $d = Array();
524
+ $d['ContactID'] = $this->id_from_url($my_data['attr']['id']);
525
+ unset($my_data['attr']);
526
+ foreach ($my_data as $dkey => $dval)
527
+ $d[$dkey] = $dval['value'];
528
+
529
+ if ($key)
530
+ {
531
+ if ($unique)
532
+ $ret[$d[$key]] = $d;
533
+ else
534
+ $ret[$d[$key]][] = $d;
535
+ }
536
+ else
537
+ $ret[] = $d;
538
+ }
539
+ return $ret;
540
+ }
541
+
542
+ //List Functions
543
+
544
+ /**
545
+ * Formats a list array into the format we always return as
546
+ * Note:
547
+ * I like to do this because the atom specification has so much extraneous data
548
+ * that I just don't care about it. This makes a sane array out of what is
549
+ * incredibly overcomplicated in my opinion.
550
+ *
551
+ * @param Array - Contact array as returned from fetch/xml_to_array
552
+ * @return Associative array in the format returned by this api
553
+ */
554
+ public function format_list($response)
555
+ {
556
+ $my_data = Array();
557
+ $my_data = $response['entry']['content']['ContactList'];
558
+ $d = Array();
559
+ $d['ListID'] = $this->id_from_url($my_data['attr']['id']);
560
+ unset($my_data['attr']);
561
+ unset($my_data['Members']);
562
+ foreach ($my_data as $key => $val)
563
+ $d[$key] = $val['value'];
564
+ return $d;
565
+ }
566
+
567
+ /**
568
+ * Add a list
569
+ * See List Data Format at http://developer.constantcontact.com/doc/contactLists for all fields
570
+ *
571
+ * @param Array $data - An associative array containing all the contact data to add
572
+ * @return Integer - ListID for the new entry
573
+ */
574
+ public function add_list($data)
575
+ {
576
+ $updated = date('Y-m-d\TH:i:s\Z');
577
+ $post = <<<end
578
+ <entry xmlns="http://www.w3.org/2005/Atom">
579
+ <title type="text"> </title>
580
+ <updated>{$updated}</updated>
581
+ <author></author>
582
+ <id>data:,none</id>
583
+ <summary type="text">Contact</summary>
584
+ <content type="application/vnd.ctct+xml">
585
+ <ContactList xmlns="http://ws.constantcontact.com/ns/1.0/">
586
+
587
+ end;
588
+
589
+ foreach ($data as $key => $val)
590
+ $post .= "\t\t\t<$key>{$val}</$key>\n";
591
+
592
+ $post .= <<<end
593
+ </ContactList>
594
+ </content>
595
+ </entry>
596
+ end;
597
+
598
+
599
+ $url= $this->api['url'].'lists';
600
+
601
+ $response = Array();
602
+ $response = $this->fetch($url,$post);
603
+ if ($this->debug['last_response'] <= 204)
604
+ return $this->id_from_url($response['entry']['id']['value']);
605
+ else
606
+ return false;
607
+ }
608
+
609
+ /**
610
+ * Returns detailed info for a particular list.
611
+ *
612
+ * @param Integer $id - ListID of the list requested.
613
+ * @return Associative array containing the list's details
614
+ */
615
+ public function get_list($id)
616
+ {
617
+ $url = $this->api['url'].'lists/'.$id;
618
+ $post = '';
619
+ $list = Array();
620
+ $list = $this->format_list($this->fetch($url,$post));
621
+
622
+ if ($this->debug['last_response'] <= 204)
623
+ return $list;
624
+ else
625
+ return false;
626
+ }
627
+
628
+ /**
629
+ * Edit a list
630
+ * See List Data Format at http://developer.constantcontact.com/doc/contactLists for all fields
631
+ *
632
+ * @param Integer $id - List ID of the list to edit
633
+ * @param Array $data - An associative array containing all the list data to edit
634
+ * @return Boolean - True on success and false on failure
635
+ */
636
+ public function edit_list($id,$data)
637
+ {
638
+ //Get the old xml from get_list() and then post after replacing values that need replacing
639
+ $url = $this->api['url'].'lists/'.$id;
640
+ $post = '';
641
+ $post = $this->fetch($url,$post,'xml');
642
+
643
+ foreach ($data as $key => $val)
644
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
645
+
646
+ $this->fetch($url,$post,'array','PUT');
647
+
648
+ if ($this->debug['last_response'] <= 204)
649
+ return true;
650
+ else
651
+ return false;
652
+ }
653
+
654
+ /**
655
+ * Return your lists.
656
+ *
657
+ * @param String $key - Optionally specify a key to use for the array
658
+ * @param Boolean $unique - Whether the key you specified is unique
659
+ * @return Associative array containing your lists indexed by whatever key specified.
660
+ */
661
+ public function get_lists($key='',$unique=true)
662
+ {
663
+ $ret = Array();
664
+
665
+ $url = $this->api['url'].'lists';
666
+ $post = '';
667
+ $response = Array();
668
+ $response = $this->fetch($url,$post);
669
+
670
+ $entries = Array();
671
+ if (isset($response['feed']['entry']['link']))
672
+ $entries[] = $response['feed']['entry'];
673
+ else
674
+ $entries = $response['feed']['entry'];
675
+ foreach ($entries as $data)
676
+ {
677
+ $my_data = Array();
678
+ $my_data = $data['content']['ContactList'];
679
+ $d = Array();
680
+ //$d['ListID'] = $this->id_from_url($my_data['attr']['id']);
681
+ $d['ListID'] = $my_data['attr']['id'];
682
+
683
+ // Exclude the default lists like active, do-not-mail and removed
684
+ if ( ! is_numeric($this->id_from_url($my_data['attr']['id'])) )
685
+ continue;
686
+
687
+ unset($my_data['attr']);
688
+ foreach ($my_data as $dkey => $dval)
689
+ {
690
+ if ( isset($dval['value']) )
691
+ $d[$dkey] = $dval['value'];
692
+ }
693
+
694
+ if ($key)
695
+ {
696
+ if ($unique)
697
+ $ret[$d[$key]] = $d;
698
+ else
699
+ $ret[$d[$key]][] = $d;
700
+ }
701
+ else
702
+ $ret[] = $d;
703
+ }
704
+ return $ret;
705
+ }
706
+
707
+ /**
708
+ * Delete a list
709
+ *
710
+ * @param Integer $id - ListID of the list to delete
711
+ * @return Boolean - True on success and false on failure
712
+ */
713
+ public function delete_list($id)
714
+ {
715
+ //Get the old xml from get_list() and then post after replacing values that need replacing
716
+ $url = $this->api['url'].'lists/'.$id;
717
+ $post = '';
718
+ $this->fetch($url,$post,'array','DELETE');
719
+
720
+ if ($this->debug['last_response'] <= 204)
721
+ return true;
722
+ else
723
+ return false;
724
+ }
725
+
726
+ //Subscription Functions
727
+
728
+ /**
729
+ * Add a subscription for an existing contact to a list
730
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
731
+ *
732
+ * @param Integer $contact_id - Contact ID of the contact to use
733
+ * @param Integer $list_id - List ID of the list to add the contact to
734
+ * @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
735
+ * @return Boolean - True on success and false on failure
736
+ */
737
+ public function add_subscription($contact_id,$list_id,$optin_source='ACTION_BY_CUSTOMER')
738
+ {
739
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
740
+ $url = $this->api['url'].'contacts/'.$contact_id;
741
+ $post = '';
742
+ $post = $this->fetch($url,$post,'xml');
743
+
744
+ if (!strstr($post,'</ContactLists>'))
745
+ $post = str_replace('</Contact>',"<ContactLists></ContactLists></Contact>",$post);
746
+
747
+ if (!strstr($post,'<OptInSource>'))
748
+ $post = str_replace('</Confirmed>',"</Confirmed>\n<OptInSource>$optin_source</OptInSource>",$post);
749
+
750
+ if (!strstr($post,'<ContactList id="'.$this->api['inner_url'].'lists/'.$list_id.'">'))
751
+ $post = str_replace('</ContactLists>','<ContactList id="'.$this->api['inner_url'].'lists/'.$list_id.'"></ContactList></ContactLists>',$post);
752
+
753
+ $this->fetch($url,$post,'array','PUT');
754
+
755
+ if ($this->debug['last_response'] <= 204)
756
+ return true;
757
+ else
758
+ return false;
759
+ }
760
+
761
+ /**
762
+ * Remove a subscription for an existing contact to a list
763
+ * See Contact Data Format at http://developer.constantcontact.com/doc/contactCollection for all fields
764
+ *
765
+ * @param Integer $contact_id - Contact ID of the contact to use
766
+ * @param Integer $list_id - List ID of the list to add the contact to
767
+ * @return Boolean - True on success and false on failure
768
+ */
769
+ public function remove_subscription($contact_id,$list_id)
770
+ {
771
+ //Get the old xml from get_contact() and then post after replacing values that need replacing
772
+ $url = $this->api['url'].'contacts/'.$contact_id;
773
+ $post = '';
774
+ $post = $this->fetch($url,$post,'xml');
775
+
776
+ $post = preg_replace('/<ContactList id="'.str_replace('/','\/',$this->api['inner_url']).'lists\/'.$list_id.'">.*?<\/ContactList>/s','',$post);
777
+
778
+ $this->fetch($url,$post,'array','PUT');
779
+
780
+ if ($this->debug['last_response'] <= 204)
781
+ return true;
782
+ else
783
+ return false;
784
+ }
785
+
786
+ //Campaign Functions
787
+
788
+ /**
789
+ * Formats a campaign array into the format we always return as
790
+ * Note:
791
+ * I like to do this because the atom specification has so much extraneous data
792
+ * that I just don't care about it. This makes a sane array out of what is
793
+ * incredibly overcomplicated in my opinion.
794
+ *
795
+ * @param Array - Contact array as returned from fetch/xml_to_array
796
+ * @return Associative array in the format returned by this api
797
+ */
798
+ public function format_campaign($response)
799
+ {
800
+ $my_data = Array();
801
+ $my_data = $response['entry']['content']['Campaign'];
802
+ $d = Array();
803
+ $d['CampaignID'] = $this->id_from_url($my_data['attr']['id']);
804
+ $d['FromID'] = $this->id_from_url($my_data['FromEmail']['Email']['attr']['id']);
805
+ $d['FromEmail'] = $my_data['FromEmail']['EmailAddress']['value'];
806
+ unset($my_data['FromEmail']);
807
+ unset($my_data['ReplyToEmail']);
808
+
809
+ unset($my_data['attr']);
810
+ foreach ($my_data as $dkey => $dval)
811
+ {
812
+ if ($dkey != 'ContactLists')
813
+ $d[$dkey] = $dval['value'];
814
+ else
815
+ {
816
+ $entries = Array();
817
+ if (isset($dval['ContactList']['link']))
818
+ $entries[] = $dval['ContactList'];
819
+ else
820
+ $entries = $dval['ContactList'];
821
+
822
+ foreach ($entries as $entry)
823
+ {
824
+ $e = Array();
825
+ $e['ListID'] = $this->id_from_url($entry['attr']['id']);
826
+ unset($entry['attr']);
827
+ unset($entry['link']);
828
+ foreach ($entry as $ekey => $eval)
829
+ $e[$ekey] = $eval['value'];
830
+ $d[$dkey][] = $e;
831
+ }
832
+ }
833
+ }
834
+ return $d;
835
+ }
836
+
837
+ /**
838
+ * Return your campaigns.
839
+ *
840
+ * @param String $key - Optionally specify a key to use for the array
841
+ * @param Boolean $unique - Whether the key you specified is unique
842
+ * @return Associative array containing your lists indexed by whatever key specified.
843
+ */
844
+ public function get_campaigns($key='',$unique=true)
845
+ {
846
+ $ret = Array();
847
+
848
+ $url = $this->api['url'].'campaigns';
849
+ $post = '';
850
+ $response = Array();
851
+ $response = $this->fetch($url,$post);
852
+
853
+ $entries = Array();
854
+ if (isset($response['feed']['entry']['link']))
855
+ $entries[] = $response['feed']['entry'];
856
+ else
857
+ $entries = $response['feed']['entry'];
858
+ foreach ($entries as $data)
859
+ {
860
+ $my_data = Array();
861
+ $my_data = $data['content']['Campaign'];
862
+ $d = Array();
863
+ $d['CampaignID'] = $this->id_from_url($my_data['attr']['id']);
864
+ unset($my_data['attr']);
865
+ foreach ($my_data as $dkey => $dval)
866
+ $d[$dkey] = $dval['value'];
867
+
868
+ if ($key)
869
+ {
870
+ if ($unique)
871
+ $ret[$d[$key]] = $d;
872
+ else
873
+ $ret[$d[$key]][] = $d;
874
+ }
875
+ else
876
+ $ret[] = $d;
877
+ }
878
+ return $ret;
879
+ }
880
+
881
+ /**
882
+ * Add a campaign
883
+ * See Campaign Data Format at http://developer.constantcontact.com/doc/manageCampaigns for all fields
884
+ *
885
+ * @param Array $data - An associative array containing all the campaign data to add
886
+ * @param Array $lists - An array of ListIDs to have this campaign send to
887
+ * @param Array $from_id - FromID to use as the from email address
888
+ * @return Integer - CampaignID for the new entry
889
+ */
890
+ public function add_campaign($data,$lists,$from_id)
891
+ {
892
+ $updated = date('Y-m-d\TH:i:s\Z');
893
+ $post = <<<end
894
+ <entry xmlns="http://www.w3.org/2005/Atom">
895
+ <link href="{$this->api['relative_url']}campaigns" rel="edit" />
896
+ <id>{$this->api['inner_url']}campaigns</id>
897
+ <title type="text">{$data['Name']}</title>
898
+ <updated>{$updated}</updated>
899
+ <author>
900
+ <name>Constant Contact</name>
901
+ </author>
902
+ <content type="application/vnd.ctct+xml">
903
+ <Campaign xmlns="http://ws.constantcontact.com/ns/1.0/" id="{$this->api['inner_url']}campaigns/">
904
+
905
+ end;
906
+
907
+ foreach ($data as $key => $val)
908
+ {
909
+ if ($key == 'Date')
910
+ $val = date('Y-m-d\TH:i:s\Z',strtotime($val)+date("Z"));
911
+ elseif ($key == 'EmailContent' || $key == 'StyleSheet' || $key == 'PermissionReminderText')
912
+ $val = urlencode($val);
913
+ elseif ($key == 'TextContent')
914
+ $val = urlencode('<Text>'.$val.'</Text>');
915
+
916
+ $post .= "\t\t\t<$key>{$val}</$key>\n";
917
+ }
918
+
919
+ $post .= "\t\t\t<ContactLists>\n";
920
+ foreach ($lists as $list_id)
921
+ $post .= "\t\t\t\t<ContactList id=\"{$this->api['inner_url']}lists/{$list_id}\" />\n";
922
+
923
+ $temp = Array();
924
+ $temp = get_from($from_id);
925
+ $email = $temp['EmailAddress'];
926
+
927
+ $post .= <<<end
928
+ </ContactLists>
929
+ <FromEmail>
930
+ <Email id="{$this->api['inner_url']}emailaddresses/$from_id">
931
+ <link xmlns="http://www.w3.org/2005/Atom" href="{$this->api['inner_url']}emailaddresses/$from_id" rel="self" />
932
+ </Email>
933
+ <EmailAddress>$email</EmailAddress>
934
+ </FromEmail>
935
+ <ReplyToEmail>
936
+ <Email id="{$this->api['inner_url']}emailaddresses/$from_id">
937
+ <link xmlns="http://www.w3.org/2005/Atom" href="{$this->api['inner_url']}emailaddresses/$from_id" rel="self" />
938
+ </Email>
939
+ <EmailAddress>$email</EmailAddress>
940
+ </ReplyToEmail>
941
+
942
+ end;
943
+
944
+ $post .= <<<end
945
+ </Campaign>
946
+ </content>
947
+ </entry>
948
+ end;
949
+
950
+
951
+ $url= $this->api['url'].'contacts';
952
+
953
+ $response = Array();
954
+ $response = $this->fetch($url,$post);
955
+ if ($this->debug['last_response'] <= 204)
956
+ return $this->id_from_url($response['entry']['id']['value']);
957
+ else
958
+ return false;
959
+ }
960
+
961
+ /**
962
+ * Returns detailed info for a particular campaign.
963
+ *
964
+ * @param Integer $id - Campaign ID of the campaign requested.
965
+ * @return Associative array containing the campaign's details
966
+ */
967
+ public function get_campaign($id)
968
+ {
969
+ $url = $this->api['url'].'campaigns/'.$id;
970
+ $post = '';
971
+ $campaign = Array();
972
+ $campaign = $this->format_campaign($this->fetch($url,$post));
973
+
974
+ if ($this->debug['last_response'] <= 204)
975
+ return $campaign;
976
+ else
977
+ return false;
978
+ }
979
+
980
+ /**
981
+ * Edit a campaign
982
+ * See Campaign Data Format at http://developer.constantcontact.com/doc/manageCampaigns for all fields
983
+ *
984
+ * @param Integer $id - Campaign ID of the list to edit
985
+ * @param Array $data - An associative array containing all the campaign data to edit
986
+ * @return Boolean - True on success and false on failure
987
+ */
988
+ public function edit_campaign($id,$data)
989
+ {
990
+ //Get the old xml from get_campaign() and then post after replacing values that need replacing
991
+ $url = $this->api['url'].'campaigns/'.$id;
992
+ $post = '';
993
+ $post = $this->fetch($url,$post,'xml');
994
+
995
+ foreach ($data as $key => $val)
996
+ $post = preg_replace("/<$key>.*?<\/{$key}>/s","<$key>$val</$key>",$post);
997
+
998
+ $this->fetch($url,$post,'array','PUT');
999
+
1000
+ if ($this->debug['last_response'] <= 204)
1001
+ return true;
1002
+ else
1003
+ return false;
1004
+ }
1005
+
1006
+ /**
1007
+ * Delete a campaign
1008
+ *
1009
+ * @param Integer $id - CampaignID of the list to delete
1010
+ * @return Boolean - True on success and false on failure
1011
+ */
1012
+ public function delete_campaign($id)
1013
+ {
1014
+ //Get the old xml from get_campaign() and then post after replacing values that need replacing
1015
+ $url = $this->api['url'].'campaigns/'.$id;
1016
+ $post = '';
1017
+ $this->fetch($url,$post,'array','DELETE');
1018
+
1019
+ if ($this->debug['last_response'] <= 204)
1020
+ return true;
1021
+ else
1022
+ return false;
1023
+ }
1024
+
1025
+ //From Functions
1026
+
1027
+ /**
1028
+ * Formats a list array into the format we always return as
1029
+ * Note:
1030
+ * I like to do this because the atom specification has so much extraneous data
1031
+ * that I just don't care about. This makes a sane array out of what is
1032
+ * incredibly overcomplicated in my opinion.
1033
+ *
1034
+ * @param Array - Contact array as returned from fetch/xml_to_array
1035
+ * @return Associative array in the format returned by this api
1036
+ */
1037
+ public function format_from($response)
1038
+ {
1039
+ $my_data = Array();
1040
+ $my_data = $response['entry']['content']['Email'];
1041
+ $d = Array();
1042
+ $d['FromID'] = $this->id_from_url($my_data['attr']['id']);
1043
+ unset($my_data['attr']);
1044
+ foreach ($my_data as $key => $val)
1045
+ $d[$key] = $val['value'];
1046
+ return $d;
1047
+ }
1048
+
1049
+ /**
1050
+ * Returns detailed info for a particular list.
1051
+ *
1052
+ * @param Integer $id - FromID of the from email requested.
1053
+ * @return Associative array containing the from's details
1054
+ */
1055
+ public function get_from($id)
1056
+ {
1057
+ $url = $this->api['url'].'settings/emailaddresses/'.$id;
1058
+ $post = '';
1059
+ $from = Array();
1060
+ $from = $this->format_from($this->fetch($url,$post));
1061
+
1062
+ if ($this->debug['last_response'] <= 204)
1063
+ return $from;
1064
+ else
1065
+ return false;
1066
+ }
1067
+
1068
+ /**
1069
+ * Return your from email addresses.
1070
+ *
1071
+ * @param String $key - Optionally specify a key to use for the array
1072
+ * @param Boolean $unique - Whether the key you specified is unique
1073
+ * @return Associative array containing your lists indexed by whatever key specified.
1074
+ */
1075
+ public function get_froms($key='',$unique=true)
1076
+ {
1077
+ $ret = Array();
1078
+
1079
+ $url = $this->api['url'].'settings/emailaddresses';
1080
+ $post = '';
1081
+ $response = Array();
1082
+ $response = $this->fetch($url,$post);
1083
+
1084
+ $entries = Array();
1085
+ if (isset($response['feed']['entry']['link']))
1086
+ $entries[] = $response['feed']['entry'];
1087
+ else
1088
+ $entries = $response['feed']['entry'];
1089
+ foreach ($entries as $data)
1090
+ {
1091
+ $my_data = Array();
1092
+ $my_data = $data['content']['Email'];
1093
+ $d = Array();
1094
+ $d['FromID'] = $this->id_from_url($my_data['attr']['id']);
1095
+ unset($my_data['attr']);
1096
+ foreach ($my_data as $dkey => $dval)
1097
+ $d[$dkey] = $dval['value'];
1098
+
1099
+ if ($key)
1100
+ {
1101
+ if ($unique)
1102
+ $ret[$d[$key]] = $d;
1103
+ else
1104
+ $ret[$d[$key]][] = $d;
1105
+ }
1106
+ else
1107
+ $ret[] = $d;
1108
+ }
1109
+ return $ret;
1110
+ }
1111
+
1112
+ }
1113
+
1114
+ ?>
power-ups/contacts.php CHANGED
@@ -40,6 +40,7 @@ require_once(LEADIN_CONTACTS_PLUGIN_DIR . '/admin/contacts-admin.php');
40
  class WPLeadInContacts extends WPLeadIn {
41
 
42
  var $admin;
 
43
 
44
  /**
45
  * Class constructor
40
  class WPLeadInContacts extends WPLeadIn {
41
 
42
  var $admin;
43
+ var $options;
44
 
45
  /**
46
  * Class constructor
power-ups/contacts/admin/contacts-admin.php CHANGED
@@ -99,11 +99,17 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
99
  $li_contact->get_contact_history();
100
 
101
  $lead_email = $li_contact->history->lead->lead_email;
 
 
 
 
 
 
 
102
 
103
- echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts">&larr; All Contacts</a>';
104
 
105
  echo '<div class="header-wrap">';
106
- echo '<img height="40px" width="40px" src="https://app.getsignals.com/avatar/image/?emails=' . $lead_email . '" />';
107
  echo '<h1 class="contact-name">' . $lead_email . '</h1>';
108
  echo '</div>';
109
 
@@ -152,7 +158,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
152
 
153
  echo '<li class="event pageview">';
154
  echo '<p class="event-title">' . $pageview['pageview_title'] . '<span class="event-time-range">' . date('g:ia', strtotime($pageview['event_date'])) . '</span></p>';
155
- echo '<a class="pageview-url" href="' . $pageview['pageview_url'] . '">' . $pageview['pageview_url'] . '</a>';
156
  echo '</li>';
157
  }
158
  else if ( $event['event_type'] == 'form' )
@@ -276,13 +282,13 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
276
  $q = $wpdb->prepare("SELECT hashkey FROM li_leads WHERE lead_id = %d", $lead_id);
277
  $lead_hash = $wpdb->get_var($q);
278
 
279
- $q = $wpdb->prepare("DELETE FROM li_pageviews WHERE lead_hashkey = %s", $lead_hash);
280
  $delete_pageviews = $wpdb->query($q);
281
 
282
- $q = $wpdb->prepare("DELETE FROM li_submissions WHERE lead_hashkey = %s", $lead_hash);
283
  $delete_submissions = $wpdb->query($q);
284
 
285
- $q = $wpdb->prepare("DELETE FROM li_leads WHERE lead_id = %d", $lead_id);
286
  $delete_lead = $wpdb->query($q);
287
 
288
  return $delete_lead;
@@ -300,10 +306,13 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
300
  {
301
  global $pagenow;
302
 
303
- if ( $pagenow == 'admin.php' && isset($_GET['page']) && strstr($_GET['page'], "leadin") )
304
  {
305
  wp_register_script('leadin-admin-js', LEADIN_PATH . '/admin/js/leadin-admin.js', array ( 'jquery' ), FALSE, TRUE);
306
  wp_enqueue_script('leadin-admin-js');
 
 
 
307
  }
308
  }
309
 
99
  $li_contact->get_contact_history();
100
 
101
  $lead_email = $li_contact->history->lead->lead_email;
102
+ $url_parts = parse_url($lead->lead_source);
103
+ $lead_source = urldecode(rtrim($url_parts['host'] . '/' . $url_parts['path'], '/'));
104
+
105
+ if ( isset($_GET['post_id']) )
106
+ echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/post.php?post=' . $_GET['post_id'] . '&action=edit#li_analytics-meta">&larr; All Viewers</a>';
107
+ else
108
+ echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts">&larr; All Contacts</a>';
109
 
 
110
 
111
  echo '<div class="header-wrap">';
112
+ echo '<img height="40px" width="40px" src="https://app.getsignals.com/avatar/image/?emails=' . $lead_email . '" class="leadin-dynamic-avatar_' . substr($lead_id, -1) . '"/>';
113
  echo '<h1 class="contact-name">' . $lead_email . '</h1>';
114
  echo '</div>';
115
 
158
 
159
  echo '<li class="event pageview">';
160
  echo '<p class="event-title">' . $pageview['pageview_title'] . '<span class="event-time-range">' . date('g:ia', strtotime($pageview['event_date'])) . '</span></p>';
161
+ echo '<a class="pageview-url" target="_blank" href="' . $pageview['pageview_url'] . '">' . $pageview['pageview_url'] . '</a>';
162
  echo '</li>';
163
  }
164
  else if ( $event['event_type'] == 'form' )
282
  $q = $wpdb->prepare("SELECT hashkey FROM li_leads WHERE lead_id = %d", $lead_id);
283
  $lead_hash = $wpdb->get_var($q);
284
 
285
+ $q = $wpdb->prepare("UPDATE li_pageviews SET pageview_deleted = 1 WHERE lead_hashkey = %s AND pageview_deleted = 0", $lead_hash);
286
  $delete_pageviews = $wpdb->query($q);
287
 
288
+ $q = $wpdb->prepare("UPDATE li_submissions SET form_deleted = 1 WHERE lead_hashkey = %s AND form_deleted = 0", $lead_hash);
289
  $delete_submissions = $wpdb->query($q);
290
 
291
+ $q = $wpdb->prepare("UPDATE li_leads SET lead_deleted = 1 WHERE lead_id = %d AND lead_deleted = 0", $lead_id);
292
  $delete_lead = $wpdb->query($q);
293
 
294
  return $delete_lead;
306
  {
307
  global $pagenow;
308
 
309
+ if ( ($pagenow == 'admin.php' && isset($_GET['page']) && strstr($_GET['page'], 'leadin')) || ( $pagenow == 'post.php' && isset($_GET['post']) && isset($_GET['action']) && strstr($_GET['action'], 'edit') ) )
310
  {
311
  wp_register_script('leadin-admin-js', LEADIN_PATH . '/admin/js/leadin-admin.js', array ( 'jquery' ), FALSE, TRUE);
312
  wp_enqueue_script('leadin-admin-js');
313
+
314
+ wp_register_script('lazyload-js', LEADIN_PATH . '/admin/js/jquery.lazyload.min.js', array ( 'jquery' ), FALSE, TRUE);
315
+ wp_enqueue_script('lazyload-js');
316
  }
317
  }
318
 
power-ups/mailchimp-list-sync.php CHANGED
@@ -39,6 +39,7 @@ require_once(LEADIN_MAILCHIMP_LIST_SYNC_PLUGIN_DIR . '/inc/MailChimp-API.php');
39
  class WPMailChimpListSync extends WPLeadIn {
40
 
41
  var $admin;
 
42
 
43
  /**
44
  * Class constructor
@@ -54,7 +55,7 @@ class WPMailChimpListSync extends WPLeadIn {
54
 
55
  global $leadin_mailchimp_list_sync_wp;
56
  $leadin_mailchimp_list_sync_wp = $this;
57
-
58
  }
59
 
60
  public function admin_init ( )
@@ -69,30 +70,20 @@ class WPMailChimpListSync extends WPLeadIn {
69
  }
70
 
71
  /**
72
- * Activate the power-up
73
  */
74
- function add_leadin_subscribe_defaults ()
75
  {
76
- $lis_options = get_option('leadin_subscribe_options');
77
-
78
- if ( ($lis_options['li_susbscibe_installed'] != 1) || (!is_array($lis_options)) )
79
- {
80
- $opt = array(
81
- 'li_susbscibe_installed' => '1',
82
- 'li_subscribe_heading' => 'Sign up for my newsletter to get new posts by email'
83
- );
84
 
85
- update_option('leadin_subscribe_options', $opt);
86
- }
87
  }
88
 
89
  function push_mailchimp_subscriber_to_list ( $email = '', $first_name = '', $last_name = '', $phone = '' )
90
  {
91
- $options = get_option('leadin_mls_options');
92
 
93
  if ( isset($options['li_mls_api_key']) && $options['li_mls_api_key'] && isset($options['li_mls_subscribers_to_list']) && $options['li_mls_subscribers_to_list'] )
94
  {
95
- $MailChimp = new MailChimp($options['li_mls_api_key']);
96
 
97
  $subscribe = $MailChimp->call("lists/subscribe", array(
98
  "id" => $options['li_mls_subscribers_to_list'],
39
  class WPMailChimpListSync extends WPLeadIn {
40
 
41
  var $admin;
42
+ var $options;
43
 
44
  /**
45
  * Class constructor
55
 
56
  global $leadin_mailchimp_list_sync_wp;
57
  $leadin_mailchimp_list_sync_wp = $this;
58
+ $this->options = get_option('leadin_mls_options');
59
  }
60
 
61
  public function admin_init ( )
70
  }
71
 
72
  /**
73
+ * Activate the power-up and add the defaults
74
  */
75
+ function add_defaults ()
76
  {
 
 
 
 
 
 
 
 
77
 
 
 
78
  }
79
 
80
  function push_mailchimp_subscriber_to_list ( $email = '', $first_name = '', $last_name = '', $phone = '' )
81
  {
82
+ $options = $this->options;
83
 
84
  if ( isset($options['li_mls_api_key']) && $options['li_mls_api_key'] && isset($options['li_mls_subscribers_to_list']) && $options['li_mls_subscribers_to_list'] )
85
  {
86
+ $MailChimp = new LI_MailChimp($options['li_mls_api_key']);
87
 
88
  $subscribe = $MailChimp->call("lists/subscribe", array(
89
  "id" => $options['li_mls_subscribers_to_list'],
power-ups/mailchimp-list-sync/admin/mailchimp-list-sync-admin.php CHANGED
@@ -82,25 +82,26 @@ class WPMailChimpListSyncAdmin extends WPLeadInAdmin {
82
  function li_mls_subscribers_to_list_callback ()
83
  {
84
  $options = get_option('leadin_mls_options');
85
- $li_mls_subscribers_to_list = ( isset($options['li_mls_subscribers_to_list']) ? $options['li_mls_subscribers_to_list'] : '' ); // Get header from options, or show default
86
-
87
  $lists = $this->li_mls_get_mailchimp_lists($options['li_mls_api_key']);
88
 
89
  echo '<select id="li_mls_subscribers_to_list" name="leadin_mls_options[li_mls_subscribers_to_list]" ' . ( ! count($lists['data']) ? 'disabled' : '' ) . '>';
90
 
91
  if ( count($lists['data']) )
92
  {
 
 
93
  foreach ( $lists['data'] as $list )
94
  {
95
- $list_set = FALSE;
96
  if ( $list['id'] == $li_mls_subscribers_to_list && !$list_set )
97
  $list_set = TRUE;
98
 
99
  echo '<option ' . ( $list['id'] == $li_mls_subscribers_to_list ? 'selected' : '' ) . ' value="' . $list['id'] . '">' . $list['name'] . '</option>';
100
-
101
- if ( !$list_set )
102
- echo '<option selected value="">No list set...</option>';
103
  }
 
 
 
104
  }
105
  else
106
  {
@@ -114,7 +115,7 @@ class WPMailChimpListSyncAdmin extends WPLeadInAdmin {
114
 
115
  function li_mls_get_mailchimp_lists ( $api_key )
116
  {
117
- $MailChimp = new MailChimp($api_key);
118
 
119
  $lists = $MailChimp->call("lists/list", array(
120
  "start" => 0, // optional, control paging of lists, start results at this list #, defaults to 1st page of data (page 0)
82
  function li_mls_subscribers_to_list_callback ()
83
  {
84
  $options = get_option('leadin_mls_options');
85
+ $li_mls_subscribers_to_list = ( isset($options['li_mls_subscribers_to_list']) ? $options['li_mls_subscribers_to_list'] : '' );
86
+
87
  $lists = $this->li_mls_get_mailchimp_lists($options['li_mls_api_key']);
88
 
89
  echo '<select id="li_mls_subscribers_to_list" name="leadin_mls_options[li_mls_subscribers_to_list]" ' . ( ! count($lists['data']) ? 'disabled' : '' ) . '>';
90
 
91
  if ( count($lists['data']) )
92
  {
93
+ $list_set = FALSE;
94
+
95
  foreach ( $lists['data'] as $list )
96
  {
 
97
  if ( $list['id'] == $li_mls_subscribers_to_list && !$list_set )
98
  $list_set = TRUE;
99
 
100
  echo '<option ' . ( $list['id'] == $li_mls_subscribers_to_list ? 'selected' : '' ) . ' value="' . $list['id'] . '">' . $list['name'] . '</option>';
 
 
 
101
  }
102
+
103
+ if ( !$list_set )
104
+ echo '<option selected value="">No list set...</option>';
105
  }
106
  else
107
  {
115
 
116
  function li_mls_get_mailchimp_lists ( $api_key )
117
  {
118
+ $MailChimp = new LI_MailChimp($api_key);
119
 
120
  $lists = $MailChimp->call("lists/list", array(
121
  "start" => 0, // optional, control paging of lists, start results at this list #, defaults to 1st page of data (page 0)
power-ups/mailchimp-list-sync/inc/MailChimp-API.php CHANGED
@@ -14,7 +14,7 @@
14
  * @author Drew McLellan <drew.mclellan@gmail.com>
15
  * @version 1.1.1
16
  */
17
- class MailChimp
18
  {
19
  private $api_key;
20
  private $api_endpoint = 'https://<dc>.api.mailchimp.com/2.0';
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';
power-ups/subscribe-widget.php CHANGED
@@ -38,6 +38,7 @@ require_once(LEADIN_SUBSCRIBE_WIDGET_PLUGIN_DIR . '/admin/subscribe-widget-admin
38
  class WPLeadInSubscribe extends WPLeadIn {
39
 
40
  var $admin;
 
41
 
42
  /**
43
  * Class constructor
@@ -51,9 +52,14 @@ class WPLeadInSubscribe extends WPLeadIn {
51
  if ( ! $activated )
52
  return false;
53
 
54
- add_filter('init', array($this, 'add_leadin_subscribe_frontend_scripts_and_styles'));
55
-
56
  add_action('get_footer', array(&$this, 'append_leadin_subscribe_settings'));
 
 
 
 
 
 
57
  }
58
 
59
  public function admin_init ( )
@@ -68,19 +74,26 @@ class WPLeadInSubscribe extends WPLeadIn {
68
  }
69
 
70
  /**
71
- * Activate the power-up
72
  */
73
- function add_leadin_subscribe_defaults ()
74
  {
75
- $lis_options = get_option('leadin_subscribe_options');
76
 
77
- if ( ($lis_options['li_susbscibe_installed'] != 1) || (!is_array($lis_options)) )
78
  {
 
79
  $opt = array(
80
- 'li_susbscibe_installed' => '1',
81
- 'li_subscribe_vex_class' => 'vex-theme-bottom-right-corner',
82
- 'li_subscribe_heading' => 'Sign up for my newsletter to get new posts by email',
83
- 'li_subscribe_btn_label' => 'SUBSCRIBE'
 
 
 
 
 
 
84
 
85
  );
86
 
@@ -91,16 +104,17 @@ class WPLeadInSubscribe extends WPLeadIn {
91
  /**
92
  * Adds a hidden input at the end of the content containing the ouput of the location, heading, and button text options
93
  *
94
- * @return
95
  */
96
  function append_leadin_subscribe_settings ()
97
  {
98
- $lis_options = get_option('leadin_subscribe_options');
99
 
100
- // Heading for the subscribe plugin
101
- echo '<input id="leadin-subscribe-vex-class" value="' . ( isset($lis_options['li_subscribe_vex_class']) ? $lis_options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' ) . '" type="hidden"/>';
102
- echo '<input id="leadin-subscribe-heading" value="' . ( isset($lis_options['li_subscribe_heading']) ? $lis_options['li_subscribe_heading'] : 'Sign up for my newsletter to get new posts by email' ) . '" type="hidden"/>';
103
- echo '<input id="leadin-subscribe-btn-label" value="' . ( isset($lis_options['li_subscribe_btn_label']) ? $lis_options['li_subscribe_btn_label'] : 'SUBSCRIBE' ) . '" type="hidden"/>';
 
 
104
 
105
  // Div checked by media query for mobile
106
  echo '<span id="leadin-subscribe-mobile-check"></span>';
@@ -117,7 +131,29 @@ class WPLeadInSubscribe extends WPLeadIn {
117
  {
118
  global $pagenow;
119
 
120
- if ( !is_admin() && $pagenow != 'wp-login.php' )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  {
122
  wp_register_script('leadin-subscribe', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/js/leadin-subscribe.js', array ('jquery', 'leadin'), false, true);
123
  wp_register_script('vex', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/js/vex.js', array ('jquery', 'leadin'), false, true);
@@ -129,11 +165,6 @@ class WPLeadInSubscribe extends WPLeadIn {
129
 
130
  wp_register_style('leadin-subscribe-vex-css', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/css/vex.css');
131
  wp_enqueue_style('leadin-subscribe-vex-css');
132
-
133
- wp_register_style('leadin-subscribe', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/css/leadin-subscribe.css');
134
- wp_enqueue_style('leadin-subscribe');
135
-
136
- //wp_localize_script('leadin', 'li_ajax', array('ajax_url' => admin_url('admin-ajax.php')));
137
  }
138
  }
139
  }
38
  class WPLeadInSubscribe extends WPLeadIn {
39
 
40
  var $admin;
41
+ var $options;
42
 
43
  /**
44
  * Class constructor
52
  if ( ! $activated )
53
  return false;
54
 
55
+ add_filter('loop_end', array($this, 'add_leadin_subscribe_frontend_scripts_and_styles'));
 
56
  add_action('get_footer', array(&$this, 'append_leadin_subscribe_settings'));
57
+ $this->options = get_option('leadin_subscribe_options');
58
+
59
+ if ( ($this->options['li_susbscibe_installed'] != 1) || (!is_array($this->options)) )
60
+ {
61
+ $this->add_defaults();
62
+ }
63
  }
64
 
65
  public function admin_init ( )
74
  }
75
 
76
  /**
77
+ * Activate the power-up and add the defaults
78
  */
79
+ function add_defaults ()
80
  {
81
+ $options = $this->options;
82
 
83
+ if ( ($options['li_susbscibe_installed'] != 1) || (!is_array($options)) )
84
  {
85
+ // conditionals below are a hack for not overwriting the users settings with defaults in 0.8.4
86
  $opt = array(
87
+ 'li_susbscibe_installed' => '1',
88
+ 'li_subscribe_vex_class' => ( isset($options['li_subscribe_vex_class']) ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner'),
89
+ 'li_subscribe_heading' => ( isset($options['li_subscribe_heading']) ? $options['li_subscribe_heading'] : 'Sign up for my newsletter to get new posts by email'),
90
+ 'li_subscribe_btn_label' => ( isset($options['li_subscribe_btn_label']) ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE'),
91
+ 'li_subscribe_name_fields' => ( isset($options['li_subscribe_name_fields']) ? $options['li_subscribe_name_fields'] : '0'),
92
+ 'li_subscribe_phone_field' => ( isset($options['li_subscribe_phone_field']) ? $options['li_subscribe_phone_field'] : '0'),
93
+ 'li_subscribe_template_posts' => '1',
94
+ 'li_subscribe_template_pages' => '1',
95
+ 'li_subscribe_template_archives' => '1',
96
+ 'li_subscribe_template_home' => '1'
97
 
98
  );
99
 
104
  /**
105
  * Adds a hidden input at the end of the content containing the ouput of the location, heading, and button text options
106
  *
 
107
  */
108
  function append_leadin_subscribe_settings ()
109
  {
110
+ $options = $this->options;
111
 
112
+ // Settings for the subscribe plugin injected into footer and pulled via jQuery on the front end
113
+ echo '<input id="leadin-subscribe-vex-class" value="' . ( isset($options['li_subscribe_vex_class']) ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' ) . '" type="hidden"/>';
114
+ echo '<input id="leadin-subscribe-heading" value="' . ( isset($options['li_subscribe_heading']) ? $options['li_subscribe_heading'] : 'Sign up for my newsletter to get new posts by email' ) . '" type="hidden"/>';
115
+ echo '<input id="leadin-subscribe-btn-label" value="' . ( isset($options['li_subscribe_btn_label']) ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE' ) . '" type="hidden"/>';
116
+ echo '<input id="leadin-subscribe-name-fields" value="' . ( isset($options['li_subscribe_name_fields']) ? $options['li_subscribe_name_fields'] : '0' ) . '" type="hidden"/>';
117
+ echo '<input id="leadin-subscribe-phone-field" value="' . ( isset($options['li_subscribe_phone_field']) ? $options['li_subscribe_phone_field'] : '0' ) . '" type="hidden"/>';
118
 
119
  // Div checked by media query for mobile
120
  echo '<span id="leadin-subscribe-mobile-check"></span>';
131
  {
132
  global $pagenow;
133
 
134
+ $options = $this->options;
135
+
136
+ // If none of the values are set it's safe to assume the user hasn't toggled any yet so we should default them all
137
+ if ( isset ($options['li_subscribe_template_posts']) || isset ($options['li_subscribe_template_pages']) || isset ($options['li_subscribe_template_archives']) || isset ($options['li_subscribe_template_home']) )
138
+ {
139
+ // disable pop-up on posts if setting not set
140
+ if ( is_single() && ! isset ($options['li_subscribe_template_posts']) )
141
+ return FALSE;
142
+
143
+ // disable pop-up on pages if setting not set
144
+ if ( is_page() && ! isset ($options['li_subscribe_template_pages']) )
145
+ return FALSE;
146
+
147
+ // disable pop-up on archives if setting not set
148
+ if ( is_archive() && ! isset ($options['li_subscribe_template_archives']) )
149
+ return FALSE;
150
+
151
+ // disable pop-up on homepage if setting not set
152
+ if ( $_SERVER["REQUEST_URI"] == '/' && ! isset ($options['li_subscribe_template_home']) )
153
+ return FALSE;
154
+ }
155
+
156
+ if ( ! is_admin() && $pagenow != 'wp-login.php' )
157
  {
158
  wp_register_script('leadin-subscribe', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/js/leadin-subscribe.js', array ('jquery', 'leadin'), false, true);
159
  wp_register_script('vex', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/js/vex.js', array ('jquery', 'leadin'), false, true);
165
 
166
  wp_register_style('leadin-subscribe-vex-css', LEADIN_SUBSCRIBE_WIDGET_PATH . '/frontend/css/vex.css');
167
  wp_enqueue_style('leadin-subscribe-vex-css');
 
 
 
 
 
168
  }
169
  }
170
  }
power-ups/subscribe-widget/admin/subscribe-widget-admin.php CHANGED
@@ -12,6 +12,7 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
12
 
13
  var $power_up_settings_section = 'leadin_subscribe_options_section';
14
  var $power_up_icon;
 
15
 
16
  /**
17
  * Class constructor
@@ -26,6 +27,7 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
26
  {
27
  $this->power_up_icon = '<span class="dashicons dashicons-email-alt"></span>';
28
  add_action('admin_init', array($this, 'leadin_subscribe_build_settings_page'));
 
29
  }
30
  }
31
 
@@ -40,10 +42,48 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
40
  {
41
  register_setting('leadin_settings_options', 'leadin_subscribe_options', array($this, 'sanitize'));
42
 
43
- add_settings_section($this->power_up_settings_section, $this->power_up_icon . 'Subscribe Pop-up', '', LEADIN_ADMIN_PATH);
44
- add_settings_field('li_subscribe_vex_class', 'Pop-up Location', array($this, 'li_subscribe_vex_class_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
45
- add_settings_field('li_subscribe_heading', 'Pop-up header text', array($this, 'li_subscribe_heading_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
46
- add_settings_field('li_subscribe_btn_label', 'Button text', array($this, 'li_subscribe_btn_label_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
  /**
@@ -55,6 +95,9 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
55
  {
56
  $new_input = array();
57
 
 
 
 
58
  if( isset( $input['li_subscribe_vex_class'] ) )
59
  $new_input['li_subscribe_vex_class'] = sanitize_text_field( $input['li_subscribe_vex_class'] );
60
 
@@ -64,20 +107,48 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
64
  if( isset( $input['li_subscribe_btn_label'] ) )
65
  $new_input['li_subscribe_btn_label'] = sanitize_text_field( $input['li_subscribe_btn_label'] );
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  return $new_input;
68
  }
69
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * Prints subscribe location input for settings page
72
  */
73
  function li_subscribe_vex_class_callback ()
74
  {
75
- $options = get_option('leadin_subscribe_options');
76
  $li_subscribe_vex_class = ( $options['li_subscribe_vex_class'] ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' ); // Get class from options, or show default
77
 
78
  echo '<select id="li_subscribe_vex_class" name="leadin_subscribe_options[li_subscribe_vex_class]">';
79
  echo '<option value="vex-theme-bottom-right-corner"' . ( $li_subscribe_vex_class == 'vex-theme-bottom-right-corner' ? ' selected' : '' ) . '>Bottom right</option>';
80
- echo '<option value="vex-theme-bottom-left-corner"' . ( $li_subscribe_vex_class == 'vex-theme-bottom-left-corner' ? ' selected' : '' ) . '>Bottom Left</option>';
81
  echo '<option value="vex-theme-top"' . ( $li_subscribe_vex_class == 'vex-theme-top' ? ' selected' : '' ) . '>Top</option>';
82
  echo '<option value="vex-theme-default"' . ( $li_subscribe_vex_class == 'vex-theme-default' ? ' selected' : '' ) . '>Pop-over content</option>';
83
  echo '</select>';
@@ -88,29 +159,86 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
88
  */
89
  function li_subscribe_heading_callback ()
90
  {
91
- $options = get_option('leadin_subscribe_options');
92
  $li_subscribe_heading = ( $options['li_subscribe_heading'] ? $options['li_subscribe_heading'] : 'Sign up for my newsletter to get new posts by email' ); // Get header from options, or show default
93
 
94
  printf(
95
- '<input id="li_subscribe_heading" type="text" id="title" name="leadin_subscribe_options[li_subscribe_heading]" value="%s" size="50"/>',
96
  $li_subscribe_heading
97
  );
98
  }
99
 
100
  /**
101
- * Prints subscribe heading text input for settings page
102
  */
103
  function li_subscribe_btn_label_callback ()
104
  {
105
- $options = get_option('leadin_subscribe_options');
106
  $li_subscribe_btn_label = ( $options['li_subscribe_btn_label'] ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE' ); // Get button text from options, or show default
107
 
108
  printf(
109
- '<input id="li_subscribe_btn_label" type="text" id="title" name="leadin_subscribe_options[li_subscribe_btn_label]" value="%s" size="50"/>',
110
  $li_subscribe_btn_label
111
  );
112
 
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
 
116
- ?>
12
 
13
  var $power_up_settings_section = 'leadin_subscribe_options_section';
14
  var $power_up_icon;
15
+ var $options;
16
 
17
  /**
18
  * Class constructor
27
  {
28
  $this->power_up_icon = '<span class="dashicons dashicons-email-alt"></span>';
29
  add_action('admin_init', array($this, 'leadin_subscribe_build_settings_page'));
30
+ $this->options = get_option('leadin_subscribe_options');
31
  }
32
  }
33
 
42
  {
43
  register_setting('leadin_settings_options', 'leadin_subscribe_options', array($this, 'sanitize'));
44
 
45
+ add_settings_section(
46
+ $this->power_up_settings_section,
47
+ $this->power_up_icon . 'Subscribe Pop-up',
48
+ array($this, 'print_hidden_settings_fields'),
49
+ LEADIN_ADMIN_PATH
50
+ );
51
+
52
+ add_settings_field(
53
+ 'li_subscribe_vex_class',
54
+ 'Pop-up Location',
55
+ array($this, 'li_subscribe_vex_class_callback'),
56
+ LEADIN_ADMIN_PATH,
57
+ $this->power_up_settings_section
58
+ );
59
+ add_settings_field(
60
+ 'li_subscribe_heading',
61
+ 'Pop-up header text',
62
+ array($this, 'li_subscribe_heading_callback'),
63
+ LEADIN_ADMIN_PATH,
64
+ $this->power_up_settings_section
65
+ );
66
+ add_settings_field(
67
+ 'li_subscribe_btn_label',
68
+ 'Button text',
69
+ array($this, 'li_subscribe_btn_label_callback'),
70
+ LEADIN_ADMIN_PATH,
71
+ $this->power_up_settings_section
72
+ );
73
+ add_settings_field(
74
+ 'li_subscribe_additional_fields',
75
+ 'Also include fields for',
76
+ array($this, 'li_subscribe_additional_fields_callback'),
77
+ LEADIN_ADMIN_PATH,
78
+ $this->power_up_settings_section
79
+ );
80
+ add_settings_field(
81
+ 'li_subscribe_templates',
82
+ 'Show subscribe pop-up on',
83
+ array($this, 'li_subscribe_templates_callback'),
84
+ LEADIN_ADMIN_PATH,
85
+ $this->power_up_settings_section
86
+ );
87
  }
88
 
89
  /**
95
  {
96
  $new_input = array();
97
 
98
+ if( isset( $input['li_susbscibe_installed'] ) )
99
+ $new_input['li_susbscibe_installed'] = sanitize_text_field( $input['li_susbscibe_installed'] );
100
+
101
  if( isset( $input['li_subscribe_vex_class'] ) )
102
  $new_input['li_subscribe_vex_class'] = sanitize_text_field( $input['li_subscribe_vex_class'] );
103
 
107
  if( isset( $input['li_subscribe_btn_label'] ) )
108
  $new_input['li_subscribe_btn_label'] = sanitize_text_field( $input['li_subscribe_btn_label'] );
109
 
110
+ if( isset( $input['li_subscribe_name_fields'] ) )
111
+ $new_input['li_subscribe_name_fields'] = sanitize_text_field( $input['li_subscribe_name_fields'] );
112
+
113
+ if( isset( $input['li_subscribe_phone_field'] ) )
114
+ $new_input['li_subscribe_phone_field'] = sanitize_text_field( $input['li_subscribe_phone_field'] );
115
+
116
+ if( isset( $input['li_subscribe_template_pages'] ) )
117
+ $new_input['li_subscribe_template_pages'] = sanitize_text_field( $input['li_subscribe_template_pages'] );
118
+
119
+ if( isset( $input['li_subscribe_template_posts'] ) )
120
+ $new_input['li_subscribe_template_posts'] = sanitize_text_field( $input['li_subscribe_template_posts'] );
121
+
122
+ if( isset( $input['li_subscribe_template_home'] ) )
123
+ $new_input['li_subscribe_template_home'] = sanitize_text_field( $input['li_subscribe_template_home'] );
124
+
125
+ if( isset( $input['li_subscribe_template_archives'] ) )
126
+ $new_input['li_subscribe_template_archives'] = sanitize_text_field( $input['li_subscribe_template_archives'] );
127
+
128
  return $new_input;
129
  }
130
 
131
+ function print_hidden_settings_fields ()
132
+ {
133
+ // Hacky solution to solve the Settings API overwriting the default values
134
+ $options = $this->options;
135
+ $li_susbscibe_installed = ( $options['li_susbscibe_installed'] ? $options['li_susbscibe_installed'] : 1 );
136
+
137
+ printf(
138
+ '<input id="li_susbscibe_installed" type="hidden" name="leadin_subscribe_options[li_susbscibe_installed]" value="%d"/>',
139
+ $li_susbscibe_installed
140
+ );
141
+ }
142
  /**
143
  * Prints subscribe location input for settings page
144
  */
145
  function li_subscribe_vex_class_callback ()
146
  {
 
147
  $li_subscribe_vex_class = ( $options['li_subscribe_vex_class'] ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' ); // Get class from options, or show default
148
 
149
  echo '<select id="li_subscribe_vex_class" name="leadin_subscribe_options[li_subscribe_vex_class]">';
150
  echo '<option value="vex-theme-bottom-right-corner"' . ( $li_subscribe_vex_class == 'vex-theme-bottom-right-corner' ? ' selected' : '' ) . '>Bottom right</option>';
151
+ echo '<option value="vex-theme-bottom-left-corner"' . ( $li_subscribe_vex_class == 'vex-theme-bottom-left-corner' ? ' selected' : '' ) . '>Bottom left</option>';
152
  echo '<option value="vex-theme-top"' . ( $li_subscribe_vex_class == 'vex-theme-top' ? ' selected' : '' ) . '>Top</option>';
153
  echo '<option value="vex-theme-default"' . ( $li_subscribe_vex_class == 'vex-theme-default' ? ' selected' : '' ) . '>Pop-over content</option>';
154
  echo '</select>';
159
  */
160
  function li_subscribe_heading_callback ()
161
  {
162
+ $options = $this->options;
163
  $li_subscribe_heading = ( $options['li_subscribe_heading'] ? $options['li_subscribe_heading'] : 'Sign up for my newsletter to get new posts by email' ); // Get header from options, or show default
164
 
165
  printf(
166
+ '<input id="li_subscribe_heading" type="text" name="leadin_subscribe_options[li_subscribe_heading]" value="%s" size="50"/>',
167
  $li_subscribe_heading
168
  );
169
  }
170
 
171
  /**
172
+ * Prints button label
173
  */
174
  function li_subscribe_btn_label_callback ()
175
  {
176
+ $options = $this->options;
177
  $li_subscribe_btn_label = ( $options['li_subscribe_btn_label'] ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE' ); // Get button text from options, or show default
178
 
179
  printf(
180
+ '<input id="li_subscribe_btn_label" type="text" name="leadin_subscribe_options[li_subscribe_btn_label]" value="%s" size="50"/>',
181
  $li_subscribe_btn_label
182
  );
183
 
184
  }
185
+
186
+ /**
187
+ * Prints additional fields for first name, last name and phone number
188
+ */
189
+ function li_subscribe_additional_fields_callback ()
190
+ {
191
+ $options = $this->options;
192
+ $li_subscribe_name_fields = ( $options['li_subscribe_name_fields'] ? $options['li_subscribe_name_fields'] : '0' ); // Get name field options from options, or show default
193
+ $li_subscribe_phone_field = ( $options['li_subscribe_phone_field'] ? $options['li_subscribe_phone_field'] : '0' ); // Get phone field preference from options, or show default
194
+
195
+ printf(
196
+ '<p><input id="li_subscribe_name_fields" type="checkbox" name="leadin_subscribe_options[li_subscribe_name_fields]" value="1"' . checked( 1, $options['li_subscribe_name_fields'], false ) . '/>' .
197
+ '<label for="li_subscribe_name_fields">First + last name</label></p>'
198
+ );
199
+
200
+ printf(
201
+ '<p><input id="li_subscribe_phone_field" type="checkbox" name="leadin_subscribe_options[li_subscribe_phone_field]" value="1"' . checked( 1, $options['li_subscribe_phone_field'], false ) . '/>' .
202
+ '<label for="li_subscribe_phone_field">Phone number</label></p>'
203
+ );
204
+ }
205
+
206
+ /**
207
+ * Prints the options for toggling the widget on posts, pages, archives and homepage
208
+ */
209
+ function li_subscribe_templates_callback ()
210
+ {
211
+ $options = $this->options;
212
+
213
+ // If none of the values are set it's safe to assume the user hasn't toggled any yet so we should default them all
214
+ if ( ! isset ($options['li_subscribe_template_posts']) && ! isset ($options['li_subscribe_template_pages']) && ! isset ($options['li_subscribe_template_archives']) && ! isset ($options['li_subscribe_template_home']) )
215
+ {
216
+ $options['li_subscribe_template_posts'] = 1;
217
+ $options['li_subscribe_template_pages'] = 1;
218
+ $options['li_subscribe_template_archives'] = 1;
219
+ $options['li_subscribe_template_home'] = 1;
220
+ }
221
+
222
+ printf(
223
+ '<p><input id="li_subscribe_template_posts" type="checkbox" name="leadin_subscribe_options[li_subscribe_template_posts]" value="1"' . checked( 1, $options['li_subscribe_template_posts'], false ) . '/>' .
224
+ '<label for="li_subscribe_template_posts">Posts</label></p>'
225
+ );
226
+
227
+ printf(
228
+ '<p><input id="li_subscribe_template_pages" type="checkbox" name="leadin_subscribe_options[li_subscribe_template_pages]" value="1"' . checked( 1, $options['li_subscribe_template_pages'], false ) . '/>' .
229
+ '<label for="li_subscribe_template_pages">Pages</label></p>'
230
+ );
231
+
232
+ printf(
233
+ '<p><input id="li_subscribe_template_archives" type="checkbox" name="leadin_subscribe_options[li_subscribe_template_archives]" value="1"' . checked( 1, $options['li_subscribe_template_archives'], false ) . '/>' .
234
+ '<label for="li_subscribe_template_archives">Archives</label></p>'
235
+ );
236
+
237
+ printf(
238
+ '<p><input id="li_subscribe_template_home" type="checkbox" name="leadin_subscribe_options[li_subscribe_template_home]" value="1"' . checked( 1, $options['li_subscribe_template_home'], false ) . '/>' .
239
+ '<label for="li_subscribe_template_home">Homepage</label></p>'
240
+ );
241
+ }
242
  }
243
 
244
+ ?>
power-ups/subscribe-widget/frontend/js/leadin-subscribe.js CHANGED
@@ -38,7 +38,7 @@ function bind_leadin_subscribe_widget ()
38
  if ($(window).scrollTop() + $(window).height() > $(document).height() / 2) {
39
  subscribe.open();
40
  } else {
41
- subscribe.close();
42
  }
43
  });
44
  };
@@ -52,15 +52,16 @@ function bind_leadin_subscribe_widget ()
52
  showCloseButton: true,
53
  className: 'leadin-subscribe ' + $('#leadin-subscribe-vex-class').val(),
54
  message: $('#leadin-subscribe-heading').val(),
55
- input: '' +
56
- '<input id="leadin-subscribe-email" name="email" type="email" placeholder="Email address" required />',
 
57
  buttons: [$.extend({}, vex.dialog.buttons.YES, { text: ( $('#leadin-subscribe-btn-label').val() ? $('#leadin-subscribe-btn-label').val() : 'SUBSCRIBE' ) })],
58
  onSubmit: function ( data )
59
  {
60
  $('.vex-dialog-form').fadeOut(300, function ( e ) {
61
  $('.vex-dialog-form').html(
62
  '<div class="vex-close"></div>' +
63
- '<h3>Thanks for Subscribing</h3>You should receive a confirmation email in your inbox shortly.' +
64
  '<div>' +
65
  '<span class="powered-by">Powered by LeadIn</span>' +
66
  '<a href="http://leadin.com/wordpress-subscribe-widget/?utm_campaign=subscribe_widget&utm_medium=email&utm_source=' + window.location.host + '"><img alt="LeadIn" height="20px" width="99px" src="http://leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png" alt="leadin.com"/></a>' +
@@ -81,7 +82,7 @@ function bind_leadin_subscribe_widget ()
81
  }
82
  });
83
 
84
- leadin_subscribe_show();
85
 
86
  $('.leadin-subscribe form.vex-dialog-form').append('<a href="http://leadin.com/pop-subscribe-form-plugin-wordpress/?utm_campaign=subscribe_widget&utm_medium=widget&utm_source=' + document.URL + '" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by LeadIn</a>');
87
  };
38
  if ($(window).scrollTop() + $(window).height() > $(document).height() / 2) {
39
  subscribe.open();
40
  } else {
41
+ //subscribe.close();
42
  }
43
  });
44
  };
52
  showCloseButton: true,
53
  className: 'leadin-subscribe ' + $('#leadin-subscribe-vex-class').val(),
54
  message: $('#leadin-subscribe-heading').val(),
55
+ input: '<input id="leadin-subscribe-email" name="email" type="email" placeholder="Email address" required />' +
56
+ (($('#leadin-subscribe-name-fields').val()==0) ? '' : '<input id="leadin-subscribe-fname" name="fname" type="text" placeholder="First Name" required /><input id="leadin-subscribe-lname" name="lname" type="text" placeholder="Last Name" required />') +
57
+ (($('#leadin-subscribe-phone-field').val()==0) ? '' : '<input id="leadin-subscribe-phone" name="phone" type="tel" placeholder="Phone" required />'),
58
  buttons: [$.extend({}, vex.dialog.buttons.YES, { text: ( $('#leadin-subscribe-btn-label').val() ? $('#leadin-subscribe-btn-label').val() : 'SUBSCRIBE' ) })],
59
  onSubmit: function ( data )
60
  {
61
  $('.vex-dialog-form').fadeOut(300, function ( e ) {
62
  $('.vex-dialog-form').html(
63
  '<div class="vex-close"></div>' +
64
+ '<h3>Thanks!<br>You should receive a confirmation email in your inbox shortly.</h3>' +
65
  '<div>' +
66
  '<span class="powered-by">Powered by LeadIn</span>' +
67
  '<a href="http://leadin.com/wordpress-subscribe-widget/?utm_campaign=subscribe_widget&utm_medium=email&utm_source=' + window.location.host + '"><img alt="LeadIn" height="20px" width="99px" src="http://leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png" alt="leadin.com"/></a>' +
82
  }
83
  });
84
 
85
+ //leadin_subscribe_show();
86
 
87
  $('.leadin-subscribe form.vex-dialog-form').append('<a href="http://leadin.com/pop-subscribe-form-plugin-wordpress/?utm_campaign=subscribe_widget&utm_medium=widget&utm_source=' + document.URL + '" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by LeadIn</a>');
88
  };
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: andygcook, nelsonjoyce
3
  Tags: lead tracking, visitor tracking, analytics, crm, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp
4
  Requires at least: 3.7
5
- Tested up to: 3.8.2
6
- Stable tag: 0.7.2
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
 
@@ -85,21 +85,73 @@ To ensure quality we've tested the most popular WordPress form builder plugins.
85
  1. Individual contact history
86
  2. Contacts list
87
  3. Sample email report
 
88
 
89
  == Changelog ==
90
 
91
- Current version: 0.7.2
92
- Current version release: 2014-04-18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  = 0.7.2 (2014.04.18) =
95
- -Bug fixes
96
  - Fix contact deletion bug
97
  - Implement data recovery fix for contacts
98
  - Bug fixes to contact merging
99
 
100
 
101
  = 0.7.1 (2014.04.11) =
102
- -Bug fixes
103
  - SVN bug fix that did not add the MailChimp List sync power-up
104
 
105
  = 0.7.0 (2014.04.10) =
2
  Contributors: andygcook, nelsonjoyce
3
  Tags: lead tracking, visitor tracking, analytics, crm, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp
4
  Requires at least: 3.7
5
+ Tested up to: 3.9.1
6
+ Stable tag: 0.9.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
 
85
  1. Individual contact history
86
  2. Contacts list
87
  3. Sample email report
88
+ 4. Pop-up subscribe widget
89
 
90
  == Changelog ==
91
 
92
+ - Current version: 0.9.0
93
+ - Current version release: 2014-05-12
94
+
95
+ = 0.9.0 (2014.05.12) =
96
+ - Bug fixes
97
+ - Remove leadin-css file enqueue call
98
+
99
+ = Enhancements =
100
+ - Show faces of people who viewed a post/page in the editor
101
+ - Add background color to avatars so they are easier to see
102
+ - Various UI fixes
103
+
104
+ = 0.8.5 (2014.05.08) =
105
+ - Bug fixes
106
+ - Fixed broken contact notification emails
107
+
108
+ = 0.8.4 (2014.05.07) =
109
+ - Bug fixes
110
+ - Fixed HTML encoding of apostrophes and special characters in the database for page titles
111
+
112
+ = Enhancements =
113
+ - Added ability to toggle subscribe widget on posts, pages, archives or the home page
114
+ - Sort contacts by last visit
115
+
116
+ = 0.8.3 (2014.05.06) =
117
+ - Bug fixes
118
+ - Merge duplicate contacts into one record
119
+ - Remove url parameters from source links in contact list
120
+ - Downgrade use of singletons so classes are compatabile with PHP 5.2
121
+
122
+ = Enhancements =
123
+ - Swap out delete statements in favor of binary "deleted" flags to minimize data loss risk
124
+ - Sort contacts by last visit
125
+
126
+ = 0.8.2 (2014.05.02) =
127
+ - Bug fixes
128
+ - Removed namespace usage in favor or a low-tech work around to be compliant with PHP 5.2 and lower
129
+
130
+ = 0.8.1 (2014.04.30) =
131
+ - Bug fixes
132
+ - Namespaced duplicate classes
133
+
134
+ = 0.8.0 (2014.04.30) =
135
+ - Bug fixes
136
+ - Fix scrolling issue with subscribe pop-up
137
+ - Duplicate class bug fixes
138
+
139
+ = Enhancements =
140
+ - Add optional first name, last name and phone fields for subscribe pop-up
141
+ - Change out contact notification emails to be from settings email address
142
+ - Ability to disable contact notification emails
143
+ - Constant Contact list sync power-up
144
+ - Sync optional contact fields (name + phone) to email service provider power-ups
145
 
146
  = 0.7.2 (2014.04.18) =
147
+ - Bug fixes
148
  - Fix contact deletion bug
149
  - Implement data recovery fix for contacts
150
  - Bug fixes to contact merging
151
 
152
 
153
  = 0.7.1 (2014.04.11) =
154
+ - Bug fixes
155
  - SVN bug fix that did not add the MailChimp List sync power-up
156
 
157
  = 0.7.0 (2014.04.10) =
screenshot-4.png ADDED
Binary file