Version Description
- Fixed the print_date() when no time is provided
- Fixed date alignment on posts block
- Folders reorganization
- Social block with a new set of icons
- Boosted performances of the lists management page (for big databases)
- Added a new scheduler diagnostic panel
- Seriously improved the cron statistics and diagnostic panel (check it out!)
- Removed obsolete migration code from ancient versions
Download this release
Release Info
Developer | satollo |
Plugin | Newsletter |
Version | 7.2.8 |
Comparing to | |
See all releases |
Code changes from version 7.2.7 to 7.2.8
- admin/admin-dark.css +0 -34
- {css → admin}/controls.css +170 -170
- {css → admin}/dropdown.css +137 -137
- {css → admin}/extensions.css +152 -152
- {css → admin}/fields.css +176 -176
- {images → admin/images}/block-icon.png +0 -0
- images/header/tnp-logo-red-header.png → admin/images/logo-red.png +0 -0
- images/header/tnp-logo-white-header@2x1.png → admin/images/logo-white.png +0 -0
- {images → admin/images}/menu-icon.png +0 -0
- {images → admin/images}/subject/android.png +0 -0
- {images → admin/images}/subject/gmail.png +0 -0
- {images → admin/images}/subject/iphone.png +0 -0
- admin/modal.css +188 -189
- {css → admin}/tabs.css +94 -94
- {css → admin}/widgets.css +377 -377
- {css → admin}/wp-editor.css +16 -16
- css/controls-dark.css +0 -61
- emails/blocks/posts/layout-one.php +135 -135
- emails/blocks/posts/layout-two.php +208 -208
- emails/blocks/social/block.php +6 -2
- emails/blocks/social/options.php +13 -9
- emails/emails.php +1410 -1410
- {images → emails/images}/arrow.png +0 -0
- {images → emails/images}/theme-screenshot.png +0 -0
- emails/new.php +174 -174
- emails/tnp-composer/_css/newsletter-builder-v2.css +1173 -1173
- emails/tnp-composer/_scripts/newsletter-builder-v2.js +980 -980
- emails/tnp-composer/blocks/_/content-01-hero.block.php +0 -48
- emails/tnp-composer/blocks/_/content-01-hero.block.png +0 -0
- emails/tnp-composer/css/backend.css +43 -40
- emails/tnp-composer/css/newsletter.css +38 -91
- emails/tnp-composer/css/newsletter.min.css +0 -1
- emails/tnp-composer/index-v2.php +198 -198
- emails/tnp-composer/modal/attachment.php +19 -19
- images/animated-overlay.gif +0 -0
- images/cd-icon-navigation.svg +0 -50
- images/errors.png +0 -0
- images/facebook.png +0 -0
- images/header/debug.png +0 -0
- images/header/documentation.png +0 -0
- images/header/facebook.png +0 -0
- images/header/forum.png +0 -0
- images/header/logo.png +0 -0
- images/header/tnp-logo-white-header.png +0 -0
- images/idea.svg +0 -1
- images/img-1.jpg +0 -0
- images/img-2.jpg +0 -0
- images/img-3.jpg +0 -0
- images/img-4.jpg +0 -0
- images/messages.png +0 -0
- images/modal-background.png +0 -0
- images/popup/bg.png +0 -0
- images/popup/button.png +0 -0
- images/preamble.png +0 -0
- images/social-1/discord.png +0 -0
- images/social-1/facebook.png +0 -0
- images/social-1/instagram.png +0 -0
- images/social-1/linkedin.png +0 -0
- images/social-1/pinterest.png +0 -0
- images/social-1/soundcloud.png +0 -0
- images/social-1/telegram.png +0 -0
- images/social-1/tiktok.png +0 -0
- images/social-1/tumblr.png +0 -0
- images/social-1/twitch.png +0 -0
- images/social-1/twitter.png +0 -0
- images/social-1/vimeo.png +0 -0
- images/social-1/vk.png +0 -0
- images/social-1/youtube.png +0 -0
- images/social-2/discord.png +0 -0
- images/social-2/facebook.png +0 -0
- images/social-2/instagram.png +0 -0
- images/social-2/linkedin.png +0 -0
- images/social-2/pinterest.png +0 -0
- images/social-2/soundcloud.png +0 -0
- images/social-2/telegram.png +0 -0
- images/social-2/tiktok.png +0 -0
- images/social-2/tumblr.png +0 -0
- images/social-2/twitch.png +0 -0
- images/social-2/twitter.png +0 -0
- images/social-2/vimeo.png +0 -0
- images/social-2/vk.png +0 -0
- images/social-2/youtube.png +0 -0
- images/tnp-logo-colore-text-white@2x.png +0 -0
- includes/controls.php +2107 -2074
- includes/cron.php +36 -0
- includes/fields.php +745 -745
- includes/system.php +263 -0
- includes/themes.php +204 -204
- includes/tnp-blocks.js +252 -252
- {css → main/css}/dashboard.css +165 -165
- {css → main/css}/welcome.css +348 -348
- main/delivery.php +0 -1
- main/diagnostic.php +0 -84
- main/index.php +318 -318
- main/js/main.js +0 -178
- main/js/{snap.svg-min.js → welcome.js} +200 -21
- main/logs.php +58 -57
- main/scheduler.php +411 -0
- main/status.php +1189 -1458
- main/welcome.php +255 -256
- plugin.php +19 -97
- readme.txt +2 -1
admin/admin-dark.css
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
@import "css/controls-dark.css";
|
2 |
-
|
3 |
-
#tnp-body {
|
4 |
-
background-color: transparent;
|
5 |
-
}
|
6 |
-
|
7 |
-
/* Tabs */
|
8 |
-
#tnp-body #tabs p {
|
9 |
-
color: #999;
|
10 |
-
}
|
11 |
-
|
12 |
-
#tnp-body #tabs .ui-tabs-panel {
|
13 |
-
background-color: transparent;
|
14 |
-
padding-left: 0 !important;
|
15 |
-
}
|
16 |
-
|
17 |
-
#tnp-body #tabs .ui-widget-header .ui-state-default {
|
18 |
-
background-color: transparent;
|
19 |
-
}
|
20 |
-
|
21 |
-
#tnp-body #tabs .ui-widget-header .ui-state-default a {
|
22 |
-
color: #fff;
|
23 |
-
}
|
24 |
-
|
25 |
-
#tnp-body #tabs .ui-widget-header .ui-state-active a {
|
26 |
-
color: #fff;
|
27 |
-
background-color: #28313C;
|
28 |
-
}
|
29 |
-
|
30 |
-
#tnp-body #tabs h3,
|
31 |
-
#tnp-body #tabs h4 {
|
32 |
-
color: #fff;
|
33 |
-
}
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{css → admin}/controls.css
RENAMED
@@ -1,171 +1,171 @@
|
|
1 |
-
/* Classes used by controls. Should be prefixed with "tnpc-" */
|
2 |
-
|
3 |
-
|
4 |
-
/* Top page messages */
|
5 |
-
.tnpc-error, .tnpc-warning, .tnpc-message,
|
6 |
-
.tnp-error, .tnp-warning, .tnp-message {
|
7 |
-
background-color: #fff;
|
8 |
-
padding: 15px;
|
9 |
-
margin: 15px 0;
|
10 |
-
font-size: 1.2em;
|
11 |
-
line-height: 1.5em;
|
12 |
-
margin-left: 10px;
|
13 |
-
}
|
14 |
-
|
15 |
-
.tnpc-error, .tnp-error {
|
16 |
-
border-left: 5px solid #dd0000;
|
17 |
-
}
|
18 |
-
|
19 |
-
.tnpc-warning, .tnp-warning {
|
20 |
-
border-left: 5px solid #ffb900;
|
21 |
-
}
|
22 |
-
|
23 |
-
.tnpc-message, .tnp-message {
|
24 |
-
border-left: 5px solid #46b450;
|
25 |
-
}
|
26 |
-
|
27 |
-
|
28 |
-
/* Structure */
|
29 |
-
|
30 |
-
/* Tables with controls */
|
31 |
-
#tnp-body .form-table {
|
32 |
-
background-color: #fff;
|
33 |
-
border: 1px solid #ECF0F1;
|
34 |
-
margin-top: 2em;
|
35 |
-
border-spacing: 4px;
|
36 |
-
border-collapse: separate;
|
37 |
-
}
|
38 |
-
|
39 |
-
#tnp-body .form-table h4,
|
40 |
-
#tnp-body .form-table h3 {
|
41 |
-
color: #444;
|
42 |
-
}
|
43 |
-
|
44 |
-
/* WP has different padding for TH and TD (why???) */
|
45 |
-
#tnp-body .form-table th, #tnp-body .form-table td {
|
46 |
-
padding: 15px;
|
47 |
-
}
|
48 |
-
|
49 |
-
#tnp-body .form-table th {
|
50 |
-
text-align: right;
|
51 |
-
font-weight: bold;
|
52 |
-
max-width: 200px;
|
53 |
-
color: #000000;
|
54 |
-
background-color: #ECF0F1;
|
55 |
-
vertical-align: middle;
|
56 |
-
}
|
57 |
-
|
58 |
-
#tnp-body .form-table th small {
|
59 |
-
font-weight: normal;
|
60 |
-
}
|
61 |
-
|
62 |
-
#tnp-body .form-table textarea {
|
63 |
-
width: 100%;
|
64 |
-
}
|
65 |
-
|
66 |
-
/* Subtables contained in a main form table TD */
|
67 |
-
#tnp-body .form-table td table {
|
68 |
-
border: 0;
|
69 |
-
border-collapse: collapse;
|
70 |
-
}
|
71 |
-
|
72 |
-
#tnp-body .form-table td table th {
|
73 |
-
background-color: transparent;
|
74 |
-
text-align: right;
|
75 |
-
width: auto;
|
76 |
-
border: 0;
|
77 |
-
padding: 3px;
|
78 |
-
font-weight: normal;
|
79 |
-
vertical-align: middle;
|
80 |
-
padding-right: 15px;
|
81 |
-
}
|
82 |
-
|
83 |
-
#tnp-body .form-table td table td {
|
84 |
-
background-color: transparent;
|
85 |
-
border: 0;
|
86 |
-
padding: 3px;
|
87 |
-
vertical-align: middle;
|
88 |
-
}
|
89 |
-
|
90 |
-
#tnp-body .form-table td table.widefat th {
|
91 |
-
background-color: transparent;
|
92 |
-
text-align: left;
|
93 |
-
width: auto;
|
94 |
-
padding: 5px;
|
95 |
-
font-weight: normal;
|
96 |
-
}
|
97 |
-
|
98 |
-
#tnp-body .form-table td table.widefat td {
|
99 |
-
background-color: transparent;
|
100 |
-
padding: 5px;
|
101 |
-
vertical-align: middle;
|
102 |
-
}
|
103 |
-
|
104 |
-
/* Fix for select 2 */
|
105 |
-
#tnp-body .form-table td ul {
|
106 |
-
margin-left: 0;
|
107 |
-
}
|
108 |
-
|
109 |
-
|
110 |
-
/* Set of checkboxes */
|
111 |
-
.tnpc-checkboxes label {
|
112 |
-
display: block;
|
113 |
-
float: left;
|
114 |
-
width: 250px;
|
115 |
-
border: 1px solid #ccc;
|
116 |
-
background-color: #f4f4f4;
|
117 |
-
margin-bottom: 5px;
|
118 |
-
padding: 5px;
|
119 |
-
white-space: nowrap;
|
120 |
-
margin-right: 5px;
|
121 |
-
overflow: hidden;
|
122 |
-
}
|
123 |
-
|
124 |
-
.tnpc-lists label {
|
125 |
-
display: block;
|
126 |
-
padding: 5px 0;
|
127 |
-
}
|
128 |
-
|
129 |
-
.tnpc-lists label span {
|
130 |
-
border-radius: 3px;
|
131 |
-
color: #fff;
|
132 |
-
background-color: #aaa;
|
133 |
-
display: inline-block;
|
134 |
-
padding: 1px 5px;
|
135 |
-
min-width: 2em;
|
136 |
-
font-size: .9em;
|
137 |
-
text-align: center;
|
138 |
-
}
|
139 |
-
|
140 |
-
|
141 |
-
/* Hint text after a field */
|
142 |
-
.tnpc-hint, p.description {
|
143 |
-
margin-top: 15px;
|
144 |
-
clear: both;
|
145 |
-
font-size: 12px !important;
|
146 |
-
color: #666;
|
147 |
-
font-style: italic;
|
148 |
-
}
|
149 |
-
|
150 |
-
/* Color picker */
|
151 |
-
.tnpc-color {
|
152 |
-
width: 40px;
|
153 |
-
font-size: 12px;
|
154 |
-
}
|
155 |
-
|
156 |
-
/* Buttons */
|
157 |
-
.tnpc-button, .tnpc-button:visited, .tnpc-button:hover, .tnpc-button:active {
|
158 |
-
min-width: 3em;
|
159 |
-
text-align: center;
|
160 |
-
color: #fff!important;
|
161 |
-
width: auto;
|
162 |
-
}
|
163 |
-
|
164 |
-
/* Lists select with triggers */
|
165 |
-
.tnpc_lists_notes {
|
166 |
-
color: #999;
|
167 |
-
font-size: .9em;
|
168 |
-
padding: 0px 0 0 15px;
|
169 |
-
border-left: 3px solid #888;
|
170 |
-
margin-top: 10px;
|
171 |
}
|
1 |
+
/* Classes used by controls. Should be prefixed with "tnpc-" */
|
2 |
+
|
3 |
+
|
4 |
+
/* Top page messages */
|
5 |
+
.tnpc-error, .tnpc-warning, .tnpc-message,
|
6 |
+
.tnp-error, .tnp-warning, .tnp-message {
|
7 |
+
background-color: #fff;
|
8 |
+
padding: 15px;
|
9 |
+
margin: 15px 0;
|
10 |
+
font-size: 1.2em;
|
11 |
+
line-height: 1.5em;
|
12 |
+
margin-left: 10px;
|
13 |
+
}
|
14 |
+
|
15 |
+
.tnpc-error, .tnp-error {
|
16 |
+
border-left: 5px solid #dd0000;
|
17 |
+
}
|
18 |
+
|
19 |
+
.tnpc-warning, .tnp-warning {
|
20 |
+
border-left: 5px solid #ffb900;
|
21 |
+
}
|
22 |
+
|
23 |
+
.tnpc-message, .tnp-message {
|
24 |
+
border-left: 5px solid #46b450;
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
/* Structure */
|
29 |
+
|
30 |
+
/* Tables with controls */
|
31 |
+
#tnp-body .form-table {
|
32 |
+
background-color: #fff;
|
33 |
+
border: 1px solid #ECF0F1;
|
34 |
+
margin-top: 2em;
|
35 |
+
border-spacing: 4px;
|
36 |
+
border-collapse: separate;
|
37 |
+
}
|
38 |
+
|
39 |
+
#tnp-body .form-table h4,
|
40 |
+
#tnp-body .form-table h3 {
|
41 |
+
color: #444;
|
42 |
+
}
|
43 |
+
|
44 |
+
/* WP has different padding for TH and TD (why???) */
|
45 |
+
#tnp-body .form-table th, #tnp-body .form-table td {
|
46 |
+
padding: 15px;
|
47 |
+
}
|
48 |
+
|
49 |
+
#tnp-body .form-table th {
|
50 |
+
text-align: right;
|
51 |
+
font-weight: bold;
|
52 |
+
max-width: 200px;
|
53 |
+
color: #000000;
|
54 |
+
background-color: #ECF0F1;
|
55 |
+
vertical-align: middle;
|
56 |
+
}
|
57 |
+
|
58 |
+
#tnp-body .form-table th small {
|
59 |
+
font-weight: normal;
|
60 |
+
}
|
61 |
+
|
62 |
+
#tnp-body .form-table textarea {
|
63 |
+
width: 100%;
|
64 |
+
}
|
65 |
+
|
66 |
+
/* Subtables contained in a main form table TD */
|
67 |
+
#tnp-body .form-table td table {
|
68 |
+
border: 0;
|
69 |
+
border-collapse: collapse;
|
70 |
+
}
|
71 |
+
|
72 |
+
#tnp-body .form-table td table th {
|
73 |
+
background-color: transparent;
|
74 |
+
text-align: right;
|
75 |
+
width: auto;
|
76 |
+
border: 0;
|
77 |
+
padding: 3px;
|
78 |
+
font-weight: normal;
|
79 |
+
vertical-align: middle;
|
80 |
+
padding-right: 15px;
|
81 |
+
}
|
82 |
+
|
83 |
+
#tnp-body .form-table td table td {
|
84 |
+
background-color: transparent;
|
85 |
+
border: 0;
|
86 |
+
padding: 3px;
|
87 |
+
vertical-align: middle;
|
88 |
+
}
|
89 |
+
|
90 |
+
#tnp-body .form-table td table.widefat th {
|
91 |
+
background-color: transparent;
|
92 |
+
text-align: left;
|
93 |
+
width: auto;
|
94 |
+
padding: 5px;
|
95 |
+
font-weight: normal;
|
96 |
+
}
|
97 |
+
|
98 |
+
#tnp-body .form-table td table.widefat td {
|
99 |
+
background-color: transparent;
|
100 |
+
padding: 5px;
|
101 |
+
vertical-align: middle;
|
102 |
+
}
|
103 |
+
|
104 |
+
/* Fix for select 2 */
|
105 |
+
#tnp-body .form-table td ul {
|
106 |
+
margin-left: 0;
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
/* Set of checkboxes */
|
111 |
+
.tnpc-checkboxes label {
|
112 |
+
display: block;
|
113 |
+
float: left;
|
114 |
+
width: 250px;
|
115 |
+
border: 1px solid #ccc;
|
116 |
+
background-color: #f4f4f4;
|
117 |
+
margin-bottom: 5px;
|
118 |
+
padding: 5px;
|
119 |
+
white-space: nowrap;
|
120 |
+
margin-right: 5px;
|
121 |
+
overflow: hidden;
|
122 |
+
}
|
123 |
+
|
124 |
+
.tnpc-lists label {
|
125 |
+
display: block;
|
126 |
+
padding: 5px 0;
|
127 |
+
}
|
128 |
+
|
129 |
+
.tnpc-lists label span {
|
130 |
+
border-radius: 3px;
|
131 |
+
color: #fff;
|
132 |
+
background-color: #aaa;
|
133 |
+
display: inline-block;
|
134 |
+
padding: 1px 5px;
|
135 |
+
min-width: 2em;
|
136 |
+
font-size: .9em;
|
137 |
+
text-align: center;
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
/* Hint text after a field */
|
142 |
+
.tnpc-hint, p.description {
|
143 |
+
margin-top: 15px;
|
144 |
+
clear: both;
|
145 |
+
font-size: 12px !important;
|
146 |
+
color: #666;
|
147 |
+
font-style: italic;
|
148 |
+
}
|
149 |
+
|
150 |
+
/* Color picker */
|
151 |
+
.tnpc-color {
|
152 |
+
width: 40px;
|
153 |
+
font-size: 12px;
|
154 |
+
}
|
155 |
+
|
156 |
+
/* Buttons */
|
157 |
+
.tnpc-button, .tnpc-button:visited, .tnpc-button:hover, .tnpc-button:active {
|
158 |
+
min-width: 3em;
|
159 |
+
text-align: center;
|
160 |
+
color: #fff!important;
|
161 |
+
width: auto;
|
162 |
+
}
|
163 |
+
|
164 |
+
/* Lists select with triggers */
|
165 |
+
.tnpc_lists_notes {
|
166 |
+
color: #999;
|
167 |
+
font-size: .9em;
|
168 |
+
padding: 0px 0 0 15px;
|
169 |
+
border-left: 3px solid #888;
|
170 |
+
margin-top: 10px;
|
171 |
}
|
{css → admin}/dropdown.css
RENAMED
@@ -1,138 +1,138 @@
|
|
1 |
-
.tnp-drowpdown ul, .tnp-drowpdown li {
|
2 |
-
margin: 0; padding: 0; border: 0;
|
3 |
-
}
|
4 |
-
|
5 |
-
.tnp-drowpdown {
|
6 |
-
margin-top: 10px;
|
7 |
-
-webkit-transition-timing-function: ease;
|
8 |
-
padding: 5px;
|
9 |
-
font-size: 12px;
|
10 |
-
margin-bottom: 10px;
|
11 |
-
color: #fff;
|
12 |
-
}
|
13 |
-
|
14 |
-
.tnp-drowpdown a {
|
15 |
-
text-decoration: none;
|
16 |
-
color: white;
|
17 |
-
letter-spacing: 0.1em;
|
18 |
-
}
|
19 |
-
|
20 |
-
.tnp-drowpdown a:hover {
|
21 |
-
color: #fff;
|
22 |
-
}
|
23 |
-
|
24 |
-
.tnp-drowpdown {
|
25 |
-
-webkit-transition: width 2s;
|
26 |
-
transition: width 2s;
|
27 |
-
}
|
28 |
-
|
29 |
-
.tnp-drowpdown ul ul {
|
30 |
-
display: none;
|
31 |
-
z-index: 10000;
|
32 |
-
}
|
33 |
-
|
34 |
-
.tnp-drowpdown ul li:hover > ul {
|
35 |
-
display: block;
|
36 |
-
}
|
37 |
-
|
38 |
-
.tnp-drowpdown ul {
|
39 |
-
padding: 0 20px;
|
40 |
-
list-style: none;
|
41 |
-
position: relative;
|
42 |
-
display: inline-table;
|
43 |
-
}
|
44 |
-
.tnp-drowpdown ul:after {
|
45 |
-
content: "";
|
46 |
-
clear: both;
|
47 |
-
display: block;
|
48 |
-
}
|
49 |
-
|
50 |
-
.tnp-drowpdown ul li {
|
51 |
-
float: left;
|
52 |
-
margin-left: 10px;
|
53 |
-
text-transform: uppercase;
|
54 |
-
-webkit-transition: all 0.2s ease-in-out;
|
55 |
-
-moz-transition: all 0.2s ease-in-out;
|
56 |
-
-o-transition: all 0.2s ease-in-out;
|
57 |
-
transition: all 0.2s ease-in-out;
|
58 |
-
}
|
59 |
-
.tnp-drowpdown ul li:hover {
|
60 |
-
background-color: #34495E;
|
61 |
-
/*border: 1px solid #34495E;*/
|
62 |
-
}
|
63 |
-
|
64 |
-
.tnp-drowpdown ul li a {
|
65 |
-
display: block;
|
66 |
-
padding: 10px 10px;
|
67 |
-
text-decoration: none;
|
68 |
-
}
|
69 |
-
|
70 |
-
.tnp-drowpdown ul li a small {
|
71 |
-
display: block;
|
72 |
-
color: #afafaf;
|
73 |
-
float: none !important;
|
74 |
-
}
|
75 |
-
|
76 |
-
.tnp-drowpdown ul ul {
|
77 |
-
background: #332D39;
|
78 |
-
border-radius: 0px;
|
79 |
-
padding: 0;
|
80 |
-
position: absolute;
|
81 |
-
}
|
82 |
-
.tnp-drowpdown ul ul li {
|
83 |
-
float: none;
|
84 |
-
position: relative;
|
85 |
-
margin-left: 0;
|
86 |
-
border: none;
|
87 |
-
text-transform: none;
|
88 |
-
line-height: 1.6em;
|
89 |
-
}
|
90 |
-
|
91 |
-
.tnp-drowpdown ul ul li:nth-child(even) {
|
92 |
-
background-color: #3b3342;
|
93 |
-
}
|
94 |
-
|
95 |
-
.tnp-drowpdown ul ul li:hover {
|
96 |
-
background: inherit;
|
97 |
-
}
|
98 |
-
.tnp-drowpdown ul ul li a {
|
99 |
-
padding: 5px 15px;
|
100 |
-
color: #fff;
|
101 |
-
}
|
102 |
-
.tnp-drowpdown ul ul li a:hover {
|
103 |
-
background: #34495E;
|
104 |
-
}
|
105 |
-
|
106 |
-
.tnp-drowpdown ul ul ul {
|
107 |
-
position: absolute; left: 100%; top:0;
|
108 |
-
}
|
109 |
-
|
110 |
-
.tnp-professional-extensions-button {
|
111 |
-
background-color: #27AE60;
|
112 |
-
border: 1px solid #27AE60 !important;
|
113 |
-
-webkit-transition: all 1s ease-in-out;
|
114 |
-
-moz-transition: all 1s ease-in-out;
|
115 |
-
-o-transition: all 1s ease-in-out;
|
116 |
-
transition: all 1s ease-in-out;
|
117 |
-
border-radius: 3px;
|
118 |
-
}
|
119 |
-
|
120 |
-
.tnp-professional-extensions-button:hover {
|
121 |
-
background-color: #2ECC71 !important;
|
122 |
-
border: 1px solid #2ECC71 !important;
|
123 |
-
}
|
124 |
-
|
125 |
-
.tnp-professional-extensions-button-red {
|
126 |
-
background-color: #C0392B;
|
127 |
-
border: 1px solid #C0392B !important;
|
128 |
-
-webkit-transition: all 1s ease-in-out;
|
129 |
-
-moz-transition: all 1s ease-in-out;
|
130 |
-
-o-transition: all 1s ease-in-out;
|
131 |
-
transition: all 1s ease-in-out;
|
132 |
-
border-radius: 3px;
|
133 |
-
}
|
134 |
-
|
135 |
-
.tnp-professional-extensions-button-red:hover {
|
136 |
-
background-color: #E74C3C !important;
|
137 |
-
border: 1px solid #E74C3C !important;
|
138 |
}
|
1 |
+
.tnp-drowpdown ul, .tnp-drowpdown li {
|
2 |
+
margin: 0; padding: 0; border: 0;
|
3 |
+
}
|
4 |
+
|
5 |
+
.tnp-drowpdown {
|
6 |
+
margin-top: 10px;
|
7 |
+
-webkit-transition-timing-function: ease;
|
8 |
+
padding: 5px;
|
9 |
+
font-size: 12px;
|
10 |
+
margin-bottom: 10px;
|
11 |
+
color: #fff;
|
12 |
+
}
|
13 |
+
|
14 |
+
.tnp-drowpdown a {
|
15 |
+
text-decoration: none;
|
16 |
+
color: white;
|
17 |
+
letter-spacing: 0.1em;
|
18 |
+
}
|
19 |
+
|
20 |
+
.tnp-drowpdown a:hover {
|
21 |
+
color: #fff;
|
22 |
+
}
|
23 |
+
|
24 |
+
.tnp-drowpdown {
|
25 |
+
-webkit-transition: width 2s;
|
26 |
+
transition: width 2s;
|
27 |
+
}
|
28 |
+
|
29 |
+
.tnp-drowpdown ul ul {
|
30 |
+
display: none;
|
31 |
+
z-index: 10000;
|
32 |
+
}
|
33 |
+
|
34 |
+
.tnp-drowpdown ul li:hover > ul {
|
35 |
+
display: block;
|
36 |
+
}
|
37 |
+
|
38 |
+
.tnp-drowpdown ul {
|
39 |
+
padding: 0 20px;
|
40 |
+
list-style: none;
|
41 |
+
position: relative;
|
42 |
+
display: inline-table;
|
43 |
+
}
|
44 |
+
.tnp-drowpdown ul:after {
|
45 |
+
content: "";
|
46 |
+
clear: both;
|
47 |
+
display: block;
|
48 |
+
}
|
49 |
+
|
50 |
+
.tnp-drowpdown ul li {
|
51 |
+
float: left;
|
52 |
+
margin-left: 10px;
|
53 |
+
text-transform: uppercase;
|
54 |
+
-webkit-transition: all 0.2s ease-in-out;
|
55 |
+
-moz-transition: all 0.2s ease-in-out;
|
56 |
+
-o-transition: all 0.2s ease-in-out;
|
57 |
+
transition: all 0.2s ease-in-out;
|
58 |
+
}
|
59 |
+
.tnp-drowpdown ul li:hover {
|
60 |
+
background-color: #34495E;
|
61 |
+
/*border: 1px solid #34495E;*/
|
62 |
+
}
|
63 |
+
|
64 |
+
.tnp-drowpdown ul li a {
|
65 |
+
display: block;
|
66 |
+
padding: 10px 10px;
|
67 |
+
text-decoration: none;
|
68 |
+
}
|
69 |
+
|
70 |
+
.tnp-drowpdown ul li a small {
|
71 |
+
display: block;
|
72 |
+
color: #afafaf;
|
73 |
+
float: none !important;
|
74 |
+
}
|
75 |
+
|
76 |
+
.tnp-drowpdown ul ul {
|
77 |
+
background: #332D39;
|
78 |
+
border-radius: 0px;
|
79 |
+
padding: 0;
|
80 |
+
position: absolute;
|
81 |
+
}
|
82 |
+
.tnp-drowpdown ul ul li {
|
83 |
+
float: none;
|
84 |
+
position: relative;
|
85 |
+
margin-left: 0;
|
86 |
+
border: none;
|
87 |
+
text-transform: none;
|
88 |
+
line-height: 1.6em;
|
89 |
+
}
|
90 |
+
|
91 |
+
.tnp-drowpdown ul ul li:nth-child(even) {
|
92 |
+
background-color: #3b3342;
|
93 |
+
}
|
94 |
+
|
95 |
+
.tnp-drowpdown ul ul li:hover {
|
96 |
+
background: inherit;
|
97 |
+
}
|
98 |
+
.tnp-drowpdown ul ul li a {
|
99 |
+
padding: 5px 15px;
|
100 |
+
color: #fff;
|
101 |
+
}
|
102 |
+
.tnp-drowpdown ul ul li a:hover {
|
103 |
+
background: #34495E;
|
104 |
+
}
|
105 |
+
|
106 |
+
.tnp-drowpdown ul ul ul {
|
107 |
+
position: absolute; left: 100%; top:0;
|
108 |
+
}
|
109 |
+
|
110 |
+
.tnp-professional-extensions-button {
|
111 |
+
background-color: #27AE60;
|
112 |
+
border: 1px solid #27AE60 !important;
|
113 |
+
-webkit-transition: all 1s ease-in-out;
|
114 |
+
-moz-transition: all 1s ease-in-out;
|
115 |
+
-o-transition: all 1s ease-in-out;
|
116 |
+
transition: all 1s ease-in-out;
|
117 |
+
border-radius: 3px;
|
118 |
+
}
|
119 |
+
|
120 |
+
.tnp-professional-extensions-button:hover {
|
121 |
+
background-color: #2ECC71 !important;
|
122 |
+
border: 1px solid #2ECC71 !important;
|
123 |
+
}
|
124 |
+
|
125 |
+
.tnp-professional-extensions-button-red {
|
126 |
+
background-color: #C0392B;
|
127 |
+
border: 1px solid #C0392B !important;
|
128 |
+
-webkit-transition: all 1s ease-in-out;
|
129 |
+
-moz-transition: all 1s ease-in-out;
|
130 |
+
-o-transition: all 1s ease-in-out;
|
131 |
+
transition: all 1s ease-in-out;
|
132 |
+
border-radius: 3px;
|
133 |
+
}
|
134 |
+
|
135 |
+
.tnp-professional-extensions-button-red:hover {
|
136 |
+
background-color: #E74C3C !important;
|
137 |
+
border: 1px solid #E74C3C !important;
|
138 |
}
|
{css → admin}/extensions.css
RENAMED
@@ -1,152 +1,152 @@
|
|
1 |
-
/* Used even by the addons manager addon */
|
2 |
-
|
3 |
-
.tnp-extension-premium-box, .tnp-extension-free-box, .tnp-integration-box {
|
4 |
-
width: 300px;
|
5 |
-
height: 220px;
|
6 |
-
/*background-color: #222B36;*/
|
7 |
-
background-color: #28313C;
|
8 |
-
text-align: center;
|
9 |
-
margin: 20px 20px 0px 0px;
|
10 |
-
float: left;
|
11 |
-
position: relative;
|
12 |
-
}
|
13 |
-
|
14 |
-
.tnp-extension-premium-box:hover, .tnp-extension-free-box:hover, .tnp-integration-box:hover {
|
15 |
-
/*background-color: #232C35;*/
|
16 |
-
background-color: #2B343F;
|
17 |
-
box-shadow: 1px 1px 15px #222B36;
|
18 |
-
}
|
19 |
-
|
20 |
-
.tnp-extension-premium-box p, .tnp-extension-free-box p, .tnp-integration-box p {
|
21 |
-
padding: 5px 10px;
|
22 |
-
color: #72777c;
|
23 |
-
font-size: 14px;
|
24 |
-
margin-top: 0px;
|
25 |
-
}
|
26 |
-
|
27 |
-
.tnp-extension-premium-box h3 {
|
28 |
-
font-family: soleil, sans-serif;
|
29 |
-
padding: 5px 8px !important;
|
30 |
-
border-radius: 3px;
|
31 |
-
display: inline-block;
|
32 |
-
font-size: 16px;
|
33 |
-
color: #fff;
|
34 |
-
margin-bottom: 0px !important;
|
35 |
-
margin-top: 25px !important;
|
36 |
-
font-weight: 300;
|
37 |
-
width: auto !important;
|
38 |
-
border-bottom: none !important;
|
39 |
-
}
|
40 |
-
|
41 |
-
.tnp-extension-free-box h3 {
|
42 |
-
font-family: soleil, sans-serif;
|
43 |
-
padding: 5px 8px !important;
|
44 |
-
border-radius: 3px;
|
45 |
-
display: inline-block;
|
46 |
-
font-size: 16px;
|
47 |
-
color: #fff;
|
48 |
-
margin-bottom: 0px !important;
|
49 |
-
margin-top: 25px !important;
|
50 |
-
font-weight: 300;
|
51 |
-
width: auto !important;
|
52 |
-
border-bottom: none !important;
|
53 |
-
}
|
54 |
-
|
55 |
-
.tnp-integration-box h3 {
|
56 |
-
font-family: soleil, sans-serif;
|
57 |
-
padding: 5px 8px !important;
|
58 |
-
border-radius: 3px;
|
59 |
-
display: inline-block;
|
60 |
-
font-size: 16px;
|
61 |
-
color: #fff;
|
62 |
-
margin-bottom: 0px !important;
|
63 |
-
margin-top: 25px !important;
|
64 |
-
font-weight: 300;
|
65 |
-
width: auto !important;
|
66 |
-
border-bottom: none !important;
|
67 |
-
}
|
68 |
-
|
69 |
-
.tnp-extension-premium-action {
|
70 |
-
bottom: 0;
|
71 |
-
position: absolute;
|
72 |
-
width: 100%;
|
73 |
-
padding: 12px;
|
74 |
-
font-family: soleil, sans-serif;
|
75 |
-
}
|
76 |
-
|
77 |
-
.tnp-extension-free-action {
|
78 |
-
bottom: 0;
|
79 |
-
position: absolute;
|
80 |
-
width: 100%;
|
81 |
-
padding: 12px;
|
82 |
-
font-family: soleil, sans-serif;
|
83 |
-
}
|
84 |
-
|
85 |
-
.tnp-integration-action {
|
86 |
-
bottom: 0;
|
87 |
-
position: absolute;
|
88 |
-
width: 100%;
|
89 |
-
padding: 12px;
|
90 |
-
font-family: soleil, sans-serif;
|
91 |
-
}
|
92 |
-
|
93 |
-
|
94 |
-
.tnp-extension-premium-action span {
|
95 |
-
color: #27AE60;
|
96 |
-
}
|
97 |
-
|
98 |
-
.tnp-extension-free-action span {
|
99 |
-
color: #27AE60;
|
100 |
-
}
|
101 |
-
|
102 |
-
.tnp-integration-action span {
|
103 |
-
color: #27AE60;
|
104 |
-
}
|
105 |
-
|
106 |
-
.tnp-extension-activate {
|
107 |
-
color: #1ABC9C;
|
108 |
-
padding: 5px 8px;
|
109 |
-
text-decoration: none;
|
110 |
-
cursor: pointer;
|
111 |
-
}
|
112 |
-
|
113 |
-
.tnp-extension-install {
|
114 |
-
color: #2980B9;
|
115 |
-
padding: 5px 8px;
|
116 |
-
text-decoration: none;
|
117 |
-
cursor: pointer;
|
118 |
-
}
|
119 |
-
|
120 |
-
.tnp-extension-buy {
|
121 |
-
color: #F1C40F;
|
122 |
-
padding: 5px 8px;
|
123 |
-
text-decoration: none;
|
124 |
-
cursor: pointer;
|
125 |
-
}
|
126 |
-
|
127 |
-
#tnp-body a.tnp-extension-details{
|
128 |
-
color: #999999;
|
129 |
-
padding: 5px 8px;
|
130 |
-
text-decoration: none;
|
131 |
-
cursor: pointer;
|
132 |
-
}
|
133 |
-
|
134 |
-
.tnp-extension-free {
|
135 |
-
color: #D35400;
|
136 |
-
padding: 5px 8px;
|
137 |
-
text-decoration: none;
|
138 |
-
cursor: pointer;
|
139 |
-
position: relative;
|
140 |
-
}
|
141 |
-
|
142 |
-
img.tnp-extensions-free-badge {
|
143 |
-
position: absolute;
|
144 |
-
display: block;
|
145 |
-
right: 0;
|
146 |
-
top: 0;
|
147 |
-
width: 70px;
|
148 |
-
}
|
149 |
-
|
150 |
-
.tnp-extensions-image img {
|
151 |
-
margin: 25px 0px -10px;
|
152 |
-
}
|
1 |
+
/* Used even by the addons manager addon */
|
2 |
+
|
3 |
+
.tnp-extension-premium-box, .tnp-extension-free-box, .tnp-integration-box {
|
4 |
+
width: 300px;
|
5 |
+
height: 220px;
|
6 |
+
/*background-color: #222B36;*/
|
7 |
+
background-color: #28313C;
|
8 |
+
text-align: center;
|
9 |
+
margin: 20px 20px 0px 0px;
|
10 |
+
float: left;
|
11 |
+
position: relative;
|
12 |
+
}
|
13 |
+
|
14 |
+
.tnp-extension-premium-box:hover, .tnp-extension-free-box:hover, .tnp-integration-box:hover {
|
15 |
+
/*background-color: #232C35;*/
|
16 |
+
background-color: #2B343F;
|
17 |
+
box-shadow: 1px 1px 15px #222B36;
|
18 |
+
}
|
19 |
+
|
20 |
+
.tnp-extension-premium-box p, .tnp-extension-free-box p, .tnp-integration-box p {
|
21 |
+
padding: 5px 10px;
|
22 |
+
color: #72777c;
|
23 |
+
font-size: 14px;
|
24 |
+
margin-top: 0px;
|
25 |
+
}
|
26 |
+
|
27 |
+
.tnp-extension-premium-box h3 {
|
28 |
+
font-family: soleil, sans-serif;
|
29 |
+
padding: 5px 8px !important;
|
30 |
+
border-radius: 3px;
|
31 |
+
display: inline-block;
|
32 |
+
font-size: 16px;
|
33 |
+
color: #fff;
|
34 |
+
margin-bottom: 0px !important;
|
35 |
+
margin-top: 25px !important;
|
36 |
+
font-weight: 300;
|
37 |
+
width: auto !important;
|
38 |
+
border-bottom: none !important;
|
39 |
+
}
|
40 |
+
|
41 |
+
.tnp-extension-free-box h3 {
|
42 |
+
font-family: soleil, sans-serif;
|
43 |
+
padding: 5px 8px !important;
|
44 |
+
border-radius: 3px;
|
45 |
+
display: inline-block;
|
46 |
+
font-size: 16px;
|
47 |
+
color: #fff;
|
48 |
+
margin-bottom: 0px !important;
|
49 |
+
margin-top: 25px !important;
|
50 |
+
font-weight: 300;
|
51 |
+
width: auto !important;
|
52 |
+
border-bottom: none !important;
|
53 |
+
}
|
54 |
+
|
55 |
+
.tnp-integration-box h3 {
|
56 |
+
font-family: soleil, sans-serif;
|
57 |
+
padding: 5px 8px !important;
|
58 |
+
border-radius: 3px;
|
59 |
+
display: inline-block;
|
60 |
+
font-size: 16px;
|
61 |
+
color: #fff;
|
62 |
+
margin-bottom: 0px !important;
|
63 |
+
margin-top: 25px !important;
|
64 |
+
font-weight: 300;
|
65 |
+
width: auto !important;
|
66 |
+
border-bottom: none !important;
|
67 |
+
}
|
68 |
+
|
69 |
+
.tnp-extension-premium-action {
|
70 |
+
bottom: 0;
|
71 |
+
position: absolute;
|
72 |
+
width: 100%;
|
73 |
+
padding: 12px;
|
74 |
+
font-family: soleil, sans-serif;
|
75 |
+
}
|
76 |
+
|
77 |
+
.tnp-extension-free-action {
|
78 |
+
bottom: 0;
|
79 |
+
position: absolute;
|
80 |
+
width: 100%;
|
81 |
+
padding: 12px;
|
82 |
+
font-family: soleil, sans-serif;
|
83 |
+
}
|
84 |
+
|
85 |
+
.tnp-integration-action {
|
86 |
+
bottom: 0;
|
87 |
+
position: absolute;
|
88 |
+
width: 100%;
|
89 |
+
padding: 12px;
|
90 |
+
font-family: soleil, sans-serif;
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
.tnp-extension-premium-action span {
|
95 |
+
color: #27AE60;
|
96 |
+
}
|
97 |
+
|
98 |
+
.tnp-extension-free-action span {
|
99 |
+
color: #27AE60;
|
100 |
+
}
|
101 |
+
|
102 |
+
.tnp-integration-action span {
|
103 |
+
color: #27AE60;
|
104 |
+
}
|
105 |
+
|
106 |
+
.tnp-extension-activate {
|
107 |
+
color: #1ABC9C;
|
108 |
+
padding: 5px 8px;
|
109 |
+
text-decoration: none;
|
110 |
+
cursor: pointer;
|
111 |
+
}
|
112 |
+
|
113 |
+
.tnp-extension-install {
|
114 |
+
color: #2980B9;
|
115 |
+
padding: 5px 8px;
|
116 |
+
text-decoration: none;
|
117 |
+
cursor: pointer;
|
118 |
+
}
|
119 |
+
|
120 |
+
.tnp-extension-buy {
|
121 |
+
color: #F1C40F;
|
122 |
+
padding: 5px 8px;
|
123 |
+
text-decoration: none;
|
124 |
+
cursor: pointer;
|
125 |
+
}
|
126 |
+
|
127 |
+
#tnp-body a.tnp-extension-details{
|
128 |
+
color: #999999;
|
129 |
+
padding: 5px 8px;
|
130 |
+
text-decoration: none;
|
131 |
+
cursor: pointer;
|
132 |
+
}
|
133 |
+
|
134 |
+
.tnp-extension-free {
|
135 |
+
color: #D35400;
|
136 |
+
padding: 5px 8px;
|
137 |
+
text-decoration: none;
|
138 |
+
cursor: pointer;
|
139 |
+
position: relative;
|
140 |
+
}
|
141 |
+
|
142 |
+
img.tnp-extensions-free-badge {
|
143 |
+
position: absolute;
|
144 |
+
display: block;
|
145 |
+
right: 0;
|
146 |
+
top: 0;
|
147 |
+
width: 70px;
|
148 |
+
}
|
149 |
+
|
150 |
+
.tnp-extensions-image img {
|
151 |
+
margin: 25px 0px -10px;
|
152 |
+
}
|
{css → admin}/fields.css
RENAMED
@@ -1,176 +1,176 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
/* STRUCTURE */
|
4 |
-
.tnp-field-row {
|
5 |
-
clear: both;
|
6 |
-
margin-left: -10px;
|
7 |
-
margin-right: -10px;
|
8 |
-
}
|
9 |
-
|
10 |
-
.tnp-field-col-2 {
|
11 |
-
width: 50%;
|
12 |
-
box-sizing: border-box;
|
13 |
-
padding: 10px;
|
14 |
-
float: left;
|
15 |
-
}
|
16 |
-
|
17 |
-
.tnp-field-col-3 {
|
18 |
-
width: 33%;
|
19 |
-
box-sizing: border-box;
|
20 |
-
padding: 10px;
|
21 |
-
float: left;
|
22 |
-
}
|
23 |
-
|
24 |
-
.tnp-field-col-20 {
|
25 |
-
width: 20%;
|
26 |
-
box-sizing: border-box;
|
27 |
-
padding: 10px;
|
28 |
-
float: left;
|
29 |
-
}
|
30 |
-
|
31 |
-
.tnp-field-col-33 {
|
32 |
-
width: 33%;
|
33 |
-
box-sizing: border-box;
|
34 |
-
padding: 10px;
|
35 |
-
float: left;
|
36 |
-
}
|
37 |
-
|
38 |
-
.tnp-field-col-66 {
|
39 |
-
width: 66%;
|
40 |
-
box-sizing: border-box;
|
41 |
-
padding: 10px;
|
42 |
-
float: left;
|
43 |
-
}
|
44 |
-
|
45 |
-
.tnp-field-col-80 {
|
46 |
-
width: 80%;
|
47 |
-
box-sizing: border-box;
|
48 |
-
padding: 10px;
|
49 |
-
float: left;
|
50 |
-
}
|
51 |
-
|
52 |
-
.tnp-field-box {
|
53 |
-
padding: 10px;
|
54 |
-
background-color: #eee !important;
|
55 |
-
border: 1px solid #bbb;
|
56 |
-
}
|
57 |
-
|
58 |
-
.tnp-section {
|
59 |
-
|
60 |
-
}
|
61 |
-
|
62 |
-
.tnp-field.tnp-separator {
|
63 |
-
border-top: 1px solid #ddd;
|
64 |
-
line-height: 0;
|
65 |
-
}
|
66 |
-
|
67 |
-
/* Single field container */
|
68 |
-
.tnp-field {
|
69 |
-
display: block;
|
70 |
-
width: 100%;
|
71 |
-
margin-bottom: 10px;
|
72 |
-
}
|
73 |
-
|
74 |
-
.tnp-field select.tnp-small {
|
75 |
-
font-size: .9em;
|
76 |
-
}
|
77 |
-
|
78 |
-
.tnp-field label.tnp-label, .tnp-field-row label.tnp-row-label {
|
79 |
-
display: block;
|
80 |
-
font-size: 12px;
|
81 |
-
font-weight: 300;
|
82 |
-
border-bottom: 1px solid #fff;
|
83 |
-
margin: 10px 0px 10px 0px;
|
84 |
-
font-family: soleil, sans-serif;
|
85 |
-
font-weight: 300;
|
86 |
-
padding-bottom: 5px;
|
87 |
-
color: #868686;
|
88 |
-
}
|
89 |
-
|
90 |
-
/* Compesate the negative row margin */
|
91 |
-
.tnp-field-row label.tnp-row-label {
|
92 |
-
margin-left: 10px;
|
93 |
-
}
|
94 |
-
|
95 |
-
.tnp-field.tnp-checkbox label {
|
96 |
-
display: inline;
|
97 |
-
}
|
98 |
-
|
99 |
-
/* Set of inlined field for font, size, color... */
|
100 |
-
tnp-field.tnp-font {
|
101 |
-
|
102 |
-
}
|
103 |
-
|
104 |
-
.tnp-field:not(.tnp-colorpicker) input {
|
105 |
-
width: 100%;
|
106 |
-
}
|
107 |
-
|
108 |
-
.tnp-field input[type=number] {
|
109 |
-
width: 100px;
|
110 |
-
}
|
111 |
-
|
112 |
-
.tnp-field.tnp-size input {
|
113 |
-
width: 60px;
|
114 |
-
display: inline;
|
115 |
-
}
|
116 |
-
|
117 |
-
.tnp-field .tnp-padding-fields {
|
118 |
-
display: inline;
|
119 |
-
}
|
120 |
-
|
121 |
-
/* Four field for block padding selection */
|
122 |
-
.tnp-field .tnp-padding-fields input {
|
123 |
-
width: 40px;
|
124 |
-
display: inline;
|
125 |
-
}
|
126 |
-
|
127 |
-
.tnp-field select {
|
128 |
-
width: auto!important;
|
129 |
-
color: #34495E;
|
130 |
-
}
|
131 |
-
|
132 |
-
.tnp-field input[type=url] {
|
133 |
-
font-family: monospace;
|
134 |
-
}
|
135 |
-
|
136 |
-
.tnp-field input[type=color] {
|
137 |
-
width: 40px;
|
138 |
-
min-height: 30px;
|
139 |
-
vertical-align: middle;
|
140 |
-
}
|
141 |
-
|
142 |
-
.tnp-field input[type=submit] {
|
143 |
-
width: auto;
|
144 |
-
}
|
145 |
-
|
146 |
-
.tnp-field input[type=checkbox] {
|
147 |
-
width: auto;
|
148 |
-
}
|
149 |
-
|
150 |
-
.tnp-field.tnpf-button .tnpf-font-family {
|
151 |
-
font-size: 13px;
|
152 |
-
}
|
153 |
-
|
154 |
-
.tnp-field.tnpf-button .tnpf-font-size {
|
155 |
-
font-size: 13px;
|
156 |
-
}
|
157 |
-
|
158 |
-
.tnp-field.tnpf-button .tnpf-font-weight {
|
159 |
-
font-size: 13px;
|
160 |
-
}
|
161 |
-
|
162 |
-
.tnp-field.tnp-categories {
|
163 |
-
|
164 |
-
}
|
165 |
-
|
166 |
-
/* The label for each category checkbox (should override the generic label appearance) */
|
167 |
-
.tnp-field.tnp-categories label {
|
168 |
-
|
169 |
-
}
|
170 |
-
|
171 |
-
.tnp-description {
|
172 |
-
margin-top: 7px;
|
173 |
-
font-style: italic;
|
174 |
-
font-weight: normal;
|
175 |
-
color: #999999;
|
176 |
-
}
|
1 |
+
|
2 |
+
|
3 |
+
/* STRUCTURE */
|
4 |
+
.tnp-field-row {
|
5 |
+
clear: both;
|
6 |
+
margin-left: -10px;
|
7 |
+
margin-right: -10px;
|
8 |
+
}
|
9 |
+
|
10 |
+
.tnp-field-col-2 {
|
11 |
+
width: 50%;
|
12 |
+
box-sizing: border-box;
|
13 |
+
padding: 10px;
|
14 |
+
float: left;
|
15 |
+
}
|
16 |
+
|
17 |
+
.tnp-field-col-3 {
|
18 |
+
width: 33%;
|
19 |
+
box-sizing: border-box;
|
20 |
+
padding: 10px;
|
21 |
+
float: left;
|
22 |
+
}
|
23 |
+
|
24 |
+
.tnp-field-col-20 {
|
25 |
+
width: 20%;
|
26 |
+
box-sizing: border-box;
|
27 |
+
padding: 10px;
|
28 |
+
float: left;
|
29 |
+
}
|
30 |
+
|
31 |
+
.tnp-field-col-33 {
|
32 |
+
width: 33%;
|
33 |
+
box-sizing: border-box;
|
34 |
+
padding: 10px;
|
35 |
+
float: left;
|
36 |
+
}
|
37 |
+
|
38 |
+
.tnp-field-col-66 {
|
39 |
+
width: 66%;
|
40 |
+
box-sizing: border-box;
|
41 |
+
padding: 10px;
|
42 |
+
float: left;
|
43 |
+
}
|
44 |
+
|
45 |
+
.tnp-field-col-80 {
|
46 |
+
width: 80%;
|
47 |
+
box-sizing: border-box;
|
48 |
+
padding: 10px;
|
49 |
+
float: left;
|
50 |
+
}
|
51 |
+
|
52 |
+
.tnp-field-box {
|
53 |
+
padding: 10px;
|
54 |
+
background-color: #eee !important;
|
55 |
+
border: 1px solid #bbb;
|
56 |
+
}
|
57 |
+
|
58 |
+
.tnp-section {
|
59 |
+
|
60 |
+
}
|
61 |
+
|
62 |
+
.tnp-field.tnp-separator {
|
63 |
+
border-top: 1px solid #ddd;
|
64 |
+
line-height: 0;
|
65 |
+
}
|
66 |
+
|
67 |
+
/* Single field container */
|
68 |
+
.tnp-field {
|
69 |
+
display: block;
|
70 |
+
width: 100%;
|
71 |
+
margin-bottom: 10px;
|
72 |
+
}
|
73 |
+
|
74 |
+
.tnp-field select.tnp-small {
|
75 |
+
font-size: .9em;
|
76 |
+
}
|
77 |
+
|
78 |
+
.tnp-field label.tnp-label, .tnp-field-row label.tnp-row-label {
|
79 |
+
display: block;
|
80 |
+
font-size: 12px;
|
81 |
+
font-weight: 300;
|
82 |
+
border-bottom: 1px solid #fff;
|
83 |
+
margin: 10px 0px 10px 0px;
|
84 |
+
font-family: soleil, sans-serif;
|
85 |
+
font-weight: 300;
|
86 |
+
padding-bottom: 5px;
|
87 |
+
color: #868686;
|
88 |
+
}
|
89 |
+
|
90 |
+
/* Compesate the negative row margin */
|
91 |
+
.tnp-field-row label.tnp-row-label {
|
92 |
+
margin-left: 10px;
|
93 |
+
}
|
94 |
+
|
95 |
+
.tnp-field.tnp-checkbox label {
|
96 |
+
display: inline;
|
97 |
+
}
|
98 |
+
|
99 |
+
/* Set of inlined field for font, size, color... */
|
100 |
+
tnp-field.tnp-font {
|
101 |
+
|
102 |
+
}
|
103 |
+
|
104 |
+
.tnp-field:not(.tnp-colorpicker) input {
|
105 |
+
width: 100%;
|
106 |
+
}
|
107 |
+
|
108 |
+
.tnp-field input[type=number] {
|
109 |
+
width: 100px;
|
110 |
+
}
|
111 |
+
|
112 |
+
.tnp-field.tnp-size input {
|
113 |
+
width: 60px;
|
114 |
+
display: inline;
|
115 |
+
}
|
116 |
+
|
117 |
+
.tnp-field .tnp-padding-fields {
|
118 |
+
display: inline;
|
119 |
+
}
|
120 |
+
|
121 |
+
/* Four field for block padding selection */
|
122 |
+
.tnp-field .tnp-padding-fields input {
|
123 |
+
width: 40px;
|
124 |
+
display: inline;
|
125 |
+
}
|
126 |
+
|
127 |
+
.tnp-field select {
|
128 |
+
width: auto!important;
|
129 |
+
color: #34495E;
|
130 |
+
}
|
131 |
+
|
132 |
+
.tnp-field input[type=url] {
|
133 |
+
font-family: monospace;
|
134 |
+
}
|
135 |
+
|
136 |
+
.tnp-field input[type=color] {
|
137 |
+
width: 40px;
|
138 |
+
min-height: 30px;
|
139 |
+
vertical-align: middle;
|
140 |
+
}
|
141 |
+
|
142 |
+
.tnp-field input[type=submit] {
|
143 |
+
width: auto;
|
144 |
+
}
|
145 |
+
|
146 |
+
.tnp-field input[type=checkbox] {
|
147 |
+
width: auto;
|
148 |
+
}
|
149 |
+
|
150 |
+
.tnp-field.tnpf-button .tnpf-font-family {
|
151 |
+
font-size: 13px;
|
152 |
+
}
|
153 |
+
|
154 |
+
.tnp-field.tnpf-button .tnpf-font-size {
|
155 |
+
font-size: 13px;
|
156 |
+
}
|
157 |
+
|
158 |
+
.tnp-field.tnpf-button .tnpf-font-weight {
|
159 |
+
font-size: 13px;
|
160 |
+
}
|
161 |
+
|
162 |
+
.tnp-field.tnp-categories {
|
163 |
+
|
164 |
+
}
|
165 |
+
|
166 |
+
/* The label for each category checkbox (should override the generic label appearance) */
|
167 |
+
.tnp-field.tnp-categories label {
|
168 |
+
|
169 |
+
}
|
170 |
+
|
171 |
+
.tnp-description {
|
172 |
+
margin-top: 7px;
|
173 |
+
font-style: italic;
|
174 |
+
font-weight: normal;
|
175 |
+
color: #999999;
|
176 |
+
}
|
{images → admin/images}/block-icon.png
RENAMED
File without changes
|
images/header/tnp-logo-red-header.png → admin/images/logo-red.png
RENAMED
File without changes
|
images/header/tnp-logo-white-header@2x1.png → admin/images/logo-white.png
RENAMED
File without changes
|
{images → admin/images}/menu-icon.png
RENAMED
File without changes
|
{images → admin/images}/subject/android.png
RENAMED
File without changes
|
{images → admin/images}/subject/gmail.png
RENAMED
File without changes
|
{images → admin/images}/subject/iphone.png
RENAMED
File without changes
|
admin/modal.css
CHANGED
@@ -1,189 +1,188 @@
|
|
1 |
-
.tnp-modal {
|
2 |
-
display: none;
|
3 |
-
position: fixed;
|
4 |
-
z-index: 100000;
|
5 |
-
left: 0;
|
6 |
-
top: 0;
|
7 |
-
width: 100%;
|
8 |
-
height: 100%;
|
9 |
-
overflow: auto;
|
10 |
-
}
|
11 |
-
|
12 |
-
.tnp-modal.open {
|
13 |
-
display: flex;
|
14 |
-
align-items: center;
|
15 |
-
justify-content: center;
|
16 |
-
background-color: rgba(0, 0, 0, 0);
|
17 |
-
animation: modal-in .4s ease-out forwards;
|
18 |
-
}
|
19 |
-
|
20 |
-
@keyframes modal-in {
|
21 |
-
100% {
|
22 |
-
background-color: rgba(0, 0, 0, 0.3);
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
.tnp-modal.on-close {
|
27 |
-
background-color: rgba(0, 0, 0, 0);
|
28 |
-
transition: background-color .4s ease-out;
|
29 |
-
}
|
30 |
-
|
31 |
-
.tnp-modal-container {
|
32 |
-
position: relative;
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
background-color
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
1 |
+
.tnp-modal {
|
2 |
+
display: none;
|
3 |
+
position: fixed;
|
4 |
+
z-index: 100000;
|
5 |
+
left: 0;
|
6 |
+
top: 0;
|
7 |
+
width: 100%;
|
8 |
+
height: 100%;
|
9 |
+
overflow: auto;
|
10 |
+
}
|
11 |
+
|
12 |
+
.tnp-modal.open {
|
13 |
+
display: flex;
|
14 |
+
align-items: center;
|
15 |
+
justify-content: center;
|
16 |
+
background-color: rgba(0, 0, 0, 0);
|
17 |
+
animation: modal-in .4s ease-out forwards;
|
18 |
+
}
|
19 |
+
|
20 |
+
@keyframes modal-in {
|
21 |
+
100% {
|
22 |
+
background-color: rgba(0, 0, 0, 0.3);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
.tnp-modal.on-close {
|
27 |
+
background-color: rgba(0, 0, 0, 0);
|
28 |
+
transition: background-color .4s ease-out;
|
29 |
+
}
|
30 |
+
|
31 |
+
.tnp-modal-container {
|
32 |
+
position: relative;
|
33 |
+
padding: 50px;
|
34 |
+
border-radius: 3px;
|
35 |
+
background-color: white;
|
36 |
+
width: 400px;
|
37 |
+
min-height: 100px;
|
38 |
+
max-height: 400px;
|
39 |
+
overflow-y: auto;
|
40 |
+
animation: modal-fadein .4s ease-out forwards;
|
41 |
+
}
|
42 |
+
|
43 |
+
.tnp-modal-container.on-close {
|
44 |
+
animation: modal-fadeout .4s ease-in forwards;
|
45 |
+
}
|
46 |
+
|
47 |
+
@keyframes modal-fadein {
|
48 |
+
0% {
|
49 |
+
opacity: 0;
|
50 |
+
transform: translateY(-100%);
|
51 |
+
}
|
52 |
+
|
53 |
+
100% {
|
54 |
+
opacity: 1;
|
55 |
+
transform: translateY(0);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
@keyframes modal-fadeout {
|
60 |
+
0% {
|
61 |
+
opacity: 1;
|
62 |
+
transform: translateY(0);
|
63 |
+
}
|
64 |
+
|
65 |
+
20% {
|
66 |
+
transform: translateY(50px);
|
67 |
+
}
|
68 |
+
|
69 |
+
100% {
|
70 |
+
opacity: 0;
|
71 |
+
transform: translateY(-100%);
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
.tnp-modal-close {
|
76 |
+
position: absolute;
|
77 |
+
cursor: pointer;
|
78 |
+
right: 0;
|
79 |
+
top: 0;
|
80 |
+
font-weight: bold;
|
81 |
+
padding: 10px;
|
82 |
+
font-size: 40px;
|
83 |
+
}
|
84 |
+
|
85 |
+
.tnp-modal-confirm {
|
86 |
+
margin: 10px 0 0 0;
|
87 |
+
}
|
88 |
+
|
89 |
+
.tnp-modal-confirm button {
|
90 |
+
float: right;
|
91 |
+
}
|
92 |
+
|
93 |
+
.tnp-modal .button-danger {
|
94 |
+
background-color: darkred;
|
95 |
+
color: #ffffff;
|
96 |
+
text-shadow: none;
|
97 |
+
width: auto;
|
98 |
+
}
|
99 |
+
|
100 |
+
.tnp-modal .button-danger:hover {
|
101 |
+
background-color: darkred;
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
/* TNP MODAL 2 */
|
106 |
+
.tnp-modal2 {
|
107 |
+
display: none;
|
108 |
+
position: fixed;
|
109 |
+
z-index: 100000;
|
110 |
+
left: 0;
|
111 |
+
top: 0;
|
112 |
+
width: 100%;
|
113 |
+
height: 100%;
|
114 |
+
overflow: auto;
|
115 |
+
}
|
116 |
+
|
117 |
+
.tnp-modal2.open {
|
118 |
+
display: flex;
|
119 |
+
align-items: center;
|
120 |
+
justify-content: center;
|
121 |
+
align-items: center;
|
122 |
+
justify-content: center;
|
123 |
+
background-color: rgba(0, 0, 0, 0);
|
124 |
+
animation: modal-in .4s ease-out forwards;
|
125 |
+
}
|
126 |
+
|
127 |
+
.tnp-modal2__content {
|
128 |
+
position: relative;
|
129 |
+
display: flex;
|
130 |
+
flex-direction: column;
|
131 |
+
border-radius: 3px;
|
132 |
+
background-color: white;
|
133 |
+
width: 400px;
|
134 |
+
min-height: 100px;
|
135 |
+
max-height: 400px;
|
136 |
+
overflow-y: hidden;
|
137 |
+
animation: modal-fadein .4s ease-out forwards;
|
138 |
+
}
|
139 |
+
|
140 |
+
.tnp-modal2__header {
|
141 |
+
padding: 20px 50px;
|
142 |
+
background-color: #ECF0F1!important;
|
143 |
+
position: relative;
|
144 |
+
text-align: center;
|
145 |
+
}
|
146 |
+
|
147 |
+
.tnp-modal2__header h2{
|
148 |
+
margin: 0;
|
149 |
+
}
|
150 |
+
|
151 |
+
.tnp-modal2__body {
|
152 |
+
overflow-y: auto;
|
153 |
+
padding: 2rem;
|
154 |
+
flex: 1 1 auto;
|
155 |
+
}
|
156 |
+
|
157 |
+
.tnp-modal2__close {
|
158 |
+
position: absolute;
|
159 |
+
cursor: pointer;
|
160 |
+
right: 0;
|
161 |
+
top: 50%;
|
162 |
+
transform: translateY(-50%);
|
163 |
+
font-weight: bold;
|
164 |
+
padding: 10px;
|
165 |
+
font-size: 40px;
|
166 |
+
}
|
167 |
+
|
168 |
+
.tnp-modal2__close:before {
|
169 |
+
content: '×';
|
170 |
+
}
|
171 |
+
|
172 |
+
.tnp-modal2.on-close {
|
173 |
+
background-color: rgba(0, 0, 0, 0);
|
174 |
+
transition: background-color .4s ease-out;
|
175 |
+
}
|
176 |
+
|
177 |
+
.tnp-modal2.on-close .tnp-modal2__content {
|
178 |
+
animation: modal-fadeout .4s ease-in forwards;
|
179 |
+
}
|
180 |
+
|
181 |
+
.tnp-modal2__body .row {
|
182 |
+
display: flex;
|
183 |
+
}
|
184 |
+
|
185 |
+
.tnp-modal2__body .col {
|
186 |
+
flex: 1;
|
187 |
+
}
|
188 |
+
|
|
{css → admin}/tabs.css
RENAMED
@@ -1,94 +1,94 @@
|
|
1 |
-
/* Since #tabs has a white background, all elements should be made dark */
|
2 |
-
|
3 |
-
#tnp-body #tabs h3,
|
4 |
-
#tnp-body #tabs h4,
|
5 |
-
#tnp-body #tabs p,
|
6 |
-
#tnp-body #tabs li,
|
7 |
-
#tnp-body #tabs input,
|
8 |
-
#tnp-body #tabs select,
|
9 |
-
#tnp-body #tabs textarea {
|
10 |
-
color: #444;
|
11 |
-
}
|
12 |
-
|
13 |
-
#tnp-body td .tnp-tabs {
|
14 |
-
|
15 |
-
}
|
16 |
-
|
17 |
-
#tnp-body td .tnp-tabs .ui-widget-header {
|
18 |
-
background-color: #ddd;
|
19 |
-
}
|
20 |
-
|
21 |
-
#tnp-body td .tnp-tabs .ui-tabs-anchor {
|
22 |
-
color: #000;
|
23 |
-
}
|
24 |
-
|
25 |
-
#tnp-body .ui-widget {
|
26 |
-
font-family: soleil, sans-serif;
|
27 |
-
}
|
28 |
-
|
29 |
-
#tnp-body #tabs {
|
30 |
-
background-color: transparent;
|
31 |
-
border: 0!important;
|
32 |
-
padding: 0;
|
33 |
-
margin: 0;
|
34 |
-
}
|
35 |
-
|
36 |
-
#tnp-body #tabs .ui-widget-header {
|
37 |
-
background: #28313C;
|
38 |
-
border: 0;
|
39 |
-
}
|
40 |
-
|
41 |
-
#tnp-body #tabs .ui-tabs-panel {
|
42 |
-
padding: 15px!important;
|
43 |
-
background-color: #fff;
|
44 |
-
}
|
45 |
-
|
46 |
-
#tnp-body #tabs a.ui-tabs-anchor,
|
47 |
-
#tnp-body #tabs a.ui-tabs-anchor:visited {
|
48 |
-
color: #444;
|
49 |
-
}
|
50 |
-
|
51 |
-
#tnp-body .ui-tabs .ui-tabs-nav {
|
52 |
-
padding: 0;
|
53 |
-
margin: 0;
|
54 |
-
}
|
55 |
-
|
56 |
-
#tnp-body .ui-tabs .ui-tabs-nav li a {
|
57 |
-
font-size: 14px;
|
58 |
-
}
|
59 |
-
|
60 |
-
#tnp-body #tabs .ui-tabs {
|
61 |
-
border-color: #28313C;
|
62 |
-
background-color: #28313C;
|
63 |
-
border: 0;
|
64 |
-
}
|
65 |
-
|
66 |
-
#tnp-body #tabs .ui-tabs .ui-tabs-nav {
|
67 |
-
margin: 0;
|
68 |
-
padding: .2em .2em 0 0;
|
69 |
-
background-color: #f2f2f2;
|
70 |
-
}
|
71 |
-
|
72 |
-
#tnp-body #tabs .ui-tabs .ui-tabs-panel {
|
73 |
-
padding: 1em 0;
|
74 |
-
background-color: #f2f2f2;
|
75 |
-
margin: 0;
|
76 |
-
border: 0;
|
77 |
-
}
|
78 |
-
|
79 |
-
#tnp-body .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
|
80 |
-
background: #fff !important;
|
81 |
-
font-weight: normal;
|
82 |
-
font-family: soleil, sans-serif;
|
83 |
-
}
|
84 |
-
|
85 |
-
|
86 |
-
#tnp-body .ui-widget-content {
|
87 |
-
background: #fff;
|
88 |
-
}
|
89 |
-
|
90 |
-
#tnp-body .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
|
91 |
-
border: none;
|
92 |
-
background: #ECF0F1;
|
93 |
-
font-family: soleil, sans-serif;
|
94 |
-
}
|
1 |
+
/* Since #tabs has a white background, all elements should be made dark */
|
2 |
+
|
3 |
+
#tnp-body #tabs h3,
|
4 |
+
#tnp-body #tabs h4,
|
5 |
+
#tnp-body #tabs p,
|
6 |
+
#tnp-body #tabs li,
|
7 |
+
#tnp-body #tabs input,
|
8 |
+
#tnp-body #tabs select,
|
9 |
+
#tnp-body #tabs textarea {
|
10 |
+
color: #444;
|
11 |
+
}
|
12 |
+
|
13 |
+
#tnp-body td .tnp-tabs {
|
14 |
+
|
15 |
+
}
|
16 |
+
|
17 |
+
#tnp-body td .tnp-tabs .ui-widget-header {
|
18 |
+
background-color: #ddd;
|
19 |
+
}
|
20 |
+
|
21 |
+
#tnp-body td .tnp-tabs .ui-tabs-anchor {
|
22 |
+
color: #000;
|
23 |
+
}
|
24 |
+
|
25 |
+
#tnp-body .ui-widget {
|
26 |
+
font-family: soleil, sans-serif;
|
27 |
+
}
|
28 |
+
|
29 |
+
#tnp-body #tabs {
|
30 |
+
background-color: transparent;
|
31 |
+
border: 0!important;
|
32 |
+
padding: 0;
|
33 |
+
margin: 0;
|
34 |
+
}
|
35 |
+
|
36 |
+
#tnp-body #tabs .ui-widget-header {
|
37 |
+
background: #28313C;
|
38 |
+
border: 0;
|
39 |
+
}
|
40 |
+
|
41 |
+
#tnp-body #tabs .ui-tabs-panel {
|
42 |
+
padding: 15px!important;
|
43 |
+
background-color: #fff;
|
44 |
+
}
|
45 |
+
|
46 |
+
#tnp-body #tabs a.ui-tabs-anchor,
|
47 |
+
#tnp-body #tabs a.ui-tabs-anchor:visited {
|
48 |
+
color: #444;
|
49 |
+
}
|
50 |
+
|
51 |
+
#tnp-body .ui-tabs .ui-tabs-nav {
|
52 |
+
padding: 0;
|
53 |
+
margin: 0;
|
54 |
+
}
|
55 |
+
|
56 |
+
#tnp-body .ui-tabs .ui-tabs-nav li a {
|
57 |
+
font-size: 14px;
|
58 |
+
}
|
59 |
+
|
60 |
+
#tnp-body #tabs .ui-tabs {
|
61 |
+
border-color: #28313C;
|
62 |
+
background-color: #28313C;
|
63 |
+
border: 0;
|
64 |
+
}
|
65 |
+
|
66 |
+
#tnp-body #tabs .ui-tabs .ui-tabs-nav {
|
67 |
+
margin: 0;
|
68 |
+
padding: .2em .2em 0 0;
|
69 |
+
background-color: #f2f2f2;
|
70 |
+
}
|
71 |
+
|
72 |
+
#tnp-body #tabs .ui-tabs .ui-tabs-panel {
|
73 |
+
padding: 1em 0;
|
74 |
+
background-color: #f2f2f2;
|
75 |
+
margin: 0;
|
76 |
+
border: 0;
|
77 |
+
}
|
78 |
+
|
79 |
+
#tnp-body .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
|
80 |
+
background: #fff !important;
|
81 |
+
font-weight: normal;
|
82 |
+
font-family: soleil, sans-serif;
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
#tnp-body .ui-widget-content {
|
87 |
+
background: #fff;
|
88 |
+
}
|
89 |
+
|
90 |
+
#tnp-body .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
|
91 |
+
border: none;
|
92 |
+
background: #ECF0F1;
|
93 |
+
font-family: soleil, sans-serif;
|
94 |
+
}
|
{css → admin}/widgets.css
RENAMED
@@ -1,377 +1,377 @@
|
|
1 |
-
/*
|
2 |
-
Widgets are blocks used within rows and columns (bootstrap like) and identified by the
|
3 |
-
class "tnp-widget"
|
4 |
-
*/
|
5 |
-
|
6 |
-
.tnp-widget {
|
7 |
-
width: 100%;
|
8 |
-
box-shadow: 0 2px 2px rgba(0, 0, 0, .1);
|
9 |
-
background: #fff;
|
10 |
-
min-height: 320px;
|
11 |
-
color: #000;
|
12 |
-
padding-bottom: 20px;
|
13 |
-
position: relative;
|
14 |
-
}
|
15 |
-
|
16 |
-
.tnp-height-full {
|
17 |
-
height: 500px !important;
|
18 |
-
}
|
19 |
-
|
20 |
-
#tnp-body .tnp-widget p {
|
21 |
-
color: #000;
|
22 |
-
margin-left: 15px;
|
23 |
-
}
|
24 |
-
|
25 |
-
/* Widget title */
|
26 |
-
.tnp-widget h3 {
|
27 |
-
font-family: soleil, sans-serif;
|
28 |
-
letter-spacing: 0.05rem;
|
29 |
-
background-color: #2980B9;
|
30 |
-
color: #fff !important;
|
31 |
-
margin: 15px 0px;
|
32 |
-
padding: 9px;
|
33 |
-
border: 0;
|
34 |
-
font-size: 14px;
|
35 |
-
font-weight: 400;
|
36 |
-
}
|
37 |
-
|
38 |
-
/* Buttons on widgets top bar */
|
39 |
-
#tnp-body .tnp-widget h3 a,
|
40 |
-
#tnp-body .tnp-widget h3 a:visited,
|
41 |
-
#tnp-body .tnp-widget h3 a:hover {
|
42 |
-
color: #fff;
|
43 |
-
}
|
44 |
-
|
45 |
-
.tnp-widget h3.red {
|
46 |
-
background-color: darkred;
|
47 |
-
}
|
48 |
-
|
49 |
-
.tnp-widget h3.gray {
|
50 |
-
background-color: darkgray;
|
51 |
-
}
|
52 |
-
|
53 |
-
.tnp-widget.tnp-inactive {
|
54 |
-
color: #999 !important;
|
55 |
-
background-color: #ddd !important;
|
56 |
-
}
|
57 |
-
|
58 |
-
.tnp-widget.tnp-inactive h3 {
|
59 |
-
background-color: #999;
|
60 |
-
color: #ccc !important;
|
61 |
-
}
|
62 |
-
|
63 |
-
/* Widget title button */
|
64 |
-
.tnp-widget h3 a {
|
65 |
-
float: right;
|
66 |
-
color: white;
|
67 |
-
text-decoration: none;
|
68 |
-
margin-left: 5px;
|
69 |
-
padding: 2px 8px;
|
70 |
-
background-color: #26C281;
|
71 |
-
border-radius: 2px;
|
72 |
-
font-weight: 300;
|
73 |
-
text-transform: capitalize;
|
74 |
-
font-size: 0.8rem;
|
75 |
-
}
|
76 |
-
|
77 |
-
/* Widget title button hover */
|
78 |
-
.tnp-widget h3 a:hover {
|
79 |
-
color: white;
|
80 |
-
text-decoration: none;
|
81 |
-
margin-left: 5px;
|
82 |
-
background-color: #2ECC71;
|
83 |
-
}
|
84 |
-
|
85 |
-
.tnp-widget .inside li {
|
86 |
-
font-size: 12px;
|
87 |
-
margin: 10px;
|
88 |
-
}
|
89 |
-
|
90 |
-
.tnp-widget .inside ul {
|
91 |
-
list-style-type: circle;
|
92 |
-
list-style-position: inside;
|
93 |
-
}
|
94 |
-
|
95 |
-
.tnp-widget .tnp-note {
|
96 |
-
color: #999;
|
97 |
-
font-size: 12px;
|
98 |
-
margin-top: 20px;
|
99 |
-
text-align: center;
|
100 |
-
padding: 0 10px;
|
101 |
-
position: absolute;
|
102 |
-
margin: 0 auto;
|
103 |
-
bottom: 10px;
|
104 |
-
}
|
105 |
-
|
106 |
-
|
107 |
-
/* Widgets with a placeholder image */
|
108 |
-
|
109 |
-
.tnp-widget .tnp-placeholder {
|
110 |
-
padding: 10px;
|
111 |
-
text-align: center;
|
112 |
-
}
|
113 |
-
|
114 |
-
.tnp-widget .tnp-placeholder img {
|
115 |
-
max-width: 100%
|
116 |
-
}
|
117 |
-
|
118 |
-
|
119 |
-
/* Widgets with two numbers (primary and secondary)*/
|
120 |
-
|
121 |
-
.tnp-widget.tnp-number {
|
122 |
-
text-align: center;
|
123 |
-
min-height: 0 !important;
|
124 |
-
height: 250px;
|
125 |
-
}
|
126 |
-
|
127 |
-
.tnp-widget .tnp-value {
|
128 |
-
font-size: 45px;
|
129 |
-
margin-top: 20px;
|
130 |
-
}
|
131 |
-
|
132 |
-
.tnp-widget .tnp-value-2 {
|
133 |
-
font-size: 20px;
|
134 |
-
margin-top: 15px;
|
135 |
-
margin-bottom: 20px;
|
136 |
-
}
|
137 |
-
|
138 |
-
|
139 |
-
/* Icons and colors inside widgets */
|
140 |
-
|
141 |
-
.tnp-icon {
|
142 |
-
margin-top: 20px;
|
143 |
-
margin-bottom: 25px;
|
144 |
-
}
|
145 |
-
|
146 |
-
.tnp-widget .tnp-icon i {
|
147 |
-
font-size: 40px;
|
148 |
-
}
|
149 |
-
|
150 |
-
.tnp-widget .tnp-blue {
|
151 |
-
color: #2980b9;
|
152 |
-
}
|
153 |
-
|
154 |
-
.tnp-widget .tnp-green {
|
155 |
-
color: #62cb31;
|
156 |
-
}
|
157 |
-
|
158 |
-
.tnp-widget .tnp-orange {
|
159 |
-
color: #ea6557;
|
160 |
-
}
|
161 |
-
|
162 |
-
.tnp-widget .tnp-red {
|
163 |
-
color: #dd3333;
|
164 |
-
}
|
165 |
-
|
166 |
-
.tnp-widget .tnp-gray {
|
167 |
-
color: #999;
|
168 |
-
}
|
169 |
-
|
170 |
-
|
171 |
-
/* Widefat tables inside a widget */
|
172 |
-
|
173 |
-
#tnp-body .tnp-widget table.widefat {
|
174 |
-
margin: 10px 15px;
|
175 |
-
width: auto;
|
176 |
-
}
|
177 |
-
|
178 |
-
#tnp-body .tnp-widget.tnp-table table.widefat thead {
|
179 |
-
background-color: #fff !important;
|
180 |
-
}
|
181 |
-
|
182 |
-
#tnp-body .tnp-widget.tnp-table table.widefat thead th {
|
183 |
-
font-weight: bold;
|
184 |
-
background-color: #fff !important;
|
185 |
-
color: #000 !important;
|
186 |
-
}
|
187 |
-
|
188 |
-
.tnp-cards-container {
|
189 |
-
display: flex;
|
190 |
-
flex-wrap: wrap;
|
191 |
-
flex-direction: row;
|
192 |
-
}
|
193 |
-
|
194 |
-
.tnp-card {
|
195 |
-
flex: 1 0;
|
196 |
-
align-content: flex-start;
|
197 |
-
margin: 15px;
|
198 |
-
font-family: soleil, sans-serif;
|
199 |
-
border-radius: 15px;
|
200 |
-
background-color: #232D3B;
|
201 |
-
-webkit-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
202 |
-
-moz-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
203 |
-
box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
204 |
-
padding: 15px;
|
205 |
-
color: #FFF;
|
206 |
-
display: flex;
|
207 |
-
flex-wrap: wrap;
|
208 |
-
position: relative;
|
209 |
-
}
|
210 |
-
|
211 |
-
.tnp-card.tnp-card-col-2 {
|
212 |
-
flex: 0 0 calc(50% - 31px);
|
213 |
-
}
|
214 |
-
|
215 |
-
@media screen and (max-width: 700px) {
|
216 |
-
.tnp-card {
|
217 |
-
flex: 1 0 100%;
|
218 |
-
}
|
219 |
-
}
|
220 |
-
|
221 |
-
@media screen and (min-width: 700px) and (max-width: 1200px) {
|
222 |
-
.tnp-card {
|
223 |
-
flex: 1 0 40%;
|
224 |
-
}
|
225 |
-
}
|
226 |
-
|
227 |
-
.tnp-card .tnp-card-title {
|
228 |
-
flex-basis: 100%;
|
229 |
-
font-size: 19px;
|
230 |
-
margin-bottom: 25px;
|
231 |
-
}
|
232 |
-
|
233 |
-
.tnp-card .tnp-card-value {
|
234 |
-
flex-basis: 75%;
|
235 |
-
font-size: 39px;
|
236 |
-
font-weight: bold;
|
237 |
-
}
|
238 |
-
|
239 |
-
.tnp-counter-animation.percentage {
|
240 |
-
display: inline-block;
|
241 |
-
min-width: 75px;
|
242 |
-
}
|
243 |
-
|
244 |
-
.tnp-card-button-container {
|
245 |
-
flex-basis: 100%;
|
246 |
-
margin-top: 60px;
|
247 |
-
}
|
248 |
-
|
249 |
-
.tnp-card-button-container a {
|
250 |
-
padding: 5px 18px;
|
251 |
-
font-size: 12px;
|
252 |
-
color: #FFF !important;
|
253 |
-
background-color: #2980B9;
|
254 |
-
border-radius: 4px;
|
255 |
-
text-decoration: none;
|
256 |
-
position: absolute;
|
257 |
-
bottom: 15px;
|
258 |
-
left: 50%;
|
259 |
-
-webkit-transform: translateX(-50%);
|
260 |
-
transform: translateX(-50%);
|
261 |
-
}
|
262 |
-
|
263 |
-
.tnp-card-button-container a:hover {
|
264 |
-
background-color: #2887c1;
|
265 |
-
}
|
266 |
-
|
267 |
-
.tnp-card-button-container a:hover {
|
268 |
-
color: #FFF !important;
|
269 |
-
}
|
270 |
-
|
271 |
-
.tnp-card-icon {
|
272 |
-
flex-basis: 25%;
|
273 |
-
display: flex;
|
274 |
-
justify-content: flex-end;
|
275 |
-
}
|
276 |
-
|
277 |
-
.tnp-card .green {
|
278 |
-
color: #81B4A3;
|
279 |
-
}
|
280 |
-
|
281 |
-
.tnp-card .yellow {
|
282 |
-
color: #F8CF61;
|
283 |
-
}
|
284 |
-
|
285 |
-
.tnp-card .red {
|
286 |
-
color: #F36C7F;
|
287 |
-
}
|
288 |
-
|
289 |
-
.tnp-card .tnp-card-description {
|
290 |
-
font-size: 11px;
|
291 |
-
line-height: 13px;
|
292 |
-
font-weight: 500;
|
293 |
-
color: #7f8286;
|
294 |
-
margin-top: 20px;
|
295 |
-
font-family: -apple-system, system-ui, BlinkMacSystemFont,
|
296 |
-
'Segoe UI', Roboto, 'Helvetica Neue',
|
297 |
-
Ubuntu, Arial, sans-serif;
|
298 |
-
}
|
299 |
-
|
300 |
-
.tnp-card .tnp-card-description .value {
|
301 |
-
color: #919498;
|
302 |
-
font-weight: 700;
|
303 |
-
}
|
304 |
-
|
305 |
-
.tnp-card .tnp-card-chart {
|
306 |
-
flex-basis: 100%;
|
307 |
-
}
|
308 |
-
|
309 |
-
.tnp-card .tnp-card-chart .mini-chart {
|
310 |
-
max-height: 200px;
|
311 |
-
max-width: 200px;
|
312 |
-
margin: 0 auto;
|
313 |
-
}
|
314 |
-
|
315 |
-
.tnp-card .tnp-card-chart.h-400 {
|
316 |
-
height: 400px;
|
317 |
-
}
|
318 |
-
|
319 |
-
.tnp-card-table,
|
320 |
-
.tnp-card-table table {
|
321 |
-
width: 100%;
|
322 |
-
}
|
323 |
-
|
324 |
-
.tnp-card-table table {
|
325 |
-
border-collapse: collapse;
|
326 |
-
}
|
327 |
-
|
328 |
-
.tnp-card-table table .w-25 {
|
329 |
-
width: 25%;
|
330 |
-
}
|
331 |
-
|
332 |
-
.tnp-card-table table .w-50 {
|
333 |
-
width: 50%;
|
334 |
-
}
|
335 |
-
|
336 |
-
.tnp-card-table table .w-75 {
|
337 |
-
width: 75%;
|
338 |
-
}
|
339 |
-
|
340 |
-
.tnp-card-table table .w-33 {
|
341 |
-
width: 33%;
|
342 |
-
}
|
343 |
-
|
344 |
-
.tnp-card-table table .w-20 {
|
345 |
-
width: 20%;
|
346 |
-
}
|
347 |
-
|
348 |
-
.tnp-card-table table .w-10 {
|
349 |
-
width: 10%;
|
350 |
-
}
|
351 |
-
|
352 |
-
.tnp-card-table table .w-80 {
|
353 |
-
width: 80%;
|
354 |
-
}
|
355 |
-
|
356 |
-
.tnp-card-table table tbody::before {
|
357 |
-
content: '';
|
358 |
-
display: table-row;
|
359 |
-
height: 15px;
|
360 |
-
}
|
361 |
-
|
362 |
-
.tnp-card-table table tbody tr {
|
363 |
-
line-height: 30px;
|
364 |
-
}
|
365 |
-
|
366 |
-
#tnp-body .tnp-card-table table tbody td,
|
367 |
-
.tnp-card-table table tbody td {
|
368 |
-
color: #FFF;
|
369 |
-
}
|
370 |
-
|
371 |
-
.tnp-card-table table tbody tr:nth-child(even) {
|
372 |
-
background-color: #26303E;
|
373 |
-
}
|
374 |
-
|
375 |
-
.mt-25 {
|
376 |
-
margin-top: 25px;
|
377 |
-
}
|
1 |
+
/*
|
2 |
+
Widgets are blocks used within rows and columns (bootstrap like) and identified by the
|
3 |
+
class "tnp-widget"
|
4 |
+
*/
|
5 |
+
|
6 |
+
.tnp-widget {
|
7 |
+
width: 100%;
|
8 |
+
box-shadow: 0 2px 2px rgba(0, 0, 0, .1);
|
9 |
+
background: #fff;
|
10 |
+
min-height: 320px;
|
11 |
+
color: #000;
|
12 |
+
padding-bottom: 20px;
|
13 |
+
position: relative;
|
14 |
+
}
|
15 |
+
|
16 |
+
.tnp-height-full {
|
17 |
+
height: 500px !important;
|
18 |
+
}
|
19 |
+
|
20 |
+
#tnp-body .tnp-widget p {
|
21 |
+
color: #000;
|
22 |
+
margin-left: 15px;
|
23 |
+
}
|
24 |
+
|
25 |
+
/* Widget title */
|
26 |
+
.tnp-widget h3 {
|
27 |
+
font-family: soleil, sans-serif;
|
28 |
+
letter-spacing: 0.05rem;
|
29 |
+
background-color: #2980B9;
|
30 |
+
color: #fff !important;
|
31 |
+
margin: 15px 0px;
|
32 |
+
padding: 9px;
|
33 |
+
border: 0;
|
34 |
+
font-size: 14px;
|
35 |
+
font-weight: 400;
|
36 |
+
}
|
37 |
+
|
38 |
+
/* Buttons on widgets top bar */
|
39 |
+
#tnp-body .tnp-widget h3 a,
|
40 |
+
#tnp-body .tnp-widget h3 a:visited,
|
41 |
+
#tnp-body .tnp-widget h3 a:hover {
|
42 |
+
color: #fff;
|
43 |
+
}
|
44 |
+
|
45 |
+
.tnp-widget h3.red {
|
46 |
+
background-color: darkred;
|
47 |
+
}
|
48 |
+
|
49 |
+
.tnp-widget h3.gray {
|
50 |
+
background-color: darkgray;
|
51 |
+
}
|
52 |
+
|
53 |
+
.tnp-widget.tnp-inactive {
|
54 |
+
color: #999 !important;
|
55 |
+
background-color: #ddd !important;
|
56 |
+
}
|
57 |
+
|
58 |
+
.tnp-widget.tnp-inactive h3 {
|
59 |
+
background-color: #999;
|
60 |
+
color: #ccc !important;
|
61 |
+
}
|
62 |
+
|
63 |
+
/* Widget title button */
|
64 |
+
.tnp-widget h3 a {
|
65 |
+
float: right;
|
66 |
+
color: white;
|
67 |
+
text-decoration: none;
|
68 |
+
margin-left: 5px;
|
69 |
+
padding: 2px 8px;
|
70 |
+
background-color: #26C281;
|
71 |
+
border-radius: 2px;
|
72 |
+
font-weight: 300;
|
73 |
+
text-transform: capitalize;
|
74 |
+
font-size: 0.8rem;
|
75 |
+
}
|
76 |
+
|
77 |
+
/* Widget title button hover */
|
78 |
+
.tnp-widget h3 a:hover {
|
79 |
+
color: white;
|
80 |
+
text-decoration: none;
|
81 |
+
margin-left: 5px;
|
82 |
+
background-color: #2ECC71;
|
83 |
+
}
|
84 |
+
|
85 |
+
.tnp-widget .inside li {
|
86 |
+
font-size: 12px;
|
87 |
+
margin: 10px;
|
88 |
+
}
|
89 |
+
|
90 |
+
.tnp-widget .inside ul {
|
91 |
+
list-style-type: circle;
|
92 |
+
list-style-position: inside;
|
93 |
+
}
|
94 |
+
|
95 |
+
.tnp-widget .tnp-note {
|
96 |
+
color: #999;
|
97 |
+
font-size: 12px;
|
98 |
+
margin-top: 20px;
|
99 |
+
text-align: center;
|
100 |
+
padding: 0 10px;
|
101 |
+
position: absolute;
|
102 |
+
margin: 0 auto;
|
103 |
+
bottom: 10px;
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
/* Widgets with a placeholder image */
|
108 |
+
|
109 |
+
.tnp-widget .tnp-placeholder {
|
110 |
+
padding: 10px;
|
111 |
+
text-align: center;
|
112 |
+
}
|
113 |
+
|
114 |
+
.tnp-widget .tnp-placeholder img {
|
115 |
+
max-width: 100%
|
116 |
+
}
|
117 |
+
|
118 |
+
|
119 |
+
/* Widgets with two numbers (primary and secondary)*/
|
120 |
+
|
121 |
+
.tnp-widget.tnp-number {
|
122 |
+
text-align: center;
|
123 |
+
min-height: 0 !important;
|
124 |
+
height: 250px;
|
125 |
+
}
|
126 |
+
|
127 |
+
.tnp-widget .tnp-value {
|
128 |
+
font-size: 45px;
|
129 |
+
margin-top: 20px;
|
130 |
+
}
|
131 |
+
|
132 |
+
.tnp-widget .tnp-value-2 {
|
133 |
+
font-size: 20px;
|
134 |
+
margin-top: 15px;
|
135 |
+
margin-bottom: 20px;
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
/* Icons and colors inside widgets */
|
140 |
+
|
141 |
+
.tnp-icon {
|
142 |
+
margin-top: 20px;
|
143 |
+
margin-bottom: 25px;
|
144 |
+
}
|
145 |
+
|
146 |
+
.tnp-widget .tnp-icon i {
|
147 |
+
font-size: 40px;
|
148 |
+
}
|
149 |
+
|
150 |
+
.tnp-widget .tnp-blue {
|
151 |
+
color: #2980b9;
|
152 |
+
}
|
153 |
+
|
154 |
+
.tnp-widget .tnp-green {
|
155 |
+
color: #62cb31;
|
156 |
+
}
|
157 |
+
|
158 |
+
.tnp-widget .tnp-orange {
|
159 |
+
color: #ea6557;
|
160 |
+
}
|
161 |
+
|
162 |
+
.tnp-widget .tnp-red {
|
163 |
+
color: #dd3333;
|
164 |
+
}
|
165 |
+
|
166 |
+
.tnp-widget .tnp-gray {
|
167 |
+
color: #999;
|
168 |
+
}
|
169 |
+
|
170 |
+
|
171 |
+
/* Widefat tables inside a widget */
|
172 |
+
|
173 |
+
#tnp-body .tnp-widget table.widefat {
|
174 |
+
margin: 10px 15px;
|
175 |
+
width: auto;
|
176 |
+
}
|
177 |
+
|
178 |
+
#tnp-body .tnp-widget.tnp-table table.widefat thead {
|
179 |
+
background-color: #fff !important;
|
180 |
+
}
|
181 |
+
|
182 |
+
#tnp-body .tnp-widget.tnp-table table.widefat thead th {
|
183 |
+
font-weight: bold;
|
184 |
+
background-color: #fff !important;
|
185 |
+
color: #000 !important;
|
186 |
+
}
|
187 |
+
|
188 |
+
.tnp-cards-container {
|
189 |
+
display: flex;
|
190 |
+
flex-wrap: wrap;
|
191 |
+
flex-direction: row;
|
192 |
+
}
|
193 |
+
|
194 |
+
.tnp-card {
|
195 |
+
flex: 1 0;
|
196 |
+
align-content: flex-start;
|
197 |
+
margin: 15px;
|
198 |
+
font-family: soleil, sans-serif;
|
199 |
+
border-radius: 15px;
|
200 |
+
background-color: #232D3B;
|
201 |
+
-webkit-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
202 |
+
-moz-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
203 |
+
box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
204 |
+
padding: 15px;
|
205 |
+
color: #FFF;
|
206 |
+
display: flex;
|
207 |
+
flex-wrap: wrap;
|
208 |
+
position: relative;
|
209 |
+
}
|
210 |
+
|
211 |
+
.tnp-card.tnp-card-col-2 {
|
212 |
+
flex: 0 0 calc(50% - 31px);
|
213 |
+
}
|
214 |
+
|
215 |
+
@media screen and (max-width: 700px) {
|
216 |
+
.tnp-card {
|
217 |
+
flex: 1 0 100%;
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
@media screen and (min-width: 700px) and (max-width: 1200px) {
|
222 |
+
.tnp-card {
|
223 |
+
flex: 1 0 40%;
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
.tnp-card .tnp-card-title {
|
228 |
+
flex-basis: 100%;
|
229 |
+
font-size: 19px;
|
230 |
+
margin-bottom: 25px;
|
231 |
+
}
|
232 |
+
|
233 |
+
.tnp-card .tnp-card-value {
|
234 |
+
flex-basis: 75%;
|
235 |
+
font-size: 39px;
|
236 |
+
font-weight: bold;
|
237 |
+
}
|
238 |
+
|
239 |
+
.tnp-counter-animation.percentage {
|
240 |
+
display: inline-block;
|
241 |
+
min-width: 75px;
|
242 |
+
}
|
243 |
+
|
244 |
+
.tnp-card-button-container {
|
245 |
+
flex-basis: 100%;
|
246 |
+
margin-top: 60px;
|
247 |
+
}
|
248 |
+
|
249 |
+
.tnp-card-button-container a {
|
250 |
+
padding: 5px 18px;
|
251 |
+
font-size: 12px;
|
252 |
+
color: #FFF !important;
|
253 |
+
background-color: #2980B9;
|
254 |
+
border-radius: 4px;
|
255 |
+
text-decoration: none;
|
256 |
+
position: absolute;
|
257 |
+
bottom: 15px;
|
258 |
+
left: 50%;
|
259 |
+
-webkit-transform: translateX(-50%);
|
260 |
+
transform: translateX(-50%);
|
261 |
+
}
|
262 |
+
|
263 |
+
.tnp-card-button-container a:hover {
|
264 |
+
background-color: #2887c1;
|
265 |
+
}
|
266 |
+
|
267 |
+
.tnp-card-button-container a:hover {
|
268 |
+
color: #FFF !important;
|
269 |
+
}
|
270 |
+
|
271 |
+
.tnp-card-icon {
|
272 |
+
flex-basis: 25%;
|
273 |
+
display: flex;
|
274 |
+
justify-content: flex-end;
|
275 |
+
}
|
276 |
+
|
277 |
+
.tnp-card .green {
|
278 |
+
color: #81B4A3;
|
279 |
+
}
|
280 |
+
|
281 |
+
.tnp-card .yellow {
|
282 |
+
color: #F8CF61;
|
283 |
+
}
|
284 |
+
|
285 |
+
.tnp-card .red {
|
286 |
+
color: #F36C7F;
|
287 |
+
}
|
288 |
+
|
289 |
+
.tnp-card .tnp-card-description {
|
290 |
+
font-size: 11px;
|
291 |
+
line-height: 13px;
|
292 |
+
font-weight: 500;
|
293 |
+
color: #7f8286;
|
294 |
+
margin-top: 20px;
|
295 |
+
font-family: -apple-system, system-ui, BlinkMacSystemFont,
|
296 |
+
'Segoe UI', Roboto, 'Helvetica Neue',
|
297 |
+
Ubuntu, Arial, sans-serif;
|
298 |
+
}
|
299 |
+
|
300 |
+
.tnp-card .tnp-card-description .value {
|
301 |
+
color: #919498;
|
302 |
+
font-weight: 700;
|
303 |
+
}
|
304 |
+
|
305 |
+
.tnp-card .tnp-card-chart {
|
306 |
+
flex-basis: 100%;
|
307 |
+
}
|
308 |
+
|
309 |
+
.tnp-card .tnp-card-chart .mini-chart {
|
310 |
+
max-height: 200px;
|
311 |
+
max-width: 200px;
|
312 |
+
margin: 0 auto;
|
313 |
+
}
|
314 |
+
|
315 |
+
.tnp-card .tnp-card-chart.h-400 {
|
316 |
+
height: 400px;
|
317 |
+
}
|
318 |
+
|
319 |
+
.tnp-card-table,
|
320 |
+
.tnp-card-table table {
|
321 |
+
width: 100%;
|
322 |
+
}
|
323 |
+
|
324 |
+
.tnp-card-table table {
|
325 |
+
border-collapse: collapse;
|
326 |
+
}
|
327 |
+
|
328 |
+
.tnp-card-table table .w-25 {
|
329 |
+
width: 25%;
|
330 |
+
}
|
331 |
+
|
332 |
+
.tnp-card-table table .w-50 {
|
333 |
+
width: 50%;
|
334 |
+
}
|
335 |
+
|
336 |
+
.tnp-card-table table .w-75 {
|
337 |
+
width: 75%;
|
338 |
+
}
|
339 |
+
|
340 |
+
.tnp-card-table table .w-33 {
|
341 |
+
width: 33%;
|
342 |
+
}
|
343 |
+
|
344 |
+
.tnp-card-table table .w-20 {
|
345 |
+
width: 20%;
|
346 |
+
}
|
347 |
+
|
348 |
+
.tnp-card-table table .w-10 {
|
349 |
+
width: 10%;
|
350 |
+
}
|
351 |
+
|
352 |
+
.tnp-card-table table .w-80 {
|
353 |
+
width: 80%;
|
354 |
+
}
|
355 |
+
|
356 |
+
.tnp-card-table table tbody::before {
|
357 |
+
content: '';
|
358 |
+
display: table-row;
|
359 |
+
height: 15px;
|
360 |
+
}
|
361 |
+
|
362 |
+
.tnp-card-table table tbody tr {
|
363 |
+
line-height: 30px;
|
364 |
+
}
|
365 |
+
|
366 |
+
#tnp-body .tnp-card-table table tbody td,
|
367 |
+
.tnp-card-table table tbody td {
|
368 |
+
color: #FFF;
|
369 |
+
}
|
370 |
+
|
371 |
+
.tnp-card-table table tbody tr:nth-child(even) {
|
372 |
+
background-color: #26303E;
|
373 |
+
}
|
374 |
+
|
375 |
+
.mt-25 {
|
376 |
+
margin-top: 25px;
|
377 |
+
}
|
{css → admin}/wp-editor.css
RENAMED
@@ -1,16 +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 |
-
}
|
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 |
+
}
|
css/controls-dark.css
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
|
2 |
-
.tnpc-error, .tnpc-warning, .tnpc-message {
|
3 |
-
background-color: #28313C;
|
4 |
-
color: #fff;
|
5 |
-
}
|
6 |
-
|
7 |
-
#tnp-body table.form-table {
|
8 |
-
border: 1px solid #666;
|
9 |
-
border-radius: 3px;
|
10 |
-
margin-top: 0;
|
11 |
-
margin-bottom: 1em;
|
12 |
-
}
|
13 |
-
|
14 |
-
#tnp-body table.form-table th {
|
15 |
-
width: 150px;
|
16 |
-
}
|
17 |
-
|
18 |
-
#tnp-body table.form-table, #tnp-body table.form-table th {
|
19 |
-
background-color: transparent;
|
20 |
-
color: #fff;
|
21 |
-
}
|
22 |
-
|
23 |
-
#tnp-body table.form-table th, #tnp-body table.form-table td {
|
24 |
-
vertical-align: top;
|
25 |
-
}
|
26 |
-
|
27 |
-
#tnp-body table.form-table td {
|
28 |
-
color: #999;
|
29 |
-
}
|
30 |
-
|
31 |
-
#tnp-body table.form-table p.description {
|
32 |
-
color: #aaa;
|
33 |
-
}
|
34 |
-
|
35 |
-
#tnp-body table.widefat {
|
36 |
-
background-color: transparent !important;
|
37 |
-
}
|
38 |
-
|
39 |
-
#tnp-body table.widefat input[type="text"] {
|
40 |
-
background-color: #28313C;
|
41 |
-
color: #fff !important;
|
42 |
-
}
|
43 |
-
|
44 |
-
#tnp-body table.widefat thead {
|
45 |
-
background-color: #28313C;
|
46 |
-
color: #fff!important;
|
47 |
-
}
|
48 |
-
|
49 |
-
#tnp-body table.widefat td {
|
50 |
-
color: #999;
|
51 |
-
}
|
52 |
-
|
53 |
-
#tnp-body table.widefat tr:nth-child(even) {
|
54 |
-
background-color: #28313C;
|
55 |
-
}
|
56 |
-
|
57 |
-
/* Set of checkboxes */
|
58 |
-
.tnpc-checkboxes label {
|
59 |
-
border: 1px solid #666;
|
60 |
-
background-color: transparent;
|
61 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emails/blocks/posts/layout-one.php
CHANGED
@@ -1,135 +1,135 @@
|
|
1 |
-
<?php
|
2 |
-
$size = ['width' => 600, 'height' => 0];
|
3 |
-
$total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
|
4 |
-
$column_width = $total_width / 2 - 10;
|
5 |
-
|
6 |
-
$title_style = TNP_Composer::get_style($options, 'title', $composer, 'title', ['scale' => .8]);
|
7 |
-
$text_style = TNP_Composer::get_style($options, '', $composer, 'text');
|
8 |
-
?>
|
9 |
-
<style>
|
10 |
-
.title {
|
11 |
-
<?php $title_style->echo_css()?>
|
12 |
-
line-height: normal !important;
|
13 |
-
padding: 0 0 5px 0;
|
14 |
-
}
|
15 |
-
|
16 |
-
.excerpt {
|
17 |
-
<?php $text_style->echo_css()?>
|
18 |
-
line-height: 1.5em !important;
|
19 |
-
padding: 10px 0 15px 0;
|
20 |
-
}
|
21 |
-
|
22 |
-
.meta {
|
23 |
-
font-family: <?php echo $text_style->font_family ?>;
|
24 |
-
color: <?php echo $text_style->font_color ?>;
|
25 |
-
font-size: <?php echo round($text_style->font_size * 0.9) ?>px;
|
26 |
-
font-weight: <?php echo $text_style->font_weight ?>;
|
27 |
-
font-style: italic;
|
28 |
-
padding: 0 0 10px 0;
|
29 |
-
line-height: normal !important;
|
30 |
-
}
|
31 |
-
.button {
|
32 |
-
padding: 15px 0;
|
33 |
-
}
|
34 |
-
</style>
|
35 |
-
|
36 |
-
|
37 |
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="responsive
|
38 |
-
|
39 |
-
<?php foreach ($posts as $post) { ?>
|
40 |
-
<?php
|
41 |
-
$url = tnp_post_permalink($post);
|
42 |
-
|
43 |
-
$media = null;
|
44 |
-
if ($show_image) {
|
45 |
-
$media = tnp_composer_block_posts_get_media($post, $size);
|
46 |
-
if ($media) {
|
47 |
-
$media->link = $url;
|
48 |
-
$media->set_width($column_width);
|
49 |
-
}
|
50 |
-
}
|
51 |
-
|
52 |
-
$meta = [];
|
53 |
-
|
54 |
-
if ($show_date) {
|
55 |
-
$meta[] = tnp_post_date($post);
|
56 |
-
}
|
57 |
-
|
58 |
-
if ($show_author) {
|
59 |
-
$author_object = get_user_by('id', $post->post_author);
|
60 |
-
if ($author_object) {
|
61 |
-
$meta[] = $author_object->display_name;
|
62 |
-
}
|
63 |
-
}
|
64 |
-
|
65 |
-
$button_options['button_url'] = $url;
|
66 |
-
$button_options['button_align'] = 'left';
|
67 |
-
?>
|
68 |
-
|
69 |
-
<tr>
|
70 |
-
<td valign="top" style="padding: 20px 0 0 0;">
|
71 |
-
|
72 |
-
<?php if ($media) { ?>
|
73 |
-
<table width="<?php echo $column_width ?>" cellpadding="0" cellspacing="0" border="0" align="left" class="responsive">
|
74 |
-
<tr>
|
75 |
-
<td style="padding-bottom: 20px;">
|
76 |
-
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
77 |
-
</td>
|
78 |
-
</tr>
|
79 |
-
</table>
|
80 |
-
<?php } ?>
|
81 |
-
|
82 |
-
<table width="<?php echo $media ? $column_width : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive" align="right"><tr><td>
|
83 |
-
|
84 |
-
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
85 |
-
<?php if ($meta) { ?>
|
86 |
-
<tr>
|
87 |
-
<td inline-class="meta" dir="<?php echo $dir ?>" align="<?php echo $align_left ?>">
|
88 |
-
<?php echo esc_html(implode(' - ', $meta)) ?>
|
89 |
-
</td>
|
90 |
-
</tr>
|
91 |
-
<?php } ?>
|
92 |
-
|
93 |
-
<tr>
|
94 |
-
<td align="<?php echo $align_left ?>" inline-class="title" class="title tnpc-row-edit tnpc-inline-editable"
|
95 |
-
data-type="title" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
|
96 |
-
<span>
|
97 |
-
<?php
|
98 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $post->ID) ?
|
99 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $post->ID) :
|
100 |
-
tnp_post_title($post)
|
101 |
-
?>
|
102 |
-
</span>
|
103 |
-
</td>
|
104 |
-
</tr>
|
105 |
-
|
106 |
-
<?php if ($excerpt_length) { ?>
|
107 |
-
<tr>
|
108 |
-
<td align="<?php echo $align_left ?>" inline-class="excerpt" class="tnpc-row-edit tnpc-inline-editable"
|
109 |
-
data-type="text" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
|
110 |
-
<?php
|
111 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $post->ID) ?
|
112 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $post->ID) :
|
113 |
-
tnp_post_excerpt($post, $excerpt_length)
|
114 |
-
?>
|
115 |
-
</td>
|
116 |
-
</tr>
|
117 |
-
<?php } ?>
|
118 |
-
|
119 |
-
<?php if ($show_read_more_button) { ?>
|
120 |
-
<tr>
|
121 |
-
<td align="<?php echo $align_left ?>" inline-class="button">
|
122 |
-
<?php echo TNP_Composer::button($button_options) ?>
|
123 |
-
</td>
|
124 |
-
</tr>
|
125 |
-
<?php } ?>
|
126 |
-
</table>
|
127 |
-
|
128 |
-
</td></tr></table>
|
129 |
-
|
130 |
-
</td>
|
131 |
-
</tr>
|
132 |
-
|
133 |
-
<?php } ?>
|
134 |
-
|
135 |
-
</table>
|
1 |
+
<?php
|
2 |
+
$size = ['width' => 600, 'height' => 0];
|
3 |
+
$total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
|
4 |
+
$column_width = $total_width / 2 - 10;
|
5 |
+
|
6 |
+
$title_style = TNP_Composer::get_style($options, 'title', $composer, 'title', ['scale' => .8]);
|
7 |
+
$text_style = TNP_Composer::get_style($options, '', $composer, 'text');
|
8 |
+
?>
|
9 |
+
<style>
|
10 |
+
.title {
|
11 |
+
<?php $title_style->echo_css()?>
|
12 |
+
line-height: normal !important;
|
13 |
+
padding: 0 0 5px 0;
|
14 |
+
}
|
15 |
+
|
16 |
+
.excerpt {
|
17 |
+
<?php $text_style->echo_css()?>
|
18 |
+
line-height: 1.5em !important;
|
19 |
+
padding: 10px 0 15px 0;
|
20 |
+
}
|
21 |
+
|
22 |
+
.meta {
|
23 |
+
font-family: <?php echo $text_style->font_family ?>;
|
24 |
+
color: <?php echo $text_style->font_color ?>;
|
25 |
+
font-size: <?php echo round($text_style->font_size * 0.9) ?>px;
|
26 |
+
font-weight: <?php echo $text_style->font_weight ?>;
|
27 |
+
font-style: italic;
|
28 |
+
padding: 0 0 10px 0;
|
29 |
+
line-height: normal !important;
|
30 |
+
}
|
31 |
+
.button {
|
32 |
+
padding: 15px 0;
|
33 |
+
}
|
34 |
+
</style>
|
35 |
+
|
36 |
+
|
37 |
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="responsive">
|
38 |
+
|
39 |
+
<?php foreach ($posts as $post) { ?>
|
40 |
+
<?php
|
41 |
+
$url = tnp_post_permalink($post);
|
42 |
+
|
43 |
+
$media = null;
|
44 |
+
if ($show_image) {
|
45 |
+
$media = tnp_composer_block_posts_get_media($post, $size);
|
46 |
+
if ($media) {
|
47 |
+
$media->link = $url;
|
48 |
+
$media->set_width($column_width);
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
$meta = [];
|
53 |
+
|
54 |
+
if ($show_date) {
|
55 |
+
$meta[] = tnp_post_date($post);
|
56 |
+
}
|
57 |
+
|
58 |
+
if ($show_author) {
|
59 |
+
$author_object = get_user_by('id', $post->post_author);
|
60 |
+
if ($author_object) {
|
61 |
+
$meta[] = $author_object->display_name;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
$button_options['button_url'] = $url;
|
66 |
+
$button_options['button_align'] = 'left';
|
67 |
+
?>
|
68 |
+
|
69 |
+
<tr>
|
70 |
+
<td valign="top" style="padding: 20px 0 0 0;">
|
71 |
+
|
72 |
+
<?php if ($media) { ?>
|
73 |
+
<table width="<?php echo $column_width ?>" cellpadding="0" cellspacing="0" border="0" align="left" class="responsive">
|
74 |
+
<tr>
|
75 |
+
<td style="padding-bottom: 20px;" width="100%">
|
76 |
+
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
77 |
+
</td>
|
78 |
+
</tr>
|
79 |
+
</table>
|
80 |
+
<?php } ?>
|
81 |
+
|
82 |
+
<table width="<?php echo $media ? $column_width : '100%' ?>" cellpadding="0" cellspacing="0" border="0" class="responsive" align="right"><tr><td>
|
83 |
+
|
84 |
+
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
85 |
+
<?php if ($meta) { ?>
|
86 |
+
<tr>
|
87 |
+
<td inline-class="meta" dir="<?php echo $dir ?>" align="<?php echo $align_left ?>">
|
88 |
+
<?php echo esc_html(implode(' - ', $meta)) ?>
|
89 |
+
</td>
|
90 |
+
</tr>
|
91 |
+
<?php } ?>
|
92 |
+
|
93 |
+
<tr>
|
94 |
+
<td align="<?php echo $align_left ?>" inline-class="title" class="title tnpc-row-edit tnpc-inline-editable"
|
95 |
+
data-type="title" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
|
96 |
+
<span>
|
97 |
+
<?php
|
98 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $post->ID) ?
|
99 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $post->ID) :
|
100 |
+
tnp_post_title($post)
|
101 |
+
?>
|
102 |
+
</span>
|
103 |
+
</td>
|
104 |
+
</tr>
|
105 |
+
|
106 |
+
<?php if ($excerpt_length) { ?>
|
107 |
+
<tr>
|
108 |
+
<td align="<?php echo $align_left ?>" inline-class="excerpt" class="tnpc-row-edit tnpc-inline-editable"
|
109 |
+
data-type="text" data-id="<?php echo $post->ID ?>" dir="<?php echo $dir ?>">
|
110 |
+
<?php
|
111 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $post->ID) ?
|
112 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $post->ID) :
|
113 |
+
tnp_post_excerpt($post, $excerpt_length)
|
114 |
+
?>
|
115 |
+
</td>
|
116 |
+
</tr>
|
117 |
+
<?php } ?>
|
118 |
+
|
119 |
+
<?php if ($show_read_more_button) { ?>
|
120 |
+
<tr>
|
121 |
+
<td align="<?php echo $align_left ?>" inline-class="button">
|
122 |
+
<?php echo TNP_Composer::button($button_options) ?>
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
<?php } ?>
|
126 |
+
</table>
|
127 |
+
|
128 |
+
</td></tr></table>
|
129 |
+
|
130 |
+
</td>
|
131 |
+
</tr>
|
132 |
+
|
133 |
+
<?php } ?>
|
134 |
+
|
135 |
+
</table>
|
emails/blocks/posts/layout-two.php
CHANGED
@@ -1,208 +1,208 @@
|
|
1 |
-
<?php
|
2 |
-
$size = array('width' => 600, 'height' => 400, "crop" => true);
|
3 |
-
$total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
|
4 |
-
$column_width = $total_width / 2 - 20;
|
5 |
-
|
6 |
-
$title_style = TNP_Composer::get_style($options, 'title', $composer, 'title', ['scale' => .8]);
|
7 |
-
$text_style = TNP_Composer::get_style($options, '', $composer, 'text');
|
8 |
-
?>
|
9 |
-
<style>
|
10 |
-
.title {
|
11 |
-
font-family: <?php echo $title_style->font_family ?>;
|
12 |
-
font-size: <?php echo $title_style->font_size ?>px;
|
13 |
-
font-weight: <?php echo $title_style->font_weight ?>;
|
14 |
-
color: <?php echo $title_style->font_color ?>;
|
15 |
-
line-height: 1.3em;
|
16 |
-
padding: 15px 0 0 0;
|
17 |
-
}
|
18 |
-
|
19 |
-
.excerpt {
|
20 |
-
font-family: <?php echo $text_style->font_family ?>;
|
21 |
-
font-size: <?php echo $text_style->font_size ?>px;
|
22 |
-
font-weight: <?php echo $text_style->font_weight ?>;
|
23 |
-
color: <?php echo $text_style->font_color ?>;
|
24 |
-
line-height: 1.4em;
|
25 |
-
padding: 5px 0 0 0;
|
26 |
-
}
|
27 |
-
|
28 |
-
.meta {
|
29 |
-
font-family: <?php echo $text_style->font_family ?>;
|
30 |
-
color: <?php echo $text_style->font_color ?>;
|
31 |
-
font-size: <?php echo round($text_style->font_size * 0.9) ?>px;
|
32 |
-
font-weight: <?php echo $text_style->font_weight ?>;
|
33 |
-
padding: 10px 0 0 0;
|
34 |
-
font-style: italic;
|
35 |
-
line-height: normal !important;
|
36 |
-
}
|
37 |
-
.button {
|
38 |
-
padding: 15px 0;
|
39 |
-
}
|
40 |
-
.column-left {
|
41 |
-
padding-right: 10px;
|
42 |
-
padding-bottom: 20px;
|
43 |
-
}
|
44 |
-
.column-right {
|
45 |
-
padding-left: 10px;
|
46 |
-
padding-bottom: 20px;
|
47 |
-
}
|
48 |
-
|
49 |
-
</style>
|
50 |
-
|
51 |
-
<table cellspacing="0" cellpadding="0" border="0" width="100%">
|
52 |
-
|
53 |
-
<?php foreach (array_chunk($posts, 2) AS $row) { ?>
|
54 |
-
<?php
|
55 |
-
$media = null;
|
56 |
-
if ($show_image) {
|
57 |
-
$media = tnp_composer_block_posts_get_media($row[0], $size, $image_placeholder_url);
|
58 |
-
$media->link = tnp_post_permalink($row[0]);
|
59 |
-
$media->set_width($column_width);
|
60 |
-
}
|
61 |
-
|
62 |
-
$meta = [];
|
63 |
-
|
64 |
-
if ($show_date) {
|
65 |
-
$meta[] = tnp_post_date($row[0]);
|
66 |
-
}
|
67 |
-
|
68 |
-
if ($show_author) {
|
69 |
-
$author_object = get_user_by('id', $row[0]->post_author);
|
70 |
-
if ($author_object) {
|
71 |
-
$meta[] = $author_object->display_name;
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
$button_options['button_url'] = tnp_post_permalink($row[0]);
|
76 |
-
?>
|
77 |
-
<tr>
|
78 |
-
<td inline-class="column-left" width="50%" valign="top" class="responsive">
|
79 |
-
|
80 |
-
|
81 |
-
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
82 |
-
<?php if ($media) { ?>
|
83 |
-
<tr>
|
84 |
-
<td align="center" valign="middle">
|
85 |
-
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
86 |
-
</td>
|
87 |
-
</tr>
|
88 |
-
<?php } ?>
|
89 |
-
<tr>
|
90 |
-
<td align="center" inline-class="title" class="title tnpc-row-edit tnpc-inline-editable" data-type="title" data-id="<?php echo $row[0]->ID ?>">
|
91 |
-
<?php
|
92 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $row[0]->ID) ?
|
93 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $row[0]->ID) :
|
94 |
-
tnp_post_title($row[0])
|
95 |
-
?>
|
96 |
-
</td>
|
97 |
-
</tr>
|
98 |
-
<?php if ($meta) { ?>
|
99 |
-
<tr>
|
100 |
-
<td inline-class="meta" class="meta">
|
101 |
-
<?php echo esc_html(implode(' - ', $meta)) ?>
|
102 |
-
</td>
|
103 |
-
</tr>
|
104 |
-
<?php } ?>
|
105 |
-
|
106 |
-
|
107 |
-
<?php if ($excerpt_length) { ?>
|
108 |
-
<tr>
|
109 |
-
<td align="center" inline-class="excerpt" class="title tnpc-row-edit tnpc-inline-editable" data-type="text" data-id="<?php echo $row[0]->ID ?>">
|
110 |
-
<?php
|
111 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $row[0]->ID) ?
|
112 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $row[0]->ID) :
|
113 |
-
tnp_post_excerpt($row[0], $excerpt_length)
|
114 |
-
?>
|
115 |
-
</td>
|
116 |
-
</tr>
|
117 |
-
<?php } ?>
|
118 |
-
|
119 |
-
<?php if ($show_read_more_button) { ?>
|
120 |
-
<tr>
|
121 |
-
<td align="center" inline-class="button">
|
122 |
-
<?php echo TNP_Composer::button($button_options) ?>
|
123 |
-
</td>
|
124 |
-
</tr>
|
125 |
-
<?php } ?>
|
126 |
-
</table>
|
127 |
-
</td>
|
128 |
-
|
129 |
-
<td inline-class="column-right" width="50%" valign="top" class="responsive">
|
130 |
-
<?php
|
131 |
-
if (isset($row[1])) {
|
132 |
-
|
133 |
-
$media = null;
|
134 |
-
if ($show_image) {
|
135 |
-
$media = tnp_composer_block_posts_get_media($row[1], $size, $image_placeholder_url);
|
136 |
-
$media->link = tnp_post_permalink($row[1]);
|
137 |
-
$media->set_width($column_width);
|
138 |
-
}
|
139 |
-
|
140 |
-
$meta = [];
|
141 |
-
|
142 |
-
if ($show_date) {
|
143 |
-
$meta[] = tnp_post_date($row[1]);
|
144 |
-
}
|
145 |
-
|
146 |
-
if ($show_author) {
|
147 |
-
$author_object = get_user_by('id', $row[1]->post_author);
|
148 |
-
if ($author_object) {
|
149 |
-
$meta[] = $author_object->display_name;
|
150 |
-
}
|
151 |
-
}
|
152 |
-
|
153 |
-
$button_options['button_url'] = tnp_post_permalink($row[1]);
|
154 |
-
?>
|
155 |
-
|
156 |
-
|
157 |
-
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
158 |
-
<?php if ($media) { ?>
|
159 |
-
<tr>
|
160 |
-
<td align="center" valign="middle">
|
161 |
-
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
162 |
-
</td>
|
163 |
-
</tr>
|
164 |
-
<?php } ?>
|
165 |
-
<tr>
|
166 |
-
<td align="center" inline-class="title" class="tnpc-row-edit tnpc-inline-editable" data-type="title" data-id="<?php echo $row[1]->ID ?>">
|
167 |
-
<?php
|
168 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $row[1]->ID) ?
|
169 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $row[1]->ID) :
|
170 |
-
tnp_post_title($row[1])
|
171 |
-
?>
|
172 |
-
</td>
|
173 |
-
</tr>
|
174 |
-
<?php if ($meta) { ?>
|
175 |
-
<tr>
|
176 |
-
<td inline-class="meta">
|
177 |
-
<?php echo esc_html(implode(' - ', $meta)) ?>
|
178 |
-
</td>
|
179 |
-
</tr>
|
180 |
-
<?php } ?>
|
181 |
-
|
182 |
-
<tr>
|
183 |
-
<td align="center" inline-class="excerpt" class="tnpc-row-edit tnpc-inline-editable" data-type="text" data-id="<?php echo $row[1]->ID ?>">
|
184 |
-
<?php
|
185 |
-
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $row[1]->ID) ?
|
186 |
-
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $row[1]->ID) :
|
187 |
-
tnp_post_excerpt($row[1], $excerpt_length)
|
188 |
-
?>
|
189 |
-
</td>
|
190 |
-
</tr>
|
191 |
-
<?php if ($show_read_more_button) { ?>
|
192 |
-
<tr>
|
193 |
-
<td align="center" inline-class="button">
|
194 |
-
<?php echo TNP_Composer::button($button_options) ?>
|
195 |
-
</td>
|
196 |
-
</tr>
|
197 |
-
<?php } ?>
|
198 |
-
</table>
|
199 |
-
<?php } ?>
|
200 |
-
|
201 |
-
|
202 |
-
</td>
|
203 |
-
</tr>
|
204 |
-
|
205 |
-
<?php } ?>
|
206 |
-
|
207 |
-
</table>
|
208 |
-
|
1 |
+
<?php
|
2 |
+
$size = array('width' => 600, 'height' => 400, "crop" => true);
|
3 |
+
$total_width = 600 - $options['block_padding_left'] - $options['block_padding_right'];
|
4 |
+
$column_width = $total_width / 2 - 20;
|
5 |
+
|
6 |
+
$title_style = TNP_Composer::get_style($options, 'title', $composer, 'title', ['scale' => .8]);
|
7 |
+
$text_style = TNP_Composer::get_style($options, '', $composer, 'text');
|
8 |
+
?>
|
9 |
+
<style>
|
10 |
+
.title {
|
11 |
+
font-family: <?php echo $title_style->font_family ?>;
|
12 |
+
font-size: <?php echo $title_style->font_size ?>px;
|
13 |
+
font-weight: <?php echo $title_style->font_weight ?>;
|
14 |
+
color: <?php echo $title_style->font_color ?>;
|
15 |
+
line-height: 1.3em;
|
16 |
+
padding: 15px 0 0 0;
|
17 |
+
}
|
18 |
+
|
19 |
+
.excerpt {
|
20 |
+
font-family: <?php echo $text_style->font_family ?>;
|
21 |
+
font-size: <?php echo $text_style->font_size ?>px;
|
22 |
+
font-weight: <?php echo $text_style->font_weight ?>;
|
23 |
+
color: <?php echo $text_style->font_color ?>;
|
24 |
+
line-height: 1.4em;
|
25 |
+
padding: 5px 0 0 0;
|
26 |
+
}
|
27 |
+
|
28 |
+
.meta {
|
29 |
+
font-family: <?php echo $text_style->font_family ?>;
|
30 |
+
color: <?php echo $text_style->font_color ?>;
|
31 |
+
font-size: <?php echo round($text_style->font_size * 0.9) ?>px;
|
32 |
+
font-weight: <?php echo $text_style->font_weight ?>;
|
33 |
+
padding: 10px 0 0 0;
|
34 |
+
font-style: italic;
|
35 |
+
line-height: normal !important;
|
36 |
+
}
|
37 |
+
.button {
|
38 |
+
padding: 15px 0;
|
39 |
+
}
|
40 |
+
.column-left {
|
41 |
+
padding-right: 10px;
|
42 |
+
padding-bottom: 20px;
|
43 |
+
}
|
44 |
+
.column-right {
|
45 |
+
padding-left: 10px;
|
46 |
+
padding-bottom: 20px;
|
47 |
+
}
|
48 |
+
|
49 |
+
</style>
|
50 |
+
|
51 |
+
<table cellspacing="0" cellpadding="0" border="0" width="100%">
|
52 |
+
|
53 |
+
<?php foreach (array_chunk($posts, 2) AS $row) { ?>
|
54 |
+
<?php
|
55 |
+
$media = null;
|
56 |
+
if ($show_image) {
|
57 |
+
$media = tnp_composer_block_posts_get_media($row[0], $size, $image_placeholder_url);
|
58 |
+
$media->link = tnp_post_permalink($row[0]);
|
59 |
+
$media->set_width($column_width);
|
60 |
+
}
|
61 |
+
|
62 |
+
$meta = [];
|
63 |
+
|
64 |
+
if ($show_date) {
|
65 |
+
$meta[] = tnp_post_date($row[0]);
|
66 |
+
}
|
67 |
+
|
68 |
+
if ($show_author) {
|
69 |
+
$author_object = get_user_by('id', $row[0]->post_author);
|
70 |
+
if ($author_object) {
|
71 |
+
$meta[] = $author_object->display_name;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
$button_options['button_url'] = tnp_post_permalink($row[0]);
|
76 |
+
?>
|
77 |
+
<tr>
|
78 |
+
<td inline-class="column-left" width="50%" valign="top" class="responsive">
|
79 |
+
|
80 |
+
|
81 |
+
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
82 |
+
<?php if ($media) { ?>
|
83 |
+
<tr>
|
84 |
+
<td align="center" valign="middle">
|
85 |
+
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
86 |
+
</td>
|
87 |
+
</tr>
|
88 |
+
<?php } ?>
|
89 |
+
<tr>
|
90 |
+
<td align="center" inline-class="title" class="title tnpc-row-edit tnpc-inline-editable" data-type="title" data-id="<?php echo $row[0]->ID ?>">
|
91 |
+
<?php
|
92 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $row[0]->ID) ?
|
93 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $row[0]->ID) :
|
94 |
+
tnp_post_title($row[0])
|
95 |
+
?>
|
96 |
+
</td>
|
97 |
+
</tr>
|
98 |
+
<?php if ($meta) { ?>
|
99 |
+
<tr>
|
100 |
+
<td align="center" inline-class="meta" class="meta">
|
101 |
+
<?php echo esc_html(implode(' - ', $meta)) ?>
|
102 |
+
</td>
|
103 |
+
</tr>
|
104 |
+
<?php } ?>
|
105 |
+
|
106 |
+
|
107 |
+
<?php if ($excerpt_length) { ?>
|
108 |
+
<tr>
|
109 |
+
<td align="center" inline-class="excerpt" class="title tnpc-row-edit tnpc-inline-editable" data-type="text" data-id="<?php echo $row[0]->ID ?>">
|
110 |
+
<?php
|
111 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $row[0]->ID) ?
|
112 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $row[0]->ID) :
|
113 |
+
tnp_post_excerpt($row[0], $excerpt_length)
|
114 |
+
?>
|
115 |
+
</td>
|
116 |
+
</tr>
|
117 |
+
<?php } ?>
|
118 |
+
|
119 |
+
<?php if ($show_read_more_button) { ?>
|
120 |
+
<tr>
|
121 |
+
<td align="center" inline-class="button">
|
122 |
+
<?php echo TNP_Composer::button($button_options) ?>
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
<?php } ?>
|
126 |
+
</table>
|
127 |
+
</td>
|
128 |
+
|
129 |
+
<td inline-class="column-right" width="50%" valign="top" class="responsive">
|
130 |
+
<?php
|
131 |
+
if (isset($row[1])) {
|
132 |
+
|
133 |
+
$media = null;
|
134 |
+
if ($show_image) {
|
135 |
+
$media = tnp_composer_block_posts_get_media($row[1], $size, $image_placeholder_url);
|
136 |
+
$media->link = tnp_post_permalink($row[1]);
|
137 |
+
$media->set_width($column_width);
|
138 |
+
}
|
139 |
+
|
140 |
+
$meta = [];
|
141 |
+
|
142 |
+
if ($show_date) {
|
143 |
+
$meta[] = tnp_post_date($row[1]);
|
144 |
+
}
|
145 |
+
|
146 |
+
if ($show_author) {
|
147 |
+
$author_object = get_user_by('id', $row[1]->post_author);
|
148 |
+
if ($author_object) {
|
149 |
+
$meta[] = $author_object->display_name;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
$button_options['button_url'] = tnp_post_permalink($row[1]);
|
154 |
+
?>
|
155 |
+
|
156 |
+
|
157 |
+
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
158 |
+
<?php if ($media) { ?>
|
159 |
+
<tr>
|
160 |
+
<td align="center" valign="middle">
|
161 |
+
<?php echo TNP_Composer::image($media, ['class' => 'fluid']) ?>
|
162 |
+
</td>
|
163 |
+
</tr>
|
164 |
+
<?php } ?>
|
165 |
+
<tr>
|
166 |
+
<td align="center" inline-class="title" class="tnpc-row-edit tnpc-inline-editable" data-type="title" data-id="<?php echo $row[1]->ID ?>">
|
167 |
+
<?php
|
168 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'title', $row[1]->ID) ?
|
169 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'title', $row[1]->ID) :
|
170 |
+
tnp_post_title($row[1])
|
171 |
+
?>
|
172 |
+
</td>
|
173 |
+
</tr>
|
174 |
+
<?php if ($meta) { ?>
|
175 |
+
<tr>
|
176 |
+
<td inline-class="meta">
|
177 |
+
<?php echo esc_html(implode(' - ', $meta)) ?>
|
178 |
+
</td>
|
179 |
+
</tr>
|
180 |
+
<?php } ?>
|
181 |
+
|
182 |
+
<tr>
|
183 |
+
<td align="center" inline-class="excerpt" class="tnpc-row-edit tnpc-inline-editable" data-type="text" data-id="<?php echo $row[1]->ID ?>">
|
184 |
+
<?php
|
185 |
+
echo TNP_Composer::is_post_field_edited_inline($options['inline_edits'], 'text', $row[1]->ID) ?
|
186 |
+
TNP_Composer::get_edited_inline_post_field($options['inline_edits'], 'text', $row[1]->ID) :
|
187 |
+
tnp_post_excerpt($row[1], $excerpt_length)
|
188 |
+
?>
|
189 |
+
</td>
|
190 |
+
</tr>
|
191 |
+
<?php if ($show_read_more_button) { ?>
|
192 |
+
<tr>
|
193 |
+
<td align="center" inline-class="button">
|
194 |
+
<?php echo TNP_Composer::button($button_options) ?>
|
195 |
+
</td>
|
196 |
+
</tr>
|
197 |
+
<?php } ?>
|
198 |
+
</table>
|
199 |
+
<?php } ?>
|
200 |
+
|
201 |
+
|
202 |
+
</td>
|
203 |
+
</tr>
|
204 |
+
|
205 |
+
<?php } ?>
|
206 |
+
|
207 |
+
</table>
|
208 |
+
|
emails/blocks/social/block.php
CHANGED
@@ -9,6 +9,8 @@
|
|
9 |
/* @var $options array */
|
10 |
|
11 |
$defaults = array(
|
|
|
|
|
12 |
'block_padding_left' => 15,
|
13 |
'block_padding_right' => 15,
|
14 |
'block_padding_bottom' => 15,
|
@@ -17,7 +19,9 @@ $defaults = array(
|
|
17 |
);
|
18 |
$options = array_merge($defaults, $options);
|
19 |
|
20 |
-
$
|
|
|
|
|
21 |
|
22 |
$socials = ['facebook', 'twitter', 'pinterest', 'linkedin', 'tumblr', 'youtube', 'soundcloud', 'instagram', 'vimeo', 'telegram', 'vk', 'discord', 'tiktok', 'twitch'];
|
23 |
|
@@ -43,7 +47,7 @@ if (!$valid_socials) {
|
|
43 |
<tr>
|
44 |
<td align="center" valign="middle">
|
45 |
<?php foreach ($valid_socials as &$social) { ?>
|
46 |
-
<a href="<?php echo esc_url($block_options[$social . '_url']) ?>" inline-class="link"><img src="<?php echo $social_icon_url ?>/<?php echo $social ?>.png" alt="<?php echo $social ?>"></a>
|
47 |
<?php } ?>
|
48 |
</td>
|
49 |
</tr>
|
9 |
/* @var $options array */
|
10 |
|
11 |
$defaults = array(
|
12 |
+
'type' => 1,
|
13 |
+
'width' => 32,
|
14 |
'block_padding_left' => 15,
|
15 |
'block_padding_right' => 15,
|
16 |
'block_padding_bottom' => 15,
|
19 |
);
|
20 |
$options = array_merge($defaults, $options);
|
21 |
|
22 |
+
$type = (int) $options['type'];
|
23 |
+
$width = (int) $options['width'];
|
24 |
+
$social_icon_url = plugins_url('newsletter') . '/images/social-' . $type;
|
25 |
|
26 |
$socials = ['facebook', 'twitter', 'pinterest', 'linkedin', 'tumblr', 'youtube', 'soundcloud', 'instagram', 'vimeo', 'telegram', 'vk', 'discord', 'tiktok', 'twitch'];
|
27 |
|
47 |
<tr>
|
48 |
<td align="center" valign="middle">
|
49 |
<?php foreach ($valid_socials as &$social) { ?>
|
50 |
+
<a href="<?php echo esc_url($block_options[$social . '_url']) ?>" inline-class="link"><img src="<?php echo $social_icon_url ?>/<?php echo $social ?>.png" width="<?php echo $width?>" height="<?php echo $width?>" alt="<?php echo $social ?>"></a>
|
51 |
<?php } ?>
|
52 |
</td>
|
53 |
</tr>
|
emails/blocks/social/options.php
CHANGED
@@ -1,9 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $options array contains all the options the current block we're ediging contains */
|
3 |
-
/* @var $controls NewsletterControls */
|
4 |
-
/* @var $fields NewsletterFields */
|
5 |
-
?>
|
6 |
-
|
7 |
-
<p>Social profiles can be configured on company info panel.</p>
|
8 |
-
|
9 |
-
<?php $fields->
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $options array contains all the options the current block we're ediging contains */
|
3 |
+
/* @var $controls NewsletterControls */
|
4 |
+
/* @var $fields NewsletterFields */
|
5 |
+
?>
|
6 |
+
|
7 |
+
<p>Social profiles can be configured on company info panel.</p>
|
8 |
+
|
9 |
+
<?php $fields->select('type', 'Appearance', ['1'=>'Round colored', '2'=>'Round monochrome']) ?>
|
10 |
+
|
11 |
+
<?php $fields->select('width', 'Size', ['16'=>'16 px', '24'=>'24 px', '32'=>'32 px']) ?>
|
12 |
+
|
13 |
+
<?php $fields->block_commons() ?>
|
emails/emails.php
CHANGED
@@ -1,1410 +1,1410 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
defined('ABSPATH') || exit;
|
4 |
-
|
5 |
-
class NewsletterEmails extends NewsletterModule {
|
6 |
-
|
7 |
-
static $instance;
|
8 |
-
|
9 |
-
const EDITOR_COMPOSER = 2;
|
10 |
-
const EDITOR_HTML = 1;
|
11 |
-
const EDITOR_TINYMCE = 0;
|
12 |
-
|
13 |
-
static $PRESETS_LIST;
|
14 |
-
|
15 |
-
const PRESET_EMAIL_TYPE = 'composer_template';
|
16 |
-
|
17 |
-
// Cache
|
18 |
-
var $blocks = null;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @return NewsletterEmails
|
22 |
-
*/
|
23 |
-
static function instance() {
|
24 |
-
if (self::$instance == null) {
|
25 |
-
self::$instance = new NewsletterEmails();
|
26 |
-
}
|
27 |
-
|
28 |
-
return self::$instance;
|
29 |
-
}
|
30 |
-
|
31 |
-
function __construct() {
|
32 |
-
self::$PRESETS_LIST = array("cta", "invite", "announcement", "posts", "sales", "product", "tour", "simple");
|
33 |
-
$this->themes = new NewsletterThemes('emails');
|
34 |
-
parent::__construct('emails', '1.1.5');
|
35 |
-
add_action('newsletter_action', array($this, 'hook_newsletter_action'), 13, 3);
|
36 |
-
|
37 |
-
if (is_admin()) {
|
38 |
-
if (defined('DOING_AJAX') && DOING_AJAX) {
|
39 |
-
add_action('wp_ajax_tnpc_render', array($this, 'tnpc_render_callback'));
|
40 |
-
add_action('wp_ajax_tnpc_preview', array($this, 'tnpc_preview_callback'));
|
41 |
-
add_action('wp_ajax_tnpc_css', array($this, 'tnpc_css_callback'));
|
42 |
-
add_action('wp_ajax_tnpc_options', array($this, 'hook_wp_ajax_tnpc_options'));
|
43 |
-
add_action('wp_ajax_tnpc_get_all_presets', array($this, 'ajax_get_all_presets'));
|
44 |
-
add_action('wp_ajax_tnpc_get_preset', array($this, 'ajax_get_preset'));
|
45 |
-
add_action('wp_ajax_tnpc_delete_preset', array($this, 'hook_wp_ajax_tnpc_delete_preset'));
|
46 |
-
add_action('wp_ajax_tnpc_regenerate_email', array($this, 'hook_wp_ajax_tnpc_regenerate_email'));
|
47 |
-
}
|
48 |
-
// Thank you to plugins which add the WP editor on other admin plugin pages...
|
49 |
-
if (isset($_GET['page']) && $_GET['page'] == 'newsletter_emails_edit') {
|
50 |
-
global $wp_actions;
|
51 |
-
$wp_actions['wp_enqueue_editor'] = 1;
|
52 |
-
}
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
function options_decode($options) {
|
57 |
-
|
58 |
-
// Start compatibility
|
59 |
-
if (is_string($options) && strpos($options, 'options[') !== false) {
|
60 |
-
$opts = array();
|
61 |
-
parse_str($options, $opts);
|
62 |
-
$options = $opts['options'];
|
63 |
-
}
|
64 |
-
// End compatibility
|
65 |
-
|
66 |
-
if (is_array($options)) {
|
67 |
-
return $options;
|
68 |
-
}
|
69 |
-
|
70 |
-
$tmp = json_decode($options, true);
|
71 |
-
if (is_null($tmp)) {
|
72 |
-
return json_decode(base64_decode($options), true);
|
73 |
-
} else {
|
74 |
-
return $tmp;
|
75 |
-
}
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
*
|
80 |
-
* @param array $options Options array
|
81 |
-
*/
|
82 |
-
function options_encode($options) {
|
83 |
-
return base64_encode(json_encode($options, JSON_HEX_TAG | JSON_HEX_AMP));
|
84 |
-
}
|
85 |
-
|
86 |
-
function hook_wp_ajax_tnpc_options() {
|
87 |
-
global $wpdb;
|
88 |
-
|
89 |
-
// TODO: Uniform to use id everywhere
|
90 |
-
// if (!isset($_REQUEST['id'])) {
|
91 |
-
// $_REQUEST['id'] = $_REQUEST['b'];
|
92 |
-
// }
|
93 |
-
|
94 |
-
$block = $this->get_block($_REQUEST['id']);
|
95 |
-
if (!$block) {
|
96 |
-
die('Block not found with id ' . esc_html($_REQUEST['id']));
|
97 |
-
}
|
98 |
-
|
99 |
-
if (!class_exists('NewsletterControls')) {
|
100 |
-
include NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
101 |
-
}
|
102 |
-
|
103 |
-
$options = $this->options_decode(stripslashes_deep($_REQUEST['options']));
|
104 |
-
$composer = isset($_POST['composer']) ? $_POST['composer'] : [];
|
105 |
-
|
106 |
-
$context = array('type' => '');
|
107 |
-
if (isset($_REQUEST['context_type'])) {
|
108 |
-
$context['type'] = $_REQUEST['context_type'];
|
109 |
-
}
|
110 |
-
|
111 |
-
$controls = new NewsletterControls($options);
|
112 |
-
$fields = new NewsletterFields($controls);
|
113 |
-
|
114 |
-
$controls->init();
|
115 |
-
echo '<input type="hidden" name="action" value="tnpc_render">';
|
116 |
-
echo '<input type="hidden" name="id" value="' . esc_attr($_REQUEST['id']) . '">';
|
117 |
-
echo '<input type="hidden" name="context_type" value="' . esc_attr($context['type']) . '">';
|
118 |
-
$inline_edits = '';
|
119 |
-
if (isset($controls->data['inline_edits'])) {
|
120 |
-
$inline_edits = $controls->data['inline_edits'];
|
121 |
-
}
|
122 |
-
echo '<input type="hidden" name="options[inline_edits]" value="', esc_attr($this->options_encode($inline_edits)), '">';
|
123 |
-
|
124 |
-
ob_start();
|
125 |
-
include $block['dir'] . '/options.php';
|
126 |
-
$content = ob_get_clean();
|
127 |
-
echo "<h2>", esc_html($block["name"]), "</h2>";
|
128 |
-
echo $content;
|
129 |
-
wp_die();
|
130 |
-
}
|
131 |
-
|
132 |
-
/**
|
133 |
-
* Retrieves the presets list (no id in GET) or a specific preset id in GET)
|
134 |
-
*/
|
135 |
-
public function ajax_get_all_presets() {
|
136 |
-
wp_send_json_success($this->get_all_preset());
|
137 |
-
}
|
138 |
-
|
139 |
-
public function ajax_get_preset() {
|
140 |
-
|
141 |
-
if (empty($_REQUEST['id'])) {
|
142 |
-
wp_send_json_error([
|
143 |
-
'msg' => __('Invalid preset ID')
|
144 |
-
]);
|
145 |
-
}
|
146 |
-
|
147 |
-
$preset_id = $_REQUEST['id'];
|
148 |
-
$preset_content = $this->get_preset_content($preset_id);
|
149 |
-
$global_options = $this->get_preset_global_options($preset_id);
|
150 |
-
|
151 |
-
wp_send_json_success([
|
152 |
-
'content' => $preset_content,
|
153 |
-
'globalOptions' => $global_options,
|
154 |
-
]);
|
155 |
-
}
|
156 |
-
|
157 |
-
private function get_preset_content($preset_id) {
|
158 |
-
|
159 |
-
$content = '';
|
160 |
-
|
161 |
-
if ($this->is_a_tnp_default_preset($preset_id)) {
|
162 |
-
|
163 |
-
// Get preset from file
|
164 |
-
$preset = $this->get_preset_from_file($preset_id);
|
165 |
-
|
166 |
-
foreach ($preset->blocks as $item) {
|
167 |
-
ob_start();
|
168 |
-
$this->render_block($item->block, true, (array) $item->options);
|
169 |
-
$content .= trim(ob_get_clean());
|
170 |
-
}
|
171 |
-
} else {
|
172 |
-
|
173 |
-
// Get preset from db
|
174 |
-
$preset_email = $this->get_email(intval($preset_id));
|
175 |
-
$global_options = $this->extract_global_options_from($preset_email);
|
176 |
-
$content = $this->regenerate_email_blocks($preset_email->message, $global_options);
|
177 |
-
}
|
178 |
-
|
179 |
-
return $content;
|
180 |
-
}
|
181 |
-
|
182 |
-
private function get_preset_global_options($preset_id) {
|
183 |
-
|
184 |
-
if ($this->is_a_tnp_default_preset($preset_id)) {
|
185 |
-
return [];
|
186 |
-
}
|
187 |
-
|
188 |
-
// Get preset from db
|
189 |
-
$preset_email = $this->get_email(intval($preset_id));
|
190 |
-
$global_options = $this->extract_global_options_from($preset_email);
|
191 |
-
|
192 |
-
return $global_options;
|
193 |
-
}
|
194 |
-
|
195 |
-
private function extract_global_options_from($email) {
|
196 |
-
$global_options = [];
|
197 |
-
foreach ($email->options as $global_option_name => $global_option) {
|
198 |
-
if (strpos($global_option_name, 'composer_') === 0) {
|
199 |
-
$global_options[str_replace('composer_', '', $global_option_name)] = $global_option;
|
200 |
-
}
|
201 |
-
}
|
202 |
-
|
203 |
-
return $global_options;
|
204 |
-
}
|
205 |
-
|
206 |
-
private function is_a_tnp_default_preset($preset_id) {
|
207 |
-
return in_array($preset_id, self::$PRESETS_LIST);
|
208 |
-
}
|
209 |
-
|
210 |
-
private function get_all_preset() {
|
211 |
-
|
212 |
-
$content = "<div class='tnpc-preset-container'>";
|
213 |
-
|
214 |
-
if ($this->is_normal_context_request()) {
|
215 |
-
$content .= "<div class='tnpc-preset-legacy-themes'><a href='" . $this->get_admin_page_url('theme') . "'>" . __('Looking for legacy themes?', 'newsletter') . "</a></div>";
|
216 |
-
}
|
217 |
-
|
218 |
-
// LOAD USER PRESETS
|
219 |
-
$user_preset_list = $this->get_emails(self::PRESET_EMAIL_TYPE);
|
220 |
-
|
221 |
-
foreach ($user_preset_list as $user_preset) {
|
222 |
-
|
223 |
-
$default_icon_url = NEWSLETTER_URL . "/emails/presets/default-icon.png?ver=2";
|
224 |
-
$preset_name = $user_preset->subject;
|
225 |
-
$delete_preset_text = __('Delete', 'newsletter');
|
226 |
-
$edit_preset_text = __('Edit', 'newsletter');
|
227 |
-
|
228 |
-
// esc_js() assumes the string will be in single quote (arghhh!!!)
|
229 |
-
$onclick_edit = 'tnpc_edit_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
230 |
-
$onclick_delete = 'tnpc_delete_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
231 |
-
$onclick_load = 'tnpc_load_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
232 |
-
|
233 |
-
$content .= "<div class='tnpc-preset' onclick='" . esc_attr($onclick_load) . "'>\n";
|
234 |
-
$content .= "<img src='$default_icon_url' title='" . esc_attr($preset_name) . "' alt='" . esc_attr($preset_name) . "'>\n";
|
235 |
-
$content .= "<span class='tnpc-preset-label'>" . esc_html($user_preset->subject) . "</span>\n";
|
236 |
-
$content .= "<span class='tnpc-delete-preset' onclick='" . esc_attr($onclick_delete) . "' title='" . esc_attr($delete_preset_text) . "'><i class='fas fa-times'></i></span>\n";
|
237 |
-
$content .= "<span class='tnpc-edit-preset' onclick='" . esc_attr($onclick_edit) . "' title='" . esc_attr($edit_preset_text) . "'><i class='fas fa-pencil-alt'></i></span>\n";
|
238 |
-
$content .= "</div>";
|
239 |
-
}
|
240 |
-
|
241 |
-
// LOAD TNP PRESETS
|
242 |
-
foreach (self::$PRESETS_LIST as $id) {
|
243 |
-
$preset = $this->get_preset_from_file($id);
|
244 |
-
$preset_name = esc_html($preset->name);
|
245 |
-
$content .= "<div class='tnpc-preset' onclick='tnpc_load_preset(\"$id\")'>";
|
246 |
-
$content .= "<img src='$preset->icon' title='$preset_name' alt='$preset_name'/>";
|
247 |
-
$content .= "<span class='tnpc-preset-label'>$preset_name</span>";
|
248 |
-
$content .= "</div>";
|
249 |
-
}
|
250 |
-
|
251 |
-
if ($this->is_normal_context_request()) {
|
252 |
-
$content .= $this->get_automated_spot_element();
|
253 |
-
$content .= $this->get_autoresponder_spot_element();
|
254 |
-
$content .= $this->get_raw_html_preset_element();
|
255 |
-
}
|
256 |
-
|
257 |
-
return $content;
|
258 |
-
}
|
259 |
-
|
260 |
-
private function is_normal_context_request() {
|
261 |
-
return empty($_REQUEST['context_type']);
|
262 |
-
}
|
263 |
-
|
264 |
-
private function is_automated_context_request() {
|
265 |
-
return isset($_REQUEST['context_type']) && $_REQUEST['context_type'] === 'automated';
|
266 |
-
}
|
267 |
-
|
268 |
-
private function is_autoresponder_context_request() {
|
269 |
-
return isset($_REQUEST['context_type']) && $_REQUEST['context_type'] === 'autoresponder';
|
270 |
-
}
|
271 |
-
|
272 |
-
private function get_automated_spot_element() {
|
273 |
-
$result = "<div class='tnpc-preset'>";
|
274 |
-
if (class_exists('NewsletterAutomated')) {
|
275 |
-
$result .= "<a href='?page=newsletter_automated_index'>";
|
276 |
-
} else {
|
277 |
-
$result .= "<a href='https://www.thenewsletterplugin.com/automated?utm_source=plugin&utm_campaign=automated&utm_medium=composer'>";
|
278 |
-
}
|
279 |
-
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/automated.png' title='Automated addon' alt='Automated'/>";
|
280 |
-
$result .= "<span class='tnpc-preset-label'>Daily, weekly and monthly newsletters</span></a>";
|
281 |
-
$result .= "</div>";
|
282 |
-
|
283 |
-
return $result;
|
284 |
-
}
|
285 |
-
|
286 |
-
private function get_autoresponder_spot_element() {
|
287 |
-
$result = "<div class='tnpc-preset'>";
|
288 |
-
if (class_exists('NewsletterAutoresponder')) {
|
289 |
-
$result .= "<a href='?page=newsletter_autoresponder_index'>";
|
290 |
-
} else {
|
291 |
-
$result .= "<a href='https://www.thenewsletterplugin.com/autoresponder?utm_source=plugin&utm_campaign=autoresponder&utm_medium=composer' target='_blank'>";
|
292 |
-
}
|
293 |
-
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/autoresponder.png' title='Autoresponder addon' alt='Autoresponder'/>";
|
294 |
-
$result .= "<span class='tnpc-preset-label'>Autoresponders</span></a>";
|
295 |
-
$result .= "</div>";
|
296 |
-
|
297 |
-
return $result;
|
298 |
-
}
|
299 |
-
|
300 |
-
private function get_raw_html_preset_element() {
|
301 |
-
|
302 |
-
$result = "<div class='tnpc-preset tnpc-preset-html' onclick='location.href=\"" . wp_nonce_url('admin.php?page=newsletter_emails_new&id=rawhtml', 'newsletter-new') . "\"'>";
|
303 |
-
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/rawhtml.png' title='RAW HTML' alt='RAW'/>";
|
304 |
-
$result .= "<span class='tnpc-preset-label'>Raw HTML</span>";
|
305 |
-
$result .= "</div>";
|
306 |
-
|
307 |
-
$result .= "<div class='clear'></div>";
|
308 |
-
$result .= "</div>";
|
309 |
-
|
310 |
-
return $result;
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Check if the preset name exists and adds an incremental suffix if the name exists.
|
315 |
-
*
|
316 |
-
* @param string $name
|
317 |
-
*
|
318 |
-
* @return string
|
319 |
-
*/
|
320 |
-
public function sanitize_preset_name($name) {
|
321 |
-
global $wpdb;
|
322 |
-
|
323 |
-
$name = empty($name) ? __('Empty name preset', 'newsletter') : $name;
|
324 |
-
$name = sanitize_text_field($name);
|
325 |
-
$type = self::PRESET_EMAIL_TYPE;
|
326 |
-
$count = (int) $wpdb->get_var("SELECT COUNT(*) FROM " . NEWSLETTER_EMAILS_TABLE . " WHERE type='$type' and subject='$name'");
|
327 |
-
|
328 |
-
$name = $count > 0 ? $name . " - " . ($count + 1) : $name;
|
329 |
-
|
330 |
-
return $name;
|
331 |
-
}
|
332 |
-
|
333 |
-
function has_dynamic_blocks($theme) {
|
334 |
-
preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
|
335 |
-
foreach ($matches[1] as $match) {
|
336 |
-
$a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
|
337 |
-
$options = $this->options_decode($a);
|
338 |
-
|
339 |
-
$block = $this->get_block($options['block_id']);
|
340 |
-
if (!$block) {
|
341 |
-
continue;
|
342 |
-
}
|
343 |
-
if ($block['type'] == 'dynamic') {
|
344 |
-
return true;
|
345 |
-
}
|
346 |
-
}
|
347 |
-
return false;
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Regenerates a saved composed email rendering each block. Regeneration is
|
352 |
-
* conditioned (possibly) by the context. The context is usually passed to blocks
|
353 |
-
* so they can act in the right manner.
|
354 |
-
*
|
355 |
-
* $context contains a type and, for automated, the last_run.
|
356 |
-
*
|
357 |
-
* $email can actually be even a string containing the full newsletter HTML code.
|
358 |
-
*
|
359 |
-
* @param TNP_Email $email (Rinominare)
|
360 |
-
* @return string
|
361 |
-
*/
|
362 |
-
function regenerate($email, $context = []) {
|
363 |
-
|
364 |
-
// Cannot be removed due to compatibility issues with old Automated versions
|
365 |
-
if (is_object($email)) {
|
366 |
-
$theme = $email->message;
|
367 |
-
} else {
|
368 |
-
$theme = $email;
|
369 |
-
}
|
370 |
-
|
371 |
-
//$this->logger->debug('Starting email regeneration');
|
372 |
-
//$this->logger->debug($context);
|
373 |
-
|
374 |
-
if (empty($theme)) {
|
375 |
-
$this->logger->debug('The email was empty');
|
376 |
-
return array('body' => '', 'subject' => '');
|
377 |
-
}
|
378 |
-
|
379 |
-
$context = array_merge(['last_run' => 0, 'type' => ''], $context);
|
380 |
-
|
381 |
-
preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
|
382 |
-
|
383 |
-
$result = '';
|
384 |
-
$subject = '';
|
385 |
-
|
386 |
-
foreach ($matches[1] as $match) {
|
387 |
-
$a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
|
388 |
-
$options = $this->options_decode($a);
|
389 |
-
|
390 |
-
$block = $this->get_block($options['block_id']);
|
391 |
-
if (!$block) {
|
392 |
-
$this->logger->debug('Unable to load the block ' . $options['block_id']);
|
393 |
-
//continue;
|
394 |
-
}
|
395 |
-
|
396 |
-
ob_start();
|
397 |
-
$out = $this->render_block($options['block_id'], true, $options, $context);
|
398 |
-
if (is_array($out)) {
|
399 |
-
if ($out['return_empty_message'] || $out['stop']) {
|
400 |
-
if (is_object($email)) {
|
401 |
-
return false;
|
402 |
-
}
|
403 |
-
return array();
|
404 |
-
}
|
405 |
-
if ($out['skip']) {
|
406 |
-
if (NEWSLETTER_DEBUG) {
|
407 |
-
$result .= 'Block removed by request';
|
408 |
-
}
|
409 |
-
continue;
|
410 |
-
}
|
411 |
-
if (empty($subject) && !empty($out['subject'])) {
|
412 |
-
$subject = $out['subject'];
|
413 |
-
}
|
414 |
-
}
|
415 |
-
$block_html = ob_get_clean();
|
416 |
-
$result .= $block_html;
|
417 |
-
}
|
418 |
-
|
419 |
-
// We need to keep the CSS/HEAD part, the regenearion is only about blocks
|
420 |
-
|
421 |
-
if (is_object($email)) {
|
422 |
-
$result = TNP_Composer::get_main_wrapper_open($email) . $result . TNP_Composer::get_main_wrapper_close($email);
|
423 |
-
}
|
424 |
-
|
425 |
-
$x = strpos($theme, '<body');
|
426 |
-
if ($x !== false) {
|
427 |
-
$x = strpos($theme, '>', $x);
|
428 |
-
$result = substr($theme, 0, $x + 1) . $result . '</body></html>';
|
429 |
-
} else {
|
430 |
-
|
431 |
-
}
|
432 |
-
|
433 |
-
if (is_object($email)) {
|
434 |
-
$email->message = $result;
|
435 |
-
$email->subject = $subject;
|
436 |
-
return true;
|
437 |
-
}
|
438 |
-
|
439 |
-
// Kept for compatibility
|
440 |
-
return array('body' => $result, 'subject' => $subject);
|
441 |
-
}
|
442 |
-
|
443 |
-
function remove_block_data($text) {
|
444 |
-
// TODO: Lavorare!
|
445 |
-
return $text;
|
446 |
-
}
|
447 |
-
|
448 |
-
static function get_outlook_wrapper_open($width = 600) {
|
449 |
-
return '<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '" style="vertical-align:top;width:' . $width . 'px;"><![endif]-->';
|
450 |
-
}
|
451 |
-
|
452 |
-
static function get_outlook_wrapper_close() {
|
453 |
-
return "<!--[if mso | IE]></td></tr></table><![endif]-->";
|
454 |
-
}
|
455 |
-
|
456 |
-
function hook_safe_style_css($rules) {
|
457 |
-
$rules[] = 'display';
|
458 |
-
return $rules;
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Renders a block identified by its id, using the block options and adding a wrapper
|
463 |
-
* if required (for the first block rendering).
|
464 |
-
*
|
465 |
-
* @param string $block_id
|
466 |
-
* @param boolean $wrapper
|
467 |
-
* @param array $options
|
468 |
-
* @param array $context
|
469 |
-
* @param array $composer
|
470 |
-
*/
|
471 |
-
function render_block($block_id = null, $wrapper = false, $options = [], $context = [], $composer = []) {
|
472 |
-
static $kses_style_filter = false;
|
473 |
-
include_once NEWSLETTER_INCLUDES_DIR . '/helper.php';
|
474 |
-
|
475 |
-
//Remove 'options_composer_' prefix
|
476 |
-
$composer_defaults = [];
|
477 |
-
foreach (TNP_Composer::get_global_style_defaults() as $global_option_name => $global_option) {
|
478 |
-
$composer_defaults[str_replace('options_composer_', '', $global_option_name)] = $global_option;
|
479 |
-
}
|
480 |
-
$composer = array_merge($composer_defaults, $composer);
|
481 |
-
|
482 |
-
$width = 600;
|
483 |
-
$font_family = 'Helvetica, Arial, sans-serif';
|
484 |
-
|
485 |
-
$global_title_font_family = $composer['title_font_family'];
|
486 |
-
$global_title_font_size = $composer['title_font_size'];
|
487 |
-
$global_title_font_color = $composer['title_font_color'];
|
488 |
-
$global_title_font_weight = $composer['title_font_weight'];
|
489 |
-
|
490 |
-
$global_text_font_family = $composer['text_font_family'];
|
491 |
-
$global_text_font_size = $composer['text_font_size'];
|
492 |
-
$global_text_font_color = $composer['text_font_color'];
|
493 |
-
$global_text_font_weight = $composer['text_font_weight'];
|
494 |
-
|
495 |
-
$global_button_font_family = $composer['button_font_family'];
|
496 |
-
$global_button_font_size = $composer['button_font_size'];
|
497 |
-
$global_button_font_color = $composer['button_font_color'];
|
498 |
-
$global_button_font_weight = $composer['button_font_weight'];
|
499 |
-
$global_button_background_color = $composer['button_background_color'];
|
500 |
-
|
501 |
-
$global_block_background = $composer['block_background'];
|
502 |
-
|
503 |
-
$info = Newsletter::instance()->get_options('info');
|
504 |
-
|
505 |
-
// Just in case...
|
506 |
-
if (!is_array($options)) {
|
507 |
-
$options = array();
|
508 |
-
}
|
509 |
-
|
510 |
-
// This code filters the HTML to remove javascript and unsecure attributes and enable the
|
511 |
-
// "display" rule for CSS which is needed in blocks to force specific "block" or "inline" or "table".
|
512 |
-
add_filter('safe_style_css', [$this, 'hook_safe_style_css'], 9999);
|
513 |
-
$options = wp_kses_post_deep($options);
|
514 |
-
remove_filter('safe_style_css', [$this, 'hook_safe_style_css']);
|
515 |
-
|
516 |
-
$block_options = get_option('newsletter_main');
|
517 |
-
|
518 |
-
$block = $this->get_block($block_id);
|
519 |
-
|
520 |
-
if (!isset($context['type']))
|
521 |
-
$context['type'] = '';
|
522 |
-
|
523 |
-
// Block not found
|
524 |
-
if (!$block) {
|
525 |
-
if ($wrapper) {
|
526 |
-
echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">';
|
527 |
-
echo '<tr>';
|
528 |
-
echo '<td data-options="" bgcolor="#ffffff" align="center" style="padding: 0; font-family: Helvetica, Arial, sans-serif;" class="edit-block">';
|
529 |
-
}
|
530 |
-
echo $this->get_outlook_wrapper_open($width);
|
531 |
-
|
532 |
-
echo '<p>Ops, this block type is no more registered!</p>';
|
533 |
-
|
534 |
-
echo $this->get_outlook_wrapper_close();
|
535 |
-
|
536 |
-
if ($wrapper) {
|
537 |
-
echo '</td></tr></table>';
|
538 |
-
}
|
539 |
-
return;
|
540 |
-
}
|
541 |
-
|
542 |
-
$out = ['subject' => '', 'return_empty_message' => false, 'stop' => false, 'skip' => false];
|
543 |
-
|
544 |
-
$dir = is_rtl() ? 'rtl' : 'ltr';
|
545 |
-
$align_left = is_rtl() ? 'right' : 'left';
|
546 |
-
$align_right = is_rtl() ? 'left' : 'right';
|
547 |
-
|
548 |
-
ob_start();
|
549 |
-
$logger = $this->logger;
|
550 |
-
include $block['dir'] . '/block.php';
|
551 |
-
$content = trim(ob_get_clean());
|
552 |
-
|
553 |
-
if (empty($content)) {
|
554 |
-
return $out;
|
555 |
-
}
|
556 |
-
|
557 |
-
$common_defaults = array(
|
558 |
-
'block_padding_top' => 0,
|
559 |
-
'block_padding_bottom' => 0,
|
560 |
-
'block_padding_right' => 0,
|
561 |
-
'block_padding_left' => 0,
|
562 |
-
'block_background' => '',
|
563 |
-
'block_background_2' => '',
|
564 |
-
'block_width' => 600,
|
565 |
-
'block_align' => 'center'
|
566 |
-
);
|
567 |
-
|
568 |
-
$options = array_merge($common_defaults, $options);
|
569 |
-
|
570 |
-
// Obsolete
|
571 |
-
$content = str_replace('{width}', $width, $content);
|
572 |
-
|
573 |
-
$content = $this->inline_css($content, true);
|
574 |
-
|
575 |
-
// CSS driven by the block
|
576 |
-
// Requited for the server side parsing and rendering
|
577 |
-
$options['block_id'] = $block_id;
|
578 |
-
|
579 |
-
$options['block_padding_top'] = (int) str_replace('px', '', $options['block_padding_top']);
|
580 |
-
$options['block_padding_bottom'] = (int) str_replace('px', '', $options['block_padding_bottom']);
|
581 |
-
$options['block_padding_right'] = (int) str_replace('px', '', $options['block_padding_right']);
|
582 |
-
$options['block_padding_left'] = (int) str_replace('px', '', $options['block_padding_left']);
|
583 |
-
|
584 |
-
$block_background = empty($options['block_background']) ? $global_block_background : $options['block_background'];
|
585 |
-
|
586 |
-
// Internal TD wrapper
|
587 |
-
$style = 'text-align: center; ';
|
588 |
-
$style .= 'width: 100% !important; ';
|
589 |
-
$style .= 'line-height: normal !important; ';
|
590 |
-
$style .= 'letter-spacing: normal; ';
|
591 |
-
$style .= 'padding-top: ' . $options['block_padding_top'] . 'px; ';
|
592 |
-
$style .= 'padding-left: ' . $options['block_padding_left'] . 'px; ';
|
593 |
-
$style .= 'padding-right: ' . $options['block_padding_right'] . 'px; ';
|
594 |
-
$style .= 'padding-bottom: ' . $options['block_padding_bottom'] . 'px; ';
|
595 |
-
$style .= 'background-color: ' . $block_background . ';';
|
596 |
-
|
597 |
-
if (isset($options['block_background_gradient'])) {
|
598 |
-
$style .= 'background: linear-gradient(180deg, ' . $block_background . ' 0%, ' . $options['block_background_2'] . ' 100%);';
|
599 |
-
}
|
600 |
-
|
601 |
-
$data = $this->options_encode($options);
|
602 |
-
// First time block creation wrapper
|
603 |
-
if ($wrapper) {
|
604 |
-
echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">', "\n";
|
605 |
-
echo "<tr>";
|
606 |
-
echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
|
607 |
-
}
|
608 |
-
|
609 |
-
// Container that fixes the width and makes the block responsive
|
610 |
-
echo $this->get_outlook_wrapper_open($options['block_width']);
|
611 |
-
|
612 |
-
echo '<table type="options" data-json="', esc_attr($data), '" class="tnpc-block-content" border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: ', $options['block_width'], 'px!important">', "\n";
|
613 |
-
echo "<tr>";
|
614 |
-
echo '<td align="', esc_attr($options['block_align']), '" style="', $style, '" bgcolor="', $block_background, '" width="100%">';
|
615 |
-
|
616 |
-
//echo "<!-- block generated content -->\n";
|
617 |
-
echo trim($content);
|
618 |
-
//echo "\n<!-- /block generated content -->\n";
|
619 |
-
|
620 |
-
echo "</td></tr></table>";
|
621 |
-
echo $this->get_outlook_wrapper_close();
|
622 |
-
|
623 |
-
// First time block creation wrapper
|
624 |
-
if ($wrapper) {
|
625 |
-
echo "</td></tr></table>";
|
626 |
-
}
|
627 |
-
|
628 |
-
return $out;
|
629 |
-
}
|
630 |
-
|
631 |
-
/**
|
632 |
-
* Ajax call to render a block with a new set of options after the settings popup
|
633 |
-
* has been saved.
|
634 |
-
*
|
635 |
-
* @param type $block_id
|
636 |
-
* @param type $wrapper
|
637 |
-
*/
|
638 |
-
function tnpc_render_callback() {
|
639 |
-
if (!check_ajax_referer('save')) {
|
640 |
-
$this->dienow('Expired request');
|
641 |
-
}
|
642 |
-
|
643 |
-
$block_id = $_POST['id'];
|
644 |
-
$wrapper = isset($_POST['full']);
|
645 |
-
$options = $this->restore_options_from_request();
|
646 |
-
|
647 |
-
$this->render_block($block_id, $wrapper, $options, [], $_POST['composer']);
|
648 |
-
wp_die();
|
649 |
-
}
|
650 |
-
|
651 |
-
function hook_wp_ajax_tnpc_regenerate_email() {
|
652 |
-
|
653 |
-
$content = stripslashes($_POST['content']);
|
654 |
-
$global_options = $_POST['composer'];
|
655 |
-
|
656 |
-
$regenerated_content = $this->regenerate_email_blocks($content, $global_options);
|
657 |
-
|
658 |
-
wp_send_json_success([
|
659 |
-
'content' => $regenerated_content,
|
660 |
-
'message' => __('Successfully updated', 'newsletter')
|
661 |
-
]);
|
662 |
-
}
|
663 |
-
|
664 |
-
private function regenerate_email_blocks($content, $global_options) {
|
665 |
-
|
666 |
-
$raw_block_options = $this->extract_encoded_blocks_options($content);
|
667 |
-
|
668 |
-
$regenerated_content = '';
|
669 |
-
|
670 |
-
foreach ($raw_block_options as $raw_block_option) {
|
671 |
-
|
672 |
-
/* $a = html_entity_decode( $raw_block_option, ENT_QUOTES, 'UTF-8' );
|
673 |
-
$block_options = $this->options_decode( $a ); */
|
674 |
-
|
675 |
-
$block_options = $this->options_decode($raw_block_option);
|
676 |
-
|
677 |
-
$block = $this->get_block($block_options['block_id']);
|
678 |
-
if (!$block) {
|
679 |
-
$this->logger->debug('Unable to load the block ' . $block_options['block_id']);
|
680 |
-
}
|
681 |
-
|
682 |
-
ob_start();
|
683 |
-
$this->render_block($block_options['block_id'], true, $block_options, [], $global_options);
|
684 |
-
$block_html = ob_get_clean();
|
685 |
-
|
686 |
-
$regenerated_content .= $block_html;
|
687 |
-
}
|
688 |
-
|
689 |
-
return $regenerated_content;
|
690 |
-
}
|
691 |
-
|
692 |
-
/**
|
693 |
-
* @param string $html_email_content Email html content
|
694 |
-
*
|
695 |
-
* @return string[] Encoded options of email blocks
|
696 |
-
*/
|
697 |
-
private function extract_encoded_blocks_options($html_email_content) {
|
698 |
-
|
699 |
-
preg_match_all('/data-json="(.*?)"/m', $html_email_content, $raw_block_options, PREG_PATTERN_ORDER);
|
700 |
-
|
701 |
-
return $raw_block_options[1];
|
702 |
-
}
|
703 |
-
|
704 |
-
function tnpc_preview_callback() {
|
705 |
-
$email = Newsletter::instance()->get_email($_REQUEST['id'], ARRAY_A);
|
706 |
-
|
707 |
-
if (empty($email)) {
|
708 |
-
echo 'Wrong email identifier';
|
709 |
-
return;
|
710 |
-
}
|
711 |
-
|
712 |
-
echo $email['message'];
|
713 |
-
|
714 |
-
wp_die();
|
715 |
-
}
|
716 |
-
|
717 |
-
function tnpc_css_callback() {
|
718 |
-
include NEWSLETTER_DIR . '/emails/tnp-composer/css/newsletter.css';
|
719 |
-
wp_die();
|
720 |
-
}
|
721 |
-
|
722 |
-
/** Returns the correct admin page to edit the newsletter with the correct editor. */
|
723 |
-
function get_editor_url($email_id, $editor_type) {
|
724 |
-
switch ($editor_type) {
|
725 |
-
case NewsletterEmails::EDITOR_COMPOSER:
|
726 |
-
return admin_url("admin.php") . '?page=newsletter_emails_composer&id=' . $email_id;
|
727 |
-
case NewsletterEmails::EDITOR_HTML:
|
728 |
-
return admin_url("admin.php") . '?page=newsletter_emails_editorhtml&id=' . $email_id;
|
729 |
-
case NewsletterEmails::EDITOR_TINYMCE:
|
730 |
-
return admin_url("admin.php") . '?page=newsletter_emails_editortinymce&id=' . $email_id;
|
731 |
-
}
|
732 |
-
}
|
733 |
-
|
734 |
-
/**
|
735 |
-
* Returns the button linked to the correct "edit" page for the passed newsletter. The edit page can be an editor
|
736 |
-
* or the targeting page (it depends on newsletter status).
|
737 |
-
*
|
738 |
-
* @param TNP_Email $email
|
739 |
-
*/
|
740 |
-
function get_edit_button($email, $only_icon = false) {
|
741 |
-
|
742 |
-
$editor_type = $this->get_editor_type($email);
|
743 |
-
if ($email->status == 'new') {
|
744 |
-
$edit_url = $this->get_editor_url($email->id, $editor_type);
|
745 |
-
} else {
|
746 |
-
$edit_url = 'admin.php?page=newsletter_emails_edit&id=' . $email->id;
|
747 |
-
}
|
748 |
-
switch ($editor_type) {
|
749 |
-
case NewsletterEmails::EDITOR_COMPOSER:
|
750 |
-
$icon_class = 'th-large';
|
751 |
-
break;
|
752 |
-
case NewsletterEmails::EDITOR_HTML:
|
753 |
-
$icon_class = 'code';
|
754 |
-
break;
|
755 |
-
default:
|
756 |
-
$icon_class = 'edit';
|
757 |
-
break;
|
758 |
-
}
|
759 |
-
if ($only_icon) {
|
760 |
-
return '<a class="button-primary" href="' . $edit_url . '" title="' . esc_attr__('Edit', 'newsletter') . '">' .
|
761 |
-
'<i class="fas fa-' . $icon_class . '"></i></a>';
|
762 |
-
} else {
|
763 |
-
return '<a class="button-primary" href="' . $edit_url . '" title="' . esc_attr__('Edit', 'newsletter') . '">' .
|
764 |
-
'<i class="fas fa-' . $icon_class . '"></i> ' . __('Edit', 'newsletter') . '</a>';
|
765 |
-
}
|
766 |
-
}
|
767 |
-
|
768 |
-
/** Returns the correct editor type for the provided newsletter. Contains backward compatibility code. */
|
769 |
-
function get_editor_type($email) {
|
770 |
-
$email = (object) $email;
|
771 |
-
$editor_type = $email->editor;
|
772 |
-
|
773 |
-
// Backward compatibility
|
774 |
-
$email_options = maybe_unserialize($email->options);
|
775 |
-
if (isset($email_options['composer'])) {
|
776 |
-
$editor_type = NewsletterEmails::EDITOR_COMPOSER;
|
777 |
-
}
|
778 |
-
// End backward compatibility
|
779 |
-
|
780 |
-
return $editor_type;
|
781 |
-
}
|
782 |
-
|
783 |
-
/**
|
784 |
-
*
|
785 |
-
* @param type $action
|
786 |
-
* @param type $user
|
787 |
-
* @param type $email
|
788 |
-
* @return type
|
789 |
-
* @global wpdb $wpdb
|
790 |
-
*/
|
791 |
-
function hook_newsletter_action($action, $user, $email) {
|
792 |
-
global $wpdb;
|
793 |
-
|
794 |
-
switch ($action) {
|
795 |
-
case 'v':
|
796 |
-
case 'view':
|
797 |
-
$id = $_GET['id'];
|
798 |
-
if ($id == 'last') {
|
799 |
-
$email = $wpdb->get_row("select * from " . NEWSLETTER_EMAILS_TABLE . " where private=0 and type='message' and status='sent' order by send_on desc limit 1");
|
800 |
-
} else {
|
801 |
-
$email = $this->get_email($_GET['id']);
|
802 |
-
}
|
803 |
-
if (empty($email)) {
|
804 |
-
header("HTTP/1.0 404 Not Found");
|
805 |
-
die('Email not found');
|
806 |
-
}
|
807 |
-
|
808 |
-
if (!Newsletter::instance()->is_allowed()) {
|
809 |
-
|
810 |
-
if ($email->status == 'new') {
|
811 |
-
header("HTTP/1.0 404 Not Found");
|
812 |
-
die('Not sent yet');
|
813 |
-
}
|
814 |
-
|
815 |
-
if ($email->private == 1) {
|
816 |
-
if (!$user) {
|
817 |
-
header("HTTP/1.0 404 Not Found");
|
818 |
-
die('No available for online view');
|
819 |
-
}
|
820 |
-
$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));
|
821 |
-
if (!$sent) {
|
822 |
-
header("HTTP/1.0 404 Not Found");
|
823 |
-
die('No available for online view');
|
824 |
-
}
|
825 |
-
}
|
826 |
-
}
|
827 |
-
|
828 |
-
|
829 |
-
header('Content-Type: text/html;charset=UTF-8');
|
830 |
-
header('X-Robots-Tag: noindex,nofollow,noarchive');
|
831 |
-
header('Cache-Control: no-cache,no-store,private');
|
832 |
-
|
833 |
-
echo $this->replace($email->message, $user, $email);
|
834 |
-
|
835 |
-
die();
|
836 |
-
break;
|
837 |
-
|
838 |
-
case 'emails-css':
|
839 |
-
$email_id = (int) $_GET['id'];
|
840 |
-
|
841 |
-
$body = Newsletter::instance()->get_email_field($email_id, 'message');
|
842 |
-
|
843 |
-
$x = strpos($body, '<style');
|
844 |
-
if ($x === false)
|
845 |
-
return;
|
846 |
-
|
847 |
-
$x = strpos($body, '>', $x);
|
848 |
-
$y = strpos($body, '</style>');
|
849 |
-
|
850 |
-
header('Content-Type: text/css;charset=UTF-8');
|
851 |
-
|
852 |
-
echo substr($body, $x + 1, $y - $x - 1);
|
853 |
-
|
854 |
-
die();
|
855 |
-
break;
|
856 |
-
|
857 |
-
case 'emails-composer-css':
|
858 |
-
header('Cache: no-cache');
|
859 |
-
header('Content-Type: text/css');
|
860 |
-
echo $this->get_composer_css();
|
861 |
-
die();
|
862 |
-
break;
|
863 |
-
|
864 |
-
case 'emails-preview':
|
865 |
-
if (!Newsletter::instance()->is_allowed()) {
|
866 |
-
die('Not enough privileges');
|
867 |
-
}
|
868 |
-
|
869 |
-
if (!check_admin_referer('view')) {
|
870 |
-
die();
|
871 |
-
}
|
872 |
-
|
873 |
-
$theme_id = $_GET['id'];
|
874 |
-
$theme = $this->themes->get_theme($theme_id);
|
875 |
-
|
876 |
-
// Used by theme code
|
877 |
-
$theme_options = $this->themes->get_options($theme_id);
|
878 |
-
|
879 |
-
$theme_url = $theme['url'];
|
880 |
-
|
881 |
-
header('Content-Type: text/html;charset=UTF-8');
|
882 |
-
|
883 |
-
include $theme['dir'] . '/theme.php';
|
884 |
-
|
885 |
-
die();
|
886 |
-
break;
|
887 |
-
|
888 |
-
case 'emails-preview-text':
|
889 |
-
header('Content-Type: text/plain;charset=UTF-8');
|
890 |
-
if (!Newsletter::instance()->is_allowed()) {
|
891 |
-
die('Not enough privileges');
|
892 |
-
}
|
893 |
-
|
894 |
-
if (!check_admin_referer('view')) {
|
895 |
-
die();
|
896 |
-
}
|
897 |
-
|
898 |
-
// Used by theme code
|
899 |
-
$theme_options = $this->get_current_theme_options();
|
900 |
-
|
901 |
-
$file = include $theme['dir'] . '/theme-text.php';
|
902 |
-
|
903 |
-
if (is_file($file)) {
|
904 |
-
include $file;
|
905 |
-
}
|
906 |
-
|
907 |
-
die();
|
908 |
-
break;
|
909 |
-
|
910 |
-
|
911 |
-
case 'emails-create':
|
912 |
-
// Newsletter from themes are created on frontend context because sometime WP themes change the way the content,
|
913 |
-
// excerpt, thumbnail are extracted.
|
914 |
-
if (!Newsletter::instance()->is_allowed()) {
|
915 |
-
die('Not enough privileges');
|
916 |
-
}
|
917 |
-
|
918 |
-
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
919 |
-
$controls = new NewsletterControls();
|
920 |
-
|
921 |
-
if (!$controls->is_action('create')) {
|
922 |
-
die('Wrong call');
|
923 |
-
}
|
924 |
-
|
925 |
-
$theme_id = $controls->data['id'];
|
926 |
-
$theme = $this->themes->get_theme($theme_id);
|
927 |
-
|
928 |
-
if (!$theme) {
|
929 |
-
die('invalid theme');
|
930 |
-
}
|
931 |
-
|
932 |
-
$this->themes->save_options($theme_id, $controls->data);
|
933 |
-
|
934 |
-
$email = array();
|
935 |
-
$email['status'] = 'new';
|
936 |
-
$email['subject'] = ''; //__('Here the email subject', 'newsletter');
|
937 |
-
$email['track'] = 1;
|
938 |
-
$email['send_on'] = time();
|
939 |
-
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
940 |
-
$email['type'] = 'message';
|
941 |
-
|
942 |
-
$theme_options = $this->themes->get_options($theme_id);
|
943 |
-
|
944 |
-
$theme_url = $theme['url'];
|
945 |
-
$theme_subject = '';
|
946 |
-
|
947 |
-
ob_start();
|
948 |
-
include $theme['dir'] . '/theme.php';
|
949 |
-
$email['message'] = ob_get_clean();
|
950 |
-
|
951 |
-
|
952 |
-
if (!empty($theme_subject)) {
|
953 |
-
$email['subject'] = $theme_subject;
|
954 |
-
}
|
955 |
-
|
956 |
-
if (file_exists($theme['dir'] . '/theme-text.php')) {
|
957 |
-
ob_start();
|
958 |
-
include $theme['dir'] . '/theme-text.php';
|
959 |
-
$email['message_text'] = ob_get_clean();
|
960 |
-
} else {
|
961 |
-
$email['message_text'] = 'You need a modern email client to read this email. Read it online: {email_url}.';
|
962 |
-
}
|
963 |
-
|
964 |
-
$email = $this->save_email($email);
|
965 |
-
|
966 |
-
$edit_url = $this->get_editor_url($email->id, $email->editor);
|
967 |
-
|
968 |
-
header('Location: ' . $edit_url);
|
969 |
-
|
970 |
-
die();
|
971 |
-
break;
|
972 |
-
}
|
973 |
-
}
|
974 |
-
|
975 |
-
function admin_menu() {
|
976 |
-
$this->add_menu_page('index', 'Newsletters');
|
977 |
-
$this->add_admin_page('list', 'Email List');
|
978 |
-
$this->add_admin_page('new', 'Email New');
|
979 |
-
$this->add_admin_page('edit', 'Email Edit');
|
980 |
-
$this->add_admin_page('theme', 'Email Themes');
|
981 |
-
$this->add_admin_page('composer', 'The Composer');
|
982 |
-
$this->add_admin_page('editorhtml', 'HTML Editor');
|
983 |
-
$this->add_admin_page('editortinymce', 'TinyMCE Editor');
|
984 |
-
}
|
985 |
-
|
986 |
-
/**
|
987 |
-
* Builds a block data structure starting from the folder containing the block
|
988 |
-
* files.
|
989 |
-
*
|
990 |
-
* @param string $dir
|
991 |
-
* @return array | WP_Error
|
992 |
-
*/
|
993 |
-
function build_block($dir) {
|
994 |
-
$dir = realpath($dir);
|
995 |
-
$dir = wp_normalize_path($dir);
|
996 |
-
$full_file = $dir . '/block.php';
|
997 |
-
if (!is_file($full_file)) {
|
998 |
-
return new WP_Error('1', 'Missing block.php file in ' . $dir);
|
999 |
-
}
|
1000 |
-
|
1001 |
-
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
1002 |
-
$file = basename($dir);
|
1003 |
-
|
1004 |
-
$data = get_file_data($full_file, ['name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'type' => 'Type']);
|
1005 |
-
$defaults = ['section' => 'content', 'name' => ucfirst($file), 'descritpion' => '', 'icon' =>
|
1006 |
-
$data = array_merge($defaults, $data);
|
1007 |
-
|
1008 |
-
if (is_file($dir . '/icon.png')) {
|
1009 |
-
$data['icon'] = content_url($relative_dir . '/icon.png');
|
1010 |
-
}
|
1011 |
-
|
1012 |
-
$data['id'] = sanitize_key($file);
|
1013 |
-
|
1014 |
-
// Absolute path of the block files
|
1015 |
-
$data['dir'] = $dir;
|
1016 |
-
$data['url'] = content_url($relative_dir);
|
1017 |
-
|
1018 |
-
return $data;
|
1019 |
-
}
|
1020 |
-
|
1021 |
-
/**
|
1022 |
-
*
|
1023 |
-
* @param type $dir
|
1024 |
-
* @return type
|
1025 |
-
*/
|
1026 |
-
function scan_blocks_dir($dir) {
|
1027 |
-
$dir = realpath($dir);
|
1028 |
-
if (!$dir) {
|
1029 |
-
return [];
|
1030 |
-
}
|
1031 |
-
$dir = wp_normalize_path($dir);
|
1032 |
-
|
1033 |
-
$list = [];
|
1034 |
-
$handle = opendir($dir);
|
1035 |
-
while ($file = readdir($handle)) {
|
1036 |
-
|
1037 |
-
$data = $this->build_block($dir . '/' . $file);
|
1038 |
-
|
1039 |
-
if (is_wp_error($data)) {
|
1040 |
-
$this->logger->error($data);
|
1041 |
-
continue;
|
1042 |
-
}
|
1043 |
-
$list[$data['id']] = $data;
|
1044 |
-
}
|
1045 |
-
closedir($handle);
|
1046 |
-
return $list;
|
1047 |
-
}
|
1048 |
-
|
1049 |
-
/**
|
1050 |
-
* Array of arrays with every registered block and legacy block converted to the new
|
1051 |
-
* format.
|
1052 |
-
*
|
1053 |
-
* @return array
|
1054 |
-
*/
|
1055 |
-
function get_blocks() {
|
1056 |
-
|
1057 |
-
if (!is_null($this->blocks)) {
|
1058 |
-
return $this->blocks;
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
$this->blocks = $this->scan_blocks_dir(__DIR__ . '/blocks');
|
1062 |
-
|
1063 |
-
$extended = $this->scan_blocks_dir(WP_CONTENT_DIR . '/extensions/newsletter/blocks');
|
1064 |
-
|
1065 |
-
$this->blocks = array_merge($extended, $this->blocks);
|
1066 |
-
|
1067 |
-
$dirs = apply_filters('newsletter_blocks_dir', array());
|
1068 |
-
|
1069 |
-
//$this->logger->debug('Block dirs:');
|
1070 |
-
//$this->logger->debug($dirs);
|
1071 |
-
|
1072 |
-
foreach ($dirs as $dir) {
|
1073 |
-
$list = $this->scan_blocks_dir($dir);
|
1074 |
-
$this->blocks = array_merge($list, $this->blocks);
|
1075 |
-
}
|
1076 |
-
|
1077 |
-
do_action('newsletter_register_blocks');
|
1078 |
-
|
1079 |
-
foreach (TNP_Composer::$block_dirs as $dir) {
|
1080 |
-
$block = $this->build_block($dir);
|
1081 |
-
if (is_wp_error($block)) {
|
1082 |
-
$this->logger->error($block);
|
1083 |
-
continue;
|
1084 |
-
}
|
1085 |
-
if (!isset($this->blocks[$block['id']])) {
|
1086 |
-
$this->blocks[$block['id']] = $block;
|
1087 |
-
} else {
|
1088 |
-
$this->logger->error('The block "' . $block['id'] . '" has already been registered');
|
1089 |
-
}
|
1090 |
-
}
|
1091 |
-
|
1092 |
-
$this->blocks = array_reverse($this->blocks);
|
1093 |
-
return $this->blocks;
|
1094 |
-
}
|
1095 |
-
|
1096 |
-
/**
|
1097 |
-
* Return a single block (associative array) checking for legacy ID as well.
|
1098 |
-
*
|
1099 |
-
* @param string $id
|
1100 |
-
* @return array
|
1101 |
-
*/
|
1102 |
-
function get_block($id) {
|
1103 |
-
switch ($id) {
|
1104 |
-
case 'content-03-text.block':
|
1105 |
-
$id = 'text';
|
1106 |
-
break;
|
1107 |
-
case 'footer-03-social.block':
|
1108 |
-
$id = 'social';
|
1109 |
-
break;
|
1110 |
-
case 'footer-02-canspam.block':
|
1111 |
-
$id = 'canspam';
|
1112 |
-
break;
|
1113 |
-
case 'content-05-image.block':
|
1114 |
-
$id = 'image';
|
1115 |
-
break;
|
1116 |
-
case 'header-01-header.block':
|
1117 |
-
$id = 'header';
|
1118 |
-
break;
|
1119 |
-
case 'footer-01-footer.block':
|
1120 |
-
$id = 'footer';
|
1121 |
-
break;
|
1122 |
-
case 'content-02-heading.block':
|
1123 |
-
$id = 'heading';
|
1124 |
-
break;
|
1125 |
-
case 'content-07-twocols.block':
|
1126 |
-
case 'content-06-posts.block':
|
1127 |
-
$id = 'posts';
|
1128 |
-
break;
|
1129 |
-
case 'content-04-cta.block':
|
1130 |
-
$id = 'cta';
|
1131 |
-
break;
|
1132 |
-
case 'content-01-hero.block':
|
1133 |
-
$id = 'hero';
|
1134 |
-
break;
|
1135 |
-
// case 'content-02-heading.block': $id = '/plugins/newsletter/emails/blocks/heading';
|
1136 |
-
// break;
|
1137 |
-
}
|
1138 |
-
|
1139 |
-
// Conversion for old full path ID
|
1140 |
-
$id = sanitize_key(basename($id));
|
1141 |
-
|
1142 |
-
// TODO: Correct id for compatibility
|
1143 |
-
$blocks = $this->get_blocks();
|
1144 |
-
if (!isset($blocks[$id])) {
|
1145 |
-
return null;
|
1146 |
-
}
|
1147 |
-
return $blocks[$id];
|
1148 |
-
}
|
1149 |
-
|
1150 |
-
function scan_presets_dir($dir = null) {
|
1151 |
-
|
1152 |
-
if (is_null($dir)) {
|
1153 |
-
$dir = __DIR__ . '/presets';
|
1154 |
-
}
|
1155 |
-
|
1156 |
-
if (!is_dir($dir)) {
|
1157 |
-
return array();
|
1158 |
-
}
|
1159 |
-
|
1160 |
-
$handle = opendir($dir);
|
1161 |
-
$list = array();
|
1162 |
-
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
1163 |
-
while ($file = readdir($handle)) {
|
1164 |
-
|
1165 |
-
if ($file == '.' || $file == '..')
|
1166 |
-
continue;
|
1167 |
-
|
1168 |
-
// The block unique key, we should find out how to build it, maybe an hash of the (relative) dir?
|
1169 |
-
$preset_id = sanitize_key($file);
|
1170 |
-
|
1171 |
-
$full_file = $dir . '/' . $file . '/preset.json';
|
1172 |
-
|
1173 |
-
if (!is_file($full_file)) {
|
1174 |
-
continue;
|
1175 |
-
}
|
1176 |
-
|
1177 |
-
$icon = content_url($relative_dir . '/' . $file . '/icon.png');
|
1178 |
-
|
1179 |
-
$list[$preset_id] = $icon;
|
1180 |
-
}
|
1181 |
-
closedir($handle);
|
1182 |
-
return $list;
|
1183 |
-
}
|
1184 |
-
|
1185 |
-
function get_preset_from_file($id, $dir = null) {
|
1186 |
-
|
1187 |
-
if (is_null($dir)) {
|
1188 |
-
$dir = __DIR__ . '/presets';
|
1189 |
-
}
|
1190 |
-
|
1191 |
-
$id = $this->sanitize_file_name($id);
|
1192 |
-
|
1193 |
-
if (!is_dir($dir . '/' . $id) || !in_array($id, self::$PRESETS_LIST)) {
|
1194 |
-
return array();
|
1195 |
-
}
|
1196 |
-
|
1197 |
-
$json_content = file_get_contents("$dir/$id/preset.json");
|
1198 |
-
$json_content = str_replace("{placeholder_base_url}", plugins_url('newsletter') . '/emails/presets', $json_content);
|
1199 |
-
$json = json_decode($json_content);
|
1200 |
-
$json->icon = NEWSLETTER_URL . "/emails/presets/$id/icon.png?ver=2";
|
1201 |
-
|
1202 |
-
return $json;
|
1203 |
-
}
|
1204 |
-
|
1205 |
-
function get_composer_css() {
|
1206 |
-
$css = file_get_contents(__DIR__ . '/tnp-composer/css/newsletter.css');
|
1207 |
-
$css .= "\n\n";
|
1208 |
-
$css .= file_get_contents(__DIR__ . '/tnp-composer/css/backend.css');
|
1209 |
-
$blocks = $this->get_blocks();
|
1210 |
-
foreach ($blocks as $block) {
|
1211 |
-
if (!file_exists($block['dir'] . '/style.css')) {
|
1212 |
-
continue;
|
1213 |
-
}
|
1214 |
-
$css .= "\n\n";
|
1215 |
-
$css .= "/* " . $block['name'] . " */\n";
|
1216 |
-
$css .= file_get_contents($block['dir'] . '/style.css');
|
1217 |
-
}
|
1218 |
-
return $css;
|
1219 |
-
}
|
1220 |
-
|
1221 |
-
/**
|
1222 |
-
* Send an email to the test subscribers.
|
1223 |
-
*
|
1224 |
-
* @param TNP_Email $email Could be any object with the TNP_Email attributes
|
1225 |
-
* @param NewsletterControls $controls
|
1226 |
-
*/
|
1227 |
-
function send_test_email($email, $controls) {
|
1228 |
-
if (!$email) {
|
1229 |
-
$controls->errors = __('Newsletter should be saved before send a test', 'newsletter');
|
1230 |
-
return;
|
1231 |
-
}
|
1232 |
-
|
1233 |
-
$original_subject = $email->subject;
|
1234 |
-
$this->set_test_subject_to($email);
|
1235 |
-
|
1236 |
-
$users = NewsletterUsers::instance()->get_test_users();
|
1237 |
-
if (count($users) == 0) {
|
1238 |
-
$controls->errors = '' . __('There are no test subscribers to send to', 'newsletter') .
|
1239 |
-
'. <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><strong>' .
|
1240 |
-
__('Read more', 'newsletter') . '</strong></a>.';
|
1241 |
-
} else {
|
1242 |
-
$r = Newsletter::instance()->send($email, $users, true);
|
1243 |
-
$emails = array();
|
1244 |
-
foreach ($users as $user) {
|
1245 |
-
$emails[] = '<a href="admin.php?page=newsletter_users_edit&id=' . $user->id . '" target="_blank">' . $user->email . '</a>';
|
1246 |
-
}
|
1247 |
-
if (is_wp_error($r)) {
|
1248 |
-
$controls->errors = 'Something went wrong. Check the error logs on status page.<br>';
|
1249 |
-
$controls->errors .= __('Test subscribers:', 'newsletter');
|
1250 |
-
$controls->errors .= ' ' . implode(', ', $emails);
|
1251 |
-
$controls->errors .= '<br>';
|
1252 |
-
$controls->errors .= '<strong>' . esc_html($r->get_error_message()) . '</strong><br>';
|
1253 |
-
$controls->errors .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __('Read more about delivery issues', 'newsletter') . '</strong></a>.';
|
1254 |
-
} else {
|
1255 |
-
$controls->messages = __('Test subscribers:', 'newsletter');
|
1256 |
-
|
1257 |
-
$controls->messages .= ' ' . implode(', ', $emails);
|
1258 |
-
$controls->messages .= '.<br>';
|
1259 |
-
$controls->messages .= '<a href="https://www.thenewsletterplugin.com/documentation/subscribers#test" target="_blank"><strong>' .
|
1260 |
-
__('Read more about test subscribers', 'newsletter') . '</strong></a>.<br>';
|
1261 |
-
$controls->messages .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __('Read more about delivery issues', 'newsletter') . '</strong></a>.';
|
1262 |
-
}
|
1263 |
-
}
|
1264 |
-
$email->subject = $original_subject;
|
1265 |
-
}
|
1266 |
-
|
1267 |
-
/**
|
1268 |
-
* Send an email to the test subscribers.
|
1269 |
-
*
|
1270 |
-
* @param TNP_Email $email Could be any object with the TNP_Email attributes
|
1271 |
-
* @param string $email_address
|
1272 |
-
*
|
1273 |
-
* @throws Exception
|
1274 |
-
*/
|
1275 |
-
function send_test_newsletter_to_email_address( $email, $email_address ) {
|
1276 |
-
|
1277 |
-
if ( ! $email ) {
|
1278 |
-
throw new Exception( __( 'Newsletter should be saved before send a test', 'newsletter' ) );
|
1279 |
-
}
|
1280 |
-
|
1281 |
-
$this->set_test_subject_to( $email );
|
1282 |
-
|
1283 |
-
$dummy_subscriber = $this->make_dummy_subscriber();
|
1284 |
-
$dummy_subscriber->email = $email_address;
|
1285 |
-
|
1286 |
-
$result = Newsletter::instance()->send( $email, [ $dummy_subscriber ], true );
|
1287 |
-
|
1288 |
-
$email = '<a href="admin.php?page=newsletter_users_edit&id=' . $dummy_subscriber->id . '" target="_blank">' . $dummy_subscriber->email . '</a>';
|
1289 |
-
|
1290 |
-
if ( is_wp_error( $result ) ) {
|
1291 |
-
$error_message = 'Something went wrong. Check the error logs on status page.<br>';
|
1292 |
-
$error_message .= __( 'Test subscribers:', 'newsletter' );
|
1293 |
-
$error_message .= ' ' . $email;
|
1294 |
-
$error_message .= '<br>';
|
1295 |
-
$error_message .= '<strong>' . esc_html( $result->get_error_message() ) . '</strong><br>';
|
1296 |
-
$error_message .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __( 'Read more about delivery issues', 'newsletter' ) . '</strong></a>.';
|
1297 |
-
throw new Exception( $error_message );
|
1298 |
-
}
|
1299 |
-
|
1300 |
-
$messages = __( 'Test subscribers:', 'newsletter' );
|
1301 |
-
|
1302 |
-
$messages .= ' ' . $email;
|
1303 |
-
$messages .= '.<br>';
|
1304 |
-
$messages .= '<a href="https://www.thenewsletterplugin.com/documentation/subscribers#test" target="_blank"><strong>' .
|
1305 |
-
__( 'Read more about test subscribers', 'newsletter' ) . '</strong></a>.<br>';
|
1306 |
-
$messages .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __( 'Read more about delivery issues', 'newsletter' ) . '</strong></a>.';
|
1307 |
-
|
1308 |
-
return $messages;
|
1309 |
-
}
|
1310 |
-
|
1311 |
-
private function set_test_subject_to($email) {
|
1312 |
-
if ( $email->subject == '' ) {
|
1313 |
-
$email->subject = '[TEST] Dummy subject, it was empty (remember to set it)';
|
1314 |
-
} else {
|
1315 |
-
$email->subject = $email->subject . ' (TEST)';
|
1316 |
-
}
|
1317 |
-
}
|
1318 |
-
|
1319 |
-
private function make_dummy_subscriber() {
|
1320 |
-
$dummy_user = new TNP_User();
|
1321 |
-
$dummy_user->id = 0;
|
1322 |
-
$dummy_user->email = 'john.doe@example.org';
|
1323 |
-
$dummy_user->name = 'John';
|
1324 |
-
$dummy_user->surname = 'Doe';
|
1325 |
-
$dummy_user->sex = 'n';
|
1326 |
-
$dummy_user->language = '';
|
1327 |
-
$dummy_user->ip = '';
|
1328 |
-
|
1329 |
-
for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
|
1330 |
-
$profile_key = "profile_$i";
|
1331 |
-
$dummy_user->$profile_key = '';
|
1332 |
-
}
|
1333 |
-
|
1334 |
-
return $dummy_user;
|
1335 |
-
}
|
1336 |
-
|
1337 |
-
function restore_options_from_request() {
|
1338 |
-
|
1339 |
-
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
1340 |
-
$controls = new NewsletterControls();
|
1341 |
-
$options = $controls->data;
|
1342 |
-
|
1343 |
-
if (isset($_POST['options']) && is_array($_POST['options'])) {
|
1344 |
-
// Get all block options
|
1345 |
-
//$options = stripslashes_deep($_POST['options']);
|
1346 |
-
|
1347 |
-
// Deserialize inline edits when
|
1348 |
-
// render is preformed on saving block options
|
1349 |
-
if (isset($options['inline_edits']) && !is_array($options['inline_edits'])) {
|
1350 |
-
$options['inline_edits'] = $this->options_decode($options['inline_edits']);
|
1351 |
-
}
|
1352 |
-
|
1353 |
-
// Restore inline edits from data-json
|
1354 |
-
// coming from inline editing
|
1355 |
-
// and merge with current inline edit
|
1356 |
-
if (isset($_POST['encoded_options'])) {
|
1357 |
-
$decoded_options = $this->options_decode($_POST['encoded_options']);
|
1358 |
-
|
1359 |
-
$to_merge_inline_edits = [];
|
1360 |
-
|
1361 |
-
if (isset($decoded_options['inline_edits'])) {
|
1362 |
-
foreach ($decoded_options['inline_edits'] as $decoded_inline_edit) {
|
1363 |
-
$to_merge_inline_edits[$decoded_inline_edit['post_id'] . $decoded_inline_edit['type']] = $decoded_inline_edit;
|
1364 |
-
}
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
//Overwrite with new edited content
|
1368 |
-
if (isset($options['inline_edits'])) {
|
1369 |
-
foreach ($options['inline_edits'] as $inline_edit) {
|
1370 |
-
$to_merge_inline_edits[$inline_edit['post_id'] . $inline_edit['type']] = $inline_edit;
|
1371 |
-
}
|
1372 |
-
}
|
1373 |
-
|
1374 |
-
$options['inline_edits'] = array_values($to_merge_inline_edits);
|
1375 |
-
$options = array_merge($decoded_options, $options);
|
1376 |
-
}
|
1377 |
-
|
1378 |
-
return $options;
|
1379 |
-
}
|
1380 |
-
|
1381 |
-
return array();
|
1382 |
-
}
|
1383 |
-
|
1384 |
-
public function hook_wp_ajax_tnpc_delete_preset() {
|
1385 |
-
|
1386 |
-
if (!wp_verify_nonce($_POST['_wpnonce'], 'preset')) {
|
1387 |
-
wp_send_json_error('Expired request');
|
1388 |
-
}
|
1389 |
-
|
1390 |
-
$preset_id = (int) $_REQUEST['presetId'];
|
1391 |
-
|
1392 |
-
$newsletter = Newsletter::instance();
|
1393 |
-
|
1394 |
-
if ($preset_id > 0) {
|
1395 |
-
$preset = $newsletter->get_email($preset_id);
|
1396 |
-
|
1397 |
-
if ($preset && $preset->type === self::PRESET_EMAIL_TYPE) {
|
1398 |
-
Newsletter::instance()->delete_email($preset_id);
|
1399 |
-
wp_send_json_success();
|
1400 |
-
} else {
|
1401 |
-
wp_send_json_error(__('Is not a preset!', 'newsletter'));
|
1402 |
-
}
|
1403 |
-
} else {
|
1404 |
-
wp_send_json_error();
|
1405 |
-
}
|
1406 |
-
}
|
1407 |
-
|
1408 |
-
}
|
1409 |
-
|
1410 |
-
NewsletterEmails::instance();
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
+
class NewsletterEmails extends NewsletterModule {
|
6 |
+
|
7 |
+
static $instance;
|
8 |
+
|
9 |
+
const EDITOR_COMPOSER = 2;
|
10 |
+
const EDITOR_HTML = 1;
|
11 |
+
const EDITOR_TINYMCE = 0;
|
12 |
+
|
13 |
+
static $PRESETS_LIST;
|
14 |
+
|
15 |
+
const PRESET_EMAIL_TYPE = 'composer_template';
|
16 |
+
|
17 |
+
// Cache
|
18 |
+
var $blocks = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return NewsletterEmails
|
22 |
+
*/
|
23 |
+
static function instance() {
|
24 |
+
if (self::$instance == null) {
|
25 |
+
self::$instance = new NewsletterEmails();
|
26 |
+
}
|
27 |
+
|
28 |
+
return self::$instance;
|
29 |
+
}
|
30 |
+
|
31 |
+
function __construct() {
|
32 |
+
self::$PRESETS_LIST = array("cta", "invite", "announcement", "posts", "sales", "product", "tour", "simple");
|
33 |
+
$this->themes = new NewsletterThemes('emails');
|
34 |
+
parent::__construct('emails', '1.1.5');
|
35 |
+
add_action('newsletter_action', array($this, 'hook_newsletter_action'), 13, 3);
|
36 |
+
|
37 |
+
if (is_admin()) {
|
38 |
+
if (defined('DOING_AJAX') && DOING_AJAX) {
|
39 |
+
add_action('wp_ajax_tnpc_render', array($this, 'tnpc_render_callback'));
|
40 |
+
add_action('wp_ajax_tnpc_preview', array($this, 'tnpc_preview_callback'));
|
41 |
+
add_action('wp_ajax_tnpc_css', array($this, 'tnpc_css_callback'));
|
42 |
+
add_action('wp_ajax_tnpc_options', array($this, 'hook_wp_ajax_tnpc_options'));
|
43 |
+
add_action('wp_ajax_tnpc_get_all_presets', array($this, 'ajax_get_all_presets'));
|
44 |
+
add_action('wp_ajax_tnpc_get_preset', array($this, 'ajax_get_preset'));
|
45 |
+
add_action('wp_ajax_tnpc_delete_preset', array($this, 'hook_wp_ajax_tnpc_delete_preset'));
|
46 |
+
add_action('wp_ajax_tnpc_regenerate_email', array($this, 'hook_wp_ajax_tnpc_regenerate_email'));
|
47 |
+
}
|
48 |
+
// Thank you to plugins which add the WP editor on other admin plugin pages...
|
49 |
+
if (isset($_GET['page']) && $_GET['page'] == 'newsletter_emails_edit') {
|
50 |
+
global $wp_actions;
|
51 |
+
$wp_actions['wp_enqueue_editor'] = 1;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
function options_decode($options) {
|
57 |
+
|
58 |
+
// Start compatibility
|
59 |
+
if (is_string($options) && strpos($options, 'options[') !== false) {
|
60 |
+
$opts = array();
|
61 |
+
parse_str($options, $opts);
|
62 |
+
$options = $opts['options'];
|
63 |
+
}
|
64 |
+
// End compatibility
|
65 |
+
|
66 |
+
if (is_array($options)) {
|
67 |
+
return $options;
|
68 |
+
}
|
69 |
+
|
70 |
+
$tmp = json_decode($options, true);
|
71 |
+
if (is_null($tmp)) {
|
72 |
+
return json_decode(base64_decode($options), true);
|
73 |
+
} else {
|
74 |
+
return $tmp;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
*
|
80 |
+
* @param array $options Options array
|
81 |
+
*/
|
82 |
+
function options_encode($options) {
|
83 |
+
return base64_encode(json_encode($options, JSON_HEX_TAG | JSON_HEX_AMP));
|
84 |
+
}
|
85 |
+
|
86 |
+
function hook_wp_ajax_tnpc_options() {
|
87 |
+
global $wpdb;
|
88 |
+
|
89 |
+
// TODO: Uniform to use id everywhere
|
90 |
+
// if (!isset($_REQUEST['id'])) {
|
91 |
+
// $_REQUEST['id'] = $_REQUEST['b'];
|
92 |
+
// }
|
93 |
+
|
94 |
+
$block = $this->get_block($_REQUEST['id']);
|
95 |
+
if (!$block) {
|
96 |
+
die('Block not found with id ' . esc_html($_REQUEST['id']));
|
97 |
+
}
|
98 |
+
|
99 |
+
if (!class_exists('NewsletterControls')) {
|
100 |
+
include NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
101 |
+
}
|
102 |
+
|
103 |
+
$options = $this->options_decode(stripslashes_deep($_REQUEST['options']));
|
104 |
+
$composer = isset($_POST['composer']) ? $_POST['composer'] : [];
|
105 |
+
|
106 |
+
$context = array('type' => '');
|
107 |
+
if (isset($_REQUEST['context_type'])) {
|
108 |
+
$context['type'] = $_REQUEST['context_type'];
|
109 |
+
}
|
110 |
+
|
111 |
+
$controls = new NewsletterControls($options);
|
112 |
+
$fields = new NewsletterFields($controls);
|
113 |
+
|
114 |
+
$controls->init();
|
115 |
+
echo '<input type="hidden" name="action" value="tnpc_render">';
|
116 |
+
echo '<input type="hidden" name="id" value="' . esc_attr($_REQUEST['id']) . '">';
|
117 |
+
echo '<input type="hidden" name="context_type" value="' . esc_attr($context['type']) . '">';
|
118 |
+
$inline_edits = '';
|
119 |
+
if (isset($controls->data['inline_edits'])) {
|
120 |
+
$inline_edits = $controls->data['inline_edits'];
|
121 |
+
}
|
122 |
+
echo '<input type="hidden" name="options[inline_edits]" value="', esc_attr($this->options_encode($inline_edits)), '">';
|
123 |
+
|
124 |
+
ob_start();
|
125 |
+
include $block['dir'] . '/options.php';
|
126 |
+
$content = ob_get_clean();
|
127 |
+
echo "<h2>", esc_html($block["name"]), "</h2>";
|
128 |
+
echo $content;
|
129 |
+
wp_die();
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Retrieves the presets list (no id in GET) or a specific preset id in GET)
|
134 |
+
*/
|
135 |
+
public function ajax_get_all_presets() {
|
136 |
+
wp_send_json_success($this->get_all_preset());
|
137 |
+
}
|
138 |
+
|
139 |
+
public function ajax_get_preset() {
|
140 |
+
|
141 |
+
if (empty($_REQUEST['id'])) {
|
142 |
+
wp_send_json_error([
|
143 |
+
'msg' => __('Invalid preset ID')
|
144 |
+
]);
|
145 |
+
}
|
146 |
+
|
147 |
+
$preset_id = $_REQUEST['id'];
|
148 |
+
$preset_content = $this->get_preset_content($preset_id);
|
149 |
+
$global_options = $this->get_preset_global_options($preset_id);
|
150 |
+
|
151 |
+
wp_send_json_success([
|
152 |
+
'content' => $preset_content,
|
153 |
+
'globalOptions' => $global_options,
|
154 |
+
]);
|
155 |
+
}
|
156 |
+
|
157 |
+
private function get_preset_content($preset_id) {
|
158 |
+
|
159 |
+
$content = '';
|
160 |
+
|
161 |
+
if ($this->is_a_tnp_default_preset($preset_id)) {
|
162 |
+
|
163 |
+
// Get preset from file
|
164 |
+
$preset = $this->get_preset_from_file($preset_id);
|
165 |
+
|
166 |
+
foreach ($preset->blocks as $item) {
|
167 |
+
ob_start();
|
168 |
+
$this->render_block($item->block, true, (array) $item->options);
|
169 |
+
$content .= trim(ob_get_clean());
|
170 |
+
}
|
171 |
+
} else {
|
172 |
+
|
173 |
+
// Get preset from db
|
174 |
+
$preset_email = $this->get_email(intval($preset_id));
|
175 |
+
$global_options = $this->extract_global_options_from($preset_email);
|
176 |
+
$content = $this->regenerate_email_blocks($preset_email->message, $global_options);
|
177 |
+
}
|
178 |
+
|
179 |
+
return $content;
|
180 |
+
}
|
181 |
+
|
182 |
+
private function get_preset_global_options($preset_id) {
|
183 |
+
|
184 |
+
if ($this->is_a_tnp_default_preset($preset_id)) {
|
185 |
+
return [];
|
186 |
+
}
|
187 |
+
|
188 |
+
// Get preset from db
|
189 |
+
$preset_email = $this->get_email(intval($preset_id));
|
190 |
+
$global_options = $this->extract_global_options_from($preset_email);
|
191 |
+
|
192 |
+
return $global_options;
|
193 |
+
}
|
194 |
+
|
195 |
+
private function extract_global_options_from($email) {
|
196 |
+
$global_options = [];
|
197 |
+
foreach ($email->options as $global_option_name => $global_option) {
|
198 |
+
if (strpos($global_option_name, 'composer_') === 0) {
|
199 |
+
$global_options[str_replace('composer_', '', $global_option_name)] = $global_option;
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
return $global_options;
|
204 |
+
}
|
205 |
+
|
206 |
+
private function is_a_tnp_default_preset($preset_id) {
|
207 |
+
return in_array($preset_id, self::$PRESETS_LIST);
|
208 |
+
}
|
209 |
+
|
210 |
+
private function get_all_preset() {
|
211 |
+
|
212 |
+
$content = "<div class='tnpc-preset-container'>";
|
213 |
+
|
214 |
+
if ($this->is_normal_context_request()) {
|
215 |
+
$content .= "<div class='tnpc-preset-legacy-themes'><a href='" . $this->get_admin_page_url('theme') . "'>" . __('Looking for legacy themes?', 'newsletter') . "</a></div>";
|
216 |
+
}
|
217 |
+
|
218 |
+
// LOAD USER PRESETS
|
219 |
+
$user_preset_list = $this->get_emails(self::PRESET_EMAIL_TYPE);
|
220 |
+
|
221 |
+
foreach ($user_preset_list as $user_preset) {
|
222 |
+
|
223 |
+
$default_icon_url = NEWSLETTER_URL . "/emails/presets/default-icon.png?ver=2";
|
224 |
+
$preset_name = $user_preset->subject;
|
225 |
+
$delete_preset_text = __('Delete', 'newsletter');
|
226 |
+
$edit_preset_text = __('Edit', 'newsletter');
|
227 |
+
|
228 |
+
// esc_js() assumes the string will be in single quote (arghhh!!!)
|
229 |
+
$onclick_edit = 'tnpc_edit_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
230 |
+
$onclick_delete = 'tnpc_delete_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
231 |
+
$onclick_load = 'tnpc_load_preset(' . ((int) $user_preset->id) . ', \'' . esc_js($preset_name) . '\', event)';
|
232 |
+
|
233 |
+
$content .= "<div class='tnpc-preset' onclick='" . esc_attr($onclick_load) . "'>\n";
|
234 |
+
$content .= "<img src='$default_icon_url' title='" . esc_attr($preset_name) . "' alt='" . esc_attr($preset_name) . "'>\n";
|
235 |
+
$content .= "<span class='tnpc-preset-label'>" . esc_html($user_preset->subject) . "</span>\n";
|
236 |
+
$content .= "<span class='tnpc-delete-preset' onclick='" . esc_attr($onclick_delete) . "' title='" . esc_attr($delete_preset_text) . "'><i class='fas fa-times'></i></span>\n";
|
237 |
+
$content .= "<span class='tnpc-edit-preset' onclick='" . esc_attr($onclick_edit) . "' title='" . esc_attr($edit_preset_text) . "'><i class='fas fa-pencil-alt'></i></span>\n";
|
238 |
+
$content .= "</div>";
|
239 |
+
}
|
240 |
+
|
241 |
+
// LOAD TNP PRESETS
|
242 |
+
foreach (self::$PRESETS_LIST as $id) {
|
243 |
+
$preset = $this->get_preset_from_file($id);
|
244 |
+
$preset_name = esc_html($preset->name);
|
245 |
+
$content .= "<div class='tnpc-preset' onclick='tnpc_load_preset(\"$id\")'>";
|
246 |
+
$content .= "<img src='$preset->icon' title='$preset_name' alt='$preset_name'/>";
|
247 |
+
$content .= "<span class='tnpc-preset-label'>$preset_name</span>";
|
248 |
+
$content .= "</div>";
|
249 |
+
}
|
250 |
+
|
251 |
+
if ($this->is_normal_context_request()) {
|
252 |
+
$content .= $this->get_automated_spot_element();
|
253 |
+
$content .= $this->get_autoresponder_spot_element();
|
254 |
+
$content .= $this->get_raw_html_preset_element();
|
255 |
+
}
|
256 |
+
|
257 |
+
return $content;
|
258 |
+
}
|
259 |
+
|
260 |
+
private function is_normal_context_request() {
|
261 |
+
return empty($_REQUEST['context_type']);
|
262 |
+
}
|
263 |
+
|
264 |
+
private function is_automated_context_request() {
|
265 |
+
return isset($_REQUEST['context_type']) && $_REQUEST['context_type'] === 'automated';
|
266 |
+
}
|
267 |
+
|
268 |
+
private function is_autoresponder_context_request() {
|
269 |
+
return isset($_REQUEST['context_type']) && $_REQUEST['context_type'] === 'autoresponder';
|
270 |
+
}
|
271 |
+
|
272 |
+
private function get_automated_spot_element() {
|
273 |
+
$result = "<div class='tnpc-preset'>";
|
274 |
+
if (class_exists('NewsletterAutomated')) {
|
275 |
+
$result .= "<a href='?page=newsletter_automated_index'>";
|
276 |
+
} else {
|
277 |
+
$result .= "<a href='https://www.thenewsletterplugin.com/automated?utm_source=plugin&utm_campaign=automated&utm_medium=composer'>";
|
278 |
+
}
|
279 |
+
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/automated.png' title='Automated addon' alt='Automated'/>";
|
280 |
+
$result .= "<span class='tnpc-preset-label'>Daily, weekly and monthly newsletters</span></a>";
|
281 |
+
$result .= "</div>";
|
282 |
+
|
283 |
+
return $result;
|
284 |
+
}
|
285 |
+
|
286 |
+
private function get_autoresponder_spot_element() {
|
287 |
+
$result = "<div class='tnpc-preset'>";
|
288 |
+
if (class_exists('NewsletterAutoresponder')) {
|
289 |
+
$result .= "<a href='?page=newsletter_autoresponder_index'>";
|
290 |
+
} else {
|
291 |
+
$result .= "<a href='https://www.thenewsletterplugin.com/autoresponder?utm_source=plugin&utm_campaign=autoresponder&utm_medium=composer' target='_blank'>";
|
292 |
+
}
|
293 |
+
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/autoresponder.png' title='Autoresponder addon' alt='Autoresponder'/>";
|
294 |
+
$result .= "<span class='tnpc-preset-label'>Autoresponders</span></a>";
|
295 |
+
$result .= "</div>";
|
296 |
+
|
297 |
+
return $result;
|
298 |
+
}
|
299 |
+
|
300 |
+
private function get_raw_html_preset_element() {
|
301 |
+
|
302 |
+
$result = "<div class='tnpc-preset tnpc-preset-html' onclick='location.href=\"" . wp_nonce_url('admin.php?page=newsletter_emails_new&id=rawhtml', 'newsletter-new') . "\"'>";
|
303 |
+
$result .= "<img src='" . plugins_url('newsletter') . "/emails/images/rawhtml.png' title='RAW HTML' alt='RAW'/>";
|
304 |
+
$result .= "<span class='tnpc-preset-label'>Raw HTML</span>";
|
305 |
+
$result .= "</div>";
|
306 |
+
|
307 |
+
$result .= "<div class='clear'></div>";
|
308 |
+
$result .= "</div>";
|
309 |
+
|
310 |
+
return $result;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Check if the preset name exists and adds an incremental suffix if the name exists.
|
315 |
+
*
|
316 |
+
* @param string $name
|
317 |
+
*
|
318 |
+
* @return string
|
319 |
+
*/
|
320 |
+
public function sanitize_preset_name($name) {
|
321 |
+
global $wpdb;
|
322 |
+
|
323 |
+
$name = empty($name) ? __('Empty name preset', 'newsletter') : $name;
|
324 |
+
$name = sanitize_text_field($name);
|
325 |
+
$type = self::PRESET_EMAIL_TYPE;
|
326 |
+
$count = (int) $wpdb->get_var("SELECT COUNT(*) FROM " . NEWSLETTER_EMAILS_TABLE . " WHERE type='$type' and subject='$name'");
|
327 |
+
|
328 |
+
$name = $count > 0 ? $name . " - " . ($count + 1) : $name;
|
329 |
+
|
330 |
+
return $name;
|
331 |
+
}
|
332 |
+
|
333 |
+
function has_dynamic_blocks($theme) {
|
334 |
+
preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
|
335 |
+
foreach ($matches[1] as $match) {
|
336 |
+
$a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
|
337 |
+
$options = $this->options_decode($a);
|
338 |
+
|
339 |
+
$block = $this->get_block($options['block_id']);
|
340 |
+
if (!$block) {
|
341 |
+
continue;
|
342 |
+
}
|
343 |
+
if ($block['type'] == 'dynamic') {
|
344 |
+
return true;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
return false;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Regenerates a saved composed email rendering each block. Regeneration is
|
352 |
+
* conditioned (possibly) by the context. The context is usually passed to blocks
|
353 |
+
* so they can act in the right manner.
|
354 |
+
*
|
355 |
+
* $context contains a type and, for automated, the last_run.
|
356 |
+
*
|
357 |
+
* $email can actually be even a string containing the full newsletter HTML code.
|
358 |
+
*
|
359 |
+
* @param TNP_Email $email (Rinominare)
|
360 |
+
* @return string
|
361 |
+
*/
|
362 |
+
function regenerate($email, $context = []) {
|
363 |
+
|
364 |
+
// Cannot be removed due to compatibility issues with old Automated versions
|
365 |
+
if (is_object($email)) {
|
366 |
+
$theme = $email->message;
|
367 |
+
} else {
|
368 |
+
$theme = $email;
|
369 |
+
}
|
370 |
+
|
371 |
+
//$this->logger->debug('Starting email regeneration');
|
372 |
+
//$this->logger->debug($context);
|
373 |
+
|
374 |
+
if (empty($theme)) {
|
375 |
+
$this->logger->debug('The email was empty');
|
376 |
+
return array('body' => '', 'subject' => '');
|
377 |
+
}
|
378 |
+
|
379 |
+
$context = array_merge(['last_run' => 0, 'type' => ''], $context);
|
380 |
+
|
381 |
+
preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
|
382 |
+
|
383 |
+
$result = '';
|
384 |
+
$subject = '';
|
385 |
+
|
386 |
+
foreach ($matches[1] as $match) {
|
387 |
+
$a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
|
388 |
+
$options = $this->options_decode($a);
|
389 |
+
|
390 |
+
$block = $this->get_block($options['block_id']);
|
391 |
+
if (!$block) {
|
392 |
+
$this->logger->debug('Unable to load the block ' . $options['block_id']);
|
393 |
+
//continue;
|
394 |
+
}
|
395 |
+
|
396 |
+
ob_start();
|
397 |
+
$out = $this->render_block($options['block_id'], true, $options, $context);
|
398 |
+
if (is_array($out)) {
|
399 |
+
if ($out['return_empty_message'] || $out['stop']) {
|
400 |
+
if (is_object($email)) {
|
401 |
+
return false;
|
402 |
+
}
|
403 |
+
return array();
|
404 |
+
}
|
405 |
+
if ($out['skip']) {
|
406 |
+
if (NEWSLETTER_DEBUG) {
|
407 |
+
$result .= 'Block removed by request';
|
408 |
+
}
|
409 |
+
continue;
|
410 |
+
}
|
411 |
+
if (empty($subject) && !empty($out['subject'])) {
|
412 |
+
$subject = $out['subject'];
|
413 |
+
}
|
414 |
+
}
|
415 |
+
$block_html = ob_get_clean();
|
416 |
+
$result .= $block_html;
|
417 |
+
}
|
418 |
+
|
419 |
+
// We need to keep the CSS/HEAD part, the regenearion is only about blocks
|
420 |
+
|
421 |
+
if (is_object($email)) {
|
422 |
+
$result = TNP_Composer::get_main_wrapper_open($email) . $result . TNP_Composer::get_main_wrapper_close($email);
|
423 |
+
}
|
424 |
+
|
425 |
+
$x = strpos($theme, '<body');
|
426 |
+
if ($x !== false) {
|
427 |
+
$x = strpos($theme, '>', $x);
|
428 |
+
$result = substr($theme, 0, $x + 1) . $result . '</body></html>';
|
429 |
+
} else {
|
430 |
+
|
431 |
+
}
|
432 |
+
|
433 |
+
if (is_object($email)) {
|
434 |
+
$email->message = $result;
|
435 |
+
$email->subject = $subject;
|
436 |
+
return true;
|
437 |
+
}
|
438 |
+
|
439 |
+
// Kept for compatibility
|
440 |
+
return array('body' => $result, 'subject' => $subject);
|
441 |
+
}
|
442 |
+
|
443 |
+
function remove_block_data($text) {
|
444 |
+
// TODO: Lavorare!
|
445 |
+
return $text;
|
446 |
+
}
|
447 |
+
|
448 |
+
static function get_outlook_wrapper_open($width = 600) {
|
449 |
+
return '<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '" style="vertical-align:top;width:' . $width . 'px;"><![endif]-->';
|
450 |
+
}
|
451 |
+
|
452 |
+
static function get_outlook_wrapper_close() {
|
453 |
+
return "<!--[if mso | IE]></td></tr></table><![endif]-->";
|
454 |
+
}
|
455 |
+
|
456 |
+
function hook_safe_style_css($rules) {
|
457 |
+
$rules[] = 'display';
|
458 |
+
return $rules;
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Renders a block identified by its id, using the block options and adding a wrapper
|
463 |
+
* if required (for the first block rendering).
|
464 |
+
*
|
465 |
+
* @param string $block_id
|
466 |
+
* @param boolean $wrapper
|
467 |
+
* @param array $options
|
468 |
+
* @param array $context
|
469 |
+
* @param array $composer
|
470 |
+
*/
|
471 |
+
function render_block($block_id = null, $wrapper = false, $options = [], $context = [], $composer = []) {
|
472 |
+
static $kses_style_filter = false;
|
473 |
+
include_once NEWSLETTER_INCLUDES_DIR . '/helper.php';
|
474 |
+
|
475 |
+
//Remove 'options_composer_' prefix
|
476 |
+
$composer_defaults = [];
|
477 |
+
foreach (TNP_Composer::get_global_style_defaults() as $global_option_name => $global_option) {
|
478 |
+
$composer_defaults[str_replace('options_composer_', '', $global_option_name)] = $global_option;
|
479 |
+
}
|
480 |
+
$composer = array_merge($composer_defaults, $composer);
|
481 |
+
|
482 |
+
$width = 600;
|
483 |
+
$font_family = 'Helvetica, Arial, sans-serif';
|
484 |
+
|
485 |
+
$global_title_font_family = $composer['title_font_family'];
|
486 |
+
$global_title_font_size = $composer['title_font_size'];
|
487 |
+
$global_title_font_color = $composer['title_font_color'];
|
488 |
+
$global_title_font_weight = $composer['title_font_weight'];
|
489 |
+
|
490 |
+
$global_text_font_family = $composer['text_font_family'];
|
491 |
+
$global_text_font_size = $composer['text_font_size'];
|
492 |
+
$global_text_font_color = $composer['text_font_color'];
|
493 |
+
$global_text_font_weight = $composer['text_font_weight'];
|
494 |
+
|
495 |
+
$global_button_font_family = $composer['button_font_family'];
|
496 |
+
$global_button_font_size = $composer['button_font_size'];
|
497 |
+
$global_button_font_color = $composer['button_font_color'];
|
498 |
+
$global_button_font_weight = $composer['button_font_weight'];
|
499 |
+
$global_button_background_color = $composer['button_background_color'];
|
500 |
+
|
501 |
+
$global_block_background = $composer['block_background'];
|
502 |
+
|
503 |
+
$info = Newsletter::instance()->get_options('info');
|
504 |
+
|
505 |
+
// Just in case...
|
506 |
+
if (!is_array($options)) {
|
507 |
+
$options = array();
|
508 |
+
}
|
509 |
+
|
510 |
+
// This code filters the HTML to remove javascript and unsecure attributes and enable the
|
511 |
+
// "display" rule for CSS which is needed in blocks to force specific "block" or "inline" or "table".
|
512 |
+
add_filter('safe_style_css', [$this, 'hook_safe_style_css'], 9999);
|
513 |
+
$options = wp_kses_post_deep($options);
|
514 |
+
remove_filter('safe_style_css', [$this, 'hook_safe_style_css']);
|
515 |
+
|
516 |
+
$block_options = get_option('newsletter_main');
|
517 |
+
|
518 |
+
$block = $this->get_block($block_id);
|
519 |
+
|
520 |
+
if (!isset($context['type']))
|
521 |
+
$context['type'] = '';
|
522 |
+
|
523 |
+
// Block not found
|
524 |
+
if (!$block) {
|
525 |
+
if ($wrapper) {
|
526 |
+
echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">';
|
527 |
+
echo '<tr>';
|
528 |
+
echo '<td data-options="" bgcolor="#ffffff" align="center" style="padding: 0; font-family: Helvetica, Arial, sans-serif;" class="edit-block">';
|
529 |
+
}
|
530 |
+
echo $this->get_outlook_wrapper_open($width);
|
531 |
+
|
532 |
+
echo '<p>Ops, this block type is no more registered!</p>';
|
533 |
+
|
534 |
+
echo $this->get_outlook_wrapper_close();
|
535 |
+
|
536 |
+
if ($wrapper) {
|
537 |
+
echo '</td></tr></table>';
|
538 |
+
}
|
539 |
+
return;
|
540 |
+
}
|
541 |
+
|
542 |
+
$out = ['subject' => '', 'return_empty_message' => false, 'stop' => false, 'skip' => false];
|
543 |
+
|
544 |
+
$dir = is_rtl() ? 'rtl' : 'ltr';
|
545 |
+
$align_left = is_rtl() ? 'right' : 'left';
|
546 |
+
$align_right = is_rtl() ? 'left' : 'right';
|
547 |
+
|
548 |
+
ob_start();
|
549 |
+
$logger = $this->logger;
|
550 |
+
include $block['dir'] . '/block.php';
|
551 |
+
$content = trim(ob_get_clean());
|
552 |
+
|
553 |
+
if (empty($content)) {
|
554 |
+
return $out;
|
555 |
+
}
|
556 |
+
|
557 |
+
$common_defaults = array(
|
558 |
+
'block_padding_top' => 0,
|
559 |
+
'block_padding_bottom' => 0,
|
560 |
+
'block_padding_right' => 0,
|
561 |
+
'block_padding_left' => 0,
|
562 |
+
'block_background' => '',
|
563 |
+
'block_background_2' => '',
|
564 |
+
'block_width' => 600,
|
565 |
+
'block_align' => 'center'
|
566 |
+
);
|
567 |
+
|
568 |
+
$options = array_merge($common_defaults, $options);
|
569 |
+
|
570 |
+
// Obsolete
|
571 |
+
$content = str_replace('{width}', $width, $content);
|
572 |
+
|
573 |
+
$content = $this->inline_css($content, true);
|
574 |
+
|
575 |
+
// CSS driven by the block
|
576 |
+
// Requited for the server side parsing and rendering
|
577 |
+
$options['block_id'] = $block_id;
|
578 |
+
|
579 |
+
$options['block_padding_top'] = (int) str_replace('px', '', $options['block_padding_top']);
|
580 |
+
$options['block_padding_bottom'] = (int) str_replace('px', '', $options['block_padding_bottom']);
|
581 |
+
$options['block_padding_right'] = (int) str_replace('px', '', $options['block_padding_right']);
|
582 |
+
$options['block_padding_left'] = (int) str_replace('px', '', $options['block_padding_left']);
|
583 |
+
|
584 |
+
$block_background = empty($options['block_background']) ? $global_block_background : $options['block_background'];
|
585 |
+
|
586 |
+
// Internal TD wrapper
|
587 |
+
$style = 'text-align: center; ';
|
588 |
+
$style .= 'width: 100% !important; ';
|
589 |
+
$style .= 'line-height: normal !important; ';
|
590 |
+
$style .= 'letter-spacing: normal; ';
|
591 |
+
$style .= 'padding-top: ' . $options['block_padding_top'] . 'px; ';
|
592 |
+
$style .= 'padding-left: ' . $options['block_padding_left'] . 'px; ';
|
593 |
+
$style .= 'padding-right: ' . $options['block_padding_right'] . 'px; ';
|
594 |
+
$style .= 'padding-bottom: ' . $options['block_padding_bottom'] . 'px; ';
|
595 |
+
$style .= 'background-color: ' . $block_background . ';';
|
596 |
+
|
597 |
+
if (isset($options['block_background_gradient'])) {
|
598 |
+
$style .= 'background: linear-gradient(180deg, ' . $block_background . ' 0%, ' . $options['block_background_2'] . ' 100%);';
|
599 |
+
}
|
600 |
+
|
601 |
+
$data = $this->options_encode($options);
|
602 |
+
// First time block creation wrapper
|
603 |
+
if ($wrapper) {
|
604 |
+
echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">', "\n";
|
605 |
+
echo "<tr>";
|
606 |
+
echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
|
607 |
+
}
|
608 |
+
|
609 |
+
// Container that fixes the width and makes the block responsive
|
610 |
+
echo $this->get_outlook_wrapper_open($options['block_width']);
|
611 |
+
|
612 |
+
echo '<table type="options" data-json="', esc_attr($data), '" class="tnpc-block-content" border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: ', $options['block_width'], 'px!important">', "\n";
|
613 |
+
echo "<tr>";
|
614 |
+
echo '<td align="', esc_attr($options['block_align']), '" style="', $style, '" bgcolor="', $block_background, '" width="100%">';
|
615 |
+
|
616 |
+
//echo "<!-- block generated content -->\n";
|
617 |
+
echo trim($content);
|
618 |
+
//echo "\n<!-- /block generated content -->\n";
|
619 |
+
|
620 |
+
echo "</td></tr></table>";
|
621 |
+
echo $this->get_outlook_wrapper_close();
|
622 |
+
|
623 |
+
// First time block creation wrapper
|
624 |
+
if ($wrapper) {
|
625 |
+
echo "</td></tr></table>";
|
626 |
+
}
|
627 |
+
|
628 |
+
return $out;
|
629 |
+
}
|
630 |
+
|
631 |
+
/**
|
632 |
+
* Ajax call to render a block with a new set of options after the settings popup
|
633 |
+
* has been saved.
|
634 |
+
*
|
635 |
+
* @param type $block_id
|
636 |
+
* @param type $wrapper
|
637 |
+
*/
|
638 |
+
function tnpc_render_callback() {
|
639 |
+
if (!check_ajax_referer('save')) {
|
640 |
+
$this->dienow('Expired request');
|
641 |
+
}
|
642 |
+
|
643 |
+
$block_id = $_POST['id'];
|
644 |
+
$wrapper = isset($_POST['full']);
|
645 |
+
$options = $this->restore_options_from_request();
|
646 |
+
|
647 |
+
$this->render_block($block_id, $wrapper, $options, [], $_POST['composer']);
|
648 |
+
wp_die();
|
649 |
+
}
|
650 |
+
|
651 |
+
function hook_wp_ajax_tnpc_regenerate_email() {
|
652 |
+
|
653 |
+
$content = stripslashes($_POST['content']);
|
654 |
+
$global_options = $_POST['composer'];
|
655 |
+
|
656 |
+
$regenerated_content = $this->regenerate_email_blocks($content, $global_options);
|
657 |
+
|
658 |
+
wp_send_json_success([
|
659 |
+
'content' => $regenerated_content,
|
660 |
+
'message' => __('Successfully updated', 'newsletter')
|
661 |
+
]);
|
662 |
+
}
|
663 |
+
|
664 |
+
private function regenerate_email_blocks($content, $global_options) {
|
665 |
+
|
666 |
+
$raw_block_options = $this->extract_encoded_blocks_options($content);
|
667 |
+
|
668 |
+
$regenerated_content = '';
|
669 |
+
|
670 |
+
foreach ($raw_block_options as $raw_block_option) {
|
671 |
+
|
672 |
+
/* $a = html_entity_decode( $raw_block_option, ENT_QUOTES, 'UTF-8' );
|
673 |
+
$block_options = $this->options_decode( $a ); */
|
674 |
+
|
675 |
+
$block_options = $this->options_decode($raw_block_option);
|
676 |
+
|
677 |
+
$block = $this->get_block($block_options['block_id']);
|
678 |
+
if (!$block) {
|
679 |
+
$this->logger->debug('Unable to load the block ' . $block_options['block_id']);
|
680 |
+
}
|
681 |
+
|
682 |
+
ob_start();
|
683 |
+
$this->render_block($block_options['block_id'], true, $block_options, [], $global_options);
|
684 |
+
$block_html = ob_get_clean();
|
685 |
+
|
686 |
+
$regenerated_content .= $block_html;
|
687 |
+
}
|
688 |
+
|
689 |
+
return $regenerated_content;
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* @param string $html_email_content Email html content
|
694 |
+
*
|
695 |
+
* @return string[] Encoded options of email blocks
|
696 |
+
*/
|
697 |
+
private function extract_encoded_blocks_options($html_email_content) {
|
698 |
+
|
699 |
+
preg_match_all('/data-json="(.*?)"/m', $html_email_content, $raw_block_options, PREG_PATTERN_ORDER);
|
700 |
+
|
701 |
+
return $raw_block_options[1];
|
702 |
+
}
|
703 |
+
|
704 |
+
function tnpc_preview_callback() {
|
705 |
+
$email = Newsletter::instance()->get_email($_REQUEST['id'], ARRAY_A);
|
706 |
+
|
707 |
+
if (empty($email)) {
|
708 |
+
echo 'Wrong email identifier';
|
709 |
+
return;
|
710 |
+
}
|
711 |
+
|
712 |
+
echo $email['message'];
|
713 |
+
|
714 |
+
wp_die();
|
715 |
+
}
|
716 |
+
|
717 |
+
function tnpc_css_callback() {
|
718 |
+
include NEWSLETTER_DIR . '/emails/tnp-composer/css/newsletter.css';
|
719 |
+
wp_die();
|
720 |
+
}
|
721 |
+
|
722 |
+
/** Returns the correct admin page to edit the newsletter with the correct editor. */
|
723 |
+
function get_editor_url($email_id, $editor_type) {
|
724 |
+
switch ($editor_type) {
|
725 |
+
case NewsletterEmails::EDITOR_COMPOSER:
|
726 |
+
return admin_url("admin.php") . '?page=newsletter_emails_composer&id=' . $email_id;
|
727 |
+
case NewsletterEmails::EDITOR_HTML:
|
728 |
+
return admin_url("admin.php") . '?page=newsletter_emails_editorhtml&id=' . $email_id;
|
729 |
+
case NewsletterEmails::EDITOR_TINYMCE:
|
730 |
+
return admin_url("admin.php") . '?page=newsletter_emails_editortinymce&id=' . $email_id;
|
731 |
+
}
|
732 |
+
}
|
733 |
+
|
734 |
+
/**
|
735 |
+
* Returns the button linked to the correct "edit" page for the passed newsletter. The edit page can be an editor
|
736 |
+
* or the targeting page (it depends on newsletter status).
|
737 |
+
*
|
738 |
+
* @param TNP_Email $email
|
739 |
+
*/
|
740 |
+
function get_edit_button($email, $only_icon = false) {
|
741 |
+
|
742 |
+
$editor_type = $this->get_editor_type($email);
|
743 |
+
if ($email->status == 'new') {
|
744 |
+
$edit_url = $this->get_editor_url($email->id, $editor_type);
|
745 |
+
} else {
|
746 |
+
$edit_url = 'admin.php?page=newsletter_emails_edit&id=' . $email->id;
|
747 |
+
}
|
748 |
+
switch ($editor_type) {
|
749 |
+
case NewsletterEmails::EDITOR_COMPOSER:
|
750 |
+
$icon_class = 'th-large';
|
751 |
+
break;
|
752 |
+
case NewsletterEmails::EDITOR_HTML:
|
753 |
+
$icon_class = 'code';
|
754 |
+
break;
|
755 |
+
default:
|
756 |
+
$icon_class = 'edit';
|
757 |
+
break;
|
758 |
+
}
|
759 |
+
if ($only_icon) {
|
760 |
+
return '<a class="button-primary" href="' . $edit_url . '" title="' . esc_attr__('Edit', 'newsletter') . '">' .
|
761 |
+
'<i class="fas fa-' . $icon_class . '"></i></a>';
|
762 |
+
} else {
|
763 |
+
return '<a class="button-primary" href="' . $edit_url . '" title="' . esc_attr__('Edit', 'newsletter') . '">' .
|
764 |
+
'<i class="fas fa-' . $icon_class . '"></i> ' . __('Edit', 'newsletter') . '</a>';
|
765 |
+
}
|
766 |
+
}
|
767 |
+
|
768 |
+
/** Returns the correct editor type for the provided newsletter. Contains backward compatibility code. */
|
769 |
+
function get_editor_type($email) {
|
770 |
+
$email = (object) $email;
|
771 |
+
$editor_type = $email->editor;
|
772 |
+
|
773 |
+
// Backward compatibility
|
774 |
+
$email_options = maybe_unserialize($email->options);
|
775 |
+
if (isset($email_options['composer'])) {
|
776 |
+
$editor_type = NewsletterEmails::EDITOR_COMPOSER;
|
777 |
+
}
|
778 |
+
// End backward compatibility
|
779 |
+
|
780 |
+
return $editor_type;
|
781 |
+
}
|
782 |
+
|
783 |
+
/**
|
784 |
+
*
|
785 |
+
* @param type $action
|
786 |
+
* @param type $user
|
787 |
+
* @param type $email
|
788 |
+
* @return type
|
789 |
+
* @global wpdb $wpdb
|
790 |
+
*/
|
791 |
+
function hook_newsletter_action($action, $user, $email) {
|
792 |
+
global $wpdb;
|
793 |
+
|
794 |
+
switch ($action) {
|
795 |
+
case 'v':
|
796 |
+
case 'view':
|
797 |
+
$id = $_GET['id'];
|
798 |
+
if ($id == 'last') {
|
799 |
+
$email = $wpdb->get_row("select * from " . NEWSLETTER_EMAILS_TABLE . " where private=0 and type='message' and status='sent' order by send_on desc limit 1");
|
800 |
+
} else {
|
801 |
+
$email = $this->get_email($_GET['id']);
|
802 |
+
}
|
803 |
+
if (empty($email)) {
|
804 |
+
header("HTTP/1.0 404 Not Found");
|
805 |
+
die('Email not found');
|
806 |
+
}
|
807 |
+
|
808 |
+
if (!Newsletter::instance()->is_allowed()) {
|
809 |
+
|
810 |
+
if ($email->status == 'new') {
|
811 |
+
header("HTTP/1.0 404 Not Found");
|
812 |
+
die('Not sent yet');
|
813 |
+
}
|
814 |
+
|
815 |
+
if ($email->private == 1) {
|
816 |
+
if (!$user) {
|
817 |
+
header("HTTP/1.0 404 Not Found");
|
818 |
+
die('No available for online view');
|
819 |
+
}
|
820 |
+
$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));
|
821 |
+
if (!$sent) {
|
822 |
+
header("HTTP/1.0 404 Not Found");
|
823 |
+
die('No available for online view');
|
824 |
+
}
|
825 |
+
}
|
826 |
+
}
|
827 |
+
|
828 |
+
|
829 |
+
header('Content-Type: text/html;charset=UTF-8');
|
830 |
+
header('X-Robots-Tag: noindex,nofollow,noarchive');
|
831 |
+
header('Cache-Control: no-cache,no-store,private');
|
832 |
+
|
833 |
+
echo $this->replace($email->message, $user, $email);
|
834 |
+
|
835 |
+
die();
|
836 |
+
break;
|
837 |
+
|
838 |
+
case 'emails-css':
|
839 |
+
$email_id = (int) $_GET['id'];
|
840 |
+
|
841 |
+
$body = Newsletter::instance()->get_email_field($email_id, 'message');
|
842 |
+
|
843 |
+
$x = strpos($body, '<style');
|
844 |
+
if ($x === false)
|
845 |
+
return;
|
846 |
+
|
847 |
+
$x = strpos($body, '>', $x);
|
848 |
+
$y = strpos($body, '</style>');
|
849 |
+
|
850 |
+
header('Content-Type: text/css;charset=UTF-8');
|
851 |
+
|
852 |
+
echo substr($body, $x + 1, $y - $x - 1);
|
853 |
+
|
854 |
+
die();
|
855 |
+
break;
|
856 |
+
|
857 |
+
case 'emails-composer-css':
|
858 |
+
header('Cache: no-cache');
|
859 |
+
header('Content-Type: text/css');
|
860 |
+
echo $this->get_composer_css();
|
861 |
+
die();
|
862 |
+
break;
|
863 |
+
|
864 |
+
case 'emails-preview':
|
865 |
+
if (!Newsletter::instance()->is_allowed()) {
|
866 |
+
die('Not enough privileges');
|
867 |
+
}
|
868 |
+
|
869 |
+
if (!check_admin_referer('view')) {
|
870 |
+
die();
|
871 |
+
}
|
872 |
+
|
873 |
+
$theme_id = $_GET['id'];
|
874 |
+
$theme = $this->themes->get_theme($theme_id);
|
875 |
+
|
876 |
+
// Used by theme code
|
877 |
+
$theme_options = $this->themes->get_options($theme_id);
|
878 |
+
|
879 |
+
$theme_url = $theme['url'];
|
880 |
+
|
881 |
+
header('Content-Type: text/html;charset=UTF-8');
|
882 |
+
|
883 |
+
include $theme['dir'] . '/theme.php';
|
884 |
+
|
885 |
+
die();
|
886 |
+
break;
|
887 |
+
|
888 |
+
case 'emails-preview-text':
|
889 |
+
header('Content-Type: text/plain;charset=UTF-8');
|
890 |
+
if (!Newsletter::instance()->is_allowed()) {
|
891 |
+
die('Not enough privileges');
|
892 |
+
}
|
893 |
+
|
894 |
+
if (!check_admin_referer('view')) {
|
895 |
+
die();
|
896 |
+
}
|
897 |
+
|
898 |
+
// Used by theme code
|
899 |
+
$theme_options = $this->get_current_theme_options();
|
900 |
+
|
901 |
+
$file = include $theme['dir'] . '/theme-text.php';
|
902 |
+
|
903 |
+
if (is_file($file)) {
|
904 |
+
include $file;
|
905 |
+
}
|
906 |
+
|
907 |
+
die();
|
908 |
+
break;
|
909 |
+
|
910 |
+
|
911 |
+
case 'emails-create':
|
912 |
+
// Newsletter from themes are created on frontend context because sometime WP themes change the way the content,
|
913 |
+
// excerpt, thumbnail are extracted.
|
914 |
+
if (!Newsletter::instance()->is_allowed()) {
|
915 |
+
die('Not enough privileges');
|
916 |
+
}
|
917 |
+
|
918 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
919 |
+
$controls = new NewsletterControls();
|
920 |
+
|
921 |
+
if (!$controls->is_action('create')) {
|
922 |
+
die('Wrong call');
|
923 |
+
}
|
924 |
+
|
925 |
+
$theme_id = $controls->data['id'];
|
926 |
+
$theme = $this->themes->get_theme($theme_id);
|
927 |
+
|
928 |
+
if (!$theme) {
|
929 |
+
die('invalid theme');
|
930 |
+
}
|
931 |
+
|
932 |
+
$this->themes->save_options($theme_id, $controls->data);
|
933 |
+
|
934 |
+
$email = array();
|
935 |
+
$email['status'] = 'new';
|
936 |
+
$email['subject'] = ''; //__('Here the email subject', 'newsletter');
|
937 |
+
$email['track'] = 1;
|
938 |
+
$email['send_on'] = time();
|
939 |
+
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
940 |
+
$email['type'] = 'message';
|
941 |
+
|
942 |
+
$theme_options = $this->themes->get_options($theme_id);
|
943 |
+
|
944 |
+
$theme_url = $theme['url'];
|
945 |
+
$theme_subject = '';
|
946 |
+
|
947 |
+
ob_start();
|
948 |
+
include $theme['dir'] . '/theme.php';
|
949 |
+
$email['message'] = ob_get_clean();
|
950 |
+
|
951 |
+
|
952 |
+
if (!empty($theme_subject)) {
|
953 |
+
$email['subject'] = $theme_subject;
|
954 |
+
}
|
955 |
+
|
956 |
+
if (file_exists($theme['dir'] . '/theme-text.php')) {
|
957 |
+
ob_start();
|
958 |
+
include $theme['dir'] . '/theme-text.php';
|
959 |
+
$email['message_text'] = ob_get_clean();
|
960 |
+
} else {
|
961 |
+
$email['message_text'] = 'You need a modern email client to read this email. Read it online: {email_url}.';
|
962 |
+
}
|
963 |
+
|
964 |
+
$email = $this->save_email($email);
|
965 |
+
|
966 |
+
$edit_url = $this->get_editor_url($email->id, $email->editor);
|
967 |
+
|
968 |
+
header('Location: ' . $edit_url);
|
969 |
+
|
970 |
+
die();
|
971 |
+
break;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
|
975 |
+
function admin_menu() {
|
976 |
+
$this->add_menu_page('index', 'Newsletters');
|
977 |
+
$this->add_admin_page('list', 'Email List');
|
978 |
+
$this->add_admin_page('new', 'Email New');
|
979 |
+
$this->add_admin_page('edit', 'Email Edit');
|
980 |
+
$this->add_admin_page('theme', 'Email Themes');
|
981 |
+
$this->add_admin_page('composer', 'The Composer');
|
982 |
+
$this->add_admin_page('editorhtml', 'HTML Editor');
|
983 |
+
$this->add_admin_page('editortinymce', 'TinyMCE Editor');
|
984 |
+
}
|
985 |
+
|
986 |
+
/**
|
987 |
+
* Builds a block data structure starting from the folder containing the block
|
988 |
+
* files.
|
989 |
+
*
|
990 |
+
* @param string $dir
|
991 |
+
* @return array | WP_Error
|
992 |
+
*/
|
993 |
+
function build_block($dir) {
|
994 |
+
$dir = realpath($dir);
|
995 |
+
$dir = wp_normalize_path($dir);
|
996 |
+
$full_file = $dir . '/block.php';
|
997 |
+
if (!is_file($full_file)) {
|
998 |
+
return new WP_Error('1', 'Missing block.php file in ' . $dir);
|
999 |
+
}
|
1000 |
+
|
1001 |
+
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
1002 |
+
$file = basename($dir);
|
1003 |
+
|
1004 |
+
$data = get_file_data($full_file, ['name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'type' => 'Type']);
|
1005 |
+
$defaults = ['section' => 'content', 'name' => ucfirst($file), 'descritpion' => '', 'icon' => plugins_url('newsletter') . '/admin/images/block-icon.png'];
|
1006 |
+
$data = array_merge($defaults, $data);
|
1007 |
+
|
1008 |
+
if (is_file($dir . '/icon.png')) {
|
1009 |
+
$data['icon'] = content_url($relative_dir . '/icon.png');
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
$data['id'] = sanitize_key($file);
|
1013 |
+
|
1014 |
+
// Absolute path of the block files
|
1015 |
+
$data['dir'] = $dir;
|
1016 |
+
$data['url'] = content_url($relative_dir);
|
1017 |
+
|
1018 |
+
return $data;
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
/**
|
1022 |
+
*
|
1023 |
+
* @param type $dir
|
1024 |
+
* @return type
|
1025 |
+
*/
|
1026 |
+
function scan_blocks_dir($dir) {
|
1027 |
+
$dir = realpath($dir);
|
1028 |
+
if (!$dir) {
|
1029 |
+
return [];
|
1030 |
+
}
|
1031 |
+
$dir = wp_normalize_path($dir);
|
1032 |
+
|
1033 |
+
$list = [];
|
1034 |
+
$handle = opendir($dir);
|
1035 |
+
while ($file = readdir($handle)) {
|
1036 |
+
|
1037 |
+
$data = $this->build_block($dir . '/' . $file);
|
1038 |
+
|
1039 |
+
if (is_wp_error($data)) {
|
1040 |
+
$this->logger->error($data);
|
1041 |
+
continue;
|
1042 |
+
}
|
1043 |
+
$list[$data['id']] = $data;
|
1044 |
+
}
|
1045 |
+
closedir($handle);
|
1046 |
+
return $list;
|
1047 |
+
}
|
1048 |
+
|
1049 |
+
/**
|
1050 |
+
* Array of arrays with every registered block and legacy block converted to the new
|
1051 |
+
* format.
|
1052 |
+
*
|
1053 |
+
* @return array
|
1054 |
+
*/
|
1055 |
+
function get_blocks() {
|
1056 |
+
|
1057 |
+
if (!is_null($this->blocks)) {
|
1058 |
+
return $this->blocks;
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
$this->blocks = $this->scan_blocks_dir(__DIR__ . '/blocks');
|
1062 |
+
|
1063 |
+
$extended = $this->scan_blocks_dir(WP_CONTENT_DIR . '/extensions/newsletter/blocks');
|
1064 |
+
|
1065 |
+
$this->blocks = array_merge($extended, $this->blocks);
|
1066 |
+
|
1067 |
+
$dirs = apply_filters('newsletter_blocks_dir', array());
|
1068 |
+
|
1069 |
+
//$this->logger->debug('Block dirs:');
|
1070 |
+
//$this->logger->debug($dirs);
|
1071 |
+
|
1072 |
+
foreach ($dirs as $dir) {
|
1073 |
+
$list = $this->scan_blocks_dir($dir);
|
1074 |
+
$this->blocks = array_merge($list, $this->blocks);
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
do_action('newsletter_register_blocks');
|
1078 |
+
|
1079 |
+
foreach (TNP_Composer::$block_dirs as $dir) {
|
1080 |
+
$block = $this->build_block($dir);
|
1081 |
+
if (is_wp_error($block)) {
|
1082 |
+
$this->logger->error($block);
|
1083 |
+
continue;
|
1084 |
+
}
|
1085 |
+
if (!isset($this->blocks[$block['id']])) {
|
1086 |
+
$this->blocks[$block['id']] = $block;
|
1087 |
+
} else {
|
1088 |
+
$this->logger->error('The block "' . $block['id'] . '" has already been registered');
|
1089 |
+
}
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
$this->blocks = array_reverse($this->blocks);
|
1093 |
+
return $this->blocks;
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
/**
|
1097 |
+
* Return a single block (associative array) checking for legacy ID as well.
|
1098 |
+
*
|
1099 |
+
* @param string $id
|
1100 |
+
* @return array
|
1101 |
+
*/
|
1102 |
+
function get_block($id) {
|
1103 |
+
switch ($id) {
|
1104 |
+
case 'content-03-text.block':
|
1105 |
+
$id = 'text';
|
1106 |
+
break;
|
1107 |
+
case 'footer-03-social.block':
|
1108 |
+
$id = 'social';
|
1109 |
+
break;
|
1110 |
+
case 'footer-02-canspam.block':
|
1111 |
+
$id = 'canspam';
|
1112 |
+
break;
|
1113 |
+
case 'content-05-image.block':
|
1114 |
+
$id = 'image';
|
1115 |
+
break;
|
1116 |
+
case 'header-01-header.block':
|
1117 |
+
$id = 'header';
|
1118 |
+
break;
|
1119 |
+
case 'footer-01-footer.block':
|
1120 |
+
$id = 'footer';
|
1121 |
+
break;
|
1122 |
+
case 'content-02-heading.block':
|
1123 |
+
$id = 'heading';
|
1124 |
+
break;
|
1125 |
+
case 'content-07-twocols.block':
|
1126 |
+
case 'content-06-posts.block':
|
1127 |
+
$id = 'posts';
|
1128 |
+
break;
|
1129 |
+
case 'content-04-cta.block':
|
1130 |
+
$id = 'cta';
|
1131 |
+
break;
|
1132 |
+
case 'content-01-hero.block':
|
1133 |
+
$id = 'hero';
|
1134 |
+
break;
|
1135 |
+
// case 'content-02-heading.block': $id = '/plugins/newsletter/emails/blocks/heading';
|
1136 |
+
// break;
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
// Conversion for old full path ID
|
1140 |
+
$id = sanitize_key(basename($id));
|
1141 |
+
|
1142 |
+
// TODO: Correct id for compatibility
|
1143 |
+
$blocks = $this->get_blocks();
|
1144 |
+
if (!isset($blocks[$id])) {
|
1145 |
+
return null;
|
1146 |
+
}
|
1147 |
+
return $blocks[$id];
|
1148 |
+
}
|
1149 |
+
|
1150 |
+
function scan_presets_dir($dir = null) {
|
1151 |
+
|
1152 |
+
if (is_null($dir)) {
|
1153 |
+
$dir = __DIR__ . '/presets';
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
if (!is_dir($dir)) {
|
1157 |
+
return array();
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
$handle = opendir($dir);
|
1161 |
+
$list = array();
|
1162 |
+
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
1163 |
+
while ($file = readdir($handle)) {
|
1164 |
+
|
1165 |
+
if ($file == '.' || $file == '..')
|
1166 |
+
continue;
|
1167 |
+
|
1168 |
+
// The block unique key, we should find out how to build it, maybe an hash of the (relative) dir?
|
1169 |
+
$preset_id = sanitize_key($file);
|
1170 |
+
|
1171 |
+
$full_file = $dir . '/' . $file . '/preset.json';
|
1172 |
+
|
1173 |
+
if (!is_file($full_file)) {
|
1174 |
+
continue;
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
$icon = content_url($relative_dir . '/' . $file . '/icon.png');
|
1178 |
+
|
1179 |
+
$list[$preset_id] = $icon;
|
1180 |
+
}
|
1181 |
+
closedir($handle);
|
1182 |
+
return $list;
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
function get_preset_from_file($id, $dir = null) {
|
1186 |
+
|
1187 |
+
if (is_null($dir)) {
|
1188 |
+
$dir = __DIR__ . '/presets';
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
$id = $this->sanitize_file_name($id);
|
1192 |
+
|
1193 |
+
if (!is_dir($dir . '/' . $id) || !in_array($id, self::$PRESETS_LIST)) {
|
1194 |
+
return array();
|
1195 |
+
}
|
1196 |
+
|
1197 |
+
$json_content = file_get_contents("$dir/$id/preset.json");
|
1198 |
+
$json_content = str_replace("{placeholder_base_url}", plugins_url('newsletter') . '/emails/presets', $json_content);
|
1199 |
+
$json = json_decode($json_content);
|
1200 |
+
$json->icon = NEWSLETTER_URL . "/emails/presets/$id/icon.png?ver=2";
|
1201 |
+
|
1202 |
+
return $json;
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
function get_composer_css() {
|
1206 |
+
$css = file_get_contents(__DIR__ . '/tnp-composer/css/newsletter.css');
|
1207 |
+
$css .= "\n\n";
|
1208 |
+
$css .= file_get_contents(__DIR__ . '/tnp-composer/css/backend.css');
|
1209 |
+
$blocks = $this->get_blocks();
|
1210 |
+
foreach ($blocks as $block) {
|
1211 |
+
if (!file_exists($block['dir'] . '/style.css')) {
|
1212 |
+
continue;
|
1213 |
+
}
|
1214 |
+
$css .= "\n\n";
|
1215 |
+
$css .= "/* " . $block['name'] . " */\n";
|
1216 |
+
$css .= file_get_contents($block['dir'] . '/style.css');
|
1217 |
+
}
|
1218 |
+
return $css;
|
1219 |
+
}
|
1220 |
+
|
1221 |
+
/**
|
1222 |
+
* Send an email to the test subscribers.
|
1223 |
+
*
|
1224 |
+
* @param TNP_Email $email Could be any object with the TNP_Email attributes
|
1225 |
+
* @param NewsletterControls $controls
|
1226 |
+
*/
|
1227 |
+
function send_test_email($email, $controls) {
|
1228 |
+
if (!$email) {
|
1229 |
+
$controls->errors = __('Newsletter should be saved before send a test', 'newsletter');
|
1230 |
+
return;
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
$original_subject = $email->subject;
|
1234 |
+
$this->set_test_subject_to($email);
|
1235 |
+
|
1236 |
+
$users = NewsletterUsers::instance()->get_test_users();
|
1237 |
+
if (count($users) == 0) {
|
1238 |
+
$controls->errors = '' . __('There are no test subscribers to send to', 'newsletter') .
|
1239 |
+
'. <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="_blank"><strong>' .
|
1240 |
+
__('Read more', 'newsletter') . '</strong></a>.';
|
1241 |
+
} else {
|
1242 |
+
$r = Newsletter::instance()->send($email, $users, true);
|
1243 |
+
$emails = array();
|
1244 |
+
foreach ($users as $user) {
|
1245 |
+
$emails[] = '<a href="admin.php?page=newsletter_users_edit&id=' . $user->id . '" target="_blank">' . $user->email . '</a>';
|
1246 |
+
}
|
1247 |
+
if (is_wp_error($r)) {
|
1248 |
+
$controls->errors = 'Something went wrong. Check the error logs on status page.<br>';
|
1249 |
+
$controls->errors .= __('Test subscribers:', 'newsletter');
|
1250 |
+
$controls->errors .= ' ' . implode(', ', $emails);
|
1251 |
+
$controls->errors .= '<br>';
|
1252 |
+
$controls->errors .= '<strong>' . esc_html($r->get_error_message()) . '</strong><br>';
|
1253 |
+
$controls->errors .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __('Read more about delivery issues', 'newsletter') . '</strong></a>.';
|
1254 |
+
} else {
|
1255 |
+
$controls->messages = __('Test subscribers:', 'newsletter');
|
1256 |
+
|
1257 |
+
$controls->messages .= ' ' . implode(', ', $emails);
|
1258 |
+
$controls->messages .= '.<br>';
|
1259 |
+
$controls->messages .= '<a href="https://www.thenewsletterplugin.com/documentation/subscribers#test" target="_blank"><strong>' .
|
1260 |
+
__('Read more about test subscribers', 'newsletter') . '</strong></a>.<br>';
|
1261 |
+
$controls->messages .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __('Read more about delivery issues', 'newsletter') . '</strong></a>.';
|
1262 |
+
}
|
1263 |
+
}
|
1264 |
+
$email->subject = $original_subject;
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
/**
|
1268 |
+
* Send an email to the test subscribers.
|
1269 |
+
*
|
1270 |
+
* @param TNP_Email $email Could be any object with the TNP_Email attributes
|
1271 |
+
* @param string $email_address
|
1272 |
+
*
|
1273 |
+
* @throws Exception
|
1274 |
+
*/
|
1275 |
+
function send_test_newsletter_to_email_address( $email, $email_address ) {
|
1276 |
+
|
1277 |
+
if ( ! $email ) {
|
1278 |
+
throw new Exception( __( 'Newsletter should be saved before send a test', 'newsletter' ) );
|
1279 |
+
}
|
1280 |
+
|
1281 |
+
$this->set_test_subject_to( $email );
|
1282 |
+
|
1283 |
+
$dummy_subscriber = $this->make_dummy_subscriber();
|
1284 |
+
$dummy_subscriber->email = $email_address;
|
1285 |
+
|
1286 |
+
$result = Newsletter::instance()->send( $email, [ $dummy_subscriber ], true );
|
1287 |
+
|
1288 |
+
$email = '<a href="admin.php?page=newsletter_users_edit&id=' . $dummy_subscriber->id . '" target="_blank">' . $dummy_subscriber->email . '</a>';
|
1289 |
+
|
1290 |
+
if ( is_wp_error( $result ) ) {
|
1291 |
+
$error_message = 'Something went wrong. Check the error logs on status page.<br>';
|
1292 |
+
$error_message .= __( 'Test subscribers:', 'newsletter' );
|
1293 |
+
$error_message .= ' ' . $email;
|
1294 |
+
$error_message .= '<br>';
|
1295 |
+
$error_message .= '<strong>' . esc_html( $result->get_error_message() ) . '</strong><br>';
|
1296 |
+
$error_message .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __( 'Read more about delivery issues', 'newsletter' ) . '</strong></a>.';
|
1297 |
+
throw new Exception( $error_message );
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
$messages = __( 'Test subscribers:', 'newsletter' );
|
1301 |
+
|
1302 |
+
$messages .= ' ' . $email;
|
1303 |
+
$messages .= '.<br>';
|
1304 |
+
$messages .= '<a href="https://www.thenewsletterplugin.com/documentation/subscribers#test" target="_blank"><strong>' .
|
1305 |
+
__( 'Read more about test subscribers', 'newsletter' ) . '</strong></a>.<br>';
|
1306 |
+
$messages .= '<a href="https://www.thenewsletterplugin.com/documentation/email-sending-issues" target="_blank"><strong>' . __( 'Read more about delivery issues', 'newsletter' ) . '</strong></a>.';
|
1307 |
+
|
1308 |
+
return $messages;
|
1309 |
+
}
|
1310 |
+
|
1311 |
+
private function set_test_subject_to($email) {
|
1312 |
+
if ( $email->subject == '' ) {
|
1313 |
+
$email->subject = '[TEST] Dummy subject, it was empty (remember to set it)';
|
1314 |
+
} else {
|
1315 |
+
$email->subject = $email->subject . ' (TEST)';
|
1316 |
+
}
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
private function make_dummy_subscriber() {
|
1320 |
+
$dummy_user = new TNP_User();
|
1321 |
+
$dummy_user->id = 0;
|
1322 |
+
$dummy_user->email = 'john.doe@example.org';
|
1323 |
+
$dummy_user->name = 'John';
|
1324 |
+
$dummy_user->surname = 'Doe';
|
1325 |
+
$dummy_user->sex = 'n';
|
1326 |
+
$dummy_user->language = '';
|
1327 |
+
$dummy_user->ip = '';
|
1328 |
+
|
1329 |
+
for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
|
1330 |
+
$profile_key = "profile_$i";
|
1331 |
+
$dummy_user->$profile_key = '';
|
1332 |
+
}
|
1333 |
+
|
1334 |
+
return $dummy_user;
|
1335 |
+
}
|
1336 |
+
|
1337 |
+
function restore_options_from_request() {
|
1338 |
+
|
1339 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
1340 |
+
$controls = new NewsletterControls();
|
1341 |
+
$options = $controls->data;
|
1342 |
+
|
1343 |
+
if (isset($_POST['options']) && is_array($_POST['options'])) {
|
1344 |
+
// Get all block options
|
1345 |
+
//$options = stripslashes_deep($_POST['options']);
|
1346 |
+
|
1347 |
+
// Deserialize inline edits when
|
1348 |
+
// render is preformed on saving block options
|
1349 |
+
if (isset($options['inline_edits']) && !is_array($options['inline_edits'])) {
|
1350 |
+
$options['inline_edits'] = $this->options_decode($options['inline_edits']);
|
1351 |
+
}
|
1352 |
+
|
1353 |
+
// Restore inline edits from data-json
|
1354 |
+
// coming from inline editing
|
1355 |
+
// and merge with current inline edit
|
1356 |
+
if (isset($_POST['encoded_options'])) {
|
1357 |
+
$decoded_options = $this->options_decode($_POST['encoded_options']);
|
1358 |
+
|
1359 |
+
$to_merge_inline_edits = [];
|
1360 |
+
|
1361 |
+
if (isset($decoded_options['inline_edits'])) {
|
1362 |
+
foreach ($decoded_options['inline_edits'] as $decoded_inline_edit) {
|
1363 |
+
$to_merge_inline_edits[$decoded_inline_edit['post_id'] . $decoded_inline_edit['type']] = $decoded_inline_edit;
|
1364 |
+
}
|
1365 |
+
}
|
1366 |
+
|
1367 |
+
//Overwrite with new edited content
|
1368 |
+
if (isset($options['inline_edits'])) {
|
1369 |
+
foreach ($options['inline_edits'] as $inline_edit) {
|
1370 |
+
$to_merge_inline_edits[$inline_edit['post_id'] . $inline_edit['type']] = $inline_edit;
|
1371 |
+
}
|
1372 |
+
}
|
1373 |
+
|
1374 |
+
$options['inline_edits'] = array_values($to_merge_inline_edits);
|
1375 |
+
$options = array_merge($decoded_options, $options);
|
1376 |
+
}
|
1377 |
+
|
1378 |
+
return $options;
|
1379 |
+
}
|
1380 |
+
|
1381 |
+
return array();
|
1382 |
+
}
|
1383 |
+
|
1384 |
+
public function hook_wp_ajax_tnpc_delete_preset() {
|
1385 |
+
|
1386 |
+
if (!wp_verify_nonce($_POST['_wpnonce'], 'preset')) {
|
1387 |
+
wp_send_json_error('Expired request');
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
$preset_id = (int) $_REQUEST['presetId'];
|
1391 |
+
|
1392 |
+
$newsletter = Newsletter::instance();
|
1393 |
+
|
1394 |
+
if ($preset_id > 0) {
|
1395 |
+
$preset = $newsletter->get_email($preset_id);
|
1396 |
+
|
1397 |
+
if ($preset && $preset->type === self::PRESET_EMAIL_TYPE) {
|
1398 |
+
Newsletter::instance()->delete_email($preset_id);
|
1399 |
+
wp_send_json_success();
|
1400 |
+
} else {
|
1401 |
+
wp_send_json_error(__('Is not a preset!', 'newsletter'));
|
1402 |
+
}
|
1403 |
+
} else {
|
1404 |
+
wp_send_json_error();
|
1405 |
+
}
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
}
|
1409 |
+
|
1410 |
+
NewsletterEmails::instance();
|
{images → emails/images}/arrow.png
RENAMED
File without changes
|
{images → emails/images}/theme-screenshot.png
RENAMED
File without changes
|
emails/new.php
CHANGED
@@ -1,175 +1,175 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $this NewsletterEmails */
|
3 |
-
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
4 |
-
|
5 |
-
$controls = new NewsletterControls();
|
6 |
-
|
7 |
-
$theme_id = $_GET['id'];
|
8 |
-
|
9 |
-
if ($theme_id === 'rawhtml' && check_admin_referer('newsletter-new')) {
|
10 |
-
$email = array();
|
11 |
-
$email['status'] = 'new';
|
12 |
-
$email['subject'] = __('Here the email subject', 'newsletter');
|
13 |
-
$email['track'] = Newsletter::instance()->options['track'];
|
14 |
-
$email['token'] = $this->get_token();
|
15 |
-
$email['type'] = 'message';
|
16 |
-
$email['send_on'] = time();
|
17 |
-
$email['editor'] = NewsletterEmails::EDITOR_HTML;
|
18 |
-
$email['message'] = "<!DOCTYPE html>\n<html>\n<head>\n<title>Your email title</title>\n</head>\n<body>\n</body>\n</html>";
|
19 |
-
$email = Newsletter::instance()->save_email($email);
|
20 |
-
|
21 |
-
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
22 |
-
return;
|
23 |
-
}
|
24 |
-
|
25 |
-
|
26 |
-
$theme = $this->themes->get_theme($theme_id);
|
27 |
-
|
28 |
-
// Should never happen
|
29 |
-
if (!$theme) {
|
30 |
-
die('Invalid theme');
|
31 |
-
}
|
32 |
-
|
33 |
-
if (!file_exists($theme['dir'] . '/theme-options.php') && check_admin_referer('newsletter-new')) {
|
34 |
-
$email = array();
|
35 |
-
$email['status'] = 'new';
|
36 |
-
$email['subject'] = __('Here the email subject', 'newsletter');
|
37 |
-
$email['track'] = Newsletter::instance()->options['track'];
|
38 |
-
$email['token'] = $this->get_token();
|
39 |
-
$email['type'] = 'message';
|
40 |
-
$email['send_on'] = time();
|
41 |
-
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
42 |
-
|
43 |
-
$theme_options = $this->themes->get_options($controls->data['theme']);
|
44 |
-
$theme_url = $theme['url'];
|
45 |
-
$theme_subject = '';
|
46 |
-
|
47 |
-
ob_start();
|
48 |
-
include $theme['dir'] . '/theme.php';
|
49 |
-
$email['message'] = ob_get_clean();
|
50 |
-
|
51 |
-
if (!empty($theme_subject)) {
|
52 |
-
$email['subject'] = $theme_subject;
|
53 |
-
}
|
54 |
-
|
55 |
-
if (file_exists($theme['dir'] . '/theme-text.php')) {
|
56 |
-
ob_start();
|
57 |
-
include $theme['dir'] . '/theme-text.php';
|
58 |
-
$email['message_text'] = ob_get_clean();
|
59 |
-
} else {
|
60 |
-
$email['message_text'] = 'You need a modern email client to read this email. Read it online: {email_url}.';
|
61 |
-
}
|
62 |
-
$email = Newsletter::instance()->save_email($email);
|
63 |
-
|
64 |
-
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
65 |
-
return;
|
66 |
-
}
|
67 |
-
|
68 |
-
if ($controls->is_action('refresh')) {
|
69 |
-
$this->themes->save_options($theme_id, $controls->data);
|
70 |
-
}
|
71 |
-
|
72 |
-
if ($controls->is_action('create')) {
|
73 |
-
|
74 |
-
$this->themes->save_options($theme_id, $controls->data);
|
75 |
-
|
76 |
-
$email = array();
|
77 |
-
$email['status'] = 'new';
|
78 |
-
$email['subject'] = __('Here the email subject', 'newsletter');
|
79 |
-
$email['track'] = Newsletter::instance()->options['track'];
|
80 |
-
$email['message_text'] = '';
|
81 |
-
$email['type'] = 'message';
|
82 |
-
$email['send_on'] = time();
|
83 |
-
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
84 |
-
|
85 |
-
$theme_options = $this->themes->get_options($theme_id);
|
86 |
-
|
87 |
-
$theme_url = $theme['url'];
|
88 |
-
$theme_subject = '';
|
89 |
-
|
90 |
-
ob_start();
|
91 |
-
include $theme['dir'] . '/theme.php';
|
92 |
-
$email['message'] = ob_get_clean();
|
93 |
-
|
94 |
-
if (!empty($theme_subject)) {
|
95 |
-
$email['subject'] = $theme_subject;
|
96 |
-
}
|
97 |
-
|
98 |
-
if (is_file($theme['dir'] . '/theme-text.php')) {
|
99 |
-
ob_start();
|
100 |
-
include $theme['dir'] . '/theme-text.php';
|
101 |
-
$email['message_text'] = ob_get_clean();
|
102 |
-
}
|
103 |
-
|
104 |
-
$email = $this->save_email($email);
|
105 |
-
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
106 |
-
return;
|
107 |
-
} else {
|
108 |
-
$controls->data = $this->themes->get_options($theme_id);
|
109 |
-
$controls->data['id'] = $theme_id;
|
110 |
-
}
|
111 |
-
?>
|
112 |
-
<style>
|
113 |
-
#tnp-body .tnp-emails-theme-options {
|
114 |
-
background-color: #fff;
|
115 |
-
padding: 10px;
|
116 |
-
margin-top: 14px;
|
117 |
-
}
|
118 |
-
|
119 |
-
#tnp-body .tnp-emails-theme-options table.form-table {
|
120 |
-
margin: 0;
|
121 |
-
}
|
122 |
-
|
123 |
-
#tnp-body .tnp-emails-theme-options h3 {
|
124 |
-
color: #000;
|
125 |
-
}
|
126 |
-
</style>
|
127 |
-
|
128 |
-
<div class="wrap tnp-emails tnp-emails-new" id="tnp-wrap">
|
129 |
-
|
130 |
-
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
131 |
-
|
132 |
-
<div id="tnp-heading">
|
133 |
-
|
134 |
-
<h2><?php _e('Create a newsletter', 'newsletter') ?>
|
135 |
-
<a class="tnp-btn-h1" href="<?php echo NewsletterEmails::instance()->get_admin_page_url('theme'); ?>"><?php _e('Back to newsletter themes', 'newsletter') ?></a>
|
136 |
-
</h2>
|
137 |
-
<br>
|
138 |
-
<p>Theme options are saved for next time you'll use this theme.</p>
|
139 |
-
|
140 |
-
</div>
|
141 |
-
|
142 |
-
<div id="tnp-body" class="tnp-body-lite">
|
143 |
-
|
144 |
-
<form method="post" action="">
|
145 |
-
<?php $controls->init(); ?>
|
146 |
-
<?php $controls->hidden('id'); ?>
|
147 |
-
<table style="width: 100%; border-collapse: collapse">
|
148 |
-
<tr>
|
149 |
-
<td style="text-align: left; vertical-align: top; border-bottom: 1px solid #ddd; padding-bottom: 10px">
|
150 |
-
<div style="float: right; margin-left: 15px;"><?php $controls->button_primary('refresh', __('Refresh the preview', 'newsletter')); ?></div>
|
151 |
-
|
152 |
-
</td>
|
153 |
-
<td style="text-align: left; vertical-align: top; border-bottom: 1px solid #ddd; padding-bottom: 10px">
|
154 |
-
<div style="float: right"><?php $controls->button_primary('create', 'Proceed to edit »', 'this.form.action=\'' . home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-create\';this.form.submit()'); ?></div>
|
155 |
-
<img style="position: relative; left: 5px; top: 10px;"src="<?php echo plugins_url('newsletter') ?>/images/arrow.png" height="35">
|
156 |
-
</td>
|
157 |
-
</tr>
|
158 |
-
<tr>
|
159 |
-
<td style="width: 500px; vertical-align: top;">
|
160 |
-
<div class="tnp-emails-theme-options">
|
161 |
-
<?php @include $theme['dir'] . '/theme-options.php'; ?>
|
162 |
-
</div>
|
163 |
-
</td>
|
164 |
-
<td style="vertical-align: top; padding-top: 15px; padding-left: 15px">
|
165 |
-
<iframe src="<?php echo wp_nonce_url(home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-preview&id=' . urlencode($theme_id) . '&ts=' . time(), 'view'); ?>" height="700" style="width: 100%; border: 1px solid #ccc"></iframe>
|
166 |
-
</td>
|
167 |
-
</tr>
|
168 |
-
</table>
|
169 |
-
|
170 |
-
</form>
|
171 |
-
</div>
|
172 |
-
|
173 |
-
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
174 |
-
|
175 |
</div>
|
1 |
+
<?php
|
2 |
+
/* @var $this NewsletterEmails */
|
3 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
4 |
+
|
5 |
+
$controls = new NewsletterControls();
|
6 |
+
|
7 |
+
$theme_id = $_GET['id'];
|
8 |
+
|
9 |
+
if ($theme_id === 'rawhtml' && check_admin_referer('newsletter-new')) {
|
10 |
+
$email = array();
|
11 |
+
$email['status'] = 'new';
|
12 |
+
$email['subject'] = __('Here the email subject', 'newsletter');
|
13 |
+
$email['track'] = Newsletter::instance()->options['track'];
|
14 |
+
$email['token'] = $this->get_token();
|
15 |
+
$email['type'] = 'message';
|
16 |
+
$email['send_on'] = time();
|
17 |
+
$email['editor'] = NewsletterEmails::EDITOR_HTML;
|
18 |
+
$email['message'] = "<!DOCTYPE html>\n<html>\n<head>\n<title>Your email title</title>\n</head>\n<body>\n</body>\n</html>";
|
19 |
+
$email = Newsletter::instance()->save_email($email);
|
20 |
+
|
21 |
+
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
$theme = $this->themes->get_theme($theme_id);
|
27 |
+
|
28 |
+
// Should never happen
|
29 |
+
if (!$theme) {
|
30 |
+
die('Invalid theme');
|
31 |
+
}
|
32 |
+
|
33 |
+
if (!file_exists($theme['dir'] . '/theme-options.php') && check_admin_referer('newsletter-new')) {
|
34 |
+
$email = array();
|
35 |
+
$email['status'] = 'new';
|
36 |
+
$email['subject'] = __('Here the email subject', 'newsletter');
|
37 |
+
$email['track'] = Newsletter::instance()->options['track'];
|
38 |
+
$email['token'] = $this->get_token();
|
39 |
+
$email['type'] = 'message';
|
40 |
+
$email['send_on'] = time();
|
41 |
+
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
42 |
+
|
43 |
+
$theme_options = $this->themes->get_options($controls->data['theme']);
|
44 |
+
$theme_url = $theme['url'];
|
45 |
+
$theme_subject = '';
|
46 |
+
|
47 |
+
ob_start();
|
48 |
+
include $theme['dir'] . '/theme.php';
|
49 |
+
$email['message'] = ob_get_clean();
|
50 |
+
|
51 |
+
if (!empty($theme_subject)) {
|
52 |
+
$email['subject'] = $theme_subject;
|
53 |
+
}
|
54 |
+
|
55 |
+
if (file_exists($theme['dir'] . '/theme-text.php')) {
|
56 |
+
ob_start();
|
57 |
+
include $theme['dir'] . '/theme-text.php';
|
58 |
+
$email['message_text'] = ob_get_clean();
|
59 |
+
} else {
|
60 |
+
$email['message_text'] = 'You need a modern email client to read this email. Read it online: {email_url}.';
|
61 |
+
}
|
62 |
+
$email = Newsletter::instance()->save_email($email);
|
63 |
+
|
64 |
+
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
65 |
+
return;
|
66 |
+
}
|
67 |
+
|
68 |
+
if ($controls->is_action('refresh')) {
|
69 |
+
$this->themes->save_options($theme_id, $controls->data);
|
70 |
+
}
|
71 |
+
|
72 |
+
if ($controls->is_action('create')) {
|
73 |
+
|
74 |
+
$this->themes->save_options($theme_id, $controls->data);
|
75 |
+
|
76 |
+
$email = array();
|
77 |
+
$email['status'] = 'new';
|
78 |
+
$email['subject'] = __('Here the email subject', 'newsletter');
|
79 |
+
$email['track'] = Newsletter::instance()->options['track'];
|
80 |
+
$email['message_text'] = '';
|
81 |
+
$email['type'] = 'message';
|
82 |
+
$email['send_on'] = time();
|
83 |
+
$email['editor'] = NewsletterEmails::EDITOR_TINYMCE;
|
84 |
+
|
85 |
+
$theme_options = $this->themes->get_options($theme_id);
|
86 |
+
|
87 |
+
$theme_url = $theme['url'];
|
88 |
+
$theme_subject = '';
|
89 |
+
|
90 |
+
ob_start();
|
91 |
+
include $theme['dir'] . '/theme.php';
|
92 |
+
$email['message'] = ob_get_clean();
|
93 |
+
|
94 |
+
if (!empty($theme_subject)) {
|
95 |
+
$email['subject'] = $theme_subject;
|
96 |
+
}
|
97 |
+
|
98 |
+
if (is_file($theme['dir'] . '/theme-text.php')) {
|
99 |
+
ob_start();
|
100 |
+
include $theme['dir'] . '/theme-text.php';
|
101 |
+
$email['message_text'] = ob_get_clean();
|
102 |
+
}
|
103 |
+
|
104 |
+
$email = $this->save_email($email);
|
105 |
+
$controls->js_redirect($this->get_editor_url($email->id, $email->editor));
|
106 |
+
return;
|
107 |
+
} else {
|
108 |
+
$controls->data = $this->themes->get_options($theme_id);
|
109 |
+
$controls->data['id'] = $theme_id;
|
110 |
+
}
|
111 |
+
?>
|
112 |
+
<style>
|
113 |
+
#tnp-body .tnp-emails-theme-options {
|
114 |
+
background-color: #fff;
|
115 |
+
padding: 10px;
|
116 |
+
margin-top: 14px;
|
117 |
+
}
|
118 |
+
|
119 |
+
#tnp-body .tnp-emails-theme-options table.form-table {
|
120 |
+
margin: 0;
|
121 |
+
}
|
122 |
+
|
123 |
+
#tnp-body .tnp-emails-theme-options h3 {
|
124 |
+
color: #000;
|
125 |
+
}
|
126 |
+
</style>
|
127 |
+
|
128 |
+
<div class="wrap tnp-emails tnp-emails-new" id="tnp-wrap">
|
129 |
+
|
130 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
131 |
+
|
132 |
+
<div id="tnp-heading">
|
133 |
+
|
134 |
+
<h2><?php _e('Create a newsletter', 'newsletter') ?>
|
135 |
+
<a class="tnp-btn-h1" href="<?php echo NewsletterEmails::instance()->get_admin_page_url('theme'); ?>"><?php _e('Back to newsletter themes', 'newsletter') ?></a>
|
136 |
+
</h2>
|
137 |
+
<br>
|
138 |
+
<p>Theme options are saved for next time you'll use this theme.</p>
|
139 |
+
|
140 |
+
</div>
|
141 |
+
|
142 |
+
<div id="tnp-body" class="tnp-body-lite">
|
143 |
+
|
144 |
+
<form method="post" action="">
|
145 |
+
<?php $controls->init(); ?>
|
146 |
+
<?php $controls->hidden('id'); ?>
|
147 |
+
<table style="width: 100%; border-collapse: collapse">
|
148 |
+
<tr>
|
149 |
+
<td style="text-align: left; vertical-align: top; border-bottom: 1px solid #ddd; padding-bottom: 10px">
|
150 |
+
<div style="float: right; margin-left: 15px;"><?php $controls->button_primary('refresh', __('Refresh the preview', 'newsletter')); ?></div>
|
151 |
+
|
152 |
+
</td>
|
153 |
+
<td style="text-align: left; vertical-align: top; border-bottom: 1px solid #ddd; padding-bottom: 10px">
|
154 |
+
<div style="float: right"><?php $controls->button_primary('create', 'Proceed to edit »', 'this.form.action=\'' . home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-create\';this.form.submit()'); ?></div>
|
155 |
+
<img style="position: relative; left: 5px; top: 10px;"src="<?php echo plugins_url('newsletter') ?>/emails/images/arrow.png" height="35">
|
156 |
+
</td>
|
157 |
+
</tr>
|
158 |
+
<tr>
|
159 |
+
<td style="width: 500px; vertical-align: top;">
|
160 |
+
<div class="tnp-emails-theme-options">
|
161 |
+
<?php @include $theme['dir'] . '/theme-options.php'; ?>
|
162 |
+
</div>
|
163 |
+
</td>
|
164 |
+
<td style="vertical-align: top; padding-top: 15px; padding-left: 15px">
|
165 |
+
<iframe src="<?php echo wp_nonce_url(home_url('/', is_ssl() ? 'https' : 'http') . '?na=emails-preview&id=' . urlencode($theme_id) . '&ts=' . time(), 'view'); ?>" height="700" style="width: 100%; border: 1px solid #ccc"></iframe>
|
166 |
+
</td>
|
167 |
+
</tr>
|
168 |
+
</table>
|
169 |
+
|
170 |
+
</form>
|
171 |
+
</div>
|
172 |
+
|
173 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
174 |
+
|
175 |
</div>
|
emails/tnp-composer/_css/newsletter-builder-v2.css
CHANGED
@@ -1,1173 +1,1173 @@
|
|
1 |
-
#wpbody-content {
|
2 |
-
padding-bottom: 15px;
|
3 |
-
}
|
4 |
-
|
5 |
-
.tnp-emails-composer {
|
6 |
-
margin: 15px 15px 0 0;
|
7 |
-
}
|
8 |
-
|
9 |
-
|
10 |
-
/* Contains the newsletter editing area and the tools */
|
11 |
-
#newsletter-builder {
|
12 |
-
height: calc(100vh - 120px);
|
13 |
-
display: flex;
|
14 |
-
flex-flow: row;
|
15 |
-
position: relative;
|
16 |
-
overflow: hidden;
|
17 |
-
box-sizing: border-box;
|
18 |
-
max-width: 1380px;
|
19 |
-
margin: 0 auto;
|
20 |
-
}
|
21 |
-
|
22 |
-
/* Contains the newsletter editing area */
|
23 |
-
#newsletter-builder-area {
|
24 |
-
display: flex;
|
25 |
-
flex-flow: column;
|
26 |
-
flex-shrink: 0;
|
27 |
-
background-color: #fff;
|
28 |
-
width: 800px;
|
29 |
-
box-sizing: border-box;
|
30 |
-
border-radius: 3px;
|
31 |
-
overflow: hidden;
|
32 |
-
float: left;
|
33 |
-
|
34 |
-
position: relative;
|
35 |
-
}
|
36 |
-
|
37 |
-
/* Contains the tools */
|
38 |
-
#newsletter-builder-sidebar {
|
39 |
-
display: flex;
|
40 |
-
flex-flow: column;
|
41 |
-
/* flex-grow: 1;*/
|
42 |
-
max-width: 510px;
|
43 |
-
min-width: 410px;
|
44 |
-
background-color: #ECF0F1;
|
45 |
-
margin-left: 20px;
|
46 |
-
overflow-y: scroll;
|
47 |
-
/* Needed for block options form */
|
48 |
-
position: relative;
|
49 |
-
border-radius: 3px;
|
50 |
-
overflow: hidden;
|
51 |
-
}
|
52 |
-
|
53 |
-
#tnpc-subject-wrap {
|
54 |
-
border-bottom: 1px solid #ccc;
|
55 |
-
padding-bottom: 20px;
|
56 |
-
padding-top: 20px;
|
57 |
-
padding-left: 20px;
|
58 |
-
position:relative;
|
59 |
-
}
|
60 |
-
|
61 |
-
#tnpc-subject-wrap th {
|
62 |
-
color: #999;
|
63 |
-
font-size: 14px;
|
64 |
-
font-weight: normal!important;
|
65 |
-
text-align: right;
|
66 |
-
padding-right: 10px;
|
67 |
-
padding-bottom: 10px;
|
68 |
-
vertical-align: middle;
|
69 |
-
}
|
70 |
-
|
71 |
-
#tnpc-subject-wrap td {
|
72 |
-
color: #000;
|
73 |
-
font-size: 14px;
|
74 |
-
font-weight: normal!important;
|
75 |
-
text-align: left;
|
76 |
-
padding-right: 10px;
|
77 |
-
padding-bottom: 10px;
|
78 |
-
vertical-align: middle;
|
79 |
-
}
|
80 |
-
|
81 |
-
#tnpc-subject-wrap th[dir=rtl] {
|
82 |
-
text-align: left;
|
83 |
-
}
|
84 |
-
#tnpc-subject-wrap td[dir=rtl] {
|
85 |
-
text-align: right;
|
86 |
-
}
|
87 |
-
#tnpc-subject-wrap td[dir=rtl] #options-title {
|
88 |
-
margin-right: 0;
|
89 |
-
}
|
90 |
-
|
91 |
-
#tnpc-subject-wrap .composer-actions {
|
92 |
-
position: absolute;
|
93 |
-
right: 10px;
|
94 |
-
bottom: 5px;
|
95 |
-
display: flex;
|
96 |
-
align-items: center;
|
97 |
-
}
|
98 |
-
|
99 |
-
#tnpc-subject-wrap .composer-view-mode {
|
100 |
-
display: flex;
|
101 |
-
}
|
102 |
-
|
103 |
-
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item {
|
104 |
-
display: block;
|
105 |
-
width: 30px;
|
106 |
-
height: 30px;
|
107 |
-
line-height: 30px;
|
108 |
-
box-sizing: content-box;
|
109 |
-
text-align: center;
|
110 |
-
margin-left: 3px;
|
111 |
-
border-radius: 3px;
|
112 |
-
border: solid 1px #3c434a;
|
113 |
-
background-color: #FFF;
|
114 |
-
color: #3c434a;
|
115 |
-
font-size: 12px;
|
116 |
-
cursor: pointer;
|
117 |
-
}
|
118 |
-
|
119 |
-
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item--active {
|
120 |
-
background-color: #2b2f3a;
|
121 |
-
border-color: #2b2f3a;
|
122 |
-
color: #FFF;
|
123 |
-
}
|
124 |
-
|
125 |
-
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item:hover{
|
126 |
-
background-color: #3c434a;
|
127 |
-
border-color: #3c434a;
|
128 |
-
color: #FFF;
|
129 |
-
}
|
130 |
-
|
131 |
-
.composer-actions .button-primary {
|
132 |
-
background-color: #2b2f3a;
|
133 |
-
}
|
134 |
-
|
135 |
-
.composer-actions .button-primary:hover {
|
136 |
-
background-color: #3c434a;
|
137 |
-
}
|
138 |
-
|
139 |
-
#test-newsletter-button {
|
140 |
-
background-color: #2b2f3a;
|
141 |
-
}
|
142 |
-
|
143 |
-
#test-newsletter-button:hover {
|
144 |
-
background-color: #3c434a;
|
145 |
-
}
|
146 |
-
|
147 |
-
#tnpc-subject #options-subject,
|
148 |
-
#options-preheader
|
149 |
-
{
|
150 |
-
width:
|
151 |
-
margin-right: 15px;
|
152 |
-
border: 1px solid #ddd;
|
153 |
-
font-size: 14px;
|
154 |
-
font-family: monospace !important;
|
155 |
-
}
|
156 |
-
|
157 |
-
#options-preheader + .tnp-description
|
158 |
-
{
|
159 |
-
margin-top: 0;
|
160 |
-
}
|
161 |
-
|
162 |
-
#tnpc-subject i {
|
163 |
-
font-size: 18px;
|
164 |
-
}
|
165 |
-
|
166 |
-
.tnp-composer-heading {
|
167 |
-
background-color: #0073aa;
|
168 |
-
border-radius: 3px !important;
|
169 |
-
position: fixed;
|
170 |
-
bottom: 0;
|
171 |
-
right: 0;
|
172 |
-
left: 56px;
|
173 |
-
z-index: 1000;
|
174 |
-
margin: 0 15px 10px 0;
|
175 |
-
}
|
176 |
-
|
177 |
-
.tnp-composer-heading h2 {
|
178 |
-
display: inline-block;
|
179 |
-
margin-left: 30px !important;
|
180 |
-
text-transform: none !important;
|
181 |
-
font-weight: 400 !important;
|
182 |
-
}
|
183 |
-
|
184 |
-
.tnp-composer-heading a {
|
185 |
-
display: inline-block;
|
186 |
-
margin-left: 30px;
|
187 |
-
}
|
188 |
-
|
189 |
-
.tnp-composer-heading form {
|
190 |
-
display: inline-block;
|
191 |
-
margin-left: 30px;
|
192 |
-
}
|
193 |
-
|
194 |
-
.tnp-composer-heading img {
|
195 |
-
width: 50px;
|
196 |
-
vertical-align: middle;
|
197 |
-
}
|
198 |
-
|
199 |
-
#newsletter-builder-sidebar h4 {
|
200 |
-
/* margin: 5px; */
|
201 |
-
/* text-align: center; */
|
202 |
-
color: #868686;
|
203 |
-
/* margin-bottom: 20px; */
|
204 |
-
font-family: Montserrat, sans-serif;
|
205 |
-
font-weight: 300;
|
206 |
-
border-bottom: 1px solid #fff;
|
207 |
-
padding-bottom: 10px;
|
208 |
-
}
|
209 |
-
|
210 |
-
/*#newsletter-builder-sidebar h4 span {
|
211 |
-
background-color: #27AE60;
|
212 |
-
padding: 2px 5px;
|
213 |
-
border-radius: 3px;
|
214 |
-
}*/
|
215 |
-
|
216 |
-
|
217 |
-
#newsletter-builder-sidebar .newsletter-sidebar-add-buttons img {
|
218 |
-
width: 150px;
|
219 |
-
height: auto;
|
220 |
-
}
|
221 |
-
|
222 |
-
.newsletter-sidebar-add-buttons {
|
223 |
-
border-radius: 4px;
|
224 |
-
padding: 5px;
|
225 |
-
margin: 5px;
|
226 |
-
}
|
227 |
-
|
228 |
-
.tnp-body-lite {
|
229 |
-
background-color: #FFFFFF !important;
|
230 |
-
}
|
231 |
-
|
232 |
-
.newsletter-sidebar-buttons-content-tab {
|
233 |
-
margin: 1px;
|
234 |
-
position: relative;
|
235 |
-
display: inline-block;
|
236 |
-
}
|
237 |
-
.newsletter-sidebar-buttons-content-tab:hover {
|
238 |
-
cursor: move;
|
239 |
-
}
|
240 |
-
.newsletter-sidebar-buttons-content-tab:hover img{
|
241 |
-
opacity: 0.8;
|
242 |
-
}
|
243 |
-
.newsletter-sidebar-buttons-content-tab:hover .newsletter-sidebar-buttons-content-tab-add{
|
244 |
-
opacity: 0.5;
|
245 |
-
}
|
246 |
-
.newsletter-sidebar-buttons-content-tab-add {
|
247 |
-
height: 100%;
|
248 |
-
width: 100%;
|
249 |
-
background-color: rgba(70,70,70,1);
|
250 |
-
position: absolute;
|
251 |
-
left: 0;
|
252 |
-
top: 0;
|
253 |
-
/*float: left;*/
|
254 |
-
/*margin-top: -15px;*/
|
255 |
-
/*margin-left: -50px;*/
|
256 |
-
-webkit-transition: all 0.5s;
|
257 |
-
-moz-transition: all 0.5s;
|
258 |
-
-o-transition: all 0.5s;
|
259 |
-
transition: all 0.5s;
|
260 |
-
z-index: 2;
|
261 |
-
opacity: 0;
|
262 |
-
text-align: center;
|
263 |
-
line-height: inherit;
|
264 |
-
color: white;
|
265 |
-
}
|
266 |
-
.newsletter-sidebar-buttons-content-tab-add:hover {
|
267 |
-
background-color: rgba(0,0,0,1);
|
268 |
-
/* cursor: pointer;*/
|
269 |
-
}
|
270 |
-
|
271 |
-
#newsletter-builder-area-center-frame-content {
|
272 |
-
/*float: left;*/
|
273 |
-
/*width: 730px;*/
|
274 |
-
/*background-color: rgba(153,153,153,1);*/
|
275 |
-
min-height: 300px!important;
|
276 |
-
padding-bottom: 75px;
|
277 |
-
/*background-color: #ECF0F1;*/
|
278 |
-
padding-top: 30px;
|
279 |
-
/*border: 1px dashed #eee;*/
|
280 |
-
overflow-y: scroll;
|
281 |
-
/*max-height: 600px;*/
|
282 |
-
}
|
283 |
-
|
284 |
-
/* https://www.codegrepper.com/code-examples/css/how+ot+hide+scroll+bar+buy+allow+mouse+scrolling+css */
|
285 |
-
#newsletter-builder-area-center-frame-content.tnp-view-mobile {
|
286 |
-
margin: 20px auto 0px auto;
|
287 |
-
width: 350px;
|
288 |
-
height: 500px;
|
289 |
-
-ms-overflow-style: none;
|
290 |
-
scrollbar-width: none;
|
291 |
-
border: 1px solid #ddd;
|
292 |
-
border-radius: 10px;
|
293 |
-
padding-top: 0;
|
294 |
-
padding-bottom: 0;
|
295 |
-
}
|
296 |
-
|
297 |
-
#newsletter-builder-area-center-frame-content.tnp-view-mobile::-webkit-scrollbar {
|
298 |
-
display: none;
|
299 |
-
}
|
300 |
-
|
301 |
-
#newsletter-builder-area-center-frame-content p {
|
302 |
-
font-size: inherit;
|
303 |
-
font-weight: inherit;
|
304 |
-
font-family: inherit;
|
305 |
-
color: inherit;
|
306 |
-
}
|
307 |
-
|
308 |
-
#newsletter-mobile-preview-area {
|
309 |
-
margin-left: 30px;
|
310 |
-
box-sizing: border-box;
|
311 |
-
margin-top: 30px;
|
312 |
-
text-align: center;
|
313 |
-
border: 1px solid #ddd;
|
314 |
-
border-radius: 10px;
|
315 |
-
padding-left: 10px;
|
316 |
-
padding-right: 10px;
|
317 |
-
padding-top: 10px;
|
318 |
-
}
|
319 |
-
#newsletter-mobile-preview-area input {
|
320 |
-
width: 100px;
|
321 |
-
}
|
322 |
-
|
323 |
-
iframe#tnpc-mobile-preview {
|
324 |
-
height: 550px;
|
325 |
-
box-sizing: border-box;
|
326 |
-
width: 320px;
|
327 |
-
border-radius: 10px;
|
328 |
-
margin-top: 20px;
|
329 |
-
margin-left: 20px;
|
330 |
-
background-color: #F6F8FD;
|
331 |
-
}
|
332 |
-
|
333 |
-
|
334 |
-
.tnpc-row {
|
335 |
-
-webkit-transition: box-shadow 0.5s;
|
336 |
-
-moz-transition: box-shadow 0.5s;
|
337 |
-
-o-transition: box-shadow 0.5s;
|
338 |
-
transition: box-shadow 0.5s;
|
339 |
-
position: relative;
|
340 |
-
}
|
341 |
-
.tnpc-row:hover {
|
342 |
-
cursor: move;
|
343 |
-
/*border: 2px dashed #999;*/
|
344 |
-
-webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
345 |
-
-moz-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
346 |
-
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
347 |
-
}
|
348 |
-
.tnpc-row.ui-sortable-helper {
|
349 |
-
max-width: 700px!important;
|
350 |
-
}
|
351 |
-
.tnpc-row-delete, .tnpc-row-edit-block, .tnpc-row-clone {
|
352 |
-
height: 30px;
|
353 |
-
width: 30px;
|
354 |
-
top: 0px;
|
355 |
-
background-color: rgba(255,255,255,0.5);
|
356 |
-
z-index: 5;
|
357 |
-
position: absolute;
|
358 |
-
color: rgba(102,102,102,1);
|
359 |
-
-webkit-transition: all 0.5s;
|
360 |
-
-moz-transition: all 0.5s;
|
361 |
-
-o-transition: all 0.5s;
|
362 |
-
transition: all 0.5s;
|
363 |
-
opacity: 0;
|
364 |
-
text-align: center;
|
365 |
-
font-size: 18px;
|
366 |
-
}
|
367 |
-
.tnpc-row-delete i, .tnpc-row-edit-block i, .tnpc-row-clone i {
|
368 |
-
line-height: 30px;
|
369 |
-
}
|
370 |
-
.tnpc-row-delete:hover {
|
371 |
-
background-color: #E74C3C;
|
372 |
-
cursor: pointer;
|
373 |
-
color: rgba(255,255,255,1);
|
374 |
-
}
|
375 |
-
.tnpc-row:hover .tnpc-row-delete, .tnpc-row:hover .tnpc-row-edit-block, .tnpc-row:hover .tnpc-row-clone {
|
376 |
-
opacity: 1;
|
377 |
-
}
|
378 |
-
.tnpc-row-delete {
|
379 |
-
right: 0px;
|
380 |
-
z-index: 5;
|
381 |
-
}
|
382 |
-
.tnpc-row-edit-block {
|
383 |
-
right: 60px;
|
384 |
-
}
|
385 |
-
.tnpc-row-edit-block:hover {
|
386 |
-
background-color: #e0e0e0;
|
387 |
-
cursor: pointer;
|
388 |
-
color: rgba(0, 0, 0, 1);
|
389 |
-
}
|
390 |
-
|
391 |
-
.tnpc-row-clone {
|
392 |
-
right: 30px;
|
393 |
-
}
|
394 |
-
.tnpc-row-clone:hover {
|
395 |
-
background-color: #e0e0e0;;
|
396 |
-
cursor: pointer;
|
397 |
-
color: rgba(0,0,0,1);
|
398 |
-
}
|
399 |
-
|
400 |
-
.tnpc-row-edit {
|
401 |
-
position: relative;
|
402 |
-
}
|
403 |
-
.tnpc-row-edit-hover {
|
404 |
-
height: 100%;
|
405 |
-
width: 100%;
|
406 |
-
background-color: rgba(63,141,191,0.8);
|
407 |
-
position: absolute;
|
408 |
-
left: 0px;
|
409 |
-
top: 0px;
|
410 |
-
cursor: default;
|
411 |
-
-webkit-transition: all 0.5s;
|
412 |
-
-moz-transition: all 0.5s;
|
413 |
-
-o-transition: all 0.5s;
|
414 |
-
transition: all 0.5s;
|
415 |
-
}
|
416 |
-
.tnpc-row-edit-hover i {
|
417 |
-
position: absolute;
|
418 |
-
height: 30px;
|
419 |
-
width: 30px;
|
420 |
-
line-height: 30px;
|
421 |
-
left: 50%;
|
422 |
-
top: 50%;
|
423 |
-
text-align: center;
|
424 |
-
margin-top: -15px;
|
425 |
-
margin-left: -15px;
|
426 |
-
color: rgba(255,255,255,1);
|
427 |
-
-webkit-transition: all 0.5s;
|
428 |
-
-moz-transition: all 0.5s;
|
429 |
-
-o-transition: all 0.5s;
|
430 |
-
transition: all 0.5s;
|
431 |
-
-webkit-border-radius: 50%;
|
432 |
-
-moz-border-radius: 50%;
|
433 |
-
border-radius: 50%;
|
434 |
-
font-size: 16px;
|
435 |
-
}
|
436 |
-
.tnpc-row-edit-hover i:hover {
|
437 |
-
background-color: rgba(0,0,0,0.5);
|
438 |
-
cursor: pointer;
|
439 |
-
}
|
440 |
-
|
441 |
-
.tnpc-drop-here {
|
442 |
-
padding:10px;
|
443 |
-
text-align: center;
|
444 |
-
}
|
445 |
-
|
446 |
-
.tnpc-edit {
|
447 |
-
height: 100vh;
|
448 |
-
width: 100vw;
|
449 |
-
z-index: 10;
|
450 |
-
display: none;
|
451 |
-
position: absolute;
|
452 |
-
top: 0px;
|
453 |
-
left: 0px;
|
454 |
-
}
|
455 |
-
|
456 |
-
.tnpc-edit-box-title {
|
457 |
-
/*float: left;*/
|
458 |
-
width: 100%;
|
459 |
-
font-size: 29px;
|
460 |
-
color: #666666;
|
461 |
-
font-weight: 300;
|
462 |
-
margin-bottom: 40px;
|
463 |
-
}
|
464 |
-
|
465 |
-
.tnpc-edit-box-content {
|
466 |
-
/*float: left;*/
|
467 |
-
width: 100%;
|
468 |
-
margin-top: 10px;
|
469 |
-
}
|
470 |
-
.tnpc-edit-box-content-text {
|
471 |
-
/*float: left;*/
|
472 |
-
width: 100%;
|
473 |
-
font-size: 15px;
|
474 |
-
color: #666666;
|
475 |
-
font-weight: 600;
|
476 |
-
margin: 15px 0px 10px;
|
477 |
-
text-transform: uppercase;
|
478 |
-
}
|
479 |
-
|
480 |
-
.tnpc-edit-box-content-text span {
|
481 |
-
font-size: 11px;
|
482 |
-
color: #95A5A6;
|
483 |
-
background-color: #D3EADC;
|
484 |
-
padding: 2px 5px;
|
485 |
-
text-transform: none;
|
486 |
-
border-radius: 5px;
|
487 |
-
}
|
488 |
-
|
489 |
-
.tnpc-edit-box-content-field {
|
490 |
-
/*float: left;*/
|
491 |
-
width: 100%;
|
492 |
-
}
|
493 |
-
|
494 |
-
.tnpc-edit-box-content-field-input {
|
495 |
-
height: 33px;
|
496 |
-
width: 380px;
|
497 |
-
border: none !important;
|
498 |
-
outline: none;
|
499 |
-
font-family: inherit;
|
500 |
-
padding-right: 10px;
|
501 |
-
font-size: 15px;
|
502 |
-
-webkit-transition: all 0.5s;
|
503 |
-
-moz-transition: all 0.5s;
|
504 |
-
-o-transition: all 0.5s;
|
505 |
-
transition: all 0.5s;
|
506 |
-
color: rgba(102,102,102,1);
|
507 |
-
margin-bottom: 10px;
|
508 |
-
}
|
509 |
-
.tnpc-edit-box-content-field-input:focus {
|
510 |
-
-webkit-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
511 |
-
-moz-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
512 |
-
box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
513 |
-
}
|
514 |
-
.tnpc-edit-box-content-field-textarea {
|
515 |
-
/*float: left;*/
|
516 |
-
height: 180px;
|
517 |
-
width: 380px;
|
518 |
-
border: 1px solid rgba(204,204,204,1);
|
519 |
-
outline: none;
|
520 |
-
font-family: inherit;
|
521 |
-
font-size: 15px;
|
522 |
-
-webkit-transition: all 0.5s;
|
523 |
-
-moz-transition: all 0.5s;
|
524 |
-
-o-transition: all 0.5s;
|
525 |
-
transition: all 0.5s;
|
526 |
-
color: rgba(102,102,102,1);
|
527 |
-
resize: none;
|
528 |
-
padding: 10px;
|
529 |
-
}
|
530 |
-
.tnpc-edit-box-content-field-textarea:focus {
|
531 |
-
-webkit-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
532 |
-
-moz-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
533 |
-
box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
534 |
-
}
|
535 |
-
.tnpc-edit-box-content-icons {
|
536 |
-
/*float: left;*/
|
537 |
-
height: 388px;
|
538 |
-
width: 388px;
|
539 |
-
border: 1px solid rgba(204,204,204,1);
|
540 |
-
margin-top: 15px;
|
541 |
-
overflow-y: scroll;
|
542 |
-
}
|
543 |
-
.tnpc-edit-box-content-icons i {
|
544 |
-
line-height: 50px;
|
545 |
-
background-color: rgba(225,225,225,1);
|
546 |
-
/*float: left;*/
|
547 |
-
height: 50px;
|
548 |
-
width: 50px;
|
549 |
-
margin-top: 10px;
|
550 |
-
margin-left: 10px;
|
551 |
-
text-align: center;
|
552 |
-
-webkit-transition: all 0.5s;
|
553 |
-
-moz-transition: all 0.5s;
|
554 |
-
-o-transition: all 0.5s;
|
555 |
-
transition: all 0.5s;
|
556 |
-
font-size: 28px;
|
557 |
-
color: rgba(51,51,51,1);
|
558 |
-
}
|
559 |
-
.tnpc-edit-box-content-icons i:hover {
|
560 |
-
cursor: pointer;
|
561 |
-
background-color: rgba(153,153,153,1);
|
562 |
-
-webkit-border-radius: 50%;
|
563 |
-
-moz-border-radius: 50%;
|
564 |
-
border-radius: 50%;
|
565 |
-
color: rgba(0,0,0,1);
|
566 |
-
}
|
567 |
-
|
568 |
-
/* Save and cancel buttons container on block options popup */
|
569 |
-
.tnpc-edit-box-buttons{
|
570 |
-
margin-top: 10px;
|
571 |
-
text-align: right;
|
572 |
-
margin-right: 10px;
|
573 |
-
}
|
574 |
-
|
575 |
-
.tnpc-edit-box-buttons-save{
|
576 |
-
height: 35px;
|
577 |
-
text-align: right;
|
578 |
-
line-height: 35px;
|
579 |
-
color: #27AE60;
|
580 |
-
font-weight: 600;
|
581 |
-
font-size: 15px;
|
582 |
-
-webkit-border-radius: 3px;
|
583 |
-
-moz-border-radius: 3px;
|
584 |
-
border-radius: 3px;
|
585 |
-
-webkit-transition: background 0.5s;
|
586 |
-
-moz-transition: background 0.5s;
|
587 |
-
-o-transition: background 0.5s;
|
588 |
-
transition: background 0.5s;
|
589 |
-
cursor: pointer;
|
590 |
-
/*float: left;*/
|
591 |
-
/*padding-right: 25px;
|
592 |
-
padding-left: 25px;
|
593 |
-
width: 33%;*/
|
594 |
-
display: inline-block;
|
595 |
-
}
|
596 |
-
.tnpc-edit-box-buttons-save:hover {
|
597 |
-
color: #2ECC71;
|
598 |
-
}
|
599 |
-
.tnpc-edit-box-buttons-cancel{
|
600 |
-
height: 35px;
|
601 |
-
text-align: right;
|
602 |
-
line-height: 35px;
|
603 |
-
color: #666;
|
604 |
-
font-weight: normal;
|
605 |
-
font-size: 15px;
|
606 |
-
-webkit-border-radius: 3px;
|
607 |
-
-moz-border-radius: 3px;
|
608 |
-
border-radius: 3px;
|
609 |
-
-webkit-transition: background 0.5s;
|
610 |
-
-moz-transition: background 0.5s;
|
611 |
-
-o-transition: background 0.5s;
|
612 |
-
transition: background 0.5s;
|
613 |
-
cursor: pointer;
|
614 |
-
/*float: left;*/
|
615 |
-
/*padding-right: 25px;
|
616 |
-
padding-left: 25px;
|
617 |
-
width: 33%;*/
|
618 |
-
display: inline-block;
|
619 |
-
margin-right: 25px;
|
620 |
-
}
|
621 |
-
.tnpc-edit-box-buttons-cancel:hover {
|
622 |
-
color: #E74C3C;
|
623 |
-
}
|
624 |
-
|
625 |
-
|
626 |
-
/* Tnp Composer Preview */
|
627 |
-
|
628 |
-
|
629 |
-
.tnpc-subject a {
|
630 |
-
font-family: Source Sans Pro;
|
631 |
-
font-weight: 700;
|
632 |
-
text-transform: uppercase;
|
633 |
-
text-decoration: none;
|
634 |
-
background-color: #3498DB;
|
635 |
-
color: white;
|
636 |
-
padding: 2px 10px;
|
637 |
-
border-radius: 10px;
|
638 |
-
font-size: 13px;
|
639 |
-
letter-spacing: 0.1em;
|
640 |
-
}
|
641 |
-
|
642 |
-
|
643 |
-
.tnpc-preview {
|
644 |
-
margin-top: 10px;
|
645 |
-
}
|
646 |
-
|
647 |
-
.tnpc-preview .fake-browser-ui iframe {
|
648 |
-
width: 700px;
|
649 |
-
}
|
650 |
-
|
651 |
-
.tnpc-preview .fake-mobile-browser-ui iframe {
|
652 |
-
width: 320px;
|
653 |
-
}
|
654 |
-
|
655 |
-
.fake-browser-ui {
|
656 |
-
padding: 30px 0 0;
|
657 |
-
border-radius: 3px;
|
658 |
-
border-bottom: 10px solid #ccc;
|
659 |
-
background: #ddd;
|
660 |
-
display: inline-block;
|
661 |
-
position: relative;
|
662 |
-
line-height: 0;
|
663 |
-
vertical-align: top;
|
664 |
-
margin-left: 20px;
|
665 |
-
}
|
666 |
-
|
667 |
-
.fake-mobile-browser-ui {
|
668 |
-
padding: 30px 10px 37px;
|
669 |
-
border-radius: 10px;
|
670 |
-
border-bottom: 10px solid #ccc;
|
671 |
-
background: #ddd;
|
672 |
-
display: inline-block;
|
673 |
-
position: relative;
|
674 |
-
line-height: 0;
|
675 |
-
margin-left: 30px;
|
676 |
-
}
|
677 |
-
|
678 |
-
.fake-browser-ui .frame {
|
679 |
-
display: block;
|
680 |
-
height: 25px;
|
681 |
-
position: absolute;
|
682 |
-
top: 12px;
|
683 |
-
left: 8px;
|
684 |
-
}
|
685 |
-
|
686 |
-
.fake-mobile-browser-ui .frame {
|
687 |
-
display: block;
|
688 |
-
height: 25px;
|
689 |
-
margin-top: 10px;
|
690 |
-
}
|
691 |
-
|
692 |
-
.fake-browser-ui span {
|
693 |
-
height: 12px;
|
694 |
-
width: 12px;
|
695 |
-
border-radius: 8px;
|
696 |
-
background-color: #eee;
|
697 |
-
border: 1px solid #dadada;
|
698 |
-
float: left;
|
699 |
-
margin: 0 0 0 4px;
|
700 |
-
}
|
701 |
-
|
702 |
-
.fake-mobile-browser-ui span {
|
703 |
-
height: 50px;
|
704 |
-
width: 50px;
|
705 |
-
border-radius: 60px;
|
706 |
-
background-color: #eee;
|
707 |
-
border: 2px solid #ccc;
|
708 |
-
display: block;
|
709 |
-
margin: auto;
|
710 |
-
}
|
711 |
-
|
712 |
-
.fake-browser-ui .bt-1 {
|
713 |
-
background-color: #ED594A;
|
714 |
-
}
|
715 |
-
|
716 |
-
.fake-browser-ui .bt-2 {
|
717 |
-
background-color: #FDD800;
|
718 |
-
}
|
719 |
-
|
720 |
-
.fake-browser-ui .bt-3 {
|
721 |
-
background-color: #5AC05A;
|
722 |
-
}
|
723 |
-
|
724 |
-
|
725 |
-
/* Tnp Html Editor */
|
726 |
-
|
727 |
-
#tnpc-html-editor {
|
728 |
-
height: 600px;
|
729 |
-
border-top: 20px solid #323232;
|
730 |
-
border-radius: 8px;
|
731 |
-
}
|
732 |
-
|
733 |
-
/* List Block Styles */ *
|
734 |
-
|
735 |
-
.tnp-select2-option {
|
736 |
-
/* background-color: red; */
|
737 |
-
}
|
738 |
-
|
739 |
-
.tnp-select2-option img {
|
740 |
-
height: 15px;
|
741 |
-
margin-right: 5px;
|
742 |
-
vertical-align: middle;
|
743 |
-
background-color: rgba(234, 234, 234, 0.25);
|
744 |
-
padding: 10px;
|
745 |
-
border-radius: 5px;
|
746 |
-
}
|
747 |
-
|
748 |
-
/* ************************************************************************** */
|
749 |
-
/* Block options layer over the sidebar */
|
750 |
-
|
751 |
-
/* Main container */
|
752 |
-
#tnpc-block-options {
|
753 |
-
/*height: 100vh;*/
|
754 |
-
z-index: 10;
|
755 |
-
flex-flow: column;
|
756 |
-
display: none;
|
757 |
-
position: absolute;
|
758 |
-
top: 0px;
|
759 |
-
left: 0px;
|
760 |
-
bottom: 0;
|
761 |
-
right: 0;
|
762 |
-
background-color: #ECF0F1;
|
763 |
-
padding: 0;
|
764 |
-
}
|
765 |
-
|
766 |
-
/* Save and cancel button container */
|
767 |
-
#tnpc-block-options-buttons {
|
768 |
-
padding: 20px;
|
769 |
-
text-align: right;
|
770 |
-
background-color: #ecf0f1;
|
771 |
-
height: 70px;
|
772 |
-
border-bottom: 1px solid #ffffff;
|
773 |
-
}
|
774 |
-
|
775 |
-
|
776 |
-
/* Form */
|
777 |
-
#tnpc-block-options-form {
|
778 |
-
background-color: #fff;
|
779 |
-
padding: 15px;
|
780 |
-
margin-top: 0;
|
781 |
-
color: #444;
|
782 |
-
background-color: #ECF0F1 !important;
|
783 |
-
flex: 1 1 auto;
|
784 |
-
overflow-y: auto;
|
785 |
-
}
|
786 |
-
|
787 |
-
|
788 |
-
#tnpc-block-options-form h3 {
|
789 |
-
color: #000;
|
790 |
-
}
|
791 |
-
|
792 |
-
#tnpc-block-options-form table.form-table th {
|
793 |
-
/*background-color: #f4f4f4;*/
|
794 |
-
width: 100%;
|
795 |
-
vertical-align: top;
|
796 |
-
float: left;
|
797 |
-
font-weight: normal;
|
798 |
-
text-transform: uppercase;
|
799 |
-
font-size: 13px;
|
800 |
-
padding-top: 10px;
|
801 |
-
padding-bottom: 5px;
|
802 |
-
padding-left: 0;
|
803 |
-
padding-right: 0;
|
804 |
-
|
805 |
-
}
|
806 |
-
|
807 |
-
#tnpc-block-options-form table.form-table td {
|
808 |
-
float: left;
|
809 |
-
padding: 0;
|
810 |
-
margin: 0;
|
811 |
-
border: 0;
|
812 |
-
width: 100%;
|
813 |
-
}
|
814 |
-
|
815 |
-
#tnpc-block-options-form table.form-table {
|
816 |
-
margin: 0px;
|
817 |
-
border-collapse: separate!important;
|
818 |
-
border-spacing: 1px!important;
|
819 |
-
}
|
820 |
-
|
821 |
-
#tnpc-block-options-form table.form-table table.tnp-button-colors {
|
822 |
-
border: 0;
|
823 |
-
border-collapse: collapse;
|
824 |
-
}
|
825 |
-
#tnpc-block-options-form table.form-table table.tnp-button-colors td {
|
826 |
-
border: 0;
|
827 |
-
padding-top: 0;
|
828 |
-
}
|
829 |
-
|
830 |
-
/* Style the tab */
|
831 |
-
.tnpc-tabs {
|
832 |
-
/*overflow: hidden;*/
|
833 |
-
background-color: #fff;
|
834 |
-
font-family: Montserrat, sans-serif;
|
835 |
-
}
|
836 |
-
|
837 |
-
/* Style the buttons that are used to open the tab content */
|
838 |
-
.tnpc-tabs button {
|
839 |
-
background-color: inherit;
|
840 |
-
float: left;
|
841 |
-
border: none;
|
842 |
-
outline: none;
|
843 |
-
cursor: pointer;
|
844 |
-
padding: 14px 16px;
|
845 |
-
transition: 0.3s;
|
846 |
-
color: #6a8ba0;
|
847 |
-
}
|
848 |
-
|
849 |
-
/* Change background color of buttons on hover */
|
850 |
-
.tnpc-tabs button:hover {
|
851 |
-
background-color: #ddd;
|
852 |
-
}
|
853 |
-
|
854 |
-
/* Create an active/current tablink class */
|
855 |
-
.tnpc-tabs button.active {
|
856 |
-
background-color: #ECF0F1;
|
857 |
-
color: #3498DB;
|
858 |
-
}
|
859 |
-
|
860 |
-
/* Style the tab content */
|
861 |
-
.tabcontent {
|
862 |
-
display: none;
|
863 |
-
padding: 6px 12px;
|
864 |
-
border-top: none;
|
865 |
-
flex: 1 1 auto;
|
866 |
-
overflow-y: auto;
|
867 |
-
}
|
868 |
-
|
869 |
-
/* Style Reset, Save, Save & Preview footer */
|
870 |
-
|
871 |
-
.tnpc-controls {
|
872 |
-
text-align: right;
|
873 |
-
}
|
874 |
-
|
875 |
-
.tnpc-logo {
|
876 |
-
float: left;
|
877 |
-
}
|
878 |
-
|
879 |
-
.tnpc-logo p {
|
880 |
-
font-family: Montserrat, Sans-serif;
|
881 |
-
color: #fff !important;
|
882 |
-
font-size: 16px;
|
883 |
-
margin-left: 20px !important;
|
884 |
-
margin-top: 5px !important;
|
885 |
-
}
|
886 |
-
|
887 |
-
#newsletter-builder-area ul {
|
888 |
-
display: block;
|
889 |
-
list-style-type: disc;
|
890 |
-
margin-block-start: 1em;
|
891 |
-
margin-block-end: 1em;
|
892 |
-
margin-inline-start: 0;
|
893 |
-
margin-inline-end: 0;
|
894 |
-
padding-inline-start: 40px;
|
895 |
-
}
|
896 |
-
|
897 |
-
#newsletter-builder-area ul li {
|
898 |
-
margin-bottom: 0;
|
899 |
-
}
|
900 |
-
|
901 |
-
/* Global Options elements style */
|
902 |
-
|
903 |
-
#tnpc-general-options select {
|
904 |
-
box-shadow: none;
|
905 |
-
border-radius: 0px;
|
906 |
-
border: none;
|
907 |
-
margin-right: 5px;
|
908 |
-
}
|
909 |
-
|
910 |
-
/* Blocks options global styles */
|
911 |
-
|
912 |
-
.tnpc-block-options-warning {
|
913 |
-
background-color: #def9e9;
|
914 |
-
padding: 10px 15px;
|
915 |
-
}
|
916 |
-
|
917 |
-
/* Presets */
|
918 |
-
.tnpc-preset-container {
|
919 |
-
max-width: 720px;
|
920 |
-
margin: 0 auto;
|
921 |
-
position: relative;
|
922 |
-
}
|
923 |
-
|
924 |
-
.tnpc-preset-legacy-themes {
|
925 |
-
position: absolute;
|
926 |
-
top: -15px;
|
927 |
-
left: 15px;
|
928 |
-
}
|
929 |
-
|
930 |
-
|
931 |
-
.tnpc-preset {
|
932 |
-
float: left;
|
933 |
-
margin: 15px;
|
934 |
-
cursor: pointer;
|
935 |
-
width: 150px;
|
936 |
-
height: 200px;
|
937 |
-
background: white;
|
938 |
-
border-radius: 8px;
|
939 |
-
box-shadow: 0 0 2px 0 #dee3e4;
|
940 |
-
position: relative;
|
941 |
-
text-align: center;
|
942 |
-
}
|
943 |
-
|
944 |
-
.tnpc-preset-html {
|
945 |
-
background-color: #5397d5;
|
946 |
-
}
|
947 |
-
|
948 |
-
.tnpc-preset-html span {
|
949 |
-
color: #fff;
|
950 |
-
}
|
951 |
-
|
952 |
-
.tnpc-preset:hover {
|
953 |
-
box-shadow: 0 0 8px 8px #dee3e4;
|
954 |
-
}
|
955 |
-
|
956 |
-
.tnpc-preset img {
|
957 |
-
width: 50px;
|
958 |
-
height: 50px;
|
959 |
-
margin-top: 50px;
|
960 |
-
}
|
961 |
-
|
962 |
-
.tnpc-preset-label {
|
963 |
-
position: absolute;
|
964 |
-
top: 150px;
|
965 |
-
left: 50%;
|
966 |
-
transform: translate(-50%, -50%);
|
967 |
-
font-size: 14px;
|
968 |
-
width: 80%;
|
969 |
-
font-family: soleil, sans-serif;
|
970 |
-
color: #2f3241;
|
971 |
-
font-weight: 200;
|
972 |
-
}
|
973 |
-
|
974 |
-
.tnpc-delete-preset {
|
975 |
-
position: absolute;
|
976 |
-
top: 0;
|
977 |
-
right: 0;
|
978 |
-
display: flex;
|
979 |
-
align-items: center;
|
980 |
-
justify-content: center;
|
981 |
-
width: 20px;
|
982 |
-
height: 20px;
|
983 |
-
background-color: #8B0000;
|
984 |
-
color: #FFF;
|
985 |
-
font-weight: bold;
|
986 |
-
border-radius: 0 8px 0 8px;
|
987 |
-
z-index: 100;
|
988 |
-
}
|
989 |
-
|
990 |
-
.tnpc-edit-preset {
|
991 |
-
position: absolute;
|
992 |
-
top: 0;
|
993 |
-
left: 0;
|
994 |
-
display: flex;
|
995 |
-
align-items: center;
|
996 |
-
justify-content: center;
|
997 |
-
width: 20px;
|
998 |
-
height: 20px;
|
999 |
-
background-color: #3498DB;
|
1000 |
-
color: #FFF;
|
1001 |
-
font-weight: bold;
|
1002 |
-
border-radius: 8px 0 8px 0;
|
1003 |
-
z-index: 100;
|
1004 |
-
}
|
1005 |
-
|
1006 |
-
.tnpc-inline-editable {
|
1007 |
-
cursor: text;
|
1008 |
-
}
|
1009 |
-
|
1010 |
-
.tnpc-inline-editable {
|
1011 |
-
cursor: text;
|
1012 |
-
position: relative;
|
1013 |
-
}
|
1014 |
-
|
1015 |
-
.tnpc-inline-editable:hover {
|
1016 |
-
color: #EEE !important;
|
1017 |
-
}
|
1018 |
-
|
1019 |
-
.tnpc-inline-editable:hover:after {
|
1020 |
-
content: '';
|
1021 |
-
cursor: pointer;
|
1022 |
-
position: absolute;
|
1023 |
-
top: 0;
|
1024 |
-
left: 0;
|
1025 |
-
width: 100%;
|
1026 |
-
height: 100%;
|
1027 |
-
background-color: rgba(0, 0, 0, 0.2);
|
1028 |
-
opacity: 1;
|
1029 |
-
border-radius: 2px;
|
1030 |
-
}
|
1031 |
-
|
1032 |
-
.tnpc-inline-editable:hover:before {
|
1033 |
-
content: '\f464';
|
1034 |
-
font-family: dashicons;
|
1035 |
-
position: absolute;
|
1036 |
-
top: 0;
|
1037 |
-
bottom: 0;
|
1038 |
-
left: 0;
|
1039 |
-
right: 0;
|
1040 |
-
margin: auto;
|
1041 |
-
width: 32px;
|
1042 |
-
height: 32px;
|
1043 |
-
font-size: 32px;
|
1044 |
-
line-height: 32px;
|
1045 |
-
color: #333;
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
.tnpc-inline-editable-form {
|
1049 |
-
position: relative;
|
1050 |
-
margin-top: 25px;
|
1051 |
-
}
|
1052 |
-
|
1053 |
-
.tnpc-inline-editable-form textarea,
|
1054 |
-
.tnpc-inline-editable-form input {
|
1055 |
-
width: 95%;
|
1056 |
-
margin-left: 20px;
|
1057 |
-
}
|
1058 |
-
|
1059 |
-
.two-columns .tnpc-inline-editable-form-actions {
|
1060 |
-
right: 0;
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
.tnpc-inline-editable-form input {
|
1064 |
-
padding: 5px;
|
1065 |
-
font-size: 25px;
|
1066 |
-
font-family: Helvetica, Arial, sans-serif;
|
1067 |
-
font-weight: normal;
|
1068 |
-
color: rgb(51, 51, 51);
|
1069 |
-
line-height: normal;
|
1070 |
-
}
|
1071 |
-
|
1072 |
-
.tnpc-inline-editable-form-actions {
|
1073 |
-
position: absolute;
|
1074 |
-
top: -25px;
|
1075 |
-
right: 5px;
|
1076 |
-
display: flex;
|
1077 |
-
align-items: center;
|
1078 |
-
flex-wrap: wrap;
|
1079 |
-
}
|
1080 |
-
|
1081 |
-
.tnpc-inline-editable-form-actions button {
|
1082 |
-
background: none;
|
1083 |
-
padding: 0;
|
1084 |
-
border: none;
|
1085 |
-
}
|
1086 |
-
|
1087 |
-
.tnpc-inline-editable-form-actions span {
|
1088 |
-
display: block;
|
1089 |
-
font-size: 25px;
|
1090 |
-
color: #333;
|
1091 |
-
cursor: pointer;
|
1092 |
-
}
|
1093 |
-
|
1094 |
-
.tnpc-inline-editable-form-actions span:first-child {
|
1095 |
-
margin-right: 5px;
|
1096 |
-
}
|
1097 |
-
|
1098 |
-
#update-preset-button {
|
1099 |
-
display: none;
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
.separator {
|
1103 |
-
display: flex;
|
1104 |
-
align-items: center;
|
1105 |
-
text-align: center;
|
1106 |
-
padding: 1em 0;
|
1107 |
-
}
|
1108 |
-
|
1109 |
-
.separator::before,
|
1110 |
-
.separator::after {
|
1111 |
-
content: '';
|
1112 |
-
flex: 1;
|
1113 |
-
border-bottom: 1px solid #3c434a;
|
1114 |
-
}
|
1115 |
-
|
1116 |
-
.separator:not(:empty)::before {
|
1117 |
-
margin-right: 1em;
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
.separator:not(:empty)::after {
|
1121 |
-
margin-left: 1em;
|
1122 |
-
}
|
1123 |
-
|
1124 |
-
#test-newsletter-modal .test-subscribers p {
|
1125 |
-
margin: 0;
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
#test-newsletter-modal h4 {
|
1129 |
-
margin: 0 0 0.5rem 0;
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
#test-newsletter-modal .separator {
|
1133 |
-
padding: 1.25rem 0;
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
|
1137 |
-
.tnp-suggest-subject {
|
1138 |
-
cursor: pointer;
|
1139 |
-
}
|
1140 |
-
|
1141 |
-
/* Drag and drop placeholder */
|
1142 |
-
.placeholder {
|
1143 |
-
border: 1px dashed #bbb!important;
|
1144 |
-
background-color: #fafafa!important;
|
1145 |
-
height: 75px;
|
1146 |
-
margin: 0 auto;
|
1147 |
-
max-width: 600px;
|
1148 |
-
box-sizing: border-box!important;
|
1149 |
-
}
|
1150 |
-
|
1151 |
-
#draggable-helper {
|
1152 |
-
width: 600px;
|
1153 |
-
border: 1px dashed #ddd;
|
1154 |
-
opacity: 80%!important;
|
1155 |
-
background-color: #fff;
|
1156 |
-
text-align: center;
|
1157 |
-
text-transform: uppercase;
|
1158 |
-
font-size: 14px;
|
1159 |
-
color: #666 !important;
|
1160 |
-
padding: 20px;
|
1161 |
-
}
|
1162 |
-
|
1163 |
-
#sortable-helper {
|
1164 |
-
width: 700px;
|
1165 |
-
height: 75px;
|
1166 |
-
border: 3px dashed #ddd;
|
1167 |
-
opacity: .7;
|
1168 |
-
background-color: #fff;
|
1169 |
-
text-align: center;
|
1170 |
-
text-transform: uppercase;
|
1171 |
-
font-size: 14px; color: #aaa;
|
1172 |
-
padding: 20px;
|
1173 |
-
}
|
1 |
+
#wpbody-content {
|
2 |
+
padding-bottom: 15px;
|
3 |
+
}
|
4 |
+
|
5 |
+
.tnp-emails-composer {
|
6 |
+
margin: 15px 15px 0 0;
|
7 |
+
}
|
8 |
+
|
9 |
+
|
10 |
+
/* Contains the newsletter editing area and the tools */
|
11 |
+
#newsletter-builder {
|
12 |
+
height: calc(100vh - 120px);
|
13 |
+
display: flex;
|
14 |
+
flex-flow: row;
|
15 |
+
position: relative;
|
16 |
+
overflow: hidden;
|
17 |
+
box-sizing: border-box;
|
18 |
+
max-width: 1380px;
|
19 |
+
margin: 0 auto;
|
20 |
+
}
|
21 |
+
|
22 |
+
/* Contains the newsletter editing area */
|
23 |
+
#newsletter-builder-area {
|
24 |
+
display: flex;
|
25 |
+
flex-flow: column;
|
26 |
+
flex-shrink: 0;
|
27 |
+
background-color: #fff;
|
28 |
+
width: 800px;
|
29 |
+
box-sizing: border-box;
|
30 |
+
border-radius: 3px;
|
31 |
+
overflow: hidden;
|
32 |
+
float: left;
|
33 |
+
|
34 |
+
position: relative;
|
35 |
+
}
|
36 |
+
|
37 |
+
/* Contains the tools */
|
38 |
+
#newsletter-builder-sidebar {
|
39 |
+
display: flex;
|
40 |
+
flex-flow: column;
|
41 |
+
/* flex-grow: 1;*/
|
42 |
+
max-width: 510px;
|
43 |
+
min-width: 410px;
|
44 |
+
background-color: #ECF0F1;
|
45 |
+
margin-left: 20px;
|
46 |
+
overflow-y: scroll;
|
47 |
+
/* Needed for block options form */
|
48 |
+
position: relative;
|
49 |
+
border-radius: 3px;
|
50 |
+
overflow: hidden;
|
51 |
+
}
|
52 |
+
|
53 |
+
#tnpc-subject-wrap {
|
54 |
+
border-bottom: 1px solid #ccc;
|
55 |
+
padding-bottom: 20px;
|
56 |
+
padding-top: 20px;
|
57 |
+
padding-left: 20px;
|
58 |
+
position:relative;
|
59 |
+
}
|
60 |
+
|
61 |
+
#tnpc-subject-wrap th {
|
62 |
+
color: #999;
|
63 |
+
font-size: 14px;
|
64 |
+
font-weight: normal!important;
|
65 |
+
text-align: right;
|
66 |
+
padding-right: 10px;
|
67 |
+
padding-bottom: 10px;
|
68 |
+
vertical-align: middle;
|
69 |
+
}
|
70 |
+
|
71 |
+
#tnpc-subject-wrap td {
|
72 |
+
color: #000;
|
73 |
+
font-size: 14px;
|
74 |
+
font-weight: normal!important;
|
75 |
+
text-align: left;
|
76 |
+
padding-right: 10px;
|
77 |
+
padding-bottom: 10px;
|
78 |
+
vertical-align: middle;
|
79 |
+
}
|
80 |
+
|
81 |
+
#tnpc-subject-wrap th[dir=rtl] {
|
82 |
+
text-align: left;
|
83 |
+
}
|
84 |
+
#tnpc-subject-wrap td[dir=rtl] {
|
85 |
+
text-align: right;
|
86 |
+
}
|
87 |
+
#tnpc-subject-wrap td[dir=rtl] #options-title {
|
88 |
+
margin-right: 0;
|
89 |
+
}
|
90 |
+
|
91 |
+
#tnpc-subject-wrap .composer-actions {
|
92 |
+
position: absolute;
|
93 |
+
right: 10px;
|
94 |
+
bottom: 5px;
|
95 |
+
display: flex;
|
96 |
+
align-items: center;
|
97 |
+
}
|
98 |
+
|
99 |
+
#tnpc-subject-wrap .composer-view-mode {
|
100 |
+
display: flex;
|
101 |
+
}
|
102 |
+
|
103 |
+
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item {
|
104 |
+
display: block;
|
105 |
+
width: 30px;
|
106 |
+
height: 30px;
|
107 |
+
line-height: 30px;
|
108 |
+
box-sizing: content-box;
|
109 |
+
text-align: center;
|
110 |
+
margin-left: 3px;
|
111 |
+
border-radius: 3px;
|
112 |
+
border: solid 1px #3c434a;
|
113 |
+
background-color: #FFF;
|
114 |
+
color: #3c434a;
|
115 |
+
font-size: 12px;
|
116 |
+
cursor: pointer;
|
117 |
+
}
|
118 |
+
|
119 |
+
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item--active {
|
120 |
+
background-color: #2b2f3a;
|
121 |
+
border-color: #2b2f3a;
|
122 |
+
color: #FFF;
|
123 |
+
}
|
124 |
+
|
125 |
+
#tnpc-subject-wrap .composer-view-mode .composer-view-mode__item:hover{
|
126 |
+
background-color: #3c434a;
|
127 |
+
border-color: #3c434a;
|
128 |
+
color: #FFF;
|
129 |
+
}
|
130 |
+
|
131 |
+
.composer-actions .button-primary {
|
132 |
+
background-color: #2b2f3a;
|
133 |
+
}
|
134 |
+
|
135 |
+
.composer-actions .button-primary:hover {
|
136 |
+
background-color: #3c434a;
|
137 |
+
}
|
138 |
+
|
139 |
+
#test-newsletter-button {
|
140 |
+
background-color: #2b2f3a;
|
141 |
+
}
|
142 |
+
|
143 |
+
#test-newsletter-button:hover {
|
144 |
+
background-color: #3c434a;
|
145 |
+
}
|
146 |
+
|
147 |
+
#tnpc-subject #options-subject-subject,
|
148 |
+
#options-preheader
|
149 |
+
{
|
150 |
+
width: 600px;
|
151 |
+
margin-right: 15px;
|
152 |
+
border: 1px solid #ddd;
|
153 |
+
font-size: 14px;
|
154 |
+
font-family: monospace !important;
|
155 |
+
}
|
156 |
+
|
157 |
+
#options-preheader + .tnp-description
|
158 |
+
{
|
159 |
+
margin-top: 0;
|
160 |
+
}
|
161 |
+
|
162 |
+
#tnpc-subject i {
|
163 |
+
font-size: 18px;
|
164 |
+
}
|
165 |
+
|
166 |
+
.tnp-composer-heading {
|
167 |
+
background-color: #0073aa;
|
168 |
+
border-radius: 3px !important;
|
169 |
+
position: fixed;
|
170 |
+
bottom: 0;
|
171 |
+
right: 0;
|
172 |
+
left: 56px;
|
173 |
+
z-index: 1000;
|
174 |
+
margin: 0 15px 10px 0;
|
175 |
+
}
|
176 |
+
|
177 |
+
.tnp-composer-heading h2 {
|
178 |
+
display: inline-block;
|
179 |
+
margin-left: 30px !important;
|
180 |
+
text-transform: none !important;
|
181 |
+
font-weight: 400 !important;
|
182 |
+
}
|
183 |
+
|
184 |
+
.tnp-composer-heading a {
|
185 |
+
display: inline-block;
|
186 |
+
margin-left: 30px;
|
187 |
+
}
|
188 |
+
|
189 |
+
.tnp-composer-heading form {
|
190 |
+
display: inline-block;
|
191 |
+
margin-left: 30px;
|
192 |
+
}
|
193 |
+
|
194 |
+
.tnp-composer-heading img {
|
195 |
+
width: 50px;
|
196 |
+
vertical-align: middle;
|
197 |
+
}
|
198 |
+
|
199 |
+
#newsletter-builder-sidebar h4 {
|
200 |
+
/* margin: 5px; */
|
201 |
+
/* text-align: center; */
|
202 |
+
color: #868686;
|
203 |
+
/* margin-bottom: 20px; */
|
204 |
+
font-family: Montserrat, sans-serif;
|
205 |
+
font-weight: 300;
|
206 |
+
border-bottom: 1px solid #fff;
|
207 |
+
padding-bottom: 10px;
|
208 |
+
}
|
209 |
+
|
210 |
+
/*#newsletter-builder-sidebar h4 span {
|
211 |
+
background-color: #27AE60;
|
212 |
+
padding: 2px 5px;
|
213 |
+
border-radius: 3px;
|
214 |
+
}*/
|
215 |
+
|
216 |
+
|
217 |
+
#newsletter-builder-sidebar .newsletter-sidebar-add-buttons img {
|
218 |
+
width: 150px;
|
219 |
+
height: auto;
|
220 |
+
}
|
221 |
+
|
222 |
+
.newsletter-sidebar-add-buttons {
|
223 |
+
border-radius: 4px;
|
224 |
+
padding: 5px;
|
225 |
+
margin: 5px;
|
226 |
+
}
|
227 |
+
|
228 |
+
.tnp-body-lite {
|
229 |
+
background-color: #FFFFFF !important;
|
230 |
+
}
|
231 |
+
|
232 |
+
.newsletter-sidebar-buttons-content-tab {
|
233 |
+
margin: 1px;
|
234 |
+
position: relative;
|
235 |
+
display: inline-block;
|
236 |
+
}
|
237 |
+
.newsletter-sidebar-buttons-content-tab:hover {
|
238 |
+
cursor: move;
|
239 |
+
}
|
240 |
+
.newsletter-sidebar-buttons-content-tab:hover img{
|
241 |
+
opacity: 0.8;
|
242 |
+
}
|
243 |
+
.newsletter-sidebar-buttons-content-tab:hover .newsletter-sidebar-buttons-content-tab-add{
|
244 |
+
opacity: 0.5;
|
245 |
+
}
|
246 |
+
.newsletter-sidebar-buttons-content-tab-add {
|
247 |
+
height: 100%;
|
248 |
+
width: 100%;
|
249 |
+
background-color: rgba(70,70,70,1);
|
250 |
+
position: absolute;
|
251 |
+
left: 0;
|
252 |
+
top: 0;
|
253 |
+
/*float: left;*/
|
254 |
+
/*margin-top: -15px;*/
|
255 |
+
/*margin-left: -50px;*/
|
256 |
+
-webkit-transition: all 0.5s;
|
257 |
+
-moz-transition: all 0.5s;
|
258 |
+
-o-transition: all 0.5s;
|
259 |
+
transition: all 0.5s;
|
260 |
+
z-index: 2;
|
261 |
+
opacity: 0;
|
262 |
+
text-align: center;
|
263 |
+
line-height: inherit;
|
264 |
+
color: white;
|
265 |
+
}
|
266 |
+
.newsletter-sidebar-buttons-content-tab-add:hover {
|
267 |
+
background-color: rgba(0,0,0,1);
|
268 |
+
/* cursor: pointer;*/
|
269 |
+
}
|
270 |
+
|
271 |
+
#newsletter-builder-area-center-frame-content {
|
272 |
+
/*float: left;*/
|
273 |
+
/*width: 730px;*/
|
274 |
+
/*background-color: rgba(153,153,153,1);*/
|
275 |
+
min-height: 300px!important;
|
276 |
+
padding-bottom: 75px;
|
277 |
+
/*background-color: #ECF0F1;*/
|
278 |
+
padding-top: 30px;
|
279 |
+
/*border: 1px dashed #eee;*/
|
280 |
+
overflow-y: scroll;
|
281 |
+
/*max-height: 600px;*/
|
282 |
+
}
|
283 |
+
|
284 |
+
/* https://www.codegrepper.com/code-examples/css/how+ot+hide+scroll+bar+buy+allow+mouse+scrolling+css */
|
285 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile {
|
286 |
+
margin: 20px auto 0px auto;
|
287 |
+
width: 350px;
|
288 |
+
height: 500px;
|
289 |
+
-ms-overflow-style: none;
|
290 |
+
scrollbar-width: none;
|
291 |
+
border: 1px solid #ddd;
|
292 |
+
border-radius: 10px;
|
293 |
+
padding-top: 0;
|
294 |
+
padding-bottom: 0;
|
295 |
+
}
|
296 |
+
|
297 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile::-webkit-scrollbar {
|
298 |
+
display: none;
|
299 |
+
}
|
300 |
+
|
301 |
+
#newsletter-builder-area-center-frame-content p {
|
302 |
+
font-size: inherit;
|
303 |
+
font-weight: inherit;
|
304 |
+
font-family: inherit;
|
305 |
+
color: inherit;
|
306 |
+
}
|
307 |
+
|
308 |
+
#newsletter-mobile-preview-area {
|
309 |
+
margin-left: 30px;
|
310 |
+
box-sizing: border-box;
|
311 |
+
margin-top: 30px;
|
312 |
+
text-align: center;
|
313 |
+
border: 1px solid #ddd;
|
314 |
+
border-radius: 10px;
|
315 |
+
padding-left: 10px;
|
316 |
+
padding-right: 10px;
|
317 |
+
padding-top: 10px;
|
318 |
+
}
|
319 |
+
#newsletter-mobile-preview-area input {
|
320 |
+
width: 100px;
|
321 |
+
}
|
322 |
+
|
323 |
+
iframe#tnpc-mobile-preview {
|
324 |
+
height: 550px;
|
325 |
+
box-sizing: border-box;
|
326 |
+
width: 320px;
|
327 |
+
border-radius: 10px;
|
328 |
+
margin-top: 20px;
|
329 |
+
margin-left: 20px;
|
330 |
+
background-color: #F6F8FD;
|
331 |
+
}
|
332 |
+
|
333 |
+
|
334 |
+
.tnpc-row {
|
335 |
+
-webkit-transition: box-shadow 0.5s;
|
336 |
+
-moz-transition: box-shadow 0.5s;
|
337 |
+
-o-transition: box-shadow 0.5s;
|
338 |
+
transition: box-shadow 0.5s;
|
339 |
+
position: relative;
|
340 |
+
}
|
341 |
+
.tnpc-row:hover {
|
342 |
+
cursor: move;
|
343 |
+
/*border: 2px dashed #999;*/
|
344 |
+
-webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
345 |
+
-moz-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
346 |
+
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.2);
|
347 |
+
}
|
348 |
+
.tnpc-row.ui-sortable-helper {
|
349 |
+
max-width: 700px!important;
|
350 |
+
}
|
351 |
+
.tnpc-row-delete, .tnpc-row-edit-block, .tnpc-row-clone {
|
352 |
+
height: 30px;
|
353 |
+
width: 30px;
|
354 |
+
top: 0px;
|
355 |
+
background-color: rgba(255,255,255,0.5);
|
356 |
+
z-index: 5;
|
357 |
+
position: absolute;
|
358 |
+
color: rgba(102,102,102,1);
|
359 |
+
-webkit-transition: all 0.5s;
|
360 |
+
-moz-transition: all 0.5s;
|
361 |
+
-o-transition: all 0.5s;
|
362 |
+
transition: all 0.5s;
|
363 |
+
opacity: 0;
|
364 |
+
text-align: center;
|
365 |
+
font-size: 18px;
|
366 |
+
}
|
367 |
+
.tnpc-row-delete i, .tnpc-row-edit-block i, .tnpc-row-clone i {
|
368 |
+
line-height: 30px;
|
369 |
+
}
|
370 |
+
.tnpc-row-delete:hover {
|
371 |
+
background-color: #E74C3C;
|
372 |
+
cursor: pointer;
|
373 |
+
color: rgba(255,255,255,1);
|
374 |
+
}
|
375 |
+
.tnpc-row:hover .tnpc-row-delete, .tnpc-row:hover .tnpc-row-edit-block, .tnpc-row:hover .tnpc-row-clone {
|
376 |
+
opacity: 1;
|
377 |
+
}
|
378 |
+
.tnpc-row-delete {
|
379 |
+
right: 0px;
|
380 |
+
z-index: 5;
|
381 |
+
}
|
382 |
+
.tnpc-row-edit-block {
|
383 |
+
right: 60px;
|
384 |
+
}
|
385 |
+
.tnpc-row-edit-block:hover {
|
386 |
+
background-color: #e0e0e0;
|
387 |
+
cursor: pointer;
|
388 |
+
color: rgba(0, 0, 0, 1);
|
389 |
+
}
|
390 |
+
|
391 |
+
.tnpc-row-clone {
|
392 |
+
right: 30px;
|
393 |
+
}
|
394 |
+
.tnpc-row-clone:hover {
|
395 |
+
background-color: #e0e0e0;;
|
396 |
+
cursor: pointer;
|
397 |
+
color: rgba(0,0,0,1);
|
398 |
+
}
|
399 |
+
|
400 |
+
.tnpc-row-edit {
|
401 |
+
position: relative;
|
402 |
+
}
|
403 |
+
.tnpc-row-edit-hover {
|
404 |
+
height: 100%;
|
405 |
+
width: 100%;
|
406 |
+
background-color: rgba(63,141,191,0.8);
|
407 |
+
position: absolute;
|
408 |
+
left: 0px;
|
409 |
+
top: 0px;
|
410 |
+
cursor: default;
|
411 |
+
-webkit-transition: all 0.5s;
|
412 |
+
-moz-transition: all 0.5s;
|
413 |
+
-o-transition: all 0.5s;
|
414 |
+
transition: all 0.5s;
|
415 |
+
}
|
416 |
+
.tnpc-row-edit-hover i {
|
417 |
+
position: absolute;
|
418 |
+
height: 30px;
|
419 |
+
width: 30px;
|
420 |
+
line-height: 30px;
|
421 |
+
left: 50%;
|
422 |
+
top: 50%;
|
423 |
+
text-align: center;
|
424 |
+
margin-top: -15px;
|
425 |
+
margin-left: -15px;
|
426 |
+
color: rgba(255,255,255,1);
|
427 |
+
-webkit-transition: all 0.5s;
|
428 |
+
-moz-transition: all 0.5s;
|
429 |
+
-o-transition: all 0.5s;
|
430 |
+
transition: all 0.5s;
|
431 |
+
-webkit-border-radius: 50%;
|
432 |
+
-moz-border-radius: 50%;
|
433 |
+
border-radius: 50%;
|
434 |
+
font-size: 16px;
|
435 |
+
}
|
436 |
+
.tnpc-row-edit-hover i:hover {
|
437 |
+
background-color: rgba(0,0,0,0.5);
|
438 |
+
cursor: pointer;
|
439 |
+
}
|
440 |
+
|
441 |
+
.tnpc-drop-here {
|
442 |
+
padding:10px;
|
443 |
+
text-align: center;
|
444 |
+
}
|
445 |
+
|
446 |
+
.tnpc-edit {
|
447 |
+
height: 100vh;
|
448 |
+
width: 100vw;
|
449 |
+
z-index: 10;
|
450 |
+
display: none;
|
451 |
+
position: absolute;
|
452 |
+
top: 0px;
|
453 |
+
left: 0px;
|
454 |
+
}
|
455 |
+
|
456 |
+
.tnpc-edit-box-title {
|
457 |
+
/*float: left;*/
|
458 |
+
width: 100%;
|
459 |
+
font-size: 29px;
|
460 |
+
color: #666666;
|
461 |
+
font-weight: 300;
|
462 |
+
margin-bottom: 40px;
|
463 |
+
}
|
464 |
+
|
465 |
+
.tnpc-edit-box-content {
|
466 |
+
/*float: left;*/
|
467 |
+
width: 100%;
|
468 |
+
margin-top: 10px;
|
469 |
+
}
|
470 |
+
.tnpc-edit-box-content-text {
|
471 |
+
/*float: left;*/
|
472 |
+
width: 100%;
|
473 |
+
font-size: 15px;
|
474 |
+
color: #666666;
|
475 |
+
font-weight: 600;
|
476 |
+
margin: 15px 0px 10px;
|
477 |
+
text-transform: uppercase;
|
478 |
+
}
|
479 |
+
|
480 |
+
.tnpc-edit-box-content-text span {
|
481 |
+
font-size: 11px;
|
482 |
+
color: #95A5A6;
|
483 |
+
background-color: #D3EADC;
|
484 |
+
padding: 2px 5px;
|
485 |
+
text-transform: none;
|
486 |
+
border-radius: 5px;
|
487 |
+
}
|
488 |
+
|
489 |
+
.tnpc-edit-box-content-field {
|
490 |
+
/*float: left;*/
|
491 |
+
width: 100%;
|
492 |
+
}
|
493 |
+
|
494 |
+
.tnpc-edit-box-content-field-input {
|
495 |
+
height: 33px;
|
496 |
+
width: 380px;
|
497 |
+
border: none !important;
|
498 |
+
outline: none;
|
499 |
+
font-family: inherit;
|
500 |
+
padding-right: 10px;
|
501 |
+
font-size: 15px;
|
502 |
+
-webkit-transition: all 0.5s;
|
503 |
+
-moz-transition: all 0.5s;
|
504 |
+
-o-transition: all 0.5s;
|
505 |
+
transition: all 0.5s;
|
506 |
+
color: rgba(102,102,102,1);
|
507 |
+
margin-bottom: 10px;
|
508 |
+
}
|
509 |
+
.tnpc-edit-box-content-field-input:focus {
|
510 |
+
-webkit-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
511 |
+
-moz-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
512 |
+
box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
513 |
+
}
|
514 |
+
.tnpc-edit-box-content-field-textarea {
|
515 |
+
/*float: left;*/
|
516 |
+
height: 180px;
|
517 |
+
width: 380px;
|
518 |
+
border: 1px solid rgba(204,204,204,1);
|
519 |
+
outline: none;
|
520 |
+
font-family: inherit;
|
521 |
+
font-size: 15px;
|
522 |
+
-webkit-transition: all 0.5s;
|
523 |
+
-moz-transition: all 0.5s;
|
524 |
+
-o-transition: all 0.5s;
|
525 |
+
transition: all 0.5s;
|
526 |
+
color: rgba(102,102,102,1);
|
527 |
+
resize: none;
|
528 |
+
padding: 10px;
|
529 |
+
}
|
530 |
+
.tnpc-edit-box-content-field-textarea:focus {
|
531 |
+
-webkit-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
532 |
+
-moz-box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
533 |
+
box-shadow: inset 0px 0px 10px 0px rgba(0,0,0,0.2);
|
534 |
+
}
|
535 |
+
.tnpc-edit-box-content-icons {
|
536 |
+
/*float: left;*/
|
537 |
+
height: 388px;
|
538 |
+
width: 388px;
|
539 |
+
border: 1px solid rgba(204,204,204,1);
|
540 |
+
margin-top: 15px;
|
541 |
+
overflow-y: scroll;
|
542 |
+
}
|
543 |
+
.tnpc-edit-box-content-icons i {
|
544 |
+
line-height: 50px;
|
545 |
+
background-color: rgba(225,225,225,1);
|
546 |
+
/*float: left;*/
|
547 |
+
height: 50px;
|
548 |
+
width: 50px;
|
549 |
+
margin-top: 10px;
|
550 |
+
margin-left: 10px;
|
551 |
+
text-align: center;
|
552 |
+
-webkit-transition: all 0.5s;
|
553 |
+
-moz-transition: all 0.5s;
|
554 |
+
-o-transition: all 0.5s;
|
555 |
+
transition: all 0.5s;
|
556 |
+
font-size: 28px;
|
557 |
+
color: rgba(51,51,51,1);
|
558 |
+
}
|
559 |
+
.tnpc-edit-box-content-icons i:hover {
|
560 |
+
cursor: pointer;
|
561 |
+
background-color: rgba(153,153,153,1);
|
562 |
+
-webkit-border-radius: 50%;
|
563 |
+
-moz-border-radius: 50%;
|
564 |
+
border-radius: 50%;
|
565 |
+
color: rgba(0,0,0,1);
|
566 |
+
}
|
567 |
+
|
568 |
+
/* Save and cancel buttons container on block options popup */
|
569 |
+
.tnpc-edit-box-buttons{
|
570 |
+
margin-top: 10px;
|
571 |
+
text-align: right;
|
572 |
+
margin-right: 10px;
|
573 |
+
}
|
574 |
+
|
575 |
+
.tnpc-edit-box-buttons-save{
|
576 |
+
height: 35px;
|
577 |
+
text-align: right;
|
578 |
+
line-height: 35px;
|
579 |
+
color: #27AE60;
|
580 |
+
font-weight: 600;
|
581 |
+
font-size: 15px;
|
582 |
+
-webkit-border-radius: 3px;
|
583 |
+
-moz-border-radius: 3px;
|
584 |
+
border-radius: 3px;
|
585 |
+
-webkit-transition: background 0.5s;
|
586 |
+
-moz-transition: background 0.5s;
|
587 |
+
-o-transition: background 0.5s;
|
588 |
+
transition: background 0.5s;
|
589 |
+
cursor: pointer;
|
590 |
+
/*float: left;*/
|
591 |
+
/*padding-right: 25px;
|
592 |
+
padding-left: 25px;
|
593 |
+
width: 33%;*/
|
594 |
+
display: inline-block;
|
595 |
+
}
|
596 |
+
.tnpc-edit-box-buttons-save:hover {
|
597 |
+
color: #2ECC71;
|
598 |
+
}
|
599 |
+
.tnpc-edit-box-buttons-cancel{
|
600 |
+
height: 35px;
|
601 |
+
text-align: right;
|
602 |
+
line-height: 35px;
|
603 |
+
color: #666;
|
604 |
+
font-weight: normal;
|
605 |
+
font-size: 15px;
|
606 |
+
-webkit-border-radius: 3px;
|
607 |
+
-moz-border-radius: 3px;
|
608 |
+
border-radius: 3px;
|
609 |
+
-webkit-transition: background 0.5s;
|
610 |
+
-moz-transition: background 0.5s;
|
611 |
+
-o-transition: background 0.5s;
|
612 |
+
transition: background 0.5s;
|
613 |
+
cursor: pointer;
|
614 |
+
/*float: left;*/
|
615 |
+
/*padding-right: 25px;
|
616 |
+
padding-left: 25px;
|
617 |
+
width: 33%;*/
|
618 |
+
display: inline-block;
|
619 |
+
margin-right: 25px;
|
620 |
+
}
|
621 |
+
.tnpc-edit-box-buttons-cancel:hover {
|
622 |
+
color: #E74C3C;
|
623 |
+
}
|
624 |
+
|
625 |
+
|
626 |
+
/* Tnp Composer Preview */
|
627 |
+
|
628 |
+
|
629 |
+
.tnpc-subject a {
|
630 |
+
font-family: Source Sans Pro;
|
631 |
+
font-weight: 700;
|
632 |
+
text-transform: uppercase;
|
633 |
+
text-decoration: none;
|
634 |
+
background-color: #3498DB;
|
635 |
+
color: white;
|
636 |
+
padding: 2px 10px;
|
637 |
+
border-radius: 10px;
|
638 |
+
font-size: 13px;
|
639 |
+
letter-spacing: 0.1em;
|
640 |
+
}
|
641 |
+
|
642 |
+
|
643 |
+
.tnpc-preview {
|
644 |
+
margin-top: 10px;
|
645 |
+
}
|
646 |
+
|
647 |
+
.tnpc-preview .fake-browser-ui iframe {
|
648 |
+
width: 700px;
|
649 |
+
}
|
650 |
+
|
651 |
+
.tnpc-preview .fake-mobile-browser-ui iframe {
|
652 |
+
width: 320px;
|
653 |
+
}
|
654 |
+
|
655 |
+
.fake-browser-ui {
|
656 |
+
padding: 30px 0 0;
|
657 |
+
border-radius: 3px;
|
658 |
+
border-bottom: 10px solid #ccc;
|
659 |
+
background: #ddd;
|
660 |
+
display: inline-block;
|
661 |
+
position: relative;
|
662 |
+
line-height: 0;
|
663 |
+
vertical-align: top;
|
664 |
+
margin-left: 20px;
|
665 |
+
}
|
666 |
+
|
667 |
+
.fake-mobile-browser-ui {
|
668 |
+
padding: 30px 10px 37px;
|
669 |
+
border-radius: 10px;
|
670 |
+
border-bottom: 10px solid #ccc;
|
671 |
+
background: #ddd;
|
672 |
+
display: inline-block;
|
673 |
+
position: relative;
|
674 |
+
line-height: 0;
|
675 |
+
margin-left: 30px;
|
676 |
+
}
|
677 |
+
|
678 |
+
.fake-browser-ui .frame {
|
679 |
+
display: block;
|
680 |
+
height: 25px;
|
681 |
+
position: absolute;
|
682 |
+
top: 12px;
|
683 |
+
left: 8px;
|
684 |
+
}
|
685 |
+
|
686 |
+
.fake-mobile-browser-ui .frame {
|
687 |
+
display: block;
|
688 |
+
height: 25px;
|
689 |
+
margin-top: 10px;
|
690 |
+
}
|
691 |
+
|
692 |
+
.fake-browser-ui span {
|
693 |
+
height: 12px;
|
694 |
+
width: 12px;
|
695 |
+
border-radius: 8px;
|
696 |
+
background-color: #eee;
|
697 |
+
border: 1px solid #dadada;
|
698 |
+
float: left;
|
699 |
+
margin: 0 0 0 4px;
|
700 |
+
}
|
701 |
+
|
702 |
+
.fake-mobile-browser-ui span {
|
703 |
+
height: 50px;
|
704 |
+
width: 50px;
|
705 |
+
border-radius: 60px;
|
706 |
+
background-color: #eee;
|
707 |
+
border: 2px solid #ccc;
|
708 |
+
display: block;
|
709 |
+
margin: auto;
|
710 |
+
}
|
711 |
+
|
712 |
+
.fake-browser-ui .bt-1 {
|
713 |
+
background-color: #ED594A;
|
714 |
+
}
|
715 |
+
|
716 |
+
.fake-browser-ui .bt-2 {
|
717 |
+
background-color: #FDD800;
|
718 |
+
}
|
719 |
+
|
720 |
+
.fake-browser-ui .bt-3 {
|
721 |
+
background-color: #5AC05A;
|
722 |
+
}
|
723 |
+
|
724 |
+
|
725 |
+
/* Tnp Html Editor */
|
726 |
+
|
727 |
+
#tnpc-html-editor {
|
728 |
+
height: 600px;
|
729 |
+
border-top: 20px solid #323232;
|
730 |
+
border-radius: 8px;
|
731 |
+
}
|
732 |
+
|
733 |
+
/* List Block Styles */ *
|
734 |
+
|
735 |
+
.tnp-select2-option {
|
736 |
+
/* background-color: red; */
|
737 |
+
}
|
738 |
+
|
739 |
+
.tnp-select2-option img {
|
740 |
+
height: 15px;
|
741 |
+
margin-right: 5px;
|
742 |
+
vertical-align: middle;
|
743 |
+
background-color: rgba(234, 234, 234, 0.25);
|
744 |
+
padding: 10px;
|
745 |
+
border-radius: 5px;
|
746 |
+
}
|
747 |
+
|
748 |
+
/* ************************************************************************** */
|
749 |
+
/* Block options layer over the sidebar */
|
750 |
+
|
751 |
+
/* Main container */
|
752 |
+
#tnpc-block-options {
|
753 |
+
/*height: 100vh;*/
|
754 |
+
z-index: 10;
|
755 |
+
flex-flow: column;
|
756 |
+
display: none;
|
757 |
+
position: absolute;
|
758 |
+
top: 0px;
|
759 |
+
left: 0px;
|
760 |
+
bottom: 0;
|
761 |
+
right: 0;
|
762 |
+
background-color: #ECF0F1;
|
763 |
+
padding: 0;
|
764 |
+
}
|
765 |
+
|
766 |
+
/* Save and cancel button container */
|
767 |
+
#tnpc-block-options-buttons {
|
768 |
+
padding: 20px;
|
769 |
+
text-align: right;
|
770 |
+
background-color: #ecf0f1;
|
771 |
+
height: 70px;
|
772 |
+
border-bottom: 1px solid #ffffff;
|
773 |
+
}
|
774 |
+
|
775 |
+
|
776 |
+
/* Form */
|
777 |
+
#tnpc-block-options-form {
|
778 |
+
background-color: #fff;
|
779 |
+
padding: 15px;
|
780 |
+
margin-top: 0;
|
781 |
+
color: #444;
|
782 |
+
background-color: #ECF0F1 !important;
|
783 |
+
flex: 1 1 auto;
|
784 |
+
overflow-y: auto;
|
785 |
+
}
|
786 |
+
|
787 |
+
|
788 |
+
#tnpc-block-options-form h3 {
|
789 |
+
color: #000;
|
790 |
+
}
|
791 |
+
|
792 |
+
#tnpc-block-options-form table.form-table th {
|
793 |
+
/*background-color: #f4f4f4;*/
|
794 |
+
width: 100%;
|
795 |
+
vertical-align: top;
|
796 |
+
float: left;
|
797 |
+
font-weight: normal;
|
798 |
+
text-transform: uppercase;
|
799 |
+
font-size: 13px;
|
800 |
+
padding-top: 10px;
|
801 |
+
padding-bottom: 5px;
|
802 |
+
padding-left: 0;
|
803 |
+
padding-right: 0;
|
804 |
+
|
805 |
+
}
|
806 |
+
|
807 |
+
#tnpc-block-options-form table.form-table td {
|
808 |
+
float: left;
|
809 |
+
padding: 0;
|
810 |
+
margin: 0;
|
811 |
+
border: 0;
|
812 |
+
width: 100%;
|
813 |
+
}
|
814 |
+
|
815 |
+
#tnpc-block-options-form table.form-table {
|
816 |
+
margin: 0px;
|
817 |
+
border-collapse: separate!important;
|
818 |
+
border-spacing: 1px!important;
|
819 |
+
}
|
820 |
+
|
821 |
+
#tnpc-block-options-form table.form-table table.tnp-button-colors {
|
822 |
+
border: 0;
|
823 |
+
border-collapse: collapse;
|
824 |
+
}
|
825 |
+
#tnpc-block-options-form table.form-table table.tnp-button-colors td {
|
826 |
+
border: 0;
|
827 |
+
padding-top: 0;
|
828 |
+
}
|
829 |
+
|
830 |
+
/* Style the tab */
|
831 |
+
.tnpc-tabs {
|
832 |
+
/*overflow: hidden;*/
|
833 |
+
background-color: #fff;
|
834 |
+
font-family: Montserrat, sans-serif;
|
835 |
+
}
|
836 |
+
|
837 |
+
/* Style the buttons that are used to open the tab content */
|
838 |
+
.tnpc-tabs button {
|
839 |
+
background-color: inherit;
|
840 |
+
float: left;
|
841 |
+
border: none;
|
842 |
+
outline: none;
|
843 |
+
cursor: pointer;
|
844 |
+
padding: 14px 16px;
|
845 |
+
transition: 0.3s;
|
846 |
+
color: #6a8ba0;
|
847 |
+
}
|
848 |
+
|
849 |
+
/* Change background color of buttons on hover */
|
850 |
+
.tnpc-tabs button:hover {
|
851 |
+
background-color: #ddd;
|
852 |
+
}
|
853 |
+
|
854 |
+
/* Create an active/current tablink class */
|
855 |
+
.tnpc-tabs button.active {
|
856 |
+
background-color: #ECF0F1;
|
857 |
+
color: #3498DB;
|
858 |
+
}
|
859 |
+
|
860 |
+
/* Style the tab content */
|
861 |
+
.tabcontent {
|
862 |
+
display: none;
|
863 |
+
padding: 6px 12px;
|
864 |
+
border-top: none;
|
865 |
+
flex: 1 1 auto;
|
866 |
+
overflow-y: auto;
|
867 |
+
}
|
868 |
+
|
869 |
+
/* Style Reset, Save, Save & Preview footer */
|
870 |
+
|
871 |
+
.tnpc-controls {
|
872 |
+
text-align: right;
|
873 |
+
}
|
874 |
+
|
875 |
+
.tnpc-logo {
|
876 |
+
float: left;
|
877 |
+
}
|
878 |
+
|
879 |
+
.tnpc-logo p {
|
880 |
+
font-family: Montserrat, Sans-serif;
|
881 |
+
color: #fff !important;
|
882 |
+
font-size: 16px;
|
883 |
+
margin-left: 20px !important;
|
884 |
+
margin-top: 5px !important;
|
885 |
+
}
|
886 |
+
|
887 |
+
#newsletter-builder-area ul {
|
888 |
+
display: block;
|
889 |
+
list-style-type: disc;
|
890 |
+
margin-block-start: 1em;
|
891 |
+
margin-block-end: 1em;
|
892 |
+
margin-inline-start: 0;
|
893 |
+
margin-inline-end: 0;
|
894 |
+
padding-inline-start: 40px;
|
895 |
+
}
|
896 |
+
|
897 |
+
#newsletter-builder-area ul li {
|
898 |
+
margin-bottom: 0;
|
899 |
+
}
|
900 |
+
|
901 |
+
/* Global Options elements style */
|
902 |
+
|
903 |
+
#tnpc-general-options select {
|
904 |
+
box-shadow: none;
|
905 |
+
border-radius: 0px;
|
906 |
+
border: none;
|
907 |
+
margin-right: 5px;
|
908 |
+
}
|
909 |
+
|
910 |
+
/* Blocks options global styles */
|
911 |
+
|
912 |
+
.tnpc-block-options-warning {
|
913 |
+
background-color: #def9e9;
|
914 |
+
padding: 10px 15px;
|
915 |
+
}
|
916 |
+
|
917 |
+
/* Presets */
|
918 |
+
.tnpc-preset-container {
|
919 |
+
max-width: 720px;
|
920 |
+
margin: 0 auto;
|
921 |
+
position: relative;
|
922 |
+
}
|
923 |
+
|
924 |
+
.tnpc-preset-legacy-themes {
|
925 |
+
position: absolute;
|
926 |
+
top: -15px;
|
927 |
+
left: 15px;
|
928 |
+
}
|
929 |
+
|
930 |
+
|
931 |
+
.tnpc-preset {
|
932 |
+
float: left;
|
933 |
+
margin: 15px;
|
934 |
+
cursor: pointer;
|
935 |
+
width: 150px;
|
936 |
+
height: 200px;
|
937 |
+
background: white;
|
938 |
+
border-radius: 8px;
|
939 |
+
box-shadow: 0 0 2px 0 #dee3e4;
|
940 |
+
position: relative;
|
941 |
+
text-align: center;
|
942 |
+
}
|
943 |
+
|
944 |
+
.tnpc-preset-html {
|
945 |
+
background-color: #5397d5;
|
946 |
+
}
|
947 |
+
|
948 |
+
.tnpc-preset-html span {
|
949 |
+
color: #fff;
|
950 |
+
}
|
951 |
+
|
952 |
+
.tnpc-preset:hover {
|
953 |
+
box-shadow: 0 0 8px 8px #dee3e4;
|
954 |
+
}
|
955 |
+
|
956 |
+
.tnpc-preset img {
|
957 |
+
width: 50px;
|
958 |
+
height: 50px;
|
959 |
+
margin-top: 50px;
|
960 |
+
}
|
961 |
+
|
962 |
+
.tnpc-preset-label {
|
963 |
+
position: absolute;
|
964 |
+
top: 150px;
|
965 |
+
left: 50%;
|
966 |
+
transform: translate(-50%, -50%);
|
967 |
+
font-size: 14px;
|
968 |
+
width: 80%;
|
969 |
+
font-family: soleil, sans-serif;
|
970 |
+
color: #2f3241;
|
971 |
+
font-weight: 200;
|
972 |
+
}
|
973 |
+
|
974 |
+
.tnpc-delete-preset {
|
975 |
+
position: absolute;
|
976 |
+
top: 0;
|
977 |
+
right: 0;
|
978 |
+
display: flex;
|
979 |
+
align-items: center;
|
980 |
+
justify-content: center;
|
981 |
+
width: 20px;
|
982 |
+
height: 20px;
|
983 |
+
background-color: #8B0000;
|
984 |
+
color: #FFF;
|
985 |
+
font-weight: bold;
|
986 |
+
border-radius: 0 8px 0 8px;
|
987 |
+
z-index: 100;
|
988 |
+
}
|
989 |
+
|
990 |
+
.tnpc-edit-preset {
|
991 |
+
position: absolute;
|
992 |
+
top: 0;
|
993 |
+
left: 0;
|
994 |
+
display: flex;
|
995 |
+
align-items: center;
|
996 |
+
justify-content: center;
|
997 |
+
width: 20px;
|
998 |
+
height: 20px;
|
999 |
+
background-color: #3498DB;
|
1000 |
+
color: #FFF;
|
1001 |
+
font-weight: bold;
|
1002 |
+
border-radius: 8px 0 8px 0;
|
1003 |
+
z-index: 100;
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
.tnpc-inline-editable {
|
1007 |
+
cursor: text;
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
.tnpc-inline-editable {
|
1011 |
+
cursor: text;
|
1012 |
+
position: relative;
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
.tnpc-inline-editable:hover {
|
1016 |
+
color: #EEE !important;
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
.tnpc-inline-editable:hover:after {
|
1020 |
+
content: '';
|
1021 |
+
cursor: pointer;
|
1022 |
+
position: absolute;
|
1023 |
+
top: 0;
|
1024 |
+
left: 0;
|
1025 |
+
width: 100%;
|
1026 |
+
height: 100%;
|
1027 |
+
background-color: rgba(0, 0, 0, 0.2);
|
1028 |
+
opacity: 1;
|
1029 |
+
border-radius: 2px;
|
1030 |
+
}
|
1031 |
+
|
1032 |
+
.tnpc-inline-editable:hover:before {
|
1033 |
+
content: '\f464';
|
1034 |
+
font-family: dashicons;
|
1035 |
+
position: absolute;
|
1036 |
+
top: 0;
|
1037 |
+
bottom: 0;
|
1038 |
+
left: 0;
|
1039 |
+
right: 0;
|
1040 |
+
margin: auto;
|
1041 |
+
width: 32px;
|
1042 |
+
height: 32px;
|
1043 |
+
font-size: 32px;
|
1044 |
+
line-height: 32px;
|
1045 |
+
color: #333;
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
.tnpc-inline-editable-form {
|
1049 |
+
position: relative;
|
1050 |
+
margin-top: 25px;
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
.tnpc-inline-editable-form textarea,
|
1054 |
+
.tnpc-inline-editable-form input {
|
1055 |
+
width: 95%;
|
1056 |
+
margin-left: 20px;
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
.two-columns .tnpc-inline-editable-form-actions {
|
1060 |
+
right: 0;
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
.tnpc-inline-editable-form input {
|
1064 |
+
padding: 5px;
|
1065 |
+
font-size: 25px;
|
1066 |
+
font-family: Helvetica, Arial, sans-serif;
|
1067 |
+
font-weight: normal;
|
1068 |
+
color: rgb(51, 51, 51);
|
1069 |
+
line-height: normal;
|
1070 |
+
}
|
1071 |
+
|
1072 |
+
.tnpc-inline-editable-form-actions {
|
1073 |
+
position: absolute;
|
1074 |
+
top: -25px;
|
1075 |
+
right: 5px;
|
1076 |
+
display: flex;
|
1077 |
+
align-items: center;
|
1078 |
+
flex-wrap: wrap;
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
.tnpc-inline-editable-form-actions button {
|
1082 |
+
background: none;
|
1083 |
+
padding: 0;
|
1084 |
+
border: none;
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
.tnpc-inline-editable-form-actions span {
|
1088 |
+
display: block;
|
1089 |
+
font-size: 25px;
|
1090 |
+
color: #333;
|
1091 |
+
cursor: pointer;
|
1092 |
+
}
|
1093 |
+
|
1094 |
+
.tnpc-inline-editable-form-actions span:first-child {
|
1095 |
+
margin-right: 5px;
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
#update-preset-button {
|
1099 |
+
display: none;
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
.separator {
|
1103 |
+
display: flex;
|
1104 |
+
align-items: center;
|
1105 |
+
text-align: center;
|
1106 |
+
padding: 1em 0;
|
1107 |
+
}
|
1108 |
+
|
1109 |
+
.separator::before,
|
1110 |
+
.separator::after {
|
1111 |
+
content: '';
|
1112 |
+
flex: 1;
|
1113 |
+
border-bottom: 1px solid #3c434a;
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
.separator:not(:empty)::before {
|
1117 |
+
margin-right: 1em;
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
.separator:not(:empty)::after {
|
1121 |
+
margin-left: 1em;
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
#test-newsletter-modal .test-subscribers p {
|
1125 |
+
margin: 0;
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
#test-newsletter-modal h4 {
|
1129 |
+
margin: 0 0 0.5rem 0;
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
#test-newsletter-modal .separator {
|
1133 |
+
padding: 1.25rem 0;
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
|
1137 |
+
.tnp-suggest-subject {
|
1138 |
+
cursor: pointer;
|
1139 |
+
}
|
1140 |
+
|
1141 |
+
/* Drag and drop placeholder */
|
1142 |
+
.placeholder {
|
1143 |
+
border: 1px dashed #bbb!important;
|
1144 |
+
background-color: #fafafa!important;
|
1145 |
+
height: 75px;
|
1146 |
+
margin: 0 auto;
|
1147 |
+
max-width: 600px;
|
1148 |
+
box-sizing: border-box!important;
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
#draggable-helper {
|
1152 |
+
width: 600px;
|
1153 |
+
border: 1px dashed #ddd;
|
1154 |
+
opacity: 80%!important;
|
1155 |
+
background-color: #fff;
|
1156 |
+
text-align: center;
|
1157 |
+
text-transform: uppercase;
|
1158 |
+
font-size: 14px;
|
1159 |
+
color: #666 !important;
|
1160 |
+
padding: 20px;
|
1161 |
+
}
|
1162 |
+
|
1163 |
+
#sortable-helper {
|
1164 |
+
width: 700px;
|
1165 |
+
height: 75px;
|
1166 |
+
border: 3px dashed #ddd;
|
1167 |
+
opacity: .7;
|
1168 |
+
background-color: #fff;
|
1169 |
+
text-align: center;
|
1170 |
+
text-transform: uppercase;
|
1171 |
+
font-size: 14px; color: #aaa;
|
1172 |
+
padding: 20px;
|
1173 |
+
}
|
emails/tnp-composer/_scripts/newsletter-builder-v2.js
CHANGED
@@ -1,980 +1,980 @@
|
|
1 |
-
// add delete buttons
|
2 |
-
jQuery.fn.add_delete = function () {
|
3 |
-
this.append('<div class="tnpc-row-delete" title="Delete"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/delete.png" width="32"></div>');
|
4 |
-
this.find('.tnpc-row-delete').perform_delete();
|
5 |
-
};
|
6 |
-
|
7 |
-
// delete row
|
8 |
-
jQuery.fn.perform_delete = function () {
|
9 |
-
this.click(function () {
|
10 |
-
tnpc_hide_block_options();
|
11 |
-
// remove block
|
12 |
-
jQuery(this).parent().remove();
|
13 |
-
tnpc_mobile_preview();
|
14 |
-
});
|
15 |
-
}
|
16 |
-
|
17 |
-
// add edit button
|
18 |
-
jQuery.fn.add_block_edit = function () {
|
19 |
-
this.append('<div class="tnpc-row-edit-block" title="Edit"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/edit.png" width="32"></div>');
|
20 |
-
this.find('.tnpc-row-edit-block').perform_block_edit();
|
21 |
-
}
|
22 |
-
|
23 |
-
// edit block
|
24 |
-
jQuery.fn.perform_block_edit = function () {
|
25 |
-
|
26 |
-
jQuery(".tnpc-row-edit-block").click(function (e) {
|
27 |
-
e.preventDefault()
|
28 |
-
});
|
29 |
-
|
30 |
-
this.click(function (e) {
|
31 |
-
|
32 |
-
e.preventDefault();
|
33 |
-
|
34 |
-
target = jQuery(this).parent().find('.edit-block');
|
35 |
-
|
36 |
-
// The row container which is a global variable and used later after the options save
|
37 |
-
container = jQuery(this).closest("table");
|
38 |
-
|
39 |
-
if (container.hasClass('tnpc-row-block')) {
|
40 |
-
|
41 |
-
tnpc_show_block_options();
|
42 |
-
|
43 |
-
var options = container.find(".tnpc-block-content").attr("data-json");
|
44 |
-
|
45 |
-
// Compatibility
|
46 |
-
if (!options) {
|
47 |
-
options = target.attr("data-options");
|
48 |
-
}
|
49 |
-
|
50 |
-
var data = {
|
51 |
-
action: "tnpc_options",
|
52 |
-
id: container.data("id"),
|
53 |
-
context_type: tnp_context_type,
|
54 |
-
options: options
|
55 |
-
};
|
56 |
-
|
57 |
-
tnpc_add_global_options(data);
|
58 |
-
|
59 |
-
builderAreaHelper.lock();
|
60 |
-
jQuery("#tnpc-block-options-form").load(ajaxurl, data, function () {
|
61 |
-
console.log('Block form options loaded');
|
62 |
-
start_options = jQuery("#tnpc-block-options-form").serializeArray();
|
63 |
-
tnpc_add_global_options(start_options);
|
64 |
-
builderAreaHelper.unlock();
|
65 |
-
});
|
66 |
-
|
67 |
-
} else {
|
68 |
-
alert("This is deprecated block version and cannot be edited. Please replace it with a new one.");
|
69 |
-
}
|
70 |
-
|
71 |
-
});
|
72 |
-
|
73 |
-
};
|
74 |
-
|
75 |
-
// add clone button
|
76 |
-
jQuery.fn.add_block_clone = function () {
|
77 |
-
this.append('<div class="tnpc-row-clone" title="Clone"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/copy.png" width="32"></div>');
|
78 |
-
this.find('.tnpc-row-clone').perform_clone();
|
79 |
-
}
|
80 |
-
|
81 |
-
// clone block
|
82 |
-
jQuery.fn.perform_clone = function () {
|
83 |
-
|
84 |
-
jQuery(".tnpc-row-clone").click(function (e) {
|
85 |
-
e.preventDefault()
|
86 |
-
});
|
87 |
-
|
88 |
-
this.click(function (e) {
|
89 |
-
|
90 |
-
e.preventDefault();
|
91 |
-
|
92 |
-
// hide block edit form
|
93 |
-
tnpc_hide_block_options();
|
94 |
-
|
95 |
-
// find the row
|
96 |
-
let row = jQuery(this).closest('.tnpc-row');
|
97 |
-
|
98 |
-
// clone the block
|
99 |
-
let new_row = row.clone();
|
100 |
-
new_row.find(".tnpc-row-delete").remove();
|
101 |
-
new_row.find(".tnpc-row-edit-block").remove();
|
102 |
-
new_row.find(".tnpc-row-clone").remove();
|
103 |
-
|
104 |
-
new_row.add_delete();
|
105 |
-
new_row.add_block_edit();
|
106 |
-
new_row.add_block_clone();
|
107 |
-
// if (new_row.hasClass('tnpc-row-block')) {
|
108 |
-
// new_row.find(".tnpc-row-edit-block i").click();
|
109 |
-
// }
|
110 |
-
new_row.insertAfter(row);
|
111 |
-
tnpc_mobile_preview();
|
112 |
-
});
|
113 |
-
};
|
114 |
-
|
115 |
-
let start_options = null;
|
116 |
-
let container = null;
|
117 |
-
|
118 |
-
jQuery(function () {
|
119 |
-
|
120 |
-
// open blocks tab
|
121 |
-
document.getElementById("defaultOpen").click();
|
122 |
-
|
123 |
-
// preload content from a body named input
|
124 |
-
var preloadedContent = jQuery('input[name="message"]').val();
|
125 |
-
if (!preloadedContent) {
|
126 |
-
preloadedContent = jQuery('input[name="options[message]"]').val();
|
127 |
-
}
|
128 |
-
|
129 |
-
if (!preloadedContent) {
|
130 |
-
tnpc_show_presets_modal();
|
131 |
-
} else {
|
132 |
-
jQuery('#newsletter-builder-area-center-frame-content').html(preloadedContent);
|
133 |
-
start_composer();
|
134 |
-
}
|
135 |
-
|
136 |
-
// subject management
|
137 |
-
jQuery('#options-subject').val(jQuery('#tnpc-form input[name="options[subject]"]').val());
|
138 |
-
|
139 |
-
// preheader management
|
140 |
-
jQuery('#options-preheader').val(jQuery('#tnpc-form input[name="options[options_preheader]"]').val());
|
141 |
-
|
142 |
-
// ======================== //
|
143 |
-
// == BACKGROUND COLOR == //
|
144 |
-
// ======================== //
|
145 |
-
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
146 |
-
|
147 |
-
function _setBuilderAreaBackgroundColor(color) {
|
148 |
-
jQuery('#newsletter-builder-area-center-frame-content').css('background-color', color);
|
149 |
-
}
|
150 |
-
|
151 |
-
window._setBuilderAreaBackgroundColor = _setBuilderAreaBackgroundColor; //BAD STUFF!!!
|
152 |
-
|
153 |
-
// ======================== //
|
154 |
-
// == BACKGROUND COLOR == //
|
155 |
-
// ======================== //
|
156 |
-
|
157 |
-
});
|
158 |
-
|
159 |
-
function BuilderAreaHelper() {
|
160 |
-
|
161 |
-
var _builderAreaEl = document.querySelector('#newsletter-builder-area');
|
162 |
-
var _overlayEl = document.createElement('div');
|
163 |
-
_overlayEl.style.zIndex = 99999;
|
164 |
-
_overlayEl.style.position = 'absolute';
|
165 |
-
_overlayEl.style.top = 0;
|
166 |
-
_overlayEl.style.left = 0;
|
167 |
-
_overlayEl.style.width = '100%';
|
168 |
-
_overlayEl.style.height = '100%';
|
169 |
-
|
170 |
-
this.lock = function () {
|
171 |
-
console.log('Lock builder area');
|
172 |
-
_builderAreaEl.appendChild(_overlayEl);
|
173 |
-
}
|
174 |
-
|
175 |
-
this.unlock = function () {
|
176 |
-
console.log('Unlock builder area');
|
177 |
-
_builderAreaEl.removeChild(_overlayEl);
|
178 |
-
}
|
179 |
-
|
180 |
-
}
|
181 |
-
|
182 |
-
let builderAreaHelper = new BuilderAreaHelper();
|
183 |
-
|
184 |
-
function init_builder_area() {
|
185 |
-
|
186 |
-
//Drag & Drop
|
187 |
-
jQuery("#newsletter-builder-area-center-frame-content").sortable({
|
188 |
-
revert: false,
|
189 |
-
placeholder: "placeholder",
|
190 |
-
forcePlaceholderSize: true,
|
191 |
-
opacity: 0.6,
|
192 |
-
tolerance: "pointer",
|
193 |
-
helper: function (e) {
|
194 |
-
var helper = jQuery(document.getElementById("sortable-helper")).clone();
|
195 |
-
return helper;
|
196 |
-
},
|
197 |
-
update: function (event, ui) {
|
198 |
-
if (ui.item.attr("id") == "draggable-helper") {
|
199 |
-
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>');
|
200 |
-
ui.item.before(loading_row);
|
201 |
-
ui.item.remove();
|
202 |
-
var data = new Array(
|
203 |
-
{"name": 'action', "value": 'tnpc_render'},
|
204 |
-
{"name": 'id', "value": ui.item.data("id")},
|
205 |
-
{"name": 'b', "value": ui.item.data("id")},
|
206 |
-
{"name": 'full', "value": 1},
|
207 |
-
{"name": '_wpnonce', "value": tnp_nonce}
|
208 |
-
);
|
209 |
-
|
210 |
-
tnpc_add_global_options(data);
|
211 |
-
|
212 |
-
jQuery.post(ajaxurl, data, function (response) {
|
213 |
-
|
214 |
-
var new_row = jQuery(response);
|
215 |
-
// ui.item.before(new_row);
|
216 |
-
// ui.item.remove();
|
217 |
-
loading_row.before(new_row);
|
218 |
-
loading_row.remove();
|
219 |
-
new_row.add_delete();
|
220 |
-
new_row.add_block_edit();
|
221 |
-
new_row.add_block_clone();
|
222 |
-
// new_row.find(".tnpc-row-edit").hover_edit();
|
223 |
-
if (new_row.hasClass('tnpc-row-block')) {
|
224 |
-
new_row.find(".tnpc-row-edit-block").click();
|
225 |
-
}
|
226 |
-
tnpc_mobile_preview();
|
227 |
-
}).fail(function () {
|
228 |
-
alert("Block rendering failed.");
|
229 |
-
loading_row.remove();
|
230 |
-
});
|
231 |
-
} else {
|
232 |
-
tnpc_mobile_preview();
|
233 |
-
}
|
234 |
-
}
|
235 |
-
});
|
236 |
-
|
237 |
-
jQuery(".newsletter-sidebar-buttons-content-tab").draggable({
|
238 |
-
connectToSortable: "#newsletter-builder-area-center-frame-content",
|
239 |
-
|
240 |
-
// Build the helper for dragging
|
241 |
-
helper: function (e) {
|
242 |
-
var helper = jQuery(document.getElementById("draggable-helper")).clone();
|
243 |
-
// Do not uset .data() with jQuery
|
244 |
-
helper.attr("data-id", e.currentTarget.dataset.id);
|
245 |
-
helper.html(e.currentTarget.dataset.name);
|
246 |
-
return helper;
|
247 |
-
},
|
248 |
-
revert: false,
|
249 |
-
start: function () {
|
250 |
-
if (jQuery('.tnpc-row').length) {
|
251 |
-
} else {
|
252 |
-
jQuery('#newsletter-builder-area-center-frame-content').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
|
253 |
-
}
|
254 |
-
},
|
255 |
-
stop: function (event, ui) {
|
256 |
-
jQuery('.tnpc-drop-here').remove();
|
257 |
-
}
|
258 |
-
});
|
259 |
-
|
260 |
-
jQuery(".tnpc-row").add_delete();
|
261 |
-
jQuery(".tnpc-row").add_block_edit();
|
262 |
-
jQuery(".tnpc-row").add_block_clone();
|
263 |
-
|
264 |
-
}
|
265 |
-
|
266 |
-
function start_composer() {
|
267 |
-
|
268 |
-
init_builder_area();
|
269 |
-
|
270 |
-
// Closes the block options layer (without saving)
|
271 |
-
jQuery("#tnpc-block-options-cancel").click(function () {
|
272 |
-
|
273 |
-
tnpc_hide_block_options();
|
274 |
-
|
275 |
-
var _target = target;
|
276 |
-
|
277 |
-
jQuery.post(ajaxurl, start_options, function (response) {
|
278 |
-
_target.html(response);
|
279 |
-
jQuery("#tnpc-block-options-form").html("");
|
280 |
-
});
|
281 |
-
});
|
282 |
-
|
283 |
-
// Fires the save event for block options
|
284 |
-
jQuery("#tnpc-block-options-save").click(function (e) {
|
285 |
-
e.preventDefault();
|
286 |
-
|
287 |
-
var _target = target;
|
288 |
-
|
289 |
-
// fix for Codemirror
|
290 |
-
if (typeof templateEditor !== 'undefined') {
|
291 |
-
templateEditor.save();
|
292 |
-
}
|
293 |
-
|
294 |
-
if (window.tinymce)
|
295 |
-
window.tinymce.triggerSave();
|
296 |
-
|
297 |
-
var data = jQuery("#tnpc-block-options-form").serializeArray();
|
298 |
-
|
299 |
-
tnpc_add_global_options(data);
|
300 |
-
|
301 |
-
tnpc_hide_block_options();
|
302 |
-
|
303 |
-
jQuery.post(ajaxurl, data, function (response) {
|
304 |
-
_target.html(response);
|
305 |
-
tnpc_mobile_preview();
|
306 |
-
jQuery("#tnpc-block-options-form").html("");
|
307 |
-
});
|
308 |
-
});
|
309 |
-
|
310 |
-
// live preview from block options *** EXPERIMENTAL ***
|
311 |
-
jQuery('#tnpc-block-options-form').change(function (event) {
|
312 |
-
var data = jQuery("#tnpc-block-options-form").serializeArray();
|
313 |
-
|
314 |
-
var _container = container;
|
315 |
-
var _target = target;
|
316 |
-
|
317 |
-
tnpc_add_global_options(data);
|
318 |
-
|
319 |
-
jQuery.post(ajaxurl, data, function (response) {
|
320 |
-
_target.html(response);
|
321 |
-
if (event.target.dataset.afterRendering === 'reload') {
|
322 |
-
_container.find(".tnpc-row-edit-block").click();
|
323 |
-
}
|
324 |
-
}).fail(function () {
|
325 |
-
alert("Block rendering failed");
|
326 |
-
});
|
327 |
-
|
328 |
-
});
|
329 |
-
|
330 |
-
tnpc_mobile_preview();
|
331 |
-
|
332 |
-
}
|
333 |
-
|
334 |
-
function tnpc_show_block_options() {
|
335 |
-
|
336 |
-
const animationDuration = 500;
|
337 |
-
|
338 |
-
//jQuery("#tnpc-blocks").fadeOut(animationDuration);
|
339 |
-
//jQuery("#tnpc-global-styles").fadeOut(animationDuration);
|
340 |
-
//jQuery("#tnpc-mobile-tab").fadeOut(animationDuration);
|
341 |
-
//jQuery("#tnpc-test-tab").fadeOut(animationDuration);
|
342 |
-
|
343 |
-
jQuery("#tnpc-block-options").fadeIn(animationDuration);
|
344 |
-
jQuery("#tnpc-block-options").css('display', 'flex');
|
345 |
-
|
346 |
-
}
|
347 |
-
|
348 |
-
function tnpc_hide_block_options() {
|
349 |
-
|
350 |
-
const animationDuration = 500;
|
351 |
-
|
352 |
-
jQuery("#tnpc-block-options").fadeOut(animationDuration);
|
353 |
-
|
354 |
-
//var $activeTab = jQuery(".tnpc-tabs .tablinks.active");
|
355 |
-
//jQuery('#' + $activeTab.data('tabId')).fadeIn(animationDuration);
|
356 |
-
|
357 |
-
jQuery("#tnpc-block-options-form").html('');
|
358 |
-
|
359 |
-
}
|
360 |
-
|
361 |
-
function tnpc_mobile_preview() {
|
362 |
-
|
363 |
-
return;
|
364 |
-
|
365 |
-
}
|
366 |
-
|
367 |
-
function tnpc_save(form) {
|
368 |
-
|
369 |
-
form.elements["options[message]"].value = tnpc_get_email_content_from_builder_area();
|
370 |
-
|
371 |
-
// When the composer is not showing the subject field (for example in Automated)
|
372 |
-
if (document.getElementById("options-preheader")) {
|
373 |
-
form.elements["options[options_preheader]"].value = jQuery('#options-preheader').val();
|
374 |
-
} else {
|
375 |
-
form.elements["options[options_preheader]"].value = "";
|
376 |
-
}
|
377 |
-
if (document.getElementById("options-subject")) {
|
378 |
-
form.elements["options[subject]"].value = jQuery('#options-subject-subject').val();
|
379 |
-
} else {
|
380 |
-
form.elements["options[subject]"].value = "";
|
381 |
-
}
|
382 |
-
|
383 |
-
var global_form = document.getElementById("tnpc-global-styles-form");
|
384 |
-
//Copy "Global styles" form inputs into main form
|
385 |
-
tnpc_copy_form(global_form, form);
|
386 |
-
|
387 |
-
}
|
388 |
-
|
389 |
-
function tnpc_get_email_content_from_builder_area() {
|
390 |
-
|
391 |
-
var $elMessage = jQuery("#newsletter-builder-area-center-frame-content").clone();
|
392 |
-
|
393 |
-
$elMessage.find('.tnpc-row-delete').remove();
|
394 |
-
$elMessage.find('.tnpc-row-edit-block').remove();
|
395 |
-
$elMessage.find('.tnpc-row-clone').remove();
|
396 |
-
$elMessage.find('.tnpc-row').removeClass('ui-draggable');
|
397 |
-
$elMessage.find('#sortable-helper').remove();
|
398 |
-
|
399 |
-
return $elMessage.html();
|
400 |
-
|
401 |
-
}
|
402 |
-
|
403 |
-
function tnpc_copy_form(source, dest) {
|
404 |
-
for (var i = 0; i < source.elements.length; i++) {
|
405 |
-
var field = document.createElement("input");
|
406 |
-
field.type = "hidden";
|
407 |
-
field.name = source.elements[i].name;
|
408 |
-
field.value = source.elements[i].value;
|
409 |
-
|
410 |
-
// Non clona le select!
|
411 |
-
//var clonedEl = source.elements[i].cloneNode();
|
412 |
-
//clonedEl.style.display = 'none';
|
413 |
-
dest.appendChild(field);
|
414 |
-
}
|
415 |
-
}
|
416 |
-
|
417 |
-
function tnpc_test() {
|
418 |
-
let form = document.getElementById("tnpc-form");
|
419 |
-
tnpc_save(form);
|
420 |
-
form.act.value = "test";
|
421 |
-
form.submit();
|
422 |
-
}
|
423 |
-
|
424 |
-
function openTab(evt, tabName) {
|
425 |
-
evt.preventDefault();
|
426 |
-
// Declare all variables
|
427 |
-
var i, tabcontent, tablinks;
|
428 |
-
|
429 |
-
// Get all elements with class="tabcontent" and hide them
|
430 |
-
tabcontent = document.getElementsByClassName("tabcontent");
|
431 |
-
for (i = 0; i < tabcontent.length; i++) {
|
432 |
-
tabcontent[i].style.display = "none";
|
433 |
-
}
|
434 |
-
|
435 |
-
// Get all elements with class="tablinks" and remove the class "active"
|
436 |
-
tablinks = document.getElementsByClassName("tablinks");
|
437 |
-
for (i = 0; i < tablinks.length; i++) {
|
438 |
-
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
439 |
-
}
|
440 |
-
|
441 |
-
// Show the current tab, and add an "active" class to the button that opened the tab
|
442 |
-
document.getElementById(tabName).style.display = "block";
|
443 |
-
evt.currentTarget.className += " active";
|
444 |
-
}
|
445 |
-
|
446 |
-
function tnpc_scratch() {
|
447 |
-
|
448 |
-
jQuery('#newsletter-builder-area-center-frame-content').html(" ");
|
449 |
-
init_builder_area();
|
450 |
-
|
451 |
-
}
|
452 |
-
|
453 |
-
function tnpc_reload_options(e) {
|
454 |
-
e.preventDefault();
|
455 |
-
let options = jQuery("#tnpc-block-options-form").serializeArray();
|
456 |
-
for (let i = 0; i < options.length; i++) {
|
457 |
-
if (options[i].name === 'action') {
|
458 |
-
options[i].value = 'tnpc_options';
|
459 |
-
}
|
460 |
-
}
|
461 |
-
|
462 |
-
jQuery("#tnpc-block-options-form").load(ajaxurl, options);
|
463 |
-
}
|
464 |
-
|
465 |
-
function tnpc_add_global_options(data) {
|
466 |
-
let globalOptions = jQuery("#tnpc-global-styles-form").serializeArray();
|
467 |
-
for (let i = 0; i < globalOptions.length; i++) {
|
468 |
-
globalOptions[i].name = globalOptions[i].name.replace("[options_", "[").replace("options[", "composer[").replace("composer_", "");
|
469 |
-
if (Array.isArray(data)) {
|
470 |
-
data.push(globalOptions[i]);
|
471 |
-
} else {
|
472 |
-
//Inline edit data format is object not array
|
473 |
-
data[globalOptions[i].name] = globalOptions[i].value;
|
474 |
-
}
|
475 |
-
}
|
476 |
-
}
|
477 |
-
|
478 |
-
// ==================================================== //
|
479 |
-
// ================= PRESET ===================== //
|
480 |
-
// ==================================================== //
|
481 |
-
|
482 |
-
//TODO non va bene tenere nel global space variabili che altri potrebbero accidentalmente modificare/usare
|
483 |
-
// ma questo è un test
|
484 |
-
const toastBottom = new TnpToast({duration: 5000, position: 'bottom right', wrapperPadding: '70px 20px'});
|
485 |
-
|
486 |
-
//TODO - spostare gestione dei preset in contesto privato ma aggiungendo comunque a window le funzioni triggerate da html (load_preset, delete_preset,...) per mantenere compatibilità?
|
487 |
-
const presetListModal = new TNPModal({
|
488 |
-
closeWhenClickOutside: true,
|
489 |
-
showClose: true,
|
490 |
-
style: {
|
491 |
-
backgroundColor: '#ECF0F1',
|
492 |
-
height: '400px',
|
493 |
-
width: '740px',
|
494 |
-
},
|
495 |
-
onClose: function () {
|
496 |
-
start_composer();
|
497 |
-
//Enable buttons
|
498 |
-
jQuery('.tnpc-controls input[type=button]').attr('disabled', false);
|
499 |
-
}
|
500 |
-
});
|
501 |
-
|
502 |
-
function tnpc_show_presets_modal() {
|
503 |
-
|
504 |
-
jQuery('.tnpc-controls input[type=button]').attr('disabled', true);
|
505 |
-
|
506 |
-
const elModalContent = presetListModal.open();
|
507 |
-
|
508 |
-
jQuery.ajax({
|
509 |
-
type: "POST",
|
510 |
-
url: ajaxurl,
|
511 |
-
data: {
|
512 |
-
action: "tnpc_get_all_presets",
|
513 |
-
context_type: tnp_context_type,
|
514 |
-
},
|
515 |
-
success: function (res) {
|
516 |
-
jQuery(elModalContent).html(res.data);
|
517 |
-
},
|
518 |
-
});
|
519 |
-
|
520 |
-
}
|
521 |
-
|
522 |
-
function tnpc_load_preset(id, subject, isEditMode) {
|
523 |
-
|
524 |
-
presetListModal.close();
|
525 |
-
|
526 |
-
jQuery.ajax({
|
527 |
-
type: "POST",
|
528 |
-
url: ajaxurl,
|
529 |
-
data: {
|
530 |
-
action: "tnpc_get_preset",
|
531 |
-
id: id
|
532 |
-
},
|
533 |
-
success: function (res) {
|
534 |
-
jQuery('#newsletter-builder-area-center-frame-content').html(res.data.content);
|
535 |
-
_restore_global_options(res.data.globalOptions);
|
536 |
-
|
537 |
-
start_composer();
|
538 |
-
|
539 |
-
if (!isEditMode) {
|
540 |
-
//Enable buttons
|
541 |
-
jQuery('.tnpc-controls input[type=button]').attr('disabled', false);
|
542 |
-
}
|
543 |
-
|
544 |
-
if (subject && subject.length > 0) {
|
545 |
-
jQuery('#options-subject').val(tnpc_remove_double_quotes_escape_from(subject));
|
546 |
-
}
|
547 |
-
},
|
548 |
-
});
|
549 |
-
|
550 |
-
function _restore_global_options(options) {
|
551 |
-
jQuery.each(options, function (name, value) {
|
552 |
-
var el = jQuery(`#tnpc-global-styles-form #options-options_composer_${name}`);
|
553 |
-
if (el.length) {
|
554 |
-
el.val(value);
|
555 |
-
}
|
556 |
-
});
|
557 |
-
|
558 |
-
tnp_controls_init();
|
559 |
-
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
560 |
-
}
|
561 |
-
|
562 |
-
}
|
563 |
-
|
564 |
-
function tnpc_save_preset(form) {
|
565 |
-
|
566 |
-
const presetName = tnpc_remove_double_quotes_from(document.querySelector('#options-subject').value);
|
567 |
-
|
568 |
-
const presetNameModal = new TNPModal({
|
569 |
-
title: 'Choose a preset name',
|
570 |
-
content: '<input type="text" id="preset_name" style="width: 100%" placeholder="Preset name" value="' + presetName + '"/>',
|
571 |
-
showConfirm: true,
|
572 |
-
clickConfirmOnPressEnter: true,
|
573 |
-
onConfirm: function () {
|
574 |
-
const inputEl = document.querySelector('#preset_name');
|
575 |
-
document.querySelector('#options-subject').value = inputEl.value;
|
576 |
-
tnpc_save(form);
|
577 |
-
form.submit();
|
578 |
-
}
|
579 |
-
});
|
580 |
-
|
581 |
-
presetNameModal.open();
|
582 |
-
|
583 |
-
}
|
584 |
-
|
585 |
-
function tnpc_delete_preset(presetId, name, event) {
|
586 |
-
event.stopPropagation();
|
587 |
-
|
588 |
-
const presetDeleteModal = new TNPModal({
|
589 |
-
title: `Are you sure to delete "${name}" preset?`,
|
590 |
-
confirmText: 'DELETE PRESET',
|
591 |
-
confirmClassName: 'button-secondary button-danger',
|
592 |
-
showConfirm: true,
|
593 |
-
onConfirm: function () {
|
594 |
-
|
595 |
-
const wrapperPresetEl = event.target.closest(".tnpc-preset");
|
596 |
-
|
597 |
-
jQuery.ajax({
|
598 |
-
type: 'POST',
|
599 |
-
dataType: 'json',
|
600 |
-
url: ajaxurl,
|
601 |
-
data: {
|
602 |
-
action: 'tnpc_delete_preset',
|
603 |
-
_wpnonce: tnp_preset_nonce,
|
604 |
-
presetId: presetId
|
605 |
-
},
|
606 |
-
success: function (response) {
|
607 |
-
if (response.success) {
|
608 |
-
wrapperPresetEl.parentNode.removeChild(wrapperPresetEl);
|
609 |
-
toastBottom.success('Preset successfully deleted!');
|
610 |
-
}
|
611 |
-
}
|
612 |
-
});
|
613 |
-
|
614 |
-
}
|
615 |
-
});
|
616 |
-
|
617 |
-
presetDeleteModal.open();
|
618 |
-
|
619 |
-
}
|
620 |
-
|
621 |
-
function tnpc_edit_preset(presetId, name, event) {
|
622 |
-
event.stopPropagation();
|
623 |
-
tnpc_load_preset(presetId, name, true);
|
624 |
-
|
625 |
-
//DISABLE BUTTON AND SHOW UPDATE BUTTON
|
626 |
-
const composerForm = document.querySelector('#tnpc-form');
|
627 |
-
const buttons = composerForm.querySelectorAll('input[type=button]');
|
628 |
-
const updatePresetButton = composerForm.querySelector('#update-preset-button');
|
629 |
-
|
630 |
-
for (btn of buttons) {
|
631 |
-
if (btn.id && btn.id === 'save-preset-button') {
|
632 |
-
btn.style.display = 'none';
|
633 |
-
updatePresetButton.style.display = 'inline';
|
634 |
-
updatePresetButton.disabled = false;
|
635 |
-
} else {
|
636 |
-
btn.disabled = true;
|
637 |
-
}
|
638 |
-
}
|
639 |
-
|
640 |
-
//Add preset id hidden field
|
641 |
-
const presetIdfield = document.createElement("input");
|
642 |
-
presetIdfield.type = "hidden";
|
643 |
-
presetIdfield.name = "preset_id";
|
644 |
-
presetIdfield.value = presetId;
|
645 |
-
composerForm.appendChild(presetIdfield);
|
646 |
-
|
647 |
-
}
|
648 |
-
|
649 |
-
function tnpc_remove_double_quotes_escape_from(str) {
|
650 |
-
return str.replace(/\\"/g, '"');
|
651 |
-
}
|
652 |
-
|
653 |
-
function tnpc_remove_double_quotes_from(str) {
|
654 |
-
return str.replace(/['"]+/g, '');
|
655 |
-
}
|
656 |
-
|
657 |
-
function tnpc_update_preset(form) {
|
658 |
-
|
659 |
-
const presetName = tnpc_remove_double_quotes_from(document.querySelector('#options-subject').value);
|
660 |
-
|
661 |
-
const presetNameModal = new TNPModal({
|
662 |
-
title: 'Choose a preset name',
|
663 |
-
content: '<input type="text" id="preset_name" style="width: 100%" placeholder="Preset name" value="' + presetName + '"/>',
|
664 |
-
showConfirm: true,
|
665 |
-
clickConfirmOnPressEnter: true,
|
666 |
-
onConfirm: function () {
|
667 |
-
const inputEl = document.querySelector('#preset_name');
|
668 |
-
document.querySelector('#options-subject').value = inputEl.value;
|
669 |
-
tnpc_save(form);
|
670 |
-
form.submit();
|
671 |
-
}
|
672 |
-
});
|
673 |
-
|
674 |
-
presetNameModal.open();
|
675 |
-
|
676 |
-
}
|
677 |
-
|
678 |
-
// ========================================================= //
|
679 |
-
// ================= PRESET FINE ===================== //
|
680 |
-
// ========================================================= //
|
681 |
-
|
682 |
-
jQuery(document).ready(function () {
|
683 |
-
'use strict'
|
684 |
-
|
685 |
-
var TNPInlineEditor = (function () {
|
686 |
-
|
687 |
-
var className = 'tnpc-inline-editable';
|
688 |
-
var newInputName = 'new_name';
|
689 |
-
var activeInlineElements = [];
|
690 |
-
|
691 |
-
function init() {
|
692 |
-
// find all inline editable elements
|
693 |
-
jQuery('#newsletter-builder-area-center-frame-content').on('click', '.' + className, function (e) {
|
694 |
-
e.preventDefault();
|
695 |
-
removeAllActiveElements();
|
696 |
-
|
697 |
-
var originalEl = jQuery(this).hide();
|
698 |
-
var newEl = jQuery(getEditableComponent(this.innerText.trim(), this.dataset.id, this.dataset.type, originalEl)).insertAfter(this);
|
699 |
-
|
700 |
-
activeInlineElements.push({'originalEl': originalEl, 'newEl': newEl});
|
701 |
-
|
702 |
-
//Add submit event listener for newly created block
|
703 |
-
jQuery('.tnpc-inline-editable-form-' + this.dataset.type + this.dataset.id).on('submit', function (e) {
|
704 |
-
submit(e, newEl, jQuery(originalEl));
|
705 |
-
});
|
706 |
-
|
707 |
-
//Add close event listener for newly created block
|
708 |
-
jQuery('.tnpc-inline-editable-form-actions .tnpc-dismiss-' + this.dataset.type + this.dataset.id).on('click', function (e) {
|
709 |
-
removeAllActiveElements();
|
710 |
-
});
|
711 |
-
|
712 |
-
});
|
713 |
-
|
714 |
-
// Close all created elements if clicked outside
|
715 |
-
jQuery('#newsletter-builder-area-center-frame-content').on('click', function (e) {
|
716 |
-
if (activeInlineElements.length > 0
|
717 |
-
&& !jQuery(e.target).hasClass(className)
|
718 |
-
&& jQuery(e.target).closest('.tnpc-inline-editable-container').length === 0) {
|
719 |
-
removeAllActiveElements();
|
720 |
-
}
|
721 |
-
});
|
722 |
-
|
723 |
-
}
|
724 |
-
|
725 |
-
function removeAllActiveElements() {
|
726 |
-
activeInlineElements.forEach(function (obj) {
|
727 |
-
obj.originalEl.show();
|
728 |
-
|
729 |
-
obj.newEl.off();
|
730 |
-
obj.newEl.remove();
|
731 |
-
});
|
732 |
-
|
733 |
-
activeInlineElements = []
|
734 |
-
}
|
735 |
-
|
736 |
-
function getEditableComponent(value, id, type, originalEl) {
|
737 |
-
|
738 |
-
var element = '';
|
739 |
-
|
740 |
-
//COPY FONT STYLE FROM ORIGINAL ELEMENT
|
741 |
-
var fontFamily = originalEl.css('font-family');
|
742 |
-
var fontSize = originalEl.css('font-size');
|
743 |
-
var styleAttr = "style='font-family:" + fontFamily + ";font-size:" + fontSize + ";'";
|
744 |
-
|
745 |
-
switch (type) {
|
746 |
-
case 'text':
|
747 |
-
{
|
748 |
-
element = "<textarea name='" + newInputName + "' class='" + className + "-textarea' rows='5' " + styleAttr + ">" + value + "</textarea>";
|
749 |
-
break;
|
750 |
-
}
|
751 |
-
case 'title':
|
752 |
-
{
|
753 |
-
element = "<textarea name='" + newInputName + "' class='" + className + "-textarea' rows='2'" + styleAttr + ">" + value + "</textarea>";
|
754 |
-
break;
|
755 |
-
}
|
756 |
-
}
|
757 |
-
|
758 |
-
var component = "<td>";
|
759 |
-
component += "<form class='tnpc-inline-editable-form tnpc-inline-editable-form-" + type + id + "'>";
|
760 |
-
component += "<input type='hidden' name='id' value='" + id + "'>";
|
761 |
-
component += "<input type='hidden' name='type' value='" + type + "'>";
|
762 |
-
component += "<input type='hidden' name='old_value' value='" + value + "'>";
|
763 |
-
component += "<div class='tnpc-inline-editable-container'>";
|
764 |
-
component += element;
|
765 |
-
component += "<div class='tnpc-inline-editable-form-actions'>";
|
766 |
-
component += "<button type='submit'><span class='dashicons dashicons-yes-alt' title='save'></span></button>";
|
767 |
-
component += "<span class='dashicons dashicons-dismiss tnpc-dismiss-" + type + id + "' title='close'></span>";
|
768 |
-
component += "</div>";
|
769 |
-
component += "</div>";
|
770 |
-
component += "</form>";
|
771 |
-
component += "</td>";
|
772 |
-
return component;
|
773 |
-
}
|
774 |
-
|
775 |
-
function submit(e, elementToDeleteAfterSubmit, elementToShow) {
|
776 |
-
e.preventDefault();
|
777 |
-
|
778 |
-
var id = elementToDeleteAfterSubmit.find('form input[name=id]').val();
|
779 |
-
var type = elementToDeleteAfterSubmit.find('form input[name=type]').val();
|
780 |
-
var newValue = elementToDeleteAfterSubmit.find('form [name="' + newInputName + '"]').val();
|
781 |
-
|
782 |
-
ajax_render_block(elementToShow, type, id, newValue);
|
783 |
-
|
784 |
-
elementToDeleteAfterSubmit.remove();
|
785 |
-
elementToShow.show();
|
786 |
-
|
787 |
-
}
|
788 |
-
|
789 |
-
function ajax_render_block(inlineElement, type, postId, newContent) {
|
790 |
-
|
791 |
-
var target = inlineElement.closest('.edit-block');
|
792 |
-
var container = target.closest('table');
|
793 |
-
var blockContent = target.children('.tnpc-block-content');
|
794 |
-
|
795 |
-
if (container.hasClass('tnpc-row-block')) {
|
796 |
-
var data = {
|
797 |
-
'action': 'tnpc_render',
|
798 |
-
'id': container.data('id'),
|
799 |
-
'b': container.data('id'),
|
800 |
-
'full': 1,
|
801 |
-
'_wpnonce': tnp_nonce,
|
802 |
-
'options': {
|
803 |
-
'inline_edits': [{
|
804 |
-
'type': type,
|
805 |
-
'post_id': postId,
|
806 |
-
'content': newContent
|
807 |
-
}]
|
808 |
-
},
|
809 |
-
'encoded_options': blockContent.data('json')
|
810 |
-
};
|
811 |
-
|
812 |
-
tnpc_add_global_options(data);
|
813 |
-
|
814 |
-
jQuery.post(ajaxurl, data, function (response) {
|
815 |
-
var new_row = jQuery(response);
|
816 |
-
|
817 |
-
container.before(new_row);
|
818 |
-
container.remove();
|
819 |
-
|
820 |
-
new_row.add_delete();
|
821 |
-
new_row.add_block_edit();
|
822 |
-
new_row.add_block_clone();
|
823 |
-
|
824 |
-
//Force reload options
|
825 |
-
if (new_row.hasClass('tnpc-row-block')) {
|
826 |
-
new_row.find(".tnpc-row-edit-block").click();
|
827 |
-
}
|
828 |
-
|
829 |
-
tnpc_mobile_preview();
|
830 |
-
|
831 |
-
}).fail(function () {
|
832 |
-
alert("Block rendering failed.");
|
833 |
-
});
|
834 |
-
|
835 |
-
}
|
836 |
-
|
837 |
-
}
|
838 |
-
|
839 |
-
return {init};
|
840 |
-
})();
|
841 |
-
|
842 |
-
TNPInlineEditor.init();
|
843 |
-
|
844 |
-
});
|
845 |
-
|
846 |
-
// =================================================== //
|
847 |
-
// =============== GLOBAL STYLE ================== //
|
848 |
-
// =================================================== //
|
849 |
-
|
850 |
-
(function globalStyleIIFE() {
|
851 |
-
|
852 |
-
var _elTrigger = document.querySelector('#tnpc-global-styles-form [name="apply"]');
|
853 |
-
|
854 |
-
_elTrigger.addEventListener('click', function (e) {
|
855 |
-
e.preventDefault();
|
856 |
-
|
857 |
-
var data = {
|
858 |
-
'action': 'tnpc_regenerate_email',
|
859 |
-
'content': tnpc_get_email_content_from_builder_area(),
|
860 |
-
'_wpnonce': tnp_nonce,
|
861 |
-
};
|
862 |
-
|
863 |
-
tnpc_add_global_options(data);
|
864 |
-
|
865 |
-
jQuery.post(ajaxurl, data, function (response) {
|
866 |
-
if (response && response.success) {
|
867 |
-
jQuery('#newsletter-builder-area-center-frame-content').html(response.data.content);
|
868 |
-
//Change background color of builder area
|
869 |
-
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
870 |
-
init_builder_area();
|
871 |
-
tnpc_mobile_preview();
|
872 |
-
|
873 |
-
toastBottom.success(response.data.message);
|
874 |
-
} else {
|
875 |
-
toastBottom.error(response.data.message);
|
876 |
-
}
|
877 |
-
});
|
878 |
-
|
879 |
-
});
|
880 |
-
|
881 |
-
})();
|
882 |
-
|
883 |
-
// ========================================================= //
|
884 |
-
// ================= SEND A TEST ===================== //
|
885 |
-
// ========================================================= //
|
886 |
-
|
887 |
-
(function sendATestIIFE($) {
|
888 |
-
|
889 |
-
var testNewsletterWithEmailFormId = '#test-newsletter-form';
|
890 |
-
var testNewsletterWithEmailForm = document.querySelector(testNewsletterWithEmailFormId);
|
891 |
-
testNewsletterWithEmailForm.addEventListener('submit', function (e) {
|
892 |
-
e.preventDefault();
|
893 |
-
var testEmail = testNewsletterWithEmailForm.querySelector('input[name="email"]').value;
|
894 |
-
|
895 |
-
let form = document.getElementById("tnpc-form");
|
896 |
-
tnpc_save(form);
|
897 |
-
|
898 |
-
form.act.value = "send-test-to-email-address";
|
899 |
-
var input = document.createElement("input");
|
900 |
-
input.setAttribute("type", "hidden");
|
901 |
-
input.setAttribute("name", "test_address_email");
|
902 |
-
input.setAttribute("value", testEmail);
|
903 |
-
form.appendChild(input);
|
904 |
-
|
905 |
-
form.submit();
|
906 |
-
});
|
907 |
-
|
908 |
-
})(jQuery);
|
909 |
-
|
910 |
-
// ================================================================== //
|
911 |
-
// ================= SUBJECT LENGTH ICONS ===================== //
|
912 |
-
// ================================================================== //
|
913 |
-
|
914 |
-
(function subjectLengthIconsIIFE($) {
|
915 |
-
var $subjectContainer = $('#tnpc-subject');
|
916 |
-
var $subjectInput = $('#tnpc-subject input');
|
917 |
-
var subjectCharCounterEl = null;
|
918 |
-
|
919 |
-
$subjectInput.on('focusin', function (e) {
|
920 |
-
$subjectContainer.find('img').fadeTo(400, 1);
|
921 |
-
});
|
922 |
-
|
923 |
-
$subjectInput.on('keyup', function (e) {
|
924 |
-
setSubjectCharactersLenght(this.value.length);
|
925 |
-
});
|
926 |
-
|
927 |
-
$subjectInput.on('focusout', function (e) {
|
928 |
-
$subjectContainer.find('img').fadeTo(300, 0);
|
929 |
-
});
|
930 |
-
|
931 |
-
function setSubjectCharactersLenght(length = 0) {
|
932 |
-
|
933 |
-
if (length === 0 && subjectCharCounterEl !== null) {
|
934 |
-
subjectCharCounterEl.remove();
|
935 |
-
subjectCharCounterEl = null;
|
936 |
-
return;
|
937 |
-
}
|
938 |
-
|
939 |
-
if (!subjectCharCounterEl) {
|
940 |
-
subjectCharCounterEl = document.createElement("span");
|
941 |
-
subjectCharCounterEl.style.position = 'absolute';
|
942 |
-
subjectCharCounterEl.style.top = '-18px';
|
943 |
-
subjectCharCounterEl.style.right = $subjectContainer[0].getBoundingClientRect().width - $subjectInput[0].getBoundingClientRect().width + 'px';
|
944 |
-
subjectCharCounterEl.style.color = '#999';
|
945 |
-
subjectCharCounterEl.style.fontSize = '0.8rem';
|
946 |
-
$subjectContainer.find('div')[0].appendChild(subjectCharCounterEl);
|
947 |
-
}
|
948 |
-
|
949 |
-
const word = length === 1 ? 'character' : 'characters';
|
950 |
-
subjectCharCounterEl.innerHTML = `${length} ${word}`;
|
951 |
-
}
|
952 |
-
|
953 |
-
})(jQuery);
|
954 |
-
|
955 |
-
// ======================================================================= //
|
956 |
-
// ================= COMPOSER MODE VIEW SWITCH ===================== //
|
957 |
-
// ======================================================================= //
|
958 |
-
|
959 |
-
(function composerModeViewIIFE($) {
|
960 |
-
const activeClass = 'composer-view-mode__item--active';
|
961 |
-
var status = 'desktop';
|
962 |
-
|
963 |
-
$('.composer-view-mode__item[data-view-mode="' + status + '"]').addClass(activeClass);
|
964 |
-
|
965 |
-
$('.composer-view-mode__item').on('click', function () {
|
966 |
-
var $el = $(this);
|
967 |
-
|
968 |
-
if ($el.data('viewMode') === 'desktop') {
|
969 |
-
status = 'desktop';
|
970 |
-
$('.composer-view-mode__item[data-view-mode="desktop"]').addClass(activeClass);
|
971 |
-
$('.composer-view-mode__item[data-view-mode="mobile"]').removeClass(activeClass);
|
972 |
-
} else if ($el.data('viewMode') === 'mobile') {
|
973 |
-
status = 'mobile';
|
974 |
-
$('.composer-view-mode__item[data-view-mode="desktop"]').removeClass(activeClass);
|
975 |
-
$('.composer-view-mode__item[data-view-mode="mobile"]').addClass(activeClass);
|
976 |
-
}
|
977 |
-
|
978 |
-
tnp_view(status);
|
979 |
-
});
|
980 |
-
})(jQuery);
|
1 |
+
// add delete buttons
|
2 |
+
jQuery.fn.add_delete = function () {
|
3 |
+
this.append('<div class="tnpc-row-delete" title="Delete"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/delete.png" width="32"></div>');
|
4 |
+
this.find('.tnpc-row-delete').perform_delete();
|
5 |
+
};
|
6 |
+
|
7 |
+
// delete row
|
8 |
+
jQuery.fn.perform_delete = function () {
|
9 |
+
this.click(function () {
|
10 |
+
tnpc_hide_block_options();
|
11 |
+
// remove block
|
12 |
+
jQuery(this).parent().remove();
|
13 |
+
tnpc_mobile_preview();
|
14 |
+
});
|
15 |
+
}
|
16 |
+
|
17 |
+
// add edit button
|
18 |
+
jQuery.fn.add_block_edit = function () {
|
19 |
+
this.append('<div class="tnpc-row-edit-block" title="Edit"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/edit.png" width="32"></div>');
|
20 |
+
this.find('.tnpc-row-edit-block').perform_block_edit();
|
21 |
+
}
|
22 |
+
|
23 |
+
// edit block
|
24 |
+
jQuery.fn.perform_block_edit = function () {
|
25 |
+
|
26 |
+
jQuery(".tnpc-row-edit-block").click(function (e) {
|
27 |
+
e.preventDefault()
|
28 |
+
});
|
29 |
+
|
30 |
+
this.click(function (e) {
|
31 |
+
|
32 |
+
e.preventDefault();
|
33 |
+
|
34 |
+
target = jQuery(this).parent().find('.edit-block');
|
35 |
+
|
36 |
+
// The row container which is a global variable and used later after the options save
|
37 |
+
container = jQuery(this).closest("table");
|
38 |
+
|
39 |
+
if (container.hasClass('tnpc-row-block')) {
|
40 |
+
|
41 |
+
tnpc_show_block_options();
|
42 |
+
|
43 |
+
var options = container.find(".tnpc-block-content").attr("data-json");
|
44 |
+
|
45 |
+
// Compatibility
|
46 |
+
if (!options) {
|
47 |
+
options = target.attr("data-options");
|
48 |
+
}
|
49 |
+
|
50 |
+
var data = {
|
51 |
+
action: "tnpc_options",
|
52 |
+
id: container.data("id"),
|
53 |
+
context_type: tnp_context_type,
|
54 |
+
options: options
|
55 |
+
};
|
56 |
+
|
57 |
+
tnpc_add_global_options(data);
|
58 |
+
|
59 |
+
builderAreaHelper.lock();
|
60 |
+
jQuery("#tnpc-block-options-form").load(ajaxurl, data, function () {
|
61 |
+
console.log('Block form options loaded');
|
62 |
+
start_options = jQuery("#tnpc-block-options-form").serializeArray();
|
63 |
+
tnpc_add_global_options(start_options);
|
64 |
+
builderAreaHelper.unlock();
|
65 |
+
});
|
66 |
+
|
67 |
+
} else {
|
68 |
+
alert("This is deprecated block version and cannot be edited. Please replace it with a new one.");
|
69 |
+
}
|
70 |
+
|
71 |
+
});
|
72 |
+
|
73 |
+
};
|
74 |
+
|
75 |
+
// add clone button
|
76 |
+
jQuery.fn.add_block_clone = function () {
|
77 |
+
this.append('<div class="tnpc-row-clone" title="Clone"><img src="' + TNP_PLUGIN_URL + '/emails/tnp-composer/_assets/copy.png" width="32"></div>');
|
78 |
+
this.find('.tnpc-row-clone').perform_clone();
|
79 |
+
}
|
80 |
+
|
81 |
+
// clone block
|
82 |
+
jQuery.fn.perform_clone = function () {
|
83 |
+
|
84 |
+
jQuery(".tnpc-row-clone").click(function (e) {
|
85 |
+
e.preventDefault()
|
86 |
+
});
|
87 |
+
|
88 |
+
this.click(function (e) {
|
89 |
+
|
90 |
+
e.preventDefault();
|
91 |
+
|
92 |
+
// hide block edit form
|
93 |
+
tnpc_hide_block_options();
|
94 |
+
|
95 |
+
// find the row
|
96 |
+
let row = jQuery(this).closest('.tnpc-row');
|
97 |
+
|
98 |
+
// clone the block
|
99 |
+
let new_row = row.clone();
|
100 |
+
new_row.find(".tnpc-row-delete").remove();
|
101 |
+
new_row.find(".tnpc-row-edit-block").remove();
|
102 |
+
new_row.find(".tnpc-row-clone").remove();
|
103 |
+
|
104 |
+
new_row.add_delete();
|
105 |
+
new_row.add_block_edit();
|
106 |
+
new_row.add_block_clone();
|
107 |
+
// if (new_row.hasClass('tnpc-row-block')) {
|
108 |
+
// new_row.find(".tnpc-row-edit-block i").click();
|
109 |
+
// }
|
110 |
+
new_row.insertAfter(row);
|
111 |
+
tnpc_mobile_preview();
|
112 |
+
});
|
113 |
+
};
|
114 |
+
|
115 |
+
let start_options = null;
|
116 |
+
let container = null;
|
117 |
+
|
118 |
+
jQuery(function () {
|
119 |
+
|
120 |
+
// open blocks tab
|
121 |
+
document.getElementById("defaultOpen").click();
|
122 |
+
|
123 |
+
// preload content from a body named input
|
124 |
+
var preloadedContent = jQuery('input[name="message"]').val();
|
125 |
+
if (!preloadedContent) {
|
126 |
+
preloadedContent = jQuery('input[name="options[message]"]').val();
|
127 |
+
}
|
128 |
+
|
129 |
+
if (!preloadedContent) {
|
130 |
+
tnpc_show_presets_modal();
|
131 |
+
} else {
|
132 |
+
jQuery('#newsletter-builder-area-center-frame-content').html(preloadedContent);
|
133 |
+
start_composer();
|
134 |
+
}
|
135 |
+
|
136 |
+
// subject management
|
137 |
+
jQuery('#options-subject').val(jQuery('#tnpc-form input[name="options[subject]"]').val());
|
138 |
+
|
139 |
+
// preheader management
|
140 |
+
jQuery('#options-preheader').val(jQuery('#tnpc-form input[name="options[options_preheader]"]').val());
|
141 |
+
|
142 |
+
// ======================== //
|
143 |
+
// == BACKGROUND COLOR == //
|
144 |
+
// ======================== //
|
145 |
+
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
146 |
+
|
147 |
+
function _setBuilderAreaBackgroundColor(color) {
|
148 |
+
jQuery('#newsletter-builder-area-center-frame-content').css('background-color', color);
|
149 |
+
}
|
150 |
+
|
151 |
+
window._setBuilderAreaBackgroundColor = _setBuilderAreaBackgroundColor; //BAD STUFF!!!
|
152 |
+
|
153 |
+
// ======================== //
|
154 |
+
// == BACKGROUND COLOR == //
|
155 |
+
// ======================== //
|
156 |
+
|
157 |
+
});
|
158 |
+
|
159 |
+
function BuilderAreaHelper() {
|
160 |
+
|
161 |
+
var _builderAreaEl = document.querySelector('#newsletter-builder-area');
|
162 |
+
var _overlayEl = document.createElement('div');
|
163 |
+
_overlayEl.style.zIndex = 99999;
|
164 |
+
_overlayEl.style.position = 'absolute';
|
165 |
+
_overlayEl.style.top = 0;
|
166 |
+
_overlayEl.style.left = 0;
|
167 |
+
_overlayEl.style.width = '100%';
|
168 |
+
_overlayEl.style.height = '100%';
|
169 |
+
|
170 |
+
this.lock = function () {
|
171 |
+
console.log('Lock builder area');
|
172 |
+
_builderAreaEl.appendChild(_overlayEl);
|
173 |
+
}
|
174 |
+
|
175 |
+
this.unlock = function () {
|
176 |
+
console.log('Unlock builder area');
|
177 |
+
_builderAreaEl.removeChild(_overlayEl);
|
178 |
+
}
|
179 |
+
|
180 |
+
}
|
181 |
+
|
182 |
+
let builderAreaHelper = new BuilderAreaHelper();
|
183 |
+
|
184 |
+
function init_builder_area() {
|
185 |
+
|
186 |
+
//Drag & Drop
|
187 |
+
jQuery("#newsletter-builder-area-center-frame-content").sortable({
|
188 |
+
revert: false,
|
189 |
+
placeholder: "placeholder",
|
190 |
+
forcePlaceholderSize: true,
|
191 |
+
opacity: 0.6,
|
192 |
+
tolerance: "pointer",
|
193 |
+
helper: function (e) {
|
194 |
+
var helper = jQuery(document.getElementById("sortable-helper")).clone();
|
195 |
+
return helper;
|
196 |
+
},
|
197 |
+
update: function (event, ui) {
|
198 |
+
if (ui.item.attr("id") == "draggable-helper") {
|
199 |
+
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>');
|
200 |
+
ui.item.before(loading_row);
|
201 |
+
ui.item.remove();
|
202 |
+
var data = new Array(
|
203 |
+
{"name": 'action', "value": 'tnpc_render'},
|
204 |
+
{"name": 'id', "value": ui.item.data("id")},
|
205 |
+
{"name": 'b', "value": ui.item.data("id")},
|
206 |
+
{"name": 'full', "value": 1},
|
207 |
+
{"name": '_wpnonce', "value": tnp_nonce}
|
208 |
+
);
|
209 |
+
|
210 |
+
tnpc_add_global_options(data);
|
211 |
+
|
212 |
+
jQuery.post(ajaxurl, data, function (response) {
|
213 |
+
|
214 |
+
var new_row = jQuery(response);
|
215 |
+
// ui.item.before(new_row);
|
216 |
+
// ui.item.remove();
|
217 |
+
loading_row.before(new_row);
|
218 |
+
loading_row.remove();
|
219 |
+
new_row.add_delete();
|
220 |
+
new_row.add_block_edit();
|
221 |
+
new_row.add_block_clone();
|
222 |
+
// new_row.find(".tnpc-row-edit").hover_edit();
|
223 |
+
if (new_row.hasClass('tnpc-row-block')) {
|
224 |
+
new_row.find(".tnpc-row-edit-block").click();
|
225 |
+
}
|
226 |
+
tnpc_mobile_preview();
|
227 |
+
}).fail(function () {
|
228 |
+
alert("Block rendering failed.");
|
229 |
+
loading_row.remove();
|
230 |
+
});
|
231 |
+
} else {
|
232 |
+
tnpc_mobile_preview();
|
233 |
+
}
|
234 |
+
}
|
235 |
+
});
|
236 |
+
|
237 |
+
jQuery(".newsletter-sidebar-buttons-content-tab").draggable({
|
238 |
+
connectToSortable: "#newsletter-builder-area-center-frame-content",
|
239 |
+
|
240 |
+
// Build the helper for dragging
|
241 |
+
helper: function (e) {
|
242 |
+
var helper = jQuery(document.getElementById("draggable-helper")).clone();
|
243 |
+
// Do not uset .data() with jQuery
|
244 |
+
helper.attr("data-id", e.currentTarget.dataset.id);
|
245 |
+
helper.html(e.currentTarget.dataset.name);
|
246 |
+
return helper;
|
247 |
+
},
|
248 |
+
revert: false,
|
249 |
+
start: function () {
|
250 |
+
if (jQuery('.tnpc-row').length) {
|
251 |
+
} else {
|
252 |
+
jQuery('#newsletter-builder-area-center-frame-content').append('<div class="tnpc-drop-here">Drag&Drop blocks here!</div>');
|
253 |
+
}
|
254 |
+
},
|
255 |
+
stop: function (event, ui) {
|
256 |
+
jQuery('.tnpc-drop-here').remove();
|
257 |
+
}
|
258 |
+
});
|
259 |
+
|
260 |
+
jQuery(".tnpc-row").add_delete();
|
261 |
+
jQuery(".tnpc-row").add_block_edit();
|
262 |
+
jQuery(".tnpc-row").add_block_clone();
|
263 |
+
|
264 |
+
}
|
265 |
+
|
266 |
+
function start_composer() {
|
267 |
+
|
268 |
+
init_builder_area();
|
269 |
+
|
270 |
+
// Closes the block options layer (without saving)
|
271 |
+
jQuery("#tnpc-block-options-cancel").click(function () {
|
272 |
+
|
273 |
+
tnpc_hide_block_options();
|
274 |
+
|
275 |
+
var _target = target;
|
276 |
+
|
277 |
+
jQuery.post(ajaxurl, start_options, function (response) {
|
278 |
+
_target.html(response);
|
279 |
+
jQuery("#tnpc-block-options-form").html("");
|
280 |
+
});
|
281 |
+
});
|
282 |
+
|
283 |
+
// Fires the save event for block options
|
284 |
+
jQuery("#tnpc-block-options-save").click(function (e) {
|
285 |
+
e.preventDefault();
|
286 |
+
|
287 |
+
var _target = target;
|
288 |
+
|
289 |
+
// fix for Codemirror
|
290 |
+
if (typeof templateEditor !== 'undefined') {
|
291 |
+
templateEditor.save();
|
292 |
+
}
|
293 |
+
|
294 |
+
if (window.tinymce)
|
295 |
+
window.tinymce.triggerSave();
|
296 |
+
|
297 |
+
var data = jQuery("#tnpc-block-options-form").serializeArray();
|
298 |
+
|
299 |
+
tnpc_add_global_options(data);
|
300 |
+
|
301 |
+
tnpc_hide_block_options();
|
302 |
+
|
303 |
+
jQuery.post(ajaxurl, data, function (response) {
|
304 |
+
_target.html(response);
|
305 |
+
tnpc_mobile_preview();
|
306 |
+
jQuery("#tnpc-block-options-form").html("");
|
307 |
+
});
|
308 |
+
});
|
309 |
+
|
310 |
+
// live preview from block options *** EXPERIMENTAL ***
|
311 |
+
jQuery('#tnpc-block-options-form').change(function (event) {
|
312 |
+
var data = jQuery("#tnpc-block-options-form").serializeArray();
|
313 |
+
|
314 |
+
var _container = container;
|
315 |
+
var _target = target;
|
316 |
+
|
317 |
+
tnpc_add_global_options(data);
|
318 |
+
|
319 |
+
jQuery.post(ajaxurl, data, function (response) {
|
320 |
+
_target.html(response);
|
321 |
+
if (event.target.dataset.afterRendering === 'reload') {
|
322 |
+
_container.find(".tnpc-row-edit-block").click();
|
323 |
+
}
|
324 |
+
}).fail(function () {
|
325 |
+
alert("Block rendering failed");
|
326 |
+
});
|
327 |
+
|
328 |
+
});
|
329 |
+
|
330 |
+
tnpc_mobile_preview();
|
331 |
+
|
332 |
+
}
|
333 |
+
|
334 |
+
function tnpc_show_block_options() {
|
335 |
+
|
336 |
+
const animationDuration = 500;
|
337 |
+
|
338 |
+
//jQuery("#tnpc-blocks").fadeOut(animationDuration);
|
339 |
+
//jQuery("#tnpc-global-styles").fadeOut(animationDuration);
|
340 |
+
//jQuery("#tnpc-mobile-tab").fadeOut(animationDuration);
|
341 |
+
//jQuery("#tnpc-test-tab").fadeOut(animationDuration);
|
342 |
+
|
343 |
+
jQuery("#tnpc-block-options").fadeIn(animationDuration);
|
344 |
+
jQuery("#tnpc-block-options").css('display', 'flex');
|
345 |
+
|
346 |
+
}
|
347 |
+
|
348 |
+
function tnpc_hide_block_options() {
|
349 |
+
|
350 |
+
const animationDuration = 500;
|
351 |
+
|
352 |
+
jQuery("#tnpc-block-options").fadeOut(animationDuration);
|
353 |
+
|
354 |
+
//var $activeTab = jQuery(".tnpc-tabs .tablinks.active");
|
355 |
+
//jQuery('#' + $activeTab.data('tabId')).fadeIn(animationDuration);
|
356 |
+
|
357 |
+
jQuery("#tnpc-block-options-form").html('');
|
358 |
+
|
359 |
+
}
|
360 |
+
|
361 |
+
function tnpc_mobile_preview() {
|
362 |
+
|
363 |
+
return;
|
364 |
+
|
365 |
+
}
|
366 |
+
|
367 |
+
function tnpc_save(form) {
|
368 |
+
|
369 |
+
form.elements["options[message]"].value = tnpc_get_email_content_from_builder_area();
|
370 |
+
|
371 |
+
// When the composer is not showing the subject field (for example in Automated)
|
372 |
+
if (document.getElementById("options-preheader")) {
|
373 |
+
form.elements["options[options_preheader]"].value = jQuery('#options-preheader').val();
|
374 |
+
} else {
|
375 |
+
form.elements["options[options_preheader]"].value = "";
|
376 |
+
}
|
377 |
+
if (document.getElementById("options-subject")) {
|
378 |
+
form.elements["options[subject]"].value = jQuery('#options-subject-subject').val();
|
379 |
+
} else {
|
380 |
+
form.elements["options[subject]"].value = "";
|
381 |
+
}
|
382 |
+
|
383 |
+
var global_form = document.getElementById("tnpc-global-styles-form");
|
384 |
+
//Copy "Global styles" form inputs into main form
|
385 |
+
tnpc_copy_form(global_form, form);
|
386 |
+
|
387 |
+
}
|
388 |
+
|
389 |
+
function tnpc_get_email_content_from_builder_area() {
|
390 |
+
|
391 |
+
var $elMessage = jQuery("#newsletter-builder-area-center-frame-content").clone();
|
392 |
+
|
393 |
+
$elMessage.find('.tnpc-row-delete').remove();
|
394 |
+
$elMessage.find('.tnpc-row-edit-block').remove();
|
395 |
+
$elMessage.find('.tnpc-row-clone').remove();
|
396 |
+
$elMessage.find('.tnpc-row').removeClass('ui-draggable');
|
397 |
+
$elMessage.find('#sortable-helper').remove();
|
398 |
+
|
399 |
+
return $elMessage.html();
|
400 |
+
|
401 |
+
}
|
402 |
+
|
403 |
+
function tnpc_copy_form(source, dest) {
|
404 |
+
for (var i = 0; i < source.elements.length; i++) {
|
405 |
+
var field = document.createElement("input");
|
406 |
+
field.type = "hidden";
|
407 |
+
field.name = source.elements[i].name;
|
408 |
+
field.value = source.elements[i].value;
|
409 |
+
|
410 |
+
// Non clona le select!
|
411 |
+
//var clonedEl = source.elements[i].cloneNode();
|
412 |
+
//clonedEl.style.display = 'none';
|
413 |
+
dest.appendChild(field);
|
414 |
+
}
|
415 |
+
}
|
416 |
+
|
417 |
+
function tnpc_test() {
|
418 |
+
let form = document.getElementById("tnpc-form");
|
419 |
+
tnpc_save(form);
|
420 |
+
form.act.value = "test";
|
421 |
+
form.submit();
|
422 |
+
}
|
423 |
+
|
424 |
+
function openTab(evt, tabName) {
|
425 |
+
evt.preventDefault();
|
426 |
+
// Declare all variables
|
427 |
+
var i, tabcontent, tablinks;
|
428 |
+
|
429 |
+
// Get all elements with class="tabcontent" and hide them
|
430 |
+
tabcontent = document.getElementsByClassName("tabcontent");
|
431 |
+
for (i = 0; i < tabcontent.length; i++) {
|
432 |
+
tabcontent[i].style.display = "none";
|
433 |
+
}
|
434 |
+
|
435 |
+
// Get all elements with class="tablinks" and remove the class "active"
|
436 |
+
tablinks = document.getElementsByClassName("tablinks");
|
437 |
+
for (i = 0; i < tablinks.length; i++) {
|
438 |
+
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
439 |
+
}
|
440 |
+
|
441 |
+
// Show the current tab, and add an "active" class to the button that opened the tab
|
442 |
+
document.getElementById(tabName).style.display = "block";
|
443 |
+
evt.currentTarget.className += " active";
|
444 |
+
}
|
445 |
+
|
446 |
+
function tnpc_scratch() {
|
447 |
+
|
448 |
+
jQuery('#newsletter-builder-area-center-frame-content').html(" ");
|
449 |
+
init_builder_area();
|
450 |
+
|
451 |
+
}
|
452 |
+
|
453 |
+
function tnpc_reload_options(e) {
|
454 |
+
e.preventDefault();
|
455 |
+
let options = jQuery("#tnpc-block-options-form").serializeArray();
|
456 |
+
for (let i = 0; i < options.length; i++) {
|
457 |
+
if (options[i].name === 'action') {
|
458 |
+
options[i].value = 'tnpc_options';
|
459 |
+
}
|
460 |
+
}
|
461 |
+
|
462 |
+
jQuery("#tnpc-block-options-form").load(ajaxurl, options);
|
463 |
+
}
|
464 |
+
|
465 |
+
function tnpc_add_global_options(data) {
|
466 |
+
let globalOptions = jQuery("#tnpc-global-styles-form").serializeArray();
|
467 |
+
for (let i = 0; i < globalOptions.length; i++) {
|
468 |
+
globalOptions[i].name = globalOptions[i].name.replace("[options_", "[").replace("options[", "composer[").replace("composer_", "");
|
469 |
+
if (Array.isArray(data)) {
|
470 |
+
data.push(globalOptions[i]);
|
471 |
+
} else {
|
472 |
+
//Inline edit data format is object not array
|
473 |
+
data[globalOptions[i].name] = globalOptions[i].value;
|
474 |
+
}
|
475 |
+
}
|
476 |
+
}
|
477 |
+
|
478 |
+
// ==================================================== //
|
479 |
+
// ================= PRESET ===================== //
|
480 |
+
// ==================================================== //
|
481 |
+
|
482 |
+
//TODO non va bene tenere nel global space variabili che altri potrebbero accidentalmente modificare/usare
|
483 |
+
// ma questo è un test
|
484 |
+
const toastBottom = new TnpToast({duration: 5000, position: 'bottom right', wrapperPadding: '70px 20px'});
|
485 |
+
|
486 |
+
//TODO - spostare gestione dei preset in contesto privato ma aggiungendo comunque a window le funzioni triggerate da html (load_preset, delete_preset,...) per mantenere compatibilità?
|
487 |
+
const presetListModal = new TNPModal({
|
488 |
+
closeWhenClickOutside: true,
|
489 |
+
showClose: true,
|
490 |
+
style: {
|
491 |
+
backgroundColor: '#ECF0F1',
|
492 |
+
height: '400px',
|
493 |
+
width: '740px',
|
494 |
+
},
|
495 |
+
onClose: function () {
|
496 |
+
start_composer();
|
497 |
+
//Enable buttons
|
498 |
+
jQuery('.tnpc-controls input[type=button]').attr('disabled', false);
|
499 |
+
}
|
500 |
+
});
|
501 |
+
|
502 |
+
function tnpc_show_presets_modal() {
|
503 |
+
|
504 |
+
jQuery('.tnpc-controls input[type=button]').attr('disabled', true);
|
505 |
+
|
506 |
+
const elModalContent = presetListModal.open();
|
507 |
+
|
508 |
+
jQuery.ajax({
|
509 |
+
type: "POST",
|
510 |
+
url: ajaxurl,
|
511 |
+
data: {
|
512 |
+
action: "tnpc_get_all_presets",
|
513 |
+
context_type: tnp_context_type,
|
514 |
+
},
|
515 |
+
success: function (res) {
|
516 |
+
jQuery(elModalContent).html(res.data);
|
517 |
+
},
|
518 |
+
});
|
519 |
+
|
520 |
+
}
|
521 |
+
|
522 |
+
function tnpc_load_preset(id, subject, isEditMode) {
|
523 |
+
|
524 |
+
presetListModal.close();
|
525 |
+
|
526 |
+
jQuery.ajax({
|
527 |
+
type: "POST",
|
528 |
+
url: ajaxurl,
|
529 |
+
data: {
|
530 |
+
action: "tnpc_get_preset",
|
531 |
+
id: id
|
532 |
+
},
|
533 |
+
success: function (res) {
|
534 |
+
jQuery('#newsletter-builder-area-center-frame-content').html(res.data.content);
|
535 |
+
_restore_global_options(res.data.globalOptions);
|
536 |
+
|
537 |
+
start_composer();
|
538 |
+
|
539 |
+
if (!isEditMode) {
|
540 |
+
//Enable buttons
|
541 |
+
jQuery('.tnpc-controls input[type=button]').attr('disabled', false);
|
542 |
+
}
|
543 |
+
|
544 |
+
if (subject && subject.length > 0) {
|
545 |
+
jQuery('#options-subject').val(tnpc_remove_double_quotes_escape_from(subject));
|
546 |
+
}
|
547 |
+
},
|
548 |
+
});
|
549 |
+
|
550 |
+
function _restore_global_options(options) {
|
551 |
+
jQuery.each(options, function (name, value) {
|
552 |
+
var el = jQuery(`#tnpc-global-styles-form #options-options_composer_${name}`);
|
553 |
+
if (el.length) {
|
554 |
+
el.val(value);
|
555 |
+
}
|
556 |
+
});
|
557 |
+
|
558 |
+
tnp_controls_init();
|
559 |
+
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
560 |
+
}
|
561 |
+
|
562 |
+
}
|
563 |
+
|
564 |
+
function tnpc_save_preset(form) {
|
565 |
+
|
566 |
+
const presetName = tnpc_remove_double_quotes_from(document.querySelector('#options-subject').value);
|
567 |
+
|
568 |
+
const presetNameModal = new TNPModal({
|
569 |
+
title: 'Choose a preset name',
|
570 |
+
content: '<input type="text" id="preset_name" style="width: 100%" placeholder="Preset name" value="' + presetName + '"/>',
|
571 |
+
showConfirm: true,
|
572 |
+
clickConfirmOnPressEnter: true,
|
573 |
+
onConfirm: function () {
|
574 |
+
const inputEl = document.querySelector('#preset_name');
|
575 |
+
document.querySelector('#options-subject').value = inputEl.value;
|
576 |
+
tnpc_save(form);
|
577 |
+
form.submit();
|
578 |
+
}
|
579 |
+
});
|
580 |
+
|
581 |
+
presetNameModal.open();
|
582 |
+
|
583 |
+
}
|
584 |
+
|
585 |
+
function tnpc_delete_preset(presetId, name, event) {
|
586 |
+
event.stopPropagation();
|
587 |
+
|
588 |
+
const presetDeleteModal = new TNPModal({
|
589 |
+
title: `Are you sure to delete "${name}" preset?`,
|
590 |
+
confirmText: 'DELETE PRESET',
|
591 |
+
confirmClassName: 'button-secondary button-danger',
|
592 |
+
showConfirm: true,
|
593 |
+
onConfirm: function () {
|
594 |
+
|
595 |
+
const wrapperPresetEl = event.target.closest(".tnpc-preset");
|
596 |
+
|
597 |
+
jQuery.ajax({
|
598 |
+
type: 'POST',
|
599 |
+
dataType: 'json',
|
600 |
+
url: ajaxurl,
|
601 |
+
data: {
|
602 |
+
action: 'tnpc_delete_preset',
|
603 |
+
_wpnonce: tnp_preset_nonce,
|
604 |
+
presetId: presetId
|
605 |
+
},
|
606 |
+
success: function (response) {
|
607 |
+
if (response.success) {
|
608 |
+
wrapperPresetEl.parentNode.removeChild(wrapperPresetEl);
|
609 |
+
toastBottom.success('Preset successfully deleted!');
|
610 |
+
}
|
611 |
+
}
|
612 |
+
});
|
613 |
+
|
614 |
+
}
|
615 |
+
});
|
616 |
+
|
617 |
+
presetDeleteModal.open();
|
618 |
+
|
619 |
+
}
|
620 |
+
|
621 |
+
function tnpc_edit_preset(presetId, name, event) {
|
622 |
+
event.stopPropagation();
|
623 |
+
tnpc_load_preset(presetId, name, true);
|
624 |
+
|
625 |
+
//DISABLE BUTTON AND SHOW UPDATE BUTTON
|
626 |
+
const composerForm = document.querySelector('#tnpc-form');
|
627 |
+
const buttons = composerForm.querySelectorAll('input[type=button]');
|
628 |
+
const updatePresetButton = composerForm.querySelector('#update-preset-button');
|
629 |
+
|
630 |
+
for (btn of buttons) {
|
631 |
+
if (btn.id && btn.id === 'save-preset-button') {
|
632 |
+
btn.style.display = 'none';
|
633 |
+
updatePresetButton.style.display = 'inline';
|
634 |
+
updatePresetButton.disabled = false;
|
635 |
+
} else {
|
636 |
+
btn.disabled = true;
|
637 |
+
}
|
638 |
+
}
|
639 |
+
|
640 |
+
//Add preset id hidden field
|
641 |
+
const presetIdfield = document.createElement("input");
|
642 |
+
presetIdfield.type = "hidden";
|
643 |
+
presetIdfield.name = "preset_id";
|
644 |
+
presetIdfield.value = presetId;
|
645 |
+
composerForm.appendChild(presetIdfield);
|
646 |
+
|
647 |
+
}
|
648 |
+
|
649 |
+
function tnpc_remove_double_quotes_escape_from(str) {
|
650 |
+
return str.replace(/\\"/g, '"');
|
651 |
+
}
|
652 |
+
|
653 |
+
function tnpc_remove_double_quotes_from(str) {
|
654 |
+
return str.replace(/['"]+/g, '');
|
655 |
+
}
|
656 |
+
|
657 |
+
function tnpc_update_preset(form) {
|
658 |
+
|
659 |
+
const presetName = tnpc_remove_double_quotes_from(document.querySelector('#options-subject').value);
|
660 |
+
|
661 |
+
const presetNameModal = new TNPModal({
|
662 |
+
title: 'Choose a preset name',
|
663 |
+
content: '<input type="text" id="preset_name" style="width: 100%" placeholder="Preset name" value="' + presetName + '"/>',
|
664 |
+
showConfirm: true,
|
665 |
+
clickConfirmOnPressEnter: true,
|
666 |
+
onConfirm: function () {
|
667 |
+
const inputEl = document.querySelector('#preset_name');
|
668 |
+
document.querySelector('#options-subject').value = inputEl.value;
|
669 |
+
tnpc_save(form);
|
670 |
+
form.submit();
|
671 |
+
}
|
672 |
+
});
|
673 |
+
|
674 |
+
presetNameModal.open();
|
675 |
+
|
676 |
+
}
|
677 |
+
|
678 |
+
// ========================================================= //
|
679 |
+
// ================= PRESET FINE ===================== //
|
680 |
+
// ========================================================= //
|
681 |
+
|
682 |
+
jQuery(document).ready(function () {
|
683 |
+
'use strict'
|
684 |
+
|
685 |
+
var TNPInlineEditor = (function () {
|
686 |
+
|
687 |
+
var className = 'tnpc-inline-editable';
|
688 |
+
var newInputName = 'new_name';
|
689 |
+
var activeInlineElements = [];
|
690 |
+
|
691 |
+
function init() {
|
692 |
+
// find all inline editable elements
|
693 |
+
jQuery('#newsletter-builder-area-center-frame-content').on('click', '.' + className, function (e) {
|
694 |
+
e.preventDefault();
|
695 |
+
removeAllActiveElements();
|
696 |
+
|
697 |
+
var originalEl = jQuery(this).hide();
|
698 |
+
var newEl = jQuery(getEditableComponent(this.innerText.trim(), this.dataset.id, this.dataset.type, originalEl)).insertAfter(this);
|
699 |
+
|
700 |
+
activeInlineElements.push({'originalEl': originalEl, 'newEl': newEl});
|
701 |
+
|
702 |
+
//Add submit event listener for newly created block
|
703 |
+
jQuery('.tnpc-inline-editable-form-' + this.dataset.type + this.dataset.id).on('submit', function (e) {
|
704 |
+
submit(e, newEl, jQuery(originalEl));
|
705 |
+
});
|
706 |
+
|
707 |
+
//Add close event listener for newly created block
|
708 |
+
jQuery('.tnpc-inline-editable-form-actions .tnpc-dismiss-' + this.dataset.type + this.dataset.id).on('click', function (e) {
|
709 |
+
removeAllActiveElements();
|
710 |
+
});
|
711 |
+
|
712 |
+
});
|
713 |
+
|
714 |
+
// Close all created elements if clicked outside
|
715 |
+
jQuery('#newsletter-builder-area-center-frame-content').on('click', function (e) {
|
716 |
+
if (activeInlineElements.length > 0
|
717 |
+
&& !jQuery(e.target).hasClass(className)
|
718 |
+
&& jQuery(e.target).closest('.tnpc-inline-editable-container').length === 0) {
|
719 |
+
removeAllActiveElements();
|
720 |
+
}
|
721 |
+
});
|
722 |
+
|
723 |
+
}
|
724 |
+
|
725 |
+
function removeAllActiveElements() {
|
726 |
+
activeInlineElements.forEach(function (obj) {
|
727 |
+
obj.originalEl.show();
|
728 |
+
|
729 |
+
obj.newEl.off();
|
730 |
+
obj.newEl.remove();
|
731 |
+
});
|
732 |
+
|
733 |
+
activeInlineElements = []
|
734 |
+
}
|
735 |
+
|
736 |
+
function getEditableComponent(value, id, type, originalEl) {
|
737 |
+
|
738 |
+
var element = '';
|
739 |
+
|
740 |
+
//COPY FONT STYLE FROM ORIGINAL ELEMENT
|
741 |
+
var fontFamily = originalEl.css('font-family');
|
742 |
+
var fontSize = originalEl.css('font-size');
|
743 |
+
var styleAttr = "style='font-family:" + fontFamily + ";font-size:" + fontSize + ";'";
|
744 |
+
|
745 |
+
switch (type) {
|
746 |
+
case 'text':
|
747 |
+
{
|
748 |
+
element = "<textarea name='" + newInputName + "' class='" + className + "-textarea' rows='5' " + styleAttr + ">" + value + "</textarea>";
|
749 |
+
break;
|
750 |
+
}
|
751 |
+
case 'title':
|
752 |
+
{
|
753 |
+
element = "<textarea name='" + newInputName + "' class='" + className + "-textarea' rows='2'" + styleAttr + ">" + value + "</textarea>";
|
754 |
+
break;
|
755 |
+
}
|
756 |
+
}
|
757 |
+
|
758 |
+
var component = "<td>";
|
759 |
+
component += "<form class='tnpc-inline-editable-form tnpc-inline-editable-form-" + type + id + "'>";
|
760 |
+
component += "<input type='hidden' name='id' value='" + id + "'>";
|
761 |
+
component += "<input type='hidden' name='type' value='" + type + "'>";
|
762 |
+
component += "<input type='hidden' name='old_value' value='" + value + "'>";
|
763 |
+
component += "<div class='tnpc-inline-editable-container'>";
|
764 |
+
component += element;
|
765 |
+
component += "<div class='tnpc-inline-editable-form-actions'>";
|
766 |
+
component += "<button type='submit'><span class='dashicons dashicons-yes-alt' title='save'></span></button>";
|
767 |
+
component += "<span class='dashicons dashicons-dismiss tnpc-dismiss-" + type + id + "' title='close'></span>";
|
768 |
+
component += "</div>";
|
769 |
+
component += "</div>";
|
770 |
+
component += "</form>";
|
771 |
+
component += "</td>";
|
772 |
+
return component;
|
773 |
+
}
|
774 |
+
|
775 |
+
function submit(e, elementToDeleteAfterSubmit, elementToShow) {
|
776 |
+
e.preventDefault();
|
777 |
+
|
778 |
+
var id = elementToDeleteAfterSubmit.find('form input[name=id]').val();
|
779 |
+
var type = elementToDeleteAfterSubmit.find('form input[name=type]').val();
|
780 |
+
var newValue = elementToDeleteAfterSubmit.find('form [name="' + newInputName + '"]').val();
|
781 |
+
|
782 |
+
ajax_render_block(elementToShow, type, id, newValue);
|
783 |
+
|
784 |
+
elementToDeleteAfterSubmit.remove();
|
785 |
+
elementToShow.show();
|
786 |
+
|
787 |
+
}
|
788 |
+
|
789 |
+
function ajax_render_block(inlineElement, type, postId, newContent) {
|
790 |
+
|
791 |
+
var target = inlineElement.closest('.edit-block');
|
792 |
+
var container = target.closest('table');
|
793 |
+
var blockContent = target.children('.tnpc-block-content');
|
794 |
+
|
795 |
+
if (container.hasClass('tnpc-row-block')) {
|
796 |
+
var data = {
|
797 |
+
'action': 'tnpc_render',
|
798 |
+
'id': container.data('id'),
|
799 |
+
'b': container.data('id'),
|
800 |
+
'full': 1,
|
801 |
+
'_wpnonce': tnp_nonce,
|
802 |
+
'options': {
|
803 |
+
'inline_edits': [{
|
804 |
+
'type': type,
|
805 |
+
'post_id': postId,
|
806 |
+
'content': newContent
|
807 |
+
}]
|
808 |
+
},
|
809 |
+
'encoded_options': blockContent.data('json')
|
810 |
+
};
|
811 |
+
|
812 |
+
tnpc_add_global_options(data);
|
813 |
+
|
814 |
+
jQuery.post(ajaxurl, data, function (response) {
|
815 |
+
var new_row = jQuery(response);
|
816 |
+
|
817 |
+
container.before(new_row);
|
818 |
+
container.remove();
|
819 |
+
|
820 |
+
new_row.add_delete();
|
821 |
+
new_row.add_block_edit();
|
822 |
+
new_row.add_block_clone();
|
823 |
+
|
824 |
+
//Force reload options
|
825 |
+
if (new_row.hasClass('tnpc-row-block')) {
|
826 |
+
new_row.find(".tnpc-row-edit-block").click();
|
827 |
+
}
|
828 |
+
|
829 |
+
tnpc_mobile_preview();
|
830 |
+
|
831 |
+
}).fail(function () {
|
832 |
+
alert("Block rendering failed.");
|
833 |
+
});
|
834 |
+
|
835 |
+
}
|
836 |
+
|
837 |
+
}
|
838 |
+
|
839 |
+
return {init};
|
840 |
+
})();
|
841 |
+
|
842 |
+
TNPInlineEditor.init();
|
843 |
+
|
844 |
+
});
|
845 |
+
|
846 |
+
// =================================================== //
|
847 |
+
// =============== GLOBAL STYLE ================== //
|
848 |
+
// =================================================== //
|
849 |
+
|
850 |
+
(function globalStyleIIFE() {
|
851 |
+
|
852 |
+
var _elTrigger = document.querySelector('#tnpc-global-styles-form [name="apply"]');
|
853 |
+
|
854 |
+
_elTrigger.addEventListener('click', function (e) {
|
855 |
+
e.preventDefault();
|
856 |
+
|
857 |
+
var data = {
|
858 |
+
'action': 'tnpc_regenerate_email',
|
859 |
+
'content': tnpc_get_email_content_from_builder_area(),
|
860 |
+
'_wpnonce': tnp_nonce,
|
861 |
+
};
|
862 |
+
|
863 |
+
tnpc_add_global_options(data);
|
864 |
+
|
865 |
+
jQuery.post(ajaxurl, data, function (response) {
|
866 |
+
if (response && response.success) {
|
867 |
+
jQuery('#newsletter-builder-area-center-frame-content').html(response.data.content);
|
868 |
+
//Change background color of builder area
|
869 |
+
_setBuilderAreaBackgroundColor(document.getElementById('options-options_composer_background').value);
|
870 |
+
init_builder_area();
|
871 |
+
tnpc_mobile_preview();
|
872 |
+
|
873 |
+
toastBottom.success(response.data.message);
|
874 |
+
} else {
|
875 |
+
toastBottom.error(response.data.message);
|
876 |
+
}
|
877 |
+
});
|
878 |
+
|
879 |
+
});
|
880 |
+
|
881 |
+
})();
|
882 |
+
|
883 |
+
// ========================================================= //
|
884 |
+
// ================= SEND A TEST ===================== //
|
885 |
+
// ========================================================= //
|
886 |
+
|
887 |
+
(function sendATestIIFE($) {
|
888 |
+
|
889 |
+
var testNewsletterWithEmailFormId = '#test-newsletter-form';
|
890 |
+
var testNewsletterWithEmailForm = document.querySelector(testNewsletterWithEmailFormId);
|
891 |
+
testNewsletterWithEmailForm.addEventListener('submit', function (e) {
|
892 |
+
e.preventDefault();
|
893 |
+
var testEmail = testNewsletterWithEmailForm.querySelector('input[name="email"]').value;
|
894 |
+
|
895 |
+
let form = document.getElementById("tnpc-form");
|
896 |
+
tnpc_save(form);
|
897 |
+
|
898 |
+
form.act.value = "send-test-to-email-address";
|
899 |
+
var input = document.createElement("input");
|
900 |
+
input.setAttribute("type", "hidden");
|
901 |
+
input.setAttribute("name", "test_address_email");
|
902 |
+
input.setAttribute("value", testEmail);
|
903 |
+
form.appendChild(input);
|
904 |
+
|
905 |
+
form.submit();
|
906 |
+
});
|
907 |
+
|
908 |
+
})(jQuery);
|
909 |
+
|
910 |
+
// ================================================================== //
|
911 |
+
// ================= SUBJECT LENGTH ICONS ===================== //
|
912 |
+
// ================================================================== //
|
913 |
+
|
914 |
+
(function subjectLengthIconsIIFE($) {
|
915 |
+
var $subjectContainer = $('#tnpc-subject');
|
916 |
+
var $subjectInput = $('#tnpc-subject input');
|
917 |
+
var subjectCharCounterEl = null;
|
918 |
+
|
919 |
+
$subjectInput.on('focusin', function (e) {
|
920 |
+
$subjectContainer.find('img').fadeTo(400, 1);
|
921 |
+
});
|
922 |
+
|
923 |
+
$subjectInput.on('keyup', function (e) {
|
924 |
+
setSubjectCharactersLenght(this.value.length);
|
925 |
+
});
|
926 |
+
|
927 |
+
$subjectInput.on('focusout', function (e) {
|
928 |
+
$subjectContainer.find('img').fadeTo(300, 0);
|
929 |
+
});
|
930 |
+
|
931 |
+
function setSubjectCharactersLenght(length = 0) {
|
932 |
+
|
933 |
+
if (length === 0 && subjectCharCounterEl !== null) {
|
934 |
+
subjectCharCounterEl.remove();
|
935 |
+
subjectCharCounterEl = null;
|
936 |
+
return;
|
937 |
+
}
|
938 |
+
|
939 |
+
if (!subjectCharCounterEl) {
|
940 |
+
subjectCharCounterEl = document.createElement("span");
|
941 |
+
subjectCharCounterEl.style.position = 'absolute';
|
942 |
+
subjectCharCounterEl.style.top = '-18px';
|
943 |
+
subjectCharCounterEl.style.right = $subjectContainer[0].getBoundingClientRect().width - $subjectInput[0].getBoundingClientRect().width + 'px';
|
944 |
+
subjectCharCounterEl.style.color = '#999';
|
945 |
+
subjectCharCounterEl.style.fontSize = '0.8rem';
|
946 |
+
$subjectContainer.find('div')[0].appendChild(subjectCharCounterEl);
|
947 |
+
}
|
948 |
+
|
949 |
+
const word = length === 1 ? 'character' : 'characters';
|
950 |
+
subjectCharCounterEl.innerHTML = `${length} ${word}`;
|
951 |
+
}
|
952 |
+
|
953 |
+
})(jQuery);
|
954 |
+
|
955 |
+
// ======================================================================= //
|
956 |
+
// ================= COMPOSER MODE VIEW SWITCH ===================== //
|
957 |
+
// ======================================================================= //
|
958 |
+
|
959 |
+
(function composerModeViewIIFE($) {
|
960 |
+
const activeClass = 'composer-view-mode__item--active';
|
961 |
+
var status = 'desktop';
|
962 |
+
|
963 |
+
$('.composer-view-mode__item[data-view-mode="' + status + '"]').addClass(activeClass);
|
964 |
+
|
965 |
+
$('.composer-view-mode__item').on('click', function () {
|
966 |
+
var $el = $(this);
|
967 |
+
|
968 |
+
if ($el.data('viewMode') === 'desktop') {
|
969 |
+
status = 'desktop';
|
970 |
+
$('.composer-view-mode__item[data-view-mode="desktop"]').addClass(activeClass);
|
971 |
+
$('.composer-view-mode__item[data-view-mode="mobile"]').removeClass(activeClass);
|
972 |
+
} else if ($el.data('viewMode') === 'mobile') {
|
973 |
+
status = 'mobile';
|
974 |
+
$('.composer-view-mode__item[data-view-mode="desktop"]').removeClass(activeClass);
|
975 |
+
$('.composer-view-mode__item[data-view-mode="mobile"]').addClass(activeClass);
|
976 |
+
}
|
977 |
+
|
978 |
+
tnp_view(status);
|
979 |
+
});
|
980 |
+
})(jQuery);
|
emails/tnp-composer/blocks/_/content-01-hero.block.php
DELETED
@@ -1,48 +0,0 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
<table border="0" cellpadding="0" cellspacing="0" width="500" class="responsive-table" align="center">
|
4 |
-
<tr>
|
5 |
-
<td>
|
6 |
-
<!-- HERO IMAGE -->
|
7 |
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
8 |
-
<tr>
|
9 |
-
<td class="padding-copy tnpc-row-edit" data-type="image">
|
10 |
-
<a href="#" target="_blank">
|
11 |
-
<img src="https://unsplash.it/500/300?image=885" width="500" border="0" alt="Insert alt text here" style="max-width: 100%!important; width: 500px!important; height: auto!important; display: block;" class="img-max">
|
12 |
-
</a>
|
13 |
-
</td>
|
14 |
-
</tr>
|
15 |
-
<tr>
|
16 |
-
<td>
|
17 |
-
<!-- COPY -->
|
18 |
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
19 |
-
<tr>
|
20 |
-
<td align="center" style="font-size: 25px; color: #333333; padding-top: 30px; font-family: Helvetica, arial, sans-serif; " class="padding-copy tnpc-row-edit" data-type="title">An Awesome Title</td>
|
21 |
-
</tr>
|
22 |
-
<tr>
|
23 |
-
<td align="center" style="padding: 20px 0 0 0; font-size: 16px; line-height: 25px; color: #666666; font-family: Helvetica, arial, sans-serif; " class="padding-copy tnpc-row-edit" data-type="text">The judge, by the way, was the King; and as he wore his crown over the wig, (look at the frontispiece if you want to see how he did it,) he did not look at all comfortable, and it was certainly not becoming.</td>
|
24 |
-
</tr>
|
25 |
-
</table>
|
26 |
-
</td>
|
27 |
-
</tr>
|
28 |
-
<tr>
|
29 |
-
<td align="center">
|
30 |
-
<!-- BULLETPROOF BUTTON -->
|
31 |
-
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="mobile-button-container">
|
32 |
-
<tr>
|
33 |
-
<td align="center" style="padding: 25px 0 0 0;" class="padding-copy">
|
34 |
-
<table border="0" cellspacing="0" cellpadding="0" class="responsive-table">
|
35 |
-
<tr>
|
36 |
-
<td align="center">
|
37 |
-
<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="button">Learn More →</a></td>
|
38 |
-
</tr>
|
39 |
-
</table>
|
40 |
-
</td>
|
41 |
-
</tr>
|
42 |
-
</table>
|
43 |
-
</td>
|
44 |
-
</tr>
|
45 |
-
</table>
|
46 |
-
</td>
|
47 |
-
</tr>
|
48 |
-
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emails/tnp-composer/blocks/_/content-01-hero.block.png
DELETED
Binary file
|
emails/tnp-composer/css/backend.css
CHANGED
@@ -1,40 +1,43 @@
|
|
1 |
-
/* Contains some rules to simulate device layout on backend preview */
|
2 |
-
|
3 |
-
#newsletter-builder-area-center-frame-content.tnp-view-mobile table[class="responsive"]
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
padding-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
padding-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
1 |
+
/* Contains some rules to simulate device layout on backend preview */
|
2 |
+
|
3 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile table[class="responsive"],
|
4 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile table.responsive
|
5 |
+
{
|
6 |
+
width:100%!important;
|
7 |
+
float: none;
|
8 |
+
display: table;
|
9 |
+
padding-left: 0;
|
10 |
+
padding-right: 0;
|
11 |
+
}
|
12 |
+
|
13 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile td[class="responsive"]{
|
14 |
+
width:100%!important;
|
15 |
+
max-width: 100%!important;
|
16 |
+
display: block;
|
17 |
+
padding-left: 0 !important;
|
18 |
+
padding-right: 0 !important;
|
19 |
+
float: none;
|
20 |
+
}
|
21 |
+
|
22 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile img[class="responsive"],
|
23 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile img.responsive
|
24 |
+
{
|
25 |
+
max-width: 100%!important;
|
26 |
+
}
|
27 |
+
|
28 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile img[class="fluid"]{
|
29 |
+
width: 100%;
|
30 |
+
max-width: 100%!important;
|
31 |
+
}
|
32 |
+
|
33 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile .pt-1 {
|
34 |
+
padding-top: 15px!important;
|
35 |
+
}
|
36 |
+
|
37 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile .pb-1 {
|
38 |
+
padding-bottom: 15px!important;
|
39 |
+
}
|
40 |
+
|
41 |
+
#newsletter-builder-area-center-frame-content.tnp-view-mobile .tnp-grid-column {
|
42 |
+
max-width: 100%!important;
|
43 |
+
}
|
emails/tnp-composer/css/newsletter.css
CHANGED
@@ -1,91 +1,38 @@
|
|
1 |
-
#outlook a{padding:0;}
|
2 |
-
.ReadMsgBody{width:100%;} .ExternalClass{width:100%;}
|
3 |
-
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
}
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
padding
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
img[class="fluid"] {
|
41 |
-
max-width: 100%!important;
|
42 |
-
width: 100%;
|
43 |
-
}
|
44 |
-
|
45 |
-
.block {
|
46 |
-
display: block;
|
47 |
-
}
|
48 |
-
|
49 |
-
td[class="responsive"]{
|
50 |
-
width:100%!important;
|
51 |
-
max-width: 100%!important;
|
52 |
-
display: block;
|
53 |
-
padding-left: 0 !important;
|
54 |
-
padding-right: 0 !important;
|
55 |
-
float: none;
|
56 |
-
}
|
57 |
-
|
58 |
-
td[class="section-padding"]{
|
59 |
-
padding: 50px 15px 50px 15px !important;
|
60 |
-
}
|
61 |
-
|
62 |
-
td[class="section-padding-bottom-image"]{
|
63 |
-
padding: 50px 15px 0 15px !important;
|
64 |
-
}
|
65 |
-
|
66 |
-
/* ADJUST BUTTONS ON MOBILE */
|
67 |
-
td[class="mobile-wrapper"]{
|
68 |
-
padding: 10px 5% 15px 5% !important;
|
69 |
-
}
|
70 |
-
|
71 |
-
td[class="responsive"]{
|
72 |
-
display: block;
|
73 |
-
width: 100% !important;
|
74 |
-
}
|
75 |
-
|
76 |
-
table[class="mobile-button-container"]{
|
77 |
-
margin:0 auto;
|
78 |
-
width:100% !important;
|
79 |
-
}
|
80 |
-
|
81 |
-
a[class="mobile-button"]{
|
82 |
-
width:80% !important;
|
83 |
-
padding: 15px !important;
|
84 |
-
border: 0 !important;
|
85 |
-
font-size: 16px !important;
|
86 |
-
}
|
87 |
-
|
88 |
-
.tnp-grid-column {
|
89 |
-
max-width: 100%!important;
|
90 |
-
}
|
91 |
-
}
|
1 |
+
#outlook a{padding:0;}
|
2 |
+
.ReadMsgBody{width:100%;} .ExternalClass{width:100%;}
|
3 |
+
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
|
4 |
+
|
5 |
+
body { margin: 0; padding: 0; height: 100%!important; width: 100%!important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%;}
|
6 |
+
table,td { border-collapse: collapse !important; mso-table-lspace: 0pt; mso-table-rspace: 0pt;}
|
7 |
+
img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; max-width: 100%!important; -ms-interpolation-mode: bicubic;}
|
8 |
+
img.aligncenter { display: block; margin: 0 auto;}
|
9 |
+
|
10 |
+
@media screen and (max-width: 525px) {
|
11 |
+
.pt-1 { padding-top: 15px!important; }
|
12 |
+
.pb-1 { padding-bottom: 15px!important; }
|
13 |
+
.responsive { width:100%!important; }
|
14 |
+
table.responsive { width:100%!important; float: none; display: table; padding-left: 0; padding-right: 0; }
|
15 |
+
table[class="responsive"] { width:100%!important; float: none; display: table; padding-left: 0; padding-right: 0; }
|
16 |
+
img[class="responsive"] { max-width: 100%!important; }
|
17 |
+
.fluid { max-width: 100%!important; width: auto; }
|
18 |
+
img[class="fluid"] { max-width: 100%!important; width: auto; }
|
19 |
+
|
20 |
+
.block { display: block; }
|
21 |
+
|
22 |
+
td[class="responsive"]{
|
23 |
+
width:100%!important;
|
24 |
+
max-width: 100%!important;
|
25 |
+
display: block;
|
26 |
+
padding-left: 0 !important;
|
27 |
+
padding-right: 0 !important;
|
28 |
+
float: none;
|
29 |
+
}
|
30 |
+
|
31 |
+
td[class="section-padding-bottom-image"]{
|
32 |
+
padding: 50px 15px 0 15px !important;
|
33 |
+
}
|
34 |
+
|
35 |
+
.tnp-grid-column {
|
36 |
+
max-width: 100%!important;
|
37 |
+
}
|
38 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emails/tnp-composer/css/newsletter.min.css
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
#outlook a{padding:0}.ReadMsgBody{width:100%}.ExternalClass{width:100%}.ExternalClass,.ExternalClass p,.ExternalClass span,.ExternalClass font,.ExternalClass td,.ExternalClass div{line-height:100%}body,table,td,a{-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}table,td{mso-table-lspace:0;mso-table-rspace:0}img{-ms-interpolation-mode:bicubic}body{margin:0;padding:0;height:100%!important;margin:0;padding:0;width:100%!important}img{border:0;height:auto;line-height:100%;outline:0;text-decoration:none;max-width:100%!important}table{border-collapse:collapse!important}img.aligncenter{display:block;margin:0 auto}@media screen and (max-width:525px){table[class="wrapper"]{width:100%!important}table[class="mobile-full-width"]{width:100%!important}img[class="mobile-full-width"]{width:100%!important;display:block}td[class="logo"]{text-align:left;padding:20px 0 20px 0!important}td[class="logo"] img{margin:0 auto!important}td[class="mobile-hide"]{display:none}img[class="mobile-hide"]{display:none!important}img[class="img-max"]{max-width:100%!important;height:auto!important}table[class="responsive-table"]{width:100%!important;max-width:100%!important}.responsive{width:100%!important;max-width:100%!important;float:none;display:block;padding-left:0;padding-right:0}table[class="responsive"]{width:100%!important;max-width:100%!important;float:none;display:block}img.responsive{width:100%!important;max-width:100%!important}.block{display:block}td[class="responsive"]{width:100%!important;max-width:100%!important;display:block;padding-left:0;padding-right:0;float:none}td[class="padding"]{padding:10px 5% 15px 5%!important}td[class="padding-copy"]{padding:10px 5% 10px 5%!important;text-align:center}td[class="padding-meta"]{padding:30px 5% 0 5%!important;text-align:center}td[class="no-pad"]{padding:0 0 20px 0!important}td[class="no-padding"]{padding:0!important}td[class="section-padding"]{padding:50px 15px 50px 15px!important}td[class="section-padding-bottom-image"]{padding:50px 15px 0 15px!important}td[class="mobile-wrapper"]{padding:10px 5% 15px 5%!important}td[class="responsive"]{display:block;width:100%!important}table[class="mobile-button-container"]{margin:0 auto;width:100%!important}a[class="mobile-button"]{width:80%!important;padding:15px!important;border:0!important;font-size:16px!important}}
|
|
emails/tnp-composer/index-v2.php
CHANGED
@@ -1,198 +1,198 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* This file is included by NewsletterControls to create the composer.
|
4 |
-
*/
|
5 |
-
/* @var $this NewsletterControls */
|
6 |
-
|
7 |
-
defined('ABSPATH') || exit;
|
8 |
-
|
9 |
-
$list = NewsletterEmails::instance()->get_blocks();
|
10 |
-
|
11 |
-
$blocks = array();
|
12 |
-
foreach ($list as $key => $data) {
|
13 |
-
if (!isset($blocks[$data['section']])) {
|
14 |
-
$blocks[$data['section']] = array();
|
15 |
-
}
|
16 |
-
$blocks[$data['section']][$key]['name'] = $data['name'];
|
17 |
-
$blocks[$data['section']][$key]['filename'] = $key;
|
18 |
-
$blocks[$data['section']][$key]['icon'] = $data['icon'];
|
19 |
-
}
|
20 |
-
|
21 |
-
// order the sections
|
22 |
-
$blocks = array_merge(array_flip(array('header', 'content', 'footer')), $blocks);
|
23 |
-
|
24 |
-
// prepare the options for the default blocks
|
25 |
-
$block_options = get_option('newsletter_main');
|
26 |
-
|
27 |
-
$fields = new NewsletterFields($controls);
|
28 |
-
|
29 |
-
$dir = is_rtl() ? 'rtl' : 'ltr';
|
30 |
-
$rev_dir = is_rtl() ? 'ltr' : 'rlt';
|
31 |
-
|
32 |
-
?>
|
33 |
-
<script type="text/javascript">
|
34 |
-
// collapse wp menu
|
35 |
-
document.body.classList.add('folded');
|
36 |
-
|
37 |
-
function tnp_view(type) {
|
38 |
-
if (type === 'mobile') {
|
39 |
-
jQuery('#newsletter-builder-area-center-frame-content').addClass('tnp-view-mobile');
|
40 |
-
} else {
|
41 |
-
jQuery('#newsletter-builder-area-center-frame-content').removeClass('tnp-view-mobile');
|
42 |
-
}
|
43 |
-
}
|
44 |
-
</script>
|
45 |
-
|
46 |
-
|
47 |
-
<style>
|
48 |
-
<?php echo NewsletterEmails::instance()->get_composer_css(); ?>
|
49 |
-
</style>
|
50 |
-
<div id="newsletter-builder" dir="ltr">
|
51 |
-
|
52 |
-
<div id="newsletter-builder-area" class="tnp-builder-column">
|
53 |
-
|
54 |
-
<?php if ( $tnpc_show_subject ) { ?>
|
55 |
-
<div id="tnpc-subject-wrap" dir="<?php echo $dir ?>">
|
56 |
-
<table role="presentation" style="width: 100%">
|
57 |
-
<tr>
|
58 |
-
<th dir="<?php echo $dir ?>"><?php _e('From', 'newsletter') ?></th>
|
59 |
-
<td dir="<?php echo $dir ?>"><?php echo esc_html( $controls->data['sender_email'] ) ?></td>
|
60 |
-
</tr>
|
61 |
-
<tr>
|
62 |
-
<th dir="<?php echo $dir ?>"><?php _e('Subject', 'newsletter') ?></th>
|
63 |
-
<td dir="<?php echo $dir ?>">
|
64 |
-
<div id="tnpc-subject">
|
65 |
-
<?php $this->subject( 'subject' ); ?>
|
66 |
-
</div>
|
67 |
-
</td>
|
68 |
-
</tr>
|
69 |
-
<tr>
|
70 |
-
<th dir="<?php echo $dir ?>"><span title="<?php esc_attr_e('Shown by some email clients as excerpt', 'newsletter')?>"><?php _e('Snippet', 'newsletter') ?></span>
|
71 |
-
<?php $this->field_help('https://www.thenewsletterplugin.com/documentation/newsletters/composer/#subject') ?>
|
72 |
-
</th>
|
73 |
-
<td dir="<?php echo $dir ?>"><?php $this->text('preheader') ?></td>
|
74 |
-
</tr>
|
75 |
-
</table>
|
76 |
-
|
77 |
-
<div style="text-align: left; margin-left: 1em;">
|
78 |
-
<a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletter-tags/"
|
79 |
-
target="_blank">You can use tags to inject subscriber fields</a>. Even on subject.
|
80 |
-
|
81 |
-
|
82 |
-
</div>
|
83 |
-
|
84 |
-
<div class="composer-actions">
|
85 |
-
|
86 |
-
<div id="attachment-newsletter-button" class="button-primary" data-tnp-modal-target="#attachment-modal">
|
87 |
-
<i class="fas fa-paperclip"></i>
|
88 |
-
</div>
|
89 |
-
|
90 |
-
<div id="test-newsletter-button" class="button-primary" data-tnp-modal-target="#test-newsletter-modal">
|
91 |
-
<i class="fas fa-paper-plane"></i> <?php _e( 'Test', 'newsletter' ) ?>
|
92 |
-
</div>
|
93 |
-
|
94 |
-
<div class="composer-view-mode">
|
95 |
-
<span class="composer-view-mode__item" data-view-mode="desktop">
|
96 |
-
<i class="fas fa-desktop"></i>
|
97 |
-
</span>
|
98 |
-
|
99 |
-
<span class="composer-view-mode__item" data-view-mode="mobile">
|
100 |
-
<i class="fas fa-mobile"></i>
|
101 |
-
<span>
|
102 |
-
</div>
|
103 |
-
|
104 |
-
</div>
|
105 |
-
|
106 |
-
<?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/test-newsletter.php' ?>
|
107 |
-
<?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/attachment.php' ?>
|
108 |
-
|
109 |
-
</div>
|
110 |
-
<?php } ?>
|
111 |
-
|
112 |
-
|
113 |
-
<div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
|
114 |
-
|
115 |
-
<!-- Composer content -->
|
116 |
-
|
117 |
-
</div>
|
118 |
-
</div>
|
119 |
-
|
120 |
-
<div id="newsletter-builder-sidebar" dir="<?php echo is_rtl() ? 'rtl' : 'ltr' ?>">
|
121 |
-
|
122 |
-
<div class="tnpc-tabs">
|
123 |
-
<button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" data-tab-id='tnpc-blocks' id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
|
124 |
-
<button class="tablinks" onclick="openTab(event, 'tnpc-global-styles')" data-tab-id='tnpc-global-styles'><?php _e('Settings', 'newsletter') ?></button>
|
125 |
-
</div>
|
126 |
-
|
127 |
-
<div id="tnpc-blocks" class="tabcontent">
|
128 |
-
<?php foreach ($blocks as $k => $section) { ?>
|
129 |
-
<div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
|
130 |
-
<!--<h4><span><?php echo ucfirst($k) ?></span></h4>-->
|
131 |
-
<?php foreach ($section AS $key => $block) { ?>
|
132 |
-
<div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $key ?>" data-name="<?php echo esc_attr($block['name']) ?>">
|
133 |
-
<img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
|
134 |
-
</div>
|
135 |
-
<?php } ?>
|
136 |
-
</div>
|
137 |
-
<?php } ?>
|
138 |
-
</div>
|
139 |
-
|
140 |
-
<div id="tnpc-global-styles" class="tabcontent">
|
141 |
-
|
142 |
-
<form id="tnpc-global-styles-form">
|
143 |
-
|
144 |
-
<div class="tnp-field-row">
|
145 |
-
<div class="tnp-field-col-2">
|
146 |
-
<?php $fields->color('options_composer_background', __('Main background', 'newsletter')) ?>
|
147 |
-
</div>
|
148 |
-
<div class="tnp-field-col-2">
|
149 |
-
<?php $fields->color('options_composer_block_background', 'Blocks background') ?>
|
150 |
-
</div>
|
151 |
-
</div>
|
152 |
-
|
153 |
-
<?php $fields->font('options_composer_title_font', __('Titles font', 'newsletter')) ?>
|
154 |
-
<?php $fields->font('options_composer_text_font', __('Text font', 'newsletter')) ?>
|
155 |
-
<?php $fields->button_style('options_composer_button', __('Button style', 'newsletter')); ?>
|
156 |
-
|
157 |
-
<button class="button-secondary" name="apply"><?php _e("Apply", 'newsletter') ?></button>
|
158 |
-
|
159 |
-
</form>
|
160 |
-
|
161 |
-
</div>
|
162 |
-
|
163 |
-
<!-- Block options container (dynamically loaded -->
|
164 |
-
<div id="tnpc-block-options">
|
165 |
-
<div id="tnpc-block-options-buttons">
|
166 |
-
<span id="tnpc-block-options-cancel" class="button-secondary"><?php _e("Cancel", "newsletter") ?></span>
|
167 |
-
<span id="tnpc-block-options-save" class="button-primary"><?php _e("Apply", "newsletter") ?></span>
|
168 |
-
</div>
|
169 |
-
<form id="tnpc-block-options-form" onsubmit="return false;"></form>
|
170 |
-
</div>
|
171 |
-
|
172 |
-
</div>
|
173 |
-
|
174 |
-
<div style="clear: both"></div>
|
175 |
-
|
176 |
-
</div>
|
177 |
-
|
178 |
-
<div style="display: none">
|
179 |
-
<div id="newsletter-preloaded-export"></div>
|
180 |
-
<!-- Block placeholder used by jQuery UI -->
|
181 |
-
<div id="draggable-helper"></div>
|
182 |
-
<div id="sortable-helper"></div>
|
183 |
-
</div>
|
184 |
-
|
185 |
-
<script type="text/javascript">
|
186 |
-
TNP_PLUGIN_URL = "<?php echo esc_js(NEWSLETTER_URL) ?>";
|
187 |
-
TNP_HOME_URL = "<?php echo esc_js(home_url('/', is_ssl() ? 'https' : 'http')) ?>";
|
188 |
-
tnp_context_type = "<?php echo esc_js($context_type) ?>";
|
189 |
-
tnp_nonce = '<?php echo esc_js(wp_create_nonce('save')) ?>';
|
190 |
-
tnp_preset_nonce = '<?php echo esc_js(wp_create_nonce('preset')) ?>';
|
191 |
-
</script>
|
192 |
-
<?php
|
193 |
-
wp_enqueue_script('tnp-composer', plugins_url('newsletter') . '/emails/tnp-composer/_scripts/newsletter-builder-v2.js', ['tnp-modal', 'tnp-toast'], NEWSLETTER_VERSION);
|
194 |
-
?>
|
195 |
-
|
196 |
-
<?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
|
197 |
-
|
198 |
-
<?php if (function_exists('wp_enqueue_editor')) wp_enqueue_editor(); ?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This file is included by NewsletterControls to create the composer.
|
4 |
+
*/
|
5 |
+
/* @var $this NewsletterControls */
|
6 |
+
|
7 |
+
defined('ABSPATH') || exit;
|
8 |
+
|
9 |
+
$list = NewsletterEmails::instance()->get_blocks();
|
10 |
+
|
11 |
+
$blocks = array();
|
12 |
+
foreach ($list as $key => $data) {
|
13 |
+
if (!isset($blocks[$data['section']])) {
|
14 |
+
$blocks[$data['section']] = array();
|
15 |
+
}
|
16 |
+
$blocks[$data['section']][$key]['name'] = $data['name'];
|
17 |
+
$blocks[$data['section']][$key]['filename'] = $key;
|
18 |
+
$blocks[$data['section']][$key]['icon'] = $data['icon'];
|
19 |
+
}
|
20 |
+
|
21 |
+
// order the sections
|
22 |
+
$blocks = array_merge(array_flip(array('header', 'content', 'footer')), $blocks);
|
23 |
+
|
24 |
+
// prepare the options for the default blocks
|
25 |
+
$block_options = get_option('newsletter_main');
|
26 |
+
|
27 |
+
$fields = new NewsletterFields($controls);
|
28 |
+
|
29 |
+
$dir = is_rtl() ? 'rtl' : 'ltr';
|
30 |
+
$rev_dir = is_rtl() ? 'ltr' : 'rlt';
|
31 |
+
|
32 |
+
?>
|
33 |
+
<script type="text/javascript">
|
34 |
+
// collapse wp menu
|
35 |
+
document.body.classList.add('folded');
|
36 |
+
|
37 |
+
function tnp_view(type) {
|
38 |
+
if (type === 'mobile') {
|
39 |
+
jQuery('#newsletter-builder-area-center-frame-content').addClass('tnp-view-mobile');
|
40 |
+
} else {
|
41 |
+
jQuery('#newsletter-builder-area-center-frame-content').removeClass('tnp-view-mobile');
|
42 |
+
}
|
43 |
+
}
|
44 |
+
</script>
|
45 |
+
|
46 |
+
|
47 |
+
<style>
|
48 |
+
<?php echo NewsletterEmails::instance()->get_composer_css(); ?>
|
49 |
+
</style>
|
50 |
+
<div id="newsletter-builder" dir="ltr">
|
51 |
+
|
52 |
+
<div id="newsletter-builder-area" class="tnp-builder-column">
|
53 |
+
|
54 |
+
<?php if ( $tnpc_show_subject ) { ?>
|
55 |
+
<div id="tnpc-subject-wrap" dir="<?php echo $dir ?>">
|
56 |
+
<table role="presentation" style="width: 100%">
|
57 |
+
<tr>
|
58 |
+
<th dir="<?php echo $dir ?>"><?php _e('From', 'newsletter') ?></th>
|
59 |
+
<td dir="<?php echo $dir ?>"><?php echo esc_html( $controls->data['sender_email'] ) ?></td>
|
60 |
+
</tr>
|
61 |
+
<tr>
|
62 |
+
<th dir="<?php echo $dir ?>"><?php _e('Subject', 'newsletter') ?></th>
|
63 |
+
<td dir="<?php echo $dir ?>">
|
64 |
+
<div id="tnpc-subject">
|
65 |
+
<?php $this->subject( 'subject' ); ?>
|
66 |
+
</div>
|
67 |
+
</td>
|
68 |
+
</tr>
|
69 |
+
<tr>
|
70 |
+
<th dir="<?php echo $dir ?>"><span title="<?php esc_attr_e('Shown by some email clients as excerpt', 'newsletter')?>"><?php _e('Snippet', 'newsletter') ?></span>
|
71 |
+
<?php $this->field_help('https://www.thenewsletterplugin.com/documentation/newsletters/composer/#subject') ?>
|
72 |
+
</th>
|
73 |
+
<td dir="<?php echo $dir ?>"><?php $this->text('preheader') ?></td>
|
74 |
+
</tr>
|
75 |
+
</table>
|
76 |
+
|
77 |
+
<div style="text-align: left; margin-left: 1em;">
|
78 |
+
<a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletter-tags/"
|
79 |
+
target="_blank">You can use tags to inject subscriber fields</a>. Even on subject.
|
80 |
+
|
81 |
+
|
82 |
+
</div>
|
83 |
+
|
84 |
+
<div class="composer-actions">
|
85 |
+
|
86 |
+
<div id="attachment-newsletter-button" class="button-primary" data-tnp-modal-target="#attachment-modal">
|
87 |
+
<i class="fas fa-paperclip"></i>
|
88 |
+
</div>
|
89 |
+
|
90 |
+
<div id="test-newsletter-button" class="button-primary" data-tnp-modal-target="#test-newsletter-modal">
|
91 |
+
<i class="fas fa-paper-plane"></i> <?php _e( 'Test', 'newsletter' ) ?>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
<div class="composer-view-mode">
|
95 |
+
<span class="composer-view-mode__item" data-view-mode="desktop">
|
96 |
+
<i class="fas fa-desktop"></i>
|
97 |
+
</span>
|
98 |
+
|
99 |
+
<span class="composer-view-mode__item" data-view-mode="mobile">
|
100 |
+
<i class="fas fa-mobile"></i>
|
101 |
+
<span>
|
102 |
+
</div>
|
103 |
+
|
104 |
+
</div>
|
105 |
+
|
106 |
+
<?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/test-newsletter.php' ?>
|
107 |
+
<?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/attachment.php' ?>
|
108 |
+
|
109 |
+
</div>
|
110 |
+
<?php } ?>
|
111 |
+
|
112 |
+
|
113 |
+
<div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
|
114 |
+
|
115 |
+
<!-- Composer content -->
|
116 |
+
|
117 |
+
</div>
|
118 |
+
</div>
|
119 |
+
|
120 |
+
<div id="newsletter-builder-sidebar" dir="<?php echo is_rtl() ? 'rtl' : 'ltr' ?>">
|
121 |
+
|
122 |
+
<div class="tnpc-tabs">
|
123 |
+
<button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" data-tab-id='tnpc-blocks' id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
|
124 |
+
<button class="tablinks" onclick="openTab(event, 'tnpc-global-styles')" data-tab-id='tnpc-global-styles'><?php _e('Settings', 'newsletter') ?></button>
|
125 |
+
</div>
|
126 |
+
|
127 |
+
<div id="tnpc-blocks" class="tabcontent">
|
128 |
+
<?php foreach ($blocks as $k => $section) { ?>
|
129 |
+
<div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
|
130 |
+
<!--<h4><span><?php echo ucfirst($k) ?></span></h4>-->
|
131 |
+
<?php foreach ($section AS $key => $block) { ?>
|
132 |
+
<div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $key ?>" data-name="<?php echo esc_attr($block['name']) ?>">
|
133 |
+
<img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
|
134 |
+
</div>
|
135 |
+
<?php } ?>
|
136 |
+
</div>
|
137 |
+
<?php } ?>
|
138 |
+
</div>
|
139 |
+
|
140 |
+
<div id="tnpc-global-styles" class="tabcontent">
|
141 |
+
|
142 |
+
<form id="tnpc-global-styles-form">
|
143 |
+
|
144 |
+
<div class="tnp-field-row">
|
145 |
+
<div class="tnp-field-col-2">
|
146 |
+
<?php $fields->color('options_composer_background', __('Main background', 'newsletter')) ?>
|
147 |
+
</div>
|
148 |
+
<div class="tnp-field-col-2">
|
149 |
+
<?php $fields->color('options_composer_block_background', 'Blocks background') ?>
|
150 |
+
</div>
|
151 |
+
</div>
|
152 |
+
|
153 |
+
<?php $fields->font('options_composer_title_font', __('Titles font', 'newsletter')) ?>
|
154 |
+
<?php $fields->font('options_composer_text_font', __('Text font', 'newsletter')) ?>
|
155 |
+
<?php $fields->button_style('options_composer_button', __('Button style', 'newsletter')); ?>
|
156 |
+
|
157 |
+
<button class="button-secondary" name="apply"><?php _e("Apply", 'newsletter') ?></button>
|
158 |
+
|
159 |
+
</form>
|
160 |
+
|
161 |
+
</div>
|
162 |
+
|
163 |
+
<!-- Block options container (dynamically loaded -->
|
164 |
+
<div id="tnpc-block-options">
|
165 |
+
<div id="tnpc-block-options-buttons">
|
166 |
+
<span id="tnpc-block-options-cancel" class="button-secondary"><?php _e("Cancel", "newsletter") ?></span>
|
167 |
+
<span id="tnpc-block-options-save" class="button-primary"><?php _e("Apply", "newsletter") ?></span>
|
168 |
+
</div>
|
169 |
+
<form id="tnpc-block-options-form" onsubmit="return false;"></form>
|
170 |
+
</div>
|
171 |
+
|
172 |
+
</div>
|
173 |
+
|
174 |
+
<div style="clear: both"></div>
|
175 |
+
|
176 |
+
</div>
|
177 |
+
|
178 |
+
<div style="display: none">
|
179 |
+
<div id="newsletter-preloaded-export"></div>
|
180 |
+
<!-- Block placeholder used by jQuery UI -->
|
181 |
+
<div id="draggable-helper"></div>
|
182 |
+
<div id="sortable-helper"></div>
|
183 |
+
</div>
|
184 |
+
|
185 |
+
<script type="text/javascript">
|
186 |
+
TNP_PLUGIN_URL = "<?php echo esc_js(NEWSLETTER_URL) ?>";
|
187 |
+
TNP_HOME_URL = "<?php echo esc_js(home_url('/', is_ssl() ? 'https' : 'http')) ?>";
|
188 |
+
tnp_context_type = "<?php echo esc_js($context_type) ?>";
|
189 |
+
tnp_nonce = '<?php echo esc_js(wp_create_nonce('save')) ?>';
|
190 |
+
tnp_preset_nonce = '<?php echo esc_js(wp_create_nonce('preset')) ?>';
|
191 |
+
</script>
|
192 |
+
<?php
|
193 |
+
wp_enqueue_script('tnp-composer', plugins_url('newsletter') . '/emails/tnp-composer/_scripts/newsletter-builder-v2.js', ['tnp-modal', 'tnp-toast'], NEWSLETTER_VERSION);
|
194 |
+
?>
|
195 |
+
|
196 |
+
<?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
|
197 |
+
|
198 |
+
<?php if (function_exists('wp_enqueue_editor')) wp_enqueue_editor(); ?>
|
emails/tnp-composer/modal/attachment.php
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
-
<div class="tnp-modal2" id="attachment-modal" aria-hidden="true">
|
2 |
-
<div class="tnp-modal2__content" role="dialog" style="width: 600px">
|
3 |
-
<header class="tnp-modal2__header">
|
4 |
-
|
5 |
-
<h2><?php _e("Attachments", 'newsletter') ?></h2>
|
6 |
-
<span class="tnp-modal2__close" data-tnp-modal-close aria-label="Close modal"></span>
|
7 |
-
</header>
|
8 |
-
|
9 |
-
<div class="tnp-modal2__body">
|
10 |
-
|
11 |
-
<p>
|
12 |
-
The Newsletter plugin does not support attachments.
|
13 |
-
<a href="https://www.thenewsletterplugin.com/documentation/adding-attachments-to-newsletters/" target="_blank">Please read more in our documentation</a>.
|
14 |
-
</p>
|
15 |
-
|
16 |
-
</div>
|
17 |
-
|
18 |
-
</div>
|
19 |
-
</div>
|
1 |
+
<div class="tnp-modal2" id="attachment-modal" aria-hidden="true">
|
2 |
+
<div class="tnp-modal2__content" role="dialog" style="width: 600px">
|
3 |
+
<header class="tnp-modal2__header">
|
4 |
+
|
5 |
+
<h2><?php _e("Attachments", 'newsletter') ?></h2>
|
6 |
+
<span class="tnp-modal2__close" data-tnp-modal-close aria-label="Close modal"></span>
|
7 |
+
</header>
|
8 |
+
|
9 |
+
<div class="tnp-modal2__body">
|
10 |
+
|
11 |
+
<p>
|
12 |
+
The Newsletter plugin does not support attachments.
|
13 |
+
<a href="https://www.thenewsletterplugin.com/documentation/adding-attachments-to-newsletters/" target="_blank">Please read more in our documentation</a>.
|
14 |
+
</p>
|
15 |
+
|
16 |
+
</div>
|
17 |
+
|
18 |
+
</div>
|
19 |
+
</div>
|
images/animated-overlay.gif
DELETED
Binary file
|
images/cd-icon-navigation.svg
DELETED
@@ -1,50 +0,0 @@
|
|
1 |
-
<?xml version="1.0" encoding="utf-8"?>
|
2 |
-
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
3 |
-
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4 |
-
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
5 |
-
width="240px" height="120px" viewBox="0 0 240 120" enable-background="new 0 0 240 120" xml:space="preserve">
|
6 |
-
<g transform="translate(22, 22)">
|
7 |
-
<path fill="#7D7160" d="M195,4h-4V1c0-0.6-0.4-1-1-1h-7c-1.7,0-3,1.3-3,3v10c0,1.7,1.3,3,3,3h12c0.6,0,1-0.4,1-1V5
|
8 |
-
C196,4.4,195.6,4,195,4z M182,3c0-0.6,0.4-1,1-1h6v2h-7V3z M194,14h-11c-0.6,0-1-0.4-1-1V6h8h4V14z"/>
|
9 |
-
<rect x="191" y="9" fill="#D2C9C0" width="2" height="2"/>
|
10 |
-
</g>
|
11 |
-
<g transform="translate(82, 22)">
|
12 |
-
<path fill="#7D7160" d="M15,4h-3V1c0-0.6-0.4-1-1-1H5C4.4,0,4,0.4,4,1v3H1C0.4,4,0,4.4,0,5v10c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1
|
13 |
-
V5C16,4.4,15.6,4,15,4z M6,2h4v2H6V2z M14,14H2V6h12V14z"/>
|
14 |
-
<rect x="5" y="7" fill="#D2C9C0" width="6" height="3"/>
|
15 |
-
</g>
|
16 |
-
<g transform="translate(142, 22)">
|
17 |
-
<circle fill="#D2C9C0" cx="6" cy="8" r="2"/>
|
18 |
-
<path fill="#7D7160" d="M10,2H6C2.7,2,0,4.7,0,8s2.7,6,6,6h4c3.3,0,6-2.7,6-6S13.3,2,10,2z M10,12H6c-2.2,0-4-1.8-4-4s1.8-4,4-4h4
|
19 |
-
c2.2,0,4,1.8,4,4S12.2,12,10,12z"/>
|
20 |
-
</g>
|
21 |
-
<g transform="translate(202, 22)">
|
22 |
-
<path fill="#7D7160" d="M-177,16h10c0.6,0,1-0.4,1-1V7.5l0.3,0.3c0.2,0.1,0.5,0.2,0.7,0.2c0.3,0,0.6-0.1,0.8-0.3
|
23 |
-
c0.4-0.4,0.3-1-0.1-1.4l-7-6c-0.4-0.3-0.9-0.3-1.3,0l-3.4,2.8V2c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1v2.8l-1.7,1.4
|
24 |
-
c-0.4,0.4-0.5,1-0.1,1.4c0.4,0.4,1,0.5,1.4,0.1l0.4-0.2V15C-178,15.6-177.6,16-177,16z M-176,5.7l4-3.4l4,3.5c0,0.1,0,0.1,0,0.2v8
|
25 |
-
h-2v-3c0-0.6-0.4-1-1-1h-2c-0.6,0-1,0.4-1,1v3h-2V5.7z"/>
|
26 |
-
<rect x="-174" y="6" fill="#D2C9C0" width="4" height="2"/>
|
27 |
-
</g>
|
28 |
-
<g transform="translate(22, 82)">
|
29 |
-
<path fill="#FF6155" d="M195,4h-4V1c0-0.6-0.4-1-1-1h-7c-1.7,0-3,1.3-3,3v10c0,1.7,1.3,3,3,3h12c0.6,0,1-0.4,1-1V5
|
30 |
-
C196,4.4,195.6,4,195,4z M182,3c0-0.6,0.4-1,1-1h6v2h-7V3z M194,14h-11c-0.6,0-1-0.4-1-1V6h8h4V14z"/>
|
31 |
-
<rect x="191" y="9" fill="#FF6155" width="2" height="2"/>
|
32 |
-
</g>
|
33 |
-
<g transform="translate(82, 82)">
|
34 |
-
<path fill="#FF6155" d="M15,4h-3V1c0-0.6-0.4-1-1-1H5C4.4,0,4,0.4,4,1v3H1C0.4,4,0,4.4,0,5v10c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1
|
35 |
-
V5C16,4.4,15.6,4,15,4z M6,2h4v2H6V2z M14,14H2V6h12V14z"/>
|
36 |
-
<rect x="5" y="7" fill="#FF6155" width="6" height="3"/>
|
37 |
-
</g>
|
38 |
-
<g transform="translate(142, 82)">
|
39 |
-
<circle fill="#FF6155" cx="6" cy="8" r="2"/>
|
40 |
-
<path fill="#FF6155" d="M10,2H6C2.7,2,0,4.7,0,8s2.7,6,6,6h4c3.3,0,6-2.7,6-6S13.3,2,10,2z M10,12H6c-2.2,0-4-1.8-4-4s1.8-4,4-4h4
|
41 |
-
c2.2,0,4,1.8,4,4S12.2,12,10,12z"/>
|
42 |
-
</g>
|
43 |
-
<g transform="translate(202, 82)">
|
44 |
-
<path fill="#FF6155" d="M-177,16h10c0.6,0,1-0.4,1-1V7.5l0.3,0.3c0.2,0.1,0.5,0.2,0.7,0.2c0.3,0,0.6-0.1,0.8-0.3
|
45 |
-
c0.4-0.4,0.3-1-0.1-1.4l-7-6c-0.4-0.3-0.9-0.3-1.3,0l-3.4,2.8V2c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1v2.8l-1.7,1.4
|
46 |
-
c-0.4,0.4-0.5,1-0.1,1.4c0.4,0.4,1,0.5,1.4,0.1l0.4-0.2V15C-178,15.6-177.6,16-177,16z M-176,5.7l4-3.4l4,3.5c0,0.1,0,0.1,0,0.2v8
|
47 |
-
h-2v-3c0-0.6-0.4-1-1-1h-2c-0.6,0-1,0.4-1,1v3h-2V5.7z"/>
|
48 |
-
<rect x="-174" y="6" fill="#FF6155" width="4" height="2"/>
|
49 |
-
</g>
|
50 |
-
</svg>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
images/errors.png
DELETED
Binary file
|
images/facebook.png
DELETED
Binary file
|
images/header/debug.png
DELETED
Binary file
|
images/header/documentation.png
DELETED
Binary file
|
images/header/facebook.png
DELETED
Binary file
|
images/header/forum.png
DELETED
Binary file
|
images/header/logo.png
DELETED
Binary file
|
images/header/tnp-logo-white-header.png
DELETED
Binary file
|
images/idea.svg
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" xml:space="preserve" width="48" height="48"><g class="nc-icon-wrapper"><path fill="#43A6DD" d="M6,25H2c-0.55225,0-1-0.44727-1-1s0.44775-1,1-1h4c0.55225,0,1,0.44727,1,1S6.55225,25,6,25z"></path> <path fill="#43A6DD" d="M11.27197,12.27246c-0.25586,0-0.51172-0.09766-0.70703-0.29297l-2.82812-2.8291 c-0.39062-0.39062-0.39062-1.02344,0-1.41406s1.02344-0.39062,1.41406,0l2.82812,2.8291c0.39062,0.39062,0.39062,1.02344,0,1.41406 C11.78369,12.1748,11.52783,12.27246,11.27197,12.27246z"></path> <path fill="#43A6DD" d="M24,7c-0.55225,0-1-0.44727-1-1V2c0-0.55273,0.44775-1,1-1s1,0.44727,1,1v4C25,6.55273,24.55225,7,24,7z"></path> <path fill="#43A6DD" d="M36.72803,12.27246c-0.25586,0-0.51172-0.09766-0.70703-0.29297c-0.39062-0.39062-0.39062-1.02344,0-1.41406 l2.82812-2.8291c0.38965-0.39062,1.02344-0.39062,1.41406,0s0.39062,1.02344,0,1.41406l-2.82812,2.8291 C37.24023,12.1748,36.98389,12.27246,36.72803,12.27246z"></path> <path fill="#43A6DD" d="M46,25h-4c-0.55225,0-1-0.44727-1-1s0.44775-1,1-1h4c0.55225,0,1,0.44727,1,1S46.55225,25,46,25z"></path> <path fill="#EFD358" d="M29,41H19v-5.01172c-5.33776-2.22651-8.67485-7.80107-7.88457-13.71942 c0.85052-6.36943,6.45305-11.26616,12.87902-11.26886C31.16545,10.997,37,16.83019,37,24c0,5.25-3.18652,9.98047-8,11.98828V41z"></path> <path fill="#E6E6E6" d="M24.00001,47h-0.00001C21.23857,47,19,44.76143,19,42v-3h10v3C29,44.76143,26.76143,47,24.00001,47z"></path> <rect x="19" y="39" fill="#B3B3B3" width="10" height="2"></rect></g></svg>
|
|
images/img-1.jpg
DELETED
Binary file
|
images/img-2.jpg
DELETED
Binary file
|
images/img-3.jpg
DELETED
Binary file
|
images/img-4.jpg
DELETED
Binary file
|
images/messages.png
DELETED
Binary file
|
images/modal-background.png
DELETED
Binary file
|
images/popup/bg.png
DELETED
Binary file
|
images/popup/button.png
DELETED
Binary file
|
images/preamble.png
DELETED
Binary file
|
images/social-1/discord.png
ADDED
Binary file
|
images/social-1/facebook.png
ADDED
Binary file
|
images/social-1/instagram.png
ADDED
Binary file
|
images/social-1/linkedin.png
ADDED
Binary file
|
images/social-1/pinterest.png
ADDED
Binary file
|
images/social-1/soundcloud.png
ADDED
Binary file
|
images/social-1/telegram.png
ADDED
Binary file
|
images/social-1/tiktok.png
ADDED
Binary file
|
images/social-1/tumblr.png
ADDED
Binary file
|
images/social-1/twitch.png
ADDED
Binary file
|
images/social-1/twitter.png
ADDED
Binary file
|
images/social-1/vimeo.png
ADDED
Binary file
|
images/social-1/vk.png
ADDED
Binary file
|
images/social-1/youtube.png
ADDED
Binary file
|
images/social-2/discord.png
ADDED
Binary file
|
images/social-2/facebook.png
ADDED
Binary file
|
images/social-2/instagram.png
ADDED
Binary file
|
images/social-2/linkedin.png
ADDED
Binary file
|
images/social-2/pinterest.png
ADDED
Binary file
|
images/social-2/soundcloud.png
ADDED
Binary file
|
images/social-2/telegram.png
ADDED
Binary file
|
images/social-2/tiktok.png
ADDED
Binary file
|
images/social-2/tumblr.png
ADDED
Binary file
|
images/social-2/twitch.png
ADDED
Binary file
|
images/social-2/twitter.png
ADDED
Binary file
|
images/social-2/vimeo.png
ADDED
Binary file
|
images/social-2/vk.png
ADDED
Binary file
|
images/social-2/youtube.png
ADDED
Binary file
|
images/tnp-logo-colore-text-white@2x.png
DELETED
Binary file
|
includes/controls.php
CHANGED
@@ -1,2074 +1,2107 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
defined('ABSPATH') || exit;
|
4 |
-
|
5 |
-
include_once __DIR__ . '/fields.php';
|
6 |
-
|
7 |
-
class NewsletterControls {
|
8 |
-
|
9 |
-
var $data = [];
|
10 |
-
var $action = false;
|
11 |
-
var $button_data = '';
|
12 |
-
var $errors = '';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var string
|
16 |
-
*/
|
17 |
-
var $messages = '';
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var array
|
21 |
-
*/
|
22 |
-
var $warnings = array();
|
23 |
-
var $countries = array(
|
24 |
-
'AF' => 'Afghanistan',
|
25 |
-
'AX' => 'Aland Islands',
|
26 |
-
'AL' => 'Albania',
|
27 |
-
'DZ' => 'Algeria',
|
28 |
-
'AS' => 'American Samoa',
|
29 |
-
'AD' => 'Andorra',
|
30 |
-
'AO' => 'Angola',
|
31 |
-
'AI' => 'Anguilla',
|
32 |
-
'AQ' => 'Antarctica',
|
33 |
-
'AG' => 'Antigua And Barbuda',
|
34 |
-
'AR' => 'Argentina',
|
35 |
-
'AM' => 'Armenia',
|
36 |
-
'AW' => 'Aruba',
|
37 |
-
'AU' => 'Australia',
|
38 |
-
'AT' => 'Austria',
|
39 |
-
'AZ' => 'Azerbaijan',
|
40 |
-
'BS' => 'Bahamas',
|
41 |
-
'BH' => 'Bahrain',
|
42 |
-
'BD' => 'Bangladesh',
|
43 |
-
'BB' => 'Barbados',
|
44 |
-
'BY' => 'Belarus',
|
45 |
-
'BE' => 'Belgium',
|
46 |
-
'BZ' => 'Belize',
|
47 |
-
'BJ' => 'Benin',
|
48 |
-
'BM' => 'Bermuda',
|
49 |
-
'BT' => 'Bhutan',
|
50 |
-
'BO' => 'Bolivia',
|
51 |
-
'BA' => 'Bosnia And Herzegovina',
|
52 |
-
'BW' => 'Botswana',
|
53 |
-
'BV' => 'Bouvet Island',
|
54 |
-
'BR' => 'Brazil',
|
55 |
-
'IO' => 'British Indian Ocean Territory',
|
56 |
-
'BN' => 'Brunei Darussalam',
|
57 |
-
'BG' => 'Bulgaria',
|
58 |
-
'BF' => 'Burkina Faso',
|
59 |
-
'BI' => 'Burundi',
|
60 |
-
'KH' => 'Cambodia',
|
61 |
-
'CM' => 'Cameroon',
|
62 |
-
'CA' => 'Canada',
|
63 |
-
'CV' => 'Cape Verde',
|
64 |
-
'KY' => 'Cayman Islands',
|
65 |
-
'CF' => 'Central African Republic',
|
66 |
-
'TD' => 'Chad',
|
67 |
-
'CL' => 'Chile',
|
68 |
-
'CN' => 'China',
|
69 |
-
'CX' => 'Christmas Island',
|
70 |
-
'CC' => 'Cocos (Keeling) Islands',
|
71 |
-
'CO' => 'Colombia',
|
72 |
-
'KM' => 'Comoros',
|
73 |
-
'CG' => 'Congo',
|
74 |
-
'CD' => 'Congo, Democratic Republic',
|
75 |
-
'CK' => 'Cook Islands',
|
76 |
-
'CR' => 'Costa Rica',
|
77 |
-
'CI' => 'Cote D\'Ivoire',
|
78 |
-
'HR' => 'Croatia',
|
79 |
-
'CU' => 'Cuba',
|
80 |
-
'CY' => 'Cyprus',
|
81 |
-
'CZ' => 'Czech Republic',
|
82 |
-
'DK' => 'Denmark',
|
83 |
-
'DJ' => 'Djibouti',
|
84 |
-
'DM' => 'Dominica',
|
85 |
-
'DO' => 'Dominican Republic',
|
86 |
-
'EC' => 'Ecuador',
|
87 |
-
'EG' => 'Egypt',
|
88 |
-
'SV' => 'El Salvador',
|
89 |
-
'GQ' => 'Equatorial Guinea',
|
90 |
-
'ER' => 'Eritrea',
|
91 |
-
'EE' => 'Estonia',
|
92 |
-
'ET' => 'Ethiopia',
|
93 |
-
'FK' => 'Falkland Islands (Malvinas)',
|
94 |
-
'FO' => 'Faroe Islands',
|
95 |
-
'FJ' => 'Fiji',
|
96 |
-
'FI' => 'Finland',
|
97 |
-
'FR' => 'France',
|
98 |
-
'GF' => 'French Guiana',
|
99 |
-
'PF' => 'French Polynesia',
|
100 |
-
'TF' => 'French Southern Territories',
|
101 |
-
'GA' => 'Gabon',
|
102 |
-
'GM' => 'Gambia',
|
103 |
-
'GE' => 'Georgia',
|
104 |
-
'DE' => 'Germany',
|
105 |
-
'GH' => 'Ghana',
|
106 |
-
'GI' => 'Gibraltar',
|
107 |
-
'GR' => 'Greece',
|
108 |
-
'GL' => 'Greenland',
|
109 |
-
'GD' => 'Grenada',
|
110 |
-
'GP' => 'Guadeloupe',
|
111 |
-
'GU' => 'Guam',
|
112 |
-
'GT' => 'Guatemala',
|
113 |
-
'GG' => 'Guernsey',
|
114 |
-
'GN' => 'Guinea',
|
115 |
-
'GW' => 'Guinea-Bissau',
|
116 |
-
'GY' => 'Guyana',
|
117 |
-
'HT' => 'Haiti',
|
118 |
-
'HM' => 'Heard Island & Mcdonald Islands',
|
119 |
-
'VA' => 'Holy See (Vatican City State)',
|
120 |
-
'HN' => 'Honduras',
|
121 |
-
'HK' => 'Hong Kong',
|
122 |
-
'HU' => 'Hungary',
|
123 |
-
'IS' => 'Iceland',
|
124 |
-
'IN' => 'India',
|
125 |
-
'ID' => 'Indonesia',
|
126 |
-
'IR' => 'Iran, Islamic Republic Of',
|
127 |
-
'IQ' => 'Iraq',
|
128 |
-
'IE' => 'Ireland',
|
129 |
-
'IM' => 'Isle Of Man',
|
130 |
-
'IL' => 'Israel',
|
131 |
-
'IT' => 'Italy',
|
132 |
-
'JM' => 'Jamaica',
|
133 |
-
'JP' => 'Japan',
|
134 |
-
'JE' => 'Jersey',
|
135 |
-
'JO' => 'Jordan',
|
136 |
-
'KZ' => 'Kazakhstan',
|
137 |
-
'KE' => 'Kenya',
|
138 |
-
'KI' => 'Kiribati',
|
139 |
-
'KR' => 'Korea',
|
140 |
-
'KW' => 'Kuwait',
|
141 |
-
'KG' => 'Kyrgyzstan',
|
142 |
-
'LA' => 'Lao People\'s Democratic Republic',
|
143 |
-
'LV' => 'Latvia',
|
144 |
-
'LB' => 'Lebanon',
|
145 |
-
'LS' => 'Lesotho',
|
146 |
-
'LR' => 'Liberia',
|
147 |
-
'LY' => 'Libyan Arab Jamahiriya',
|
148 |
-
'LI' => 'Liechtenstein',
|
149 |
-
'LT' => 'Lithuania',
|
150 |
-
'LU' => 'Luxembourg',
|
151 |
-
'MO' => 'Macao',
|
152 |
-
'MK' => 'Macedonia',
|
153 |
-
'MG' => 'Madagascar',
|
154 |
-
'MW' => 'Malawi',
|
155 |
-
'MY' => 'Malaysia',
|
156 |
-
'MV' => 'Maldives',
|
157 |
-
'ML' => 'Mali',
|
158 |
-
'MT' => 'Malta',
|
159 |
-
'MH' => 'Marshall Islands',
|
160 |
-
'MQ' => 'Martinique',
|
161 |
-
'MR' => 'Mauritania',
|
162 |
-
'MU' => 'Mauritius',
|
163 |
-
'YT' => 'Mayotte',
|
164 |
-
'MX' => 'Mexico',
|
165 |
-
'FM' => 'Micronesia, Federated States Of',
|
166 |
-
'MD' => 'Moldova',
|
167 |
-
'MC' => 'Monaco',
|
168 |
-
'MN' => 'Mongolia',
|
169 |
-
'ME' => 'Montenegro',
|
170 |
-
'MS' => 'Montserrat',
|
171 |
-
'MA' => 'Morocco',
|
172 |
-
'MZ' => 'Mozambique',
|
173 |
-
'MM' => 'Myanmar',
|
174 |
-
'NA' => 'Namibia',
|
175 |
-
'NR' => 'Nauru',
|
176 |
-
'NP' => 'Nepal',
|
177 |
-
'NL' => 'Netherlands',
|
178 |
-
'AN' => 'Netherlands Antilles',
|
179 |
-
'NC' => 'New Caledonia',
|
180 |
-
'NZ' => 'New Zealand',
|
181 |
-
'NI' => 'Nicaragua',
|
182 |
-
'NE' => 'Niger',
|
183 |
-
'NG' => 'Nigeria',
|
184 |
-
'NU' => 'Niue',
|
185 |
-
'NF' => 'Norfolk Island',
|
186 |
-
'MP' => 'Northern Mariana Islands',
|
187 |
-
'NO' => 'Norway',
|
188 |
-
'OM' => 'Oman',
|
189 |
-
'PK' => 'Pakistan',
|
190 |
-
'PW' => 'Palau',
|
191 |
-
'PS' => 'Palestinian Territory, Occupied',
|
192 |
-
'PA' => 'Panama',
|
193 |
-
'PG' => 'Papua New Guinea',
|
194 |
-
'PY' => 'Paraguay',
|
195 |
-
'PE' => 'Peru',
|
196 |
-
'PH' => 'Philippines',
|
197 |
-
'PN' => 'Pitcairn',
|
198 |
-
'PL' => 'Poland',
|
199 |
-
'PT' => 'Portugal',
|
200 |
-
'PR' => 'Puerto Rico',
|
201 |
-
'QA' => 'Qatar',
|
202 |
-
'RE' => 'Reunion',
|
203 |
-
'RO' => 'Romania',
|
204 |
-
'RU' => 'Russian Federation',
|
205 |
-
'RW' => 'Rwanda',
|
206 |
-
'BL' => 'Saint Barthelemy',
|
207 |
-
'SH' => 'Saint Helena',
|
208 |
-
'KN' => 'Saint Kitts And Nevis',
|
209 |
-
'LC' => 'Saint Lucia',
|
210 |
-
'MF' => 'Saint Martin',
|
211 |
-
'PM' => 'Saint Pierre And Miquelon',
|
212 |
-
'VC' => 'Saint Vincent And Grenadines',
|
213 |
-
'WS' => 'Samoa',
|
214 |
-
'SM' => 'San Marino',
|
215 |
-
'ST' => 'Sao Tome And Principe',
|
216 |
-
'SA' => 'Saudi Arabia',
|
217 |
-
'SN' => 'Senegal',
|
218 |
-
'RS' => 'Serbia',
|
219 |
-
'SC' => 'Seychelles',
|
220 |
-
'SL' => 'Sierra Leone',
|
221 |
-
'SG' => 'Singapore',
|
222 |
-
'SK' => 'Slovakia',
|
223 |
-
'SI' => 'Slovenia',
|
224 |
-
'SB' => 'Solomon Islands',
|
225 |
-
'SO' => 'Somalia',
|
226 |
-
'ZA' => 'South Africa',
|
227 |
-
'GS' => 'South Georgia And Sandwich Isl.',
|
228 |
-
'ES' => 'Spain',
|
229 |
-
'LK' => 'Sri Lanka',
|
230 |
-
'SD' => 'Sudan',
|
231 |
-
'SR' => 'Suriname',
|
232 |
-
'SJ' => 'Svalbard And Jan Mayen',
|
233 |
-
'SZ' => 'Swaziland',
|
234 |
-
'SE' => 'Sweden',
|
235 |
-
'CH' => 'Switzerland',
|
236 |
-
'SY' => 'Syrian Arab Republic',
|
237 |
-
'TW' => 'Taiwan',
|
238 |
-
'TJ' => 'Tajikistan',
|
239 |
-
'TZ' => 'Tanzania',
|
240 |
-
'TH' => 'Thailand',
|
241 |
-
'TL' => 'Timor-Leste',
|
242 |
-
'TG' => 'Togo',
|
243 |
-
'TK' => 'Tokelau',
|
244 |
-
'TO' => 'Tonga',
|
245 |
-
'TT' => 'Trinidad And Tobago',
|
246 |
-
'TN' => 'Tunisia',
|
247 |
-
'TR' => 'Turkey',
|
248 |
-
'TM' => 'Turkmenistan',
|
249 |
-
'TC' => 'Turks And Caicos Islands',
|
250 |
-
'TV' => 'Tuvalu',
|
251 |
-
'UG' => 'Uganda',
|
252 |
-
'UA' => 'Ukraine',
|
253 |
-
'AE' => 'United Arab Emirates',
|
254 |
-
'GB' => 'United Kingdom',
|
255 |
-
'US' => 'United States',
|
256 |
-
'UM' => 'United States Outlying Islands',
|
257 |
-
'UY' => 'Uruguay',
|
258 |
-
'UZ' => 'Uzbekistan',
|
259 |
-
'VU' => 'Vanuatu',
|
260 |
-
'VE' => 'Venezuela',
|
261 |
-
'VN' => 'Viet Nam',
|
262 |
-
'VG' => 'Virgin Islands, British',
|
263 |
-
'VI' => 'Virgin Islands, U.S.',
|
264 |
-
'WF' => 'Wallis And Futuna',
|
265 |
-
'EH' => 'Western Sahara',
|
266 |
-
'YE' => 'Yemen',
|
267 |
-
'ZM' => 'Zambia',
|
268 |
-
'ZW' => 'Zimbabwe',
|
269 |
-
'XX' => 'Undefined',
|
270 |
-
'CW' => 'Curaçao',
|
271 |
-
'SS' => 'South Sudan',
|
272 |
-
'EU' => 'Europe (generic)',
|
273 |
-
'A1' => 'Anonymous IP',
|
274 |
-
'A2' => 'Satellite IP'
|
275 |
-
);
|
276 |
-
|
277 |
-
/**
|
278 |
-
*
|
279 |
-
* @param array $options
|
280 |
-
*/
|
281 |
-
function __construct($options = null) {
|
282 |
-
if ($options === null) {
|
283 |
-
if (isset($_POST['options'])) {
|
284 |
-
$this->data = stripslashes_deep($_POST['options']);
|
285 |
-
}
|
286 |
-
} else {
|
287 |
-
$this->data = (array) $options;
|
288 |
-
}
|
289 |
-
|
290 |
-
if (isset($_REQUEST['act'])) {
|
291 |
-
$this->action = $_REQUEST['act'];
|
292 |
-
}
|
293 |
-
|
294 |
-
if (isset($_REQUEST['btn'])) {
|
295 |
-
$this->button_data = $_REQUEST['btn'];
|
296 |
-
}
|
297 |
-
// Fields analysis
|
298 |
-
if (isset($_REQUEST['tnp_fields'])) {
|
299 |
-
$fields = $_REQUEST['tnp_fields'];
|
300 |
-
if (is_array($fields)) {
|
301 |
-
foreach ($fields as $name => $type) {
|
302 |
-
if ($type == 'datetime') {
|
303 |
-
// Ex. The user insert 01/07/2012 14:30 and it set the time zone to +2. We cannot use the
|
304 |
-
// mktime, since it uses the time zone of the machine. We create the time as if we are on
|
305 |
-
// GMT 0 and then we subtract the GMT offset (the example date and time on GMT+2 happens
|
306 |
-
// "before").
|
307 |
-
|
308 |
-
$time = gmmktime((int) $_REQUEST[$name . '_hour'], 0, 0, (int) $_REQUEST[$name . '_month'], (int) $_REQUEST[$name . '_day'], (int) $_REQUEST[$name . '_year']);
|
309 |
-
$time -= get_option('gmt_offset') * 3600;
|
310 |
-
$this->data[$name] = $time;
|
311 |
-
continue;
|
312 |
-
}
|
313 |
-
if ($type === 'array') {
|
314 |
-
if (!isset($this->data[$name]))
|
315 |
-
$this->data[$name] = [];
|
316 |
-
}
|
317 |
-
if ($type === 'checkbox') {
|
318 |
-
if (!isset($this->data[$name])) {
|
319 |
-
$this->data[$name] = 0;
|
320 |
-
}
|
321 |
-
}
|
322 |
-
}
|
323 |
-
}
|
324 |
-
}
|
325 |
-
}
|
326 |
-
|
327 |
-
function set_data($data) {
|
328 |
-
if (is_array($data)) {
|
329 |
-
$this->data = $data;
|
330 |
-
} else if (is_object($data)) {
|
331 |
-
$this->data = (array) $data;
|
332 |
-
} else {
|
333 |
-
$this->data = [];
|
334 |
-
}
|
335 |
-
}
|
336 |
-
|
337 |
-
function merge($options) {
|
338 |
-
if (!is_array($options))
|
339 |
-
return;
|
340 |
-
if ($this->data == null)
|
341 |
-
$this->data = array();
|
342 |
-
$this->data = array_merge($this->data, $options);
|
343 |
-
}
|
344 |
-
|
345 |
-
function merge_defaults($defaults) {
|
346 |
-
if ($this->data == null)
|
347 |
-
$this->data = $defaults;
|
348 |
-
else
|
349 |
-
$this->data = array_merge($defaults, $this->data);
|
350 |
-
}
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Return true is there in an asked action is no action name is specified or
|
354 |
-
* true is the requested action matches the passed action.
|
355 |
-
* Dies if it is not a safe call.
|
356 |
-
*/
|
357 |
-
function is_action($action = null) {
|
358 |
-
if ($action == null)
|
359 |
-
return $this->action != null;
|
360 |
-
if ($this->action == null)
|
361 |
-
return false;
|
362 |
-
if ($this->action != $action)
|
363 |
-
return false;
|
364 |
-
if (check_admin_referer('save'))
|
365 |
-
return true;
|
366 |
-
die('Invalid call');
|
367 |
-
}
|
368 |
-
|
369 |
-
function get_value($name, $def = null) {
|
370 |
-
if (!isset($this->data[$name])) {
|
371 |
-
return $def;
|
372 |
-
}
|
373 |
-
return $this->data[$name];
|
374 |
-
}
|
375 |
-
|
376 |
-
function get_value_array($name) {
|
377 |
-
if (!isset($this->data[$name]) || !is_array($this->data[$name]))
|
378 |
-
return array();
|
379 |
-
return $this->data[$name];
|
380 |
-
}
|
381 |
-
|
382 |
-
function show_error($text) {
|
383 |
-
echo '<div class="tnp-error">', $text, '</div>';
|
384 |
-
}
|
385 |
-
|
386 |
-
function show_warning($text) {
|
387 |
-
echo '<div class="tnp-warning">', $text, '</div>';
|
388 |
-
}
|
389 |
-
|
390 |
-
function show_message($text) {
|
391 |
-
echo '<div class="tnpc-message">', $text, '</div>';
|
392 |
-
}
|
393 |
-
|
394 |
-
/**
|
395 |
-
* Show the errors and messages.
|
396 |
-
*/
|
397 |
-
function show() {
|
398 |
-
static $shown = false;
|
399 |
-
|
400 |
-
if ($shown) {
|
401 |
-
return;
|
402 |
-
}
|
403 |
-
$shown = true;
|
404 |
-
|
405 |
-
if (!empty($this->errors)) {
|
406 |
-
echo '<div class="tnpc-error">';
|
407 |
-
echo $this->errors;
|
408 |
-
echo '</div>';
|
409 |
-
}
|
410 |
-
if (!empty($this->warnings)) {
|
411 |
-
foreach ((array) $this->warnings as $warning) {
|
412 |
-
echo '<div class="tnpc-warning">';
|
413 |
-
echo $warning;
|
414 |
-
echo '</div>';
|
415 |
-
}
|
416 |
-
}
|
417 |
-
if (!empty($this->messages)) {
|
418 |
-
echo '<div class="tnpc-message">';
|
419 |
-
echo $this->messages;
|
420 |
-
echo '</div>';
|
421 |
-
}
|
422 |
-
}
|
423 |
-
|
424 |
-
function add_message($text) {
|
425 |
-
if (!empty($this->messages)) {
|
426 |
-
$this->messages .= '<br><br>';
|
427 |
-
}
|
428 |
-
$this->messages .= $text;
|
429 |
-
}
|
430 |
-
|
431 |
-
function add_message_saved() {
|
432 |
-
if (!empty($this->messages)) {
|
433 |
-
$this->messages .= '<br><br>';
|
434 |
-
}
|
435 |
-
$this->messages .= __('Saved.', 'newsletter');
|
436 |
-
}
|
437 |
-
|
438 |
-
function add_message_deleted() {
|
439 |
-
if (!empty($this->messages)) {
|
440 |
-
$this->messages .= '<br><br>';
|
441 |
-
}
|
442 |
-
$this->messages .= __('Deleted.', 'newsletter');
|
443 |
-
}
|
444 |
-
|
445 |
-
function add_message_reset() {
|
446 |
-
if (!empty($this->messages)) {
|
447 |
-
$this->messages .= '<br><br>';
|
448 |
-
}
|
449 |
-
$this->messages .= __('Options reset.', 'newsletter');
|
450 |
-
}
|
451 |
-
|
452 |
-
function add_message_done() {
|
453 |
-
if (!empty($this->messages)) {
|
454 |
-
$this->messages .= '<br><br>';
|
455 |
-
}
|
456 |
-
$this->messages .= __('Done.', 'newsletter');
|
457 |
-
}
|
458 |
-
|
459 |
-
function add_language_warning() {
|
460 |
-
$newsletter = Newsletter::instance();
|
461 |
-
$current_language = $newsletter->get_current_language();
|
462 |
-
|
463 |
-
if (!$current_language) {
|
464 |
-
return;
|
465 |
-
}
|
466 |
-
$this->warnings[] = 'You are configuring the language <strong>' . $newsletter->get_language_label($current_language) . '</strong>. Switch to "all languages" to see all options.';
|
467 |
-
}
|
468 |
-
|
469 |
-
function switch_to_all_languages_notice() {
|
470 |
-
echo '<div class="tnpc-languages-notice">';
|
471 |
-
_e('Switch the administration side to "all languages" to set these options', 'newsletter');
|
472 |
-
echo '</div>';
|
473 |
-
}
|
474 |
-
|
475 |
-
function hint($text, $url = '') {
|
476 |
-
echo '<div class="tnpc-hint">';
|
477 |
-
// Do not escape that, it can be formatted
|
478 |
-
echo $text;
|
479 |
-
if (!empty($url)) {
|
480 |
-
echo ' <a href="' . esc_attr($url) . '" target="_blank">Read more</a>.';
|
481 |
-
}
|
482 |
-
echo '</div>';
|
483 |
-
}
|
484 |
-
|
485 |
-
function yesno($name) {
|
486 |
-
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
487 |
-
|
488 |
-
echo '<select style="width: 60px" name="options[', esc_attr($name), ']">';
|
489 |
-
echo '<option value="0"';
|
490 |
-
if ($value == 0) {
|
491 |
-
echo ' selected';
|
492 |
-
}
|
493 |
-
echo '>', __('No', 'newsletter'), '</option>';
|
494 |
-
echo '<option value="1"';
|
495 |
-
if ($value == 1) {
|
496 |
-
echo ' selected';
|
497 |
-
}
|
498 |
-
echo '>', __('Yes', 'newsletter'), '</option>';
|
499 |
-
echo '</select> ';
|
500 |
-
}
|
501 |
-
|
502 |
-
function enabled($name = 'enabled', $attrs = []) {
|
503 |
-
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
504 |
-
$name = esc_attr($name);
|
505 |
-
|
506 |
-
echo '<select style="width: 100px" name="options[', $name, ']" id="options-', $name, '"';
|
507 |
-
if (isset($attrs['bind_to'])) {
|
508 |
-
echo ' onchange="tnp_select_toggle(this, \'', $attrs['bind_to'], '\')"';
|
509 |
-
}
|
510 |
-
echo '>';
|
511 |
-
echo '<option value="0"';
|
512 |
-
if ($value == 0) {
|
513 |
-
echo ' selected';
|
514 |
-
}
|
515 |
-
echo '>', __('Disabled', 'newsletter'), '</option>';
|
516 |
-
echo '<option value="1"';
|
517 |
-
if ($value == 1) {
|
518 |
-
echo ' selected';
|
519 |
-
}
|
520 |
-
echo '>', __('Enabled', 'newsletter'), '</option>';
|
521 |
-
echo '</select>';
|
522 |
-
if (isset($attrs['bind_to'])) {
|
523 |
-
if ($value) {
|
524 |
-
echo '<script>jQuery(function ($) {$("#options-', $attrs['bind_to'], '").show()})</script>';
|
525 |
-
} else {
|
526 |
-
echo '<script>jQuery(function ($) {$("#options-', $attrs['bind_to'], '").hide()})</script>';
|
527 |
-
}
|
528 |
-
}
|
529 |
-
}
|
530 |
-
|
531 |
-
function disabled($name) {
|
532 |
-
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
533 |
-
|
534 |
-
echo '<select style="width: 100px" name="options[' . esc_attr($name) . ']">';
|
535 |
-
echo '<option value="0"';
|
536 |
-
if ($value == 0) {
|
537 |
-
echo ' selected';
|
538 |
-
}
|
539 |
-
echo '>Enabled</option>';
|
540 |
-
echo '<option value="1"';
|
541 |
-
if ($value == 1) {
|
542 |
-
echo ' selected';
|
543 |
-
}
|
544 |
-
echo '>Disabled</option>';
|
545 |
-
echo '</select>';
|
546 |
-
}
|
547 |
-
|
548 |
-
/**
|
549 |
-
* Creates a set of checkbox all named as $name with values and labels extracted from
|
550 |
-
* $values_labels. A checkbox will be checked if internal data under key $name is an array
|
551 |
-
* and contains the value of the current (echoing) checkbox.
|
552 |
-
*
|
553 |
-
* On submit it produces an array under the name $name IF at least one checkbox has
|
554 |
-
* been checked. Otherwise the key won't be present.
|
555 |
-
*
|
556 |
-
* @param array $values
|
557 |
-
* @param string $name
|
558 |
-
* @param array $values_labels
|
559 |
-
*/
|
560 |
-
function checkboxes_group($name, $values_labels) {
|
561 |
-
$value_array = $this->get_value_array($name);
|
562 |
-
|
563 |
-
echo '<div class="tnpc-checkboxes">';
|
564 |
-
foreach ($values_labels as $value => $label) {
|
565 |
-
echo '<label><input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . '][]" value="' . esc_attr($value) . '"';
|
566 |
-
if (array_search($value, $value_array) !== false) {
|
567 |
-
echo ' checked';
|
568 |
-
}
|
569 |
-
echo '>';
|
570 |
-
if ($label != '') {
|
571 |
-
echo ' ' . esc_html($label);
|
572 |
-
}
|
573 |
-
echo "</label>";
|
574 |
-
}
|
575 |
-
echo "<div style='clear: both'></div>";
|
576 |
-
}
|
577 |
-
|
578 |
-
/** Creates a checkbox group with all public post types.
|
579 |
-
*/
|
580 |
-
function post_types($name = 'post_types') {
|
581 |
-
$list = array();
|
582 |
-
$post_types = get_post_types(array('public' => true), 'objects', 'and');
|
583 |
-
foreach ($post_types as $post_type) {
|
584 |
-
$list[$post_type->name] = $post_type->labels->name;
|
585 |
-
}
|
586 |
-
|
587 |
-
$this->checkboxes_group($name, $list);
|
588 |
-
}
|
589 |
-
|
590 |
-
function posts_select($name, $max = 20, $args = array()) {
|
591 |
-
$args = array_merge(array(
|
592 |
-
'posts_per_page' => 5,
|
593 |
-
'offset' => 0,
|
594 |
-
'category' => '',
|
595 |
-
'category_name' => '',
|
596 |
-
'orderby' => 'date',
|
597 |
-
'order' => 'DESC',
|
598 |
-
'include' => '',
|
599 |
-
'exclude' => '',
|
600 |
-
'meta_key' => '',
|
601 |
-
'meta_value' => '',
|
602 |
-
'post_type' => 'post',
|
603 |
-
'post_mime_type' => '',
|
604 |
-
'post_parent' => '',
|
605 |
-
'author' => '',
|
606 |
-
'author_name' => '',
|
607 |
-
'post_status' => 'publish',
|
608 |
-
'suppress_filters' => true
|
609 |
-
), $args);
|
610 |
-
$args['posts_per_page'] = $max;
|
611 |
-
|
612 |
-
$posts = get_posts($args);
|
613 |
-
$options = array();
|
614 |
-
foreach ($posts as $post) {
|
615 |
-
$options['' . $post->ID] = $post->post_title;
|
616 |
-
}
|
617 |
-
|
618 |
-
$this->select($name, $options);
|
619 |
-
}
|
620 |
-
|
621 |
-
function select_number($name, $min, $max) {
|
622 |
-
$options = array();
|
623 |
-
for ($i = $min; $i <= $max; $i++) {
|
624 |
-
$options['' . $i] = $i;
|
625 |
-
}
|
626 |
-
$this->select($name, $options);
|
627 |
-
}
|
628 |
-
|
629 |
-
function page($name = 'page', $first = null, $language = '', $show_id = false) {
|
630 |
-
$args = array(
|
631 |
-
'post_type' => 'page',
|
632 |
-
'posts_per_page' => 1000,
|
633 |
-
'offset' => 0,
|
634 |
-
'orderby' => 'post_title',
|
635 |
-
'post_status' => 'any',
|
636 |
-
'suppress_filters' => true
|
637 |
-
);
|
638 |
-
|
639 |
-
$pages = get_posts($args);
|
640 |
-
//$pages = get_pages();
|
641 |
-
$options = array();
|
642 |
-
foreach ($pages as $page) {
|
643 |
-
/* @var $page WP_Post */
|
644 |
-
$label = $page->post_title;
|
645 |
-
if ($page->post_status != 'publish') {
|
646 |
-
$label .= ' (' . $page->post_status . ')';
|
647 |
-
}
|
648 |
-
if ($show_id) {
|
649 |
-
$label .= ' [' . $page->ID . ']';
|
650 |
-
}
|
651 |
-
$options[$page->ID] = $label;
|
652 |
-
}
|
653 |
-
$this->select($name, $options, $first);
|
654 |
-
}
|
655 |
-
|
656 |
-
/** Used to create a select which is part of a group of controls identified by $name that will
|
657 |
-
* produce an array of values as $_REQUEST['name'].
|
658 |
-
* @param string $name
|
659 |
-
* @param array $options Associative array
|
660 |
-
*/
|
661 |
-
function select_group($name, $options) {
|
662 |
-
$value_array = $this->get_value_array($name);
|
663 |
-
|
664 |
-
echo '<select name="options[' . esc_attr($name) . '][]">';
|
665 |
-
|
666 |
-
foreach ($options as $key => $label) {
|
667 |
-
echo '<option value="' . esc_attr($key) . '"';
|
668 |
-
if (array_search($key, $value_array) !== false) {
|
669 |
-
echo ' selected';
|
670 |
-
}
|
671 |
-
echo '>' . esc_html($label) . '</option>';
|
672 |
-
}
|
673 |
-
|
674 |
-
echo '</select>';
|
675 |
-
}
|
676 |
-
|
677 |
-
function select($name, $options, $first = null, $attrs = []) {
|
678 |
-
echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']"';
|
679 |
-
if ($attrs) {
|
680 |
-
foreach ($attrs as $key => $value) {
|
681 |
-
echo ' ', $key, '="' . esc_attr($value), '"';
|
682 |
-
}
|
683 |
-
}
|
684 |
-
echo '>';
|
685 |
-
if (!empty($first)) {
|
686 |
-
echo '<option value="">' . esc_html($first) . '</option>';
|
687 |
-
}
|
688 |
-
$value = $this->get_value($name);
|
689 |
-
foreach ($options as $key => $label) {
|
690 |
-
echo '<option value="' . esc_attr($key) . '"';
|
691 |
-
if ($value == $key) {
|
692 |
-
echo ' selected';
|
693 |
-
}
|
694 |
-
echo '>' . esc_html($label) . '</option>';
|
695 |
-
}
|
696 |
-
echo '</select>';
|
697 |
-
}
|
698 |
-
|
699 |
-
function select_images($name, $options, $first = null) {
|
700 |
-
$value = $this->get_value($name);
|
701 |
-
|
702 |
-
echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" style="min-width: 200px">';
|
703 |
-
if (!empty($first)) {
|
704 |
-
echo '<option value="">' . esc_html($first) . '</option>';
|
705 |
-
} else {
|
706 |
-
// if (empty($value)) {
|
707 |
-
// $keys = array_keys($options);
|
708 |
-
// $value = $keys[0];
|
709 |
-
// }
|
710 |
-
}
|
711 |
-
foreach ($options as $key => $data) {
|
712 |
-
echo '<option value="' . esc_attr($key) . '" image="' . esc_attr($data['image']) . '"';
|
713 |
-
if ($value == $key)
|
714 |
-
echo ' selected';
|
715 |
-
echo '>' . esc_html($data['label']) . '</option>';
|
716 |
-
}
|
717 |
-
echo '</select>';
|
718 |
-
echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
|
719 |
-
}
|
720 |
-
|
721 |
-
function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder = '') {
|
722 |
-
|
723 |
-
if ($multiple) {
|
724 |
-
$option_name = "options[" . esc_attr($name) . "][]";
|
725 |
-
} else {
|
726 |
-
$option_name = "options[" . esc_attr($name) . "]";
|
727 |
-
}
|
728 |
-
|
729 |
-
if (is_null($style)) {
|
730 |
-
$style = 'width: 100%';
|
731 |
-
}
|
732 |
-
|
733 |
-
$value = $this->get_value($name);
|
734 |
-
|
735 |
-
echo '<select id="options-', esc_attr($name), '" name="', $option_name, '" style="', $style, '"',
|
736 |
-
($multiple ? ' multiple' : ''), '>';
|
737 |
-
if (!empty($first)) {
|
738 |
-
echo '<option value="">' . esc_html($first) . '</option>';
|
739 |
-
}
|
740 |
-
|
741 |
-
foreach ($options as $key => $data) {
|
742 |
-
echo '<option value="' . esc_attr($key) . '"';
|
743 |
-
if (is_array($value) && in_array($key, $value) || (!is_null($value) && $value == $key )) {
|
744 |
-
echo ' selected';
|
745 |
-
}
|
746 |
-
echo '>' . esc_html($data) . '</option>';
|
747 |
-
}
|
748 |
-
|
749 |
-
echo '</select>';
|
750 |
-
echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
|
751 |
-
}
|
752 |
-
|
753 |
-
function select_grouped($name, $groups) {
|
754 |
-
$value = $this->get_value($name);
|
755 |
-
$name = esc_attr($name);
|
756 |
-
echo '<select name="options[', $name, ']">';
|
757 |
-
|
758 |
-
foreach ($groups as $group) {
|
759 |
-
echo '<optgroup label="' . esc_attr($group['']) . '">';
|
760 |
-
if (!empty($group)) {
|
761 |
-
foreach ($group as $key => $label) {
|
762 |
-
if ($key == '') {
|
763 |
-
continue;
|
764 |
-
}
|
765 |
-
echo '<option value="' . esc_attr($key) . '"';
|
766 |
-
if ($value == $key) {
|
767 |
-
echo ' selected';
|
768 |
-
}
|
769 |
-
echo '>' . esc_html($label) . '</option>';
|
770 |
-
}
|
771 |
-
}
|
772 |
-
echo '</optgroup>';
|
773 |
-
}
|
774 |
-
echo '</select>';
|
775 |
-
}
|
776 |
-
|
777 |
-
/**
|
778 |
-
* Generated a select control with all available templates. From version 3 there are
|
779 |
-
* only on kind of templates, they are no more separated by type.
|
780 |
-
*/
|
781 |
-
function themes($name, $themes, $submit_on_click = true) {
|
782 |
-
foreach ($themes as $key => $data) {
|
783 |
-
echo '<label style="display: block; float: left; text-align: center; margin-right: 10px;">';
|
784 |
-
echo esc_html($key) . '<br>';
|
785 |
-
echo '<img src="' . esc_attr($data['screenshot']) . '" width="100" height="100" style="border: 1px solid #666; padding: 5px"><br>';
|
786 |
-
echo '<input style="position: relative; top: -40px" type="radio" onchange="this.form.act.value=\'theme\';this.form.submit()" name="options[' . esc_attr($name) . ']" value="' . esc_attr($key) . '"';
|
787 |
-
if ($this->data[$name] == $key) {
|
788 |
-
echo ' checked';
|
789 |
-
}
|
790 |
-
echo '>';
|
791 |
-
echo '</label>';
|
792 |
-
}
|
793 |
-
echo '<div style="clear: both"></div>';
|
794 |
-
}
|
795 |
-
|
796 |
-
function value($name) {
|
797 |
-
echo esc_html($this->data[$name]);
|
798 |
-
}
|
799 |
-
|
800 |
-
function value_date($name, $show_remaining = true) {
|
801 |
-
$time = $this->get_value($name);
|
802 |
-
|
803 |
-
echo gmdate(get_option('date_format') . ' ' . get_option('time_format'), $time + get_option('gmt_offset') * 3600);
|
804 |
-
$delta = $time - time();
|
805 |
-
if ($show_remaining && $delta > 0) {
|
806 |
-
echo 'Remaining: ';
|
807 |
-
$delta = $time - time();
|
808 |
-
$days = floor($delta / (24 * 3600));
|
809 |
-
$delta = $delta - $days * 24 * 3600;
|
810 |
-
$hours = floor($delta / 3600);
|
811 |
-
$delta = $delta - $hours * 3600;
|
812 |
-
$minutes = floor($delta / 60);
|
813 |
-
|
814 |
-
if ($days > 0) {
|
815 |
-
echo $days . ' days ';
|
816 |
-
}
|
817 |
-
echo $hours . ' hours ';
|
818 |
-
echo $minutes . ' minutes ';
|
819 |
-
}
|
820 |
-
}
|
821 |
-
|
822 |
-
function password($name, $size = 20, $placeholder = '') {
|
823 |
-
$value = $this->get_value($name);
|
824 |
-
$name = esc_attr($name);
|
825 |
-
echo '<input id="options-', $name, '" placeholder="' . esc_attr($placeholder) . '" name="options[', $name, ']" type="password" autocomplete="off" ';
|
826 |
-
if (!empty($size)) {
|
827 |
-
echo 'size="', $size, '" ';
|
828 |
-
}
|
829 |
-
echo 'value="', esc_attr($value), '">';
|
830 |
-
}
|
831 |
-
|
832 |
-
function text($name, $size = 20, $placeholder = '') {
|
833 |
-
$value = $this->get_value($name);
|
834 |
-
$name = esc_attr($name);
|
835 |
-
echo '<input id="options-', $name, '" placeholder="' . esc_attr($placeholder) . '" title="' . esc_attr($placeholder) . '" name="options[', $name, ']" type="text" ';
|
836 |
-
if (!empty($size)) {
|
837 |
-
echo 'size="', esc_attr($size), '" ';
|
838 |
-
}
|
839 |
-
echo 'value="', esc_attr($value), '">';
|
840 |
-
}
|
841 |
-
|
842 |
-
function text_email($name, $size = 40) {
|
843 |
-
$value = $this->get_value($name);
|
844 |
-
echo '<input name="options[' . esc_attr($name) . ']" type="email" placeholder="';
|
845 |
-
echo esc_attr__('Valid email address', 'newsletter');
|
846 |
-
echo '" size="' . esc_attr($size) . '" value="';
|
847 |
-
echo esc_attr($value);
|
848 |
-
echo '">';
|
849 |
-
}
|
850 |
-
|
851 |
-
function text_url($name, $size = 40) {
|
852 |
-
$value = $this->get_value($name);
|
853 |
-
echo '<input name="options[' . esc_attr($name) . ']" type="url" placeholder="http://..." size="' . esc_attr($size) . '" value="';
|
854 |
-
echo esc_attr($value);
|
855 |
-
echo '"/>';
|
856 |
-
}
|
857 |
-
|
858 |
-
function hidden($name) {
|
859 |
-
$value = $this->get_value($name);
|
860 |
-
echo '<input name="options[', esc_attr($name), ']" id="options-', esc_attr($name), '" type="hidden" value="', esc_attr($value), '">';
|
861 |
-
}
|
862 |
-
|
863 |
-
/**
|
864 |
-
* General button.
|
865 |
-
*
|
866 |
-
*
|
867 |
-
*
|
868 |
-
*
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
echo
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
echo
|
940 |
-
}
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
}
|
952 |
-
|
953 |
-
function
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
}
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
function
|
966 |
-
$this->btn(
|
967 |
-
}
|
968 |
-
|
969 |
-
function
|
970 |
-
$this->btn('
|
971 |
-
}
|
972 |
-
|
973 |
-
function
|
974 |
-
$this->
|
975 |
-
}
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
function
|
982 |
-
$this->
|
983 |
-
}
|
984 |
-
|
985 |
-
function
|
986 |
-
$this->
|
987 |
-
}
|
988 |
-
|
989 |
-
function
|
990 |
-
$this->btn_link($url, '', ['icon' => 'fa-
|
991 |
-
}
|
992 |
-
|
993 |
-
function
|
994 |
-
$this->btn_link($url, '', ['icon' => 'fa-
|
995 |
-
}
|
996 |
-
|
997 |
-
function
|
998 |
-
$this->btn_link($url, '', ['icon' => 'fa-
|
999 |
-
}
|
1000 |
-
|
1001 |
-
function
|
1002 |
-
$this->btn_link($url, '', ['icon' => 'fa-
|
1003 |
-
}
|
1004 |
-
|
1005 |
-
function
|
1006 |
-
$this->btn_link($url, '', ['icon' => 'fa-
|
1007 |
-
}
|
1008 |
-
|
1009 |
-
function
|
1010 |
-
$this->
|
1011 |
-
}
|
1012 |
-
|
1013 |
-
function
|
1014 |
-
$this->btn_link($url,
|
1015 |
-
}
|
1016 |
-
|
1017 |
-
function
|
1018 |
-
$this->
|
1019 |
-
}
|
1020 |
-
|
1021 |
-
function
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
}
|
1028 |
-
|
1029 |
-
function
|
1030 |
-
$this->
|
1031 |
-
}
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
$
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
echo '<textarea id="options-'
|
1094 |
-
echo esc_html($value);
|
1095 |
-
echo '</textarea>';
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
echo '
|
1128 |
-
}
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
echo '<
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
echo '
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
$
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
echo '
|
1229 |
-
}
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
*
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
$
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
echo '
|
1277 |
-
}
|
1278 |
-
|
1279 |
-
/**
|
1280 |
-
*
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
echo '<
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
echo '
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
$
|
1317 |
-
|
1318 |
-
|
1319 |
-
$
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
echo '<
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
$
|
1359 |
-
}
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
$this->
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
echo '
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
echo '<
|
1438 |
-
for ($i =
|
1439 |
-
echo '<option value="' . $i . '"';
|
1440 |
-
if ($
|
1441 |
-
echo ' selected';
|
1442 |
-
}
|
1443 |
-
echo '>' . $i . '</option>';
|
1444 |
-
}
|
1445 |
-
echo '</select>';
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
$
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
echo '
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
echo '<
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
for ($i =
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
})
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
}
|
1611 |
-
function
|
1612 |
-
if (
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
if (
|
1631 |
-
|
1632 |
-
}
|
1633 |
-
|
1634 |
-
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
1638 |
-
|
1639 |
-
function
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
1661 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
|
1668 |
-
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
function
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
$
|
1703 |
-
|
1704 |
-
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
echo '
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
|
1751 |
-
|
1752 |
-
|
1753 |
-
|
1754 |
-
$
|
1755 |
-
|
1756 |
-
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
1760 |
-
|
1761 |
-
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
1765 |
-
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
$
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
$
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
echo '
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
1812 |
-
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
1831 |
-
$
|
1832 |
-
|
1833 |
-
$
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
$
|
1855 |
-
|
1856 |
-
|
1857 |
-
|
1858 |
-
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
if (
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
|
1894 |
-
|
1895 |
-
}
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
|
1903 |
-
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
|
1908 |
-
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
1912 |
-
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
1923 |
-
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
1930 |
-
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
|
1938 |
-
|
1939 |
-
|
1940 |
-
|
1941 |
-
*
|
1942 |
-
*
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
echo '<
|
1948 |
-
}
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
echo '<
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
echo
|
1966 |
-
|
1967 |
-
|
1968 |
-
|
1969 |
-
|
1970 |
-
}
|
1971 |
-
|
1972 |
-
|
1973 |
-
|
1974 |
-
|
1975 |
-
|
1976 |
-
|
1977 |
-
|
1978 |
-
|
1979 |
-
|
1980 |
-
|
1981 |
-
echo '</
|
1982 |
-
}
|
1983 |
-
|
1984 |
-
/**
|
1985 |
-
*
|
1986 |
-
*
|
1987 |
-
* @param type $
|
1988 |
-
*/
|
1989 |
-
function
|
1990 |
-
|
1991 |
-
|
1992 |
-
$
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
if ($
|
1997 |
-
|
1998 |
-
|
1999 |
-
|
2000 |
-
|
2001 |
-
|
2002 |
-
|
2003 |
-
$
|
2004 |
-
|
2005 |
-
|
2006 |
-
|
2007 |
-
|
2008 |
-
|
2009 |
-
|
2010 |
-
$
|
2011 |
-
|
2012 |
-
$
|
2013 |
-
echo '<
|
2014 |
-
|
2015 |
-
|
2016 |
-
|
2017 |
-
|
2018 |
-
|
2019 |
-
|
2020 |
-
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
|
2032 |
-
|
2033 |
-
|
2034 |
-
|
2035 |
-
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
$
|
2044 |
-
|
2045 |
-
|
2046 |
-
|
2047 |
-
|
2048 |
-
|
2049 |
-
|
2050 |
-
|
2051 |
-
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
2057 |
-
|
2058 |
-
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
|
2063 |
-
|
2064 |
-
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
-
|
2070 |
-
|
2071 |
-
|
2072 |
-
|
2073 |
-
|
2074 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
+
include_once __DIR__ . '/fields.php';
|
6 |
+
|
7 |
+
class NewsletterControls {
|
8 |
+
|
9 |
+
var $data = [];
|
10 |
+
var $action = false;
|
11 |
+
var $button_data = '';
|
12 |
+
var $errors = '';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
var $messages = '';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
var $warnings = array();
|
23 |
+
var $countries = array(
|
24 |
+
'AF' => 'Afghanistan',
|
25 |
+
'AX' => 'Aland Islands',
|
26 |
+
'AL' => 'Albania',
|
27 |
+
'DZ' => 'Algeria',
|
28 |
+
'AS' => 'American Samoa',
|
29 |
+
'AD' => 'Andorra',
|
30 |
+
'AO' => 'Angola',
|
31 |
+
'AI' => 'Anguilla',
|
32 |
+
'AQ' => 'Antarctica',
|
33 |
+
'AG' => 'Antigua And Barbuda',
|
34 |
+
'AR' => 'Argentina',
|
35 |
+
'AM' => 'Armenia',
|
36 |
+
'AW' => 'Aruba',
|
37 |
+
'AU' => 'Australia',
|
38 |
+
'AT' => 'Austria',
|
39 |
+
'AZ' => 'Azerbaijan',
|
40 |
+
'BS' => 'Bahamas',
|
41 |
+
'BH' => 'Bahrain',
|
42 |
+
'BD' => 'Bangladesh',
|
43 |
+
'BB' => 'Barbados',
|
44 |
+
'BY' => 'Belarus',
|
45 |
+
'BE' => 'Belgium',
|
46 |
+
'BZ' => 'Belize',
|
47 |
+
'BJ' => 'Benin',
|
48 |
+
'BM' => 'Bermuda',
|
49 |
+
'BT' => 'Bhutan',
|
50 |
+
'BO' => 'Bolivia',
|
51 |
+
'BA' => 'Bosnia And Herzegovina',
|
52 |
+
'BW' => 'Botswana',
|
53 |
+
'BV' => 'Bouvet Island',
|
54 |
+
'BR' => 'Brazil',
|
55 |
+
'IO' => 'British Indian Ocean Territory',
|
56 |
+
'BN' => 'Brunei Darussalam',
|
57 |
+
'BG' => 'Bulgaria',
|
58 |
+
'BF' => 'Burkina Faso',
|
59 |
+
'BI' => 'Burundi',
|
60 |
+
'KH' => 'Cambodia',
|
61 |
+
'CM' => 'Cameroon',
|
62 |
+
'CA' => 'Canada',
|
63 |
+
'CV' => 'Cape Verde',
|
64 |
+
'KY' => 'Cayman Islands',
|
65 |
+
'CF' => 'Central African Republic',
|
66 |
+
'TD' => 'Chad',
|
67 |
+
'CL' => 'Chile',
|
68 |
+
'CN' => 'China',
|
69 |
+
'CX' => 'Christmas Island',
|
70 |
+
'CC' => 'Cocos (Keeling) Islands',
|
71 |
+
'CO' => 'Colombia',
|
72 |
+
'KM' => 'Comoros',
|
73 |
+
'CG' => 'Congo',
|
74 |
+
'CD' => 'Congo, Democratic Republic',
|
75 |
+
'CK' => 'Cook Islands',
|
76 |
+
'CR' => 'Costa Rica',
|
77 |
+
'CI' => 'Cote D\'Ivoire',
|
78 |
+
'HR' => 'Croatia',
|
79 |
+
'CU' => 'Cuba',
|
80 |
+
'CY' => 'Cyprus',
|
81 |
+
'CZ' => 'Czech Republic',
|
82 |
+
'DK' => 'Denmark',
|
83 |
+
'DJ' => 'Djibouti',
|
84 |
+
'DM' => 'Dominica',
|
85 |
+
'DO' => 'Dominican Republic',
|
86 |
+
'EC' => 'Ecuador',
|
87 |
+
'EG' => 'Egypt',
|
88 |
+
'SV' => 'El Salvador',
|
89 |
+
'GQ' => 'Equatorial Guinea',
|
90 |
+
'ER' => 'Eritrea',
|
91 |
+
'EE' => 'Estonia',
|
92 |
+
'ET' => 'Ethiopia',
|
93 |
+
'FK' => 'Falkland Islands (Malvinas)',
|
94 |
+
'FO' => 'Faroe Islands',
|
95 |
+
'FJ' => 'Fiji',
|
96 |
+
'FI' => 'Finland',
|
97 |
+
'FR' => 'France',
|
98 |
+
'GF' => 'French Guiana',
|
99 |
+
'PF' => 'French Polynesia',
|
100 |
+
'TF' => 'French Southern Territories',
|
101 |
+
'GA' => 'Gabon',
|
102 |
+
'GM' => 'Gambia',
|
103 |
+
'GE' => 'Georgia',
|
104 |
+
'DE' => 'Germany',
|
105 |
+
'GH' => 'Ghana',
|
106 |
+
'GI' => 'Gibraltar',
|
107 |
+
'GR' => 'Greece',
|
108 |
+
'GL' => 'Greenland',
|
109 |
+
'GD' => 'Grenada',
|
110 |
+
'GP' => 'Guadeloupe',
|
111 |
+
'GU' => 'Guam',
|
112 |
+
'GT' => 'Guatemala',
|
113 |
+
'GG' => 'Guernsey',
|
114 |
+
'GN' => 'Guinea',
|
115 |
+
'GW' => 'Guinea-Bissau',
|
116 |
+
'GY' => 'Guyana',
|
117 |
+
'HT' => 'Haiti',
|
118 |
+
'HM' => 'Heard Island & Mcdonald Islands',
|
119 |
+
'VA' => 'Holy See (Vatican City State)',
|
120 |
+
'HN' => 'Honduras',
|
121 |
+
'HK' => 'Hong Kong',
|
122 |
+
'HU' => 'Hungary',
|
123 |
+
'IS' => 'Iceland',
|
124 |
+
'IN' => 'India',
|
125 |
+
'ID' => 'Indonesia',
|
126 |
+
'IR' => 'Iran, Islamic Republic Of',
|
127 |
+
'IQ' => 'Iraq',
|
128 |
+
'IE' => 'Ireland',
|
129 |
+
'IM' => 'Isle Of Man',
|
130 |
+
'IL' => 'Israel',
|
131 |
+
'IT' => 'Italy',
|
132 |
+
'JM' => 'Jamaica',
|
133 |
+
'JP' => 'Japan',
|
134 |
+
'JE' => 'Jersey',
|
135 |
+
'JO' => 'Jordan',
|
136 |
+
'KZ' => 'Kazakhstan',
|
137 |
+
'KE' => 'Kenya',
|
138 |
+
'KI' => 'Kiribati',
|
139 |
+
'KR' => 'Korea',
|
140 |
+
'KW' => 'Kuwait',
|
141 |
+
'KG' => 'Kyrgyzstan',
|
142 |
+
'LA' => 'Lao People\'s Democratic Republic',
|
143 |
+
'LV' => 'Latvia',
|
144 |
+
'LB' => 'Lebanon',
|
145 |
+
'LS' => 'Lesotho',
|
146 |
+
'LR' => 'Liberia',
|
147 |
+
'LY' => 'Libyan Arab Jamahiriya',
|
148 |
+
'LI' => 'Liechtenstein',
|
149 |
+
'LT' => 'Lithuania',
|
150 |
+
'LU' => 'Luxembourg',
|
151 |
+
'MO' => 'Macao',
|
152 |
+
'MK' => 'Macedonia',
|
153 |
+
'MG' => 'Madagascar',
|
154 |
+
'MW' => 'Malawi',
|
155 |
+
'MY' => 'Malaysia',
|
156 |
+
'MV' => 'Maldives',
|
157 |
+
'ML' => 'Mali',
|
158 |
+
'MT' => 'Malta',
|
159 |
+
'MH' => 'Marshall Islands',
|
160 |
+
'MQ' => 'Martinique',
|
161 |
+
'MR' => 'Mauritania',
|
162 |
+
'MU' => 'Mauritius',
|
163 |
+
'YT' => 'Mayotte',
|
164 |
+
'MX' => 'Mexico',
|
165 |
+
'FM' => 'Micronesia, Federated States Of',
|
166 |
+
'MD' => 'Moldova',
|
167 |
+
'MC' => 'Monaco',
|
168 |
+
'MN' => 'Mongolia',
|
169 |
+
'ME' => 'Montenegro',
|
170 |
+
'MS' => 'Montserrat',
|
171 |
+
'MA' => 'Morocco',
|
172 |
+
'MZ' => 'Mozambique',
|
173 |
+
'MM' => 'Myanmar',
|
174 |
+
'NA' => 'Namibia',
|
175 |
+
'NR' => 'Nauru',
|
176 |
+
'NP' => 'Nepal',
|
177 |
+
'NL' => 'Netherlands',
|
178 |
+
'AN' => 'Netherlands Antilles',
|
179 |
+
'NC' => 'New Caledonia',
|
180 |
+
'NZ' => 'New Zealand',
|
181 |
+
'NI' => 'Nicaragua',
|
182 |
+
'NE' => 'Niger',
|
183 |
+
'NG' => 'Nigeria',
|
184 |
+
'NU' => 'Niue',
|
185 |
+
'NF' => 'Norfolk Island',
|
186 |
+
'MP' => 'Northern Mariana Islands',
|
187 |
+
'NO' => 'Norway',
|
188 |
+
'OM' => 'Oman',
|
189 |
+
'PK' => 'Pakistan',
|
190 |
+
'PW' => 'Palau',
|
191 |
+
'PS' => 'Palestinian Territory, Occupied',
|
192 |
+
'PA' => 'Panama',
|
193 |
+
'PG' => 'Papua New Guinea',
|
194 |
+
'PY' => 'Paraguay',
|
195 |
+
'PE' => 'Peru',
|
196 |
+
'PH' => 'Philippines',
|
197 |
+
'PN' => 'Pitcairn',
|
198 |
+
'PL' => 'Poland',
|
199 |
+
'PT' => 'Portugal',
|
200 |
+
'PR' => 'Puerto Rico',
|
201 |
+
'QA' => 'Qatar',
|
202 |
+
'RE' => 'Reunion',
|
203 |
+
'RO' => 'Romania',
|
204 |
+
'RU' => 'Russian Federation',
|
205 |
+
'RW' => 'Rwanda',
|
206 |
+
'BL' => 'Saint Barthelemy',
|
207 |
+
'SH' => 'Saint Helena',
|
208 |
+
'KN' => 'Saint Kitts And Nevis',
|
209 |
+
'LC' => 'Saint Lucia',
|
210 |
+
'MF' => 'Saint Martin',
|
211 |
+
'PM' => 'Saint Pierre And Miquelon',
|
212 |
+
'VC' => 'Saint Vincent And Grenadines',
|
213 |
+
'WS' => 'Samoa',
|
214 |
+
'SM' => 'San Marino',
|
215 |
+
'ST' => 'Sao Tome And Principe',
|
216 |
+
'SA' => 'Saudi Arabia',
|
217 |
+
'SN' => 'Senegal',
|
218 |
+
'RS' => 'Serbia',
|
219 |
+
'SC' => 'Seychelles',
|
220 |
+
'SL' => 'Sierra Leone',
|
221 |
+
'SG' => 'Singapore',
|
222 |
+
'SK' => 'Slovakia',
|
223 |
+
'SI' => 'Slovenia',
|
224 |
+
'SB' => 'Solomon Islands',
|
225 |
+
'SO' => 'Somalia',
|
226 |
+
'ZA' => 'South Africa',
|
227 |
+
'GS' => 'South Georgia And Sandwich Isl.',
|
228 |
+
'ES' => 'Spain',
|
229 |
+
'LK' => 'Sri Lanka',
|
230 |
+
'SD' => 'Sudan',
|
231 |
+
'SR' => 'Suriname',
|
232 |
+
'SJ' => 'Svalbard And Jan Mayen',
|
233 |
+
'SZ' => 'Swaziland',
|
234 |
+
'SE' => 'Sweden',
|
235 |
+
'CH' => 'Switzerland',
|
236 |
+
'SY' => 'Syrian Arab Republic',
|
237 |
+
'TW' => 'Taiwan',
|
238 |
+
'TJ' => 'Tajikistan',
|
239 |
+
'TZ' => 'Tanzania',
|
240 |
+
'TH' => 'Thailand',
|
241 |
+
'TL' => 'Timor-Leste',
|
242 |
+
'TG' => 'Togo',
|
243 |
+
'TK' => 'Tokelau',
|
244 |
+
'TO' => 'Tonga',
|
245 |
+
'TT' => 'Trinidad And Tobago',
|
246 |
+
'TN' => 'Tunisia',
|
247 |
+
'TR' => 'Turkey',
|
248 |
+
'TM' => 'Turkmenistan',
|
249 |
+
'TC' => 'Turks And Caicos Islands',
|
250 |
+
'TV' => 'Tuvalu',
|
251 |
+
'UG' => 'Uganda',
|
252 |
+
'UA' => 'Ukraine',
|
253 |
+
'AE' => 'United Arab Emirates',
|
254 |
+
'GB' => 'United Kingdom',
|
255 |
+
'US' => 'United States',
|
256 |
+
'UM' => 'United States Outlying Islands',
|
257 |
+
'UY' => 'Uruguay',
|
258 |
+
'UZ' => 'Uzbekistan',
|
259 |
+
'VU' => 'Vanuatu',
|
260 |
+
'VE' => 'Venezuela',
|
261 |
+
'VN' => 'Viet Nam',
|
262 |
+
'VG' => 'Virgin Islands, British',
|
263 |
+
'VI' => 'Virgin Islands, U.S.',
|
264 |
+
'WF' => 'Wallis And Futuna',
|
265 |
+
'EH' => 'Western Sahara',
|
266 |
+
'YE' => 'Yemen',
|
267 |
+
'ZM' => 'Zambia',
|
268 |
+
'ZW' => 'Zimbabwe',
|
269 |
+
'XX' => 'Undefined',
|
270 |
+
'CW' => 'Curaçao',
|
271 |
+
'SS' => 'South Sudan',
|
272 |
+
'EU' => 'Europe (generic)',
|
273 |
+
'A1' => 'Anonymous IP',
|
274 |
+
'A2' => 'Satellite IP'
|
275 |
+
);
|
276 |
+
|
277 |
+
/**
|
278 |
+
*
|
279 |
+
* @param array $options
|
280 |
+
*/
|
281 |
+
function __construct($options = null) {
|
282 |
+
if ($options === null) {
|
283 |
+
if (isset($_POST['options'])) {
|
284 |
+
$this->data = stripslashes_deep($_POST['options']);
|
285 |
+
}
|
286 |
+
} else {
|
287 |
+
$this->data = (array) $options;
|
288 |
+
}
|
289 |
+
|
290 |
+
if (isset($_REQUEST['act'])) {
|
291 |
+
$this->action = $_REQUEST['act'];
|
292 |
+
}
|
293 |
+
|
294 |
+
if (isset($_REQUEST['btn'])) {
|
295 |
+
$this->button_data = $_REQUEST['btn'];
|
296 |
+
}
|
297 |
+
// Fields analysis
|
298 |
+
if (isset($_REQUEST['tnp_fields'])) {
|
299 |
+
$fields = $_REQUEST['tnp_fields'];
|
300 |
+
if (is_array($fields)) {
|
301 |
+
foreach ($fields as $name => $type) {
|
302 |
+
if ($type == 'datetime') {
|
303 |
+
// Ex. The user insert 01/07/2012 14:30 and it set the time zone to +2. We cannot use the
|
304 |
+
// mktime, since it uses the time zone of the machine. We create the time as if we are on
|
305 |
+
// GMT 0 and then we subtract the GMT offset (the example date and time on GMT+2 happens
|
306 |
+
// "before").
|
307 |
+
|
308 |
+
$time = gmmktime((int) $_REQUEST[$name . '_hour'], 0, 0, (int) $_REQUEST[$name . '_month'], (int) $_REQUEST[$name . '_day'], (int) $_REQUEST[$name . '_year']);
|
309 |
+
$time -= get_option('gmt_offset') * 3600;
|
310 |
+
$this->data[$name] = $time;
|
311 |
+
continue;
|
312 |
+
}
|
313 |
+
if ($type === 'array') {
|
314 |
+
if (!isset($this->data[$name]))
|
315 |
+
$this->data[$name] = [];
|
316 |
+
}
|
317 |
+
if ($type === 'checkbox') {
|
318 |
+
if (!isset($this->data[$name])) {
|
319 |
+
$this->data[$name] = 0;
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
}
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
function set_data($data) {
|
328 |
+
if (is_array($data)) {
|
329 |
+
$this->data = $data;
|
330 |
+
} else if (is_object($data)) {
|
331 |
+
$this->data = (array) $data;
|
332 |
+
} else {
|
333 |
+
$this->data = [];
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
function merge($options) {
|
338 |
+
if (!is_array($options))
|
339 |
+
return;
|
340 |
+
if ($this->data == null)
|
341 |
+
$this->data = array();
|
342 |
+
$this->data = array_merge($this->data, $options);
|
343 |
+
}
|
344 |
+
|
345 |
+
function merge_defaults($defaults) {
|
346 |
+
if ($this->data == null)
|
347 |
+
$this->data = $defaults;
|
348 |
+
else
|
349 |
+
$this->data = array_merge($defaults, $this->data);
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Return true is there in an asked action is no action name is specified or
|
354 |
+
* true is the requested action matches the passed action.
|
355 |
+
* Dies if it is not a safe call.
|
356 |
+
*/
|
357 |
+
function is_action($action = null) {
|
358 |
+
if ($action == null)
|
359 |
+
return $this->action != null;
|
360 |
+
if ($this->action == null)
|
361 |
+
return false;
|
362 |
+
if ($this->action != $action)
|
363 |
+
return false;
|
364 |
+
if (check_admin_referer('save'))
|
365 |
+
return true;
|
366 |
+
die('Invalid call');
|
367 |
+
}
|
368 |
+
|
369 |
+
function get_value($name, $def = null) {
|
370 |
+
if (!isset($this->data[$name])) {
|
371 |
+
return $def;
|
372 |
+
}
|
373 |
+
return $this->data[$name];
|
374 |
+
}
|
375 |
+
|
376 |
+
function get_value_array($name) {
|
377 |
+
if (!isset($this->data[$name]) || !is_array($this->data[$name]))
|
378 |
+
return array();
|
379 |
+
return $this->data[$name];
|
380 |
+
}
|
381 |
+
|
382 |
+
function show_error($text) {
|
383 |
+
echo '<div class="tnp-error">', $text, '</div>';
|
384 |
+
}
|
385 |
+
|
386 |
+
function show_warning($text) {
|
387 |
+
echo '<div class="tnp-warning">', $text, '</div>';
|
388 |
+
}
|
389 |
+
|
390 |
+
function show_message($text) {
|
391 |
+
echo '<div class="tnpc-message">', $text, '</div>';
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Show the errors and messages.
|
396 |
+
*/
|
397 |
+
function show() {
|
398 |
+
static $shown = false;
|
399 |
+
|
400 |
+
if ($shown) {
|
401 |
+
return;
|
402 |
+
}
|
403 |
+
$shown = true;
|
404 |
+
|
405 |
+
if (!empty($this->errors)) {
|
406 |
+
echo '<div class="tnpc-error">';
|
407 |
+
echo $this->errors;
|
408 |
+
echo '</div>';
|
409 |
+
}
|
410 |
+
if (!empty($this->warnings)) {
|
411 |
+
foreach ((array) $this->warnings as $warning) {
|
412 |
+
echo '<div class="tnpc-warning">';
|
413 |
+
echo $warning;
|
414 |
+
echo '</div>';
|
415 |
+
}
|
416 |
+
}
|
417 |
+
if (!empty($this->messages)) {
|
418 |
+
echo '<div class="tnpc-message">';
|
419 |
+
echo $this->messages;
|
420 |
+
echo '</div>';
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
function add_message($text) {
|
425 |
+
if (!empty($this->messages)) {
|
426 |
+
$this->messages .= '<br><br>';
|
427 |
+
}
|
428 |
+
$this->messages .= $text;
|
429 |
+
}
|
430 |
+
|
431 |
+
function add_message_saved() {
|
432 |
+
if (!empty($this->messages)) {
|
433 |
+
$this->messages .= '<br><br>';
|
434 |
+
}
|
435 |
+
$this->messages .= __('Saved.', 'newsletter');
|
436 |
+
}
|
437 |
+
|
438 |
+
function add_message_deleted() {
|
439 |
+
if (!empty($this->messages)) {
|
440 |
+
$this->messages .= '<br><br>';
|
441 |
+
}
|
442 |
+
$this->messages .= __('Deleted.', 'newsletter');
|
443 |
+
}
|
444 |
+
|
445 |
+
function add_message_reset() {
|
446 |
+
if (!empty($this->messages)) {
|
447 |
+
$this->messages .= '<br><br>';
|
448 |
+
}
|
449 |
+
$this->messages .= __('Options reset.', 'newsletter');
|
450 |
+
}
|
451 |
+
|
452 |
+
function add_message_done() {
|
453 |
+
if (!empty($this->messages)) {
|
454 |
+
$this->messages .= '<br><br>';
|
455 |
+
}
|
456 |
+
$this->messages .= __('Done.', 'newsletter');
|
457 |
+
}
|
458 |
+
|
459 |
+
function add_language_warning() {
|
460 |
+
$newsletter = Newsletter::instance();
|
461 |
+
$current_language = $newsletter->get_current_language();
|
462 |
+
|
463 |
+
if (!$current_language) {
|
464 |
+
return;
|
465 |
+
}
|
466 |
+
$this->warnings[] = 'You are configuring the language <strong>' . $newsletter->get_language_label($current_language) . '</strong>. Switch to "all languages" to see all options.';
|
467 |
+
}
|
468 |
+
|
469 |
+
function switch_to_all_languages_notice() {
|
470 |
+
echo '<div class="tnpc-languages-notice">';
|
471 |
+
_e('Switch the administration side to "all languages" to set these options', 'newsletter');
|
472 |
+
echo '</div>';
|
473 |
+
}
|
474 |
+
|
475 |
+
function hint($text, $url = '') {
|
476 |
+
echo '<div class="tnpc-hint">';
|
477 |
+
// Do not escape that, it can be formatted
|
478 |
+
echo $text;
|
479 |
+
if (!empty($url)) {
|
480 |
+
echo ' <a href="' . esc_attr($url) . '" target="_blank">Read more</a>.';
|
481 |
+
}
|
482 |
+
echo '</div>';
|
483 |
+
}
|
484 |
+
|
485 |
+
function yesno($name) {
|
486 |
+
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
487 |
+
|
488 |
+
echo '<select style="width: 60px" name="options[', esc_attr($name), ']">';
|
489 |
+
echo '<option value="0"';
|
490 |
+
if ($value == 0) {
|
491 |
+
echo ' selected';
|
492 |
+
}
|
493 |
+
echo '>', __('No', 'newsletter'), '</option>';
|
494 |
+
echo '<option value="1"';
|
495 |
+
if ($value == 1) {
|
496 |
+
echo ' selected';
|
497 |
+
}
|
498 |
+
echo '>', __('Yes', 'newsletter'), '</option>';
|
499 |
+
echo '</select> ';
|
500 |
+
}
|
501 |
+
|
502 |
+
function enabled($name = 'enabled', $attrs = []) {
|
503 |
+
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
504 |
+
$name = esc_attr($name);
|
505 |
+
|
506 |
+
echo '<select style="width: 100px" name="options[', $name, ']" id="options-', $name, '"';
|
507 |
+
if (isset($attrs['bind_to'])) {
|
508 |
+
echo ' onchange="tnp_select_toggle(this, \'', $attrs['bind_to'], '\')"';
|
509 |
+
}
|
510 |
+
echo '>';
|
511 |
+
echo '<option value="0"';
|
512 |
+
if ($value == 0) {
|
513 |
+
echo ' selected';
|
514 |
+
}
|
515 |
+
echo '>', __('Disabled', 'newsletter'), '</option>';
|
516 |
+
echo '<option value="1"';
|
517 |
+
if ($value == 1) {
|
518 |
+
echo ' selected';
|
519 |
+
}
|
520 |
+
echo '>', __('Enabled', 'newsletter'), '</option>';
|
521 |
+
echo '</select>';
|
522 |
+
if (isset($attrs['bind_to'])) {
|
523 |
+
if ($value) {
|
524 |
+
echo '<script>jQuery(function ($) {$("#options-', $attrs['bind_to'], '").show()})</script>';
|
525 |
+
} else {
|
526 |
+
echo '<script>jQuery(function ($) {$("#options-', $attrs['bind_to'], '").hide()})</script>';
|
527 |
+
}
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
function disabled($name) {
|
532 |
+
$value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;
|
533 |
+
|
534 |
+
echo '<select style="width: 100px" name="options[' . esc_attr($name) . ']">';
|
535 |
+
echo '<option value="0"';
|
536 |
+
if ($value == 0) {
|
537 |
+
echo ' selected';
|
538 |
+
}
|
539 |
+
echo '>Enabled</option>';
|
540 |
+
echo '<option value="1"';
|
541 |
+
if ($value == 1) {
|
542 |
+
echo ' selected';
|
543 |
+
}
|
544 |
+
echo '>Disabled</option>';
|
545 |
+
echo '</select>';
|
546 |
+
}
|
547 |
+
|
548 |
+
/**
|
549 |
+
* Creates a set of checkbox all named as $name with values and labels extracted from
|
550 |
+
* $values_labels. A checkbox will be checked if internal data under key $name is an array
|
551 |
+
* and contains the value of the current (echoing) checkbox.
|
552 |
+
*
|
553 |
+
* On submit it produces an array under the name $name IF at least one checkbox has
|
554 |
+
* been checked. Otherwise the key won't be present.
|
555 |
+
*
|
556 |
+
* @param array $values
|
557 |
+
* @param string $name
|
558 |
+
* @param array $values_labels
|
559 |
+
*/
|
560 |
+
function checkboxes_group($name, $values_labels) {
|
561 |
+
$value_array = $this->get_value_array($name);
|
562 |
+
|
563 |
+
echo '<div class="tnpc-checkboxes">';
|
564 |
+
foreach ($values_labels as $value => $label) {
|
565 |
+
echo '<label><input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . '][]" value="' . esc_attr($value) . '"';
|
566 |
+
if (array_search($value, $value_array) !== false) {
|
567 |
+
echo ' checked';
|
568 |
+
}
|
569 |
+
echo '>';
|
570 |
+
if ($label != '') {
|
571 |
+
echo ' ' . esc_html($label);
|
572 |
+
}
|
573 |
+
echo "</label>";
|
574 |
+
}
|
575 |
+
echo "<div style='clear: both'></div>";
|
576 |
+
}
|
577 |
+
|
578 |
+
/** Creates a checkbox group with all public post types.
|
579 |
+
*/
|
580 |
+
function post_types($name = 'post_types') {
|
581 |
+
$list = array();
|
582 |
+
$post_types = get_post_types(array('public' => true), 'objects', 'and');
|
583 |
+
foreach ($post_types as $post_type) {
|
584 |
+
$list[$post_type->name] = $post_type->labels->name;
|
585 |
+
}
|
586 |
+
|
587 |
+
$this->checkboxes_group($name, $list);
|
588 |
+
}
|
589 |
+
|
590 |
+
function posts_select($name, $max = 20, $args = array()) {
|
591 |
+
$args = array_merge(array(
|
592 |
+
'posts_per_page' => 5,
|
593 |
+
'offset' => 0,
|
594 |
+
'category' => '',
|
595 |
+
'category_name' => '',
|
596 |
+
'orderby' => 'date',
|
597 |
+
'order' => 'DESC',
|
598 |
+
'include' => '',
|
599 |
+
'exclude' => '',
|
600 |
+
'meta_key' => '',
|
601 |
+
'meta_value' => '',
|
602 |
+
'post_type' => 'post',
|
603 |
+
'post_mime_type' => '',
|
604 |
+
'post_parent' => '',
|
605 |
+
'author' => '',
|
606 |
+
'author_name' => '',
|
607 |
+
'post_status' => 'publish',
|
608 |
+
'suppress_filters' => true
|
609 |
+
), $args);
|
610 |
+
$args['posts_per_page'] = $max;
|
611 |
+
|
612 |
+
$posts = get_posts($args);
|
613 |
+
$options = array();
|
614 |
+
foreach ($posts as $post) {
|
615 |
+
$options['' . $post->ID] = $post->post_title;
|
616 |
+
}
|
617 |
+
|
618 |
+
$this->select($name, $options);
|
619 |
+
}
|
620 |
+
|
621 |
+
function select_number($name, $min, $max) {
|
622 |
+
$options = array();
|
623 |
+
for ($i = $min; $i <= $max; $i++) {
|
624 |
+
$options['' . $i] = $i;
|
625 |
+
}
|
626 |
+
$this->select($name, $options);
|
627 |
+
}
|
628 |
+
|
629 |
+
function page($name = 'page', $first = null, $language = '', $show_id = false) {
|
630 |
+
$args = array(
|
631 |
+
'post_type' => 'page',
|
632 |
+
'posts_per_page' => 1000,
|
633 |
+
'offset' => 0,
|
634 |
+
'orderby' => 'post_title',
|
635 |
+
'post_status' => 'any',
|
636 |
+
'suppress_filters' => true
|
637 |
+
);
|
638 |
+
|
639 |
+
$pages = get_posts($args);
|
640 |
+
//$pages = get_pages();
|
641 |
+
$options = array();
|
642 |
+
foreach ($pages as $page) {
|
643 |
+
/* @var $page WP_Post */
|
644 |
+
$label = $page->post_title;
|
645 |
+
if ($page->post_status != 'publish') {
|
646 |
+
$label .= ' (' . $page->post_status . ')';
|
647 |
+
}
|
648 |
+
if ($show_id) {
|
649 |
+
$label .= ' [' . $page->ID . ']';
|
650 |
+
}
|
651 |
+
$options[$page->ID] = $label;
|
652 |
+
}
|
653 |
+
$this->select($name, $options, $first);
|
654 |
+
}
|
655 |
+
|
656 |
+
/** Used to create a select which is part of a group of controls identified by $name that will
|
657 |
+
* produce an array of values as $_REQUEST['name'].
|
658 |
+
* @param string $name
|
659 |
+
* @param array $options Associative array
|
660 |
+
*/
|
661 |
+
function select_group($name, $options) {
|
662 |
+
$value_array = $this->get_value_array($name);
|
663 |
+
|
664 |
+
echo '<select name="options[' . esc_attr($name) . '][]">';
|
665 |
+
|
666 |
+
foreach ($options as $key => $label) {
|
667 |
+
echo '<option value="' . esc_attr($key) . '"';
|
668 |
+
if (array_search($key, $value_array) !== false) {
|
669 |
+
echo ' selected';
|
670 |
+
}
|
671 |
+
echo '>' . esc_html($label) . '</option>';
|
672 |
+
}
|
673 |
+
|
674 |
+
echo '</select>';
|
675 |
+
}
|
676 |
+
|
677 |
+
function select($name, $options, $first = null, $attrs = []) {
|
678 |
+
echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']"';
|
679 |
+
if ($attrs) {
|
680 |
+
foreach ($attrs as $key => $value) {
|
681 |
+
echo ' ', $key, '="' . esc_attr($value), '"';
|
682 |
+
}
|
683 |
+
}
|
684 |
+
echo '>';
|
685 |
+
if (!empty($first)) {
|
686 |
+
echo '<option value="">' . esc_html($first) . '</option>';
|
687 |
+
}
|
688 |
+
$value = $this->get_value($name);
|
689 |
+
foreach ($options as $key => $label) {
|
690 |
+
echo '<option value="' . esc_attr($key) . '"';
|
691 |
+
if ($value == $key) {
|
692 |
+
echo ' selected';
|
693 |
+
}
|
694 |
+
echo '>' . esc_html($label) . '</option>';
|
695 |
+
}
|
696 |
+
echo '</select>';
|
697 |
+
}
|
698 |
+
|
699 |
+
function select_images($name, $options, $first = null) {
|
700 |
+
$value = $this->get_value($name);
|
701 |
+
|
702 |
+
echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" style="min-width: 200px">';
|
703 |
+
if (!empty($first)) {
|
704 |
+
echo '<option value="">' . esc_html($first) . '</option>';
|
705 |
+
} else {
|
706 |
+
// if (empty($value)) {
|
707 |
+
// $keys = array_keys($options);
|
708 |
+
// $value = $keys[0];
|
709 |
+
// }
|
710 |
+
}
|
711 |
+
foreach ($options as $key => $data) {
|
712 |
+
echo '<option value="' . esc_attr($key) . '" image="' . esc_attr($data['image']) . '"';
|
713 |
+
if ($value == $key)
|
714 |
+
echo ' selected';
|
715 |
+
echo '>' . esc_html($data['label']) . '</option>';
|
716 |
+
}
|
717 |
+
echo '</select>';
|
718 |
+
echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
|
719 |
+
}
|
720 |
+
|
721 |
+
function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder = '') {
|
722 |
+
|
723 |
+
if ($multiple) {
|
724 |
+
$option_name = "options[" . esc_attr($name) . "][]";
|
725 |
+
} else {
|
726 |
+
$option_name = "options[" . esc_attr($name) . "]";
|
727 |
+
}
|
728 |
+
|
729 |
+
if (is_null($style)) {
|
730 |
+
$style = 'width: 100%';
|
731 |
+
}
|
732 |
+
|
733 |
+
$value = $this->get_value($name);
|
734 |
+
|
735 |
+
echo '<select id="options-', esc_attr($name), '" name="', $option_name, '" style="', $style, '"',
|
736 |
+
($multiple ? ' multiple' : ''), '>';
|
737 |
+
if (!empty($first)) {
|
738 |
+
echo '<option value="">' . esc_html($first) . '</option>';
|
739 |
+
}
|
740 |
+
|
741 |
+
foreach ($options as $key => $data) {
|
742 |
+
echo '<option value="' . esc_attr($key) . '"';
|
743 |
+
if (is_array($value) && in_array($key, $value) || (!is_null($value) && $value == $key )) {
|
744 |
+
echo ' selected';
|
745 |
+
}
|
746 |
+
echo '>' . esc_html($data) . '</option>';
|
747 |
+
}
|
748 |
+
|
749 |
+
echo '</select>';
|
750 |
+
echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
|
751 |
+
}
|
752 |
+
|
753 |
+
function select_grouped($name, $groups) {
|
754 |
+
$value = $this->get_value($name);
|
755 |
+
$name = esc_attr($name);
|
756 |
+
echo '<select name="options[', $name, ']">';
|
757 |
+
|
758 |
+
foreach ($groups as $group) {
|
759 |
+
echo '<optgroup label="' . esc_attr($group['']) . '">';
|
760 |
+
if (!empty($group)) {
|
761 |
+
foreach ($group as $key => $label) {
|
762 |
+
if ($key == '') {
|
763 |
+
continue;
|
764 |
+
}
|
765 |
+
echo '<option value="' . esc_attr($key) . '"';
|
766 |
+
if ($value == $key) {
|
767 |
+
echo ' selected';
|
768 |
+
}
|
769 |
+
echo '>' . esc_html($label) . '</option>';
|
770 |
+
}
|
771 |
+
}
|
772 |
+
echo '</optgroup>';
|
773 |
+
}
|
774 |
+
echo '</select>';
|
775 |
+
}
|
776 |
+
|
777 |
+
/**
|
778 |
+
* Generated a select control with all available templates. From version 3 there are
|
779 |
+
* only on kind of templates, they are no more separated by type.
|
780 |
+
*/
|
781 |
+
function themes($name, $themes, $submit_on_click = true) {
|
782 |
+
foreach ($themes as $key => $data) {
|
783 |
+
echo '<label style="display: block; float: left; text-align: center; margin-right: 10px;">';
|
784 |
+
echo esc_html($key) . '<br>';
|
785 |
+
echo '<img src="' . esc_attr($data['screenshot']) . '" width="100" height="100" style="border: 1px solid #666; padding: 5px"><br>';
|
786 |
+
echo '<input style="position: relative; top: -40px" type="radio" onchange="this.form.act.value=\'theme\';this.form.submit()" name="options[' . esc_attr($name) . ']" value="' . esc_attr($key) . '"';
|
787 |
+
if ($this->data[$name] == $key) {
|
788 |
+
echo ' checked';
|
789 |
+
}
|
790 |
+
echo '>';
|
791 |
+
echo '</label>';
|
792 |
+
}
|
793 |
+
echo '<div style="clear: both"></div>';
|
794 |
+
}
|
795 |
+
|
796 |
+
function value($name) {
|
797 |
+
echo esc_html($this->data[$name]);
|
798 |
+
}
|
799 |
+
|
800 |
+
function value_date($name, $show_remaining = true) {
|
801 |
+
$time = $this->get_value($name);
|
802 |
+
|
803 |
+
echo gmdate(get_option('date_format') . ' ' . get_option('time_format'), $time + get_option('gmt_offset') * 3600);
|
804 |
+
$delta = $time - time();
|
805 |
+
if ($show_remaining && $delta > 0) {
|
806 |
+
echo 'Remaining: ';
|
807 |
+
$delta = $time - time();
|
808 |
+
$days = floor($delta / (24 * 3600));
|
809 |
+
$delta = $delta - $days * 24 * 3600;
|
810 |
+
$hours = floor($delta / 3600);
|
811 |
+
$delta = $delta - $hours * 3600;
|
812 |
+
$minutes = floor($delta / 60);
|
813 |
+
|
814 |
+
if ($days > 0) {
|
815 |
+
echo $days . ' days ';
|
816 |
+
}
|
817 |
+
echo $hours . ' hours ';
|
818 |
+
echo $minutes . ' minutes ';
|
819 |
+
}
|
820 |
+
}
|
821 |
+
|
822 |
+
function password($name, $size = 20, $placeholder = '') {
|
823 |
+
$value = $this->get_value($name);
|
824 |
+
$name = esc_attr($name);
|
825 |
+
echo '<input id="options-', $name, '" placeholder="' . esc_attr($placeholder) . '" name="options[', $name, ']" type="password" autocomplete="off" ';
|
826 |
+
if (!empty($size)) {
|
827 |
+
echo 'size="', $size, '" ';
|
828 |
+
}
|
829 |
+
echo 'value="', esc_attr($value), '">';
|
830 |
+
}
|
831 |
+
|
832 |
+
function text($name, $size = 20, $placeholder = '') {
|
833 |
+
$value = $this->get_value($name);
|
834 |
+
$name = esc_attr($name);
|
835 |
+
echo '<input id="options-', $name, '" placeholder="' . esc_attr($placeholder) . '" title="' . esc_attr($placeholder) . '" name="options[', $name, ']" type="text" ';
|
836 |
+
if (!empty($size)) {
|
837 |
+
echo 'size="', esc_attr($size), '" ';
|
838 |
+
}
|
839 |
+
echo 'value="', esc_attr($value), '">';
|
840 |
+
}
|
841 |
+
|
842 |
+
function text_email($name, $size = 40) {
|
843 |
+
$value = $this->get_value($name);
|
844 |
+
echo '<input name="options[' . esc_attr($name) . ']" type="email" placeholder="';
|
845 |
+
echo esc_attr__('Valid email address', 'newsletter');
|
846 |
+
echo '" size="' . esc_attr($size) . '" value="';
|
847 |
+
echo esc_attr($value);
|
848 |
+
echo '">';
|
849 |
+
}
|
850 |
+
|
851 |
+
function text_url($name, $size = 40) {
|
852 |
+
$value = $this->get_value($name);
|
853 |
+
echo '<input name="options[' . esc_attr($name) . ']" type="url" placeholder="http://..." size="' . esc_attr($size) . '" value="';
|
854 |
+
echo esc_attr($value);
|
855 |
+
echo '"/>';
|
856 |
+
}
|
857 |
+
|
858 |
+
function hidden($name) {
|
859 |
+
$value = $this->get_value($name);
|
860 |
+
echo '<input name="options[', esc_attr($name), ']" id="options-', esc_attr($name), '" type="hidden" value="', esc_attr($value), '">';
|
861 |
+
}
|
862 |
+
|
863 |
+
/**
|
864 |
+
* General button. Attributes:
|
865 |
+
* - id: the element HTML id
|
866 |
+
* - confirm: if string the text is shown in a confirmation message, if true shows a standard confirm message
|
867 |
+
* - icon: the font awesome icon name (fa-xxx)
|
868 |
+
* - style: the CSS style
|
869 |
+
* - data: free data associated to the button click ($controls->button_data) for example to pass the element ID from a list of elements
|
870 |
+
*
|
871 |
+
* @param string $action
|
872 |
+
* @param string $label
|
873 |
+
* @param array $attrs
|
874 |
+
*/
|
875 |
+
function btn($action, $label, $attrs = []) {
|
876 |
+
echo '<button class="button-primary tnpc-button"';
|
877 |
+
if (isset($attrs['id'])) {
|
878 |
+
echo ' id="', esc_attrs($attrs['id']), '"';
|
879 |
+
}
|
880 |
+
$onclick = "this.form.act.value='" . esc_attr(esc_js(trim($action))) . "';";
|
881 |
+
if (!empty($attrs['data'])) {
|
882 |
+
$onclick .= "this.form.btn.value='" . esc_attr(esc_js($attrs['data'])) . "';";
|
883 |
+
}
|
884 |
+
if (isset($attrs['confirm'])) {
|
885 |
+
if (is_string($attrs['confirm'])) {
|
886 |
+
$onclick .= "if (!confirm('" . esc_attr(esc_js($attrs['confirm'])) . "')) return false;";
|
887 |
+
} else if ($attrs['confirm'] === true) {
|
888 |
+
$onclick .= "if (!confirm('" . esc_attr(esc_js(__('Proceed?', 'newsletter'))) . "')) return false;";
|
889 |
+
}
|
890 |
+
}
|
891 |
+
echo 'onclick="', $onclick, '"';
|
892 |
+
if (!empty($attrs['title'])) {
|
893 |
+
echo ' title="', esc_attr($attrs['title']), '"';
|
894 |
+
}
|
895 |
+
if (!empty($attrs['style'])) {
|
896 |
+
echo ' style="', esc_attr($attrs['style']), '"';
|
897 |
+
}
|
898 |
+
echo '>';
|
899 |
+
if (!empty($attrs['icon'])) {
|
900 |
+
echo '<i class="fas ', esc_attr($attrs['icon']), '"></i>';
|
901 |
+
if (!empty($label)) {
|
902 |
+
echo ' ', esc_html($label);
|
903 |
+
}
|
904 |
+
} else {
|
905 |
+
echo esc_html($label);
|
906 |
+
}
|
907 |
+
echo '</button>';
|
908 |
+
}
|
909 |
+
|
910 |
+
/**
|
911 |
+
* Creates a link looking lie a standard button. Attributes:
|
912 |
+
* - title: the link "title" HTML attribute
|
913 |
+
* - target: the link "target" HTML attribute
|
914 |
+
* - icon: the font awesome icon name (fa-xxx)
|
915 |
+
* - style: the CSS style
|
916 |
+
*
|
917 |
+
* @param string $url
|
918 |
+
* @param string $label
|
919 |
+
* @param array $attrs
|
920 |
+
*/
|
921 |
+
function btn_link($url, $label, $attrs = []) {
|
922 |
+
echo '<a href="', esc_attr($url), '" class="button-primary tnpc-button"';
|
923 |
+
if (!empty($attrs['style'])) {
|
924 |
+
echo ' style="', esc_attr($attrs['style']), '"';
|
925 |
+
}
|
926 |
+
if (!empty($attrs['title'])) {
|
927 |
+
echo ' title="', esc_attr($attrs['title']), '"';
|
928 |
+
}
|
929 |
+
if (!empty($attrs['target'])) {
|
930 |
+
echo ' target="', esc_attr($attrs['target']), '"';
|
931 |
+
}
|
932 |
+
echo '>';
|
933 |
+
if (!empty($attrs['icon'])) {
|
934 |
+
echo '<i class="fas ', esc_attr($attrs['icon']), '"></i>';
|
935 |
+
if (!empty($label)) {
|
936 |
+
echo ' ', esc_html($label);
|
937 |
+
}
|
938 |
+
} else {
|
939 |
+
echo esc_html($label);
|
940 |
+
}
|
941 |
+
echo '</a>';
|
942 |
+
}
|
943 |
+
|
944 |
+
function button($action, $label, $function = '', $id = '') {
|
945 |
+
$id = !empty($id) ? " id=\"$id\" " : '';
|
946 |
+
if ($function != null) {
|
947 |
+
echo '<input ' . $id . ' class="button-primary tnpc-button" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_html($function) . '"/>';
|
948 |
+
} else {
|
949 |
+
echo '<input ' . $id . ' class="button-primary tnpc-button" type="submit" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';return true;"/>';
|
950 |
+
}
|
951 |
+
}
|
952 |
+
|
953 |
+
function action_link($action, $label, $function = null) {
|
954 |
+
if ($function != null) {
|
955 |
+
echo '<input class="button-link tnpc-button" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_html($function) . '"/>';
|
956 |
+
} else {
|
957 |
+
echo '<input class="button-link tnpc-button" type="submit" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';return true;"/>';
|
958 |
+
}
|
959 |
+
}
|
960 |
+
|
961 |
+
function button_save() {
|
962 |
+
$this->btn('save', __('Save', 'newsletter'), ['icon' => 'fa-save']);
|
963 |
+
}
|
964 |
+
|
965 |
+
function button_reset($action = 'reset') {
|
966 |
+
$this->btn($action, __('Reset', 'newsletter'), ['icon' => 'fa-reply', 'confirm' => true]);
|
967 |
+
}
|
968 |
+
|
969 |
+
function button_copy($data = '') {
|
970 |
+
$this->btn('copy', __('Duplicate', 'newsletter'), ['data' => $data, 'icon' => 'fa-copy', 'confirm' => true]);
|
971 |
+
}
|
972 |
+
|
973 |
+
function button_icon_copy($data = '') {
|
974 |
+
$this->btn('copy', '', ['data' => $data, 'icon' => 'fa-copy', 'confirm' => true, 'title' => __('Duplicate', 'newsletter')]);
|
975 |
+
}
|
976 |
+
|
977 |
+
/**
|
978 |
+
* Creates a button with "delete" action.
|
979 |
+
* @param type $data
|
980 |
+
*/
|
981 |
+
function button_delete($data = '') {
|
982 |
+
$this->btn('delete', __('Delete', 'newsletter'), ['data' => $data, 'icon' => 'fa-times', 'confirm' => true, 'style' => 'background-color: darkred; color: #ffffff']);
|
983 |
+
}
|
984 |
+
|
985 |
+
function button_icon_delete($data = '') {
|
986 |
+
$this->btn('delete', '', ['data' => $data, 'icon' => 'fa-times', 'confirm' => true, 'title' => __('Delete', 'newsletter'), 'style' => 'background-color: darkred; color: #ffffff']);
|
987 |
+
}
|
988 |
+
|
989 |
+
function button_icon_configure($url) {
|
990 |
+
$this->btn_link($url, '', ['icon' => 'fa-cog', 'title' => __('Configure', 'newsletter')]);
|
991 |
+
}
|
992 |
+
|
993 |
+
function button_icon_subscribers($url) {
|
994 |
+
$this->btn_link($url, '', ['icon' => 'fa-users', 'title' => __('Subscribers', 'newsletter')]);
|
995 |
+
}
|
996 |
+
|
997 |
+
function button_statistics($url) {
|
998 |
+
$this->btn_link($url, __('Statistics', 'newsletter'), ['icon' => 'fa-chart-bar']);
|
999 |
+
}
|
1000 |
+
|
1001 |
+
function button_icon_statistics($url) {
|
1002 |
+
$this->btn_link($url, '', ['icon' => 'fa-chart-bar', 'title' => __('Statistics', 'newsletter')]);
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
function button_icon_view($url) {
|
1006 |
+
$this->btn_link($url, '', ['icon' => 'fa-eye', 'title' => __('View', 'newsletter'), 'target' => '_blank']);
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
function button_icon_newsletters($url) {
|
1010 |
+
$this->btn_link($url, '', ['icon' => 'fa-file-alt', 'title' => __('Newsletters', 'newsletter')]);
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
function button_icon_design($url) {
|
1014 |
+
$this->btn_link($url, '', ['icon' => 'fa-paint-brush', 'title' => __('Design', 'newsletter')]);
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
function button_icon_edit($url) {
|
1018 |
+
$this->btn_link($url, '', ['icon' => 'fa-edit', 'title' => __('Edit', 'newsletter')]);
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
function button_icon_back($url) {
|
1022 |
+
$this->btn_link($url, '', ['icon' => 'fa-chevron-left', 'title' => __('Back', 'newsletter')]);
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
function button_icon($action, $icon, $title = '', $data = '', $confirm = false) {
|
1026 |
+
$this->btn($action, '', ['data' => $data, 'icon' => $icon, 'title' => $title, 'confirm' => $confirm]);
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
function button_back($url) {
|
1030 |
+
$this->btn_link($url, __('Back', 'newsletter'), ['icon' => 'fa-chevron-left']);
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
function button_test($action = 'test') {
|
1034 |
+
$this->btn($action, __('Test', 'newsletter'), ['icon' => 'fa-vial']);
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
/**
|
1038 |
+
* @deprecated
|
1039 |
+
*/
|
1040 |
+
function button_primary($action, $label, $function = null) {
|
1041 |
+
if ($function != null) {
|
1042 |
+
echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_attr($function) . '">', $label, '</button>';
|
1043 |
+
} else {
|
1044 |
+
echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\'; return true;"/>', $label, '</button>';
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
/**
|
1049 |
+
* @deprecated
|
1050 |
+
*/
|
1051 |
+
function button_confirm($action, $label, $message = '', $data = '') {
|
1052 |
+
$this->btn($action, $label, ['data' => $data, 'confirm' => $message]);
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
/**
|
1056 |
+
* @deprecated
|
1057 |
+
* @param string $url
|
1058 |
+
* @param string $label Not escaped.
|
1059 |
+
*/
|
1060 |
+
function button_link($url, $label = '') {
|
1061 |
+
echo '<a href="', esc_attr($url), '" class="button-primary">', $label, '</a>';
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
function editor($name, $rows = 5, $cols = 75) {
|
1065 |
+
echo '<textarea class="visual" name="options[' . esc_attr($name) . ']" style="width: 100%" wrap="off" rows="' . esc_attr($rows) . '">';
|
1066 |
+
echo esc_html($this->get_value($name));
|
1067 |
+
echo '</textarea>';
|
1068 |
+
}
|
1069 |
+
|
1070 |
+
function wp_editor($name, $settings = []) {
|
1071 |
+
|
1072 |
+
add_filter('mce_buttons', function ($mce_buttons) {
|
1073 |
+
$mce_buttons[] = 'wp_add_media';
|
1074 |
+
//$mce_buttons[] = 'wp_code';
|
1075 |
+
return $mce_buttons;
|
1076 |
+
});
|
1077 |
+
|
1078 |
+
$settings = array_merge(['media_buttons' => false], $settings);
|
1079 |
+
|
1080 |
+
$value = $this->get_value($name);
|
1081 |
+
wp_editor($value, $name, array_merge(array(
|
1082 |
+
'tinymce' => array('content_css' => plugins_url('newsletter') . '/admin/wp-editor.css?ver=' . NEWSLETTER_VERSION),
|
1083 |
+
'textarea_name' => 'options[' . esc_attr($name) . ']',
|
1084 |
+
'wpautop' => false
|
1085 |
+
), $settings));
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
function textarea($name, $width = '100%', $height = '50') {
|
1089 |
+
$value = $this->get_value($name);
|
1090 |
+
if (is_array($value)) {
|
1091 |
+
$value = implode("\n", $value);
|
1092 |
+
}
|
1093 |
+
echo '<textarea id="options-' . esc_attr($name) . '" class="dynamic" name="options[' . esc_attr($name) . ']" wrap="off" style="width:' . esc_attr($width) . ';height:' . esc_attr($height) . '">';
|
1094 |
+
echo esc_html($value);
|
1095 |
+
echo '</textarea>';
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
function textarea_fixed($name, $width = '100%', $height = '200') {
|
1099 |
+
$value = $this->get_value($name);
|
1100 |
+
$name = esc_attr($name);
|
1101 |
+
echo '<textarea id="options-', $name, '" name="options[', $name, ']" wrap="off" style="width:', esc_attr($width), ';height:', esc_attr($height), 'px">';
|
1102 |
+
echo esc_html($value);
|
1103 |
+
echo '</textarea>';
|
1104 |
+
}
|
1105 |
+
|
1106 |
+
function textarea_preview($name, $width = '100%', $height = '200', $header = '', $footer = '', $switch_button = true) {
|
1107 |
+
$value = $this->get_value($name);
|
1108 |
+
$name = esc_attr($name);
|
1109 |
+
if ($switch_button) {
|
1110 |
+
echo '<input class="button-primary" type="button" onclick="newsletter_textarea_preview(\'options-', $name, '\', \'\', \'\')" value="Switch editor/preview">';
|
1111 |
+
echo '<br><br>';
|
1112 |
+
}
|
1113 |
+
echo '<div style="box-sizing: border-box; position: relative; margin: 0; padding: 0; width:' . esc_attr($width) . '; height:' . esc_attr($height) . '">';
|
1114 |
+
echo '<textarea id="options-', $name, '" name="options[', $name, ']" wrap="off" style="width:' . esc_attr($width) . ';height:' . esc_attr($height) . 'px">';
|
1115 |
+
echo esc_html($value);
|
1116 |
+
echo '</textarea>';
|
1117 |
+
echo '<div id="options-', $name, '-preview" style="box-sizing: border-box; background-color: #eee; border: 1px solid #bbb; padding: 15px; width: auto; position: absolute; top: 20px; left: 20px; box-shadow: 0 0 20px #777; z-index: 10000; display: none">';
|
1118 |
+
echo '<iframe id="options-', $name, '-iframe" class="tnp-editor-preview-desktop"></iframe>';
|
1119 |
+
echo '<iframe id="options-', $name, '-iframe-phone" class="tnp-editor-preview-mobile"></iframe>';
|
1120 |
+
echo '</div>';
|
1121 |
+
echo '</div>';
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
function email($prefix, $editor = null, $disable_option = false, $settings = array()) {
|
1125 |
+
if ($disable_option) {
|
1126 |
+
$this->disabled($prefix . '_disabled');
|
1127 |
+
echo '<br>';
|
1128 |
+
}
|
1129 |
+
|
1130 |
+
$this->text($prefix . '_subject', 90, 'Subject');
|
1131 |
+
echo '<br><br>';
|
1132 |
+
|
1133 |
+
if ($editor == 'wordpress') {
|
1134 |
+
$this->wp_editor($prefix . '_message', $settings);
|
1135 |
+
} else if ($editor == 'textarea') {
|
1136 |
+
$this->textarea($prefix . '_message');
|
1137 |
+
} else {
|
1138 |
+
$this->editor($prefix . '_message');
|
1139 |
+
}
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
/**
|
1143 |
+
* Standard checkbox, when not checked no value is transmitted (checkbox2).
|
1144 |
+
*
|
1145 |
+
* @param string $name
|
1146 |
+
* @param string $label
|
1147 |
+
*/
|
1148 |
+
function checkbox($name, $label = '') {
|
1149 |
+
if ($label != '') {
|
1150 |
+
echo '<label>';
|
1151 |
+
}
|
1152 |
+
echo '<input type="checkbox" id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="1"';
|
1153 |
+
if (!empty($this->data[$name])) {
|
1154 |
+
echo ' checked';
|
1155 |
+
}
|
1156 |
+
echo '>';
|
1157 |
+
if ($label != '') {
|
1158 |
+
echo ' ' . esc_html($label) . '</label>';
|
1159 |
+
}
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
/**
|
1163 |
+
* Checkbox with a hidden field to transmit 1 or 0 even when the checkbox is not checked.
|
1164 |
+
*
|
1165 |
+
* @param string $name
|
1166 |
+
* @param string $label
|
1167 |
+
*/
|
1168 |
+
function checkbox2($name, $label = '') {
|
1169 |
+
if ($label != '') {
|
1170 |
+
echo '<label>';
|
1171 |
+
}
|
1172 |
+
echo '<input type="checkbox" id="' . esc_attr($name) . '" onchange="document.getElementById(\'' . esc_attr($name) . '_hidden\').value=this.checked?\'1\':\'0\'"';
|
1173 |
+
if (!empty($this->data[$name])) {
|
1174 |
+
echo ' checked';
|
1175 |
+
}
|
1176 |
+
echo '>';
|
1177 |
+
if ($label != '') {
|
1178 |
+
echo ' ' . esc_html($label) . '</label>';
|
1179 |
+
}
|
1180 |
+
echo '<input type="hidden" id="' . esc_attr($name) . '_hidden" name="options[' . esc_attr($name) . ']" value="';
|
1181 |
+
|
1182 |
+
echo empty($this->data[$name]) ? '0' : '1';
|
1183 |
+
echo '">';
|
1184 |
+
}
|
1185 |
+
|
1186 |
+
function radio($name, $value, $label = '') {
|
1187 |
+
if ($label != '') {
|
1188 |
+
echo '<label>';
|
1189 |
+
}
|
1190 |
+
echo '<input type="radio" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="' . esc_attr($value) . '"';
|
1191 |
+
$v = $this->get_value($name);
|
1192 |
+
if ($v == $value) {
|
1193 |
+
echo ' checked';
|
1194 |
+
}
|
1195 |
+
echo '>';
|
1196 |
+
if ($label != '') {
|
1197 |
+
echo ' ' . esc_html($label) . '</label>';
|
1198 |
+
}
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
/**
|
1202 |
+
* Creates a checkbox named $name and checked if the internal data contains under
|
1203 |
+
* the key $name an array containig the passed value.
|
1204 |
+
*/
|
1205 |
+
function checkbox_group($name, $value, $label = '', $attrs = []) {
|
1206 |
+
$attrs = wp_parse_args($attrs, ['label_escape' => true]);
|
1207 |
+
echo '<label><input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . '][]" value="' . esc_attr($value) . '"';
|
1208 |
+
if (isset($this->data[$name]) && is_array($this->data[$name]) && array_search($value, $this->data[$name]) !== false) {
|
1209 |
+
echo ' checked';
|
1210 |
+
}
|
1211 |
+
echo '>';
|
1212 |
+
if ($label != '') {
|
1213 |
+
if ($attrs['label_escape']) {
|
1214 |
+
echo esc_html($label);
|
1215 |
+
} else {
|
1216 |
+
echo $label;
|
1217 |
+
}
|
1218 |
+
}
|
1219 |
+
echo '</label>';
|
1220 |
+
}
|
1221 |
+
|
1222 |
+
function checkboxes($name, $options) {
|
1223 |
+
echo '<div class="tnpc-checkboxes">';
|
1224 |
+
foreach ($options as $value => $label) {
|
1225 |
+
$this->checkbox_group($name, $value, $label);
|
1226 |
+
}
|
1227 |
+
echo '<div style="clear: both"></div>';
|
1228 |
+
echo '</div>';
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
function color($name, $default = '') {
|
1232 |
+
$value = esc_attr($this->get_value($name, $default));
|
1233 |
+
$name = esc_attr($name);
|
1234 |
+
echo '<input class="tnpc-color" id="options-', $name, '" name="options[', $name, ']" type="text" value="', $value, '">';
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
/** Creates a set of checkbox named $name_[category id] (so they are posted with distinct names).
|
1238 |
+
*/
|
1239 |
+
function categories($name = 'category') {
|
1240 |
+
$categories = get_categories();
|
1241 |
+
echo '<div class="tnpc-checkboxes">';
|
1242 |
+
foreach ($categories as $c) {
|
1243 |
+
$this->checkbox($name . '_' . $c->cat_ID, esc_html($c->cat_name));
|
1244 |
+
}
|
1245 |
+
echo '<div style="clear: both"></div>';
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
/**
|
1249 |
+
* Creates a set of checkbox to activate the profile preferences. Every checkbox has a DIV around to
|
1250 |
+
* be formatted.
|
1251 |
+
*/
|
1252 |
+
function categories_group($name, $show_mode = false) {
|
1253 |
+
$categories = get_categories();
|
1254 |
+
if ($show_mode) {
|
1255 |
+
$this->select($name . '_mode', array('include' => 'To be included', 'exclude' => 'To be excluded'));
|
1256 |
+
}
|
1257 |
+
echo '<div class="tnpc-checkboxes">';
|
1258 |
+
foreach ($categories as &$c) {
|
1259 |
+
$this->checkbox_group($name, $c->cat_ID, esc_html($c->cat_name));
|
1260 |
+
}
|
1261 |
+
echo '<div style="clear: both"></div>';
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
/**
|
1265 |
+
* Creates a set of checkboxes named $name_[preference number] (so they are
|
1266 |
+
* distinct fields).
|
1267 |
+
* Empty preferences are skipped.
|
1268 |
+
*/
|
1269 |
+
function preferences($name = 'preferences') {
|
1270 |
+
$lists = Newsletter::instance()->get_lists();
|
1271 |
+
|
1272 |
+
echo '<div class="tnpc-checkboxes">';
|
1273 |
+
foreach ($lists as $list) {
|
1274 |
+
$this->checkbox2($name . '_' . $list->id, esc_html($list->name));
|
1275 |
+
}
|
1276 |
+
echo '<div style="clear: both"></div>';
|
1277 |
+
}
|
1278 |
+
|
1279 |
+
/** A list of all lists defined each one with a checkbox to select it. An array
|
1280 |
+
* of ID of all checked lists is submitted.
|
1281 |
+
*
|
1282 |
+
* @param string $name
|
1283 |
+
*/
|
1284 |
+
function lists($name = 'lists') {
|
1285 |
+
echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
|
1286 |
+
$this->preferences_group($name);
|
1287 |
+
}
|
1288 |
+
|
1289 |
+
function lists_checkboxes($name = 'lists') {
|
1290 |
+
$this->preferences_group($name);
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
/**
|
1294 |
+
* Creates a set of checkboxes all names $name[] and the preference number as value
|
1295 |
+
* so the selected checkboxes are retrieved as an array of values ($REQUEST[$name]
|
1296 |
+
* will be an array if at east one preference is checked).
|
1297 |
+
*/
|
1298 |
+
function preferences_group($name = 'preferences') {
|
1299 |
+
|
1300 |
+
$lists = Newsletter::instance()->get_lists();
|
1301 |
+
|
1302 |
+
echo '<div class="tnpc-lists">';
|
1303 |
+
foreach ($lists as $list) {
|
1304 |
+
$this->checkbox_group($name, $list->id, '<span>' . $list->id . '</span> ' . esc_html($list->name), ['label_escape' => false]);
|
1305 |
+
}
|
1306 |
+
echo '<a href="https://www.thenewsletterplugin.com/documentation/newsletter-lists" target="_blank">'
|
1307 |
+
. 'Click here to read more about lists.'
|
1308 |
+
. '</a>';
|
1309 |
+
echo '</div>';
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
/** Creates as many selects as the active preferences with the three values
|
1313 |
+
* 'any', 'yes', 'no' corresponding to the values 0, 1, 2.
|
1314 |
+
*/
|
1315 |
+
function preferences_selects($name = 'preferences', $skip_empty = false) {
|
1316 |
+
$lists = Newsletter::instance()->get_lists();
|
1317 |
+
|
1318 |
+
echo '<div class="newsletter-preferences-group">';
|
1319 |
+
foreach ($lists as $list) {
|
1320 |
+
|
1321 |
+
echo '<div class="newsletter-preferences-item">';
|
1322 |
+
|
1323 |
+
$this->select($name . '_' . $list->id, array(0 => 'Any', 1 => 'Yes', 2 => 'No'));
|
1324 |
+
echo '(' . $list->id . ') ' . esc_html($list->name);
|
1325 |
+
|
1326 |
+
echo '</div>';
|
1327 |
+
}
|
1328 |
+
echo '<div style="clear: both"></div>';
|
1329 |
+
echo '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Click here know more about preferences.</a> They can be configured on Subscription/Form field panel.';
|
1330 |
+
echo '</div>';
|
1331 |
+
}
|
1332 |
+
|
1333 |
+
/**
|
1334 |
+
* Creates a single select with the active preferences.
|
1335 |
+
*/
|
1336 |
+
function preferences_select($name = 'preference', $empty_label = null) {
|
1337 |
+
$lists = $this->get_list_options($empty_label);
|
1338 |
+
$this->select($name, $lists);
|
1339 |
+
echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fas fa-edit"></i></a>';
|
1340 |
+
}
|
1341 |
+
|
1342 |
+
function lists_select($name = 'list', $empty_label = null) {
|
1343 |
+
$lists = $this->get_list_options($empty_label);
|
1344 |
+
$this->select($name, $lists);
|
1345 |
+
}
|
1346 |
+
|
1347 |
+
function lists_select_with_notes($name = 'list', $empty_label = null) {
|
1348 |
+
|
1349 |
+
$value = $this->get_value($name);
|
1350 |
+
|
1351 |
+
$lists = Newsletter::instance()->get_lists();
|
1352 |
+
$options = [];
|
1353 |
+
if ($empty_label) {
|
1354 |
+
$options[''] = $empty_label;
|
1355 |
+
}
|
1356 |
+
|
1357 |
+
foreach ($lists as $list) {
|
1358 |
+
$options['' . $list->id] = '(' . $list->id . ') ' . esc_html($list->name);
|
1359 |
+
}
|
1360 |
+
|
1361 |
+
$this->select($name, $options, null, ['onchange' => 'tnp_lists_toggle(this); return true;']);
|
1362 |
+
echo '<div id="options-', esc_attr($name), '-notes" class="tnpc_lists_notes">';
|
1363 |
+
foreach ($lists as $list) {
|
1364 |
+
$id = $list->id;
|
1365 |
+
$notes = apply_filters('newsletter_lists_notes', [], $id);
|
1366 |
+
|
1367 |
+
echo '<div class="list_', $id, '" style="display: ', ($value == $id ? 'block' : 'none'), '">';
|
1368 |
+
if ($list->forced) {
|
1369 |
+
echo 'Enforced on subscription<br>';
|
1370 |
+
}
|
1371 |
+
echo implode('<br>', $notes);
|
1372 |
+
echo '</div>';
|
1373 |
+
}
|
1374 |
+
echo '</div>';
|
1375 |
+
}
|
1376 |
+
|
1377 |
+
function public_lists_select($name = 'list', $empty_label = null) {
|
1378 |
+
$lists = $this->get_public_list_options($empty_label);
|
1379 |
+
$this->select($name, $lists);
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
/**
|
1383 |
+
* Generates an associative array with the active lists to be used in a select.
|
1384 |
+
* @param string $empty_label
|
1385 |
+
* @return array
|
1386 |
+
*/
|
1387 |
+
function get_list_options($empty_label = null) {
|
1388 |
+
$objs = Newsletter::instance()->get_lists();
|
1389 |
+
$lists = array();
|
1390 |
+
if ($empty_label) {
|
1391 |
+
$lists[''] = $empty_label;
|
1392 |
+
}
|
1393 |
+
foreach ($objs as $list) {
|
1394 |
+
$lists['' . $list->id] = '(' . $list->id . ') ' . esc_html($list->name);
|
1395 |
+
}
|
1396 |
+
return $lists;
|
1397 |
+
}
|
1398 |
+
|
1399 |
+
function get_public_list_options($empty_label = null) {
|
1400 |
+
$objs = Newsletter::instance()->get_lists_public();
|
1401 |
+
$lists = array();
|
1402 |
+
if ($empty_label) {
|
1403 |
+
$lists[''] = $empty_label;
|
1404 |
+
}
|
1405 |
+
foreach ($objs as $list) {
|
1406 |
+
$lists['' . $list->id] = '(' . $list->id . ') ' . esc_html($list->name);
|
1407 |
+
}
|
1408 |
+
return $lists;
|
1409 |
+
}
|
1410 |
+
|
1411 |
+
function date($name) {
|
1412 |
+
$this->hidden($name);
|
1413 |
+
$year = date('Y', $this->data[$name]);
|
1414 |
+
$day = date('j', $this->data[$name]);
|
1415 |
+
$month = date('m', $this->data[$name]);
|
1416 |
+
$onchange = "this.form.elements['options[" . esc_attr($name) . "]'].value = new Date(document.getElementById('" . esc_attr($name) . "_year').value, document.getElementById('" . esc_attr($name) . "_month').value, document.getElementById('" . esc_attr($name) . "_day').value, 12, 0, 0).getTime()/1000";
|
1417 |
+
echo '<select id="' . $name . '_month" onchange="' . esc_attr($onchange) . '">';
|
1418 |
+
for ($i = 0; $i < 12; $i++) {
|
1419 |
+
echo '<option value="' . $i . '"';
|
1420 |
+
if ($month - 1 == $i) {
|
1421 |
+
echo ' selected';
|
1422 |
+
}
|
1423 |
+
echo '>' . date('F', mktime(0, 0, 0, $i + 1, 1, 2000)) . '</option>';
|
1424 |
+
}
|
1425 |
+
echo '</select>';
|
1426 |
+
|
1427 |
+
echo '<select id="' . esc_attr($name) . '_day" onchange="' . esc_attr($onchange) . '">';
|
1428 |
+
for ($i = 1; $i <= 31; $i++) {
|
1429 |
+
echo '<option value="' . $i . '"';
|
1430 |
+
if ($day == $i) {
|
1431 |
+
echo ' selected';
|
1432 |
+
}
|
1433 |
+
echo '>' . $i . '</option>';
|
1434 |
+
}
|
1435 |
+
echo '</select>';
|
1436 |
+
|
1437 |
+
echo '<select id="' . esc_attr($name) . '_year" onchange="' . esc_attr($onchange) . '">';
|
1438 |
+
for ($i = 2011; $i <= 2021; $i++) {
|
1439 |
+
echo '<option value="' . $i . '"';
|
1440 |
+
if ($year == $i) {
|
1441 |
+
echo ' selected';
|
1442 |
+
}
|
1443 |
+
echo '>' . $i . '</option>';
|
1444 |
+
}
|
1445 |
+
echo '</select>';
|
1446 |
+
}
|
1447 |
+
|
1448 |
+
/**
|
1449 |
+
* Creates a set of fields to collect a date and sends back the triplet year, month and day.
|
1450 |
+
*
|
1451 |
+
* @param string $name
|
1452 |
+
*/
|
1453 |
+
function date2($name) {
|
1454 |
+
$year = $this->get_value($name . '_year');
|
1455 |
+
$day = $this->get_value($name . '_day');
|
1456 |
+
$month = $this->get_value($name . '_month');
|
1457 |
+
|
1458 |
+
echo '<select name="options[' . $name . '_month]">';
|
1459 |
+
echo '<option value="">-</option>';
|
1460 |
+
for ($i = 1; $i <= 12; $i++) {
|
1461 |
+
echo '<option value="' . $i . '"';
|
1462 |
+
if ($month == $i) {
|
1463 |
+
echo ' selected';
|
1464 |
+
}
|
1465 |
+
echo '>' . date_i18n('F', mktime(0, 0, 0, $i, 1, 2000)) . '</option>';
|
1466 |
+
}
|
1467 |
+
echo '</select>';
|
1468 |
+
|
1469 |
+
echo '<select name="options[' . esc_attr($name) . '_day]">';
|
1470 |
+
echo '<option value="">-</option>';
|
1471 |
+
for ($i = 1; $i <= 31; $i++) {
|
1472 |
+
echo '<option value="' . $i . '"';
|
1473 |
+
if ($day == $i) {
|
1474 |
+
echo ' selected';
|
1475 |
+
}
|
1476 |
+
echo '>' . $i . '</option>';
|
1477 |
+
}
|
1478 |
+
echo '</select>';
|
1479 |
+
|
1480 |
+
echo '<select name="options[' . esc_attr($name) . '_year]">';
|
1481 |
+
echo '<option value="">-</option>';
|
1482 |
+
for ($i = 2011; $i <= 2021; $i++) {
|
1483 |
+
echo '<option value="' . $i . '"';
|
1484 |
+
if ($year == $i) {
|
1485 |
+
echo ' selected';
|
1486 |
+
}
|
1487 |
+
echo '>' . $i . '</option>';
|
1488 |
+
}
|
1489 |
+
echo '</select>';
|
1490 |
+
}
|
1491 |
+
|
1492 |
+
/**
|
1493 |
+
* Date and time (hour) selector. Timestamp stored.
|
1494 |
+
*/
|
1495 |
+
function datetime($name) {
|
1496 |
+
echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="datetime">';
|
1497 |
+
$value = (int) $this->get_value($name);
|
1498 |
+
if (empty($value)) {
|
1499 |
+
$value = time();
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
$time = $value + get_option('gmt_offset') * 3600;
|
1503 |
+
$year = gmdate('Y', $time);
|
1504 |
+
$day = gmdate('j', $time);
|
1505 |
+
$month = gmdate('m', $time);
|
1506 |
+
$hour = gmdate('H', $time);
|
1507 |
+
|
1508 |
+
echo '<select name="' . esc_attr($name) . '_month">';
|
1509 |
+
for ($i = 1; $i <= 12; $i++) {
|
1510 |
+
echo '<option value="' . $i . '"';
|
1511 |
+
if ($month == $i) {
|
1512 |
+
echo ' selected';
|
1513 |
+
}
|
1514 |
+
echo '>' . date('F', mktime(0, 0, 0, $i, 1, 2000)) . '</option>';
|
1515 |
+
}
|
1516 |
+
echo '</select>';
|
1517 |
+
|
1518 |
+
echo '<select name="' . esc_attr($name) . '_day">';
|
1519 |
+
for ($i = 1; $i <= 31; $i++) {
|
1520 |
+
echo '<option value="' . $i . '"';
|
1521 |
+
if ($day == $i) {
|
1522 |
+
echo ' selected';
|
1523 |
+
}
|
1524 |
+
echo '>' . $i . '</option>';
|
1525 |
+
}
|
1526 |
+
echo '</select>';
|
1527 |
+
|
1528 |
+
$last_year = date('Y') + 2;
|
1529 |
+
echo '<select name="' . esc_attr($name) . '_year">';
|
1530 |
+
for ($i = 2011; $i <= $last_year; $i++) {
|
1531 |
+
echo '<option value="' . $i . '"';
|
1532 |
+
if ($year == $i) {
|
1533 |
+
echo ' selected';
|
1534 |
+
}
|
1535 |
+
echo '>' . $i . '</option>';
|
1536 |
+
}
|
1537 |
+
echo '</select>';
|
1538 |
+
|
1539 |
+
echo '<select name="' . esc_attr($name) . '_hour">';
|
1540 |
+
for ($i = 0; $i <= 23; $i++) {
|
1541 |
+
echo '<option value="' . $i . '"';
|
1542 |
+
if ($hour == $i) {
|
1543 |
+
echo ' selected';
|
1544 |
+
}
|
1545 |
+
echo '>' . $i . ':00</option>';
|
1546 |
+
}
|
1547 |
+
echo '</select>';
|
1548 |
+
}
|
1549 |
+
|
1550 |
+
function hours($name) {
|
1551 |
+
$hours = array();
|
1552 |
+
for ($i = 0; $i < 24; $i++) {
|
1553 |
+
$hours['' . $i] = sprintf('%02d', $i) . ':00';
|
1554 |
+
}
|
1555 |
+
$this->select($name, $hours);
|
1556 |
+
}
|
1557 |
+
|
1558 |
+
function days($name) {
|
1559 |
+
$days = array(0 => 'Every day', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday');
|
1560 |
+
$this->select($name, $days);
|
1561 |
+
}
|
1562 |
+
|
1563 |
+
function init($options = array()) {
|
1564 |
+
$cookie_name = 'newsletter_tab';
|
1565 |
+
if (isset($options['cookie_name'])) {
|
1566 |
+
$cookie_name = $options['cookie_name'];
|
1567 |
+
}
|
1568 |
+
echo '<script type="text/javascript">
|
1569 |
+
jQuery(document).ready(function(){
|
1570 |
+
|
1571 |
+
tnp_controls_init();
|
1572 |
+
|
1573 |
+
jQuery("textarea.dynamic").focus(function() {
|
1574 |
+
jQuery("textarea.dynamic").css("height", "50px");
|
1575 |
+
jQuery(this).css("height", "400px");
|
1576 |
+
});
|
1577 |
+
tabs = jQuery("#tabs").tabs({
|
1578 |
+
active : jQuery.cookie("' . $cookie_name . '"),
|
1579 |
+
activate : function( event, ui ){
|
1580 |
+
jQuery.cookie("' . $cookie_name . '", ui.newTab.index(),{expires: 1});
|
1581 |
+
}
|
1582 |
+
});
|
1583 |
+
jQuery(".tnp-tabs").tabs({});
|
1584 |
+
|
1585 |
+
});
|
1586 |
+
function newsletter_media(name) {
|
1587 |
+
var tnp_uploader = wp.media({
|
1588 |
+
title: "Select an image",
|
1589 |
+
button: {
|
1590 |
+
text: "Select"
|
1591 |
+
},
|
1592 |
+
multiple: false
|
1593 |
+
}).on("select", function() {
|
1594 |
+
var media = tnp_uploader.state().get("selection").first();
|
1595 |
+
document.getElementById(name + "_id").value = media.id;
|
1596 |
+
jQuery("#" + name + "_id").trigger("change");
|
1597 |
+
//alert(media.attributes.url);
|
1598 |
+
if (media.attributes.url.substring(0, 0) == "/") {
|
1599 |
+
media.attributes.url = "' . site_url('/') . '" + media.attributes.url;
|
1600 |
+
}
|
1601 |
+
document.getElementById(name + "_url").value = media.attributes.url;
|
1602 |
+
|
1603 |
+
var img_url = media.attributes.url;
|
1604 |
+
if (typeof media.attributes.sizes.medium !== "undefined") img_url = media.attributes.sizes.medium.url;
|
1605 |
+
if (img_url.substring(0, 0) == "/") {
|
1606 |
+
img_url = "' . site_url('/') . '" + img_url;
|
1607 |
+
}
|
1608 |
+
document.getElementById(name + "_img").src = img_url;
|
1609 |
+
}).open();
|
1610 |
+
}
|
1611 |
+
function newsletter_media_remove(name) {
|
1612 |
+
if (confirm("Are you sure?")) {
|
1613 |
+
document.getElementById(name + "_id").value = "";
|
1614 |
+
document.getElementById(name + "_url").value = "";
|
1615 |
+
document.getElementById(name + "_img").src = "' . plugins_url('newsletter') . '/images/nomedia.png";
|
1616 |
+
}
|
1617 |
+
}
|
1618 |
+
function newsletter_textarea_preview(id, header, footer) {
|
1619 |
+
var d = document.getElementById(id + "-iframe").contentWindow.document;
|
1620 |
+
d.open();
|
1621 |
+
if (templateEditor) {
|
1622 |
+
d.write(templateEditor.getValue());
|
1623 |
+
} else {
|
1624 |
+
d.write(header + document.getElementById(id).value + footer);
|
1625 |
+
}
|
1626 |
+
d.close();
|
1627 |
+
|
1628 |
+
var d = document.getElementById(id + "-iframe-phone").contentWindow.document;
|
1629 |
+
d.open();
|
1630 |
+
if (templateEditor) {
|
1631 |
+
d.write(templateEditor.getValue());
|
1632 |
+
} else {
|
1633 |
+
d.write(header + document.getElementById(id).value + footer);
|
1634 |
+
}
|
1635 |
+
d.close();
|
1636 |
+
//jQuery("#" + id + "-iframe-phone").toggle();
|
1637 |
+
jQuery("#" + id + "-preview").toggle();
|
1638 |
+
}
|
1639 |
+
function tnp_select_images(state) {
|
1640 |
+
if (!state.id) { return state.text; }
|
1641 |
+
var $state = jQuery("<span class=\"tnp-select2-option\"><img style=\"height: 20px!important; position: relative; top: 5px\" src=\"" + state.element.getAttribute("image") + "\"> " + state.text + "</span>");
|
1642 |
+
return $state;
|
1643 |
+
}
|
1644 |
+
function tnp_select_images_selection(state) {
|
1645 |
+
if (!state.id) { return state.text; }
|
1646 |
+
var $state = jQuery("<span class=\"tnp-select2-option\"><img style=\"height: 20px!important; position: relative; top: 5px\" src=\"" + state.element.getAttribute("image") + "\"> " + state.text + "</span>");
|
1647 |
+
return $state;
|
1648 |
+
}
|
1649 |
+
|
1650 |
+
|
1651 |
+
</script>
|
1652 |
+
';
|
1653 |
+
echo '<input name="act" type="hidden" value=""/>';
|
1654 |
+
echo '<input name="btn" type="hidden" value=""/>';
|
1655 |
+
wp_nonce_field('save');
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
function log_level($name = 'log_level') {
|
1659 |
+
$this->select($name, array(0 => 'None', 2 => 'Error', 3 => 'Normal', 4 => 'Debug'));
|
1660 |
+
}
|
1661 |
+
|
1662 |
+
function update_option($name, $data = null) {
|
1663 |
+
if ($data == null) {
|
1664 |
+
$data = $this->data;
|
1665 |
+
}
|
1666 |
+
update_option($name, $data);
|
1667 |
+
if (isset($data['log_level'])) {
|
1668 |
+
update_option($name . '_log_level', $data['log_level']);
|
1669 |
+
}
|
1670 |
+
}
|
1671 |
+
|
1672 |
+
function js_redirect($url) {
|
1673 |
+
echo '<script>';
|
1674 |
+
echo 'location.href="' . $url . '"';
|
1675 |
+
echo '</script>';
|
1676 |
+
die();
|
1677 |
+
}
|
1678 |
+
|
1679 |
+
/**
|
1680 |
+
* @deprecated
|
1681 |
+
*/
|
1682 |
+
function get_test_subscribers() {
|
1683 |
+
return NewsletterUsers::instance()->get_test_users();
|
1684 |
+
}
|
1685 |
+
|
1686 |
+
/**
|
1687 |
+
* Attributes:
|
1688 |
+
* weight: [true|false]
|
1689 |
+
* color: [true|false]
|
1690 |
+
*
|
1691 |
+
* @param string $name
|
1692 |
+
* @param array $attrs
|
1693 |
+
*/
|
1694 |
+
function css_font($name = 'font', $attrs = array()) {
|
1695 |
+
$default = [
|
1696 |
+
'color' => true,
|
1697 |
+
'weight' => true,
|
1698 |
+
'hide_size' => false,
|
1699 |
+
'hide_weight' => false,
|
1700 |
+
'hide_color' => false,
|
1701 |
+
];
|
1702 |
+
$attrs = array_merge($default, $attrs);
|
1703 |
+
$this->css_font_family($name . '_family', !empty($attrs['family_default']));
|
1704 |
+
if (!$attrs['hide_size']) {
|
1705 |
+
$this->css_font_size($name . '_size', !empty($attrs['size_default']));
|
1706 |
+
}
|
1707 |
+
if ($attrs['weight'] && !$attrs['hide_weight']) {
|
1708 |
+
$this->css_font_weight($name . '_weight', !empty($attrs['weight_default']));
|
1709 |
+
}
|
1710 |
+
if ($attrs['color'] && !$attrs['hide_color']) {
|
1711 |
+
$this->color($name . '_color');
|
1712 |
+
}
|
1713 |
+
}
|
1714 |
+
|
1715 |
+
function css_font_size($name = 'font_size', $show_empty_option = false) {
|
1716 |
+
$value = $this->get_value($name);
|
1717 |
+
|
1718 |
+
echo '<select class="tnpf-font-size" id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']">';
|
1719 |
+
if ($show_empty_option) {
|
1720 |
+
echo "<option value=''>-</option>";
|
1721 |
+
}
|
1722 |
+
for ($i = 8; $i <= 50; $i++) {
|
1723 |
+
echo '<option value="' . $i . '"';
|
1724 |
+
if ($value == $i) {
|
1725 |
+
echo ' selected';
|
1726 |
+
}
|
1727 |
+
echo '>' . $i . '</option>';
|
1728 |
+
}
|
1729 |
+
echo '</select>';
|
1730 |
+
}
|
1731 |
+
|
1732 |
+
function css_font_weight($name = 'font_weight', $show_empty_option = false) {
|
1733 |
+
$value = $this->get_value($name);
|
1734 |
+
|
1735 |
+
$fonts = array('normal' => 'Normal', 'bold' => 'Bold');
|
1736 |
+
|
1737 |
+
echo '<select class="tnpf-font-weight" id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']">';
|
1738 |
+
if ($show_empty_option) {
|
1739 |
+
echo "<option value=''>-</option>";
|
1740 |
+
}
|
1741 |
+
foreach ($fonts as $key => $font) {
|
1742 |
+
echo '<option value="', esc_attr($key), '"';
|
1743 |
+
if ($value == $key) {
|
1744 |
+
echo ' selected';
|
1745 |
+
}
|
1746 |
+
echo '>', esc_html($font), '</option>';
|
1747 |
+
}
|
1748 |
+
echo '</select>';
|
1749 |
+
}
|
1750 |
+
|
1751 |
+
function css_font_family($name = 'font_family', $show_empty_option = false) {
|
1752 |
+
$value = $this->get_value($name);
|
1753 |
+
|
1754 |
+
$fonts = [];
|
1755 |
+
if ($show_empty_option) {
|
1756 |
+
$fonts[''] = 'Default';
|
1757 |
+
}
|
1758 |
+
|
1759 |
+
$fonts = array_merge($fonts, ['Helvetica, Arial, sans-serif' => 'Helvetica, Arial',
|
1760 |
+
'Arial Black, Gadget, sans-serif' => 'Arial Black, Gadget',
|
1761 |
+
'Garamond, serif' => 'Garamond',
|
1762 |
+
'Courier, monospace' => 'Courier',
|
1763 |
+
'Comic Sans MS, cursive' => 'Comic Sans MS',
|
1764 |
+
'Impact, Charcoal, sans-serif' => 'Impact, Charcoal',
|
1765 |
+
'Tahoma, Geneva, sans-serif' => 'Tahoma, Geneva',
|
1766 |
+
'Times New Roman, Times, serif' => 'Times New Roman',
|
1767 |
+
'Verdana, Geneva, sans-serif' => 'Verdana, Geneva']);
|
1768 |
+
|
1769 |
+
echo '<select class="tnpf-font-family" id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']">';
|
1770 |
+
foreach ($fonts as $font => $label) {
|
1771 |
+
echo '<option value="', esc_attr($font), '"';
|
1772 |
+
if ($value == $font) {
|
1773 |
+
echo ' selected';
|
1774 |
+
}
|
1775 |
+
echo '>', esc_html($label), '</option>';
|
1776 |
+
}
|
1777 |
+
echo '</select>';
|
1778 |
+
}
|
1779 |
+
|
1780 |
+
function css_text_align($name) {
|
1781 |
+
$options = array('left' => __('Left', 'newsletter'), 'right' => __('Right', 'newsletter'),
|
1782 |
+
'center' => __('Center', 'newsletter'));
|
1783 |
+
$this->select($name, $options);
|
1784 |
+
}
|
1785 |
+
|
1786 |
+
function css_border($name) {
|
1787 |
+
$value = $this->get_value($name . '_width');
|
1788 |
+
|
1789 |
+
echo 'width <select id="options-' . esc_attr($name) . '-width" name="options[' . esc_attr($name) . '_width]">';
|
1790 |
+
for ($i = 0; $i < 10; $i++) {
|
1791 |
+
echo '<option value="' . $i . '"';
|
1792 |
+
if ($value == $i) {
|
1793 |
+
echo ' selected';
|
1794 |
+
}
|
1795 |
+
echo '>' . $i . '</option>';
|
1796 |
+
}
|
1797 |
+
echo '</select> px ';
|
1798 |
+
|
1799 |
+
$this->select($name . '_type', array('solid' => 'Solid', 'dashed' => 'Dashed'));
|
1800 |
+
|
1801 |
+
$this->color($name . '_color');
|
1802 |
+
|
1803 |
+
$value = $this->get_value($name . '_radius');
|
1804 |
+
|
1805 |
+
echo ' radius <select id="options-' . esc_attr($name) . '-radius" name="options[' . esc_attr($name) . '_radius]">';
|
1806 |
+
for ($i = 0; $i < 10; $i++) {
|
1807 |
+
echo '<option value="' . $i . '"';
|
1808 |
+
if ($value == $i) {
|
1809 |
+
echo ' selected';
|
1810 |
+
}
|
1811 |
+
echo '>' . $i . '</option>';
|
1812 |
+
}
|
1813 |
+
echo '</select> px';
|
1814 |
+
}
|
1815 |
+
|
1816 |
+
/**
|
1817 |
+
* Media selector using the media library of WP. Produces a field which values is an array containing 'id' and 'url'.
|
1818 |
+
*
|
1819 |
+
* @param string $name
|
1820 |
+
*/
|
1821 |
+
function media($name) {
|
1822 |
+
if (isset($this->data[$name]['id'])) {
|
1823 |
+
$media_id = (int) $this->data[$name]['id'];
|
1824 |
+
$media = wp_get_attachment_image_src($media_id, 'medium');
|
1825 |
+
$media_full = wp_get_attachment_image_src($media_id, 'full');
|
1826 |
+
} else {
|
1827 |
+
$media = false;
|
1828 |
+
}
|
1829 |
+
echo '<div style="position: relative">';
|
1830 |
+
echo '<a style="position: absolute; top: 5px; right: 5px; background-color: none; color: #000; padding: 0px 5px 6px 5px; font-size: 24px; display: block; text-decoration: none" href="#" onclick="newsletter_media_remove(\'' . esc_attr($name) . '\'); return false">×</a>';
|
1831 |
+
if ($media === false) {
|
1832 |
+
$media = array('', '', '');
|
1833 |
+
$media_full = array('', '', '');
|
1834 |
+
$media_id = 0;
|
1835 |
+
echo '<img style="max-width: 200px; max-height: 150px; width: 100px;" id="' . esc_attr($name) . '_img" src="' . plugins_url('newsletter') . '/images/nomedia.png" onclick="newsletter_media(\'' . esc_attr($name) . '\')">';
|
1836 |
+
} else {
|
1837 |
+
echo '<img style="max-width: 200px; max-height: 150px;" id="' . esc_attr($name) . '_img" src="' . esc_attr($media[0]) . '" onclick="newsletter_media(\'' . esc_attr($name) . '\')">';
|
1838 |
+
}
|
1839 |
+
|
1840 |
+
echo '</div>';
|
1841 |
+
echo '<input type="hidden" id="' . esc_attr($name) . '_id" name="options[' . esc_attr($name) . '][id]" value="' . esc_attr($media_id) . '" size="5">';
|
1842 |
+
echo '<input type="hidden" id="' . esc_attr($name) . '_url" name="options[' . esc_attr($name) . '][url]" value="' . esc_attr($media_full[0]) . '" size="50">';
|
1843 |
+
}
|
1844 |
+
|
1845 |
+
function media_input($option, $name, $label) {
|
1846 |
+
|
1847 |
+
if (!empty($label)) {
|
1848 |
+
$output = '<label class="select" for="tnp_' . esc_attr($name) . '">' . esc_html($label) . ':</label>';
|
1849 |
+
}
|
1850 |
+
$output .= '<input id="tnp_' . esc_attr($name) . '" type="text" size="36" name="' . esc_attr($option) . '[' . esc_attr($name) . ']" value="' . esc_attr($val) . '" />';
|
1851 |
+
$output .= '<input id="tnp_' . esc_attr($name) . '_button" class="button-primary" type="button" value="Select Image" />';
|
1852 |
+
$output .= '<br class="clear"/>';
|
1853 |
+
|
1854 |
+
echo $output;
|
1855 |
+
}
|
1856 |
+
|
1857 |
+
function language($name = 'language', $empty_label = 'All') {
|
1858 |
+
if (!class_exists('SitePress') && !function_exists('pll_default_language') && !class_exists('TRP_Translate_Press')) {
|
1859 |
+
echo __('Install a multilanguage plugin.', 'newsletter');
|
1860 |
+
echo ' <a href="https://www.thenewsletterplugin.com/documentation/multilanguage" target="_blank">', __('Read more', 'newsletter'), '</a>';
|
1861 |
+
return;
|
1862 |
+
}
|
1863 |
+
|
1864 |
+
$languages = Newsletter::instance()->get_languages();
|
1865 |
+
if (!empty($empty_label)) {
|
1866 |
+
$languages = array_merge(array('' => $empty_label), $languages);
|
1867 |
+
}
|
1868 |
+
$this->select($name, $languages);
|
1869 |
+
}
|
1870 |
+
|
1871 |
+
function is_multilanguage() {
|
1872 |
+
return Newsletter::instance()->is_multilanguage();
|
1873 |
+
}
|
1874 |
+
|
1875 |
+
/**
|
1876 |
+
* Creates a checkbox group with all active languages. Each checkbox is named
|
1877 |
+
* $name[] and values with the relative language code.
|
1878 |
+
*
|
1879 |
+
* @param string $name
|
1880 |
+
*/
|
1881 |
+
function languages($name = 'languages') {
|
1882 |
+
if (!$this->is_multilanguage()) {
|
1883 |
+
echo __('Install WPML or Polylang for multilanguage support', 'newsletter');
|
1884 |
+
return;
|
1885 |
+
}
|
1886 |
+
|
1887 |
+
$language_options = Newsletter::instance()->get_languages();
|
1888 |
+
|
1889 |
+
if (empty($language_options)) {
|
1890 |
+
echo __('Your multilanguage plugin is not supported or there are no languages defined', 'newsletter');
|
1891 |
+
return;
|
1892 |
+
}
|
1893 |
+
|
1894 |
+
$this->checkboxes_group($name, $language_options);
|
1895 |
+
}
|
1896 |
+
|
1897 |
+
/**
|
1898 |
+
* Prints a formatted date using the formats and timezone of WP, including the current date and time and the
|
1899 |
+
* time left to the passed time.
|
1900 |
+
*
|
1901 |
+
* @param int $time
|
1902 |
+
* @param int $now
|
1903 |
+
* @param bool $left
|
1904 |
+
* @return string
|
1905 |
+
*/
|
1906 |
+
static function print_date($time = null, $now = false, $left = false) {
|
1907 |
+
if (is_null($time)) {
|
1908 |
+
$time = time();
|
1909 |
+
}
|
1910 |
+
if ($time == false) {
|
1911 |
+
$buffer = 'none';
|
1912 |
+
} else {
|
1913 |
+
$buffer = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $time + get_option('gmt_offset') * 3600);
|
1914 |
+
|
1915 |
+
if ($now) {
|
1916 |
+
$buffer .= ' (now: ' . gmdate(get_option('date_format') . ' ' .
|
1917 |
+
get_option('time_format'), time() + get_option('gmt_offset') * 3600);
|
1918 |
+
$buffer .= ')';
|
1919 |
+
}
|
1920 |
+
if ($left) {
|
1921 |
+
if ($time - time() < 0) {
|
1922 |
+
$buffer .= ', ' . (time() - $time) . ' seconds late';
|
1923 |
+
} else {
|
1924 |
+
$buffer .= ', ' . gmdate('H:i:s', $time - time()) . ' left';
|
1925 |
+
}
|
1926 |
+
}
|
1927 |
+
}
|
1928 |
+
return $buffer;
|
1929 |
+
}
|
1930 |
+
|
1931 |
+
static function delta_time($delta = 0) {
|
1932 |
+
$seconds = $delta % 60;
|
1933 |
+
$minutes = floor(($delta / 60) % 60);
|
1934 |
+
$hours = floor(($delta / (60 * 60)) % 24);
|
1935 |
+
$days = floor($delta / (24 * 60 * 60));
|
1936 |
+
|
1937 |
+
return $days . ' day(s), ' . $hours . ' hour(s), ' . $minutes . ' minute(s)';
|
1938 |
+
}
|
1939 |
+
|
1940 |
+
/**
|
1941 |
+
* Prints the help button near a form field. The label is used as icon title.
|
1942 |
+
*
|
1943 |
+
* @param string $url
|
1944 |
+
* @param string $label
|
1945 |
+
*/
|
1946 |
+
static function help($url, $label = '') {
|
1947 |
+
echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fas fa-question-circle"></i></a>';
|
1948 |
+
}
|
1949 |
+
|
1950 |
+
static function idea($url, $label = '') {
|
1951 |
+
echo '<a href="', $url, '" target="_blank" title="', esc_attr($label), '"><i class="fas fa-lightbulb-o"></i></a>';
|
1952 |
+
}
|
1953 |
+
|
1954 |
+
static function field_help($url, $text = '') {
|
1955 |
+
if (strpos($url, 'http') !== 0) {
|
1956 |
+
$url = 'https://www.thenewsletterplugin.com' . $url;
|
1957 |
+
}
|
1958 |
+
echo '<a href="', $url, '" target="_blank" style="text-decoration: none" title="' . esc_attr(__('Read more', 'newsletter')) . '"><i class="fas fa-question-circle"></i>';
|
1959 |
+
if ($text)
|
1960 |
+
echo ' ', $text;
|
1961 |
+
echo '</a>';
|
1962 |
+
}
|
1963 |
+
|
1964 |
+
static function field_label($label, $help_url = false) {
|
1965 |
+
echo $label;
|
1966 |
+
if ($help_url) {
|
1967 |
+
echo ' ';
|
1968 |
+
self::field_help($help_url);
|
1969 |
+
}
|
1970 |
+
}
|
1971 |
+
|
1972 |
+
/**
|
1973 |
+
* Prints a panel link to the documentation.
|
1974 |
+
*
|
1975 |
+
* @param type $url
|
1976 |
+
* @param type $text
|
1977 |
+
*/
|
1978 |
+
static function panel_help($url, $text = '') {
|
1979 |
+
if (empty($text))
|
1980 |
+
$text = __('Need help?', 'newsletter');
|
1981 |
+
echo '<span class="tnp-panel-help"><a href="', $url, '" target="_blank">', $text, '</a></span>';
|
1982 |
+
}
|
1983 |
+
|
1984 |
+
/**
|
1985 |
+
* Prints an administration page link to the documentation (just under the administration page title.
|
1986 |
+
* @param type $url
|
1987 |
+
* @param type $text
|
1988 |
+
*/
|
1989 |
+
static function page_help($url, $text = '') {
|
1990 |
+
if (empty($text))
|
1991 |
+
$text = __('Need help?', 'newsletter');
|
1992 |
+
echo '<div class="tnp-page-help"><a href="', $url, '" target="_blank">', $text, '</a></div>';
|
1993 |
+
}
|
1994 |
+
|
1995 |
+
static function print_truncated($text, $size = 50) {
|
1996 |
+
if (mb_strlen($text) < $size)
|
1997 |
+
return esc_html($text);
|
1998 |
+
$sub = mb_substr($text, 0, $size);
|
1999 |
+
echo '<span title="', esc_attr($text), '">', esc_html($sub), '...</span>';
|
2000 |
+
}
|
2001 |
+
|
2002 |
+
function block_background($name = 'block_background') {
|
2003 |
+
$this->color($name);
|
2004 |
+
}
|
2005 |
+
|
2006 |
+
function block_padding($name = 'block_padding', $options = array()) {
|
2007 |
+
echo '<div style="text-align: center; width: 250px;">';
|
2008 |
+
$this->text($name . '_top', 5);
|
2009 |
+
echo '<br>';
|
2010 |
+
$this->text($name . '_left', 5);
|
2011 |
+
echo " ";
|
2012 |
+
$this->text($name . '_right', 5);
|
2013 |
+
echo '<br>';
|
2014 |
+
$this->text($name . '_bottom', 5);
|
2015 |
+
echo '</div>';
|
2016 |
+
}
|
2017 |
+
|
2018 |
+
/**
|
2019 |
+
* Adds the fields used by the composer (version 1) in the page form.
|
2020 |
+
*
|
2021 |
+
* @param type $name
|
2022 |
+
*/
|
2023 |
+
function composer_fields($name = 'body') {
|
2024 |
+
|
2025 |
+
// body
|
2026 |
+
$value = $this->get_value($name);
|
2027 |
+
|
2028 |
+
// Extracts only the body part
|
2029 |
+
$x = strpos($value, '<body');
|
2030 |
+
if ($x) {
|
2031 |
+
$x = strpos($value, '>', $x);
|
2032 |
+
$y = strpos($value, '</body>');
|
2033 |
+
$value = substr($value, $x + 1, $y - $x - 1);
|
2034 |
+
}
|
2035 |
+
|
2036 |
+
/* Cleans up uncorrectly stored newsletter bodies */
|
2037 |
+
$value = preg_replace('/<style\s+.*?>.*?<\\/style>/is', '', $value);
|
2038 |
+
$value = preg_replace('/<meta.*?>/', '', $value);
|
2039 |
+
$value = preg_replace('/<title\s+.*?>.*?<\\/title>/i', '', $value);
|
2040 |
+
$value = trim($value);
|
2041 |
+
|
2042 |
+
// Required since esc_html DOES NOT escape the HTML entities (apparently)
|
2043 |
+
$value = str_replace('&', '&', $value);
|
2044 |
+
$value = str_replace('"', '"', $value);
|
2045 |
+
$value = str_replace('<', '<', $value);
|
2046 |
+
$value = str_replace('>', '>', $value);
|
2047 |
+
echo '<input type="hidden" name="options[', esc_attr($name), ']" id="options-', esc_attr($name), '" value="', esc_attr($value), '">';
|
2048 |
+
|
2049 |
+
// Used by composer to rebuild the full HTML
|
2050 |
+
$css = NewsletterEmails::instance()->get_composer_css();
|
2051 |
+
echo '<input type="hidden" name="options[css]" id="options-css" value="', esc_attr($css), '">';
|
2052 |
+
|
2053 |
+
// subject
|
2054 |
+
$value = $this->get_value('subject');
|
2055 |
+
echo '<input type="hidden" name="options[subject]" id="options-subject" value="', esc_attr($value), '">';
|
2056 |
+
}
|
2057 |
+
|
2058 |
+
function composer_load($name = 'body', $show_subject = false, $show_test = true, $context_type = '') {
|
2059 |
+
|
2060 |
+
global $controls;
|
2061 |
+
global $tnpc_show_subject;
|
2062 |
+
$tnpc_show_subject = $show_subject;
|
2063 |
+
|
2064 |
+
wp_enqueue_style('tnpc-style', plugins_url('newsletter') . '/emails/tnp-composer/_css/newsletter-builder.css', array(), time());
|
2065 |
+
|
2066 |
+
include NEWSLETTER_DIR . '/emails/tnp-composer/index.php';
|
2067 |
+
}
|
2068 |
+
|
2069 |
+
/**
|
2070 |
+
* Adds the fields used by the composer (version 2) in the page form.
|
2071 |
+
*/
|
2072 |
+
function composer_fields_v2($name = 'message') {
|
2073 |
+
|
2074 |
+
// The composer, on saving, fills in those fields
|
2075 |
+
$this->hidden('subject');
|
2076 |
+
$this->hidden('message');
|
2077 |
+
$this->hidden('options_preheader');
|
2078 |
+
|
2079 |
+
//$preheader_value = $this->get_value('options_preheader');
|
2080 |
+
// echo '<input name="options[preheader]" id="options-preheader" type="hidden" value="', esc_attr($preheader_value), '">';
|
2081 |
+
}
|
2082 |
+
|
2083 |
+
function composer_load_v2($show_subject = false, $show_test = true, $context_type = '') {
|
2084 |
+
|
2085 |
+
global $tnpc_show_subject;
|
2086 |
+
$tnpc_show_subject = $show_subject;
|
2087 |
+
|
2088 |
+
echo "<link href='", plugins_url('newsletter'), "/emails/tnp-composer/_css/newsletter-builder-v2.css?ver=" . NEWSLETTER_VERSION . "' rel='stylesheet' type='text/css'>";
|
2089 |
+
|
2090 |
+
$controls = $this;
|
2091 |
+
include NEWSLETTER_DIR . '/emails/tnp-composer/index-v2.php';
|
2092 |
+
}
|
2093 |
+
|
2094 |
+
function subject($name) {
|
2095 |
+
$value = $this->get_value($name);
|
2096 |
+
// Leave the ID with this prefix!
|
2097 |
+
echo '<div style="position: relative"><input size="80" id="options-subject-', esc_attr($name), '" name="options[' . esc_attr($name) . ']" type="text" placeholder="" value="';
|
2098 |
+
echo esc_attr($value);
|
2099 |
+
echo '">';
|
2100 |
+
echo ' <i class="far fa-lightbulb tnp-suggest-subject" data-tnp-modal-target="#subject-ideas-modal"></i>';
|
2101 |
+
|
2102 |
+
echo '<img src="', plugins_url('newsletter'), '/admin/images/subject/android.png" style="position: absolute; width: 16px; left: 330px; top: 25px; display: block; opacity: 0">';
|
2103 |
+
echo '<img src="', plugins_url('newsletter'), '/admin/images/subject/iphone.png" style="position: absolute; width: 16px; left: 380px; top: 25px; display: block; opacity: 0">';
|
2104 |
+
echo '</div>';
|
2105 |
+
}
|
2106 |
+
|
2107 |
+
}
|
includes/cron.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Set up and log the cron system. To be loaded at the plugin start.
|
4 |
+
*/
|
5 |
+
defined('ABSPATH') || exit;
|
6 |
+
|
7 |
+
// Can be redefined in wp-config.php (not recommended)
|
8 |
+
if (!defined('NEWSLETTER_CRON_INTERVAL')) {
|
9 |
+
define('NEWSLETTER_CRON_INTERVAL', 300);
|
10 |
+
}
|
11 |
+
|
12 |
+
// Logging of the cron calls to debug the so many situations where the cron is not triggered at all (grrr...).
|
13 |
+
if (defined('DOING_CRON') && DOING_CRON) {
|
14 |
+
$calls = get_option('newsletter_diagnostic_cron_calls', []);
|
15 |
+
// Protection against scrambled options or bad written database caching plugin (yes, it happened, grrr...).
|
16 |
+
if (!is_array($calls)) {
|
17 |
+
$calls = [];
|
18 |
+
}
|
19 |
+
$calls[] = time();
|
20 |
+
// TODO: create a constant for samples limit
|
21 |
+
if (count($calls) > 100) {
|
22 |
+
// TODO: optimize using array_slice() and call every ten records
|
23 |
+
array_shift($calls);
|
24 |
+
}
|
25 |
+
update_option('newsletter_diagnostic_cron_calls', $calls, false);
|
26 |
+
}
|
27 |
+
|
28 |
+
// As soon as possible but with low priority so it is ecxecutes as last filter to avoid bad witten
|
29 |
+
// filters which remove other's schedules (yes, it happened, grrr...).
|
30 |
+
add_filter('cron_schedules', function ($schedules) {
|
31 |
+
$schedules['newsletter'] = [
|
32 |
+
'interval' => NEWSLETTER_CRON_INTERVAL,
|
33 |
+
'display' => 'Every ' . NEWSLETTER_CRON_INTERVAL . ' seconds'
|
34 |
+
];
|
35 |
+
return $schedules;
|
36 |
+
}, 1000);
|
includes/fields.php
CHANGED
@@ -1,745 +1,745 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class NewsletterFields {
|
4 |
-
/* @var NewsletterControls */
|
5 |
-
|
6 |
-
var $controls;
|
7 |
-
|
8 |
-
public function __construct(NewsletterControls $controls) {
|
9 |
-
$this->controls = $controls;
|
10 |
-
}
|
11 |
-
|
12 |
-
public function _open($subclass = '') {
|
13 |
-
echo '<div class="tnp-field ', $subclass, '">';
|
14 |
-
}
|
15 |
-
|
16 |
-
public function _close() {
|
17 |
-
echo '</div>';
|
18 |
-
}
|
19 |
-
|
20 |
-
public function _label($text, $for = '') {
|
21 |
-
if (empty($text)) {
|
22 |
-
return;
|
23 |
-
}
|
24 |
-
// Do not escape, HTML allowed
|
25 |
-
echo '<label class="tnp-label">', $text, '</label>';
|
26 |
-
}
|
27 |
-
|
28 |
-
public function _description($attrs) {
|
29 |
-
if (empty($attrs['description'])) {
|
30 |
-
return;
|
31 |
-
}
|
32 |
-
// Do not escape, HTML allowed
|
33 |
-
echo '<div class="tnp-description">', $attrs['description'], '</div>';
|
34 |
-
}
|
35 |
-
|
36 |
-
public function _id($name) {
|
37 |
-
return 'options-' . esc_attr($name);
|
38 |
-
}
|
39 |
-
|
40 |
-
public function _name($name) {
|
41 |
-
return 'options[' . esc_attr($name) . ']';
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Adds some empty basic atributes to avoid the isset() checking.
|
46 |
-
*
|
47 |
-
* @param array $attrs
|
48 |
-
* @return array
|
49 |
-
*/
|
50 |
-
public function _merge_base_attrs($attrs) {
|
51 |
-
return array_merge(['description' => '', 'label' => '', 'help_url' => ''], $attrs);
|
52 |
-
}
|
53 |
-
|
54 |
-
/** Adds some basic attributes and the provided default ones.
|
55 |
-
*
|
56 |
-
* @param array $attrs
|
57 |
-
* @param array $defaults
|
58 |
-
* @return array
|
59 |
-
*/
|
60 |
-
public function _merge_attrs($attrs, $defaults = []) {
|
61 |
-
return array_merge(['description' => '', 'label' => '', 'help_url' => ''], $defaults, $attrs);
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* A form section title.
|
66 |
-
*
|
67 |
-
* @param string $title
|
68 |
-
*/
|
69 |
-
public function section($title = '') {
|
70 |
-
// Do not escape, HTML allowed
|
71 |
-
echo '<h3 class="tnp-section">', $title, '</h3>';
|
72 |
-
}
|
73 |
-
|
74 |
-
public function separator() {
|
75 |
-
echo '<div class="tnp-field tnp-separator"></div>';
|
76 |
-
}
|
77 |
-
|
78 |
-
public function checkbox($name, $label = '', $attrs = []) {
|
79 |
-
$attrs = $this->_merge_base_attrs($attrs);
|
80 |
-
$this->_open('tnp-checkbox');
|
81 |
-
$this->controls->checkbox($name, $label);
|
82 |
-
$this->_description($attrs);
|
83 |
-
$this->_close();
|
84 |
-
}
|
85 |
-
|
86 |
-
/** General Input field with default type = text
|
87 |
-
*
|
88 |
-
* Attributes:
|
89 |
-
* - label_after (default: none): small text ti be displayed after the text field
|
90 |
-
* - min (default: none): minimum number of characters
|
91 |
-
* - max (default: none): maximum number of characters
|
92 |
-
* - size (default: none): size in pixels
|
93 |
-
*/
|
94 |
-
public function input($name, $label = '', $attrs = []) {
|
95 |
-
$attrs = $this->_merge_attrs($attrs, ['placeholder' => '', 'size' => 0, 'label_after' => '', 'type' => 'text']);
|
96 |
-
$this->_open();
|
97 |
-
$this->_label($label);
|
98 |
-
$value = $this->controls->get_value($name);
|
99 |
-
|
100 |
-
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="', esc_attr($attrs['type']), '"';
|
101 |
-
|
102 |
-
if (!empty($attrs['size'])) {
|
103 |
-
echo ' style="width: ', $attrs['size'], 'px"';
|
104 |
-
}
|
105 |
-
|
106 |
-
if (isset($attrs['min'])) {
|
107 |
-
echo ' min="' . (int) $attrs['min'] . '"';
|
108 |
-
}
|
109 |
-
|
110 |
-
if (isset($attrs['max'])) {
|
111 |
-
echo ' max="' . (int) $attrs['max'] . '"';
|
112 |
-
}
|
113 |
-
|
114 |
-
echo ' value="', esc_attr($value), '">';
|
115 |
-
|
116 |
-
if (!empty($attrs['label_after'])) {
|
117 |
-
echo $attrs['label_after'];
|
118 |
-
}
|
119 |
-
|
120 |
-
$this->_description($attrs);
|
121 |
-
$this->_close();
|
122 |
-
}
|
123 |
-
|
124 |
-
public function text($name, $label = '', $attrs = []) {
|
125 |
-
$attrs['type'] = 'text';
|
126 |
-
$this->input($name, $label, $attrs);
|
127 |
-
}
|
128 |
-
|
129 |
-
public function text_on_off($name, $label = '', $attrs = []) {
|
130 |
-
$attrs = $this->_merge_attrs($attrs, ['placeholder' => '', 'size' => 0, 'label_after' => '', 'type' => 'text']);
|
131 |
-
$this->_open();
|
132 |
-
$this->_label($label);
|
133 |
-
$value = $this->controls->get_value($name);
|
134 |
-
|
135 |
-
echo '<input type="hidden" name="tnp_fields[' . esc_attr($name . '_enabled') . ']" value="checkbox">';
|
136 |
-
echo '<input id="', $this->_id($name . '_enabled'), '" name="', $this->_name($name . '_enabled'), '" type="checkbox" value="1"';
|
137 |
-
if (!empty($this->controls->get_value($name . '_enabled'))) {
|
138 |
-
echo ' checked';
|
139 |
-
}
|
140 |
-
echo '> ';
|
141 |
-
|
142 |
-
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="text"';
|
143 |
-
|
144 |
-
echo ' style="width: 90%;"';
|
145 |
-
|
146 |
-
if (isset($attrs['min'])) {
|
147 |
-
echo ' min="' . (int) $attrs['min'] . '"';
|
148 |
-
}
|
149 |
-
|
150 |
-
if (isset($attrs['max'])) {
|
151 |
-
echo ' max="' . (int) $attrs['max'] . '"';
|
152 |
-
}
|
153 |
-
|
154 |
-
echo ' value="', esc_attr($value), '">';
|
155 |
-
|
156 |
-
if (!empty($attrs['label_after'])) {
|
157 |
-
echo $attrs['label_after'];
|
158 |
-
}
|
159 |
-
|
160 |
-
$this->_description($attrs);
|
161 |
-
$this->_close();
|
162 |
-
}
|
163 |
-
|
164 |
-
public function number($name, $label = '', $attrs = []) {
|
165 |
-
$attrs = array_merge(['type' => 'number'], $attrs);
|
166 |
-
$this->input($name, $label, $attrs);
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* A set of text fields, named $name_1, $name_2, ...
|
171 |
-
*
|
172 |
-
* Attributes:
|
173 |
-
* - label_after: a label to show after the field column
|
174 |
-
*
|
175 |
-
* @param type $name
|
176 |
-
* @param type $label
|
177 |
-
* @param type $count
|
178 |
-
* @param type $attrs
|
179 |
-
*/
|
180 |
-
public function multitext($name, $label = '', $count = 10, $attrs = []) {
|
181 |
-
$attrs = $this->_merge_attrs($attrs, ['description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => '']);
|
182 |
-
$this->_open();
|
183 |
-
$this->_label($label);
|
184 |
-
|
185 |
-
for ($i = 1; $i <= $count; $i++) {
|
186 |
-
$value = $this->controls->get_value($name . '_' . $i);
|
187 |
-
echo '<input id="', $this->_id($name . '_' . $i), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name, '_', $i, ']" type="text"';
|
188 |
-
if (!empty($attrs['size'])) {
|
189 |
-
echo ' style="width: ', $attrs['size'], 'px"';
|
190 |
-
}
|
191 |
-
echo ' value="', esc_attr($value), '">';
|
192 |
-
}
|
193 |
-
if (!empty($attrs['label_after'])) {
|
194 |
-
echo $attrs['label_after'];
|
195 |
-
}
|
196 |
-
$this->_description($attrs);
|
197 |
-
$this->_close();
|
198 |
-
}
|
199 |
-
|
200 |
-
public function textarea($name, $label = '', $attrs = []) {
|
201 |
-
$attrs = $this->_merge_attrs($attrs, ['width' => '100%', 'height' => '150']);
|
202 |
-
$this->_open();
|
203 |
-
$this->_label($label);
|
204 |
-
$this->controls->textarea_fixed($name, $attrs['width'], $attrs['height']);
|
205 |
-
$this->_description($attrs);
|
206 |
-
$this->_close();
|
207 |
-
}
|
208 |
-
|
209 |
-
public function wp_editor($name, $label = '', $attrs = []) {
|
210 |
-
global $wp_version;
|
211 |
-
|
212 |
-
$attrs = $this->_merge_attrs($attrs);
|
213 |
-
$this->_open();
|
214 |
-
$this->_label($label);
|
215 |
-
$value = $this->controls->get_value($name);
|
216 |
-
$name = esc_attr($name);
|
217 |
-
|
218 |
-
// Uhm...
|
219 |
-
if (is_array($value)) {
|
220 |
-
$value = implode("\n", $value);
|
221 |
-
}
|
222 |
-
if (version_compare($wp_version, '4.8', '<')) {
|
223 |
-
echo '<p><strong>Rich editor available only with WP 4.8+</strong></p>';
|
224 |
-
}
|
225 |
-
echo '<textarea class="tnpf-wp-editor" id="options-', $name, '" name="options[', $name, ']" style="width: 100%;height:250px">';
|
226 |
-
echo esc_html($value);
|
227 |
-
echo '</textarea>';
|
228 |
-
|
229 |
-
if (version_compare($wp_version, '4.8', '>=')) {
|
230 |
-
|
231 |
-
$paragraph_style = " p { font-family: ${attrs['text_font_family']}; font-size: ${attrs['text_font_size']}px; font-weight: ${attrs['text_font_weight']}; color: ${attrs['text_font_color']}; line-height: 1.5em; }";
|
232 |
-
$content_style = $paragraph_style;
|
233 |
-
|
234 |
-
echo '<script>';
|
235 |
-
echo 'wp.editor.remove("options-', $name, '");';
|
236 |
-
echo 'wp.editor.initialize("options-', $name, '", { tinymce: {content_style: "' . $content_style . '", toolbar1: "undo redo | formatselect fontselect fontsizeselect | bold italic forecolor backcolor | link unlink | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | wp_add_media | charmap | rtl ltr", fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px", plugins: "link textcolor colorpicker lists wordpress charmap directionality", default_link_target: "_blank", relative_urls : false, convert_urls: false, keep_styles: true }});';
|
237 |
-
echo '</script>';
|
238 |
-
}
|
239 |
-
$this->_description($attrs);
|
240 |
-
$this->_close();
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* Attributes:
|
245 |
-
* - realod: when true is forces a submit of the form (used to change the form fields or values for example when changing layout or color scheme)
|
246 |
-
*
|
247 |
-
* @param type $name
|
248 |
-
* @param type $label
|
249 |
-
* @param type $options
|
250 |
-
* @param type $attrs
|
251 |
-
*/
|
252 |
-
public function select($name, $label = '', $options = [], $attrs = []) {
|
253 |
-
$attrs = $this->_merge_attrs($attrs, ['reload' => false, 'after-rendering' => '', 'class' => '']);
|
254 |
-
$this->_open();
|
255 |
-
$this->_label($label);
|
256 |
-
$value = $this->controls->get_value($name);
|
257 |
-
|
258 |
-
echo '<select id="', $this->_id($name), '" name="', $this->_name($name), '"';
|
259 |
-
if ($attrs['class']) {
|
260 |
-
echo ' class="', esc_attr($attrs['class']), '"';
|
261 |
-
}
|
262 |
-
if ($attrs['reload']) {
|
263 |
-
echo ' onchange="tnpc_reload_options(event)"';
|
264 |
-
}
|
265 |
-
if (!empty($attrs['after-rendering'])) {
|
266 |
-
echo ' data-after-rendering="', $attrs['after-rendering'], '"';
|
267 |
-
}
|
268 |
-
echo '>';
|
269 |
-
// if (!empty($first)) {
|
270 |
-
// echo '<option value="">', esc_html($first), '</option>';
|
271 |
-
// }
|
272 |
-
|
273 |
-
foreach ($options as $key => $text) {
|
274 |
-
echo '<option value="', esc_attr($key), '"';
|
275 |
-
if ($value == $key) {
|
276 |
-
echo ' selected';
|
277 |
-
}
|
278 |
-
echo '>', esc_html($text), '</option>';
|
279 |
-
}
|
280 |
-
echo '</select>';
|
281 |
-
|
282 |
-
$this->_description($attrs);
|
283 |
-
$this->_close();
|
284 |
-
}
|
285 |
-
|
286 |
-
public function align($name = 'align') {
|
287 |
-
$this->select($name,
|
288 |
-
__('Align', 'newsletter'),
|
289 |
-
['center' => __('Center', 'newsletter'), 'left' => __('Left', 'newsletter'), 'right' => __('Right')]
|
290 |
-
);
|
291 |
-
}
|
292 |
-
|
293 |
-
public function yesno($name, $label = '', $attrs = []) {
|
294 |
-
$attrs = $this->_merge_attrs($attrs);
|
295 |
-
$this->_open();
|
296 |
-
$this->_label($label);
|
297 |
-
$this->controls->yesno($name);
|
298 |
-
$this->_description($attrs);
|
299 |
-
$this->_close();
|
300 |
-
}
|
301 |
-
|
302 |
-
public function select_number($name, $label = '', $min, $max, $attrs = []) {
|
303 |
-
$attrs = $this->_merge_attrs($attrs);
|
304 |
-
$this->_open();
|
305 |
-
$this->_label($label);
|
306 |
-
$this->controls->select_number($name, $min, $max);
|
307 |
-
$this->_description($attrs);
|
308 |
-
$this->_close();
|
309 |
-
}
|
310 |
-
|
311 |
-
/**
|
312 |
-
* General field to collect an element dimension in pixels
|
313 |
-
*
|
314 |
-
* Attributes:
|
315 |
-
* - size: field width in pixels
|
316 |
-
*/
|
317 |
-
public function size($name, $label = '', $attrs = []) {
|
318 |
-
$attrs = $this->_merge_attrs($attrs, ['description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => 'px']);
|
319 |
-
$this->_open('tnp-size');
|
320 |
-
$this->_label($label);
|
321 |
-
$value = $this->controls->get_value($name);
|
322 |
-
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="text"';
|
323 |
-
if (!empty($attrs['size'])) {
|
324 |
-
echo ' style="width: ', $attrs['size'], 'px"';
|
325 |
-
}
|
326 |
-
echo ' value="', esc_attr($value), '">', $attrs['label_after'];
|
327 |
-
$this->_description($attrs);
|
328 |
-
$this->_close();
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Collects a color in HEX format with a picker.
|
333 |
-
*/
|
334 |
-
public function color($name, $label, $attrs = []) {
|
335 |
-
$this->_open('tnp-color');
|
336 |
-
$this->_label($label);
|
337 |
-
$this->controls->color($name);
|
338 |
-
$this->_description($attrs);
|
339 |
-
$this->_close();
|
340 |
-
}
|
341 |
-
|
342 |
-
/**
|
343 |
-
* Configuration for a simple button with label and color
|
344 |
-
*
|
345 |
-
* Attributes:
|
346 |
-
* - weight: if true (default) shows the font weight selector
|
347 |
-
* - url_paceholder: the placeholder for the URL field
|
348 |
-
* - url: if true (default) shows the URL field (sometime the URL is produced elsewhere, for example on post list)
|
349 |
-
*/
|
350 |
-
public function button($name, $label = '', $attrs = []) {
|
351 |
-
$attrs = $this->_merge_attrs($attrs,
|
352 |
-
[
|
353 |
-
'placeholder' => 'Label...',
|
354 |
-
'url_placeholder' => 'https://...',
|
355 |
-
'url' => true,
|
356 |
-
'weight' => true,
|
357 |
-
'family_default' => false,
|
358 |
-
'size_default' => false,
|
359 |
-
'weight_default' => false,
|
360 |
-
]);
|
361 |
-
|
362 |
-
$this->_open('tnpf-button');
|
363 |
-
$this->_label($label);
|
364 |
-
$value = $this->controls->get_value($name . '_label');
|
365 |
-
$name_esc = esc_attr($name);
|
366 |
-
echo '<div class="tnp-field-row">';
|
367 |
-
echo '<div class="tnp-field-col-2">';
|
368 |
-
echo '<input id="', $this->_id($name . '_label'), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name_esc, '_label]" type="text"';
|
369 |
-
echo ' style="width: 100%"';
|
370 |
-
echo ' value="', esc_attr($value), '">';
|
371 |
-
echo '</div>';
|
372 |
-
|
373 |
-
if ($attrs['url']) {
|
374 |
-
$value = $this->controls->get_value($name . '_url');
|
375 |
-
echo '<div class="tnp-field-col-2">';
|
376 |
-
$width = isset($attrs['media']) ? '90%' : '100%';
|
377 |
-
echo '<input id="', $this->_id($name . '_url'), '" placeholder="', esc_attr($attrs['url_placeholder']), '" name="options[',
|
378 |
-
$name_esc, '_url]" type="url" style="width: ', $width, '" value="', esc_attr($value), '">';
|
379 |
-
if (isset($attrs['media'])) {
|
380 |
-
echo ' <i class="far fa-folder-open" data-field="', $this->_id($name . '_url'), '" onclick="tnp_fields_url_select(this)"></i>';
|
381 |
-
}
|
382 |
-
echo '</div>';
|
383 |
-
}
|
384 |
-
echo '<div style="clear: both"></div>';
|
385 |
-
echo '</div>';
|
386 |
-
$this->controls->css_font($name . '_font', [
|
387 |
-
'weight' => $attrs['weight'],
|
388 |
-
'family_default' => $attrs['family_default'],
|
389 |
-
'size_default' => $attrs['size_default'],
|
390 |
-
'weight_default' => $attrs['weight_default']
|
391 |
-
]);
|
392 |
-
$this->controls->color($name . '_background');
|
393 |
-
$this->_close();
|
394 |
-
}
|
395 |
-
|
396 |
-
public function button_style($name, $label = '') {
|
397 |
-
|
398 |
-
$this->_open('tnp-font');
|
399 |
-
$this->_label($label);
|
400 |
-
$this->controls->css_font($name . '_font');
|
401 |
-
$this->controls->color($name . '_background_color');
|
402 |
-
$this->_close();
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* URL input field
|
407 |
-
*
|
408 |
-
* @param string $name
|
409 |
-
* @param string $label
|
410 |
-
* @param array $attrs
|
411 |
-
*/
|
412 |
-
public function url($name, $label = '', $attrs = []) {
|
413 |
-
$attrs = $this->_merge_attrs($attrs, ['placeholder' => 'https://...']);
|
414 |
-
$this->_open('tnp-url');
|
415 |
-
$this->_label($label);
|
416 |
-
$this->controls->text_url($name);
|
417 |
-
if (isset($attrs['media'])) {
|
418 |
-
echo '<i class="far fa-folder-open" onclick="tnp_fields_url_select(\'options_', $name, '\')"></i>';
|
419 |
-
}
|
420 |
-
$this->_description($attrs);
|
421 |
-
$this->_close();
|
422 |
-
}
|
423 |
-
|
424 |
-
/**
|
425 |
-
* Provides a list of custom post types.
|
426 |
-
*
|
427 |
-
* @param string $name
|
428 |
-
* @param string $label
|
429 |
-
* @param array $attrs
|
430 |
-
*/
|
431 |
-
public function post_type($name = 'post_type', $label = '', $attrs = []) {
|
432 |
-
|
433 |
-
$post_types = get_post_types(['public' => true], 'objects', 'and');
|
434 |
-
|
435 |
-
$attrs = array_merge(['description' => ''], $attrs);
|
436 |
-
$this->_open('tnp-post-type');
|
437 |
-
$this->_label($label);
|
438 |
-
|
439 |
-
$options = ['post' => 'Standard posts', 'page' => 'Pages'];
|
440 |
-
|
441 |
-
foreach ($post_types as $post_type) {
|
442 |
-
if ($post_type->name == 'post' || $post_type->name == 'page' || $post_type->name == 'attachment') {
|
443 |
-
continue;
|
444 |
-
}
|
445 |
-
$options[$post_type->name] = $post_type->labels->name;
|
446 |
-
}
|
447 |
-
|
448 |
-
$value = $this->controls->get_value($name);
|
449 |
-
|
450 |
-
echo '<select id="', $this->_id($name), '" name="options[' . esc_attr($name) . ']" onchange="tnpc_reload_options(event); return false;">';
|
451 |
-
// if (!empty($first)) {
|
452 |
-
// echo '<option value="">' . esc_html($first) . '</option>';
|
453 |
-
// }
|
454 |
-
$label = esc_html($label);
|
455 |
-
foreach ($options as $key => $label) {
|
456 |
-
echo '<option value="' . esc_attr($key) . '"';
|
457 |
-
if ($value == $key)
|
458 |
-
echo ' selected';
|
459 |
-
echo '>', $label, '</option>';
|
460 |
-
}
|
461 |
-
echo '</select>';
|
462 |
-
|
463 |
-
$this->_description($attrs);
|
464 |
-
$this->_close();
|
465 |
-
}
|
466 |
-
|
467 |
-
function posts($name, $label, $count = 20, $args = []) {
|
468 |
-
$args = array_merge(array('filters' => array(
|
469 |
-
'posts_per_page' => 5,
|
470 |
-
'offset' => 0,
|
471 |
-
'category' => '',
|
472 |
-
'category_name' => '',
|
473 |
-
'orderby' => 'date',
|
474 |
-
'order' => 'DESC',
|
475 |
-
'include' => '',
|
476 |
-
'exclude' => '',
|
477 |
-
'meta_key' => '',
|
478 |
-
'meta_value' => '',
|
479 |
-
'post_type' => 'post',
|
480 |
-
'post_mime_type' => '',
|
481 |
-
'post_parent' => '',
|
482 |
-
'author' => '',
|
483 |
-
'author_name' => '',
|
484 |
-
'post_status' => 'publish',
|
485 |
-
'suppress_filters' => true),
|
486 |
-
'last_post_option' => false
|
487 |
-
), $args);
|
488 |
-
$args['filters']['posts_per_page'] = $count;
|
489 |
-
|
490 |
-
$posts = get_posts($args['filters']);
|
491 |
-
$options = array();
|
492 |
-
if ($args['last_post_option']) {
|
493 |
-
$options['last'] = 'Most recent post';
|
494 |
-
}
|
495 |
-
foreach ($posts as $post) {
|
496 |
-
$options['' . $post->ID] = $post->post_title;
|
497 |
-
}
|
498 |
-
|
499 |
-
$this->select($name, $label, $options);
|
500 |
-
}
|
501 |
-
|
502 |
-
function lists($name, $label, $attrs = []) {
|
503 |
-
$attrs = $this->_merge_attrs($attrs, ['empty_label' => null]);
|
504 |
-
$this->_open();
|
505 |
-
$this->_label($label);
|
506 |
-
$lists = $this->controls->get_list_options($attrs['empty_label']);
|
507 |
-
$this->controls->select($name, $lists);
|
508 |
-
$this->_description($attrs);
|
509 |
-
$this->_close();
|
510 |
-
}
|
511 |
-
|
512 |
-
/**
|
513 |
-
* Media selector using the WP media library (for images and files.
|
514 |
-
* The field to use it the {$name}_id which contains the media id.
|
515 |
-
*
|
516 |
-
* Attributes:
|
517 |
-
* - alt: if true shows the alternate text field for the "alt" attribute
|
518 |
-
* - layout: if set to "mini" the controls is shown as a mini selector, no labels
|
519 |
-
*
|
520 |
-
* @param string $name
|
521 |
-
* @param string $label
|
522 |
-
* @param array $attrs
|
523 |
-
*/
|
524 |
-
public function media($name, $label = '', $attrs = []) {
|
525 |
-
$attrs = $this->_merge_attrs($attrs, ['alt' => false, 'layout' => '']);
|
526 |
-
|
527 |
-
if (empty($attrs['layout'])) {
|
528 |
-
$this->_open('tnp-media');
|
529 |
-
$this->_label($label);
|
530 |
-
$this->controls->media($name);
|
531 |
-
if ($attrs['alt']) {
|
532 |
-
$this->controls->text($name . '_alt', 20, 'Alternative text');
|
533 |
-
}
|
534 |
-
$this->_description($attrs);
|
535 |
-
$this->_close();
|
536 |
-
} else {
|
537 |
-
if (isset($this->controls->data[$name]['id'])) {
|
538 |
-
$media_id = (int) $this->controls->data[$name]['id'];
|
539 |
-
$media = wp_get_attachment_image_src($media_id, 'thumbnail');
|
540 |
-
} else {
|
541 |
-
$media = false;
|
542 |
-
$media_id = 0;
|
543 |
-
}
|
544 |
-
echo '<div class="tnpf-media-mini-select" data-name="' . esc_attr($name) . '" style="width: 100px; height: 100px; overflow: hidden; border: 1px dashed #999; position: relative" onclick="tnp_fields_media_mini_select(this)">';
|
545 |
-
echo '<a style="position: absolute; top: 5px; right: 5px; background-color: #000; color: #fff; padding: 0px 5px 6px 5px; font-size: 24px; display: block; text-decoration: none" href="#" onclick="tnp_fields_media_mini_remove(\'' . esc_attr($name) . '\'); return false;">×</a>';
|
546 |
-
if ($media) {
|
547 |
-
echo '<img style="max-width: 100%; height: auto; display: block" id="' . esc_attr($name) . '_img" src="' . esc_attr($media[0]) . '">';
|
548 |
-
} else {
|
549 |
-
echo '<img style="max-width: 100%; height: auto; display: block" id="' . esc_attr($name) . '_img" src="">';
|
550 |
-
}
|
551 |
-
|
552 |
-
echo '</div>';
|
553 |
-
echo '<input type="hidden" id="' . esc_attr($name) . '_id" name="options[' . esc_attr($name) . '][id]" value="' . esc_attr($media_id) . '">';
|
554 |
-
}
|
555 |
-
}
|
556 |
-
|
557 |
-
public function categories($name = 'categories', $label = '', $attrs = []) {
|
558 |
-
if (empty($label)) {
|
559 |
-
$label = __('Categories', 'newsletter');
|
560 |
-
}
|
561 |
-
$attrs = $this->_merge_attrs($attrs);
|
562 |
-
$this->_open('tnp-categories');
|
563 |
-
$this->_label($label);
|
564 |
-
$this->controls->categories_group($name);
|
565 |
-
$this->_description($attrs);
|
566 |
-
$this->_close();
|
567 |
-
}
|
568 |
-
|
569 |
-
/**
|
570 |
-
* The field name is preset to tax_$taxonomy. A different name can be specified
|
571 |
-
* with the attribute 'name'.
|
572 |
-
* @param type $taxonomy
|
573 |
-
* @param type $label
|
574 |
-
* @param type $attrs
|
575 |
-
*/
|
576 |
-
public function terms($taxonomy, $label = '', $attrs = []) {
|
577 |
-
if (isset($attrs['name'])) {
|
578 |
-
$name = $attrs['name'];
|
579 |
-
} else {
|
580 |
-
$name = 'tax_' . $taxonomy;
|
581 |
-
}
|
582 |
-
if (empty($label)) {
|
583 |
-
$label = __('Terms', 'newsletter');
|
584 |
-
}
|
585 |
-
$attrs = $this->_merge_attrs($attrs);
|
586 |
-
$this->_open('tnp-categories');
|
587 |
-
$this->_label($label);
|
588 |
-
$terms = get_terms($taxonomy);
|
589 |
-
|
590 |
-
if (empty($terms)) {
|
591 |
-
echo 'No terms in use';
|
592 |
-
} else {
|
593 |
-
|
594 |
-
echo '<div class="newsletter-checkboxes-group">';
|
595 |
-
foreach ($terms as $term) {
|
596 |
-
/* @var $term WP_Term */
|
597 |
-
echo '<div class="newsletter-checkboxes-item">';
|
598 |
-
$this->controls->checkbox_group($name, $term->term_id, esc_html($term->name));
|
599 |
-
echo '</div>';
|
600 |
-
}
|
601 |
-
echo '<div style="clear: both"></div>';
|
602 |
-
echo '</div>';
|
603 |
-
}
|
604 |
-
|
605 |
-
$this->_description($attrs);
|
606 |
-
$this->_close();
|
607 |
-
}
|
608 |
-
|
609 |
-
/**
|
610 |
-
* Shows a language selector only if the blog is multilanguage.
|
611 |
-
*
|
612 |
-
* @param string $name
|
613 |
-
* @param string $label
|
614 |
-
* @param array $attrs
|
615 |
-
*/
|
616 |
-
public function language($name = 'language', $label = '', $attrs = []) {
|
617 |
-
if (!Newsletter::instance()->is_multilanguage()) {
|
618 |
-
return;
|
619 |
-
}
|
620 |
-
if (empty($label)) {
|
621 |
-
$label = __('Language', 'newsletter');
|
622 |
-
}
|
623 |
-
$attrs = $this->_merge_attrs($attrs);
|
624 |
-
$this->_open('tnp-language');
|
625 |
-
$this->_label($label);
|
626 |
-
$this->controls->language($name);
|
627 |
-
$this->_description($attrs);
|
628 |
-
$this->_close();
|
629 |
-
}
|
630 |
-
|
631 |
-
/**
|
632 |
-
* Collects font details for a text: family, color, size and weight to be used
|
633 |
-
* directly on CSS rules. Size is a pure number.
|
634 |
-
*
|
635 |
-
* Attributes:
|
636 |
-
* - family: true|false enable or not the font family field
|
637 |
-
* - family_default: true|false enables the default entry with an empty key value
|
638 |
-
* - color: true|false enable or not the color field
|
639 |
-
* - weight: true|false enable or not the weight field
|
640 |
-
* - size: true|false enable or not the size selection
|
641 |
-
*
|
642 |
-
* @param type $name
|
643 |
-
* @param type $label
|
644 |
-
* @param array $attrs
|
645 |
-
*/
|
646 |
-
public function font($name = 'font', $label = 'Font', $attrs = []) {
|
647 |
-
$attrs = $this->_merge_base_attrs($attrs);
|
648 |
-
$attrs = array_merge([
|
649 |
-
'hide_family' => false,
|
650 |
-
'family' => true,
|
651 |
-
'color' => true,
|
652 |
-
'size' => true,
|
653 |
-
'weight' => true,
|
654 |
-
'family_default' => false,
|
655 |
-
'size_default' => false,
|
656 |
-
'weight_default' => false,
|
657 |
-
], $attrs);
|
658 |
-
|
659 |
-
$this->_open('tnp-font');
|
660 |
-
$this->_label($label);
|
661 |
-
|
662 |
-
$this->controls->css_font_family($name . '_family', !empty($attrs['family_default']));
|
663 |
-
|
664 |
-
if ($attrs['size']) {
|
665 |
-
$this->controls->css_font_size($name . '_size', !empty($attrs['size_default']));
|
666 |
-
}
|
667 |
-
if ($attrs['weight']) {
|
668 |
-
$this->controls->css_font_weight($name . '_weight', !empty($attrs['weight_default']));
|
669 |
-
}
|
670 |
-
if ($attrs['color']) {
|
671 |
-
$this->controls->color($name . '_color');
|
672 |
-
}
|
673 |
-
|
674 |
-
$this->_description($attrs);
|
675 |
-
$this->_close();
|
676 |
-
}
|
677 |
-
|
678 |
-
/**
|
679 |
-
* Collects fout number values representing the padding of a box. The values can
|
680 |
-
* be found as {$name}_top, {$name}_bottom, {$name}_left, {$name}_right.
|
681 |
-
*
|
682 |
-
* @param type $name
|
683 |
-
* @param type $label
|
684 |
-
* @param type $attrs
|
685 |
-
*/
|
686 |
-
public function padding($name = 'block_padding', $label = 'Padding', $attrs = []) {
|
687 |
-
$attrs = $this->_merge_base_attrs($attrs);
|
688 |
-
$attrs = array_merge(['padding_top' => 0, 'padding_left' => 0, 'padding_right' => 0, 'padding_bottom' => 0], $attrs);
|
689 |
-
$field_only = !empty($attrs['field_only']);
|
690 |
-
|
691 |
-
if (!$field_only) {
|
692 |
-
$this->_open('tnp-padding');
|
693 |
-
$this->_label($label);
|
694 |
-
}
|
695 |
-
echo '<div class="tnp-padding-fields">';
|
696 |
-
echo '←';
|
697 |
-
$this->controls->text($name . '_left', 5);
|
698 |
-
echo ' ';
|
699 |
-
echo '↑';
|
700 |
-
$this->controls->text($name . '_top', 5);
|
701 |
-
echo ' ';
|
702 |
-
|
703 |
-
$this->controls->text($name . '_bottom', 5);
|
704 |
-
echo '↓';
|
705 |
-
echo ' ';
|
706 |
-
$this->controls->text($name . '_right', 5);
|
707 |
-
echo '→';
|
708 |
-
echo '</div>';
|
709 |
-
if (!$field_only) {
|
710 |
-
$this->_description($attrs);
|
711 |
-
$this->_close();
|
712 |
-
}
|
713 |
-
}
|
714 |
-
|
715 |
-
/**
|
716 |
-
* Background color selector for a block.
|
717 |
-
*/
|
718 |
-
public function block_background() {
|
719 |
-
$this->color('block_background', __('Block Background', 'newsletter'));
|
720 |
-
}
|
721 |
-
|
722 |
-
/**
|
723 |
-
* Padding selector for a block.
|
724 |
-
*/
|
725 |
-
public function block_padding() {
|
726 |
-
$this->padding('block_padding', __('Padding', 'newsletter'));
|
727 |
-
}
|
728 |
-
|
729 |
-
public function block_commons() {
|
730 |
-
|
731 |
-
$this->_open('tnp-block-commons');
|
732 |
-
$this->_label('Padding and background');
|
733 |
-
$this->controls->color('block_background');
|
734 |
-
|
735 |
-
echo ' → ';
|
736 |
-
$this->controls->checkbox('block_background_gradient');
|
737 |
-
$this->controls->color('block_background_2');
|
738 |
-
|
739 |
-
echo ' ';
|
740 |
-
$this->padding('block_padding', '', ['field_only' => true]);
|
741 |
-
echo '<div class="tnp-description">Gradients are displayed only by few clients</div>';
|
742 |
-
$this->_close();
|
743 |
-
}
|
744 |
-
|
745 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class NewsletterFields {
|
4 |
+
/* @var NewsletterControls */
|
5 |
+
|
6 |
+
var $controls;
|
7 |
+
|
8 |
+
public function __construct(NewsletterControls $controls) {
|
9 |
+
$this->controls = $controls;
|
10 |
+
}
|
11 |
+
|
12 |
+
public function _open($subclass = '') {
|
13 |
+
echo '<div class="tnp-field ', $subclass, '">';
|
14 |
+
}
|
15 |
+
|
16 |
+
public function _close() {
|
17 |
+
echo '</div>';
|
18 |
+
}
|
19 |
+
|
20 |
+
public function _label($text, $for = '') {
|
21 |
+
if (empty($text)) {
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
// Do not escape, HTML allowed
|
25 |
+
echo '<label class="tnp-label">', $text, '</label>';
|
26 |
+
}
|
27 |
+
|
28 |
+
public function _description($attrs) {
|
29 |
+
if (empty($attrs['description'])) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
// Do not escape, HTML allowed
|
33 |
+
echo '<div class="tnp-description">', $attrs['description'], '</div>';
|
34 |
+
}
|
35 |
+
|
36 |
+
public function _id($name) {
|
37 |
+
return 'options-' . esc_attr($name);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function _name($name) {
|
41 |
+
return 'options[' . esc_attr($name) . ']';
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Adds some empty basic atributes to avoid the isset() checking.
|
46 |
+
*
|
47 |
+
* @param array $attrs
|
48 |
+
* @return array
|
49 |
+
*/
|
50 |
+
public function _merge_base_attrs($attrs) {
|
51 |
+
return array_merge(['description' => '', 'label' => '', 'help_url' => ''], $attrs);
|
52 |
+
}
|
53 |
+
|
54 |
+
/** Adds some basic attributes and the provided default ones.
|
55 |
+
*
|
56 |
+
* @param array $attrs
|
57 |
+
* @param array $defaults
|
58 |
+
* @return array
|
59 |
+
*/
|
60 |
+
public function _merge_attrs($attrs, $defaults = []) {
|
61 |
+
return array_merge(['description' => '', 'label' => '', 'help_url' => ''], $defaults, $attrs);
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* A form section title.
|
66 |
+
*
|
67 |
+
* @param string $title
|
68 |
+
*/
|
69 |
+
public function section($title = '') {
|
70 |
+
// Do not escape, HTML allowed
|
71 |
+
echo '<h3 class="tnp-section">', $title, '</h3>';
|
72 |
+
}
|
73 |
+
|
74 |
+
public function separator() {
|
75 |
+
echo '<div class="tnp-field tnp-separator"></div>';
|
76 |
+
}
|
77 |
+
|
78 |
+
public function checkbox($name, $label = '', $attrs = []) {
|
79 |
+
$attrs = $this->_merge_base_attrs($attrs);
|
80 |
+
$this->_open('tnp-checkbox');
|
81 |
+
$this->controls->checkbox($name, $label);
|
82 |
+
$this->_description($attrs);
|
83 |
+
$this->_close();
|
84 |
+
}
|
85 |
+
|
86 |
+
/** General Input field with default type = text
|
87 |
+
*
|
88 |
+
* Attributes:
|
89 |
+
* - label_after (default: none): small text ti be displayed after the text field
|
90 |
+
* - min (default: none): minimum number of characters
|
91 |
+
* - max (default: none): maximum number of characters
|
92 |
+
* - size (default: none): size in pixels
|
93 |
+
*/
|
94 |
+
public function input($name, $label = '', $attrs = []) {
|
95 |
+
$attrs = $this->_merge_attrs($attrs, ['placeholder' => '', 'size' => 0, 'label_after' => '', 'type' => 'text']);
|
96 |
+
$this->_open();
|
97 |
+
$this->_label($label);
|
98 |
+
$value = $this->controls->get_value($name);
|
99 |
+
|
100 |
+
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="', esc_attr($attrs['type']), '"';
|
101 |
+
|
102 |
+
if (!empty($attrs['size'])) {
|
103 |
+
echo ' style="width: ', $attrs['size'], 'px"';
|
104 |
+
}
|
105 |
+
|
106 |
+
if (isset($attrs['min'])) {
|
107 |
+
echo ' min="' . (int) $attrs['min'] . '"';
|
108 |
+
}
|
109 |
+
|
110 |
+
if (isset($attrs['max'])) {
|
111 |
+
echo ' max="' . (int) $attrs['max'] . '"';
|
112 |
+
}
|
113 |
+
|
114 |
+
echo ' value="', esc_attr($value), '">';
|
115 |
+
|
116 |
+
if (!empty($attrs['label_after'])) {
|
117 |
+
echo $attrs['label_after'];
|
118 |
+
}
|
119 |
+
|
120 |
+
$this->_description($attrs);
|
121 |
+
$this->_close();
|
122 |
+
}
|
123 |
+
|
124 |
+
public function text($name, $label = '', $attrs = []) {
|
125 |
+
$attrs['type'] = 'text';
|
126 |
+
$this->input($name, $label, $attrs);
|
127 |
+
}
|
128 |
+
|
129 |
+
public function text_on_off($name, $label = '', $attrs = []) {
|
130 |
+
$attrs = $this->_merge_attrs($attrs, ['placeholder' => '', 'size' => 0, 'label_after' => '', 'type' => 'text']);
|
131 |
+
$this->_open();
|
132 |
+
$this->_label($label);
|
133 |
+
$value = $this->controls->get_value($name);
|
134 |
+
|
135 |
+
echo '<input type="hidden" name="tnp_fields[' . esc_attr($name . '_enabled') . ']" value="checkbox">';
|
136 |
+
echo '<input id="', $this->_id($name . '_enabled'), '" name="', $this->_name($name . '_enabled'), '" type="checkbox" value="1"';
|
137 |
+
if (!empty($this->controls->get_value($name . '_enabled'))) {
|
138 |
+
echo ' checked';
|
139 |
+
}
|
140 |
+
echo '> ';
|
141 |
+
|
142 |
+
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="text"';
|
143 |
+
|
144 |
+
echo ' style="width: 90%;"';
|
145 |
+
|
146 |
+
if (isset($attrs['min'])) {
|
147 |
+
echo ' min="' . (int) $attrs['min'] . '"';
|
148 |
+
}
|
149 |
+
|
150 |
+
if (isset($attrs['max'])) {
|
151 |
+
echo ' max="' . (int) $attrs['max'] . '"';
|
152 |
+
}
|
153 |
+
|
154 |
+
echo ' value="', esc_attr($value), '">';
|
155 |
+
|
156 |
+
if (!empty($attrs['label_after'])) {
|
157 |
+
echo $attrs['label_after'];
|
158 |
+
}
|
159 |
+
|
160 |
+
$this->_description($attrs);
|
161 |
+
$this->_close();
|
162 |
+
}
|
163 |
+
|
164 |
+
public function number($name, $label = '', $attrs = []) {
|
165 |
+
$attrs = array_merge(['type' => 'number'], $attrs);
|
166 |
+
$this->input($name, $label, $attrs);
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* A set of text fields, named $name_1, $name_2, ...
|
171 |
+
*
|
172 |
+
* Attributes:
|
173 |
+
* - label_after: a label to show after the field column
|
174 |
+
*
|
175 |
+
* @param type $name
|
176 |
+
* @param type $label
|
177 |
+
* @param type $count
|
178 |
+
* @param type $attrs
|
179 |
+
*/
|
180 |
+
public function multitext($name, $label = '', $count = 10, $attrs = []) {
|
181 |
+
$attrs = $this->_merge_attrs($attrs, ['description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => '']);
|
182 |
+
$this->_open();
|
183 |
+
$this->_label($label);
|
184 |
+
|
185 |
+
for ($i = 1; $i <= $count; $i++) {
|
186 |
+
$value = $this->controls->get_value($name . '_' . $i);
|
187 |
+
echo '<input id="', $this->_id($name . '_' . $i), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name, '_', $i, ']" type="text"';
|
188 |
+
if (!empty($attrs['size'])) {
|
189 |
+
echo ' style="width: ', $attrs['size'], 'px"';
|
190 |
+
}
|
191 |
+
echo ' value="', esc_attr($value), '">';
|
192 |
+
}
|
193 |
+
if (!empty($attrs['label_after'])) {
|
194 |
+
echo $attrs['label_after'];
|
195 |
+
}
|
196 |
+
$this->_description($attrs);
|
197 |
+
$this->_close();
|
198 |
+
}
|
199 |
+
|
200 |
+
public function textarea($name, $label = '', $attrs = []) {
|
201 |
+
$attrs = $this->_merge_attrs($attrs, ['width' => '100%', 'height' => '150']);
|
202 |
+
$this->_open();
|
203 |
+
$this->_label($label);
|
204 |
+
$this->controls->textarea_fixed($name, $attrs['width'], $attrs['height']);
|
205 |
+
$this->_description($attrs);
|
206 |
+
$this->_close();
|
207 |
+
}
|
208 |
+
|
209 |
+
public function wp_editor($name, $label = '', $attrs = []) {
|
210 |
+
global $wp_version;
|
211 |
+
|
212 |
+
$attrs = $this->_merge_attrs($attrs);
|
213 |
+
$this->_open();
|
214 |
+
$this->_label($label);
|
215 |
+
$value = $this->controls->get_value($name);
|
216 |
+
$name = esc_attr($name);
|
217 |
+
|
218 |
+
// Uhm...
|
219 |
+
if (is_array($value)) {
|
220 |
+
$value = implode("\n", $value);
|
221 |
+
}
|
222 |
+
if (version_compare($wp_version, '4.8', '<')) {
|
223 |
+
echo '<p><strong>Rich editor available only with WP 4.8+</strong></p>';
|
224 |
+
}
|
225 |
+
echo '<textarea class="tnpf-wp-editor" id="options-', $name, '" name="options[', $name, ']" style="width: 100%;height:250px">';
|
226 |
+
echo esc_html($value);
|
227 |
+
echo '</textarea>';
|
228 |
+
|
229 |
+
if (version_compare($wp_version, '4.8', '>=')) {
|
230 |
+
|
231 |
+
$paragraph_style = " p { font-family: ${attrs['text_font_family']}; font-size: ${attrs['text_font_size']}px; font-weight: ${attrs['text_font_weight']}; color: ${attrs['text_font_color']}; line-height: 1.5em; }";
|
232 |
+
$content_style = $paragraph_style;
|
233 |
+
|
234 |
+
echo '<script>';
|
235 |
+
echo 'wp.editor.remove("options-', $name, '");';
|
236 |
+
echo 'wp.editor.initialize("options-', $name, '", { tinymce: {content_style: "' . $content_style . '", toolbar1: "undo redo | formatselect fontselect fontsizeselect | bold italic forecolor backcolor | link unlink | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | wp_add_media | charmap | rtl ltr", fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px", plugins: "link textcolor colorpicker lists wordpress charmap directionality", default_link_target: "_blank", relative_urls : false, convert_urls: false, keep_styles: true }});';
|
237 |
+
echo '</script>';
|
238 |
+
}
|
239 |
+
$this->_description($attrs);
|
240 |
+
$this->_close();
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Attributes:
|
245 |
+
* - realod: when true is forces a submit of the form (used to change the form fields or values for example when changing layout or color scheme)
|
246 |
+
*
|
247 |
+
* @param type $name
|
248 |
+
* @param type $label
|
249 |
+
* @param type $options
|
250 |
+
* @param type $attrs
|
251 |
+
*/
|
252 |
+
public function select($name, $label = '', $options = [], $attrs = []) {
|
253 |
+
$attrs = $this->_merge_attrs($attrs, ['reload' => false, 'after-rendering' => '', 'class' => '']);
|
254 |
+
$this->_open();
|
255 |
+
$this->_label($label);
|
256 |
+
$value = $this->controls->get_value($name);
|
257 |
+
|
258 |
+
echo '<select id="', $this->_id($name), '" name="', $this->_name($name), '"';
|
259 |
+
if ($attrs['class']) {
|
260 |
+
echo ' class="', esc_attr($attrs['class']), '"';
|
261 |
+
}
|
262 |
+
if ($attrs['reload']) {
|
263 |
+
echo ' onchange="tnpc_reload_options(event)"';
|
264 |
+
}
|
265 |
+
if (!empty($attrs['after-rendering'])) {
|
266 |
+
echo ' data-after-rendering="', $attrs['after-rendering'], '"';
|
267 |
+
}
|
268 |
+
echo '>';
|
269 |
+
// if (!empty($first)) {
|
270 |
+
// echo '<option value="">', esc_html($first), '</option>';
|
271 |
+
// }
|
272 |
+
|
273 |
+
foreach ($options as $key => $text) {
|
274 |
+
echo '<option value="', esc_attr($key), '"';
|
275 |
+
if ($value == $key) {
|
276 |
+
echo ' selected';
|
277 |
+
}
|
278 |
+
echo '>', esc_html($text), '</option>';
|
279 |
+
}
|
280 |
+
echo '</select>';
|
281 |
+
|
282 |
+
$this->_description($attrs);
|
283 |
+
$this->_close();
|
284 |
+
}
|
285 |
+
|
286 |
+
public function align($name = 'align') {
|
287 |
+
$this->select($name,
|
288 |
+
__('Align', 'newsletter'),
|
289 |
+
['center' => __('Center', 'newsletter'), 'left' => __('Left', 'newsletter'), 'right' => __('Right')]
|
290 |
+
);
|
291 |
+
}
|
292 |
+
|
293 |
+
public function yesno($name, $label = '', $attrs = []) {
|
294 |
+
$attrs = $this->_merge_attrs($attrs);
|
295 |
+
$this->_open();
|
296 |
+
$this->_label($label);
|
297 |
+
$this->controls->yesno($name);
|
298 |
+
$this->_description($attrs);
|
299 |
+
$this->_close();
|
300 |
+
}
|
301 |
+
|
302 |
+
public function select_number($name, $label = '', $min = 0, $max = 10, $attrs = []) {
|
303 |
+
$attrs = $this->_merge_attrs($attrs);
|
304 |
+
$this->_open();
|
305 |
+
$this->_label($label);
|
306 |
+
$this->controls->select_number($name, $min, $max);
|
307 |
+
$this->_description($attrs);
|
308 |
+
$this->_close();
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* General field to collect an element dimension in pixels
|
313 |
+
*
|
314 |
+
* Attributes:
|
315 |
+
* - size: field width in pixels
|
316 |
+
*/
|
317 |
+
public function size($name, $label = '', $attrs = []) {
|
318 |
+
$attrs = $this->_merge_attrs($attrs, ['description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => 'px']);
|
319 |
+
$this->_open('tnp-size');
|
320 |
+
$this->_label($label);
|
321 |
+
$value = $this->controls->get_value($name);
|
322 |
+
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="', $this->_name($name), '" type="text"';
|
323 |
+
if (!empty($attrs['size'])) {
|
324 |
+
echo ' style="width: ', $attrs['size'], 'px"';
|
325 |
+
}
|
326 |
+
echo ' value="', esc_attr($value), '">', $attrs['label_after'];
|
327 |
+
$this->_description($attrs);
|
328 |
+
$this->_close();
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Collects a color in HEX format with a picker.
|
333 |
+
*/
|
334 |
+
public function color($name, $label, $attrs = []) {
|
335 |
+
$this->_open('tnp-color');
|
336 |
+
$this->_label($label);
|
337 |
+
$this->controls->color($name);
|
338 |
+
$this->_description($attrs);
|
339 |
+
$this->_close();
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Configuration for a simple button with label and color
|
344 |
+
*
|
345 |
+
* Attributes:
|
346 |
+
* - weight: if true (default) shows the font weight selector
|
347 |
+
* - url_paceholder: the placeholder for the URL field
|
348 |
+
* - url: if true (default) shows the URL field (sometime the URL is produced elsewhere, for example on post list)
|
349 |
+
*/
|
350 |
+
public function button($name, $label = '', $attrs = []) {
|
351 |
+
$attrs = $this->_merge_attrs($attrs,
|
352 |
+
[
|
353 |
+
'placeholder' => 'Label...',
|
354 |
+
'url_placeholder' => 'https://...',
|
355 |
+
'url' => true,
|
356 |
+
'weight' => true,
|
357 |
+
'family_default' => false,
|
358 |
+
'size_default' => false,
|
359 |
+
'weight_default' => false,
|
360 |
+
]);
|
361 |
+
|
362 |
+
$this->_open('tnpf-button');
|
363 |
+
$this->_label($label);
|
364 |
+
$value = $this->controls->get_value($name . '_label');
|
365 |
+
$name_esc = esc_attr($name);
|
366 |
+
echo '<div class="tnp-field-row">';
|
367 |
+
echo '<div class="tnp-field-col-2">';
|
368 |
+
echo '<input id="', $this->_id($name . '_label'), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name_esc, '_label]" type="text"';
|
369 |
+
echo ' style="width: 100%"';
|
370 |
+
echo ' value="', esc_attr($value), '">';
|
371 |
+
echo '</div>';
|
372 |
+
|
373 |
+
if ($attrs['url']) {
|
374 |
+
$value = $this->controls->get_value($name . '_url');
|
375 |
+
echo '<div class="tnp-field-col-2">';
|
376 |
+
$width = isset($attrs['media']) ? '90%' : '100%';
|
377 |
+
echo '<input id="', $this->_id($name . '_url'), '" placeholder="', esc_attr($attrs['url_placeholder']), '" name="options[',
|
378 |
+
$name_esc, '_url]" type="url" style="width: ', $width, '" value="', esc_attr($value), '">';
|
379 |
+
if (isset($attrs['media'])) {
|
380 |
+
echo ' <i class="far fa-folder-open" data-field="', $this->_id($name . '_url'), '" onclick="tnp_fields_url_select(this)"></i>';
|
381 |
+
}
|
382 |
+
echo '</div>';
|
383 |
+
}
|
384 |
+
echo '<div style="clear: both"></div>';
|
385 |
+
echo '</div>';
|
386 |
+
$this->controls->css_font($name . '_font', [
|
387 |
+
'weight' => $attrs['weight'],
|
388 |
+
'family_default' => $attrs['family_default'],
|
389 |
+
'size_default' => $attrs['size_default'],
|
390 |
+
'weight_default' => $attrs['weight_default']
|
391 |
+
]);
|
392 |
+
$this->controls->color($name . '_background');
|
393 |
+
$this->_close();
|
394 |
+
}
|
395 |
+
|
396 |
+
public function button_style($name, $label = '') {
|
397 |
+
|
398 |
+
$this->_open('tnp-font');
|
399 |
+
$this->_label($label);
|
400 |
+
$this->controls->css_font($name . '_font');
|
401 |
+
$this->controls->color($name . '_background_color');
|
402 |
+
$this->_close();
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* URL input field
|
407 |
+
*
|
408 |
+
* @param string $name
|
409 |
+
* @param string $label
|
410 |
+
* @param array $attrs
|
411 |
+
*/
|
412 |
+
public function url($name, $label = '', $attrs = []) {
|
413 |
+
$attrs = $this->_merge_attrs($attrs, ['placeholder' => 'https://...']);
|
414 |
+
$this->_open('tnp-url');
|
415 |
+
$this->_label($label);
|
416 |
+
$this->controls->text_url($name);
|
417 |
+
if (isset($attrs['media'])) {
|
418 |
+
echo '<i class="far fa-folder-open" onclick="tnp_fields_url_select(\'options_', $name, '\')"></i>';
|
419 |
+
}
|
420 |
+
$this->_description($attrs);
|
421 |
+
$this->_close();
|
422 |
+
}
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Provides a list of custom post types.
|
426 |
+
*
|
427 |
+
* @param string $name
|
428 |
+
* @param string $label
|
429 |
+
* @param array $attrs
|
430 |
+
*/
|
431 |
+
public function post_type($name = 'post_type', $label = '', $attrs = []) {
|
432 |
+
|
433 |
+
$post_types = get_post_types(['public' => true], 'objects', 'and');
|
434 |
+
|
435 |
+
$attrs = array_merge(['description' => ''], $attrs);
|
436 |
+
$this->_open('tnp-post-type');
|
437 |
+
$this->_label($label);
|
438 |
+
|
439 |
+
$options = ['post' => 'Standard posts', 'page' => 'Pages'];
|
440 |
+
|
441 |
+
foreach ($post_types as $post_type) {
|
442 |
+
if ($post_type->name == 'post' || $post_type->name == 'page' || $post_type->name == 'attachment') {
|
443 |
+
continue;
|
444 |
+
}
|
445 |
+
$options[$post_type->name] = $post_type->labels->name;
|
446 |
+
}
|
447 |
+
|
448 |
+
$value = $this->controls->get_value($name);
|
449 |
+
|
450 |
+
echo '<select id="', $this->_id($name), '" name="options[' . esc_attr($name) . ']" onchange="tnpc_reload_options(event); return false;">';
|
451 |
+
// if (!empty($first)) {
|
452 |
+
// echo '<option value="">' . esc_html($first) . '</option>';
|
453 |
+
// }
|
454 |
+
$label = esc_html($label);
|
455 |
+
foreach ($options as $key => $label) {
|
456 |
+
echo '<option value="' . esc_attr($key) . '"';
|
457 |
+
if ($value == $key)
|
458 |
+
echo ' selected';
|
459 |
+
echo '>', $label, '</option>';
|
460 |
+
}
|
461 |
+
echo '</select>';
|
462 |
+
|
463 |
+
$this->_description($attrs);
|
464 |
+
$this->_close();
|
465 |
+
}
|
466 |
+
|
467 |
+
function posts($name, $label, $count = 20, $args = []) {
|
468 |
+
$args = array_merge(array('filters' => array(
|
469 |
+
'posts_per_page' => 5,
|
470 |
+
'offset' => 0,
|
471 |
+
'category' => '',
|
472 |
+
'category_name' => '',
|
473 |
+
'orderby' => 'date',
|
474 |
+
'order' => 'DESC',
|
475 |
+
'include' => '',
|
476 |
+
'exclude' => '',
|
477 |
+
'meta_key' => '',
|
478 |
+
'meta_value' => '',
|
479 |
+
'post_type' => 'post',
|
480 |
+
'post_mime_type' => '',
|
481 |
+
'post_parent' => '',
|
482 |
+
'author' => '',
|
483 |
+
'author_name' => '',
|
484 |
+
'post_status' => 'publish',
|
485 |
+
'suppress_filters' => true),
|
486 |
+
'last_post_option' => false
|
487 |
+
), $args);
|
488 |
+
$args['filters']['posts_per_page'] = $count;
|
489 |
+
|
490 |
+
$posts = get_posts($args['filters']);
|
491 |
+
$options = array();
|
492 |
+
if ($args['last_post_option']) {
|
493 |
+
$options['last'] = 'Most recent post';
|
494 |
+
}
|
495 |
+
foreach ($posts as $post) {
|
496 |
+
$options['' . $post->ID] = $post->post_title;
|
497 |
+
}
|
498 |
+
|
499 |
+
$this->select($name, $label, $options);
|
500 |
+
}
|
501 |
+
|
502 |
+
function lists($name, $label, $attrs = []) {
|
503 |
+
$attrs = $this->_merge_attrs($attrs, ['empty_label' => null]);
|
504 |
+
$this->_open();
|
505 |
+
$this->_label($label);
|
506 |
+
$lists = $this->controls->get_list_options($attrs['empty_label']);
|
507 |
+
$this->controls->select($name, $lists);
|
508 |
+
$this->_description($attrs);
|
509 |
+
$this->_close();
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Media selector using the WP media library (for images and files.
|
514 |
+
* The field to use it the {$name}_id which contains the media id.
|
515 |
+
*
|
516 |
+
* Attributes:
|
517 |
+
* - alt: if true shows the alternate text field for the "alt" attribute
|
518 |
+
* - layout: if set to "mini" the controls is shown as a mini selector, no labels
|
519 |
+
*
|
520 |
+
* @param string $name
|
521 |
+
* @param string $label
|
522 |
+
* @param array $attrs
|
523 |
+
*/
|
524 |
+
public function media($name, $label = '', $attrs = []) {
|
525 |
+
$attrs = $this->_merge_attrs($attrs, ['alt' => false, 'layout' => '']);
|
526 |
+
|
527 |
+
if (empty($attrs['layout'])) {
|
528 |
+
$this->_open('tnp-media');
|
529 |
+
$this->_label($label);
|
530 |
+
$this->controls->media($name);
|
531 |
+
if ($attrs['alt']) {
|
532 |
+
$this->controls->text($name . '_alt', 20, 'Alternative text');
|
533 |
+
}
|
534 |
+
$this->_description($attrs);
|
535 |
+
$this->_close();
|
536 |
+
} else {
|
537 |
+
if (isset($this->controls->data[$name]['id'])) {
|
538 |
+
$media_id = (int) $this->controls->data[$name]['id'];
|
539 |
+
$media = wp_get_attachment_image_src($media_id, 'thumbnail');
|
540 |
+
} else {
|
541 |
+
$media = false;
|
542 |
+
$media_id = 0;
|
543 |
+
}
|
544 |
+
echo '<div class="tnpf-media-mini-select" data-name="' . esc_attr($name) . '" style="width: 100px; height: 100px; overflow: hidden; border: 1px dashed #999; position: relative" onclick="tnp_fields_media_mini_select(this)">';
|
545 |
+
echo '<a style="position: absolute; top: 5px; right: 5px; background-color: #000; color: #fff; padding: 0px 5px 6px 5px; font-size: 24px; display: block; text-decoration: none" href="#" onclick="tnp_fields_media_mini_remove(\'' . esc_attr($name) . '\'); return false;">×</a>';
|
546 |
+
if ($media) {
|
547 |
+
echo '<img style="max-width: 100%; height: auto; display: block" id="' . esc_attr($name) . '_img" src="' . esc_attr($media[0]) . '">';
|
548 |
+
} else {
|
549 |
+
echo '<img style="max-width: 100%; height: auto; display: block" id="' . esc_attr($name) . '_img" src="">';
|
550 |
+
}
|
551 |
+
|
552 |
+
echo '</div>';
|
553 |
+
echo '<input type="hidden" id="' . esc_attr($name) . '_id" name="options[' . esc_attr($name) . '][id]" value="' . esc_attr($media_id) . '">';
|
554 |
+
}
|
555 |
+
}
|
556 |
+
|
557 |
+
public function categories($name = 'categories', $label = '', $attrs = []) {
|
558 |
+
if (empty($label)) {
|
559 |
+
$label = __('Categories', 'newsletter');
|
560 |
+
}
|
561 |
+
$attrs = $this->_merge_attrs($attrs);
|
562 |
+
$this->_open('tnp-categories');
|
563 |
+
$this->_label($label);
|
564 |
+
$this->controls->categories_group($name);
|
565 |
+
$this->_description($attrs);
|
566 |
+
$this->_close();
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* The field name is preset to tax_$taxonomy. A different name can be specified
|
571 |
+
* with the attribute 'name'.
|
572 |
+
* @param type $taxonomy
|
573 |
+
* @param type $label
|
574 |
+
* @param type $attrs
|
575 |
+
*/
|
576 |
+
public function terms($taxonomy, $label = '', $attrs = []) {
|
577 |
+
if (isset($attrs['name'])) {
|
578 |
+
$name = $attrs['name'];
|
579 |
+
} else {
|
580 |
+
$name = 'tax_' . $taxonomy;
|
581 |
+
}
|
582 |
+
if (empty($label)) {
|
583 |
+
$label = __('Terms', 'newsletter');
|
584 |
+
}
|
585 |
+
$attrs = $this->_merge_attrs($attrs);
|
586 |
+
$this->_open('tnp-categories');
|
587 |
+
$this->_label($label);
|
588 |
+
$terms = get_terms($taxonomy);
|
589 |
+
|
590 |
+
if (empty($terms)) {
|
591 |
+
echo 'No terms in use';
|
592 |
+
} else {
|
593 |
+
|
594 |
+
echo '<div class="newsletter-checkboxes-group">';
|
595 |
+
foreach ($terms as $term) {
|
596 |
+
/* @var $term WP_Term */
|
597 |
+
echo '<div class="newsletter-checkboxes-item">';
|
598 |
+
$this->controls->checkbox_group($name, $term->term_id, esc_html($term->name));
|
599 |
+
echo '</div>';
|
600 |
+
}
|
601 |
+
echo '<div style="clear: both"></div>';
|
602 |
+
echo '</div>';
|
603 |
+
}
|
604 |
+
|
605 |
+
$this->_description($attrs);
|
606 |
+
$this->_close();
|
607 |
+
}
|
608 |
+
|
609 |
+
/**
|
610 |
+
* Shows a language selector only if the blog is multilanguage.
|
611 |
+
*
|
612 |
+
* @param string $name
|
613 |
+
* @param string $label
|
614 |
+
* @param array $attrs
|
615 |
+
*/
|
616 |
+
public function language($name = 'language', $label = '', $attrs = []) {
|
617 |
+
if (!Newsletter::instance()->is_multilanguage()) {
|
618 |
+
return;
|
619 |
+
}
|
620 |
+
if (empty($label)) {
|
621 |
+
$label = __('Language', 'newsletter');
|
622 |
+
}
|
623 |
+
$attrs = $this->_merge_attrs($attrs);
|
624 |
+
$this->_open('tnp-language');
|
625 |
+
$this->_label($label);
|
626 |
+
$this->controls->language($name);
|
627 |
+
$this->_description($attrs);
|
628 |
+
$this->_close();
|
629 |
+
}
|
630 |
+
|
631 |
+
/**
|
632 |
+
* Collects font details for a text: family, color, size and weight to be used
|
633 |
+
* directly on CSS rules. Size is a pure number.
|
634 |
+
*
|
635 |
+
* Attributes:
|
636 |
+
* - family: true|false enable or not the font family field
|
637 |
+
* - family_default: true|false enables the default entry with an empty key value
|
638 |
+
* - color: true|false enable or not the color field
|
639 |
+
* - weight: true|false enable or not the weight field
|
640 |
+
* - size: true|false enable or not the size selection
|
641 |
+
*
|
642 |
+
* @param type $name
|
643 |
+
* @param type $label
|
644 |
+
* @param array $attrs
|
645 |
+
*/
|
646 |
+
public function font($name = 'font', $label = 'Font', $attrs = []) {
|
647 |
+
$attrs = $this->_merge_base_attrs($attrs);
|
648 |
+
$attrs = array_merge([
|
649 |
+
'hide_family' => false,
|
650 |
+
'family' => true,
|
651 |
+
'color' => true,
|
652 |
+
'size' => true,
|
653 |
+
'weight' => true,
|
654 |
+
'family_default' => false,
|
655 |
+
'size_default' => false,
|
656 |
+
'weight_default' => false,
|
657 |
+
], $attrs);
|
658 |
+
|
659 |
+
$this->_open('tnp-font');
|
660 |
+
$this->_label($label);
|
661 |
+
|
662 |
+
$this->controls->css_font_family($name . '_family', !empty($attrs['family_default']));
|
663 |
+
|
664 |
+
if ($attrs['size']) {
|
665 |
+
$this->controls->css_font_size($name . '_size', !empty($attrs['size_default']));
|
666 |
+
}
|
667 |
+
if ($attrs['weight']) {
|
668 |
+
$this->controls->css_font_weight($name . '_weight', !empty($attrs['weight_default']));
|
669 |
+
}
|
670 |
+
if ($attrs['color']) {
|
671 |
+
$this->controls->color($name . '_color');
|
672 |
+
}
|
673 |
+
|
674 |
+
$this->_description($attrs);
|
675 |
+
$this->_close();
|
676 |
+
}
|
677 |
+
|
678 |
+
/**
|
679 |
+
* Collects fout number values representing the padding of a box. The values can
|
680 |
+
* be found as {$name}_top, {$name}_bottom, {$name}_left, {$name}_right.
|
681 |
+
*
|
682 |
+
* @param type $name
|
683 |
+
* @param type $label
|
684 |
+
* @param type $attrs
|
685 |
+
*/
|
686 |
+
public function padding($name = 'block_padding', $label = 'Padding', $attrs = []) {
|
687 |
+
$attrs = $this->_merge_base_attrs($attrs);
|
688 |
+
$attrs = array_merge(['padding_top' => 0, 'padding_left' => 0, 'padding_right' => 0, 'padding_bottom' => 0], $attrs);
|
689 |
+
$field_only = !empty($attrs['field_only']);
|
690 |
+
|
691 |
+
if (!$field_only) {
|
692 |
+
$this->_open('tnp-padding');
|
693 |
+
$this->_label($label);
|
694 |
+
}
|
695 |
+
echo '<div class="tnp-padding-fields">';
|
696 |
+
echo '←';
|
697 |
+
$this->controls->text($name . '_left', 5);
|
698 |
+
echo ' ';
|
699 |
+
echo '↑';
|
700 |
+
$this->controls->text($name . '_top', 5);
|
701 |
+
echo ' ';
|
702 |
+
|
703 |
+
$this->controls->text($name . '_bottom', 5);
|
704 |
+
echo '↓';
|
705 |
+
echo ' ';
|
706 |
+
$this->controls->text($name . '_right', 5);
|
707 |
+
echo '→';
|
708 |
+
echo '</div>';
|
709 |
+
if (!$field_only) {
|
710 |
+
$this->_description($attrs);
|
711 |
+
$this->_close();
|
712 |
+
}
|
713 |
+
}
|
714 |
+
|
715 |
+
/**
|
716 |
+
* Background color selector for a block.
|
717 |
+
*/
|
718 |
+
public function block_background() {
|
719 |
+
$this->color('block_background', __('Block Background', 'newsletter'));
|
720 |
+
}
|
721 |
+
|
722 |
+
/**
|
723 |
+
* Padding selector for a block.
|
724 |
+
*/
|
725 |
+
public function block_padding() {
|
726 |
+
$this->padding('block_padding', __('Padding', 'newsletter'));
|
727 |
+
}
|
728 |
+
|
729 |
+
public function block_commons() {
|
730 |
+
|
731 |
+
$this->_open('tnp-block-commons');
|
732 |
+
$this->_label('Padding and background');
|
733 |
+
$this->controls->color('block_background');
|
734 |
+
|
735 |
+
echo ' → ';
|
736 |
+
$this->controls->checkbox('block_background_gradient');
|
737 |
+
$this->controls->color('block_background_2');
|
738 |
+
|
739 |
+
echo ' ';
|
740 |
+
$this->padding('block_padding', '', ['field_only' => true]);
|
741 |
+
echo '<div class="tnp-description">Gradients are displayed only by few clients</div>';
|
742 |
+
$this->_close();
|
743 |
+
}
|
744 |
+
|
745 |
+
}
|
includes/system.php
ADDED
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
+
class NewsletterSystem {
|
6 |
+
|
7 |
+
static $instance;
|
8 |
+
|
9 |
+
const JOB_OK = 0;
|
10 |
+
const JOB_MISSING = 2;
|
11 |
+
const JOB_LATE = 1;
|
12 |
+
const JOB_SKIPPED = 3;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return NewsletterSystem
|
16 |
+
*/
|
17 |
+
static function instance() {
|
18 |
+
if (self::$instance == null) {
|
19 |
+
self::$instance = new NewsletterSystem();
|
20 |
+
}
|
21 |
+
return self::$instance;
|
22 |
+
}
|
23 |
+
|
24 |
+
function __construct() {
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
function reset_cron_stats() {
|
29 |
+
update_option('newsletter_diagnostic_cron_calls', [], false);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
*
|
34 |
+
* @param type $calls
|
35 |
+
* @return \TNP_Cron_Stats
|
36 |
+
*/
|
37 |
+
function get_cron_stats() {
|
38 |
+
$calls = get_option('newsletter_diagnostic_cron_calls', []);
|
39 |
+
|
40 |
+
// Not enough data
|
41 |
+
if (count($calls) < 12) {
|
42 |
+
return null;
|
43 |
+
}
|
44 |
+
|
45 |
+
$stats = new TNP_Cron_Stats();
|
46 |
+
|
47 |
+
for ($i = 1; $i < count($calls); $i++) {
|
48 |
+
$delta = $calls[$i] - $calls[$i - 1];
|
49 |
+
$stats->deltas[] = $delta;
|
50 |
+
if ($stats->min > $delta) {
|
51 |
+
$stats->min = $delta;
|
52 |
+
}
|
53 |
+
if ($stats->max < $delta) {
|
54 |
+
$stats->max = $delta;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
$stats->avg = round(array_sum($stats->deltas) / count($stats->deltas));
|
58 |
+
$stats->good = $stats->avg < NEWSLETTER_CRON_INTERVAL * 1.1; // 10% error
|
59 |
+
return $stats;
|
60 |
+
}
|
61 |
+
|
62 |
+
function get_last_cron_call() {
|
63 |
+
$calls = get_option('newsletter_diagnostic_cron_calls', []);
|
64 |
+
if (empty($calls))
|
65 |
+
return 0;
|
66 |
+
return end($calls);
|
67 |
+
}
|
68 |
+
|
69 |
+
function has_newsletter_schedule() {
|
70 |
+
$schedules = wp_get_schedules();
|
71 |
+
if (!empty($schedules)) {
|
72 |
+
foreach ($schedules as $key => $data) {
|
73 |
+
if ($key == 'newsletter') {
|
74 |
+
return true;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
return false;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
*
|
83 |
+
* @return boolean|int
|
84 |
+
*/
|
85 |
+
function get_job_delay() {
|
86 |
+
$x = wp_next_scheduled('newsletter');
|
87 |
+
return $x === false ? false : time() - $x;
|
88 |
+
}
|
89 |
+
|
90 |
+
function get_job_schedule() {
|
91 |
+
return wp_next_scheduled('newsletter');
|
92 |
+
}
|
93 |
+
|
94 |
+
function get_cache_job_status($refresh = false) {
|
95 |
+
$status = get_transient('newsletter_job_status');
|
96 |
+
if ($status === false || $refresh) {
|
97 |
+
$status = $this->get_job_status();
|
98 |
+
set_transient('newsletter_job_status', $status, DAY_IN_SECONDS);
|
99 |
+
}
|
100 |
+
return $status;
|
101 |
+
}
|
102 |
+
|
103 |
+
function get_job_status() {
|
104 |
+
|
105 |
+
$x = wp_next_scheduled('newsletter');
|
106 |
+
if ($x === false) {
|
107 |
+
return self::JOB_MISSING;
|
108 |
+
}
|
109 |
+
|
110 |
+
// Special case: the scheduler has been triggered but the job not executed
|
111 |
+
$calls = get_option('newsletter_diagnostic_cron_calls', []);
|
112 |
+
if (!empty($calls)) {
|
113 |
+
$last = end($calls);
|
114 |
+
if ($last > $x) {
|
115 |
+
return self::JOB_SKIPPED;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
if (time() - $x > 900) {
|
120 |
+
return self::JOB_LATE;
|
121 |
+
}
|
122 |
+
return self::JOB_OK;
|
123 |
+
}
|
124 |
+
|
125 |
+
function reset_send_stats() {
|
126 |
+
update_option('newsletter_diagnostic_send_calls', [], false);
|
127 |
+
}
|
128 |
+
|
129 |
+
function get_send_stats() {
|
130 |
+
// Send calls stats
|
131 |
+
$send_calls = get_option('newsletter_diagnostic_send_calls', []);
|
132 |
+
if (!$send_calls) {
|
133 |
+
return null;
|
134 |
+
}
|
135 |
+
$send_max = 0;
|
136 |
+
$send_min = PHP_INT_MAX;
|
137 |
+
$send_total_time = 0;
|
138 |
+
$send_total_emails = 0;
|
139 |
+
$send_completed = 0;
|
140 |
+
$stats = new TNP_Send_stats();
|
141 |
+
|
142 |
+
// Batches
|
143 |
+
for ($i = 0; $i < count($send_calls); $i++) {
|
144 |
+
// 0 - batch start time
|
145 |
+
// 1 - batch end time
|
146 |
+
// 2 - number of sent email in this batch
|
147 |
+
// 3 - 0: prematurely stopped, 1: completed
|
148 |
+
if (empty($send_calls[$i][2])) {
|
149 |
+
continue;
|
150 |
+
}
|
151 |
+
if ($send_calls[$i][2] <= 1) {
|
152 |
+
continue;
|
153 |
+
}
|
154 |
+
|
155 |
+
$delta = $send_calls[$i][1] - $send_calls[$i][0];
|
156 |
+
$send_total_time += $delta;
|
157 |
+
$send_total_emails += $send_calls[$i][2];
|
158 |
+
|
159 |
+
$send_mean = $delta / $send_calls[$i][2];
|
160 |
+
$stats->means[] = $send_mean;
|
161 |
+
$stats->sizes[] = $send_calls[$i][2];
|
162 |
+
if ($send_min > $send_mean) {
|
163 |
+
$send_min = $send_mean;
|
164 |
+
}
|
165 |
+
if ($send_max < $send_mean) {
|
166 |
+
$send_max = $send_mean;
|
167 |
+
}
|
168 |
+
if (isset($send_calls[$i][3]) && $send_calls[$i][3]) {
|
169 |
+
$send_completed++;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
if (empty($stats->means)) {
|
174 |
+
return null;
|
175 |
+
}
|
176 |
+
$send_mean = $send_total_time / $send_total_emails;
|
177 |
+
|
178 |
+
$stats->min = round($send_min, 2);
|
179 |
+
$stats->max = round($send_max, 2);
|
180 |
+
$stats->mean = round($send_mean, 2);
|
181 |
+
$stats->total_time = round($send_total_time);
|
182 |
+
$stats->total_emails = $send_total_emails;
|
183 |
+
$stats->total_runs = count($stats->means);
|
184 |
+
|
185 |
+
$stats->completed = $send_completed;
|
186 |
+
$stats->interrupted = $stats->total_runs - $stats->completed;
|
187 |
+
return $stats;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Returns a list of functions attached to the prvoded filter or action name.
|
192 |
+
*
|
193 |
+
* @global array $wp_filter
|
194 |
+
* @param string $tag
|
195 |
+
* @return string
|
196 |
+
*/
|
197 |
+
function get_hook_functions($tag) {
|
198 |
+
global $wp_filter;
|
199 |
+
if (isset($wp_filter[$tag])) {
|
200 |
+
$b = '';
|
201 |
+
foreach ($wp_filter[$tag]->callbacks as $priority => $functions) {
|
202 |
+
|
203 |
+
foreach ($functions as $function) {
|
204 |
+
$b .= '[' . $priority . '] ';
|
205 |
+
if (is_array($function['function'])) {
|
206 |
+
if (is_object($function['function'][0])) {
|
207 |
+
$b .= get_class($function['function'][0]) . '::' . $function['function'][1];
|
208 |
+
} else {
|
209 |
+
$b .= $function['function'][0] . '::' . $function['function'][1];
|
210 |
+
}
|
211 |
+
} else {
|
212 |
+
if (is_object($function['function'])) {
|
213 |
+
$fn = new ReflectionFunction($function['function']);
|
214 |
+
$b .= get_class($fn->getClosureThis()) . '(closure)';
|
215 |
+
} else {
|
216 |
+
$b .= $function['function'];
|
217 |
+
}
|
218 |
+
}
|
219 |
+
$b .= "<br>";
|
220 |
+
}
|
221 |
+
}
|
222 |
+
}
|
223 |
+
return $b;
|
224 |
+
}
|
225 |
+
|
226 |
+
}
|
227 |
+
|
228 |
+
class TNP_Cron_Stats {
|
229 |
+
|
230 |
+
var $min = PHP_INT_MAX;
|
231 |
+
var $max = 0;
|
232 |
+
var $avg = 0;
|
233 |
+
/* List of intervals between cron calls */
|
234 |
+
var $deltas = [];
|
235 |
+
/* If the cron is triggered enough often */
|
236 |
+
var $good = true;
|
237 |
+
|
238 |
+
}
|
239 |
+
|
240 |
+
class TNP_Send_Stats {
|
241 |
+
|
242 |
+
/* Emails sent */
|
243 |
+
var $total_emails;
|
244 |
+
/* Total batches collected (1 sized-batch by Autoresponder are ignored) */
|
245 |
+
var $total_runs;
|
246 |
+
/* Total sending time of the collected batches */
|
247 |
+
var $total_time;
|
248 |
+
/* Batch completed without timeout or max emails limit */
|
249 |
+
var $completed;
|
250 |
+
/* Batches interrupted due to reached limits */
|
251 |
+
var $interrupted;
|
252 |
+
/* Min time to send an email */
|
253 |
+
var $min = PHP_INT_MAX;
|
254 |
+
/* Max time to send an email */
|
255 |
+
var $max = 0;
|
256 |
+
/* Average time to send all collected emails */
|
257 |
+
var $mean = 0;
|
258 |
+
/* List of single batches average per email sending time */
|
259 |
+
var $means = [];
|
260 |
+
/* Number of emails in the single batches */
|
261 |
+
var $sizes = [];
|
262 |
+
|
263 |
+
}
|
includes/themes.php
CHANGED
@@ -1,204 +1,204 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
defined('ABSPATH') || exit;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @property string $id Theme identifier
|
7 |
-
* @property string $dir Absolute path to the theme folder
|
8 |
-
* @property string $name Theme name
|
9 |
-
*/
|
10 |
-
class TNP_Theme {
|
11 |
-
|
12 |
-
var $dir;
|
13 |
-
var $name;
|
14 |
-
|
15 |
-
public function get_defaults() {
|
16 |
-
@include $this->dir . '/theme-defaults.php';
|
17 |
-
if (!isset($theme_defaults) || !is_array($theme_defaults)) {
|
18 |
-
return array();
|
19 |
-
}
|
20 |
-
return $theme_defaults;
|
21 |
-
}
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Registers a Newsletter theme to be shown as option on standard newsletter creation
|
26 |
-
* Designers love functions...
|
27 |
-
* @param string $dir The absolute path of a folder containing a Newsletter theme
|
28 |
-
*/
|
29 |
-
function tnp_register_theme($dir) {
|
30 |
-
NewsletterThemes::register_theme($dir);
|
31 |
-
}
|
32 |
-
|
33 |
-
class NewsletterThemes {
|
34 |
-
|
35 |
-
var $module;
|
36 |
-
var $is_extension = false;
|
37 |
-
static $registered_theme_dirs = array();
|
38 |
-
|
39 |
-
static function register_theme($dir) {
|
40 |
-
if (!file_exists($dir . '/theme.php')) {
|
41 |
-
$error = new WP_Error('1', 'theme.php missing on folder ' . $dir);
|
42 |
-
return $error;
|
43 |
-
}
|
44 |
-
self::$registered_theme_dirs[] = $dir;
|
45 |
-
return true;
|
46 |
-
}
|
47 |
-
|
48 |
-
function __construct($module, $is_extension = false) {
|
49 |
-
$this->module = $module;
|
50 |
-
$this->is_extension = $is_extension;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Build an associative array which represent a theme starting from the theme
|
55 |
-
* parsing the files in the theme folder.<br>
|
56 |
-
* dir - the full path to the theme folder<br>
|
57 |
-
* url - the full url to the theme folder (to reference assets like images)<br>
|
58 |
-
* id - the folder name, used as unique identifier<br>
|
59 |
-
* screenshot - url to an image representing the theme (400x400)<br>
|
60 |
-
* name - the readable theme name extracted from the theme.php<br>
|
61 |
-
*
|
62 |
-
* description - not used
|
63 |
-
* type - not used
|
64 |
-
*
|
65 |
-
* @param string $dir
|
66 |
-
* @return array
|
67 |
-
*/
|
68 |
-
function build_theme($dir) {
|
69 |
-
|
70 |
-
if (!is_dir($dir)) {
|
71 |
-
return null;
|
72 |
-
}
|
73 |
-
|
74 |
-
if (!is_file($dir . '/theme.php')) {
|
75 |
-
return null;
|
76 |
-
}
|
77 |
-
|
78 |
-
$data = get_file_data($dir . '/theme.php', array('name' => 'Name', 'type' => 'Type', 'description' => 'Description'));
|
79 |
-
$data['id'] = basename($dir);
|
80 |
-
$data['dir'] = $dir;
|
81 |
-
if (empty($data['name'])) {
|
82 |
-
$data['name'] = $data['id'];
|
83 |
-
}
|
84 |
-
|
85 |
-
if (empty($data['type'])) {
|
86 |
-
$data['type'] = 'standard';
|
87 |
-
}
|
88 |
-
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
89 |
-
$data['url'] = content_url($relative_dir);
|
90 |
-
$screenshot = $dir . '/screenshot.png';
|
91 |
-
if (is_file($screenshot)) {
|
92 |
-
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
93 |
-
$data['screenshot'] = $data['url'] . '/screenshot.png';
|
94 |
-
} else {
|
95 |
-
$data['screenshot'] = plugins_url('newsletter') . '/images/theme-screenshot.png';
|
96 |
-
}
|
97 |
-
return $data;
|
98 |
-
}
|
99 |
-
|
100 |
-
function get_all_with_data() {
|
101 |
-
$list = array();
|
102 |
-
|
103 |
-
// Packaged themes
|
104 |
-
$list['default'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/default');
|
105 |
-
$list['blank'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/blank');
|
106 |
-
$list['cta-2015'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/cta-2015');
|
107 |
-
$list['vimeo-like'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/vimeo-like');
|
108 |
-
$list['pint'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/pint');
|
109 |
-
|
110 |
-
// Extensions folder scan
|
111 |
-
$dir = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes';
|
112 |
-
$handle = @opendir($dir);
|
113 |
-
|
114 |
-
if ($handle !== false) {
|
115 |
-
while ($file = readdir($handle)) {
|
116 |
-
|
117 |
-
$data = $this->build_theme($dir . '/' . $file);
|
118 |
-
|
119 |
-
if (!$data || isset($list[$data['id']])) {
|
120 |
-
continue;
|
121 |
-
}
|
122 |
-
|
123 |
-
$list[$data['id']] = $data;
|
124 |
-
}
|
125 |
-
closedir($handle);
|
126 |
-
}
|
127 |
-
|
128 |
-
// Registered themes
|
129 |
-
do_action('newsletter_register_themes');
|
130 |
-
|
131 |
-
foreach (self::$registered_theme_dirs as $dir) {
|
132 |
-
$data = $this->build_theme($dir);
|
133 |
-
if (!$data || isset($list[$data['id']])) {
|
134 |
-
continue;
|
135 |
-
}
|
136 |
-
|
137 |
-
$list[$data['id']] = $data;
|
138 |
-
}
|
139 |
-
|
140 |
-
return $list;
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Returns a data structure containing the theme details.
|
145 |
-
*
|
146 |
-
* @param string $id
|
147 |
-
* @return array
|
148 |
-
*/
|
149 |
-
function get_theme($id) {
|
150 |
-
$themes = $this->get_all_with_data();
|
151 |
-
if (isset($themes[$id])) {
|
152 |
-
return $themes[$id];
|
153 |
-
}
|
154 |
-
return null;
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
*
|
159 |
-
* @param type $theme
|
160 |
-
* @param type $options
|
161 |
-
* @param type $module
|
162 |
-
*/
|
163 |
-
function save_options($theme_id, &$options) {
|
164 |
-
$theme_options = array();
|
165 |
-
foreach ($options as $key => &$value) {
|
166 |
-
if (substr($key, 0, 6) != 'theme_')
|
167 |
-
continue;
|
168 |
-
$theme_options[$key] = $value;
|
169 |
-
}
|
170 |
-
update_option('newsletter_' . $this->module . '_theme_' . $theme_id, $theme_options, false);
|
171 |
-
}
|
172 |
-
|
173 |
-
function get_options($theme_id) {
|
174 |
-
$options = get_option('newsletter_' . $this->module . '_theme_' . $theme_id);
|
175 |
-
// To avoid merge problems.
|
176 |
-
if (!is_array($options)) {
|
177 |
-
$options = array();
|
178 |
-
}
|
179 |
-
|
180 |
-
$theme = $this->get_theme($theme_id);
|
181 |
-
|
182 |
-
$file = $theme['dir'] . '/theme-defaults.php';
|
183 |
-
if (is_file($file)) {
|
184 |
-
@include $file;
|
185 |
-
}
|
186 |
-
if (isset($theme_defaults) && is_array($theme_defaults)) {
|
187 |
-
$options = array_merge($theme_defaults, $options);
|
188 |
-
}
|
189 |
-
|
190 |
-
// main options merge
|
191 |
-
$main_options = Newsletter::instance()->options;
|
192 |
-
foreach ($main_options as $key => $value) {
|
193 |
-
$options['main_' . $key] = $value;
|
194 |
-
}
|
195 |
-
|
196 |
-
$info_options = Newsletter::instance()->get_options('info');
|
197 |
-
foreach ($info_options as $key => $value) {
|
198 |
-
$options['main_' . $key] = $value;
|
199 |
-
}
|
200 |
-
|
201 |
-
return $options;
|
202 |
-
}
|
203 |
-
}
|
204 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @property string $id Theme identifier
|
7 |
+
* @property string $dir Absolute path to the theme folder
|
8 |
+
* @property string $name Theme name
|
9 |
+
*/
|
10 |
+
class TNP_Theme {
|
11 |
+
|
12 |
+
var $dir;
|
13 |
+
var $name;
|
14 |
+
|
15 |
+
public function get_defaults() {
|
16 |
+
@include $this->dir . '/theme-defaults.php';
|
17 |
+
if (!isset($theme_defaults) || !is_array($theme_defaults)) {
|
18 |
+
return array();
|
19 |
+
}
|
20 |
+
return $theme_defaults;
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Registers a Newsletter theme to be shown as option on standard newsletter creation
|
26 |
+
* Designers love functions...
|
27 |
+
* @param string $dir The absolute path of a folder containing a Newsletter theme
|
28 |
+
*/
|
29 |
+
function tnp_register_theme($dir) {
|
30 |
+
NewsletterThemes::register_theme($dir);
|
31 |
+
}
|
32 |
+
|
33 |
+
class NewsletterThemes {
|
34 |
+
|
35 |
+
var $module;
|
36 |
+
var $is_extension = false;
|
37 |
+
static $registered_theme_dirs = array();
|
38 |
+
|
39 |
+
static function register_theme($dir) {
|
40 |
+
if (!file_exists($dir . '/theme.php')) {
|
41 |
+
$error = new WP_Error('1', 'theme.php missing on folder ' . $dir);
|
42 |
+
return $error;
|
43 |
+
}
|
44 |
+
self::$registered_theme_dirs[] = $dir;
|
45 |
+
return true;
|
46 |
+
}
|
47 |
+
|
48 |
+
function __construct($module, $is_extension = false) {
|
49 |
+
$this->module = $module;
|
50 |
+
$this->is_extension = $is_extension;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Build an associative array which represent a theme starting from the theme
|
55 |
+
* parsing the files in the theme folder.<br>
|
56 |
+
* dir - the full path to the theme folder<br>
|
57 |
+
* url - the full url to the theme folder (to reference assets like images)<br>
|
58 |
+
* id - the folder name, used as unique identifier<br>
|
59 |
+
* screenshot - url to an image representing the theme (400x400)<br>
|
60 |
+
* name - the readable theme name extracted from the theme.php<br>
|
61 |
+
*
|
62 |
+
* description - not used
|
63 |
+
* type - not used
|
64 |
+
*
|
65 |
+
* @param string $dir
|
66 |
+
* @return array
|
67 |
+
*/
|
68 |
+
function build_theme($dir) {
|
69 |
+
|
70 |
+
if (!is_dir($dir)) {
|
71 |
+
return null;
|
72 |
+
}
|
73 |
+
|
74 |
+
if (!is_file($dir . '/theme.php')) {
|
75 |
+
return null;
|
76 |
+
}
|
77 |
+
|
78 |
+
$data = get_file_data($dir . '/theme.php', array('name' => 'Name', 'type' => 'Type', 'description' => 'Description'));
|
79 |
+
$data['id'] = basename($dir);
|
80 |
+
$data['dir'] = $dir;
|
81 |
+
if (empty($data['name'])) {
|
82 |
+
$data['name'] = $data['id'];
|
83 |
+
}
|
84 |
+
|
85 |
+
if (empty($data['type'])) {
|
86 |
+
$data['type'] = 'standard';
|
87 |
+
}
|
88 |
+
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
89 |
+
$data['url'] = content_url($relative_dir);
|
90 |
+
$screenshot = $dir . '/screenshot.png';
|
91 |
+
if (is_file($screenshot)) {
|
92 |
+
$relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
|
93 |
+
$data['screenshot'] = $data['url'] . '/screenshot.png';
|
94 |
+
} else {
|
95 |
+
$data['screenshot'] = plugins_url('newsletter') . '/emails/images/theme-screenshot.png';
|
96 |
+
}
|
97 |
+
return $data;
|
98 |
+
}
|
99 |
+
|
100 |
+
function get_all_with_data() {
|
101 |
+
$list = array();
|
102 |
+
|
103 |
+
// Packaged themes
|
104 |
+
$list['default'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/default');
|
105 |
+
$list['blank'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/blank');
|
106 |
+
$list['cta-2015'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/cta-2015');
|
107 |
+
$list['vimeo-like'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/vimeo-like');
|
108 |
+
$list['pint'] = $this->build_theme(NEWSLETTER_DIR . '/emails/themes/pint');
|
109 |
+
|
110 |
+
// Extensions folder scan
|
111 |
+
$dir = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes';
|
112 |
+
$handle = @opendir($dir);
|
113 |
+
|
114 |
+
if ($handle !== false) {
|
115 |
+
while ($file = readdir($handle)) {
|
116 |
+
|
117 |
+
$data = $this->build_theme($dir . '/' . $file);
|
118 |
+
|
119 |
+
if (!$data || isset($list[$data['id']])) {
|
120 |
+
continue;
|
121 |
+
}
|
122 |
+
|
123 |
+
$list[$data['id']] = $data;
|
124 |
+
}
|
125 |
+
closedir($handle);
|
126 |
+
}
|
127 |
+
|
128 |
+
// Registered themes
|
129 |
+
do_action('newsletter_register_themes');
|
130 |
+
|
131 |
+
foreach (self::$registered_theme_dirs as $dir) {
|
132 |
+
$data = $this->build_theme($dir);
|
133 |
+
if (!$data || isset($list[$data['id']])) {
|
134 |
+
continue;
|
135 |
+
}
|
136 |
+
|
137 |
+
$list[$data['id']] = $data;
|
138 |
+
}
|
139 |
+
|
140 |
+
return $list;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Returns a data structure containing the theme details.
|
145 |
+
*
|
146 |
+
* @param string $id
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
function get_theme($id) {
|
150 |
+
$themes = $this->get_all_with_data();
|
151 |
+
if (isset($themes[$id])) {
|
152 |
+
return $themes[$id];
|
153 |
+
}
|
154 |
+
return null;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
*
|
159 |
+
* @param type $theme
|
160 |
+
* @param type $options
|
161 |
+
* @param type $module
|
162 |
+
*/
|
163 |
+
function save_options($theme_id, &$options) {
|
164 |
+
$theme_options = array();
|
165 |
+
foreach ($options as $key => &$value) {
|
166 |
+
if (substr($key, 0, 6) != 'theme_')
|
167 |
+
continue;
|
168 |
+
$theme_options[$key] = $value;
|
169 |
+
}
|
170 |
+
update_option('newsletter_' . $this->module . '_theme_' . $theme_id, $theme_options, false);
|
171 |
+
}
|
172 |
+
|
173 |
+
function get_options($theme_id) {
|
174 |
+
$options = get_option('newsletter_' . $this->module . '_theme_' . $theme_id);
|
175 |
+
// To avoid merge problems.
|
176 |
+
if (!is_array($options)) {
|
177 |
+
$options = array();
|
178 |
+
}
|
179 |
+
|
180 |
+
$theme = $this->get_theme($theme_id);
|
181 |
+
|
182 |
+
$file = $theme['dir'] . '/theme-defaults.php';
|
183 |
+
if (is_file($file)) {
|
184 |
+
@include $file;
|
185 |
+
}
|
186 |
+
if (isset($theme_defaults) && is_array($theme_defaults)) {
|
187 |
+
$options = array_merge($theme_defaults, $options);
|
188 |
+
}
|
189 |
+
|
190 |
+
// main options merge
|
191 |
+
$main_options = Newsletter::instance()->options;
|
192 |
+
foreach ($main_options as $key => $value) {
|
193 |
+
$options['main_' . $key] = $value;
|
194 |
+
}
|
195 |
+
|
196 |
+
$info_options = Newsletter::instance()->get_options('info');
|
197 |
+
foreach ($info_options as $key => $value) {
|
198 |
+
$options['main_' . $key] = $value;
|
199 |
+
}
|
200 |
+
|
201 |
+
return $options;
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
includes/tnp-blocks.js
CHANGED
@@ -1,252 +1,252 @@
|
|
1 |
-
(function (blocks, editor, element, components) {
|
2 |
-
|
3 |
-
const el = element.createElement;
|
4 |
-
const {registerBlockType} = blocks;
|
5 |
-
const { RichText, InspectorControls, withColors, PanelColorSettings, getColorClassName, AlignmentToolbar, BlockControls } = editor;
|
6 |
-
const { Fragment } = element;
|
7 |
-
const { TextControl, RadioControl, Panel, PanelBody, PanelRow, SelectControl, RangeControl } = components;
|
8 |
-
const colorSamples = [
|
9 |
-
{
|
10 |
-
name: 'GREEN SEA',
|
11 |
-
slug: 'GREENSEA',
|
12 |
-
color: '#16A085'
|
13 |
-
},
|
14 |
-
{
|
15 |
-
name: 'NEPHRITIS',
|
16 |
-
slug: 'NEPHRITIS',
|
17 |
-
color: '#27AE60'
|
18 |
-
},
|
19 |
-
{
|
20 |
-
name: 'BELIZE HOLE',
|
21 |
-
slug: 'BELIZEHOLE',
|
22 |
-
color: '#2980B9'
|
23 |
-
},
|
24 |
-
{
|
25 |
-
name: 'WISTERIA',
|
26 |
-
slug: 'WISTERIA',
|
27 |
-
color: '#8E44AD'
|
28 |
-
},
|
29 |
-
{
|
30 |
-
name: 'MIDNIGHT BLUE',
|
31 |
-
slug: 'MIDNIGHTBLUE',
|
32 |
-
color: '#2C3E50'
|
33 |
-
},
|
34 |
-
{
|
35 |
-
name: 'ORANGE',
|
36 |
-
slug: 'ORANGE',
|
37 |
-
color: '#F39C12'
|
38 |
-
},
|
39 |
-
{
|
40 |
-
name: 'ALIZARIN',
|
41 |
-
slug: 'ALIZARIN',
|
42 |
-
color: '#E74C3C'
|
43 |
-
},
|
44 |
-
{
|
45 |
-
name: 'WHITE',
|
46 |
-
slug: 'WHITE',
|
47 |
-
color: '#FFFFFF'
|
48 |
-
},
|
49 |
-
{
|
50 |
-
name: 'CLOUDS',
|
51 |
-
slug: 'CLOUDS',
|
52 |
-
color: '#ECF0F1'
|
53 |
-
},
|
54 |
-
{
|
55 |
-
name: 'ASBESTOS',
|
56 |
-
slug: 'ASBESTOS',
|
57 |
-
color: '#7F8C8D'
|
58 |
-
}
|
59 |
-
];
|
60 |
-
|
61 |
-
registerBlockType('tnp/minimal', {
|
62 |
-
title: 'Newsletter subscription form',
|
63 |
-
icon: 'email',
|
64 |
-
category: 'common',
|
65 |
-
keywords: ['newsletter', 'subscription', 'form'],
|
66 |
-
attributes: {
|
67 |
-
formtype: {type: 'string', default: 'minimal'},
|
68 |
-
content: { type: 'array', source: 'children', selector: 'p', default: 'Subscribe to our newsletter!'},
|
69 |
-
list_ids: { type: 'string' },
|
70 |
-
rowColor: { type: 'string'},
|
71 |
-
customRowColor: { type: 'string'},
|
72 |
-
textColor: { type: 'string'},
|
73 |
-
customTextColor: { type: 'string'},
|
74 |
-
buttonColor: { type: 'string'},
|
75 |
-
customButtonColor: { type: 'string'},
|
76 |
-
padding: {type: 'integer', default: 20},
|
77 |
-
alignment: { type: 'string'}
|
78 |
-
},
|
79 |
-
|
80 |
-
edit: withColors('rowColor', 'textColor', 'buttonColor')(function (props) {
|
81 |
-
|
82 |
-
function onChangeContent( newContent ) {
|
83 |
-
props.setAttributes( { content: newContent } );
|
84 |
-
}
|
85 |
-
|
86 |
-
function onChangeAlignment( newAlignment ) {
|
87 |
-
props.setAttributes( { alignment: newAlignment } );
|
88 |
-
}
|
89 |
-
|
90 |
-
return el( Fragment, {},
|
91 |
-
el( InspectorControls, {},
|
92 |
-
|
93 |
-
// 1st Panel - Form Settings
|
94 |
-
el( PanelBody, { title: 'Form Settings', initialOpen: true },
|
95 |
-
|
96 |
-
/* Form type */
|
97 |
-
el( RadioControl,
|
98 |
-
{
|
99 |
-
label: 'Form type',
|
100 |
-
options : [
|
101 |
-
{ label: 'Minimal', value: 'minimal' },
|
102 |
-
{ label: 'Full', value: 'full' },
|
103 |
-
],
|
104 |
-
onChange: ( value ) => {
|
105 |
-
props.setAttributes( { formtype: value } );
|
106 |
-
},
|
107 |
-
selected: props.attributes.formtype
|
108 |
-
}
|
109 |
-
),
|
110 |
-
|
111 |
-
/* Lists field */
|
112 |
-
el( PanelRow, {},
|
113 |
-
el( TextControl,
|
114 |
-
{
|
115 |
-
label: 'Lists IDs (comma separated)',
|
116 |
-
onChange: ( value ) => {
|
117 |
-
props.setAttributes( { list_ids: value } );
|
118 |
-
},
|
119 |
-
value: props.attributes.list_ids
|
120 |
-
}
|
121 |
-
)
|
122 |
-
)
|
123 |
-
),
|
124 |
-
|
125 |
-
/* Style */
|
126 |
-
el( PanelColorSettings, {
|
127 |
-
title: 'Style',
|
128 |
-
colorSettings: [
|
129 |
-
{
|
130 |
-
colors: colorSamples, // here you can pass custom colors
|
131 |
-
value: props.rowColor.color,
|
132 |
-
label: 'Background color',
|
133 |
-
onChange: props.setRowColor,
|
134 |
-
},
|
135 |
-
{
|
136 |
-
colors: colorSamples, // here you can pass custom colors
|
137 |
-
value: props.textColor.color,
|
138 |
-
label: 'Text color',
|
139 |
-
onChange: props.setTextColor,
|
140 |
-
},
|
141 |
-
{
|
142 |
-
colors: colorSamples, // here you can pass custom colors
|
143 |
-
value: props.buttonColor.color,
|
144 |
-
label: 'Button color',
|
145 |
-
onChange: props.setButtonColor,
|
146 |
-
}
|
147 |
-
]
|
148 |
-
}),
|
149 |
-
|
150 |
-
el( RangeControl,
|
151 |
-
{
|
152 |
-
label: 'Padding',
|
153 |
-
min: 0,
|
154 |
-
max: 100,
|
155 |
-
onChange: ( value ) => {
|
156 |
-
props.setAttributes( { padding: value } );
|
157 |
-
},
|
158 |
-
value: props.attributes.padding
|
159 |
-
}
|
160 |
-
)
|
161 |
-
|
162 |
-
),
|
163 |
-
|
164 |
-
el(
|
165 |
-
"div",
|
166 |
-
{style: {backgroundColor: props.rowColor.color, color: props.textColor.color, padding: props.attributes.padding, textAlign: props.attributes.alignment}},
|
167 |
-
el(
|
168 |
-
BlockControls,
|
169 |
-
{ key: 'controls' },
|
170 |
-
el(
|
171 |
-
AlignmentToolbar,
|
172 |
-
{
|
173 |
-
value: props.attributes.alignment,
|
174 |
-
onChange: onChangeAlignment
|
175 |
-
}
|
176 |
-
)
|
177 |
-
),
|
178 |
-
el(RichText,
|
179 |
-
{
|
180 |
-
tagName: 'p',
|
181 |
-
format: 'string',
|
182 |
-
onChange: onChangeContent,
|
183 |
-
value: props.attributes.content,
|
184 |
-
// formattingControls: [ 'bold' ]
|
185 |
-
}),
|
186 |
-
el('div',
|
187 |
-
{style: {backgroundColor: 'lightGrey', margin: '20px', padding: '5px',
|
188 |
-
fontFamily: '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif'}},
|
189 |
-
el('svg',
|
190 |
-
{
|
191 |
-
width: 20,
|
192 |
-
height: 20
|
193 |
-
},
|
194 |
-
wp.element.createElement( 'path',
|
195 |
-
{
|
196 |
-
d: "M6 14H4V6h2V4H2v12h4M7.1 17h2.1l3.7-14h-2.1M14 4v2h2v8h-2v2h4V4"
|
197 |
-
}
|
198 |
-
)
|
199 |
-
),
|
200 |
-
' Newsletter Form'
|
201 |
-
),
|
202 |
-
))
|
203 |
-
}),
|
204 |
-
save: function (props) {
|
205 |
-
|
206 |
-
var rowClass = getColorClassName( 'row-color', props.attributes.rowColor );
|
207 |
-
var textClass = getColorClassName( 'text-color', props.attributes.textColor );
|
208 |
-
var buttonClass = getColorClassName( 'button-color', props.attributes.buttonColor );
|
209 |
-
|
210 |
-
formtype_attr = "";
|
211 |
-
if (props.attributes.formtype != "full") {
|
212 |
-
formtype_attr = " type=\"minimal\"";
|
213 |
-
}
|
214 |
-
|
215 |
-
lists_attr = "";
|
216 |
-
if (props.attributes.list_ids) {
|
217 |
-
lists_attr = " lists=\"" + props.attributes.list_ids + "\"";
|
218 |
-
}
|
219 |
-
|
220 |
-
button_color_attr = "";
|
221 |
-
button_color = buttonClass ? undefined : props.attributes.customButtonColor;
|
222 |
-
if (button_color) {
|
223 |
-
button_color_attr = " button_color=\"" + button_color + "\"";
|
224 |
-
}
|
225 |
-
|
226 |
-
var formStyles = {
|
227 |
-
backgroundColor: rowClass ? undefined : props.attributes.customRowColor,
|
228 |
-
color: textClass ? undefined : props.attributes.customTextColor,
|
229 |
-
padding: props.attributes.padding,
|
230 |
-
textAlign: props.attributes.alignment
|
231 |
-
};
|
232 |
-
|
233 |
-
return (
|
234 |
-
el('div', {style: formStyles},
|
235 |
-
el( RichText.Content, {
|
236 |
-
tagName: 'p',
|
237 |
-
value: props.attributes.content
|
238 |
-
}),
|
239 |
-
el(
|
240 |
-
"div",
|
241 |
-
{},
|
242 |
-
"[newsletter_form" + formtype_attr + lists_attr + button_color_attr + "]"
|
243 |
-
)));
|
244 |
-
}
|
245 |
-
});
|
246 |
-
|
247 |
-
})(
|
248 |
-
window.wp.blocks,
|
249 |
-
window.wp.
|
250 |
-
window.wp.element,
|
251 |
-
window.wp.components,
|
252 |
-
);
|
1 |
+
(function (blocks, editor, element, components) {
|
2 |
+
|
3 |
+
const el = element.createElement;
|
4 |
+
const {registerBlockType} = blocks;
|
5 |
+
const { RichText, InspectorControls, withColors, PanelColorSettings, getColorClassName, AlignmentToolbar, BlockControls } = editor;
|
6 |
+
const { Fragment } = element;
|
7 |
+
const { TextControl, RadioControl, Panel, PanelBody, PanelRow, SelectControl, RangeControl } = components;
|
8 |
+
const colorSamples = [
|
9 |
+
{
|
10 |
+
name: 'GREEN SEA',
|
11 |
+
slug: 'GREENSEA',
|
12 |
+
color: '#16A085'
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'NEPHRITIS',
|
16 |
+
slug: 'NEPHRITIS',
|
17 |
+
color: '#27AE60'
|
18 |
+
},
|
19 |
+
{
|
20 |
+
name: 'BELIZE HOLE',
|
21 |
+
slug: 'BELIZEHOLE',
|
22 |
+
color: '#2980B9'
|
23 |
+
},
|
24 |
+
{
|
25 |
+
name: 'WISTERIA',
|
26 |
+
slug: 'WISTERIA',
|
27 |
+
color: '#8E44AD'
|
28 |
+
},
|
29 |
+
{
|
30 |
+
name: 'MIDNIGHT BLUE',
|
31 |
+
slug: 'MIDNIGHTBLUE',
|
32 |
+
color: '#2C3E50'
|
33 |
+
},
|
34 |
+
{
|
35 |
+
name: 'ORANGE',
|
36 |
+
slug: 'ORANGE',
|
37 |
+
color: '#F39C12'
|
38 |
+
},
|
39 |
+
{
|
40 |
+
name: 'ALIZARIN',
|
41 |
+
slug: 'ALIZARIN',
|
42 |
+
color: '#E74C3C'
|
43 |
+
},
|
44 |
+
{
|
45 |
+
name: 'WHITE',
|
46 |
+
slug: 'WHITE',
|
47 |
+
color: '#FFFFFF'
|
48 |
+
},
|
49 |
+
{
|
50 |
+
name: 'CLOUDS',
|
51 |
+
slug: 'CLOUDS',
|
52 |
+
color: '#ECF0F1'
|
53 |
+
},
|
54 |
+
{
|
55 |
+
name: 'ASBESTOS',
|
56 |
+
slug: 'ASBESTOS',
|
57 |
+
color: '#7F8C8D'
|
58 |
+
}
|
59 |
+
];
|
60 |
+
|
61 |
+
registerBlockType('tnp/minimal', {
|
62 |
+
title: 'Newsletter subscription form',
|
63 |
+
icon: 'email',
|
64 |
+
category: 'common',
|
65 |
+
keywords: ['newsletter', 'subscription', 'form'],
|
66 |
+
attributes: {
|
67 |
+
formtype: {type: 'string', default: 'minimal'},
|
68 |
+
content: { type: 'array', source: 'children', selector: 'p', default: 'Subscribe to our newsletter!'},
|
69 |
+
list_ids: { type: 'string' },
|
70 |
+
rowColor: { type: 'string'},
|
71 |
+
customRowColor: { type: 'string'},
|
72 |
+
textColor: { type: 'string'},
|
73 |
+
customTextColor: { type: 'string'},
|
74 |
+
buttonColor: { type: 'string'},
|
75 |
+
customButtonColor: { type: 'string'},
|
76 |
+
padding: {type: 'integer', default: 20},
|
77 |
+
alignment: { type: 'string'}
|
78 |
+
},
|
79 |
+
|
80 |
+
edit: withColors('rowColor', 'textColor', 'buttonColor')(function (props) {
|
81 |
+
|
82 |
+
function onChangeContent( newContent ) {
|
83 |
+
props.setAttributes( { content: newContent } );
|
84 |
+
}
|
85 |
+
|
86 |
+
function onChangeAlignment( newAlignment ) {
|
87 |
+
props.setAttributes( { alignment: newAlignment } );
|
88 |
+
}
|
89 |
+
|
90 |
+
return el( Fragment, {},
|
91 |
+
el( InspectorControls, {},
|
92 |
+
|
93 |
+
// 1st Panel - Form Settings
|
94 |
+
el( PanelBody, { title: 'Form Settings', initialOpen: true },
|
95 |
+
|
96 |
+
/* Form type */
|
97 |
+
el( RadioControl,
|
98 |
+
{
|
99 |
+
label: 'Form type',
|
100 |
+
options : [
|
101 |
+
{ label: 'Minimal', value: 'minimal' },
|
102 |
+
{ label: 'Full', value: 'full' },
|
103 |
+
],
|
104 |
+
onChange: ( value ) => {
|
105 |
+
props.setAttributes( { formtype: value } );
|
106 |
+
},
|
107 |
+
selected: props.attributes.formtype
|
108 |
+
}
|
109 |
+
),
|
110 |
+
|
111 |
+
/* Lists field */
|
112 |
+
el( PanelRow, {},
|
113 |
+
el( TextControl,
|
114 |
+
{
|
115 |
+
label: 'Lists IDs (comma separated)',
|
116 |
+
onChange: ( value ) => {
|
117 |
+
props.setAttributes( { list_ids: value } );
|
118 |
+
},
|
119 |
+
value: props.attributes.list_ids
|
120 |
+
}
|
121 |
+
)
|
122 |
+
)
|
123 |
+
),
|
124 |
+
|
125 |
+
/* Style */
|
126 |
+
el( PanelColorSettings, {
|
127 |
+
title: 'Style',
|
128 |
+
colorSettings: [
|
129 |
+
{
|
130 |
+
colors: colorSamples, // here you can pass custom colors
|
131 |
+
value: props.rowColor.color,
|
132 |
+
label: 'Background color',
|
133 |
+
onChange: props.setRowColor,
|
134 |
+
},
|
135 |
+
{
|
136 |
+
colors: colorSamples, // here you can pass custom colors
|
137 |
+
value: props.textColor.color,
|
138 |
+
label: 'Text color',
|
139 |
+
onChange: props.setTextColor,
|
140 |
+
},
|
141 |
+
{
|
142 |
+
colors: colorSamples, // here you can pass custom colors
|
143 |
+
value: props.buttonColor.color,
|
144 |
+
label: 'Button color',
|
145 |
+
onChange: props.setButtonColor,
|
146 |
+
}
|
147 |
+
]
|
148 |
+
}),
|
149 |
+
|
150 |
+
el( RangeControl,
|
151 |
+
{
|
152 |
+
label: 'Padding',
|
153 |
+
min: 0,
|
154 |
+
max: 100,
|
155 |
+
onChange: ( value ) => {
|
156 |
+
props.setAttributes( { padding: value } );
|
157 |
+
},
|
158 |
+
value: props.attributes.padding
|
159 |
+
}
|
160 |
+
)
|
161 |
+
|
162 |
+
),
|
163 |
+
|
164 |
+
el(
|
165 |
+
"div",
|
166 |
+
{style: {backgroundColor: props.rowColor.color, color: props.textColor.color, padding: props.attributes.padding, textAlign: props.attributes.alignment}},
|
167 |
+
el(
|
168 |
+
BlockControls,
|
169 |
+
{ key: 'controls' },
|
170 |
+
el(
|
171 |
+
AlignmentToolbar,
|
172 |
+
{
|
173 |
+
value: props.attributes.alignment,
|
174 |
+
onChange: onChangeAlignment
|
175 |
+
}
|
176 |
+
)
|
177 |
+
),
|
178 |
+
el(RichText,
|
179 |
+
{
|
180 |
+
tagName: 'p',
|
181 |
+
format: 'string',
|
182 |
+
onChange: onChangeContent,
|
183 |
+
value: props.attributes.content,
|
184 |
+
// formattingControls: [ 'bold' ]
|
185 |
+
}),
|
186 |
+
el('div',
|
187 |
+
{style: {backgroundColor: 'lightGrey', margin: '20px', padding: '5px',
|
188 |
+
fontFamily: '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif'}},
|
189 |
+
el('svg',
|
190 |
+
{
|
191 |
+
width: 20,
|
192 |
+
height: 20
|
193 |
+
},
|
194 |
+
wp.element.createElement( 'path',
|
195 |
+
{
|
196 |
+
d: "M6 14H4V6h2V4H2v12h4M7.1 17h2.1l3.7-14h-2.1M14 4v2h2v8h-2v2h4V4"
|
197 |
+
}
|
198 |
+
)
|
199 |
+
),
|
200 |
+
' Newsletter Form'
|
201 |
+
),
|
202 |
+
))
|
203 |
+
}),
|
204 |
+
save: function (props) {
|
205 |
+
|
206 |
+
var rowClass = getColorClassName( 'row-color', props.attributes.rowColor );
|
207 |
+
var textClass = getColorClassName( 'text-color', props.attributes.textColor );
|
208 |
+
var buttonClass = getColorClassName( 'button-color', props.attributes.buttonColor );
|
209 |
+
|
210 |
+
formtype_attr = "";
|
211 |
+
if (props.attributes.formtype != "full") {
|
212 |
+
formtype_attr = " type=\"minimal\"";
|
213 |
+
}
|
214 |
+
|
215 |
+
lists_attr = "";
|
216 |
+
if (props.attributes.list_ids) {
|
217 |
+
lists_attr = " lists=\"" + props.attributes.list_ids + "\"";
|
218 |
+
}
|
219 |
+
|
220 |
+
button_color_attr = "";
|
221 |
+
button_color = buttonClass ? undefined : props.attributes.customButtonColor;
|
222 |
+
if (button_color) {
|
223 |
+
button_color_attr = " button_color=\"" + button_color + "\"";
|
224 |
+
}
|
225 |
+
|
226 |
+
var formStyles = {
|
227 |
+
backgroundColor: rowClass ? undefined : props.attributes.customRowColor,
|
228 |
+
color: textClass ? undefined : props.attributes.customTextColor,
|
229 |
+
padding: props.attributes.padding,
|
230 |
+
textAlign: props.attributes.alignment
|
231 |
+
};
|
232 |
+
|
233 |
+
return (
|
234 |
+
el('div', {style: formStyles},
|
235 |
+
el( RichText.Content, {
|
236 |
+
tagName: 'p',
|
237 |
+
value: props.attributes.content
|
238 |
+
}),
|
239 |
+
el(
|
240 |
+
"div",
|
241 |
+
{},
|
242 |
+
"[newsletter_form" + formtype_attr + lists_attr + button_color_attr + "]"
|
243 |
+
)));
|
244 |
+
}
|
245 |
+
});
|
246 |
+
|
247 |
+
})(
|
248 |
+
window.wp.blocks,
|
249 |
+
window.wp.blockEditor,
|
250 |
+
window.wp.element,
|
251 |
+
window.wp.components,
|
252 |
+
);
|
{css → main/css}/dashboard.css
RENAMED
@@ -1,166 +1,166 @@
|
|
1 |
-
/* This is loaded inline in the main/index.php file */
|
2 |
-
|
3 |
-
#wpfooter {
|
4 |
-
position: relative;
|
5 |
-
}
|
6 |
-
|
7 |
-
.tnp-dashboard {
|
8 |
-
background-color: #f2f5f9;
|
9 |
-
color: #222222;
|
10 |
-
}
|
11 |
-
|
12 |
-
.tnp-dashboard .tnp-cards-container {
|
13 |
-
background-color: #28313c;
|
14 |
-
}
|
15 |
-
|
16 |
-
/* Row Break Helper */
|
17 |
-
|
18 |
-
.break {
|
19 |
-
flex-basis: 100%;
|
20 |
-
height: 0;
|
21 |
-
}
|
22 |
-
|
23 |
-
.tnp-dashboard .tnp-card {
|
24 |
-
flex: 1 0;
|
25 |
-
align-content: flex-start;
|
26 |
-
margin: 15px;
|
27 |
-
font-family: soleil, sans-serif;
|
28 |
-
border-radius: 15px;
|
29 |
-
background-color: #232D3B;
|
30 |
-
-webkit-box-shadow: 1px 1px 7px 0px rgb(0 0 0 / 15%);
|
31 |
-
-moz-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
32 |
-
box-shadow: 1px 1px 7px 0px rgb(0 0 0 / 15%);
|
33 |
-
padding: 15px;
|
34 |
-
color: #FFF;
|
35 |
-
display: flex;
|
36 |
-
flex-wrap: wrap;
|
37 |
-
position: relative;
|
38 |
-
}
|
39 |
-
|
40 |
-
.tnp-dashboard .tnp-card a, .tnp-dashboard .tnp-card a:active {
|
41 |
-
text-decoration: none;
|
42 |
-
color: inherit !important;
|
43 |
-
}
|
44 |
-
|
45 |
-
|
46 |
-
.tnp-dashboard .tnp-card .tnp-card-title {
|
47 |
-
flex-basis: 80%;
|
48 |
-
font-weight: 900;
|
49 |
-
margin: 0px 0px 30px;
|
50 |
-
font-size: 17px;
|
51 |
-
}
|
52 |
-
|
53 |
-
.tnp-dashboard .tnp-card .tnp-card-upper-buttons {
|
54 |
-
flex-basis: 10%;
|
55 |
-
font-weight: 900;
|
56 |
-
margin: 0px 0px 10px;
|
57 |
-
font-size: 15px;
|
58 |
-
}
|
59 |
-
|
60 |
-
.tnp-dashboard .tnp-card .tnp-card-description {
|
61 |
-
font-size: 12px;
|
62 |
-
line-height: 16px;
|
63 |
-
font-weight: 500;
|
64 |
-
margin: 0px 0px 20px;
|
65 |
-
}
|
66 |
-
|
67 |
-
.tnp-dashboard .tnp-card .tnp-card-content {
|
68 |
-
width: 100%;
|
69 |
-
}
|
70 |
-
|
71 |
-
.tnp-dashboard .tnp-card .tnp-card-button-container {
|
72 |
-
margin-top: 40px;
|
73 |
-
}
|
74 |
-
|
75 |
-
.tnp-dashboard .tnp-card .tnp-card-button-container a {
|
76 |
-
position: absolute;
|
77 |
-
padding: 7px 15px;
|
78 |
-
font-size: 14px;
|
79 |
-
font-weight: 500;
|
80 |
-
color: #FFF !important;
|
81 |
-
background-color: #2980b9;
|
82 |
-
border-radius: 4px;
|
83 |
-
text-decoration: none;
|
84 |
-
bottom: 15px;
|
85 |
-
left: auto;
|
86 |
-
-webkit-transform: none;
|
87 |
-
transform: none;
|
88 |
-
}
|
89 |
-
|
90 |
-
.tnp-dashboard .tnp-card .tnp-card-button-container a:hover {
|
91 |
-
background-color: #2980b9e6;
|
92 |
-
}
|
93 |
-
|
94 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletter-list {
|
95 |
-
display: flex;
|
96 |
-
margin: 10px 0px;
|
97 |
-
align-items: center;
|
98 |
-
background-color: #263240;
|
99 |
-
border-radius: 5px;
|
100 |
-
padding: 10px 10px;
|
101 |
-
}
|
102 |
-
|
103 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-subject {
|
104 |
-
flex-basis: 50%;
|
105 |
-
margin-right: 10px;
|
106 |
-
}
|
107 |
-
|
108 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-status {
|
109 |
-
flex-basis: 10%;
|
110 |
-
margin-right: 10px;
|
111 |
-
}
|
112 |
-
|
113 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-progress {
|
114 |
-
flex-basis: 30%;
|
115 |
-
margin-right: 10px;
|
116 |
-
}
|
117 |
-
|
118 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-action {
|
119 |
-
flex-basis: 5%;
|
120 |
-
margin-left: auto;
|
121 |
-
}
|
122 |
-
|
123 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-email {
|
124 |
-
flex-basis: 40%;
|
125 |
-
margin-right: 10px;
|
126 |
-
}
|
127 |
-
|
128 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-name {
|
129 |
-
flex-basis: 30%;
|
130 |
-
margin-right: 10px;
|
131 |
-
}
|
132 |
-
|
133 |
-
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-status {
|
134 |
-
flex-basis: 20%;
|
135 |
-
margin-right: 10px;
|
136 |
-
}
|
137 |
-
|
138 |
-
.tnp-dashboard .tnp-card .tnp-card-documentation-index {
|
139 |
-
background-color: #2a3544;
|
140 |
-
padding: 15px 20px 17px 5px;
|
141 |
-
border-radius: 15px;
|
142 |
-
font-size: 15px;
|
143 |
-
margin: 10px;
|
144 |
-
}
|
145 |
-
|
146 |
-
.tnp-dashboard .tnp-card .tnp-card-documentation-index svg {
|
147 |
-
margin: 0px 10px;
|
148 |
-
vertical-align: text-bottom;
|
149 |
-
fill: #fff;
|
150 |
-
stroke: #fff;
|
151 |
-
}
|
152 |
-
|
153 |
-
.tnp-dashboard .tnp-card .tnp-card-documentation-index:hover {
|
154 |
-
animation: ease-in 4s;
|
155 |
-
background-color: #323e4e;
|
156 |
-
}
|
157 |
-
|
158 |
-
.tnp-card .tnp-canvas {
|
159 |
-
width: 100%;
|
160 |
-
}
|
161 |
-
|
162 |
-
/* CSS Gradients */
|
163 |
-
|
164 |
-
.tnp-mimosa {
|
165 |
-
background-color: #fd7278;
|
166 |
}
|
1 |
+
/* This is loaded inline in the main/index.php file */
|
2 |
+
|
3 |
+
#wpfooter {
|
4 |
+
position: relative;
|
5 |
+
}
|
6 |
+
|
7 |
+
.tnp-dashboard {
|
8 |
+
background-color: #f2f5f9;
|
9 |
+
color: #222222;
|
10 |
+
}
|
11 |
+
|
12 |
+
.tnp-dashboard .tnp-cards-container {
|
13 |
+
background-color: #28313c;
|
14 |
+
}
|
15 |
+
|
16 |
+
/* Row Break Helper */
|
17 |
+
|
18 |
+
.break {
|
19 |
+
flex-basis: 100%;
|
20 |
+
height: 0;
|
21 |
+
}
|
22 |
+
|
23 |
+
.tnp-dashboard .tnp-card {
|
24 |
+
flex: 1 0;
|
25 |
+
align-content: flex-start;
|
26 |
+
margin: 15px;
|
27 |
+
font-family: soleil, sans-serif;
|
28 |
+
border-radius: 15px;
|
29 |
+
background-color: #232D3B;
|
30 |
+
-webkit-box-shadow: 1px 1px 7px 0px rgb(0 0 0 / 15%);
|
31 |
+
-moz-box-shadow: 1px 1px 7px 0px rgba(0, 0, 0, 0.15);
|
32 |
+
box-shadow: 1px 1px 7px 0px rgb(0 0 0 / 15%);
|
33 |
+
padding: 15px;
|
34 |
+
color: #FFF;
|
35 |
+
display: flex;
|
36 |
+
flex-wrap: wrap;
|
37 |
+
position: relative;
|
38 |
+
}
|
39 |
+
|
40 |
+
.tnp-dashboard .tnp-card a, .tnp-dashboard .tnp-card a:active {
|
41 |
+
text-decoration: none;
|
42 |
+
color: inherit !important;
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
.tnp-dashboard .tnp-card .tnp-card-title {
|
47 |
+
flex-basis: 80%;
|
48 |
+
font-weight: 900;
|
49 |
+
margin: 0px 0px 30px;
|
50 |
+
font-size: 17px;
|
51 |
+
}
|
52 |
+
|
53 |
+
.tnp-dashboard .tnp-card .tnp-card-upper-buttons {
|
54 |
+
flex-basis: 10%;
|
55 |
+
font-weight: 900;
|
56 |
+
margin: 0px 0px 10px;
|
57 |
+
font-size: 15px;
|
58 |
+
}
|
59 |
+
|
60 |
+
.tnp-dashboard .tnp-card .tnp-card-description {
|
61 |
+
font-size: 12px;
|
62 |
+
line-height: 16px;
|
63 |
+
font-weight: 500;
|
64 |
+
margin: 0px 0px 20px;
|
65 |
+
}
|
66 |
+
|
67 |
+
.tnp-dashboard .tnp-card .tnp-card-content {
|
68 |
+
width: 100%;
|
69 |
+
}
|
70 |
+
|
71 |
+
.tnp-dashboard .tnp-card .tnp-card-button-container {
|
72 |
+
margin-top: 40px;
|
73 |
+
}
|
74 |
+
|
75 |
+
.tnp-dashboard .tnp-card .tnp-card-button-container a {
|
76 |
+
position: absolute;
|
77 |
+
padding: 7px 15px;
|
78 |
+
font-size: 14px;
|
79 |
+
font-weight: 500;
|
80 |
+
color: #FFF !important;
|
81 |
+
background-color: #2980b9;
|
82 |
+
border-radius: 4px;
|
83 |
+
text-decoration: none;
|
84 |
+
bottom: 15px;
|
85 |
+
left: auto;
|
86 |
+
-webkit-transform: none;
|
87 |
+
transform: none;
|
88 |
+
}
|
89 |
+
|
90 |
+
.tnp-dashboard .tnp-card .tnp-card-button-container a:hover {
|
91 |
+
background-color: #2980b9e6;
|
92 |
+
}
|
93 |
+
|
94 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletter-list {
|
95 |
+
display: flex;
|
96 |
+
margin: 10px 0px;
|
97 |
+
align-items: center;
|
98 |
+
background-color: #263240;
|
99 |
+
border-radius: 5px;
|
100 |
+
padding: 10px 10px;
|
101 |
+
}
|
102 |
+
|
103 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-subject {
|
104 |
+
flex-basis: 50%;
|
105 |
+
margin-right: 10px;
|
106 |
+
}
|
107 |
+
|
108 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-status {
|
109 |
+
flex-basis: 10%;
|
110 |
+
margin-right: 10px;
|
111 |
+
}
|
112 |
+
|
113 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-progress {
|
114 |
+
flex-basis: 30%;
|
115 |
+
margin-right: 10px;
|
116 |
+
}
|
117 |
+
|
118 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-action {
|
119 |
+
flex-basis: 5%;
|
120 |
+
margin-left: auto;
|
121 |
+
}
|
122 |
+
|
123 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-email {
|
124 |
+
flex-basis: 40%;
|
125 |
+
margin-right: 10px;
|
126 |
+
}
|
127 |
+
|
128 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-name {
|
129 |
+
flex-basis: 30%;
|
130 |
+
margin-right: 10px;
|
131 |
+
}
|
132 |
+
|
133 |
+
.tnp-dashboard .tnp-card .tnp-card-newsletters-subscriber-status {
|
134 |
+
flex-basis: 20%;
|
135 |
+
margin-right: 10px;
|
136 |
+
}
|
137 |
+
|
138 |
+
.tnp-dashboard .tnp-card .tnp-card-documentation-index {
|
139 |
+
background-color: #2a3544;
|
140 |
+
padding: 15px 20px 17px 5px;
|
141 |
+
border-radius: 15px;
|
142 |
+
font-size: 15px;
|
143 |
+
margin: 10px;
|
144 |
+
}
|
145 |
+
|
146 |
+
.tnp-dashboard .tnp-card .tnp-card-documentation-index svg {
|
147 |
+
margin: 0px 10px;
|
148 |
+
vertical-align: text-bottom;
|
149 |
+
fill: #fff;
|
150 |
+
stroke: #fff;
|
151 |
+
}
|
152 |
+
|
153 |
+
.tnp-dashboard .tnp-card .tnp-card-documentation-index:hover {
|
154 |
+
animation: ease-in 4s;
|
155 |
+
background-color: #323e4e;
|
156 |
+
}
|
157 |
+
|
158 |
+
.tnp-card .tnp-canvas {
|
159 |
+
width: 100%;
|
160 |
+
}
|
161 |
+
|
162 |
+
/* CSS Gradients */
|
163 |
+
|
164 |
+
.tnp-mimosa {
|
165 |
+
background-color: #fd7278;
|
166 |
}
|
{css → main/css}/welcome.css
RENAMED
@@ -1,348 +1,348 @@
|
|
1 |
-
/* This is loaded inline in the welcome.php page */
|
2 |
-
|
3 |
-
.cd-slider-wrapper {
|
4 |
-
position: relative;
|
5 |
-
width: 100%;
|
6 |
-
height: 90vh;
|
7 |
-
/* hide horizontal scrollbar on IE11 */
|
8 |
-
overflow: hidden;
|
9 |
-
margin: 0 auto;
|
10 |
-
}
|
11 |
-
.cd-slider-wrapper .cd-slider, .cd-slider-wrapper .cd-slider > li {
|
12 |
-
height: 100%;
|
13 |
-
width: 100%;
|
14 |
-
}
|
15 |
-
|
16 |
-
.tnp-logo-big {
|
17 |
-
width: 300px;
|
18 |
-
}
|
19 |
-
|
20 |
-
.tnp-row {
|
21 |
-
display: table-row;
|
22 |
-
}
|
23 |
-
|
24 |
-
.tnp-third {
|
25 |
-
width: 33%;
|
26 |
-
float: left;
|
27 |
-
}
|
28 |
-
|
29 |
-
.tnp-welcome-confirm-button {
|
30 |
-
color: #fff;
|
31 |
-
padding: 10px 30px;
|
32 |
-
background-color: #2ECC71;
|
33 |
-
font-weight: 700;
|
34 |
-
font-size: 15px;
|
35 |
-
box-shadow: 0 20px 38px rgba(0, 0, 0, 0.16);
|
36 |
-
text-decoration: none;
|
37 |
-
display: inline-block;
|
38 |
-
text-align: center;
|
39 |
-
margin: 20px auto 0px;
|
40 |
-
}
|
41 |
-
|
42 |
-
.tnp-welcome-confirm-button:hover {
|
43 |
-
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
44 |
-
color: #fff;
|
45 |
-
}
|
46 |
-
|
47 |
-
.tnp-welcome-confirm-button:visited {
|
48 |
-
color: #fff;
|
49 |
-
text-decoration: none;
|
50 |
-
}
|
51 |
-
|
52 |
-
.tnp-welcome-link-button {
|
53 |
-
color: #fff;
|
54 |
-
padding: 10px 30px;
|
55 |
-
background-color: #3498DB;
|
56 |
-
font-weight: 700;
|
57 |
-
font-size: 15px;
|
58 |
-
box-shadow: 0 20px 38px rgba(0, 0, 0, 0.16);
|
59 |
-
text-decoration: none;
|
60 |
-
}
|
61 |
-
|
62 |
-
.tnp-welcome-link-button:hover {
|
63 |
-
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
64 |
-
color: #fff;
|
65 |
-
}
|
66 |
-
|
67 |
-
.tnp-welcome-link-button:visited {
|
68 |
-
color: #fff;
|
69 |
-
text-decoration: none;
|
70 |
-
}
|
71 |
-
|
72 |
-
#tnp-welcome input[type="text"], #tnp-welcome input[type="email"] {
|
73 |
-
max-width: 90%;
|
74 |
-
}
|
75 |
-
|
76 |
-
.tnp-welcome-next {
|
77 |
-
background-color: #2ECC71;
|
78 |
-
padding: 10px 20px;
|
79 |
-
color: white;
|
80 |
-
text-decoration: none;
|
81 |
-
font-weight: 600;
|
82 |
-
font-size: 16px;
|
83 |
-
margin: 0px 10px;
|
84 |
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);
|
85 |
-
width: -moz-fit-content;
|
86 |
-
width: -webkit-fit-content;
|
87 |
-
width: fit-content;
|
88 |
-
display: flex;
|
89 |
-
align-items: center;
|
90 |
-
}
|
91 |
-
|
92 |
-
.tnp-welcome-next:hover {
|
93 |
-
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
94 |
-
color: #fff;
|
95 |
-
}
|
96 |
-
|
97 |
-
.tnp-welcome-next:visited {
|
98 |
-
color: #fff;
|
99 |
-
text-decoration: none;
|
100 |
-
}
|
101 |
-
|
102 |
-
.tnp-welcome-prev {
|
103 |
-
background-color: #3498DB;
|
104 |
-
padding: 10px 20px;
|
105 |
-
color: white;
|
106 |
-
text-decoration: none;
|
107 |
-
font-weight: 600;
|
108 |
-
font-size: 16px;
|
109 |
-
margin: 0px 0px 0px 10px;
|
110 |
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);
|
111 |
-
width: -moz-fit-content;
|
112 |
-
width: -webkit-fit-content;
|
113 |
-
width: fit-content;
|
114 |
-
display: flex;
|
115 |
-
align-items: center;
|
116 |
-
}
|
117 |
-
|
118 |
-
.tnp-welcome-prev:hover {
|
119 |
-
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
120 |
-
color: #fff;
|
121 |
-
}
|
122 |
-
|
123 |
-
.tnp-welcome-prev:visited {
|
124 |
-
color: #fff;
|
125 |
-
text-decoration: none;
|
126 |
-
}
|
127 |
-
|
128 |
-
.tnp-welcome-next svg {
|
129 |
-
margin-left: 10px;
|
130 |
-
}
|
131 |
-
|
132 |
-
.tnp-welcome-prev svg {
|
133 |
-
margin-right: 10px;
|
134 |
-
}
|
135 |
-
|
136 |
-
.cd-slider input {
|
137 |
-
width: 250px;
|
138 |
-
height: 40px;
|
139 |
-
border: 1px solid #6c7280;
|
140 |
-
background: #454a56;
|
141 |
-
color: white;
|
142 |
-
color: white;
|
143 |
-
padding: 0px 10px;
|
144 |
-
}
|
145 |
-
|
146 |
-
.cd-slider > li {
|
147 |
-
position: absolute;
|
148 |
-
top: 0;
|
149 |
-
left: 0;
|
150 |
-
opacity: 0;
|
151 |
-
/* used to vertically center its content */
|
152 |
-
display: table;
|
153 |
-
background-position: center center;
|
154 |
-
background-repeat: no-repeat;
|
155 |
-
-webkit-font-smoothing: antialiased;
|
156 |
-
-moz-osx-font-smoothing: grayscale;
|
157 |
-
}
|
158 |
-
.cd-slider > li.visible {
|
159 |
-
/* selected slide */
|
160 |
-
position: relative;
|
161 |
-
z-index: 2;
|
162 |
-
opacity: 1;
|
163 |
-
}
|
164 |
-
.cd-slider > li:first-of-type {
|
165 |
-
background-color: #2B313A;
|
166 |
-
}
|
167 |
-
.cd-slider > li:nth-of-type(2) {
|
168 |
-
background-color: #2B313A;
|
169 |
-
}
|
170 |
-
.cd-slider > li:nth-of-type(3) {
|
171 |
-
background-color: #2B313A;
|
172 |
-
}
|
173 |
-
.cd-slider > li:nth-of-type(4) {
|
174 |
-
background-color: #2B313A;
|
175 |
-
}
|
176 |
-
.cd-slider > li:first-of-type, .cd-slider > li:nth-of-type(2), .cd-slider > li:nth-of-type(3), .cd-slider > li:nth-of-type(4) {
|
177 |
-
background-size: cover;
|
178 |
-
}
|
179 |
-
.cd-slider > li > div {
|
180 |
-
/* vertically center the slider content */
|
181 |
-
display: table-cell;
|
182 |
-
vertical-align: middle;
|
183 |
-
text-align: center;
|
184 |
-
}
|
185 |
-
.cd-slider > li h2, .cd-slider > li p {
|
186 |
-
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
187 |
-
line-height: 1.2;
|
188 |
-
margin: 0 auto 14px;
|
189 |
-
color: #ffffff;
|
190 |
-
width: 90%;
|
191 |
-
max-width: 320px;
|
192 |
-
}
|
193 |
-
.cd-slider > li h2 {
|
194 |
-
font-size: 40px;
|
195 |
-
}
|
196 |
-
.cd-slider > li p {
|
197 |
-
font-size: 18px;
|
198 |
-
line-height: 26px;
|
199 |
-
text-align: left;
|
200 |
-
color: #B8C3C9;
|
201 |
-
margin: 40px auto;
|
202 |
-
}
|
203 |
-
|
204 |
-
.cd-slider > li .cd-btn {
|
205 |
-
display: inline-block;
|
206 |
-
padding: 1.2em 1.4em;
|
207 |
-
margin-top: .8em;
|
208 |
-
background-color: rgba(0, 0, 0, 0.6);
|
209 |
-
border-radius: .25em;
|
210 |
-
font-size: 1.3rem;
|
211 |
-
font-weight: 700;
|
212 |
-
letter-spacing: 1px;
|
213 |
-
color: #ffffff;
|
214 |
-
text-transform: uppercase;
|
215 |
-
-webkit-transition: background-color 0.2s;
|
216 |
-
-moz-transition: background-color 0.2s;
|
217 |
-
transition: background-color 0.2s;
|
218 |
-
}
|
219 |
-
.no-touch .cd-slider > li .cd-btn:hover {
|
220 |
-
background-color: rgba(0, 0, 0, 0.8);
|
221 |
-
}
|
222 |
-
@media only screen and (min-width: 768px) {
|
223 |
-
.cd-slider > li h2, .cd-slider > li p {
|
224 |
-
max-width: 520px;
|
225 |
-
}
|
226 |
-
.cd-slider > li h2 {
|
227 |
-
font-size: 40px;
|
228 |
-
}
|
229 |
-
.cd-slider > li p {
|
230 |
-
font-size: 18px;
|
231 |
-
line-height: 26px;
|
232 |
-
text-align: left;
|
233 |
-
color: #B8C3C9;
|
234 |
-
margin: 40px auto;
|
235 |
-
|
236 |
-
}
|
237 |
-
}
|
238 |
-
@media only screen and (min-width: 1170px) {
|
239 |
-
.cd-slider > li h2, .cd-slider > li p {
|
240 |
-
margin-bottom: 20px;
|
241 |
-
}
|
242 |
-
.cd-slider > li h2 {
|
243 |
-
font-size: 40px;
|
244 |
-
}
|
245 |
-
.cd-slider > li p {
|
246 |
-
font-size: 18px;
|
247 |
-
line-height: 26px;
|
248 |
-
text-align: center;
|
249 |
-
color: #B8C3C9;
|
250 |
-
margin: 30px auto;
|
251 |
-
}
|
252 |
-
}
|
253 |
-
|
254 |
-
/* --------------------------------
|
255 |
-
|
256 |
-
Tnp Welcome Slider Navigation
|
257 |
-
|
258 |
-
-------------------------------- */
|
259 |
-
.cd-slider-navigation {
|
260 |
-
position: relative;
|
261 |
-
bottom: 110px;
|
262 |
-
z-index: 3;
|
263 |
-
display: flex;
|
264 |
-
justify-content: center;
|
265 |
-
}
|
266 |
-
|
267 |
-
/* svg cover layer */
|
268 |
-
|
269 |
-
.cd-svg-cover {
|
270 |
-
position: absolute;
|
271 |
-
z-index: 1;
|
272 |
-
left: 0;
|
273 |
-
top: 0;
|
274 |
-
height: 100%;
|
275 |
-
width: 100%;
|
276 |
-
opacity: 0;
|
277 |
-
}
|
278 |
-
.cd-svg-cover path {
|
279 |
-
fill: #ED6A6A;
|
280 |
-
}
|
281 |
-
.cd-svg-cover.is-animating {
|
282 |
-
z-index: 4;
|
283 |
-
opacity: 1;
|
284 |
-
-webkit-transition: opacity 0.6s;
|
285 |
-
-moz-transition: opacity 0.6s;
|
286 |
-
transition: opacity 0.6s;
|
287 |
-
}
|
288 |
-
|
289 |
-
/* Switch element style */
|
290 |
-
|
291 |
-
/* The switch - the box around the slider */
|
292 |
-
.switch {
|
293 |
-
position: relative;
|
294 |
-
display: inline-block;
|
295 |
-
width: 60px;
|
296 |
-
height: 34px;
|
297 |
-
}
|
298 |
-
|
299 |
-
/* Hide default HTML checkbox */
|
300 |
-
.switch input {display:none;}
|
301 |
-
|
302 |
-
/* The slider */
|
303 |
-
.slider {
|
304 |
-
position: absolute;
|
305 |
-
cursor: pointer;
|
306 |
-
top: 0;
|
307 |
-
left: 0;
|
308 |
-
right: 0;
|
309 |
-
bottom: 0;
|
310 |
-
background-color: #ccc;
|
311 |
-
-webkit-transition: .4s;
|
312 |
-
transition: .4s;
|
313 |
-
}
|
314 |
-
|
315 |
-
.slider:before {
|
316 |
-
position: absolute;
|
317 |
-
content: "";
|
318 |
-
height: 26px;
|
319 |
-
width: 26px;
|
320 |
-
left: 4px;
|
321 |
-
bottom: 4px;
|
322 |
-
background-color: white;
|
323 |
-
-webkit-transition: .4s;
|
324 |
-
transition: .4s;
|
325 |
-
}
|
326 |
-
|
327 |
-
input:checked + .slider {
|
328 |
-
background-color: #2196F3;
|
329 |
-
}
|
330 |
-
|
331 |
-
input:focus + .slider {
|
332 |
-
box-shadow: 0 0 1px #2196F3;
|
333 |
-
}
|
334 |
-
|
335 |
-
input:checked + .slider:before {
|
336 |
-
-webkit-transform: translateX(26px);
|
337 |
-
-ms-transform: translateX(26px);
|
338 |
-
transform: translateX(26px);
|
339 |
-
}
|
340 |
-
|
341 |
-
/* Rounded sliders */
|
342 |
-
.slider.round {
|
343 |
-
border-radius: 34px;
|
344 |
-
}
|
345 |
-
|
346 |
-
.slider.round:before {
|
347 |
-
border-radius: 50%;
|
348 |
-
}
|
1 |
+
/* This is loaded inline in the welcome.php page */
|
2 |
+
|
3 |
+
.cd-slider-wrapper {
|
4 |
+
position: relative;
|
5 |
+
width: 100%;
|
6 |
+
height: 90vh;
|
7 |
+
/* hide horizontal scrollbar on IE11 */
|
8 |
+
overflow: hidden;
|
9 |
+
margin: 0 auto;
|
10 |
+
}
|
11 |
+
.cd-slider-wrapper .cd-slider, .cd-slider-wrapper .cd-slider > li {
|
12 |
+
height: 100%;
|
13 |
+
width: 100%;
|
14 |
+
}
|
15 |
+
|
16 |
+
.tnp-logo-big {
|
17 |
+
width: 300px;
|
18 |
+
}
|
19 |
+
|
20 |
+
.tnp-row {
|
21 |
+
display: table-row;
|
22 |
+
}
|
23 |
+
|
24 |
+
.tnp-third {
|
25 |
+
width: 33%;
|
26 |
+
float: left;
|
27 |
+
}
|
28 |
+
|
29 |
+
.tnp-welcome-confirm-button {
|
30 |
+
color: #fff;
|
31 |
+
padding: 10px 30px;
|
32 |
+
background-color: #2ECC71;
|
33 |
+
font-weight: 700;
|
34 |
+
font-size: 15px;
|
35 |
+
box-shadow: 0 20px 38px rgba(0, 0, 0, 0.16);
|
36 |
+
text-decoration: none;
|
37 |
+
display: inline-block;
|
38 |
+
text-align: center;
|
39 |
+
margin: 20px auto 0px;
|
40 |
+
}
|
41 |
+
|
42 |
+
.tnp-welcome-confirm-button:hover {
|
43 |
+
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
44 |
+
color: #fff;
|
45 |
+
}
|
46 |
+
|
47 |
+
.tnp-welcome-confirm-button:visited {
|
48 |
+
color: #fff;
|
49 |
+
text-decoration: none;
|
50 |
+
}
|
51 |
+
|
52 |
+
.tnp-welcome-link-button {
|
53 |
+
color: #fff;
|
54 |
+
padding: 10px 30px;
|
55 |
+
background-color: #3498DB;
|
56 |
+
font-weight: 700;
|
57 |
+
font-size: 15px;
|
58 |
+
box-shadow: 0 20px 38px rgba(0, 0, 0, 0.16);
|
59 |
+
text-decoration: none;
|
60 |
+
}
|
61 |
+
|
62 |
+
.tnp-welcome-link-button:hover {
|
63 |
+
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
64 |
+
color: #fff;
|
65 |
+
}
|
66 |
+
|
67 |
+
.tnp-welcome-link-button:visited {
|
68 |
+
color: #fff;
|
69 |
+
text-decoration: none;
|
70 |
+
}
|
71 |
+
|
72 |
+
#tnp-welcome input[type="text"], #tnp-welcome input[type="email"] {
|
73 |
+
max-width: 90%;
|
74 |
+
}
|
75 |
+
|
76 |
+
.tnp-welcome-next {
|
77 |
+
background-color: #2ECC71;
|
78 |
+
padding: 10px 20px;
|
79 |
+
color: white;
|
80 |
+
text-decoration: none;
|
81 |
+
font-weight: 600;
|
82 |
+
font-size: 16px;
|
83 |
+
margin: 0px 10px;
|
84 |
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);
|
85 |
+
width: -moz-fit-content;
|
86 |
+
width: -webkit-fit-content;
|
87 |
+
width: fit-content;
|
88 |
+
display: flex;
|
89 |
+
align-items: center;
|
90 |
+
}
|
91 |
+
|
92 |
+
.tnp-welcome-next:hover {
|
93 |
+
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
94 |
+
color: #fff;
|
95 |
+
}
|
96 |
+
|
97 |
+
.tnp-welcome-next:visited {
|
98 |
+
color: #fff;
|
99 |
+
text-decoration: none;
|
100 |
+
}
|
101 |
+
|
102 |
+
.tnp-welcome-prev {
|
103 |
+
background-color: #3498DB;
|
104 |
+
padding: 10px 20px;
|
105 |
+
color: white;
|
106 |
+
text-decoration: none;
|
107 |
+
font-weight: 600;
|
108 |
+
font-size: 16px;
|
109 |
+
margin: 0px 0px 0px 10px;
|
110 |
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);
|
111 |
+
width: -moz-fit-content;
|
112 |
+
width: -webkit-fit-content;
|
113 |
+
width: fit-content;
|
114 |
+
display: flex;
|
115 |
+
align-items: center;
|
116 |
+
}
|
117 |
+
|
118 |
+
.tnp-welcome-prev:hover {
|
119 |
+
box-shadow: 0 0 38px rgba(0, 0, 0, 0.16);
|
120 |
+
color: #fff;
|
121 |
+
}
|
122 |
+
|
123 |
+
.tnp-welcome-prev:visited {
|
124 |
+
color: #fff;
|
125 |
+
text-decoration: none;
|
126 |
+
}
|
127 |
+
|
128 |
+
.tnp-welcome-next svg {
|
129 |
+
margin-left: 10px;
|
130 |
+
}
|
131 |
+
|
132 |
+
.tnp-welcome-prev svg {
|
133 |
+
margin-right: 10px;
|
134 |
+
}
|
135 |
+
|
136 |
+
.cd-slider input {
|
137 |
+
width: 250px;
|
138 |
+
height: 40px;
|
139 |
+
border: 1px solid #6c7280;
|
140 |
+
background: #454a56;
|
141 |
+
color: white;
|
142 |
+
color: white;
|
143 |
+
padding: 0px 10px;
|
144 |
+
}
|
145 |
+
|
146 |
+
.cd-slider > li {
|
147 |
+
position: absolute;
|
148 |
+
top: 0;
|
149 |
+
left: 0;
|
150 |
+
opacity: 0;
|
151 |
+
/* used to vertically center its content */
|
152 |
+
display: table;
|
153 |
+
background-position: center center;
|
154 |
+
background-repeat: no-repeat;
|
155 |
+
-webkit-font-smoothing: antialiased;
|
156 |
+
-moz-osx-font-smoothing: grayscale;
|
157 |
+
}
|
158 |
+
.cd-slider > li.visible {
|
159 |
+
/* selected slide */
|
160 |
+
position: relative;
|
161 |
+
z-index: 2;
|
162 |
+
opacity: 1;
|
163 |
+
}
|
164 |
+
.cd-slider > li:first-of-type {
|
165 |
+
background-color: #2B313A;
|
166 |
+
}
|
167 |
+
.cd-slider > li:nth-of-type(2) {
|
168 |
+
background-color: #2B313A;
|
169 |
+
}
|
170 |
+
.cd-slider > li:nth-of-type(3) {
|
171 |
+
background-color: #2B313A;
|
172 |
+
}
|
173 |
+
.cd-slider > li:nth-of-type(4) {
|
174 |
+
background-color: #2B313A;
|
175 |
+
}
|
176 |
+
.cd-slider > li:first-of-type, .cd-slider > li:nth-of-type(2), .cd-slider > li:nth-of-type(3), .cd-slider > li:nth-of-type(4) {
|
177 |
+
background-size: cover;
|
178 |
+
}
|
179 |
+
.cd-slider > li > div {
|
180 |
+
/* vertically center the slider content */
|
181 |
+
display: table-cell;
|
182 |
+
vertical-align: middle;
|
183 |
+
text-align: center;
|
184 |
+
}
|
185 |
+
.cd-slider > li h2, .cd-slider > li p {
|
186 |
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
187 |
+
line-height: 1.2;
|
188 |
+
margin: 0 auto 14px;
|
189 |
+
color: #ffffff;
|
190 |
+
width: 90%;
|
191 |
+
max-width: 320px;
|
192 |
+
}
|
193 |
+
.cd-slider > li h2 {
|
194 |
+
font-size: 40px;
|
195 |
+
}
|
196 |
+
.cd-slider > li p {
|
197 |
+
font-size: 18px;
|
198 |
+
line-height: 26px;
|
199 |
+
text-align: left;
|
200 |
+
color: #B8C3C9;
|
201 |
+
margin: 40px auto;
|
202 |
+
}
|
203 |
+
|
204 |
+
.cd-slider > li .cd-btn {
|
205 |
+
display: inline-block;
|
206 |
+
padding: 1.2em 1.4em;
|
207 |
+
margin-top: .8em;
|
208 |
+
background-color: rgba(0, 0, 0, 0.6);
|
209 |
+
border-radius: .25em;
|
210 |
+
font-size: 1.3rem;
|
211 |
+
font-weight: 700;
|
212 |
+
letter-spacing: 1px;
|
213 |
+
color: #ffffff;
|
214 |
+
text-transform: uppercase;
|
215 |
+
-webkit-transition: background-color 0.2s;
|
216 |
+
-moz-transition: background-color 0.2s;
|
217 |
+
transition: background-color 0.2s;
|
218 |
+
}
|
219 |
+
.no-touch .cd-slider > li .cd-btn:hover {
|
220 |
+
background-color: rgba(0, 0, 0, 0.8);
|
221 |
+
}
|
222 |
+
@media only screen and (min-width: 768px) {
|
223 |
+
.cd-slider > li h2, .cd-slider > li p {
|
224 |
+
max-width: 520px;
|
225 |
+
}
|
226 |
+
.cd-slider > li h2 {
|
227 |
+
font-size: 40px;
|
228 |
+
}
|
229 |
+
.cd-slider > li p {
|
230 |
+
font-size: 18px;
|
231 |
+
line-height: 26px;
|
232 |
+
text-align: left;
|
233 |
+
color: #B8C3C9;
|
234 |
+
margin: 40px auto;
|
235 |
+
|
236 |
+
}
|
237 |
+
}
|
238 |
+
@media only screen and (min-width: 1170px) {
|
239 |
+
.cd-slider > li h2, .cd-slider > li p {
|
240 |
+
margin-bottom: 20px;
|
241 |
+
}
|
242 |
+
.cd-slider > li h2 {
|
243 |
+
font-size: 40px;
|
244 |
+
}
|
245 |
+
.cd-slider > li p {
|
246 |
+
font-size: 18px;
|
247 |
+
line-height: 26px;
|
248 |
+
text-align: center;
|
249 |
+
color: #B8C3C9;
|
250 |
+
margin: 30px auto;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
/* --------------------------------
|
255 |
+
|
256 |
+
Tnp Welcome Slider Navigation
|
257 |
+
|
258 |
+
-------------------------------- */
|
259 |
+
.cd-slider-navigation {
|
260 |
+
position: relative;
|
261 |
+
bottom: 110px;
|
262 |
+
z-index: 3;
|
263 |
+
display: flex;
|
264 |
+
justify-content: center;
|
265 |
+
}
|
266 |
+
|
267 |
+
/* svg cover layer */
|
268 |
+
|
269 |
+
.cd-svg-cover {
|
270 |
+
position: absolute;
|
271 |
+
z-index: 1;
|
272 |
+
left: 0;
|
273 |
+
top: 0;
|
274 |
+
height: 100%;
|
275 |
+
width: 100%;
|
276 |
+
opacity: 0;
|
277 |
+
}
|
278 |
+
.cd-svg-cover path {
|
279 |
+
fill: #ED6A6A;
|
280 |
+
}
|
281 |
+
.cd-svg-cover.is-animating {
|
282 |
+
z-index: 4;
|
283 |
+
opacity: 1;
|
284 |
+
-webkit-transition: opacity 0.6s;
|
285 |
+
-moz-transition: opacity 0.6s;
|
286 |
+
transition: opacity 0.6s;
|
287 |
+
}
|
288 |
+
|
289 |
+
/* Switch element style */
|
290 |
+
|
291 |
+
/* The switch - the box around the slider */
|
292 |
+
.switch {
|
293 |
+
position: relative;
|
294 |
+
display: inline-block;
|
295 |
+
width: 60px;
|
296 |
+
height: 34px;
|
297 |
+
}
|
298 |
+
|
299 |
+
/* Hide default HTML checkbox */
|
300 |
+
.switch input {display:none;}
|
301 |
+
|
302 |
+
/* The slider */
|
303 |
+
.slider {
|
304 |
+
position: absolute;
|
305 |
+
cursor: pointer;
|
306 |
+
top: 0;
|
307 |
+
left: 0;
|
308 |
+
right: 0;
|
309 |
+
bottom: 0;
|
310 |
+
background-color: #ccc;
|
311 |
+
-webkit-transition: .4s;
|
312 |
+
transition: .4s;
|
313 |
+
}
|
314 |
+
|
315 |
+
.slider:before {
|
316 |
+
position: absolute;
|
317 |
+
content: "";
|
318 |
+
height: 26px;
|
319 |
+
width: 26px;
|
320 |
+
left: 4px;
|
321 |
+
bottom: 4px;
|
322 |
+
background-color: white;
|
323 |
+
-webkit-transition: .4s;
|
324 |
+
transition: .4s;
|
325 |
+
}
|
326 |
+
|
327 |
+
input:checked + .slider {
|
328 |
+
background-color: #2196F3;
|
329 |
+
}
|
330 |
+
|
331 |
+
input:focus + .slider {
|
332 |
+
box-shadow: 0 0 1px #2196F3;
|
333 |
+
}
|
334 |
+
|
335 |
+
input:checked + .slider:before {
|
336 |
+
-webkit-transform: translateX(26px);
|
337 |
+
-ms-transform: translateX(26px);
|
338 |
+
transform: translateX(26px);
|
339 |
+
}
|
340 |
+
|
341 |
+
/* Rounded sliders */
|
342 |
+
.slider.round {
|
343 |
+
border-radius: 34px;
|
344 |
+
}
|
345 |
+
|
346 |
+
.slider.round:before {
|
347 |
+
border-radius: 50%;
|
348 |
+
}
|
main/delivery.php
CHANGED
@@ -92,7 +92,6 @@ function tnp_get_hook_functions($tag) {
|
|
92 |
foreach ($wp_filter[$tag]->callbacks as $priority => $functions) {
|
93 |
|
94 |
foreach ($functions as $function) {
|
95 |
-
//var_dump($function);
|
96 |
$b .= '[' . $priority . '] ';
|
97 |
if (is_array($function['function'])) {
|
98 |
if (is_object($function['function'][0])) {
|
92 |
foreach ($wp_filter[$tag]->callbacks as $priority => $functions) {
|
93 |
|
94 |
foreach ($functions as $function) {
|
|
|
95 |
$b .= '[' . $priority . '] ';
|
96 |
if (is_array($function['function'])) {
|
97 |
if (is_object($function['function'][0])) {
|
main/diagnostic.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $this Newsletter */
|
3 |
-
/* @var $wpdb wpdb */
|
4 |
-
|
5 |
-
defined('ABSPATH') || exit;
|
6 |
-
|
7 |
-
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
8 |
-
$controls = new NewsletterControls();
|
9 |
-
|
10 |
-
function tnp_get_hook_functions($tag) {
|
11 |
-
global $wp_filter;
|
12 |
-
if (isset($wp_filter)) {
|
13 |
-
$b = '';
|
14 |
-
foreach ($wp_filter[$tag]->callbacks as $priority => $functions) {
|
15 |
-
|
16 |
-
foreach ($functions as $function) {
|
17 |
-
//var_dump($function);
|
18 |
-
$b .= '[' . $priority . '] ';
|
19 |
-
if (is_array($function['function'])) {
|
20 |
-
if (is_object($function['function'][0])) {
|
21 |
-
$b .= get_class($function['function'][0]) . '::' . $function['function'][1];
|
22 |
-
} else {
|
23 |
-
$b .= $function['function'][0] . '::' . $function['function'][1];
|
24 |
-
}
|
25 |
-
} else {
|
26 |
-
if (is_object($function['function'])) {
|
27 |
-
$fn = new ReflectionFunction($function['function']);
|
28 |
-
$b .= get_class($fn->getClosureThis()) . '(closure)';
|
29 |
-
} else {
|
30 |
-
$b .= $function['function'];
|
31 |
-
}
|
32 |
-
}
|
33 |
-
$b .= "<br>";
|
34 |
-
}
|
35 |
-
}
|
36 |
-
}
|
37 |
-
return $b;
|
38 |
-
}
|
39 |
-
?>
|
40 |
-
|
41 |
-
<div class="wrap tnp-main-diagnostic" id="tnp-wrap">
|
42 |
-
|
43 |
-
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
44 |
-
|
45 |
-
<div id="tnp-heading">
|
46 |
-
|
47 |
-
<h2><?php _e('Diagnostic', 'newsletter') ?></h2>
|
48 |
-
|
49 |
-
</div>
|
50 |
-
|
51 |
-
<div id="tnp-body">
|
52 |
-
|
53 |
-
<form method="post" action="">
|
54 |
-
<?php $controls->init(); ?>
|
55 |
-
|
56 |
-
<h3>Hooks</h3>
|
57 |
-
<table class="widefat" id="tnp-status-table">
|
58 |
-
|
59 |
-
<thead>
|
60 |
-
<tr>
|
61 |
-
<th>Parameter</th>
|
62 |
-
<th><?php _e('Status', 'newsletter') ?></th>
|
63 |
-
<th>Action</th>
|
64 |
-
</tr>
|
65 |
-
</thead>
|
66 |
-
|
67 |
-
<tbody>
|
68 |
-
<tr>
|
69 |
-
<td>Filter "newsletter_replace"</td>
|
70 |
-
<td>
|
71 |
-
</td>
|
72 |
-
<td>
|
73 |
-
<?php echo tnp_get_hook_functions('newsletter_replace') ?>
|
74 |
-
</td>
|
75 |
-
|
76 |
-
</tr>
|
77 |
-
</tbody>
|
78 |
-
</table>
|
79 |
-
</form>
|
80 |
-
</div>
|
81 |
-
|
82 |
-
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
83 |
-
|
84 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main/index.php
CHANGED
@@ -1,318 +1,318 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $this Newsletter */
|
3 |
-
|
4 |
-
defined('ABSPATH') || exit;
|
5 |
-
|
6 |
-
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
7 |
-
$controls = new NewsletterControls();
|
8 |
-
|
9 |
-
wp_enqueue_script('tnp-chart');
|
10 |
-
|
11 |
-
if ($controls->is_action('feed_enable')) {
|
12 |
-
delete_option('newsletter_feed_demo_disable');
|
13 |
-
$controls->messages = 'Feed by Mail demo panels enabled. On next page reload it will show up.';
|
14 |
-
}
|
15 |
-
|
16 |
-
if ($controls->is_action('feed_disable')) {
|
17 |
-
update_option('newsletter_feed_demo_disable', 1);
|
18 |
-
$controls->messages = 'Feed by Mail demo panel disabled. On next page reload it will disappear.';
|
19 |
-
}
|
20 |
-
|
21 |
-
$emails_module = NewsletterEmails::instance();
|
22 |
-
$statistics_module = NewsletterStatistics::instance();
|
23 |
-
$emails = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where type='message' order by id desc limit 5");
|
24 |
-
|
25 |
-
$users_module = NewsletterUsers::instance();
|
26 |
-
$query = "select * from " . NEWSLETTER_USERS_TABLE . " order by id desc limit 5";
|
27 |
-
$subscribers = $wpdb->get_results($query);
|
28 |
-
|
29 |
-
// Retrieves the last standard newsletter
|
30 |
-
$last_email = $wpdb->get_row(
|
31 |
-
$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()));
|
32 |
-
|
33 |
-
if ($last_email) {
|
34 |
-
$report = $statistics_module->get_statistics($last_email);
|
35 |
-
$last_email_sent = $report->total;
|
36 |
-
$last_email_opened = $report->open_count;
|
37 |
-
$last_email_notopened = $last_email_sent - $last_email_opened;
|
38 |
-
$last_email_clicked = $report->click_count;
|
39 |
-
$last_email_opened -= $last_email_clicked;
|
40 |
-
|
41 |
-
$overall_sent = $wpdb->get_var("select sum(sent) from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending')");
|
42 |
-
|
43 |
-
$overall_opened = $wpdb->get_var("select count(distinct user_id,email_id) from " . NEWSLETTER_STATS_TABLE);
|
44 |
-
$overall_notopened = $overall_sent - $overall_opened;
|
45 |
-
$overall_clicked = $wpdb->get_var("select count(distinct user_id,email_id) from " . NEWSLETTER_STATS_TABLE . " where url<>''");
|
46 |
-
$overall_opened -= $overall_clicked;
|
47 |
-
} else {
|
48 |
-
$last_email_opened = 500;
|
49 |
-
$last_email_notopened = 400;
|
50 |
-
$last_email_clicked = 200;
|
51 |
-
|
52 |
-
$overall_opened = 500;
|
53 |
-
$overall_notopened = 400;
|
54 |
-
$overall_clicked = 200;
|
55 |
-
}
|
56 |
-
|
57 |
-
$months = $wpdb->get_results("select count(*) as c, concat(year(created), '-', date_format(created, '%m')) as d "
|
58 |
-
. "from " . NEWSLETTER_USERS_TABLE . " where status='C' "
|
59 |
-
. "group by concat(year(created), '-', date_format(created, '%m')) order by d desc limit 12");
|
60 |
-
$values = array();
|
61 |
-
$labels = array();
|
62 |
-
foreach ($months as $month) {
|
63 |
-
$values[] = (int) $month->c;
|
64 |
-
$labels[] = date("M y", date_create_from_format("Y-m", $month->d)->getTimestamp());
|
65 |
-
}
|
66 |
-
$values = array_reverse($values);
|
67 |
-
$labels = array_reverse($labels);
|
68 |
-
|
69 |
-
$lists = $this->get_lists();
|
70 |
-
?>
|
71 |
-
|
72 |
-
<style>
|
73 |
-
<?php include
|
74 |
-
</style>
|
75 |
-
|
76 |
-
<div class="wrap" id="tnp-wrap">
|
77 |
-
|
78 |
-
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
79 |
-
|
80 |
-
<div id="tnp-body" class="tnp-main-index">
|
81 |
-
<div class="tnp-dashboard">
|
82 |
-
<div class="tnp-cards-container">
|
83 |
-
<div class="tnp-card tnp-mimosa">
|
84 |
-
<div class="tnp-card-title">Forms</div>
|
85 |
-
<div class="tnp-card-description">Setup the form fields and labels.</div>
|
86 |
-
<div class="tnp-card-button-container">
|
87 |
-
<a href="?page=newsletter_subscription_profile">Edit forms</a>
|
88 |
-
</div>
|
89 |
-
</div>
|
90 |
-
<div class="tnp-card">
|
91 |
-
<div class="tnp-card-title">Lists</div>
|
92 |
-
<div class="tnp-card-description">You have <?php echo count($lists) ?> lists.</div>
|
93 |
-
<div class="tnp-card-button-container">
|
94 |
-
<a href="?page=newsletter_subscription_lists">Manage</a>
|
95 |
-
</div>
|
96 |
-
</div>
|
97 |
-
<div class="tnp-card">
|
98 |
-
<div class="tnp-card-title">Delivery</div>
|
99 |
-
<div class="tnp-card-description">Change the delivery speed, sender name and return path.</div>
|
100 |
-
<div class="tnp-card-button-container">
|
101 |
-
<a href="?page=newsletter_main_main">Change the delivery settings</a>
|
102 |
-
</div>
|
103 |
-
</div>
|
104 |
-
<div class="tnp-card">
|
105 |
-
<div class="tnp-card-title">Personal Info</div>
|
106 |
-
<div class="tnp-card-description">Set your company name, address, socials.</div>
|
107 |
-
<div class="tnp-card-button-container">
|
108 |
-
<a href="?page=newsletter_main_info">Edit your info</a>
|
109 |
-
</div>
|
110 |
-
</div>
|
111 |
-
</div>
|
112 |
-
<div class="tnp-cards-container">
|
113 |
-
<div class="tnp-card">
|
114 |
-
<div class="tnp-card-title">Newsletters</div>
|
115 |
-
<div class="tnp-card-upper-buttons"><a href="?page=newsletter_emails_composer"><?php _e('New', 'newsletter') ?></a></div>
|
116 |
-
<div class="tnp-card-upper-buttons"><a href="?page=newsletter_emails_index"><?php _e('List', 'newsletter') ?></a></div>
|
117 |
-
<div class="tnp-card-content">
|
118 |
-
<?php foreach ($emails as $email) { ?>
|
119 |
-
<div class="tnp-card-newsletter-list">
|
120 |
-
<?php
|
121 |
-
$subject = $email->subject ? $email->subject : "Newsletter #" . $email->id;
|
122 |
-
?>
|
123 |
-
<div class="tnp-card-newsletters-subject">
|
124 |
-
<?php echo esc_html($subject) ?>
|
125 |
-
</div>
|
126 |
-
<div class="tnp-card-newsletters-status">
|
127 |
-
<?php $emails_module->show_email_status_label($email) ?>
|
128 |
-
</div>
|
129 |
-
<div class="tnp-card-newsletters-progress">
|
130 |
-
<?php $emails_module->show_email_progress_bar($email, array('scheduled' => true)) ?>
|
131 |
-
</div>
|
132 |
-
<div class="tnp-card-newsletters-action">
|
133 |
-
<?php
|
134 |
-
if ($email->status === TNP_Email::STATUS_SENT || $email->status === TNP_Email::STATUS_SENDING) {
|
135 |
-
echo '<a class="button-primary" href="' . $statistics_module->get_statistics_url($email->id) . '"><i class="fas fa-chart-bar"></i></a>';
|
136 |
-
} else {
|
137 |
-
echo $emails_module->get_edit_button($email, true);
|
138 |
-
}
|
139 |
-
?>
|
140 |
-
</div>
|
141 |
-
</div>
|
142 |
-
<?php } ?>
|
143 |
-
</div>
|
144 |
-
</div>
|
145 |
-
|
146 |
-
<div class="tnp-card">
|
147 |
-
<div class="tnp-card-title">Last Subscribers</div>
|
148 |
-
<div class="tnp-card-upper-buttons"><a href="<?php echo $users_module->get_admin_page_url('new'); ?>"><?php _e('New', 'newsletter') ?></a></div>
|
149 |
-
<div class="tnp-card-upper-buttons"><a href="<?php echo $users_module->get_admin_page_url('index'); ?>"><?php _e('List', 'newsletter') ?></a></div>
|
150 |
-
<div class="tnp-card-content">
|
151 |
-
|
152 |
-
<?php foreach ($subscribers as $s) { ?>
|
153 |
-
<div class="tnp-card-newsletter-list">
|
154 |
-
<div class="tnp-card-newsletters-subscriber-email">
|
155 |
-
<?php echo esc_html($s->email) ?>
|
156 |
-
</div>
|
157 |
-
|
158 |
-
<div class="tnp-card-newsletters-subscriber-name">
|
159 |
-
<?php echo esc_html($s->name) ?> <?php echo esc_html($s->surname) ?>
|
160 |
-
</div>
|
161 |
-
<div class="tnp-card-newsletters-subscriber-status">
|
162 |
-
<?php echo $emails_module->get_user_status_label($s) ?>
|
163 |
-
</div>
|
164 |
-
<div class="tnp-card-newsletters-action">
|
165 |
-
<a class="button-primary"
|
166 |
-
title="<?php _e('Edit', 'newsletter') ?>"
|
167 |
-
href="<?php echo $users_module->get_admin_page_url('edit'); ?>&id=<?php echo $s->id; ?>"><i
|
168 |
-
class="fas fa-edit"></i></a>
|
169 |
-
<!--
|
170 |
-
<a title="<?php _e('Profile', 'newsletter') ?>"
|
171 |
-
href="<?php echo home_url('/') ?>?na=p&nk=<?php echo $s->id . '-' . $s->token; ?>"
|
172 |
-
class="button-primary" target="_blank"><i
|
173 |
-
class="fas fa-user"></i></a>-->
|
174 |
-
</div>
|
175 |
-
</div>
|
176 |
-
<?php } ?>
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
</div>
|
181 |
-
</div>
|
182 |
-
</div>
|
183 |
-
<div class="tnp-cards-container">
|
184 |
-
<div class="tnp-card">
|
185 |
-
<div class="tnp-card-title"><?php _e('Subscriptions', 'newsletter') ?></div>
|
186 |
-
<div class="tnp-canvas">
|
187 |
-
<canvas id="tnp-events-chart-canvas" height="300"></canvas>
|
188 |
-
</div>
|
189 |
-
|
190 |
-
<script type="text/javascript">
|
191 |
-
var events_data = {
|
192 |
-
labels: <?php echo json_encode($labels) ?>,
|
193 |
-
datasets: [
|
194 |
-
{
|
195 |
-
label: "<?php _e('Subscriptions', 'newsletter') ?>",
|
196 |
-
fill: true,
|
197 |
-
strokeColor: "#27AE60",
|
198 |
-
backgroundColor: "#293544",
|
199 |
-
borderColor: "#27AE60",
|
200 |
-
pointBorderColor: "#27AE60",
|
201 |
-
pointBackgroundColor: "#ECF0F1",
|
202 |
-
data: <?php echo json_encode($values) ?>
|
203 |
-
}
|
204 |
-
]
|
205 |
-
};
|
206 |
-
|
207 |
-
jQuery(document).ready(function ($) {
|
208 |
-
ctxe = $('#tnp-events-chart-canvas').get(0).getContext("2d");
|
209 |
-
eventsLineChart = new Chart(ctxe, {
|
210 |
-
type: 'line', data: events_data,
|
211 |
-
options: {
|
212 |
-
maintainAspectRatio: false,
|
213 |
-
xresponsive: true,
|
214 |
-
scales: {
|
215 |
-
xAxes: [{
|
216 |
-
type: "category",
|
217 |
-
"id": "x-axis-1",
|
218 |
-
gridLines: {display: false},
|
219 |
-
ticks: {fontFamily: "soleil"}
|
220 |
-
}],
|
221 |
-
yAxes: [
|
222 |
-
{
|
223 |
-
type: "linear",
|
224 |
-
"id": "y-axis-1",
|
225 |
-
gridLines: {display: false},
|
226 |
-
ticks: {fontFamily: "soleil"}
|
227 |
-
},
|
228 |
-
]
|
229 |
-
},
|
230 |
-
}
|
231 |
-
});
|
232 |
-
});
|
233 |
-
</script>
|
234 |
-
</div>
|
235 |
-
<div class="tnp-card">
|
236 |
-
<div class="tnp-card-title"><?php _e('Documentation', 'newsletter') ?></div>
|
237 |
-
<div class="break"></div>
|
238 |
-
<a href="https://www.thenewsletterplugin.com/documentation/installation/" target="_blank">
|
239 |
-
<div class="tnp-card-documentation-index">
|
240 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
241 |
-
Installation
|
242 |
-
</div>
|
243 |
-
</a>
|
244 |
-
<a href="https://www.thenewsletterplugin.com/documentation/subscription/" target="_blank">
|
245 |
-
<div class="tnp-card-documentation-index">
|
246 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
247 |
-
Subscription
|
248 |
-
</div>
|
249 |
-
</a>
|
250 |
-
<a href="https://www.thenewsletterplugin.com/category/tips" target="_blank">
|
251 |
-
<div class="tnp-card-documentation-index">
|
252 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
253 |
-
Tips & Tricks
|
254 |
-
</div>
|
255 |
-
</a>
|
256 |
-
<a href="https://www.thenewsletterplugin.com/documentation/subscribers-and-management/" target="_blank">
|
257 |
-
<div class="tnp-card-documentation-index">
|
258 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
259 |
-
Subscribers and management
|
260 |
-
</div>
|
261 |
-
</a>
|
262 |
-
<a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletters-module/" target="_blank">
|
263 |
-
<div class="tnp-card-documentation-index">
|
264 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
265 |
-
Creating Newsletters
|
266 |
-
</div>
|
267 |
-
</a>
|
268 |
-
<a href="https://www.thenewsletterplugin.com/documentation/addons/" target="_blank">
|
269 |
-
<div class="tnp-card-documentation-index">
|
270 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
271 |
-
Premium Addons
|
272 |
-
</div>
|
273 |
-
</a>
|
274 |
-
<a href="https://www.thenewsletterplugin.com/documentation/customization/" target="_blank">
|
275 |
-
<div class="tnp-card-documentation-index">
|
276 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
277 |
-
Customization
|
278 |
-
</div>
|
279 |
-
</a>
|
280 |
-
<a href="https://www.thenewsletterplugin.com/documentation/delivery-and-spam/" target="_blank">
|
281 |
-
<div class="tnp-card-documentation-index">
|
282 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
283 |
-
Delivery and spam
|
284 |
-
</div>
|
285 |
-
</a>
|
286 |
-
<a href="https://www.thenewsletterplugin.com/documentation/developers/" target="_blank">
|
287 |
-
<div class="tnp-card-documentation-index">
|
288 |
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
289 |
-
Developers & Advanced Topics
|
290 |
-
</div>
|
291 |
-
</a>
|
292 |
-
</div>
|
293 |
-
</div>
|
294 |
-
<div class="tnp-cards-container">
|
295 |
-
<div class="tnp-card" style="align-self: flex-start">
|
296 |
-
<div class="tnp-card-title"><?php _e('Developers', 'newsletter') ?></div>
|
297 |
-
<div class="tnp-card-description">Extending Newsletter by yourself? There is something for you as well!</div>
|
298 |
-
<div class="tnp-card-button-container">
|
299 |
-
<a href="https://www.thenewsletterplugin.com/documentation/developers/" target="_blank">Developer's love 💛</a>
|
300 |
-
</div>
|
301 |
-
</div>
|
302 |
-
<div class="tnp-card">
|
303 |
-
<div class="tnp-card-title"><?php _e('Video Tutorials', 'newsletter') ?></div>
|
304 |
-
<div class="tnp-card-description">We have some videos to help gest the most from Newsletter.</div>
|
305 |
-
<div class="tnp-card-video">
|
306 |
-
<iframe width="560" height="315" src="https://www.youtube.com/embed/zmVmW84Bw9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
307 |
-
</div>
|
308 |
-
<div class="tnp-card-button-container">
|
309 |
-
<a href="https://www.thenewsletterplugin.com/video-tutorials" target="_blank">See the videos</a>
|
310 |
-
</div>
|
311 |
-
</div>
|
312 |
-
</div>
|
313 |
-
|
314 |
-
</div>
|
315 |
-
|
316 |
-
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
317 |
-
|
318 |
-
</div>
|
1 |
+
<?php
|
2 |
+
/* @var $this Newsletter */
|
3 |
+
|
4 |
+
defined('ABSPATH') || exit;
|
5 |
+
|
6 |
+
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
7 |
+
$controls = new NewsletterControls();
|
8 |
+
|
9 |
+
wp_enqueue_script('tnp-chart');
|
10 |
+
|
11 |
+
if ($controls->is_action('feed_enable')) {
|
12 |
+
delete_option('newsletter_feed_demo_disable');
|
13 |
+
$controls->messages = 'Feed by Mail demo panels enabled. On next page reload it will show up.';
|
14 |
+
}
|
15 |
+
|
16 |
+
if ($controls->is_action('feed_disable')) {
|
17 |
+
update_option('newsletter_feed_demo_disable', 1);
|
18 |
+
$controls->messages = 'Feed by Mail demo panel disabled. On next page reload it will disappear.';
|
19 |
+
}
|
20 |
+
|
21 |
+
$emails_module = NewsletterEmails::instance();
|
22 |
+
$statistics_module = NewsletterStatistics::instance();
|
23 |
+
$emails = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where type='message' order by id desc limit 5");
|
24 |
+
|
25 |
+
$users_module = NewsletterUsers::instance();
|
26 |
+
$query = "select * from " . NEWSLETTER_USERS_TABLE . " order by id desc limit 5";
|
27 |
+
$subscribers = $wpdb->get_results($query);
|
28 |
+
|
29 |
+
// Retrieves the last standard newsletter
|
30 |
+
$last_email = $wpdb->get_row(
|
31 |
+
$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()));
|
32 |
+
|
33 |
+
if ($last_email) {
|
34 |
+
$report = $statistics_module->get_statistics($last_email);
|
35 |
+
$last_email_sent = $report->total;
|
36 |
+
$last_email_opened = $report->open_count;
|
37 |
+
$last_email_notopened = $last_email_sent - $last_email_opened;
|
38 |
+
$last_email_clicked = $report->click_count;
|
39 |
+
$last_email_opened -= $last_email_clicked;
|
40 |
+
|
41 |
+
$overall_sent = $wpdb->get_var("select sum(sent) from " . NEWSLETTER_EMAILS_TABLE . " where type='message' and status in ('sent', 'sending')");
|
42 |
+
|
43 |
+
$overall_opened = $wpdb->get_var("select count(distinct user_id,email_id) from " . NEWSLETTER_STATS_TABLE);
|
44 |
+
$overall_notopened = $overall_sent - $overall_opened;
|
45 |
+
$overall_clicked = $wpdb->get_var("select count(distinct user_id,email_id) from " . NEWSLETTER_STATS_TABLE . " where url<>''");
|
46 |
+
$overall_opened -= $overall_clicked;
|
47 |
+
} else {
|
48 |
+
$last_email_opened = 500;
|
49 |
+
$last_email_notopened = 400;
|
50 |
+
$last_email_clicked = 200;
|
51 |
+
|
52 |
+
$overall_opened = 500;
|
53 |
+
$overall_notopened = 400;
|
54 |
+
$overall_clicked = 200;
|
55 |
+
}
|
56 |
+
|
57 |
+
$months = $wpdb->get_results("select count(*) as c, concat(year(created), '-', date_format(created, '%m')) as d "
|
58 |
+
. "from " . NEWSLETTER_USERS_TABLE . " where status='C' "
|
59 |
+
. "group by concat(year(created), '-', date_format(created, '%m')) order by d desc limit 12");
|
60 |
+
$values = array();
|
61 |
+
$labels = array();
|
62 |
+
foreach ($months as $month) {
|
63 |
+
$values[] = (int) $month->c;
|
64 |
+
$labels[] = date("M y", date_create_from_format("Y-m", $month->d)->getTimestamp());
|
65 |
+
}
|
66 |
+
$values = array_reverse($values);
|
67 |
+
$labels = array_reverse($labels);
|
68 |
+
|
69 |
+
$lists = $this->get_lists();
|
70 |
+
?>
|
71 |
+
|
72 |
+
<style>
|
73 |
+
<?php include __DIR__ . '/css/dashboard.css' ?>
|
74 |
+
</style>
|
75 |
+
|
76 |
+
<div class="wrap" id="tnp-wrap">
|
77 |
+
|
78 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
79 |
+
|
80 |
+
<div id="tnp-body" class="tnp-main-index">
|
81 |
+
<div class="tnp-dashboard">
|
82 |
+
<div class="tnp-cards-container">
|
83 |
+
<div class="tnp-card tnp-mimosa">
|
84 |
+
<div class="tnp-card-title">Forms</div>
|
85 |
+
<div class="tnp-card-description">Setup the form fields and labels.</div>
|
86 |
+
<div class="tnp-card-button-container">
|
87 |
+
<a href="?page=newsletter_subscription_profile">Edit forms</a>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
<div class="tnp-card">
|
91 |
+
<div class="tnp-card-title">Lists</div>
|
92 |
+
<div class="tnp-card-description">You have <?php echo count($lists) ?> lists.</div>
|
93 |
+
<div class="tnp-card-button-container">
|
94 |
+
<a href="?page=newsletter_subscription_lists">Manage</a>
|
95 |
+
</div>
|
96 |
+
</div>
|
97 |
+
<div class="tnp-card">
|
98 |
+
<div class="tnp-card-title">Delivery</div>
|
99 |
+
<div class="tnp-card-description">Change the delivery speed, sender name and return path.</div>
|
100 |
+
<div class="tnp-card-button-container">
|
101 |
+
<a href="?page=newsletter_main_main">Change the delivery settings</a>
|
102 |
+
</div>
|
103 |
+
</div>
|
104 |
+
<div class="tnp-card">
|
105 |
+
<div class="tnp-card-title">Personal Info</div>
|
106 |
+
<div class="tnp-card-description">Set your company name, address, socials.</div>
|
107 |
+
<div class="tnp-card-button-container">
|
108 |
+
<a href="?page=newsletter_main_info">Edit your info</a>
|
109 |
+
</div>
|
110 |
+
</div>
|
111 |
+
</div>
|
112 |
+
<div class="tnp-cards-container">
|
113 |
+
<div class="tnp-card">
|
114 |
+
<div class="tnp-card-title">Newsletters</div>
|
115 |
+
<div class="tnp-card-upper-buttons"><a href="?page=newsletter_emails_composer"><?php _e('New', 'newsletter') ?></a></div>
|
116 |
+
<div class="tnp-card-upper-buttons"><a href="?page=newsletter_emails_index"><?php _e('List', 'newsletter') ?></a></div>
|
117 |
+
<div class="tnp-card-content">
|
118 |
+
<?php foreach ($emails as $email) { ?>
|
119 |
+
<div class="tnp-card-newsletter-list">
|
120 |
+
<?php
|
121 |
+
$subject = $email->subject ? $email->subject : "Newsletter #" . $email->id;
|
122 |
+
?>
|
123 |
+
<div class="tnp-card-newsletters-subject">
|
124 |
+
<?php echo esc_html($subject) ?>
|
125 |
+
</div>
|
126 |
+
<div class="tnp-card-newsletters-status">
|
127 |
+
<?php $emails_module->show_email_status_label($email) ?>
|
128 |
+
</div>
|
129 |
+
<div class="tnp-card-newsletters-progress">
|
130 |
+
<?php $emails_module->show_email_progress_bar($email, array('scheduled' => true)) ?>
|
131 |
+
</div>
|
132 |
+
<div class="tnp-card-newsletters-action">
|
133 |
+
<?php
|
134 |
+
if ($email->status === TNP_Email::STATUS_SENT || $email->status === TNP_Email::STATUS_SENDING) {
|
135 |
+
echo '<a class="button-primary" href="' . $statistics_module->get_statistics_url($email->id) . '"><i class="fas fa-chart-bar"></i></a>';
|
136 |
+
} else {
|
137 |
+
echo $emails_module->get_edit_button($email, true);
|
138 |
+
}
|
139 |
+
?>
|
140 |
+
</div>
|
141 |
+
</div>
|
142 |
+
<?php } ?>
|
143 |
+
</div>
|
144 |
+
</div>
|
145 |
+
|
146 |
+
<div class="tnp-card">
|
147 |
+
<div class="tnp-card-title">Last Subscribers</div>
|
148 |
+
<div class="tnp-card-upper-buttons"><a href="<?php echo $users_module->get_admin_page_url('new'); ?>"><?php _e('New', 'newsletter') ?></a></div>
|
149 |
+
<div class="tnp-card-upper-buttons"><a href="<?php echo $users_module->get_admin_page_url('index'); ?>"><?php _e('List', 'newsletter') ?></a></div>
|
150 |
+
<div class="tnp-card-content">
|
151 |
+
|
152 |
+
<?php foreach ($subscribers as $s) { ?>
|
153 |
+
<div class="tnp-card-newsletter-list">
|
154 |
+
<div class="tnp-card-newsletters-subscriber-email">
|
155 |
+
<?php echo esc_html($s->email) ?>
|
156 |
+
</div>
|
157 |
+
|
158 |
+
<div class="tnp-card-newsletters-subscriber-name">
|
159 |
+
<?php echo esc_html($s->name) ?> <?php echo esc_html($s->surname) ?>
|
160 |
+
</div>
|
161 |
+
<div class="tnp-card-newsletters-subscriber-status">
|
162 |
+
<?php echo $emails_module->get_user_status_label($s) ?>
|
163 |
+
</div>
|
164 |
+
<div class="tnp-card-newsletters-action">
|
165 |
+
<a class="button-primary"
|
166 |
+
title="<?php _e('Edit', 'newsletter') ?>"
|
167 |
+
href="<?php echo $users_module->get_admin_page_url('edit'); ?>&id=<?php echo $s->id; ?>"><i
|
168 |
+
class="fas fa-edit"></i></a>
|
169 |
+
<!--
|
170 |
+
<a title="<?php _e('Profile', 'newsletter') ?>"
|
171 |
+
href="<?php echo home_url('/') ?>?na=p&nk=<?php echo $s->id . '-' . $s->token; ?>"
|
172 |
+
class="button-primary" target="_blank"><i
|
173 |
+
class="fas fa-user"></i></a>-->
|
174 |
+
</div>
|
175 |
+
</div>
|
176 |
+
<?php } ?>
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
</div>
|
181 |
+
</div>
|
182 |
+
</div>
|
183 |
+
<div class="tnp-cards-container">
|
184 |
+
<div class="tnp-card">
|
185 |
+
<div class="tnp-card-title"><?php _e('Subscriptions', 'newsletter') ?></div>
|
186 |
+
<div class="tnp-canvas">
|
187 |
+
<canvas id="tnp-events-chart-canvas" height="300"></canvas>
|
188 |
+
</div>
|
189 |
+
|
190 |
+
<script type="text/javascript">
|
191 |
+
var events_data = {
|
192 |
+
labels: <?php echo json_encode($labels) ?>,
|
193 |
+
datasets: [
|
194 |
+
{
|
195 |
+
label: "<?php _e('Subscriptions', 'newsletter') ?>",
|
196 |
+
fill: true,
|
197 |
+
strokeColor: "#27AE60",
|
198 |
+
backgroundColor: "#293544",
|
199 |
+
borderColor: "#27AE60",
|
200 |
+
pointBorderColor: "#27AE60",
|
201 |
+
pointBackgroundColor: "#ECF0F1",
|
202 |
+
data: <?php echo json_encode($values) ?>
|
203 |
+
}
|
204 |
+
]
|
205 |
+
};
|
206 |
+
|
207 |
+
jQuery(document).ready(function ($) {
|
208 |
+
ctxe = $('#tnp-events-chart-canvas').get(0).getContext("2d");
|
209 |
+
eventsLineChart = new Chart(ctxe, {
|
210 |
+
type: 'line', data: events_data,
|
211 |
+
options: {
|
212 |
+
maintainAspectRatio: false,
|
213 |
+
xresponsive: true,
|
214 |
+
scales: {
|
215 |
+
xAxes: [{
|
216 |
+
type: "category",
|
217 |
+
"id": "x-axis-1",
|
218 |
+
gridLines: {display: false},
|
219 |
+
ticks: {fontFamily: "soleil"}
|
220 |
+
}],
|
221 |
+
yAxes: [
|
222 |
+
{
|
223 |
+
type: "linear",
|
224 |
+
"id": "y-axis-1",
|
225 |
+
gridLines: {display: false},
|
226 |
+
ticks: {fontFamily: "soleil"}
|
227 |
+
},
|
228 |
+
]
|
229 |
+
},
|
230 |
+
}
|
231 |
+
});
|
232 |
+
});
|
233 |
+
</script>
|
234 |
+
</div>
|
235 |
+
<div class="tnp-card">
|
236 |
+
<div class="tnp-card-title"><?php _e('Documentation', 'newsletter') ?></div>
|
237 |
+
<div class="break"></div>
|
238 |
+
<a href="https://www.thenewsletterplugin.com/documentation/installation/" target="_blank">
|
239 |
+
<div class="tnp-card-documentation-index">
|
240 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
241 |
+
Installation
|
242 |
+
</div>
|
243 |
+
</a>
|
244 |
+
<a href="https://www.thenewsletterplugin.com/documentation/subscription/" target="_blank">
|
245 |
+
<div class="tnp-card-documentation-index">
|
246 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
247 |
+
Subscription
|
248 |
+
</div>
|
249 |
+
</a>
|
250 |
+
<a href="https://www.thenewsletterplugin.com/category/tips" target="_blank">
|
251 |
+
<div class="tnp-card-documentation-index">
|
252 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
253 |
+
Tips & Tricks
|
254 |
+
</div>
|
255 |
+
</a>
|
256 |
+
<a href="https://www.thenewsletterplugin.com/documentation/subscribers-and-management/" target="_blank">
|
257 |
+
<div class="tnp-card-documentation-index">
|
258 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
259 |
+
Subscribers and management
|
260 |
+
</div>
|
261 |
+
</a>
|
262 |
+
<a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletters-module/" target="_blank">
|
263 |
+
<div class="tnp-card-documentation-index">
|
264 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
265 |
+
Creating Newsletters
|
266 |
+
</div>
|
267 |
+
</a>
|
268 |
+
<a href="https://www.thenewsletterplugin.com/documentation/addons/" target="_blank">
|
269 |
+
<div class="tnp-card-documentation-index">
|
270 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
271 |
+
Premium Addons
|
272 |
+
</div>
|
273 |
+
</a>
|
274 |
+
<a href="https://www.thenewsletterplugin.com/documentation/customization/" target="_blank">
|
275 |
+
<div class="tnp-card-documentation-index">
|
276 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
277 |
+
Customization
|
278 |
+
</div>
|
279 |
+
</a>
|
280 |
+
<a href="https://www.thenewsletterplugin.com/documentation/delivery-and-spam/" target="_blank">
|
281 |
+
<div class="tnp-card-documentation-index">
|
282 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
283 |
+
Delivery and spam
|
284 |
+
</div>
|
285 |
+
</a>
|
286 |
+
<a href="https://www.thenewsletterplugin.com/documentation/developers/" target="_blank">
|
287 |
+
<div class="tnp-card-documentation-index">
|
288 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="20" height="20"><title>saved items</title><g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" ><path d="M37,4h3a4,4,0,0,1,4,4V40a4,4,0,0,1-4,4H8a4,4,0,0,1-4-4V8A4,4,0,0,1,8,4h3" fill="none" stroke-miterlimit="10"/> <polygon points="32 24 24 18 16 24 16 4 32 4 32 24" fill="none" stroke-miterlimit="10" data-color="color-2"/></g></svg>
|
289 |
+
Developers & Advanced Topics
|
290 |
+
</div>
|
291 |
+
</a>
|
292 |
+
</div>
|
293 |
+
</div>
|
294 |
+
<div class="tnp-cards-container">
|
295 |
+
<div class="tnp-card" style="align-self: flex-start">
|
296 |
+
<div class="tnp-card-title"><?php _e('Developers', 'newsletter') ?></div>
|
297 |
+
<div class="tnp-card-description">Extending Newsletter by yourself? There is something for you as well!</div>
|
298 |
+
<div class="tnp-card-button-container">
|
299 |
+
<a href="https://www.thenewsletterplugin.com/documentation/developers/" target="_blank">Developer's love 💛</a>
|
300 |
+
</div>
|
301 |
+
</div>
|
302 |
+
<div class="tnp-card">
|
303 |
+
<div class="tnp-card-title"><?php _e('Video Tutorials', 'newsletter') ?></div>
|
304 |
+
<div class="tnp-card-description">We have some videos to help gest the most from Newsletter.</div>
|
305 |
+
<div class="tnp-card-video">
|
306 |
+
<iframe width="560" height="315" src="https://www.youtube.com/embed/zmVmW84Bw9A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
307 |
+
</div>
|
308 |
+
<div class="tnp-card-button-container">
|
309 |
+
<a href="https://www.thenewsletterplugin.com/video-tutorials" target="_blank">See the videos</a>
|
310 |
+
</div>
|
311 |
+
</div>
|
312 |
+
</div>
|
313 |
+
|
314 |
+
</div>
|
315 |
+
|
316 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
317 |
+
|
318 |
+
</div>
|
main/js/main.js
DELETED
@@ -1,178 +0,0 @@
|
|
1 |
-
|
2 |
-
/*
|
3 |
-
convert a cubic bezier value to a custom mina easing
|
4 |
-
http://stackoverflow.com/questions/25265197/how-to-convert-a-cubic-bezier-value-to-a-custom-mina-easing-snap-svg
|
5 |
-
*/
|
6 |
-
var duration = 300,
|
7 |
-
delay = 300,
|
8 |
-
epsilon = (1000 / 60 / duration) / 4,
|
9 |
-
firstCustomMinaAnimation = bezier(.42, .03, .77, .63, epsilon),
|
10 |
-
secondCustomMinaAnimation = bezier(.27, .5, .6, .99, epsilon);
|
11 |
-
|
12 |
-
jQuery(document).ready(function () {
|
13 |
-
//initialize the slider
|
14 |
-
jQuery('.cd-slider-wrapper').each(function () {
|
15 |
-
initSlider(jQuery(this));
|
16 |
-
});
|
17 |
-
});
|
18 |
-
|
19 |
-
function initSlider(sliderWrapper) {
|
20 |
-
//cache jQuery objects
|
21 |
-
slider = sliderWrapper.find('.cd-slider'),
|
22 |
-
sliderNavigation = sliderWrapper.find('.cd-slider-navigation').find('li'),
|
23 |
-
svgCoverLayer = sliderWrapper.find('div.cd-svg-cover'),
|
24 |
-
pathId = svgCoverLayer.find('path').attr('id'),
|
25 |
-
svgPath = Snap('#' + pathId);
|
26 |
-
|
27 |
-
//store path 'd' attribute values
|
28 |
-
pathArray = [];
|
29 |
-
pathArray[0] = svgCoverLayer.data('step1');
|
30 |
-
pathArray[1] = svgCoverLayer.data('step6');
|
31 |
-
pathArray[2] = svgCoverLayer.data('step2');
|
32 |
-
pathArray[3] = svgCoverLayer.data('step7');
|
33 |
-
pathArray[4] = svgCoverLayer.data('step3');
|
34 |
-
pathArray[5] = svgCoverLayer.data('step8');
|
35 |
-
pathArray[6] = svgCoverLayer.data('step4');
|
36 |
-
pathArray[7] = svgCoverLayer.data('step9');
|
37 |
-
pathArray[8] = svgCoverLayer.data('step5');
|
38 |
-
pathArray[9] = svgCoverLayer.data('step10');
|
39 |
-
|
40 |
-
//update visible slide when user clicks .cd-slider-navigation buttons
|
41 |
-
sliderNavigation.on('click', function (event) {
|
42 |
-
event.preventDefault();
|
43 |
-
var selectedItem = jQuery(this);
|
44 |
-
if (!selectedItem.hasClass('selected')) {
|
45 |
-
// if it's not already selected
|
46 |
-
var selectedSlidePosition = selectedItem.index(),
|
47 |
-
selectedSlide = slider.children('li').eq(selectedSlidePosition),
|
48 |
-
visibleSlide = slider.find('.visible'),
|
49 |
-
visibleSlidePosition = visibleSlide.index(),
|
50 |
-
direction = '';
|
51 |
-
direction = (visibleSlidePosition < selectedSlidePosition) ? 'next' : 'prev';
|
52 |
-
updateSlide(visibleSlide, selectedSlide, direction, svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
53 |
-
}
|
54 |
-
});
|
55 |
-
}
|
56 |
-
|
57 |
-
function nextSlide() {
|
58 |
-
var visibleSlide = slider.find('.visible');
|
59 |
-
jQuery.post("?page=newsletter_main_welcome&noheader=1&action=save", jQuery("#tnp-welcome").serialize());
|
60 |
-
var visibleSlidePosition = visibleSlide.index();
|
61 |
-
var selectedSlide = slider.children('li').eq(visibleSlidePosition + 1);
|
62 |
-
if (selectedSlide.hasClass("tnp-last-slide")) {
|
63 |
-
jQuery(".cd-slider-navigation").hide();
|
64 |
-
}
|
65 |
-
|
66 |
-
updateSlide(visibleSlide, selectedSlide, "next", svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
67 |
-
|
68 |
-
}
|
69 |
-
|
70 |
-
function prevSlide() {
|
71 |
-
var visibleSlide = slider.find('.visible');
|
72 |
-
var visibleSlidePosition = visibleSlide.index();
|
73 |
-
var selectedSlide = slider.children('li').eq(visibleSlidePosition - 1);
|
74 |
-
|
75 |
-
updateSlide(visibleSlide, selectedSlide, "prev", svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
76 |
-
if (selectedSlide.hasClass("tnp-first-slide")) {
|
77 |
-
jQuery(".cd-slider-navigation a.tnp-welcome-prev").hide();
|
78 |
-
}
|
79 |
-
}
|
80 |
-
|
81 |
-
function updateSlide(oldSlide, newSlide, direction, svgCoverLayer, sliderNavigation, paths, svgPath) {
|
82 |
-
if (direction == 'next') {
|
83 |
-
var path1 = paths[0],
|
84 |
-
path2 = paths[2],
|
85 |
-
path3 = paths[4];
|
86 |
-
path4 = paths[6];
|
87 |
-
path5 = paths[8];
|
88 |
-
} else {
|
89 |
-
var path1 = paths[1],
|
90 |
-
path2 = paths[3],
|
91 |
-
path3 = paths[5];
|
92 |
-
path4 = paths[7];
|
93 |
-
path5 = paths[9];
|
94 |
-
}
|
95 |
-
|
96 |
-
svgCoverLayer.addClass('is-animating');
|
97 |
-
svgPath.attr('d', path1);
|
98 |
-
svgPath.animate({'d': path2}, duration, firstCustomMinaAnimation, function () {
|
99 |
-
svgPath.animate({'d': path3}, duration, secondCustomMinaAnimation, function () {
|
100 |
-
oldSlide.removeClass('visible');
|
101 |
-
newSlide.addClass('visible');
|
102 |
-
updateNavSlide(newSlide, sliderNavigation);
|
103 |
-
setTimeout(function () {
|
104 |
-
svgPath.animate({'d': path4}, duration, firstCustomMinaAnimation, function () {
|
105 |
-
svgPath.animate({'d': path5}, duration, secondCustomMinaAnimation, function () {
|
106 |
-
svgCoverLayer.removeClass('is-animating');
|
107 |
-
if (direction == "next") {
|
108 |
-
jQuery(".cd-slider-navigation a.tnp-welcome-prev").show();
|
109 |
-
}
|
110 |
-
});
|
111 |
-
});
|
112 |
-
}, delay);
|
113 |
-
});
|
114 |
-
});
|
115 |
-
}
|
116 |
-
|
117 |
-
function updateNavSlide(actualSlide, sliderNavigation) {
|
118 |
-
var position = actualSlide.index();
|
119 |
-
sliderNavigation.removeClass('selected').eq(position).addClass('selected');
|
120 |
-
}
|
121 |
-
|
122 |
-
function bezier(x1, y1, x2, y2, epsilon) {
|
123 |
-
//https://github.com/arian/cubic-bezier
|
124 |
-
var curveX = function (t) {
|
125 |
-
var v = 1 - t;
|
126 |
-
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
127 |
-
};
|
128 |
-
|
129 |
-
var curveY = function (t) {
|
130 |
-
var v = 1 - t;
|
131 |
-
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
132 |
-
};
|
133 |
-
|
134 |
-
var derivativeCurveX = function (t) {
|
135 |
-
var v = 1 - t;
|
136 |
-
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
137 |
-
};
|
138 |
-
|
139 |
-
return function (t) {
|
140 |
-
|
141 |
-
var x = t, t0, t1, t2, x2, d2, i;
|
142 |
-
|
143 |
-
// First try a few iterations of Newton's method -- normally very fast.
|
144 |
-
for (t2 = x, i = 0; i < 8; i++) {
|
145 |
-
x2 = curveX(t2) - x;
|
146 |
-
if (Math.abs(x2) < epsilon)
|
147 |
-
return curveY(t2);
|
148 |
-
d2 = derivativeCurveX(t2);
|
149 |
-
if (Math.abs(d2) < 1e-6)
|
150 |
-
break;
|
151 |
-
t2 = t2 - x2 / d2;
|
152 |
-
}
|
153 |
-
|
154 |
-
t0 = 0, t1 = 1, t2 = x;
|
155 |
-
|
156 |
-
if (t2 < t0)
|
157 |
-
return curveY(t0);
|
158 |
-
if (t2 > t1)
|
159 |
-
return curveY(t1);
|
160 |
-
|
161 |
-
// Fallback to the bisection method for reliability.
|
162 |
-
while (t0 < t1) {
|
163 |
-
x2 = curveX(t2);
|
164 |
-
if (Math.abs(x2 - x) < epsilon)
|
165 |
-
return curveY(t2);
|
166 |
-
if (x > x2)
|
167 |
-
t0 = t2;
|
168 |
-
else
|
169 |
-
t1 = t2;
|
170 |
-
t2 = (t1 - t0) * .5 + t0;
|
171 |
-
}
|
172 |
-
|
173 |
-
// Failure
|
174 |
-
return curveY(t2);
|
175 |
-
|
176 |
-
};
|
177 |
-
}
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main/js/{snap.svg-min.js → welcome.js}
RENAMED
@@ -1,21 +1,200 @@
|
|
1 |
-
// Snap.svg 0.4.1
|
2 |
-
//
|
3 |
-
// Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved.
|
4 |
-
//
|
5 |
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
6 |
-
// you may not use this file except in compliance with the License.
|
7 |
-
// You may obtain a copy of the License at
|
8 |
-
//
|
9 |
-
// http://www.apache.org/licenses/LICENSE-2.0
|
10 |
-
//
|
11 |
-
// Unless required by applicable law or agreed to in writing, software
|
12 |
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
13 |
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 |
-
// See the License for the specific language governing permissions and
|
15 |
-
// limitations under the License.
|
16 |
-
//
|
17 |
-
// build: 2015-04-13
|
18 |
-
|
19 |
-
!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g=/\s*,\s*/,h="*",i=function(a,b){return a-b},j={n:{}},k=function(){for(var a=0,b=this.length;b>a;a++)if("undefined"!=typeof this[a])return this[a]},l=function(){for(var a=this.length;--a;)if("undefined"!=typeof this[a])return this[a]},m=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=m.listeners(a),j=0,n=[],o={},p=[],q=b;p.firstDefined=k,p.lastDefined=l,b=a,c=0;for(var r=0,s=h.length;s>r;r++)"zIndex"in h[r]&&(n.push(h[r].zIndex),h[r].zIndex<0&&(o[h[r].zIndex]=h[r]));for(n.sort(i);n[j]<0;)if(e=o[n[j++]],p.push(e.apply(d,g)),c)return c=f,p;for(r=0;s>r;r++)if(e=h[r],"zIndex"in e)if(e.zIndex==n[j]){if(p.push(e.apply(d,g)),c)break;do if(j++,e=o[n[j]],e&&p.push(e.apply(d,g)),c)break;while(e)}else o[e.zIndex]=e;else if(p.push(e.apply(d,g)),c)break;return c=f,b=q,p};m._events=j,m.listeners=function(a){var b,c,d,e,g,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,g=m.length;g>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[h]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},m.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(g),d=0,e=c.length;e>d;d++)!function(a){for(var c,d=a.split(f),e=j,g=0,h=d.length;h>g;g++)e=e.n,e=e.hasOwnProperty(d[g])&&e[d[g]]||(e[d[g]]={n:{}});for(e.f=e.f||[],g=0,h=e.f.length;h>g;g++)if(e.f[g]==b){c=!0;break}!c&&e.f.push(b)}(c[d]);return function(a){+a==+a&&(b.zIndex=+a)}},m.f=function(a){var b=[].slice.call(arguments,1);return function(){m.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},m.stop=function(){c=1},m.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},m.nts=function(){return b.split(f)},m.off=m.unbind=function(a,b){if(!a)return void(m._events=j={n:{}});var c=a.split(g);if(c.length>1)for(var d=0,i=c.length;i>d;d++)m.off(c[d],b);else{c=a.split(f);var k,l,n,d,i,o,p,q=[j];for(d=0,i=c.length;i>d;d++)for(o=0;o<q.length;o+=n.length-2){if(n=[o,1],k=q[o].n,c[d]!=h)k[c[d]]&&n.push(k[c[d]]);else for(l in k)k[e](l)&&n.push(k[l]);q.splice.apply(q,n)}for(d=0,i=q.length;i>d;d++)for(k=q[d];k.n;){if(b){if(k.f){for(o=0,p=k.f.length;p>o;o++)if(k.f[o]==b){k.f.splice(o,1);break}!k.f.length&&delete k.f}for(l in k.n)if(k.n[e](l)&&k.n[l].f){var r=k.n[l].f;for(o=0,p=r.length;p>o;o++)if(r[o]==b){r.splice(o,1);break}!r.length&&delete k.n[l].f}}else{delete k.f;for(l in k.n)k.n[e](l)&&k.n[l].f&&delete k.n[l].f}k=k.n}}},m.once=function(a,b){var c=function(){return m.unbind(a,c),b.apply(this,arguments)};return m.on(a,c)},m.version=d,m.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=m:"function"==typeof define&&define.amd?define("eve",[],function(){return m}):a.eve=m}(this),function(a,b){if("function"==typeof define&&define.amd)define(["eve"],function(c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("eve");module.exports=b(a,c)}else b(a,a.eve)}(window||this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(a){function c(a,b){if(a){if(a.nodeType)return w(a);if(e(a,"array")&&c.set)return c.set.apply(c,a);if(a instanceof s)return a;if(null==b)return a=y.doc.querySelector(String(a)),w(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new v(a,b)}function d(a,b){if(b){if("#text"==a&&(a=y.doc.createTextNode(b.text||b["#text"]||"")),"#comment"==a&&(a=y.doc.createComment(b.text||b["#text"]||"")),"string"==typeof a&&(a=d(a)),"string"==typeof b)return 1==a.nodeType?"xlink:"==b.substring(0,6)?a.getAttributeNS(T,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(U,b.substring(4)):a.getAttribute(b):"text"==b?a.nodeValue:null;if(1==a.nodeType){for(var c in b)if(b[z](c)){var e=A(b[c]);e?"xlink:"==c.substring(0,6)?a.setAttributeNS(T,c.substring(6),e):"xml:"==c.substring(0,4)?a.setAttributeNS(U,c.substring(4),e):a.setAttribute(c,e):a.removeAttribute(c)}}else"text"in b&&(a.nodeValue=b.text)}else a=y.doc.createElementNS(U,a);return a}function e(a,b){return b=A.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||J.call(a).slice(8,-1).toLowerCase()==b}function f(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=f(a[c]));return b}function h(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function i(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},i=d.count=d.count||[];return g[z](f)?(h(i,f),c?c(g[f]):g[f]):(i.length>=1e3&&delete g[i.shift()],i.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function j(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*D.atan2(-h,-g)/H+360)%360:0}return j(a,b,e,f)-j(c,d,e,f)}function k(a){return a%360*H/180}function l(a){return 180*a/H%360}function m(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,D.tan(k(d[0])),1,0,0]:"skewY"==c?["m",1,D.tan(k(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function n(a,b){var d=ab(a),e=new c.Matrix;if(d)for(var f=0,g=d.length;g>f;f++){var h,i,j,k,l,m=d[f],n=m.length,o=A(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function o(a){var b=a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||a.node.parentNode&&w(a.node.parentNode)||c.select("svg")||c(0,0),d=b.select("defs"),e=null==d?!1:d.node;return e||(e=u("defs",b.node).node),e}function p(a){return a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||c.select("svg")}function q(a,b,c){function e(a){if(null==a)return I;if(a==+a)return a;d(j,{width:a});try{return j.getBBox().width}catch(b){return 0}}function f(a){if(null==a)return I;if(a==+a)return a;d(j,{height:a});try{return j.getBBox().height}catch(b){return 0}}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=p(a).node,i={},j=h.querySelector(".svg---mgr");switch(j||(j=d("rect"),d(j,{x:-9e9,y:-9e9,width:10,height:10,"class":"svg---mgr",fill:"none"}),h.appendChild(j)),a.type){case"rect":g("rx",e),g("ry",f);case"image":g("width",e),g("height",f);case"text":g("x",e),g("y",f);break;case"circle":g("cx",e),g("cy",f),g("r",e);break;case"ellipse":g("cx",e),g("cy",f),g("rx",e),g("ry",f);break;case"line":g("x1",e),g("x2",e),g("y1",f),g("y2",f);break;case"marker":g("refX",e),g("markerWidth",e),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",e),g("fy",f);break;case"tspan":g("dx",e),g("dy",f);break;default:g(b,e)}return h.removeChild(j),i}function r(a){e(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;b<a.length;b++)"set"==a[b].type?a[b].forEach(function(a){d.appendChild(a.node)}):d.appendChild(a[b].node);var f=d.childNodes;for(b=0;b<f.length;b++)this[c++]=w(f[b]);return this}function s(a){if(a.snap in V)return V[a.snap];var b;try{b=a.ownerSVGElement}catch(c){}this.node=a,b&&(this.paper=new v(b)),this.type=a.tagName||a.nodeName;var d=this.id=S(this);if(this.anims={},this._={transform:[]},a.snap=d,V[d]=this,"g"==this.type&&(this.add=r),this.type in{g:1,mask:1,pattern:1,symbol:1})for(var e in v.prototype)v.prototype[z](e)&&(this[e]=v.prototype[e])}function t(a){this.node=a}function u(a,b){var c=d(a);b.appendChild(c);var e=w(c);return e}function v(a,b){var c,e,f,g=v.prototype;if(a&&"svg"==a.tagName){if(a.snap in V)return V[a.snap];var h=a.ownerDocument;c=new s(a),e=a.getElementsByTagName("desc")[0],f=a.getElementsByTagName("defs")[0],e||(e=d("desc"),e.appendChild(h.createTextNode("Created with Snap")),c.node.appendChild(e)),f||(f=d("defs"),c.node.appendChild(f)),c.defs=f;for(var i in g)g[z](i)&&(c[i]=g[i]);c.paper=c.root=c}else c=u("svg",y.doc.body),d(c.node,{height:b,version:1.1,width:a,xmlns:U});return c}function w(a){return a?a instanceof s||a instanceof t?a:a.tagName&&"svg"==a.tagName.toLowerCase()?new v(a):a.tagName&&"object"==a.tagName.toLowerCase()&&"image/svg+xml"==a.type?new v(a.contentDocument.getElementsByTagName("svg")[0]):new s(a):a}function x(a,b){for(var c=0,d=a.length;d>c;c++){var e={type:a[c].type,attr:a[c].attr()},f=a[c].children();b.push(e),f.length&&x(f,e.childNodes=[])}}c.version="0.4.0",c.toString=function(){return"Snap v"+this.version},c._={};var y={win:a.window,doc:a.window.document};c._.glob=y;{var z="hasOwnProperty",A=String,B=parseFloat,C=parseInt,D=Math,E=D.max,F=D.min,G=D.abs,H=(D.pow,D.PI),I=(D.round,""),J=Object.prototype.toString,K=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,L=(c._.separator=/[,\s]+/,/[\s]*,[\s]*/),M={hs:1,rg:1},N=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,O=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,P=/(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/gi,Q=0,R="S"+(+new Date).toString(36),S=function(a){return(a&&a.type?a.type:I)+R+(Q++).toString(36)},T="http://www.w3.org/1999/xlink",U="http://www.w3.org/2000/svg",V={};c.url=function(a){return"url('#"+a+"')"}}c._.$=d,c._.id=S,c.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return A(b).replace(a,function(a,b){return c(a,b,d)})}}(),c._.clone=f,c._.cacher=i,c.rad=k,c.deg=l,c.sin=function(a){return D.sin(c.rad(a))},c.tan=function(a){return D.tan(c.rad(a))},c.cos=function(a){return D.cos(c.rad(a))},c.asin=function(a){return c.deg(D.asin(a))},c.acos=function(a){return c.deg(D.acos(a))},c.atan=function(a){return c.deg(D.atan(a))},c.atan2=function(a){return c.deg(D.atan2(a))},c.angle=j,c.len=function(a,b,d,e){return Math.sqrt(c.len2(a,b,d,e))},c.len2=function(a,b,c,d){return(a-c)*(a-c)+(b-d)*(b-d)},c.closestPoint=function(a,b,c){function d(a){var d=a.x-b,e=a.y-c;return d*d+e*e}for(var e,f,g,h,i=a.node,j=i.getTotalLength(),k=j/i.pathSegList.numberOfItems*.125,l=1/0,m=0;j>=m;m+=k)(h=d(g=i.getPointAtLength(m)))<l&&(e=g,f=m,l=h);for(k*=.5;k>.5;){var n,o,p,q,r,s;(p=f-k)>=0&&(r=d(n=i.getPointAtLength(p)))<l?(e=n,f=p,l=r):(q=f+k)<=j&&(s=d(o=i.getPointAtLength(q)))<l?(e=o,f=q,l=s):k*=.5}return e={x:e.x,y:e.y,length:f,distance:Math.sqrt(l)}},c.is=e,c.snapTo=function(a,b,c){if(c=e(c,"finite")?c:10,e(a,"array")){for(var d=a.length;d--;)if(G(a[d]-b)<=c)return a[d]}else{a=+a;var f=b%a;if(c>f)return b-f;if(f>a-c)return b-f+a}return b},c.getRGB=i(function(a){if(!a||(a=A(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:Z};if(!(M[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=W(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};var b,d,f,g,h,i,j=a.match(K);return j?(j[2]&&(f=C(j[2].substring(5),16),d=C(j[2].substring(3,5),16),b=C(j[2].substring(1,3),16)),j[3]&&(f=C((h=j[3].charAt(3))+h,16),d=C((h=j[3].charAt(2))+h,16),b=C((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=B(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),f=B(i[2]),"%"==i[2].slice(-1)&&(f*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsb2rgb(b,d,f,g)):j[6]?(i=j[6].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsl2rgb(b,d,f,g)):(b=F(D.round(b),255),d=F(D.round(d),255),f=F(D.round(f),255),g=F(E(g,0),1),j={r:b,g:d,b:f,toString:Z},j.hex="#"+(16777216|f|d<<8|b<<16).toString(16).slice(1),j.opacity=e(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z}},c),c.hsb=i(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=i(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=i(function(a,b,c,d){if(e(d,"finite")){var f=D.round;return"rgba("+[f(a),f(b),f(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var W=function(a){var b=y.doc.getElementsByTagName("head")[0]||y.doc.getElementsByTagName("svg")[0],c="rgb(255, 0, 0)";return(W=i(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=y.doc.defaultView.getComputedStyle(b,I).getPropertyValue("color");return d==c?null:d}))(a)},X=function(){return"hsb("+[this.h,this.s,this.b]+")"},Y=function(){return"hsl("+[this.h,this.s,this.l]+")"},Z=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},$=function(a,b,d){if(null==b&&e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&e(a,string)){var f=c.getRGB(a);a=f.r,b=f.g,d=f.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},_=function(a,b,d,f){a=D.round(255*a),b=D.round(255*b),d=D.round(255*d);var g={r:a,g:b,b:d,opacity:e(f,"finite")?f:1,hex:c.rgb(a,b,d),toString:Z};return e(f,"finite")&&(g.opacity=f),g};c.color=function(a){var b;return e(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):e(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(e(a,"string")&&(a=c.getRGB(a)),e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=Z,a},c.hsb2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var f,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-G(a%2-1)),f=g=h=c-j,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.hsl2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var f,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-G(a%2-1)),f=g=h=c-j/2,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.rgb2hsb=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=E(a,b,c),g=f-F(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:X}},c.rgb2hsl=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=E(a,b,c),h=F(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:Y}},c.parsePathString=function(a){if(!a)return null;var b=c.path(a);if(b.arr)return c.path.clone(b.arr);var d={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},f=[];return e(a,"array")&&e(a[0],"array")&&(f=c.path.clone(a)),f.length||A(a).replace(N,function(a,b,c){var e=[],g=b.toLowerCase();if(c.replace(P,function(a,b){b&&e.push(+b)}),"m"==g&&e.length>2&&(f.push([b].concat(e.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==e.length&&f.push([b,e[0]]),"r"==g)f.push([b].concat(e));else for(;e.length>=d[g]&&(f.push([b].concat(e.splice(0,d[g]))),d[g]););}),f.toString=c.path.toString,b.arr=c.path.clone(f),f};var ab=c.parseTransformString=function(a){if(!a)return null;var b=[];return e(a,"array")&&e(a[0],"array")&&(b=c.path.clone(a)),b.length||A(a).replace(O,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(P,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=c.path.toString,b};c._.svgTransform2string=m,c._.rgTransform=/^[a-z][\s]*-?\.?\d/i,c._.transform2matrix=n,c._unit2px=q;y.doc.contains||y.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};c._.getSomeDefs=o,c._.getSomeSVG=p,c.select=function(a){return a=A(a).replace(/([^\\]):/g,"$1\\:"),w(y.doc.querySelector(a))},c.selectAll=function(a){for(var b=y.doc.querySelectorAll(a),d=(c.set||Array)(),e=0;e<b.length;e++)d.push(w(b[e]));return d},setInterval(function(){for(var a in V)if(V[z](a)){var b=V[a],c=b.node;("svg"!=b.type&&!c.ownerSVGElement||"svg"==b.type&&(!c.parentNode||"ownerSVGElement"in c.parentNode&&!c.ownerSVGElement))&&delete V[a]}},1e4),s.prototype.attr=function(a,c){var d=this,f=d.node;if(!a){if(1!=f.nodeType)return{text:f.nodeValue};for(var g=f.attributes,h={},i=0,j=g.length;j>i;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d},c.parse=function(a){var b=y.doc.createDocumentFragment(),c=!0,d=y.doc.createElement("div");if(a=A(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a="<svg>"+a+"</svg>",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return new t(b)},c.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=y.doc.createDocumentFragment(),d=0,e=a.length;e>d;d++){var f=a[d];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(c.parse(f).node)}return new t(b)},c._.make=u,c._.wrap=w,v.prototype.el=function(a,b){var c=u(a,this.node);return b&&c.attr(b),c},s.prototype.children=function(){for(var a=[],b=this.node.childNodes,d=0,e=b.length;e>d;d++)a[d]=c(b[d]);return a},s.prototype.toJSON=function(){var a=[];return x([this],a),a[0]},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return bb[z](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):d(this.node,a)});var bb={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),e={};c=c.substring(c.lastIndexOf(".")+1),e[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});bb[z](g)?this.node.style[f]=null==a?I:a:d(this.node,e)}),function(){}(v.prototype),c.ajax=function(a,c,d,f){var g=new XMLHttpRequest,h=S();if(g){if(e(c,"function"))f=d,d=c,c=null;else if(e(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,f,g)},4==g.readyState?g:(g.send(c),g)}},c.load=function(a,b,d){c.ajax(a,function(a){var e=c.parse(a.responseText);d?b.call(d,e):b(e)})};var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return c.getElementByPoint=function(a,b){var c=this,d=(c.canvas,y.doc.elementFromPoint(a,b));if(y.win.opera&&"svg"==d.tagName){var e=cb(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?w(d):null},c.plugin=function(a){a(c,s,v,y,t)},y.win.Snap=c,c}(a||this);return d.plugin(function(d,e,f,g,h){function i(a,b){if(null==b){var c=!0;if(b=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new d.Matrix;b=d._.svgTransform2string(b)}else b=d._.rgTransform.test(b)?o(b).replace(/\.{3}|\u2026/g,a._.transform||""):d._.svgTransform2string(b),n(b,"array")&&(b=d.path?d.path.toString.call(b):o(b)),a._.transform=b;var e=d._.transform2matrix(b,a.getBBox(1));return c?e:void(a.matrix=e)}function j(a){function b(a,b){var c=q(a.node,b);c=c&&c.match(f),c=c&&c[2],c&&"#"==c.charAt()&&(c=c.substring(1),c&&(h[c]=(h[c]||[]).concat(function(c){var d={};d[b]=URL(c),q(a.node,d)})))}function c(a){var b=q(a.node,"xlink:href");b&&"#"==b.charAt()&&(b=b.substring(1),b&&(h[b]=(h[b]||[]).concat(function(b){a.attr("xlink:href","#"+b)})))}for(var d,e=a.selectAll("*"),f=/^\s*url\(("|'|)(.*)\1\)\s*$/,g=[],h={},i=0,j=e.length;j>i;i++){d=e[i],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var k=q(d.node,"id");k&&(q(d.node,{id:d.id}),g.push({old:k,id:d.id}))}for(i=0,j=g.length;j>i;i++){var l=h[g[i].old];if(l)for(var m=0,n=l.length;n>m;m++)l[m](g[i].id)}}function k(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function l(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=u(d[e]).toString());a&&(b+="</"+this.type+">")}else a&&(b+="/>");return b}}var m=e.prototype,n=d.is,o=String,p=d._unit2px,q=d._.$,r=d._.make,s=d._.getSomeDefs,t="hasOwnProperty",u=d._.wrap;m.getBBox=function(a){if(!d.Matrix||!d.path)return this.node.getBBox();var b=this,c=new d.Matrix;if(b.removed)return d._.box();for(;"use"==b.type;)if(a||(c=c.add(b.transform().localMatrix.translate(b.attr("x")||0,b.attr("y")||0))),b.original)b=b.original;else{var e=b.attr("xlink:href");b=b.original=b.node.ownerDocument.getElementById(e.substring(e.indexOf("#")+1))}var f=b._,g=d.path.get[b.type]||d.path.get.deflt;try{return a?(f.bboxwt=g?d.path.getBBox(b.realPath=g(b)):d._.box(b.node.getBBox()),d._.box(f.bboxwt)):(b.realPath=g(b),b.matrix=b.transform().localMatrix,f.bbox=d.path.getBBox(d.path.map(b.realPath,c.add(b.matrix))),d._.box(f.bbox))}catch(h){return d._.box()}};var v=function(){return this.string};m.transform=function(a){var b=this._;if(null==a){for(var c,e=this,f=new d.Matrix(this.node.getCTM()),g=i(this),h=[g],j=new d.Matrix,k=g.toTransformString(),l=o(g)==o(this.matrix)?o(b.transform):k;"svg"!=e.type&&(e=e.parent());)h.push(i(e));for(c=h.length;c--;)j.add(h[c]);return{string:l,globalMatrix:f,totalMatrix:j,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:j.toTransformString(),local:k,toString:v}}return a instanceof d.Matrix?(this.matrix=a,this._.transform=a.toTransformString()):i(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?q(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?q(this.node,{patternTransform:this.matrix}):q(this.node,{transform:this.matrix})),this},m.parent=function(){return u(this.node.parentNode)},m.append=m.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=u(a),this.node.appendChild(a.node),a.paper=this.paper}return this},m.appendTo=function(a){return a&&(a=u(a),a.append(this)),this},m.prepend=function(a){if(a){if("set"==a.type){var b,c=this;return a.forEach(function(a){b?b.after(a):c.prepend(a),b=a}),this}a=u(a);var d=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),d&&d.add()}return this},m.prependTo=function(a){return a=u(a),a.prepend(this),this},m.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=u(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},m.after=function(a){a=u(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},m.insertBefore=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.insertAfter=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},m.select=function(a){return u(this.node.querySelector(a))},m.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;e<b.length;e++)c.push(u(b[e]));return c},m.asPX=function(a,b){return null==b&&(b=this.attr(a)),+p(this,a,b)},m.use=function(){var a,b=this.node.id;return b||(b=this.id,q(this.node,{id:b})),a="linearGradient"==this.type||"radialGradient"==this.type||"pattern"==this.type?r(this.type,this.node.parentNode):r("use",this.node.parentNode),q(a.node,{"xlink:href":"#"+b}),a.original=this,a},m.clone=function(){var a=u(this.node.cloneNode(!0));return q(a.node,"id")&&q(a.node,{id:a.id}),j(a),a.insertAfter(this),a},m.toDefs=function(){var a=s(this);return a.appendChild(this.node),this},m.pattern=m.toPattern=function(a,b,c,d){var e=r("pattern",s(this));return null==a&&(a=this.getBBox()),n(a,"object")&&"x"in a&&(b=a.y,c=a.width,d=a.height,a=a.x),q(e.node,{x:a,y:b,width:c,height:d,patternUnits:"userSpaceOnUse",id:e.id,viewBox:[a,b,c,d].join(" ")}),e.node.appendChild(this.node),e},m.marker=function(a,b,c,d,e,f){var g=r("marker",s(this));return null==a&&(a=this.getBBox()),n(a,"object")&&"x"in a&&(b=a.y,c=a.width,d=a.height,e=a.refX||a.cx,f=a.refY||a.cy,a=a.x),q(g.node,{viewBox:[a,b,c,d].join(" "),markerWidth:c,markerHeight:d,orient:"auto",refX:e||0,refY:f||0,id:g.id}),g.node.appendChild(this.node),g};var w=function(a,b,d,e){"function"!=typeof d||d.length||(e=d,d=c.linear),this.attr=a,this.dur=b,d&&(this.easing=d),e&&(this.callback=e)};d._.Animation=w,d.animation=function(a,b,c,d){return new w(a,b,c,d)},m.inAnim=function(){var a=this,b=[];for(var c in a.anims)a.anims[t](c)&&!function(a){b.push({anim:new w(a._attrs,a.dur,a.easing,a._callback),mina:a,curStatus:a.status(),status:function(b){return a.status(b)},stop:function(){a.stop()}})}(a.anims[c]);return b},d.animate=function(a,d,e,f,g,h){"function"!=typeof g||g.length||(h=g,g=c.linear);var i=c.time(),j=c(a,d,i,i+f,c.time,e,g);return h&&b.once("mina.finish."+j.id,h),j},m.stop=function(){for(var a=this.inAnim(),b=0,c=a.length;c>b;b++)a[b].stop();return this},m.animate=function(a,d,e,f){"function"!=typeof e||e.length||(f=e,e=c.linear),a instanceof w&&(f=a.callback,e=a.easing,d=a.dur,a=a.attr);var g,h,i,j,l=[],m=[],p={},q=this;for(var r in a)if(a[t](r)){q.equal?(j=q.equal(r,o(a[r])),g=j.from,h=j.to,i=j.f):(g=+q.attr(r),h=+a[r]);var s=n(g,"array")?g.length:1;p[r]=k(l.length,l.length+s,i),l=l.concat(g),m=m.concat(h)}var u=c.time(),v=c(l,m,u,u+d,c.time,function(a){var b={};for(var c in p)p[t](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[v.id]=v,v._attrs=a,v._callback=f,b("snap.animcreated."+q.id,v),b.once("mina.finish."+v.id,function(){delete q.anims[v.id],f&&f.call(q)}),b.once("mina.stop."+v.id,function(){delete q.anims[v.id]}),q};var x={};m.data=function(a,c){var e=x[this.id]=x[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e;
|
20 |
-
if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[t](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a]}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},m.removeData=function(a){return null==a?x[this.id]={}:x[this.id]&&delete x[this.id][a],this},m.outerSVG=m.toString=l(1),m.innerSVG=l(),m.toDataURL=function(){if(a&&a.btoa){var b=this.getBBox(),c=d.format('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}" viewBox="{x} {y} {width} {height}">{contents}</svg>',{x:+b.x.toFixed(3),y:+b.y.toFixed(3),width:+b.width.toFixed(3),height:+b.height.toFixed(3),contents:this.outerSVG()});return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(c)))}},h.prototype.select=m.select,h.prototype.selectAll=m.selectAll}),d.plugin(function(a){function b(a,b,d,e,f,g){return null==b&&"[object SVGMatrix]"==c.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+d,this.d=+e,this.e=+f,this.f=+g):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var c=Object.prototype.toString,d=String,e=Math,f="";!function(c){function g(a){return a[0]*a[0]+a[1]*a[1]}function h(a){var b=e.sqrt(g(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}c.add=function(a,c,d,e,f,g){var h,i,j,k,l=[[],[],[]],m=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],n=[[a,d,f],[c,e,g],[0,0,1]];for(a&&a instanceof b&&(n=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),h=0;3>h;h++)for(i=0;3>i;i++){for(k=0,j=0;3>j;j++)k+=m[h][j]*n[j][i];l[h][i]=k}return this.a=l[0][0],this.b=l[1][0],this.c=l[0][1],this.d=l[1][1],this.e=l[0][2],this.f=l[1][2],this},c.invert=function(){var a=this,c=a.a*a.d-a.b*a.c;return new b(a.d/c,-a.b/c,-a.c/c,a.a/c,(a.c*a.f-a.d*a.e)/c,(a.b*a.e-a.a*a.f)/c)},c.clone=function(){return new b(this.a,this.b,this.c,this.d,this.e,this.f)},c.translate=function(a,b){return this.add(1,0,0,1,a,b)},c.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},c.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var f=+e.cos(b).toFixed(9),g=+e.sin(b).toFixed(9);return this.add(f,g,-g,f,c,d),this.add(1,0,0,1,-c,-d)},c.x=function(a,b){return a*this.a+b*this.c+this.e},c.y=function(a,b){return a*this.b+b*this.d+this.f},c.get=function(a){return+this[d.fromCharCode(97+a)].toFixed(4)},c.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},c.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},c.determinant=function(){return this.a*this.d-this.b*this.c},c.split=function(){var b={};b.dx=this.e,b.dy=this.f;var c=[[this.a,this.c],[this.b,this.d]];b.scalex=e.sqrt(g(c[0])),h(c[0]),b.shear=c[0][0]*c[1][0]+c[0][1]*c[1][1],c[1]=[c[1][0]-c[0][0]*b.shear,c[1][1]-c[0][1]*b.shear],b.scaley=e.sqrt(g(c[1])),h(c[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var d=-c[0][1],f=c[1][1];return 0>f?(b.rotate=a.deg(e.acos(f)),0>d&&(b.rotate=360-b.rotate)):b.rotate=a.deg(e.asin(d)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},c.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:f)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:f)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:f))}}(b.prototype),a.Matrix=b,a.matrix=function(a,c,d,e,f,g){return new b(a,c,d,e,f,g)}}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,n(this).appendChild(e),e=l(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||p(e.node,{id:e.id});var g=q(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=a(n(this).ownerSVGElement).gradient(e);h?(h.node.id||p(h.node,{id:h.id}),g=q(h.node.id)):g=e}else g=r(g);var i={};i[d]=g,p(this.node,i),this.node.style[d]=t}}function h(a){b.stop(),a==+a&&(a+="px"),this.node.style.fontSize=a}function i(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&b.push(1==f.childNodes.length&&3==f.firstChild.nodeType?f.firstChild.nodeValue:i(f))}return b}function j(){return b.stop(),this.node.style.fontSize}var k=a._.make,l=a._.wrap,m=a.is,n=a._.getSomeDefs,o=/^url\(#?([^)]+)\)$/,p=a._.$,q=a.url,r=String,s=a._.separator,t="";b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,n(this).appendChild(a),a=l(a)),"mask"==a.type)var d=a;else d=k("mask",n(this)),d.node.appendChild(a.node);!d.node.id&&p(d.node,{id:d.id}),p(this.node,{mask:q(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){if(b.stop(),"clipPath"==a.type)var d=a;else d=k("clipPath",n(this)),d.node.appendChild(a.node),!d.node.id&&p(d.node,{id:d.id});p(this.node,{"clip-path":q(d.node.id||d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var u=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=r(a);var b=a.match(u);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(c){b.stop(),m(c,"array")&&m(c[0],"array")&&(c=a.path.toString.call(c)),c=r(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),p(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=r(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=m(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):m(a,"array")?a.join(" "):a,p(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),p(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(m(a,"string")){var g=n(this),h=l(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=l(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=p("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=l(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=p("tspan");if(m(a,"array"))for(var c=0;c<a.length;c++)b.appendChild(d(a[c]));else b.appendChild(e.doc.createTextNode(a));return b.normalize&&b.normalize(),b};c.firstChild;)c.removeChild(c.firstChild);for(var f=d(a);f.firstChild;)c.appendChild(f.firstChild)}b.stop()})(-1),b.on("snap.util.attr.fontSize",h)(-1),b.on("snap.util.attr.font-size",h)(-1),b.on("snap.util.getattr.transform",function(){return b.stop(),this.transform()})(-1),b.on("snap.util.getattr.textpath",function(){return b.stop(),this.textPath})(-1),function(){function c(c){return function(){b.stop();var d=e.doc.defaultView.getComputedStyle(this.node,null).getPropertyValue("marker-"+c);return"none"==d?d:a(e.doc.getElementById(d.match(o)[1]))}}function d(a){return function(c){b.stop();var d="marker"+a.charAt(0).toUpperCase()+a.substring(1);if(""==c||!c)return void(this.node.style[d]="none");if("marker"==c.type){var e=c.node.id;return e||p(c.node,{id:c.id}),void(this.node.style[d]=q(e))}}}b.on("snap.util.getattr.marker-end",c("end"))(-1),b.on("snap.util.getattr.markerEnd",c("end"))(-1),b.on("snap.util.getattr.marker-start",c("start"))(-1),b.on("snap.util.getattr.markerStart",c("start"))(-1),b.on("snap.util.getattr.marker-mid",c("mid"))(-1),b.on("snap.util.getattr.markerMid",c("mid"))(-1),b.on("snap.util.attr.marker-end",d("end"))(-1),b.on("snap.util.attr.markerEnd",d("end"))(-1),b.on("snap.util.attr.marker-start",d("start"))(-1),b.on("snap.util.attr.markerStart",d("start"))(-1),b.on("snap.util.attr.marker-mid",d("mid"))(-1),b.on("snap.util.attr.markerMid",d("mid"))(-1)}(),b.on("snap.util.getattr.r",function(){return"rect"==this.type&&p(this.node,"rx")==p(this.node,"ry")?(b.stop(),p(this.node,"rx")):void 0})(-1),b.on("snap.util.getattr.text",function(){if("text"==this.type||"tspan"==this.type){b.stop();var a=i(this.node);return 1==a.length?a[0]:a}})(-1),b.on("snap.util.getattr.#text",function(){return this.node.textContent})(-1),b.on("snap.util.getattr.viewBox",function(){b.stop();var c=p(this.node,"viewBox");return c?(c=c.split(s),a._.box(+c[0],+c[1],+c[2],+c[3])):void 0})(-1),b.on("snap.util.getattr.points",function(){var a=p(this.node,"points");return b.stop(),a?a.split(s):void 0})(-1),b.on("snap.util.getattr.path",function(){var a=p(this.node,"d");return b.stop(),a})(-1),b.on("snap.util.getattr.class",function(){return this.node.className.baseVal})(-1),b.on("snap.util.getattr.fontSize",j)(-1),b.on("snap.util.getattr.font-size",j)(-1)}),d.plugin(function(a,b){var c=/\S+/g,d=String,e=b.prototype;e.addClass=function(a){var b,e,f,g,h=d(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];if(h.length){for(b=0;f=h[b++];)e=k.indexOf(f),~e||k.push(f);g=k.join(" "),j!=g&&(i.className.baseVal=g)}return this},e.removeClass=function(a){var b,e,f,g,h=d(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];if(k.length){for(b=0;f=h[b++];)e=k.indexOf(f),~e&&k.splice(e,1);g=k.join(" "),j!=g&&(i.className.baseVal=g)}return this},e.hasClass=function(a){var b=this.node,d=b.className.baseVal,e=d.match(c)||[];return!!~e.indexOf(a)},e.toggleClass=function(a,b){if(null!=b)return b?this.addClass(a):this.removeClass(a);var d,e,f,g,h=(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];for(d=0;f=h[d++];)e=k.indexOf(f),~e?k.splice(e,1):k.push(f);return g=k.join(" "),j!=g&&(i.className.baseVal=g),this}}),d.plugin(function(){function a(a){return a}function c(a){return function(b){return+b.toFixed(3)+a}}var d={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"/":function(a,b){return a/b},"*":function(a,b){return a*b}},e=String,f=/[a-z]+$/i,g=/^\s*([+\-\/*])\s*=\s*([\d.eE+\-]+)\s*([^\d\s]+)?\s*$/;b.on("snap.util.attr",function(a){var c=e(a).match(g);if(c){var h=b.nt(),i=h.substring(h.lastIndexOf(".")+1),j=this.attr(i),k={};b.stop();var l=c[3]||"",m=j.match(f),n=d[c[1]];if(m&&m==l?a=n(parseFloat(j),+c[2]):(j=this.asPX(i),a=n(this.asPX(i),this.asPX(i,c[2]+l))),isNaN(j)||isNaN(a))return;k[i]=a,this.attr(k)}})(-10),b.on("snap.util.equal",function(h,i){var j=e(this.attr(h)||""),k=e(i).match(g);if(k){b.stop();var l=k[3]||"",m=j.match(f),n=d[k[1]];return m&&m==l?{from:parseFloat(j),to:n(parseFloat(j),+k[2]),f:c(m)}:(j=this.asPX(h),{from:j,to:n(j,this.asPX(h,k[2]+l)),f:a})}})(-10)}),d.plugin(function(c,d,e,f){var g=e.prototype,h=c.is;g.rect=function(a,b,c,d,e,f){var g;return null==f&&(f=e),h(a,"object")&&"[object Object]"==a?g=a:null!=a&&(g={x:a,y:b,width:c,height:d},null!=e&&(g.rx=e,g.ry=f)),this.el("rect",g)},g.circle=function(a,b,c){var d;return h(a,"object")&&"[object Object]"==a?d=a:null!=a&&(d={cx:a,cy:b,r:c}),this.el("circle",d)};var i=function(){function a(){this.parentNode.removeChild(this)}return function(b,c){var d=f.doc.createElement("img"),e=f.doc.body;d.style.cssText="position:absolute;left:-9999em;top:-9999em",d.onload=function(){c.call(d),d.onload=d.onerror=null,e.removeChild(d)},d.onerror=a,e.appendChild(d),d.src=b}}();g.image=function(a,b,d,e,f){var g=this.el("image");if(h(a,"object")&&"src"in a)g.attr(a);else if(null!=a){var j={"xlink:href":a,preserveAspectRatio:"none"};null!=b&&null!=d&&(j.x=b,j.y=d),null!=e&&null!=f?(j.width=e,j.height=f):i(a,function(){c._.$(g.node,{width:this.offsetWidth,height:this.offsetHeight})}),c._.$(g.node,j)}return g},g.ellipse=function(a,b,c,d){var e;return h(a,"object")&&"[object Object]"==a?e=a:null!=a&&(e={cx:a,cy:b,rx:c,ry:d}),this.el("ellipse",e)},g.path=function(a){var b;return h(a,"object")&&!h(a,"array")?b=a:a&&(b={d:a}),this.el("path",b)},g.group=g.g=function(a){var b=this.el("g");return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},g.svg=function(a,b,c,d,e,f,g,i){var j={};return h(a,"object")&&null==b?j=a:(null!=a&&(j.x=a),null!=b&&(j.y=b),null!=c&&(j.width=c),null!=d&&(j.height=d),null!=e&&null!=f&&null!=g&&null!=i&&(j.viewBox=[e,f,g,i])),this.el("svg",j)},g.mask=function(a){var b=this.el("mask");return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},g.ptrn=function(a,b,c,d,e,f,g,i){if(h(a,"object"))var j=a;else j={patternUnits:"userSpaceOnUse"},a&&(j.x=a),b&&(j.y=b),null!=c&&(j.width=c),null!=d&&(j.height=d),j.viewBox=null!=e&&null!=f&&null!=g&&null!=i?[e,f,g,i]:[a||0,b||0,c||0,d||0];return this.el("pattern",j)},g.use=function(a){return null!=a?(a instanceof d&&(a.attr("id")||a.attr({id:c._.id(a)}),a=a.attr("id")),"#"==String(a).charAt()&&(a=a.substring(1)),this.el("use",{"xlink:href":"#"+a})):d.prototype.use.call(this)},g.symbol=function(a,b,c,d){var e={};return null!=a&&null!=b&&null!=c&&null!=d&&(e.viewBox=[a,b,c,d]),this.el("symbol",e)},g.text=function(a,b,c){var d={};return h(a,"object")?d=a:null!=a&&(d={x:a,y:b,text:c||""}),this.el("text",d)},g.line=function(a,b,c,d){var e={};return h(a,"object")?e=a:null!=a&&(e={x1:a,x2:c,y1:b,y2:d}),this.el("line",e)},g.polyline=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},g.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function d(){return this.selectAll("stop")}function e(a,b){var d=k("stop"),e={offset:+b+"%"};return a=c.color(a),e["stop-color"]=a.hex,a.opacity<1&&(e["stop-opacity"]=a.opacity),k(d,e),this.node.appendChild(d),this}function f(){if("linearGradient"==this.type){var a=k(this.node,"x1")||0,b=k(this.node,"x2")||1,d=k(this.node,"y1")||0,e=k(this.node,"y2")||0;return c._.box(a,d,math.abs(b-a),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return c._.box(f-h,g-h,2*h,2*h)}function h(a,c){function d(a,b){for(var c=(b-l)/(a-m),d=m;a>d;d++)g[d].offset=+(+l+c*(d-m)).toFixed(2);m=a,l=b}var e,f=b("snap.util.grad.parse",null,c).firstDefined();if(!f)return null;f.params.unshift(a),e="l"==f.type.toLowerCase()?i.apply(0,f.params):j.apply(0,f.params),f.type!=f.type.toLowerCase()&&k(e.node,{gradientUnits:"userSpaceOnUse"});var g=f.stops,h=g.length,l=0,m=0;h--;for(var n=0;h>n;n++)"offset"in g[n]&&d(n,g[n].offset);for(g[h].offset=g[h].offset||100,d(h,g[h].offset),n=0;h>=n;n++){var o=g[n];e.addStop(o.color,o.offset)}return e}function i(a,b,g,h,i){var j=c._.make("linearGradient",a);return j.stops=d,j.addStop=e,j.getBBox=f,null!=b&&k(j.node,{x1:b,y1:g,x2:h,y2:i}),j}function j(a,b,g,h,i,j){var l=c._.make("radialGradient",a);return l.stops=d,l.addStop=e,l.getBBox=f,null!=b&&k(l.node,{cx:b,cy:g,r:h}),null!=i&&null!=j&&k(l.node,{fx:i,fy:j}),l}var k=c._.$;g.gradient=function(a){return h(this.defs,a)},g.gradientLinear=function(a,b,c,d){return i(this.defs,a,b,c,d)},g.gradientRadial=function(a,b,c,d,e){return j(this.defs,a,b,c,d,e)},g.toString=function(){var a,b=this.node.ownerDocument,d=b.createDocumentFragment(),e=b.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),c._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),a=e.innerHTML,d.removeChild(d.firstChild),a},g.toDataURL=function(){return a&&a.btoa?"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(this))):void 0},g.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):g.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b){function c(a){var b=c.ps=c.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[K](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function d(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:N.min(c,d)/2,r2:N.max(c,d)/2,r0:N.sqrt(c*c+d*d)/2,path:w(a,b,c,d),vb:[a,b,c,d].join(" ")}}function e(){return this.join(",").replace(L,"$1")}function f(a){var b=J(a);return b.toString=e,b}function g(a,b,c,d,e,f,g,h,j){return null==j?n(a,b,c,d,e,f,g,h):i(a,b,c,d,e,f,g,h,o(a,b,c,d,e,f,g,h,j))}function h(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,h){a instanceof b&&(a=a.attr("d")),a=E(a);for(var j,k,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.x<b.x2&&a.x>b.x||b.x<a.x2&&b.x>a.x)&&(a.y<b.y2&&a.y>b.y||b.y<a.y2&&b.y>a.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)<i)){var j,k=1,l=k/2,m=k-l,o=.01;for(j=n(a,b,c,d,e,f,g,h,m);S(j-i)>o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)<P(e,g)||P(a,c)>Q(e,g)||Q(b,d)<P(f,h)||P(b,d)>Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/8),k=~~(g/8),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&t(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.closest=function(b,c,e,f){for(var g=100,h=d(b-g/2,c-g/2,g,g),i=[],j=e[0].hasOwnProperty("x")?function(a){return{x:e[a].x,y:e[a].y}}:function(a){return{x:e[a],y:f[a]}},l=0;1e6>=g&&!l;){for(var m=0,n=e.length;n>m;m++){var o=j(m);if(k(h,o.x,o.y)){l++,i.push(o);break}}l||(g*=2,h=d(b-g/2,c-g/2,g,g))}if(1e6!=g){var p,q=1/0;for(m=0,n=i.length;n>m;m++){var r=a.len(b,c,i[m].x,i[m].y);q>r&&(q=r,i[m].len=r,p=i[m])}return p}},a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.bindings={},this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h=arguments;if(a.is(d,"array")&&a.is(h[h.length-1],"array"))var i=!0;var j,k=function(){j?this.b=j:j=this.b},l=0,m=this,n=g&&function(){++l==m.length&&g.call(this)
|
21 |
-
};return this.forEach(function(a,c){b.once("snap.animcreated."+a.id,k),i?h[c]&&a.animate.apply(a,h[c]):a.animate(d,e,f,n)})},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.bind=function(a,b,c){var d={};if("function"==typeof b)this.bindings[a]=b;else{var e=c||a;this.bindings[a]=function(a){d[e]=a,b.attr(d)}}return this},g.attr=function(a){var b={};for(var c in a)this.bindings[c]?this.bindings[c](a[c]):b[c]=a[c];for(var d=0,e=this.items.length;e>d;d++)this.items[d].attr(b);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;c<arguments.length;c++)i.push(arguments[c]);for(c=0;b>c;c++)h.push(this[a+c]);for(;c<this.length-a;c++)g.push(this[a+c]);var j=i.length;for(c=0;c<j+g.length;c++)this.items[a+c]=this[a+c]=j>c?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.Set=f,a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,c){function d(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function e(b,c,e){c=p(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];for(var f,g,h,i,l=Math.max(b.length,c.length),m=[],n=[],o=0;l>o;o++){if(h=b[o]||d(c[o]),i=c[o]||d(h),h[0]!=i[0]||"r"==h[0].toLowerCase()&&(h[2]!=i[2]||h[3]!=i[3])||"s"==h[0].toLowerCase()&&(h[3]!=i[3]||h[4]!=i[4])){b=a._.transform2matrix(b,e()),c=a._.transform2matrix(c,e()),m=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],n=[["m",c.a,c.b,c.c,c.d,c.e,c.f]];break}for(m[o]=[],n[o]=[],f=0,g=Math.max(h.length,i.length);g>f;f++)f in h&&(m[o][f]=h[f]),f in i&&(n[o][f]=i[f])}return{from:k(m),to:k(n),f:j(m)}}function f(a){return a}function g(a){return function(b){return+b.toFixed(3)+a}}function h(a){return a.join(" ")}function i(b){return a.rgb(b[0],b[1],b[2])}function j(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function k(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}function l(a){return isFinite(parseFloat(a))}function m(b,c){return a.is(b,"array")&&a.is(c,"array")?b.toString()==c.toString():!1}var n={},o=/[a-z]+$/i,p=String;n.stroke=n.fill="colour",c.prototype.equal=function(a,c){return b("snap.util.equal",this,a,c).firstDefined()},b.on("snap.util.equal",function(b,c){var d,q,r=p(this.attr(b)||""),s=this;if(l(r)&&l(c))return{from:parseFloat(r),to:parseFloat(c),f:f};if("colour"==n[b])return d=a.color(r),q=a.color(c),{from:[d.r,d.g,d.b,d.opacity],to:[q.r,q.g,q.b,q.opacity],f:i};if("viewBox"==b)return d=this.attr(b).vb.split(" ").map(Number),q=c.split(" ").map(Number),{from:d,to:q,f:h};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),e(r,c,function(){return s.getBBox(1)});if("d"==b||"path"==b)return d=a.path.toCubic(r,c),{from:k(d[0]),to:k(d[1]),f:j(d[0])};if("points"==b)return d=p(r).split(a._.separator),q=p(c).split(a._.separator),{from:d,to:q,f:function(a){return a}};var t=r.match(o),u=p(c).match(o);return t&&m(t,u)?{from:parseFloat(r),to:parseFloat(c),f:g(t)}:{from:this.asPX(b),to:this.asPX(b,c),f:f}})}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=(function(a,b){var c="y"==a?"scrollTop":"scrollLeft",d=b&&b.node?b.node.ownerDocument:e.doc;return d[c in d.documentElement?"documentElement":"body"][c]}),l=function(){return this.originalEvent.preventDefault()},m=function(){return this.originalEvent.stopPropagation()},n=function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y",d),i=k("x",d);if(h&&j[g](b))for(var n=0,o=e.targetTouches&&e.targetTouches.length;o>n;n++)if(e.targetTouches[n].target==a||a.contains(e.targetTouches[n].target)){var p=e;e=e.targetTouches[n],e.originalEvent=p,e.preventDefault=l,e.stopPropagation=m;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}},o=[],p=function(a){for(var c,d=a.clientX,e=a.clientY,f=k("y"),g=k("x"),i=o.length;i--;){if(c=o[i],h){for(var j,l=a.touches&&a.touches.length;l--;)if(j=a.touches[l],j.identifier==c.el._drag.id||c.el.node.contains(j.target)){d=j.clientX,e=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();{var m=c.el.node;m.nextSibling,m.parentNode,m.style.display}d+=g,e+=f,b("snap.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},q=function(c){a.unmousemove(p).unmouseup(q);for(var d,e=o.length;e--;)d=o[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c),b.off("snap.drag.*."+d.el.id);o=[]},r=i.length;r--;)!function(b){a[b]=f[b]=function(c,d){if(a.is(c,"function"))this.events=this.events||[],this.events.push({name:b,f:c,unbind:n(this.node||document,b,c,d||this)});else for(var e=0,f=this.events.length;f>e;e++)if(this.events[e].name==b)try{this.events[e].f.call(this)}catch(g){}return this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[r]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var s=[];f.drag=function(c,d,e,f,g,h){function i(i,j,l){(i.originalEvent||i).preventDefault(),k._drag.x=j,k._drag.y=l,k._drag.id=i.identifier,!o.length&&a.mousemove(p).mouseup(q),o.push({el:k,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+k.id,d),c&&b.on("snap.drag.move."+k.id,c),e&&b.on("snap.drag.end."+k.id,e),b("snap.drag.start."+k.id,g||f||k,j,l,i)}function j(a,c,d){b("snap.draginit."+k.id,k,a,c,d)}var k=this;if(!arguments.length){var l;return k.drag(function(a,b){this.attr({transform:l+(l?"T":"t")+[a,b]})},function(){l=this.transform().local})}return b.on("snap.draginit."+k.id,i),k._drag={},s.push({el:k,start:i,init:j}),k.mousedown(j),k},f.undrag=function(){for(var c=s.length;c--;)s[c].el==this&&(this.unmousedown(s[c].init),s.splice(c,1),b.unbind("snap.drag.*."+this.id),b.unbind("snap.draginit."+this.id));return!s.length&&a.unmousemove(p).unmouseup(q),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('<feGaussianBlur stdDeviation="{def}"/>',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('<feGaussianBlur in="SourceAlpha" stdDeviation="{blur}"/><feOffset dx="{dx}" dy="{dy}" result="offsetblur"/><feFlood flood-color="{color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="{opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {b} {h} 0 0 0 0 0 1 0"/>',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {h} {i} 0 0 0 0 0 1 0"/>',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="saturate" values="{amount}"/>',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('<feColorMatrix type="hueRotate" values="{angle}"/>',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="table" tableValues="{amount} {amount2}"/><feFuncG type="table" tableValues="{amount} {amount2}"/><feFuncB type="table" tableValues="{amount} {amount2}"/></feComponentTransfer>',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}"/><feFuncG type="linear" slope="{amount}"/><feFuncB type="linear" slope="{amount}"/></feComponentTransfer>',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}" intercept="{amount2}"/><feFuncG type="linear" slope="{amount}" intercept="{amount2}"/><feFuncB type="linear" slope="{amount}" intercept="{amount2}"/></feComponentTransfer>',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d.plugin(function(a,b){var c=a._.box,d=a.is,e=/^[^a-z]*([tbmlrc])/i,f=function(){return"T"+this.dx+","+this.dy};b.prototype.getAlign=function(a,b){null==b&&d(a,"string")&&(b=a,a=null),a=a||this.paper;var g=a.getBBox?a.getBBox():c(a),h=this.getBBox(),i={};switch(b=b&&b.match(e),b=b?b[1].toLowerCase():"c"){case"t":i.dx=0,i.dy=g.y-h.y;break;case"b":i.dx=0,i.dy=g.y2-h.y2;break;case"m":i.dx=0,i.dy=g.cy-h.cy;break;case"l":i.dx=g.x-h.x,i.dy=0;break;case"r":i.dx=g.x2-h.x2,i.dy=0;break;default:i.dx=g.cx-h.cx,i.dy=0}return i.toString=f,i},b.prototype.align=function(a,b){return this.transform("..."+this.getAlign(a,b))}}),d});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Snap.svg 0.4.1
|
2 |
+
//
|
3 |
+
// Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved.
|
4 |
+
//
|
5 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
6 |
+
// you may not use this file except in compliance with the License.
|
7 |
+
// You may obtain a copy of the License at
|
8 |
+
//
|
9 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
10 |
+
//
|
11 |
+
// Unless required by applicable law or agreed to in writing, software
|
12 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
13 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 |
+
// See the License for the specific language governing permissions and
|
15 |
+
// limitations under the License.
|
16 |
+
//
|
17 |
+
// build: 2015-04-13
|
18 |
+
|
19 |
+
!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g=/\s*,\s*/,h="*",i=function(a,b){return a-b},j={n:{}},k=function(){for(var a=0,b=this.length;b>a;a++)if("undefined"!=typeof this[a])return this[a]},l=function(){for(var a=this.length;--a;)if("undefined"!=typeof this[a])return this[a]},m=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=m.listeners(a),j=0,n=[],o={},p=[],q=b;p.firstDefined=k,p.lastDefined=l,b=a,c=0;for(var r=0,s=h.length;s>r;r++)"zIndex"in h[r]&&(n.push(h[r].zIndex),h[r].zIndex<0&&(o[h[r].zIndex]=h[r]));for(n.sort(i);n[j]<0;)if(e=o[n[j++]],p.push(e.apply(d,g)),c)return c=f,p;for(r=0;s>r;r++)if(e=h[r],"zIndex"in e)if(e.zIndex==n[j]){if(p.push(e.apply(d,g)),c)break;do if(j++,e=o[n[j]],e&&p.push(e.apply(d,g)),c)break;while(e)}else o[e.zIndex]=e;else if(p.push(e.apply(d,g)),c)break;return c=f,b=q,p};m._events=j,m.listeners=function(a){var b,c,d,e,g,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,g=m.length;g>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[h]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},m.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(g),d=0,e=c.length;e>d;d++)!function(a){for(var c,d=a.split(f),e=j,g=0,h=d.length;h>g;g++)e=e.n,e=e.hasOwnProperty(d[g])&&e[d[g]]||(e[d[g]]={n:{}});for(e.f=e.f||[],g=0,h=e.f.length;h>g;g++)if(e.f[g]==b){c=!0;break}!c&&e.f.push(b)}(c[d]);return function(a){+a==+a&&(b.zIndex=+a)}},m.f=function(a){var b=[].slice.call(arguments,1);return function(){m.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},m.stop=function(){c=1},m.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},m.nts=function(){return b.split(f)},m.off=m.unbind=function(a,b){if(!a)return void(m._events=j={n:{}});var c=a.split(g);if(c.length>1)for(var d=0,i=c.length;i>d;d++)m.off(c[d],b);else{c=a.split(f);var k,l,n,d,i,o,p,q=[j];for(d=0,i=c.length;i>d;d++)for(o=0;o<q.length;o+=n.length-2){if(n=[o,1],k=q[o].n,c[d]!=h)k[c[d]]&&n.push(k[c[d]]);else for(l in k)k[e](l)&&n.push(k[l]);q.splice.apply(q,n)}for(d=0,i=q.length;i>d;d++)for(k=q[d];k.n;){if(b){if(k.f){for(o=0,p=k.f.length;p>o;o++)if(k.f[o]==b){k.f.splice(o,1);break}!k.f.length&&delete k.f}for(l in k.n)if(k.n[e](l)&&k.n[l].f){var r=k.n[l].f;for(o=0,p=r.length;p>o;o++)if(r[o]==b){r.splice(o,1);break}!r.length&&delete k.n[l].f}}else{delete k.f;for(l in k.n)k.n[e](l)&&k.n[l].f&&delete k.n[l].f}k=k.n}}},m.once=function(a,b){var c=function(){return m.unbind(a,c),b.apply(this,arguments)};return m.on(a,c)},m.version=d,m.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=m:"function"==typeof define&&define.amd?define("eve",[],function(){return m}):a.eve=m}(this),function(a,b){if("function"==typeof define&&define.amd)define(["eve"],function(c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("eve");module.exports=b(a,c)}else b(a,a.eve)}(window||this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(a){function c(a,b){if(a){if(a.nodeType)return w(a);if(e(a,"array")&&c.set)return c.set.apply(c,a);if(a instanceof s)return a;if(null==b)return a=y.doc.querySelector(String(a)),w(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new v(a,b)}function d(a,b){if(b){if("#text"==a&&(a=y.doc.createTextNode(b.text||b["#text"]||"")),"#comment"==a&&(a=y.doc.createComment(b.text||b["#text"]||"")),"string"==typeof a&&(a=d(a)),"string"==typeof b)return 1==a.nodeType?"xlink:"==b.substring(0,6)?a.getAttributeNS(T,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(U,b.substring(4)):a.getAttribute(b):"text"==b?a.nodeValue:null;if(1==a.nodeType){for(var c in b)if(b[z](c)){var e=A(b[c]);e?"xlink:"==c.substring(0,6)?a.setAttributeNS(T,c.substring(6),e):"xml:"==c.substring(0,4)?a.setAttributeNS(U,c.substring(4),e):a.setAttribute(c,e):a.removeAttribute(c)}}else"text"in b&&(a.nodeValue=b.text)}else a=y.doc.createElementNS(U,a);return a}function e(a,b){return b=A.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||J.call(a).slice(8,-1).toLowerCase()==b}function f(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=f(a[c]));return b}function h(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function i(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},i=d.count=d.count||[];return g[z](f)?(h(i,f),c?c(g[f]):g[f]):(i.length>=1e3&&delete g[i.shift()],i.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function j(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*D.atan2(-h,-g)/H+360)%360:0}return j(a,b,e,f)-j(c,d,e,f)}function k(a){return a%360*H/180}function l(a){return 180*a/H%360}function m(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,D.tan(k(d[0])),1,0,0]:"skewY"==c?["m",1,D.tan(k(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function n(a,b){var d=ab(a),e=new c.Matrix;if(d)for(var f=0,g=d.length;g>f;f++){var h,i,j,k,l,m=d[f],n=m.length,o=A(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function o(a){var b=a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||a.node.parentNode&&w(a.node.parentNode)||c.select("svg")||c(0,0),d=b.select("defs"),e=null==d?!1:d.node;return e||(e=u("defs",b.node).node),e}function p(a){return a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||c.select("svg")}function q(a,b,c){function e(a){if(null==a)return I;if(a==+a)return a;d(j,{width:a});try{return j.getBBox().width}catch(b){return 0}}function f(a){if(null==a)return I;if(a==+a)return a;d(j,{height:a});try{return j.getBBox().height}catch(b){return 0}}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=p(a).node,i={},j=h.querySelector(".svg---mgr");switch(j||(j=d("rect"),d(j,{x:-9e9,y:-9e9,width:10,height:10,"class":"svg---mgr",fill:"none"}),h.appendChild(j)),a.type){case"rect":g("rx",e),g("ry",f);case"image":g("width",e),g("height",f);case"text":g("x",e),g("y",f);break;case"circle":g("cx",e),g("cy",f),g("r",e);break;case"ellipse":g("cx",e),g("cy",f),g("rx",e),g("ry",f);break;case"line":g("x1",e),g("x2",e),g("y1",f),g("y2",f);break;case"marker":g("refX",e),g("markerWidth",e),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",e),g("fy",f);break;case"tspan":g("dx",e),g("dy",f);break;default:g(b,e)}return h.removeChild(j),i}function r(a){e(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;b<a.length;b++)"set"==a[b].type?a[b].forEach(function(a){d.appendChild(a.node)}):d.appendChild(a[b].node);var f=d.childNodes;for(b=0;b<f.length;b++)this[c++]=w(f[b]);return this}function s(a){if(a.snap in V)return V[a.snap];var b;try{b=a.ownerSVGElement}catch(c){}this.node=a,b&&(this.paper=new v(b)),this.type=a.tagName||a.nodeName;var d=this.id=S(this);if(this.anims={},this._={transform:[]},a.snap=d,V[d]=this,"g"==this.type&&(this.add=r),this.type in{g:1,mask:1,pattern:1,symbol:1})for(var e in v.prototype)v.prototype[z](e)&&(this[e]=v.prototype[e])}function t(a){this.node=a}function u(a,b){var c=d(a);b.appendChild(c);var e=w(c);return e}function v(a,b){var c,e,f,g=v.prototype;if(a&&"svg"==a.tagName){if(a.snap in V)return V[a.snap];var h=a.ownerDocument;c=new s(a),e=a.getElementsByTagName("desc")[0],f=a.getElementsByTagName("defs")[0],e||(e=d("desc"),e.appendChild(h.createTextNode("Created with Snap")),c.node.appendChild(e)),f||(f=d("defs"),c.node.appendChild(f)),c.defs=f;for(var i in g)g[z](i)&&(c[i]=g[i]);c.paper=c.root=c}else c=u("svg",y.doc.body),d(c.node,{height:b,version:1.1,width:a,xmlns:U});return c}function w(a){return a?a instanceof s||a instanceof t?a:a.tagName&&"svg"==a.tagName.toLowerCase()?new v(a):a.tagName&&"object"==a.tagName.toLowerCase()&&"image/svg+xml"==a.type?new v(a.contentDocument.getElementsByTagName("svg")[0]):new s(a):a}function x(a,b){for(var c=0,d=a.length;d>c;c++){var e={type:a[c].type,attr:a[c].attr()},f=a[c].children();b.push(e),f.length&&x(f,e.childNodes=[])}}c.version="0.4.0",c.toString=function(){return"Snap v"+this.version},c._={};var y={win:a.window,doc:a.window.document};c._.glob=y;{var z="hasOwnProperty",A=String,B=parseFloat,C=parseInt,D=Math,E=D.max,F=D.min,G=D.abs,H=(D.pow,D.PI),I=(D.round,""),J=Object.prototype.toString,K=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,L=(c._.separator=/[,\s]+/,/[\s]*,[\s]*/),M={hs:1,rg:1},N=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,O=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,P=/(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/gi,Q=0,R="S"+(+new Date).toString(36),S=function(a){return(a&&a.type?a.type:I)+R+(Q++).toString(36)},T="http://www.w3.org/1999/xlink",U="http://www.w3.org/2000/svg",V={};c.url=function(a){return"url('#"+a+"')"}}c._.$=d,c._.id=S,c.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return A(b).replace(a,function(a,b){return c(a,b,d)})}}(),c._.clone=f,c._.cacher=i,c.rad=k,c.deg=l,c.sin=function(a){return D.sin(c.rad(a))},c.tan=function(a){return D.tan(c.rad(a))},c.cos=function(a){return D.cos(c.rad(a))},c.asin=function(a){return c.deg(D.asin(a))},c.acos=function(a){return c.deg(D.acos(a))},c.atan=function(a){return c.deg(D.atan(a))},c.atan2=function(a){return c.deg(D.atan2(a))},c.angle=j,c.len=function(a,b,d,e){return Math.sqrt(c.len2(a,b,d,e))},c.len2=function(a,b,c,d){return(a-c)*(a-c)+(b-d)*(b-d)},c.closestPoint=function(a,b,c){function d(a){var d=a.x-b,e=a.y-c;return d*d+e*e}for(var e,f,g,h,i=a.node,j=i.getTotalLength(),k=j/i.pathSegList.numberOfItems*.125,l=1/0,m=0;j>=m;m+=k)(h=d(g=i.getPointAtLength(m)))<l&&(e=g,f=m,l=h);for(k*=.5;k>.5;){var n,o,p,q,r,s;(p=f-k)>=0&&(r=d(n=i.getPointAtLength(p)))<l?(e=n,f=p,l=r):(q=f+k)<=j&&(s=d(o=i.getPointAtLength(q)))<l?(e=o,f=q,l=s):k*=.5}return e={x:e.x,y:e.y,length:f,distance:Math.sqrt(l)}},c.is=e,c.snapTo=function(a,b,c){if(c=e(c,"finite")?c:10,e(a,"array")){for(var d=a.length;d--;)if(G(a[d]-b)<=c)return a[d]}else{a=+a;var f=b%a;if(c>f)return b-f;if(f>a-c)return b-f+a}return b},c.getRGB=i(function(a){if(!a||(a=A(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:Z};if(!(M[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=W(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};var b,d,f,g,h,i,j=a.match(K);return j?(j[2]&&(f=C(j[2].substring(5),16),d=C(j[2].substring(3,5),16),b=C(j[2].substring(1,3),16)),j[3]&&(f=C((h=j[3].charAt(3))+h,16),d=C((h=j[3].charAt(2))+h,16),b=C((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=B(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),f=B(i[2]),"%"==i[2].slice(-1)&&(f*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsb2rgb(b,d,f,g)):j[6]?(i=j[6].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsl2rgb(b,d,f,g)):(b=F(D.round(b),255),d=F(D.round(d),255),f=F(D.round(f),255),g=F(E(g,0),1),j={r:b,g:d,b:f,toString:Z},j.hex="#"+(16777216|f|d<<8|b<<16).toString(16).slice(1),j.opacity=e(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z}},c),c.hsb=i(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=i(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=i(function(a,b,c,d){if(e(d,"finite")){var f=D.round;return"rgba("+[f(a),f(b),f(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var W=function(a){var b=y.doc.getElementsByTagName("head")[0]||y.doc.getElementsByTagName("svg")[0],c="rgb(255, 0, 0)";return(W=i(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=y.doc.defaultView.getComputedStyle(b,I).getPropertyValue("color");return d==c?null:d}))(a)},X=function(){return"hsb("+[this.h,this.s,this.b]+")"},Y=function(){return"hsl("+[this.h,this.s,this.l]+")"},Z=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},$=function(a,b,d){if(null==b&&e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&e(a,string)){var f=c.getRGB(a);a=f.r,b=f.g,d=f.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},_=function(a,b,d,f){a=D.round(255*a),b=D.round(255*b),d=D.round(255*d);var g={r:a,g:b,b:d,opacity:e(f,"finite")?f:1,hex:c.rgb(a,b,d),toString:Z};return e(f,"finite")&&(g.opacity=f),g};c.color=function(a){var b;return e(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):e(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(e(a,"string")&&(a=c.getRGB(a)),e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=Z,a},c.hsb2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var f,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-G(a%2-1)),f=g=h=c-j,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.hsl2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var f,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-G(a%2-1)),f=g=h=c-j/2,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.rgb2hsb=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=E(a,b,c),g=f-F(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:X}},c.rgb2hsl=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=E(a,b,c),h=F(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:Y}},c.parsePathString=function(a){if(!a)return null;var b=c.path(a);if(b.arr)return c.path.clone(b.arr);var d={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},f=[];return e(a,"array")&&e(a[0],"array")&&(f=c.path.clone(a)),f.length||A(a).replace(N,function(a,b,c){var e=[],g=b.toLowerCase();if(c.replace(P,function(a,b){b&&e.push(+b)}),"m"==g&&e.length>2&&(f.push([b].concat(e.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==e.length&&f.push([b,e[0]]),"r"==g)f.push([b].concat(e));else for(;e.length>=d[g]&&(f.push([b].concat(e.splice(0,d[g]))),d[g]););}),f.toString=c.path.toString,b.arr=c.path.clone(f),f};var ab=c.parseTransformString=function(a){if(!a)return null;var b=[];return e(a,"array")&&e(a[0],"array")&&(b=c.path.clone(a)),b.length||A(a).replace(O,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(P,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=c.path.toString,b};c._.svgTransform2string=m,c._.rgTransform=/^[a-z][\s]*-?\.?\d/i,c._.transform2matrix=n,c._unit2px=q;y.doc.contains||y.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};c._.getSomeDefs=o,c._.getSomeSVG=p,c.select=function(a){return a=A(a).replace(/([^\\]):/g,"$1\\:"),w(y.doc.querySelector(a))},c.selectAll=function(a){for(var b=y.doc.querySelectorAll(a),d=(c.set||Array)(),e=0;e<b.length;e++)d.push(w(b[e]));return d},setInterval(function(){for(var a in V)if(V[z](a)){var b=V[a],c=b.node;("svg"!=b.type&&!c.ownerSVGElement||"svg"==b.type&&(!c.parentNode||"ownerSVGElement"in c.parentNode&&!c.ownerSVGElement))&&delete V[a]}},1e4),s.prototype.attr=function(a,c){var d=this,f=d.node;if(!a){if(1!=f.nodeType)return{text:f.nodeValue};for(var g=f.attributes,h={},i=0,j=g.length;j>i;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d},c.parse=function(a){var b=y.doc.createDocumentFragment(),c=!0,d=y.doc.createElement("div");if(a=A(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a="<svg>"+a+"</svg>",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return new t(b)},c.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=y.doc.createDocumentFragment(),d=0,e=a.length;e>d;d++){var f=a[d];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(c.parse(f).node)}return new t(b)},c._.make=u,c._.wrap=w,v.prototype.el=function(a,b){var c=u(a,this.node);return b&&c.attr(b),c},s.prototype.children=function(){for(var a=[],b=this.node.childNodes,d=0,e=b.length;e>d;d++)a[d]=c(b[d]);return a},s.prototype.toJSON=function(){var a=[];return x([this],a),a[0]},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return bb[z](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):d(this.node,a)});var bb={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),e={};c=c.substring(c.lastIndexOf(".")+1),e[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});bb[z](g)?this.node.style[f]=null==a?I:a:d(this.node,e)}),function(){}(v.prototype),c.ajax=function(a,c,d,f){var g=new XMLHttpRequest,h=S();if(g){if(e(c,"function"))f=d,d=c,c=null;else if(e(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,f,g)},4==g.readyState?g:(g.send(c),g)}},c.load=function(a,b,d){c.ajax(a,function(a){var e=c.parse(a.responseText);d?b.call(d,e):b(e)})};var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return c.getElementByPoint=function(a,b){var c=this,d=(c.canvas,y.doc.elementFromPoint(a,b));if(y.win.opera&&"svg"==d.tagName){var e=cb(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?w(d):null},c.plugin=function(a){a(c,s,v,y,t)},y.win.Snap=c,c}(a||this);return d.plugin(function(d,e,f,g,h){function i(a,b){if(null==b){var c=!0;if(b=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new d.Matrix;b=d._.svgTransform2string(b)}else b=d._.rgTransform.test(b)?o(b).replace(/\.{3}|\u2026/g,a._.transform||""):d._.svgTransform2string(b),n(b,"array")&&(b=d.path?d.path.toString.call(b):o(b)),a._.transform=b;var e=d._.transform2matrix(b,a.getBBox(1));return c?e:void(a.matrix=e)}function j(a){function b(a,b){var c=q(a.node,b);c=c&&c.match(f),c=c&&c[2],c&&"#"==c.charAt()&&(c=c.substring(1),c&&(h[c]=(h[c]||[]).concat(function(c){var d={};d[b]=URL(c),q(a.node,d)})))}function c(a){var b=q(a.node,"xlink:href");b&&"#"==b.charAt()&&(b=b.substring(1),b&&(h[b]=(h[b]||[]).concat(function(b){a.attr("xlink:href","#"+b)})))}for(var d,e=a.selectAll("*"),f=/^\s*url\(("|'|)(.*)\1\)\s*$/,g=[],h={},i=0,j=e.length;j>i;i++){d=e[i],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var k=q(d.node,"id");k&&(q(d.node,{id:d.id}),g.push({old:k,id:d.id}))}for(i=0,j=g.length;j>i;i++){var l=h[g[i].old];if(l)for(var m=0,n=l.length;n>m;m++)l[m](g[i].id)}}function k(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function l(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=u(d[e]).toString());a&&(b+="</"+this.type+">")}else a&&(b+="/>");return b}}var m=e.prototype,n=d.is,o=String,p=d._unit2px,q=d._.$,r=d._.make,s=d._.getSomeDefs,t="hasOwnProperty",u=d._.wrap;m.getBBox=function(a){if(!d.Matrix||!d.path)return this.node.getBBox();var b=this,c=new d.Matrix;if(b.removed)return d._.box();for(;"use"==b.type;)if(a||(c=c.add(b.transform().localMatrix.translate(b.attr("x")||0,b.attr("y")||0))),b.original)b=b.original;else{var e=b.attr("xlink:href");b=b.original=b.node.ownerDocument.getElementById(e.substring(e.indexOf("#")+1))}var f=b._,g=d.path.get[b.type]||d.path.get.deflt;try{return a?(f.bboxwt=g?d.path.getBBox(b.realPath=g(b)):d._.box(b.node.getBBox()),d._.box(f.bboxwt)):(b.realPath=g(b),b.matrix=b.transform().localMatrix,f.bbox=d.path.getBBox(d.path.map(b.realPath,c.add(b.matrix))),d._.box(f.bbox))}catch(h){return d._.box()}};var v=function(){return this.string};m.transform=function(a){var b=this._;if(null==a){for(var c,e=this,f=new d.Matrix(this.node.getCTM()),g=i(this),h=[g],j=new d.Matrix,k=g.toTransformString(),l=o(g)==o(this.matrix)?o(b.transform):k;"svg"!=e.type&&(e=e.parent());)h.push(i(e));for(c=h.length;c--;)j.add(h[c]);return{string:l,globalMatrix:f,totalMatrix:j,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:j.toTransformString(),local:k,toString:v}}return a instanceof d.Matrix?(this.matrix=a,this._.transform=a.toTransformString()):i(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?q(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?q(this.node,{patternTransform:this.matrix}):q(this.node,{transform:this.matrix})),this},m.parent=function(){return u(this.node.parentNode)},m.append=m.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=u(a),this.node.appendChild(a.node),a.paper=this.paper}return this},m.appendTo=function(a){return a&&(a=u(a),a.append(this)),this},m.prepend=function(a){if(a){if("set"==a.type){var b,c=this;return a.forEach(function(a){b?b.after(a):c.prepend(a),b=a}),this}a=u(a);var d=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),d&&d.add()}return this},m.prependTo=function(a){return a=u(a),a.prepend(this),this},m.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=u(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},m.after=function(a){a=u(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},m.insertBefore=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.insertAfter=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},m.select=function(a){return u(this.node.querySelector(a))},m.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;e<b.length;e++)c.push(u(b[e]));return c},m.asPX=function(a,b){return null==b&&(b=this.attr(a)),+p(this,a,b)},m.use=function(){var a,b=this.node.id;return b||(b=this.id,q(this.node,{id:b})),a="linearGradient"==this.type||"radialGradient"==this.type||"pattern"==this.type?r(this.type,this.node.parentNode):r("use",this.node.parentNode),q(a.node,{"xlink:href":"#"+b}),a.original=this,a},m.clone=function(){var a=u(this.node.cloneNode(!0));return q(a.node,"id")&&q(a.node,{id:a.id}),j(a),a.insertAfter(this),a},m.toDefs=function(){var a=s(this);return a.appendChild(this.node),this},m.pattern=m.toPattern=function(a,b,c,d){var e=r("pattern",s(this));return null==a&&(a=this.getBBox()),n(a,"object")&&"x"in a&&(b=a.y,c=a.width,d=a.height,a=a.x),q(e.node,{x:a,y:b,width:c,height:d,patternUnits:"userSpaceOnUse",id:e.id,viewBox:[a,b,c,d].join(" ")}),e.node.appendChild(this.node),e},m.marker=function(a,b,c,d,e,f){var g=r("marker",s(this));return null==a&&(a=this.getBBox()),n(a,"object")&&"x"in a&&(b=a.y,c=a.width,d=a.height,e=a.refX||a.cx,f=a.refY||a.cy,a=a.x),q(g.node,{viewBox:[a,b,c,d].join(" "),markerWidth:c,markerHeight:d,orient:"auto",refX:e||0,refY:f||0,id:g.id}),g.node.appendChild(this.node),g};var w=function(a,b,d,e){"function"!=typeof d||d.length||(e=d,d=c.linear),this.attr=a,this.dur=b,d&&(this.easing=d),e&&(this.callback=e)};d._.Animation=w,d.animation=function(a,b,c,d){return new w(a,b,c,d)},m.inAnim=function(){var a=this,b=[];for(var c in a.anims)a.anims[t](c)&&!function(a){b.push({anim:new w(a._attrs,a.dur,a.easing,a._callback),mina:a,curStatus:a.status(),status:function(b){return a.status(b)},stop:function(){a.stop()}})}(a.anims[c]);return b},d.animate=function(a,d,e,f,g,h){"function"!=typeof g||g.length||(h=g,g=c.linear);var i=c.time(),j=c(a,d,i,i+f,c.time,e,g);return h&&b.once("mina.finish."+j.id,h),j},m.stop=function(){for(var a=this.inAnim(),b=0,c=a.length;c>b;b++)a[b].stop();return this},m.animate=function(a,d,e,f){"function"!=typeof e||e.length||(f=e,e=c.linear),a instanceof w&&(f=a.callback,e=a.easing,d=a.dur,a=a.attr);var g,h,i,j,l=[],m=[],p={},q=this;for(var r in a)if(a[t](r)){q.equal?(j=q.equal(r,o(a[r])),g=j.from,h=j.to,i=j.f):(g=+q.attr(r),h=+a[r]);var s=n(g,"array")?g.length:1;p[r]=k(l.length,l.length+s,i),l=l.concat(g),m=m.concat(h)}var u=c.time(),v=c(l,m,u,u+d,c.time,function(a){var b={};for(var c in p)p[t](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[v.id]=v,v._attrs=a,v._callback=f,b("snap.animcreated."+q.id,v),b.once("mina.finish."+v.id,function(){delete q.anims[v.id],f&&f.call(q)}),b.once("mina.stop."+v.id,function(){delete q.anims[v.id]}),q};var x={};m.data=function(a,c){var e=x[this.id]=x[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e;
|
20 |
+
if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[t](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a]}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},m.removeData=function(a){return null==a?x[this.id]={}:x[this.id]&&delete x[this.id][a],this},m.outerSVG=m.toString=l(1),m.innerSVG=l(),m.toDataURL=function(){if(a&&a.btoa){var b=this.getBBox(),c=d.format('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}" viewBox="{x} {y} {width} {height}">{contents}</svg>',{x:+b.x.toFixed(3),y:+b.y.toFixed(3),width:+b.width.toFixed(3),height:+b.height.toFixed(3),contents:this.outerSVG()});return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(c)))}},h.prototype.select=m.select,h.prototype.selectAll=m.selectAll}),d.plugin(function(a){function b(a,b,d,e,f,g){return null==b&&"[object SVGMatrix]"==c.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+d,this.d=+e,this.e=+f,this.f=+g):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var c=Object.prototype.toString,d=String,e=Math,f="";!function(c){function g(a){return a[0]*a[0]+a[1]*a[1]}function h(a){var b=e.sqrt(g(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}c.add=function(a,c,d,e,f,g){var h,i,j,k,l=[[],[],[]],m=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],n=[[a,d,f],[c,e,g],[0,0,1]];for(a&&a instanceof b&&(n=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),h=0;3>h;h++)for(i=0;3>i;i++){for(k=0,j=0;3>j;j++)k+=m[h][j]*n[j][i];l[h][i]=k}return this.a=l[0][0],this.b=l[1][0],this.c=l[0][1],this.d=l[1][1],this.e=l[0][2],this.f=l[1][2],this},c.invert=function(){var a=this,c=a.a*a.d-a.b*a.c;return new b(a.d/c,-a.b/c,-a.c/c,a.a/c,(a.c*a.f-a.d*a.e)/c,(a.b*a.e-a.a*a.f)/c)},c.clone=function(){return new b(this.a,this.b,this.c,this.d,this.e,this.f)},c.translate=function(a,b){return this.add(1,0,0,1,a,b)},c.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},c.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var f=+e.cos(b).toFixed(9),g=+e.sin(b).toFixed(9);return this.add(f,g,-g,f,c,d),this.add(1,0,0,1,-c,-d)},c.x=function(a,b){return a*this.a+b*this.c+this.e},c.y=function(a,b){return a*this.b+b*this.d+this.f},c.get=function(a){return+this[d.fromCharCode(97+a)].toFixed(4)},c.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},c.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},c.determinant=function(){return this.a*this.d-this.b*this.c},c.split=function(){var b={};b.dx=this.e,b.dy=this.f;var c=[[this.a,this.c],[this.b,this.d]];b.scalex=e.sqrt(g(c[0])),h(c[0]),b.shear=c[0][0]*c[1][0]+c[0][1]*c[1][1],c[1]=[c[1][0]-c[0][0]*b.shear,c[1][1]-c[0][1]*b.shear],b.scaley=e.sqrt(g(c[1])),h(c[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var d=-c[0][1],f=c[1][1];return 0>f?(b.rotate=a.deg(e.acos(f)),0>d&&(b.rotate=360-b.rotate)):b.rotate=a.deg(e.asin(d)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},c.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:f)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:f)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:f))}}(b.prototype),a.Matrix=b,a.matrix=function(a,c,d,e,f,g){return new b(a,c,d,e,f,g)}}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,n(this).appendChild(e),e=l(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||p(e.node,{id:e.id});var g=q(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=a(n(this).ownerSVGElement).gradient(e);h?(h.node.id||p(h.node,{id:h.id}),g=q(h.node.id)):g=e}else g=r(g);var i={};i[d]=g,p(this.node,i),this.node.style[d]=t}}function h(a){b.stop(),a==+a&&(a+="px"),this.node.style.fontSize=a}function i(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&b.push(1==f.childNodes.length&&3==f.firstChild.nodeType?f.firstChild.nodeValue:i(f))}return b}function j(){return b.stop(),this.node.style.fontSize}var k=a._.make,l=a._.wrap,m=a.is,n=a._.getSomeDefs,o=/^url\(#?([^)]+)\)$/,p=a._.$,q=a.url,r=String,s=a._.separator,t="";b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,n(this).appendChild(a),a=l(a)),"mask"==a.type)var d=a;else d=k("mask",n(this)),d.node.appendChild(a.node);!d.node.id&&p(d.node,{id:d.id}),p(this.node,{mask:q(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){if(b.stop(),"clipPath"==a.type)var d=a;else d=k("clipPath",n(this)),d.node.appendChild(a.node),!d.node.id&&p(d.node,{id:d.id});p(this.node,{"clip-path":q(d.node.id||d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var u=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=r(a);var b=a.match(u);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(c){b.stop(),m(c,"array")&&m(c[0],"array")&&(c=a.path.toString.call(c)),c=r(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),p(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=r(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=m(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):m(a,"array")?a.join(" "):a,p(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),p(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(m(a,"string")){var g=n(this),h=l(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=l(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=p("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=l(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=p("tspan");if(m(a,"array"))for(var c=0;c<a.length;c++)b.appendChild(d(a[c]));else b.appendChild(e.doc.createTextNode(a));return b.normalize&&b.normalize(),b};c.firstChild;)c.removeChild(c.firstChild);for(var f=d(a);f.firstChild;)c.appendChild(f.firstChild)}b.stop()})(-1),b.on("snap.util.attr.fontSize",h)(-1),b.on("snap.util.attr.font-size",h)(-1),b.on("snap.util.getattr.transform",function(){return b.stop(),this.transform()})(-1),b.on("snap.util.getattr.textpath",function(){return b.stop(),this.textPath})(-1),function(){function c(c){return function(){b.stop();var d=e.doc.defaultView.getComputedStyle(this.node,null).getPropertyValue("marker-"+c);return"none"==d?d:a(e.doc.getElementById(d.match(o)[1]))}}function d(a){return function(c){b.stop();var d="marker"+a.charAt(0).toUpperCase()+a.substring(1);if(""==c||!c)return void(this.node.style[d]="none");if("marker"==c.type){var e=c.node.id;return e||p(c.node,{id:c.id}),void(this.node.style[d]=q(e))}}}b.on("snap.util.getattr.marker-end",c("end"))(-1),b.on("snap.util.getattr.markerEnd",c("end"))(-1),b.on("snap.util.getattr.marker-start",c("start"))(-1),b.on("snap.util.getattr.markerStart",c("start"))(-1),b.on("snap.util.getattr.marker-mid",c("mid"))(-1),b.on("snap.util.getattr.markerMid",c("mid"))(-1),b.on("snap.util.attr.marker-end",d("end"))(-1),b.on("snap.util.attr.markerEnd",d("end"))(-1),b.on("snap.util.attr.marker-start",d("start"))(-1),b.on("snap.util.attr.markerStart",d("start"))(-1),b.on("snap.util.attr.marker-mid",d("mid"))(-1),b.on("snap.util.attr.markerMid",d("mid"))(-1)}(),b.on("snap.util.getattr.r",function(){return"rect"==this.type&&p(this.node,"rx")==p(this.node,"ry")?(b.stop(),p(this.node,"rx")):void 0})(-1),b.on("snap.util.getattr.text",function(){if("text"==this.type||"tspan"==this.type){b.stop();var a=i(this.node);return 1==a.length?a[0]:a}})(-1),b.on("snap.util.getattr.#text",function(){return this.node.textContent})(-1),b.on("snap.util.getattr.viewBox",function(){b.stop();var c=p(this.node,"viewBox");return c?(c=c.split(s),a._.box(+c[0],+c[1],+c[2],+c[3])):void 0})(-1),b.on("snap.util.getattr.points",function(){var a=p(this.node,"points");return b.stop(),a?a.split(s):void 0})(-1),b.on("snap.util.getattr.path",function(){var a=p(this.node,"d");return b.stop(),a})(-1),b.on("snap.util.getattr.class",function(){return this.node.className.baseVal})(-1),b.on("snap.util.getattr.fontSize",j)(-1),b.on("snap.util.getattr.font-size",j)(-1)}),d.plugin(function(a,b){var c=/\S+/g,d=String,e=b.prototype;e.addClass=function(a){var b,e,f,g,h=d(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];if(h.length){for(b=0;f=h[b++];)e=k.indexOf(f),~e||k.push(f);g=k.join(" "),j!=g&&(i.className.baseVal=g)}return this},e.removeClass=function(a){var b,e,f,g,h=d(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];if(k.length){for(b=0;f=h[b++];)e=k.indexOf(f),~e&&k.splice(e,1);g=k.join(" "),j!=g&&(i.className.baseVal=g)}return this},e.hasClass=function(a){var b=this.node,d=b.className.baseVal,e=d.match(c)||[];return!!~e.indexOf(a)},e.toggleClass=function(a,b){if(null!=b)return b?this.addClass(a):this.removeClass(a);var d,e,f,g,h=(a||"").match(c)||[],i=this.node,j=i.className.baseVal,k=j.match(c)||[];for(d=0;f=h[d++];)e=k.indexOf(f),~e?k.splice(e,1):k.push(f);return g=k.join(" "),j!=g&&(i.className.baseVal=g),this}}),d.plugin(function(){function a(a){return a}function c(a){return function(b){return+b.toFixed(3)+a}}var d={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"/":function(a,b){return a/b},"*":function(a,b){return a*b}},e=String,f=/[a-z]+$/i,g=/^\s*([+\-\/*])\s*=\s*([\d.eE+\-]+)\s*([^\d\s]+)?\s*$/;b.on("snap.util.attr",function(a){var c=e(a).match(g);if(c){var h=b.nt(),i=h.substring(h.lastIndexOf(".")+1),j=this.attr(i),k={};b.stop();var l=c[3]||"",m=j.match(f),n=d[c[1]];if(m&&m==l?a=n(parseFloat(j),+c[2]):(j=this.asPX(i),a=n(this.asPX(i),this.asPX(i,c[2]+l))),isNaN(j)||isNaN(a))return;k[i]=a,this.attr(k)}})(-10),b.on("snap.util.equal",function(h,i){var j=e(this.attr(h)||""),k=e(i).match(g);if(k){b.stop();var l=k[3]||"",m=j.match(f),n=d[k[1]];return m&&m==l?{from:parseFloat(j),to:n(parseFloat(j),+k[2]),f:c(m)}:(j=this.asPX(h),{from:j,to:n(j,this.asPX(h,k[2]+l)),f:a})}})(-10)}),d.plugin(function(c,d,e,f){var g=e.prototype,h=c.is;g.rect=function(a,b,c,d,e,f){var g;return null==f&&(f=e),h(a,"object")&&"[object Object]"==a?g=a:null!=a&&(g={x:a,y:b,width:c,height:d},null!=e&&(g.rx=e,g.ry=f)),this.el("rect",g)},g.circle=function(a,b,c){var d;return h(a,"object")&&"[object Object]"==a?d=a:null!=a&&(d={cx:a,cy:b,r:c}),this.el("circle",d)};var i=function(){function a(){this.parentNode.removeChild(this)}return function(b,c){var d=f.doc.createElement("img"),e=f.doc.body;d.style.cssText="position:absolute;left:-9999em;top:-9999em",d.onload=function(){c.call(d),d.onload=d.onerror=null,e.removeChild(d)},d.onerror=a,e.appendChild(d),d.src=b}}();g.image=function(a,b,d,e,f){var g=this.el("image");if(h(a,"object")&&"src"in a)g.attr(a);else if(null!=a){var j={"xlink:href":a,preserveAspectRatio:"none"};null!=b&&null!=d&&(j.x=b,j.y=d),null!=e&&null!=f?(j.width=e,j.height=f):i(a,function(){c._.$(g.node,{width:this.offsetWidth,height:this.offsetHeight})}),c._.$(g.node,j)}return g},g.ellipse=function(a,b,c,d){var e;return h(a,"object")&&"[object Object]"==a?e=a:null!=a&&(e={cx:a,cy:b,rx:c,ry:d}),this.el("ellipse",e)},g.path=function(a){var b;return h(a,"object")&&!h(a,"array")?b=a:a&&(b={d:a}),this.el("path",b)},g.group=g.g=function(a){var b=this.el("g");return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},g.svg=function(a,b,c,d,e,f,g,i){var j={};return h(a,"object")&&null==b?j=a:(null!=a&&(j.x=a),null!=b&&(j.y=b),null!=c&&(j.width=c),null!=d&&(j.height=d),null!=e&&null!=f&&null!=g&&null!=i&&(j.viewBox=[e,f,g,i])),this.el("svg",j)},g.mask=function(a){var b=this.el("mask");return 1==arguments.length&&a&&!a.type?b.attr(a):arguments.length&&b.add(Array.prototype.slice.call(arguments,0)),b},g.ptrn=function(a,b,c,d,e,f,g,i){if(h(a,"object"))var j=a;else j={patternUnits:"userSpaceOnUse"},a&&(j.x=a),b&&(j.y=b),null!=c&&(j.width=c),null!=d&&(j.height=d),j.viewBox=null!=e&&null!=f&&null!=g&&null!=i?[e,f,g,i]:[a||0,b||0,c||0,d||0];return this.el("pattern",j)},g.use=function(a){return null!=a?(a instanceof d&&(a.attr("id")||a.attr({id:c._.id(a)}),a=a.attr("id")),"#"==String(a).charAt()&&(a=a.substring(1)),this.el("use",{"xlink:href":"#"+a})):d.prototype.use.call(this)},g.symbol=function(a,b,c,d){var e={};return null!=a&&null!=b&&null!=c&&null!=d&&(e.viewBox=[a,b,c,d]),this.el("symbol",e)},g.text=function(a,b,c){var d={};return h(a,"object")?d=a:null!=a&&(d={x:a,y:b,text:c||""}),this.el("text",d)},g.line=function(a,b,c,d){var e={};return h(a,"object")?e=a:null!=a&&(e={x1:a,x2:c,y1:b,y2:d}),this.el("line",e)},g.polyline=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},g.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function d(){return this.selectAll("stop")}function e(a,b){var d=k("stop"),e={offset:+b+"%"};return a=c.color(a),e["stop-color"]=a.hex,a.opacity<1&&(e["stop-opacity"]=a.opacity),k(d,e),this.node.appendChild(d),this}function f(){if("linearGradient"==this.type){var a=k(this.node,"x1")||0,b=k(this.node,"x2")||1,d=k(this.node,"y1")||0,e=k(this.node,"y2")||0;return c._.box(a,d,math.abs(b-a),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return c._.box(f-h,g-h,2*h,2*h)}function h(a,c){function d(a,b){for(var c=(b-l)/(a-m),d=m;a>d;d++)g[d].offset=+(+l+c*(d-m)).toFixed(2);m=a,l=b}var e,f=b("snap.util.grad.parse",null,c).firstDefined();if(!f)return null;f.params.unshift(a),e="l"==f.type.toLowerCase()?i.apply(0,f.params):j.apply(0,f.params),f.type!=f.type.toLowerCase()&&k(e.node,{gradientUnits:"userSpaceOnUse"});var g=f.stops,h=g.length,l=0,m=0;h--;for(var n=0;h>n;n++)"offset"in g[n]&&d(n,g[n].offset);for(g[h].offset=g[h].offset||100,d(h,g[h].offset),n=0;h>=n;n++){var o=g[n];e.addStop(o.color,o.offset)}return e}function i(a,b,g,h,i){var j=c._.make("linearGradient",a);return j.stops=d,j.addStop=e,j.getBBox=f,null!=b&&k(j.node,{x1:b,y1:g,x2:h,y2:i}),j}function j(a,b,g,h,i,j){var l=c._.make("radialGradient",a);return l.stops=d,l.addStop=e,l.getBBox=f,null!=b&&k(l.node,{cx:b,cy:g,r:h}),null!=i&&null!=j&&k(l.node,{fx:i,fy:j}),l}var k=c._.$;g.gradient=function(a){return h(this.defs,a)},g.gradientLinear=function(a,b,c,d){return i(this.defs,a,b,c,d)},g.gradientRadial=function(a,b,c,d,e){return j(this.defs,a,b,c,d,e)},g.toString=function(){var a,b=this.node.ownerDocument,d=b.createDocumentFragment(),e=b.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),c._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),a=e.innerHTML,d.removeChild(d.firstChild),a},g.toDataURL=function(){return a&&a.btoa?"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(this))):void 0},g.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):g.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b){function c(a){var b=c.ps=c.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[K](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function d(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:N.min(c,d)/2,r2:N.max(c,d)/2,r0:N.sqrt(c*c+d*d)/2,path:w(a,b,c,d),vb:[a,b,c,d].join(" ")}}function e(){return this.join(",").replace(L,"$1")}function f(a){var b=J(a);return b.toString=e,b}function g(a,b,c,d,e,f,g,h,j){return null==j?n(a,b,c,d,e,f,g,h):i(a,b,c,d,e,f,g,h,o(a,b,c,d,e,f,g,h,j))}function h(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,h){a instanceof b&&(a=a.attr("d")),a=E(a);for(var j,k,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.x<b.x2&&a.x>b.x||b.x<a.x2&&b.x>a.x)&&(a.y<b.y2&&a.y>b.y||b.y<a.y2&&b.y>a.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)<i)){var j,k=1,l=k/2,m=k-l,o=.01;for(j=n(a,b,c,d,e,f,g,h,m);S(j-i)>o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)<P(e,g)||P(a,c)>Q(e,g)||Q(b,d)<P(f,h)||P(b,d)>Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/8),k=~~(g/8),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&t(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.closest=function(b,c,e,f){for(var g=100,h=d(b-g/2,c-g/2,g,g),i=[],j=e[0].hasOwnProperty("x")?function(a){return{x:e[a].x,y:e[a].y}}:function(a){return{x:e[a],y:f[a]}},l=0;1e6>=g&&!l;){for(var m=0,n=e.length;n>m;m++){var o=j(m);if(k(h,o.x,o.y)){l++,i.push(o);break}}l||(g*=2,h=d(b-g/2,c-g/2,g,g))}if(1e6!=g){var p,q=1/0;for(m=0,n=i.length;n>m;m++){var r=a.len(b,c,i[m].x,i[m].y);q>r&&(q=r,i[m].len=r,p=i[m])}return p}},a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.bindings={},this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h=arguments;if(a.is(d,"array")&&a.is(h[h.length-1],"array"))var i=!0;var j,k=function(){j?this.b=j:j=this.b},l=0,m=this,n=g&&function(){++l==m.length&&g.call(this)
|
21 |
+
};return this.forEach(function(a,c){b.once("snap.animcreated."+a.id,k),i?h[c]&&a.animate.apply(a,h[c]):a.animate(d,e,f,n)})},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.bind=function(a,b,c){var d={};if("function"==typeof b)this.bindings[a]=b;else{var e=c||a;this.bindings[a]=function(a){d[e]=a,b.attr(d)}}return this},g.attr=function(a){var b={};for(var c in a)this.bindings[c]?this.bindings[c](a[c]):b[c]=a[c];for(var d=0,e=this.items.length;e>d;d++)this.items[d].attr(b);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;c<arguments.length;c++)i.push(arguments[c]);for(c=0;b>c;c++)h.push(this[a+c]);for(;c<this.length-a;c++)g.push(this[a+c]);var j=i.length;for(c=0;c<j+g.length;c++)this.items[a+c]=this[a+c]=j>c?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.Set=f,a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,c){function d(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function e(b,c,e){c=p(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];for(var f,g,h,i,l=Math.max(b.length,c.length),m=[],n=[],o=0;l>o;o++){if(h=b[o]||d(c[o]),i=c[o]||d(h),h[0]!=i[0]||"r"==h[0].toLowerCase()&&(h[2]!=i[2]||h[3]!=i[3])||"s"==h[0].toLowerCase()&&(h[3]!=i[3]||h[4]!=i[4])){b=a._.transform2matrix(b,e()),c=a._.transform2matrix(c,e()),m=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],n=[["m",c.a,c.b,c.c,c.d,c.e,c.f]];break}for(m[o]=[],n[o]=[],f=0,g=Math.max(h.length,i.length);g>f;f++)f in h&&(m[o][f]=h[f]),f in i&&(n[o][f]=i[f])}return{from:k(m),to:k(n),f:j(m)}}function f(a){return a}function g(a){return function(b){return+b.toFixed(3)+a}}function h(a){return a.join(" ")}function i(b){return a.rgb(b[0],b[1],b[2])}function j(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function k(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}function l(a){return isFinite(parseFloat(a))}function m(b,c){return a.is(b,"array")&&a.is(c,"array")?b.toString()==c.toString():!1}var n={},o=/[a-z]+$/i,p=String;n.stroke=n.fill="colour",c.prototype.equal=function(a,c){return b("snap.util.equal",this,a,c).firstDefined()},b.on("snap.util.equal",function(b,c){var d,q,r=p(this.attr(b)||""),s=this;if(l(r)&&l(c))return{from:parseFloat(r),to:parseFloat(c),f:f};if("colour"==n[b])return d=a.color(r),q=a.color(c),{from:[d.r,d.g,d.b,d.opacity],to:[q.r,q.g,q.b,q.opacity],f:i};if("viewBox"==b)return d=this.attr(b).vb.split(" ").map(Number),q=c.split(" ").map(Number),{from:d,to:q,f:h};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),e(r,c,function(){return s.getBBox(1)});if("d"==b||"path"==b)return d=a.path.toCubic(r,c),{from:k(d[0]),to:k(d[1]),f:j(d[0])};if("points"==b)return d=p(r).split(a._.separator),q=p(c).split(a._.separator),{from:d,to:q,f:function(a){return a}};var t=r.match(o),u=p(c).match(o);return t&&m(t,u)?{from:parseFloat(r),to:parseFloat(c),f:g(t)}:{from:this.asPX(b),to:this.asPX(b,c),f:f}})}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=(function(a,b){var c="y"==a?"scrollTop":"scrollLeft",d=b&&b.node?b.node.ownerDocument:e.doc;return d[c in d.documentElement?"documentElement":"body"][c]}),l=function(){return this.originalEvent.preventDefault()},m=function(){return this.originalEvent.stopPropagation()},n=function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y",d),i=k("x",d);if(h&&j[g](b))for(var n=0,o=e.targetTouches&&e.targetTouches.length;o>n;n++)if(e.targetTouches[n].target==a||a.contains(e.targetTouches[n].target)){var p=e;e=e.targetTouches[n],e.originalEvent=p,e.preventDefault=l,e.stopPropagation=m;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}},o=[],p=function(a){for(var c,d=a.clientX,e=a.clientY,f=k("y"),g=k("x"),i=o.length;i--;){if(c=o[i],h){for(var j,l=a.touches&&a.touches.length;l--;)if(j=a.touches[l],j.identifier==c.el._drag.id||c.el.node.contains(j.target)){d=j.clientX,e=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();{var m=c.el.node;m.nextSibling,m.parentNode,m.style.display}d+=g,e+=f,b("snap.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},q=function(c){a.unmousemove(p).unmouseup(q);for(var d,e=o.length;e--;)d=o[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c),b.off("snap.drag.*."+d.el.id);o=[]},r=i.length;r--;)!function(b){a[b]=f[b]=function(c,d){if(a.is(c,"function"))this.events=this.events||[],this.events.push({name:b,f:c,unbind:n(this.node||document,b,c,d||this)});else for(var e=0,f=this.events.length;f>e;e++)if(this.events[e].name==b)try{this.events[e].f.call(this)}catch(g){}return this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[r]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var s=[];f.drag=function(c,d,e,f,g,h){function i(i,j,l){(i.originalEvent||i).preventDefault(),k._drag.x=j,k._drag.y=l,k._drag.id=i.identifier,!o.length&&a.mousemove(p).mouseup(q),o.push({el:k,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+k.id,d),c&&b.on("snap.drag.move."+k.id,c),e&&b.on("snap.drag.end."+k.id,e),b("snap.drag.start."+k.id,g||f||k,j,l,i)}function j(a,c,d){b("snap.draginit."+k.id,k,a,c,d)}var k=this;if(!arguments.length){var l;return k.drag(function(a,b){this.attr({transform:l+(l?"T":"t")+[a,b]})},function(){l=this.transform().local})}return b.on("snap.draginit."+k.id,i),k._drag={},s.push({el:k,start:i,init:j}),k.mousedown(j),k},f.undrag=function(){for(var c=s.length;c--;)s[c].el==this&&(this.unmousedown(s[c].init),s.splice(c,1),b.unbind("snap.drag.*."+this.id),b.unbind("snap.draginit."+this.id));return!s.length&&a.unmousemove(p).unmouseup(q),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('<feGaussianBlur stdDeviation="{def}"/>',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('<feGaussianBlur in="SourceAlpha" stdDeviation="{blur}"/><feOffset dx="{dx}" dy="{dy}" result="offsetblur"/><feFlood flood-color="{color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="{opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {b} {h} 0 0 0 0 0 1 0"/>',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {h} {i} 0 0 0 0 0 1 0"/>',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('<feColorMatrix type="saturate" values="{amount}"/>',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('<feColorMatrix type="hueRotate" values="{angle}"/>',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="table" tableValues="{amount} {amount2}"/><feFuncG type="table" tableValues="{amount} {amount2}"/><feFuncB type="table" tableValues="{amount} {amount2}"/></feComponentTransfer>',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}"/><feFuncG type="linear" slope="{amount}"/><feFuncB type="linear" slope="{amount}"/></feComponentTransfer>',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}" intercept="{amount2}"/><feFuncG type="linear" slope="{amount}" intercept="{amount2}"/><feFuncB type="linear" slope="{amount}" intercept="{amount2}"/></feComponentTransfer>',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d.plugin(function(a,b){var c=a._.box,d=a.is,e=/^[^a-z]*([tbmlrc])/i,f=function(){return"T"+this.dx+","+this.dy};b.prototype.getAlign=function(a,b){null==b&&d(a,"string")&&(b=a,a=null),a=a||this.paper;var g=a.getBBox?a.getBBox():c(a),h=this.getBBox(),i={};switch(b=b&&b.match(e),b=b?b[1].toLowerCase():"c"){case"t":i.dx=0,i.dy=g.y-h.y;break;case"b":i.dx=0,i.dy=g.y2-h.y2;break;case"m":i.dx=0,i.dy=g.cy-h.cy;break;case"l":i.dx=g.x-h.x,i.dy=0;break;case"r":i.dx=g.x2-h.x2,i.dy=0;break;default:i.dx=g.cx-h.cx,i.dy=0}return i.toString=f,i},b.prototype.align=function(a,b){return this.transform("..."+this.getAlign(a,b))}}),d});
|
22 |
+
|
23 |
+
|
24 |
+
/*
|
25 |
+
convert a cubic bezier value to a custom mina easing
|
26 |
+
http://stackoverflow.com/questions/25265197/how-to-convert-a-cubic-bezier-value-to-a-custom-mina-easing-snap-svg
|
27 |
+
*/
|
28 |
+
var duration = 300,
|
29 |
+
delay = 300,
|
30 |
+
epsilon = (1000 / 60 / duration) / 4,
|
31 |
+
firstCustomMinaAnimation = bezier(.42, .03, .77, .63, epsilon),
|
32 |
+
secondCustomMinaAnimation = bezier(.27, .5, .6, .99, epsilon);
|
33 |
+
|
34 |
+
jQuery(document).ready(function () {
|
35 |
+
//initialize the slider
|
36 |
+
jQuery('.cd-slider-wrapper').each(function () {
|
37 |
+
initSlider(jQuery(this));
|
38 |
+
});
|
39 |
+
});
|
40 |
+
|
41 |
+
function initSlider(sliderWrapper) {
|
42 |
+
//cache jQuery objects
|
43 |
+
slider = sliderWrapper.find('.cd-slider'),
|
44 |
+
sliderNavigation = sliderWrapper.find('.cd-slider-navigation').find('li'),
|
45 |
+
svgCoverLayer = sliderWrapper.find('div.cd-svg-cover'),
|
46 |
+
pathId = svgCoverLayer.find('path').attr('id'),
|
47 |
+
svgPath = Snap('#' + pathId);
|
48 |
+
|
49 |
+
//store path 'd' attribute values
|
50 |
+
pathArray = [];
|
51 |
+
pathArray[0] = svgCoverLayer.data('step1');
|
52 |
+
pathArray[1] = svgCoverLayer.data('step6');
|
53 |
+
pathArray[2] = svgCoverLayer.data('step2');
|
54 |
+
pathArray[3] = svgCoverLayer.data('step7');
|
55 |
+
pathArray[4] = svgCoverLayer.data('step3');
|
56 |
+
pathArray[5] = svgCoverLayer.data('step8');
|
57 |
+
pathArray[6] = svgCoverLayer.data('step4');
|
58 |
+
pathArray[7] = svgCoverLayer.data('step9');
|
59 |
+
pathArray[8] = svgCoverLayer.data('step5');
|
60 |
+
pathArray[9] = svgCoverLayer.data('step10');
|
61 |
+
|
62 |
+
//update visible slide when user clicks .cd-slider-navigation buttons
|
63 |
+
sliderNavigation.on('click', function (event) {
|
64 |
+
event.preventDefault();
|
65 |
+
var selectedItem = jQuery(this);
|
66 |
+
if (!selectedItem.hasClass('selected')) {
|
67 |
+
// if it's not already selected
|
68 |
+
var selectedSlidePosition = selectedItem.index(),
|
69 |
+
selectedSlide = slider.children('li').eq(selectedSlidePosition),
|
70 |
+
visibleSlide = slider.find('.visible'),
|
71 |
+
visibleSlidePosition = visibleSlide.index(),
|
72 |
+
direction = '';
|
73 |
+
direction = (visibleSlidePosition < selectedSlidePosition) ? 'next' : 'prev';
|
74 |
+
updateSlide(visibleSlide, selectedSlide, direction, svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
75 |
+
}
|
76 |
+
});
|
77 |
+
}
|
78 |
+
|
79 |
+
function nextSlide() {
|
80 |
+
var visibleSlide = slider.find('.visible');
|
81 |
+
jQuery.post("?page=newsletter_main_welcome&noheader=1&action=save", jQuery("#tnp-welcome").serialize());
|
82 |
+
var visibleSlidePosition = visibleSlide.index();
|
83 |
+
var selectedSlide = slider.children('li').eq(visibleSlidePosition + 1);
|
84 |
+
if (selectedSlide.hasClass("tnp-last-slide")) {
|
85 |
+
jQuery(".cd-slider-navigation").hide();
|
86 |
+
}
|
87 |
+
|
88 |
+
updateSlide(visibleSlide, selectedSlide, "next", svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
89 |
+
|
90 |
+
}
|
91 |
+
|
92 |
+
function prevSlide() {
|
93 |
+
var visibleSlide = slider.find('.visible');
|
94 |
+
var visibleSlidePosition = visibleSlide.index();
|
95 |
+
var selectedSlide = slider.children('li').eq(visibleSlidePosition - 1);
|
96 |
+
|
97 |
+
updateSlide(visibleSlide, selectedSlide, "prev", svgCoverLayer, sliderNavigation, pathArray, svgPath);
|
98 |
+
if (selectedSlide.hasClass("tnp-first-slide")) {
|
99 |
+
jQuery(".cd-slider-navigation a.tnp-welcome-prev").hide();
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
function updateSlide(oldSlide, newSlide, direction, svgCoverLayer, sliderNavigation, paths, svgPath) {
|
104 |
+
if (direction == 'next') {
|
105 |
+
var path1 = paths[0],
|
106 |
+
path2 = paths[2],
|
107 |
+
path3 = paths[4];
|
108 |
+
path4 = paths[6];
|
109 |
+
path5 = paths[8];
|
110 |
+
} else {
|
111 |
+
var path1 = paths[1],
|
112 |
+
path2 = paths[3],
|
113 |
+
path3 = paths[5];
|
114 |
+
path4 = paths[7];
|
115 |
+
path5 = paths[9];
|
116 |
+
}
|
117 |
+
|
118 |
+
svgCoverLayer.addClass('is-animating');
|
119 |
+
svgPath.attr('d', path1);
|
120 |
+
svgPath.animate({'d': path2}, duration, firstCustomMinaAnimation, function () {
|
121 |
+
svgPath.animate({'d': path3}, duration, secondCustomMinaAnimation, function () {
|
122 |
+
oldSlide.removeClass('visible');
|
123 |
+
newSlide.addClass('visible');
|
124 |
+
updateNavSlide(newSlide, sliderNavigation);
|
125 |
+
setTimeout(function () {
|
126 |
+
svgPath.animate({'d': path4}, duration, firstCustomMinaAnimation, function () {
|
127 |
+
svgPath.animate({'d': path5}, duration, secondCustomMinaAnimation, function () {
|
128 |
+
svgCoverLayer.removeClass('is-animating');
|
129 |
+
if (direction == "next") {
|
130 |
+
jQuery(".cd-slider-navigation a.tnp-welcome-prev").show();
|
131 |
+
}
|
132 |
+
});
|
133 |
+
});
|
134 |
+
}, delay);
|
135 |
+
});
|
136 |
+
});
|
137 |
+
}
|
138 |
+
|
139 |
+
function updateNavSlide(actualSlide, sliderNavigation) {
|
140 |
+
var position = actualSlide.index();
|
141 |
+
sliderNavigation.removeClass('selected').eq(position).addClass('selected');
|
142 |
+
}
|
143 |
+
|
144 |
+
function bezier(x1, y1, x2, y2, epsilon) {
|
145 |
+
//https://github.com/arian/cubic-bezier
|
146 |
+
var curveX = function (t) {
|
147 |
+
var v = 1 - t;
|
148 |
+
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
149 |
+
};
|
150 |
+
|
151 |
+
var curveY = function (t) {
|
152 |
+
var v = 1 - t;
|
153 |
+
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
154 |
+
};
|
155 |
+
|
156 |
+
var derivativeCurveX = function (t) {
|
157 |
+
var v = 1 - t;
|
158 |
+
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
159 |
+
};
|
160 |
+
|
161 |
+
return function (t) {
|
162 |
+
|
163 |
+
var x = t, t0, t1, t2, x2, d2, i;
|
164 |
+
|
165 |
+
// First try a few iterations of Newton's method -- normally very fast.
|
166 |
+
for (t2 = x, i = 0; i < 8; i++) {
|
167 |
+
x2 = curveX(t2) - x;
|
168 |
+
if (Math.abs(x2) < epsilon)
|
169 |
+
return curveY(t2);
|
170 |
+
d2 = derivativeCurveX(t2);
|
171 |
+
if (Math.abs(d2) < 1e-6)
|
172 |
+
break;
|
173 |
+
t2 = t2 - x2 / d2;
|
174 |
+
}
|
175 |
+
|
176 |
+
t0 = 0, t1 = 1, t2 = x;
|
177 |
+
|
178 |
+
if (t2 < t0)
|
179 |
+
return curveY(t0);
|
180 |
+
if (t2 > t1)
|
181 |
+
return curveY(t1);
|
182 |
+
|
183 |
+
// Fallback to the bisection method for reliability.
|
184 |
+
while (t0 < t1) {
|
185 |
+
x2 = curveX(t2);
|
186 |
+
if (Math.abs(x2 - x) < epsilon)
|
187 |
+
return curveY(t2);
|
188 |
+
if (x > x2)
|
189 |
+
t0 = t2;
|
190 |
+
else
|
191 |
+
t1 = t2;
|
192 |
+
t2 = (t1 - t0) * .5 + t0;
|
193 |
+
}
|
194 |
+
|
195 |
+
// Failure
|
196 |
+
return curveY(t2);
|
197 |
+
|
198 |
+
};
|
199 |
+
}
|
200 |
+
|
main/logs.php
CHANGED
@@ -1,57 +1,58 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $this Newsletter */
|
3 |
-
/* @var $wpdb wpdb */
|
4 |
-
|
5 |
-
defined('ABSPATH') || exit;
|
6 |
-
|
7 |
-
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
8 |
-
$controls = new NewsletterControls();
|
9 |
-
|
10 |
-
if ($controls->is_action('delete_logs')) {
|
11 |
-
$files = glob(WP_CONTENT_DIR . '/logs/newsletter/*.txt');
|
12 |
-
foreach ($files as $file) {
|
13 |
-
if (is_file($file))
|
14 |
-
unlink($file);
|
15 |
-
}
|
16 |
-
$secret = NewsletterModule::get_token(8);
|
17 |
-
update_option('newsletter_logger_secret', $secret);
|
18 |
-
$controls->messages = 'Logs deleted';
|
19 |
-
}
|
20 |
-
|
21 |
-
?>
|
22 |
-
|
23 |
-
|
24 |
-
<div class="wrap tnp-main-status" id="tnp-wrap">
|
25 |
-
|
26 |
-
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
27 |
-
|
28 |
-
<div id="tnp-heading">
|
29 |
-
|
30 |
-
<h2><?php _e('Logs', 'newsletter') ?></h2>
|
31 |
-
|
32 |
-
</div>
|
33 |
-
|
34 |
-
<div id="tnp-body">
|
35 |
-
|
36 |
-
<form method="post" action="">
|
37 |
-
<?php $controls->init(); ?>
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
echo '
|
45 |
-
echo '</
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
1 |
+
<?php
|
2 |
+
/* @var $this Newsletter */
|
3 |
+
/* @var $wpdb wpdb */
|
4 |
+
|
5 |
+
defined('ABSPATH') || exit;
|
6 |
+
|
7 |
+
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
8 |
+
$controls = new NewsletterControls();
|
9 |
+
|
10 |
+
if ($controls->is_action('delete_logs')) {
|
11 |
+
$files = glob(WP_CONTENT_DIR . '/logs/newsletter/*.txt');
|
12 |
+
foreach ($files as $file) {
|
13 |
+
if (is_file($file))
|
14 |
+
unlink($file);
|
15 |
+
}
|
16 |
+
$secret = NewsletterModule::get_token(8);
|
17 |
+
update_option('newsletter_logger_secret', $secret);
|
18 |
+
$controls->messages = 'Logs deleted';
|
19 |
+
}
|
20 |
+
|
21 |
+
?>
|
22 |
+
|
23 |
+
|
24 |
+
<div class="wrap tnp-main-status" id="tnp-wrap">
|
25 |
+
|
26 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
27 |
+
|
28 |
+
<div id="tnp-heading">
|
29 |
+
|
30 |
+
<h2><?php _e('Logs', 'newsletter') ?></h2>
|
31 |
+
|
32 |
+
</div>
|
33 |
+
|
34 |
+
<div id="tnp-body">
|
35 |
+
|
36 |
+
<form method="post" action="">
|
37 |
+
<?php $controls->init(); ?>
|
38 |
+
|
39 |
+
|
40 |
+
<ul class="tnp-log-files">
|
41 |
+
<?php
|
42 |
+
$files = glob(WP_CONTENT_DIR . '/logs/newsletter/*.txt'); // get all file names
|
43 |
+
foreach ($files as $file) { // iterate files
|
44 |
+
echo '<li><a href="' . WP_CONTENT_URL . '/logs/newsletter/' . basename($file) . '" target="_blank">' . basename($file) . '</a>';
|
45 |
+
echo ' <span class="tnp-log-size">(' . size_format(filesize($file)) . ')</span>';
|
46 |
+
echo '</li>';
|
47 |
+
}
|
48 |
+
?>
|
49 |
+
</ul>
|
50 |
+
|
51 |
+
<?php $controls->button('delete_logs', 'Delete all'); ?>
|
52 |
+
|
53 |
+
</form>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
57 |
+
|
58 |
+
</div>
|
main/scheduler.php
ADDED
@@ -0,0 +1,411 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $this Newsletter */
|
3 |
+
/* @var $wpdb wpdb */
|
4 |
+
|
5 |
+
defined('ABSPATH') || exit;
|
6 |
+
|
7 |
+
wp_enqueue_script('tnp-chart');
|
8 |
+
|
9 |
+
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
10 |
+
$controls = new NewsletterControls();
|
11 |
+
$system = NewsletterSystem::instance();
|
12 |
+
|
13 |
+
if ($controls->is_action('reset')) {
|
14 |
+
$system->reset_cron_stats();
|
15 |
+
$controls->add_message_done();
|
16 |
+
}
|
17 |
+
|
18 |
+
if ($controls->is_action('reschedule')) {
|
19 |
+
wp_clear_scheduled_hook('newsletter');
|
20 |
+
wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
|
21 |
+
$controls->add_message_done();
|
22 |
+
}
|
23 |
+
|
24 |
+
if ($controls->is_action('trigger')) {
|
25 |
+
wp_clear_scheduled_hook('newsletter');
|
26 |
+
wp_schedule_event(time() + NEWSLETTER_CRON_INTERVAL, 'newsletter', 'newsletter');
|
27 |
+
Newsletter::instance()->hook_newsletter();
|
28 |
+
$controls->add_message_done();
|
29 |
+
}
|
30 |
+
|
31 |
+
if ($controls->is_action('test')) {
|
32 |
+
$response = wp_remote_get(site_url('/wp-cron.php') . '?' . time());
|
33 |
+
if (is_wp_error($response)) {
|
34 |
+
$controls->errors = 'Test failed: ' . esc_html($response->get_error_message());
|
35 |
+
} else if (wp_remote_retrieve_response_code($response) != 200) {
|
36 |
+
$controls->errors = 'Test failed: ' . esc_html(wp_remote_retrieve_response_message($response));
|
37 |
+
} else {
|
38 |
+
$controls->add_message('Test ok');
|
39 |
+
}
|
40 |
+
|
41 |
+
if ($controls->errors) {
|
42 |
+
$controls->errors .= '<br>Report this error to your provider saying the site cannot make an HTTP call to its wp-cron.php file and copying the error message above.';
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
function tnp_status_print_flag($condition, $url = '') {
|
47 |
+
switch ($condition) {
|
48 |
+
case 0: echo ' <span class="tnp-ko">KO</span>';
|
49 |
+
break;
|
50 |
+
case 1: echo '<span class="tnp-ok">OK</span>';
|
51 |
+
break;
|
52 |
+
case 2: echo '<span class="tnp-maybe">MAYBE</span>';
|
53 |
+
break;
|
54 |
+
}
|
55 |
+
if ($url) {
|
56 |
+
echo '<a href="', $url, '" target="_blank">Read more</a>';
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
$system = NewsletterSystem::instance();
|
61 |
+
?>
|
62 |
+
|
63 |
+
<style>
|
64 |
+
#tnp-body table.widefat td {
|
65 |
+
vertical-align: top;
|
66 |
+
}
|
67 |
+
#tnp-body table.widefat td.status {
|
68 |
+
text-align: center;
|
69 |
+
}
|
70 |
+
</style>
|
71 |
+
<div class="wrap tnp-main-status" id="tnp-wrap">
|
72 |
+
|
73 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
74 |
+
|
75 |
+
<div id="tnp-heading">
|
76 |
+
|
77 |
+
<h2><?php _e('WordPress Scheduler and Newsletter Delivery Engine', 'newsletter') ?></h2>
|
78 |
+
<p>
|
79 |
+
The scheduler is a WordPress component that executes <strong>background tasks</strong>
|
80 |
+
(publish future post, run backups, send newsletters, ...).
|
81 |
+
<br>
|
82 |
+
Here some steps you can consider if the scheduler has issues.
|
83 |
+
</p>
|
84 |
+
<ul>
|
85 |
+
<li>Check the <a href="<?php echo admin_url('/site-health.php') ?>">site health panel</a> and try to solve the issues identified by WordPress in your site</li>
|
86 |
+
<li>Install the <a href="https://wordpress.org/plugins/wp-crontrol/" target="_blank">WP Crontol</a> plugin which shows all the scheduled jobs and delays</li>
|
87 |
+
<li>Configure an <a href="https://www.thenewsletterplugin.com/documentation/delivery-and-spam/newsletter-delivery-engine/" target="_blank">external cron service</a>
|
88 |
+
(if you have a license you can use our <a href="https://www.thenewsletterplugin.com/account/cron/" target="_blank">cron service</a>)</li>
|
89 |
+
</ul>
|
90 |
+
</div>
|
91 |
+
|
92 |
+
<div id="tnp-body">
|
93 |
+
|
94 |
+
|
95 |
+
<form method="post" action="">
|
96 |
+
<?php $controls->init(); ?>
|
97 |
+
|
98 |
+
<table class="widefat">
|
99 |
+
<?php
|
100 |
+
$status = $system->get_job_status();
|
101 |
+
$condition = $status == NewsletterSystem::JOB_OK ? 1 : 0;
|
102 |
+
?>
|
103 |
+
<tr>
|
104 |
+
<td>Delivery background job</td>
|
105 |
+
<td class="status">
|
106 |
+
<?php tnp_status_print_flag($condition, 'https://www.thenewsletterplugin.com/documentation/delivery-and-spam/newsletter-delivery-engine/') ?>
|
107 |
+
</td>
|
108 |
+
<td>
|
109 |
+
<?php
|
110 |
+
switch ($status) {
|
111 |
+
case NewsletterSystem::JOB_MISSING:
|
112 |
+
echo 'The engine schdule is missing. Try to deactivate and reactivate the Newsletter plugin.';
|
113 |
+
break;
|
114 |
+
case NewsletterSystem::JOB_LATE:
|
115 |
+
echo 'The engine schdule is late. You probably need and external scheduler trigger.';
|
116 |
+
break;
|
117 |
+
case NewsletterSystem::JOB_SKIPPED:
|
118 |
+
echo 'The engine schdule has been skipped. The schduler is overloaded or a job has fatal error and blocks the scheduler.';
|
119 |
+
break;
|
120 |
+
case NewsletterSystem::JOB_OK:
|
121 |
+
echo 'Everything seems fine!';
|
122 |
+
break;
|
123 |
+
}
|
124 |
+
?>
|
125 |
+
<br><br>
|
126 |
+
Next run: <?php echo $controls->print_date($system->get_job_schedule(), false, true) ?>
|
127 |
+
<br><br>
|
128 |
+
<?php
|
129 |
+
if ($status == NewsletterSystem::JOB_LATE) {
|
130 |
+
$controls->button('trigger', 'Run manually');
|
131 |
+
}
|
132 |
+
?>
|
133 |
+
</td>
|
134 |
+
</tr>
|
135 |
+
|
136 |
+
|
137 |
+
<tr>
|
138 |
+
<td>Last cron call</td>
|
139 |
+
<td class="status"> </td>
|
140 |
+
<td>
|
141 |
+
<?php echo $controls->print_date($system->get_last_cron_call()) ?>
|
142 |
+
</td>
|
143 |
+
</tr>
|
144 |
+
|
145 |
+
|
146 |
+
<tr>
|
147 |
+
<?php
|
148 |
+
$stats = NewsletterSystem::instance()->get_cron_stats();
|
149 |
+
?>
|
150 |
+
<td>
|
151 |
+
Cron call stats
|
152 |
+
</td>
|
153 |
+
<?php if ($stats == null) { ?>
|
154 |
+
<td class="status">
|
155 |
+
|
156 |
+
</td>
|
157 |
+
<td>
|
158 |
+
Not enough data, some hours are still required.
|
159 |
+
</td>
|
160 |
+
|
161 |
+
<?php } else { ?>
|
162 |
+
|
163 |
+
<?php
|
164 |
+
$condition = $stats->good ? 1 : 0;
|
165 |
+
?>
|
166 |
+
|
167 |
+
<td class="status">
|
168 |
+
<?php tnp_status_print_flag($condition, 'https://www.thenewsletterplugin.com/documentation/delivery-and-spam/newsletter-delivery-engine/') ?>
|
169 |
+
</td>
|
170 |
+
<td>
|
171 |
+
<?php if ($condition == 0) { ?>
|
172 |
+
The blog cron system is NOT triggered enough often.<br>
|
173 |
+
<?php } ?>
|
174 |
+
|
175 |
+
Samples <?php echo count($stats->deltas) ?>, average <?php echo $stats->avg ?> s, max <?php echo $stats->max ?> s, min <?php echo $stats->min ?> s
|
176 |
+
|
177 |
+
<canvas id="tnp-cron-chart" style="width: 550px; height: 180px"></canvas>
|
178 |
+
<script>
|
179 |
+
jQuery(function () {
|
180 |
+
var cronChartData = {
|
181 |
+
labels: <?php echo json_encode(range(1, count($stats->deltas))) ?>,
|
182 |
+
datasets: [
|
183 |
+
{
|
184 |
+
label: "Batch Average Time",
|
185 |
+
data: <?php echo json_encode($stats->deltas) ?>,
|
186 |
+
borderColor: '#2980b9',
|
187 |
+
fill: false
|
188 |
+
}]
|
189 |
+
};
|
190 |
+
var cronChartConfig = {
|
191 |
+
type: "line",
|
192 |
+
data: cronChartData,
|
193 |
+
options: {
|
194 |
+
responsive: false,
|
195 |
+
maintainAspectRatio: false,
|
196 |
+
scales: {
|
197 |
+
x: {
|
198 |
+
type: 'linear'
|
199 |
+
}
|
200 |
+
}
|
201 |
+
}
|
202 |
+
};
|
203 |
+
new Chart('tnp-cron-chart', cronChartConfig);
|
204 |
+
});
|
205 |
+
</script>
|
206 |
+
|
207 |
+
<?php $controls->button_reset() ?>
|
208 |
+
|
209 |
+
</td>
|
210 |
+
<?php } ?>
|
211 |
+
</tr>
|
212 |
+
|
213 |
+
<?php
|
214 |
+
$condition = $system->has_newsletter_schedule() ? 1 : 0;
|
215 |
+
$schedules = wp_get_schedules();
|
216 |
+
?>
|
217 |
+
<tr>
|
218 |
+
<td>
|
219 |
+
Newsletter engine schedule
|
220 |
+
</td>
|
221 |
+
<td class="status"><?php tnp_status_print_flag($condition) ?></td>
|
222 |
+
<td>
|
223 |
+
<?php if (!$condition) { ?>
|
224 |
+
The Newsletter schedule is not present probably another plugin is interfering with the starndard WordPress scheuling system.<br>
|
225 |
+
You can reactivate it, but is the problem persist
|
226 |
+
<?php $controls->button('reschedule', 'Reactivate') ?>
|
227 |
+
<?php } ?>
|
228 |
+
|
229 |
+
Registered recurring schedules:<br>
|
230 |
+
<ul style="margin-left: 0em;">
|
231 |
+
<?php
|
232 |
+
if (!empty($schedules)) {
|
233 |
+
foreach ($schedules as $key => $data) {
|
234 |
+
if ($key == 'newsletter') {
|
235 |
+
echo '<li style="padding: 0; margin: 0; font-weight: bold">', esc_html($key . ' - ' . $data['interval']), ' seconds</li>';
|
236 |
+
} else {
|
237 |
+
echo '<li style="padding: 0; margin: 0;">', esc_html($key . ' - ' . $data['interval']), ' seconds</li>';
|
238 |
+
}
|
239 |
+
}
|
240 |
+
}
|
241 |
+
?>
|
242 |
+
</ul>
|
243 |
+
</td>
|
244 |
+
</tr>
|
245 |
+
|
246 |
+
|
247 |
+
<tr>
|
248 |
+
<td>Cron URL</td>
|
249 |
+
<td class="status"> </td>
|
250 |
+
<td>
|
251 |
+
<strong><?php echo esc_html(site_url('/wp-cron.php')) ?></strong>
|
252 |
+
<br><br>
|
253 |
+
Can be used to trigger the WordPress scheduler from an external cron service.
|
254 |
+
</td>
|
255 |
+
</tr>
|
256 |
+
|
257 |
+
|
258 |
+
|
259 |
+
|
260 |
+
<tr>
|
261 |
+
<td>
|
262 |
+
WordPress scheduler auto trigger
|
263 |
+
</td>
|
264 |
+
<td class="status">
|
265 |
+
<?php //tnp_status_print_flag($condition) ?>
|
266 |
+
</td>
|
267 |
+
<td>
|
268 |
+
<?php $controls->button_test() ?>
|
269 |
+
</td>
|
270 |
+
</tr>
|
271 |
+
|
272 |
+
<?php
|
273 |
+
$condition = (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) ? 2 : 1;
|
274 |
+
?>
|
275 |
+
<tr>
|
276 |
+
<td>
|
277 |
+
<code>DISABLE_WP_CRON</code>
|
278 |
+
</td>
|
279 |
+
<td class="status">
|
280 |
+
<?php tnp_status_print_flag($condition) ?>
|
281 |
+
</td>
|
282 |
+
<td>
|
283 |
+
<?php if ($condition == 2) { ?>
|
284 |
+
The constant <code>DISABLE_WP_CRON</code> is set to <code>true</code> (probably in <code>wp-config.php</code>). That disables the scheduler auto triggering and it's
|
285 |
+
good ONLY if you setup an external trigger.
|
286 |
+
<?php } ?>
|
287 |
+
</td>
|
288 |
+
</tr>
|
289 |
+
|
290 |
+
<tr>
|
291 |
+
<td>
|
292 |
+
<code>ALTERNATE_WP_CRON</code>
|
293 |
+
</td>
|
294 |
+
<td class="status">
|
295 |
+
|
296 |
+
</td>
|
297 |
+
<td>
|
298 |
+
<?php if (defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON) { ?>
|
299 |
+
Using the alternate cron trigger. Rare configuration but should not be a problem.
|
300 |
+
<?php } else { ?>
|
301 |
+
Option not active, it's ok.
|
302 |
+
<?php } ?>
|
303 |
+
</td>
|
304 |
+
</tr>
|
305 |
+
|
306 |
+
<?php
|
307 |
+
$condition = NEWSLETTER_CRON_INTERVAL == 300 ? 1 : 2;
|
308 |
+
?>
|
309 |
+
<tr>
|
310 |
+
<td><code>NEWSLETTER_CRON_INTERVAL</code></td>
|
311 |
+
<td class="status">
|
312 |
+
<?php tnp_status_print_flag($condition) ?>
|
313 |
+
</td>
|
314 |
+
<td>
|
315 |
+
<?php echo NEWSLETTER_CRON_INTERVAL, ' seconds'; ?>
|
316 |
+
<br><br>
|
317 |
+
How often the Newsletter engine should be activated. Default 300 seconds. Different value can be set on your <code>wp-config.php</code>
|
318 |
+
(not recommended).
|
319 |
+
</td>
|
320 |
+
</tr>
|
321 |
+
|
322 |
+
|
323 |
+
<?php
|
324 |
+
$condition = WP_CRON_LOCK_TIMEOUT != MINUTE_IN_SECONDS ? 2 : 1;
|
325 |
+
?>
|
326 |
+
<tr>
|
327 |
+
<td><code>WP_CRON_LOCK_TIMEOUT</code></td>
|
328 |
+
<td class="status">
|
329 |
+
<?php tnp_status_print_flag($condition) ?>
|
330 |
+
</td>
|
331 |
+
<td>
|
332 |
+
<?php echo WP_CRON_LOCK_TIMEOUT, ' seconds'; ?>
|
333 |
+
|
334 |
+
<?php if ($condition == 2) { ?>
|
335 |
+
<br>
|
336 |
+
A non standard (<?php echo MINUTE_IN_SECONDS ?> seconds) value is specified probably in your <code>wp-config.php</code>.
|
337 |
+
<?php } ?>
|
338 |
+
</td>
|
339 |
+
</tr>
|
340 |
+
|
341 |
+
|
342 |
+
<?php
|
343 |
+
$condition = (defined('NEWSLETTER_CRON_WARNINGS') && !NEWSLETTER_CRON_WARNINGS) ? 2 : 1;
|
344 |
+
?>
|
345 |
+
<tr>
|
346 |
+
|
347 |
+
<td>
|
348 |
+
<code>NEWSLETTER_CRON_WARNINGS</code>
|
349 |
+
</td>
|
350 |
+
<td class="status">
|
351 |
+
<?php tnp_status_print_flag($condition) ?>
|
352 |
+
</td>
|
353 |
+
<td>
|
354 |
+
<?php if ($condition == 2) { ?>
|
355 |
+
Scheduler warnings are disabled in your <code>wp-config.php</code> with the constant <code>NEWSLETTER_CRON_WARNINGS</code> set to true.
|
356 |
+
<?php } else { ?>
|
357 |
+
Scheduler warnings are enabled
|
358 |
+
<?php } ?>
|
359 |
+
</td>
|
360 |
+
</tr>
|
361 |
+
|
362 |
+
<?php
|
363 |
+
$condition = has_filter('pre_reschedule_event') ? 2 : 1;
|
364 |
+
?>
|
365 |
+
<tr>
|
366 |
+
<td><code>pre_reschedule_event</code></td>
|
367 |
+
<td class="status">
|
368 |
+
<?php tnp_status_print_flag($condition) ?>
|
369 |
+
</td>
|
370 |
+
<td>
|
371 |
+
<?php if ($condition == 2) { ?>
|
372 |
+
One or more plugin are filtering the jobs rescheduling. If a recurrent job (like the newsletter generation with Automated) disappers
|
373 |
+
this is a good starting point.<br><br>
|
374 |
+
<?php } ?>
|
375 |
+
Attached functions:<br>
|
376 |
+
<?php echo $system->get_hook_functions('pre_reschedule_event') ?>
|
377 |
+
</td>
|
378 |
+
</tr>
|
379 |
+
|
380 |
+
<?php
|
381 |
+
$transient = get_transient('doing_cron');
|
382 |
+
?>
|
383 |
+
<tr>
|
384 |
+
<td>Transient <code>doing_cron</code></td>
|
385 |
+
<td class="status">
|
386 |
+
<?php //tnp_status_print_flag($condition) ?>
|
387 |
+
</td>
|
388 |
+
<td>
|
389 |
+
<?php if ($transient) { ?>
|
390 |
+
<?php
|
391 |
+
echo esc_html($transient);
|
392 |
+
if (is_numeric($transient)) {
|
393 |
+
echo ' (', $controls->print_date((int) $transient), ')';
|
394 |
+
}
|
395 |
+
?>
|
396 |
+
<?php } else { ?>
|
397 |
+
[unset]
|
398 |
+
<?php } ?>
|
399 |
+
<br><br>
|
400 |
+
When set it means the scheduler is executing background jobs. Install the WP Crontol plugin to have more information about
|
401 |
+
your site background jobs.
|
402 |
+
</td>
|
403 |
+
</tr>
|
404 |
+
</table>
|
405 |
+
|
406 |
+
</form>
|
407 |
+
</div>
|
408 |
+
|
409 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
410 |
+
|
411 |
+
</div>
|
main/status.php
CHANGED
@@ -1,1458 +1,1189 @@
|
|
1 |
-
<?php
|
2 |
-
/* @var $this Newsletter */
|
3 |
-
/* @var $wpdb wpdb */
|
4 |
-
|
5 |
-
defined('ABSPATH') || exit;
|
6 |
-
|
7 |
-
wp_enqueue_script('tnp-chart');
|
8 |
-
|
9 |
-
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
10 |
-
$controls = new NewsletterControls();
|
11 |
-
|
12 |
-
$
|
13 |
-
|
14 |
-
$
|
15 |
-
$
|
16 |
-
$
|
17 |
-
if (
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
if (
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
if ($controls->
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
$
|
69 |
-
|
70 |
-
$
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
if ($
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
$
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
$
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
<
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
<
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
$condition
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
<?php
|
373 |
-
</td>
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
<td>
|
452 |
-
|
453 |
-
</td>
|
454 |
-
<td>
|
455 |
-
<?php
|
456 |
-
|
457 |
-
|
458 |
-
<?php
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
$
|
469 |
-
if (
|
470 |
-
$
|
471 |
-
|
472 |
-
if (
|
473 |
-
$
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
?>
|
479 |
-
<tr>
|
480 |
-
<td>
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
<?php } ?>
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
<td>
|
671 |
-
|
672 |
-
</td>
|
673 |
-
<td>
|
674 |
-
<?php
|
675 |
-
|
676 |
-
|
677 |
-
<?php
|
678 |
-
|
679 |
-
<?php } ?>
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
<td>
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
<?php
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
<?php
|
791 |
-
|
792 |
-
<?php } ?>
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
<?php
|
824 |
-
|
825 |
-
<?php } ?>
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
<td>
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
<?php } ?>
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
</td>
|
898 |
-
<td>
|
899 |
-
<?php
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
<?php } else { ?>
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
<td>
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
<?php
|
959 |
-
</td>
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
<tr>
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
<
|
1127 |
-
|
1128 |
-
</
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
<
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
<
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
</
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
$wait_timeout = $wpdb->get_var("select @@wait_timeout");
|
1191 |
-
$condition = ($wait_timeout < 30) ? 0 : 1;
|
1192 |
-
?>
|
1193 |
-
<tr>
|
1194 |
-
<td>Database wait timeout</td>
|
1195 |
-
<td>
|
1196 |
-
<?php tnp_status_print_flag($condition) ?>
|
1197 |
-
</td>
|
1198 |
-
<td>
|
1199 |
-
Your database wait timeout is <?php echo $wait_timeout; ?> seconds<br>
|
1200 |
-
<?php if ($wait_timeout < 30) { ?>
|
1201 |
-
That value is low and could produce database connection errors while sending emails or during long import
|
1202 |
-
sessions. Ask the provider to raise it at least to 60 seconds.
|
1203 |
-
<?php } ?>
|
1204 |
-
</td>
|
1205 |
-
</tr>
|
1206 |
-
|
1207 |
-
<?php
|
1208 |
-
$res = $wpdb->query("drop table if exists {$wpdb->prefix}newsletter_test");
|
1209 |
-
$res = $wpdb->query("create table if not exists {$wpdb->prefix}newsletter_test (id int(20))");
|
1210 |
-
$condition = $res === false ? 0 : 1;
|
1211 |
-
?>
|
1212 |
-
<tr>
|
1213 |
-
<td>Database table creation</td>
|
1214 |
-
<td>
|
1215 |
-
<?php tnp_status_print_flag($condition) ?>
|
1216 |
-
</td>
|
1217 |
-
<td>
|
1218 |
-
<?php if ($res === false) { ?>
|
1219 |
-
Check the privileges of the user you use to connect to the database, it seems it cannot create tables.<br>
|
1220 |
-
(<?php echo esc_html($wpdb->last_error) ?>)
|
1221 |
-
<?php } else { ?>
|
1222 |
-
<?php } ?>
|
1223 |
-
</td>
|
1224 |
-
</tr>
|
1225 |
-
|
1226 |
-
<?php
|
1227 |
-
$res = $wpdb->query("alter table {$wpdb->prefix}newsletter_test add column id1 int(20)");
|
1228 |
-
$condition = $res === false ? 0 : 1;
|
1229 |
-
?>
|
1230 |
-
<tr>
|
1231 |
-
<td>Database table change</td>
|
1232 |
-
<td>
|
1233 |
-
<?php tnp_status_print_flag($condition) ?>
|
1234 |
-
</td>
|
1235 |
-
<td>
|
1236 |
-
<?php if ($res === false) { ?>
|
1237 |
-
Check the privileges of the user you use to connect to the database, it seems it cannot change the tables. It's require to update the
|
1238 |
-
plugin.<br>
|
1239 |
-
(<?php echo esc_html($wpdb->last_error) ?>)
|
1240 |
-
<?php } else { ?>
|
1241 |
-
<?php } ?>
|
1242 |
-
</td>
|
1243 |
-
</tr>
|
1244 |
-
|
1245 |
-
<?php
|
1246 |
-
// Clean up
|
1247 |
-
$res = $wpdb->query("drop table if exists {$wpdb->prefix}newsletter_test");
|
1248 |
-
?>
|
1249 |
-
|
1250 |
-
<?php if (!get_option('newsletter_stats_email_column_upgraded', false)) { ?>
|
1251 |
-
<?php
|
1252 |
-
$data_type = $wpdb->get_var(
|
1253 |
-
$wpdb->prepare('SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s',
|
1254 |
-
DB_NAME, NEWSLETTER_STATS_TABLE, 'email_id'));
|
1255 |
-
$to_upgrade = strtoupper($data_type) == 'INT' ? false : true;
|
1256 |
-
?>
|
1257 |
-
<?php if ($to_upgrade) { ?>
|
1258 |
-
<tr>
|
1259 |
-
<td>Database stats table upgrade</td>
|
1260 |
-
<td><?php tnp_status_print_flag(0) ?></td>
|
1261 |
-
<td><?php $controls->button('stats_email_column_upgrade', 'Stats table upgrade') ?></td>
|
1262 |
-
</tr>
|
1263 |
-
<?php } ?>
|
1264 |
-
<?php } ?>
|
1265 |
-
|
1266 |
-
</tbody>
|
1267 |
-
</table>
|
1268 |
-
|
1269 |
-
<h3>3rd party plugins</h3>
|
1270 |
-
<table class="widefat" id="tnp-status-table">
|
1271 |
-
<thead>
|
1272 |
-
<tr>
|
1273 |
-
<th>Plugin</th>
|
1274 |
-
<th><?php _e('Status', 'newsletter') ?></th>
|
1275 |
-
<th>Action</th>
|
1276 |
-
</tr>
|
1277 |
-
</thead>
|
1278 |
-
<tbody>
|
1279 |
-
<?php if (is_plugin_active('plugin-load-filter/plugin-load-filter.php')) { ?>
|
1280 |
-
<tr>
|
1281 |
-
<td><a href="https://wordpress.org/plugins/plugin-load-filter/" target="_blank">Plugin load filter</a></td>
|
1282 |
-
<td>
|
1283 |
-
<span class="tnp-maybe">MAY BE</span>
|
1284 |
-
</td>
|
1285 |
-
<td>
|
1286 |
-
Be sure Newsletter is set as active in EVERY context.
|
1287 |
-
</td>
|
1288 |
-
</tr>
|
1289 |
-
<?php } ?>
|
1290 |
-
</tbody>
|
1291 |
-
</table>
|
1292 |
-
|
1293 |
-
<h3>General parameters</h3>
|
1294 |
-
<table class="widefat" id="tnp-parameters-table">
|
1295 |
-
<thead>
|
1296 |
-
<tr>
|
1297 |
-
<th>Parameter</th>
|
1298 |
-
<th>Value</th>
|
1299 |
-
</tr>
|
1300 |
-
</thead>
|
1301 |
-
<tbody>
|
1302 |
-
|
1303 |
-
<tr>
|
1304 |
-
<td>Newsletter version</td>
|
1305 |
-
<td>
|
1306 |
-
<?php echo NEWSLETTER_VERSION ?>
|
1307 |
-
</td>
|
1308 |
-
</tr>
|
1309 |
-
|
1310 |
-
<tr>
|
1311 |
-
<td>NEWSLETTER_MAX_EXECUTION_TIME</td>
|
1312 |
-
<td>
|
1313 |
-
<?php
|
1314 |
-
if (defined('NEWSLETTER_MAX_EXECUTION_TIME')) {
|
1315 |
-
echo NEWSLETTER_MAX_EXECUTION_TIME . ' (seconds)';
|
1316 |
-
} else {
|
1317 |
-
echo 'Not set';
|
1318 |
-
}
|
1319 |
-
?>
|
1320 |
-
</td>
|
1321 |
-
</tr>
|
1322 |
-
<tr>
|
1323 |
-
<td>NEWSLETTER_CRON_INTERVAL</td>
|
1324 |
-
<td>
|
1325 |
-
<?php echo NEWSLETTER_CRON_INTERVAL . ' (seconds)'; ?>
|
1326 |
-
</td>
|
1327 |
-
</tr>
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
<?php /*
|
1332 |
-
<tr>
|
1333 |
-
<td>WordPress plugin url</td>
|
1334 |
-
<td>
|
1335 |
-
<?php echo WP_PLUGIN_URL; ?>
|
1336 |
-
<br>
|
1337 |
-
Filters:
|
1338 |
-
|
1339 |
-
<?php
|
1340 |
-
if (isset($wp_filter))
|
1341 |
-
$filters = $wp_filter['plugins_url'];
|
1342 |
-
if (!isset($filters) || !is_array($filters))
|
1343 |
-
echo 'no filters attached to "plugin_urls"';
|
1344 |
-
else {
|
1345 |
-
echo '<ul>';
|
1346 |
-
foreach ($filters as &$filter) {
|
1347 |
-
foreach ($filter as &$entry) {
|
1348 |
-
echo '<li>';
|
1349 |
-
if (is_array($entry['function']))
|
1350 |
-
echo esc_html(get_class($entry['function'][0]) . '->' . $entry['function'][1]);
|
1351 |
-
else
|
1352 |
-
echo esc_html($entry['function']);
|
1353 |
-
echo '</li>';
|
1354 |
-
}
|
1355 |
-
}
|
1356 |
-
echo '</ul>';
|
1357 |
-
}
|
1358 |
-
?>
|
1359 |
-
<p class="description">
|
1360 |
-
This value should contains the full URL to your plugin folder. If there are filters
|
1361 |
-
attached, the value can be different from the original generated by WordPress and sometime worng.
|
1362 |
-
</p>
|
1363 |
-
</td>
|
1364 |
-
</tr>
|
1365 |
-
*/ ?>
|
1366 |
-
|
1367 |
-
<tr>
|
1368 |
-
<td>Absolute path</td>
|
1369 |
-
<td>
|
1370 |
-
<?php echo esc_html(ABSPATH); ?>
|
1371 |
-
</td>
|
1372 |
-
</tr>
|
1373 |
-
<tr>
|
1374 |
-
<td>Tables Prefix</td>
|
1375 |
-
<td>
|
1376 |
-
<?php echo $wpdb->prefix; ?>
|
1377 |
-
</td>
|
1378 |
-
</tr>
|
1379 |
-
</tbody>
|
1380 |
-
</table>
|
1381 |
-
|
1382 |
-
|
1383 |
-
<?php if (isset($_GET['debug'])) { ?>
|
1384 |
-
|
1385 |
-
<h3>Database Tables</h3>
|
1386 |
-
<h4><?php echo $wpdb->prefix ?>newsletter</h4>
|
1387 |
-
<?php
|
1388 |
-
$rs = $wpdb->get_results("describe {$wpdb->prefix}newsletter");
|
1389 |
-
?>
|
1390 |
-
<table class="tnp-db-table">
|
1391 |
-
<thead>
|
1392 |
-
<tr>
|
1393 |
-
<th>Field</th>
|
1394 |
-
<th>Type</th>
|
1395 |
-
<th>Null</th>
|
1396 |
-
<th>Key</th>
|
1397 |
-
<th>Default</th>
|
1398 |
-
<th>Extra</th>
|
1399 |
-
</tr>
|
1400 |
-
</thead>
|
1401 |
-
<tbody>
|
1402 |
-
<?php foreach ($rs as $r) { ?>
|
1403 |
-
<tr>
|
1404 |
-
<td><?php echo esc_html($r->Field) ?></td>
|
1405 |
-
<td><?php echo esc_html($r->Type) ?></td>
|
1406 |
-
<td><?php echo esc_html($r->Null) ?></td>
|
1407 |
-
<td><?php echo esc_html($r->Key) ?></td>
|
1408 |
-
<td><?php echo esc_html($r->Default) ?></td>
|
1409 |
-
<td><?php echo esc_html($r->Extra) ?></td>
|
1410 |
-
</tr>
|
1411 |
-
<?php } ?>
|
1412 |
-
</tbody>
|
1413 |
-
</table>
|
1414 |
-
|
1415 |
-
<h4><?php echo $wpdb->prefix ?>newsletter_emails</h4>
|
1416 |
-
<?php
|
1417 |
-
$rs = $wpdb->get_results("show full columns from {$wpdb->prefix}newsletter_emails");
|
1418 |
-
?>
|
1419 |
-
<table class="tnp-db-table">
|
1420 |
-
<thead>
|
1421 |
-
<tr>
|
1422 |
-
<th>Field</th>
|
1423 |
-
<th>Type</th>
|
1424 |
-
<th>Collation</th>
|
1425 |
-
<th>Null</th>
|
1426 |
-
<th>Key</th>
|
1427 |
-
<th>Default</th>
|
1428 |
-
<th>Extra</th>
|
1429 |
-
</tr>
|
1430 |
-
</thead>
|
1431 |
-
<tbody>
|
1432 |
-
<?php foreach ($rs as $r) { ?>
|
1433 |
-
<tr>
|
1434 |
-
<td><?php echo esc_html($r->Field) ?></td>
|
1435 |
-
<td><?php echo esc_html($r->Type) ?></td>
|
1436 |
-
<td><?php echo esc_html($r->Collation) ?></td>
|
1437 |
-
<td><?php echo esc_html($r->Null) ?></td>
|
1438 |
-
<td><?php echo esc_html($r->Key) ?></td>
|
1439 |
-
<td><?php echo esc_html($r->Default) ?></td>
|
1440 |
-
<td><?php echo esc_html($r->Extra) ?></td>
|
1441 |
-
</tr>
|
1442 |
-
<?php } ?>
|
1443 |
-
</tbody>
|
1444 |
-
</table>
|
1445 |
-
|
1446 |
-
|
1447 |
-
<h3>Extensions</h3>
|
1448 |
-
<pre style="font-size: 11px; font-family: monospace; background-color: #efefef; color: #444"><?php echo esc_html(print_r(get_option('newsletter_extension_versions'), true)); ?></pre>
|
1449 |
-
|
1450 |
-
<h3>Update plugins data</h3>
|
1451 |
-
<pre style="font-size: 11px; font-family: monospace; background-color: #efefef; color: #444"><?php echo esc_html(print_r(get_site_transient('update_plugins'), true)); ?></pre>
|
1452 |
-
|
1453 |
-
<?php } ?>
|
1454 |
-
</div>
|
1455 |
-
|
1456 |
-
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
1457 |
-
|
1458 |
-
</div>
|
1 |
+
<?php
|
2 |
+
/* @var $this Newsletter */
|
3 |
+
/* @var $wpdb wpdb */
|
4 |
+
|
5 |
+
defined('ABSPATH') || exit;
|
6 |
+
|
7 |
+
wp_enqueue_script('tnp-chart');
|
8 |
+
|
9 |
+
include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
10 |
+
$controls = new NewsletterControls();
|
11 |
+
|
12 |
+
$system = NewsletterSystem::instance();
|
13 |
+
|
14 |
+
if ($controls->is_action('delete_logs')) {
|
15 |
+
$files = glob(WP_CONTENT_DIR . '/logs/newsletter/*.txt');
|
16 |
+
foreach ($files as $file) {
|
17 |
+
if (is_file($file))
|
18 |
+
unlink($file);
|
19 |
+
}
|
20 |
+
$secret = NewsletterModule::get_token(8);
|
21 |
+
update_option('newsletter_logger_secret', $secret);
|
22 |
+
$controls->messages = 'Logs deleted';
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
if ($controls->is_action('conversion')) {
|
28 |
+
$this->logger->info('Maybe convert to utf8mb4');
|
29 |
+
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
30 |
+
if (function_exists('maybe_convert_table_to_utf8mb4')) {
|
31 |
+
$r = maybe_convert_table_to_utf8mb4(NEWSLETTER_EMAILS_TABLE);
|
32 |
+
if (!$r) {
|
33 |
+
$controls->errors .= 'It was not possible to run the conversion for the table ' . NEWSLETTER_EMAILS_TABLE . ' - ';
|
34 |
+
$controls->errors .= $wpdb->last_error . '<br>';
|
35 |
+
}
|
36 |
+
$r = maybe_convert_table_to_utf8mb4(NEWSLETTER_USERS_TABLE);
|
37 |
+
if (!$r) {
|
38 |
+
$controls->errors .= 'It was not possible to run the conversion for the table ' . NEWSLETTER_EMAILS_TABLE . ' - ';
|
39 |
+
$controls->errors .= $wpdb->last_error . '<br>';
|
40 |
+
}
|
41 |
+
$controls->messages .= 'Done.';
|
42 |
+
} else {
|
43 |
+
$controls->errors = 'Table conversion function not available';
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
if ($controls->is_action('reset_send_stats')) {
|
48 |
+
$system->reset_send_stats();
|
49 |
+
$controls->add_message_done();
|
50 |
+
}
|
51 |
+
|
52 |
+
if ($controls->is_action('test')) {
|
53 |
+
|
54 |
+
if (!NewsletterModule::is_email($controls->data['test_email'])) {
|
55 |
+
$controls->errors = 'The test email address is not set or is not correct.';
|
56 |
+
}
|
57 |
+
|
58 |
+
if (empty($controls->errors)) {
|
59 |
+
|
60 |
+
$options = $controls->data;
|
61 |
+
|
62 |
+
if ($controls->data['test_email'] == $this->options['sender_email']) {
|
63 |
+
$controls->messages .= '<strong>Warning:</strong> you are using as test email the same address configured as sender in main configuration. Test can fail because of that.<br>';
|
64 |
+
}
|
65 |
+
|
66 |
+
$message = NewsletterMailerAddon::get_test_message($controls->data['test_email'], 'Newsletter test email at ' . date(DATE_ISO8601));
|
67 |
+
|
68 |
+
$r = $this->deliver($message);
|
69 |
+
|
70 |
+
if (!is_wp_error($r)) {
|
71 |
+
$options['mail'] = 1;
|
72 |
+
$controls->messages .= '<strong>SUCCESS</strong><br>';
|
73 |
+
$controls->messages .= 'Anyway if the message does not appear the mailbox (check even the spam folder) you can ';
|
74 |
+
$controls->messages .= '<a href="https://www.thenewsletterplugin.com/documentation/?p=15170" target="_blank"><strong>read more here</strong></a>.';
|
75 |
+
} else {
|
76 |
+
$options['mail'] = 0;
|
77 |
+
$options['mail_error'] = $r->get_error_message();
|
78 |
+
|
79 |
+
$controls->errors .= '<strong>FAILED</strong> (' . $r->get_error_message() . ')<br>';
|
80 |
+
|
81 |
+
if (!empty($this->options['return_path'])) {
|
82 |
+
$controls->errors .= '- Try to remove the return path on main settings.<br>';
|
83 |
+
}
|
84 |
+
|
85 |
+
$controls->errors .= '<a href="https://www.thenewsletterplugin.com/documentation/?p=15170" target="_blank"><strong>' . __('Read more', 'newsletter') . '</strong></a>.';
|
86 |
+
|
87 |
+
$parts = explode('@', $this->options['sender_email']);
|
88 |
+
$sitename = strtolower($_SERVER['SERVER_NAME']);
|
89 |
+
if (substr($sitename, 0, 4) == 'www.') {
|
90 |
+
$sitename = substr($sitename, 4);
|
91 |
+
}
|
92 |
+
if (strtolower($sitename) != strtolower($parts[1])) {
|
93 |
+
$controls->errors .= '- Try to set on main setting a sender address with the same domain of your blog: ' . $sitename . ' (you are using ' . $this->options['sender_email'] . ')<br>';
|
94 |
+
}
|
95 |
+
}
|
96 |
+
$this->save_options($options, 'status');
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
if ($controls->is_action('stats_email_column_upgrade')) {
|
101 |
+
$this->query("alter table " . NEWSLETTER_STATS_TABLE . " drop index email_id");
|
102 |
+
$this->query("alter table " . NEWSLETTER_STATS_TABLE . " drop index user_id");
|
103 |
+
$this->query("alter table `" . NEWSLETTER_STATS_TABLE . "` modify column `email_id` int(11) not null default 0");
|
104 |
+
$this->query("create index email_id on " . NEWSLETTER_STATS_TABLE . " (email_id)");
|
105 |
+
$this->query("create index user_id on " . NEWSLETTER_STATS_TABLE . " (user_id)");
|
106 |
+
$controls->add_message_done();
|
107 |
+
update_option('newsletter_stats_email_column_upgraded', true);
|
108 |
+
}
|
109 |
+
|
110 |
+
$options = $this->get_options('status');
|
111 |
+
|
112 |
+
// Compute the number of newsletters ongoing and other stats
|
113 |
+
$emails = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where status='sending' and send_on<" . time() . " order by id asc");
|
114 |
+
$total = 0;
|
115 |
+
$queued = 0;
|
116 |
+
foreach ($emails as $email) {
|
117 |
+
$total += $email->total;
|
118 |
+
$queued += $email->total - $email->sent;
|
119 |
+
}
|
120 |
+
$speed = Newsletter::$instance->options['scheduler_max'];
|
121 |
+
|
122 |
+
function tnp_status_print_flag($condition) {
|
123 |
+
switch ($condition) {
|
124 |
+
case 0: echo ' <span class="tnp-ko">KO</span>';
|
125 |
+
break;
|
126 |
+
case 1: echo '<span class="tnp-ok">OK</span>';
|
127 |
+
break;
|
128 |
+
case 2: echo '<span class="tnp-maybe">MAYBE</span>';
|
129 |
+
break;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
class TNP_WPDB extends wpdb {
|
134 |
+
|
135 |
+
public function get_table_charset($table) {
|
136 |
+
return parent::get_table_charset($table);
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
140 |
+
|
141 |
+
$tnp_wpdb = new TNP_WPDB(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
|
142 |
+
?>
|
143 |
+
<style>
|
144 |
+
table.widefat tbody tr>td:first-child {
|
145 |
+
width: 150px!important;
|
146 |
+
}
|
147 |
+
</style>
|
148 |
+
|
149 |
+
<div class="wrap tnp-main-status" id="tnp-wrap">
|
150 |
+
|
151 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
152 |
+
|
153 |
+
<div id="tnp-heading">
|
154 |
+
|
155 |
+
<h2><?php _e('System Status', 'newsletter') ?></h2>
|
156 |
+
|
157 |
+
</div>
|
158 |
+
|
159 |
+
<div id="tnp-body">
|
160 |
+
|
161 |
+
<form method="post" action="">
|
162 |
+
<?php $controls->init(); ?>
|
163 |
+
|
164 |
+
|
165 |
+
<h3>Delivery</h3>
|
166 |
+
<table class="widefat" id="tnp-status-table">
|
167 |
+
|
168 |
+
<thead>
|
169 |
+
<tr>
|
170 |
+
<th>Parameter</th>
|
171 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
172 |
+
<th>Action</th>
|
173 |
+
</tr>
|
174 |
+
|
175 |
+
</thead>
|
176 |
+
|
177 |
+
<tbody>
|
178 |
+
|
179 |
+
<tr>
|
180 |
+
<td>Delivering</td>
|
181 |
+
<td class="status">
|
182 |
+
|
183 |
+
</td>
|
184 |
+
<td>
|
185 |
+
<?php if (count($emails)) { ?>
|
186 |
+
Delivering <?php echo count($emails) ?> newsletters to about <?php echo $queued ?> recipients.
|
187 |
+
At speed of <?php echo $speed ?> emails per hour it will take <?php printf('%.1f', $queued / $speed) ?> hours to finish.
|
188 |
+
|
189 |
+
<?php } else { ?>
|
190 |
+
Nothing delivering right now
|
191 |
+
<?php } ?>
|
192 |
+
</td>
|
193 |
+
|
194 |
+
</tr>
|
195 |
+
<tr>
|
196 |
+
<td>Mailer</td>
|
197 |
+
<td>
|
198 |
+
|
199 |
+
</td>
|
200 |
+
<td>
|
201 |
+
<?php
|
202 |
+
$mailer = Newsletter::instance()->get_mailer();
|
203 |
+
$name = 'Unknown';
|
204 |
+
if (is_object($mailer)) {
|
205 |
+
if (method_exists($mailer, 'get_description')) {
|
206 |
+
$name = $mailer->get_description();
|
207 |
+
} else {
|
208 |
+
$name = get_class($mailer);
|
209 |
+
}
|
210 |
+
}
|
211 |
+
?>
|
212 |
+
|
213 |
+
<?php echo esc_html($name) ?>
|
214 |
+
</td>
|
215 |
+
</tr>
|
216 |
+
<?php
|
217 |
+
$stats = $system->get_send_stats();
|
218 |
+
|
219 |
+
if ($stats) {
|
220 |
+
$condition = $stats->mean > 2 ? 2 : 1;
|
221 |
+
?>
|
222 |
+
<tr>
|
223 |
+
<td id="tnp-speed">
|
224 |
+
Send details
|
225 |
+
</td>
|
226 |
+
<td class="status">
|
227 |
+
<?php tnp_status_print_flag($condition) ?>
|
228 |
+
|
229 |
+
</td>
|
230 |
+
<td>
|
231 |
+
<?php if ($condition) { ?>
|
232 |
+
<strong>Sending an email is taking more than 1 second, rather slow.</strong>
|
233 |
+
<a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-performance" target="_blank">Read more</a>.
|
234 |
+
<br>
|
235 |
+
<?php } ?>
|
236 |
+
Average time to send an email: <?php echo $stats->mean ?> seconds<br>
|
237 |
+
<?php if ($stats->mean > 0) { ?>
|
238 |
+
Max speed: <?php echo sprintf("%.2f", 1.0 / $stats->mean * 3600) ?> emails per hour<br>
|
239 |
+
<?php } ?>
|
240 |
+
|
241 |
+
Max mean time measured: <?php echo $stats->max ?> seconds<br>
|
242 |
+
Min mean time measured: <?php echo $stats->min ?> seconds<br>
|
243 |
+
Total emails in the sample: <?php echo $stats->total_emails ?><br>
|
244 |
+
Total sending time: <?php echo $stats->total_time ?> seconds<br>
|
245 |
+
Runs in the sample: <?php echo $stats->total_runs ?><br>
|
246 |
+
Runs prematurely interrupted: <?php echo $stats->interrupted ?><br>
|
247 |
+
|
248 |
+
|
249 |
+
<canvas id="tnp-send-chart" style="width: 550px; height: 150px"></canvas>
|
250 |
+
<script>
|
251 |
+
jQuery(function () {
|
252 |
+
var sendChartData = {
|
253 |
+
labels: <?php echo json_encode(range(1, count($stats->means))) ?>,
|
254 |
+
datasets: [
|
255 |
+
{
|
256 |
+
label: "Batch Average Time",
|
257 |
+
data: <?php echo json_encode($stats->means) ?>,
|
258 |
+
borderColor: '#2980b9',
|
259 |
+
fill: false
|
260 |
+
}/*,
|
261 |
+
{
|
262 |
+
label: "Batch Average Time",
|
263 |
+
data: <?php echo json_encode($stats->sizes) ?>,
|
264 |
+
borderColor: '#b98028',
|
265 |
+
fill: false
|
266 |
+
}*/]
|
267 |
+
};
|
268 |
+
var sendChartConfig = {
|
269 |
+
type: "line",
|
270 |
+
data: sendChartData,
|
271 |
+
options: {
|
272 |
+
responsive: false,
|
273 |
+
maintainAspectRatio: false
|
274 |
+
}
|
275 |
+
};
|
276 |
+
new Chart('tnp-send-chart', sendChartConfig);
|
277 |
+
});
|
278 |
+
</script>
|
279 |
+
<br>
|
280 |
+
<?php $controls->button_reset('reset_send_stats') ?>
|
281 |
+
</td>
|
282 |
+
</tr>
|
283 |
+
<?php } else { ?>
|
284 |
+
<tr>
|
285 |
+
<td>
|
286 |
+
Sending statistics
|
287 |
+
</td>
|
288 |
+
<td>
|
289 |
+
|
290 |
+
</td>
|
291 |
+
<td>
|
292 |
+
Not enough data available.
|
293 |
+
</td>
|
294 |
+
</tr>
|
295 |
+
<?php } ?>
|
296 |
+
</tbody>
|
297 |
+
</table>
|
298 |
+
|
299 |
+
<h3>General checks</h3>
|
300 |
+
<table class="widefat" id="tnp-status-table">
|
301 |
+
|
302 |
+
<thead>
|
303 |
+
<tr>
|
304 |
+
<th>Parameter</th>
|
305 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
306 |
+
<th>Action</th>
|
307 |
+
</tr>
|
308 |
+
|
309 |
+
</thead>
|
310 |
+
|
311 |
+
<tbody>
|
312 |
+
|
313 |
+
<tr>
|
314 |
+
<?php
|
315 |
+
$page_id = $this->get_newsletter_page_id();
|
316 |
+
$page = $this->get_newsletter_page();
|
317 |
+
$condition = 1;
|
318 |
+
if ($page_id) {
|
319 |
+
if (!$page || $page->post_status !== 'publish') {
|
320 |
+
$condition = 0;
|
321 |
+
}
|
322 |
+
} else {
|
323 |
+
$condition = 2;
|
324 |
+
}
|
325 |
+
?>
|
326 |
+
<td>
|
327 |
+
Dedicated page<br>
|
328 |
+
<small>The blog page Newsletter uses for messages</small>
|
329 |
+
</td>
|
330 |
+
<td>
|
331 |
+
<?php tnp_status_print_flag($condition) ?>
|
332 |
+
</td>
|
333 |
+
<td>
|
334 |
+
<?php if ($condition == 2) { ?>
|
335 |
+
Newsletter is using a neutral page to show messages, if you want to use a dedicated page, configure it on
|
336 |
+
<a href="?page=newsletter_main_main">main settings</a>.
|
337 |
+
<?php } else if ($condition == 0) { ?>
|
338 |
+
A dedicated page is set but it is no more available or no more published. Review the dedicated page on
|
339 |
+
<a href="?page=newsletter_main_main">main settings</a>.
|
340 |
+
<?php } ?>
|
341 |
+
</td>
|
342 |
+
</tr>
|
343 |
+
|
344 |
+
<tr>
|
345 |
+
<?php
|
346 |
+
$page_id = $this->get_newsletter_page_id();
|
347 |
+
$page = $this->get_newsletter_page();
|
348 |
+
$condition = 1;
|
349 |
+
if ($page_id) {
|
350 |
+
if (!$page) {
|
351 |
+
$condition = 0;
|
352 |
+
} else {
|
353 |
+
$content = $page->post_content;
|
354 |
+
if (strpos($content, '[newsletter]') === false && strpos($content, '[newsletter ') === false) {
|
355 |
+
$condition = 2;
|
356 |
+
}
|
357 |
+
}
|
358 |
+
}
|
359 |
+
?>
|
360 |
+
<td>
|
361 |
+
Dedicated page content<br>
|
362 |
+
</td>
|
363 |
+
<td>
|
364 |
+
<?php tnp_status_print_flag($condition) ?>
|
365 |
+
</td>
|
366 |
+
<td>
|
367 |
+
<?php if ($condition == 2) { ?>
|
368 |
+
The page seems to not contain the <code>[newsletter]</code>, but sometime it cannot be detected if you use
|
369 |
+
a visual composer. <a href="post.php?post=<?php echo $page->ID ?>&action=edit" target="_blank">Please, check the page</a>.
|
370 |
+
<?php } else if ($condition == 0) { ?>
|
371 |
+
The dedicated page seems to not be available.
|
372 |
+
<?php } ?>
|
373 |
+
</td>
|
374 |
+
</tr>
|
375 |
+
|
376 |
+
<?php
|
377 |
+
$method = '';
|
378 |
+
if (function_exists('get_filesystem_method')) {
|
379 |
+
$method = get_filesystem_method(array(), WP_PLUGIN_DIR);
|
380 |
+
}
|
381 |
+
if (empty($method))
|
382 |
+
$condition = 2;
|
383 |
+
else if ($method == 'direct')
|
384 |
+
$condition = 1;
|
385 |
+
else
|
386 |
+
$condition = 0;
|
387 |
+
?>
|
388 |
+
<tr>
|
389 |
+
<td>Add-ons installable</td>
|
390 |
+
<td>
|
391 |
+
<?php tnp_status_print_flag($condition) ?>
|
392 |
+
</td>
|
393 |
+
<td>
|
394 |
+
<?php if ($condition == 2) { ?>
|
395 |
+
No able to check, just try the add-ons manager one click install
|
396 |
+
<?php } else if ($condition == 1) { ?>
|
397 |
+
The add-ons manager can install our add-ons
|
398 |
+
<?php } else { ?>
|
399 |
+
The plugins dir could be read-only, you can install add-ons uploading the package from the
|
400 |
+
plugins panel (or uploading them directly via FTP). This is unusual you should ask te provider
|
401 |
+
about file and folder permissions.
|
402 |
+
<?php } ?>
|
403 |
+
</td>
|
404 |
+
|
405 |
+
</tr>
|
406 |
+
|
407 |
+
|
408 |
+
<?php
|
409 |
+
$return_path = $this->options['return_path'];
|
410 |
+
if (!empty($return_path)) {
|
411 |
+
list($return_path_local, $return_path_domain) = explode('@', $return_path);
|
412 |
+
}
|
413 |
+
$sender = $this->options['sender_email'];
|
414 |
+
if (!empty($sender)) {
|
415 |
+
list($sender_local, $sender_domain) = explode('@', $sender);
|
416 |
+
}
|
417 |
+
?>
|
418 |
+
<tr>
|
419 |
+
<td>Return path</td>
|
420 |
+
<td>
|
421 |
+
<?php if (empty($return_path)) { ?>
|
422 |
+
<span class="tnp-ok">OK</span>
|
423 |
+
<?php } else { ?>
|
424 |
+
<?php if ($sender_domain != $return_path_domain) { ?>
|
425 |
+
<span class="tnp-maybe">MAYBE</span>
|
426 |
+
<?php } else { ?>
|
427 |
+
<span class="tnp-ok">OK</span>
|
428 |
+
<?php } ?>
|
429 |
+
<?php } ?>
|
430 |
+
|
431 |
+
</td>
|
432 |
+
<td>
|
433 |
+
<?php if (!empty($return_path)) { ?>
|
434 |
+
Some providers require the return path domain <code><?php echo esc_html($return_path_domain) ?></code> to be identical
|
435 |
+
to the sender domain <code><?php echo esc_html($sender_domain) ?></code>. See the main settings.
|
436 |
+
<?php } else { ?>
|
437 |
+
<?php } ?>
|
438 |
+
</td>
|
439 |
+
|
440 |
+
</tr>
|
441 |
+
|
442 |
+
|
443 |
+
|
444 |
+
|
445 |
+
|
446 |
+
<tr>
|
447 |
+
<?php
|
448 |
+
$condition = NEWSLETTER_EXTENSION_UPDATE ? 1 : 0;
|
449 |
+
?>
|
450 |
+
<td>Addons update</td>
|
451 |
+
<td>
|
452 |
+
<?php tnp_status_print_flag($condition) ?>
|
453 |
+
</td>
|
454 |
+
<td>
|
455 |
+
<?php if ($condition == 0) { ?>
|
456 |
+
Newsletter Addons update is disabled (probably in your <code>wp-config.php</code> file the constant
|
457 |
+
<code>NEWSLETTER_EXTENSION_UPDATE</code> is set to <code>true</code>)
|
458 |
+
<?php } else { ?>
|
459 |
+
Newsletter Addons can be updated
|
460 |
+
<?php } ?>
|
461 |
+
</td>
|
462 |
+
|
463 |
+
</tr>
|
464 |
+
|
465 |
+
|
466 |
+
<?php
|
467 |
+
$res = 0;
|
468 |
+
$response = wp_remote_post(home_url('/') . '?na=test');
|
469 |
+
if (is_wp_error($response)) {
|
470 |
+
$res = 1;
|
471 |
+
$message = $response->get_error_message();
|
472 |
+
} else if (wp_remote_retrieve_response_code($response) != 200) {
|
473 |
+
$res = 1;
|
474 |
+
$message = wp_remote_retrieve_response_message($response);
|
475 |
+
} else if (wp_remote_retrieve_body($response) !== 'ok') {
|
476 |
+
$res = 2;
|
477 |
+
}
|
478 |
+
?>
|
479 |
+
<tr>
|
480 |
+
<td>
|
481 |
+
Action call
|
482 |
+
</td>
|
483 |
+
<td>
|
484 |
+
<?php if (!$res) { ?>
|
485 |
+
<span class="tnp-ko">KO</span>
|
486 |
+
<?php } else { ?>
|
487 |
+
<span class="tnp-ok">OK</span>
|
488 |
+
<?php } ?>
|
489 |
+
</td>
|
490 |
+
<td>
|
491 |
+
<?php if ($res === 1) { ?>
|
492 |
+
The blog is not responding to Newsletter URLs: ask the provider or your IT consultant to check this problem. Report the URL and error below<br>
|
493 |
+
Error: <?php echo esc_html($message) ?><br>
|
494 |
+
<?php } else if ($res === 2) { ?>
|
495 |
+
The response does not contain the "ok" text: probably a caching/optimization plugin or a server configuration is forcing the blog to ignore
|
496 |
+
the URL's query string. Reported that to your system administrator.
|
497 |
+
<?php } ?>
|
498 |
+
Url: <?php echo esc_html(home_url('/') . '?na=test') ?><br>
|
499 |
+
</td>
|
500 |
+
</tr>
|
501 |
+
|
502 |
+
|
503 |
+
<tr>
|
504 |
+
<?php
|
505 |
+
$res = true;
|
506 |
+
$response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/extensions.json');
|
507 |
+
$condition = 1;
|
508 |
+
if (is_wp_error($response)) {
|
509 |
+
$res = false;
|
510 |
+
$condition = 0;
|
511 |
+
$message = $response->get_error_message();
|
512 |
+
} else {
|
513 |
+
if (wp_remote_retrieve_response_code($response) != 200) {
|
514 |
+
$res = false;
|
515 |
+
$condition = 0;
|
516 |
+
$message = wp_remote_retrieve_response_message($response);
|
517 |
+
}
|
518 |
+
}
|
519 |
+
?>
|
520 |
+
|
521 |
+
<td>
|
522 |
+
Addons version check<br>
|
523 |
+
<small>Your blog can check the professional addon updates?</small>
|
524 |
+
</td>
|
525 |
+
<td>
|
526 |
+
<?php tnp_status_print_flag($condition) ?>
|
527 |
+
</td>
|
528 |
+
<td>
|
529 |
+
<?php if ($condition == 0) { ?>
|
530 |
+
The blog cannot contact www.thenewsletterplugin.com to check the license or the extension versions.<br>
|
531 |
+
Error: <?php echo esc_html($message) ?><br>
|
532 |
+
<?php } else { ?>
|
533 |
+
|
534 |
+
<?php } ?>
|
535 |
+
</td>
|
536 |
+
</tr>
|
537 |
+
|
538 |
+
|
539 |
+
|
540 |
+
|
541 |
+
|
542 |
+
|
543 |
+
|
544 |
+
|
545 |
+
|
546 |
+
<?php /*
|
547 |
+
$memory = intval(WP_MEMORY_LIMIT);
|
548 |
+
if (false !== strpos(WP_MEMORY_LIMIT, 'G'))
|
549 |
+
$memory *= 1024;
|
550 |
+
?>
|
551 |
+
<tr>
|
552 |
+
<td>
|
553 |
+
PHP memory limit
|
554 |
+
</td>
|
555 |
+
<td>
|
556 |
+
<?php if ($memory < 64) { ?>
|
557 |
+
<span class="tnp-ko">MAYBE</span>
|
558 |
+
<?php } else if ($memory < 128) { ?>
|
559 |
+
<span class="tnp-maybe">MAYBE</span>
|
560 |
+
<?php } else { ?>
|
561 |
+
<span class="tnp-ok">OK</span>
|
562 |
+
<?php } ?>
|
563 |
+
</td>
|
564 |
+
<td>
|
565 |
+
WordPress WP_MEMORY_LIMIT is set to <?php echo $memory ?> megabyte but your PHP setting could allow more than that.
|
566 |
+
Anyway we suggest to set the value to at least 64M.
|
567 |
+
<a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-memory" target="_blank">Read more</a>.
|
568 |
+
<?php if ($memory < 64) { ?>
|
569 |
+
This value is too low you should increase it adding <code>define('WP_MEMORY_LIMIT', '64M');</code> to your <code>wp-config.php</code>.
|
570 |
+
<a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-memory" target="_blank">Read more</a>.
|
571 |
+
<?php } else if ($memory < 128) { ?>
|
572 |
+
The value should be fine, it depends on how many plugins you're running and how many resource are required by your theme.
|
573 |
+
Blank pages may happen with low memory problems. Eventually increase it adding <code>define('WP_MEMORY_LIMIT', '128M');</code>
|
574 |
+
to your <code>wp-config.php</code>.
|
575 |
+
<a href="https://www.thenewsletterplugin.com/documentation/status-panel#status-memory" target="_blank">Read more</a>.
|
576 |
+
<?php } else { ?>
|
577 |
+
|
578 |
+
<?php } ?>
|
579 |
+
|
580 |
+
</td>
|
581 |
+
</tr>
|
582 |
+
*/ ?>
|
583 |
+
|
584 |
+
<?php
|
585 |
+
$ip = gethostbyname($_SERVER['HTTP_HOST']);
|
586 |
+
$name = gethostbyaddr($ip);
|
587 |
+
$res = true;
|
588 |
+
if (strpos($name, '.secureserver.net') !== false) {
|
589 |
+
//$smtp = get_option('newsletter_main_smtp');
|
590 |
+
//if (!empty($smtp['enabled']))
|
591 |
+
$res = false;
|
592 |
+
$message = 'If you\'re hosted with GoDaddy, be sure to set their SMTP (relay-hosting.secureserver.net, without username and password) to send emails
|
593 |
+
on Newsletter SMTP panel.
|
594 |
+
Remember they limits you to 250 emails per day. Open them a ticket for more details.';
|
595 |
+
}
|
596 |
+
if (strpos($name, '.aruba.it') !== false) {
|
597 |
+
$res = false;
|
598 |
+
$message = 'If you\'re hosted with Aruba consider to use an external SMTP (Sendgrid, Mailjet, Mailgun, Amazon SES, Elasticemail, Sparkpost, ...)
|
599 |
+
since their mail service is not good. If you have your personal email with them, you can try to use the SMTP of your
|
600 |
+
pesonal account. Ask the support for the SMTP parameters and configure them on Newsletter SMTP panel.';
|
601 |
+
}
|
602 |
+
?>
|
603 |
+
<tr>
|
604 |
+
<td>Your Server</td>
|
605 |
+
<td>
|
606 |
+
<?php if ($res === false) { ?>
|
607 |
+
<span class="tnp-maybe">MAYBE</span>
|
608 |
+
<?php } else { ?>
|
609 |
+
<span class="tnp-ok">OK</span>
|
610 |
+
<?php } ?>
|
611 |
+
|
612 |
+
|
613 |
+
</td>
|
614 |
+
<td>
|
615 |
+
<?php if ($res === false) { ?>
|
616 |
+
<?php echo $message ?>
|
617 |
+
<?php } else { ?>
|
618 |
+
|
619 |
+
<?php } ?>
|
620 |
+
IP: <?php echo $ip ?><br>
|
621 |
+
Name: <?php echo $name ?><br>
|
622 |
+
</td>
|
623 |
+
</tr>
|
624 |
+
|
625 |
+
<?php
|
626 |
+
wp_mkdir_p(NEWSLETTER_LOG_DIR);
|
627 |
+
$condition = is_dir(NEWSLETTER_LOG_DIR) && is_writable(NEWSLETTER_LOG_DIR) ? 1 : 0;
|
628 |
+
if ($condition) {
|
629 |
+
@file_put_contents(NEWSLETTER_LOG_DIR . '/test.txt', "");
|
630 |
+
$condition = is_file(NEWSLETTER_LOG_DIR . '/test.txt') ? 1 : 0;
|
631 |
+
if ($condition) {
|
632 |
+
@unlink(NEWSLETTER_LOG_DIR . '/test.txt');
|
633 |
+
}
|
634 |
+
}
|
635 |
+
?>
|
636 |
+
<tr>
|
637 |
+
<td>
|
638 |
+
Log folder
|
639 |
+
</td>
|
640 |
+
<td>
|
641 |
+
<?php tnp_status_print_flag($condition) ?>
|
642 |
+
</td>
|
643 |
+
<td>
|
644 |
+
The log folder is <?php echo esc_html(NEWSLETTER_LOG_DIR) ?><br>
|
645 |
+
<?php if (!$res) { ?>
|
646 |
+
Cannot create the folder or it is not writable.
|
647 |
+
<?php } ?>
|
648 |
+
</td>
|
649 |
+
</tr>
|
650 |
+
</tbody>
|
651 |
+
</table>
|
652 |
+
|
653 |
+
|
654 |
+
<h3>WordPress</h3>
|
655 |
+
|
656 |
+
<table class="widefat" id="tnp-status-table">
|
657 |
+
<thead>
|
658 |
+
<tr>
|
659 |
+
<th>Parameter</th>
|
660 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
661 |
+
<th>Action</th>
|
662 |
+
</tr>
|
663 |
+
</thead>
|
664 |
+
<tbody>
|
665 |
+
|
666 |
+
<tr>
|
667 |
+
<?php
|
668 |
+
$condition = (defined('WP_DEBUG') && WP_DEBUG) ? 2 : 1;
|
669 |
+
?>
|
670 |
+
<td>
|
671 |
+
WordPress debug mode
|
672 |
+
</td>
|
673 |
+
<td>
|
674 |
+
<?php tnp_status_print_flag($condition) ?>
|
675 |
+
</td>
|
676 |
+
<td>
|
677 |
+
<?php if (defined('WP_DEBUG') && WP_DEBUG) { ?>
|
678 |
+
WordPress is in debug mode it is not recommended on a production system. See the constant <code>WP_DEBUG</code> inside the <code>wp-config.php</code>.
|
679 |
+
<?php } else { ?>
|
680 |
+
|
681 |
+
<?php } ?>
|
682 |
+
</td>
|
683 |
+
</tr>
|
684 |
+
|
685 |
+
|
686 |
+
|
687 |
+
<tr>
|
688 |
+
<?php
|
689 |
+
$charset = get_option('blog_charset');
|
690 |
+
$condition = $charset === 'UTF-8' ? 1 : 0;
|
691 |
+
?>
|
692 |
+
<td>Blog Charset</td>
|
693 |
+
<td>
|
694 |
+
<?php tnp_status_print_flag($condition) ?>
|
695 |
+
</td>
|
696 |
+
<td>
|
697 |
+
Charset: <?php echo esc_html($charset) ?>
|
698 |
+
<br>
|
699 |
+
|
700 |
+
<?php if ($condition == 1) { ?>
|
701 |
+
|
702 |
+
<?php } else { ?>
|
703 |
+
It is recommended to use
|
704 |
+
the <code>UTF-8</code> charset but the <a href="https://codex.wordpress.org/Converting_Database_Character_Sets" target="_blank">conversion</a>
|
705 |
+
could be tricky. If you're not experiencing problem, leave things as is.
|
706 |
+
<?php } ?>
|
707 |
+
</td>
|
708 |
+
</tr>
|
709 |
+
|
710 |
+
<tr>
|
711 |
+
<?php
|
712 |
+
$condition = (strpos(home_url('/'), 'http') !== 0) ? 0 : 1;
|
713 |
+
?>
|
714 |
+
<td>Home URL</td>
|
715 |
+
<td>
|
716 |
+
<?php tnp_status_print_flag($condition) ?>
|
717 |
+
</td>
|
718 |
+
<td>
|
719 |
+
Value: <?php echo home_url('/'); ?>
|
720 |
+
<br>
|
721 |
+
<?php if ($condition == 0) { ?>
|
722 |
+
Your home URL is not absolute, emails require absolute URLs.
|
723 |
+
Probably you have a protocol agnostic plugin installed to manage both HTTPS and HTTP in your
|
724 |
+
blog.
|
725 |
+
<?php } else { ?>
|
726 |
+
|
727 |
+
<?php } ?>
|
728 |
+
</td>
|
729 |
+
</tr>
|
730 |
+
|
731 |
+
<tr>
|
732 |
+
<?php
|
733 |
+
$condition = (strpos(WP_CONTENT_URL, 'http') !== 0) ? 0 : 1;
|
734 |
+
?>
|
735 |
+
<td>WP_CONTENT_URL</td>
|
736 |
+
<td>
|
737 |
+
<?php tnp_status_print_flag($condition) ?>
|
738 |
+
</td>
|
739 |
+
<td>
|
740 |
+
Value: <?php echo esc_html(WP_CONTENT_URL); ?>
|
741 |
+
<br>
|
742 |
+
<?php if ($condition == 0) { ?>
|
743 |
+
Your content URL is not absolute, emails require absolute URLs when they have images inside.
|
744 |
+
Newsletter tries to deal with this problem but when a problem with images persists, you should try to remove
|
745 |
+
from your <code>wp-config.php</code> the <code>WP_CONTENT_URL</code> define and check again.
|
746 |
+
<?php } else { ?>
|
747 |
+
|
748 |
+
<?php } ?>
|
749 |
+
</td>
|
750 |
+
</tr>
|
751 |
+
|
752 |
+
<tr>
|
753 |
+
<?php
|
754 |
+
set_transient('newsletter_transient_test', 1, 300);
|
755 |
+
delete_transient('newsletter_transient_test');
|
756 |
+
$res = get_transient('newsletter_transient_test');
|
757 |
+
$condition = ($res !== false) ? 0 : 1;
|
758 |
+
?>
|
759 |
+
<td>WordPress transients</td>
|
760 |
+
<td>
|
761 |
+
<?php tnp_status_print_flag($condition) ?>
|
762 |
+
</td>
|
763 |
+
<td>
|
764 |
+
<?php if ($res !== false) { ?>
|
765 |
+
Transients cannot be delete. This can block the delivery engine. Usually it is due to a not well coded plugin installed.
|
766 |
+
<?php } else { ?>
|
767 |
+
<?php } ?>
|
768 |
+
</td>
|
769 |
+
</tr>
|
770 |
+
</tbody>
|
771 |
+
</table>
|
772 |
+
|
773 |
+
|
774 |
+
|
775 |
+
<h3>PHP</h3>
|
776 |
+
<table class="widefat" id="tnp-status-table">
|
777 |
+
<thead>
|
778 |
+
<tr>
|
779 |
+
<th>Parameter</th>
|
780 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
781 |
+
<th>Action</th>
|
782 |
+
</tr>
|
783 |
+
</thead>
|
784 |
+
<tbody>
|
785 |
+
<tr>
|
786 |
+
<td>PHP version</td>
|
787 |
+
<td>
|
788 |
+
<?php if (version_compare(phpversion(), '5.6', '<')) { ?>
|
789 |
+
<span class="tnp-ko">KO</span>
|
790 |
+
<?php } else { ?>
|
791 |
+
<span class="tnp-ok">OK</span>
|
792 |
+
<?php } ?>
|
793 |
+
|
794 |
+
</td>
|
795 |
+
<td>
|
796 |
+
Your PHP version is <?php echo phpversion() ?><br>
|
797 |
+
<?php if (version_compare(phpversion(), '5.3', '<')) { ?>
|
798 |
+
Newsletter plugin works correctly with PHP version 5.6 or greater. Ask your provider to upgrade your PHP. Your version is
|
799 |
+
unsupported even by the PHP community.
|
800 |
+
<?php } ?>
|
801 |
+
</td>
|
802 |
+
|
803 |
+
</tr>
|
804 |
+
|
805 |
+
<tr>
|
806 |
+
<?php
|
807 |
+
$value = (int) ini_get('max_execution_time');
|
808 |
+
$res = true;
|
809 |
+
$condition = 1;
|
810 |
+
if ($value != 0 && $value < NEWSLETTER_CRON_INTERVAL) {
|
811 |
+
$res = set_time_limit(NEWSLETTER_CRON_INTERVAL);
|
812 |
+
if ($res)
|
813 |
+
$condition = 1;
|
814 |
+
else
|
815 |
+
$condition = 0;
|
816 |
+
}
|
817 |
+
?>
|
818 |
+
<td>PHP execution time limit</td>
|
819 |
+
<td>
|
820 |
+
<?php tnp_status_print_flag($condition) ?>
|
821 |
+
</td>
|
822 |
+
<td>
|
823 |
+
<?php if (!$res) { ?>
|
824 |
+
Your PHP execution time limit is <?php echo $value ?> seconds. It cannot be changed and it is too lower to grant the maximum delivery rate of Newsletter.
|
825 |
+
<?php } else { ?>
|
826 |
+
Your PHP execution time limit is <?php echo $value ?> seconds and can be eventually changed by Newsletter.<br>
|
827 |
+
<?php } ?>
|
828 |
+
|
829 |
+
</td>
|
830 |
+
|
831 |
+
</tr>
|
832 |
+
|
833 |
+
|
834 |
+
<tr>
|
835 |
+
<?php
|
836 |
+
$condition = function_exists('curl_version');
|
837 |
+
?>
|
838 |
+
<td>Curl version</td>
|
839 |
+
<td>
|
840 |
+
<?php if (!$condition) { ?>
|
841 |
+
<span class="tnp-ko">KO</span>
|
842 |
+
<?php } else { ?>
|
843 |
+
<span class="tnp-ok">OK</span>
|
844 |
+
<?php } ?>
|
845 |
+
|
846 |
+
</td>
|
847 |
+
<td>
|
848 |
+
<?php
|
849 |
+
if (!$condition) {
|
850 |
+
echo 'cUrl is not available, ask the provider to install it and activate the PHP cUrl library';
|
851 |
+
} else {
|
852 |
+
$version = curl_version();
|
853 |
+
echo 'Version: ' . $version['version'] . '<br>';
|
854 |
+
echo 'SSL Version: ' . $version['ssl_version'] . '<br>';
|
855 |
+
}
|
856 |
+
?>
|
857 |
+
</td>
|
858 |
+
|
859 |
+
</tr>
|
860 |
+
<?php if (ini_get('opcache.validate_timestamps') === '0') { ?>
|
861 |
+
<tr>
|
862 |
+
<td>
|
863 |
+
Opcache
|
864 |
+
</td>
|
865 |
+
|
866 |
+
<td>
|
867 |
+
<span class="tnp-ko">KO</span>
|
868 |
+
</td>
|
869 |
+
|
870 |
+
<td>
|
871 |
+
You have the PHP opcache active with file validation disable so every blog plugins update needs a webserver restart!
|
872 |
+
</td>
|
873 |
+
</tr>
|
874 |
+
<?php } ?>
|
875 |
+
</tbody>
|
876 |
+
</table>
|
877 |
+
|
878 |
+
<h3>Database</h3>
|
879 |
+
<table class="widefat" id="tnp-status-table">
|
880 |
+
<thead>
|
881 |
+
<tr>
|
882 |
+
<th>Parameter</th>
|
883 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
884 |
+
<th>Action</th>
|
885 |
+
</tr>
|
886 |
+
</thead>
|
887 |
+
<tbody>
|
888 |
+
<tr>
|
889 |
+
<td>Database Charset</td>
|
890 |
+
<td>
|
891 |
+
<?php if ($wpdb->charset != 'utf8mb4') { ?>
|
892 |
+
<span class="tnp-ko">KO</span>
|
893 |
+
<?php } else { ?>
|
894 |
+
<span class="tnp-ok">OK</span>
|
895 |
+
<?php } ?>
|
896 |
+
|
897 |
+
</td>
|
898 |
+
<td>
|
899 |
+
Charset: <?php echo $wpdb->charset; ?>
|
900 |
+
<br>
|
901 |
+
<?php if ($wpdb->charset != 'utf8mb4') { ?>
|
902 |
+
The recommended charset for your database is <code>utf8mb4</code> to avoid possible saving errors when you use emoji.
|
903 |
+
Read the WordPress Codex <a href="https://codex.wordpress.org/Converting_Database_Character_Sets" target="_blank">conversion
|
904 |
+
instructions</a> (skilled technicia required).
|
905 |
+
<?php } else { ?>
|
906 |
+
If you experience newsletter saving database error
|
907 |
+
<?php $controls->button('conversion', 'Try tables upgrade') ?>
|
908 |
+
<?php } ?>
|
909 |
+
</td>
|
910 |
+
</tr>
|
911 |
+
|
912 |
+
<tr>
|
913 |
+
<td>get_table_charset()</td>
|
914 |
+
<td>
|
915 |
+
|
916 |
+
</td>
|
917 |
+
<td>
|
918 |
+
<?php echo esc_html(NEWSLETTER_USERS_TABLE), ': ', esc_html($tnp_wpdb->get_table_charset(NEWSLETTER_USERS_TABLE)) ?>
|
919 |
+
</td>
|
920 |
+
</tr>
|
921 |
+
|
922 |
+
|
923 |
+
|
924 |
+
|
925 |
+
<?php
|
926 |
+
$wait_timeout = $wpdb->get_var("select @@wait_timeout");
|
927 |
+
$condition = ($wait_timeout < 30) ? 0 : 1;
|
928 |
+
?>
|
929 |
+
<tr>
|
930 |
+
<td>Database wait timeout</td>
|
931 |
+
<td>
|
932 |
+
<?php tnp_status_print_flag($condition) ?>
|
933 |
+
</td>
|
934 |
+
<td>
|
935 |
+
Your database wait timeout is <?php echo $wait_timeout; ?> seconds<br>
|
936 |
+
<?php if ($wait_timeout < 30) { ?>
|
937 |
+
That value is low and could produce database connection errors while sending emails or during long import
|
938 |
+
sessions. Ask the provider to raise it at least to 60 seconds.
|
939 |
+
<?php } ?>
|
940 |
+
</td>
|
941 |
+
</tr>
|
942 |
+
|
943 |
+
<?php
|
944 |
+
$res = $wpdb->query("drop table if exists {$wpdb->prefix}newsletter_test");
|
945 |
+
$res = $wpdb->query("create table if not exists {$wpdb->prefix}newsletter_test (id int(20))");
|
946 |
+
$condition = $res === false ? 0 : 1;
|
947 |
+
?>
|
948 |
+
<tr>
|
949 |
+
<td>Database table creation</td>
|
950 |
+
<td>
|
951 |
+
<?php tnp_status_print_flag($condition) ?>
|
952 |
+
</td>
|
953 |
+
<td>
|
954 |
+
<?php if ($res === false) { ?>
|
955 |
+
Check the privileges of the user you use to connect to the database, it seems it cannot create tables.<br>
|
956 |
+
(<?php echo esc_html($wpdb->last_error) ?>)
|
957 |
+
<?php } else { ?>
|
958 |
+
<?php } ?>
|
959 |
+
</td>
|
960 |
+
</tr>
|
961 |
+
|
962 |
+
<?php
|
963 |
+
$res = $wpdb->query("alter table {$wpdb->prefix}newsletter_test add column id1 int(20)");
|
964 |
+
$condition = $res === false ? 0 : 1;
|
965 |
+
?>
|
966 |
+
<tr>
|
967 |
+
<td>Database table change</td>
|
968 |
+
<td>
|
969 |
+
<?php tnp_status_print_flag($condition) ?>
|
970 |
+
</td>
|
971 |
+
<td>
|
972 |
+
<?php if ($res === false) { ?>
|
973 |
+
Check the privileges of the user you use to connect to the database, it seems it cannot change the tables. It's require to update the
|
974 |
+
plugin.<br>
|
975 |
+
(<?php echo esc_html($wpdb->last_error) ?>)
|
976 |
+
<?php } else { ?>
|
977 |
+
<?php } ?>
|
978 |
+
</td>
|
979 |
+
</tr>
|
980 |
+
|
981 |
+
<?php
|
982 |
+
// Clean up
|
983 |
+
$res = $wpdb->query("drop table if exists {$wpdb->prefix}newsletter_test");
|
984 |
+
?>
|
985 |
+
|
986 |
+
<?php if (!get_option('newsletter_stats_email_column_upgraded', false)) { ?>
|
987 |
+
<?php
|
988 |
+
$data_type = $wpdb->get_var(
|
989 |
+
$wpdb->prepare('SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s',
|
990 |
+
DB_NAME, NEWSLETTER_STATS_TABLE, 'email_id'));
|
991 |
+
$to_upgrade = strtoupper($data_type) == 'INT' ? false : true;
|
992 |
+
?>
|
993 |
+
<?php if ($to_upgrade) { ?>
|
994 |
+
<tr>
|
995 |
+
<td>Database stats table upgrade</td>
|
996 |
+
<td><?php tnp_status_print_flag(0) ?></td>
|
997 |
+
<td><?php $controls->button('stats_email_column_upgrade', 'Stats table upgrade') ?></td>
|
998 |
+
</tr>
|
999 |
+
<?php } ?>
|
1000 |
+
<?php } ?>
|
1001 |
+
|
1002 |
+
</tbody>
|
1003 |
+
</table>
|
1004 |
+
|
1005 |
+
<h3>3rd party plugins</h3>
|
1006 |
+
<table class="widefat" id="tnp-status-table">
|
1007 |
+
<thead>
|
1008 |
+
<tr>
|
1009 |
+
<th>Plugin</th>
|
1010 |
+
<th><?php _e('Status', 'newsletter') ?></th>
|
1011 |
+
<th>Action</th>
|
1012 |
+
</tr>
|
1013 |
+
</thead>
|
1014 |
+
<tbody>
|
1015 |
+
<?php if (is_plugin_active('plugin-load-filter/plugin-load-filter.php')) { ?>
|
1016 |
+
<tr>
|
1017 |
+
<td><a href="https://wordpress.org/plugins/plugin-load-filter/" target="_blank">Plugin load filter</a></td>
|
1018 |
+
<td>
|
1019 |
+
<span class="tnp-maybe">MAY BE</span>
|
1020 |
+
</td>
|
1021 |
+
<td>
|
1022 |
+
Be sure Newsletter is set as active in EVERY context.
|
1023 |
+
</td>
|
1024 |
+
</tr>
|
1025 |
+
<?php } ?>
|
1026 |
+
</tbody>
|
1027 |
+
</table>
|
1028 |
+
|
1029 |
+
<h3>General parameters</h3>
|
1030 |
+
<table class="widefat" id="tnp-parameters-table">
|
1031 |
+
<thead>
|
1032 |
+
<tr>
|
1033 |
+
<th>Parameter</th>
|
1034 |
+
<th>Value</th>
|
1035 |
+
</tr>
|
1036 |
+
</thead>
|
1037 |
+
<tbody>
|
1038 |
+
|
1039 |
+
<tr>
|
1040 |
+
<td>Newsletter version</td>
|
1041 |
+
<td>
|
1042 |
+
<?php echo NEWSLETTER_VERSION ?>
|
1043 |
+
</td>
|
1044 |
+
</tr>
|
1045 |
+
|
1046 |
+
<tr>
|
1047 |
+
<td>NEWSLETTER_MAX_EXECUTION_TIME</td>
|
1048 |
+
<td>
|
1049 |
+
<?php
|
1050 |
+
if (defined('NEWSLETTER_MAX_EXECUTION_TIME')) {
|
1051 |
+
echo NEWSLETTER_MAX_EXECUTION_TIME . ' (seconds)';
|
1052 |
+
} else {
|
1053 |
+
echo 'Not set';
|
1054 |
+
}
|
1055 |
+
?>
|
1056 |
+
</td>
|
1057 |
+
</tr>
|
1058 |
+
|
1059 |
+
|
1060 |
+
|
1061 |
+
|
1062 |
+
<?php /*
|
1063 |
+
<tr>
|
1064 |
+
<td>WordPress plugin url</td>
|
1065 |
+
<td>
|
1066 |
+
<?php echo WP_PLUGIN_URL; ?>
|
1067 |
+
<br>
|
1068 |
+
Filters:
|
1069 |
+
|
1070 |
+
<?php
|
1071 |
+
if (isset($wp_filter))
|
1072 |
+
$filters = $wp_filter['plugins_url'];
|
1073 |
+
if (!isset($filters) || !is_array($filters))
|
1074 |
+
echo 'no filters attached to "plugin_urls"';
|
1075 |
+
else {
|
1076 |
+
echo '<ul>';
|
1077 |
+
foreach ($filters as &$filter) {
|
1078 |
+
foreach ($filter as &$entry) {
|
1079 |
+
echo '<li>';
|
1080 |
+
if (is_array($entry['function']))
|
1081 |
+
echo esc_html(get_class($entry['function'][0]) . '->' . $entry['function'][1]);
|
1082 |
+
else
|
1083 |
+
echo esc_html($entry['function']);
|
1084 |
+
echo '</li>';
|
1085 |
+
}
|
1086 |
+
}
|
1087 |
+
echo '</ul>';
|
1088 |
+
}
|
1089 |
+
?>
|
1090 |
+
<p class="description">
|
1091 |
+
This value should contains the full URL to your plugin folder. If there are filters
|
1092 |
+
attached, the value can be different from the original generated by WordPress and sometime worng.
|
1093 |
+
</p>
|
1094 |
+
</td>
|
1095 |
+
</tr>
|
1096 |
+
*/ ?>
|
1097 |
+
|
1098 |
+
<tr>
|
1099 |
+
<td>Absolute path</td>
|
1100 |
+
<td>
|
1101 |
+
<?php echo esc_html(ABSPATH); ?>
|
1102 |
+
</td>
|
1103 |
+
</tr>
|
1104 |
+
<tr>
|
1105 |
+
<td>Tables Prefix</td>
|
1106 |
+
<td>
|
1107 |
+
<?php echo $wpdb->prefix; ?>
|
1108 |
+
</td>
|
1109 |
+
</tr>
|
1110 |
+
</tbody>
|
1111 |
+
</table>
|
1112 |
+
|
1113 |
+
|
1114 |
+
<?php if (isset($_GET['debug'])) { ?>
|
1115 |
+
|
1116 |
+
<h3>Database Tables</h3>
|
1117 |
+
<h4><?php echo $wpdb->prefix ?>newsletter</h4>
|
1118 |
+
<?php
|
1119 |
+
$rs = $wpdb->get_results("describe {$wpdb->prefix}newsletter");
|
1120 |
+
?>
|
1121 |
+
<table class="tnp-db-table">
|
1122 |
+
<thead>
|
1123 |
+
<tr>
|
1124 |
+
<th>Field</th>
|
1125 |
+
<th>Type</th>
|
1126 |
+
<th>Null</th>
|
1127 |
+
<th>Key</th>
|
1128 |
+
<th>Default</th>
|
1129 |
+
<th>Extra</th>
|
1130 |
+
</tr>
|
1131 |
+
</thead>
|
1132 |
+
<tbody>
|
1133 |
+
<?php foreach ($rs as $r) { ?>
|
1134 |
+
<tr>
|
1135 |
+
<td><?php echo esc_html($r->Field) ?></td>
|
1136 |
+
<td><?php echo esc_html($r->Type) ?></td>
|
1137 |
+
<td><?php echo esc_html($r->Null) ?></td>
|
1138 |
+
<td><?php echo esc_html($r->Key) ?></td>
|
1139 |
+
<td><?php echo esc_html($r->Default) ?></td>
|
1140 |
+
<td><?php echo esc_html($r->Extra) ?></td>
|
1141 |
+
</tr>
|
1142 |
+
<?php } ?>
|
1143 |
+
</tbody>
|
1144 |
+
</table>
|
1145 |
+
|
1146 |
+
<h4><?php echo $wpdb->prefix ?>newsletter_emails</h4>
|
1147 |
+
<?php
|
1148 |
+
$rs = $wpdb->get_results("show full columns from {$wpdb->prefix}newsletter_emails");
|
1149 |
+
?>
|
1150 |
+
<table class="tnp-db-table">
|
1151 |
+
<thead>
|
1152 |
+
<tr>
|
1153 |
+
<th>Field</th>
|
1154 |
+
<th>Type</th>
|
1155 |
+
<th>Collation</th>
|
1156 |
+
<th>Null</th>
|
1157 |
+
<th>Key</th>
|
1158 |
+
<th>Default</th>
|
1159 |
+
<th>Extra</th>
|
1160 |
+
</tr>
|
1161 |
+
</thead>
|
1162 |
+
<tbody>
|
1163 |
+
<?php foreach ($rs as $r) { ?>
|
1164 |
+
<tr>
|
1165 |
+
<td><?php echo esc_html($r->Field) ?></td>
|
1166 |
+
<td><?php echo esc_html($r->Type) ?></td>
|
1167 |
+
<td><?php echo esc_html($r->Collation) ?></td>
|
1168 |
+
<td><?php echo esc_html($r->Null) ?></td>
|
1169 |
+
<td><?php echo esc_html($r->Key) ?></td>
|
1170 |
+
<td><?php echo esc_html($r->Default) ?></td>
|
1171 |
+
<td><?php echo esc_html($r->Extra) ?></td>
|
1172 |
+
</tr>
|
1173 |
+
<?php } ?>
|
1174 |
+
</tbody>
|
1175 |
+
</table>
|
1176 |
+
|
1177 |
+
|
1178 |
+
<h3>Extensions</h3>
|
1179 |
+
<pre style="font-size: 11px; font-family: monospace; background-color: #efefef; color: #444"><?php echo esc_html(print_r(get_option('newsletter_extension_versions'), true)); ?></pre>
|
1180 |
+
|
1181 |
+
<h3>Update plugins data</h3>
|
1182 |
+
<pre style="font-size: 11px; font-family: monospace; background-color: #efefef; color: #444"><?php echo esc_html(print_r(get_site_transient('update_plugins'), true)); ?></pre>
|
1183 |
+
|
1184 |
+
<?php } ?>
|
1185 |
+
</div>
|
1186 |
+
|
1187 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
1188 |
+
|
1189 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main/welcome.php
CHANGED
@@ -1,256 +1,255 @@
|
|
1 |
-
<?php
|
2 |
-
defined('ABSPATH') || exit;
|
3 |
-
|
4 |
-
// Very very naif
|
5 |
-
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_GET['action']) && $_GET['action'] == 'save') {
|
6 |
-
|
7 |
-
// Sender name
|
8 |
-
$module = Newsletter::instance();
|
9 |
-
$options = $module->get_options();
|
10 |
-
$options['sender_name'] = trim(stripslashes($_POST['sender_name']));
|
11 |
-
$options['sender_email'] = trim(strtolower(stripslashes($_POST['sender_email'])));
|
12 |
-
$module->save_options($options);
|
13 |
-
|
14 |
-
// Profile setting
|
15 |
-
$module = NewsletterSubscription::instance();
|
16 |
-
$options = $module->get_options('profile');
|
17 |
-
$options['privacy_status'] = isset($_POST['field_privacy']) ? 1 : 0;
|
18 |
-
$options['name_status'] = isset($_POST['field_name']) ? 2 : 0;
|
19 |
-
$options['subscribe'] = trim(stripslashes($_POST['field_subscribe']));
|
20 |
-
if (empty($options['subscribe']))
|
21 |
-
$options['subscribe'] = 'Subscribe';
|
22 |
-
$module->save_options($options, 'profile');
|
23 |
-
die();
|
24 |
-
}
|
25 |
-
|
26 |
-
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_GET['action']) && $_GET['action'] == 'test') {
|
27 |
-
$module = Newsletter::instance();
|
28 |
-
$email = $_POST['test_email'];
|
29 |
-
$status_options = $module->get_options('status');
|
30 |
-
|
31 |
-
if (!NewsletterModule::is_email($email)) {
|
32 |
-
echo _e('Please check the email address, it seems wrong.', 'newsletter');
|
33 |
-
die();
|
34 |
-
}
|
35 |
-
// Newsletter mail
|
36 |
-
$text = array();
|
37 |
-
$text['html'] = '<p>This is an <b>HTML</b> test email sent using the sender data set on Newsletter main setting. <a href="https://www.thenewsletterplugin.com">This is a link to an external site</a>.</p>';
|
38 |
-
$text['text'] = 'This is a textual test email part sent using the sender data set on Newsletter main setting.';
|
39 |
-
$r = $module->mail($email, 'Newsletter test email at ' . date(DATE_ISO8601), $text);
|
40 |
-
|
41 |
-
if ($r) {
|
42 |
-
$status_options['mail'] = 1;
|
43 |
-
$module->save_options($status_options, 'status');
|
44 |
-
echo _e('Check your mailbox for a test message. Check the spam folder as well.', 'newsletter');
|
45 |
-
die();
|
46 |
-
} else {
|
47 |
-
$status_options['mail'] = 0;
|
48 |
-
$status_options['mail_error'] = $module->mail_last_error;
|
49 |
-
$module->save_options($status_options, 'status');
|
50 |
-
echo _e('There was an error. Complete the setup and then use the status panel to check it out.', 'newsletter');
|
51 |
-
die();
|
52 |
-
}
|
53 |
-
die();
|
54 |
-
}
|
55 |
-
|
56 |
-
$profile_options = NewsletterSubscription::instance()->get_options('profile');
|
57 |
-
$main_options = Newsletter::instance()->get_options();
|
58 |
-
$subscription_options = NewsletterSubscription::instance()->get_options();
|
59 |
-
|
60 |
-
$logger = Newsletter::instance()->logger;
|
61 |
-
|
62 |
-
$page_exists = get_option('newsletter_page');
|
63 |
-
|
64 |
-
if (empty($page_exists)) {
|
65 |
-
$module = Newsletter::instance();
|
66 |
-
$logger->info('Dedicated page creation');
|
67 |
-
// Page creation
|
68 |
-
$page = array();
|
69 |
-
$page['post_title'] = 'Newsletter';
|
70 |
-
$page['post_content'] = '[newsletter]';
|
71 |
-
$page['post_status'] = 'publish';
|
72 |
-
$page['post_type'] = 'page';
|
73 |
-
$page['comment_status'] = 'closed';
|
74 |
-
$page['ping_status'] = 'closed';
|
75 |
-
$page['post_category'] = array(1);
|
76 |
-
|
77 |
-
// Insert the post into the database
|
78 |
-
$page_id = wp_insert_post($page);
|
79 |
-
|
80 |
-
$main_options['page'] = $page_id;
|
81 |
-
Newsletter::instance()->save_options($main_options);
|
82 |
-
$main_options = Newsletter::instance()->get_options();
|
83 |
-
$page_exists = true;
|
84 |
-
update_option('newsletter_page', $page_id, false);
|
85 |
-
|
86 |
-
// Test subscriber creation
|
87 |
-
$users = $module->get_test_users();
|
88 |
-
if (!$users) {
|
89 |
-
global $current_user;
|
90 |
-
$user = array();
|
91 |
-
$user['email'] = $current_user->user_email;
|
92 |
-
$user['name'] = $current_user->first_name;
|
93 |
-
$user['surname'] = $current_user->last_name;
|
94 |
-
$user['test'] = 1;
|
95 |
-
$user['status'] = TNP_User::STATUS_CONFIRMED;
|
96 |
-
$module->save_user($user);
|
97 |
-
}
|
98 |
-
} else {
|
99 |
-
$logger->info('Dedicated page already exists');
|
100 |
-
}
|
101 |
-
?>
|
102 |
-
<style>
|
103 |
-
<?php include
|
104 |
-
</style>
|
105 |
-
<script src="<?php echo plugins_url('newsletter') ?>/main/js/
|
106 |
-
<script
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
form.
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
<
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
<
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
<
|
139 |
-
<
|
140 |
-
<input type="text" placeholder="<?php esc_attr_e('Sender
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
<
|
148 |
-
<
|
149 |
-
|
150 |
-
|
151 |
-
<
|
152 |
-
|
153 |
-
<
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
<
|
159 |
-
|
160 |
-
<
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
<
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
<
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
<
|
181 |
-
<
|
182 |
-
<
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
<
|
193 |
-
<
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
<
|
205 |
-
<
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
<
|
211 |
-
<
|
212 |
-
<
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
<
|
217 |
-
<a href="" target="_blank"><i class="fab fa-
|
218 |
-
<a href="" target="_blank"><i class="fab fa-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
<
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
<a class="tnp-welcome-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
<
|
240 |
-
<
|
241 |
-
<
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
<input type="
|
250 |
-
<input type="hidden" value="
|
251 |
-
<input type="hidden" value="
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
</div>
|
1 |
+
<?php
|
2 |
+
defined('ABSPATH') || exit;
|
3 |
+
|
4 |
+
// Very very naif
|
5 |
+
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_GET['action']) && $_GET['action'] == 'save') {
|
6 |
+
|
7 |
+
// Sender name
|
8 |
+
$module = Newsletter::instance();
|
9 |
+
$options = $module->get_options();
|
10 |
+
$options['sender_name'] = trim(stripslashes($_POST['sender_name']));
|
11 |
+
$options['sender_email'] = trim(strtolower(stripslashes($_POST['sender_email'])));
|
12 |
+
$module->save_options($options);
|
13 |
+
|
14 |
+
// Profile setting
|
15 |
+
$module = NewsletterSubscription::instance();
|
16 |
+
$options = $module->get_options('profile');
|
17 |
+
$options['privacy_status'] = isset($_POST['field_privacy']) ? 1 : 0;
|
18 |
+
$options['name_status'] = isset($_POST['field_name']) ? 2 : 0;
|
19 |
+
$options['subscribe'] = trim(stripslashes($_POST['field_subscribe']));
|
20 |
+
if (empty($options['subscribe']))
|
21 |
+
$options['subscribe'] = 'Subscribe';
|
22 |
+
$module->save_options($options, 'profile');
|
23 |
+
die();
|
24 |
+
}
|
25 |
+
|
26 |
+
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_GET['action']) && $_GET['action'] == 'test') {
|
27 |
+
$module = Newsletter::instance();
|
28 |
+
$email = $_POST['test_email'];
|
29 |
+
$status_options = $module->get_options('status');
|
30 |
+
|
31 |
+
if (!NewsletterModule::is_email($email)) {
|
32 |
+
echo _e('Please check the email address, it seems wrong.', 'newsletter');
|
33 |
+
die();
|
34 |
+
}
|
35 |
+
// Newsletter mail
|
36 |
+
$text = array();
|
37 |
+
$text['html'] = '<p>This is an <b>HTML</b> test email sent using the sender data set on Newsletter main setting. <a href="https://www.thenewsletterplugin.com">This is a link to an external site</a>.</p>';
|
38 |
+
$text['text'] = 'This is a textual test email part sent using the sender data set on Newsletter main setting.';
|
39 |
+
$r = $module->mail($email, 'Newsletter test email at ' . date(DATE_ISO8601), $text);
|
40 |
+
|
41 |
+
if ($r) {
|
42 |
+
$status_options['mail'] = 1;
|
43 |
+
$module->save_options($status_options, 'status');
|
44 |
+
echo _e('Check your mailbox for a test message. Check the spam folder as well.', 'newsletter');
|
45 |
+
die();
|
46 |
+
} else {
|
47 |
+
$status_options['mail'] = 0;
|
48 |
+
$status_options['mail_error'] = $module->mail_last_error;
|
49 |
+
$module->save_options($status_options, 'status');
|
50 |
+
echo _e('There was an error. Complete the setup and then use the status panel to check it out.', 'newsletter');
|
51 |
+
die();
|
52 |
+
}
|
53 |
+
die();
|
54 |
+
}
|
55 |
+
|
56 |
+
$profile_options = NewsletterSubscription::instance()->get_options('profile');
|
57 |
+
$main_options = Newsletter::instance()->get_options();
|
58 |
+
$subscription_options = NewsletterSubscription::instance()->get_options();
|
59 |
+
|
60 |
+
$logger = Newsletter::instance()->logger;
|
61 |
+
|
62 |
+
$page_exists = get_option('newsletter_page');
|
63 |
+
|
64 |
+
if (empty($page_exists)) {
|
65 |
+
$module = Newsletter::instance();
|
66 |
+
$logger->info('Dedicated page creation');
|
67 |
+
// Page creation
|
68 |
+
$page = array();
|
69 |
+
$page['post_title'] = 'Newsletter';
|
70 |
+
$page['post_content'] = '[newsletter]';
|
71 |
+
$page['post_status'] = 'publish';
|
72 |
+
$page['post_type'] = 'page';
|
73 |
+
$page['comment_status'] = 'closed';
|
74 |
+
$page['ping_status'] = 'closed';
|
75 |
+
$page['post_category'] = array(1);
|
76 |
+
|
77 |
+
// Insert the post into the database
|
78 |
+
$page_id = wp_insert_post($page);
|
79 |
+
|
80 |
+
$main_options['page'] = $page_id;
|
81 |
+
Newsletter::instance()->save_options($main_options);
|
82 |
+
$main_options = Newsletter::instance()->get_options();
|
83 |
+
$page_exists = true;
|
84 |
+
update_option('newsletter_page', $page_id, false);
|
85 |
+
|
86 |
+
// Test subscriber creation
|
87 |
+
$users = $module->get_test_users();
|
88 |
+
if (!$users) {
|
89 |
+
global $current_user;
|
90 |
+
$user = array();
|
91 |
+
$user['email'] = $current_user->user_email;
|
92 |
+
$user['name'] = $current_user->first_name;
|
93 |
+
$user['surname'] = $current_user->last_name;
|
94 |
+
$user['test'] = 1;
|
95 |
+
$user['status'] = TNP_User::STATUS_CONFIRMED;
|
96 |
+
$module->save_user($user);
|
97 |
+
}
|
98 |
+
} else {
|
99 |
+
$logger->info('Dedicated page already exists');
|
100 |
+
}
|
101 |
+
?>
|
102 |
+
<style>
|
103 |
+
<?php include __DIR__ . '/css/welcome.css' ?>
|
104 |
+
</style>
|
105 |
+
<script src="<?php echo plugins_url('newsletter') ?>/main/js/welcome.js"></script>
|
106 |
+
<script>
|
107 |
+
// Email test
|
108 |
+
function tnp_welcome_test() {
|
109 |
+
jQuery.post("?page=newsletter_main_welcome&noheader=1&action=test",
|
110 |
+
jQuery("#tnp-welcome").serialize(),
|
111 |
+
function (response) {
|
112 |
+
alert(response);
|
113 |
+
});
|
114 |
+
}
|
115 |
+
|
116 |
+
function tnp_welcome_subscribe() {
|
117 |
+
var form = document.getElementById("tnp-subscription");
|
118 |
+
form.elements["ne"].value = document.getElementById("tnp-ne").value;
|
119 |
+
form.submit();
|
120 |
+
alert('Thank you!');
|
121 |
+
}
|
122 |
+
</script>
|
123 |
+
<div class="wrap" id="tnp-wrap">
|
124 |
+
<form id="tnp-welcome">
|
125 |
+
<section class="cd-slider-wrapper">
|
126 |
+
<ul class="cd-slider">
|
127 |
+
<li class="tnp-first-slide visible">
|
128 |
+
<div>
|
129 |
+
<img class="tnp-logo-big" src="<?php echo plugins_url('newsletter') ?>/admin/images/logo-white.png">
|
130 |
+
<p><?php _e('Welcome to The Newsletter Plugin and thank your for choosing the best mail management system for Wordpress!', 'newsletter'); ?><br><br>
|
131 |
+
<?php _e('In this short tutorial we will guide you through some of the basic settings to get the most out of our plugin. ', 'newsletter'); ?></p>
|
132 |
+
</div>
|
133 |
+
</li>
|
134 |
+
|
135 |
+
<li data-update="tnp_slider_sender">
|
136 |
+
<div>
|
137 |
+
<h2><?php _e('Sender', 'newsletter'); ?></h2>
|
138 |
+
<p><?php _e('Choose which name and email address you\'d like to appear as the sender of your newsletters.', 'newsletter'); ?></p>
|
139 |
+
<input type="text" placeholder="<?php esc_attr_e('Sender name', 'newsletter') ?>" value="<?php echo esc_attr($main_options['sender_name']) ?>" name="sender_name">
|
140 |
+
<input type="text" placeholder="<?php esc_attr_e('Sender email', 'newsletter') ?>" value="<?php echo esc_attr($main_options['sender_email']) ?>" name="sender_email">
|
141 |
+
</div>
|
142 |
+
</li>
|
143 |
+
|
144 |
+
<li>
|
145 |
+
<div>
|
146 |
+
<h2><?php _e('Subscription Forms', 'newsletter'); ?></h2>
|
147 |
+
<p><?php _e('Choose what to ask to your subscribers in your forms.', 'newsletter'); ?></p>
|
148 |
+
<div class="row tnp-row-padded">
|
149 |
+
<div class="tnp-col-3-boxed">
|
150 |
+
<p><?php _e('Ask for their name', 'newsletter'); ?></p>
|
151 |
+
<label class="switch">
|
152 |
+
<input type="checkbox" name="field_name" <?php echo $profile_options['name_status'] > 0 ? 'checked' : '' ?>>
|
153 |
+
<span class="slider round"></span>
|
154 |
+
</label>
|
155 |
+
</div>
|
156 |
+
<div class="tnp-col-3-boxed">
|
157 |
+
<p><?php _e('Add a privacy checkbox', 'newsletter'); ?></p>
|
158 |
+
<label class="switch">
|
159 |
+
<input type="checkbox" name="field_privacy" <?php echo $profile_options['privacy_status'] > 0 ? 'checked' : '' ?>>
|
160 |
+
<span class="slider round"></span>
|
161 |
+
</label>
|
162 |
+
</div>
|
163 |
+
<div class="tnp-col-3-boxed">
|
164 |
+
<p><?php _e('Subscribe button label', 'newsletter'); ?></p>
|
165 |
+
<input type="text" value="<?php echo esc_attr($profile_options['subscribe']) ?>" name="field_subscribe">
|
166 |
+
</div>
|
167 |
+
</div>
|
168 |
+
|
169 |
+
</li>
|
170 |
+
|
171 |
+
<li>
|
172 |
+
<div>
|
173 |
+
<h2><?php _e('Subscription and Edit<br>page creation', 'newsletter'); ?></h2>
|
174 |
+
<p><?php _e('We\'ve just created the page where your visitors will subscribe and where they will edit their preferences.', 'newsletter'); ?></p>
|
175 |
+
</div>
|
176 |
+
</li>
|
177 |
+
<li>
|
178 |
+
<div>
|
179 |
+
<h2><?php _e('Time for some tests!', 'newsletter'); ?></h2>
|
180 |
+
<p><?php _e('Check if your website can send emails correctly.', 'newsletter'); ?></p>
|
181 |
+
<input type="email" value="<?php echo esc_attr(get_option('admin_email')) ?>" name="test_email" placeholder="<?php _e('Email address', 'newsletter'); ?>">
|
182 |
+
<div>
|
183 |
+
<a href="#" class="tnp-welcome-confirm-button" onclick="tnp_welcome_test(); return false;"><?php _e('Send a test message', 'newsletter'); ?></a>
|
184 |
+
</div>
|
185 |
+
</div>
|
186 |
+
</li>
|
187 |
+
|
188 |
+
|
189 |
+
<li>
|
190 |
+
<div>
|
191 |
+
<h2><?php _e('Add Newsletter widget to sidebar', 'newsletter'); ?></h2>
|
192 |
+
<p><?php _e('If you use sidebars in your blog, it may be a good idea to add a subscription form there. Remember to come back here when you\'re done', 'newsletter'); ?> ;)</p>
|
193 |
+
<div>
|
194 |
+
<a href="<?php echo admin_url('widgets.php') ?>" class="tnp-welcome-confirm-button" target="_blank"><?php _e('Take me to my widget settings (opens in a new window)', 'newsletter'); ?></a>
|
195 |
+
</div>
|
196 |
+
</div>
|
197 |
+
</li>
|
198 |
+
|
199 |
+
|
200 |
+
|
201 |
+
<li class="tnp-last-slide">
|
202 |
+
<div>
|
203 |
+
<svg style="margin-bottom: 25px;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" xml:space="preserve" width="64" height="64"><g class="nc-icon-wrapper"><path fill="#FFD764" d="M24,47C11.31738,47,1,36.68213,1,24S11.31738,1,24,1s23,10.31787,23,23S36.68262,47,24,47z"></path> <path fill="#444444" d="M17,19c-0.55273,0-1-0.44775-1-1c0-1.10303-0.89746-2-2-2s-2,0.89697-2,2c0,0.55225-0.44727,1-1,1 s-1-0.44775-1-1c0-2.20557,1.79395-4,4-4s4,1.79443,4,4C18,18.55225,17.55273,19,17,19z"></path> <path fill="#444444" d="M37,19c-0.55273,0-1-0.44775-1-1c0-1.10303-0.89746-2-2-2s-2,0.89697-2,2c0,0.55225-0.44727,1-1,1 s-1-0.44775-1-1c0-2.20557,1.79395-4,4-4s4,1.79443,4,4C38,18.55225,37.55273,19,37,19z"></path> <path fill="#FFFFFF" d="M35.6051,32C35.85382,31.03912,36,30.03748,36,29c0-0.55225-0.44727-1-1-1H13c-0.55273,0-1,0.44775-1,1 c0,1.03748,0.14618,2.03912,0.3949,3H35.6051z"></path> <path fill="#AE453E" d="M12.3949,32c1.33734,5.16699,6.02551,9,11.6051,9s10.26776-3.83301,11.6051-9H12.3949z"></path> <path fill="#FA645A" d="M18.01404,39.38495C19.77832,40.40594,21.81903,41,24,41s4.22168-0.59406,5.98596-1.61505 C28.75952,37.35876,26.54126,36,24,36S19.24048,37.35876,18.01404,39.38495z"></path></g></svg>
|
204 |
+
<h2>Hooooray!</h2>
|
205 |
+
<p><?php _e('You\'re now ready to begin using Newsletter!', 'newsletter'); ?></p>
|
206 |
+
|
207 |
+
<div class="row tnp-row-padded">
|
208 |
+
<div class="tnp-col-3-boxed">
|
209 |
+
<p><?php _e('Be always updated with the latest releases and tips from our headquarters', 'newsletter'); ?></p>
|
210 |
+
<input type="email" placeholder="<?php esc_attr_e('Your email') ?>" value="<?php echo esc_attr(get_option("admin_email")) ?>" id="tnp-ne" name="ne" value="<?php echo get_option('admin_email') ?>">
|
211 |
+
<br>
|
212 |
+
<a href="#" class="tnp-welcome-confirm-button" onclick="tnp_welcome_subscribe(); return false;"><?php _e('Subscribe', 'newsletter'); ?></a>
|
213 |
+
</div>
|
214 |
+
<div class="tnp-col-3-boxed">
|
215 |
+
<p><?php _e('You can also follow us through our social accounts', 'newsletter'); ?> :)</p>
|
216 |
+
<a href="" target="_blank"><i class="fab fa-facebook-f fa-3x" style="color:#fff;" aria-hidden="true"></i></a>
|
217 |
+
<a href="" target="_blank"><i class="fab fa-youtube fa-3x" style="color:#fff; margin-left: 40px;" aria-hidden="true"></i></a>
|
218 |
+
<a href="" target="_blank"><i class="fab fa-twitter fa-3x" style="color:#fff; margin-left: 40px;" aria-hidden="true"></i></a>
|
219 |
+
|
220 |
+
</div>
|
221 |
+
<div class="tnp-col-3-boxed">
|
222 |
+
<p><?php _e('If you are unsure on how to use some features of Newsletter, reach for our official documentation.', 'newsletter'); ?></p>
|
223 |
+
<a href="https://www.thenewsletterplugin.com/documentation" class="tnp-welcome-link-button" target="_blank"><?php _e('Documentation', 'newsletter'); ?></a>
|
224 |
+
</div>
|
225 |
+
</div>
|
226 |
+
|
227 |
+
<p><a href="<?php echo admin_url('admin.php?page=newsletter_main_index') ?>" class="tnp-welcome-link-button"><?php _e('Go to your dashboard', 'newsletter'); ?></a></p>
|
228 |
+
|
229 |
+
</li>
|
230 |
+
</ul> <!-- .cd-slider -->
|
231 |
+
|
232 |
+
<div class="cd-slider-navigation">
|
233 |
+
<a class="tnp-welcome-prev" style="display: none" href="#" onclick="prevSlide(); return false;"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" xml:space="preserve" width="16" height="16>"<g class="nc-icon-wrapper" fill="#ffffff"><path fill="#ffffff" d="M17,23.414L6.293,12.707c-0.391-0.391-0.391-1.023,0-1.414L17,0.586L18.414,2l-10,10l10,10L17,23.414z"></path></g></svg><?php _e('Previous', 'newsletter'); ?></a>
|
234 |
+
<a class="tnp-welcome-next" href="#" onclick="nextSlide(); return false;"><?php _e('Next', 'newsletter'); ?><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" xml:space="preserve" width="16" height="16"><g class="nc-icon-wrapper" fill="#ffffff"><path fill="#ffffff" d="M7,23.414L5.586,22l10-10l-10-10L7,0.586l10.707,10.707c0.391,0.391,0.391,1.023,0,1.414L7,23.414z"></path></g></svg></a>
|
235 |
+
</div>
|
236 |
+
|
237 |
+
<div class="cd-svg-cover" data-step1="M1402,800h-2V0.6c0-0.3,0-0.3,0-0.6h2v294V800z" data-step2="M1400,800H383L770.7,0.6c0.2-0.3,0.5-0.6,0.9-0.6H1400v294V800z" data-step3="M1400,800H0V0.6C0,0.4,0,0.3,0,0h1400v294V800z" data-step4="M615,800H0V0.6C0,0.4,0,0.3,0,0h615L393,312L615,800z" data-step5="M0,800h-2V0.6C-2,0.4-2,0.3-2,0h2v312V800z" data-step6="M-2,800h2L0,0.6C0,0.3,0,0.3,0,0l-2,0v294V800z" data-step7="M0,800h1017L629.3,0.6c-0.2-0.3-0.5-0.6-0.9-0.6L0,0l0,294L0,800z" data-step8="M0,800h1400V0.6c0-0.2,0-0.3,0-0.6L0,0l0,294L0,800z" data-step9="M785,800h615V0.6c0-0.2,0-0.3,0-0.6L785,0l222,312L785,800z" data-step10="M1400,800h2V0.6c0-0.2,0-0.3,0-0.6l-2,0v312V800z">
|
238 |
+
<svg height='100%' width="100%" preserveAspectRatio="none" viewBox="0 0 1400 800">
|
239 |
+
<title>SVG cover layer</title>
|
240 |
+
<desc>an animated layer to switch from one slide to the next one</desc>
|
241 |
+
<path id="cd-changing-path" d="M1402,800h-2V0.6c0-0.3,0-0.3,0-0.6h2v294V800z"/>
|
242 |
+
</svg>
|
243 |
+
</div> .cd-svg-cover
|
244 |
+
</section> <!-- .cd-slider-wrapper -->
|
245 |
+
</form>
|
246 |
+
|
247 |
+
<form target="tnp-tunnel" id="tnp-subscription" action="https://www.thenewsletterplugin.com/?na=s" method="post" style="display: none">
|
248 |
+
<input type="email" name="ne" value="">
|
249 |
+
<input type="hidden" value="plugin-welcome" name="nr">
|
250 |
+
<input type="hidden" value="3" name="nl[]">
|
251 |
+
<input type="hidden" value="single" name="optin">
|
252 |
+
</form>
|
253 |
+
<iframe name="tnp-tunnel" style="display: none"></iframe>
|
254 |
+
|
255 |
+
</div>
|
|
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: 7.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.
|
@@ -37,16 +37,10 @@ if (version_compare(phpversion(), '5.6', '<')) {
|
|
37 |
return;
|
38 |
}
|
39 |
|
40 |
-
define('NEWSLETTER_VERSION', '7.2.
|
41 |
|
42 |
global $newsletter, $wpdb;
|
43 |
|
44 |
-
if (!defined('NEWSLETTER_DARK'))
|
45 |
-
define('NEWSLETTER_DARK', false);
|
46 |
-
|
47 |
-
if (!defined('NEWSLETTER_BETA'))
|
48 |
-
define('NEWSLETTER_BETA', false);
|
49 |
-
|
50 |
// For acceptance tests, DO NOT CHANGE
|
51 |
if (!defined('NEWSLETTER_DEBUG'))
|
52 |
define('NEWSLETTER_DEBUG', false);
|
@@ -71,6 +65,7 @@ define('NEWSLETTER_SLUG', 'newsletter');
|
|
71 |
define('NEWSLETTER_DIR', __DIR__);
|
72 |
define('NEWSLETTER_INCLUDES_DIR', __DIR__ . '/includes');
|
73 |
|
|
|
74 |
define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
|
75 |
|
76 |
if (!defined('NEWSLETTER_LIST_MAX'))
|
@@ -82,14 +77,13 @@ if (!defined('NEWSLETTER_PROFILE_MAX'))
|
|
82 |
if (!defined('NEWSLETTER_FORMS_MAX'))
|
83 |
define('NEWSLETTER_FORMS_MAX', 10);
|
84 |
|
85 |
-
if (!defined('NEWSLETTER_CRON_INTERVAL'))
|
86 |
-
define('NEWSLETTER_CRON_INTERVAL', 300);
|
87 |
-
|
88 |
if (!defined('NEWSLETTER_HEADER'))
|
89 |
define('NEWSLETTER_HEADER', true);
|
90 |
|
91 |
require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
|
92 |
require_once NEWSLETTER_INCLUDES_DIR . '/TNP.php';
|
|
|
|
|
93 |
|
94 |
class Newsletter extends NewsletterModule {
|
95 |
|
@@ -109,16 +103,12 @@ class Newsletter extends NewsletterModule {
|
|
109 |
var $user;
|
110 |
var $error;
|
111 |
var $theme;
|
112 |
-
|
113 |
-
var $theme_max_posts;
|
114 |
-
var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
|
115 |
-
var $theme_posts; // WP_Query object
|
116 |
var $action = '';
|
117 |
|
118 |
/** @var Newsletter */
|
119 |
static $instance;
|
120 |
|
121 |
-
const MAX_CRON_SAMPLES = 100;
|
122 |
const STATUS_NOT_CONFIRMED = 'S';
|
123 |
const STATUS_CONFIRMED = 'C';
|
124 |
|
@@ -144,15 +134,6 @@ class Newsletter extends NewsletterModule {
|
|
144 |
|
145 |
$this->time_start = time();
|
146 |
|
147 |
-
// Here because the upgrade is called by the parent constructor and uses the scheduler
|
148 |
-
add_filter('cron_schedules', function ($schedules) {
|
149 |
-
$schedules['newsletter'] = array(
|
150 |
-
'interval' => NEWSLETTER_CRON_INTERVAL, // seconds
|
151 |
-
'display' => 'Every ' . NEWSLETTER_CRON_INTERVAL . ' seconds by Newsletter'
|
152 |
-
);
|
153 |
-
return $schedules;
|
154 |
-
}, 1000);
|
155 |
-
|
156 |
parent::__construct('main', '1.6.6', null, array('info', 'smtp'));
|
157 |
|
158 |
$max = $this->options['scheduler_max'];
|
@@ -167,8 +148,6 @@ class Newsletter extends NewsletterModule {
|
|
167 |
|
168 |
add_action('newsletter', array($this, 'hook_newsletter'), 1);
|
169 |
|
170 |
-
$this->update_cron_stats();
|
171 |
-
|
172 |
register_activation_hook(__FILE__, array($this, 'hook_activate'));
|
173 |
register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
|
174 |
|
@@ -282,38 +261,6 @@ class Newsletter extends NewsletterModule {
|
|
282 |
do_action('newsletter_action', $this->action, $user, $email);
|
283 |
}
|
284 |
|
285 |
-
function update_cron_stats() {
|
286 |
-
if (defined('DOING_CRON') && DOING_CRON) {
|
287 |
-
$calls = get_option('newsletter_diagnostic_cron_calls', []);
|
288 |
-
if (!is_array($calls)) $calls = []; // Protection agains scrambled options or bad written caching DB caching plugin
|
289 |
-
$calls[] = time();
|
290 |
-
if (count($calls) > self::MAX_CRON_SAMPLES) {
|
291 |
-
array_shift($calls);
|
292 |
-
}
|
293 |
-
update_option('newsletter_diagnostic_cron_calls', $calls, false);
|
294 |
-
|
295 |
-
if (count($calls) > 50) {
|
296 |
-
$mean = 0;
|
297 |
-
$max = 0;
|
298 |
-
$min = 0;
|
299 |
-
for ($i = 1; $i < count($calls); $i++) {
|
300 |
-
$diff = $calls[$i] - $calls[$i - 1];
|
301 |
-
$mean += $diff;
|
302 |
-
if ($min == 0 || $min > $diff) {
|
303 |
-
$min = $diff;
|
304 |
-
}
|
305 |
-
if ($max < $diff) {
|
306 |
-
$max = $diff;
|
307 |
-
}
|
308 |
-
}
|
309 |
-
$mean = $mean / count($calls) - 1;
|
310 |
-
update_option('newsletter_diagnostic_cron_data', array('mean' => $mean, 'max' => $max, 'min' => $min), false);
|
311 |
-
} else {
|
312 |
-
update_option('newsletter_diagnostic_cron_data', '', false);
|
313 |
-
}
|
314 |
-
}
|
315 |
-
}
|
316 |
-
|
317 |
function hook_activate() {
|
318 |
// Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
|
319 |
// the every-five-minutes schedule named "newsletter" is not present.
|
@@ -413,31 +360,6 @@ class Newsletter extends NewsletterModule {
|
|
413 |
wp_clear_scheduled_hook('newsletter');
|
414 |
wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
|
415 |
|
416 |
-
wp_clear_scheduled_hook('newsletter_extension_versions');
|
417 |
-
// No more required
|
418 |
-
//wp_schedule_event(time() + 30, 'daily', 'newsletter_extension_versions');
|
419 |
-
|
420 |
-
$subscription_options = get_option('newsletter', array());
|
421 |
-
|
422 |
-
// Settings migration
|
423 |
-
if (empty($this->options['page'])) {
|
424 |
-
if (isset($subscription_options['page']))
|
425 |
-
$this->options['page'] = $subscription_options['page'];
|
426 |
-
$this->save_options($this->options);
|
427 |
-
}
|
428 |
-
|
429 |
-
if (empty($this->options['css']) && !empty($subscription_options['css'])) {
|
430 |
-
$this->options['css'] = $subscription_options['css'];
|
431 |
-
$this->save_options($this->options);
|
432 |
-
}
|
433 |
-
|
434 |
-
// Migration of "info" options
|
435 |
-
$info_options = $this->get_options('info');
|
436 |
-
if (!empty($this->options['header_logo']) && empty($info_options['header_logo'])) {
|
437 |
-
$info_options = $this->options;
|
438 |
-
$this->save_options($info_options, 'info');
|
439 |
-
}
|
440 |
-
|
441 |
if (!empty($this->options['editor'])) {
|
442 |
if (empty($this->options['roles'])) {
|
443 |
$this->options['roles'] = array('editor');
|
@@ -474,7 +396,7 @@ class Newsletter extends NewsletterModule {
|
|
474 |
return;
|
475 |
}
|
476 |
|
477 |
-
add_menu_page('Newsletter', 'Newsletter', 'exist', 'newsletter_main_index', '', plugins_url('newsletter') . '/images/menu-icon.png', '30.333');
|
478 |
|
479 |
$this->add_menu_page('index', __('Dashboard', 'newsletter'));
|
480 |
$this->add_admin_page('info', __('Company info', 'newsletter'));
|
@@ -488,6 +410,7 @@ class Newsletter extends NewsletterModule {
|
|
488 |
$this->add_admin_page('status', __('Status', 'newsletter'));
|
489 |
$this->add_admin_page('delivery', __('Delivery Diagnostic', 'newsletter'));
|
490 |
$this->add_admin_page('logs', __('Logs', 'newsletter'));
|
|
|
491 |
$this->add_admin_page('diagnostic', __('Diagnostic', 'newsletter'));
|
492 |
$this->add_admin_page('test', __('Test', 'newsletter'));
|
493 |
}
|
@@ -560,17 +483,12 @@ class Newsletter extends NewsletterModule {
|
|
560 |
wp_enqueue_style('tnp-admin-fontawesome', $newsletter_url . '/vendor/fa/css/all.min.css', [], NEWSLETTER_VERSION);
|
561 |
wp_enqueue_style('tnp-admin-jquery-ui', $newsletter_url . '/vendor/jquery-ui/jquery-ui.min.css', [], NEWSLETTER_VERSION);
|
562 |
wp_enqueue_style('tnp-admin', $newsletter_url . '/admin/admin.css', [], NEWSLETTER_VERSION);
|
563 |
-
wp_enqueue_style('tnp-admin-dropdown', $newsletter_url . '/
|
564 |
-
wp_enqueue_style('tnp-admin-tabs', $newsletter_url . '/
|
565 |
-
wp_enqueue_style('tnp-admin-controls', $newsletter_url . '/
|
566 |
-
wp_enqueue_style('tnp-admin-fields', $newsletter_url . '/
|
567 |
-
wp_enqueue_style('tnp-admin-widgets', $newsletter_url . '/
|
568 |
-
wp_enqueue_style('tnp-admin-extensions', $newsletter_url . '/
|
569 |
-
|
570 |
-
if (NEWSLETTER_DARK) {
|
571 |
-
wp_enqueue_style('tnp-admin-dark', $newsletter_url . '/admin/admin-dark.css', ['tnp-admin'], NEWSLETTER_VERSION);
|
572 |
-
wp_enqueue_style('tnp-admin-controls-dark', $newsletter_url . '/css/controls-dark.css', ['tnp-admin-controls'], NEWSLETTER_VERSION);
|
573 |
-
}
|
574 |
|
575 |
$translations_array = array(
|
576 |
'save_to_update_counter' => __('Save the newsletter to update the counter!', 'newsletter')
|
@@ -861,7 +779,7 @@ class Newsletter extends NewsletterModule {
|
|
861 |
$send_calls = get_option('newsletter_diagnostic_send_calls', []);
|
862 |
$send_calls[] = array($start_time, $end_time, $count, $result);
|
863 |
|
864 |
-
if (count($send_calls) >
|
865 |
array_shift($send_calls);
|
866 |
|
867 |
update_option('newsletter_diagnostic_send_calls', $send_calls, false);
|
@@ -1517,6 +1435,10 @@ class Newsletter extends NewsletterModule {
|
|
1517 |
|
1518 |
$newsletter = Newsletter::instance();
|
1519 |
|
|
|
|
|
|
|
|
|
1520 |
require_once NEWSLETTER_DIR . '/subscription/subscription.php';
|
1521 |
require_once NEWSLETTER_DIR . '/unsubscription/unsubscription.php';
|
1522 |
require_once NEWSLETTER_DIR . '/profile/profile.php';
|
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: 7.2.8
|
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.
|
37 |
return;
|
38 |
}
|
39 |
|
40 |
+
define('NEWSLETTER_VERSION', '7.2.8');
|
41 |
|
42 |
global $newsletter, $wpdb;
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
// For acceptance tests, DO NOT CHANGE
|
45 |
if (!defined('NEWSLETTER_DEBUG'))
|
46 |
define('NEWSLETTER_DEBUG', false);
|
65 |
define('NEWSLETTER_DIR', __DIR__);
|
66 |
define('NEWSLETTER_INCLUDES_DIR', __DIR__ . '/includes');
|
67 |
|
68 |
+
// Deperacted since plugin can change the plugins_url()
|
69 |
define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
|
70 |
|
71 |
if (!defined('NEWSLETTER_LIST_MAX'))
|
77 |
if (!defined('NEWSLETTER_FORMS_MAX'))
|
78 |
define('NEWSLETTER_FORMS_MAX', 10);
|
79 |
|
|
|
|
|
|
|
80 |
if (!defined('NEWSLETTER_HEADER'))
|
81 |
define('NEWSLETTER_HEADER', true);
|
82 |
|
83 |
require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
|
84 |
require_once NEWSLETTER_INCLUDES_DIR . '/TNP.php';
|
85 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/cron.php';
|
86 |
+
|
87 |
|
88 |
class Newsletter extends NewsletterModule {
|
89 |
|
103 |
var $user;
|
104 |
var $error;
|
105 |
var $theme;
|
106 |
+
|
|
|
|
|
|
|
107 |
var $action = '';
|
108 |
|
109 |
/** @var Newsletter */
|
110 |
static $instance;
|
111 |
|
|
|
112 |
const STATUS_NOT_CONFIRMED = 'S';
|
113 |
const STATUS_CONFIRMED = 'C';
|
114 |
|
134 |
|
135 |
$this->time_start = time();
|
136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
parent::__construct('main', '1.6.6', null, array('info', 'smtp'));
|
138 |
|
139 |
$max = $this->options['scheduler_max'];
|
148 |
|
149 |
add_action('newsletter', array($this, 'hook_newsletter'), 1);
|
150 |
|
|
|
|
|
151 |
register_activation_hook(__FILE__, array($this, 'hook_activate'));
|
152 |
register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
|
153 |
|
261 |
do_action('newsletter_action', $this->action, $user, $email);
|
262 |
}
|
263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
function hook_activate() {
|
265 |
// Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
|
266 |
// the every-five-minutes schedule named "newsletter" is not present.
|
360 |
wp_clear_scheduled_hook('newsletter');
|
361 |
wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
|
362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
if (!empty($this->options['editor'])) {
|
364 |
if (empty($this->options['roles'])) {
|
365 |
$this->options['roles'] = array('editor');
|
396 |
return;
|
397 |
}
|
398 |
|
399 |
+
add_menu_page('Newsletter', 'Newsletter', 'exist', 'newsletter_main_index', '', plugins_url('newsletter') . '/admin/images/menu-icon.png', '30.333');
|
400 |
|
401 |
$this->add_menu_page('index', __('Dashboard', 'newsletter'));
|
402 |
$this->add_admin_page('info', __('Company info', 'newsletter'));
|
410 |
$this->add_admin_page('status', __('Status', 'newsletter'));
|
411 |
$this->add_admin_page('delivery', __('Delivery Diagnostic', 'newsletter'));
|
412 |
$this->add_admin_page('logs', __('Logs', 'newsletter'));
|
413 |
+
$this->add_admin_page('scheduler', __('Scheduler', 'newsletter'));
|
414 |
$this->add_admin_page('diagnostic', __('Diagnostic', 'newsletter'));
|
415 |
$this->add_admin_page('test', __('Test', 'newsletter'));
|
416 |
}
|
483 |
wp_enqueue_style('tnp-admin-fontawesome', $newsletter_url . '/vendor/fa/css/all.min.css', [], NEWSLETTER_VERSION);
|
484 |
wp_enqueue_style('tnp-admin-jquery-ui', $newsletter_url . '/vendor/jquery-ui/jquery-ui.min.css', [], NEWSLETTER_VERSION);
|
485 |
wp_enqueue_style('tnp-admin', $newsletter_url . '/admin/admin.css', [], NEWSLETTER_VERSION);
|
486 |
+
wp_enqueue_style('tnp-admin-dropdown', $newsletter_url . '/admin/dropdown.css', [], NEWSLETTER_VERSION);
|
487 |
+
wp_enqueue_style('tnp-admin-tabs', $newsletter_url . '/admin/tabs.css', [], NEWSLETTER_VERSION);
|
488 |
+
wp_enqueue_style('tnp-admin-controls', $newsletter_url . '/admin/controls.css', [], NEWSLETTER_VERSION);
|
489 |
+
wp_enqueue_style('tnp-admin-fields', $newsletter_url . '/admin/fields.css', [], NEWSLETTER_VERSION);
|
490 |
+
wp_enqueue_style('tnp-admin-widgets', $newsletter_url . '/admin/widgets.css', [], NEWSLETTER_VERSION);
|
491 |
+
wp_enqueue_style('tnp-admin-extensions', $newsletter_url . '/admin/extensions.css', [], NEWSLETTER_VERSION);
|
|
|
|
|
|
|
|
|
|
|
492 |
|
493 |
$translations_array = array(
|
494 |
'save_to_update_counter' => __('Save the newsletter to update the counter!', 'newsletter')
|
779 |
$send_calls = get_option('newsletter_diagnostic_send_calls', []);
|
780 |
$send_calls[] = array($start_time, $end_time, $count, $result);
|
781 |
|
782 |
+
if (count($send_calls) > 100)
|
783 |
array_shift($send_calls);
|
784 |
|
785 |
update_option('newsletter_diagnostic_send_calls', $send_calls, false);
|
1435 |
|
1436 |
$newsletter = Newsletter::instance();
|
1437 |
|
1438 |
+
if (is_admin()) {
|
1439 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/system.php';
|
1440 |
+
}
|
1441 |
+
|
1442 |
require_once NEWSLETTER_DIR . '/subscription/subscription.php';
|
1443 |
require_once NEWSLETTER_DIR . '/unsubscription/unsubscription.php';
|
1444 |
require_once NEWSLETTER_DIR . '/profile/profile.php';
|
readme.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
=== Newsletter ===
|
2 |
Tags: newsletter, email marketing, welcome email, signup forms, contact, lead generation, marketing automation
|
3 |
Tested up to: 5.8.1
|
4 |
-
Stable tag: 7.2.
|
5 |
Contributors: satollo,webagile,michael-travan
|
6 |
License: GPLv2 or later
|
7 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
@@ -118,9 +118,20 @@ Thank you, The Newsletter Team
|
|
118 |
|
119 |
== Changelog ==
|
120 |
|
|
1 |
=== Newsletter ===
|
2 |
Tags: newsletter, email marketing, welcome email, signup forms, contact, lead generation, marketing automation
|
3 |
Tested up to: 5.8.1
|
4 |
+
Stable tag: 7.2.8
|
5 |
Contributors: satollo,webagile,michael-travan
|
6 |
License: GPLv2 or later
|
7 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
118 |
|
119 |
== Changelog ==
|
120 |
|
121 |
+
= 7.2.8 =
|