Newsletter - Version 5.1.2

Version Description

Download this release

Release Info

Developer satollo
Plugin Icon 128x128 Newsletter
Version 5.1.2
Comparing to
See all releases

Code changes from version 5.1.1 to 5.1.2

Files changed (87) hide show
  1. admin.css +155 -271
  2. css/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  3. css/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  4. css/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  5. css/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  6. css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  7. css/jquery-ui/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  8. css/jquery-ui/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  9. css/jquery-ui/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  10. css/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  11. css/jquery-ui/images/ui-icons_0073ea_256x240.png +0 -0
  12. css/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
  13. css/jquery-ui/images/ui-icons_2e83ff_256x240.png +0 -0
  14. css/jquery-ui/images/ui-icons_454545_256x240.png +0 -0
  15. css/jquery-ui/images/ui-icons_666666_256x240.png +0 -0
  16. css/jquery-ui/images/ui-icons_888888_256x240.png +0 -0
  17. css/jquery-ui/images/ui-icons_cd0a0a_256x240.png +0 -0
  18. css/jquery-ui/images/ui-icons_ff0084_256x240.png +0 -0
  19. css/jquery-ui/images/ui-icons_ffffff_256x240.png +0 -0
  20. css/jquery-ui/jquery-ui.css +0 -1225
  21. css/wp-editor.css +16 -0
  22. editor.css +0 -4
  23. emails/blocks/cta/block.php +39 -0
  24. emails/{tnp-composer/blocks/content-04-cta.block.png → blocks/cta/icon.png} +0 -0
  25. emails/blocks/cta/options.php +43 -0
  26. emails/blocks/preheader/block.php +32 -0
  27. emails/blocks/preheader/icon.png +0 -0
  28. emails/blocks/preheader/options.php +19 -0
  29. emails/blocks/separator/block.php +29 -0
  30. emails/blocks/separator/icon.png +0 -0
  31. emails/blocks/separator/options.php +28 -0
  32. emails/composer.php +16 -21
  33. emails/cpreview.php +0 -517
  34. emails/edit-composer.php +30 -0
  35. emails/edit-editor.php +64 -0
  36. emails/edit-html.php +33 -0
  37. emails/edit.php +175 -253
  38. emails/editor.css +15 -4
  39. emails/emails.php +48 -19
  40. emails/index.php +17 -40
  41. emails/new.php +4 -2
  42. emails/theme.php +1 -1
  43. emails/themes/blank/theme-options.php +1 -1
  44. emails/themes/blank/theme.php +2 -2
  45. emails/themes/cta-2015/theme-options.php +1 -1
  46. emails/themes/cta-2015/theme.php +1 -45
  47. emails/themes/default/theme-options.php +8 -9
  48. emails/themes/default/theme.php +4 -4
  49. emails/themes/xmas-2014/images/footer.png +0 -0
  50. emails/themes/xmas-2014/images/header.png +0 -0
  51. emails/themes/xmas-2014/screenshot.png +0 -0
  52. emails/themes/xmas-2014/theme.php +0 -125
  53. emails/tnp-composer/_css/newsletter-builder.css +26 -16
  54. emails/tnp-composer/_scripts/newsletter-builder.js +19 -23
  55. emails/tnp-composer/blocks/content-02-heading.block.php +2 -2
  56. emails/tnp-composer/blocks/content-04-cta.block.php +0 -24
  57. emails/tnp-composer/blocks/header-01-header.block.php +1 -1
  58. emails/tnp-composer/edit.php +32 -1268
  59. emails/tnp-composer/index.php +39 -56
  60. header-extension.php +0 -31
  61. includes/controls.php +121 -26
  62. includes/module.php +336 -14
  63. includes/store.php +29 -5
  64. main/index.php +18 -3
  65. main/info.php +137 -171
  66. main/languages/en_US.php +2 -1
  67. main/main.php +47 -136
  68. main/status.php +25 -9
  69. plugin.php +14 -362
  70. readme.txt +13 -2
  71. statistics/statistics.php +10 -15
  72. statistics/view-urls.php +1 -1
  73. statistics/view.php +5 -10
  74. subscription/languages/en_US.php +1 -0
  75. subscription/options.php +77 -177
  76. subscription/page.php +1 -1
  77. subscription/subscription.php +21 -69
  78. tnp-header.php +48 -42
  79. users/edit.php +40 -70
  80. users/import.php +16 -16
  81. users/index.php +153 -152
  82. users/massive.php +184 -233
  83. users/new.php +23 -16
  84. users/statistics-time.php +11 -10
  85. users/statistics.php +133 -147
  86. users/users.php +0 -34
  87. widget/minimal.php +1 -1
admin.css CHANGED
@@ -1,9 +1,9 @@
1
 
2
  @import url(//fonts.googleapis.com/css?family=Montserrat:400,700);
3
- @import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:700);
4
  @import url(//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css);
5
  @import url(css/dropdown.css);
6
- @import url(css/jquery-ui/jquery-ui.css);
7
 
8
  /* Bootstrap like */
9
 
@@ -60,34 +60,50 @@
60
 
61
  @media all and (max-width: 1100px) {
62
  .col-md-12 {width: 100%;}
63
- .col-md-11 {width: 100%;}
64
- .col-md-10 {width: 100%;}
65
- .col-md-9 {width: 100%;}
66
- .col-md-8 {width: 100%;}
67
- .col-md-7 {width: 100%;}
68
- .col-md-6 {width: 100%;}
69
- .col-md-5 {width: 100%;}
70
- .col-md-4 {width: 100%;}
71
- .col-md-3 {width: 100%;}
72
- .col-md-2 {width: 100%;}
73
- .col-md-1 {width: 100%;}
74
  }
75
 
76
 
77
  /* Global Fonts */
78
 
79
- #tnp-wrap {
 
 
 
 
 
 
 
80
  font-family: "Open Sans", sans-serif;
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- /* HEADER *********************************************************************/
85
  #tnp-header {
86
  text-align: left;
87
  font-size: 12px;
88
- xheight: 110px;
89
  color: #fff;
90
- font-family: "Montserrat",sans-serif;
91
  }
92
 
93
  #tnp-header input {
@@ -134,54 +150,6 @@
134
  margin: 15px 0;
135
  }
136
 
137
- /* Admin header for extensions */
138
- #newsletter-header-ext {
139
- text-align: left;
140
- background-color: #fff;
141
- padding: 10px;
142
- font-size: 12px;
143
- border: 1px solid #ccc;
144
- float: right;
145
- width: 300px;
146
- }
147
-
148
- #newsletter-header-ext a {
149
- margin-right: 10px;
150
- text-decoration: none;
151
- }
152
-
153
- #newsletter-path {
154
-
155
- }
156
-
157
- #newsletter-nav {
158
- margin-bottom: 15px;
159
- }
160
-
161
- .newsletter-separator {
162
- clear: both;
163
- height: 5px;
164
- }
165
-
166
- /*
167
- .tnp-wrap, .tnp-wrap td, .tnp-wrap th, .tnp-wrap input, .tnp-wrap textarea {
168
- font-size: 13px;
169
- font-family: sans-serif;
170
- line-height: 130%;
171
- }
172
- */
173
-
174
- #tnp-body,
175
- #tnp-body p,
176
- #tnp-body td,
177
- #tnp-body th,
178
- #tnp-body input,
179
- #tnp-body select,
180
- #tnp-body textarea
181
- {
182
- xfont-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
183
- }
184
-
185
  /* Default font colors for our dark background page body */
186
  #tnp-body h1,
187
  #tnp-body h2,
@@ -191,12 +159,6 @@
191
  color: #fff;
192
  }
193
 
194
- #tnp-body td h1,
195
- #tnp-body td h2,
196
- #tnp-body td h3 {
197
- font-family: "Montserrat",sans-serif!important;
198
- }
199
-
200
  #tnp-body a, #tnp-body a:hover, #tnp-body a:visited, #tnp-body a:active {
201
  color: #E67E22; /* Orange */
202
  }
@@ -223,6 +185,11 @@
223
  text-shadow: none;
224
  }
225
 
 
 
 
 
 
226
  /* Standard button */
227
  #tnp-body .tnp-button {
228
  color: #fff;
@@ -262,20 +229,14 @@
262
  color: #27AE60; /* Green */
263
  }
264
 
 
 
265
  #tnp-body .form-table {
266
  background-color: #fff;
267
  border: 1px solid #ECF0F1;
268
  margin-top: 2em;
269
- }
270
-
271
- #tnp-body .widefat thead {
272
- background-color: #3498DB;
273
- font-family: "Montserrat", sans-serif;
274
- color: #fff !important;
275
- }
276
-
277
- #tnp-body .widefat thead tr th {
278
- color: #fff !important;
279
  }
280
 
281
  #tnp-body .form-table th {
@@ -284,9 +245,6 @@
284
  max-width: 200px;
285
  color: #000000;
286
  background-color: #ECF0F1;
287
- border-bottom: 4px solid #fff;
288
-
289
-
290
  }
291
 
292
  #tnp-body .form-table th small {
@@ -314,13 +272,35 @@
314
  text-align: left;
315
  font-weight: bold;
316
  }
317
- /* End of a table inside a form table */
318
 
319
- /* Wide fat tables */
 
 
 
 
 
 
 
 
320
  #tnp-body .widefat th {
321
  text-align: left;
322
  }
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  /* Buttons on widgets top bar */
325
  #tnp-body .tnp-widget h3 a,
326
  #tnp-body .tnp-widget h3 a:visited,
@@ -356,40 +336,6 @@
356
  color: #fff;
357
  }
358
 
359
- #tnp-body #tabs .ui-widget-header {
360
- background: #28313C;
361
- border: 0;
362
- }
363
-
364
- #tnp-body #tabs .ui-tabs-panel {
365
- padding: 15px!important;
366
- background-color: #fff;
367
- }
368
-
369
- #tnp-body #tabs a.ui-tabs-anchor,
370
- #tnp-body #tabs a.ui-tabs-anchor:visited {
371
- color: #444;
372
- }
373
-
374
-
375
-
376
- div.submit {
377
- margin-top: 5px;
378
- padding: 5px;
379
- }
380
-
381
- .bordered-table {
382
- border-collapse: collapse;
383
- }
384
-
385
- .bordered-table td, .bordered-table th {
386
- border: 1px solid #ccc;
387
- padding: 3px;
388
- }
389
-
390
- .newsletter-button {
391
- font-size: 10px;
392
- }
393
  table.clicks td {
394
  border: 1px solid #666;
395
  padding: 2px;
@@ -412,34 +358,6 @@ table.clicks {
412
  background-color: #aaa;
413
  }
414
 
415
-
416
-
417
- .hints {
418
- xborder: 1px solid #e4e4ee;
419
- xbackground-color: #f4f4ff;
420
- xpadding: 5px;
421
- margin-top: 10px;
422
- xborder-radius: 4px 4px;
423
- font-size: 13px;
424
- color: #666;
425
- font-style: italic;
426
- xbackground-color: #fcf8e3;
427
- xborder-color: #faebcc;
428
- }
429
-
430
- .intro {
431
- font-size: 11px;
432
- margin: 6px 6px 8px;
433
- }
434
-
435
-
436
- .newsletter-badge {
437
- color: #fff;
438
- background-color: #666;
439
- border-radius: 5px;
440
- padding: 1px 5px;
441
- }
442
-
443
  .tnp-checkboxes label {
444
  display: block;
445
  float: left;
@@ -505,15 +423,11 @@ table.clicks {
505
  display: inline;
506
  }
507
 
508
- .ui-tabs .ui-tabs-nav li a {
509
- font-size: 14px;
510
- }
511
 
512
 
513
 
514
- .widefat td, .widefat th {
515
- vertical-align: middle;
516
- }
517
 
518
  /*
519
  .form-table td label {
@@ -616,65 +530,6 @@ table.clicks {
616
  margin-bottom: 1em;
617
  }
618
 
619
- .newsletter-buttons-bottom {
620
- }
621
-
622
- .newsletter-buttons-top {
623
- }
624
-
625
- /* Text under the panel title to explain the panel purpose. */
626
- /*
627
- .preamble {
628
- margin-bottom: 15px;
629
- border-radius: 3px;
630
- background-color: #f4f4f4;
631
- padding: 10px;
632
- background-image: url("images/preamble.png");
633
- background-repeat: no-repeat;
634
- background-position: left;
635
- padding-left: 65px;
636
- font-size: 13px;
637
- font-family: sans-serif;
638
- }
639
-
640
- .preamble p {
641
- margin: 0;
642
- }
643
- */
644
-
645
- .newsletter-preamble {
646
- margin-bottom: 15px;
647
- xborder-radius: 3px;
648
- xbackground-color: #f4f4f4;
649
- xpadding: 10px;
650
- xbackground-image: url("images/preamble.png");
651
- xbackground-repeat: no-repeat;
652
- xbackground-position: left;
653
- xpadding-left: 65px;
654
- font-size: 13px;
655
- xfont-family: sans-serif;
656
- }
657
-
658
- .newsletter-preamble p {
659
- margin: 0;
660
- }
661
-
662
- .tab-preamble {
663
- font-size: 13px;
664
- line-height: normal;
665
- xfont-family: sans-serif;
666
- xcolor: #3a87ad;
667
- xbackground-color: #d9edf7;
668
- xborder: 1px solid #bce8f1;
669
- xpadding: 15px;
670
- xmargin-bottom: 20px;
671
- xborder-radius: 4px;
672
- }
673
-
674
- .tab-preamble p {
675
- margin: 0 0 5px 0;
676
- }
677
-
678
  .tnp-paginator {
679
  margin-top: 10px;
680
  margin-bottom: 5px;
@@ -746,9 +601,6 @@ table.clicks {
746
  color: #444;
747
  }
748
 
749
- .tnp-wrap a[target=_blank] {
750
- }
751
-
752
  /* .tnp-wrap a[target=_blank]:after {
753
  content: "»";
754
  }*/
@@ -781,11 +633,6 @@ table.clicks {
781
 
782
  /* CSS General Font Styles */
783
 
784
- .tnp-wrap p {
785
- /*font-family: "Montserrat";*/
786
- font-weight: 400;
787
- }
788
-
789
  p.description {
790
  font-size: 12px !important;
791
  }
@@ -824,26 +671,6 @@ p.description {
824
  margin-left: 10px;
825
  }
826
 
827
- /* Stefano 4.0 */
828
-
829
- .ui-tabs {
830
- border-color: #28313C;
831
- background-color: #28313C;
832
- border: 0;
833
- }
834
-
835
- .ui-tabs .ui-tabs-nav {
836
- margin: 0;
837
- padding: .2em .2em 0 0;
838
- background-color: #f2f2f2;
839
- }
840
-
841
- .ui-tabs .ui-tabs-panel {
842
- padding: 1em 0;
843
- background-color: #f2f2f2;
844
- margin: 0;
845
- border: 0;
846
- }
847
 
848
  /* Altrimenti si crea una striscia bianca in mezzo alla pagina! */
849
 
@@ -876,9 +703,9 @@ p.description {
876
  /* background-color: #34495E; */
877
  /* color: #fff !important; */
878
  margin-bottom: 10px;
879
- /* width: 200px;*/
880
  /* text-align: right; */
881
- /* border-bottom: 2px solid #27AE60;*/
882
  }
883
 
884
 
@@ -1102,11 +929,6 @@ p.description {
1102
 
1103
  /* Footer */
1104
 
1105
- #tnp-footer div {
1106
- width: 33%;
1107
- display: inline-block;
1108
- }
1109
-
1110
  #tnp-footer {
1111
  margin-top: 10px;
1112
  padding: 20px 10px 10px 40px;
@@ -1114,6 +936,11 @@ p.description {
1114
  font-family: "Montserrat", sans-serif;
1115
  }
1116
 
 
 
 
 
 
1117
  #tnp-footer a {
1118
  color: #fff;
1119
  text-decoration: none;
@@ -1375,10 +1202,69 @@ table.widefat {
1375
  margin: 5px;
1376
  }
1377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1378
 
1379
- /* Extension Panel */
 
 
 
 
1380
 
1381
 
 
 
 
1382
 
1383
  .tnp-extension-premium-box, .tnp-extension-free-box, .tnp-integration-box {
1384
  width: 300px;
@@ -1402,18 +1288,6 @@ table.widefat {
1402
  margin-top: 0px;
1403
  }
1404
 
1405
- /*.tnp-extension-premium-box {
1406
- border-top: 10px solid #F39C12;
1407
- }
1408
-
1409
- .tnp-extension-free-box {
1410
- border-top: 10px solid #2ECC71;
1411
- }
1412
-
1413
- .tnp-integration-box {
1414
- border-top: 10px solid #3498DB;
1415
- }*/
1416
-
1417
  .tnp-extension-premium-box h3 {
1418
  font-family: "Montserrat", sans-serif;
1419
  padding: 5px 8px !important;
@@ -1613,16 +1487,26 @@ img.tnp-extensions-free-badge {
1613
  margin-bottom: 20px;
1614
  }
1615
 
1616
- /* Michael - Nuovo Stile Tabelle Plugin */
1617
 
1618
- .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
1619
- background: #fff !important;
1620
- font-weight: normal;
1621
- font-family: "Montserrat", sans-serif;
 
 
1622
  }
1623
 
1624
- .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
1625
- border: none;
1626
- background: #ECF0F1;
1627
- font-family: "Montserrat", sans-serif;
1628
- }
 
 
 
 
 
 
 
 
 
1
 
2
  @import url(//fonts.googleapis.com/css?family=Montserrat:400,700);
3
+ @import url(//fonts.googleapis.com/css?family=Open+Sans:400,600);
4
  @import url(//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css);
5
  @import url(css/dropdown.css);
6
+ @import url(//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css);
7
 
8
  /* Bootstrap like */
9
 
60
 
61
  @media all and (max-width: 1100px) {
62
  .col-md-12 {width: 100%;}
63
+ .col-md-11 {width: 100%;}
64
+ .col-md-10 {width: 100%;}
65
+ .col-md-9 {width: 100%;}
66
+ .col-md-8 {width: 100%;}
67
+ .col-md-7 {width: 100%;}
68
+ .col-md-6 {width: 100%;}
69
+ .col-md-5 {width: 100%;}
70
+ .col-md-4 {width: 100%;}
71
+ .col-md-3 {width: 100%;}
72
+ .col-md-2 {width: 100%;}
73
+ .col-md-1 {width: 100%;}
74
  }
75
 
76
 
77
  /* Global Fonts */
78
 
79
+ #tnp-wrap,
80
+ #tnp-header,
81
+ #tnp-body p,
82
+ #tnp-body td,
83
+ #tnp-body td p,
84
+ #tnp-body input,
85
+ #tnp-body select,
86
+ #tnp-body textarea {
87
  font-family: "Open Sans", sans-serif;
88
  }
89
 
90
+ #tnp-body h1,
91
+ #tnp-body h2,
92
+ #tnp-body h3,
93
+ #tnp-body h4 {
94
+ font-family: "Montserrat", sans-serif;
95
+ }
96
+
97
+
98
+ /*******************************************************************************
99
+ * Header
100
+ */
101
 
 
102
  #tnp-header {
103
  text-align: left;
104
  font-size: 12px;
 
105
  color: #fff;
106
+ font-family: "Montserrat", sans-serif;
107
  }
108
 
109
  #tnp-header input {
150
  margin: 15px 0;
151
  }
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  /* Default font colors for our dark background page body */
154
  #tnp-body h1,
155
  #tnp-body h2,
159
  color: #fff;
160
  }
161
 
 
 
 
 
 
 
162
  #tnp-body a, #tnp-body a:hover, #tnp-body a:visited, #tnp-body a:active {
163
  color: #E67E22; /* Orange */
164
  }
185
  text-shadow: none;
186
  }
187
 
188
+ /* Icon in button media selector */
189
+ #tnp-body span.wp-media-buttons-icon:before {
190
+ color: #fff;
191
+ }
192
+
193
  /* Standard button */
194
  #tnp-body .tnp-button {
195
  color: #fff;
229
  color: #27AE60; /* Green */
230
  }
231
 
232
+
233
+ /* Tables of class form-table */
234
  #tnp-body .form-table {
235
  background-color: #fff;
236
  border: 1px solid #ECF0F1;
237
  margin-top: 2em;
238
+ border-spacing: 4px;
239
+ border-collapse: separate;
 
 
 
 
 
 
 
 
240
  }
241
 
242
  #tnp-body .form-table th {
245
  max-width: 200px;
246
  color: #000000;
247
  background-color: #ECF0F1;
 
 
 
248
  }
249
 
250
  #tnp-body .form-table th small {
272
  text-align: left;
273
  font-weight: bold;
274
  }
 
275
 
276
+
277
+ /*******************************************************************************
278
+ * Wide fat tables
279
+ */
280
+
281
+ #tnp-body .widefat {
282
+ width: auto;
283
+ }
284
+
285
  #tnp-body .widefat th {
286
  text-align: left;
287
  }
288
 
289
+ #tnp-body .widefat thead {
290
+ background-color: #3498DB;
291
+ font-family: "Montserrat", sans-serif;
292
+ color: #fff !important;
293
+ }
294
+
295
+ #tnp-body .widefat thead tr th {
296
+ color: #fff !important;
297
+ }
298
+
299
+ #tnp-body .widefat td, .widefat th {
300
+ vertical-align: middle;
301
+ }
302
+
303
+
304
  /* Buttons on widgets top bar */
305
  #tnp-body .tnp-widget h3 a,
306
  #tnp-body .tnp-widget h3 a:visited,
336
  color: #fff;
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  table.clicks td {
340
  border: 1px solid #666;
341
  padding: 2px;
358
  background-color: #aaa;
359
  }
360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  .tnp-checkboxes label {
362
  display: block;
363
  float: left;
423
  display: inline;
424
  }
425
 
 
 
 
426
 
427
 
428
 
429
+
430
+
 
431
 
432
  /*
433
  .form-table td label {
530
  margin-bottom: 1em;
531
  }
532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  .tnp-paginator {
534
  margin-top: 10px;
535
  margin-bottom: 5px;
601
  color: #444;
602
  }
603
 
 
 
 
604
  /* .tnp-wrap a[target=_blank]:after {
605
  content: "»";
606
  }*/
633
 
634
  /* CSS General Font Styles */
635
 
 
 
 
 
 
636
  p.description {
637
  font-size: 12px !important;
638
  }
671
  margin-left: 10px;
672
  }
673
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
 
675
  /* Altrimenti si crea una striscia bianca in mezzo alla pagina! */
676
 
703
  /* background-color: #34495E; */
704
  /* color: #fff !important; */
705
  margin-bottom: 10px;
706
+ /* width: 200px;*/
707
  /* text-align: right; */
708
+ /* border-bottom: 2px solid #27AE60;*/
709
  }
710
 
711
 
929
 
930
  /* Footer */
931
 
 
 
 
 
 
932
  #tnp-footer {
933
  margin-top: 10px;
934
  padding: 20px 10px 10px 40px;
936
  font-family: "Montserrat", sans-serif;
937
  }
938
 
939
+ #tnp-footer div {
940
+ width: 33%;
941
+ display: inline-block;
942
+ }
943
+
944
  #tnp-footer a {
945
  color: #fff;
946
  text-decoration: none;
1202
  margin: 5px;
1203
  }
1204
 
1205
+ /*******************************************************************************
1206
+ * Overrides some jQuery UI styles, specially for tabs and only inside the
1207
+ * #tnp-body div
1208
+ */
1209
+
1210
+ #tnp-body .ui-widget {
1211
+ font-family: "Montserrat", sans-serif;
1212
+ }
1213
+
1214
+ #tnp-body #tabs .ui-widget-header {
1215
+ background: #28313C;
1216
+ border: 0;
1217
+ }
1218
+
1219
+ #tnp-body #tabs .ui-tabs-panel {
1220
+ padding: 15px!important;
1221
+ background-color: #fff;
1222
+ }
1223
+
1224
+ #tnp-body #tabs a.ui-tabs-anchor,
1225
+ #tnp-body #tabs a.ui-tabs-anchor:visited {
1226
+ color: #444;
1227
+ }
1228
+
1229
+ #tnp-body .ui-tabs .ui-tabs-nav li a {
1230
+ font-size: 14px;
1231
+ }
1232
+
1233
+ #tnp-body .ui-tabs {
1234
+ border-color: #28313C;
1235
+ background-color: #28313C;
1236
+ border: 0;
1237
+ }
1238
+
1239
+ #tnp-body .ui-tabs .ui-tabs-nav {
1240
+ margin: 0;
1241
+ padding: .2em .2em 0 0;
1242
+ background-color: #f2f2f2;
1243
+ }
1244
+
1245
+ #tnp-body .ui-tabs .ui-tabs-panel {
1246
+ padding: 1em 0;
1247
+ background-color: #f2f2f2;
1248
+ margin: 0;
1249
+ border: 0;
1250
+ }
1251
+
1252
+ #tnp-body .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
1253
+ background: #fff !important;
1254
+ font-weight: normal;
1255
+ font-family: "Montserrat", sans-serif;
1256
+ }
1257
 
1258
+ #tnp-body .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
1259
+ border: none;
1260
+ background: #ECF0F1;
1261
+ font-family: "Montserrat", sans-serif;
1262
+ }
1263
 
1264
 
1265
+ /*******************************************************************************
1266
+ * Extension Panel
1267
+ */
1268
 
1269
  .tnp-extension-premium-box, .tnp-extension-free-box, .tnp-integration-box {
1270
  width: 300px;
1288
  margin-top: 0px;
1289
  }
1290
 
 
 
 
 
 
 
 
 
 
 
 
 
1291
  .tnp-extension-premium-box h3 {
1292
  font-family: "Montserrat", sans-serif;
1293
  padding: 5px 8px !important;
1487
  margin-bottom: 20px;
1488
  }
1489
 
 
1490
 
1491
+ /* Theme options and theme preview styles */
1492
+
1493
+ #tnp-body div.tnp-emails-theme-options {
1494
+ background-color: #fff;
1495
+ padding: 10px;
1496
+ margin-top: 14px;
1497
  }
1498
 
1499
+ #tnp-body div.tnp-emails-theme-options table.form-table {
1500
+ margin: 0;
1501
+ }
1502
+
1503
+ #tnp-body div.tnp-emails-theme-options h3 {
1504
+ color: #000;
1505
+ }
1506
+
1507
+ .tnp-emails-edit #options-subject {
1508
+ font-size: 20px;
1509
+ display: inline-block;
1510
+ margin-bottom: 10px;
1511
+ width: 100%;
1512
+ }
css/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png DELETED
Binary file
css/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png DELETED
Binary file
css/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png DELETED
Binary file
css/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png DELETED
Binary file
css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png DELETED
Binary file
css/jquery-ui/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png DELETED
Binary file
css/jquery-ui/images/ui-bg_highlight-soft_25_0073ea_1x100.png DELETED
Binary file
css/jquery-ui/images/ui-bg_highlight-soft_50_dddddd_1x100.png DELETED
Binary file
css/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png DELETED
Binary file
css/jquery-ui/images/ui-icons_0073ea_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_222222_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_2e83ff_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_454545_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_666666_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_888888_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_cd0a0a_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_ff0084_256x240.png DELETED
Binary file
css/jquery-ui/images/ui-icons_ffffff_256x240.png DELETED
Binary file
css/jquery-ui/jquery-ui.css DELETED
@@ -1,1225 +0,0 @@
1
- /*! jQuery UI - v1.11.4 - 2015-12-31
2
- * http://jqueryui.com
3
- * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
4
- * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
5
- * Copyright jQuery Foundation and other contributors; Licensed MIT */
6
-
7
- /* Layout helpers
8
- ----------------------------------*/
9
- .ui-helper-hidden {
10
- display: none;
11
- }
12
- .ui-helper-hidden-accessible {
13
- border: 0;
14
- clip: rect(0 0 0 0);
15
- height: 1px;
16
- margin: -1px;
17
- overflow: hidden;
18
- padding: 0;
19
- position: absolute;
20
- width: 1px;
21
- }
22
- .ui-helper-reset {
23
- margin: 0;
24
- padding: 0;
25
- border: 0;
26
- outline: 0;
27
- line-height: 1.3;
28
- text-decoration: none;
29
- font-size: 100%;
30
- list-style: none;
31
- }
32
- .ui-helper-clearfix:before,
33
- .ui-helper-clearfix:after {
34
- content: "";
35
- display: table;
36
- border-collapse: collapse;
37
- }
38
- .ui-helper-clearfix:after {
39
- clear: both;
40
- }
41
- .ui-helper-clearfix {
42
- min-height: 0; /* support: IE7 */
43
- }
44
- .ui-helper-zfix {
45
- width: 100%;
46
- height: 100%;
47
- top: 0;
48
- left: 0;
49
- position: absolute;
50
- opacity: 0;
51
- filter:Alpha(Opacity=0); /* support: IE8 */
52
- }
53
-
54
- .ui-front {
55
- z-index: 100;
56
- }
57
-
58
-
59
- /* Interaction Cues
60
- ----------------------------------*/
61
- .ui-state-disabled {
62
- cursor: default !important;
63
- }
64
-
65
-
66
- /* Icons
67
- ----------------------------------*/
68
-
69
- /* states and images */
70
- .ui-icon {
71
- display: block;
72
- text-indent: -99999px;
73
- overflow: hidden;
74
- background-repeat: no-repeat;
75
- }
76
-
77
-
78
- /* Misc visuals
79
- ----------------------------------*/
80
-
81
- /* Overlays */
82
- .ui-widget-overlay {
83
- position: fixed;
84
- top: 0;
85
- left: 0;
86
- width: 100%;
87
- height: 100%;
88
- }
89
- .ui-draggable-handle {
90
- -ms-touch-action: none;
91
- touch-action: none;
92
- }
93
- .ui-resizable {
94
- position: relative;
95
- }
96
- .ui-resizable-handle {
97
- position: absolute;
98
- font-size: 0.1px;
99
- display: block;
100
- -ms-touch-action: none;
101
- touch-action: none;
102
- }
103
- .ui-resizable-disabled .ui-resizable-handle,
104
- .ui-resizable-autohide .ui-resizable-handle {
105
- display: none;
106
- }
107
- .ui-resizable-n {
108
- cursor: n-resize;
109
- height: 7px;
110
- width: 100%;
111
- top: -5px;
112
- left: 0;
113
- }
114
- .ui-resizable-s {
115
- cursor: s-resize;
116
- height: 7px;
117
- width: 100%;
118
- bottom: -5px;
119
- left: 0;
120
- }
121
- .ui-resizable-e {
122
- cursor: e-resize;
123
- width: 7px;
124
- right: -5px;
125
- top: 0;
126
- height: 100%;
127
- }
128
- .ui-resizable-w {
129
- cursor: w-resize;
130
- width: 7px;
131
- left: -5px;
132
- top: 0;
133
- height: 100%;
134
- }
135
- .ui-resizable-se {
136
- cursor: se-resize;
137
- width: 12px;
138
- height: 12px;
139
- right: 1px;
140
- bottom: 1px;
141
- }
142
- .ui-resizable-sw {
143
- cursor: sw-resize;
144
- width: 9px;
145
- height: 9px;
146
- left: -5px;
147
- bottom: -5px;
148
- }
149
- .ui-resizable-nw {
150
- cursor: nw-resize;
151
- width: 9px;
152
- height: 9px;
153
- left: -5px;
154
- top: -5px;
155
- }
156
- .ui-resizable-ne {
157
- cursor: ne-resize;
158
- width: 9px;
159
- height: 9px;
160
- right: -5px;
161
- top: -5px;
162
- }
163
- .ui-selectable {
164
- -ms-touch-action: none;
165
- touch-action: none;
166
- }
167
- .ui-selectable-helper {
168
- position: absolute;
169
- z-index: 100;
170
- border: 1px dotted black;
171
- }
172
- .ui-sortable-handle {
173
- -ms-touch-action: none;
174
- touch-action: none;
175
- }
176
- .ui-accordion .ui-accordion-header {
177
- display: block;
178
- cursor: pointer;
179
- position: relative;
180
- margin: 2px 0 0 0;
181
- padding: .5em .5em .5em .7em;
182
- min-height: 0; /* support: IE7 */
183
- font-size: 100%;
184
- }
185
- .ui-accordion .ui-accordion-icons {
186
- padding-left: 2.2em;
187
- }
188
- .ui-accordion .ui-accordion-icons .ui-accordion-icons {
189
- padding-left: 2.2em;
190
- }
191
- .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
192
- position: absolute;
193
- left: .5em;
194
- top: 50%;
195
- margin-top: -8px;
196
- }
197
- .ui-accordion .ui-accordion-content {
198
- padding: 1em 2.2em;
199
- border-top: 0;
200
- overflow: auto;
201
- }
202
- .ui-autocomplete {
203
- position: absolute;
204
- top: 0;
205
- left: 0;
206
- cursor: default;
207
- }
208
- .ui-button {
209
- display: inline-block;
210
- position: relative;
211
- padding: 0;
212
- line-height: normal;
213
- margin-right: .1em;
214
- cursor: pointer;
215
- vertical-align: middle;
216
- text-align: center;
217
- overflow: visible; /* removes extra width in IE */
218
- }
219
- .ui-button,
220
- .ui-button:link,
221
- .ui-button:visited,
222
- .ui-button:hover,
223
- .ui-button:active {
224
- text-decoration: none;
225
- }
226
- /* to make room for the icon, a width needs to be set here */
227
- .ui-button-icon-only {
228
- width: 2.2em;
229
- }
230
- /* button elements seem to need a little more width */
231
- button.ui-button-icon-only {
232
- width: 2.4em;
233
- }
234
- .ui-button-icons-only {
235
- width: 3.4em;
236
- }
237
- button.ui-button-icons-only {
238
- width: 3.7em;
239
- }
240
-
241
- /* button text element */
242
- .ui-button .ui-button-text {
243
- display: block;
244
- line-height: normal;
245
- }
246
- .ui-button-text-only .ui-button-text {
247
- padding: .4em 1em;
248
- }
249
- .ui-button-icon-only .ui-button-text,
250
- .ui-button-icons-only .ui-button-text {
251
- padding: .4em;
252
- text-indent: -9999999px;
253
- }
254
- .ui-button-text-icon-primary .ui-button-text,
255
- .ui-button-text-icons .ui-button-text {
256
- padding: .4em 1em .4em 2.1em;
257
- }
258
- .ui-button-text-icon-secondary .ui-button-text,
259
- .ui-button-text-icons .ui-button-text {
260
- padding: .4em 2.1em .4em 1em;
261
- }
262
- .ui-button-text-icons .ui-button-text {
263
- padding-left: 2.1em;
264
- padding-right: 2.1em;
265
- }
266
- /* no icon support for input elements, provide padding by default */
267
- input.ui-button {
268
- padding: .4em 1em;
269
- }
270
-
271
- /* button icon element(s) */
272
- .ui-button-icon-only .ui-icon,
273
- .ui-button-text-icon-primary .ui-icon,
274
- .ui-button-text-icon-secondary .ui-icon,
275
- .ui-button-text-icons .ui-icon,
276
- .ui-button-icons-only .ui-icon {
277
- position: absolute;
278
- top: 50%;
279
- margin-top: -8px;
280
- }
281
- .ui-button-icon-only .ui-icon {
282
- left: 50%;
283
- margin-left: -8px;
284
- }
285
- .ui-button-text-icon-primary .ui-button-icon-primary,
286
- .ui-button-text-icons .ui-button-icon-primary,
287
- .ui-button-icons-only .ui-button-icon-primary {
288
- left: .5em;
289
- }
290
- .ui-button-text-icon-secondary .ui-button-icon-secondary,
291
- .ui-button-text-icons .ui-button-icon-secondary,
292
- .ui-button-icons-only .ui-button-icon-secondary {
293
- right: .5em;
294
- }
295
-
296
- /* button sets */
297
- .ui-buttonset {
298
- margin-right: 7px;
299
- }
300
- .ui-buttonset .ui-button {
301
- margin-left: 0;
302
- margin-right: -.3em;
303
- }
304
-
305
- /* workarounds */
306
- /* reset extra padding in Firefox, see h5bp.com/l */
307
- input.ui-button::-moz-focus-inner,
308
- button.ui-button::-moz-focus-inner {
309
- border: 0;
310
- padding: 0;
311
- }
312
- .ui-datepicker {
313
- width: 17em;
314
- padding: .2em .2em 0;
315
- display: none;
316
- }
317
- .ui-datepicker .ui-datepicker-header {
318
- position: relative;
319
- padding: .2em 0;
320
- }
321
- .ui-datepicker .ui-datepicker-prev,
322
- .ui-datepicker .ui-datepicker-next {
323
- position: absolute;
324
- top: 2px;
325
- width: 1.8em;
326
- height: 1.8em;
327
- }
328
- .ui-datepicker .ui-datepicker-prev-hover,
329
- .ui-datepicker .ui-datepicker-next-hover {
330
- top: 1px;
331
- }
332
- .ui-datepicker .ui-datepicker-prev {
333
- left: 2px;
334
- }
335
- .ui-datepicker .ui-datepicker-next {
336
- right: 2px;
337
- }
338
- .ui-datepicker .ui-datepicker-prev-hover {
339
- left: 1px;
340
- }
341
- .ui-datepicker .ui-datepicker-next-hover {
342
- right: 1px;
343
- }
344
- .ui-datepicker .ui-datepicker-prev span,
345
- .ui-datepicker .ui-datepicker-next span {
346
- display: block;
347
- position: absolute;
348
- left: 50%;
349
- margin-left: -8px;
350
- top: 50%;
351
- margin-top: -8px;
352
- }
353
- .ui-datepicker .ui-datepicker-title {
354
- margin: 0 2.3em;
355
- line-height: 1.8em;
356
- text-align: center;
357
- }
358
- .ui-datepicker .ui-datepicker-title select {
359
- font-size: 1em;
360
- margin: 1px 0;
361
- }
362
- .ui-datepicker select.ui-datepicker-month,
363
- .ui-datepicker select.ui-datepicker-year {
364
- width: 45%;
365
- }
366
- .ui-datepicker table {
367
- width: 100%;
368
- font-size: .9em;
369
- border-collapse: collapse;
370
- margin: 0 0 .4em;
371
- }
372
- .ui-datepicker th {
373
- padding: .7em .3em;
374
- text-align: center;
375
- font-weight: bold;
376
- border: 0;
377
- }
378
- .ui-datepicker td {
379
- border: 0;
380
- padding: 1px;
381
- }
382
- .ui-datepicker td span,
383
- .ui-datepicker td a {
384
- display: block;
385
- padding: .2em;
386
- text-align: right;
387
- text-decoration: none;
388
- }
389
- .ui-datepicker .ui-datepicker-buttonpane {
390
- background-image: none;
391
- margin: .7em 0 0 0;
392
- padding: 0 .2em;
393
- border-left: 0;
394
- border-right: 0;
395
- border-bottom: 0;
396
- }
397
- .ui-datepicker .ui-datepicker-buttonpane button {
398
- float: right;
399
- margin: .5em .2em .4em;
400
- cursor: pointer;
401
- padding: .2em .6em .3em .6em;
402
- width: auto;
403
- overflow: visible;
404
- }
405
- .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
406
- float: left;
407
- }
408
-
409
- /* with multiple calendars */
410
- .ui-datepicker.ui-datepicker-multi {
411
- width: auto;
412
- }
413
- .ui-datepicker-multi .ui-datepicker-group {
414
- float: left;
415
- }
416
- .ui-datepicker-multi .ui-datepicker-group table {
417
- width: 95%;
418
- margin: 0 auto .4em;
419
- }
420
- .ui-datepicker-multi-2 .ui-datepicker-group {
421
- width: 50%;
422
- }
423
- .ui-datepicker-multi-3 .ui-datepicker-group {
424
- width: 33.3%;
425
- }
426
- .ui-datepicker-multi-4 .ui-datepicker-group {
427
- width: 25%;
428
- }
429
- .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
430
- .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
431
- border-left-width: 0;
432
- }
433
- .ui-datepicker-multi .ui-datepicker-buttonpane {
434
- clear: left;
435
- }
436
- .ui-datepicker-row-break {
437
- clear: both;
438
- width: 100%;
439
- font-size: 0;
440
- }
441
-
442
- /* RTL support */
443
- .ui-datepicker-rtl {
444
- direction: rtl;
445
- }
446
- .ui-datepicker-rtl .ui-datepicker-prev {
447
- right: 2px;
448
- left: auto;
449
- }
450
- .ui-datepicker-rtl .ui-datepicker-next {
451
- left: 2px;
452
- right: auto;
453
- }
454
- .ui-datepicker-rtl .ui-datepicker-prev:hover {
455
- right: 1px;
456
- left: auto;
457
- }
458
- .ui-datepicker-rtl .ui-datepicker-next:hover {
459
- left: 1px;
460
- right: auto;
461
- }
462
- .ui-datepicker-rtl .ui-datepicker-buttonpane {
463
- clear: right;
464
- }
465
- .ui-datepicker-rtl .ui-datepicker-buttonpane button {
466
- float: left;
467
- }
468
- .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
469
- .ui-datepicker-rtl .ui-datepicker-group {
470
- float: right;
471
- }
472
- .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
473
- .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
474
- border-right-width: 0;
475
- border-left-width: 1px;
476
- }
477
- .ui-dialog {
478
- overflow: hidden;
479
- position: absolute;
480
- top: 0;
481
- left: 0;
482
- padding: .2em;
483
- outline: 0;
484
- }
485
- .ui-dialog .ui-dialog-titlebar {
486
- padding: .4em 1em;
487
- position: relative;
488
- }
489
- .ui-dialog .ui-dialog-title {
490
- float: left;
491
- margin: .1em 0;
492
- white-space: nowrap;
493
- width: 90%;
494
- overflow: hidden;
495
- text-overflow: ellipsis;
496
- }
497
- .ui-dialog .ui-dialog-titlebar-close {
498
- position: absolute;
499
- right: .3em;
500
- top: 50%;
501
- width: 20px;
502
- margin: -10px 0 0 0;
503
- padding: 1px;
504
- height: 20px;
505
- }
506
- .ui-dialog .ui-dialog-content {
507
- position: relative;
508
- border: 0;
509
- padding: .5em 1em;
510
- background: none;
511
- overflow: auto;
512
- }
513
- .ui-dialog .ui-dialog-buttonpane {
514
- text-align: left;
515
- border-width: 1px 0 0 0;
516
- background-image: none;
517
- margin-top: .5em;
518
- padding: .3em 1em .5em .4em;
519
- }
520
- .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
521
- float: right;
522
- }
523
- .ui-dialog .ui-dialog-buttonpane button {
524
- margin: .5em .4em .5em 0;
525
- cursor: pointer;
526
- }
527
- .ui-dialog .ui-resizable-se {
528
- width: 12px;
529
- height: 12px;
530
- right: -5px;
531
- bottom: -5px;
532
- background-position: 16px 16px;
533
- }
534
- .ui-draggable .ui-dialog-titlebar {
535
- cursor: move;
536
- }
537
- .ui-menu {
538
- list-style: none;
539
- padding: 0;
540
- margin: 0;
541
- display: block;
542
- outline: none;
543
- }
544
- .ui-menu .ui-menu {
545
- position: absolute;
546
- }
547
- .ui-menu .ui-menu-item {
548
- position: relative;
549
- margin: 0;
550
- padding: 3px 1em 3px .4em;
551
- cursor: pointer;
552
- min-height: 0; /* support: IE7 */
553
- /* support: IE10, see #8844 */
554
- list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
555
- }
556
- .ui-menu .ui-menu-divider {
557
- margin: 5px 0;
558
- height: 0;
559
- font-size: 0;
560
- line-height: 0;
561
- border-width: 1px 0 0 0;
562
- }
563
- .ui-menu .ui-state-focus,
564
- .ui-menu .ui-state-active {
565
- margin: -1px;
566
- }
567
-
568
- /* icon support */
569
- .ui-menu-icons {
570
- position: relative;
571
- }
572
- .ui-menu-icons .ui-menu-item {
573
- padding-left: 2em;
574
- }
575
-
576
- /* left-aligned */
577
- .ui-menu .ui-icon {
578
- position: absolute;
579
- top: 0;
580
- bottom: 0;
581
- left: .2em;
582
- margin: auto 0;
583
- }
584
-
585
- /* right-aligned */
586
- .ui-menu .ui-menu-icon {
587
- left: auto;
588
- right: 0;
589
- }
590
- .ui-progressbar {
591
- height: 2em;
592
- text-align: left;
593
- overflow: hidden;
594
- }
595
- .ui-progressbar .ui-progressbar-value {
596
- margin: -1px;
597
- height: 100%;
598
- }
599
- .ui-progressbar .ui-progressbar-overlay {
600
- background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
601
- height: 100%;
602
- filter: alpha(opacity=25); /* support: IE8 */
603
- opacity: 0.25;
604
- }
605
- .ui-progressbar-indeterminate .ui-progressbar-value {
606
- background-image: none;
607
- }
608
- .ui-selectmenu-menu {
609
- padding: 0;
610
- margin: 0;
611
- position: absolute;
612
- top: 0;
613
- left: 0;
614
- display: none;
615
- }
616
- .ui-selectmenu-menu .ui-menu {
617
- overflow: auto;
618
- /* Support: IE7 */
619
- overflow-x: hidden;
620
- padding-bottom: 1px;
621
- }
622
- .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
623
- font-size: 1em;
624
- font-weight: bold;
625
- line-height: 1.5;
626
- padding: 2px 0.4em;
627
- margin: 0.5em 0 0 0;
628
- height: auto;
629
- border: 0;
630
- }
631
- .ui-selectmenu-open {
632
- display: block;
633
- }
634
- .ui-selectmenu-button {
635
- display: inline-block;
636
- overflow: hidden;
637
- position: relative;
638
- text-decoration: none;
639
- cursor: pointer;
640
- }
641
- .ui-selectmenu-button span.ui-icon {
642
- right: 0.5em;
643
- left: auto;
644
- margin-top: -8px;
645
- position: absolute;
646
- top: 50%;
647
- }
648
- .ui-selectmenu-button span.ui-selectmenu-text {
649
- text-align: left;
650
- padding: 0.4em 2.1em 0.4em 1em;
651
- display: block;
652
- line-height: 1.4;
653
- overflow: hidden;
654
- text-overflow: ellipsis;
655
- white-space: nowrap;
656
- }
657
- .ui-slider {
658
- position: relative;
659
- text-align: left;
660
- }
661
- .ui-slider .ui-slider-handle {
662
- position: absolute;
663
- z-index: 2;
664
- width: 1.2em;
665
- height: 1.2em;
666
- cursor: default;
667
- -ms-touch-action: none;
668
- touch-action: none;
669
- }
670
- .ui-slider .ui-slider-range {
671
- position: absolute;
672
- z-index: 1;
673
- font-size: .7em;
674
- display: block;
675
- border: 0;
676
- background-position: 0 0;
677
- }
678
-
679
- /* support: IE8 - See #6727 */
680
- .ui-slider.ui-state-disabled .ui-slider-handle,
681
- .ui-slider.ui-state-disabled .ui-slider-range {
682
- filter: inherit;
683
- }
684
-
685
- .ui-slider-horizontal {
686
- height: .8em;
687
- }
688
- .ui-slider-horizontal .ui-slider-handle {
689
- top: -.3em;
690
- margin-left: -.6em;
691
- }
692
- .ui-slider-horizontal .ui-slider-range {
693
- top: 0;
694
- height: 100%;
695
- }
696
- .ui-slider-horizontal .ui-slider-range-min {
697
- left: 0;
698
- }
699
- .ui-slider-horizontal .ui-slider-range-max {
700
- right: 0;
701
- }
702
-
703
- .ui-slider-vertical {
704
- width: .8em;
705
- height: 100px;
706
- }
707
- .ui-slider-vertical .ui-slider-handle {
708
- left: -.3em;
709
- margin-left: 0;
710
- margin-bottom: -.6em;
711
- }
712
- .ui-slider-vertical .ui-slider-range {
713
- left: 0;
714
- width: 100%;
715
- }
716
- .ui-slider-vertical .ui-slider-range-min {
717
- bottom: 0;
718
- }
719
- .ui-slider-vertical .ui-slider-range-max {
720
- top: 0;
721
- }
722
- .ui-spinner {
723
- position: relative;
724
- display: inline-block;
725
- overflow: hidden;
726
- padding: 0;
727
- vertical-align: middle;
728
- }
729
- .ui-spinner-input {
730
- border: none;
731
- background: none;
732
- color: inherit;
733
- padding: 0;
734
- margin: .2em 0;
735
- vertical-align: middle;
736
- margin-left: .4em;
737
- margin-right: 22px;
738
- }
739
- .ui-spinner-button {
740
- width: 16px;
741
- height: 50%;
742
- font-size: .5em;
743
- padding: 0;
744
- margin: 0;
745
- text-align: center;
746
- position: absolute;
747
- cursor: default;
748
- display: block;
749
- overflow: hidden;
750
- right: 0;
751
- }
752
- /* more specificity required here to override default borders */
753
- .ui-spinner a.ui-spinner-button {
754
- border-top: none;
755
- border-bottom: none;
756
- border-right: none;
757
- }
758
- /* vertically center icon */
759
- .ui-spinner .ui-icon {
760
- position: absolute;
761
- margin-top: -8px;
762
- top: 50%;
763
- left: 0;
764
- }
765
- .ui-spinner-up {
766
- top: 0;
767
- }
768
- .ui-spinner-down {
769
- bottom: 0;
770
- }
771
-
772
- /* TR overrides */
773
- .ui-spinner .ui-icon-triangle-1-s {
774
- /* need to fix icons sprite */
775
- background-position: -65px -16px;
776
- }
777
- .ui-tabs {
778
- position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
779
- padding: .2em;
780
- }
781
- .ui-tabs .ui-tabs-nav {
782
- margin: 0;
783
- padding: .2em .2em 0;
784
- }
785
- .ui-tabs .ui-tabs-nav li {
786
- list-style: none;
787
- float: left;
788
- position: relative;
789
- top: 0;
790
- margin: 1px .2em 0 0;
791
- border-bottom-width: 0;
792
- padding: 0;
793
- white-space: nowrap;
794
- }
795
- .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
796
- float: left;
797
- padding: .5em 1em;
798
- text-decoration: none;
799
- }
800
- .ui-tabs .ui-tabs-nav li.ui-tabs-active {
801
- margin-bottom: -1px;
802
- padding-bottom: 1px;
803
- }
804
- .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
805
- .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
806
- .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
807
- cursor: text;
808
- }
809
- .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
810
- cursor: pointer;
811
- }
812
- .ui-tabs .ui-tabs-panel {
813
- display: block;
814
- border-width: 0;
815
- padding: 1em 1.4em;
816
- background: none;
817
- }
818
- .ui-tooltip {
819
- padding: 8px;
820
- position: absolute;
821
- z-index: 9999;
822
- max-width: 300px;
823
- -webkit-box-shadow: 0 0 5px #aaa;
824
- box-shadow: 0 0 5px #aaa;
825
- }
826
- body .ui-tooltip {
827
- border-width: 2px;
828
- }
829
-
830
- /* Component containers
831
- ----------------------------------*/
832
- .ui-widget {
833
- xfont-family: Verdana,Arial,sans-serif;
834
- xfont-size: 1.1em;
835
- }
836
- .ui-widget .ui-widget {
837
- font-size: 1em;
838
- }
839
- .ui-widget input,
840
- .ui-widget select,
841
- .ui-widget textarea,
842
- .ui-widget button {
843
- xfont-family: Verdana,Arial,sans-serif;
844
- xfont-size: 1em;
845
- }
846
- .ui-widget-content {
847
- border: 1px solid #aaaaaa;
848
- background: #ffffff;
849
- color: #222222;
850
- }
851
- .ui-widget-content a {
852
- color: #222222;
853
- }
854
- .ui-widget-header {
855
- border: 1px solid #aaaaaa;
856
- background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
857
- color: #222222;
858
- font-weight: bold;
859
- }
860
- .ui-widget-header a {
861
- color: #222222;
862
- }
863
-
864
- /* Interaction states
865
- ----------------------------------*/
866
- .ui-state-default,
867
- .ui-widget-content .ui-state-default,
868
- .ui-widget-header .ui-state-default {
869
- border: 1px solid #d3d3d3;
870
- background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
871
- font-weight: normal;
872
- color: #555555;
873
- }
874
- .ui-state-default a,
875
- .ui-state-default a:link,
876
- .ui-state-default a:visited {
877
- color: #555555;
878
- text-decoration: none;
879
- }
880
- .ui-state-hover,
881
- .ui-widget-content .ui-state-hover,
882
- .ui-widget-header .ui-state-hover,
883
- .ui-state-focus,
884
- .ui-widget-content .ui-state-focus,
885
- .ui-widget-header .ui-state-focus {
886
- border: 1px solid #999999;
887
- background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
888
- font-weight: normal;
889
- color: #212121;
890
- }
891
- .ui-state-hover a,
892
- .ui-state-hover a:hover,
893
- .ui-state-hover a:link,
894
- .ui-state-hover a:visited,
895
- .ui-state-focus a,
896
- .ui-state-focus a:hover,
897
- .ui-state-focus a:link,
898
- .ui-state-focus a:visited {
899
- color: #212121;
900
- text-decoration: none;
901
- }
902
- .ui-state-active,
903
- .ui-widget-content .ui-state-active,
904
- .ui-widget-header .ui-state-active {
905
- border: 1px solid #aaaaaa;
906
- background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
907
- font-weight: normal;
908
- color: #212121;
909
- }
910
- .ui-state-active a,
911
- .ui-state-active a:link,
912
- .ui-state-active a:visited {
913
- color: #212121;
914
- text-decoration: none;
915
- }
916
-
917
- /* Interaction Cues
918
- ----------------------------------*/
919
- .ui-state-highlight,
920
- .ui-widget-content .ui-state-highlight,
921
- .ui-widget-header .ui-state-highlight {
922
- border: 1px solid #fcefa1;
923
- background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
924
- color: #363636;
925
- }
926
- .ui-state-highlight a,
927
- .ui-widget-content .ui-state-highlight a,
928
- .ui-widget-header .ui-state-highlight a {
929
- color: #363636;
930
- }
931
- .ui-state-error,
932
- .ui-widget-content .ui-state-error,
933
- .ui-widget-header .ui-state-error {
934
- border: 1px solid #cd0a0a;
935
- background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
936
- color: #cd0a0a;
937
- }
938
- .ui-state-error a,
939
- .ui-widget-content .ui-state-error a,
940
- .ui-widget-header .ui-state-error a {
941
- color: #cd0a0a;
942
- }
943
- .ui-state-error-text,
944
- .ui-widget-content .ui-state-error-text,
945
- .ui-widget-header .ui-state-error-text {
946
- color: #cd0a0a;
947
- }
948
- .ui-priority-primary,
949
- .ui-widget-content .ui-priority-primary,
950
- .ui-widget-header .ui-priority-primary {
951
- font-weight: bold;
952
- }
953
- .ui-priority-secondary,
954
- .ui-widget-content .ui-priority-secondary,
955
- .ui-widget-header .ui-priority-secondary {
956
- opacity: .7;
957
- filter:Alpha(Opacity=70); /* support: IE8 */
958
- font-weight: normal;
959
- }
960
- .ui-state-disabled,
961
- .ui-widget-content .ui-state-disabled,
962
- .ui-widget-header .ui-state-disabled {
963
- opacity: .35;
964
- filter:Alpha(Opacity=35); /* support: IE8 */
965
- background-image: none;
966
- }
967
- .ui-state-disabled .ui-icon {
968
- filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
969
- }
970
-
971
- /* Icons
972
- ----------------------------------*/
973
-
974
- /* states and images */
975
- .ui-icon {
976
- width: 16px;
977
- height: 16px;
978
- }
979
- .ui-icon,
980
- .ui-widget-content .ui-icon {
981
- background-image: url("images/ui-icons_222222_256x240.png");
982
- }
983
- .ui-widget-header .ui-icon {
984
- background-image: url("images/ui-icons_222222_256x240.png");
985
- }
986
- .ui-state-default .ui-icon {
987
- background-image: url("images/ui-icons_888888_256x240.png");
988
- }
989
- .ui-state-hover .ui-icon,
990
- .ui-state-focus .ui-icon {
991
- background-image: url("images/ui-icons_454545_256x240.png");
992
- }
993
- .ui-state-active .ui-icon {
994
- background-image: url("images/ui-icons_454545_256x240.png");
995
- }
996
- .ui-state-highlight .ui-icon {
997
- background-image: url("images/ui-icons_2e83ff_256x240.png");
998
- }
999
- .ui-state-error .ui-icon,
1000
- .ui-state-error-text .ui-icon {
1001
- background-image: url("images/ui-icons_cd0a0a_256x240.png");
1002
- }
1003
-
1004
- /* positioning */
1005
- .ui-icon-blank { background-position: 16px 16px; }
1006
- .ui-icon-carat-1-n { background-position: 0 0; }
1007
- .ui-icon-carat-1-ne { background-position: -16px 0; }
1008
- .ui-icon-carat-1-e { background-position: -32px 0; }
1009
- .ui-icon-carat-1-se { background-position: -48px 0; }
1010
- .ui-icon-carat-1-s { background-position: -64px 0; }
1011
- .ui-icon-carat-1-sw { background-position: -80px 0; }
1012
- .ui-icon-carat-1-w { background-position: -96px 0; }
1013
- .ui-icon-carat-1-nw { background-position: -112px 0; }
1014
- .ui-icon-carat-2-n-s { background-position: -128px 0; }
1015
- .ui-icon-carat-2-e-w { background-position: -144px 0; }
1016
- .ui-icon-triangle-1-n { background-position: 0 -16px; }
1017
- .ui-icon-triangle-1-ne { background-position: -16px -16px; }
1018
- .ui-icon-triangle-1-e { background-position: -32px -16px; }
1019
- .ui-icon-triangle-1-se { background-position: -48px -16px; }
1020
- .ui-icon-triangle-1-s { background-position: -64px -16px; }
1021
- .ui-icon-triangle-1-sw { background-position: -80px -16px; }
1022
- .ui-icon-triangle-1-w { background-position: -96px -16px; }
1023
- .ui-icon-triangle-1-nw { background-position: -112px -16px; }
1024
- .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
1025
- .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
1026
- .ui-icon-arrow-1-n { background-position: 0 -32px; }
1027
- .ui-icon-arrow-1-ne { background-position: -16px -32px; }
1028
- .ui-icon-arrow-1-e { background-position: -32px -32px; }
1029
- .ui-icon-arrow-1-se { background-position: -48px -32px; }
1030
- .ui-icon-arrow-1-s { background-position: -64px -32px; }
1031
- .ui-icon-arrow-1-sw { background-position: -80px -32px; }
1032
- .ui-icon-arrow-1-w { background-position: -96px -32px; }
1033
- .ui-icon-arrow-1-nw { background-position: -112px -32px; }
1034
- .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1035
- .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1036
- .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1037
- .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1038
- .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1039
- .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1040
- .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1041
- .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1042
- .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
1043
- .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1044
- .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1045
- .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1046
- .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1047
- .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1048
- .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1049
- .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1050
- .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1051
- .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1052
- .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1053
- .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1054
- .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1055
- .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1056
- .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1057
- .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1058
- .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1059
- .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1060
- .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1061
- .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1062
- .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1063
- .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1064
- .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1065
- .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1066
- .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1067
- .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1068
- .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1069
- .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1070
- .ui-icon-arrow-4 { background-position: 0 -80px; }
1071
- .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1072
- .ui-icon-extlink { background-position: -32px -80px; }
1073
- .ui-icon-newwin { background-position: -48px -80px; }
1074
- .ui-icon-refresh { background-position: -64px -80px; }
1075
- .ui-icon-shuffle { background-position: -80px -80px; }
1076
- .ui-icon-transfer-e-w { background-position: -96px -80px; }
1077
- .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1078
- .ui-icon-folder-collapsed { background-position: 0 -96px; }
1079
- .ui-icon-folder-open { background-position: -16px -96px; }
1080
- .ui-icon-document { background-position: -32px -96px; }
1081
- .ui-icon-document-b { background-position: -48px -96px; }
1082
- .ui-icon-note { background-position: -64px -96px; }
1083
- .ui-icon-mail-closed { background-position: -80px -96px; }
1084
- .ui-icon-mail-open { background-position: -96px -96px; }
1085
- .ui-icon-suitcase { background-position: -112px -96px; }
1086
- .ui-icon-comment { background-position: -128px -96px; }
1087
- .ui-icon-person { background-position: -144px -96px; }
1088
- .ui-icon-print { background-position: -160px -96px; }
1089
- .ui-icon-trash { background-position: -176px -96px; }
1090
- .ui-icon-locked { background-position: -192px -96px; }
1091
- .ui-icon-unlocked { background-position: -208px -96px; }
1092
- .ui-icon-bookmark { background-position: -224px -96px; }
1093
- .ui-icon-tag { background-position: -240px -96px; }
1094
- .ui-icon-home { background-position: 0 -112px; }
1095
- .ui-icon-flag { background-position: -16px -112px; }
1096
- .ui-icon-calendar { background-position: -32px -112px; }
1097
- .ui-icon-cart { background-position: -48px -112px; }
1098
- .ui-icon-pencil { background-position: -64px -112px; }
1099
- .ui-icon-clock { background-position: -80px -112px; }
1100
- .ui-icon-disk { background-position: -96px -112px; }
1101
- .ui-icon-calculator { background-position: -112px -112px; }
1102
- .ui-icon-zoomin { background-position: -128px -112px; }
1103
- .ui-icon-zoomout { background-position: -144px -112px; }
1104
- .ui-icon-search { background-position: -160px -112px; }
1105
- .ui-icon-wrench { background-position: -176px -112px; }
1106
- .ui-icon-gear { background-position: -192px -112px; }
1107
- .ui-icon-heart { background-position: -208px -112px; }
1108
- .ui-icon-star { background-position: -224px -112px; }
1109
- .ui-icon-link { background-position: -240px -112px; }
1110
- .ui-icon-cancel { background-position: 0 -128px; }
1111
- .ui-icon-plus { background-position: -16px -128px; }
1112
- .ui-icon-plusthick { background-position: -32px -128px; }
1113
- .ui-icon-minus { background-position: -48px -128px; }
1114
- .ui-icon-minusthick { background-position: -64px -128px; }
1115
- .ui-icon-close { background-position: -80px -128px; }
1116
- .ui-icon-closethick { background-position: -96px -128px; }
1117
- .ui-icon-key { background-position: -112px -128px; }
1118
- .ui-icon-lightbulb { background-position: -128px -128px; }
1119
- .ui-icon-scissors { background-position: -144px -128px; }
1120
- .ui-icon-clipboard { background-position: -160px -128px; }
1121
- .ui-icon-copy { background-position: -176px -128px; }
1122
- .ui-icon-contact { background-position: -192px -128px; }
1123
- .ui-icon-image { background-position: -208px -128px; }
1124
- .ui-icon-video { background-position: -224px -128px; }
1125
- .ui-icon-script { background-position: -240px -128px; }
1126
- .ui-icon-alert { background-position: 0 -144px; }
1127
- .ui-icon-info { background-position: -16px -144px; }
1128
- .ui-icon-notice { background-position: -32px -144px; }
1129
- .ui-icon-help { background-position: -48px -144px; }
1130
- .ui-icon-check { background-position: -64px -144px; }
1131
- .ui-icon-bullet { background-position: -80px -144px; }
1132
- .ui-icon-radio-on { background-position: -96px -144px; }
1133
- .ui-icon-radio-off { background-position: -112px -144px; }
1134
- .ui-icon-pin-w { background-position: -128px -144px; }
1135
- .ui-icon-pin-s { background-position: -144px -144px; }
1136
- .ui-icon-play { background-position: 0 -160px; }
1137
- .ui-icon-pause { background-position: -16px -160px; }
1138
- .ui-icon-seek-next { background-position: -32px -160px; }
1139
- .ui-icon-seek-prev { background-position: -48px -160px; }
1140
- .ui-icon-seek-end { background-position: -64px -160px; }
1141
- .ui-icon-seek-start { background-position: -80px -160px; }
1142
- /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1143
- .ui-icon-seek-first { background-position: -80px -160px; }
1144
- .ui-icon-stop { background-position: -96px -160px; }
1145
- .ui-icon-eject { background-position: -112px -160px; }
1146
- .ui-icon-volume-off { background-position: -128px -160px; }
1147
- .ui-icon-volume-on { background-position: -144px -160px; }
1148
- .ui-icon-power { background-position: 0 -176px; }
1149
- .ui-icon-signal-diag { background-position: -16px -176px; }
1150
- .ui-icon-signal { background-position: -32px -176px; }
1151
- .ui-icon-battery-0 { background-position: -48px -176px; }
1152
- .ui-icon-battery-1 { background-position: -64px -176px; }
1153
- .ui-icon-battery-2 { background-position: -80px -176px; }
1154
- .ui-icon-battery-3 { background-position: -96px -176px; }
1155
- .ui-icon-circle-plus { background-position: 0 -192px; }
1156
- .ui-icon-circle-minus { background-position: -16px -192px; }
1157
- .ui-icon-circle-close { background-position: -32px -192px; }
1158
- .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1159
- .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1160
- .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1161
- .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1162
- .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1163
- .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1164
- .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1165
- .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1166
- .ui-icon-circle-zoomin { background-position: -176px -192px; }
1167
- .ui-icon-circle-zoomout { background-position: -192px -192px; }
1168
- .ui-icon-circle-check { background-position: -208px -192px; }
1169
- .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1170
- .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1171
- .ui-icon-circlesmall-close { background-position: -32px -208px; }
1172
- .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1173
- .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1174
- .ui-icon-squaresmall-close { background-position: -80px -208px; }
1175
- .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1176
- .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1177
- .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1178
- .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1179
- .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1180
- .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1181
-
1182
-
1183
- /* Misc visuals
1184
- ----------------------------------*/
1185
-
1186
- /* Corner radius */
1187
- .ui-corner-all,
1188
- .ui-corner-top,
1189
- .ui-corner-left,
1190
- .ui-corner-tl {
1191
- border-top-left-radius: 4px;
1192
- }
1193
- .ui-corner-all,
1194
- .ui-corner-top,
1195
- .ui-corner-right,
1196
- .ui-corner-tr {
1197
- border-top-right-radius: 4px;
1198
- }
1199
- .ui-corner-all,
1200
- .ui-corner-bottom,
1201
- .ui-corner-left,
1202
- .ui-corner-bl {
1203
- border-bottom-left-radius: 4px;
1204
- }
1205
- .ui-corner-all,
1206
- .ui-corner-bottom,
1207
- .ui-corner-right,
1208
- .ui-corner-br {
1209
- border-bottom-right-radius: 4px;
1210
- }
1211
-
1212
- /* Overlays */
1213
- .ui-widget-overlay {
1214
- background: #aaaaaa;
1215
- opacity: .3;
1216
- filter: Alpha(Opacity=30); /* support: IE8 */
1217
- }
1218
- .ui-widget-shadow {
1219
- margin: -8px 0 0 -8px;
1220
- padding: 8px;
1221
- background: #aaaaaa;
1222
- opacity: .3;
1223
- filter: Alpha(Opacity=30); /* support: IE8 */
1224
- border-radius: 8px;
1225
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/wp-editor.css ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* The CSS used for the WP editor on administration panels */
2
+ body {
3
+ font-size: 16px;
4
+ font-family: sans-serif;
5
+ margin: 20px;
6
+ }
7
+
8
+ .mce-content-body p, table, ul, ol {
9
+ margin-bottom: 15px;
10
+ width: 650px;
11
+ line-height: 24px;
12
+ }
13
+
14
+ img {
15
+ max-width: 100%;
16
+ }
editor.css DELETED
@@ -1,4 +0,0 @@
1
- body {
2
- font-size: 12px;
3
- }
4
-
 
 
 
 
emails/blocks/cta/block.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Name: Call To Action
4
+ * Section: content
5
+ * Description: Call to action button
6
+ *
7
+ */
8
+
9
+ /* @var $options array */
10
+ /* @var $wpdb wpdb */
11
+
12
+ if (empty($options['text'])) {
13
+ $options['text'] = 'Call to action';
14
+ }
15
+ if (empty($options['background'])) {
16
+ $options['background'] = '#256F9C';
17
+ }
18
+ if (empty($options['color'])) {
19
+ $options['color'] = '#ffffff';
20
+ }
21
+ if (empty($options['url'])) {
22
+ $options['url'] = '#';
23
+ }
24
+ if (empty($options['font_size'])) {
25
+ $options['font_size'] = '16';
26
+ }
27
+ if (empty($options['font_family'])) {
28
+ $options['font_family'] = 'Helvetica, Arial, sans-serif';
29
+ }
30
+ ?>
31
+ <table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table">
32
+ <tr>
33
+ <td align="center" style="text-align: center; padding: 20px;" class="padding-copy">
34
+
35
+ <a href="<?php echo $options['url'] ?>" target="_blank" rel="noopener" style="line-height: normal; font-size: <?php echo $options['font_size'] ?>px; font-family: <?php echo $options['font_family'] ?>; font-weight: normal; color: <?php echo $options['color'] ?>; text-decoration: none; background-color: <?php echo $options['background'] ?>; border-top: 15px solid <?php echo $options['background'] ?>; border-bottom: 15px solid <?php echo $options['background'] ?>; border-left: 25px solid <?php echo $options['background'] ?>; border-right: 25px solid <?php echo $options['background'] ?>; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; display: inline-block;"><?php echo $options['text'] ?></a>
36
+
37
+ </td>
38
+ </tr>
39
+ </table>
emails/{tnp-composer/blocks/content-04-cta.block.png → blocks/cta/icon.png} RENAMED
File without changes
emails/blocks/cta/options.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $options array contains all the options the current block we're ediging contains */
3
+ /* @var $controls NewsletterControls */
4
+ ?>
5
+
6
+ <table class="form-table">
7
+ <tr>
8
+ <th>Text</th>
9
+ <td>
10
+ <?php $controls->text('text') ?>
11
+ </td>
12
+ </tr>
13
+ <tr>
14
+ <th>Button color</th>
15
+ <td>
16
+ <?php $controls->color('background') ?>
17
+ </td>
18
+ </tr>
19
+ <tr>
20
+ <th>Text color</th>
21
+ <td>
22
+ <?php $controls->color('color') ?>
23
+ </td>
24
+ </tr>
25
+ <tr>
26
+ <th>Link to</th>
27
+ <td>
28
+ <?php $controls->text('url', 50, 'https://...') ?>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <th>Font size</th>
33
+ <td>
34
+ <?php $controls->css_font_size('font_size') ?>
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <th>Font family</th>
39
+ <td>
40
+ <?php $controls->css_font_family('font_family') ?>
41
+ </td>
42
+ </tr>
43
+ </table>
emails/blocks/preheader/block.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Name: Preheader
4
+ * Section: header
5
+ * Description: Preheader
6
+ *
7
+ */
8
+
9
+ /* @var $options array */
10
+ /* @var $wpdb wpdb */
11
+
12
+
13
+
14
+ if (empty($options['view'])) {
15
+ $options['view'] = 'View online';
16
+ }
17
+ if (empty($options['text'])) {
18
+ $options['text'] = 'Few words summary';
19
+ }
20
+ ?>
21
+
22
+
23
+ <table border="0" cellpadding="0" cellspacing="0" width="750" class="responsive-table" style="max-width: 100%!important">
24
+ <tr>
25
+ <td style="padding: 20px; text-align: center; font-size: 13px!important; color: #444;" width="50%" valign="top" align="center">
26
+ <?php echo $options['text']?>
27
+ </td>
28
+ <td style="padding: 20px; text-align: center;" width="50%" valign="top" align="center">
29
+ <a href="{email_url}" target="_blank" rel="noopener" style="text-decoration: none; color: #444; font-size: 13px!important;"><?php echo $options['view']?></a>
30
+ </td>
31
+ </tr>
32
+ </table>
emails/blocks/preheader/icon.png ADDED
Binary file
emails/blocks/preheader/options.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $options array contains all the options the current block we're ediging contains */
3
+ /* @var $controls NewsletterControls */
4
+ ?>
5
+
6
+ <table class="form-table">
7
+ <tr>
8
+ <th><?php _e('Text', 'newsletter') ?></th>
9
+ <td>
10
+ <?php $controls->text('text', 70) ?>
11
+ </td>
12
+ </tr>
13
+ <tr>
14
+ <th><?php _e('View', 'newsletter') ?></th>
15
+ <td>
16
+ <?php $controls->text('view', 70) ?>
17
+ </td>
18
+ </tr>
19
+ </table>
emails/blocks/separator/block.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Name: Separator
4
+ * Section: content
5
+ * Description: Separator
6
+ *
7
+ */
8
+
9
+ /* @var $options array */
10
+ /* @var $wpdb wpdb */
11
+
12
+
13
+
14
+ if (empty($options['color'])) {
15
+ $options['color'] = '#dddddd';
16
+ }
17
+ if (empty($options['height'])) {
18
+ $options['height'] = 1;
19
+ }
20
+ ?>
21
+
22
+
23
+ <table border="0" cellpadding="0" cellspacing="0" width="750" class="responsive-table" style="max-width: 100%!important">
24
+ <tr>
25
+ <td style="padding: 20px;" bgcolor="<?php echo $options['background'] ?>">
26
+ <div style="height: <?php echo $options['height'] ?>px!important; background-color: <?php echo $options['color'] ?>; border: 0; margin:0; padding: 0; line-height: 0; width: 100%!important; display: block;"></div>
27
+ </td>
28
+ </tr>
29
+ </table>
emails/blocks/separator/icon.png ADDED
Binary file
emails/blocks/separator/options.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $options array contains all the options the current block we're ediging contains */
3
+ /* @var $controls NewsletterControls */
4
+ ?>
5
+
6
+ <table class="form-table">
7
+
8
+ <tr>
9
+ <th><?php _e('Color', 'newsletter')?></th>
10
+ <td>
11
+ <?php $controls->color('color') ?>
12
+ </td>
13
+ </tr>
14
+ <!--
15
+ <tr>
16
+ <th>Link to</th>
17
+ <td>
18
+ <?php $controls->text('url', 50, 'https://...') ?>
19
+ </td>
20
+ </tr>
21
+ -->
22
+ <tr>
23
+ <th><?php _e('Height', 'newsletter')?></th>
24
+ <td>
25
+ <?php $controls->select('height', array('1'=>1, '2'=>2, '3'=>3, '4'=>4, '5'=>5)) ?>
26
+ </td>
27
+ </tr>
28
+ </table>
emails/composer.php CHANGED
@@ -1,12 +1,11 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
6
  $module = NewsletterEmails::instance();
7
- // Add the color picker css file
8
  wp_enqueue_style('wp-color-picker');
9
- // Include our custom jQuery file with WordPress Color Picker dependency
10
  wp_enqueue_script('wp-color-picker');
11
 
12
  // TNP Composer style
@@ -14,7 +13,7 @@ wp_enqueue_style('tnpc-style', plugins_url('/tnp-composer/_css/newsletter-builde
14
  //wp_enqueue_style('tnpc-newsletter-style', plugins_url('/tnp-composer/css/newsletter.css', __FILE__));
15
  wp_enqueue_style('tnpc-newsletter-style', home_url('/') . '?na=emails-composer-css');
16
 
17
- if (($controls->is_action('save') || $controls->is_action('preview')) && !$_GET['id']) {
18
 
19
  $module->save_options($controls->data);
20
 
@@ -39,7 +38,7 @@ To change your subscription follow: {profile_url}.';
39
  $email['type'] = 'message';
40
  $email['send_on'] = time();
41
  $email['query'] = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
42
-
43
  $email = Newsletter::instance()->save_email($email, ARRAY_A);
44
  } elseif (isset($_GET['id'])) {
45
 
@@ -61,10 +60,10 @@ To change your subscription follow: {profile_url}.';
61
  if ($controls->is_action('preview')) {
62
  ?>
63
  <script>
64
- location.href = "<?php echo $module->get_admin_page_url('cpreview'); ?>&id=<?php echo $email['id']; ?>";
65
  </script>
66
  <div class="wrap">
67
- <p><a href="<?php echo $module->get_admin_page_url('cpreview'); ?>&id=<?php echo $email['id']; ?>">click here to proceed</a>.</p>
68
  </div>
69
  <?php
70
  return;
@@ -74,37 +73,33 @@ if ($controls->data == null) {
74
  $controls->data = $module->get_options();
75
  }
76
 
77
- //$body = $controls->data['body'];
78
  $body = "";
79
  if (isset($email)) {
80
  $body = $email['message'];
81
- }
82
-
83
  ?>
84
 
85
- <div class="wrap" id="tnp-wrap">
86
-
87
- <?php $help_url = 'https://www.thenewsletterplugin.com/plugins/newsletter/newsletters-module'; ?>
88
- <?php //include NEWSLETTER_DIR . '/tnp-header.php'; ?>
89
 
90
  <div id="tnp-heading" class="tnp-composer-heading">
91
-
92
- <img src="https://cdn.thenewsletterplugin.com/tests/tnp-composer-heading.png">
93
- <h2><?php _e('Compose a newsletter', 'newsletter') ?></h2>
94
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/composer" target="_blank"><i class="fa fa-life-ring"></i> <?php _e('Read the guide', 'newsletter') ?></a>
 
95
  <form method="post" action="" id="tnpc-form">
96
  <?php $controls->init(); ?>
97
  <?php $controls->hidden('subject'); ?>
98
  <?php $controls->hidden('body'); ?>
99
  <?php $controls->button_reset(); ?>
100
- <?php $controls->button('save', __('Save','newsletter'), 'create();'); ?>
101
- <?php $controls->button('preview', __('Save & Preview','newsletter') . ' &raquo;', 'create();'); ?>
102
  </form>
103
  </div>
104
 
105
 
106
 
107
- <?php include NEWSLETTER_DIR . '/emails/tnp-composer/index.php'; ?>
108
 
109
 
110
  </div>
1
  <?php
2
+ defined('ABSPATH') || exit;
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
6
  $module = NewsletterEmails::instance();
7
+
8
  wp_enqueue_style('wp-color-picker');
 
9
  wp_enqueue_script('wp-color-picker');
10
 
11
  // TNP Composer style
13
  //wp_enqueue_style('tnpc-newsletter-style', plugins_url('/tnp-composer/css/newsletter.css', __FILE__));
14
  wp_enqueue_style('tnpc-newsletter-style', home_url('/') . '?na=emails-composer-css');
15
 
16
+ if (($controls->is_action('save') || $controls->is_action('preview')) && !isset($_GET['id'])) {
17
 
18
  $module->save_options($controls->data);
19
 
38
  $email['type'] = 'message';
39
  $email['send_on'] = time();
40
  $email['query'] = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
41
+
42
  $email = Newsletter::instance()->save_email($email, ARRAY_A);
43
  } elseif (isset($_GET['id'])) {
44
 
60
  if ($controls->is_action('preview')) {
61
  ?>
62
  <script>
63
+ location.href = "<?php echo $module->get_admin_page_url('edit'); ?>&id=<?php echo $email['id']; ?>";
64
  </script>
65
  <div class="wrap">
66
+ <p><a href="<?php echo $module->get_admin_page_url('edit'); ?>&id=<?php echo $email['id']; ?>">click here to proceed</a>.</p>
67
  </div>
68
  <?php
69
  return;
73
  $controls->data = $module->get_options();
74
  }
75
 
 
76
  $body = "";
77
  if (isset($email)) {
78
  $body = $email['message'];
79
+ }
 
80
  ?>
81
 
82
+ <div class="wrap tnp-emails-composer" id="tnp-wrap">
 
 
 
83
 
84
  <div id="tnp-heading" class="tnp-composer-heading">
85
+ <!--
86
+ <img src="https://cdn.thenewsletterplugin.com/tests/tnp-composer-heading.png">
87
+ <h2><?php _e('Compose a newsletter', 'newsletter') ?></h2>
88
+ <a href="https://www.thenewsletterplugin.com/plugins/newsletter/composer" target="_blank"><i class="fa fa-life-ring"></i> <?php _e('Read the guide', 'newsletter') ?></a>
89
+ -->
90
  <form method="post" action="" id="tnpc-form">
91
  <?php $controls->init(); ?>
92
  <?php $controls->hidden('subject'); ?>
93
  <?php $controls->hidden('body'); ?>
94
  <?php $controls->button_reset(); ?>
95
+ <?php $controls->button('save', __('Save', 'newsletter'), 'create();'); ?>
96
+ <?php $controls->button('preview', __('Save & Preview', 'newsletter') . ' &raquo;', 'create();'); ?>
97
  </form>
98
  </div>
99
 
100
 
101
 
102
+ <?php include NEWSLETTER_DIR . '/emails/tnp-composer/index.php'; ?>
103
 
104
 
105
  </div>
emails/cpreview.php DELETED
@@ -1,517 +0,0 @@
1
- <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
-
5
- require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
- $controls = new NewsletterControls();
7
- $module = NewsletterEmails::instance();
8
-
9
- // Always required
10
- $email = Newsletter::instance()->get_email((int) $_GET['id'], ARRAY_A);
11
- $email['options'] = maybe_unserialize($email['options']);
12
- if (!is_array($email['options']))
13
- $email['options'] = array();
14
-
15
- // TNP Composer style
16
- wp_enqueue_style('tnpc-style', plugins_url('/tnp-composer/_css/newsletter-builder.css', __FILE__));
17
-
18
- if (empty($email)) {
19
- echo 'Wrong email identifier';
20
- return;
21
- }
22
- $email_id = $email['id'];
23
-
24
- // If there is no action we assume we are enter the first time so we populate the
25
- // $nc->data with the editable email fields
26
- if (!$controls->is_action()) {
27
- $controls->data = $email;
28
- if (!empty($email['preferences'])) {
29
- $controls->data['preferences'] = explode(',', $email['preferences']);
30
- }
31
- if (!empty($email['sex'])) {
32
- $controls->data['sex'] = explode(',', $email['sex']);
33
- }
34
-
35
- $controls->data = array_merge($controls->data, $email['options']);
36
-
37
- foreach ($email['options'] as $name => $value) {
38
- $controls->data['options_' . $name] = $value;
39
- }
40
- }
41
-
42
- if ($controls->is_action('change-private')) {
43
- $data = array();
44
- $data['private'] = $controls->data['private'] ? 0 : 1;
45
- $data['id'] = $email['id'];
46
- Newsletter::instance()->save_email($data);
47
- $controls->add_message_saved();
48
- $controls->data = $email;
49
- $controls->data['private'] = $data['private'];
50
- }
51
-
52
-
53
- if ($controls->is_action('test') || $controls->is_action('save') || $controls->is_action('send') || $controls->is_action('editor')) {
54
-
55
- // If we were editing with visual editor (==0), we must read the extra <body> content
56
- if ($email['editor'] == 0) {
57
- // no editing possible, just preview
58
- } else {
59
- $email['message'] = $controls->data['message'];
60
- }
61
-
62
- $email['message_text'] = $controls->data['message_text'];
63
- $email['subject'] = $controls->data['subject'];
64
- $email['track'] = $controls->data['track'];
65
- $email['private'] = $controls->data['private'];
66
-
67
- // Builds the extended options
68
- //$email['options'] = array();
69
- $email['options']['preferences_status'] = $controls->data['preferences_status'];
70
- if (isset($controls->data['preferences'])) {
71
- $email['options']['preferences'] = $controls->data['preferences'];
72
- } else {
73
- $email['options']['preferences'] = array();
74
- }
75
- if (isset($controls->data['sex'])) {
76
- $email['options']['sex'] = $controls->data['sex'];
77
- } else {
78
- $email['options']['sex'] = array();
79
- }
80
-
81
- foreach ($controls->data as $name => $value) {
82
- if (strpos($name, 'options_') === 0) {
83
- $email['options'][substr($name, 8)] = $value;
84
- }
85
- }
86
-
87
- $email['options']['status'] = $controls->data['status'];
88
- $email['options']['preferences_status_operator'] = $controls->data['preferences_status_operator'];
89
- $email['options']['wp_users'] = $controls->data['wp_users'];
90
- $email['options']['composer'] = true;
91
-
92
- $email['options'] = serialize($email['options']);
93
-
94
- if (isset($controls->data['preferences'])) {
95
- $email['preferences'] = implode(',', $controls->data['preferences']);
96
- } else {
97
- $email['preferences'] = '';
98
- }
99
-
100
- if (isset($controls->data['sex'])) {
101
- $email['sex'] = implode(',', $controls->data['sex']);
102
- } else {
103
- $email['sex'] = '';
104
- }
105
-
106
- // Before send, we build the query to extract subscriber, so the delivery engine does not
107
- // have to worry about the email parameters
108
- if ($controls->data['status'] == 'S') {
109
- $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='S'";
110
- } else {
111
- $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
112
- }
113
-
114
- if ($controls->data['wp_users'] == '1') {
115
- $query .= " and wp_user_id<>0";
116
- }
117
-
118
-
119
- if (isset($controls->data['preferences'])) {
120
- $preferences = $controls->data['preferences'];
121
-
122
- // Not set one of the preferences specified
123
- $operator = $controls->data['preferences_status_operator'] == 0 ? ' or ' : ' and ';
124
- if ($controls->data['preferences_status'] == 1) {
125
- $query .= " and (";
126
- foreach ($preferences as $x) {
127
- $query .= "list_" . ((int) $x) . "=0" . $operator;
128
- }
129
- $query = substr($query, 0, -4);
130
- $query .= ")";
131
- } else {
132
- $query .= " and (";
133
- foreach ($preferences as $x) {
134
- $query .= "list_" . ((int) $x) . "=1" . $operator;
135
- }
136
- $query = substr($query, 0, -4);
137
- $query .= ")";
138
- }
139
- }
140
-
141
- if (isset($controls->data['sex'])) {
142
- $sex = $controls->data['sex'];
143
- if (is_array($sex)) {
144
- $query .= " and sex in (";
145
- foreach ($sex as $x) {
146
- $query .= "'" . esc_sql($x) . "', ";
147
- }
148
- $query = substr($query, 0, -2);
149
- $query .= ")";
150
- }
151
- }
152
-
153
- $res = Newsletter::instance()->save_email($email);
154
-
155
- $e = $module->get_email($email_id);
156
- $e->options = maybe_unserialize($e->options);
157
- $query = apply_filters('newsletter_emails_email_query', $query, $e);
158
-
159
- $email['query'] = $query;
160
- if ($email['status'] == 'sent') {
161
- $email['total'] = $email['sent'];
162
- } else {
163
- $email['total'] = $wpdb->get_var(str_replace('*', 'count(*)', $query));
164
- }
165
- if ($controls->is_action('send') && $controls->data['send_on'] < time()) {
166
- $controls->data['send_on'] = time();
167
- }
168
- $email['send_on'] = $controls->data['send_on'];
169
-
170
- if ($controls->is_action('editor')) {
171
- $email['editor'] = $email['editor'] == 0 ? 1 : 0;
172
- }
173
-
174
- // Cleans up of tag
175
- $email['message'] = NewsletterModule::clean_url_tags($email['message']);
176
-
177
- $res = Newsletter::instance()->save_email($email);
178
- if ($res === false) {
179
- $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
180
- }
181
-
182
- $controls->data['message'] = $email['message'];
183
-
184
- $controls->add_message_saved();
185
- }
186
-
187
- if ($controls->is_action('send')) {
188
- // Todo subject check
189
- if ($email['subject'] == '') {
190
- $controls->errors = __('A subject is required to send', 'newsletter');
191
- } else {
192
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
193
- $email['status'] = 'sending';
194
- $controls->messages .= __('Now sending, see the progress on newsletter list', 'newsletter');
195
- }
196
- }
197
-
198
- if ($controls->is_action('pause')) {
199
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'paused'), array('id' => $email_id));
200
- $email['status'] = 'paused';
201
- }
202
-
203
- if ($controls->is_action('continue')) {
204
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
205
- $email['status'] = 'sending';
206
- }
207
-
208
- if ($controls->is_action('abort')) {
209
- $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set last_id=0, sent=0, status='new' where id=" . $email_id);
210
- $email['status'] = 'new';
211
- $email['sent'] = 0;
212
- $email['last_id'] = 0;
213
- $controls->messages = __('Delivery definitively cancelled', 'newsletter');
214
- }
215
-
216
- if ($controls->is_action('test')) {
217
- if ($email['subject'] == '') {
218
- $controls->errors = __('A subject is required to send', 'newsletter');
219
- } else {
220
- $users = NewsletterUsers::instance()->get_test_users();
221
- if (count($users) == 0) {
222
- $controls->messages = '<strong>' . __('There are no test subscribers to send to', 'newsletter') . '</strong>';
223
- } else {
224
- Newsletter::instance()->send(Newsletter::instance()->get_email($email_id), $users);
225
- $controls->messages = __('Test newsletter sent to:', 'newsletter');
226
- foreach ($users as &$user) {
227
- $controls->messages .= ' ' . $user->email;
228
- }
229
- $controls->messages .= '.';
230
- }
231
-
232
- $controls->messages .= '<br>';
233
- $controls->messages .= '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank">' .
234
- __('Read more about test subscribers', 'newsletter') . '</a>.';
235
-
236
- $controls->messages .= '<br>If diagnostic emails are delivered but test emails are not, try to change the encoding to "base 64" on main configuration panel';
237
- }
238
- }
239
-
240
- //$template = '{message}';
241
- //
242
- //if ($email['editor'] == 0) {
243
- // $x = strpos($controls->data['message'], '<body');
244
- // // Some time the message in $nc->data is already cleaned up, it depends on action called
245
- // if ($x !== false) {
246
- // $x = strpos($controls->data['message'], '>', $x);
247
- // $y = strpos($controls->data['message'], '</body>');
248
- //
249
- // $template = substr($controls->data['message'], 0, $x) . '{message}' . substr($controls->data['message'], $y);
250
- // $controls->data['message'] = substr($controls->data['message'], $x + 1, $y - $x - 1);
251
- // }
252
- //}
253
- ?>
254
- <style>
255
- #options-subject {
256
- font-size: 20px;
257
- display: inline-block;
258
- margin-bottom: 10px;
259
- width: 100%;
260
- }
261
- </style>
262
- <div class="wrap" id="tnp-wrap">
263
-
264
- <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
265
-
266
- <div id="tnp-heading">
267
-
268
- <h2><?php _e('Preview Newsletter', 'newsletter') ?></h2>
269
-
270
- </div>
271
-
272
- <div id="tnp-body">
273
-
274
- <?php
275
- if ($controls->data['status'] == 'S') {
276
- echo '<div class="newsletter-message">Warning! This email is configured to be sent to NOT CONFIRMED subscribers.</div>';
277
- }
278
- ?>
279
-
280
- <form method="post" action="" id="newsletter-form">
281
-
282
- <?php $controls->init(array('cookie_name' => 'newsletter_emails_edit_tab')); ?>
283
-
284
- <p class="submit">
285
- <?php $controls->button_back('?page=newsletter_emails_composer&id=' . $email['id']) ?>
286
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_save(); ?>
287
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('test', 'Save and test', 'Save and send test emails to test addresses?'); ?>
288
-
289
- <?php if ($email['status'] == 'new') $controls->button_confirm('send', __('Send', 'newsletter'), __('Start real delivery?', 'newsletter')); ?>
290
- <?php if ($email['status'] == 'sending') $controls->button_confirm('pause', __('Pause', 'newsletter'), __('Pause the delivery?', 'newsletter')); ?>
291
- <?php if ($email['status'] == 'paused') $controls->button_confirm('continue', __('Continue', 'newsletter'), 'Continue the delivery?'); ?>
292
- <?php if ($email['status'] == 'paused') $controls->button_confirm('abort', __('Stop', 'newsletter'), __('This totally stop the delivery, ok?', 'newsletter')); ?>
293
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('editor', 'Save and switch to ' . ($email['editor'] == 0 ? 'HTML source editor' : 'Preview'), 'Sure?'); ?>
294
- </p>
295
-
296
- <?php $controls->text('subject', 70, 'Subject'); ?>
297
-
298
- <div id="tabs">
299
- <ul>
300
- <li><a href="#tabs-a"><?php _e('Message', 'newsletter') ?></a></li>
301
- <li><a href="#tabs-b"><?php _e('Message (textual)', 'newsletter') ?></a></li>
302
- <li><a href="#tabs-c"><?php _e('Targeting', 'newsletter') ?></a></li>
303
- <li><a href="#tabs-d"><?php _e('Other', 'newsletter') ?></a></li>
304
- <li><a href="#tabs-status"><?php _e('Status', 'newsletter') ?></a></li>
305
- </ul>
306
-
307
-
308
- <div id="tabs-a">
309
-
310
- <?php if ($email['editor'] == 0) { ?>
311
-
312
- <div class="tnpc-preview">
313
- <!-- Flat Laptop Browser -->
314
- <div class="fake-browser-ui">
315
- <div class="frame">
316
- <span class="bt-1"></span>
317
- <span class="bt-2"></span>
318
- <span class="bt-3"></span>
319
- </div>
320
- <iframe id="tnpc-preview-desktop" src="" width="700" height="507" alt="Test" frameborder="0"></iframe>
321
- </div>
322
-
323
- <!-- Flat Mobile Browser -->
324
- <div class="fake-mobile-browser-ui">
325
- <iframe id="tnpc-preview-mobile" src="" width="250" height="445" alt="Test" frameborder="0"></iframe>
326
- <div class="frame">
327
- <span class="bt-4"></span>
328
- </div>
329
- </div>
330
- </div>
331
-
332
- <script type="text/javascript">
333
- preview_url = ajaxurl + "?action=tnpc_preview&id=<?php echo $email_id ?>";
334
- jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').attr("src", preview_url);
335
- setTimeout(function () {
336
- jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').contents().find("a").click(function (e) {
337
- e.preventDefault();
338
- })
339
- }, 500);
340
- </script>
341
-
342
- <?php } else { ?>
343
- <?php include __DIR__ . '/edit-html.php'; ?>
344
- <?php } ?>
345
-
346
- </div>
347
-
348
-
349
- <div id="tabs-b">
350
- <p>
351
- This is the textual version of your newsletter. If you empty it, only an HTML version will be sent but
352
- is an anti-spam best practice to include a text only version.
353
- </p>
354
-
355
- <?php $controls->textarea_fixed('message_text', '100%', '500'); ?>
356
- </div>
357
-
358
-
359
- <div id="tabs-c">
360
- <table class="form-table">
361
-
362
- <tr valign="top">
363
- <th><?php _e('Gender', 'newsletter'); ?></th>
364
- <td>
365
- <?php $controls->checkboxes_group('sex', array('f' => 'Women', 'm' => 'Men', 'n' => 'Not specified')); ?>
366
- <p class="description">
367
- Leaving all gender options unselected disable this filter.
368
- </p>
369
- </td>
370
- </tr>
371
- <tr valign="top">
372
- <th><?php _e('Lists', 'newsletter'); ?></th>
373
- <td>
374
- Subscribers with
375
- <?php $controls->select('preferences_status_operator', array(0 => 'at least one list', 1 => 'all lists')); ?>
376
-
377
- <?php $controls->select('preferences_status', array(0 => 'active', 1 => 'not active')); ?>
378
- <?php _e('checked below', 'newsletter') ?>
379
-
380
- <?php $controls->preferences_group('preferences', true); ?>
381
- <p class="description">
382
- You can address the newsletter to subscribers who selected at least one of the options or to who
383
- has not selected at least one of the options.
384
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Read more about the "NOT ACTIVE" usage</a>.
385
- </p>
386
- </td>
387
- </tr>
388
-
389
- <tr valign="top">
390
- <th><?php _e('Status', 'newsletter') ?></th>
391
- <td>
392
- <?php $controls->select('status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'))); ?>
393
-
394
- <p class="description">
395
- <?php _e('Send to not confirmed subscribers ONLY to ask for confirmation including the {subscription_confirm_url} tag.', 'newsletter') ?>
396
- </p>
397
- </td>
398
- </tr>
399
- <tr valign="top">
400
- <th>Only to WordPress users?</th>
401
- <td>
402
- <?php $controls->yesno('wp_users'); ?>
403
-
404
- <p class="description">
405
- Limit to the subscribers which are WordPress users as well.
406
- </p>
407
- </td>
408
- </tr>
409
- <tr valign="top">
410
- <th>
411
- <?php _e('Subscribers count', 'newsletter') ?>
412
- </th>
413
- <td>
414
- <?php
415
- if ($email['status'] != 'sent') {
416
- echo $wpdb->get_var(str_replace('*', 'count(*)', $email['query']));
417
- } else {
418
- echo $email['sent'];
419
- }
420
- ?>
421
- <p class="description">
422
- <?php _e('Save to update if on targeting filters have been changed', 'newsletter') ?>
423
- </p>
424
- </td>
425
- </tr>
426
- </table>
427
-
428
- <?php do_action('newsletter_emails_edit_target', $module->get_email($email_id), $controls) ?>
429
- </div>
430
-
431
-
432
- <div id="tabs-d">
433
- <table class="form-table">
434
- <tr valign="top">
435
- <th><?php _e('Keep private', 'newsletter') ?></th>
436
- <td>
437
- <?php $controls->yesno('private'); ?>
438
- <?php if ($email['status'] == 'sent') { ?>
439
- <?php $controls->button('change-private', __('Toggle'))?>
440
- <?php } ?>
441
- <p class="description">
442
- <?php _e('Hide/show from public sent newsletter list.', 'newsletter') ?>
443
- <?php _e('Required', 'newsletter') ?>: <a href="" target="_blank">Newsletter Archive Extension</a>
444
- </p>
445
- </td>
446
- </tr>
447
- <tr valign="top">
448
- <th><?php _e('Track clicks and message opening', 'newsletter') ?></th>
449
- <td>
450
- <?php $controls->yesno('track'); ?>
451
- </td>
452
- </tr>
453
- <tr valign="top">
454
- <th><?php _e('Send on', 'newsletter') ?></th>
455
- <td>
456
- <?php $controls->datetime('send_on'); ?> (now: <?php echo date_i18n(get_option('date_format') . ' ' . get_option('time_format')); ?>)
457
- <p class="description">
458
- If the current date and time are wrong, check your timezone on the General WordPress settings.
459
- </p>
460
- </td>
461
- </tr>
462
- </table>
463
-
464
- <?php do_action('newsletter_emails_edit_other', $module->get_email($email_id), $controls) ?>
465
- </div>
466
-
467
- <div id="tabs-status">
468
- <table class="form-table">
469
- <tr valign="top">
470
- <th>Email status</th>
471
- <td><?php echo esc_html($email['status']); ?></td>
472
- </tr>
473
- <tr valign="top">
474
- <th>Messages sent</th>
475
- <td><?php echo $email['sent'] ?> of <?php echo $email['total'] ?></td>
476
- </tr>
477
- <tr valign="top">
478
- <th>Query (tech)</th>
479
- <td><?php echo esc_html($email['query']) ?></td>
480
- </tr>
481
- <tr valign="top">
482
- <th>Token (tech)</th>
483
- <td><?php echo esc_html($email['token']) ?></td>
484
- </tr>
485
- </table>
486
- </div>
487
-
488
- <!--
489
- <div id="tabs-5">
490
- <p>Tags documented below can be used on newsletter body. Some of them can be used on subject as well.</p>
491
-
492
- <p>
493
- Special tags, like the preference setting tag, can be used to highly interact with your subscribers, see
494
- the Newsletter Preferences page for examples.
495
- </p>
496
- --
497
-
498
- <dl>
499
- <dt>{set_preference_N}</dt>
500
- <dd>
501
- This tag creates a URL which, once clicked, set the preference numner N on the user profile and redirecting the
502
- subscriber to his profile panel. Preferences can be configured on Subscription/Form fields panel.
503
- </dd>
504
- </dl>
505
-
506
- </ul>
507
- </div>
508
- -->
509
-
510
- </div>
511
-
512
- </form>
513
- </div>
514
-
515
- <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
516
-
517
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/edit-composer.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <a class="button-primary" href="?page=newsletter_emails_composer&id=<?php echo $email['id'] ?>"><?php _e('Edit', 'newsletter') ?></a>
2
+ <div class="tnpc-preview">
3
+ <!-- Flat Laptop Browser -->
4
+ <div class="fake-browser-ui">
5
+ <div class="frame">
6
+ <span class="bt-1"></span>
7
+ <span class="bt-2"></span>
8
+ <span class="bt-3"></span>
9
+ </div>
10
+ <iframe id="tnpc-preview-desktop" src="" width="700" height="507" alt="Test" frameborder="0"></iframe>
11
+ </div>
12
+
13
+ <!-- Flat Mobile Browser -->
14
+ <div class="fake-mobile-browser-ui">
15
+ <iframe id="tnpc-preview-mobile" src="" width="250" height="445" alt="Test" frameborder="0"></iframe>
16
+ <div class="frame">
17
+ <span class="bt-4"></span>
18
+ </div>
19
+ </div>
20
+ </div>
21
+
22
+ <script type="text/javascript">
23
+ preview_url = ajaxurl + "?action=tnpc_preview&id=<?php echo $email_id ?>";
24
+ jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').attr("src", preview_url);
25
+ setTimeout(function () {
26
+ jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').contents().find("a").click(function (e) {
27
+ e.preventDefault();
28
+ })
29
+ }, 500);
30
+ </script>
emails/edit-editor.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.3/tinymce.min.js"></script>
2
+ <script type="text/javascript">
3
+ var template = <?php echo json_encode($template) ?>;
4
+
5
+ // https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
6
+ tinymce.init({
7
+ height: 700,
8
+ mode: "specific_textareas",
9
+ editor_selector: "visual",
10
+ statusbar: true,
11
+ allow_conditional_comments: true,
12
+ table_toolbar: "tableprops tablecellprops tabledelete | tableinsertrowbefore tableinsertrowafter tabledeleterow | " +
13
+ "tableinsertcolbefore tableinsertcolafter tabledeletecol",
14
+ toolbar: "formatselect fontselect fontsizeselect | bold italic underline strikethrough forecolor backcolor | alignleft alignright aligncenter alignjustify | bullist numlist | link unlink | image",
15
+ //theme: "advanced",
16
+ entity_encoding: "raw",
17
+ image_advtab: true,
18
+ image_title: true,
19
+ plugins: "table fullscreen legacyoutput textcolor colorpicker link image code lists advlist",
20
+ relative_urls: false,
21
+ remove_script_host: false,
22
+ document_base_url: "<?php echo esc_js(get_option('home')) ?>/",
23
+ content_css: ["<?php echo plugins_url('newsletter') ?>/emails/editor.css", "<?php echo home_url('/') . '?na=emails-css&id=' . $email_id . '&' . time(); ?>"]
24
+ });
25
+
26
+ </script>
27
+ <script>
28
+ function tnp_media() {
29
+ var tnp_uploader = wp.media({
30
+ title: "Select an image",
31
+ button: {
32
+ text: "Select"
33
+ },
34
+ frame: 'post',
35
+ multiple: false,
36
+ displaySetting: true,
37
+ displayUserSettings: true
38
+ }).on("insert", function () {
39
+ wp.media;
40
+ var media = tnp_uploader.state().get("selection").first();
41
+ if (media.attributes.url.indexOf("http") !== 0)
42
+ media.attributes.url = "http:" + media.attributes.url;
43
+
44
+ if (!media.attributes.mime.startsWith("image")) {
45
+
46
+ tinyMCE.execCommand('mceInsertLink', false, media.attributes.url);
47
+
48
+ } else {
49
+ var display = tnp_uploader.state().display(media);
50
+ var url = media.attributes.sizes[display.attributes.size].url;
51
+
52
+ tinyMCE.execCommand('mceInsertContent', false, '<img src="' + url + '" style="max-width: 100%">');
53
+
54
+ }
55
+ }).open();
56
+ }
57
+
58
+ </script>
59
+ <input type="button" class="button-primary" value="Add media" onclick="tnp_media()">
60
+
61
+ <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-tags" target="_blank"><?php _e('Available tags', 'newsletter') ?></a>
62
+ <br><br>
63
+
64
+ <?php $controls->editor('message', 30); ?>
emails/edit-html.php CHANGED
@@ -25,6 +25,39 @@
25
  });
26
  </script>
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  <input class="button-primary" type="button" onclick="newsletter_textarea_preview('options-message'); return false;" value="Switch editor/preview">
29
 
30
  <input type="button" class="button-primary" value="Add media" onclick="tnp_media()">
25
  });
26
  </script>
27
 
28
+ <script>
29
+ function tnp_media(name) {
30
+ var tnp_uploader = wp.media({
31
+ title: "Select an image",
32
+ button: {
33
+ text: "Select"
34
+ },
35
+ frame: 'post',
36
+ multiple: false,
37
+ displaySetting: true,
38
+ displayUserSettings: true
39
+ }).on("insert", function () {
40
+ wp.media;
41
+ var media = tnp_uploader.state().get("selection").first();
42
+ if (media.attributes.url.indexOf("http") !== 0)
43
+ media.attributes.url = "http:" + media.attributes.url;
44
+
45
+ if (!media.attributes.mime.startsWith("image")) {
46
+
47
+ templateEditor.getDoc().replaceRange(url, templateEditor.getDoc().getCursor());
48
+
49
+ } else {
50
+ var display = tnp_uploader.state().display(media);
51
+ var url = media.attributes.sizes[display.attributes.size].url;
52
+
53
+ templateEditor.getDoc().replaceRange('<img src="' + url + '">', templateEditor.getDoc().getCursor());
54
+
55
+ }
56
+ }).open();
57
+ }
58
+
59
+ </script>
60
+
61
  <input class="button-primary" type="button" onclick="newsletter_textarea_preview('options-message'); return false;" value="Switch editor/preview">
62
 
63
  <input type="button" class="button-primary" value="Add media" onclick="tnp_media()">
emails/edit.php CHANGED
@@ -5,29 +5,50 @@ $controls = new NewsletterControls();
5
  $module = NewsletterEmails::instance();
6
 
7
  // Always required
8
- $email = Newsletter::instance()->get_email((int) $_GET['id'], ARRAY_A);
9
- $email['options'] = maybe_unserialize($email['options']);
10
- if (!is_array($email['options']))
11
- $email['options'] = array();
12
 
13
  if (empty($email)) {
14
  echo 'Wrong email identifier';
15
  return;
16
  }
 
17
  $email_id = $email['id'];
18
 
19
- // If there is no action we assume we are enter the first time so we populate the
20
- // $nc->data with the editable email fields
21
- if (!$controls->is_action()) {
22
- $controls->data = $email;
23
- if (!empty($email['preferences'])) {
24
- $controls->data['preferences'] = explode(',', $email['preferences']);
 
 
 
 
 
 
 
 
 
25
  }
26
- if (!empty($email['sex'])) {
27
- $controls->data['sex'] = explode(',', $email['sex']);
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
 
29
 
30
- $controls->data = array_merge($controls->data, $email['options']);
 
31
 
32
  foreach ($email['options'] as $name => $value) {
33
  $controls->data['options_' . $name] = $value;
@@ -38,25 +59,33 @@ if ($controls->is_action('change-private')) {
38
  $data = array();
39
  $data['private'] = $controls->data['private'] ? 0 : 1;
40
  $data['id'] = $email['id'];
41
- Newsletter::instance()->save_email($data);
42
  $controls->add_message_saved();
 
43
  $controls->data = $email;
44
- $controls->data['private'] = $data['private'];
 
 
45
  }
46
 
47
  if ($controls->is_action('test') || $controls->is_action('save') || $controls->is_action('send') || $controls->is_action('editor')) {
48
 
49
 
50
  // If we were editing with visual editor (==0), we must read the extra <body> content
51
- $controls->data['message'] = str_ireplace('<script', '<noscript', $controls->data['message']);
52
- $controls->data['message'] = str_ireplace('</script', '</noscript', $controls->data['message']);
 
 
 
53
  if ($email['editor'] == 0) {
54
- $x = strpos($email['message'], '<body');
55
- if ($x !== false) {
56
- $x = strpos($email['message'], '>', $x);
57
- $email['message'] = substr($email['message'], 0, $x + 1) . $controls->data['message'] . '</body></html>';
58
- } else {
59
- $email['message'] = '<html><body>' . $controls->data['message'] . '</body></html>';
 
 
60
  }
61
  } else {
62
  $email['message'] = $controls->data['message'];
@@ -66,95 +95,63 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
66
  $email['track'] = $controls->data['track'];
67
  $email['private'] = $controls->data['private'];
68
 
69
- // Builds the extended options
70
- //$email['options'] = array();
71
- $email['options']['preferences_status'] = $controls->data['preferences_status'];
72
- if (isset($controls->data['preferences'])) {
73
- $email['options']['preferences'] = $controls->data['preferences'];
74
- } else {
75
- $email['options']['preferences'] = array();
76
- }
77
- if (isset($controls->data['sex'])) {
78
- $email['options']['sex'] = $controls->data['sex'];
79
- } else {
80
- $email['options']['sex'] = array();
81
- }
82
-
83
  foreach ($controls->data as $name => $value) {
84
  if (strpos($name, 'options_') === 0) {
85
  $email['options'][substr($name, 8)] = $value;
86
  }
87
  }
88
-
89
- $email['options']['status'] = $controls->data['status'];
90
- $email['options']['preferences_status_operator'] = $controls->data['preferences_status_operator'];
91
- $email['options']['wp_users'] = $controls->data['wp_users'];
92
-
93
- $email['options'] = serialize($email['options']);
94
-
95
- if (isset($controls->data['preferences'])) {
96
- $email['preferences'] = implode(',', $controls->data['preferences']);
97
- } else {
98
- $email['preferences'] = '';
99
- }
100
-
101
- if (isset($controls->data['sex'])) {
102
- $email['sex'] = implode(',', $controls->data['sex']);
103
- } else {
104
- $email['sex'] = '';
105
- }
106
 
107
  // Before send, we build the query to extract subscriber, so the delivery engine does not
108
  // have to worry about the email parameters
109
- if ($controls->data['status'] == 'S') {
110
  $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='S'";
111
  } else {
112
  $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
113
  }
114
 
115
- if ($controls->data['wp_users'] == '1') {
116
  $query .= " and wp_user_id<>0";
117
  }
118
 
 
 
 
 
 
119
 
120
- if (isset($controls->data['preferences'])) {
121
- $preferences = $controls->data['preferences'];
122
-
123
- // Not set one of the preferences specified
124
- $operator = $controls->data['preferences_status_operator'] == 0 ? ' or ' : ' and ';
125
- if ($controls->data['preferences_status'] == 1) {
126
- $query .= " and (";
127
- foreach ($preferences as $x) {
128
- $query .= "list_" . ((int) $x) . "=0" . $operator;
129
- }
130
- $query = substr($query, 0, -4);
131
- $query .= ")";
132
  } else {
133
- $query .= " and (";
134
- foreach ($preferences as $x) {
135
- $query .= "list_" . ((int) $x) . "=1" . $operator;
136
- }
137
- $query = substr($query, 0, -4);
138
- $query .= ")";
139
  }
140
  }
141
-
142
- if (isset($controls->data['sex'])) {
143
- $sex = $controls->data['sex'];
 
 
 
 
 
 
 
 
 
144
  if (is_array($sex)) {
145
  $query .= " and sex in (";
146
  foreach ($sex as $x) {
147
- $query .= "'" . esc_sql($x) . "', ";
148
  }
149
  $query = substr($query, 0, -2);
150
  $query .= ")";
151
  }
152
  }
153
 
154
- $res = Newsletter::instance()->save_email($email);
155
 
156
- $e = $module->get_email($email_id);
157
- $e->options = maybe_unserialize($e->options);
158
  $query = apply_filters('newsletter_emails_email_query', $query, $e);
159
 
160
  $email['query'] = $query;
@@ -175,6 +172,9 @@ if ($controls->is_action('test') || $controls->is_action('save') || $controls->i
175
  // Cleans up of tag
176
  $email['message'] = NewsletterModule::clean_url_tags($email['message']);
177
 
 
 
 
178
  $res = Newsletter::instance()->save_email($email);
179
  if ($res === false) {
180
  $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
@@ -233,106 +233,64 @@ if ($controls->is_action('test')) {
233
  $controls->messages .= '<br>';
234
  $controls->messages .= '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank">' .
235
  __('Read more about test subscribers', 'newsletter') . '</a>.';
236
-
237
- $controls->messages .= '<br>If diagnostic emails are delivered but test emails are not, try to change the encoding to "base 64" on main configuration panel';
238
  }
239
  }
240
 
241
- $template = '{message}';
242
  if ($email['editor'] == 0) {
243
- $x = strpos($controls->data['message'], '<body');
244
- // Some time the message in $nc->data is already cleaned up, it depends on action called
245
- if ($x !== false) {
246
- $x = strpos($controls->data['message'], '>', $x);
247
- $y = strpos($controls->data['message'], '</body>');
248
-
249
- $template = substr($controls->data['message'], 0, $x) . '{message}' . substr($controls->data['message'], $y);
250
- $controls->data['message'] = substr($controls->data['message'], $x + 1, $y - $x - 1);
251
- }
252
  }
253
- ?>
254
-
255
-
256
- <?php if ($email['editor'] == 1) { ?>
257
-
258
- <?php } else { ?>
259
-
260
- <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.3/tinymce.min.js"></script>
261
- <script type="text/javascript">
262
- var template = <?php echo json_encode($template) ?>;
263
-
264
- // https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
265
- tinymce.init({
266
- height: 700,
267
- mode: "specific_textareas",
268
- editor_selector: "visual",
269
- statusbar: true,
270
- allow_conditional_comments: true,
271
- table_toolbar: "tableprops tablecellprops tabledelete | tableinsertrowbefore tableinsertrowafter tabledeleterow | " +
272
- "tableinsertcolbefore tableinsertcolafter tabledeletecol",
273
- toolbar: "formatselect fontselect fontsizeselect | bold italic underline strikethrough forecolor backcolor | alignleft alignright aligncenter alignjustify | bullist numlist | link unlink | image",
274
- //theme: "advanced",
275
- entity_encoding: "raw",
276
- image_advtab: true,
277
- image_title: true,
278
- plugins: "table fullscreen legacyoutput textcolor colorpicker link image code lists advlist",
279
- relative_urls: false,
280
- remove_script_host: false,
281
- document_base_url: "<?php echo esc_js(get_option('home')) ?>/",
282
- content_css: ["<?php echo plugins_url('newsletter') ?>/emails/editor.css", "<?php echo home_url('/') . '?na=emails-css&id=' . $email_id . '&' . time(); ?>"]
283
- });
284
-
285
- </script>
286
- <?php } ?>
287
-
288
- <style>
289
- #options-subject {
290
- font-size: 20px;
291
- display: inline-block;
292
- margin-bottom: 10px;
293
- width: 100%;
294
- }
295
 
296
- </style>
297
- <script>
298
- function tnp_media(name) {
299
- var tnp_uploader = wp.media({
300
- title: "Select an image",
301
- button: {
302
- text: "Select"
303
- },
304
- frame: 'post',
305
- multiple: false,
306
- displaySetting: true,
307
- displayUserSettings: true
308
- }).on("insert", function () {
309
- wp.media;
310
- var media = tnp_uploader.state().get("selection").first();
311
- if (media.attributes.url.indexOf("http") !== 0)
312
- media.attributes.url = "http:" + media.attributes.url;
313
-
314
- if (!media.attributes.mime.startsWith("image")) {
315
- if (typeof templateEditor !== "undefined") {
316
- templateEditor.getDoc().replaceRange(url, templateEditor.getDoc().getCursor());
317
- } else {
318
- tinyMCE.execCommand('mceInsertLink', false, media.attributes.url);
319
- }
320
- } else {
321
- var display = tnp_uploader.state().display(media);
322
- var url = media.attributes.sizes[display.attributes.size].url;
323
- if (typeof templateEditor !== "undefined") {
324
- templateEditor.getDoc().replaceRange('<img src="' + url + '">', templateEditor.getDoc().getCursor());
325
- } else {
326
- tinyMCE.execCommand('mceInsertContent', false, '<img src="' + url + '" />');
327
- }
328
- }
329
- }).open();
330
- }
331
-
332
- </script>
333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- <div class="wrap" id="tnp-wrap">
336
 
337
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
338
 
@@ -344,25 +302,23 @@ if ($email['editor'] == 0) {
344
 
345
  <div id="tnp-body">
346
 
347
- <?php
348
- if ($controls->data['status'] == 'S') {
349
- echo '<div class="newsletter-message">Warning! This email is configured to be sent to NOT CONFIRMED subscribers.</div>';
350
- }
351
- ?>
352
 
353
  <form method="post" action="" id="newsletter-form">
354
  <?php $controls->init(array('cookie_name' => 'newsletter_emails_edit_tab')); ?>
355
 
356
  <div class="tnp-submit">
 
357
  <?php $controls->button_back('?page=newsletter_emails_index') ?>
358
  <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_save(); ?>
359
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('test', 'Save and test', 'Save and send test emails to test addresses?'); ?>
360
 
361
  <?php if ($email['status'] == 'new') $controls->button_confirm('send', __('Send', 'newsletter'), __('Start real delivery?', 'newsletter')); ?>
362
  <?php if ($email['status'] == 'sending') $controls->button_confirm('pause', __('Pause', 'newsletter'), __('Pause the delivery?', 'newsletter')); ?>
363
  <?php if ($email['status'] == 'paused') $controls->button_confirm('continue', __('Continue', 'newsletter'), 'Continue the delivery?'); ?>
364
  <?php if ($email['status'] == 'paused') $controls->button_confirm('abort', __('Stop', 'newsletter'), __('This totally stop the delivery, ok?', 'newsletter')); ?>
365
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('editor', 'Save and switch to ' . ($email['editor'] == 0 ? 'HTML source' : 'visual') . ' editor', 'Sure?'); ?>
 
366
  </div>
367
 
368
  <?php $controls->text('subject', 70, 'Subject'); ?>
@@ -379,22 +335,17 @@ if ($email['editor'] == 0) {
379
 
380
  <div id="tabs-a">
381
 
382
-
383
-
384
-
385
-
386
- <?php if ($email['editor'] == 0) { ?>
387
- <input type="button" class="button-primary" value="Add media" onclick="tnp_media()">
388
-
389
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-tags" target="_blank"><?php _e('Available tags', 'newsletter') ?></a>
390
- <br><br>
391
-
392
- <?php $controls->editor('message', 30); ?>
393
-
394
- <?php } else { ?>
395
- <?php include __DIR__ . '/edit-html.php'; ?>
396
- <?php } ?>
397
-
398
 
399
  </div>
400
 
@@ -413,58 +364,55 @@ if ($email['editor'] == 0) {
413
 
414
 
415
  <div id="tabs-c">
 
 
 
 
 
 
 
416
  <table class="form-table">
417
 
418
  <tr valign="top">
419
- <th><?php _e('Gender', 'newsletter'); ?></th>
420
  <td>
421
- <?php $controls->checkboxes_group('sex', array('f' => 'Women', 'm' => 'Men', 'n' => 'Not specified')); ?>
422
- <p class="description">
423
- Leaving all gender options unselected disable this filter.
424
- </p>
425
  </td>
426
  </tr>
427
  <tr valign="top">
428
- <th><?php _e('Lists', 'newsletter'); ?></th>
429
  <td>
430
- Subscribers with
431
- <?php $controls->select('preferences_status_operator', array(0 => 'at least one list', 1 => 'all lists')); ?>
432
-
433
- <?php $controls->select('preferences_status', array(0 => 'active', 1 => 'not active')); ?>
434
- <?php _e('checked below', 'newsletter') ?>
435
-
436
- <?php $controls->preferences_group('preferences', true); ?>
437
- <p class="description">
438
- You can address the newsletter to subscribers who selected at least one of the options or to who
439
- has not selected at least one of the options.
440
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Read more about the "NOT ACTIVE" usage</a>.
441
- </p>
442
  </td>
443
  </tr>
444
 
445
  <tr valign="top">
446
  <th><?php _e('Status', 'newsletter') ?></th>
447
  <td>
448
- <?php $controls->select('status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'))); ?>
449
 
450
- <p class="description">
451
- <?php _e('Send to not confirmed subscribers ONLY to ask for confirmation including the {subscription_confirm_url} tag.', 'newsletter') ?>
452
- </p>
453
  </td>
454
  </tr>
455
  <tr valign="top">
456
- <th>Only to WordPress users?</th>
457
  <td>
458
- <?php $controls->yesno('wp_users'); ?>
459
-
460
- <p class="description">
461
- Limit to the subscribers which are WordPress users as well.
462
- </p>
463
  </td>
464
  </tr>
465
  <tr valign="top">
466
  <th>
467
- <?php _e('Subscribers count', 'newsletter') ?>
468
  </th>
469
  <td>
470
  <?php
@@ -492,7 +440,7 @@ if ($email['editor'] == 0) {
492
  <td>
493
  <?php $controls->yesno('private'); ?>
494
  <?php if ($email['status'] == 'sent') { ?>
495
- <?php $controls->button('change-private', __('Toggle'))?>
496
  <?php } ?>
497
  <p class="description">
498
  <?php _e('Hide/show from public sent newsletter list.', 'newsletter') ?>
@@ -510,9 +458,6 @@ if ($email['editor'] == 0) {
510
  <th><?php _e('Send on', 'newsletter') ?></th>
511
  <td>
512
  <?php $controls->datetime('send_on'); ?> (now: <?php echo date_i18n(get_option('date_format') . ' ' . get_option('time_format')); ?>)
513
- <p class="description">
514
- If the current date and time are wrong, check your timezone on the General WordPress settings.
515
- </p>
516
  </td>
517
  </tr>
518
  </table>
@@ -540,29 +485,6 @@ if ($email['editor'] == 0) {
540
  </tr>
541
  </table>
542
  </div>
543
-
544
- <!--
545
- <div id="tabs-5">
546
- <p>Tags documented below can be used on newsletter body. Some of them can be used on subject as well.</p>
547
-
548
- <p>
549
- Special tags, like the preference setting tag, can be used to highly interact with your subscribers, see
550
- the Newsletter Preferences page for examples.
551
- </p>
552
- --
553
-
554
- <dl>
555
- <dt>{set_preference_N}</dt>
556
- <dd>
557
- This tag creates a URL which, once clicked, set the preference numner N on the user profile and redirecting the
558
- subscriber to his profile panel. Preferences can be configured on Subscription/Form fields panel.
559
- </dd>
560
- </dl>
561
-
562
- </ul>
563
- </div>
564
- -->
565
-
566
  </div>
567
 
568
  </form>
5
  $module = NewsletterEmails::instance();
6
 
7
  // Always required
8
+ $email = Newsletter::instance()->get_email($_GET['id'], ARRAY_A);
 
 
 
9
 
10
  if (empty($email)) {
11
  echo 'Wrong email identifier';
12
  return;
13
  }
14
+
15
  $email_id = $email['id'];
16
 
17
+ $composer = isset($email['options']['composer']);
18
+
19
+ if ($composer) {
20
+ wp_enqueue_style('tnpc-style', plugins_url('/tnp-composer/_css/newsletter-builder.css', __FILE__));
21
+ }
22
+
23
+ // Preferences conversions
24
+ if (!isset($email['options']['lists'])) {
25
+
26
+ $options_profile = get_option('newsletter_profile');
27
+
28
+ if (empty($controls->data['preferences_status_operator'])) {
29
+ $email['options']['lists_operator'] = 'or';
30
+ } else {
31
+ $email['options']['lists_operator'] = 'and';
32
  }
33
+ $controls->data['options_lists'] = array();
34
+ $controls->data['options_lists_exclude'] = array();
35
+
36
+ if (!empty($email['preferences'])) {
37
+ $preferences = explode(',', $email['preferences']);
38
+ $value = empty($email['options']['preferences_status']) ? 'on' : 'off';
39
+
40
+ foreach ($preferences as $x) {
41
+ if ($value == 'on') {
42
+ $controls->data['options_lists'][] = $x;
43
+ } else {
44
+ $controls->data['options_lists_exclude'][] = $x;
45
+ }
46
+ }
47
  }
48
+ }
49
 
50
+ if (!$controls->is_action()) {
51
+ $controls->data = $email;
52
 
53
  foreach ($email['options'] as $name => $value) {
54
  $controls->data['options_' . $name] = $value;
59
  $data = array();
60
  $data['private'] = $controls->data['private'] ? 0 : 1;
61
  $data['id'] = $email['id'];
62
+ $email = Newsletter::instance()->save_email($data, ARRAY_A);
63
  $controls->add_message_saved();
64
+
65
  $controls->data = $email;
66
+ foreach ($email['options'] as $name => $value) {
67
+ $controls->data['options_' . $name] = $value;
68
+ }
69
  }
70
 
71
  if ($controls->is_action('test') || $controls->is_action('save') || $controls->is_action('send') || $controls->is_action('editor')) {
72
 
73
 
74
  // If we were editing with visual editor (==0), we must read the extra <body> content
75
+ if (!empty($controls->data['message'])) {
76
+ $controls->data['message'] = str_ireplace('<script', '<noscript', $controls->data['message']);
77
+ $controls->data['message'] = str_ireplace('</script', '</noscript', $controls->data['message']);
78
+ }
79
+
80
  if ($email['editor'] == 0) {
81
+ if (!empty($controls->data['message'])) {
82
+ $x = strpos($email['message'], '<body');
83
+ if ($x !== false) {
84
+ $x = strpos($email['message'], '>', $x);
85
+ $email['message'] = substr($email['message'], 0, $x + 1) . $controls->data['message'] . '</body></html>';
86
+ } else {
87
+ $email['message'] = '<html><body>' . $controls->data['message'] . '</body></html>';
88
+ }
89
  }
90
  } else {
91
  $email['message'] = $controls->data['message'];
95
  $email['track'] = $controls->data['track'];
96
  $email['private'] = $controls->data['private'];
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  foreach ($controls->data as $name => $value) {
99
  if (strpos($name, 'options_') === 0) {
100
  $email['options'][substr($name, 8)] = $value;
101
  }
102
  }
103
+
104
+ //var_dump($email);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  // Before send, we build the query to extract subscriber, so the delivery engine does not
107
  // have to worry about the email parameters
108
+ if ($email['options']['status'] == 'S') {
109
  $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='S'";
110
  } else {
111
  $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
112
  }
113
 
114
+ if ($email['options']['wp_users'] == '1') {
115
  $query .= " and wp_user_id<>0";
116
  }
117
 
118
+ $list_where = array();
119
+ foreach ($email['options']['lists'] as $list) {
120
+ $list = (int)$list;
121
+ $list_where[] = 'list_' . $list . '=1';
122
+ }
123
 
124
+ if (!empty($list_where)) {
125
+ if (isset($email['options']['lists_operator']) && $email['options']['lists_operator'] == 'and') {
126
+ $query .= ' and (' . implode(' and ', $list_where) . ')';
 
 
 
 
 
 
 
 
 
127
  } else {
128
+ $query .= ' and (' . implode(' or ', $list_where) . ')';
 
 
 
 
 
129
  }
130
  }
131
+
132
+ $list_where = array();
133
+ foreach ($email['options']['lists_exclude'] as $list) {
134
+ $list = (int)$list;
135
+ $list_where[] = 'list_' . $list . '=0';
136
+ }
137
+ if (!empty($list_where)) {
138
+ $query .= ' and (' . implode(' or ', $list_where) . ')';
139
+ }
140
+
141
+ if (isset($email['options']['sex'])) {
142
+ $sex = $email['options']['sex'];
143
  if (is_array($sex)) {
144
  $query .= " and sex in (";
145
  foreach ($sex as $x) {
146
+ $query .= "'" . esc_sql((string) $x) . "', ";
147
  }
148
  $query = substr($query, 0, -2);
149
  $query .= ")";
150
  }
151
  }
152
 
153
+ $e = Newsletter::instance()->save_email($email);
154
 
 
 
155
  $query = apply_filters('newsletter_emails_email_query', $query, $e);
156
 
157
  $email['query'] = $query;
172
  // Cleans up of tag
173
  $email['message'] = NewsletterModule::clean_url_tags($email['message']);
174
 
175
+ //$email = apply_filters('newsletter_emails_pre_save', $email);
176
+ //$module->logger->fatal($email);
177
+
178
  $res = Newsletter::instance()->save_email($email);
179
  if ($res === false) {
180
  $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
233
  $controls->messages .= '<br>';
234
  $controls->messages .= '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank">' .
235
  __('Read more about test subscribers', 'newsletter') . '</a>.';
 
 
236
  }
237
  }
238
 
 
239
  if ($email['editor'] == 0) {
240
+ $controls->data['message'] = $module->extract_body($controls->data['message']);
 
 
 
 
 
 
 
 
241
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
+ if ($controls->data['options_status'] == 'S') {
244
+ $controls->warnings[] = __('This newsletter will be sent to not confirmed subscribers.', 'newsletter');
245
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
+ /*
248
+ $host = parse_url(home_url(), PHP_URL_HOST);
249
+ $parts = array_reverse(explode('.', $host));
250
+ $host = $parts[1] . '.' . $parts[0];
251
+
252
+ $re = '/["\'](https?:\/\/[^\/\s]+\/\S+\.(jpg|png|gif))["\']/i';
253
+ preg_match_all($re, $controls->data['message'], $matches);
254
+ $images = array();
255
+ if (isset($matches[1])) {
256
+ //echo 'Ci sono immagini';
257
+ //var_dump($matches[1]);
258
+ foreach ($matches[1] as $url) {
259
+ $h = parse_url($url, PHP_URL_HOST);
260
+ $p = array_reverse(explode('.', $h));
261
+ $h = $p[1] . '.' . $p[0];
262
+ if ($h == $host)
263
+ continue;
264
+ $images[] = $url;
265
+ }
266
+ }
267
+
268
+ if ($images) {
269
+ //$controls->warnings[] = __('Message body contains images from external domains.', 'newsletter') . ' <a href="">' . __('Read more', 'newsletter') . '</a>';
270
+ }
271
+ */
272
+ /*
273
+ if ($images) {
274
+ $upload = wp_upload_dir();
275
+ $dir = $upload['basedir'] . '/newsletter/' . $email['id'];
276
+ $baseurl = $upload['baseurl'] . '/newsletter/' . $email['id'];
277
+
278
+ // Cannot work on systems with forced relative paths
279
+ if (strpos($baseurl, 'http') === 0) {
280
+ wp_mkdir_p($dir);
281
+ foreach ($images as $url) {
282
+ $file = basename(parse_url($url, PHP_URL_PATH));
283
+ $file = sanitize_file_name($file);
284
+ if (copy($url, $dir . '/' . $file)) {
285
+ $controls->data['message'] = str_replace($url, $baseurl . '/' . $file, $controls->data['message']);
286
+ }
287
+ }
288
+ }
289
+ }
290
+ */
291
+ ?>
292
 
293
+ <div class="wrap tnp-emails tnp-emails-edit" id="tnp-wrap">
294
 
295
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
296
 
302
 
303
  <div id="tnp-body">
304
 
305
+
 
 
 
 
306
 
307
  <form method="post" action="" id="newsletter-form">
308
  <?php $controls->init(array('cookie_name' => 'newsletter_emails_edit_tab')); ?>
309
 
310
  <div class="tnp-submit">
311
+
312
  <?php $controls->button_back('?page=newsletter_emails_index') ?>
313
  <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_save(); ?>
314
+ <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button('test', __('Test', 'newsletter')); ?>
315
 
316
  <?php if ($email['status'] == 'new') $controls->button_confirm('send', __('Send', 'newsletter'), __('Start real delivery?', 'newsletter')); ?>
317
  <?php if ($email['status'] == 'sending') $controls->button_confirm('pause', __('Pause', 'newsletter'), __('Pause the delivery?', 'newsletter')); ?>
318
  <?php if ($email['status'] == 'paused') $controls->button_confirm('continue', __('Continue', 'newsletter'), 'Continue the delivery?'); ?>
319
  <?php if ($email['status'] == 'paused') $controls->button_confirm('abort', __('Stop', 'newsletter'), __('This totally stop the delivery, ok?', 'newsletter')); ?>
320
+ <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button('editor', __('Switch editor')); ?>
321
+ <?php //if ($images) $controls->button_confirm('import', __('Import images', 'newsletter'), 'Proceed?') ?>
322
  </div>
323
 
324
  <?php $controls->text('subject', 70, 'Subject'); ?>
335
 
336
  <div id="tabs-a">
337
 
338
+ <?php
339
+ if ($email['editor'] == 0) {
340
+ if ($composer) {
341
+ include __DIR__ . '/edit-composer.php';
342
+ } else {
343
+ include __DIR__ . '/edit-editor.php';
344
+ }
345
+ } else {
346
+ include __DIR__ . '/edit-html.php';
347
+ }
348
+ ?>
 
 
 
 
 
349
 
350
  </div>
351
 
364
 
365
 
366
  <div id="tabs-c">
367
+ <p>
368
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/newsletter-targeting') ?>
369
+ </p>
370
+
371
+ <p>
372
+ <?php _e('Leaving all multichoice options unselected is like to select all them', 'newsletter'); ?>
373
+ </p>
374
  <table class="form-table">
375
 
376
  <tr valign="top">
377
+ <th><?php _e('Gender', 'newsletter') ?></th>
378
  <td>
379
+ <?php $controls->checkboxes_group('options_sex', array('f' => 'Women', 'm' => 'Men', 'n' => 'Not specified')); ?>
 
 
 
380
  </td>
381
  </tr>
382
  <tr valign="top">
383
+ <th><?php _e('Lists', 'newsletter') ?></th>
384
  <td>
385
+ <?php
386
+ $lists = $controls->get_list_options();
387
+ ?>
388
+ <?php $controls->select('options_lists_operator', array('or'=>__('Match at least one of', 'newsletter'), 'and'=>__('Match all of', 'newsletter'))); ?>
389
+
390
+ <?php $controls->select2('options_lists', $lists, null, true, null, __('All', 'newsletter')); ?>
391
+
392
+ <p><?php _e('must not in one of', 'newsletter')?></p>
393
+
394
+ <?php $controls->select2('options_lists_exclude', $lists, null, true, null, __('None', 'newsletter')); ?>
395
+
396
+
397
  </td>
398
  </tr>
399
 
400
  <tr valign="top">
401
  <th><?php _e('Status', 'newsletter') ?></th>
402
  <td>
403
+ <?php $controls->select('options_status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'))); ?>
404
 
 
 
 
405
  </td>
406
  </tr>
407
  <tr valign="top">
408
+ <th><?php _e('Only to subscribers linked to WP users', 'newsletter') ?></th>
409
  <td>
410
+ <?php $controls->yesno('options_wp_users'); ?>
 
 
 
 
411
  </td>
412
  </tr>
413
  <tr valign="top">
414
  <th>
415
+ <?php _e('Approximated subscribers count', 'newsletter') ?>
416
  </th>
417
  <td>
418
  <?php
440
  <td>
441
  <?php $controls->yesno('private'); ?>
442
  <?php if ($email['status'] == 'sent') { ?>
443
+ <?php $controls->button('change-private', __('Toggle')) ?>
444
  <?php } ?>
445
  <p class="description">
446
  <?php _e('Hide/show from public sent newsletter list.', 'newsletter') ?>
458
  <th><?php _e('Send on', 'newsletter') ?></th>
459
  <td>
460
  <?php $controls->datetime('send_on'); ?> (now: <?php echo date_i18n(get_option('date_format') . ' ' . get_option('time_format')); ?>)
 
 
 
461
  </td>
462
  </tr>
463
  </table>
485
  </tr>
486
  </table>
487
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  </div>
489
 
490
  </form>
emails/editor.css CHANGED
@@ -1,4 +1,15 @@
1
- body, td, pre {
2
- font-size: 12px;
3
- }
4
-
 
 
 
 
 
 
 
 
 
 
 
1
+ /* The CSS used for the WP editor on administration panels */
2
+ body {
3
+ font-size: 16px;
4
+ font-family: sans-serif;
5
+ margin: 20px;
6
+ }
7
+
8
+ .mce-content-body p, table, ul, ol {
9
+ margin-bottom: 15px;
10
+ line-height: 24px;
11
+ }
12
+
13
+ img {
14
+ max-width: 100%;
15
+ }
emails/emails.php CHANGED
@@ -61,7 +61,13 @@ class NewsletterEmails extends NewsletterModule {
61
  function tnpc_render_callback() {
62
  $block_options = get_option('newsletter_main');
63
  $block = $this->get_block($_POST['b']);
64
- if ($block) {
 
 
 
 
 
 
65
 
66
  if (isset($_POST['options']) && is_array($_POST['options'])) {
67
  $options = stripslashes_deep($_POST['options']);
@@ -96,8 +102,6 @@ class NewsletterEmails extends NewsletterModule {
96
  }
97
  wp_die();
98
  }
99
- include NEWSLETTER_DIR . '/emails/tnp-composer/blocks/' . sanitize_file_name($_POST['b']) . '.php';
100
- wp_die(); // this is required to terminate immediately and return a proper response
101
  }
102
 
103
  function tnpc_preview_callback() {
@@ -125,27 +129,37 @@ class NewsletterEmails extends NewsletterModule {
125
 
126
  switch ($newsletter->action) {
127
  case 'v':
128
- // TODO: Change to Newsletter::instance()->get:email(), not urgent
129
- $email = $this->get_email((int) $_GET['id']);
130
  if (empty($email)) {
 
131
  die('Email not found');
132
  }
133
 
134
- if ($email->private == 1) {
135
- die('No available for online view');
 
136
  }
137
 
138
  $user = NewsletterSubscription::instance()->get_user_from_request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  header('Content-Type: text/html;charset=UTF-8');
140
  header('X-Robots-Tag: noindex,nofollow,noarchive');
141
  header('Cache-Control: no-cache,no-store,private');
142
 
143
- // TODO: To be removed
144
- if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/view.php')) {
145
- include WP_CONTENT_DIR . '/extensions/newsletter/view.php';
146
- die();
147
- }
148
-
149
  echo $newsletter->replace($email->message, $user, $email->id);
150
 
151
  die();
@@ -317,7 +331,7 @@ class NewsletterEmails extends NewsletterModule {
317
  $this->add_admin_page('edit', 'Email Edit');
318
  $this->add_admin_page('theme', 'Email Themes');
319
  $this->add_admin_page('composer', 'The Composer');
320
- $this->add_admin_page('cpreview', 'The Composer Preview');
321
  }
322
 
323
  /**
@@ -437,13 +451,18 @@ class NewsletterEmails extends NewsletterModule {
437
  $filename = $path_parts['filename'];
438
  $section = substr($filename, 0, strpos($filename, '-'));
439
  $index = substr($filename, strpos($filename, '-') + 1, 2);
440
- $blocks[$index]['name'] = substr($filename, strrpos($filename, '-') + 1);
441
- $blocks[$index]['filename'] = $filename;
442
- $blocks[$index]['icon'] = plugins_url('newsletter') . '/emails/tnp-composer/blocks/' . $filename . '.png';
443
- $blocks[$index]['section'] = $section;
444
- $blocks[$index]['description'] = '';
 
 
445
  }
446
 
 
 
 
447
  $dirs = apply_filters('newsletter_blocks_dir', array());
448
 
449
  foreach ($dirs as $dir) {
@@ -455,6 +474,16 @@ class NewsletterEmails extends NewsletterModule {
455
  }
456
 
457
  function get_block($id) {
 
 
 
 
 
 
 
 
 
 
458
  $blocks = $this->get_blocks();
459
  if (!isset($blocks[$id])) {
460
  return null;
61
  function tnpc_render_callback() {
62
  $block_options = get_option('newsletter_main');
63
  $block = $this->get_block($_POST['b']);
64
+ if (!$block) {
65
+ die('Not found');
66
+ }
67
+ if (strpos($block['filename'], '.block')) {
68
+ include NEWSLETTER_DIR . '/emails/tnp-composer/blocks/' . $block['filename'] . '.php';
69
+ wp_die();
70
+ } else {
71
 
72
  if (isset($_POST['options']) && is_array($_POST['options'])) {
73
  $options = stripslashes_deep($_POST['options']);
102
  }
103
  wp_die();
104
  }
 
 
105
  }
106
 
107
  function tnpc_preview_callback() {
129
 
130
  switch ($newsletter->action) {
131
  case 'v':
132
+ case 'view':
133
+ $email = $this->get_email($_GET['id']);
134
  if (empty($email)) {
135
+ header("HTTP/1.0 404 Not Found");
136
  die('Email not found');
137
  }
138
 
139
+ if ($email->status == 'new') {
140
+ header("HTTP/1.0 404 Not Found");
141
+ die('Not sent yet');
142
  }
143
 
144
  $user = NewsletterSubscription::instance()->get_user_from_request();
145
+
146
+ if ($email->private == 1) {
147
+ if (!$user) {
148
+ header("HTTP/1.0 404 Not Found");
149
+ die('No available for online view');
150
+ }
151
+ $sent = $wpdb->get_row($wpdb->prepare("select * from " . NEWSLETTER_SENT_TABLE . " where email_id=%d and user_id=%d limit 1", $email->id, $user->id));
152
+ if (!$sent) {
153
+ header("HTTP/1.0 404 Not Found");
154
+ die('No available for online view');
155
+ }
156
+ }
157
+
158
+
159
  header('Content-Type: text/html;charset=UTF-8');
160
  header('X-Robots-Tag: noindex,nofollow,noarchive');
161
  header('Cache-Control: no-cache,no-store,private');
162
 
 
 
 
 
 
 
163
  echo $newsletter->replace($email->message, $user, $email->id);
164
 
165
  die();
331
  $this->add_admin_page('edit', 'Email Edit');
332
  $this->add_admin_page('theme', 'Email Themes');
333
  $this->add_admin_page('composer', 'The Composer');
334
+ //$this->add_admin_page('cpreview', 'The Composer Preview');
335
  }
336
 
337
  /**
451
  $filename = $path_parts['filename'];
452
  $section = substr($filename, 0, strpos($filename, '-'));
453
  $index = substr($filename, strpos($filename, '-') + 1, 2);
454
+ $block = array();
455
+ $block['name'] = substr($filename, strrpos($filename, '-') + 1);
456
+ $block['filename'] = $filename;
457
+ $block['icon'] = plugins_url('newsletter') . '/emails/tnp-composer/blocks/' . $filename . '.png';
458
+ $block['section'] = $section;
459
+ $block['description'] = '';
460
+ $blocks[$filename] = $block;
461
  }
462
 
463
+ $list = $this->scan_blocks_dir(__DIR__ . '/blocks');
464
+
465
+ $blocks = array_merge($blocks, $list);
466
  $dirs = apply_filters('newsletter_blocks_dir', array());
467
 
468
  foreach ($dirs as $dir) {
474
  }
475
 
476
  function get_block($id) {
477
+ switch ($id) {
478
+ // case 'content-05-image.block': $id = '/plugins/newsletter/emails/blocks/image';
479
+ // break;
480
+ case 'content-04-cta.block': $id = '/plugins/newsletter/emails/blocks/cta';
481
+ break;
482
+ // case 'content-02-heading.block': $id = '/plugins/newsletter/emails/blocks/heading';
483
+ // break;
484
+ }
485
+
486
+ // TODO: Correct id for compatibility
487
  $blocks = $this->get_blocks();
488
  if (!isset($blocks[$id])) {
489
  return null;
emails/index.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
@@ -10,16 +11,6 @@ if ($controls->is_action('convert')) {
10
  $controls->messages = 'Converted!';
11
  }
12
 
13
- if ($controls->is_action('unconvert')) {
14
- $wpdb->query("update wp_newsletter_emails set type='email' where type='message'");
15
- $controls->messages = 'Unconverted!';
16
- }
17
-
18
- if ($controls->is_action('send')) {
19
- $newsletter->hook_newsletter();
20
- $controls->messages .= __('Delivery engine triggered.', 'newsletter');
21
- }
22
-
23
  if ($controls->is_action('copy')) {
24
  $original = Newsletter::instance()->get_email($_POST['btn']);
25
  $email = array();
@@ -30,7 +21,7 @@ if ($controls->is_action('copy')) {
30
  $email['type'] = 'message';
31
  $email['editor'] = $original->editor;
32
  $email['track'] = $original->track;
33
- if(isset($original->options)) {
34
  $original_options = unserialize($original->options);
35
  $email['options'] = serialize(array('composer' => $original_options['composer']));
36
  }
@@ -52,7 +43,7 @@ if ($controls->is_action('delete_selected')) {
52
  $emails = Newsletter::instance()->get_emails('message');
53
  ?>
54
 
55
- <div class="wrap" id="tnp-wrap">
56
 
57
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
58
 
@@ -67,25 +58,12 @@ $emails = Newsletter::instance()->get_emails('message');
67
  <form method="post" action="">
68
  <?php $controls->init(); ?>
69
 
70
- <?php if ($module->has_old_emails()) { ?>
71
- <div class="newsletter-message">
72
- <p>
73
- Your Newsletter installation has emails still in old format. To get them listed, you should convert them in
74
- a new format. Would you to convert them now?
75
- </p>
76
- <p>
77
- <?php $controls->button('convert', 'Convert now'); ?>
78
- </p>
79
- </div>
80
- <?php } ?>
81
-
82
  <p>
83
  <a href="<?php echo $module->get_admin_page_url('theme'); ?>" class="button-primary"><?php _e('New newsletter', 'newsletter') ?></a>
84
- <?php $controls->button_confirm('delete_selected', __('Delete selected newsletters', 'newsletter'), __('Proceed?', 'newsletter'));
85
- ?>
86
- <?php $controls->button('send', __('Trigger the delivery engine', 'newsletter')); ?>
87
  </p>
88
- <table class="widefat">
89
  <thead>
90
  <tr>
91
  <th>&nbsp;</th>
@@ -99,11 +77,13 @@ $emails = Newsletter::instance()->get_emails('message');
99
  <th>&nbsp;</th>
100
  <th>&nbsp;</th>
101
  <th>&nbsp;</th>
 
102
  </tr>
103
  </thead>
104
 
105
  <tbody>
106
- <?php foreach ($emails as $email) {
 
107
  $email_options = maybe_unserialize($email->options);
108
  $composer = isset($email_options['composer']);
109
  ?>
@@ -134,26 +114,23 @@ $emails = Newsletter::instance()->get_emails('message');
134
  <td><?php if ($email->status == 'sent' || $email->status == 'sending') echo $email->sent . ' ' . __('of', 'newsletter') . ' ' . $email->total; ?></td>
135
  <td><?php if ($email->status == 'sent' || $email->status == 'sending') echo $module->format_date($email->send_on); ?></td>
136
  <td><?php echo $email->track == 1 ? __('Yes', 'newsletter') : __('No', 'newsletter'); ?></td>
137
- <td><a class="button-primary" href="<?php echo $module->get_admin_page_url($composer ? 'composer' : 'edit'); ?>&amp;id=<?php echo $email->id; ?>"><i class="fa fa-<?php echo $composer?'th-large':'pencil'?>"></i> <?php _e('Edit', 'newsletter') ?></a></td>
138
  <td>
139
  <a class="button-primary" href="<?php echo NewsletterStatistics::instance()->get_statistics_url($email->id); ?>"><i class="fa fa-bar-chart"></i> <?php _e('Statistics', 'newsletter') ?></a>
140
  </td>
 
141
  <td><?php $controls->button_copy($email->id); ?></td>
142
  <td><?php $controls->button_delete($email->id); ?></td>
143
  </tr>
144
- <?php } ?>
145
  </tbody>
146
- <tfoot>
147
- <tr>
148
- <td colspan="11">
149
- (*) <?php _e('Expected total at the end of the delivery may differ, due to subscriptions/unsubscriptions occured meanwhile.', 'newsletter') ?>
150
- </td>
151
- </tr>
152
- </tfoot>
153
  </table>
 
 
 
154
  </form>
155
  </div>
156
 
157
- <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
158
 
159
  </div>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
11
  $controls->messages = 'Converted!';
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
14
  if ($controls->is_action('copy')) {
15
  $original = Newsletter::instance()->get_email($_POST['btn']);
16
  $email = array();
21
  $email['type'] = 'message';
22
  $email['editor'] = $original->editor;
23
  $email['track'] = $original->track;
24
+ if (isset($original->options)) {
25
  $original_options = unserialize($original->options);
26
  $email['options'] = serialize(array('composer' => $original_options['composer']));
27
  }
43
  $emails = Newsletter::instance()->get_emails('message');
44
  ?>
45
 
46
+ <div class="wrap tnp-emails tnp-emails-index" id="tnp-wrap">
47
 
48
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
49
 
58
  <form method="post" action="">
59
  <?php $controls->init(); ?>
60
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  <p>
62
  <a href="<?php echo $module->get_admin_page_url('theme'); ?>" class="button-primary"><?php _e('New newsletter', 'newsletter') ?></a>
63
+ <?php $controls->button_confirm('delete_selected', __('Delete selected newsletters', 'newsletter'), __('Proceed?', 'newsletter')); ?>
64
+
 
65
  </p>
66
+ <table class="widefat" style="width: 100%">
67
  <thead>
68
  <tr>
69
  <th>&nbsp;</th>
77
  <th>&nbsp;</th>
78
  <th>&nbsp;</th>
79
  <th>&nbsp;</th>
80
+ <th>&nbsp;</th>
81
  </tr>
82
  </thead>
83
 
84
  <tbody>
85
+ <?php
86
+ foreach ($emails as $email) {
87
  $email_options = maybe_unserialize($email->options);
88
  $composer = isset($email_options['composer']);
89
  ?>
114
  <td><?php if ($email->status == 'sent' || $email->status == 'sending') echo $email->sent . ' ' . __('of', 'newsletter') . ' ' . $email->total; ?></td>
115
  <td><?php if ($email->status == 'sent' || $email->status == 'sending') echo $module->format_date($email->send_on); ?></td>
116
  <td><?php echo $email->track == 1 ? __('Yes', 'newsletter') : __('No', 'newsletter'); ?></td>
117
+ <td><a class="button-primary" href="<?php echo $module->get_admin_page_url($composer ? 'composer' : 'edit'); ?>&amp;id=<?php echo $email->id; ?>"><i class="fa fa-<?php echo $composer ? 'th-large' : 'pencil' ?>"></i> <?php _e('Edit', 'newsletter') ?></a></td>
118
  <td>
119
  <a class="button-primary" href="<?php echo NewsletterStatistics::instance()->get_statistics_url($email->id); ?>"><i class="fa fa-bar-chart"></i> <?php _e('Statistics', 'newsletter') ?></a>
120
  </td>
121
+ <td><a class="button-primary" target="_blank" rel="noopener" href="<?php echo home_url('/')?>?na=view&id=<?php echo $email->id; ?>"><i class="fa fa-eye"></i>&nbsp;<?php _e('View', 'newsletter')?></a></td>
122
  <td><?php $controls->button_copy($email->id); ?></td>
123
  <td><?php $controls->button_delete($email->id); ?></td>
124
  </tr>
125
+ <?php } ?>
126
  </tbody>
 
 
 
 
 
 
 
127
  </table>
128
+ <p>
129
+ (*) <?php _e('Expected total at the end of the delivery may differ, due to subscriptions/unsubscriptions occured meanwhile.', 'newsletter') ?>
130
+ </p>
131
  </form>
132
  </div>
133
 
134
+ <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
135
 
136
  </div>
emails/new.php CHANGED
@@ -135,7 +135,7 @@ function newsletter_emails_get_theme_options($theme) {
135
  }
136
  ?>
137
 
138
- <div class="wrap" id="tnp-wrap">
139
 
140
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
141
 
@@ -167,8 +167,10 @@ function newsletter_emails_get_theme_options($theme) {
167
  </td>
168
  </tr>
169
  <tr>
170
- <td style="width: 600px; vertical-align: top; padding-top: 10px">
 
171
  <?php @include $module->get_current_theme_file_path('theme-options.php'); ?>
 
172
  </td>
173
  <td style="vertical-align: top; padding-top: 15px; padding-left: 15px">
174
  <iframe src="<?php echo wp_nonce_url(home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-preview&ts=' . time(), 'view'); ?>" height="700" style="width: 100%; border: 1px solid #ccc"></iframe>
135
  }
136
  ?>
137
 
138
+ <div class="wrap tnp-emails tnp-emails-new" id="tnp-wrap">
139
 
140
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
141
 
167
  </td>
168
  </tr>
169
  <tr>
170
+ <td style="width: 500px; vertical-align: top;">
171
+ <div class="tnp-emails-theme-options">
172
  <?php @include $module->get_current_theme_file_path('theme-options.php'); ?>
173
+ </div>
174
  </td>
175
  <td style="vertical-align: top; padding-top: 15px; padding-left: 15px">
176
  <iframe src="<?php echo wp_nonce_url(home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-preview&ts=' . time(), 'view'); ?>" height="700" style="width: 100%; border: 1px solid #ccc"></iframe>
emails/theme.php CHANGED
@@ -48,7 +48,7 @@ function newsletter_emails_get_theme_options($theme) {
48
  $themes = $module->themes->get_all_with_data();
49
  ?>
50
 
51
- <div class="wrap" id="tnp-wrap">
52
 
53
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
54
 
48
  $themes = $module->themes->get_all_with_data();
49
  ?>
50
 
51
+ <div class="wrap tnp-emails tnp-emails-theme" id="tnp-wrap">
52
 
53
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
54
 
emails/themes/blank/theme-options.php CHANGED
@@ -3,7 +3,7 @@ if (!defined('ABSPATH')) exit;
3
  ?>
4
  <table class="form-table">
5
  <tr>
6
- <th>Disable social links</th>
7
  <td><?php $controls->checkbox('theme_social_disable', ''); ?></td>
8
  </tr>
9
  </table>
3
  ?>
4
  <table class="form-table">
5
  <tr>
6
+ <th><?php _e('Disable social links', 'newsletter') ?></th>
7
  <td><?php $controls->checkbox('theme_social_disable', ''); ?></td>
8
  </tr>
9
  </table>
emails/themes/blank/theme.php CHANGED
@@ -18,7 +18,7 @@ if (!defined('ABSPATH')) exit;
18
  </p>
19
 
20
  <p>
21
- here the forewords of your shiny new newsletter. Most of the times a simple layout is the best.
22
  </p>
23
  <h2>There is more for you!</h2>
24
 
@@ -32,7 +32,7 @@ if (!defined('ABSPATH')) exit;
32
 
33
  <hr>
34
  <p>
35
- To unsubscribe <a href="{unsubscription_url}">click here</a>, to edit your subscription
36
  <a href="{profile_url}">click here</a>.
37
  </p>
38
  <p>
18
  </p>
19
 
20
  <p>
21
+ here the foreword of your shiny new newsletter. Most of the times a simple layout is the best.
22
  </p>
23
  <h2>There is more for you!</h2>
24
 
32
 
33
  <hr>
34
  <p>
35
+ To cancel <a href="{unsubscription_url}">click here</a>, to edit your subscription
36
  <a href="{profile_url}">click here</a>.
37
  </p>
38
  <p>
emails/themes/cta-2015/theme-options.php CHANGED
@@ -3,7 +3,7 @@ if (!defined('ABSPATH')) exit;
3
  ?>
4
  <table class="form-table">
5
  <tr>
6
- <th>Main color</th>
7
  <td>
8
  <?php $controls->color('theme_color'); ?> (eg. #87aa14)
9
  </td>
3
  ?>
4
  <table class="form-table">
5
  <tr>
6
+ <th><?php _e('Primary color', 'newsletter') ?></th>
7
  <td>
8
  <?php $controls->color('theme_color'); ?> (eg. #87aa14)
9
  </td>
emails/themes/cta-2015/theme.php CHANGED
@@ -95,51 +95,7 @@ $social_icon_url = plugins_url('newsletter') . '/emails/themes/cta-2015/images';
95
  </tr>
96
  </table>
97
 
98
- <!-- social -->
99
- <table cellpadding="5" align="center">
100
- <tr>
101
- <?php if (!empty($theme_options['main_facebook_url'])) { ?>
102
- <td align="center" valign="top">
103
- <a href="<?php echo $theme_options['main_facebook_url'] ?>"><img src="<?php echo $social_icon_url ?>/facebook.png" alt="Facebook"></a>
104
- </td>
105
- <?php } ?>
106
-
107
- <?php if (!empty($theme_options['main_googleplus_url'])) { ?>
108
- <td align="center" valign="top">
109
- <a href="<?php echo $theme_options['main_googleplus_url'] ?>"><img src="<?php echo $social_icon_url ?>/googleplus.png"></a>
110
- </td>
111
- <?php } ?>
112
-
113
- <?php if (!empty($theme_options['main_twitter_url'])) { ?>
114
- <td align="center" valign="top">
115
- <a href="<?php echo $theme_options['main_twitter_url'] ?>"><img src="<?php echo $social_icon_url ?>/twitter.png"></a>
116
- </td>
117
- <?php } ?>
118
-
119
- <?php if (!empty($theme_options['main_linkedin_url'])) { ?>
120
- <td align="center" valign="top">
121
- <a href="<?php echo $theme_options['main_linkedin_url'] ?>"><img src="<?php echo $social_icon_url ?>/linkedin.png"></a>
122
- </td>
123
- <?php } ?>
124
-
125
- <?php if (!empty($theme_options['main_youtube_url'])) { ?>
126
- <td align="center" valign="top">
127
- <a href="<?php echo $theme_options['main_youtube_url'] ?>"><img src="<?php echo $social_icon_url ?>/youtube.png"></a>
128
- </td>
129
- <?php } ?>
130
-
131
- <?php if (!empty($theme_options['main_vimeo_url'])) { ?>
132
- <td align="center" valign="top">
133
- <a href="<?php echo $theme_options['main_vimeo_url'] ?>"><img src="<?php echo $social_icon_url ?>/vimeo.png"></a>
134
- </td>
135
- <?php } ?>
136
- <?php if (!empty($theme_options['main_instagram_url'])) { ?>
137
- <td align="center" valign="top">
138
- <a href="<?php echo $theme_options['main_instagram_url'] ?>"><img src="<?php echo $social_icon_url ?>/instagram.png"></a>
139
- </td>
140
- <?php } ?>
141
- </tr>
142
- </table>
143
 
144
  <!-- spacer -->
145
  <table cellpadding="0" cellspacing="0" align="center" bgcolor="#ffffff" border="0" width="100%">
95
  </tr>
96
  </table>
97
 
98
+ <?php include WP_PLUGIN_DIR . '/newsletter/emails/themes/default/footer.php'; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  <!-- spacer -->
101
  <table cellpadding="0" cellspacing="0" align="center" bgcolor="#ffffff" border="0" width="100%">
emails/themes/default/theme-options.php CHANGED
@@ -5,23 +5,23 @@ defined('ABSPATH') || exit;
5
  <table class="form-table">
6
  <tr><td colspan="2">General options for header, social links and footer sections could also be set in <a href="?page=newsletter_main_main">Blog Info panel</a>.</td></tr>
7
  <tr>
8
- <th>Base color</th>
9
  <td>
10
  <?php $controls->color('theme_color'); ?>
11
  <p class="description" style="display: inline">Hex values, e.g. #FF0000</p>
12
  </td>
13
  </tr>
14
  <tr>
15
- <th>Disable social links</th>
16
  <td><?php $controls->checkbox('theme_social_disable', ''); ?></td>
17
  </tr>
18
 
19
  </table>
20
 
21
- <h3>Posts</h3>
22
  <table class="form-table">
23
  <tr>
24
- <th>Posts</th>
25
  <td>
26
  <?php $controls->checkbox('theme_posts', 'Add latest posts'); ?>
27
  <br>
@@ -31,29 +31,28 @@ defined('ABSPATH') || exit;
31
  </td>
32
  </tr>
33
  <tr>
34
- <th>Categories</th>
35
  <td>
36
  <?php $controls->categories_group('theme_categories'); ?>
37
  </td>
38
  </tr>
39
  <tr>
40
- <th>Tags</th>
41
  <td>
42
  <?php $controls->text('theme_tags', 30); ?>
43
  <p class="description" style="display: inline"> comma separated</p>
44
  </td>
45
  </tr>
46
  <tr>
47
- <th>Max posts</th>
48
  <td>
49
  <?php $controls->text('theme_max_posts', 5); ?>
50
  </td>
51
  </tr>
52
  <tr>
53
- <th>Post types to include</th>
54
  <td>
55
  <?php $controls->post_types('theme_post_types'); ?>
56
- <div class="hints">Leave all unchecked for default behaviour.</div>
57
  </td>
58
  </tr>
59
  </table>
5
  <table class="form-table">
6
  <tr><td colspan="2">General options for header, social links and footer sections could also be set in <a href="?page=newsletter_main_main">Blog Info panel</a>.</td></tr>
7
  <tr>
8
+ <th><?php _e('Primary color', 'newsletter') ?></th>
9
  <td>
10
  <?php $controls->color('theme_color'); ?>
11
  <p class="description" style="display: inline">Hex values, e.g. #FF0000</p>
12
  </td>
13
  </tr>
14
  <tr>
15
+ <th><?php _e('Disable social links', 'newsletter') ?></th>
16
  <td><?php $controls->checkbox('theme_social_disable', ''); ?></td>
17
  </tr>
18
 
19
  </table>
20
 
21
+ <h3><?php _e('Posts', 'newsletter') ?></h3>
22
  <table class="form-table">
23
  <tr>
24
+ <th>&nbsp;</th>
25
  <td>
26
  <?php $controls->checkbox('theme_posts', 'Add latest posts'); ?>
27
  <br>
31
  </td>
32
  </tr>
33
  <tr>
34
+ <th><?php _e('Categories', 'newsletter') ?></th>
35
  <td>
36
  <?php $controls->categories_group('theme_categories'); ?>
37
  </td>
38
  </tr>
39
  <tr>
40
+ <th><?php _e('Tags', 'newsletter') ?></th>
41
  <td>
42
  <?php $controls->text('theme_tags', 30); ?>
43
  <p class="description" style="display: inline"> comma separated</p>
44
  </td>
45
  </tr>
46
  <tr>
47
+ <th><?php _e('Max posts', 'newsletter') ?></th>
48
  <td>
49
  <?php $controls->text('theme_max_posts', 5); ?>
50
  </td>
51
  </tr>
52
  <tr>
53
+ <th><?php _e('Post types', 'newsletter') ?></th>
54
  <td>
55
  <?php $controls->post_types('theme_post_types'); ?>
 
56
  </td>
57
  </tr>
58
  </table>
emails/themes/default/theme.php CHANGED
@@ -12,10 +12,10 @@
12
 
13
  global $newsletter, $post;
14
 
15
- if (!defined('ABSPATH')) exit;
16
 
17
- $color = $theme_options['theme_color'];
18
- if (empty($color)) $color = '#000000';
19
 
20
  if (isset($theme_options['theme_posts'])) {
21
  $filters = array();
@@ -50,7 +50,7 @@ if (isset($theme_options['theme_posts'])) {
50
  </style>
51
  </head>
52
  <body style="margin: 0!important; padding: 0!important">
53
- <div style="background-color: #ECF2F6; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #666; margin: 0 auto; padding: 0;">
54
 
55
  <br>
56
  <table align="center" bgcolor="#ffffff" width="100%" style="max-width: 600px; width: 100%; border-collapse: collapse; background-color: #000" cellpadding="0" cellspacing="0" border="0">
12
 
13
  global $newsletter, $post;
14
 
15
+ defined('ABSPATH') || exit;
16
 
17
+ if (empty($theme_options['theme_color'])) $color = '#000000';
18
+ else $color = $theme_options['theme_color'];
19
 
20
  if (isset($theme_options['theme_posts'])) {
21
  $filters = array();
50
  </style>
51
  </head>
52
  <body style="margin: 0!important; padding: 0!important">
53
+ <div style="background-color: #f4f4f4; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #666; margin: 0 auto; padding: 0;">
54
 
55
  <br>
56
  <table align="center" bgcolor="#ffffff" width="100%" style="max-width: 600px; width: 100%; border-collapse: collapse; background-color: #000" cellpadding="0" cellspacing="0" border="0">
emails/themes/xmas-2014/images/footer.png DELETED
Binary file
emails/themes/xmas-2014/images/header.png DELETED
Binary file
emails/themes/xmas-2014/screenshot.png DELETED
Binary file
emails/themes/xmas-2014/theme.php DELETED
@@ -1,125 +0,0 @@
1
- <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
- ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
5
- <html xmlns="http://www.w3.org/1999/xhtml">
6
- <head>
7
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
- <title></title>
9
-
10
- <style type="text/css">
11
- .ExternalClass {width:100%;}
12
-
13
- .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {
14
- line-height: 100%;
15
- }
16
-
17
- body {-webkit-text-size-adjust:none; -ms-text-size-adjust:none;}
18
-
19
- body {margin:0; padding:0;}
20
-
21
- table td {border-collapse:collapse;}
22
-
23
- p {margin:0; padding:0; margin-bottom:1em;}
24
-
25
- h1, h2, h3, h4, h5, h6 {
26
- color: #666;
27
- line-height: 100%;
28
- }
29
-
30
- a, a:link {
31
- color:#2A5DB0;
32
- text-decoration: underline;
33
- }
34
-
35
- body, #body_style {
36
- background:#A52B00;
37
- min-height:1000px;
38
- xcolor:#000;
39
- font-family:Arial, Helvetica, sans-serif;
40
- font-size:14px;
41
- }
42
-
43
- span.yshortcuts { color:#000; background-color:none; border:none;}
44
- span.yshortcuts:hover,
45
- span.yshortcuts:active,
46
- span.yshortcuts:focus {color:#000; background-color:none; border:none;}
47
-
48
- a:visited { color: #3c96e2; text-decoration: none}
49
- a:focus { color: #3c96e2; text-decoration: underline}
50
- a:hover { color: #3c96e2; text-decoration: underline}
51
-
52
- @media only screen and (max-device-width: 480px) {
53
-
54
-
55
- body[yahoo] #container1 {display:block !important}
56
- body[yahoo] p {font-size: 10px}
57
-
58
- }
59
-
60
- @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
61
-
62
-
63
- body[yahoo] #container1 {display:block !important}
64
- body[yahoo] p {font-size: 14px}
65
-
66
- }
67
-
68
- </style>
69
-
70
-
71
- </head>
72
- <body style="margin-top: 0; background:#A52B00; min-height:1000px; color:#000;font-family:Arial, Helvetica, sans-serif; font-size:14px"
73
- alink="#FF0000" link="#FF0000" bgcolor="#A52B00" text="#000000" yahoo="fix">
74
-
75
- <div id="body_style" style="padding:0px">
76
-
77
- <table cellpadding="0" cellspacing="0" border="0" bgcolor="#ffffff" width="600" align="center">
78
- <tr>
79
- <td width="600" colspan="3"><img src="<?php echo $theme_url; ?>/images/header.png"></td>
80
- </tr>
81
- <tr>
82
- <td width="600" align="center" colspan="3">
83
- <h1><?php echo get_option('blogname'); ?></h1>
84
- </td>
85
- </tr>
86
- <tr>
87
- <td width="20">&nbsp;</td>
88
- <td width="560">
89
- <p>Hi {name},</p>
90
-
91
- <p>The Newsletter Team wishes you merry Christmas and happy New Year. This time of year is special for us and we would like
92
- to share this time with you, also.</p>
93
-
94
- <p>We'll take a rest for few days with our families but we have a <strong>big surprise</strong> for YOU that will
95
- be unvealed the first days of the New Year.</p>
96
-
97
- <p>Curious? You can <a href="<?php echo get_option('blogname'); ?>">discover a little more right now</a>.</p>
98
-
99
- <p>
100
- See you soon, TNT.<br>
101
- <a href="<?php echo get_option('blogname'); ?>">https://www.thenewsletterplugin.com</a>
102
- </p>
103
-
104
- </td>
105
- <td width="20">&nbsp;</td>
106
- </tr>
107
- <td width="600" colspan="3">
108
- <?php include WP_PLUGIN_DIR . '/newsletter/emails/themes/default/social.php'; ?>
109
- </td>
110
- <tr>
111
- <td width="20">&nbsp;</td>
112
- <td width="560" style="color:#666">
113
- <p>To change your subscription, <a target="_blank" href="{profile_url}">click here</a>.
114
- </td>
115
- <td width="20">&nbsp;</td>
116
- </tr>
117
- <tr>
118
- <td width="600" colspan="3" bgcolor="#A52B00"><img src="<?php echo $theme_url; ?>/images/footer.png"></td>
119
- </tr>
120
- </table>
121
-
122
- </div>
123
-
124
- </body>
125
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/tnp-composer/_css/newsletter-builder.css CHANGED
@@ -28,22 +28,21 @@
28
 
29
 
30
 
31
-
32
  #newsletter-builder {
33
  position: relative;
34
  overflow: hidden;
35
- width: 100%;
36
  background-color: #FFFFFF;
37
  }
38
- #newsletter-builder-sidebar {
39
- float: left;
40
- /*position: absolute;*/
41
- left: 0px;
42
- top: 0px;
43
  overflow: auto;
44
- height: 100%;
 
 
 
 
45
  z-index: 1;
46
- height: 80vh;
47
  width: 270px;
48
  }
49
 
@@ -117,10 +116,7 @@
117
  }
118
 
119
  #newsletter-builder-area {
120
- overflow: auto;
121
  xbackground-color: #EDF1F4;
122
- height: 80vh;
123
- float: left;
124
  width: 860px;
125
  margin-left: 30px;
126
  box-sizing: border-box;
@@ -143,13 +139,10 @@
143
  }
144
 
145
  #newsletter-mobile-preview-area {
146
- float: left;
147
  margin-left: 30px;
148
  box-sizing: border-box;
149
  margin-top: 30px;
150
  text-align: center;
151
- height: 550px;
152
- min-height: 500px;
153
  border: 1px solid #eee;
154
  border-radius: 10px;
155
  padding-left: 10px;
@@ -161,7 +154,7 @@
161
 
162
  #tnp-mobile-preview {
163
  width: 340px!important;
164
- height: 100%;
165
  padding-top: 10px;
166
  padding-bottom: 10px;
167
  box-sizing: border-box;
@@ -583,3 +576,20 @@
583
  padding: 10px;
584
  border-radius: 5px;
585
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
 
30
 
 
31
  #newsletter-builder {
32
  position: relative;
33
  overflow: hidden;
34
+ xwidth: 100%;
35
  background-color: #FFFFFF;
36
  }
37
+
38
+ .tnp-builder-column {
 
 
 
39
  overflow: auto;
40
+ height: 75vh;
41
+ float: left;
42
+ }
43
+
44
+ #newsletter-builder-sidebar {
45
  z-index: 1;
 
46
  width: 270px;
47
  }
48
 
116
  }
117
 
118
  #newsletter-builder-area {
 
119
  xbackground-color: #EDF1F4;
 
 
120
  width: 860px;
121
  margin-left: 30px;
122
  box-sizing: border-box;
139
  }
140
 
141
  #newsletter-mobile-preview-area {
 
142
  margin-left: 30px;
143
  box-sizing: border-box;
144
  margin-top: 30px;
145
  text-align: center;
 
 
146
  border: 1px solid #eee;
147
  border-radius: 10px;
148
  padding-left: 10px;
154
 
155
  #tnp-mobile-preview {
156
  width: 340px!important;
157
+ height: 95%;
158
  padding-top: 10px;
159
  padding-bottom: 10px;
160
  box-sizing: border-box;
576
  padding: 10px;
577
  border-radius: 5px;
578
  }
579
+
580
+ /* Block option modal popup */
581
+
582
+ #tnpc-block-options-form {
583
+ background-color: #fff;
584
+ padding: 10px;
585
+ }
586
+
587
+ #tnpc-block-options-form th, #tnpc-block-options-form td {
588
+ padding: 5px;
589
+ }
590
+
591
+ #tnpc-block-options-form table.form-table {
592
+ margin: 0px;
593
+ border-collapse: separate!important;
594
+ border-spacing: 3px!important;
595
+ }
emails/tnp-composer/_scripts/newsletter-builder.js CHANGED
@@ -75,14 +75,11 @@ jQuery.fn.hover_edit = function () {
75
  if (target.attr("data-type") == 'title') {
76
  jQuery("#tnpc-edit-title .title").val(target.text());
77
  jQuery("#tnpc-edit-title .color").val(target.css("color"));
78
- jQuery("#tnpc-edit-title .color").wpColorPicker({
79
- // change: function (event, ui) {
80
- // jQuery('.bgcolor').iris('hide');
81
- // },
82
- });
83
  jQuery("#tnpc-edit-title .color").wpColorPicker().iris('color', target.css("color"));
84
 
85
  jQuery("#tnpc-edit-title-font-size").val(parseInt(target.css("fontSize")));
 
86
  jQuery("#tnpc-edit-title-text-align").val(target.css("textAlign"));
87
 
88
  jQuery("#tnpc-edit-title").fadeIn(500);
@@ -94,6 +91,7 @@ jQuery.fn.hover_edit = function () {
94
  target.css("color", jQuery("#tnpc-edit-title .color").val());
95
 
96
  target.css("fontSize", jQuery("#tnpc-edit-title-font-size").val() + "px");
 
97
  target.css("textAlign", jQuery("#tnpc-edit-title-text-align").val());
98
 
99
  tnp_mobile_preview();
@@ -116,17 +114,6 @@ jQuery.fn.hover_edit = function () {
116
  });
117
  }
118
 
119
- //edit icon
120
- if (target.attr("data-type") == 'icon') {
121
- jQuery("#tnpc-edit-icon").fadeIn(500);
122
- jQuery("#tnpc-edit-icon .tnpc-edit-box").slideDown(500);
123
- jQuery("#tnpc-edit-icon i").click(function () {
124
- jQuery(this).parent().parent().parent().parent().fadeOut(500)
125
- jQuery(this).parent().parent().parent().slideUp(500)
126
- target.children('i').attr('class', jQuery(this).attr('class'));
127
- });
128
- }//
129
-
130
  });
131
  }, function () {
132
  jQuery(this).children(".tnpc-row-edit-hover").remove();
@@ -342,19 +329,21 @@ jQuery(function () {
342
  //Drag & Drop
343
  jQuery("#newsletter-builder-area-center-frame-content").sortable({
344
  revert: false,
345
- //placeholder: "placeholder",
346
  forcePlaceholderSize: true,
347
  opacity: 0.6,
348
  tolerance: "pointer",
349
  update: function (event, ui) {
 
 
350
  //debugger;
351
- if (ui.item.hasClass("newsletter-sidebar-buttons-content-tab")) {
352
  loading_row = jQuery('<div style="text-align: center; padding: 20px; background-color: #d4d5d6; color: #52BE7F;"><i class="fa fa-cog fa-2x fa-spin" /></div>');
353
  ui.item.before(loading_row);
354
  ui.item.remove();
355
  var data = {
356
  'action': 'tnpc_render',
357
- 'b': ui.item.data("file"),
358
  'full': 1
359
  };
360
  jQuery.post(ajaxurl, data, function (response) {
@@ -384,11 +373,20 @@ jQuery(function () {
384
 
385
  jQuery(".newsletter-sidebar-buttons-content-tab").draggable({
386
  connectToSortable: "#newsletter-builder-area-center-frame-content",
387
- helper: "clone",
 
 
 
 
 
 
 
 
 
388
  revert: false,
389
  start: function () {
390
  if (jQuery('.tnpc-row').length) {
391
- jQuery('.tnpc-row').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
392
  } else {
393
  jQuery('#newsletter-builder-area-center-frame-content').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
394
  }
@@ -396,8 +394,6 @@ jQuery(function () {
396
  stop: function (event, ui) {
397
  //debugger;
398
  jQuery('.tnpc-drop-here').remove();
399
-
400
-
401
  }
402
  });
403
 
75
  if (target.attr("data-type") == 'title') {
76
  jQuery("#tnpc-edit-title .title").val(target.text());
77
  jQuery("#tnpc-edit-title .color").val(target.css("color"));
78
+ jQuery("#tnpc-edit-title .color").wpColorPicker({});
 
 
 
 
79
  jQuery("#tnpc-edit-title .color").wpColorPicker().iris('color', target.css("color"));
80
 
81
  jQuery("#tnpc-edit-title-font-size").val(parseInt(target.css("fontSize")));
82
+ jQuery("#tnpc-edit-title-font-family").val(target.css("fontFamily"));
83
  jQuery("#tnpc-edit-title-text-align").val(target.css("textAlign"));
84
 
85
  jQuery("#tnpc-edit-title").fadeIn(500);
91
  target.css("color", jQuery("#tnpc-edit-title .color").val());
92
 
93
  target.css("fontSize", jQuery("#tnpc-edit-title-font-size").val() + "px");
94
+ target.css("fontFamily", jQuery("#tnpc-edit-title-font-family").val());
95
  target.css("textAlign", jQuery("#tnpc-edit-title-text-align").val());
96
 
97
  tnp_mobile_preview();
114
  });
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
117
  });
118
  }, function () {
119
  jQuery(this).children(".tnpc-row-edit-hover").remove();
329
  //Drag & Drop
330
  jQuery("#newsletter-builder-area-center-frame-content").sortable({
331
  revert: false,
332
+ placeholder: "placeholder",
333
  forcePlaceholderSize: true,
334
  opacity: 0.6,
335
  tolerance: "pointer",
336
  update: function (event, ui) {
337
+ //console.log(event);
338
+ //console.log(ui.item.data("id"));
339
  //debugger;
340
+ if (ui.item.attr("id") == "draggable-helper") {
341
  loading_row = jQuery('<div style="text-align: center; padding: 20px; background-color: #d4d5d6; color: #52BE7F;"><i class="fa fa-cog fa-2x fa-spin" /></div>');
342
  ui.item.before(loading_row);
343
  ui.item.remove();
344
  var data = {
345
  'action': 'tnpc_render',
346
+ 'b': ui.item.data("id"),
347
  'full': 1
348
  };
349
  jQuery.post(ajaxurl, data, function (response) {
373
 
374
  jQuery(".newsletter-sidebar-buttons-content-tab").draggable({
375
  connectToSortable: "#newsletter-builder-area-center-frame-content",
376
+ //helper: "clone",
377
+ helper: function(e) {
378
+ //console.log(e.currentTarget.dataset.id);
379
+ //debugger;
380
+ var helper = jQuery(document.getElementById("draggable-helper")).clone();
381
+ // Do not uset .data() with jQuery
382
+ helper.attr("data-id", e.currentTarget.dataset.id);
383
+ helper.html(e.currentTarget.dataset.name);
384
+ return helper;
385
+ },
386
  revert: false,
387
  start: function () {
388
  if (jQuery('.tnpc-row').length) {
389
+ //jQuery('.tnpc-row').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
390
  } else {
391
  jQuery('#newsletter-builder-area-center-frame-content').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
392
  }
394
  stop: function (event, ui) {
395
  //debugger;
396
  jQuery('.tnpc-drop-here').remove();
 
 
397
  }
398
  });
399
 
emails/tnp-composer/blocks/content-02-heading.block.php CHANGED
@@ -1,12 +1,12 @@
1
  <!-- ONE COLUMN SECTION -->
2
  <table border="0" cellpadding="0" cellspacing="0" width="100%" class="tnpc-row" data-id="content-02">
3
  <tr>
4
- <td bgcolor="#ffffff" align="center" style="padding: 15px; font-family: Helvetica, Arial, sans-serif;" class="section-padding edit-block">
5
 
6
  <table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table" style="max-width: 100%!important">
7
  <tr>
8
  <td>
9
- <div style="line-height: normal; font-size: 25px; color: #333333; text-align: center; border: 0; width: 100%!important; display: block; background-color: transparent" class="tnpc-row-edit" data-type="title">An Awesome Title</div>
10
  </td>
11
  </tr>
12
  </table>
1
  <!-- ONE COLUMN SECTION -->
2
  <table border="0" cellpadding="0" cellspacing="0" width="100%" class="tnpc-row" data-id="content-02">
3
  <tr>
4
+ <td bgcolor="#ffffff" align="center" style="padding: 15px;" class="section-padding edit-block">
5
 
6
  <table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table" style="max-width: 100%!important">
7
  <tr>
8
  <td>
9
+ <div style="line-height: normal; font-size: 25px; font-family: Helvetica; color: #333333; text-align: center; border: 0; width: 100%!important; display: block; background-color: transparent" class="tnpc-row-edit" data-type="title">An Awesome Title</div>
10
  </td>
11
  </tr>
12
  </table>
emails/tnp-composer/blocks/content-04-cta.block.php DELETED
@@ -1,24 +0,0 @@
1
- <!-- ONE COLUMN SECTION -->
2
- <table border="0" cellpadding="0" cellspacing="0" width="100%" class="tnpc-row" data-id="content-04">
3
- <tr>
4
- <td bgcolor="#ffffff" align="center" style="padding: 20px 15px 20px 15px; font-family: Helvetica, Arial, sans-serif;" class="section-padding edit-block">
5
-
6
- <table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table">
7
- <tr>
8
- <td align="center" style="padding: 0 0 0 0;" class="padding-copy">
9
-
10
- <table border="0" cellspacing="0" cellpadding="0" class="responsive-table">
11
- <tr>
12
- <td align="center">
13
- <a href="#" target="_blank" style="font-size: 16px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #ffffff; text-decoration: none; background-color: #256F9C; border-top: 15px solid #256F9C; border-bottom: 15px solid #256F9C; border-left: 25px solid #256F9C; border-right: 25px solid #256F9C; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; display: inline-block;" class="mobile-button tnpc-row-edit" data-type="link">Learn More &rarr;</a>
14
- </td>
15
- </tr>
16
- </table>
17
-
18
- </td>
19
- </tr>
20
- </table>
21
-
22
- </td>
23
- </tr>
24
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
emails/tnp-composer/blocks/header-01-header.block.php CHANGED
@@ -14,7 +14,7 @@
14
  <?php if (!empty($block_options['header_logo']['url'])) { ?>
15
  <img alt="<?php echo esc_attr($block_options['header_title']) ?>" src="<?php echo $block_options['header_logo']['url'] ?>" style="display: block; width: 180px;" border="0">
16
  <?php } else { ?>
17
- <img alt="<?php echo esc_attr($block_options['header_title']) ?>" src="http://placehold.it/180x100&text=<?php echo esc_attr($block_options['header_title']) ?>" style="display: block; width: 180px;" border="0">
18
  <?php } ?>
19
  </a>
20
  </td>
14
  <?php if (!empty($block_options['header_logo']['url'])) { ?>
15
  <img alt="<?php echo esc_attr($block_options['header_title']) ?>" src="<?php echo $block_options['header_logo']['url'] ?>" style="display: block; width: 180px;" border="0">
16
  <?php } else { ?>
17
+ <img alt="<?php echo esc_attr($block_options['header_title']) ?>" src="https://placehold.it/180x100&text=<?php echo esc_attr($block_options['header_title']) ?>" style="display: block; width: 180px;" border="0">
18
  <?php } ?>
19
  </a>
20
  </td>
emails/tnp-composer/edit.php CHANGED
@@ -103,6 +103,28 @@ if (!defined('ABSPATH')) exit;
103
  <div class="tnpc-edit-box-content-text"><?php _e("Text Color", "newsletter") ?></div>
104
  <div class="tnpc-edit-box-content-field"><input type="text" class="tnpc-edit-box-content-field-input color"/></div>
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  <div class="tnpc-edit-box-content-text"><?php _e("Font size", "newsletter") ?></div>
107
  <div class="tnpc-edit-box-content-field">
108
  <select id="tnpc-edit-title-font-size">
@@ -115,6 +137,7 @@ if (!defined('ABSPATH')) exit;
115
  <select id="tnpc-edit-title-text-align">
116
  <option value="center">Center</option>
117
  <option value="left">Left</option>
 
118
  </select>
119
  </div>
120
  </div>
@@ -141,1272 +164,7 @@ if (!defined('ABSPATH')) exit;
141
  </div>
142
  </div>
143
 
144
-
145
- <div class="tnpc-edit" id="tnpc-edit-icon">
146
- <div class="tnpc-edit-box">
147
- <div class="tnpc-edit-box-title"><?php _e("Edit Icon", "newsletter") ?></div>
148
-
149
- <div class="tnpc-edit-box-content">
150
- <div class="tnpc-edit-box-content-text"><?php _e("Select Icon", "newsletter") ?></div>
151
- <div class="tnpc-edit-box-content-icons">
152
-
153
-
154
- <i class="fa fa-glass"></i>
155
- <i class="fa fa-music"></i>
156
- <i class="fa fa-search"></i>
157
- <i class="fa fa-envelope-o"></i>
158
- <i class="fa fa-heart"></i>
159
- <i class="fa fa-star"></i>
160
- <i class="fa fa-star-o"></i>
161
- <i class="fa fa-user"></i>
162
- <i class="fa fa-film"></i>
163
- <i class="fa fa-th-large"></i>
164
- <i class="fa fa-th"></i>
165
- <i class="fa fa-th-list"></i>
166
- <i class="fa fa-check"></i>
167
- <i class="fa fa-times"></i>
168
- <i class="fa fa-search-plus"></i>
169
- <i class="fa fa-search-minus"></i>
170
- <i class="fa fa-power-off"></i>
171
- <i class="fa fa-signal"></i>
172
- <i class="fa fa-cog"></i>
173
- <i class="fa fa-trash-o"></i>
174
- <i class="fa fa-home"></i>
175
- <i class="fa fa-file-o"></i>
176
- <i class="fa fa-clock-o"></i>
177
- <i class="fa fa-road"></i>
178
- <i class="fa fa-download"></i>
179
- <i class="fa fa-arrow-circle-o-down"></i>
180
- <i class="fa fa-arrow-circle-o-up"></i>
181
- <i class="fa fa-inbox"></i>
182
- <i class="fa fa-play-circle-o"></i>
183
- <i class="fa fa-repeat"></i>
184
- <i class="fa fa-refresh"></i>
185
- <i class="fa fa-list-alt"></i>
186
- <i class="fa fa-lock"></i>
187
- <i class="fa fa-flag"></i>
188
- <i class="fa fa-headphones"></i>
189
- <i class="fa fa-volume-off"></i>
190
- <i class="fa fa-volume-down"></i>
191
- <i class="fa fa-volume-up"></i>
192
- <i class="fa fa-qrcode"></i>
193
- <i class="fa fa-barcode"></i>
194
- <i class="fa fa-tag"></i>
195
- <i class="fa fa-tags"></i>
196
- <i class="fa fa-book"></i>
197
- <i class="fa fa-bookmark"></i>
198
- <i class="fa fa-print"></i>
199
- <i class="fa fa-camera"></i>
200
- <i class="fa fa-font"></i>
201
- <i class="fa fa-bold"></i>
202
- <i class="fa fa-italic"></i>
203
- <i class="fa fa-text-height"></i>
204
- <i class="fa fa-text-width"></i>
205
- <i class="fa fa-align-left"></i>
206
- <i class="fa fa-align-center"></i>
207
- <i class="fa fa-align-right"></i>
208
- <i class="fa fa-align-justify"></i>
209
- <i class="fa fa-list"></i>
210
- <i class="fa fa-outdent"></i>
211
- <i class="fa fa-indent"></i>
212
- <i class="fa fa-video-camera"></i>
213
- <i class="fa fa-picture-o"></i>
214
- <i class="fa fa-pencil"></i>
215
- <i class="fa fa-map-marker"></i>
216
- <i class="fa fa-adjust"></i>
217
- <i class="fa fa-tint"></i>
218
- <i class="fa fa-pencil-square-o"></i>
219
- <i class="fa fa-share-square-o"></i>
220
- <i class="fa fa-check-square-o"></i>
221
- <i class="fa fa-arrows"></i>
222
- <i class="fa fa-step-backward"></i>
223
- <i class="fa fa-fast-backward"></i>
224
- <i class="fa fa-backward"></i>
225
- <i class="fa fa-play"></i>
226
- <i class="fa fa-pause"></i>
227
- <i class="fa fa-stop"></i>
228
- <i class="fa fa-forward"></i>
229
- <i class="fa fa-fast-forward"></i>
230
- <i class="fa fa-step-forward"></i>
231
- <i class="fa fa-eject"></i>
232
- <i class="fa fa-chevron-left"></i>
233
- <i class="fa fa-chevron-right"></i>
234
- <i class="fa fa-plus-circle"></i>
235
- <i class="fa fa-minus-circle"></i>
236
- <i class="fa fa-times-circle"></i>
237
- <i class="fa fa-check-circle"></i>
238
- <i class="fa fa-question-circle"></i>
239
- <i class="fa fa-info-circle"></i>
240
- <i class="fa fa-crosshairs"></i>
241
- <i class="fa fa-times-circle-o"></i>
242
- <i class="fa fa-check-circle-o"></i>
243
- <i class="fa fa-ban"></i>
244
- <i class="fa fa-arrow-left"></i>
245
- <i class="fa fa-arrow-right"></i>
246
- <i class="fa fa-arrow-up"></i>
247
- <i class="fa fa-arrow-down"></i>
248
- <i class="fa fa-share"></i>
249
- <i class="fa fa-expand"></i>
250
- <i class="fa fa-compress"></i>
251
- <i class="fa fa-plus"></i>
252
- <i class="fa fa-minus"></i>
253
- <i class="fa fa-asterisk"></i>
254
- <i class="fa fa-exclamation-circle"></i>
255
- <i class="fa fa-gift"></i>
256
- <i class="fa fa-leaf"></i>
257
- <i class="fa fa-fire"></i>
258
- <i class="fa fa-eye"></i>
259
- <i class="fa fa-eye-slash"></i>
260
- <i class="fa fa-exclamation-triangle"></i>
261
- <i class="fa fa-plane"></i>
262
- <i class="fa fa-calendar"></i>
263
- <i class="fa fa-random"></i>
264
- <i class="fa fa-comment"></i>
265
- <i class="fa fa-magnet"></i>
266
- <i class="fa fa-chevron-up"></i>
267
- <i class="fa fa-chevron-down"></i>
268
- <i class="fa fa-retweet"></i>
269
- <i class="fa fa-shopping-cart"></i>
270
- <i class="fa fa-folder"></i>
271
- <i class="fa fa-folder-open"></i>
272
- <i class="fa fa-arrows-v"></i>
273
- <i class="fa fa-arrows-h"></i>
274
- <i class="fa fa-bar-chart"></i>
275
- <i class="fa fa-twitter-square"></i>
276
- <i class="fa fa-facebook-square"></i>
277
- <i class="fa fa-camera-retro"></i>
278
- <i class="fa fa-key"></i>
279
- <i class="fa fa-cogs"></i>
280
- <i class="fa fa-comments"></i>
281
- <i class="fa fa-thumbs-o-up"></i>
282
- <i class="fa fa-thumbs-o-down"></i>
283
- <i class="fa fa-star-half"></i>
284
- <i class="fa fa-heart-o"></i>
285
- <i class="fa fa-sign-out"></i>
286
- <i class="fa fa-linkedin-square"></i>
287
- <i class="fa fa-thumb-tack"></i>
288
- <i class="fa fa-external-link"></i>
289
- <i class="fa fa-sign-in"></i>
290
- <i class="fa fa-trophy"></i>
291
- <i class="fa fa-github-square"></i>
292
- <i class="fa fa-upload"></i>
293
- <i class="fa fa-lemon-o"></i>
294
- <i class="fa fa-phone"></i>
295
- <i class="fa fa-square-o"></i>
296
- <i class="fa fa-bookmark-o"></i>
297
- <i class="fa fa-phone-square"></i>
298
- <i class="fa fa-twitter"></i>
299
- <i class="fa fa-facebook"></i>
300
- <i class="fa fa-github"></i>
301
- <i class="fa fa-unlock"></i>
302
- <i class="fa fa-credit-card"></i>
303
- <i class="fa fa-rss"></i>
304
- <i class="fa fa-hdd-o"></i>
305
- <i class="fa fa-bullhorn"></i>
306
- <i class="fa fa-bell"></i>
307
- <i class="fa fa-certificate"></i>
308
- <i class="fa fa-hand-o-right"></i>
309
- <i class="fa fa-hand-o-left"></i>
310
- <i class="fa fa-hand-o-up"></i>
311
- <i class="fa fa-hand-o-down"></i>
312
- <i class="fa fa-arrow-circle-left"></i>
313
- <i class="fa fa-arrow-circle-right"></i>
314
- <i class="fa fa-arrow-circle-up"></i>
315
- <i class="fa fa-arrow-circle-down"></i>
316
- <i class="fa fa-globe"></i>
317
- <i class="fa fa-wrench"></i>
318
- <i class="fa fa-tasks"></i>
319
- <i class="fa fa-filter"></i>
320
- <i class="fa fa-briefcase"></i>
321
- <i class="fa fa-arrows-alt"></i>
322
- <i class="fa fa-users"></i>
323
- <i class="fa fa-link"></i>
324
- <i class="fa fa-cloud"></i>
325
- <i class="fa fa-flask"></i>
326
- <i class="fa fa-scissors"></i>
327
- <i class="fa fa-files-o"></i>
328
- <i class="fa fa-paperclip"></i>
329
- <i class="fa fa-floppy-o"></i>
330
- <i class="fa fa-square"></i>
331
- <i class="fa fa-bars"></i>
332
- <i class="fa fa-list-ul"></i>
333
- <i class="fa fa-list-ol"></i>
334
- <i class="fa fa-strikethrough"></i>
335
- <i class="fa fa-underline"></i>
336
- <i class="fa fa-table"></i>
337
- <i class="fa fa-magic"></i>
338
- <i class="fa fa-truck"></i>
339
- <i class="fa fa-pinterest"></i>
340
- <i class="fa fa-pinterest-square"></i>
341
- <i class="fa fa-google-plus-square"></i>
342
- <i class="fa fa-google-plus"></i>
343
- <i class="fa fa-money"></i>
344
- <i class="fa fa-caret-down"></i>
345
- <i class="fa fa-caret-up"></i>
346
- <i class="fa fa-caret-left"></i>
347
- <i class="fa fa-caret-right"></i>
348
- <i class="fa fa-columns"></i>
349
- <i class="fa fa-sort"></i>
350
- <i class="fa fa-sort-desc"></i>
351
- <i class="fa fa-sort-asc"></i>
352
- <i class="fa fa-envelope"></i>
353
- <i class="fa fa-linkedin"></i>
354
- <i class="fa fa-undo"></i>
355
- <i class="fa fa-gavel"></i>
356
- <i class="fa fa-tachometer"></i>
357
- <i class="fa fa-comment-o"></i>
358
- <i class="fa fa-comments-o"></i>
359
- <i class="fa fa-bolt"></i>
360
- <i class="fa fa-sitemap"></i>
361
- <i class="fa fa-umbrella"></i>
362
- <i class="fa fa-clipboard"></i>
363
- <i class="fa fa-lightbulb-o"></i>
364
- <i class="fa fa-exchange"></i>
365
- <i class="fa fa-cloud-download"></i>
366
- <i class="fa fa-cloud-upload"></i>
367
- <i class="fa fa-user-md"></i>
368
- <i class="fa fa-stethoscope"></i>
369
- <i class="fa fa-suitcase"></i>
370
- <i class="fa fa-bell-o"></i>
371
- <i class="fa fa-coffee"></i>
372
- <i class="fa fa-cutlery"></i>
373
- <i class="fa fa-file-text-o"></i>
374
- <i class="fa fa-building-o"></i>
375
- <i class="fa fa-hospital-o"></i>
376
- <i class="fa fa-ambulance"></i>
377
- <i class="fa fa-medkit"></i>
378
- <i class="fa fa-fighter-jet"></i>
379
- <i class="fa fa-beer"></i>
380
- <i class="fa fa-h-square"></i>
381
- <i class="fa fa-plus-square"></i>
382
- <i class="fa fa-angle-double-left"></i>
383
- <i class="fa fa-angle-double-right"></i>
384
- <i class="fa fa-angle-double-up"></i>
385
- <i class="fa fa-angle-double-down"></i>
386
- <i class="fa fa-angle-left"></i>
387
- <i class="fa fa-angle-right"></i>
388
- <i class="fa fa-angle-up"></i>
389
- <i class="fa fa-angle-down"></i>
390
- <i class="fa fa-desktop"></i>
391
- <i class="fa fa-laptop"></i>
392
- <i class="fa fa-tablet"></i>
393
- <i class="fa fa-mobile"></i>
394
- <i class="fa fa-circle-o"></i>
395
- <i class="fa fa-quote-left"></i>
396
- <i class="fa fa-quote-right"></i>
397
- <i class="fa fa-spinner"></i>
398
- <i class="fa fa-circle"></i>
399
- <i class="fa fa-reply"></i>
400
- <i class="fa fa-github-alt"></i>
401
- <i class="fa fa-folder-o"></i>
402
- <i class="fa fa-folder-open-o"></i>
403
- <i class="fa fa-smile-o"></i>
404
- <i class="fa fa-frown-o"></i>
405
- <i class="fa fa-meh-o"></i>
406
- <i class="fa fa-gamepad"></i>
407
- <i class="fa fa-keyboard-o"></i>
408
- <i class="fa fa-flag-o"></i>
409
- <i class="fa fa-flag-checkered"></i>
410
- <i class="fa fa-terminal"></i>
411
- <i class="fa fa-code"></i>
412
- <i class="fa fa-reply-all"></i>
413
- <i class="fa fa-star-half-o"></i>
414
- <i class="fa fa-location-arrow"></i>
415
- <i class="fa fa-crop"></i>
416
- <i class="fa fa-code-fork"></i>
417
- <i class="fa fa-chain-broken"></i>
418
- <i class="fa fa-question"></i>
419
- <i class="fa fa-info"></i>
420
- <i class="fa fa-exclamation"></i>
421
- <i class="fa fa-superscript"></i>
422
- <i class="fa fa-subscript"></i>
423
- <i class="fa fa-eraser"></i>
424
- <i class="fa fa-puzzle-piece"></i>
425
- <i class="fa fa-microphone"></i>
426
- <i class="fa fa-microphone-slash"></i>
427
- <i class="fa fa-shield"></i>
428
- <i class="fa fa-calendar-o"></i>
429
- <i class="fa fa-fire-extinguisher"></i>
430
- <i class="fa fa-rocket"></i>
431
- <i class="fa fa-maxcdn"></i>
432
- <i class="fa fa-chevron-circle-left"></i>
433
- <i class="fa fa-chevron-circle-right"></i>
434
- <i class="fa fa-chevron-circle-up"></i>
435
- <i class="fa fa-chevron-circle-down"></i>
436
- <i class="fa fa-html5"></i>
437
- <i class="fa fa-css3"></i>
438
- <i class="fa fa-anchor"></i>
439
- <i class="fa fa-unlock-alt"></i>
440
- <i class="fa fa-bullseye"></i>
441
- <i class="fa fa-ellipsis-h"></i>
442
- <i class="fa fa-ellipsis-v"></i>
443
- <i class="fa fa-rss-square"></i>
444
- <i class="fa fa-play-circle"></i>
445
- <i class="fa fa-ticket"></i>
446
- <i class="fa fa-minus-square"></i>
447
- <i class="fa fa-minus-square-o"></i>
448
- <i class="fa fa-level-up"></i>
449
- <i class="fa fa-level-down"></i>
450
- <i class="fa fa-check-square"></i>
451
- <i class="fa fa-pencil-square"></i>
452
- <i class="fa fa-external-link-square"></i>
453
- <i class="fa fa-share-square"></i>
454
- <i class="fa fa-compass"></i>
455
- <i class="fa fa-caret-square-o-down"></i>
456
- <i class="fa fa-caret-square-o-up"></i>
457
- <i class="fa fa-caret-square-o-right"></i>
458
- <i class="fa fa-eur"></i>
459
- <i class="fa fa-gbp"></i>
460
- <i class="fa fa-usd"></i>
461
- <i class="fa fa-inr"></i>
462
- <i class="fa fa-jpy"></i>
463
- <i class="fa fa-rub"></i>
464
- <i class="fa fa-krw"></i>
465
- <i class="fa fa-btc"></i>
466
- <i class="fa fa-file"></i>
467
- <i class="fa fa-file-text"></i>
468
- <i class="fa fa-sort-alpha-asc"></i>
469
- <i class="fa fa-sort-alpha-desc"></i>
470
- <i class="fa fa-sort-amount-asc"></i>
471
- <i class="fa fa-sort-amount-desc"></i>
472
- <i class="fa fa-sort-numeric-asc"></i>
473
- <i class="fa fa-sort-numeric-desc"></i>
474
- <i class="fa fa-thumbs-up"></i>
475
- <i class="fa fa-thumbs-down"></i>
476
- <i class="fa fa-youtube-square"></i>
477
- <i class="fa fa-youtube"></i>
478
- <i class="fa fa-xing"></i>
479
- <i class="fa fa-xing-square"></i>
480
- <i class="fa fa-youtube-play"></i>
481
- <i class="fa fa-dropbox"></i>
482
- <i class="fa fa-stack-overflow"></i>
483
- <i class="fa fa-instagram"></i>
484
- <i class="fa fa-flickr"></i>
485
- <i class="fa fa-adn"></i>
486
- <i class="fa fa-bitbucket"></i>
487
- <i class="fa fa-bitbucket-square"></i>
488
- <i class="fa fa-tumblr"></i>
489
- <i class="fa fa-tumblr-square"></i>
490
- <i class="fa fa-long-arrow-down"></i>
491
- <i class="fa fa-long-arrow-up"></i>
492
- <i class="fa fa-long-arrow-left"></i>
493
- <i class="fa fa-long-arrow-right"></i>
494
- <i class="fa fa-apple"></i>
495
- <i class="fa fa-windows"></i>
496
- <i class="fa fa-android"></i>
497
- <i class="fa fa-linux"></i>
498
- <i class="fa fa-dribbble"></i>
499
- <i class="fa fa-skype"></i>
500
- <i class="fa fa-foursquare"></i>
501
- <i class="fa fa-trello"></i>
502
- <i class="fa fa-female"></i>
503
- <i class="fa fa-male"></i>
504
- <i class="fa fa-gratipay"></i>
505
- <i class="fa fa-sun-o"></i>
506
- <i class="fa fa-moon-o"></i>
507
- <i class="fa fa-archive"></i>
508
- <i class="fa fa-bug"></i>
509
- <i class="fa fa-vk"></i>
510
- <i class="fa fa-weibo"></i>
511
- <i class="fa fa-renren"></i>
512
- <i class="fa fa-pagelines"></i>
513
- <i class="fa fa-stack-exchange"></i>
514
- <i class="fa fa-arrow-circle-o-right"></i>
515
- <i class="fa fa-arrow-circle-o-left"></i>
516
- <i class="fa fa-caret-square-o-left"></i>
517
- <i class="fa fa-dot-circle-o"></i>
518
- <i class="fa fa-wheelchair"></i>
519
- <i class="fa fa-vimeo-square"></i>
520
- <i class="fa fa-try"></i>
521
- <i class="fa fa-plus-square-o"></i>
522
- <i class="fa fa-space-shuttle"></i>
523
- <i class="fa fa-slack"></i>
524
- <i class="fa fa-envelope-square"></i>
525
- <i class="fa fa-wordpress"></i>
526
- <i class="fa fa-openid"></i>
527
- <i class="fa fa-university"></i>
528
- <i class="fa fa-graduation-cap"></i>
529
- <i class="fa fa-yahoo"></i>
530
- <i class="fa fa-google"></i>
531
- <i class="fa fa-reddit"></i>
532
- <i class="fa fa-reddit-square"></i>
533
- <i class="fa fa-stumbleupon-circle"></i>
534
- <i class="fa fa-stumbleupon"></i>
535
- <i class="fa fa-delicious"></i>
536
- <i class="fa fa-digg"></i>
537
- <i class="fa fa-pied-piper"></i>
538
- <i class="fa fa-pied-piper-alt"></i>
539
- <i class="fa fa-drupal"></i>
540
- <i class="fa fa-joomla"></i>
541
- <i class="fa fa-language"></i>
542
- <i class="fa fa-fax"></i>
543
- <i class="fa fa-building"></i>
544
- <i class="fa fa-child"></i>
545
- <i class="fa fa-paw"></i>
546
- <i class="fa fa-spoon"></i>
547
- <i class="fa fa-cube"></i>
548
- <i class="fa fa-cubes"></i>
549
- <i class="fa fa-behance"></i>
550
- <i class="fa fa-behance-square"></i>
551
- <i class="fa fa-steam"></i>
552
- <i class="fa fa-steam-square"></i>
553
- <i class="fa fa-recycle"></i>
554
- <i class="fa fa-car"></i>
555
- <i class="fa fa-taxi"></i>
556
- <i class="fa fa-tree"></i>
557
- <i class="fa fa-spotify"></i>
558
- <i class="fa fa-deviantart"></i>
559
- <i class="fa fa-soundcloud"></i>
560
- <i class="fa fa-database"></i>
561
- <i class="fa fa-file-pdf-o"></i>
562
- <i class="fa fa-file-word-o"></i>
563
- <i class="fa fa-file-excel-o"></i>
564
- <i class="fa fa-file-powerpoint-o"></i>
565
- <i class="fa fa-file-image-o"></i>
566
- <i class="fa fa-file-archive-o"></i>
567
- <i class="fa fa-file-audio-o"></i>
568
- <i class="fa fa-file-video-o"></i>
569
- <i class="fa fa-file-code-o"></i>
570
- <i class="fa fa-vine"></i>
571
- <i class="fa fa-codepen"></i>
572
- <i class="fa fa-jsfiddle"></i>
573
- <i class="fa fa-life-ring"></i>
574
- <i class="fa fa-circle-o-notch"></i>
575
- <i class="fa fa-rebel"></i>
576
- <i class="fa fa-empire"></i>
577
- <i class="fa fa-git-square"></i>
578
- <i class="fa fa-git"></i>
579
- <i class="fa fa-hacker-news"></i>
580
- <i class="fa fa-tencent-weibo"></i>
581
- <i class="fa fa-qq"></i>
582
- <i class="fa fa-weixin"></i>
583
- <i class="fa fa-paper-plane"></i>
584
- <i class="fa fa-paper-plane-o"></i>
585
- <i class="fa fa-history"></i>
586
- <i class="fa fa-circle-thin"></i>
587
- <i class="fa fa-header"></i>
588
- <i class="fa fa-paragraph"></i>
589
- <i class="fa fa-sliders"></i>
590
- <i class="fa fa-share-alt"></i>
591
- <i class="fa fa-share-alt-square"></i>
592
- <i class="fa fa-bomb"></i>
593
- <i class="fa fa-futbol-o"></i>
594
- <i class="fa fa-tty"></i>
595
- <i class="fa fa-binoculars"></i>
596
- <i class="fa fa-plug"></i>
597
- <i class="fa fa-slideshare"></i>
598
- <i class="fa fa-twitch"></i>
599
- <i class="fa fa-yelp"></i>
600
- <i class="fa fa-newspaper-o"></i>
601
- <i class="fa fa-wifi"></i>
602
- <i class="fa fa-calculator"></i>
603
- <i class="fa fa-paypal"></i>
604
- <i class="fa fa-google-wallet"></i>
605
- <i class="fa fa-cc-visa"></i>
606
- <i class="fa fa-cc-mastercard"></i>
607
- <i class="fa fa-cc-discover"></i>
608
- <i class="fa fa-cc-amex"></i>
609
- <i class="fa fa-cc-paypal"></i>
610
- <i class="fa fa-cc-stripe"></i>
611
- <i class="fa fa-bell-slash"></i>
612
- <i class="fa fa-bell-slash-o"></i>
613
- <i class="fa fa-trash"></i>
614
- <i class="fa fa-copyright"></i>
615
- <i class="fa fa-at"></i>
616
- <i class="fa fa-eyedropper"></i>
617
- <i class="fa fa-paint-brush"></i>
618
- <i class="fa fa-birthday-cake"></i>
619
- <i class="fa fa-area-chart"></i>
620
- <i class="fa fa-pie-chart"></i>
621
- <i class="fa fa-line-chart"></i>
622
- <i class="fa fa-lastfm"></i>
623
- <i class="fa fa-lastfm-square"></i>
624
- <i class="fa fa-toggle-off"></i>
625
- <i class="fa fa-toggle-on"></i>
626
- <i class="fa fa-bicycle"></i>
627
- <i class="fa fa-bus"></i>
628
- <i class="fa fa-ioxhost"></i>
629
- <i class="fa fa-angellist"></i>
630
- <i class="fa fa-cc"></i>
631
- <i class="fa fa-ils"></i>
632
- <i class="fa fa-meanpath"></i>
633
- <i class="fa fa-buysellads"></i>
634
- <i class="fa fa-connectdevelop"></i>
635
- <i class="fa fa-dashcube"></i>
636
- <i class="fa fa-forumbee"></i>
637
- <i class="fa fa-leanpub"></i>
638
- <i class="fa fa-sellsy"></i>
639
- <i class="fa fa-shirtsinbulk"></i>
640
- <i class="fa fa-simplybuilt"></i>
641
- <i class="fa fa-skyatlas"></i>
642
- <i class="fa fa-cart-plus"></i>
643
- <i class="fa fa-cart-arrow-down"></i>
644
- <i class="fa fa-diamond"></i>
645
- <i class="fa fa-ship"></i>
646
- <i class="fa fa-user-secret"></i>
647
- <i class="fa fa-motorcycle"></i>
648
- <i class="fa fa-street-view"></i>
649
- <i class="fa fa-heartbeat"></i>
650
- <i class="fa fa-venus"></i>
651
- <i class="fa fa-mars"></i>
652
- <i class="fa fa-mercury"></i>
653
- <i class="fa fa-transgender"></i>
654
- <i class="fa fa-transgender-alt"></i>
655
- <i class="fa fa-venus-double"></i>
656
- <i class="fa fa-mars-double"></i>
657
- <i class="fa fa-venus-mars"></i>
658
- <i class="fa fa-mars-stroke"></i>
659
- <i class="fa fa-mars-stroke-v"></i>
660
- <i class="fa fa-mars-stroke-h"></i>
661
- <i class="fa fa-neuter"></i>
662
- <i class="fa fa-facebook-official"></i>
663
- <i class="fa fa-pinterest-p"></i>
664
- <i class="fa fa-whatsapp"></i>
665
- <i class="fa fa-server"></i>
666
- <i class="fa fa-user-plus"></i>
667
- <i class="fa fa-user-times"></i>
668
- <i class="fa fa-bed"></i>
669
- <i class="fa fa-viacoin"></i>
670
- <i class="fa fa-train"></i>
671
- <i class="fa fa-subway"></i>
672
- <i class="fa fa-medium"></i>
673
- <i class="fa fa-warning margin-right-sm"></i>
674
- <i class="fa fa-exclamation-circle margin-right-sm"></i>
675
- <i class="fa fa-bed"></i>
676
- <i class="fa fa-buysellads"></i>
677
- <i class="fa fa-cart-arrow-down"></i>
678
- <i class="fa fa-cart-plus"></i>
679
- <i class="fa fa-connectdevelop"></i>
680
- <i class="fa fa-dashcube"></i>
681
- <i class="fa fa-diamond"></i>
682
- <i class="fa fa-facebook-official"></i>
683
- <i class="fa fa-forumbee"></i>
684
- <i class="fa fa-heartbeat"></i>
685
- <i class="fa fa-hotel"></i>
686
- <i class="fa fa-leanpub"></i>
687
- <i class="fa fa-mars"></i>
688
- <i class="fa fa-mars-double"></i>
689
- <i class="fa fa-mars-stroke"></i>
690
- <i class="fa fa-mars-stroke-h"></i>
691
- <i class="fa fa-mars-stroke-v"></i>
692
- <i class="fa fa-medium"></i>
693
- <i class="fa fa-mercury"></i>
694
- <i class="fa fa-motorcycle"></i>
695
- <i class="fa fa-neuter"></i>
696
- <i class="fa fa-pinterest-p"></i>
697
- <i class="fa fa-sellsy"></i>
698
- <i class="fa fa-server"></i>
699
- <i class="fa fa-ship"></i>
700
- <i class="fa fa-shirtsinbulk"></i>
701
- <i class="fa fa-simplybuilt"></i>
702
- <i class="fa fa-skyatlas"></i>
703
- <i class="fa fa-street-view"></i>
704
- <i class="fa fa-subway"></i>
705
- <i class="fa fa-train"></i>
706
- <i class="fa fa-transgender"></i>
707
- <i class="fa fa-transgender-alt"></i>
708
- <i class="fa fa-user-plus"></i>
709
- <i class="fa fa-user-secret"></i>
710
- <i class="fa fa-user-times"></i>
711
- <i class="fa fa-venus"></i>
712
- <i class="fa fa-venus-double"></i>
713
- <i class="fa fa-venus-mars"></i>
714
- <i class="fa fa-viacoin"></i>
715
- <i class="fa fa-whatsapp"></i>
716
- <i class="fa fa-adjust"></i>
717
- <i class="fa fa-anchor"></i>
718
- <i class="fa fa-archive"></i>
719
- <i class="fa fa-area-chart"></i>
720
- <i class="fa fa-arrows"></i>
721
- <i class="fa fa-arrows-h"></i>
722
- <i class="fa fa-arrows-v"></i>
723
- <i class="fa fa-asterisk"></i>
724
- <i class="fa fa-at"></i>
725
- <i class="fa fa-automobile"></i>
726
- <i class="fa fa-ban"></i>
727
- <i class="fa fa-bank"></i>
728
- <i class="fa fa-bar-chart"></i>
729
- <i class="fa fa-bar-chart-o"></i>
730
- <i class="fa fa-barcode"></i>
731
- <i class="fa fa-bars"></i>
732
- <i class="fa fa-bed"></i>
733
- <i class="fa fa-beer"></i>
734
- <i class="fa fa-bell"></i>
735
- <i class="fa fa-bell-o"></i>
736
- <i class="fa fa-bell-slash"></i>
737
- <i class="fa fa-bell-slash-o"></i>
738
- <i class="fa fa-bicycle"></i>
739
- <i class="fa fa-binoculars"></i>
740
- <i class="fa fa-birthday-cake"></i>
741
- <i class="fa fa-bolt"></i>
742
- <i class="fa fa-bomb"></i>
743
- <i class="fa fa-book"></i>
744
- <i class="fa fa-bookmark"></i>
745
- <i class="fa fa-bookmark-o"></i>
746
- <i class="fa fa-briefcase"></i>
747
- <i class="fa fa-bug"></i>
748
- <i class="fa fa-building"></i>
749
- <i class="fa fa-building-o"></i>
750
- <i class="fa fa-bullhorn"></i>
751
- <i class="fa fa-bullseye"></i>
752
- <i class="fa fa-bus"></i>
753
- <i class="fa fa-cab"></i>
754
- <i class="fa fa-calculator"></i>
755
- <i class="fa fa-calendar"></i>
756
- <i class="fa fa-calendar-o"></i>
757
- <i class="fa fa-camera"></i>
758
- <i class="fa fa-camera-retro"></i>
759
- <i class="fa fa-car"></i>
760
- <i class="fa fa-caret-square-o-down"></i>
761
- <i class="fa fa-caret-square-o-left"></i>
762
- <i class="fa fa-caret-square-o-right"></i>
763
- <i class="fa fa-caret-square-o-up"></i>
764
- <i class="fa fa-cart-arrow-down"></i>
765
- <i class="fa fa-cart-plus"></i>
766
- <i class="fa fa-cc"></i>
767
- <i class="fa fa-certificate"></i>
768
- <i class="fa fa-check"></i>
769
- <i class="fa fa-check-circle"></i>
770
- <i class="fa fa-check-circle-o"></i>
771
- <i class="fa fa-check-square"></i>
772
- <i class="fa fa-check-square-o"></i>
773
- <i class="fa fa-child"></i>
774
- <i class="fa fa-circle"></i>
775
- <i class="fa fa-circle-o"></i>
776
- <i class="fa fa-circle-o-notch"></i>
777
- <i class="fa fa-circle-thin"></i>
778
- <i class="fa fa-clock-o"></i>
779
- <i class="fa fa-close"></i>
780
- <i class="fa fa-cloud"></i>
781
- <i class="fa fa-cloud-download"></i>
782
- <i class="fa fa-cloud-upload"></i>
783
- <i class="fa fa-code"></i>
784
- <i class="fa fa-code-fork"></i>
785
- <i class="fa fa-coffee"></i>
786
- <i class="fa fa-cog"></i>
787
- <i class="fa fa-cogs"></i>
788
- <i class="fa fa-comment"></i>
789
- <i class="fa fa-comment-o"></i>
790
- <i class="fa fa-comments"></i>
791
- <i class="fa fa-comments-o"></i>
792
- <i class="fa fa-compass"></i>
793
- <i class="fa fa-copyright"></i>
794
- <i class="fa fa-credit-card"></i>
795
- <i class="fa fa-crop"></i>
796
- <i class="fa fa-crosshairs"></i>
797
- <i class="fa fa-cube"></i>
798
- <i class="fa fa-cubes"></i>
799
- <i class="fa fa-cutlery"></i>
800
- <i class="fa fa-dashboard"></i>
801
- <i class="fa fa-database"></i>
802
- <i class="fa fa-desktop"></i>
803
- <i class="fa fa-diamond"></i>
804
- <i class="fa fa-dot-circle-o"></i>
805
- <i class="fa fa-download"></i>
806
- <i class="fa fa-edit"></i>
807
- <i class="fa fa-ellipsis-h"></i>
808
- <i class="fa fa-ellipsis-v"></i>
809
- <i class="fa fa-envelope"></i>
810
- <i class="fa fa-envelope-o"></i>
811
- <i class="fa fa-envelope-square"></i>
812
- <i class="fa fa-eraser"></i>
813
- <i class="fa fa-exchange"></i>
814
- <i class="fa fa-exclamation"></i>
815
- <i class="fa fa-exclamation-circle"></i>
816
- <i class="fa fa-exclamation-triangle"></i>
817
- <i class="fa fa-external-link"></i>
818
- <i class="fa fa-external-link-square"></i>
819
- <i class="fa fa-eye"></i>
820
- <i class="fa fa-eye-slash"></i>
821
- <i class="fa fa-eyedropper"></i>
822
- <i class="fa fa-fax"></i>
823
- <i class="fa fa-female"></i>
824
- <i class="fa fa-fighter-jet"></i>
825
- <i class="fa fa-file-archive-o"></i>
826
- <i class="fa fa-file-audio-o"></i>
827
- <i class="fa fa-file-code-o"></i>
828
- <i class="fa fa-file-excel-o"></i>
829
- <i class="fa fa-file-image-o"></i>
830
- <i class="fa fa-file-movie-o"></i>
831
- <i class="fa fa-file-pdf-o"></i>
832
- <i class="fa fa-file-photo-o"></i>
833
- <i class="fa fa-file-picture-o"></i>
834
- <i class="fa fa-file-powerpoint-o"></i>
835
- <i class="fa fa-file-sound-o"></i>
836
- <i class="fa fa-file-video-o"></i>
837
- <i class="fa fa-file-word-o"></i>
838
- <i class="fa fa-file-zip-o"></i>
839
- <i class="fa fa-film"></i>
840
- <i class="fa fa-filter"></i>
841
- <i class="fa fa-fire"></i>
842
- <i class="fa fa-fire-extinguisher"></i>
843
- <i class="fa fa-flag"></i>
844
- <i class="fa fa-flag-checkered"></i>
845
- <i class="fa fa-flag-o"></i>
846
- <i class="fa fa-flash"></i>
847
- <i class="fa fa-flask"></i>
848
- <i class="fa fa-folder"></i>
849
- <i class="fa fa-folder-o"></i>
850
- <i class="fa fa-folder-open"></i>
851
- <i class="fa fa-folder-open-o"></i>
852
- <i class="fa fa-frown-o"></i>
853
- <i class="fa fa-futbol-o"></i>
854
- <i class="fa fa-gamepad"></i>
855
- <i class="fa fa-gavel"></i>
856
- <i class="fa fa-gear"></i>
857
- <i class="fa fa-gears"></i>
858
- <i class="fa fa-genderless"></i>
859
- <i class="fa fa-gift"></i>
860
- <i class="fa fa-glass"></i>
861
- <i class="fa fa-globe"></i>
862
- <i class="fa fa-graduation-cap"></i>
863
- <i class="fa fa-group"></i>
864
- <i class="fa fa-hdd-o"></i>
865
- <i class="fa fa-headphones"></i>
866
- <i class="fa fa-heart"></i>
867
- <i class="fa fa-heart-o"></i>
868
- <i class="fa fa-heartbeat"></i>
869
- <i class="fa fa-history"></i>
870
- <i class="fa fa-home"></i>
871
- <i class="fa fa-hotel"></i>
872
- <i class="fa fa-image"></i>
873
- <i class="fa fa-inbox"></i>
874
- <i class="fa fa-info"></i>
875
- <i class="fa fa-info-circle"></i>
876
- <i class="fa fa-institution"></i>
877
- <i class="fa fa-key"></i>
878
- <i class="fa fa-keyboard-o"></i>
879
- <i class="fa fa-language"></i>
880
- <i class="fa fa-laptop"></i>
881
- <i class="fa fa-leaf"></i>
882
- <i class="fa fa-legal"></i>
883
- <i class="fa fa-lemon-o"></i>
884
- <i class="fa fa-level-down"></i>
885
- <i class="fa fa-level-up"></i>
886
- <i class="fa fa-life-bouy"></i>
887
- <i class="fa fa-life-buoy"></i>
888
- <i class="fa fa-life-ring"></i>
889
- <i class="fa fa-life-saver"></i>
890
- <i class="fa fa-lightbulb-o"></i>
891
- <i class="fa fa-line-chart"></i>
892
- <i class="fa fa-location-arrow"></i>
893
- <i class="fa fa-lock"></i>
894
- <i class="fa fa-magic"></i>
895
- <i class="fa fa-magnet"></i>
896
- <i class="fa fa-mail-forward"></i>
897
- <i class="fa fa-mail-reply"></i>
898
- <i class="fa fa-mail-reply-all"></i>
899
- <i class="fa fa-male"></i>
900
- <i class="fa fa-map-marker"></i>
901
- <i class="fa fa-meh-o"></i>
902
- <i class="fa fa-microphone"></i>
903
- <i class="fa fa-microphone-slash"></i>
904
- <i class="fa fa-minus"></i>
905
- <i class="fa fa-minus-circle"></i>
906
- <i class="fa fa-minus-square"></i>
907
- <i class="fa fa-minus-square-o"></i>
908
- <i class="fa fa-mobile"></i>
909
- <i class="fa fa-mobile-phone"></i>
910
- <i class="fa fa-money"></i>
911
- <i class="fa fa-moon-o"></i>
912
- <i class="fa fa-mortar-board"></i>
913
- <i class="fa fa-motorcycle"></i>
914
- <i class="fa fa-music"></i>
915
- <i class="fa fa-navicon"></i>
916
- <i class="fa fa-newspaper-o"></i>
917
- <i class="fa fa-paint-brush"></i>
918
- <i class="fa fa-paper-plane"></i>
919
- <i class="fa fa-paper-plane-o"></i>
920
- <i class="fa fa-paw"></i>
921
- <i class="fa fa-pencil"></i>
922
- <i class="fa fa-pencil-square"></i>
923
- <i class="fa fa-pencil-square-o"></i>
924
- <i class="fa fa-phone"></i>
925
- <i class="fa fa-phone-square"></i>
926
- <i class="fa fa-photo"></i>
927
- <i class="fa fa-picture-o"></i>
928
- <i class="fa fa-pie-chart"></i>
929
- <i class="fa fa-plane"></i>
930
- <i class="fa fa-plug"></i>
931
- <i class="fa fa-plus"></i>
932
- <i class="fa fa-plus-circle"></i>
933
- <i class="fa fa-plus-square"></i>
934
- <i class="fa fa-plus-square-o"></i>
935
- <i class="fa fa-power-off"></i>
936
- <i class="fa fa-print"></i>
937
- <i class="fa fa-puzzle-piece"></i>
938
- <i class="fa fa-qrcode"></i>
939
- <i class="fa fa-question"></i>
940
- <i class="fa fa-question-circle"></i>
941
- <i class="fa fa-quote-left"></i>
942
- <i class="fa fa-quote-right"></i>
943
- <i class="fa fa-random"></i>
944
- <i class="fa fa-recycle"></i>
945
- <i class="fa fa-refresh"></i>
946
- <i class="fa fa-remove"></i>
947
- <i class="fa fa-reorder"></i>
948
- <i class="fa fa-reply"></i>
949
- <i class="fa fa-reply-all"></i>
950
- <i class="fa fa-retweet"></i>
951
- <i class="fa fa-road"></i>
952
- <i class="fa fa-rocket"></i>
953
- <i class="fa fa-rss"></i>
954
- <i class="fa fa-rss-square"></i>
955
- <i class="fa fa-search"></i>
956
- <i class="fa fa-search-minus"></i>
957
- <i class="fa fa-search-plus"></i>
958
- <i class="fa fa-send"></i>
959
- <i class="fa fa-send-o"></i>
960
- <i class="fa fa-server"></i>
961
- <i class="fa fa-share"></i>
962
- <i class="fa fa-share-alt"></i>
963
- <i class="fa fa-share-alt-square"></i>
964
- <i class="fa fa-share-square"></i>
965
- <i class="fa fa-share-square-o"></i>
966
- <i class="fa fa-shield"></i>
967
- <i class="fa fa-ship"></i>
968
- <i class="fa fa-shopping-cart"></i>
969
- <i class="fa fa-sign-in"></i>
970
- <i class="fa fa-sign-out"></i>
971
- <i class="fa fa-signal"></i>
972
- <i class="fa fa-sitemap"></i>
973
- <i class="fa fa-sliders"></i>
974
- <i class="fa fa-smile-o"></i>
975
- <i class="fa fa-soccer-ball-o"></i>
976
- <i class="fa fa-sort"></i>
977
- <i class="fa fa-sort-alpha-asc"></i>
978
- <i class="fa fa-sort-alpha-desc"></i>
979
- <i class="fa fa-sort-amount-asc"></i>
980
- <i class="fa fa-sort-amount-desc"></i>
981
- <i class="fa fa-sort-asc"></i>
982
- <i class="fa fa-sort-desc"></i>
983
- <i class="fa fa-sort-down"></i>
984
- <i class="fa fa-sort-numeric-asc"></i>
985
- <i class="fa fa-sort-numeric-desc"></i>
986
- <i class="fa fa-sort-up"></i>
987
- <i class="fa fa-space-shuttle"></i>
988
- <i class="fa fa-spinner"></i>
989
- <i class="fa fa-spoon"></i>
990
- <i class="fa fa-square"></i>
991
- <i class="fa fa-square-o"></i>
992
- <i class="fa fa-star"></i>
993
- <i class="fa fa-star-half"></i>
994
- <i class="fa fa-star-half-empty"></i>
995
- <i class="fa fa-star-half-full"></i>
996
- <i class="fa fa-star-half-o"></i>
997
- <i class="fa fa-star-o"></i>
998
- <i class="fa fa-street-view"></i>
999
- <i class="fa fa-suitcase"></i>
1000
- <i class="fa fa-sun-o"></i>
1001
- <i class="fa fa-support"></i>
1002
- <i class="fa fa-tablet"></i>
1003
- <i class="fa fa-tachometer"></i>
1004
- <i class="fa fa-tag"></i>
1005
- <i class="fa fa-tags"></i>
1006
- <i class="fa fa-tasks"></i>
1007
- <i class="fa fa-taxi"></i>
1008
- <i class="fa fa-terminal"></i>
1009
- <i class="fa fa-thumb-tack"></i>
1010
- <i class="fa fa-thumbs-down"></i>
1011
- <i class="fa fa-thumbs-o-down"></i>
1012
- <i class="fa fa-thumbs-o-up"></i>
1013
- <i class="fa fa-thumbs-up"></i>
1014
- <i class="fa fa-ticket"></i>
1015
- <i class="fa fa-times"></i>
1016
- <i class="fa fa-times-circle"></i>
1017
- <i class="fa fa-times-circle-o"></i>
1018
- <i class="fa fa-tint"></i>
1019
- <i class="fa fa-toggle-down"></i>
1020
- <i class="fa fa-toggle-left"></i>
1021
- <i class="fa fa-toggle-off"></i>
1022
- <i class="fa fa-toggle-on"></i>
1023
- <i class="fa fa-toggle-right"></i>
1024
- <i class="fa fa-toggle-up"></i>
1025
- <i class="fa fa-trash"></i>
1026
- <i class="fa fa-trash-o"></i>
1027
- <i class="fa fa-tree"></i>
1028
- <i class="fa fa-trophy"></i>
1029
- <i class="fa fa-truck"></i>
1030
- <i class="fa fa-tty"></i>
1031
- <i class="fa fa-umbrella"></i>
1032
- <i class="fa fa-university"></i>
1033
- <i class="fa fa-unlock"></i>
1034
- <i class="fa fa-unlock-alt"></i>
1035
- <i class="fa fa-unsorted"></i>
1036
- <i class="fa fa-upload"></i>
1037
- <i class="fa fa-user"></i>
1038
- <i class="fa fa-user-plus"></i>
1039
- <i class="fa fa-user-secret"></i>
1040
- <i class="fa fa-user-times"></i>
1041
- <i class="fa fa-users"></i>
1042
- <i class="fa fa-video-camera"></i>
1043
- <i class="fa fa-volume-down"></i>
1044
- <i class="fa fa-volume-off"></i>
1045
- <i class="fa fa-volume-up"></i>
1046
- <i class="fa fa-warning"></i>
1047
- <i class="fa fa-wheelchair"></i>
1048
- <i class="fa fa-wifi"></i>
1049
- <i class="fa fa-wrench"></i>
1050
- <i class="fa fa-ambulance"></i>
1051
- <i class="fa fa-automobile"></i>
1052
- <i class="fa fa-bicycle"></i>
1053
- <i class="fa fa-bus"></i>
1054
- <i class="fa fa-cab"></i>
1055
- <i class="fa fa-car"></i>
1056
- <i class="fa fa-fighter-jet"></i>
1057
- <i class="fa fa-motorcycle"></i>
1058
- <i class="fa fa-plane"></i>
1059
- <i class="fa fa-rocket"></i>
1060
- <i class="fa fa-ship"></i>
1061
- <i class="fa fa-space-shuttle"></i>
1062
- <i class="fa fa-subway"></i>
1063
- <i class="fa fa-taxi"></i>
1064
- <i class="fa fa-train"></i>
1065
- <i class="fa fa-truck"></i>
1066
- <i class="fa fa-wheelchair"></i>
1067
- <i class="fa fa-circle-thin"></i>
1068
- <i class="fa fa-genderless"></i>
1069
- <i class="fa fa-mars"></i>
1070
- <i class="fa fa-mars-double"></i>
1071
- <i class="fa fa-mars-stroke"></i>
1072
- <i class="fa fa-mars-stroke-h"></i>
1073
- <i class="fa fa-mars-stroke-v"></i>
1074
- <i class="fa fa-mercury"></i>
1075
- <i class="fa fa-neuter"></i>
1076
- <i class="fa fa-transgender"></i>
1077
- <i class="fa fa-transgender-alt"></i>
1078
- <i class="fa fa-venus"></i>
1079
- <i class="fa fa-venus-double"></i>
1080
- <i class="fa fa-venus-mars"></i>
1081
- <i class="fa fa-file"></i>
1082
- <i class="fa fa-file-archive-o"></i>
1083
- <i class="fa fa-file-audio-o"></i>
1084
- <i class="fa fa-file-code-o"></i>
1085
- <i class="fa fa-file-excel-o"></i>
1086
- <i class="fa fa-file-image-o"></i>
1087
- <i class="fa fa-file-movie-o"></i>
1088
- <i class="fa fa-file-o"></i>
1089
- <i class="fa fa-file-pdf-o"></i>
1090
- <i class="fa fa-file-photo-o"></i>
1091
- <i class="fa fa-file-picture-o"></i>
1092
- <i class="fa fa-file-powerpoint-o"></i>
1093
- <i class="fa fa-file-sound-o"></i>
1094
- <i class="fa fa-file-text"></i>
1095
- <i class="fa fa-file-text-o"></i>
1096
- <i class="fa fa-file-video-o"></i>
1097
- <i class="fa fa-file-word-o"></i>
1098
- <i class="fa fa-file-zip-o"></i>
1099
- <i class="fa fa-info-circle fa-lg fa-li"></i>
1100
- <i class="fa fa-circle-o-notch"></i>
1101
- <i class="fa fa-cog"></i>
1102
- <i class="fa fa-gear"></i>
1103
- <i class="fa fa-refresh"></i>
1104
- <i class="fa fa-spinner"></i>
1105
- <i class="fa fa-check-square"></i>
1106
- <i class="fa fa-check-square-o"></i>
1107
- <i class="fa fa-circle"></i>
1108
- <i class="fa fa-circle-o"></i>
1109
- <i class="fa fa-dot-circle-o"></i>
1110
- <i class="fa fa-minus-square"></i>
1111
- <i class="fa fa-minus-square-o"></i>
1112
- <i class="fa fa-plus-square"></i>
1113
- <i class="fa fa-plus-square-o"></i>
1114
- <i class="fa fa-square"></i>
1115
- <i class="fa fa-square-o"></i>
1116
- <i class="fa fa-cc-amex"></i>
1117
- <i class="fa fa-cc-discover"></i>
1118
- <i class="fa fa-cc-mastercard"></i>
1119
- <i class="fa fa-cc-paypal"></i>
1120
- <i class="fa fa-cc-stripe"></i>
1121
- <i class="fa fa-cc-visa"></i>
1122
- <i class="fa fa-credit-card"></i>
1123
- <i class="fa fa-google-wallet"></i>
1124
- <i class="fa fa-paypal"></i>
1125
- <i class="fa fa-area-chart"></i>
1126
- <i class="fa fa-bar-chart"></i>
1127
- <i class="fa fa-bar-chart-o"></i>
1128
- <i class="fa fa-line-chart"></i>
1129
- <i class="fa fa-pie-chart"></i>
1130
- <i class="fa fa-bitcoin"></i>
1131
- <i class="fa fa-btc"></i>
1132
- <i class="fa fa-cny"></i>
1133
- <i class="fa fa-dollar"></i>
1134
- <i class="fa fa-eur"></i>
1135
- <i class="fa fa-euro"></i>
1136
- <i class="fa fa-gbp"></i>
1137
- <i class="fa fa-ils"></i>
1138
- <i class="fa fa-inr"></i>
1139
- <i class="fa fa-jpy"></i>
1140
- <i class="fa fa-krw"></i>
1141
- <i class="fa fa-money"></i>
1142
- <i class="fa fa-rmb"></i>
1143
- <i class="fa fa-rouble"></i>
1144
- <i class="fa fa-rub"></i>
1145
- <i class="fa fa-ruble"></i>
1146
- <i class="fa fa-rupee"></i>
1147
- <i class="fa fa-shekel"></i>
1148
- <i class="fa fa-sheqel"></i>
1149
- <i class="fa fa-try"></i>
1150
- <i class="fa fa-turkish-lira"></i>
1151
- <i class="fa fa-usd"></i>
1152
- <i class="fa fa-won"></i>
1153
- <i class="fa fa-yen"></i>
1154
- <i class="fa fa-align-center"></i>
1155
- <i class="fa fa-align-justify"></i>
1156
- <i class="fa fa-align-left"></i>
1157
- <i class="fa fa-align-right"></i>
1158
- <i class="fa fa-bold"></i>
1159
- <i class="fa fa-chain"></i>
1160
- <i class="fa fa-chain-broken"></i>
1161
- <i class="fa fa-clipboard"></i>
1162
- <i class="fa fa-columns"></i>
1163
- <i class="fa fa-copy"></i>
1164
- <i class="fa fa-cut"></i>
1165
- <i class="fa fa-dedent"></i>
1166
- <i class="fa fa-eraser"></i>
1167
- <i class="fa fa-file"></i>
1168
- <i class="fa fa-file-o"></i>
1169
- <i class="fa fa-file-text"></i>
1170
- <i class="fa fa-file-text-o"></i>
1171
- <i class="fa fa-files-o"></i>
1172
- <i class="fa fa-floppy-o"></i>
1173
- <i class="fa fa-font"></i>
1174
- <i class="fa fa-header"></i>
1175
- <i class="fa fa-indent"></i>
1176
- <i class="fa fa-italic"></i>
1177
- <i class="fa fa-link"></i>
1178
- <i class="fa fa-list"></i>
1179
- <i class="fa fa-list-alt"></i>
1180
- <i class="fa fa-list-ol"></i>
1181
- <i class="fa fa-list-ul"></i>
1182
- <i class="fa fa-outdent"></i>
1183
- <i class="fa fa-paperclip"></i>
1184
- <i class="fa fa-paragraph"></i>
1185
- <i class="fa fa-paste"></i>
1186
- <i class="fa fa-repeat"></i>
1187
- <i class="fa fa-rotate-left"></i>
1188
- <i class="fa fa-rotate-right"></i>
1189
- <i class="fa fa-save"></i>
1190
- <i class="fa fa-scissors"></i>
1191
- <i class="fa fa-strikethrough"></i>
1192
- <i class="fa fa-subscript"></i>
1193
- <i class="fa fa-superscript"></i>
1194
- <i class="fa fa-table"></i>
1195
- <i class="fa fa-text-height"></i>
1196
- <i class="fa fa-text-width"></i>
1197
- <i class="fa fa-th"></i>
1198
- <i class="fa fa-th-large"></i>
1199
- <i class="fa fa-th-list"></i>
1200
- <i class="fa fa-underline"></i>
1201
- <i class="fa fa-undo"></i>
1202
- <i class="fa fa-unlink"></i>
1203
- <i class="fa fa-angle-double-down"></i>
1204
- <i class="fa fa-angle-double-left"></i>
1205
- <i class="fa fa-angle-double-right"></i>
1206
- <i class="fa fa-angle-double-up"></i>
1207
- <i class="fa fa-angle-down"></i>
1208
- <i class="fa fa-angle-left"></i>
1209
- <i class="fa fa-angle-right"></i>
1210
- <i class="fa fa-angle-up"></i>
1211
- <i class="fa fa-arrow-circle-down"></i>
1212
- <i class="fa fa-arrow-circle-left"></i>
1213
- <i class="fa fa-arrow-circle-o-down"></i>
1214
- <i class="fa fa-arrow-circle-o-left"></i>
1215
- <i class="fa fa-arrow-circle-o-right"></i>
1216
- <i class="fa fa-arrow-circle-o-up"></i>
1217
- <i class="fa fa-arrow-circle-right"></i>
1218
- <i class="fa fa-arrow-circle-up"></i>
1219
- <i class="fa fa-arrow-down"></i>
1220
- <i class="fa fa-arrow-left"></i>
1221
- <i class="fa fa-arrow-right"></i>
1222
- <i class="fa fa-arrow-up"></i>
1223
- <i class="fa fa-arrows"></i>
1224
- <i class="fa fa-arrows-alt"></i>
1225
- <i class="fa fa-arrows-h"></i>
1226
- <i class="fa fa-arrows-v"></i>
1227
- <i class="fa fa-caret-down"></i>
1228
- <i class="fa fa-caret-left"></i>
1229
- <i class="fa fa-caret-right"></i>
1230
- <i class="fa fa-caret-square-o-down"></i>
1231
- <i class="fa fa-caret-square-o-left"></i>
1232
- <i class="fa fa-caret-square-o-right"></i>
1233
- <i class="fa fa-caret-square-o-up"></i>
1234
- <i class="fa fa-caret-up"></i>
1235
- <i class="fa fa-chevron-circle-down"></i>
1236
- <i class="fa fa-chevron-circle-left"></i>
1237
- <i class="fa fa-chevron-circle-right"></i>
1238
- <i class="fa fa-chevron-circle-up"></i>
1239
- <i class="fa fa-chevron-down"></i>
1240
- <i class="fa fa-chevron-left"></i>
1241
- <i class="fa fa-chevron-right"></i>
1242
- <i class="fa fa-chevron-up"></i>
1243
- <i class="fa fa-hand-o-down"></i>
1244
- <i class="fa fa-hand-o-left"></i>
1245
- <i class="fa fa-hand-o-right"></i>
1246
- <i class="fa fa-hand-o-up"></i>
1247
- <i class="fa fa-long-arrow-down"></i>
1248
- <i class="fa fa-long-arrow-left"></i>
1249
- <i class="fa fa-long-arrow-right"></i>
1250
- <i class="fa fa-long-arrow-up"></i>
1251
- <i class="fa fa-toggle-down"></i>
1252
- <i class="fa fa-toggle-left"></i>
1253
- <i class="fa fa-toggle-right"></i>
1254
- <i class="fa fa-toggle-up"></i>
1255
- <i class="fa fa-arrows-alt"></i>
1256
- <i class="fa fa-backward"></i>
1257
- <i class="fa fa-compress"></i>
1258
- <i class="fa fa-eject"></i>
1259
- <i class="fa fa-expand"></i>
1260
- <i class="fa fa-fast-backward"></i>
1261
- <i class="fa fa-fast-forward"></i>
1262
- <i class="fa fa-forward"></i>
1263
- <i class="fa fa-pause"></i>
1264
- <i class="fa fa-play"></i>
1265
- <i class="fa fa-play-circle"></i>
1266
- <i class="fa fa-play-circle-o"></i>
1267
- <i class="fa fa-step-backward"></i>
1268
- <i class="fa fa-step-forward"></i>
1269
- <i class="fa fa-stop"></i>
1270
- <i class="fa fa-youtube-play"></i>
1271
- <i class="fa fa-warning"></i>
1272
- <i class="fa fa-adn"></i>
1273
- <i class="fa fa-android"></i>
1274
- <i class="fa fa-angellist"></i>
1275
- <i class="fa fa-apple"></i>
1276
- <i class="fa fa-behance"></i>
1277
- <i class="fa fa-behance-square"></i>
1278
- <i class="fa fa-bitbucket"></i>
1279
- <i class="fa fa-bitbucket-square"></i>
1280
- <i class="fa fa-bitcoin"></i>
1281
- <i class="fa fa-btc"></i>
1282
- <i class="fa fa-buysellads"></i>
1283
- <i class="fa fa-cc-amex"></i>
1284
- <i class="fa fa-cc-discover"></i>
1285
- <i class="fa fa-cc-mastercard"></i>
1286
- <i class="fa fa-cc-paypal"></i>
1287
- <i class="fa fa-cc-stripe"></i>
1288
- <i class="fa fa-cc-visa"></i>
1289
- <i class="fa fa-codepen"></i>
1290
- <i class="fa fa-connectdevelop"></i>
1291
- <i class="fa fa-css3"></i>
1292
- <i class="fa fa-dashcube"></i>
1293
- <i class="fa fa-delicious"></i>
1294
- <i class="fa fa-deviantart"></i>
1295
- <i class="fa fa-digg"></i>
1296
- <i class="fa fa-dribbble"></i>
1297
- <i class="fa fa-dropbox"></i>
1298
- <i class="fa fa-drupal"></i>
1299
- <i class="fa fa-empire"></i>
1300
- <i class="fa fa-facebook"></i>
1301
- <i class="fa fa-facebook-f"></i>
1302
- <i class="fa fa-facebook-official"></i>
1303
- <i class="fa fa-facebook-square"></i>
1304
- <i class="fa fa-flickr"></i>
1305
- <i class="fa fa-forumbee"></i>
1306
- <i class="fa fa-foursquare"></i>
1307
- <i class="fa fa-ge"></i>
1308
- <i class="fa fa-git"></i>
1309
- <i class="fa fa-git-square"></i>
1310
- <i class="fa fa-github"></i>
1311
- <i class="fa fa-github-alt"></i>
1312
- <i class="fa fa-github-square"></i>
1313
- <i class="fa fa-gittip"></i>
1314
- <i class="fa fa-google"></i>
1315
- <i class="fa fa-google-plus"></i>
1316
- <i class="fa fa-google-plus-square"></i>
1317
- <i class="fa fa-google-wallet"></i>
1318
- <i class="fa fa-gratipay"></i>
1319
- <i class="fa fa-hacker-news"></i>
1320
- <i class="fa fa-html5"></i>
1321
- <i class="fa fa-instagram"></i>
1322
- <i class="fa fa-ioxhost"></i>
1323
- <i class="fa fa-joomla"></i>
1324
- <i class="fa fa-jsfiddle"></i>
1325
- <i class="fa fa-lastfm"></i>
1326
- <i class="fa fa-lastfm-square"></i>
1327
- <i class="fa fa-leanpub"></i>
1328
- <i class="fa fa-linkedin"></i>
1329
- <i class="fa fa-linkedin-square"></i>
1330
- <i class="fa fa-linux"></i>
1331
- <i class="fa fa-maxcdn"></i>
1332
- <i class="fa fa-meanpath"></i>
1333
- <i class="fa fa-medium"></i>
1334
- <i class="fa fa-openid"></i>
1335
- <i class="fa fa-pagelines"></i>
1336
- <i class="fa fa-paypal"></i>
1337
- <i class="fa fa-pied-piper"></i>
1338
- <i class="fa fa-pied-piper-alt"></i>
1339
- <i class="fa fa-pinterest"></i>
1340
- <i class="fa fa-pinterest-p"></i>
1341
- <i class="fa fa-pinterest-square"></i>
1342
- <i class="fa fa-qq"></i>
1343
- <i class="fa fa-ra"></i>
1344
- <i class="fa fa-rebel"></i>
1345
- <i class="fa fa-reddit"></i>
1346
- <i class="fa fa-reddit-square"></i>
1347
- <i class="fa fa-renren"></i>
1348
- <i class="fa fa-sellsy"></i>
1349
- <i class="fa fa-share-alt"></i>
1350
- <i class="fa fa-share-alt-square"></i>
1351
- <i class="fa fa-shirtsinbulk"></i>
1352
- <i class="fa fa-simplybuilt"></i>
1353
- <i class="fa fa-skyatlas"></i>
1354
- <i class="fa fa-skype"></i>
1355
- <i class="fa fa-slack"></i>
1356
- <i class="fa fa-slideshare"></i>
1357
- <i class="fa fa-soundcloud"></i>
1358
- <i class="fa fa-spotify"></i>
1359
- <i class="fa fa-stack-exchange"></i>
1360
- <i class="fa fa-stack-overflow"></i>
1361
- <i class="fa fa-steam"></i>
1362
- <i class="fa fa-steam-square"></i>
1363
- <i class="fa fa-stumbleupon"></i>
1364
- <i class="fa fa-stumbleupon-circle"></i>
1365
- <i class="fa fa-tencent-weibo"></i>
1366
- <i class="fa fa-trello"></i>
1367
- <i class="fa fa-tumblr"></i>
1368
- <i class="fa fa-tumblr-square"></i>
1369
- <i class="fa fa-twitch"></i>
1370
- <i class="fa fa-twitter"></i>
1371
- <i class="fa fa-twitter-square"></i>
1372
- <i class="fa fa-viacoin"></i>
1373
- <i class="fa fa-vimeo-square"></i>
1374
- <i class="fa fa-vine"></i>
1375
- <i class="fa fa-vk"></i>
1376
- <i class="fa fa-wechat"></i>
1377
- <i class="fa fa-weibo"></i>
1378
- <i class="fa fa-weixin"></i>
1379
- <i class="fa fa-whatsapp"></i>
1380
- <i class="fa fa-windows"></i>
1381
- <i class="fa fa-wordpress"></i>
1382
- <i class="fa fa-xing"></i>
1383
- <i class="fa fa-xing-square"></i>
1384
- <i class="fa fa-yahoo"></i>
1385
- <i class="fa fa-yelp"></i>
1386
- <i class="fa fa-youtube"></i>
1387
- <i class="fa fa-youtube-play"></i>
1388
- <i class="fa fa-youtube-square"></i>
1389
- <i class="fa fa-ambulance"></i>
1390
- <i class="fa fa-h-square"></i>
1391
- <i class="fa fa-heart"></i>
1392
- <i class="fa fa-heart-o"></i>
1393
- <i class="fa fa-heartbeat"></i>
1394
- <i class="fa fa-hospital-o"></i>
1395
- <i class="fa fa-medkit"></i>
1396
- <i class="fa fa-plus-square"></i>
1397
- <i class="fa fa-stethoscope"></i>
1398
- <i class="fa fa-user-md"></i>
1399
- <i class="fa fa-wheelchair"></i>
1400
-
1401
-
1402
- </div>
1403
- </div>
1404
- <div class="tnpc-edit-box-buttons">
1405
- <div class="tnpc-edit-box-buttons-cancel" style="margin-left:0px;"><?php _e("Cancel", "newsletter") ?></div>
1406
- </div>
1407
- </div>
1408
- </div>
1409
-
1410
  <div class="tnpc-edit" id="tnpc-edit-block">
1411
  <div class="tnpc-edit-box">
1412
  <div class="tnpc-edit-box-title"><?php _e("Edit Block", "newsletter") ?></div>
@@ -1435,6 +193,13 @@ if (!defined('ABSPATH')) exit;
1435
  </optgroup>
1436
  </select>
1437
  </div>
 
 
 
 
 
 
 
1438
  </div>
1439
  <div class="tnpc-edit-box-buttons">
1440
  <div class="tnpc-edit-box-buttons-save"><?php _e("Save", "newsletter") ?></div>
@@ -1493,8 +258,7 @@ if (!defined('ABSPATH')) exit;
1493
 
1494
  <div class="tnpc-edit" id="tnpc-block-options">
1495
  <div class="tnpc-edit-box">
1496
- <form id="tnpc-block-options-form" onsubmit="return false;">
1497
- </form>
1498
  <div class="tnpc-edit-box-buttons">
1499
  <div class="tnpc-edit-box-buttons-save"><?php _e("Save", "newsletter") ?></div>
1500
  <div class="tnpc-edit-box-buttons-cancel"><?php _e("Cancel", "newsletter") ?></div>
103
  <div class="tnpc-edit-box-content-text"><?php _e("Text Color", "newsletter") ?></div>
104
  <div class="tnpc-edit-box-content-field"><input type="text" class="tnpc-edit-box-content-field-input color"/></div>
105
 
106
+ <div class="tnpc-edit-box-content-text"><?php _e("Font family", "newsletter") ?></div>
107
+ <div class="tnpc-edit-box-content-field">
108
+ <select id="tnpc-edit-title-font-family">
109
+ <optgroup label="Sans Serif Web Safe Fonts">
110
+ <option value="Arial">Arial</option>
111
+ <option value="Arial Black">Arial Black</option>
112
+ <option value="Tahoma">Tahoma</option>
113
+ <option value="Trebuchet MS">Trebuchet MS</option>
114
+ <option value="Verdana">Verdana</option>
115
+ </optgroup>
116
+ <optgroup label="Serif Web Safe Fonts">
117
+ <option value="Georgia">Georgia</option>
118
+ <option value="Times">Times</option>
119
+ <option value="Times New Roman">Times New Roman</option>
120
+ </optgroup>
121
+ <optgroup label="Monospace Fonts">
122
+ <option value="Courier">Courier</option>
123
+ <option value="Courier New">Courier New</option>
124
+ </optgroup>
125
+ </select>
126
+ </div>
127
+
128
  <div class="tnpc-edit-box-content-text"><?php _e("Font size", "newsletter") ?></div>
129
  <div class="tnpc-edit-box-content-field">
130
  <select id="tnpc-edit-title-font-size">
137
  <select id="tnpc-edit-title-text-align">
138
  <option value="center">Center</option>
139
  <option value="left">Left</option>
140
+ <option value="right">Right</option>
141
  </select>
142
  </div>
143
  </div>
164
  </div>
165
  </div>
166
 
167
+ <!-- On eline text block, like headings -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  <div class="tnpc-edit" id="tnpc-edit-block">
169
  <div class="tnpc-edit-box">
170
  <div class="tnpc-edit-box-title"><?php _e("Edit Block", "newsletter") ?></div>
193
  </optgroup>
194
  </select>
195
  </div>
196
+ <div class="tnpc-edit-box-content-field">
197
+ <select class="tnpc-edit-box-content-field-input font-size">
198
+ <?php for ($i=9; $i<51; $i++) { ?>
199
+ <option value="<?php echo $i?>"><?php echo $i?></option>
200
+ <?php } ?>
201
+ </select>
202
+ </div>
203
  </div>
204
  <div class="tnpc-edit-box-buttons">
205
  <div class="tnpc-edit-box-buttons-save"><?php _e("Save", "newsletter") ?></div>
258
 
259
  <div class="tnpc-edit" id="tnpc-block-options">
260
  <div class="tnpc-edit-box">
261
+ <form id="tnpc-block-options-form" onsubmit="return false;"></form>
 
262
  <div class="tnpc-edit-box-buttons">
263
  <div class="tnpc-edit-box-buttons-save"><?php _e("Save", "newsletter") ?></div>
264
  <div class="tnpc-edit-box-buttons-cancel"><?php _e("Cancel", "newsletter") ?></div>
emails/tnp-composer/index.php CHANGED
@@ -1,31 +1,15 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
-
5
- /* READ THE BLOCKS */
6
- $blocks_dir = NEWSLETTER_DIR . '/emails/tnp-composer/blocks/';
7
- $files = glob($blocks_dir . '*.block.php');
8
- foreach ($files as $file) {
9
- $path_parts = pathinfo($file);
10
- $filename = $path_parts['filename'];
11
- $section = substr($filename, 0, strpos($filename, '-'));
12
- $index = substr($filename, strpos($filename, '-') + 1, 2);
13
- $blocks[$section][$index]['name'] = substr($filename, strrpos($filename, '-') + 1);
14
- $blocks[$section][$index]['filename'] = $filename;
15
- }
16
-
17
- $dirs = apply_filters('newsletter_blocks_dir', array());
18
-
19
- foreach ($dirs as $dir) {
20
- $dir = str_replace('\\', '/', $dir);
21
 
22
- $list = NewsletterEmails::instance()->scan_blocks_dir($dir);
23
 
24
- foreach ($list as $key => $data) {
25
- $blocks[$data['section']][$key]['name'] = $data['name'];
26
- $blocks[$data['section']][$key]['filename'] = $key;
27
- $blocks[$data['section']][$key]['icon'] = $data['icon'];
28
- }
 
 
29
  }
30
 
31
  // order the sections
@@ -36,13 +20,10 @@ $block_options = get_option('newsletter_main');
36
  ?>
37
  <style>
38
  .placeholder {
39
- border: 1px dotted #bbb!important;
40
- border-style: dotted!important;
41
- border-color: #bbb!important;
42
- border-width: 1px!important;
43
- background-color: #fff!important;
44
  height: 50px;
45
- margin: 15px 0;
46
  width: 100%;
47
  box-sizing: border-box!important;
48
  }
@@ -51,32 +32,24 @@ $block_options = get_option('newsletter_main');
51
  }
52
  </style>
53
 
54
- <div id="newsletter-preloaded-export" style="display: none;"></div>
55
-
56
  <div id="newsletter-builder">
57
 
58
- <div id="newsletter-builder-sidebar">
59
 
60
  <?php foreach ($blocks as $k => $section) { ?>
61
- <div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
62
- <h4><span><?php echo ucfirst($k) ?></span></h4>
63
- <?php foreach ($section AS $key => $block) { ?>
64
- <div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $k . '-' . $key ?>" data-file="<?php echo $block['filename'] ?>">
65
- <?php if (isset($block['icon'])) { ?>
66
- <img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
67
- <?php } else if (file_exists(NEWSLETTER_DIR . '/emails/tnp-composer/blocks/' . $block['filename'] . '.png')) { ?>
68
- <img src="<?php echo plugins_url('newsletter'); ?>/emails/tnp-composer/blocks/<?php echo $block['filename'] ?>.png" title="Drag&Drop">
69
- <?php } else { ?>
70
- <img src="http://placehold.it/200x100?text=<?php echo $block['name'] ?>" title="Drag&Drop">
71
- <?php } ?>
72
  </div>
73
- <?php } ?>
74
- </div>
75
  <?php } ?>
76
 
77
  </div>
78
 
79
- <div id="newsletter-builder-area">
80
 
81
  <div id="newsletter-builder-area-center-frame-content">
82
 
@@ -84,29 +57,39 @@ $block_options = get_option('newsletter_main');
84
  if (isset($email)) {
85
  echo NewsletterModule::extract_body($body);
86
  } else {
87
- include $blocks_dir . 'header-01-header.block.php';
88
- include $blocks_dir . 'content-01-hero.block.php';
89
- include $blocks_dir . 'footer-01-footer.block.php';
90
- include $blocks_dir . 'footer-02-canspam.block.php';
 
91
  }
92
  ?>
93
 
94
  </div>
95
  </div>
96
 
97
- <div id="newsletter-mobile-preview-area">
98
  <iframe id="tnp-mobile-preview"></iframe>
99
  </div>
100
 
 
101
  </div>
102
 
103
- <div id="tnp-body">
104
- <?php include NEWSLETTER_DIR . '/emails/tnp-composer/edit.php'; ?>
 
 
 
 
 
 
105
  </div>
106
 
 
 
107
  <script type="text/javascript">
108
  TNP_PLUGIN_URL = "<?php echo NEWSLETTER_URL ?>";
109
- TNP_HOME_URL = "<?php echo home_url('/', is_ssl()?'https':'http') ?>";
110
  </script>
111
  <script type="text/javascript" src="<?php echo plugins_url('newsletter'); ?>/emails/tnp-composer/_scripts/newsletter-builder.js?ver=<?php echo time() ?>"></script>
112
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.3/tinymce.min.js"></script>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ $list = NewsletterEmails::instance()->get_blocks();
5
 
6
+ $blocks = array();
7
+ foreach ($list as $key => $data) {
8
+ if (!isset($blocks[$data['section']]))
9
+ $blocks[$data['section']] = array();
10
+ $blocks[$data['section']][$key]['name'] = $data['name'];
11
+ $blocks[$data['section']][$key]['filename'] = $key;
12
+ $blocks[$data['section']][$key]['icon'] = $data['icon'];
13
  }
14
 
15
  // order the sections
20
  ?>
21
  <style>
22
  .placeholder {
23
+ border: 3px dashed #ddd!important;
24
+ background-color: #eee!important;
 
 
 
25
  height: 50px;
26
+ margin: 0;
27
  width: 100%;
28
  box-sizing: border-box!important;
29
  }
32
  }
33
  </style>
34
 
 
 
35
  <div id="newsletter-builder">
36
 
37
+ <div id="newsletter-builder-sidebar" class="tnp-builder-column">
38
 
39
  <?php foreach ($blocks as $k => $section) { ?>
40
+ <div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
41
+ <h4><span><?php echo ucfirst($k) ?></span></h4>
42
+ <?php foreach ($section AS $key => $block) { ?>
43
+ <div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $key ?>" data-name="<?php echo esc_attr($block['name']) ?>">
44
+ <img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
45
+ </div>
46
+ <?php } ?>
 
 
 
 
47
  </div>
 
 
48
  <?php } ?>
49
 
50
  </div>
51
 
52
+ <div id="newsletter-builder-area" class="tnp-builder-column">
53
 
54
  <div id="newsletter-builder-area-center-frame-content">
55
 
57
  if (isset($email)) {
58
  echo NewsletterModule::extract_body($body);
59
  } else {
60
+ include __DIR__ . '/blocks/header-01-header.block.php';
61
+ include __DIR__ . '/blocks/content-05-image.block.php';
62
+ include __DIR__ . '/blocks/content-01-hero.block.php';
63
+ include __DIR__ . '/blocks/footer-01-footer.block.php';
64
+ include __DIR__ . '/blocks/footer-02-canspam.block.php';
65
  }
66
  ?>
67
 
68
  </div>
69
  </div>
70
 
71
+ <div id="newsletter-mobile-preview-area" class="tnp-builder-column">
72
  <iframe id="tnp-mobile-preview"></iframe>
73
  </div>
74
 
75
+ <div style="clear: both"></div>
76
  </div>
77
 
78
+
79
+ <div style="display: none">
80
+ <div id="newsletter-preloaded-export"></div>
81
+ <div id="draggable-helper" style="width: 500px; border: 3px dashed #ddd; opacity: .7; background-color: #fff; text-align: center; text-transform: uppercase; font-size: 14px; color: #aaa; padding: 20px;"></div>
82
+ </div>
83
+
84
+ <div id="tnp-body" style="margin: 0; padding: 0; overflow: hidden; border: 0;">
85
+ <?php include NEWSLETTER_DIR . '/emails/tnp-composer/edit.php'; ?>
86
  </div>
87
 
88
+
89
+
90
  <script type="text/javascript">
91
  TNP_PLUGIN_URL = "<?php echo NEWSLETTER_URL ?>";
92
+ TNP_HOME_URL = "<?php echo home_url('/', is_ssl() ? 'https' : 'http') ?>";
93
  </script>
94
  <script type="text/javascript" src="<?php echo plugins_url('newsletter'); ?>/emails/tnp-composer/_scripts/newsletter-builder.js?ver=<?php echo time() ?>"></script>
95
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.3/tinymce.min.js"></script>
header-extension.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /*
3
- * Header file for the extensions administrative panels.
4
- *
5
- * - no top noticies
6
- * - no donation link
7
- */
8
-
9
- if (!defined('ABSPATH')) exit;
10
-
11
- ?>
12
- <?php if (NEWSLETTER_HEADER) { ?>
13
- <div id="newsletter-header-ext">
14
- <div style="text-align: center; margin-top: 5px;">
15
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-documentation" target="_blank"><img style="vertical-align: bottom" src="<?php echo plugins_url('newsletter'); ?>/images/header/documentation.png"> Documentation</a>
16
- <a href="https://www.thenewsletterplugin.com/forums" target="_blank"><img style="vertical-align: bottom" src="<?php echo plugins_url('newsletter'); ?>/images/header/forum.png"> Forum</a>
17
- <a href="https://www.facebook.com/thenewsletterplugin
18
- " target="_blank"><img style="vertical-align: bottom" src="<?php echo plugins_url('newsletter'); ?>/images/header/facebook.png"> Facebook</a>
19
-
20
- <!--<a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-collaboration" target="_blank">Collaboration</a>-->
21
- </div>
22
-
23
- <div style="text-align: center; margin-top: 5px;">
24
- <form style="margin: 0;" action="https://www.thenewsletterplugin.com/wp-content/plugins/newsletter/do/subscribe.php" method="post" target="_blank">
25
- My Newsletter<!-- to thenewsletterplugin.com--> <input type="email" name="ne" required placeholder="Your email" style="padding: 2px">
26
- <input type="submit" value="Go" style="padding: 2px">
27
- </form>
28
- </div>
29
- </div>
30
- <?php } ?>
31
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/controls.php CHANGED
@@ -355,7 +355,7 @@ class NewsletterControls {
355
  echo '</div>';
356
  }
357
  if (!empty($this->warnings)) {
358
- foreach ($this->warnings as $warning) {
359
  echo '<div class="tnp-warning">';
360
  echo $warning;
361
  echo '</div>';
@@ -593,15 +593,22 @@ class NewsletterControls {
593
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
594
  }
595
 
596
- function select2($name, $options, $first = null, $multiple = false, $style = "width: 100%") {
597
 
598
- if ($multiple)
599
  $option_name = "options[" . esc_attr($name) . "][]";
600
- else $option_name = "options[" . esc_attr($name) . "]";
 
 
601
 
 
 
 
 
602
  $value = $this->get_value($name);
603
 
604
- echo '<select id="options-' . esc_attr($name) . '" name="' . $option_name . '" style="'. $style .'" ' . ($multiple ? 'multiple="multiple"' : '') . '>';
 
605
  if (!empty($first)) {
606
  echo '<option value="">' . esc_html($first) . '</option>';
607
  }
@@ -613,7 +620,7 @@ class NewsletterControls {
613
  echo '>' . esc_html($data) . '</option>';
614
  }
615
  echo '</select>';
616
- echo '<script>jQuery("#options-' . esc_attr($name) . '").select2();</script>';
617
  }
618
 
619
  function select_grouped($name, $groups) {
@@ -694,7 +701,7 @@ class NewsletterControls {
694
  function text_email($name, $size = 40) {
695
  $value = $this->get_value($name);
696
  echo '<input name="options[' . esc_attr($name) . ']" type="email" placeholder="';
697
- echo esc_attr(__('Valid email address', 'newsletter'));
698
  echo '" size="' . esc_attr($size) . '" value="';
699
  echo esc_attr($value);
700
  echo '">';
@@ -733,7 +740,7 @@ class NewsletterControls {
733
  echo '<button class="button-secondary" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'reset\';if (!confirm(\'';
734
  echo esc_attr(esc_js(__('Proceed?', 'newsletter')));
735
  echo '\')) return false;">';
736
- //echo '<i class="fa fa-times"></i> ';
737
  echo esc_html(__('Reset', 'newsletter'));
738
  echo '</button>';
739
  }
@@ -797,8 +804,12 @@ class NewsletterControls {
797
 
798
  function wp_editor($name, $settings = array()) {
799
  $value = $this->get_value($name);
800
- wp_editor($value, $name, array_merge(array('textarea_name' => 'options[' . esc_attr($name) . ']', 'wpautop' => false), $settings));
801
- echo '<p class="description">You can install <a href="https://wordpress.org/plugins/tinymce-advanced/" target="_blank">TinyMCE Advanced</a> for advanced editing features</p>';
 
 
 
 
802
  }
803
 
804
  function textarea($name, $width = '100%', $height = '50') {
@@ -840,7 +851,8 @@ class NewsletterControls {
840
  }
841
 
842
  $this->text($prefix . '_subject', 90, 'Subject');
843
-
 
844
  if ($editor == 'wordpress') {
845
  $this->wp_editor($prefix . '_message');
846
  } else if ($editor == 'textarea') {
@@ -856,7 +868,7 @@ class NewsletterControls {
856
  }
857
  echo '<input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="1"';
858
  if (!empty($this->data[$name])) {
859
- echo ' checked="checked"';
860
  }
861
  echo '>';
862
  if ($label != '') {
@@ -976,12 +988,6 @@ class NewsletterControls {
976
  $this->checkbox2($name . '_' . $i, esc_html($options_profile['list_' . $i]));
977
  echo '</div>';
978
  }
979
- echo '<div style="clear: both"></div>';
980
- echo '</div>';
981
- echo '<div class="hints">';
982
- echo 'User\'s preferences can be activated from the "Subscription Form" panel. They can be used to simulate lists or create private groups. The number is the "preference number". ';
983
- echo '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Read more about preferences</a>.';
984
- echo '</div>';
985
  }
986
 
987
  /**
@@ -1048,6 +1054,23 @@ class NewsletterControls {
1048
  $this->select($name, $lists);
1049
  echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fa fa-edit"></i></a>';
1050
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1051
 
1052
  function date($name) {
1053
  $this->hidden($name);
@@ -1254,13 +1277,6 @@ class NewsletterControls {
1254
  echo '</script>';
1255
  }
1256
 
1257
- /**
1258
- * @deprecated
1259
- */
1260
- function save_user($subscriber) {
1261
- return NewsletterUsers::instance()->save_user($user);
1262
- }
1263
-
1264
  /**
1265
  * @deprecated
1266
  */
@@ -1281,6 +1297,29 @@ class NewsletterControls {
1281
  }
1282
  echo '</select>&nbsp;px';
1283
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1284
 
1285
  function css_border($name) {
1286
  $value = $this->get_value($name . '_width');
@@ -1312,6 +1351,11 @@ class NewsletterControls {
1312
  echo '</select>&nbsp;px';
1313
  }
1314
 
 
 
 
 
 
1315
  function media($name) {
1316
  if (isset($this->data[$name])) {
1317
  $media_id = (int) $this->data[$name]['id'];
@@ -1348,6 +1392,15 @@ class NewsletterControls {
1348
  echo $output;
1349
  }
1350
 
 
 
 
 
 
 
 
 
 
1351
  static function print_date($time = null, $now = false, $left = false) {
1352
  if (is_null($time)) {
1353
  $time = time();
@@ -1368,8 +1421,50 @@ class NewsletterControls {
1368
  return $buffer;
1369
  }
1370
 
 
 
 
 
 
 
1371
  static function help($url, $label='') {
1372
- echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-question-circle"></i></a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1373
  }
1374
 
1375
  }
355
  echo '</div>';
356
  }
357
  if (!empty($this->warnings)) {
358
+ foreach ((array)$this->warnings as $warning) {
359
  echo '<div class="tnp-warning">';
360
  echo $warning;
361
  echo '</div>';
593
  echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
594
  }
595
 
596
+ function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder='') {
597
 
598
+ if ($multiple) {
599
  $option_name = "options[" . esc_attr($name) . "][]";
600
+ } else {
601
+ $option_name = "options[" . esc_attr($name) . "]";
602
+ }
603
 
604
+ if (is_null($style)) {
605
+ $style = 'width: 100%';
606
+ }
607
+
608
  $value = $this->get_value($name);
609
 
610
+ echo '<select id="options-', esc_attr($name), '" name="', $option_name, '" style="', $style, '"',
611
+ ($multiple ? ' multiple' : ''), ' placeholder="', esc_attr($placeholder), '">';
612
  if (!empty($first)) {
613
  echo '<option value="">' . esc_html($first) . '</option>';
614
  }
620
  echo '>' . esc_html($data) . '</option>';
621
  }
622
  echo '</select>';
623
+ echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
624
  }
625
 
626
  function select_grouped($name, $groups) {
701
  function text_email($name, $size = 40) {
702
  $value = $this->get_value($name);
703
  echo '<input name="options[' . esc_attr($name) . ']" type="email" placeholder="';
704
+ echo esc_attr__('Valid email address', 'newsletter');
705
  echo '" size="' . esc_attr($size) . '" value="';
706
  echo esc_attr($value);
707
  echo '">';
740
  echo '<button class="button-secondary" onclick="this.form.btn.value=\'' . esc_attr($data) . '\';this.form.act.value=\'reset\';if (!confirm(\'';
741
  echo esc_attr(esc_js(__('Proceed?', 'newsletter')));
742
  echo '\')) return false;">';
743
+ echo '<i class="fa fa-reply"></i> ';
744
  echo esc_html(__('Reset', 'newsletter'));
745
  echo '</button>';
746
  }
804
 
805
  function wp_editor($name, $settings = array()) {
806
  $value = $this->get_value($name);
807
+ wp_editor($value, $name, array_merge(array(
808
+ 'tinymce' => array('content_css' => plugins_url('newsletter') . '/css/wp-editor.css?ver=' . filemtime(NEWSLETTER_DIR . '/css/wp-editor.css')),
809
+ 'textarea_name' => 'options[' . esc_attr($name) . ']',
810
+ 'wpautop' => false
811
+ ), $settings));
812
+ //echo '<p class="description">You can install <a href="https://wordpress.org/plugins/tinymce-advanced/" target="_blank">TinyMCE Advanced</a> for advanced editing features</p>';
813
  }
814
 
815
  function textarea($name, $width = '100%', $height = '50') {
851
  }
852
 
853
  $this->text($prefix . '_subject', 90, 'Subject');
854
+ echo '<br><br>';
855
+
856
  if ($editor == 'wordpress') {
857
  $this->wp_editor($prefix . '_message');
858
  } else if ($editor == 'textarea') {
868
  }
869
  echo '<input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="1"';
870
  if (!empty($this->data[$name])) {
871
+ echo ' checked';
872
  }
873
  echo '>';
874
  if ($label != '') {
988
  $this->checkbox2($name . '_' . $i, esc_html($options_profile['list_' . $i]));
989
  echo '</div>';
990
  }
 
 
 
 
 
 
991
  }
992
 
993
  /**
1054
  $this->select($name, $lists);
1055
  echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fa fa-edit"></i></a>';
1056
  }
1057
+
1058
+ /**
1059
+ * Generates an associative array with the active lists to be used in a select.
1060
+ * @param string $empty_label
1061
+ * @return array
1062
+ */
1063
+ function get_list_options($empty_label = null) {
1064
+ $options_profile = get_option('newsletter_profile');
1065
+ $lists = array();
1066
+ if ($empty_label) {
1067
+ $lists[''] = $empty_label;
1068
+ }
1069
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1070
+ $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
1071
+ }
1072
+ return $lists;
1073
+ }
1074
 
1075
  function date($name) {
1076
  $this->hidden($name);
1277
  echo '</script>';
1278
  }
1279
 
 
 
 
 
 
 
 
1280
  /**
1281
  * @deprecated
1282
  */
1297
  }
1298
  echo '</select>&nbsp;px';
1299
  }
1300
+
1301
+ function css_font_family($name) {
1302
+ $value = $this->get_value($name);
1303
+
1304
+ $fonts = array('Helvetica, Arial, sans-serif', 'Arial Black, Gadget, sans-serif', 'Garamond, serif', 'Courier, monospace', 'Cominc Sans MS, cursive', 'Impact, Charcoal, sans-serif',
1305
+ 'Tahoma, Geneva, sans-serif', 'Times New Roman, Times, serif', 'Verdana, Geneva, sans-serif');
1306
+
1307
+ echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']">';
1308
+ foreach ($fonts as $font) {
1309
+ echo '<option value="', esc_attr($font), '"';
1310
+ if ($value == $font) {
1311
+ echo ' selected';
1312
+ }
1313
+ echo '>', esc_html($font), '</option>';
1314
+ }
1315
+ echo '</select>';
1316
+ }
1317
+
1318
+ function css_text_align($name) {
1319
+ $options = array('left'=>__('Left', 'newsletter'), 'right'=>__('Right', 'newsletter'),
1320
+ 'center'=>__('Center', 'newsletter'));
1321
+ $this->select($name, $options);
1322
+ }
1323
 
1324
  function css_border($name) {
1325
  $value = $this->get_value($name . '_width');
1351
  echo '</select>&nbsp;px';
1352
  }
1353
 
1354
+ /**
1355
+ * Media selector using the media library of WP. Produces a field which values is an array containing 'id' and 'url'.
1356
+ *
1357
+ * @param string $name
1358
+ */
1359
  function media($name) {
1360
  if (isset($this->data[$name])) {
1361
  $media_id = (int) $this->data[$name]['id'];
1392
  echo $output;
1393
  }
1394
 
1395
+ /**
1396
+ * Prints a formatted date using the formats and timezone of WP, including the current date and time and the
1397
+ * time left to the passed time.
1398
+ *
1399
+ * @param int $time
1400
+ * @param int $now
1401
+ * @param bool $left
1402
+ * @return string
1403
+ */
1404
  static function print_date($time = null, $now = false, $left = false) {
1405
  if (is_null($time)) {
1406
  $time = time();
1421
  return $buffer;
1422
  }
1423
 
1424
+ /**
1425
+ * Prints the help button near a form field. The label is used as icon title.
1426
+ *
1427
+ * @param string $url
1428
+ * @param string $label
1429
+ */
1430
  static function help($url, $label='') {
1431
+ echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-question-circle-o"></i></a>';
1432
+ }
1433
+
1434
+ static function idea($url, $label='') {
1435
+ echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fa fa-lightbulb-o"></i></a>';
1436
+ }
1437
+
1438
+ static function field_help($url, $text = '') {
1439
+ if (empty($text)) $text = __('Read more', 'newsletter');
1440
+ echo '<i class="fa fa-question-circle"></i>&nbsp;<a href="', $url, '" target="_blank">', $text, '</a>';
1441
+ }
1442
+
1443
+ /**
1444
+ * Prints a panel link to the documentation.
1445
+ *
1446
+ * @param type $url
1447
+ * @param type $text
1448
+ */
1449
+ static function panel_help($url, $text = '') {
1450
+ if (empty($text)) $text = __('Need help?', 'newsletter');
1451
+ echo '<div class="tnp-panel-help"><a href="', $url, '" target="_blank">', $text, '</a></div>';
1452
+ }
1453
+
1454
+ /**
1455
+ * Prints an administration page link to the documentation (just under the administration page title.
1456
+ * @param type $url
1457
+ * @param type $text
1458
+ */
1459
+ static function page_help($url, $text = '') {
1460
+ if (empty($text)) $text = __('Need help?', 'newsletter');
1461
+ echo '<div class="tnp-page-help"><a href="', $url, '" target="_blank">', $text, '</a></div>';
1462
+ }
1463
+
1464
+ static function print_truncated($text, $size=50) {
1465
+ if (mb_strlen($text) < $size) return esc_html($text);
1466
+ $sub = mb_substr($text, 0, $size);
1467
+ echo '<span title="', esc_attr($text), '">', esc_html($sub), '...</span>';
1468
  }
1469
 
1470
  }
includes/module.php CHANGED
@@ -80,6 +80,16 @@ class NewsletterModule {
80
  $this->available_version = get_option($this->prefix . '_available_version');
81
  }
82
  }
 
 
 
 
 
 
 
 
 
 
83
 
84
  function first_install() {
85
 
@@ -153,7 +163,8 @@ class NewsletterModule {
153
  */
154
  function get_options($sub = '') {
155
  $options = get_option($this->get_prefix($sub), array());
156
- if (!is_array($options)) return array();
 
157
  return $options;
158
  }
159
 
@@ -208,7 +219,8 @@ class NewsletterModule {
208
  }
209
 
210
  function merge_options($options, $sub = '') {
211
- if (!is_array($options)) $options = array();
 
212
  $old_options = $this->get_options($sub);
213
  $this->save_options(array_merge($old_options, $options), $sub);
214
  }
@@ -297,13 +309,14 @@ class NewsletterModule {
297
  }
298
 
299
  /**
300
- * Returns the email address normalized, lowecase with no spaces. If it's not a valid email
301
- * returns null.
302
  */
303
  static function normalize_email($email) {
 
304
  $email = strtolower(trim($email));
305
  if (!is_email($email)) {
306
- return null;
307
  }
308
  //$email = apply_filters('newsletter_normalize_email', $email);
309
  return $email;
@@ -324,8 +337,10 @@ class NewsletterModule {
324
  }
325
 
326
  static function is_email($email, $empty_ok = false) {
 
 
327
  $email = strtolower(trim($email));
328
-
329
  if ($email == '') {
330
  return $empty_ok;
331
  }
@@ -433,9 +448,10 @@ class NewsletterModule {
433
  }
434
 
435
  $result = array(array(), array());
436
-
437
- if (empty($posts)) return $result;
438
-
 
439
  foreach ($posts as &$post) {
440
  if (self::is_post_old($post, $time))
441
  $result[1][] = $post;
@@ -586,6 +602,7 @@ class NewsletterModule {
586
  if ($type == null) {
587
  $list = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " order by id desc", $format);
588
  } else {
 
589
  $list = $wpdb->get_results($wpdb->prepare("select * from " . NEWSLETTER_EMAILS_TABLE . " where type=%s order by id desc", $type), $format);
590
  }
591
  if ($wpdb->last_error) {
@@ -598,10 +615,59 @@ class NewsletterModule {
598
  return $list;
599
  }
600
 
 
 
 
 
 
 
601
  function get_email($id, $format = OBJECT) {
602
- return $this->store->get_single(NEWSLETTER_EMAILS_TABLE, (int) $id, $format);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
  }
604
 
 
 
 
 
605
  function get_email_status_label($email) {
606
  switch ($email->status) {
607
  case 'sending':
@@ -712,6 +778,31 @@ class NewsletterModule {
712
  }
713
  return $r;
714
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
 
716
  function get_list($id) {
717
  global $wpdb;
@@ -775,6 +866,52 @@ class NewsletterModule {
775
  return $content;
776
  }
777
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
 
779
  function set_user_wp_user_id($user_id, $wp_user_id) {
780
  $this->store->set_field(NEWSLETTER_USERS_TABLE, $user_id, 'wp_user_id', $wp_user_id);
@@ -783,6 +920,189 @@ class NewsletterModule {
783
  function get_user_by_wp_user_id($wp_user_id, $format = OBJECT) {
784
  return $this->store->get_single_by_field(NEWSLETTER_USERS_TABLE, 'wp_user_id', $wp_user_id, $format);
785
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
786
 
787
  public static function antibot_form_check() {
788
  return strtolower($_SERVER['REQUEST_METHOD']) == 'post' && isset($_POST['ts']) && time() - $_POST['ts'] < 30;
@@ -851,11 +1171,13 @@ class NewsletterModule {
851
  return 0;
852
  return round($value / $total * 100);
853
  }
854
-
855
  static function to_int_id($var) {
856
- if (is_object($var)) return (int)$var->id;
857
- if (is_array($var)) return (int)$var['id'];
858
- return (int)$var;
 
 
859
  }
860
 
861
  }
80
  $this->available_version = get_option($this->prefix . '_available_version');
81
  }
82
  }
83
+
84
+ /**
85
+ * Exceutes a query and log it.
86
+ */
87
+ function query($query) {
88
+ global $wpdb;
89
+
90
+ $this->log($query, 3);
91
+ return $wpdb->query($query);
92
+ }
93
 
94
  function first_install() {
95
 
163
  */
164
  function get_options($sub = '') {
165
  $options = get_option($this->get_prefix($sub), array());
166
+ if (!is_array($options))
167
+ return array();
168
  return $options;
169
  }
170
 
219
  }
220
 
221
  function merge_options($options, $sub = '') {
222
+ if (!is_array($options))
223
+ $options = array();
224
  $old_options = $this->get_options($sub);
225
  $this->save_options(array_merge($old_options, $options), $sub);
226
  }
309
  }
310
 
311
  /**
312
+ * Returns the email address normalized, lowercase with no spaces. If it's not a valid email
313
+ * returns false.
314
  */
315
  static function normalize_email($email) {
316
+ if (!is_string($email)) return false;
317
  $email = strtolower(trim($email));
318
  if (!is_email($email)) {
319
+ return false;
320
  }
321
  //$email = apply_filters('newsletter_normalize_email', $email);
322
  return $email;
337
  }
338
 
339
  static function is_email($email, $empty_ok = false) {
340
+
341
+ if (!is_string($email)) return false;
342
  $email = strtolower(trim($email));
343
+
344
  if ($email == '') {
345
  return $empty_ok;
346
  }
448
  }
449
 
450
  $result = array(array(), array());
451
+
452
+ if (empty($posts))
453
+ return $result;
454
+
455
  foreach ($posts as &$post) {
456
  if (self::is_post_old($post, $time))
457
  $result[1][] = $post;
602
  if ($type == null) {
603
  $list = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " order by id desc", $format);
604
  } else {
605
+ $type = (string)$type;
606
  $list = $wpdb->get_results($wpdb->prepare("select * from " . NEWSLETTER_EMAILS_TABLE . " where type=%s order by id desc", $type), $format);
607
  }
608
  if ($wpdb->last_error) {
615
  return $list;
616
  }
617
 
618
+ /**
619
+ * Retrieves an email from DB and unserialize the options.
620
+ *
621
+ * @param mixed $id
622
+ * @param string $format
623
+ */
624
  function get_email($id, $format = OBJECT) {
625
+ $email = $this->store->get_single(NEWSLETTER_EMAILS_TABLE, $id, $format);
626
+ if ($format == OBJECT) {
627
+ $email->options = maybe_unserialize($email->options);
628
+ if (!is_array($email->options)) $email->options = array();
629
+ } else if ($format == ARRAY_A) {
630
+ $email['options'] = maybe_unserialize($email['options']);
631
+ if (!is_array($email['options'])) $email['options'] = array();
632
+ }
633
+ return $email;
634
+ }
635
+
636
+ /**
637
+ * Save an email and provide serialization, if needed, of $email['options'].
638
+ */
639
+ function save_email($email, $return_format = OBJECT) {
640
+ if (is_object($email)) {
641
+ $email = (array) $email;
642
+ }
643
+
644
+ if (isset($email['subject'])) {
645
+ if (mb_strlen($email['subject'], 'UTF-8') > 250) {
646
+ $email['subject'] = mb_substr($email['subject'], 0, 250, 'UTF-8');
647
+ }
648
+ }
649
+ if (isset($email['options']) && is_array($email['options'])) {
650
+ $email['options'] = serialize($email['options']);
651
+ }
652
+ $email = $this->store->save(NEWSLETTER_EMAILS_TABLE, $email, $return_format);
653
+ if ($return_format == OBJECT) {
654
+ $email->options = maybe_unserialize($email->options);
655
+ if (!is_array($email->options)) $email->options = array();
656
+ } else if ($return_format == ARRAY_A) {
657
+ $email['options'] = maybe_unserialize($email['options']);
658
+ if (!is_array($email['options'])) $email['options'] = array();
659
+ }
660
+ return $email;
661
+ }
662
+
663
+ function delete_email($id) {
664
+ return $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
665
  }
666
 
667
+ function get_email_field($id, $field_name) {
668
+ return $this->store->get_field(NEWSLETTER_EMAILS_TABLE, $id, $field_name);
669
+ }
670
+
671
  function get_email_status_label($email) {
672
  switch ($email->status) {
673
  case 'sending':
778
  }
779
  return $r;
780
  }
781
+
782
+ /**
783
+ * Return the user identified by the "nk" parameter (POST or GET).
784
+ * If no user can be found, returns null.
785
+ * If die_on_fail is true, it dies.
786
+ *
787
+ * @param bool $die_on_fail
788
+ * @return type
789
+ */
790
+ function get_user_from_request($die_on_fail = false) {
791
+ $id = 0;
792
+ if (isset($_REQUEST['nk'])) {
793
+ list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
794
+ }
795
+ $user = $this->get_user($id);
796
+
797
+ if ($user == null || $token != $user->token) {
798
+ if ($die_on_fail) {
799
+ die('No subscriber found.');
800
+ } else {
801
+ return null;
802
+ }
803
+ }
804
+ return $user;
805
+ }
806
 
807
  function get_list($id) {
808
  global $wpdb;
866
  return $content;
867
  }
868
  }
869
+
870
+ /**
871
+ * Returns a list of users marked as "test user".
872
+ * @return array
873
+ */
874
+ function get_test_users() {
875
+ return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
876
+ }
877
+
878
+ function delete_user($id) {
879
+ global $wpdb;
880
+ $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
881
+ if ($r !== false) {
882
+ $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
883
+ }
884
+ }
885
+
886
+ /**
887
+ *
888
+ * @global Newsletter $newsletter
889
+ * @param int|string $id_or_email
890
+ * @param string $status
891
+ * @return boolean
892
+ */
893
+ function set_user_status($id_or_email, $status) {
894
+ global $wpdb;
895
+ $status = (string)$status;
896
+ $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
897
+
898
+ $id_or_email = strtolower(trim($id_or_email));
899
+ if (is_numeric($id_or_email)) {
900
+ $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
901
+ } else {
902
+ $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
903
+ }
904
+
905
+ if ($wpdb->last_error) {
906
+ $this->logger->error($wpdb->last_error);
907
+ return false;
908
+ }
909
+ return $r;
910
+ }
911
+
912
+ function set_user_field($id, $field, $value) {
913
+ $this->store->set_field(NEWSLETTER_USERS_TABLE, $id, $field, $value);
914
+ }
915
 
916
  function set_user_wp_user_id($user_id, $wp_user_id) {
917
  $this->store->set_field(NEWSLETTER_USERS_TABLE, $user_id, 'wp_user_id', $wp_user_id);
920
  function get_user_by_wp_user_id($wp_user_id, $format = OBJECT) {
921
  return $this->store->get_single_by_field(NEWSLETTER_USERS_TABLE, 'wp_user_id', $wp_user_id, $format);
922
  }
923
+
924
+ /**
925
+ * Replace any kind of newsletter placeholder in a text.
926
+ */
927
+ function replace($text, $user = null, $email_id = null, $referrer = null) {
928
+ global $wpdb;
929
+
930
+ //$this->logger->debug('Replace start');
931
+ if (is_array($user)) {
932
+ $user = $this->get_user($user['id']);
933
+ }
934
+
935
+ $email = null;
936
+ if (is_object($email_id)) {
937
+ $email = $email_id;
938
+ $email_id = $email->id;
939
+ } else if (is_numeric($email_id)) {
940
+ $email = $this->get_email($email_id);
941
+ }
942
+
943
+ $text = apply_filters('newsletter_replace', $text, $user, $email);
944
+
945
+ $text = $this->replace_url($text, 'BLOG_URL', home_url('/'));
946
+ $text = $this->replace_url($text, 'HOME_URL', home_url('/'));
947
+
948
+ $text = str_replace('{blog_title}', get_option('blogname'), $text);
949
+ $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
950
+
951
+ $text = $this->replace_date($text);
952
+
953
+ if ($user != null) {
954
+ $options_profile = get_option('newsletter_profile');
955
+
956
+ $text = str_replace('{email}', $user->email, $text);
957
+ if (empty($user->name)) {
958
+ $text = str_replace(' {name}', '', $text);
959
+ $text = str_replace('{name}', '', $text);
960
+ } else {
961
+ $text = str_replace('{name}', $user->name, $text);
962
+ }
963
+
964
+ switch ($user->sex) {
965
+ case 'm': $text = str_replace('{title}', $options_profile['title_male'], $text);
966
+ break;
967
+ case 'f': $text = str_replace('{title}', $options_profile['title_female'], $text);
968
+ break;
969
+ case 'n': $text = str_replace('{title}', $options_profile['title_none'], $text);
970
+ break;
971
+ default:
972
+ $text = str_replace('{title}', '', $text);
973
+ }
974
+
975
+
976
+ $text = str_replace('{surname}', $user->surname, $text);
977
+ $text = str_replace('{last_name}', $user->surname, $text);
978
+
979
+ $full_name = trim($user->name . ' ' . $user->surname);
980
+ if (empty($full_name)) {
981
+ $text = str_replace(' {full_name}', '', $text);
982
+ $text = str_replace('{full_name}', '', $text);
983
+ } else {
984
+ $text = str_replace('{full_name}', $full_name, $text);
985
+ }
986
+
987
+ $text = str_replace('{token}', $user->token, $text);
988
+ $text = str_replace('%7Btoken%7D', $user->token, $text);
989
+ $text = str_replace('{id}', $user->id, $text);
990
+ $text = str_replace('%7Bid%7D', $user->id, $text);
991
+ $text = str_replace('{ip}', $user->ip, $text);
992
+ $text = str_replace('{key}', $user->id . '-' . $user->token, $text);
993
+ $text = str_replace('%7Bkey%7D', $user->id . '-' . $user->token, $text);
994
+
995
+ if (strpos($text, '{profile_form}') !== false) {
996
+ $text = str_replace('{profile_form}', NewsletterSubscription::instance()->get_profile_form_html5($user), $text);
997
+ }
998
+
999
+ for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1000
+ $p = 'profile_' . $i;
1001
+ $text = str_replace('{profile_' . $i . '}', $user->$p, $text);
1002
+ }
1003
+
1004
+ $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
1005
+ $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
1006
+ $nk = $user->id . '-' . $user->token;
1007
+
1008
+ $options_subscription = NewsletterSubscription::instance()->options;
1009
+
1010
+ if ($email) {
1011
+ $text = str_replace('{email_id}', $email->id, $text);
1012
+ $text = str_replace('{email_subject}', $email->subject, $text);
1013
+ }
1014
+
1015
+ $home_url = home_url('/');
1016
+ //$text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', self::add_qs(plugins_url('do.php', __FILE__), 'a=c' . $id_token));
1017
+
1018
+ $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1019
+ $text = $this->replace_url($text, 'ACTIVATION_URL', $home_url . '?na=c&nk=' . $nk);
1020
+
1021
+ $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1022
+ //$text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', NEWSLETTER_URL . '/do/unsubscribe.php?nk=' . $nk);
1023
+ $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1024
+ // $text = $this->replace_url($text, 'CHANGE_URL', plugins_url('newsletter/do/change.php'));
1025
+
1026
+ // Obsolete.
1027
+ $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
1028
+ $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
1029
+ $text = $this->replace_url($text, 'FEED_SUBSCRIPTION_URL', self::add_qs($base, 'nm=es' . $id_token));
1030
+ $text = $this->replace_url($text, 'FEED_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=eu' . $id_token));
1031
+
1032
+
1033
+ if (empty($options_profile['profile_url']))
1034
+ $text = $this->replace_url($text, 'PROFILE_URL', $home_url . '?na=p&nk=' . $nk);
1035
+ else
1036
+ $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
1037
+
1038
+ $text = $this->replace_url($text, 'UNLOCK_URL', $home_url . '?na=ul&nk=' . $nk);
1039
+ if (!empty($email_id)) {
1040
+ $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email_id . '&amp;nk=' . $nk);
1041
+ }
1042
+
1043
+ // for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1044
+ // $text = $this->replace_url($text, 'LIST_' . $i . '_SUBSCRIPTION_URL', self::add_qs($base, 'nm=ls&amp;nl=' . $i . $id_token));
1045
+ // $text = $this->replace_url($text, 'LIST_' . $i . '_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=lu&amp;nl=' . $i . $id_token));
1046
+ // }
1047
+
1048
+ // Profile fields change links
1049
+ // $text = $this->replace_url($text, 'SET_SEX_MALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=m');
1050
+ // $text = $this->replace_url($text, 'SET_SEX_FEMALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=f');
1051
+ // $text = $this->replace_url($text, 'SET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=feed');
1052
+ // $text = $this->replace_url($text, 'UNSET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=feed');
1053
+ // for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1054
+ // $text = $this->replace_url($text, 'SET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=preference_' . $i);
1055
+ // $text = $this->replace_url($text, 'UNSET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=preference_' . $i);
1056
+ // }
1057
+ }
1058
+
1059
+ if (strpos($text, '{subscription_form}') !== false) {
1060
+ $text = str_replace('{subscription_form}', NewsletterSubscription::instance()->get_subscription_form($referrer), $text);
1061
+ } else {
1062
+ for ($i = 1; $i <= 10; $i++) {
1063
+ if (strpos($text, "{subscription_form_$i}") !== false) {
1064
+ $text = str_replace("{subscription_form_$i}", NewsletterSubscription::instance()->get_form($i), $text);
1065
+ break;
1066
+ }
1067
+ }
1068
+ }
1069
+
1070
+ //$this->logger->debug('Replace end');
1071
+ return $text;
1072
+ }
1073
+
1074
+ function replace_date($text) {
1075
+ $text = str_replace('{date}', date_i18n(get_option('date_format')), $text);
1076
+
1077
+ // Date processing
1078
+ $x = 0;
1079
+ while (($x = strpos($text, '{date_', $x)) !== false) {
1080
+ $y = strpos($text, '}', $x);
1081
+ if ($y === false)
1082
+ continue;
1083
+ $f = substr($text, $x + 6, $y - $x - 6);
1084
+ $text = substr($text, 0, $x) . date($f) . substr($text, $y + 1);
1085
+ }
1086
+ return $text;
1087
+ }
1088
+
1089
+ function replace_url($text, $tag, $url) {
1090
+ $home = trailingslashit(home_url());
1091
+ $tag_lower = strtolower($tag);
1092
+ $text = str_replace($home . '{' . $tag_lower . '}', $url, $text);
1093
+ $text = str_replace($home . '%7B' . $tag_lower . '%7D', $url, $text);
1094
+ $text = str_replace('{' . $tag_lower . '}', $url, $text);
1095
+ $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
1096
+
1097
+ $text = str_replace('%7B' . $tag_lower . '_encoded%7D', urlencode($url), $text);
1098
+ $text = str_replace('{' . $tag_lower . '_encoded}', urlencode($url), $text);
1099
+
1100
+ // for compatibility
1101
+ $text = str_replace($home . $tag, $url, $text);
1102
+
1103
+ return $text;
1104
+ }
1105
+
1106
 
1107
  public static function antibot_form_check() {
1108
  return strtolower($_SERVER['REQUEST_METHOD']) == 'post' && isset($_POST['ts']) && time() - $_POST['ts'] < 30;
1171
  return 0;
1172
  return round($value / $total * 100);
1173
  }
1174
+
1175
  static function to_int_id($var) {
1176
+ if (is_object($var))
1177
+ return (int) $var->id;
1178
+ if (is_array($var))
1179
+ return (int) $var['id'];
1180
+ return (int) $var;
1181
  }
1182
 
1183
  }
includes/store.php CHANGED
@@ -33,10 +33,12 @@ class NewsletterStore {
33
 
34
  function get_field($table, $id, $field_name) {
35
  global $wpdb;
36
- if (preg_match('/^[a-zA-Z]+$/', $field_name) == 0) {
 
37
  $this->logger->error('Invalis field name: ' . $field_name);
38
  return false;
39
  }
 
40
  $r = $wpdb->get_var($wpdb->prepare("select $field_name from $table where id=%d limit 1", $id));
41
  if ($wpdb->last_error) {
42
  $this->logger->error($wpdb->last_error);
@@ -47,12 +49,20 @@ class NewsletterStore {
47
 
48
  function get_single($table, $id, $format = OBJECT) {
49
  global $wpdb;
 
50
  return $this->get_single_by_query($wpdb->prepare("select * from $table where id=%d limit 1", $id), $format);
51
  }
52
 
53
  function get_single_by_field($table, $field_name, $field_value, $format = OBJECT) {
54
  global $wpdb;
55
- return $this->get_single_by_query("select * from $table where $field_name='" . esc_sql($field_value) . "' limit 1", $format);
 
 
 
 
 
 
 
56
  }
57
 
58
  function get_count($table, $where = null) {
@@ -116,7 +126,7 @@ class NewsletterStore {
116
  }
117
 
118
  if (isset($data['id'])) {
119
- $id = $data['id'];
120
  unset($data['id']);
121
  if (!empty($data)) {
122
  $r = $wpdb->update($table, $this->sanitize($data), array('id' => $id));
@@ -146,7 +156,14 @@ class NewsletterStore {
146
 
147
  function increment($table, $id, $field) {
148
  global $wpdb;
149
- $result = $wpdb->query("update $table set $field=$field+1 where id=$id");
 
 
 
 
 
 
 
150
 
151
  if ($wpdb->last_error) {
152
  $this->logger->error($wpdb->last_error);
@@ -165,9 +182,12 @@ class NewsletterStore {
165
  function delete($table, $id) {
166
  global $wpdb;
167
  if (is_array($id)) {
 
 
 
168
  $wpdb->query("delete from " . $table . " where id in (" . implode(',', $id) . ")");
169
  } else {
170
- $wpdb->delete($table, array('id' => $id));
171
  }
172
  if ($wpdb->last_error) {
173
  $this->logger->error($wpdb->last_error);
@@ -196,6 +216,10 @@ class NewsletterStore {
196
 
197
  function set_field($table, $id, $field, $value) {
198
  global $wpdb;
 
 
 
 
199
  if (preg_match('/^[a-zA-Z_]+$/', $field) == 0) {
200
  $this->logger->error('Invalis field name: ' . $field_name);
201
  return false;
33
 
34
  function get_field($table, $id, $field_name) {
35
  global $wpdb;
36
+ $field_name = (string)$field_name;
37
+ if (preg_match('/^[a-zA-Z_]+$/', $field_name) == 0) {
38
  $this->logger->error('Invalis field name: ' . $field_name);
39
  return false;
40
  }
41
+ $id = (int)$id;
42
  $r = $wpdb->get_var($wpdb->prepare("select $field_name from $table where id=%d limit 1", $id));
43
  if ($wpdb->last_error) {
44
  $this->logger->error($wpdb->last_error);
49
 
50
  function get_single($table, $id, $format = OBJECT) {
51
  global $wpdb;
52
+ $id = (int)$id;
53
  return $this->get_single_by_query($wpdb->prepare("select * from $table where id=%d limit 1", $id), $format);
54
  }
55
 
56
  function get_single_by_field($table, $field_name, $field_value, $format = OBJECT) {
57
  global $wpdb;
58
+ $field_name = (string)$field_name;
59
+ $field_value = (string)$field_value;
60
+
61
+ if (preg_match('/^[a-zA-Z_]+$/', $field_name) == 0) {
62
+ $this->logger->error('Invalis field name: ' . $field_name);
63
+ return false;
64
+ }
65
+ return $this->get_single_by_query($wpdb->prepare("select * from $table where $field_name=%s limit 1", $field_value), $format);
66
  }
67
 
68
  function get_count($table, $where = null) {
126
  }
127
 
128
  if (isset($data['id'])) {
129
+ $id = (int)$data['id'];
130
  unset($data['id']);
131
  if (!empty($data)) {
132
  $r = $wpdb->update($table, $this->sanitize($data), array('id' => $id));
156
 
157
  function increment($table, $id, $field) {
158
  global $wpdb;
159
+ $id = (int)$id;
160
+ $field = (string)$field;
161
+
162
+ if (preg_match('/^[a-zA-Z_]+$/', $field) == 0) {
163
+ $this->logger->error('Invalis field name: ' . $field);
164
+ return false;
165
+ }
166
+ $result = $wpdb->query($wpdb->prepare("update $table set $field=$field+1 where id=%d", $id));
167
 
168
  if ($wpdb->last_error) {
169
  $this->logger->error($wpdb->last_error);
182
  function delete($table, $id) {
183
  global $wpdb;
184
  if (is_array($id)) {
185
+ for ($i=0; $i<count($id); $i++) {
186
+ $id[$i] = (int)$id[$i];
187
+ }
188
  $wpdb->query("delete from " . $table . " where id in (" . implode(',', $id) . ")");
189
  } else {
190
+ $wpdb->delete($table, array('id' => (int)$id));
191
  }
192
  if ($wpdb->last_error) {
193
  $this->logger->error($wpdb->last_error);
216
 
217
  function set_field($table, $id, $field, $value) {
218
  global $wpdb;
219
+ $field = (string)$field;
220
+ $id = (int)$id;
221
+ $value = (string)$value;
222
+
223
  if (preg_match('/^[a-zA-Z_]+$/', $field) == 0) {
224
  $this->logger->error('Invalis field name: ' . $field_name);
225
  return false;
main/index.php CHANGED
@@ -25,14 +25,15 @@ $query = "select * from " . NEWSLETTER_USERS_TABLE . " order by id desc";
25
  $query .= " limit 10";
26
  $subscribers = $wpdb->get_results($query);
27
 
 
28
  $last_email = $wpdb->get_row(
29
  $wpdb->prepare("select * from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending') and send_on<%d order by id desc limit 1", time()));
30
 
31
  if ($last_email) {
32
  $last_email_sent = $last_email->sent;
33
- $last_email_opened = $wpdb->get_var("select count(distinct user_id) from " . NEWSLETTER_STATS_TABLE . " where email_id=" . $last_email->id);
34
  $last_email_notopened = $last_email_sent - $last_email_opened;
35
- $last_email_clicked = $wpdb->get_var("select count(distinct user_id) from " . NEWSLETTER_STATS_TABLE . " where url<>'' and email_id=" . $last_email->id);
36
  $last_email_opened -= $last_email_clicked;
37
 
38
  $overall_sent = $wpdb->get_var("select sum(sent) from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending')");
@@ -70,7 +71,7 @@ $labels = array_reverse($labels);
70
 
71
  <div id="tnp-heading">
72
 
73
- <h2>TNP <?php _e('Dashboard', 'newsletter') ?></h2>
74
  <p><?php _e('Your powerful control panel', 'newsletter') ?></p>
75
 
76
  </div>
@@ -80,6 +81,7 @@ $labels = array_reverse($labels);
80
  <div id="dashboard-widgets" class="metabox-holder">
81
  <div id="postbox-container-1" class="postbox-container">
82
  <div id="normal-sortables" class="meta-box-sortables ui-sortable">
 
83
  <!-- START Statistics -->
84
  <div id="tnp-dash-statistics" class="postbox">
85
  <h3><?php _e('Statistics', 'newsletter') ?>
@@ -160,6 +162,18 @@ $labels = array_reverse($labels);
160
  });
161
  </script>
162
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  <div id="canvas-holder">
164
  <canvas id="tnp-events-chart-canvas"></canvas>
165
  </div>
@@ -199,6 +213,7 @@ $labels = array_reverse($labels);
199
  </div>
200
  </div>
201
  <!-- END Statistics -->
 
202
  <!-- START Documentation -->
203
  <div id="tnp-dash-documentation" class="postbox">
204
  <h3><?php _e('Documentation', 'newsletter') ?>
25
  $query .= " limit 10";
26
  $subscribers = $wpdb->get_results($query);
27
 
28
+ // Retrieves the last standard newsletter
29
  $last_email = $wpdb->get_row(
30
  $wpdb->prepare("select * from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending') and send_on<%d order by id desc limit 1", time()));
31
 
32
  if ($last_email) {
33
  $last_email_sent = $last_email->sent;
34
+ $last_email_opened = NewsletterStatistics::instance()->get_open_count($last_email->id);
35
  $last_email_notopened = $last_email_sent - $last_email_opened;
36
+ $last_email_clicked = NewsletterStatistics::instance()->get_click_count($last_email->id);
37
  $last_email_opened -= $last_email_clicked;
38
 
39
  $overall_sent = $wpdb->get_var("select sum(sent) from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending')");
71
 
72
  <div id="tnp-heading">
73
 
74
+ <h2><?php _e('Dashboard', 'newsletter') ?></h2>
75
  <p><?php _e('Your powerful control panel', 'newsletter') ?></p>
76
 
77
  </div>
81
  <div id="dashboard-widgets" class="metabox-holder">
82
  <div id="postbox-container-1" class="postbox-container">
83
  <div id="normal-sortables" class="meta-box-sortables ui-sortable">
84
+
85
  <!-- START Statistics -->
86
  <div id="tnp-dash-statistics" class="postbox">
87
  <h3><?php _e('Statistics', 'newsletter') ?>
162
  });
163
  </script>
164
 
165
+ </div>
166
+ </div>
167
+ <!-- END Statistics -->
168
+
169
+
170
+
171
+ <!-- START Statistics -->
172
+ <div id="tnp-dash-statistics" class="postbox">
173
+ <h3><?php _e('Subscriptions', 'newsletter') ?></h3>
174
+ <div class="inside">
175
+
176
+
177
  <div id="canvas-holder">
178
  <canvas id="tnp-events-chart-canvas"></canvas>
179
  </div>
213
  </div>
214
  </div>
215
  <!-- END Statistics -->
216
+
217
  <!-- START Documentation -->
218
  <div id="tnp-dash-documentation" class="postbox">
219
  <h3><?php _e('Documentation', 'newsletter') ?>
main/info.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $module = Newsletter::instance();
@@ -21,182 +22,147 @@ if (!$controls->is_action()) {
21
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
22
 
23
  <div id="tnp-heading">
24
-
25
  <h2><?php _e('Company Info', 'newsletter') ?></h2>
26
- <p>
27
- These informations are used by Newsletter themes to automatically generate some sections of regular newsletters,
28
- <a href="https://www.thenewsletterplugin.com/feed-by-mail-extension?utm_source=plugin&utm_medium=link&utm_campaign=newsletter-feed" target="_blank">
29
- auto messages
30
- </a> and
31
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/follow-up-module?utm_source=plugin&utm_medium=link&utm_campaign=newsletter-followup" target="_blank">
32
- follow-up mails
33
- </a>.
34
- Themes may not use all these fields and/or have specific alternate configurations. All fields are <strong>optional</strong>.
35
- </p>
36
-
37
  </div>
38
  <div id="tnp-body">
39
 
40
- <form method="post" action="">
41
- <?php $controls->init(); ?>
42
-
43
- <div id="tabs">
44
-
45
- <ul>
46
- <li><a href="#tabs-general"><?php _e('General', 'newsletter') ?></a></li>
47
- <li><a href="#tabs-social"><?php _e('Social', 'newsletter') ?></a></li>
48
- </ul>
49
-
50
- <div id="tabs-general">
51
- <h3>Header Settings</h3>
52
-
53
- <table class="form-table">
54
- <tr valign="top">
55
- <th>
56
- Logo
57
- <div class="tnp-tip">
58
- <span class="tip-button">Tip</span>
59
- <span class="tip-content">
60
- Keep the file lightweight and ideally smaller than 500px in width and 200px in height.
61
- Remember that .png images provide best performances with text and shapes logos.
62
- </span>
63
- </div>
64
- </th>
65
- <td>
66
- <?php $controls->media('header_logo', 'medium'); ?>
67
- <p class="description">
68
- Click to change. This should be your logo in .png or .jpg format.
69
- </p>
70
- </td>
71
- </tr>
72
- <tr>
73
- <th>Title</th>
74
- <td>
75
- <?php $controls->text('header_title', 40); ?>
76
- <p class="description">Appears only when no logo has been uploaded or when it's blocked by email clients.</p>
77
- </td>
78
- </tr>
79
- <tr>
80
- <th>Subtitle</th>
81
- <td>
82
- <?php $controls->text('header_sub', 40); ?>
83
- <p class="description">Appears only if present.</p>
84
- </td>
85
- </tr>
86
- </table>
87
-
88
- <h3>Footer Settings</h3>
89
-
90
- <table class="form-table">
91
- <tr valign="top">
92
- <th>Blog or company name</th>
93
- <td>
94
- <?php $controls->text('footer_title', 40); ?>
95
- <p class="description">
96
- User or corporation name to be displayed on the newsletter footer.
97
- </p>
98
- </td>
99
- </tr>
100
- <tr valign="top">
101
- <th>Address</th>
102
- <td>
103
- <?php $controls->text('footer_contact', 40); ?>
104
- <p class="description">
105
- Your real address, if available. The CAN-SPAM Act requires it.
106
- </p>
107
- </td>
108
- </tr>
109
- <tr>
110
- <th>Copyright, privacy or legal text</th>
111
- <td>
112
- <?php $controls->text('footer_legal', 40); ?>
113
- <p class="description">
114
- Any copyright, privacy or legal text you want on the newsletter footer.
115
- </p>
116
- </td>
117
- </tr>
118
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  </div>
120
- <div id="tabs-social">
121
- <h3>Social Settings</h3>
122
-
123
- <p>Social icons will be added automatically to your newsletter only for set URLs.</p>
124
-
125
- <table class="form-table">
126
- <tr valign="top">
127
- <th>Facebook</th>
128
- <td>
129
- <?php $controls->text('facebook_url', 40); ?>
130
- <p class="description">
131
- Your Facebook url (e.g. https://www.facebook.com/thenewsletterplugin)
132
- </p>
133
- </td>
134
- </tr>
135
- <tr valign="top">
136
- <th>Google+</th>
137
- <td>
138
- <?php $controls->text('googleplus_url', 40); ?>
139
- <p class="description">
140
- Your Google+ url (e.g. https://plus.google.com/...)
141
- </p>
142
- </td>
143
- </tr>
144
- <tr valign="top">
145
- <th>Twitter</th>
146
- <td>
147
- <?php $controls->text('twitter_url', 40); ?>
148
- <p class="description">
149
- Your Twitter url (e.g. https://twitter.com/...)
150
- </p>
151
- </td>
152
- </tr>
153
- <tr valign="top">
154
- <th>Linkedin</th>
155
- <td>
156
- <?php $controls->text('linkedin_url', 40); ?>
157
- <p class="description">
158
- Your Linkedin url (e.g. https://www.linkedin.com/in/...)
159
- </p>
160
- </td>
161
- </tr>
162
- <tr valign="top">
163
- <th>YouTube</th>
164
- <td>
165
- <?php $controls->text('youtube_url', 40); ?>
166
- <p class="description">
167
- Your YouTube url (e.g. https://www.youtube.com/channel/...)
168
- </p>
169
- </td>
170
- </tr>
171
- <tr valign="top">
172
- <th>Vimeo</th>
173
- <td>
174
- <?php $controls->text('vimeo_url', 40); ?>
175
- <p class="description">
176
- Your Vimeo url (e.g. http://vimeo.com/...)
177
- </p>
178
- </td>
179
- </tr>
180
- <tr valign="top">
181
- <th>Instagram</th>
182
- <td>
183
- <?php $controls->text('instagram_url', 40); ?>
184
- <p class="description">
185
- Your Instagram url (e.g. http://instagram.com/...)
186
- </p>
187
- </td>
188
- </tr>
189
- </table>
190
- </div>
191
- </div>
192
 
193
- <p>
194
- <?php $controls->button('save', 'Save'); ?>
195
- </p>
 
 
 
196
 
197
- </form>
198
- </div>
199
-
200
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
201
-
202
  </div>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $module = Newsletter::instance();
22
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
23
 
24
  <div id="tnp-heading">
25
+
26
  <h2><?php _e('Company Info', 'newsletter') ?></h2>
27
+
 
 
 
 
 
 
 
 
 
 
28
  </div>
29
  <div id="tnp-body">
30
 
31
+ <form method="post" action="">
32
+ <?php $controls->init(); ?>
33
+
34
+ <div id="tabs">
35
+
36
+ <ul>
37
+ <li><a href="#tabs-general"><?php _e('General', 'newsletter') ?></a></li>
38
+ <li><a href="#tabs-social"><?php _e('Social', 'newsletter') ?></a></li>
39
+ </ul>
40
+
41
+ <div id="tabs-general">
42
+ <h3><?php _e('Header Settings', 'newsletter') ?></h3>
43
+
44
+ <table class="form-table">
45
+ <tr valign="top">
46
+ <th>
47
+ <?php _e('Logo', 'newsletter') ?><br>
48
+ <?php $controls->help('https://www.thenewsletterplugin.com/documentation/newsletter-configuration#company-logo') ?>
49
+ </th>
50
+ <td style="cursor: pointer">
51
+ <?php $controls->media('header_logo', 'medium'); ?>
52
+ </td>
53
+ </tr>
54
+ <tr>
55
+ <th><?php _e('Title', 'newsletter') ?></th>
56
+ <td>
57
+ <?php $controls->text('header_title', 40); ?>
58
+ </td>
59
+ </tr>
60
+ <tr>
61
+ <th><?php _e('Motto', 'newsletter') ?></th>
62
+ <td>
63
+ <?php $controls->text('header_sub', 40); ?>
64
+ </td>
65
+ </tr>
66
+ </table>
67
+
68
+ <h3><?php _e('Footer Settings', 'newsletter') ?></h3>
69
+
70
+ <table class="form-table">
71
+ <tr valign="top">
72
+ <th><?php _e('Company name', 'newsletter') ?></th>
73
+ <td>
74
+ <?php $controls->text('footer_title', 40); ?>
75
+ </td>
76
+ </tr>
77
+ <tr valign="top">
78
+ <th><?php _e('Address', 'newsletter') ?></th>
79
+ <td>
80
+ <?php $controls->text('footer_contact', 40); ?>
81
+ </td>
82
+ </tr>
83
+ <tr>
84
+ <th><?php _e('Copyright or legal text', 'newsletter') ?></th>
85
+ <td>
86
+ <?php $controls->text('footer_legal', 40); ?>
87
+ </td>
88
+ </tr>
89
+ </table>
90
+ </div>
91
+
92
+ <div id="tabs-social">
93
+
94
+ <table class="form-table">
95
+ <tr valign="top">
96
+ <th>Facebook URL</th>
97
+ <td>
98
+ <?php $controls->text('facebook_url', 40); ?>
99
+ </td>
100
+ </tr>
101
+ <tr valign="top">
102
+ <th>Twitter URL</th>
103
+ <td>
104
+ <?php $controls->text('twitter_url', 40); ?>
105
+ </td>
106
+ </tr>
107
+ <tr valign="top">
108
+ <th>Instagram URL</th>
109
+ <td>
110
+ <?php $controls->text('instagram_url', 40); ?>
111
+ </td>
112
+ </tr>
113
+ <tr valign="top">
114
+ <th>Google+ URL</th>
115
+ <td>
116
+ <?php $controls->text('googleplus_url', 40); ?>
117
+ </td>
118
+ </tr>
119
+ <tr valign="top">
120
+ <th>Pinterest URL</th>
121
+ <td>
122
+ <?php $controls->text('pinterest_url', 40); ?>
123
+ </td>
124
+ </tr>
125
+ <tr valign="top">
126
+ <th>Linkedin URL</th>
127
+ <td>
128
+ <?php $controls->text('linkedin_url', 40); ?>
129
+ </td>
130
+ </tr>
131
+ <tr valign="top">
132
+ <th>Tumblr URL</th>
133
+ <td>
134
+ <?php $controls->text('tumblr_url', 40); ?>
135
+ </td>
136
+ </tr>
137
+ <tr valign="top">
138
+ <th>YouTube URL</th>
139
+ <td>
140
+ <?php $controls->text('youtube_url', 40); ?>
141
+ </td>
142
+ </tr>
143
+ <tr valign="top">
144
+ <th>Vimeo URL</th>
145
+ <td>
146
+ <?php $controls->text('vimeo_url', 40); ?>
147
+ </td>
148
+ </tr>
149
+ <tr valign="top">
150
+ <th>Soundcloud URL</th>
151
+ <td>
152
+ <?php $controls->text('soundcloud_url', 40); ?>
153
+ </td>
154
+ </tr>
155
+ </table>
156
+ </div>
157
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
+ <p>
160
+ <?php $controls->button('save', 'Save'); ?>
161
+ </p>
162
+
163
+ </form>
164
+ </div>
165
 
 
 
 
166
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
167
+
168
  </div>
main/languages/en_US.php CHANGED
@@ -13,5 +13,6 @@ $options = array(
13
  'sender_name' => get_option('blogname'),
14
  'editor' => 0,
15
  'scheduler_max' => 100,
16
- 'phpmailer'=>0
 
17
  );
13
  'sender_name' => get_option('blogname'),
14
  'editor' => 0,
15
  'scheduler_max' => 100,
16
+ 'phpmailer'=>0,
17
+ 'debug'=>0
18
  );
main/main.php CHANGED
@@ -9,17 +9,6 @@ $module = Newsletter::instance();
9
  if (!$controls->is_action()) {
10
  $controls->data = get_option('newsletter_main');
11
  } else {
12
- if ($controls->is_action('remove')) {
13
-
14
- $wpdb->query("delete from " . $wpdb->prefix . "options where option_name like 'newsletter%'");
15
-
16
- $wpdb->query("drop table " . $wpdb->prefix . "newsletter, " . $wpdb->prefix . "newsletter_stats, " .
17
- $wpdb->prefix . "newsletter_emails, " .
18
- $wpdb->prefix . "newsletter_work");
19
-
20
- echo 'Newsletter plugin destroyed. Please, deactivate it now.';
21
- return;
22
- }
23
 
24
  if ($controls->is_action('save')) {
25
  $errors = null;
@@ -28,43 +17,48 @@ if (!$controls->is_action()) {
28
  $controls->data['sender_email'] = $newsletter->normalize_email($controls->data['sender_email']);
29
  if (!$newsletter->is_email($controls->data['sender_email'])) {
30
  $controls->errors .= __('The sender email address is not correct.', 'newsletter') . '<br>';
 
 
31
  }
32
 
33
- $controls->data['return_path'] = $newsletter->normalize_email($controls->data['return_path']);
34
  if (!$newsletter->is_email($controls->data['return_path'], true)) {
35
  $controls->errors .= __('Return path email is not correct.', 'newsletter') . '<br>';
 
 
36
  }
37
 
38
- $controls->data['php_time_limit'] = (int) $controls->data['php_time_limit'];
39
- if ($controls->data['php_time_limit'] == 0)
40
- unset($controls->data['php_time_limit']);
41
-
42
- //$controls->data['test_email'] = $newsletter->normalize_email($controls->data['test_email']);
43
- //if (!$newsletter->is_email($controls->data['test_email'], true)) {
44
- // $controls->errors .= 'Test email is not correct.<br />';
45
- //}
46
 
47
- $controls->data['reply_to'] = $newsletter->normalize_email($controls->data['reply_to']);
48
  if (!$newsletter->is_email($controls->data['reply_to'], true)) {
49
  $controls->errors .= __('Reply to email is not correct.', 'newsletter') . '<br>';
 
 
50
  }
51
 
52
- $controls->data['contract_key'] = trim($controls->data['contract_key']);
 
 
53
 
54
  if (empty($controls->errors)) {
55
  $module->merge_options($controls->data);
56
- $controls->messages .= __('Saved.', 'newsletter');
57
  }
58
-
59
  update_option('newsletter_log_level', $controls->data['log_level']);
60
-
61
  $module->hook_newsletter_extension_versions(true);
62
  delete_transient("tnp_extensions_json");
63
  }
64
  }
65
 
66
- if (!empty($controls->data['contract_key'])) {
67
- $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . $controls->data['contract_key'], array('sslverify'=>false));
 
 
 
 
 
 
 
68
  if (is_wp_error($response)) {
69
  /* @var $response WP_Error */
70
  $controls->errors .= 'It seems that your blog cannot contact the license validator. Ask your provider to unlock the HTTP/HTTPS connections to www.thenewsletterplugin.com<br>';
@@ -84,17 +78,16 @@ if (!empty($controls->data['contract_key'])) {
84
  $module->merge_options($controls->data);
85
  }
86
 
87
-
88
  $return_path = $module->options['return_path'];
 
89
  if (!empty($return_path)) {
90
  list($return_path_local, $return_path_domain) = explode('@', $return_path);
91
 
92
  $sender = $module->options['sender_email'];
93
  list($sender_local, $sender_domain) = explode('@', $sender);
94
 
95
-
96
  if ($sender_domain != $return_path_domain) {
97
- $controls->messages .= '<br><br>Your Return Path domain is different from your Sender domain. Providers may require them to be identical';
98
  }
99
  }
100
  ?>
@@ -124,9 +117,7 @@ if (!empty($return_path)) {
124
  <div id="tabs-basic">
125
 
126
  <p>
127
- <strong>Important!</strong>
128
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration" target="_blank">Read the configuration page</a>
129
- to know every details about these settings.
130
  </p>
131
 
132
 
@@ -135,65 +126,43 @@ if (!empty($return_path)) {
135
  <tr valign="top">
136
  <th><?php _e('Sender email address', 'newsletter') ?></th>
137
  <td>
138
- <?php $controls->text_email('sender_email', 40); ?> (valid email address)
139
-
140
- <p class="description">
141
- <?php _e('Email address from which subscribers will see your email coming.', 'newsletter') ?>
142
- Since this setting can
143
- affect the reliability of delivery,
144
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#sender" target="_blank">read my notes here</a> (important).
145
- Generally use an address within your domain name.
146
- </p>
147
  </td>
148
  </tr>
149
  <tr>
150
  <th><?php _e('Sender name', 'newsletter') ?></th>
151
  <td>
152
- <?php $controls->text('sender_name', 40); ?> (optional)
153
-
154
- <p class="description">
155
- <?php _e('Name from which subscribers will see your email coming (for example your blog title).', 'newsletter') ?>
156
- Since this setting can affect the reliability of delivery (usually under Windows)
157
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#sender" target="_blank">read my notes here</a>.
158
- </p>
159
  </td>
160
  </tr>
161
 
162
  <tr valign="top">
163
  <th><?php _e('Return path', 'newsletter') ?></th>
164
  <td>
165
- <?php $controls->text_email('return_path', 40); ?> (valid email address, default empty)
166
- <p class="description">
167
- Email address where delivery error messages are sent by mailing systems (eg. mailbox full, invalid address, ...).<br>
168
- Some providers do not accept this field: they can block emails or force it to a different value affecting the delivery reliability.
169
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#return-path" target="_blank">Read my notes here</a> (important).
170
- </p>
171
  </td>
172
  </tr>
173
  <tr valign="top">
174
  <th><?php _e('Reply to', 'newsletter') ?></th>
175
  <td>
176
  <?php $controls->text_email('reply_to', 40); ?>
177
- <p class="description">
178
- This is the email address where subscribers will reply (eg. if they want to reply to a newsletter). Leave it blank if
179
- you don't want to specify a different address from the sender email above. Since this setting can
180
- affect the reliability of delivery,
181
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#reply-to" target="_blank">read my notes here</a> (important).
182
- </p>
183
  </td>
184
  </tr>
185
 
186
  <tr valign="top">
187
- <th>License key</th>
188
  <td>
189
- <?php $controls->text('contract_key', 40); ?>
190
- <p class="description">
191
- This key is used by <a href="https://www.thenewsletterplugin.com/plugins/newsletter" target="_blank">extensions</a> to
192
- self update. It does not unlock hidden features or like!
193
  <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
194
- <br>A global license key is actually defined, this value will be ignored.
 
 
 
 
 
195
  <?php } ?>
196
- </p>
197
  </td>
198
  </tr>
199
 
@@ -203,15 +172,7 @@ if (!empty($return_path)) {
203
  <div id="tabs-speed">
204
 
205
  <p>
206
- You can set the speed of the email delivery as <strong>emails per hour</strong>. The delivery engine
207
- runs every <strong>5 minutes</strong> and sends a limited number of email to keep the sending rate
208
- below the specified limit. For example if you set 120 emails per hour the delivery engine will
209
- send at most 10 emails per run.
210
- </p>
211
- <p>
212
- <strong>Important!</strong> Read the
213
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-delivery-engine" target="_blank">delivery engine page</a>
214
- to solve speed problems and find blog setup examples to make it work at the best.
215
  </p>
216
 
217
  <table class="form-table">
@@ -219,11 +180,7 @@ if (!empty($return_path)) {
219
  <th><?php _e('Max emails per hour', 'newsletter') ?></th>
220
  <td>
221
  <?php $controls->text('scheduler_max', 5); ?>
222
- <p class="description">
223
- The Newsletter delivery engine respects this limit and it should be set to a value less than the maximum allowed by your provider
224
- (Hostgator: 500 per hour, Dreamhost: 100 per hour, Go Daddy: 1000 per <strong>day</strong> using their SMTP, Gmail: 500 per day).
225
- Read <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-delivery-engine" target="_blank">more on delivery engine</a> (important).
226
- </p>
227
  </td>
228
  </tr>
229
  </table>
@@ -233,13 +190,13 @@ if (!empty($return_path)) {
233
  <div id="tabs-advanced">
234
 
235
  <p>
236
- Every setting is explained <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#advanced" target="_blank">here</a>.
237
  </p>
238
 
239
  <table class="form-table">
240
 
241
  <tr valign="top">
242
- <th>Enable access to blog editors?</th>
243
  <td>
244
  <?php $controls->yesno('editor'); ?>
245
  </td>
@@ -247,7 +204,7 @@ if (!empty($return_path)) {
247
 
248
  <tr>
249
  <th>
250
- Log level
251
  </th>
252
  <td>
253
  <?php $controls->log_level('log_level'); ?>
@@ -255,67 +212,24 @@ if (!empty($return_path)) {
255
  </tr>
256
 
257
  <tr valign="top">
258
- <th>Debug mode</th>
259
  <td>
260
  <?php $controls->yesno('debug', 40); ?>
261
- <p class="description">
262
- In debug mode Newsletter intercepts PHP errors. To be used only by the support team.
263
- </p>
264
- </td>
265
- </tr>
266
-
267
- <tr valign="top">
268
- <th>API key</th>
269
- <td>
270
- <?php $controls->text('api_key', 40); ?>
271
- <p class="description">
272
- When non-empty can be used to directly call the API for external integration. See API documentation on
273
- documentation panel.
274
- </p>
275
  </td>
276
  </tr>
277
 
278
- <tr>
279
- <th>Custom CSS</th>
280
- <td>
281
- <?php $controls->textarea('css'); ?>
282
- <p class="description">
283
- This option is obsolete and will be removed, use the custom style field in the subscription configuration panel.
284
- </p>
285
- </td>
286
- </tr>
287
  <tr valign="top">
288
- <th>Send email directly</th>
289
  <td>
290
  <?php $controls->yesno('phpmailer'); ?>
291
- <p class="description">
292
- Instead of using WordPress email are sent directly by Newsletter.
293
- This enable the textual part of newsletters and the content encoding setting.
294
- Keep at "No" if you're using
295
- ans SMTP plugin like Postman.
296
- <a href=" https://www.thenewsletterplugin.com/configuration-tnin-send-email" target="_blank">Read more</a>.
297
- </p>
298
  </td>
299
  </tr>
300
  <tr valign="top">
301
- <th>Email body content encoding</th>
302
  <td>
303
  <?php $controls->select('content_transfer_encoding', array('' => 'Default', '8bit' => '8 bit', 'base64' => 'Base 64', 'binary' => 'Binary', 'quoted-printable' => 'Quoted printable', '7bit' => '7 bit')); ?>
304
- <p class="description">
305
- Sometimes setting it to Base 64 solves problem with old mail servers (for example truncated or unformatted emails.
306
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#enconding" target="_blank">Read more here</a>.
307
- Works only with direct email sending, see the option above.
308
- </p>
309
- </td>
310
- </tr>
311
- <tr valign="top">
312
- <th>PHP max execution time</th>
313
- <td>
314
- <?php $controls->text('php_time_limit', 10); ?>
315
- (before write in something, <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#advanced" target="_blank">read here</a>)
316
- <p class="description">
317
- Sets the PHP max execution time in seconds, overriding the default of your server.
318
- </p>
319
  </td>
320
  </tr>
321
  </table>
@@ -323,8 +237,6 @@ if (!empty($return_path)) {
323
  </div>
324
 
325
 
326
-
327
-
328
  </div> <!-- tabs -->
329
 
330
  <p>
@@ -332,7 +244,6 @@ if (!empty($return_path)) {
332
  </p>
333
 
334
  </form>
335
- <p></p>
336
  </div>
337
 
338
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
9
  if (!$controls->is_action()) {
10
  $controls->data = get_option('newsletter_main');
11
  } else {
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  if ($controls->is_action('save')) {
14
  $errors = null;
17
  $controls->data['sender_email'] = $newsletter->normalize_email($controls->data['sender_email']);
18
  if (!$newsletter->is_email($controls->data['sender_email'])) {
19
  $controls->errors .= __('The sender email address is not correct.', 'newsletter') . '<br>';
20
+ } else {
21
+ $controls->data['sender_email'] = $newsletter->normalize_email($controls->data['sender_email']);
22
  }
23
 
 
24
  if (!$newsletter->is_email($controls->data['return_path'], true)) {
25
  $controls->errors .= __('Return path email is not correct.', 'newsletter') . '<br>';
26
+ } else {
27
+ $controls->data['return_path'] = $newsletter->normalize_email($controls->data['return_path']);
28
  }
29
 
 
 
 
 
 
 
 
 
30
 
 
31
  if (!$newsletter->is_email($controls->data['reply_to'], true)) {
32
  $controls->errors .= __('Reply to email is not correct.', 'newsletter') . '<br>';
33
+ } else {
34
+ $controls->data['reply_to'] = $newsletter->normalize_email($controls->data['reply_to']);
35
  }
36
 
37
+ if (!empty($controls->data['contract_key'])) {
38
+ $controls->data['contract_key'] = trim($controls->data['contract_key']);
39
+ }
40
 
41
  if (empty($controls->errors)) {
42
  $module->merge_options($controls->data);
43
+ $controls->add_message_saved();
44
  }
45
+
46
  update_option('newsletter_log_level', $controls->data['log_level']);
47
+
48
  $module->hook_newsletter_extension_versions(true);
49
  delete_transient("tnp_extensions_json");
50
  }
51
  }
52
 
53
+ if (!empty($controls->data['contract_key']) || defined('NEWSLETTER_LICENSE_KEY')) {
54
+
55
+ if (defined('NEWSLETTER_LICENSE_KEY')) {
56
+ $license_key = NEWSLETTER_LICENSE_KEY;
57
+ } else {
58
+ $license_key = $controls->data['contract_key'];
59
+ }
60
+ $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . urlencode($license_key), array('sslverify' => false));
61
+
62
  if (is_wp_error($response)) {
63
  /* @var $response WP_Error */
64
  $controls->errors .= 'It seems that your blog cannot contact the license validator. Ask your provider to unlock the HTTP/HTTPS connections to www.thenewsletterplugin.com<br>';
78
  $module->merge_options($controls->data);
79
  }
80
 
 
81
  $return_path = $module->options['return_path'];
82
+
83
  if (!empty($return_path)) {
84
  list($return_path_local, $return_path_domain) = explode('@', $return_path);
85
 
86
  $sender = $module->options['sender_email'];
87
  list($sender_local, $sender_domain) = explode('@', $sender);
88
 
 
89
  if ($sender_domain != $return_path_domain) {
90
+ $controls->warnings[] = __('Your Return Path domain is different from your Sender domain. Providers may require them to match.', 'newsletter');
91
  }
92
  }
93
  ?>
117
  <div id="tabs-basic">
118
 
119
  <p>
120
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration') ?>
 
 
121
  </p>
122
 
123
 
126
  <tr valign="top">
127
  <th><?php _e('Sender email address', 'newsletter') ?></th>
128
  <td>
129
+ <?php $controls->text_email('sender_email', 40); ?>
130
+ <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#sender') ?>
 
 
 
 
 
 
 
131
  </td>
132
  </tr>
133
  <tr>
134
  <th><?php _e('Sender name', 'newsletter') ?></th>
135
  <td>
136
+ <?php $controls->text('sender_name', 40); ?>
 
 
 
 
 
 
137
  </td>
138
  </tr>
139
 
140
  <tr valign="top">
141
  <th><?php _e('Return path', 'newsletter') ?></th>
142
  <td>
143
+ <?php $controls->text_email('return_path', 40); ?>
144
+ <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#return-path') ?>
 
 
 
 
145
  </td>
146
  </tr>
147
  <tr valign="top">
148
  <th><?php _e('Reply to', 'newsletter') ?></th>
149
  <td>
150
  <?php $controls->text_email('reply_to', 40); ?>
151
+ <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#reply-to') ?>
 
 
 
 
 
152
  </td>
153
  </tr>
154
 
155
  <tr valign="top">
156
+ <th><?php _e('License key', 'newsletter') ?></th>
157
  <td>
 
 
 
 
158
  <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
159
+ <?php _e('A license key is set in your wp-config.php','newsletter') ?>
160
+ <?php } else { ?>
161
+ <?php $controls->text('contract_key', 40); ?>
162
+ <p class="description">
163
+ <?php printf(__('Find it in <a href="%s" target="_blank">your account</a> page', 'newsletter'), "https://www.thenewsletterplugin.com/account") ?>
164
+ </p>
165
  <?php } ?>
 
166
  </td>
167
  </tr>
168
 
172
  <div id="tabs-speed">
173
 
174
  <p>
175
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-delivery-engine') ?>
 
 
 
 
 
 
 
 
176
  </p>
177
 
178
  <table class="form-table">
180
  <th><?php _e('Max emails per hour', 'newsletter') ?></th>
181
  <td>
182
  <?php $controls->text('scheduler_max', 5); ?>
183
+ <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-delivery-engine') ?>
 
 
 
 
184
  </td>
185
  </tr>
186
  </table>
190
  <div id="tabs-advanced">
191
 
192
  <p>
193
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#advanced') ?>
194
  </p>
195
 
196
  <table class="form-table">
197
 
198
  <tr valign="top">
199
+ <th><?php _e('Enable access to blog editors?', 'newsletter') ?></th>
200
  <td>
201
  <?php $controls->yesno('editor'); ?>
202
  </td>
204
 
205
  <tr>
206
  <th>
207
+ <?php _e('Log level', 'newsletter') ?>
208
  </th>
209
  <td>
210
  <?php $controls->log_level('log_level'); ?>
212
  </tr>
213
 
214
  <tr valign="top">
215
+ <th><?php _e('Debug mode', 'newsletter') ?></th>
216
  <td>
217
  <?php $controls->yesno('debug', 40); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  </td>
219
  </tr>
220
 
 
 
 
 
 
 
 
 
 
221
  <tr valign="top">
222
+ <th><?php _e('Send email directly', 'newsletter') ?></th>
223
  <td>
224
  <?php $controls->yesno('phpmailer'); ?>
225
+ <?php $controls->help('https://www.thenewsletterplugin.com/configuration-tnin-send-email'); ?>
 
 
 
 
 
 
226
  </td>
227
  </tr>
228
  <tr valign="top">
229
+ <th><?php _e('Email encoding', 'newsletter') ?></th>
230
  <td>
231
  <?php $controls->select('content_transfer_encoding', array('' => 'Default', '8bit' => '8 bit', 'base64' => 'Base 64', 'binary' => 'Binary', 'quoted-printable' => 'Quoted printable', '7bit' => '7 bit')); ?>
232
+ <?php $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#encoding') ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  </td>
234
  </tr>
235
  </table>
237
  </div>
238
 
239
 
 
 
240
  </div> <!-- tabs -->
241
 
242
  <p>
244
  </p>
245
 
246
  </form>
 
247
  </div>
248
 
249
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
main/status.php CHANGED
@@ -64,7 +64,9 @@ if ($controls->is_action('test')) {
64
  $r = $module->mail($controls->data['test_email'], 'Newsletter test email at ' . date(DATE_ISO8601), $text);
65
 
66
  $controls->messages .= 'Email sent with Newsletter';
67
- if ($module->mail_method) {
 
 
68
  $controls->messages .= ' (with a mail delivery extension)';
69
  } else {
70
  $smtp_options = $module->get_smtp_options();
@@ -721,15 +723,27 @@ $options = $module->get_options('status');
721
  ?>
722
  <tr>
723
  <td>
724
- Send timing
725
  </td>
726
  <td>
727
-
 
 
 
 
728
  </td>
729
  <td>
 
 
 
 
730
  Average time to send an email: <?php echo sprintf("%.2f", $send_mean) ?> seconds<br>
731
- Max mean time measured: <?php echo $send_max ?> seconds<br>
732
- Min mean time measured: <?php echo $send_min ?> seconds<br>
 
 
 
 
733
  Total email in the sample: <?php echo $send_total_emails ?><br>
734
  Runs in the sample: <?php echo count($send_calls); ?><br>
735
  Runs prematurely interrupted: <?php echo sprintf("%.2f", (count($send_calls) - $send_completed) * 100.0 / count($send_calls)) ?>%<br>
@@ -782,11 +796,13 @@ $options = $module->get_options('status');
782
  <td>
783
  Your memory limit is set to <?php echo $memory ?> megabyte<br>
784
  <?php if ($memory < 64) { ?>
785
- This value is too low you should increase it adding <code>define('WP_MEMORY_LIMIT', '64M');</code> to your wp-config.php.
 
786
  <?php } else if ($memory < 128) { ?>
787
- The value should be fine, it depends on how many plugin you're running and how many resource are required by your theme.
788
- Blank pages are usually syntoms of low memory. Eventually increase it adding <code>define('WP_MEMORY_LIMIT', '128M');</code>
789
- to your wp-config.php.
 
790
  <?php } else { ?>
791
 
792
  <?php } ?>
64
  $r = $module->mail($controls->data['test_email'], 'Newsletter test email at ' . date(DATE_ISO8601), $text);
65
 
66
  $controls->messages .= 'Email sent with Newsletter';
67
+ if ($module->the_mailer) {
68
+ $controls->messages .= ' (with a mailer extension)';
69
+ } else if ($module->mail_method) {
70
  $controls->messages .= ' (with a mail delivery extension)';
71
  } else {
72
  $smtp_options = $module->get_smtp_options();
723
  ?>
724
  <tr>
725
  <td>
726
+ Send details
727
  </td>
728
  <td>
729
+ <?php if ($send_mean > 1) { ?>
730
+ <span class="tnp-ko">KO</span>
731
+ <?php } else { ?>
732
+ <span class="tnp-ok">OK</span>
733
+ <?php } ?>
734
  </td>
735
  <td>
736
+ <?php if ($send_mean > 1) { ?>
737
+ <strong>Sending an email is taking more than 1 second, rather slow.</strong>
738
+ <a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-performance" target="_blank">Read more</a>.
739
+ <?php } ?>
740
  Average time to send an email: <?php echo sprintf("%.2f", $send_mean) ?> seconds<br>
741
+ <?php if ($send_mean > 0) { ?>
742
+ Max speed: <?php echo sprintf("%.2f", 1.0/$send_mean*3600) ?> emails per hour<br>
743
+ <?php } ?>
744
+
745
+ Max mean time measured: <?php echo sprintf("%.2f", $send_max) ?> seconds<br>
746
+ Min mean time measured: <?php echo sprintf("%.2f", $send_min) ?> seconds<br>
747
  Total email in the sample: <?php echo $send_total_emails ?><br>
748
  Runs in the sample: <?php echo count($send_calls); ?><br>
749
  Runs prematurely interrupted: <?php echo sprintf("%.2f", (count($send_calls) - $send_completed) * 100.0 / count($send_calls)) ?>%<br>
796
  <td>
797
  Your memory limit is set to <?php echo $memory ?> megabyte<br>
798
  <?php if ($memory < 64) { ?>
799
+ This value is too low you should increase it adding <code>define('WP_MEMORY_LIMIT', '64M');</code> to your <code>wp-config.php</code>.
800
+ <a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-memory" target="_blank">Read more</a>.
801
  <?php } else if ($memory < 128) { ?>
802
+ The value should be fine, it depends on how many plugins you're running and how many resource are required by your theme.
803
+ Blank pages may happen with low memory problems. Eventually increase it adding <code>define('WP_MEMORY_LIMIT', '128M');</code>
804
+ to your <code>wp-config.php</code>.
805
+ <a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-memory" target="_blank">Read more</a>.
806
  <?php } else { ?>
807
 
808
  <?php } ?>
plugin.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
- Version: 5.1.1
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -14,7 +14,7 @@
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
- define('NEWSLETTER_VERSION', '5.1.1');
18
 
19
  global $wpdb, $newsletter;
20
 
@@ -40,18 +40,6 @@ define('NEWSLETTER_INCLUDES_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG . '/incl
40
 
41
  // Almost obsolete but the first two must be kept for compatibility with modules
42
  define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
43
- define('NEWSLETTER_EMAIL_URL', NEWSLETTER_URL . '/do/view.php');
44
-
45
- define('NEWSLETTER_SUBSCRIPTION_POPUP_URL', NEWSLETTER_URL . '/do/subscription-popup.php');
46
- define('NEWSLETTER_SUBSCRIBE_URL', NEWSLETTER_URL . '/do/subscribe.php');
47
- define('NEWSLETTER_SUBSCRIBE_POPUP_URL', NEWSLETTER_URL . '/do/subscribe-popup.php');
48
- define('NEWSLETTER_PROFILE_URL', NEWSLETTER_URL . '/do/profile.php');
49
- define('NEWSLETTER_SAVE_URL', NEWSLETTER_URL . '/do/save.php');
50
- define('NEWSLETTER_CONFIRM_URL', NEWSLETTER_URL . '/do/confirm.php');
51
- define('NEWSLETTER_CHANGE_URL', NEWSLETTER_URL . '/do/change.php');
52
- define('NEWSLETTER_UNLOCK_URL', NEWSLETTER_URL . '/do/unlock.php');
53
- define('NEWSLETTER_UNSUBSCRIBE_URL', NEWSLETTER_URL . '/do/unsubscribe.php');
54
- define('NEWSLETTER_UNSUBSCRIPTION_URL', NEWSLETTER_URL . '/do/unsubscription.php');
55
 
56
  if (!defined('NEWSLETTER_LIST_MAX'))
57
  define('NEWSLETTER_LIST_MAX', 20);
@@ -102,7 +90,6 @@ class Newsletter extends NewsletterModule {
102
  var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
103
  var $theme_posts; // WP_Query object
104
  // Secret key to create a unique log file name (and may be other)
105
- var $lock_found = false;
106
  var $action = '';
107
  static $instance;
108
 
@@ -181,16 +168,11 @@ class Newsletter extends NewsletterModule {
181
  return;
182
  }
183
 
184
- // TODO: Meditation on how to use those ones...
185
  register_activation_hook(__FILE__, array($this, 'hook_activate'));
186
  register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
187
 
188
  add_action('admin_init', array($this, 'hook_admin_init'));
189
 
190
- add_action('wp_head', array($this, 'hook_wp_head'));
191
-
192
- add_filter('the_content', array($this, 'hook_the_content'), 99);
193
-
194
  if (is_admin()) {
195
  add_action('admin_head', array($this, 'hook_admin_head'));
196
 
@@ -411,7 +393,7 @@ class Newsletter extends NewsletterModule {
411
  if ($this->is_admin_page()) {
412
  wp_enqueue_script('jquery-ui-tabs');
413
  wp_enqueue_media();
414
- wp_enqueue_style('tnp-admin', plugins_url('newsletter') . '/admin.css', array(), time());
415
  wp_enqueue_script('tnp-admin', plugins_url('newsletter') . '/admin.js', array(), time());
416
 
417
  wp_enqueue_style('tnp-select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css');
@@ -483,14 +465,6 @@ class Newsletter extends NewsletterModule {
483
  echo '</style>';
484
  }
485
 
486
- function hook_wp_head() {
487
- if (!empty($this->options['css'])) {
488
- echo "<style type='text/css'>\n";
489
- echo $this->options['css'];
490
- echo "</style>";
491
- }
492
- }
493
-
494
  function relink($text, $email_id, $user_id, $email_token = '') {
495
  return NewsletterStatistics::instance()->relink($text, $email_id, $user_id, $email_token);
496
  }
@@ -668,23 +642,6 @@ class Newsletter extends NewsletterModule {
668
  return $result;
669
  }
670
 
671
- /**
672
- * Probably obsolete.
673
- */
674
- function execute($text, $user = null) {
675
- global $wpdb;
676
- ob_start();
677
- $r = eval('?' . '>' . $text);
678
- if ($r === false) {
679
- $this->error = 'Error while executing a PHP expression in a message body. See log file.';
680
- $this->log('Error on execution of ' . $text, 1);
681
- ob_end_clean();
682
- return false;
683
- }
684
-
685
- return ob_get_clean();
686
- }
687
-
688
  /**
689
  * This function checks is, during processing, we are getting to near to system limits and should stop any further
690
  * work (when returns true).
@@ -695,35 +652,29 @@ class Newsletter extends NewsletterModule {
695
  if (!$this->limits_set) {
696
  $this->logger->debug('limits_exceeded> Setting the limits for the first time');
697
 
698
- $max_time = NEWSLETTER_CRON_INTERVAL;
699
-
700
- // Actually it should be set on startup, anyway the scripts use as time base the startup time
701
- if (!empty($this->options['php_time_limit'])) {
702
- @set_time_limit((int) $this->options['php_time_limit']);
703
- } else if (defined('NEWSLETTER_MAX_EXECUTION_TIME')) {
704
- @set_time_limit(NEWSLETTER_MAX_EXECUTION_TIME);
705
- } else {
706
- @set_time_limit(NEWSLETTER_CRON_INTERVAL);
707
- }
708
 
709
  $max_time = (int) (@ini_get('max_execution_time') * 0.95);
710
- if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL)
711
  $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
 
712
 
713
  $this->time_limit = $this->time_start + $max_time;
714
 
715
  $this->logger->info('limits_exceeded> Max time set to ' . $max_time);
716
 
717
- $max = $this->options['scheduler_max'];
718
- if (!is_numeric($max))
719
  $max = 100;
 
720
  $this->email_limit = max(floor($max / 12), 1);
721
  $this->logger->debug('limits_exceeded> Max number of emails can send: ' . $this->email_limit);
722
 
723
  $wpdb->query("set session wait_timeout=300");
724
  // From default-constants.php
725
- if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 ))
726
  @ini_set('memory_limit', '256M');
 
727
 
728
  $this->limits_set = true;
729
  }
@@ -1027,10 +978,7 @@ class Newsletter extends NewsletterModule {
1027
 
1028
  if (isset($_REQUEST['nk'])) {
1029
  list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
1030
- } else if (isset($_REQUEST['ni'])) {
1031
- $id = (int) $_REQUEST['ni'];
1032
- $token = $_REQUEST['nt'];
1033
- } else if (isset($_COOKIE['newsletter'])) {
1034
  list ($id, $token) = @explode('-', $_COOKIE['newsletter'], 2);
1035
  }
1036
 
@@ -1039,315 +987,19 @@ class Newsletter extends NewsletterModule {
1039
  }
1040
 
1041
  $wp_user_id = get_current_user_id();
1042
- if (empty($wp_user_id))
1043
  return null;
 
1044
 
1045
  $user = $this->get_user_by_wp_user_id($wp_user_id);
1046
  return $user;
1047
  }
1048
 
1049
- function replace_date($text) {
1050
- $text = str_replace('{date}', date_i18n(get_option('date_format')), $text);
1051
-
1052
- // Date processing
1053
- $x = 0;
1054
- while (($x = strpos($text, '{date_', $x)) !== false) {
1055
- $y = strpos($text, '}', $x);
1056
- if ($y === false)
1057
- continue;
1058
- $f = substr($text, $x + 6, $y - $x - 6);
1059
- $text = substr($text, 0, $x) . date($f) . substr($text, $y + 1);
1060
- }
1061
- return $text;
1062
- }
1063
-
1064
- /**
1065
- * Replace any kind of newsletter placeholder in a text.
1066
- */
1067
- function replace($text, $user = null, $email_id = null, $referrer = null) {
1068
- global $wpdb;
1069
-
1070
- //$this->logger->debug('Replace start');
1071
- if (is_array($user)) {
1072
- $user = $this->get_user($user['id']);
1073
- }
1074
-
1075
- $email = null;
1076
- if (is_object($email_id)) {
1077
- $email = $email_id;
1078
- $email_id = $email->id;
1079
- } else if (is_numeric($email_id)) {
1080
- $email = $this->get_email($email_id);
1081
- }
1082
-
1083
- $text = apply_filters('newsletter_replace', $text, $user, $email);
1084
-
1085
- $text = $this->replace_url($text, 'BLOG_URL', home_url('/'));
1086
- $text = $this->replace_url($text, 'HOME_URL', home_url('/'));
1087
-
1088
- $text = str_replace('{blog_title}', get_option('blogname'), $text);
1089
- $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
1090
-
1091
- $text = $this->replace_date($text);
1092
-
1093
- if ($user != null) {
1094
- $options_profile = get_option('newsletter_profile');
1095
-
1096
- $text = str_replace('{email}', $user->email, $text);
1097
- if (empty($user->name)) {
1098
- $text = str_replace(' {name}', '', $text);
1099
- $text = str_replace('{name}', '', $text);
1100
- } else {
1101
- $text = str_replace('{name}', $user->name, $text);
1102
- }
1103
-
1104
- switch ($user->sex) {
1105
- case 'm': $text = str_replace('{title}', $options_profile['title_male'], $text);
1106
- break;
1107
- case 'f': $text = str_replace('{title}', $options_profile['title_female'], $text);
1108
- break;
1109
- case 'n': $text = str_replace('{title}', $options_profile['title_none'], $text);
1110
- break;
1111
- default:
1112
- $text = str_replace('{title}', '', $text);
1113
- }
1114
-
1115
-
1116
- $text = str_replace('{surname}', $user->surname, $text);
1117
- $text = str_replace('{last_name}', $user->surname, $text);
1118
-
1119
- $full_name = trim($user->name . ' ' . $user->surname);
1120
- if (empty($full_name)) {
1121
- $text = str_replace(' {full_name}', '', $text);
1122
- $text = str_replace('{full_name}', '', $text);
1123
- } else {
1124
- $text = str_replace('{full_name}', $full_name, $text);
1125
- }
1126
-
1127
- $text = str_replace('{token}', $user->token, $text);
1128
- $text = str_replace('%7Btoken%7D', $user->token, $text);
1129
- $text = str_replace('{id}', $user->id, $text);
1130
- $text = str_replace('%7Bid%7D', $user->id, $text);
1131
- $text = str_replace('{ip}', $user->ip, $text);
1132
- $text = str_replace('{key}', $user->id . '-' . $user->token, $text);
1133
- $text = str_replace('%7Bkey%7D', $user->id . '-' . $user->token, $text);
1134
-
1135
- if (strpos($text, '{profile_form}') !== false) {
1136
- $text = str_replace('{profile_form}', NewsletterSubscription::instance()->get_profile_form_html5($user), $text);
1137
- }
1138
-
1139
- for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1140
- $p = 'profile_' . $i;
1141
- $text = str_replace('{profile_' . $i . '}', $user->$p, $text);
1142
- }
1143
-
1144
- // $profile = $wpdb->get_results("select name,value from " . $wpdb->prefix . "newsletter_profiles where newsletter_id=" . $user->id);
1145
- // foreach ($profile as $field) {
1146
- // $text = str_ireplace('{np_' . $field->name . '}', htmlspecialchars($field->value), $text);
1147
- // }
1148
- //
1149
- // $text = preg_replace('/\\{np_.+\}/i', '', $text);
1150
-
1151
- $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
1152
- $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
1153
- $nk = $user->id . '-' . $user->token;
1154
-
1155
- $options_subscription = NewsletterSubscription::instance()->options;
1156
-
1157
- if ($email) {
1158
- $text = str_replace('{email_id}', $email->id, $text);
1159
- $text = str_replace('{email_subject}', $email->subject, $text);
1160
- }
1161
-
1162
- $home_url = home_url('/');
1163
- //$text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', self::add_qs(plugins_url('do.php', __FILE__), 'a=c' . $id_token));
1164
- $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', $home_url . '?na=c&nk=' . $nk);
1165
- $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', $home_url . '?na=uc&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1166
- //$text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', NEWSLETTER_URL . '/do/unsubscribe.php?nk=' . $nk);
1167
- $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', $home_url . '?na=u&nk=' . $nk . ($email ? '&nek=' . $email->id : ''));
1168
- $text = $this->replace_url($text, 'CHANGE_URL', plugins_url('newsletter/do/change.php'));
1169
-
1170
- // Obsolete.
1171
- $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
1172
- $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
1173
- $text = $this->replace_url($text, 'FEED_SUBSCRIPTION_URL', self::add_qs($base, 'nm=es' . $id_token));
1174
- $text = $this->replace_url($text, 'FEED_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=eu' . $id_token));
1175
-
1176
-
1177
- if (empty($options_profile['profile_url']))
1178
- $text = $this->replace_url($text, 'PROFILE_URL', $home_url . '?na=p&nk=' . $nk);
1179
- else
1180
- $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
1181
-
1182
- //$text = $this->replace_url($text, 'UNLOCK_URL', self::add_qs($this->options_main['lock_url'], 'nm=m' . $id_token));
1183
- $text = $this->replace_url($text, 'UNLOCK_URL', $home_url . '?na=ul&nk=' . $nk);
1184
- if (!empty($email_id)) {
1185
- $text = $this->replace_url($text, 'EMAIL_URL', $home_url . '?na=v&id=' . $email_id . '&amp;nk=' . $nk);
1186
- }
1187
-
1188
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1189
- $text = $this->replace_url($text, 'LIST_' . $i . '_SUBSCRIPTION_URL', self::add_qs($base, 'nm=ls&amp;nl=' . $i . $id_token));
1190
- $text = $this->replace_url($text, 'LIST_' . $i . '_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=lu&amp;nl=' . $i . $id_token));
1191
- }
1192
-
1193
- // Profile fields change links
1194
- $text = $this->replace_url($text, 'SET_SEX_MALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=m');
1195
- $text = $this->replace_url($text, 'SET_SEX_FEMALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=f');
1196
- $text = $this->replace_url($text, 'SET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=feed');
1197
- $text = $this->replace_url($text, 'UNSET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=feed');
1198
- for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1199
- $text = $this->replace_url($text, 'SET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=preference_' . $i);
1200
- $text = $this->replace_url($text, 'UNSET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=preference_' . $i);
1201
- }
1202
- }
1203
-
1204
- if (strpos($text, '{subscription_form}') !== false) {
1205
- $text = str_replace('{subscription_form}', NewsletterSubscription::instance()->get_subscription_form($referrer), $text);
1206
- } else {
1207
- for ($i = 1; $i <= 10; $i++) {
1208
- if (strpos($text, "{subscription_form_$i}") !== false) {
1209
- $text = str_replace("{subscription_form_$i}", NewsletterSubscription::instance()->get_form($i), $text);
1210
- break;
1211
- }
1212
- }
1213
- }
1214
-
1215
- //$this->logger->debug('Replace end');
1216
- return $text;
1217
- }
1218
-
1219
- function replace_url($text, $tag, $url) {
1220
- $home = trailingslashit(home_url());
1221
- $tag_lower = strtolower($tag);
1222
- $text = str_replace($home . '{' . $tag_lower . '}', $url, $text);
1223
- $text = str_replace($home . '%7B' . $tag_lower . '%7D', $url, $text);
1224
- $text = str_replace('{' . $tag_lower . '}', $url, $text);
1225
- $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
1226
-
1227
- $text = str_replace('%7B' . $tag_lower . '_encoded%7D', urlencode($url), $text);
1228
- $text = str_replace('{' . $tag_lower . '_encoded}', urlencode($url), $text);
1229
-
1230
- // for compatibility
1231
- $text = str_replace($home . $tag, $url, $text);
1232
-
1233
- return $text;
1234
- }
1235
-
1236
  function hook_shutdown() {
1237
  if ($this->mailer != null)
1238
  $this->mailer->SmtpClose();
1239
  }
1240
 
1241
- function hook_the_content($content) {
1242
- global $post, $cache_stop;
1243
-
1244
- if ($this->lock_found || !is_singular() || is_user_logged_in()) {
1245
- return $content;
1246
- }
1247
-
1248
- if (!empty($this->options['lock_ids'])) {
1249
- $ids = explode(',', $this->options['lock_ids']);
1250
- }
1251
-
1252
- if (!empty($ids) && (has_tag($ids) || in_category($ids) || in_array($post->post_name, $ids))) {
1253
- $cache_stop = true;
1254
- $user = $this->check_user();
1255
- if ($user == null || $user->status != 'C') {
1256
- $buffer = $this->replace($this->options['lock_message']);
1257
- return '<div class="newsletter-lock">' . do_shortcode($buffer) . '</div>';
1258
- }
1259
- }
1260
-
1261
- return $content;
1262
- }
1263
-
1264
- /**
1265
- * Exceutes a query and log it.
1266
- */
1267
- function query($query) {
1268
- global $wpdb;
1269
-
1270
- $this->log($query, 3);
1271
- return $wpdb->query($query);
1272
- }
1273
-
1274
- function get_user_from_request($required = false) {
1275
- if (isset($_REQUEST['nk'])) {
1276
- list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
1277
- } else if (isset($_REQUEST['ni'])) {
1278
- $id = (int) $_REQUEST['ni'];
1279
- $token = $_REQUEST['nt'];
1280
- }
1281
- $user = $this->get_user($id);
1282
-
1283
- if ($user == null || $token != $user->token) {
1284
- if ($required)
1285
- die('No subscriber found.');
1286
- else
1287
- return null;
1288
- }
1289
- return $user;
1290
- }
1291
-
1292
- /** Save an email and provide serialization, if needed, of $email['options']. */
1293
- function save_email($email, $return_format = OBJECT) {
1294
- if (is_object($email)) {
1295
- $email = (array) $email;
1296
- }
1297
-
1298
- if (isset($email['subject'])) {
1299
- if (mb_strlen($email['subject'], 'UTF-8') > 250) {
1300
- $email['subject'] = mb_substr($email['subject'], 0, 250, 'UTF-8');
1301
- }
1302
- }
1303
- if (isset($email['options']) && is_array($email['options']))
1304
- $email['options'] = serialize($email['options']);
1305
- return $this->store->save(NEWSLETTER_EMAILS_TABLE, $email, $return_format);
1306
- }
1307
-
1308
- function delete_email($id) {
1309
- return $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
1310
- }
1311
-
1312
- function get_email_field($id, $field_name) {
1313
- return $this->store->get_field(NEWSLETTER_EMAILS_TABLE, $id, $field_name);
1314
- }
1315
-
1316
- /**
1317
- * Returns a list of users marked as "test user".
1318
- * @return array
1319
- */
1320
- function get_test_users() {
1321
- return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
1322
- }
1323
-
1324
- function delete_user($id) {
1325
- global $wpdb;
1326
- $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
1327
- if ($r !== false) {
1328
- $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
1329
- }
1330
- }
1331
-
1332
- function set_user_status($id_or_email, $status) {
1333
- global $wpdb;
1334
-
1335
- $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
1336
-
1337
- $id_or_email = strtolower(trim($id_or_email));
1338
- if (is_numeric($id_or_email)) {
1339
- $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
1340
- } else {
1341
- $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
1342
- }
1343
-
1344
- if ($wpdb->last_error) {
1345
- $this->logger->error($wpdb->last_error);
1346
- return false;
1347
- }
1348
- return $r;
1349
- }
1350
-
1351
  /**
1352
  * Called weekly if at least one extension is active.
1353
  */
4
  Plugin Name: Newsletter
5
  Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
+ Version: 5.1.2
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
14
  */
15
 
16
  // Used as dummy parameter on css and js links
17
+ define('NEWSLETTER_VERSION', '5.1.2');
18
 
19
  global $wpdb, $newsletter;
20
 
40
 
41
  // Almost obsolete but the first two must be kept for compatibility with modules
42
  define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  if (!defined('NEWSLETTER_LIST_MAX'))
45
  define('NEWSLETTER_LIST_MAX', 20);
90
  var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
91
  var $theme_posts; // WP_Query object
92
  // Secret key to create a unique log file name (and may be other)
 
93
  var $action = '';
94
  static $instance;
95
 
168
  return;
169
  }
170
 
 
171
  register_activation_hook(__FILE__, array($this, 'hook_activate'));
172
  register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
173
 
174
  add_action('admin_init', array($this, 'hook_admin_init'));
175
 
 
 
 
 
176
  if (is_admin()) {
177
  add_action('admin_head', array($this, 'hook_admin_head'));
178
 
393
  if ($this->is_admin_page()) {
394
  wp_enqueue_script('jquery-ui-tabs');
395
  wp_enqueue_media();
396
+ wp_enqueue_style('tnp-admin', plugins_url('newsletter') . '/admin.css', array(), filemtime(NEWSLETTER_DIR . '/admin.css'));
397
  wp_enqueue_script('tnp-admin', plugins_url('newsletter') . '/admin.js', array(), time());
398
 
399
  wp_enqueue_style('tnp-select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css');
465
  echo '</style>';
466
  }
467
 
 
 
 
 
 
 
 
 
468
  function relink($text, $email_id, $user_id, $email_token = '') {
469
  return NewsletterStatistics::instance()->relink($text, $email_id, $user_id, $email_token);
470
  }
642
  return $result;
643
  }
644
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  /**
646
  * This function checks is, during processing, we are getting to near to system limits and should stop any further
647
  * work (when returns true).
652
  if (!$this->limits_set) {
653
  $this->logger->debug('limits_exceeded> Setting the limits for the first time');
654
 
655
+ @set_time_limit(NEWSLETTER_CRON_INTERVAL+30);
 
 
 
 
 
 
 
 
 
656
 
657
  $max_time = (int) (@ini_get('max_execution_time') * 0.95);
658
+ if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL) {
659
  $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
660
+ }
661
 
662
  $this->time_limit = $this->time_start + $max_time;
663
 
664
  $this->logger->info('limits_exceeded> Max time set to ' . $max_time);
665
 
666
+ $max = (int)$this->options['scheduler_max'];
667
+ if (!$max) {
668
  $max = 100;
669
+ }
670
  $this->email_limit = max(floor($max / 12), 1);
671
  $this->logger->debug('limits_exceeded> Max number of emails can send: ' . $this->email_limit);
672
 
673
  $wpdb->query("set session wait_timeout=300");
674
  // From default-constants.php
675
+ if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 )) {
676
  @ini_set('memory_limit', '256M');
677
+ }
678
 
679
  $this->limits_set = true;
680
  }
978
 
979
  if (isset($_REQUEST['nk'])) {
980
  list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
981
+ } if (isset($_COOKIE['newsletter'])) {
 
 
 
982
  list ($id, $token) = @explode('-', $_COOKIE['newsletter'], 2);
983
  }
984
 
987
  }
988
 
989
  $wp_user_id = get_current_user_id();
990
+ if (empty($wp_user_id)) {
991
  return null;
992
+ }
993
 
994
  $user = $this->get_user_by_wp_user_id($wp_user_id);
995
  return $user;
996
  }
997
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
998
  function hook_shutdown() {
999
  if ($this->mailer != null)
1000
  $this->mailer->SmtpClose();
1001
  }
1002
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1003
  /**
1004
  * Called weekly if at least one extension is active.
1005
  */
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Newsletter ===
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
- Tested up to: 4.8.2
5
- Stable tag: 5.1.1
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
@@ -85,6 +85,17 @@ Thank you, The Newsletter Team
85
 
86
  == Changelog ==
87
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  == 5.1.1 ==
90
 
1
  === Newsletter ===
2
  Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
3
  Requires at least: 3.4.0
4
+ Tested up to: 4.9
5
+ Stable tag: 5.1.2
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
85
 
86
  == Changelog ==
87
 
88
+ == NEXT ==
89
+
90
+ * Improved the speed report on status panel
91
+ * Removed the obsolete diagnostic panel
92
+ * Removed obsolete code
93
+ * Removed the locked content menu entry (please install the free content lock extension)
94
+ * Fixed validation call on widget minimal
95
+ * Added more translatable strings
96
+ * Fixed the editor CSS when a theme has its own
97
+ * Confirmation is now activation
98
+ * CSS clean up
99
 
100
  == 5.1.1 ==
101
 
statistics/statistics.php CHANGED
@@ -26,7 +26,7 @@ class NewsletterStatistics extends NewsletterModule {
26
  add_action('admin_enqueue_scripts', array($this, 'hook_admin_enqueue_scripts'));
27
  }
28
  }
29
-
30
  function hook_admin_enqueue_scripts() {
31
  if (isset($_GET['page']) && (strpos($_GET['page'], 'newsletter_statistics') === 0 || strpos($_GET['page'], 'newsletter_reports') === 0)) {
32
  wp_enqueue_style('newsletter-admin-statistics', plugins_url('newsletter') . '/statistics/css/tnp-statistics.css', array('tnp-admin'), time());
@@ -165,7 +165,7 @@ class NewsletterStatistics extends NewsletterModule {
165
  global $wpdb, $charset_collate;
166
 
167
  parent::upgrade();
168
-
169
  $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_stats` (
170
  `id` int(11) NOT NULL AUTO_INCREMENT,
171
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -181,17 +181,13 @@ class NewsletterStatistics extends NewsletterModule {
181
  KEY `email_id` (`email_id`),
182
  KEY `user_id` (`user_id`)
183
  ) $charset_collate;";
184
-
185
  dbDelta($sql);
186
 
187
  if (empty($this->options['key'])) {
188
  $this->options['key'] = md5($_SERVER['REMOTE_ADDR'] . rand(100000, 999999) . time());
189
  $this->save_options($this->options);
190
  }
191
-
192
- $this->upgrade_query("ALTER TABLE `{$wpdb->prefix}newsletter_emails` ADD COLUMN `open_count` int UNSIGNED NOT NULL DEFAULT 0");
193
- $this->upgrade_query("ALTER TABLE `{$wpdb->prefix}newsletter_emails` ADD COLUMN `click_count` int UNSIGNED NOT NULL DEFAULT 0");
194
- $this->upgrade_query("alter table {$wpdb->prefix}newsletter_emails change column read_count open_count int not null default 0");
195
  }
196
 
197
  function admin_menu() {
@@ -273,11 +269,11 @@ class NewsletterStatistics extends NewsletterModule {
273
  $wpdb->query($wpdb->prepare("update " . NEWSLETTER_EMAILS_TABLE . " set send_on=unix_timestamp(created) where id=%d limit 1", $email->id));
274
  $email = $this->get_email($email->id);
275
  }
276
-
277
  if ($email->status == 'sending') {
278
  return;
279
  }
280
-
281
  if ($email->type == 'followup') {
282
  return;
283
  }
@@ -304,28 +300,27 @@ class NewsletterStatistics extends NewsletterModule {
304
  $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter_sent s1 join " . $wpdb->prefix . "newsletter_stats s2 on s1.user_id=s2.user_id and s1.email_id=s2.email_id and s1.email_id=%d set s1.open=1, s1.ip=s2.ip", $email->id));
305
  $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter_sent s1 join " . $wpdb->prefix . "newsletter_stats s2 on s1.user_id=s2.user_id and s1.email_id=s2.email_id and s2.url<>'' and s1.email_id=%d set s1.open=2, s1.ip=s2.ip", $email->id));
306
  }
307
-
308
  function get_total_count($email_id) {
309
  global $wpdb;
310
- return (int)$wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where email_id=%d", $this->to_int_id($email_id)));
311
  }
312
-
313
  function get_open_count($email_id) {
314
  global $wpdb;
315
 
316
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where open>0 and email_id=%d", $this->to_int_id($email_id)));
317
-
318
  }
319
 
320
  function get_click_count($email_id) {
321
  global $wpdb;
322
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where open>1 and email_id=%d", $this->to_int_id($email_id)));
323
  }
324
-
325
  function get_error_count($email_id) {
326
  global $wpdb;
327
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where status>0 and email_id=%d", $this->to_int_id($email_id)));
328
- }
329
 
330
  }
331
 
26
  add_action('admin_enqueue_scripts', array($this, 'hook_admin_enqueue_scripts'));
27
  }
28
  }
29
+
30
  function hook_admin_enqueue_scripts() {
31
  if (isset($_GET['page']) && (strpos($_GET['page'], 'newsletter_statistics') === 0 || strpos($_GET['page'], 'newsletter_reports') === 0)) {
32
  wp_enqueue_style('newsletter-admin-statistics', plugins_url('newsletter') . '/statistics/css/tnp-statistics.css', array('tnp-admin'), time());
165
  global $wpdb, $charset_collate;
166
 
167
  parent::upgrade();
168
+
169
  $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_stats` (
170
  `id` int(11) NOT NULL AUTO_INCREMENT,
171
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
181
  KEY `email_id` (`email_id`),
182
  KEY `user_id` (`user_id`)
183
  ) $charset_collate;";
184
+
185
  dbDelta($sql);
186
 
187
  if (empty($this->options['key'])) {
188
  $this->options['key'] = md5($_SERVER['REMOTE_ADDR'] . rand(100000, 999999) . time());
189
  $this->save_options($this->options);
190
  }
 
 
 
 
191
  }
192
 
193
  function admin_menu() {
269
  $wpdb->query($wpdb->prepare("update " . NEWSLETTER_EMAILS_TABLE . " set send_on=unix_timestamp(created) where id=%d limit 1", $email->id));
270
  $email = $this->get_email($email->id);
271
  }
272
+
273
  if ($email->status == 'sending') {
274
  return;
275
  }
276
+
277
  if ($email->type == 'followup') {
278
  return;
279
  }
300
  $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter_sent s1 join " . $wpdb->prefix . "newsletter_stats s2 on s1.user_id=s2.user_id and s1.email_id=s2.email_id and s1.email_id=%d set s1.open=1, s1.ip=s2.ip", $email->id));
301
  $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter_sent s1 join " . $wpdb->prefix . "newsletter_stats s2 on s1.user_id=s2.user_id and s1.email_id=s2.email_id and s2.url<>'' and s1.email_id=%d set s1.open=2, s1.ip=s2.ip", $email->id));
302
  }
303
+
304
  function get_total_count($email_id) {
305
  global $wpdb;
306
+ return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where email_id=%d", $this->to_int_id($email_id)));
307
  }
308
+
309
  function get_open_count($email_id) {
310
  global $wpdb;
311
 
312
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where open>0 and email_id=%d", $this->to_int_id($email_id)));
 
313
  }
314
 
315
  function get_click_count($email_id) {
316
  global $wpdb;
317
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where open>1 and email_id=%d", $this->to_int_id($email_id)));
318
  }
319
+
320
  function get_error_count($email_id) {
321
  global $wpdb;
322
  return (int) $wpdb->get_var($wpdb->prepare("select count(*) from " . NEWSLETTER_SENT_TABLE . " where status>0 and email_id=%d", $this->to_int_id($email_id)));
323
+ }
324
 
325
  }
326
 
statistics/view-urls.php CHANGED
@@ -20,7 +20,7 @@ $email = $module->get_email($email_id);
20
 
21
  <p><a href="admin.php?page=newsletter_statistics_view&id=<?php echo $email->id ?>" class="button-primary">Back to the dashboard</a></p>
22
 
23
- <p>Clicked links detail is available with <a href="https://www.thenewsletterplugin.com/plugins/newsletter/reports-module" target="_blank">Report Extension</a>.</p>
24
 
25
  </div>
26
 
20
 
21
  <p><a href="admin.php?page=newsletter_statistics_view&id=<?php echo $email->id ?>" class="button-primary">Back to the dashboard</a></p>
22
 
23
+ <p>Clicked link details are available with <a href="https://www.thenewsletterplugin.com/plugins/newsletter/reports-module" target="_blank">Report Extension</a>.</p>
24
 
25
  </div>
26
 
statistics/view.php CHANGED
@@ -8,16 +8,15 @@ $controls = new NewsletterControls();
8
 
9
  wp_enqueue_script('tnp-chart');
10
 
11
- $email_id = (int) $_GET['id'];
12
- $email = $module->get_email($email_id);
13
 
14
- $module->maybe_fix_sent_stats($email);
15
  $module->update_stats($email);
16
 
17
 
18
- $total_count = $module->get_total_count($email_id);
19
- $open_count = $module->get_open_count($email_id);
20
- $click_count = $module->get_click_count($email_id);
21
 
22
  ?>
23
 
@@ -25,12 +24,8 @@ $click_count = $module->get_click_count($email_id);
25
  <?php include NEWSLETTER_DIR . '/tnp-header.php' ?>
26
  <div id="tnp-heading">
27
  <h2><?php _e('Statistics of', 'newsletter') ?> "<?php echo htmlspecialchars($email->subject); ?>"</h2>
28
-
29
- <?php $controls->show(); ?>
30
-
31
  </div>
32
 
33
-
34
  <div id="tnp-body" style="min-width: 500px">
35
 
36
  <?php if ($email->status == 'new') { ?>
8
 
9
  wp_enqueue_script('tnp-chart');
10
 
11
+ $email = $module->get_email($_GET['id']);
 
12
 
13
+ //$module->maybe_fix_sent_stats($email);
14
  $module->update_stats($email);
15
 
16
 
17
+ $total_count = $module->get_total_count($email->id);
18
+ $open_count = $module->get_open_count($email->id);
19
+ $click_count = $module->get_click_count($email->id);
20
 
21
  ?>
22
 
24
  <?php include NEWSLETTER_DIR . '/tnp-header.php' ?>
25
  <div id="tnp-heading">
26
  <h2><?php _e('Statistics of', 'newsletter') ?> "<?php echo htmlspecialchars($email->subject); ?>"</h2>
 
 
 
27
  </div>
28
 
 
29
  <div id="tnp-body" style="min-width: 500px">
30
 
31
  <?php if ($email->status == 'new') { ?>
subscription/languages/en_US.php CHANGED
@@ -14,6 +14,7 @@ $options = array();
14
 
15
  $options['noconfirmation'] = 0;
16
  $options['antiflood'] = 10;
 
17
 
18
  // Profile page
19
  $options['profile_text'] = __("{profile_form}
14
 
15
  $options['noconfirmation'] = 0;
16
  $options['antiflood'] = 10;
17
+ $options['notify_email'] = get_option('admin_email');
18
 
19
  // Profile page
20
  $options['profile_text'] = __("{profile_form}
subscription/options.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
@@ -53,7 +54,7 @@ if ($controls->is_action()) {
53
 
54
  $controls->data['confirmed_url'] = trim($controls->data['confirmed_url']);
55
  $controls->data['confirmation_url'] = trim($controls->data['confirmation_url']);
56
-
57
  if (!empty($controls->data['page'])) {
58
  $controls->data['url'] = ''; // do not unset
59
  }
@@ -132,7 +133,7 @@ if (empty($controls->data['page'])) {
132
  $controls->messages .= '<p>You should set a dedicated page for Newsletter which used to interact with your subscribers.</p>';
133
  } else {
134
  $post = get_post($controls->data['page']);
135
-
136
  if (!$post || $post->post_status != 'publish') {
137
  $controls->errors .= '<p>The dedicated page selected below does not exist anymore or has been unpublished. Please, select a different one.</p>';
138
  } else {
@@ -141,7 +142,6 @@ if (empty($controls->data['page'])) {
141
  }
142
  }
143
  }
144
-
145
  ?>
146
 
147
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.css" type="text/css">
@@ -172,15 +172,7 @@ if (empty($controls->data['page'])) {
172
  <div id="tnp-heading">
173
 
174
  <h2><?php _e('Subscription, Profile Page Configuration', 'newsletter') ?></h2>
175
-
176
- <p>
177
- In this panel you can configure the subscription, set up every message, the single or double opt in and
178
- even a customized subscription form.
179
- </p>
180
- <p>
181
- Page layout where messages are shown is managed by subscription/page.php file which contains instruction on how to
182
- customize it OR use a WordPress page for messages as described on subscription configuration.
183
- </p>
184
 
185
  </div>
186
 
@@ -190,60 +182,54 @@ if (empty($controls->data['page'])) {
190
  <?php $controls->init(); ?>
191
  <div id="tabs">
192
  <ul>
193
- <li><a href="#tabs-general">General</a></li>
194
- <li><a href="#tabs-2">Subscription</a></li>
195
- <li><a href="#tabs-3">Confirmation</a></li>
196
- <li><a href="#tabs-4">Welcome</a></li>
197
- <li><a href="#tabs-9">Profile</a></li>
198
- <li><a href="#tabs-7">Docs</a></li>
199
  </ul>
200
 
201
  <div id="tabs-general">
202
  <table class="form-table">
203
  <tr valign="top">
204
- <th>Opt In</th>
205
  <td>
206
- <?php $controls->select('noconfirmation', array(0 => 'Double Opt In', 1 => 'Single Opt In')); ?>
207
- <p class="description">
208
- <strong>Double Opt In</strong> means subscribers need to confirm their email address by an activation link sent them on a activation email message.<br />
209
- <strong>Single Opt In</strong> means subscribers do not need to confirm their email address.<br />
210
- </p>
211
  </td>
212
  </tr>
213
  <tr valign="top">
214
- <th>Newsletter dedicated page</th>
215
  <td>
216
- <?php $controls->page('page', 'The Newsletter standard unstyled page'); ?>
217
  <?php
218
  if (empty($controls->data['url']) && empty($controls->data['page'])) {
219
- $controls->button('create', 'Create a page for me');
220
  }
221
  ?>
222
  <?php if (!empty($controls->data['url'])) { ?>
223
- <p class="description">
224
- <strong>
225
- You're currently using the URL <code><?php echo esc_html($controls->data['url'])?></code>
226
- as dedicated page. Please select the corrisponding page above (new as version 4.6.5+).
227
- </strong>
228
- </p>
 
229
  <?php } ?>
230
  </td>
231
  </tr>
232
  <tr valign="top">
233
- <th>Notifications</th>
234
  <td>
235
  <?php $controls->yesno('notify'); ?>
236
- to: <?php $controls->text_email('notify_email'); ?> (email address, leave empty for the WordPress administration email <?php echo get_option('admin_email'); ?>)
237
- <p class="description">
238
- Notifications are sent on confirmed subscriptions and cancellations.
239
- </p>
240
  </td>
241
  </tr>
242
  <tr valign="top">
243
- <th><?php _e('Custom styles', 'newsletter')?></th>
244
  <td>
245
  <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
246
- <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
247
  <?php } ?>
248
  <?php $controls->textarea('css'); ?>
249
  </td>
@@ -256,46 +242,41 @@ if (empty($controls->data['page'])) {
256
 
257
  <table class="form-table">
258
  <tr valign="top">
259
- <th>Subscription page</th>
260
  <td>
261
  <?php $controls->wp_editor('subscription_text'); ?>
262
- <p class="description">
263
- Use <strong>{subscription_form}</strong> to insert the subscription form where you prefer in the text or
264
- <strong>{subscription_form_N}</strong> (with N from 1 to 10) to insert one of the custom forms.
265
- </p>
266
  </td>
267
  </tr>
268
  <tr valign="top">
269
- <th><?php _e('Forced lists', 'newsletter')?></th>
270
  <td>
271
  <?php $controls->preferences(); ?>
272
- <p class="description">
273
- Add to new subscribers these lists by default.
274
- </p>
275
  </td>
276
  </tr>
277
  <tr valign="top">
278
- <th>Disable antibot/antispam?</th>
279
  <td>
280
  <?php $controls->yesno('antibot_disable'); ?>
281
  <p class="description">
282
- Required for ajax form subsmissions.
283
  </p>
284
  </td>
285
  </tr>
286
  <tr valign="top">
287
- <th>Antiflood</th>
288
  <td>
289
- <?php $controls->select('antiflood', array(
290
- 0=>__('Disabled', 'newsletter'),
291
- 5=>'5 ' . __('seconds', 'newsletter'),
292
- 10=>'10 ' . __('seconds', 'newsletter'),
293
- 15=>'15 ' . __('seconds', 'newsletter'),
294
- 30=>'30 ' . __('seconds', 'newsletter'),
295
- 60=>'1 ' . __('minute', 'newsletter'),
296
- 120=>'2 ' . __('minutes', 'newsletter'),
297
- 300=>'5 ' . __('minutes', 'newsletter')
298
- )); ?>
 
 
299
  <?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
300
  </td>
301
  </tr>
@@ -308,8 +289,8 @@ if (empty($controls->data['page'])) {
308
  <tr valign="top">
309
  <th>Already subscribed page content</th>
310
  <td>
311
- <?php //$controls->wp_editor('already_confirmed_text'); ?><br>
312
- <?php //$controls->checkbox('resend_welcome_email_disabled', 'Do not resend the welcome email'); ?>
313
  <p class="description">
314
  Shown when the email is already subscribed and confirmed. The welcome email, if not disabled, will
315
  be sent. Find out more on this topic on its
@@ -319,12 +300,9 @@ if (empty($controls->data['page'])) {
319
  </tr>
320
  -->
321
  <tr valign="top">
322
- <th>Error page content</th>
323
  <td>
324
  <?php $controls->wp_editor('error_text'); ?>
325
- <p class="description">
326
- Message shown when the email is bounced or other errors occurred.
327
- </p>
328
  </td>
329
  </tr>
330
  </table>
@@ -332,47 +310,33 @@ if (empty($controls->data['page'])) {
332
 
333
 
334
  <div id="tabs-3">
335
-
336
- <p>This configuration applies only when you sent the double opt-in mode.</p>
337
-
 
338
  <table class="form-table">
339
  <tr valign="top">
340
- <th>Confirmation required message</th>
341
  <td>
342
  <?php $controls->wp_editor('confirmation_text'); ?>
343
- <p class="description">
344
- This message is shown to just subscribed users which require to confirm the subscription
345
- following the instructions sent them with the following email. Invite them to check the mailbox and to
346
- give a look to the spam folder if no messages are received within 10 minutes.
347
- </p>
348
  </td>
349
  </tr>
350
 
351
  <tr valign="top">
352
- <th>Alternative custom confirmation required page</th>
353
  <td>
354
- <?php $controls->text('confirmation_url', 70); ?>
355
- <p class="description">
356
- A full page address (http://yourblog.com/confirm) to be used instead of message above.
357
- If left empty the message above is used.
358
- </p>
359
  </td>
360
  </tr>
361
 
362
 
363
  <!-- CONFIRMATION EMAIL -->
364
  <tr valign="top">
365
- <th>Confirmation email</th>
366
  <td>
367
  <?php $controls->email('confirmation', 'wordpress'); ?>
 
368
  <?php $controls->button('test-confirmation', 'Send a test'); ?>
369
- <p class="description">
370
- Message sent by email to new subscribers with instructions to confirm their subscription
371
- (for double opt-in process). Do not forget to add the <strong>{subscription_confirm_url}</strong>
372
- that users must click to activate their subscription.<br />
373
- Sometime can be useful to add a <strong>{unsubscription_url}</strong> to let users to
374
- cancel if they wrongly subscribed to your newsletter.
375
- </p>
376
  </td>
377
  </tr>
378
  </table>
@@ -380,58 +344,41 @@ if (empty($controls->data['page'])) {
380
 
381
 
382
  <div id="tabs-4">
 
 
 
383
  <table class="form-table">
384
  <tr valign="top">
385
- <th>Welcome message</th>
386
  <td>
387
  <?php $controls->wp_editor('confirmed_text'); ?>
388
- <p class="description">
389
- Showed when the user follow the confirmation URL sent to him with previous email
390
- settings or if signed up directly with no double opt-in process. You can use the <strong>{profile_form}</strong> tag to let the user to
391
- complete it's profile.
392
- </p>
393
  </td>
394
  </tr>
395
 
396
  <tr valign="top">
397
- <th>Alternative custom welcome page</th>
398
  <td>
399
- <?php $controls->text('confirmed_url', 70); ?>
400
- <p class="description">
401
- A full page address (http://yourblog.com/welcome) to be used instead of message above. If empty the message is
402
- used.
403
- </p>
404
  </td>
405
  </tr>
406
 
407
  <tr valign="top">
408
- <th>Conversion tracking code<br/><small>ADVANCED</small></th>
 
409
  <td>
410
  <?php $controls->textarea('confirmed_tracking'); ?>
411
- <p class="description">
412
- The code is injected AS-IS in welcome page and can be used to track conversion
413
- (you can use PHP if needed). It does not work with a custom welcome page.
414
- Conversion code is usually supply by tracking services,
415
- like Google AdWords, Google Analytics and so on.
416
- </p>
417
  </td>
418
  </tr>
419
 
420
  <!-- WELCOME/CONFIRMED EMAIL -->
421
  <tr valign="top">
422
  <th>
423
- Welcome email<br /><small>The right place where to put bonus content link</small>
424
  </th>
425
  <td>
426
  <?php $controls->email('confirmed', 'wordpress', true); ?>
 
427
  <?php $controls->button('test-confirmed', 'Send a test'); ?>
428
- <p class="description">
429
- Email sent to the user to confirm his subscription, the successful confirmation
430
- page, the welcome email. This is the right message where to put a <strong>{unlock_url}</strong> link to remember to the
431
- user where is the premium content (if any, main configuration panel).<br />
432
- It's a good idea to add the <strong>{unsubscription_url}</strong> too and the <strong>{profile_url}</strong>
433
- letting users to cancel or manage/complete their profile.
434
- </p>
435
  </td>
436
  </tr>
437
 
@@ -441,34 +388,24 @@ if (empty($controls->data['page'])) {
441
  <!-- PROFILE -->
442
  <div id="tabs-9">
443
 
444
- <p>
445
- The page shown when the subscriber wants to edit his profile following the link
446
- {profile_url} you added to a newsletter pr the welcome email.
447
- </p>
448
-
449
-
450
  <table class="form-table">
 
451
  <tr valign="top">
452
- <th>Customized profile page</th>
 
 
453
  <td>
454
- <?php $controls->text('profile_url', 70); ?>
455
- <p class="description">
456
- A full page address (e.g. http://yourblog.com/profile) to be used to show and edit the subscriber profile.
457
- Leave empty to use an auto generated page or the main Newsletter page with the message below.
458
- <br>
459
- The custom page must contain the [newsletter_profile] shortcode.
460
- </p>
461
  </td>
462
  </tr>
 
463
  <tr valign="top">
464
- <th>Profile page</th>
465
  <td>
466
- <?php $controls->wp_editor('profile_text'); ?>
467
- <p class="description">
468
- This is the page where subscribers can edit their data and it must contain the {profile_form} tag. <a href="'https://www.thenewsletterplugin.com/plugins/newsletter/subscription-module#profile" target="_blank">Read more</a>.
469
- </p>
470
  </td>
471
  </tr>
 
472
  <tr>
473
  <th>Other messages</th>
474
  <td>
@@ -486,48 +423,11 @@ if (empty($controls->data['page'])) {
486
  </table>
487
  </div>
488
 
489
- <div id="tabs-7">
490
-
491
- <h4>User's data</h4>
492
- <p>
493
- <strong>{name}</strong>
494
- The user name<br />
495
- <strong>{surname}</strong>
496
- The user surname<br />
497
- <strong>{email}</strong>
498
- The user email<br />
499
- <strong>{ip}</strong>
500
- The IP address from where the subscription started<br />
501
- <strong>{id}</strong>
502
- The user id<br />
503
- <strong>{token}</strong>
504
- The user secret token<br />
505
- <strong>{profile_N}</strong>
506
- The user profile field number N (from 1 to 19)<br />
507
- </p>
508
-
509
- <h4>Action URLs and forms</h4>
510
- <p>
511
- <strong>{subscription_confirm_url}</strong>
512
- URL to build a link to confirmation of subscription when double opt-in is used. To be used on confirmation email.<br />
513
- <strong>{unsubscription_url}</strong>
514
- URL to build a link to start the cancellation process. To be used on every newsletter to let the user to cancel.<br />
515
- <strong>{unsubscription_confirm_url}</strong>
516
- URL to build a link to an immediate cancellation action. Can be used on newsletters if you want an immediate cancellation or
517
- on cancellation page (displayed on {unsubscription_url}) to ask a cancellation confirmation.<br />
518
- <strong>{profile_url}</strong>
519
- URL to build a link to user's profile page (see the User Profile panel)<br />
520
- <strong>{unlock_url}</strong>
521
- Special URL to build a link that on click unlocks protected contents. See Main Configuration panel.<br />
522
- <strong>{profile_form}</strong>
523
- Insert the profile form with user's data. Usually it make sense only on welcome page.<br />
524
- </p>
525
- </div>
526
  </div>
527
 
528
  <p>
529
- <?php $controls->button_save(); ?>
530
- <?php $controls->button_confirm('reset', 'Reset all', 'Are you sure you want to reset all?'); ?>
531
  </p>
532
 
533
  </form>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
54
 
55
  $controls->data['confirmed_url'] = trim($controls->data['confirmed_url']);
56
  $controls->data['confirmation_url'] = trim($controls->data['confirmation_url']);
57
+
58
  if (!empty($controls->data['page'])) {
59
  $controls->data['url'] = ''; // do not unset
60
  }
133
  $controls->messages .= '<p>You should set a dedicated page for Newsletter which used to interact with your subscribers.</p>';
134
  } else {
135
  $post = get_post($controls->data['page']);
136
+
137
  if (!$post || $post->post_status != 'publish') {
138
  $controls->errors .= '<p>The dedicated page selected below does not exist anymore or has been unpublished. Please, select a different one.</p>';
139
  } else {
142
  }
143
  }
144
  }
 
145
  ?>
146
 
147
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.css" type="text/css">
172
  <div id="tnp-heading">
173
 
174
  <h2><?php _e('Subscription, Profile Page Configuration', 'newsletter') ?></h2>
175
+ <?php $controls->page_help('https://www.thenewsletterplugin.com/documentation/subscription') ?>
 
 
 
 
 
 
 
 
176
 
177
  </div>
178
 
182
  <?php $controls->init(); ?>
183
  <div id="tabs">
184
  <ul>
185
+ <li><a href="#tabs-general"><?php _e('General', 'newsletter') ?></a></li>
186
+ <li><a href="#tabs-2"><?php _e('Subscription', 'newsletter') ?></a></li>
187
+ <li><a href="#tabs-3"><?php _e('Activation', 'newsletter') ?></a></li>
188
+ <li><a href="#tabs-4"><?php _e('Welcome', 'newsletter') ?></a></li>
189
+ <li><a href="#tabs-9"><?php _e('Profile', 'newsletter') ?></a></li>
 
190
  </ul>
191
 
192
  <div id="tabs-general">
193
  <table class="form-table">
194
  <tr valign="top">
195
+ <th><?php _e('Opt In', 'newsletter') ?></th>
196
  <td>
197
+ <?php $controls->select('noconfirmation', array(0 => __('Double Opt In', 'newsletter'), 1 => __('Single Opt In', 'newsletter'))); ?>
198
+ <?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#opt-in') ?>
 
 
 
199
  </td>
200
  </tr>
201
  <tr valign="top">
202
+ <th><?php _e('Dedicated page', 'newsletter') ?></th>
203
  <td>
204
+ <?php $controls->page('page', __('Unstyled page', 'newsletter')); ?>
205
  <?php
206
  if (empty($controls->data['url']) && empty($controls->data['page'])) {
207
+ $controls->button('create', __('Create the page', 'newsletter'));
208
  }
209
  ?>
210
  <?php if (!empty($controls->data['url'])) { ?>
211
+ <!-- do not translate, will be removed -->
212
+ <p class="description">
213
+ <strong>
214
+ You're currently using the URL <code><?php echo esc_html($controls->data['url']) ?></code>
215
+ as dedicated page. Please select the corrisponding page above (new as version 4.6.5+).
216
+ </strong>
217
+ </p>
218
  <?php } ?>
219
  </td>
220
  </tr>
221
  <tr valign="top">
222
+ <th><?php _e('Notifications', 'newsletter') ?></th>
223
  <td>
224
  <?php $controls->yesno('notify'); ?>
225
+ <?php $controls->text_email('notify_email'); ?>
 
 
 
226
  </td>
227
  </tr>
228
  <tr valign="top">
229
+ <th><?php _e('Custom styles', 'newsletter') ?></th>
230
  <td>
231
  <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
232
+ <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
233
  <?php } ?>
234
  <?php $controls->textarea('css'); ?>
235
  </td>
242
 
243
  <table class="form-table">
244
  <tr valign="top">
245
+ <th><?php _e('Subscription page', 'newsletter') ?><br><?php echo $controls->help('https://www.thenewsletterplugin.com/documentation/newsletter-tags') ?></th>
246
  <td>
247
  <?php $controls->wp_editor('subscription_text'); ?>
 
 
 
 
248
  </td>
249
  </tr>
250
  <tr valign="top">
251
+ <th><?php _e('Forced lists', 'newsletter') ?></th>
252
  <td>
253
  <?php $controls->preferences(); ?>
 
 
 
254
  </td>
255
  </tr>
256
  <tr valign="top">
257
+ <th><?php _e('Disable antibot/antispam?', 'newsletter') ?></th>
258
  <td>
259
  <?php $controls->yesno('antibot_disable'); ?>
260
  <p class="description">
261
+ <?php _e ('Disable for ajax form submission', 'newsletter'); ?>
262
  </p>
263
  </td>
264
  </tr>
265
  <tr valign="top">
266
+ <th><?php _e('Antiflood', 'newsletter') ?></th>
267
  <td>
268
+ <?php
269
+ $controls->select('antiflood', array(
270
+ 0 => __('Disabled', 'newsletter'),
271
+ 5 => '5 ' . __('seconds', 'newsletter'),
272
+ 10 => '10 ' . __('seconds', 'newsletter'),
273
+ 15 => '15 ' . __('seconds', 'newsletter'),
274
+ 30 => '30 ' . __('seconds', 'newsletter'),
275
+ 60 => '1 ' . __('minute', 'newsletter'),
276
+ 120 => '2 ' . __('minutes', 'newsletter'),
277
+ 300 => '5 ' . __('minutes', 'newsletter')
278
+ ));
279
+ ?>
280
  <?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
281
  </td>
282
  </tr>
289
  <tr valign="top">
290
  <th>Already subscribed page content</th>
291
  <td>
292
+ <?php //$controls->wp_editor('already_confirmed_text'); ?><br>
293
+ <?php //$controls->checkbox('resend_welcome_email_disabled', 'Do not resend the welcome email'); ?>
294
  <p class="description">
295
  Shown when the email is already subscribed and confirmed. The welcome email, if not disabled, will
296
  be sent. Find out more on this topic on its
300
  </tr>
301
  -->
302
  <tr valign="top">
303
+ <th><?php _e('Error page', 'newsletter') ?></th>
304
  <td>
305
  <?php $controls->wp_editor('error_text'); ?>
 
 
 
306
  </td>
307
  </tr>
308
  </table>
310
 
311
 
312
  <div id="tabs-3">
313
+
314
+ <p><?php _e('Only for double opt-in mode.', 'newsletter') ?></p>
315
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscription#activation') ?>
316
+
317
  <table class="form-table">
318
  <tr valign="top">
319
+ <th><?php _e('Activation message', 'newsletter') ?></th>
320
  <td>
321
  <?php $controls->wp_editor('confirmation_text'); ?>
 
 
 
 
 
322
  </td>
323
  </tr>
324
 
325
  <tr valign="top">
326
+ <th><?php _e ('Alternative activation page', 'newsletter'); ?></th>
327
  <td>
328
+ <?php $controls->text('confirmation_url', 70, 'https://...'); ?>
 
 
 
 
329
  </td>
330
  </tr>
331
 
332
 
333
  <!-- CONFIRMATION EMAIL -->
334
  <tr valign="top">
335
+ <th><?php _e('Activation email', 'newsletter') ?></th>
336
  <td>
337
  <?php $controls->email('confirmation', 'wordpress'); ?>
338
+ <br>
339
  <?php $controls->button('test-confirmation', 'Send a test'); ?>
 
 
 
 
 
 
 
340
  </td>
341
  </tr>
342
  </table>
344
 
345
 
346
  <div id="tabs-4">
347
+ <p>
348
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscription#welcome') ?>
349
+ </p>
350
  <table class="form-table">
351
  <tr valign="top">
352
+ <th><?php _e('Welcome message', 'newsletter') ?></th>
353
  <td>
354
  <?php $controls->wp_editor('confirmed_text'); ?>
 
 
 
 
 
355
  </td>
356
  </tr>
357
 
358
  <tr valign="top">
359
+ <th><?php _e('Alternative welcome page URL', 'newsletter') ?></th>
360
  <td>
361
+ <?php $controls->text('confirmed_url', 70, 'https://...'); ?>
 
 
 
 
362
  </td>
363
  </tr>
364
 
365
  <tr valign="top">
366
+ <th><?php _e('Conversion tracking code', 'newsletter') ?>
367
+ <?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#conversion') ?></th>
368
  <td>
369
  <?php $controls->textarea('confirmed_tracking'); ?>
 
 
 
 
 
 
370
  </td>
371
  </tr>
372
 
373
  <!-- WELCOME/CONFIRMED EMAIL -->
374
  <tr valign="top">
375
  <th>
376
+ <?php _e('Welcome email', 'newsletter') ?>
377
  </th>
378
  <td>
379
  <?php $controls->email('confirmed', 'wordpress', true); ?>
380
+ <br>
381
  <?php $controls->button('test-confirmed', 'Send a test'); ?>
 
 
 
 
 
 
 
382
  </td>
383
  </tr>
384
 
388
  <!-- PROFILE -->
389
  <div id="tabs-9">
390
 
 
 
 
 
 
 
391
  <table class="form-table">
392
+
393
  <tr valign="top">
394
+ <th><?php _e('Profile page', 'newsletter') ?>
395
+ <br><?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#profile') ?>
396
+ </th>
397
  <td>
398
+ <?php $controls->wp_editor('profile_text'); ?>
 
 
 
 
 
 
399
  </td>
400
  </tr>
401
+
402
  <tr valign="top">
403
+ <th><?php _e('Alternative profile page URL', 'newsletter') ?></th>
404
  <td>
405
+ <?php $controls->text('profile_url', 70); ?>
 
 
 
406
  </td>
407
  </tr>
408
+
409
  <tr>
410
  <th>Other messages</th>
411
  <td>
423
  </table>
424
  </div>
425
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  </div>
427
 
428
  <p>
429
+ <?php $controls->button_save() ?>
430
+ <?php $controls->button_reset() ?>
431
  </p>
432
 
433
  </form>
subscription/page.php CHANGED
@@ -15,7 +15,7 @@
15
  if (!defined('ABSPATH')) exit;
16
 
17
  $module = NewsletterSubscription::instance();
18
- $user = $module->get_user_from_request();
19
  $message_key = $module->get_message_key_from_request();
20
  $message = $newsletter->replace($module->options[$message_key . '_text'], $user);
21
  if (isset($module->options[$message_key . '_tracking'])) {
15
  if (!defined('ABSPATH')) exit;
16
 
17
  $module = NewsletterSubscription::instance();
18
+ $user = $module->get_user_from_request(true);
19
  $message_key = $module->get_message_key_from_request();
20
  $message = $newsletter->replace($module->options[$message_key . '_text'], $user);
21
  if (isset($module->options[$message_key . '_tracking'])) {
subscription/subscription.php CHANGED
@@ -93,7 +93,7 @@ class NewsletterSubscription extends NewsletterModule {
93
  case 'subscribe':
94
  // Flood check
95
  if (!empty($this->options['antiflood'])) {
96
- $ip = $_SERVER['REMOTE_ADDR'];
97
  $email = $this->is_email($_REQUEST['ne']);
98
  $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
99
 
@@ -426,7 +426,7 @@ class NewsletterSubscription extends NewsletterModule {
426
  }
427
  }
428
 
429
- $user = $newsletter->save_user($user);
430
 
431
  // Notification to admin (only for new confirmed subscriptions)
432
  if ($user->status == 'C') {
@@ -644,64 +644,41 @@ class NewsletterSubscription extends NewsletterModule {
644
  */
645
  function unsubscribe() {
646
  $newsletter = Newsletter::instance();
647
- $user = $this->get_user_from_request();
648
-
649
- //$this->logger->debug('Unsubscription for:');
650
- //$this->logger->debug($user);
651
-
652
- setcookie('newsletter', '', time() - 3600);
653
- if ($user == null) {
654
- //$this->logger->debug('Not found');
655
- die('Subscriber not found');
656
- }
657
 
658
  if ($user->status == 'U') {
659
  return $user;
660
  }
661
 
662
- if ($user->status != 'C') {
663
- $user->status = 'E';
664
- return $user;
665
- }
666
-
667
- if ($user->status == 'C') {
668
- $newsletter->set_user_status($user->id, 'U');
669
- do_action('newsletter_unsubscribed', $user);
670
 
671
- global $wpdb;
672
- if (isset($_REQUEST['nek'])) {
673
- list($email_id, $email_token) = explode('-', $_REQUEST['nek']);
674
- $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email_id, 'unsub_time' => time()), array('id' => $user->id));
675
- }
676
-
677
- if (empty($this->options['unsubscribed_disabled'])) {
678
- $this->mail($user->email, $newsletter->replace($this->options['unsubscribed_subject'], $user), $newsletter->replace($this->options['unsubscribed_message'], $user));
679
- }
680
- $this->notify_admin($user, 'Newsletter unsubscription');
681
  }
682
 
683
- // Here the subscriber has status U
684
- return $user;
 
 
685
  }
686
 
687
  function save_profile() {
688
- $newsletter = Newsletter::instance();
689
 
690
- $user = $this->get_user_from_request();
691
- if ($user == null) {
692
- die('No subscriber found.');
693
- }
694
 
695
  $options_profile = get_option('newsletter_profile', array());
696
  $options_main = get_option('newsletter_main', array());
697
 
698
- if (!$newsletter->is_email($_REQUEST['ne'])) {
699
  $user->alert = $this->options['profile_error'];
700
  return $user;
701
  }
702
 
703
  $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
704
- $email_changed = $email != $user->email;
705
 
706
  // If the email has been changed, check if it is available
707
  if ($email_changed) {
@@ -714,8 +691,8 @@ class NewsletterSubscription extends NewsletterModule {
714
 
715
  // General data
716
  $data['email'] = $email;
717
- $data['name'] = $newsletter->normalize_name(stripslashes($_REQUEST['nn']));
718
- $data['surname'] = $newsletter->normalize_name(stripslashes($_REQUEST['ns']));
719
  if ($options_profile['sex_status'] >= 1) {
720
  $data['sex'] = $_REQUEST['nx'][0];
721
  // Wrong data injection check
@@ -751,7 +728,7 @@ class NewsletterSubscription extends NewsletterModule {
751
  // Feed by Mail service is saved here
752
  $data = apply_filters('newsletter_profile_save', $data);
753
 
754
- $user = $newsletter->save_user($data);
755
 
756
  // Email has been changed? Are we using double opt-in?
757
  $opt_in = (int) $this->options['noconfirmation'];
@@ -761,7 +738,7 @@ class NewsletterSubscription extends NewsletterModule {
761
  if (empty($this->options['confirmation_disabled'])) {
762
  $message = $this->options['confirmation_message'];
763
  $subject = $this->options['confirmation_subject'];
764
- $res = $this->mail($user->email, $newsletter->replace($subject, $user), $newsletter->replace($message, $user));
765
  $alert = $this->options['profile_email_changed'];
766
  }
767
  }
@@ -828,31 +805,6 @@ class NewsletterSubscription extends NewsletterModule {
828
  die();
829
  }
830
 
831
- /**
832
- * Loads the user using the request parameters (nk or nt and ni).
833
- *
834
- * @global Newsletter $newsletter
835
- * @return null
836
- */
837
- function get_user_from_request() {
838
- $newsletter = Newsletter::instance();
839
-
840
- if (isset($_REQUEST['nk'])) {
841
- list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
842
- } else if (isset($_REQUEST['ni'])) {
843
- $id = (int) $_REQUEST['ni'];
844
- $token = $_REQUEST['nt'];
845
- } else {
846
- return null;
847
- }
848
- $user = $newsletter->get_user($id);
849
-
850
- if ($user == null || $token != $user->token) {
851
- return null;
852
- }
853
- return $user;
854
- }
855
-
856
  function get_email_from_request() {
857
  $newsletter = Newsletter::instance();
858
 
@@ -1688,7 +1640,7 @@ class NewsletterSubscription extends NewsletterModule {
1688
  // Lists
1689
  $lists = '';
1690
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1691
- if ($options['list_' . $i . '_status'] == 0) {
1692
  continue;
1693
  }
1694
 
93
  case 'subscribe':
94
  // Flood check
95
  if (!empty($this->options['antiflood'])) {
96
+ $ip = (string)$_SERVER['REMOTE_ADDR'];
97
  $email = $this->is_email($_REQUEST['ne']);
98
  $updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
99
 
426
  }
427
  }
428
 
429
+ $user = $this->save_user($user);
430
 
431
  // Notification to admin (only for new confirmed subscriptions)
432
  if ($user->status == 'C') {
644
  */
645
  function unsubscribe() {
646
  $newsletter = Newsletter::instance();
647
+ $user = $this->get_user_from_request(true);
 
 
 
 
 
 
 
 
 
648
 
649
  if ($user->status == 'U') {
650
  return $user;
651
  }
652
 
653
+ $newsletter->set_user_status($user->id, 'U');
654
+ do_action('newsletter_unsubscribed', $user);
 
 
 
 
 
 
655
 
656
+ global $wpdb;
657
+ if (isset($_REQUEST['nek'])) {
658
+ list($email_id, $email_token) = explode('-', $_REQUEST['nek']);
659
+ $wpdb->update(NEWSLETTER_USERS_TABLE, array('unsub_email_id' => (int) $email_id, 'unsub_time' => time()), array('id' => $user->id));
 
 
 
 
 
 
660
  }
661
 
662
+ if (empty($this->options['unsubscribed_disabled'])) {
663
+ $this->mail($user->email, $newsletter->replace($this->options['unsubscribed_subject'], $user), $newsletter->replace($this->options['unsubscribed_message'], $user));
664
+ }
665
+ $this->notify_admin($user, 'Newsletter unsubscription');
666
  }
667
 
668
  function save_profile() {
 
669
 
670
+ $user = $this->get_user_from_request(true);
 
 
 
671
 
672
  $options_profile = get_option('newsletter_profile', array());
673
  $options_main = get_option('newsletter_main', array());
674
 
675
+ if (!$this->is_email($_REQUEST['ne'])) {
676
  $user->alert = $this->options['profile_error'];
677
  return $user;
678
  }
679
 
680
  $email = $this->normalize_email(stripslashes($_REQUEST['ne']));
681
+ $email_changed = ($email != $user->email);
682
 
683
  // If the email has been changed, check if it is available
684
  if ($email_changed) {
691
 
692
  // General data
693
  $data['email'] = $email;
694
+ $data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
695
+ $data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
696
  if ($options_profile['sex_status'] >= 1) {
697
  $data['sex'] = $_REQUEST['nx'][0];
698
  // Wrong data injection check
728
  // Feed by Mail service is saved here
729
  $data = apply_filters('newsletter_profile_save', $data);
730
 
731
+ $user = $this->save_user($data);
732
 
733
  // Email has been changed? Are we using double opt-in?
734
  $opt_in = (int) $this->options['noconfirmation'];
738
  if (empty($this->options['confirmation_disabled'])) {
739
  $message = $this->options['confirmation_message'];
740
  $subject = $this->options['confirmation_subject'];
741
+ $res = $this->mail($user->email, $this->replace($subject, $user), $this->replace($message, $user));
742
  $alert = $this->options['profile_email_changed'];
743
  }
744
  }
805
  die();
806
  }
807
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808
  function get_email_from_request() {
809
  $newsletter = Newsletter::instance();
810
 
1640
  // Lists
1641
  $lists = '';
1642
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
1643
+ if ($options['list_' . $i . '_status'] == 0 || $options['list_' . $i . '_status'] == 3) {
1644
  continue;
1645
  }
1646
 
tnp-header.php CHANGED
@@ -25,6 +25,13 @@ function newsletter_print_entries($group) {
25
  }
26
  }
27
  }
 
 
 
 
 
 
 
28
  ?>
29
 
30
  <div class="tnp-drowpdown" id="tnp-header">
@@ -53,20 +60,27 @@ function newsletter_print_entries($group) {
53
  <small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
54
 
55
 
56
- <li><a href="?page=newsletter_subscription_profile"><i class="fa fa-check-square-o"></i> <?php _e('Subscription Form Fields, Buttons, Labels', 'newsletter') ?>
57
- <small><?php _e('When and what data to collect', 'newsletter') ?></small></a></li>
58
- <li><a href="?page=newsletter_subscription_lists"><i class="fa fa-th-list"></i> <?php _e('Lists', 'newsletter') ?>
59
- <small><?php _e('Profile the subscribers for a better targeting', 'newsletter') ?></small></a></li>
60
- <li><a href="?page=newsletter_subscription_unsubscription"><i class="fa fa-sign-out"></i> <?php _e('Unsubscription', 'newsletter') ?>
61
- <small><?php _e('How to give the last goodbye (or avoid it!)', 'newsletter') ?></small></a></li>
62
- <?php if (!file_exists(WP_PLUGIN_DIR . '/newsletter-lock')) { ?>
63
- <li><a href="?page=newsletter_lock_index"><i class="fa fa-lock"></i> <?php _e('Locked Content', 'newsletter') ?>
64
- <small><?php _e('Make your best content available only upon subscription', 'newsletter') ?></small></a></li>
65
- <?php } ?>
66
- <li><a href="?page=newsletter_subscription_forms"><i class="fa fa-pencil"></i> <?php _e('Custom Forms', 'newsletter') ?>
67
- <small><?php _e('Hand coded form storage', 'newsletter') ?></small></a></li>
68
- <li><a href="?page=newsletter_subscription_template"><i class="fa fa-file-text-o"></i> <?php _e('Messages Template', 'newsletter') ?>
69
- <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a></li>
 
 
 
 
 
 
 
70
  <?php
71
  newsletter_print_entries('subscription');
72
  ?>
@@ -89,18 +103,31 @@ function newsletter_print_entries($group) {
89
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a></li>
90
  <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
91
  <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
92
- <li><a href="?page=newsletter_main_smtp"><i class="fa fa-envelope-o"></i> <?php _e('SMTP', 'newsletter') ?>
93
- <small><?php _e('External mail servers', 'newsletter') ?></small></a></li>
94
- <li><a href="?page=newsletter_main_diagnostic"><i class="fa fa-tasks"></i> <?php _e('Diagnostics', 'newsletter') ?>
95
- <small><?php _e('Something not working? Start here!', 'newsletter') ?></small></a></li>
 
 
 
 
 
96
  <?php
97
  newsletter_print_entries('settings');
98
  ?>
99
  </ul>
100
  </li>
101
- <li><a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?></a></li>
 
 
 
 
 
 
 
 
102
  <?php
103
- if (empty(Newsletter::instance()->options['contract_key'])) {
104
  ?>
105
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
106
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Extensions', 'newsletter') ?></a>
@@ -136,7 +163,7 @@ function newsletter_print_entries($group) {
136
  <div class="tnp-notice">
137
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=rate' ?>" class="tnp-dismiss">&times;</a>
138
 
139
- We never asked before and we're curious: <a href="http://wordpress.org/extend/plugins/newsletter/" target="_blank">would you rate this plugin</a>?
140
  (few seconds required - account on WordPress.org required, every blog owner should have one...). <strong>Really appreciated, The Newsletter Team</strong>.
141
 
142
  </div>
@@ -152,27 +179,6 @@ function newsletter_print_entries($group) {
152
  </div>
153
  <?php } ?>
154
 
155
- <?php
156
- $newsletter_wp_options = get_option('newsletter_wp');
157
- if (isset($_GET['debug']) || !isset($dismissed['newsletter-wp']) && !is_plugin_active('/newsletter-wpusers/wpusers.php') && !empty($newsletter_wp_options['subscribe'])) { ?>
158
- <div class="tnp-notice">
159
- <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-wp' ?>" class="tnp-dismiss">&times;</a>
160
- The <strong>WP Users Integration</strong> feature is now managed with a free extension. Please install it from the
161
- <a href="?page=newsletter_main_extensions">Extensions panel</a>. Thank you.
162
- </div>
163
- <?php } ?>
164
-
165
- <?php
166
- $newsletter_lock_options = get_option('newsletter_lock');
167
- if (isset($_GET['debug']) || !isset($dismissed['newsletter-lock']) && !file_exists(WP_PLUGIN_DIR . '/newsletter-wp') && !empty($newsletter_lock_options['enabled'])) { ?>
168
- <div class="tnp-notice">
169
- <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-lock' ?>" class="tnp-dismiss">&times;</a>
170
- The <strong>Locked Content</strong> feature is now managed with a free extension. Please install it from the
171
- <a href="?page=newsletter_main_extensions">Extensions panel</a>. Thank you.
172
- </div>
173
- <?php } ?>
174
-
175
-
176
  <?php if (isset($_GET['debug']) || !isset($dismissed['newsletter-subscribe']) && get_option('newsletter_install_time') && get_option('newsletter_install_time') < time() - 86400 * 15) { ?>
177
  <div class="tnp-notice">
178
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-subscribe' ?>" class="tnp-dismiss">&times;</a>
25
  }
26
  }
27
  }
28
+
29
+ // Check the status to show a warning if needed
30
+ $status_options = Newsletter::instance()->get_options('status');
31
+ $warning = false;
32
+
33
+ $warning |= empty($status_options['mail']);
34
+
35
  ?>
36
 
37
  <div class="tnp-drowpdown" id="tnp-header">
60
  <small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
61
 
62
 
63
+ <li>
64
+ <a href="?page=newsletter_subscription_profile"><i class="fa fa-check-square-o"></i> <?php _e('Subscription Form Fields, Buttons, Labels', 'newsletter') ?>
65
+ <small><?php _e('When and what data to collect', 'newsletter') ?></small></a>
66
+ </li>
67
+ <li>
68
+ <a href="?page=newsletter_subscription_lists"><i class="fa fa-th-list"></i> <?php _e('Lists', 'newsletter') ?>
69
+ <small><?php _e('Profile the subscribers for a better targeting', 'newsletter') ?></small></a>
70
+ </li>
71
+ <li>
72
+ <a href="?page=newsletter_subscription_unsubscription"><i class="fa fa-sign-out"></i> <?php _e('Unsubscription', 'newsletter') ?>
73
+ <small><?php _e('How to give the last goodbye (or avoid it!)', 'newsletter') ?></small></a>
74
+ </li>
75
+
76
+ <li>
77
+ <a href="?page=newsletter_subscription_forms"><i class="fa fa-pencil"></i> <?php _e('Custom Forms', 'newsletter') ?>
78
+ <small><?php _e('Hand coded form storage', 'newsletter') ?></small></a>
79
+ </li>
80
+ <li>
81
+ <a href="?page=newsletter_subscription_template"><i class="fa fa-file-text-o"></i> <?php _e('Messages Template', 'newsletter') ?>
82
+ <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a>
83
+ </li>
84
  <?php
85
  newsletter_print_entries('subscription');
86
  ?>
103
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a></li>
104
  <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
105
  <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
106
+
107
+ <?php if (!class_exists('NewsletterSmtp')) { ?>
108
+ <li>
109
+ <a href="?page=newsletter_main_smtp"><i class="fa fa-envelope-o"></i> <?php _e('SMTP', 'newsletter') ?>
110
+ <small><?php _e('External mail server', 'newsletter') ?></small>
111
+ </a>
112
+ </li>
113
+ <?php } ?>
114
+
115
  <?php
116
  newsletter_print_entries('settings');
117
  ?>
118
  </ul>
119
  </li>
120
+
121
+ <li>
122
+ <a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
123
+ <?php if ($warning) { ?>
124
+ <i class="fa fa-exclamation-triangle" style="color: red;"></i>
125
+ <?php } ?>
126
+ </a>
127
+ </li>
128
+
129
  <?php
130
+ if (empty(Newsletter::instance()->options['contract_key']) && !defined('NEWSLETTER_LICENSE_KEY')) {
131
  ?>
132
  <li class="tnp-professional-extensions-button"><a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=header" target="_blank">
133
  <i class="fa fa-trophy"></i> <?php _e('Get Professional Extensions', 'newsletter') ?></a>
163
  <div class="tnp-notice">
164
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=rate' ?>" class="tnp-dismiss">&times;</a>
165
 
166
+ We never asked before and we're curious: <a href="http://wordpress.org/plugins/newsletter/" target="_blank">would you rate this plugin</a>?
167
  (few seconds required - account on WordPress.org required, every blog owner should have one...). <strong>Really appreciated, The Newsletter Team</strong>.
168
 
169
  </div>
179
  </div>
180
  <?php } ?>
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  <?php if (isset($_GET['debug']) || !isset($dismissed['newsletter-subscribe']) && get_option('newsletter_install_time') && get_option('newsletter_install_time') < time() - 86400 * 15) { ?>
183
  <div class="tnp-notice">
184
  <a href="<?php echo $_SERVER['REQUEST_URI'] . '&noheader=1&dismiss=newsletter-subscribe' ?>" class="tnp-dismiss">&times;</a>
users/edit.php CHANGED
@@ -11,14 +11,14 @@ $id = (int) $_GET['id'];
11
  if ($controls->is_action('save')) {
12
 
13
  $email = $module->normalize_email($controls->data['email']);
14
- if ($email == null) {
15
- $controls->errors = 'The email address is not valid';
16
  }
17
 
18
  if (empty($controls->errors)) {
19
  $user = $module->get_user($controls->data['email']);
20
  if ($user && $user->id != $id) {
21
- $controls->errors = 'The email address is already taken by another subscriber';
22
  }
23
  }
24
 
@@ -29,13 +29,17 @@ if ($controls->is_action('save')) {
29
  $controls->data['list_' . $i] = 0;
30
  }
31
  }
 
 
 
 
32
 
33
  $controls->data['id'] = $id;
34
  $r = $module->save_user($controls->data);
35
  if ($r === false) {
36
- $controls->errors = 'Unable to update, may be the email (if changed) is duplicated.';
37
  } else {
38
- $controls->messages = 'Updated.';
39
  $controls->data = $module->get_user($id, ARRAY_A);
40
  }
41
  }
@@ -55,8 +59,6 @@ $options_profile = get_option('newsletter_profile');
55
 
56
  $panels = Newsletter::instance()->panels;
57
 
58
- //$wpdb->query($wpdb->prepare("insert ignore into " . $wpdb->prefix . "newsletter_sent (user_id, email_id, time) select user_id, email_id, UNIX_TIMESTAMP(created) from " . NEWSLETTER_STATS_TABLE . " where user_id=%d", $id));
59
-
60
  function percent($value, $total) {
61
  if ($total == 0)
62
  return '-';
@@ -75,7 +77,7 @@ function percentValue($value, $total) {
75
  google.charts.load('current', {'packages': ['corechart', 'geomap']});
76
  </script>
77
 
78
- <div class="wrap" id="tnp-wrap">
79
 
80
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
81
 
@@ -85,7 +87,7 @@ function percentValue($value, $total) {
85
 
86
  </div>
87
 
88
- <div id="tnp-body" class="tnp-users tnp-users-edit">
89
 
90
  <form method="post" action="">
91
  <p>
@@ -105,53 +107,47 @@ function percentValue($value, $total) {
105
 
106
  </ul>
107
 
108
- <div id="tabs-general">
109
 
110
  <?php do_action('newsletter_users_edit_general', $id, $controls) ?>
111
 
112
  <table class="form-table">
113
 
114
  <tr valign="top">
115
- <th>Email address</th>
116
  <td>
117
  <?php $controls->text('email', 60); ?>
118
  </td>
119
  </tr>
120
  <tr valign="top">
121
- <th>First name</th>
122
  <td>
123
  <?php $controls->text('name', 50); ?>
124
- <p class="description">
125
- If you collect only the name of the subscriber without distinction of first and last name this field is used.
126
- </p>
127
  </td>
128
  </tr>
129
  <tr valign="top">
130
- <th>Last name</th>
131
  <td>
132
  <?php $controls->text('surname', 50); ?>
133
  </td>
134
  </tr>
135
  <tr valign="top">
136
- <th>Gender</th>
137
  <td>
138
  <?php $controls->select('sex', array('n' => 'Not specified', 'f' => 'female', 'm' => 'male')); ?>
139
  </td>
140
  </tr>
141
  <tr valign="top">
142
- <th>Status</th>
143
  <td>
144
  <?php $controls->select('status', array('C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
145
  </td>
146
  </tr>
147
  <tr valign="top">
148
- <th>Test subscriber?</th>
 
149
  <td>
150
  <?php $controls->yesno('test'); ?>
151
- <p class="description">
152
- A test subscriber is a regular subscriber that is even used as recipint when sending test newsletter are sent
153
- (for example to check the layout).
154
- </p>
155
  </td>
156
  </tr>
157
 
@@ -161,24 +157,14 @@ function percentValue($value, $total) {
161
  <th>Feed by mail</th>
162
  <td>
163
  <?php $controls->yesno('feed'); ?>
164
- <p class="description">
165
- "Yes" when this subscriber has the feed by mail service active. The
166
- <a href="https://www.thenewsletterplugin.com/feed-by-mail-extension?utm_source=plugin&utm_medium=link&utm_campaign=newsletter-feed" target="_blank">feed by mail is an extension of this plugin</a>.
167
- </p>
168
  </td>
169
  </tr>
170
  </table>
171
  </div>
172
- <div id="tabs-preferences">
173
- <div class="tab-preamble">
174
- <p>
175
- The subscriber's preferences are a set of "on/off" fields that can be used while sending newsletter to
176
- select a subset of subscribes.
177
- </p>
178
- </div>
179
  <table class="form-table">
180
  <tr>
181
- <th>Preferences</th>
182
  <td>
183
  <?php $controls->preferences('list'); ?>
184
  </td>
@@ -186,25 +172,21 @@ function percentValue($value, $total) {
186
  </table>
187
  </div>
188
 
189
- <div id="tabs-profile">
190
- <div class="tab-preamble">
191
- <p>
192
- The user's profile is a set of optional and textual fields you can collect along with the subscription process
193
- or when the user's editing his profile. Those fields can be configured in the "Subscription Form" panel.
194
- </p>
195
- </div>
196
  <table class="widefat">
197
  <thead>
198
  <tr>
199
- <th>Number</th>
200
- <th>Name</th>
201
- <th>Value</th>
202
  </tr>
203
  </thead>
204
  <tbody>
205
  <?php
206
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
207
- echo '<tr><td>(' . $i . ') ';
 
208
  echo '</td><td>';
209
  echo esc_html($options_profile['profile_' . $i]);
210
  echo '</td><td>';
@@ -216,12 +198,8 @@ function percentValue($value, $total) {
216
  </table>
217
  </div>
218
 
219
- <div id="tabs-other">
220
- <div class="tab-preamble">
221
- <p>
222
- Other user's data collected or generated along the subscription process.
223
- </p>
224
- </div>
225
  <table class="form-table">
226
  <tr valign="top">
227
  <th>ID</th>
@@ -230,48 +208,40 @@ function percentValue($value, $total) {
230
  </td>
231
  </tr>
232
  <tr valign="top">
233
- <th><?php _e('Created', 'newsletter')?></th>
234
  <td>
235
  <?php $controls->value('created'); ?>
236
  </td>
237
  </tr>
238
  <tr valign="top">
239
- <th><?php _e('WP user ID', 'newsletter')?></th>
240
  <td>
241
  <?php $controls->text('wp_user_id'); ?>
242
  </td>
243
  </tr>
244
  <tr valign="top">
245
- <th>From IP address</th>
246
  <td>
247
  <?php $controls->value('ip'); ?>
248
- <p class="description">
249
- Internet address from which the subscription started. Required by many providers.
250
- </p>
251
  </td>
252
  </tr>
253
  <tr valign="top">
254
- <th>Secret token</th>
255
  <td>
256
  <?php $controls->text('token', 50); ?>
257
- <p class="description">
258
- This secret token is used to access the profile page and edit profile data, to confirm and cancel the subscription.
259
- </p>
260
  </td>
261
  </tr>
262
  <tr valign="top">
263
- <th>Profile URL</th>
264
  <td>
265
- <?php echo esc_html(home_url('/') . '?na=pe&nk=' . $id . '-' . $controls->data['token']) ?>
266
- <p class="description">
267
- The URL which lands on the user profile editing page. It can be added on newsletters using the {profile_url} tag.
268
- </p>
269
  </td>
270
  </tr>
271
 
272
  </table>
273
  </div>
274
- <div id="tabs-newsletters">
275
  <p>Newsletter sent to this subscriber.</p>
276
  <?php if (!has_action('newsletter_user_newsletters_tab') && !has_action('newsletter_users_edit_newsletters')) { ?>
277
  <div class="tnp-tab-notice">
@@ -295,9 +265,9 @@ function percentValue($value, $total) {
295
 
296
  </div>
297
 
298
- <p class="submit">
299
  <?php $controls->button_save(); ?>
300
- <?php $controls->button('delete', 'Delete'); ?>
301
  </p>
302
 
303
  </form>
11
  if ($controls->is_action('save')) {
12
 
13
  $email = $module->normalize_email($controls->data['email']);
14
+ if (empty($email)) {
15
+ $controls->errors = __('Wrong email address', 'newsletter');
16
  }
17
 
18
  if (empty($controls->errors)) {
19
  $user = $module->get_user($controls->data['email']);
20
  if ($user && $user->id != $id) {
21
+ $controls->errors = __('The email address is already in use', 'newsletter');
22
  }
23
  }
24
 
29
  $controls->data['list_' . $i] = 0;
30
  }
31
  }
32
+
33
+ if (empty($controls->data['token'])) {
34
+ $controls->data['token'] = $module->get_token();
35
+ }
36
 
37
  $controls->data['id'] = $id;
38
  $r = $module->save_user($controls->data);
39
  if ($r === false) {
40
+ $controls->errors = __('Error. Check the log files.', 'newsletter');
41
  } else {
42
+ $controls->add_message_saved();
43
  $controls->data = $module->get_user($id, ARRAY_A);
44
  }
45
  }
59
 
60
  $panels = Newsletter::instance()->panels;
61
 
 
 
62
  function percent($value, $total) {
63
  if ($total == 0)
64
  return '-';
77
  google.charts.load('current', {'packages': ['corechart', 'geomap']});
78
  </script>
79
 
80
+ <div class="wrap tnp-users tnp-users-edit" id="tnp-wrap">
81
 
82
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
83
 
87
 
88
  </div>
89
 
90
+ <div id="tnp-body">
91
 
92
  <form method="post" action="">
93
  <p>
107
 
108
  </ul>
109
 
110
+ <div id="tabs-general" class="tnp-tab">
111
 
112
  <?php do_action('newsletter_users_edit_general', $id, $controls) ?>
113
 
114
  <table class="form-table">
115
 
116
  <tr valign="top">
117
+ <th><?php _e ('Email', 'newsletter'); ?></th>
118
  <td>
119
  <?php $controls->text('email', 60); ?>
120
  </td>
121
  </tr>
122
  <tr valign="top">
123
+ <th><?php _e ('First name', 'newsletter'); ?></th>
124
  <td>
125
  <?php $controls->text('name', 50); ?>
 
 
 
126
  </td>
127
  </tr>
128
  <tr valign="top">
129
+ <th><?php _e('Last name', 'newsletter'); ?></th>
130
  <td>
131
  <?php $controls->text('surname', 50); ?>
132
  </td>
133
  </tr>
134
  <tr valign="top">
135
+ <th><?php _e ('Gender', 'newsletter'); ?></th>
136
  <td>
137
  <?php $controls->select('sex', array('n' => 'Not specified', 'f' => 'female', 'm' => 'male')); ?>
138
  </td>
139
  </tr>
140
  <tr valign="top">
141
+ <th><?php _e ('Status', 'newsletter'); ?></th>
142
  <td>
143
  <?php $controls->select('status', array('C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
144
  </td>
145
  </tr>
146
  <tr valign="top">
147
+ <th><?php _e ('Test subscriber', 'newsletter'); ?>
148
+ <br><?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscribers#test-subscribers') ?></th>
149
  <td>
150
  <?php $controls->yesno('test'); ?>
 
 
 
 
151
  </td>
152
  </tr>
153
 
157
  <th>Feed by mail</th>
158
  <td>
159
  <?php $controls->yesno('feed'); ?>
 
 
 
 
160
  </td>
161
  </tr>
162
  </table>
163
  </div>
164
+ <div id="tabs-preferences" class="tnp-tab">
 
 
 
 
 
 
165
  <table class="form-table">
166
  <tr>
167
+ <th><?php _e('Lists', 'newsletter') ?><br><?php echo $controls->help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences') ?></th>
168
  <td>
169
  <?php $controls->preferences('list'); ?>
170
  </td>
172
  </table>
173
  </div>
174
 
175
+ <div id="tabs-profile" class="tnp-tab">
176
+
 
 
 
 
 
177
  <table class="widefat">
178
  <thead>
179
  <tr>
180
+ <th>#</th>
181
+ <th><?php _e ('Name', 'newsletter'); ?></th>
182
+ <th><?php _e ('Value', 'newsletter'); ?></th>
183
  </tr>
184
  </thead>
185
  <tbody>
186
  <?php
187
  for ($i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i++) {
188
+ echo '<tr><td>';
189
+ echo $i;
190
  echo '</td><td>';
191
  echo esc_html($options_profile['profile_' . $i]);
192
  echo '</td><td>';
198
  </table>
199
  </div>
200
 
201
+ <div id="tabs-other" class="tnp-tab">
202
+
 
 
 
 
203
  <table class="form-table">
204
  <tr valign="top">
205
  <th>ID</th>
208
  </td>
209
  </tr>
210
  <tr valign="top">
211
+ <th><?php _e('Created', 'newsletter') ?></th>
212
  <td>
213
  <?php $controls->value('created'); ?>
214
  </td>
215
  </tr>
216
  <tr valign="top">
217
+ <th><?php _e('WP user ID', 'newsletter') ?></th>
218
  <td>
219
  <?php $controls->text('wp_user_id'); ?>
220
  </td>
221
  </tr>
222
  <tr valign="top">
223
+ <th><?php _e ('IP address', 'newsletter'); ?></th>
224
  <td>
225
  <?php $controls->value('ip'); ?>
 
 
 
226
  </td>
227
  </tr>
228
  <tr valign="top">
229
+ <th><?php _e ('Secret token', 'newsletter'); ?></th>
230
  <td>
231
  <?php $controls->text('token', 50); ?>
 
 
 
232
  </td>
233
  </tr>
234
  <tr valign="top">
235
+ <th><?php _e ('Profile URL', 'newsletter'); ?></th>
236
  <td>
237
+ <?php $profile_url = esc_html(home_url('/') . '?na=pe&nk=' . $id . '-' . $controls->data['token']); ?>
238
+ <a href='<?php echo $profile_url ?>' target="_blank"><?php echo $profile_url ?></a>
 
 
239
  </td>
240
  </tr>
241
 
242
  </table>
243
  </div>
244
+ <div id="tabs-newsletters" class="tnp-tab">
245
  <p>Newsletter sent to this subscriber.</p>
246
  <?php if (!has_action('newsletter_user_newsletters_tab') && !has_action('newsletter_users_edit_newsletters')) { ?>
247
  <div class="tnp-tab-notice">
265
 
266
  </div>
267
 
268
+ <p>
269
  <?php $controls->button_save(); ?>
270
+ <?php $controls->button_delete(); ?>
271
  </p>
272
 
273
  </form>
users/import.php CHANGED
@@ -63,24 +63,24 @@ if ($controls->is_action('import')) {
63
  continue;
64
  }
65
 
66
- $subscriber = NewsletterUsers::instance()->get_user($email, ARRAY_A);
67
  if ($subscriber == null) {
68
  $subscriber = array();
69
  $subscriber['email'] = $email;
70
  if (isset($data[1])) {
71
- $subscriber['name'] = $newsletter->normalize_name($data[1]);
72
  }
73
  if (isset($data[2])) {
74
- $subscriber['surname'] = $newsletter->normalize_name($data[2]);
75
  }
76
  if (isset($data[3])) {
77
- $subscriber['sex'] = $newsletter->normalize_sex($data[3]);
78
  }
79
  $subscriber['status'] = $controls->data['import_as'];
80
  foreach ($controls->data['preferences'] as $i) {
81
  $subscriber['list_' . $i] = 1;
82
  }
83
- NewsletterUsers::instance()->save_user($subscriber);
84
  $results .= '[ADDED] ' . $line . "\n";
85
  $added_count++;
86
  } else {
@@ -91,10 +91,10 @@ if ($controls->is_action('import')) {
91
  }
92
 
93
  if ($mode == 'overwrite') {
94
- $subscriber['name'] = $newsletter->normalize_name($data[1]);
95
- $subscriber['surname'] = $newsletter->normalize_name($data[2]);
96
  if (isset($data[3])) {
97
- $subscriber['sex'] = $newsletter->normalize_sex($data[3]);
98
  }
99
  if (isset($controls->data['override_status'])) {
100
  $subscriber['status'] = $controls->data['import_as'];
@@ -111,10 +111,10 @@ if ($controls->is_action('import')) {
111
  }
112
 
113
  if ($mode == 'update') {
114
- $subscriber['name'] = $newsletter->normalize_name($data[1]);
115
- $subscriber['surname'] = $newsletter->normalize_name($data[2]);
116
  if (isset($data[3])) {
117
- $subscriber['sex'] = $newsletter->normalize_sex($data[3]);
118
  }
119
  if (isset($controls->data['override_status'])) {
120
  $subscriber['status'] = $controls->data['import_as'];
@@ -176,20 +176,20 @@ if ($controls->is_action('import')) {
176
  </tr>
177
 
178
  <tr valign="top">
179
- <th>Import mode</th>
180
  <td>
181
  <?php $controls->select('mode', array('update' => 'Update', 'overwrite' => 'Overwrite', 'skip' => 'Skip')); ?>
182
  if email is already present
183
- <div class="hints">
184
  <strong>Update</strong>: <?php _e('user data will be updated, existing preferences will be left untouched and new ones will be added.', 'newsletter') ?><br />
185
  <strong>Overwrite</strong>: <?php _e('user data will be overwritten with new informations (like name and preferences).', 'newsletter') ?><br />
186
  <strong>Skip</strong>: <?php _e('user data will be left untouched if already present.', 'newsletter') ?>
187
- </div>
188
  </td>
189
  </tr>
190
 
191
  <tr valign="top">
192
- <th>Preferences</th>
193
  <td>
194
  <?php $controls->preferences_group('preferences', true); ?>
195
  <div class="hints">
@@ -199,7 +199,7 @@ if ($controls->is_action('import')) {
199
  </tr>
200
 
201
  <tr valign="top">
202
- <th>Field Separator</th>
203
  <td>
204
  <?php $controls->select('separator', array(';' => 'Semicolon', ',' => 'Comma', 'tab' => 'Tabulation')); ?>
205
  </td>
63
  continue;
64
  }
65
 
66
+ $subscriber = $module->get_user($email, ARRAY_A);
67
  if ($subscriber == null) {
68
  $subscriber = array();
69
  $subscriber['email'] = $email;
70
  if (isset($data[1])) {
71
+ $subscriber['name'] = $module->normalize_name($data[1]);
72
  }
73
  if (isset($data[2])) {
74
+ $subscriber['surname'] = $module->normalize_name($data[2]);
75
  }
76
  if (isset($data[3])) {
77
+ $subscriber['sex'] = $module->normalize_sex($data[3]);
78
  }
79
  $subscriber['status'] = $controls->data['import_as'];
80
  foreach ($controls->data['preferences'] as $i) {
81
  $subscriber['list_' . $i] = 1;
82
  }
83
+ $module->save_user($subscriber);
84
  $results .= '[ADDED] ' . $line . "\n";
85
  $added_count++;
86
  } else {
91
  }
92
 
93
  if ($mode == 'overwrite') {
94
+ $subscriber['name'] = $module->normalize_name($data[1]);
95
+ $subscriber['surname'] = $module->normalize_name($data[2]);
96
  if (isset($data[3])) {
97
+ $subscriber['sex'] = $module->normalize_sex($data[3]);
98
  }
99
  if (isset($controls->data['override_status'])) {
100
  $subscriber['status'] = $controls->data['import_as'];
111
  }
112
 
113
  if ($mode == 'update') {
114
+ $subscriber['name'] = $module->normalize_name($data[1]);
115
+ $subscriber['surname'] = $module->normalize_name($data[2]);
116
  if (isset($data[3])) {
117
+ $subscriber['sex'] = $module->normalize_sex($data[3]);
118
  }
119
  if (isset($controls->data['override_status'])) {
120
  $subscriber['status'] = $controls->data['import_as'];
176
  </tr>
177
 
178
  <tr valign="top">
179
+ <th><?php _e('Import mode', 'newsletter') ?></th>
180
  <td>
181
  <?php $controls->select('mode', array('update' => 'Update', 'overwrite' => 'Overwrite', 'skip' => 'Skip')); ?>
182
  if email is already present
183
+ <p class="description">
184
  <strong>Update</strong>: <?php _e('user data will be updated, existing preferences will be left untouched and new ones will be added.', 'newsletter') ?><br />
185
  <strong>Overwrite</strong>: <?php _e('user data will be overwritten with new informations (like name and preferences).', 'newsletter') ?><br />
186
  <strong>Skip</strong>: <?php _e('user data will be left untouched if already present.', 'newsletter') ?>
187
+ </p>
188
  </td>
189
  </tr>
190
 
191
  <tr valign="top">
192
+ <th><?php _e('Lists', 'newsletter') ?></th>
193
  <td>
194
  <?php $controls->preferences_group('preferences', true); ?>
195
  <div class="hints">
199
  </tr>
200
 
201
  <tr valign="top">
202
+ <th><?php _e('Field separator', 'newsletter') ?></th>
203
  <td>
204
  <?php $controls->select('separator', array(';' => 'Semicolon', ',' => 'Comma', 'tab' => 'Tabulation')); ?>
205
  </td>
users/index.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
 
@@ -15,20 +16,21 @@ $options_main = get_option('newsletter_main');
15
  if ($controls->is_action()) {
16
  if ($controls->is_action('reset')) {
17
  $controls->data = array();
 
 
18
  }
19
- $controls->data['search_page'] = (int)$controls->data['search_page']-1;
20
  $module->save_options($controls->data, 'search');
21
- }
22
- else {
23
  $controls->data = $module->get_options('search');
24
- if (empty($controls->data['search_page'])) $controls->data['search_page'] = 0;
 
25
  }
26
 
27
- $lists = array(''=>'Any List');
28
- for ($i=1; $i<=NEWSLETTER_LIST_MAX; $i++)
29
- {
30
- if (empty($options_lists['list_' . $i])) continue;
31
- $lists[''.$i] = '(' . $i . ') ' . $options_lists['list_' . $i];
32
  }
33
 
34
  if ($controls->is_action('resend')) {
@@ -46,12 +48,12 @@ if ($controls->is_action('resend_welcome')) {
46
  }
47
 
48
  if ($controls->is_action('remove')) {
49
- $wpdb->query($wpdb->prepare("delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", $controls->button_data));
50
  unset($controls->data['subscriber_id']);
51
  }
52
 
53
  // We build the query condition
54
- $where = "where 1=1";
55
  $query_args = array();
56
  $text = trim($controls->get_value('search_text'));
57
  if ($text) {
@@ -75,9 +77,11 @@ if (!empty($controls->data['search_status'])) {
75
  }
76
 
77
  if (!empty($controls->data['search_list'])) {
78
- $where .= " and list_" . ((int)$controls->data['search_list']) . "=1";
79
  }
80
 
 
 
81
  // Total items, total pages
82
  $items_per_page = 20;
83
  if (!empty($query_args)) {
@@ -85,7 +89,8 @@ if (!empty($query_args)) {
85
  }
86
  $count = Newsletter::instance()->store->get_count(NEWSLETTER_USERS_TABLE, $where);
87
  $last_page = floor($count / $items_per_page) - ($count % $items_per_page == 0 ? 1 : 0);
88
- if ($last_page < 0) $last_page = 0;
 
89
 
90
  if ($controls->is_action('last')) {
91
  $controls->data['search_page'] = $last_page;
@@ -94,172 +99,168 @@ if ($controls->is_action('first')) {
94
  $controls->data['search_page'] = 0;
95
  }
96
  if ($controls->is_action('next')) {
97
- $controls->data['search_page'] = (int)$controls->data['search_page']+1;
98
  }
99
  if ($controls->is_action('prev')) {
100
- $controls->data['search_page'] = (int)$controls->data['search_page']-1;
101
  }
102
  if ($controls->is_action('search')) {
103
  $controls->data['search_page'] = 0;
104
  }
105
 
106
  // Eventually fix the page
107
- if ($controls->data['search_page'] < 0) $controls->data['search_page'] = 0;
108
- if ($controls->data['search_page'] > $last_page) $controls->data['search_page'] = $last_page;
 
 
109
 
110
  $query = "select * from " . NEWSLETTER_USERS_TABLE . ' ' . $where . " order by id desc";
111
- $query .= " limit " . ($controls->data['search_page']*$items_per_page) . "," . $items_per_page;
112
  $list = $wpdb->get_results($query);
113
 
114
  // Move to base 1
115
- $controls->data['search_page']++;
116
  ?>
117
 
118
- <div class="wrap" id="tnp-wrap">
119
 
120
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
121
 
122
  <div id="tnp-heading">
123
-
124
- <h2><?php _e('Search and Edit', 'newsletter')?>
125
- <a class="tnp-btn-h1" href="?page=newsletter_users_new"><?php _e('Add a new subscriber', 'newsletter') ?></a>
126
  </h2>
127
 
128
  </div>
129
 
130
- <div id="tnp-body" class="tnp-users tnp-users-index">
131
 
132
- <form id="channel" method="post" action="">
133
- <?php $controls->init(); ?>
134
 
135
- <div class="tnp-subscribers-search">
136
- <?php $controls->text('search_text', 80, __('Search text', 'newsletter')); ?>
137
 
138
- <?php _e('filter by', 'newsletter')?>:
139
- <?php $controls->select('search_status', array(''=>'Any status', 'T'=>'Test subscribers', 'C'=>'Confirmed', 'S'=>'Not confirmed', 'U'=>'Unsubscribed', 'B'=>'Bounced')); ?>
140
  <?php $controls->select('search_list', $lists); ?>
141
-
142
- <?php $controls->button('search', __('Search', 'newsletter')); ?>
143
- <?php if ($where != "where 1=1") { ?>
144
- <?php $controls->button('reset', __('Reset Filters', 'newsletter')); ?>
145
- <?php } ?>
146
- <br>
147
- <?php $controls->checkbox('show_preferences', __('Show lists', 'newsletter')); ?>
148
- </div>
149
-
150
- <div class="tnp-paginator">
151
-
152
- <?php $controls->button('first', '«'); ?>
153
- <?php $controls->button('prev', '‹'); ?>
154
- <?php $controls->text('search_page', 3); ?> of <?php echo $last_page+1 ?> <?php $controls->button('go', __('Go', 'newsletter')); ?>
155
- <?php $controls->button('next', '›'); ?>
156
- <?php $controls->button('last', '»'); ?>
157
 
158
- <?php echo $count ?> <?php _e('subscriber(s) found', 'newsletter')?>
159
-
160
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
- <table class="widefat">
163
- <thead>
164
- <tr>
165
- <th>Id</th>
166
- <th>Email/Name</th>
167
- <?php if (isset($options['show_profile']) && $options['show_profile'] == 1) { ?>
168
- <th>Profile</th>
169
- <?php } ?>
170
- <th><?php _e('Status', 'newsletter') ?></th>
171
- <?php if (isset($options['show_preferences']) && $options['show_preferences'] == 1) { ?>
172
- <th><?php _e('Preferences', 'newsletter') ?></th>
173
- <?php } ?>
174
- <th>Actions</th>
175
- <?php if (isset($options['search_clicks']) && $options['search_clicks'] == 1) { ?>
176
- <th>Clicks</th>
177
- <?php } ?>
178
- </tr>
179
- </thead>
180
- <?php foreach($list as $s) { ?>
181
- <tr class="<?php echo ($i++%2==0)?'alternate':''; ?>">
182
-
183
- <td>
184
- <?php echo $s->id; ?>
185
- </td>
186
-
187
- <td>
188
- <?php echo $s->email; ?><br /><?php echo $s->name; ?> <?php echo $s->surname; ?>
189
- </td>
190
-
191
-
192
- <?php if (isset($options['show_profile']) && $options['show_profile'] == 1) { ?>
193
- <td>
194
- <small>
195
- <?php
196
- for ($i=1; $i<NEWSLETTER_PROFILE_MAX; $i++) {
197
- if ($options_profile['profile_' . $i] == '') continue;
198
- echo $options_profile['profile_' . $i];
199
- echo ':';
200
- $key = 'profile_' . $i;
201
- echo htmlspecialchars($s->$key);
202
- echo '<br />';
203
- }
204
- ?>
205
- </small>
206
- </td>
207
- <?php } ?>
208
-
209
- <td>
210
- <small>
211
- <?php
212
- switch ($s->status) {
213
- case 'S': _e('NOT CONFIRMED', 'newsletter'); break;
214
- case 'C': _e('CONFIRMED', 'newsletter'); break;
215
- case 'U': _e('UNSUBSCRIBED', 'newsletter'); break;
216
- case 'B': _e('BOUNCED', 'newsletter'); break;
217
- }
218
- ?>
219
- </small>
220
- </td>
221
-
222
- <?php if (isset($options['show_preferences']) && $options['show_preferences'] == 1) { ?>
223
- <td>
224
- <small>
225
- <?php
226
- for ($i=1; $i<=NEWSLETTER_LIST_MAX; $i++) {
227
- if (!isset($lists['' . $i])) continue;
228
- $l = 'list_' . $i;
229
- if ($s->$l == 1) echo esc_html($lists['' . $i]) . '<br />';
230
- }
231
- ?>
232
- </small>
233
- </td>
234
- <?php } ?>
235
-
236
- <td>
237
- <a class="button-secondary" href="<?php echo $module->get_admin_page_url('edit'); ?>&amp;id=<?php echo $s->id; ?>"><?php _e('Edit', 'newsletter') ?></a>
238
- <?php $controls->button_confirm('remove', __('Remove', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
239
-
240
- <?php //$controls->button('status', 'Confirm', 'newsletter_set_status(this.form,' . $s->id . ',\'C\')'); ?>
241
- <?php //$controls->button('status', 'Unconfirm', 'newsletter_set_status(this.form,' . $s->id . ',\'S\')'); ?>
242
-
243
- <?php $controls->button_confirm('resend', __('Resend confirmation', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
244
- <?php $controls->button_confirm('resend_welcome', __('Resend welcome', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
245
- <a href="<?php echo home_url('/') ?>?na=p&nk=<?php echo $s->id . '-' . $s->token; ?>" class="button-primary" target="_blank"><?php _e('Profile page', 'newsletter') ?></a>
246
- </td>
247
-
248
-
249
- </tr>
250
- <?php } ?>
251
- </table>
252
- <div class="tnp-paginator">
253
-
254
- <?php $controls->button('first', '«'); ?>
255
- <?php $controls->button('prev', '‹'); ?>
256
- <?php $controls->text('search_page', 3); ?> of <?php echo $last_page+1 ?> <?php $controls->button('go', __('Go', 'newsletter')); ?>
257
- <?php $controls->button('next', '›'); ?>
258
- <?php $controls->button('last', '»'); ?>
259
- </div>
260
- </form>
261
- </div>
262
-
263
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
264
-
265
  </div>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
 
16
  if ($controls->is_action()) {
17
  if ($controls->is_action('reset')) {
18
  $controls->data = array();
19
+ } else {
20
+ $controls->data['search_page'] = (int) $controls->data['search_page'] - 1;
21
  }
 
22
  $module->save_options($controls->data, 'search');
23
+ } else {
 
24
  $controls->data = $module->get_options('search');
25
+ if (empty($controls->data['search_page']))
26
+ $controls->data['search_page'] = 0;
27
  }
28
 
29
+ $lists = array('' => 'Any List');
30
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
31
+ if (empty($options_lists['list_' . $i]))
32
+ continue;
33
+ $lists['' . $i] = '(' . $i . ') ' . $options_lists['list_' . $i];
34
  }
35
 
36
  if ($controls->is_action('resend')) {
48
  }
49
 
50
  if ($controls->is_action('remove')) {
51
+ $wpdb->query($wpdb->prepare("delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $controls->button_data));
52
  unset($controls->data['subscriber_id']);
53
  }
54
 
55
  // We build the query condition
56
+ $where = 'where 1=1';
57
  $query_args = array();
58
  $text = trim($controls->get_value('search_text'));
59
  if ($text) {
77
  }
78
 
79
  if (!empty($controls->data['search_list'])) {
80
+ $where .= " and list_" . ((int) $controls->data['search_list']) . "=1";
81
  }
82
 
83
+ $filtered = $where != 'where 1=1';
84
+
85
  // Total items, total pages
86
  $items_per_page = 20;
87
  if (!empty($query_args)) {
89
  }
90
  $count = Newsletter::instance()->store->get_count(NEWSLETTER_USERS_TABLE, $where);
91
  $last_page = floor($count / $items_per_page) - ($count % $items_per_page == 0 ? 1 : 0);
92
+ if ($last_page < 0)
93
+ $last_page = 0;
94
 
95
  if ($controls->is_action('last')) {
96
  $controls->data['search_page'] = $last_page;
99
  $controls->data['search_page'] = 0;
100
  }
101
  if ($controls->is_action('next')) {
102
+ $controls->data['search_page'] = (int) $controls->data['search_page'] + 1;
103
  }
104
  if ($controls->is_action('prev')) {
105
+ $controls->data['search_page'] = (int) $controls->data['search_page'] - 1;
106
  }
107
  if ($controls->is_action('search')) {
108
  $controls->data['search_page'] = 0;
109
  }
110
 
111
  // Eventually fix the page
112
+ if ($controls->data['search_page'] < 0)
113
+ $controls->data['search_page'] = 0;
114
+ if ($controls->data['search_page'] > $last_page)
115
+ $controls->data['search_page'] = $last_page;
116
 
117
  $query = "select * from " . NEWSLETTER_USERS_TABLE . ' ' . $where . " order by id desc";
118
+ $query .= " limit " . ($controls->data['search_page'] * $items_per_page) . "," . $items_per_page;
119
  $list = $wpdb->get_results($query);
120
 
121
  // Move to base 1
122
+ $controls->data['search_page'] ++;
123
  ?>
124
 
125
+ <div class="wrap tnp-users tnp-users-index" id="tnp-wrap">
126
 
127
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
128
 
129
  <div id="tnp-heading">
130
+
131
+ <h2><?php _e('Subscribers', 'newsletter') ?>
132
+ <a class="tnp-btn-h1" href="?page=newsletter_users_new">+</a>
133
  </h2>
134
 
135
  </div>
136
 
137
+ <div id="tnp-body">
138
 
139
+ <form id="channel" method="post" action="">
140
+ <?php $controls->init(); ?>
141
 
142
+ <div class="tnp-subscribers-search">
143
+ <?php $controls->text('search_text', 45, __('Search text', 'newsletter')); ?>
144
 
145
+ <?php _e('filter by', 'newsletter') ?>:
146
+ <?php $controls->select('search_status', array('' => 'Any status', 'T' => 'Test subscribers', 'C' => 'Confirmed', 'S' => 'Not confirmed', 'U' => 'Unsubscribed', 'B' => 'Bounced')); ?>
147
  <?php $controls->select('search_list', $lists); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ <?php $controls->button('search', __('Search', 'newsletter')); ?>
150
+ <?php if ($where != "where 1=1") { ?>
151
+ <?php $controls->button('reset', __('Reset Filters', 'newsletter')); ?>
152
+ <?php } ?>
153
+ <br>
154
+ <?php $controls->checkbox('show_preferences', __('Show lists', 'newsletter')); ?>
155
+ </div>
156
+
157
+ <?php if ($filtered) { ?>
158
+ <p><?php _e('The list below is filtered.', 'newsletter') ?></p>
159
+ <?php } ?>
160
+
161
+ <div class="tnp-paginator">
162
+
163
+ <?php $controls->button('first', '«'); ?>
164
+ <?php $controls->button('prev', '‹'); ?>
165
+ <?php $controls->text('search_page', 3); ?> of <?php echo $last_page + 1 ?> <?php $controls->button('go', __('Go', 'newsletter')); ?>
166
+ <?php $controls->button('next', '›'); ?>
167
+ <?php $controls->button('last', '»'); ?>
168
+
169
+ <?php echo $count ?> <?php _e('subscriber(s) found', 'newsletter') ?>
170
+
171
+ </div>
172
+
173
+ <table class="widefat">
174
+ <thead>
175
+ <tr>
176
+ <th>Id</th>
177
+ <th>Email</th>
178
+ <th><?php _e('Name', 'newsletter') ?></th>
179
+ <th><?php _e('Status', 'newsletter') ?></th>
180
+ <?php if (isset($options['show_preferences']) && $options['show_preferences'] == 1) { ?>
181
+ <th><?php _e('Lists', 'newsletter') ?></th>
182
+ <?php } ?>
183
+ <th>&nbsp;</th>
184
+ <th>&nbsp;</th>
185
+ <th>&nbsp;</th>
186
+ </tr>
187
+ </thead>
188
+ <?php foreach ($list as $s) { ?>
189
+ <tr class="<?php echo ($i++ % 2 == 0) ? 'alternate' : ''; ?>">
190
+
191
+ <td>
192
+ <?php echo $s->id; ?>
193
+ </td>
194
+
195
+ <td>
196
+ <?php echo esc_html($s->email); ?>
197
+ </td>
198
+
199
+ <td>
200
+ <?php echo esc_html($s->name); ?> <?php echo esc_html($s->surname); ?>
201
+ </td>
202
+
203
+ <td>
204
+ <small>
205
+ <?php
206
+ switch ($s->status) {
207
+ case 'S': _e('NOT CONFIRMED', 'newsletter');
208
+ break;
209
+ case 'C': _e('CONFIRMED', 'newsletter');
210
+ break;
211
+ case 'U': _e('UNSUBSCRIBED', 'newsletter');
212
+ break;
213
+ case 'B': _e('BOUNCED', 'newsletter');
214
+ break;
215
+ }
216
+ ?>
217
+ </small>
218
+ </td>
219
+
220
+ <?php if (isset($options['show_preferences']) && $options['show_preferences'] == 1) { ?>
221
+ <td>
222
+ <small>
223
+ <?php
224
+ for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
225
+ if (!isset($lists['' . $i]))
226
+ continue;
227
+ $l = 'list_' . $i;
228
+ if ($s->$l == 1)
229
+ echo esc_html($lists['' . $i]) . '<br />';
230
+ }
231
+ ?>
232
+ </small>
233
+ </td>
234
+ <?php } ?>
235
+
236
+ <td>
237
+ <a class="button-secondary" href="<?php echo $module->get_admin_page_url('edit'); ?>&amp;id=<?php echo $s->id; ?>"><?php _e('Edit', 'newsletter') ?></a>
238
+ </td>
239
+ <td>
240
+ <?php $controls->button_confirm('remove', __('Remove', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
241
+ </td>
242
+ <td style="text-align: center">
243
+ <?php if ($s->status == "C") { ?>
244
+ <?php $controls->button_confirm('resend_welcome', __('Resend welcome', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
245
+ <?php } else { ?>
246
+ <?php $controls->button_confirm('resend', __('Resend activation', 'newsletter'), __('Proceed?', 'newsletter'), $s->id); ?>
247
+ <?php } ?>
248
+ </td>
249
+
250
+ </tr>
251
+ <?php } ?>
252
+ </table>
253
+ <div class="tnp-paginator">
254
+
255
+ <?php $controls->button('first', '«'); ?>
256
+ <?php $controls->button('prev', '‹'); ?>
257
+ <?php $controls->text('search_page', 3); ?> of <?php echo $last_page + 1 ?> <?php $controls->button('go', __('Go', 'newsletter')); ?>
258
+ <?php $controls->button('next', '›'); ?>
259
+ <?php $controls->button('last', '»'); ?>
260
+ </div>
261
+ </form>
262
+ </div>
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
265
+
266
  </div>
users/massive.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
 
@@ -10,80 +11,65 @@ $options_profile = get_option('newsletter_profile');
10
 
11
  $lists = array();
12
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
13
- if (!isset($options_profile['list_' . $i])) $options_profile['list_' . $i] = '';
14
- $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
 
15
  }
16
 
17
  if ($controls->is_action('remove_unconfirmed')) {
18
- $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='S'");
19
- $controls->messages = __('Subscribers not confirmed deleted: ', 'newsletter') . $r . '.';
20
  }
21
 
22
  if ($controls->is_action('remove_unsubscribed')) {
23
- $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='U'");
24
- $controls->messages = __('Subscribers unsubscribed deleted: ', 'newsletter') . $r . '.';
25
  }
26
 
27
  if ($controls->is_action('remove_bounced')) {
28
- $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='B'");
29
- $controls->messages = __('Subscribers bounced deleted: ', 'newsletter') . $r . '.';
30
  }
31
 
32
  if ($controls->is_action('unconfirm_all')) {
33
- $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set status='S' where status='C'");
34
- $controls->messages = __('Subscribers changed to not confirmed: ', 'newsletter') . $r . '.';
35
  }
36
 
37
  if ($controls->is_action('confirm_all')) {
38
- $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set status='C' where status='S'");
39
- $controls->messages = __('Subscribers changed to confirmed: ', 'newsletter') . $r . '.';
40
  }
41
 
42
  if ($controls->is_action('remove_all')) {
43
- $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE);
44
- $controls->messages = __('Subscribers deleted: ', 'newsletter') . $r . '.';
45
  }
46
 
47
  if ($controls->is_action('list_add')) {
48
- $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set list_" . ((int)$controls->data['list']) . "=1");
49
- $controls->messages = $r . ' ' . __('added to the list/preference', 'newsletter') . ' ' . $controls->data['list'];
50
  }
51
 
52
  if ($controls->is_action('list_remove')) {
53
- $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set list_" . ((int)$controls->data['list']) . "=0");
54
- $controls->messages = $r . ' ' . __('removed to the list/preference', 'newsletter') . ' ' . $controls->data['list'];
55
  }
56
 
57
  if ($controls->is_action('list_delete')) {
58
- $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where list_" . ((int)$controls->data['list']) . "<>0");
59
  }
60
 
61
  if ($controls->is_action('list_manage')) {
62
- if ($controls->data['list_action'] == 'move') {
63
- $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int)$controls->data['list_1']) . '=0, list_' . ((int)$controls->data['list_2']) . '=1' .
64
- ' where list_' . $controls->data['list_1'] . '=1');
65
- }
66
-
67
- if ($controls->data['list_action'] == 'add') {
68
- $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int)$controls->data['list_2']) . '=1' .
69
- ' where list_' . $controls->data['list_1'] . '=1');
70
- }
71
- }
72
-
73
- if ($controls->is_action('resend_all')) {
74
- $list = $wpdb->get_results("select * from " . NEWSLETTER_USERS_TABLE . " where status='S'");
75
- $opts = get_option('newsletter');
76
-
77
- if ($list) {
78
- $controls->messages = __('Confirmation email sent to:', 'newsletter');
79
- foreach ($list as &$user) {
80
- $controls->messages .= $user->email . ' ';
81
- $newsletter->mail($user->email, $newsletter->replace($opts['confirmation_subject'], $user), $newsletter->replace($opts['confirmation_message'], $user));
82
- }
83
- } else {
84
- $controls->errors = 'No subscribers to which rensend the confirmation email';
85
  }
86
 
 
 
 
 
87
  }
88
 
89
  if ($controls->is_action('bounces')) {
@@ -96,36 +82,37 @@ if ($controls->is_action('bounces')) {
96
  $results = '';
97
  foreach ($lines as &$email) {
98
  $email = trim($email);
99
- if (empty($email)) continue;
 
100
 
101
  $total++;
102
 
103
  $email = NewsletterModule::normalize_email($email);
104
  if (empty($email)) {
105
- $results .= '[INVALID] ' . $email . "\n";
106
- $error++;
107
  continue;
108
  }
109
 
110
  $user = NewsletterUsers::instance()->get_user($email);
111
 
112
  if ($user == null) {
113
- $results .= '[NOT FOUND] ' . $email . "\n";
114
- $not_found++;
115
- continue;
116
  }
117
 
118
  if ($user->status == 'B') {
119
- $results .= '[ALREADY BOUNCED] ' . $email . "\n";
120
- $already_bounced++;
121
- continue;
122
  }
123
 
124
  $r = NewsletterUsers::instance()->set_user_status($email, 'B');
125
  if ($r === 0) {
126
- $results .= '[BOUNCED] ' . $email . "\n";
127
- $marked++;
128
- continue;
129
  }
130
  }
131
 
@@ -137,190 +124,154 @@ if ($controls->is_action('bounces')) {
137
  }
138
  ?>
139
 
140
- <div class="wrap" id="tnp-wrap">
141
-
142
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
143
-
144
  <div id="tnp-heading">
145
 
146
- <h2><?php _e('Subscribers Maintenance', 'newsletter')?></h2>
147
- <p><?php _e('Please, backup before run a massive action.', 'newsletter')?></p>
148
-
149
  </div>
150
-
151
- <div id="tnp-body" class="tnp-users tnp-users-massive">
152
-
153
- <?php if (!empty($results)) { ?>
154
-
155
- <h3>Results</h3>
156
-
157
- <textarea wrap="off" style="width: 100%; height: 150px; font-size: 11px; font-family: monospace"><?php echo htmlspecialchars($results) ?></textarea>
158
-
159
- <?php } ?>
160
-
161
-
162
- <form method="post" action="">
163
- <?php $controls->init(); ?>
164
-
165
- <div id="tabs">
166
- <ul>
167
- <li><a href="#tabs-1"><?php _e('Massive actions', 'newsletter')?></a></li>
168
- <li><a href="#tabs-2"><?php _e('Preferences/lists management', 'newsletter')?></a></li>
169
- <li><a href="#tabs-3"><?php _e('Other', 'newsletter')?></a></li>
170
- <li><a href="#tabs-4">Bounces</a></li>
171
- </ul>
172
-
173
- <div id="tabs-1">
174
- <table class="widefat">
175
- <thead>
176
- <tr>
177
- <th><?php _e('Status', 'newsletter')?></th>
178
- <th><?php _e('Total', 'newsletter')?></th>
179
- <th><?php _e('Actions', 'newsletter')?></th>
180
- </tr>
181
- </thead>
182
- <tr>
183
- <td><?php _e('Total collected emails', 'newsletter')?></td>
184
- <td>
185
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE); ?>
186
- </td>
187
- <td nowrap>
188
- <?php $controls->button_confirm('remove_all', __('Delete all', 'newsletter'), __('Are you sure you want to remove ALL subscribers?', 'newsletter')); ?>
189
- </td>
190
- </tr>
191
- <tr>
192
- <td><?php _e('Confirmed', 'newsletter')?></td>
193
- <td>
194
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
195
- </td>
196
- <td nowrap>
197
- <?php $controls->button_confirm('unconfirm_all', __('Unconfirm all', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
198
- </td>
199
- </tr>
200
- <tr>
201
- <td>Not confirmed</td>
202
- <td>
203
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='S'"); ?>
204
- </td>
205
- <td nowrap>
206
- <?php $controls->button_confirm('remove_unconfirmed', __('Delete all not confirmed', 'newsletter'), __('Are you sure you want to delete ALL not confirmed subscribers?', 'newsletter')); ?>
207
- <?php $controls->button_confirm('confirm_all', __('Confirm all', 'newsletter'), __('Are you sure you want to mark ALL subscribers as confirmed?', 'newsletter')); ?>
208
- <p class="description">
209
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#resend-confirm" target="_blank"><?php _e('We have some tips about global actions, read more.', 'newsletter')?></a>
210
- </p>
211
- </td>
212
- </tr>
213
- <tr>
214
- <td><?php _e('Unsubscribed', 'newsletter')?></td>
215
- <td>
216
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
217
- </td>
218
- <td>
219
- <?php $controls->button_confirm('remove_unsubscribed', __('Delete all unsubscribed', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
220
- </td>
221
- </tr>
222
-
223
- <tr>
224
- <td><?php _e('Bounced', 'newsletter')?></td>
225
- <td>
226
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
227
- </td>
228
- <td>
229
- <?php $controls->button_confirm('remove_bounced', __('Delete all bounced', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
230
- </td>
231
- </tr>
232
- </table>
233
- <p>Bounce are not detected by Newsletter plugin.</p>
234
-
235
- <h3><?php _e('Gender', 'newsletter')?></h3>
236
- <?php
237
- // TODO: do them with a single query
238
- $all_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'");
239
- $male_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where sex='m' and status='C'");
240
- $female_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where sex='f' and status='C'");
241
- $other_count = ($all_count-$male_count-$female_count)
242
- ?>
243
- <table class="widefat">
244
- <thead><tr><th><?php _e('Gender', 'newsletter')?></th><th>Total</th></thead>
245
- <tr><td>Male</td><td><?php echo $male_count; ?></td></tr>
246
- <tr><td>Female</td><td><?php echo $female_count; ?></td></tr>
247
- <tr><td>Not specified</td><td><?php echo $other_count; ?></td></tr>
248
- </table>
249
- </div>
250
-
251
-
252
- <div id="tabs-2">
253
- <table class="form-table">
254
- <tr>
255
- <th><?php _e('Preferences/lists management', 'newsletter')?></th>
256
- <td>
257
- For preference <?php $controls->select('list', $lists); ?>:
258
- <?php $controls->button_confirm('list_add', 'Add it to every user', __('Are you sure?', 'newsletter')); ?>
259
- <?php $controls->button_confirm('list_remove', 'Remove it from every user', __('Are you sure?', 'newsletter')); ?>
260
- <?php $controls->button_confirm('list_delete', 'Delete subscribers of it', __('Are you sure?', 'newsletter')); ?>
261
- <br /><br />
262
- <?php $controls->select('list_action', array('move' => 'Change', 'add' => 'Add')); ?>
263
- all subscribers with preference <?php $controls->select('list_1', $lists); ?>
264
- to preference <?php $controls->select('list_2', $lists); ?>
265
- <?php $controls->button_confirm('list_manage', 'Go!', 'Are you sure?'); ?>
266
- <div class="hints">
267
- If you choose to <strong>delete</strong> users in a list, they will be
268
- <strong>physically deleted</strong> from the database (no way back).
269
- </div>
270
- </td>
271
- </tr>
272
- </table>
273
- </div>
274
-
275
-
276
- <div id="tabs-3">
277
- <p><?php _e('Totals refer only to confirmed subscribers.', 'newsletter')?></p>
278
- <table class="widefat">
279
- <thead>
280
- <tr>
281
- <th><?php _e('Number', 'newsletter')?></th>
282
- <th><?php _e('Preference', 'newsletter')?></th>
283
- <th><?php _e('Total', 'newsletter')?></th>
284
- </tr>
285
- </thead>
286
- <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
287
- <tr>
288
- <td><?php echo $i; ?></td>
289
- <td><?php echo esc_html($options_profile['list_' . $i]); ?></td>
290
- <td>
291
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $i . "=1 and status='C'"); ?>
292
- </td>
293
- </tr>
294
- <?php } ?>
295
- </table>
296
- </div>
297
-
298
- <div id="tabs-4">
299
- <p>
300
- Import a set of bounced email addresses: they will be marked as "bounced" and no more contacted. Sending
301
- emails to bounced address (many times) can put your server in some black list.
302
- </p>
303
-
304
- <table class="form-table">
305
- <tr>
306
- <th><?php _e('Bounced addresses', 'newsletter')?></th>
307
- <td>
308
- <?php $controls->textarea('bounced_emails'); ?>
309
- <p class="description">
310
- <?php _e('One email address per line.', 'newsletter')?>One email address per line.
311
- </p>
312
- </td>
313
- </tr>
314
- </table>
315
-
316
- <?php $controls->button_confirm('bounces', 'Mark those emails as bounced', __('Are you sure?', 'newsletter')); ?>
317
- </div>
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  </div>
320
 
321
- </form>
322
- </div>
323
-
324
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
325
-
326
  </div>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
 
11
 
12
  $lists = array();
13
  for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
14
+ if (!isset($options_profile['list_' . $i]))
15
+ $options_profile['list_' . $i] = '';
16
+ $lists['' . $i] = '(' . $i . ') ' . $options_profile['list_' . $i];
17
  }
18
 
19
  if ($controls->is_action('remove_unconfirmed')) {
20
+ $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='S'");
21
+ $controls->messages = __('Subscribers not confirmed deleted: ', 'newsletter') . $r . '.';
22
  }
23
 
24
  if ($controls->is_action('remove_unsubscribed')) {
25
+ $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='U'");
26
+ $controls->messages = __('Subscribers unsubscribed deleted: ', 'newsletter') . $r . '.';
27
  }
28
 
29
  if ($controls->is_action('remove_bounced')) {
30
+ $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where status='B'");
31
+ $controls->messages = __('Subscribers bounced deleted: ', 'newsletter') . $r . '.';
32
  }
33
 
34
  if ($controls->is_action('unconfirm_all')) {
35
+ $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set status='S' where status='C'");
36
+ $controls->messages = __('Subscribers changed to not confirmed: ', 'newsletter') . $r . '.';
37
  }
38
 
39
  if ($controls->is_action('confirm_all')) {
40
+ $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set status='C' where status='S'");
41
+ $controls->messages = __('Subscribers changed to confirmed: ', 'newsletter') . $r . '.';
42
  }
43
 
44
  if ($controls->is_action('remove_all')) {
45
+ $r = $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE);
46
+ $controls->messages = __('Subscribers deleted: ', 'newsletter') . $r . '.';
47
  }
48
 
49
  if ($controls->is_action('list_add')) {
50
+ $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set list_" . ((int) $controls->data['list']) . "=1");
51
+ $controls->messages = $r . ' ' . __('added to the list', 'newsletter') . ' ' . $controls->data['list'];
52
  }
53
 
54
  if ($controls->is_action('list_remove')) {
55
+ $r = $wpdb->query("update " . NEWSLETTER_USERS_TABLE . " set list_" . ((int) $controls->data['list']) . "=0");
56
+ $controls->messages = $r . ' ' . __('removed to the list', 'newsletter') . ' ' . $controls->data['list'];
57
  }
58
 
59
  if ($controls->is_action('list_delete')) {
60
+ $wpdb->query("delete from " . NEWSLETTER_USERS_TABLE . " where list_" . ((int) $controls->data['list']) . "<>0");
61
  }
62
 
63
  if ($controls->is_action('list_manage')) {
64
+ if ($controls->data['list_action'] == 'move') {
65
+ $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int) $controls->data['list_1']) . '=0, list_' . ((int) $controls->data['list_2']) . '=1' .
66
+ ' where list_' . $controls->data['list_1'] . '=1');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
+ if ($controls->data['list_action'] == 'add') {
70
+ $wpdb->query("update " . NEWSLETTER_USERS_TABLE . ' set list_' . ((int) $controls->data['list_2']) . '=1' .
71
+ ' where list_' . $controls->data['list_1'] . '=1');
72
+ }
73
  }
74
 
75
  if ($controls->is_action('bounces')) {
82
  $results = '';
83
  foreach ($lines as &$email) {
84
  $email = trim($email);
85
+ if (empty($email))
86
+ continue;
87
 
88
  $total++;
89
 
90
  $email = NewsletterModule::normalize_email($email);
91
  if (empty($email)) {
92
+ $results .= '[INVALID] ' . $email . "\n";
93
+ $error++;
94
  continue;
95
  }
96
 
97
  $user = NewsletterUsers::instance()->get_user($email);
98
 
99
  if ($user == null) {
100
+ $results .= '[NOT FOUND] ' . $email . "\n";
101
+ $not_found++;
102
+ continue;
103
  }
104
 
105
  if ($user->status == 'B') {
106
+ $results .= '[ALREADY BOUNCED] ' . $email . "\n";
107
+ $already_bounced++;
108
+ continue;
109
  }
110
 
111
  $r = NewsletterUsers::instance()->set_user_status($email, 'B');
112
  if ($r === 0) {
113
+ $results .= '[BOUNCED] ' . $email . "\n";
114
+ $marked++;
115
+ continue;
116
  }
117
  }
118
 
124
  }
125
  ?>
126
 
127
+ <div class="wrap tnp-users tnp-users-massive" id="tnp-wrap">
128
+
129
  <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
130
+
131
  <div id="tnp-heading">
132
 
133
+ <h2><?php _e('Subscribers Maintenance', 'newsletter') ?></h2>
134
+ <p><?php _e('Please, backup before run a massive action.', 'newsletter') ?></p>
135
+
136
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
+ <div id="tnp-body">
139
+
140
+ <?php if (!empty($results)) { ?>
141
+
142
+ <h3>Results</h3>
143
+
144
+ <textarea wrap="off" style="width: 100%; height: 150px; font-size: 11px; font-family: monospace"><?php echo htmlspecialchars($results) ?></textarea>
145
+
146
+ <?php } ?>
147
+
148
+
149
+ <form method="post" action="">
150
+ <?php $controls->init(); ?>
151
+
152
+ <div id="tabs">
153
+ <ul>
154
+ <li><a href="#tabs-1"><?php _e('General', 'newsletter') ?></a></li>
155
+ <li><a href="#tabs-2"><?php _e('Lists', 'newsletter') ?></a></li>
156
+ <li><a href="#tabs-4"><?php _e('Bounces', 'newsletter') ?></a></li>
157
+ </ul>
158
+
159
+ <div id="tabs-1">
160
+ <table class="widefat">
161
+ <thead>
162
+ <tr>
163
+ <th><?php _e('Status', 'newsletter') ?></th>
164
+ <th><?php _e('Total', 'newsletter') ?></th>
165
+ <th><?php _e('Actions', 'newsletter') ?></th>
166
+ </tr>
167
+ </thead>
168
+ <tr>
169
+ <td><?php _e('Total collected emails', 'newsletter') ?></td>
170
+ <td>
171
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE); ?>
172
+ </td>
173
+ <td nowrap>
174
+ <?php $controls->button_confirm('remove_all', __('Delete all', 'newsletter'), __('Are you sure you want to remove ALL subscribers?', 'newsletter')); ?>
175
+ </td>
176
+ </tr>
177
+ <tr>
178
+ <td><?php _e('Confirmed', 'newsletter') ?></td>
179
+ <td>
180
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
181
+ </td>
182
+ <td nowrap>
183
+ <?php $controls->button_confirm('unconfirm_all', __('Unconfirm all', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
184
+ </td>
185
+ </tr>
186
+ <tr>
187
+ <td>Not confirmed</td>
188
+ <td>
189
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='S'"); ?>
190
+ </td>
191
+ <td nowrap>
192
+ <?php $controls->button_confirm('remove_unconfirmed', __('Delete all not confirmed', 'newsletter'), __('Are you sure you want to delete ALL not confirmed subscribers?', 'newsletter')); ?>
193
+ <?php $controls->button_confirm('confirm_all', __('Confirm all', 'newsletter'), __('Are you sure you want to mark ALL subscribers as confirmed?', 'newsletter')); ?>
194
+ <p class="description">
195
+ <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#resend-activation" target="_blank"><?php _e('We have some tips about global actions, read more.', 'newsletter') ?></a>
196
+ </p>
197
+ </td>
198
+ </tr>
199
+ <tr>
200
+ <td><?php _e('Unsubscribed', 'newsletter') ?></td>
201
+ <td>
202
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
203
+ </td>
204
+ <td>
205
+ <?php $controls->button_confirm('remove_unsubscribed', __('Delete all unsubscribed', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
206
+ </td>
207
+ </tr>
208
+
209
+ <tr>
210
+ <td><?php _e('Bounced', 'newsletter') ?></td>
211
+ <td>
212
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
213
+ </td>
214
+ <td>
215
+ <?php $controls->button_confirm('remove_bounced', __('Delete all bounced', 'newsletter'), __('Are you sure?', 'newsletter')); ?>
216
+ </td>
217
+ </tr>
218
+ </table>
219
+
220
+
221
+ </div>
222
+
223
+
224
+ <div id="tabs-2">
225
+ <table class="form-table">
226
+ <tr>
227
+ <th>&nbsp;</th>
228
+ <td>
229
+ <?php $controls->select('list', $lists) ?>:
230
+ <?php $controls->button_confirm('list_add', 'Add it to every user', __('Are you sure?', 'newsletter')); ?>
231
+ <?php $controls->button_confirm('list_remove', 'Remove it from every user', __('Are you sure?', 'newsletter')); ?>
232
+ <?php $controls->button_confirm('list_delete', 'Delete subscribers of it', __('Are you sure?', 'newsletter')); ?>
233
+ <br><br>
234
+ <?php $controls->select('list_action', array('move' => 'Change', 'add' => 'Add')); ?>
235
+ <?php _e('all subscribers in', 'newsletter')?> <?php $controls->select('list_1', $lists); ?>
236
+ <?php _e('to', 'newsletter')?> <?php $controls->select('list_2', $lists); ?>
237
+ <?php $controls->button_confirm('list_manage', 'Go!', 'Are you sure?'); ?>
238
+ <p class="description">
239
+ If you choose to <strong>delete</strong> users in a list, they will be
240
+ <strong>physically deleted</strong> from the database (no way back).
241
+ </p>
242
+ </td>
243
+ </tr>
244
+ </table>
245
+ </div>
246
+
247
+
248
+
249
+ <div id="tabs-4">
250
+ <p>
251
+ Import a set of bounced email addresses: they will be marked as "bounced" and no more contacted. Sending
252
+ messages to bounced address (many times) can put your server in some black list.
253
+ </p>
254
+
255
+ <table class="form-table">
256
+ <tr>
257
+ <th><?php _e('Bounced addresses', 'newsletter') ?></th>
258
+ <td>
259
+ <?php $controls->textarea('bounced_emails'); ?>
260
+ <p class="description">
261
+ <?php _e('One email address per line.', 'newsletter') ?>
262
+ </p>
263
+ </td>
264
+ </tr>
265
+ </table>
266
+
267
+ <?php $controls->button_confirm('bounces', 'Mark those emails as bounced', __('Are you sure?', 'newsletter')); ?>
268
+ </div>
269
+
270
+ </div>
271
+
272
+ </form>
273
  </div>
274
 
 
 
 
275
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
276
+
277
  </div>
users/new.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
- if (!defined('ABSPATH')) exit;
 
3
 
4
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $controls = new NewsletterControls();
@@ -7,17 +8,23 @@ $module = NewsletterUsers::instance();
7
 
8
  if ($controls->is_action('save')) {
9
 
10
- $controls->data['status'] = 'C';
11
- $controls->data['sex'] = 'n';
12
-
13
- $user = $module->save_user($controls->data);
14
- if ($user === false) {
15
- $controls->errors = 'This email already exists.';
16
- } else {
17
- echo '<script>';
18
- echo 'location.href="' . $module->get_admin_page_url('edit') . '&id=' . $user->id . '"';
19
- echo '</script>';
20
- return;
 
 
 
 
 
 
21
  }
22
  }
23
  ?>
@@ -39,10 +46,10 @@ if ($controls->is_action('save')) {
39
 
40
  <table class="form-table">
41
  <tr valign="top">
42
- <th>New email address</th>
43
  <td>
44
- <?php $controls->text('email', 60); ?>
45
- <?php $controls->button('save', 'Proceed'); ?>
46
 
47
  </td>
48
  </tr>
@@ -53,4 +60,4 @@ if ($controls->is_action('save')) {
53
 
54
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
55
 
56
- </div>
1
  <?php
2
+ if (!defined('ABSPATH'))
3
+ exit;
4
 
5
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
  $controls = new NewsletterControls();
8
 
9
  if ($controls->is_action('save')) {
10
 
11
+ if (!is_email($controls->data['email'])) {
12
+ $controls->errors = __('Wrong email address.', 'newsletter');
13
+ }
14
+
15
+ if (empty($controls->errors)) {
16
+ $controls->data['status'] = 'C';
17
+ $controls->data['sex'] = 'n';
18
+
19
+ $user = $module->save_user($controls->data);
20
+ if ($user === false) {
21
+ $controls->errors = __('This subscriber already exists.', 'newsletter');
22
+ } else {
23
+ echo '<script>';
24
+ echo 'location.href="' . $module->get_admin_page_url('edit') . '&id=' . $user->id . '"';
25
+ echo '</script>';
26
+ return;
27
+ }
28
  }
29
  }
30
  ?>
46
 
47
  <table class="form-table">
48
  <tr valign="top">
49
+ <th><?php _e('Email', 'newsletter')?></th>
50
  <td>
51
+ <?php $controls->text_email('email', 60); ?>
52
+ <?php $controls->button('save', '&raquo;'); ?>
53
 
54
  </td>
55
  </tr>
60
 
61
  <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
62
 
63
+ </div>
users/statistics-time.php CHANGED
@@ -5,16 +5,16 @@ if (!defined('ABSPATH'))
5
 
6
  <div class="row">
7
  <div class="col-md-6">
8
- <h3>Subscriptions by month (max 12 months)</h3>
9
  <?php
10
  $months = $wpdb->get_results("select count(*) as c, concat(year(created), '-', date_format(created, '%m')) as d from " . NEWSLETTER_USERS_TABLE . " where status='C' group by concat(year(created), '-', date_format(created, '%m')) order by d desc limit 12");
11
  ?>
12
 
13
- <table class="widefat" style="width: auto">
14
  <thead>
15
  <tr valign="top">
16
- <th>Date</th>
17
- <th>Subscribers</th>
18
  </tr>
19
  </thead>
20
  <?php foreach ($months as &$day) { ?>
@@ -26,17 +26,18 @@ if (!defined('ABSPATH'))
26
  </table>
27
 
28
  </div>
 
29
  <div class="col-md-6">
30
-
31
- <h3>Subscriptions by day (max 90 days)</h3>
32
  <?php
33
  $list = $wpdb->get_results("select count(*) as c, date(created) as d from " . NEWSLETTER_USERS_TABLE . " where status='C' group by date(created) order by d desc limit 90");
34
  ?>
35
- <table class="widefat" style="width: auto">
36
  <thead>
37
  <tr valign="top">
38
- <th>Date</th>
39
- <th>Subscribers</th>
40
  </tr>
41
  </thead>
42
  <?php foreach ($list as $day) { ?>
@@ -46,7 +47,7 @@ if (!defined('ABSPATH'))
46
  </tr>
47
  <?php } ?>
48
  </table>
49
-
50
  </div>
51
 
52
  </div>
5
 
6
  <div class="row">
7
  <div class="col-md-6">
8
+ <h3><?php _e('Subscriptions by month (max 12 months)', 'newsletter') ?></h3>
9
  <?php
10
  $months = $wpdb->get_results("select count(*) as c, concat(year(created), '-', date_format(created, '%m')) as d from " . NEWSLETTER_USERS_TABLE . " where status='C' group by concat(year(created), '-', date_format(created, '%m')) order by d desc limit 12");
11
  ?>
12
 
13
+ <table class="widefat">
14
  <thead>
15
  <tr valign="top">
16
+ <th><?php _e('Year and month', 'newsletter') ?></th>
17
+ <th><?php _e('Total', 'newsletter') ?></th>
18
  </tr>
19
  </thead>
20
  <?php foreach ($months as &$day) { ?>
26
  </table>
27
 
28
  </div>
29
+
30
  <div class="col-md-6">
31
+
32
+ <h3><?php _e('Subscriptions by day (max 90 days)', 'newsletter') ?></h3>
33
  <?php
34
  $list = $wpdb->get_results("select count(*) as c, date(created) as d from " . NEWSLETTER_USERS_TABLE . " where status='C' group by date(created) order by d desc limit 90");
35
  ?>
36
+ <table class="widefat">
37
  <thead>
38
  <tr valign="top">
39
+ <th><?php _e('Date', 'newsletter') ?></th>
40
+ <th><?php _e('Total', 'newsletter') ?></th>
41
  </tr>
42
  </thead>
43
  <?php foreach ($list as $day) { ?>
47
  </tr>
48
  <?php } ?>
49
  </table>
50
+
51
  </div>
52
 
53
  </div>
users/statistics.php CHANGED
@@ -22,7 +22,7 @@ $controls = new NewsletterControls();
22
 
23
  <div class="wrap" id="tnp-wrap">
24
 
25
- <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
26
 
27
  <div id="tnp-heading">
28
 
@@ -32,15 +32,15 @@ $controls = new NewsletterControls();
32
 
33
  <div id="tnp-body" class="tnp-users-statistics">
34
 
35
- <?php $controls->init(); ?>
36
 
37
  <div id="tabs">
38
 
39
  <ul>
40
  <li><a href="#tab-overview">Overview</a></li>
41
- <li><a href="#tabs-preferences">Lists</a></li>
42
  <li><a href="#tabs-countries">World Map</a></li>
43
- <li><a href="#tabs-referrers">Referrers</a></li>
44
  <li><a href="#tabs-sources">Sources</a></li>
45
  <li><a href="#tabs-gender">Gender</a></li>
46
  <li><a href="#tabs-time">By time</a></li>
@@ -49,75 +49,73 @@ $controls = new NewsletterControls();
49
  <div id="tab-overview">
50
 
51
  <table class="widefat" style="width: auto">
52
- <thead><tr><th>Status</th><th>Total</th></thead>
53
- <tr valign="top">
54
- <td>Any</td>
55
- <td>
56
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE); ?>
57
- </td>
58
- </tr>
59
- <tr>
60
- <td>Confirmed</td>
61
- <td>
62
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
63
- </td>
64
- </tr>
65
- <tr>
66
- <td>Not confirmed</td>
67
- <td>
68
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='S'"); ?>
69
- </td>
70
- </tr>
71
- <tr>
72
- <td>Subscribed to feed by mail</td>
73
- <td>
74
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C' and feed=1"); ?>
75
- </td>
76
- </tr>
77
- <tr>
78
- <td>Unsubscribed</td>
79
- <td>
80
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
81
- </td>
82
- </tr>
83
- <tr>
84
- <td>Bounced</td>
85
- <td>
86
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
87
- </td>
88
- </tr>
 
89
  </table>
90
 
91
  </div>
92
 
93
 
94
- <div id="tabs-preferences">
95
-
96
- <div class="tab-preamble">
97
- <p>
98
- Subscriber count per list.
99
- <a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Read more about lists</a> and/or
100
- configure them from te "Lists" panel.
101
- <p>
102
- </div>
103
 
104
  <table class="widefat" style="width: auto">
105
  <thead>
106
  <tr>
107
- <th>List</th>
108
- <th>Total</th>
109
- </thead>
110
- <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
111
- <?php if (empty($options_profile['list_' . $i])) continue; ?>
112
- <tr>
113
- <td><?php echo '(' . $i . ') ' . esc_html($options_profile['list_' . $i]) ?></td>
114
- <td>
115
- <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $i . "=1 and status='C'"); ?>
116
- </td>
117
  </tr>
118
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
119
  </table>
120
-
121
  </div>
122
 
123
 
@@ -133,56 +131,66 @@ $controls = new NewsletterControls();
133
 
134
 
135
  <div id="tabs-referrers">
136
- <div class="tab-preamble">
137
- <p>The referrer is a special (hidden) fields collected during the subscription. For example the widget
138
- adds the "widget" referrer to his generated form. With custom forms you can add
139
- your own referrer using an hidden field named "nr".
140
- </p>
141
- </div>
142
  <?php
143
- $list = $wpdb->get_results("select referrer, count(*) as total from " . NEWSLETTER_USERS_TABLE . " where status='C' group by referrer order by total desc");
144
  ?>
145
  <table class="widefat" style="width: auto">
146
  <thead>
147
- <tr><th>Referrer</th><th>Total</th>
148
- </thead>
149
- <?php foreach ($list as $row) { ?>
150
  <tr>
151
- <td><?php echo empty($row->referrer) ? '[undefined]' : esc_html($row->referrer) ?></td>
152
- <td><?php echo $row->total; ?></td>
 
 
 
153
  </tr>
154
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
155
  </table>
156
 
157
  </div>
158
 
159
 
160
  <div id="tabs-sources">
161
-
162
- <div class="tab-preamble">
163
- <p>
164
- URLs from which the subscription started. For example, if you use the widget on your blog sidebar
165
- you can discover which page is converting more.
166
- </p>
167
- </div>
168
-
169
  <?php
170
- $list = $wpdb->get_results("select http_referer, count(*) as total from " . NEWSLETTER_USERS_TABLE . " where status='C' group by http_referer order by count(*) desc limit 100");
171
  ?>
172
  <table class="widefat" style="width: auto">
173
  <thead>
174
  <tr>
175
  <th>URL</th>
176
- <th>Total</th>
 
 
 
 
177
  </thead>
178
  <tbody>
179
- <?php foreach ($list as $row) { ?>
180
  <tr>
181
- <td><?php echo empty($row->http_referer) ? '[undefined]' : esc_html($row->http_referer) ?></td>
182
- <td><?php echo $row->total; ?></td>
 
 
 
183
  </tr>
184
- <?php } ?>
185
- <tbody>
186
  </table>
187
 
188
  </div>
@@ -190,69 +198,47 @@ $controls = new NewsletterControls();
190
 
191
  <div id="tabs-gender">
192
 
193
-
194
  <?php
195
- $male_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where sex='m' and status='C'");
196
- $female_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where sex='f' and status='C'");
197
- $other_count = ($all_count - $male_count - $female_count);
198
- $gender_data = array($female_count, $male_count, $other_count);
199
  ?>
200
-
201
- <div class="row">
202
- <div class="col-md-6">
203
- <canvas id="tnp-gender-chart" style="width: 300px!important; height: 300px!important"></canvas>
204
- </div>
205
-
206
- <div class="col-md-6">
207
- <table class="widefat" style="width: auto">
208
- <thead>
209
- <tr>
210
- <th>Gender</th>
211
- <th>Total</th>
212
- </thead>
213
- <tbody>
214
- <tr>
215
- <td>Male</td>
216
- <td><?php echo $male_count; ?></td>
 
217
  </tr>
218
  <tr>
219
- <td>Female</td>
220
- <td><?php echo $female_count; ?></td>
 
 
 
221
  </tr>
222
  <tr>
223
- <td>Other</td>
224
- <td><?php echo $other_count; ?></td>
 
 
 
225
  </tr>
226
- </table>
227
- </div>
228
- </div>
229
- <script>
230
- var gender_data = {
231
- labels: [
232
- "Female",
233
- "Male",
234
- "Other"
235
- ],
236
- datasets: [
237
- {
238
- data: <?php echo json_encode($gender_data) ?>,
239
- backgroundColor: [
240
- "#2980B9",
241
- "#27AE60",
242
- "#555555"
243
- ],
244
- hoverBackgroundColor: [
245
- "#2980B9",
246
- "#27AE60",
247
- "#555555"
248
- ]
249
- }]};
250
-
251
- jQuery(document).ready(function ($) {
252
- gender_ctx = $('#tnp-gender-chart').get(0).getContext("2d");
253
- new Chart(gender_ctx, {type: 'doughnut', data: gender_data, options: {responsive: false, legend: {labels: {boxWidth: 10}}}});
254
- });
255
- </script>
256
 
257
 
258
  </div>
@@ -281,7 +267,7 @@ $controls = new NewsletterControls();
281
 
282
  </div>
283
 
284
- <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
285
 
286
  </div>
287
 
22
 
23
  <div class="wrap" id="tnp-wrap">
24
 
25
+ <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
26
 
27
  <div id="tnp-heading">
28
 
32
 
33
  <div id="tnp-body" class="tnp-users-statistics">
34
 
35
+ <?php $controls->init(); ?>
36
 
37
  <div id="tabs">
38
 
39
  <ul>
40
  <li><a href="#tab-overview">Overview</a></li>
41
+ <li><a href="#tabs-lists">Lists</a></li>
42
  <li><a href="#tabs-countries">World Map</a></li>
43
+ <li><a href="#tabs-referrers">Referrer</a></li>
44
  <li><a href="#tabs-sources">Sources</a></li>
45
  <li><a href="#tabs-gender">Gender</a></li>
46
  <li><a href="#tabs-time">By time</a></li>
49
  <div id="tab-overview">
50
 
51
  <table class="widefat" style="width: auto">
52
+ <thead>
53
+ <tr>
54
+ <th><?php _e('Status', 'newsletter') ?></th>
55
+ <th><?php _e('Total', 'newsletter') ?></th>
56
+ </tr>
57
+ </thead>
58
+ <tbody>
59
+ <tr valign="top">
60
+ <td><?php _e('Any', 'newsletter') ?></td>
61
+ <td>
62
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE); ?>
63
+ </td>
64
+ </tr>
65
+ <tr>
66
+ <td><?php _e('Confirmed', 'newsletter') ?></td>
67
+ <td>
68
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'"); ?>
69
+ </td>
70
+ </tr>
71
+ <tr>
72
+ <td><?php _e('Not confirmed', 'newsletter') ?></td>
73
+ <td>
74
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='S'"); ?>
75
+ </td>
76
+ </tr>
77
+ <tr>
78
+ <td><?php _e('Unsubscribed', 'newsletter') ?></td>
79
+ <td>
80
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='U'"); ?>
81
+ </td>
82
+ </tr>
83
+ <tr>
84
+ <td><?php _e('Bounced', 'newsletter') ?></td>
85
+ <td>
86
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='B'"); ?>
87
+ </td>
88
+ </tr>
89
+ </tbody>
90
  </table>
91
 
92
  </div>
93
 
94
 
95
+ <div id="tabs-lists">
 
 
 
 
 
 
 
 
96
 
97
  <table class="widefat" style="width: auto">
98
  <thead>
99
  <tr>
100
+ <th>&nbsp;</th>
101
+ <th><?php _e('List', 'newsletter') ?></th>
102
+ <th><?php _e('Total', 'newsletter') ?> (*)</th>
 
 
 
 
 
 
 
103
  </tr>
104
+ </thead>
105
+ <tbody>
106
+ <?php for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) { ?>
107
+ <?php if (empty($options_profile['list_' . $i])) continue; ?>
108
+ <tr>
109
+ <td><?php echo $i ?></td>
110
+ <td><?php echo esc_html($options_profile['list_' . $i]) ?></td>
111
+ <td>
112
+ <?php echo $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where list_" . $i . "=1 and status='C'"); ?>
113
+ </td>
114
+ </tr>
115
+ <?php } ?>
116
+ </tbody>
117
  </table>
118
+ (*) <?php _e('Confirmed', 'newsletter') ?>
119
  </div>
120
 
121
 
131
 
132
 
133
  <div id="tabs-referrers">
134
+ <p>
135
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscribers-statistics#referrer') ?>
136
+ </p>
 
 
 
137
  <?php
138
+ $list = $wpdb->get_results("select referrer, SUM(if(status='C', 1, 0)) as confirmed, SUM(if(status='S', 1, 0)) as unconfirmed, SUM(if(status='B', 1, 0)) as bounced, SUM(if(status='U', 1, 0)) as unsubscribed from " . NEWSLETTER_USERS_TABLE . " group by referrer order by confirmed desc");
139
  ?>
140
  <table class="widefat" style="width: auto">
141
  <thead>
 
 
 
142
  <tr>
143
+ <th><?php _e('Referrer', 'newsletter') ?></th>
144
+ <th><?php _e('Confirmed', 'newsletter') ?></th>
145
+ <th><?php _e('Not confirmed', 'newsletter') ?></th>
146
+ <th><?php _e('Unsubscribed', 'newsletter') ?></th>
147
+ <th><?php _e('Bounced', 'newsletter') ?></th>
148
  </tr>
149
+ </thead>
150
+ <tbody>
151
+ <?php foreach ($list as $row) { ?>
152
+ <tr>
153
+ <td><?php echo empty($row->referrer) ? '[not set]' : esc_html($row->referrer) ?></td>
154
+ <td><?php echo $row->confirmed; ?></td>
155
+ <td><?php echo $row->unconfirmed; ?></td>
156
+ <td><?php echo $row->unsubscribed; ?></td>
157
+ <td><?php echo $row->bounced; ?></td>
158
+ </tr>
159
+ <?php } ?>
160
+ </tbody>
161
  </table>
162
 
163
  </div>
164
 
165
 
166
  <div id="tabs-sources">
167
+ <p>
168
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscribers-statistics#source') ?>
169
+ </p>
 
 
 
 
 
170
  <?php
171
+ $list = $wpdb->get_results("select http_referer, SUM(if(status='C', 1, 0)) as confirmed, SUM(if(status='S', 1, 0)) as unconfirmed, SUM(if(status='B', 1, 0)) as bounced, SUM(if(status='U', 1, 0)) as unsubscribed from " . NEWSLETTER_USERS_TABLE . " group by http_referer order by count(*) desc limit 100");
172
  ?>
173
  <table class="widefat" style="width: auto">
174
  <thead>
175
  <tr>
176
  <th>URL</th>
177
+ <th><?php _e('Confirmed', 'newsletter') ?></th>
178
+ <th><?php _e('Not confirmed', 'newsletter') ?></th>
179
+ <th><?php _e('Unsubscribed', 'newsletter') ?></th>
180
+ <th><?php _e('Bounced', 'newsletter') ?></th>
181
+ </tr>
182
  </thead>
183
  <tbody>
184
+ <?php foreach ($list as $row) { ?>
185
  <tr>
186
+ <td><?php echo empty($row->http_referer) ? '[not set]' : $controls->print_truncated($row->http_referer, 120) ?></td>
187
+ <td><?php echo $row->confirmed; ?></td>
188
+ <td><?php echo $row->unconfirmed; ?></td>
189
+ <td><?php echo $row->unsubscribed; ?></td>
190
+ <td><?php echo $row->bounced; ?></td>
191
  </tr>
192
+ <?php } ?>
193
+ </tbody>
194
  </table>
195
 
196
  </div>
198
 
199
  <div id="tabs-gender">
200
 
201
+
202
  <?php
203
+ $male_count = $wpdb->get_row("select SUM(if(status='C', 1, 0)) as confirmed, SUM(if(status='S', 1, 0)) as unconfirmed, SUM(if(status='B', 1, 0)) as bounced, SUM(if(status='U', 1, 0)) as unsubscribed from " . NEWSLETTER_USERS_TABLE . " where sex='m'");
204
+ $female_count = $wpdb->get_row("select SUM(if(status='C', 1, 0)) as confirmed, SUM(if(status='S', 1, 0)) as unconfirmed, SUM(if(status='B', 1, 0)) as bounced, SUM(if(status='U', 1, 0)) as unsubscribed from " . NEWSLETTER_USERS_TABLE . " where sex='f'");
205
+ $none_count = $wpdb->get_row("select SUM(if(status='C', 1, 0)) as confirmed, SUM(if(status='S', 1, 0)) as unconfirmed, SUM(if(status='B', 1, 0)) as bounced, SUM(if(status='U', 1, 0)) as unsubscribed from " . NEWSLETTER_USERS_TABLE . " where sex='n'");
 
206
  ?>
207
+
208
+ <table class="widefat">
209
+ <thead>
210
+ <tr>
211
+ <th><?php _e('Gender', 'newsletter')?></th>
212
+ <th><?php _e('Confirmed', 'newsletter') ?></th>
213
+ <th><?php _e('Not confirmed', 'newsletter') ?></th>
214
+ <th><?php _e('Unsubscribed', 'newsletter') ?></th>
215
+ <th><?php _e('Bounced', 'newsletter') ?></th>
216
+ </tr>
217
+ </thead>
218
+ <tbody>
219
+ <tr>
220
+ <td><?php _e('Female', 'newsletter')?></td>
221
+ <td><?php echo $female_count->confirmed; ?></td>
222
+ <td><?php echo $female_count->unconfirmed; ?></td>
223
+ <td><?php echo $female_count->unsubscribed; ?></td>
224
+ <td><?php echo $female_count->bounced; ?></td>
225
  </tr>
226
  <tr>
227
+ <td><?php _e('Female', 'newsletter')?></td>
228
+ <td><?php echo $male_count->confirmed; ?></td>
229
+ <td><?php echo $male_count->unconfirmed; ?></td>
230
+ <td><?php echo $male_count->unsubscribed; ?></td>
231
+ <td><?php echo $male_count->bounced; ?></td>
232
  </tr>
233
  <tr>
234
+ <td><?php _e('Not specified', 'newsletter')?></td>
235
+ <td><?php echo $none_count->confirmed; ?></td>
236
+ <td><?php echo $none_count->unconfirmed; ?></td>
237
+ <td><?php echo $none_count->unsubscribed; ?></td>
238
+ <td><?php echo $none_count->bounced; ?></td>
239
  </tr>
240
+ </tbody>
241
+ </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
 
244
  </div>
267
 
268
  </div>
269
 
270
+ <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
271
 
272
  </div>
273
 
users/users.php CHANGED
@@ -186,40 +186,6 @@ class NewsletterUsers extends NewsletterModule {
186
  return $text;
187
  }
188
 
189
- /**
190
- * Returns a list of users marked as "test user".
191
- * @global Newsletter $newsletter
192
- * @return array
193
- */
194
- function get_test_users() {
195
- $newsletter = Newsletter::instance();
196
- return $newsletter->get_test_users();
197
- }
198
-
199
- /**
200
- * @global Newsletter $newsletter
201
- */
202
- function delete_user($id) {
203
- $newsletter = Newsletter::instance();
204
- return $newsletter->delete_user($id);
205
- }
206
-
207
- /**
208
- *
209
- * @global Newsletter $newsletter
210
- * @param int|string $id_or_email
211
- * @param string $status
212
- * @return boolean
213
- */
214
- function set_user_status($id_or_email, $status) {
215
- $newsletter = Newsletter::instance();
216
- return $newsletter->set_user_status($id_or_email, $status);
217
- }
218
-
219
- function set_user_field($id, $field, $value) {
220
- $this->store->set_field(NEWSLETTER_USERS_TABLE, $id, $field, $value);
221
- }
222
-
223
  }
224
 
225
  NewsletterUsers::instance();
186
  return $text;
187
  }
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
190
 
191
  NewsletterUsers::instance();
widget/minimal.php CHANGED
@@ -29,7 +29,7 @@ class NewsletterWidgetMinimal extends WP_Widget {
29
 
30
 
31
  $form = '<div class="tnp tnp-widget-minimal">';
32
- $form .= '<form action="' . esc_attr(home_url('/')) . '?na=s" method="post">';
33
  if (isset($instance['nl']) && is_array($instance['nl'])) {
34
  foreach ($instance['nl'] as $a) {
35
  $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";
29
 
30
 
31
  $form = '<div class="tnp tnp-widget-minimal">';
32
+ $form .= '<form action="' . esc_attr(home_url('/')) . '?na=s" method="post" onsubmit="return newsletter_check(this)">';
33
  if (isset($instance['nl']) && is_array($instance['nl'])) {
34
  foreach ($instance['nl'] as $a) {
35
  $form .= "<input type='hidden' name='nl[]' value='" . ((int) trim($a)) . "'>\n";