Newsletter - Version 7.4.2

Version Description

  • Fixed the post date (regression)
  • Added link to the automatic plaintext generator plugin by franciscus
  • Possible fix for our Gutenberg block (sometimes) not working
  • Added uoloads dir and url on System>Status panel
  • Fixed Status panel error when a newsletter is in "error" status
  • Added default width to the logo on header block
Download this release

Release Info

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

Code changes from version 7.4.1 to 7.4.2

emails/blocks/footer/block.php CHANGED
@@ -6,11 +6,11 @@
6
  */
7
 
8
  $default_options = array(
9
- 'view' => 'View online',
10
  'view_enabled' => 1,
11
- 'profile' => 'Manage your subscription',
12
  'profile_enabled' => 1,
13
- 'unsubscribe' => 'Unsubscribe',
14
  'unsubscribe_enabled' => 1,
15
  'font_family' => '',
16
  'font_size' => '',
6
  */
7
 
8
  $default_options = array(
9
+ 'view' => __('View online', 'newsletter'),
10
  'view_enabled' => 1,
11
+ 'profile' => __('Manage your subscription', 'newsletter'),
12
  'profile_enabled' => 1,
13
+ 'unsubscribe' => __('Unsubscribe', 'newsletter'),
14
  'unsubscribe_enabled' => 1,
15
  'font_family' => '',
16
  'font_size' => '',
emails/blocks/header/block.php CHANGED
@@ -1,50 +1,49 @@
1
- <?php
2
-
3
- /*
4
- * Name: Header
5
- * Section: header
6
- * Description: Default header with company info
7
- */
8
-
9
- $default_options = array(
10
- 'font_family' => '',
11
- 'font_size' => '',
12
- 'font_color' => '',
13
- 'font_weight' => '',
14
- 'logo_height' => 100,
15
- 'logo_width' => '',
16
- 'block_padding_top' => 15,
17
- 'block_padding_bottom' => 15,
18
- 'block_padding_left' => 15,
19
- 'block_padding_right' => 15,
20
- 'block_background' => '',
21
- 'layout' => ''
22
- );
23
- $options = array_merge($default_options, $options);
24
-
25
- if (empty($info['header_logo']['id'])) {
26
- $media = false;
27
- } else {
28
- $media = tnp_get_media($info['header_logo']['id'], 'large');
29
- if ($media) {
30
- $media->alt = $info['header_title'];
31
- $media->link = home_url();
32
- }
33
- }
34
-
35
- $empty = !$media && empty($info['header_sub']) && empty($info['header_title']);
36
-
37
- if ($empty) {
38
- echo '<p>Please, set your company info.</p>';
39
- } elseif ($options['layout'] === 'logo') {
40
- include __DIR__ . '/layout-logo.php';
41
- return;
42
- } elseif ($options['layout'] === 'titlemotto') {
43
- include __DIR__ . '/layout-titlemotto.php';
44
- return;
45
- } else {
46
- include __DIR__ . '/layout-default.php';
47
- return;
48
- }
49
- ?>
50
-
1
+ <?php
2
+
3
+ /*
4
+ * Name: Header
5
+ * Section: header
6
+ * Description: Default header with company info
7
+ */
8
+
9
+ $default_options = array(
10
+ 'font_family' => '',
11
+ 'font_size' => '',
12
+ 'font_color' => '',
13
+ 'font_weight' => '',
14
+ 'logo_width' => 120,
15
+ 'block_padding_top' => 15,
16
+ 'block_padding_bottom' => 15,
17
+ 'block_padding_left' => 15,
18
+ 'block_padding_right' => 15,
19
+ 'block_background' => '',
20
+ 'layout' => ''
21
+ );
22
+ $options = array_merge($default_options, $options);
23
+
24
+ if (empty($info['header_logo']['id'])) {
25
+ $media = false;
26
+ } else {
27
+ $media = tnp_get_media($info['header_logo']['id'], 'large');
28
+ if ($media) {
29
+ $media->alt = $info['header_title'];
30
+ $media->link = home_url();
31
+ }
32
+ }
33
+
34
+ $empty = !$media && empty($info['header_sub']) && empty($info['header_title']);
35
+
36
+ if ($empty) {
37
+ echo '<p>Please, set your company info.</p>';
38
+ } elseif ($options['layout'] === 'logo') {
39
+ include __DIR__ . '/layout-logo.php';
40
+ return;
41
+ } elseif ($options['layout'] === 'titlemotto') {
42
+ include __DIR__ . '/layout-titlemotto.php';
43
+ return;
44
+ } else {
45
+ include __DIR__ . '/layout-default.php';
46
+ return;
47
+ }
48
+ ?>
49
+
 
emails/blocks/header/layout-logo.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- if (!$media) {
3
- echo '<p>Set your logo on company info page, thank you.</p>';
4
- return;
5
- }
6
- $image_width = 600-$options['block_padding_left']-$options['block_padding_right'];
7
- if ($options['logo_width']) {
8
- $image_width = min($options['logo_width'], $image_width);
9
- }
10
- $media->set_width($image_width);
11
- ?>
12
- <a href="<?php echo esc_url($media->link) ?>" target="_blank"><img src="<?php echo $media->url ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>" class="fluid"></a>
1
+ <?php
2
+ if (!$media) {
3
+ echo '<p>Set your logo on company info page, thank you.</p>';
4
+ return;
5
+ }
6
+ $image_width = 600-$options['block_padding_left']-$options['block_padding_right'];
7
+ if ($options['logo_width']) {
8
+ $image_width = min($options['logo_width'], $image_width);
9
+ }
10
+ $media->set_width($image_width);
11
+ ?>
12
+ <a href="<?php echo esc_url($media->link) ?>" target="_blank"><img src="<?php echo $media->url ?>" width="<?php echo $media->width ?>" height="<?php echo $media->height ?>" border="0" alt="<?php echo esc_attr($media->alt) ?>"></a>
emails/edit.php CHANGED
@@ -1,597 +1,602 @@
1
- <?php
2
- /* @var $this NewsletterEmails */
3
- defined('ABSPATH') || exit;
4
-
5
- /* @var $wpdb wpdb */
6
- require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
7
- $controls = new NewsletterControls();
8
- $module = NewsletterEmails::instance();
9
-
10
- function tnp_prepare_controls($email, $controls) {
11
- $controls->data = $email;
12
-
13
- foreach ($email['options'] as $name => $value) {
14
- $controls->data['options_' . $name] = $value;
15
- }
16
- }
17
-
18
- // Always required
19
- $email = $this->get_email($_GET['id'], ARRAY_A);
20
-
21
- if (empty($email)) {
22
- echo 'Wrong email identifier';
23
- return;
24
- }
25
-
26
- $email_id = $email['id'];
27
-
28
- /* Satus changes which require a reload */
29
- if ($controls->is_action('pause')) {
30
- $this->admin_logger->info('Newsletter ' . $email_id . ' paused');
31
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'paused'), array('id' => $email_id));
32
- $email = $this->get_email($_GET['id'], ARRAY_A);
33
- tnp_prepare_controls($email, $controls);
34
- }
35
-
36
- if ($controls->is_action('continue')) {
37
- $this->admin_logger->info('Newsletter ' . $email_id . ' restarted');
38
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
39
- $email = $this->get_email($_GET['id'], ARRAY_A);
40
- tnp_prepare_controls($email, $controls);
41
- }
42
-
43
- if ($controls->is_action('abort')) {
44
- $this->admin_logger->info('Newsletter ' . $email_id . ' aborted');
45
- $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set last_id=0, sent=0, status='new' where id=" . $email_id);
46
- $email = $this->get_email($_GET['id'], ARRAY_A);
47
- tnp_prepare_controls($email, $controls);
48
- $controls->messages = __('Delivery definitively cancelled', 'newsletter');
49
- }
50
-
51
- if ($controls->is_action('change-private')) {
52
- $data = [];
53
- $data['private'] = $controls->data['private'];
54
- $data['id'] = $email['id'];
55
- $email = $this->save_email($data, ARRAY_A);
56
- $controls->add_message_saved();
57
-
58
- tnp_prepare_controls($email, $controls);
59
- }
60
-
61
-
62
- $editor_type = $this->get_editor_type($email);
63
-
64
- // Backward compatibility: preferences conversion
65
- if (!$controls->is_action()) {
66
- if (!isset($email['options']['lists'])) {
67
-
68
- $options_profile = get_option('newsletter_profile');
69
-
70
- if (empty($controls->data['preferences_status_operator'])) {
71
- $email['options']['lists_operator'] = 'or';
72
- } else {
73
- $email['options']['lists_operator'] = 'and';
74
- }
75
- $controls->data['options_lists'] = array();
76
- $controls->data['options_lists_exclude'] = array();
77
-
78
- if (!empty($email['preferences'])) {
79
- $preferences = explode(',', $email['preferences']);
80
- $value = empty($email['options']['preferences_status']) ? 'on' : 'off';
81
-
82
- foreach ($preferences as $x) {
83
- if ($value == 'on') {
84
- $controls->data['options_lists'][] = $x;
85
- } else {
86
- $controls->data['options_lists_exclude'][] = $x;
87
- }
88
- }
89
- }
90
- }
91
- }
92
- // End backward compatibility
93
-
94
- if (!$controls->is_action()) {
95
- tnp_prepare_controls($email, $controls);
96
- }
97
-
98
- if ($controls->is_action('html')) {
99
-
100
- $this->admin_logger->info('Newsletter ' . $email_id . ' converted to HTML');
101
-
102
- $data = [];
103
- $data['editor'] = NewsletterEmails::EDITOR_HTML;
104
- $data['id'] = $email_id;
105
-
106
- // Backward compatibility: clean up the composer flag
107
- $data['options'] = $email['options'];
108
- unset($data['options']['composer']);
109
- // End backward compatibility
110
-
111
- $email = $this->save_email($data, ARRAY_A);
112
- $controls->messages = 'You can now edit the newsletter as pure HTML';
113
-
114
- tnp_prepare_controls($email, $controls);
115
-
116
- $editor_type = NewsletterEmails::EDITOR_HTML;
117
- }
118
-
119
-
120
-
121
- if ($controls->is_action('test') || $controls->is_action('save') || $controls->is_action('send') || $controls->is_action('schedule')) {
122
-
123
- if ($email['updated'] != $controls->data['updated']) {
124
- $controls->errors = 'This newsletter has been modified by someone else. Cannot save.';
125
- } else {
126
- $email['updated'] = time();
127
- if ($controls->is_action('save')) {
128
- $this->admin_logger->info('Saving newsletter: ' . $email_id);
129
- } else if ($controls->is_action('send')) {
130
- $this->admin_logger->info('Sending newsletter: ' . $email_id);
131
- } else if ($controls->is_action('schedule')) {
132
- $this->admin_logger->info('Scheduling newsletter: ' . $email_id);
133
- }
134
-
135
- $email['subject'] = $controls->data['subject'];
136
- $email['track'] = $controls->data['track'];
137
- $email['editor'] = $editor_type;
138
- $email['private'] = $controls->data['private'];
139
- $email['message_text'] = $controls->data['message_text'];
140
- if ($controls->is_action('send')) {
141
- $email['send_on'] = time();
142
- } else {
143
- // Patch, empty on continuation
144
- if (!empty($controls->data['send_on'])) {
145
- $email['send_on'] = $controls->data['send_on'];
146
- }
147
- }
148
-
149
- // Reset and refill the options
150
- // Try without the reset and let's see where the problems are
151
- //$email['options'] = array();
152
- // Reset only specific keys
153
- unset($email['options']['lists']);
154
- unset($email['options']['lists_operator']);
155
- unset($email['options']['lists_exclude']);
156
- unset($email['options']['sex']);
157
- for ($i = 1; $i <= 20; $i++) {
158
- unset($email['options']["profile_$i"]);
159
- }
160
-
161
- // Patch for Geo addon to be solved with a filter
162
- unset($email['options']['countries']);
163
- unset($email['options']['regions']);
164
- unset($email['options']['cities']);
165
-
166
- foreach ($controls->data as $name => $value) {
167
- if (strpos($name, 'options_') === 0) {
168
- $email['options'][substr($name, 8)] = $value;
169
- }
170
- }
171
-
172
- // Before send, we build the query to extract subscriber, so the delivery engine does not
173
- // have to worry about the email parameters
174
- if ($email['options']['status'] == 'S') {
175
- $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='S'";
176
- } else {
177
- $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
178
- }
179
-
180
- if ($email['options']['wp_users'] == '1') {
181
- $query .= " and wp_user_id<>0";
182
- }
183
-
184
- if (!empty($email['options']['language'])) {
185
- $query .= " and language='" . esc_sql((string) $email['options']['language']) . "'";
186
- }
187
-
188
-
189
- $list_where = array();
190
- if (isset($email['options']['lists']) && count($email['options']['lists'])) {
191
- foreach ($email['options']['lists'] as $list) {
192
- $list = (int) $list;
193
- $list_where[] = 'list_' . $list . '=1';
194
- }
195
- }
196
-
197
- if (!empty($list_where)) {
198
- if (isset($email['options']['lists_operator']) && $email['options']['lists_operator'] == 'and') {
199
- $query .= ' and (' . implode(' and ', $list_where) . ')';
200
- } else {
201
- $query .= ' and (' . implode(' or ', $list_where) . ')';
202
- }
203
- }
204
-
205
- // Excluded lists
206
- $list_where = array();
207
- if (isset($email['options']['lists_exclude']) && count($email['options']['lists_exclude'])) {
208
- foreach ($email['options']['lists_exclude'] as $list) {
209
- $list = (int) $list;
210
- $list_where[] = 'list_' . $list . '=0';
211
- }
212
- }
213
- if (!empty($list_where)) {
214
- // Must not be in one of the excluded lists
215
- $query .= ' and (' . implode(' and ', $list_where) . ')';
216
- }
217
-
218
- // Gender
219
- if (isset($email['options']['sex'])) {
220
- $sex = $email['options']['sex'];
221
- if (is_array($sex) && count($sex)) {
222
- $query .= " and sex in (";
223
- foreach ($sex as $x) {
224
- $query .= "'" . esc_sql((string) $x) . "', ";
225
- }
226
- $query = substr($query, 0, -2);
227
- $query .= ")";
228
- }
229
- }
230
-
231
- // Profile fields filter
232
- $profile_clause = array();
233
- for ($i = 1; $i <= 20; $i++) {
234
- if (isset($email["options"]["profile_$i"]) && count($email["options"]["profile_$i"])) {
235
- $profile_clause[] = 'profile_' . $i . " IN ('" . implode("','", esc_sql($email["options"]["profile_$i"])) . "') ";
236
- }
237
- }
238
-
239
- if (!empty($profile_clause)) {
240
- $query .= ' and (' . implode(' and ', $profile_clause) . ')';
241
- }
242
-
243
- // Temporary save to have an object and call the query filter
244
- $e = Newsletter::instance()->save_email($email);
245
- $query = apply_filters('newsletter_emails_email_query', $query, $e);
246
-
247
- $email['query'] = $query;
248
- if ($email['status'] == 'sent') {
249
- $email['total'] = $email['sent'];
250
- } else {
251
- $email['total'] = $wpdb->get_var(str_replace('*', 'count(*)', $query));
252
- }
253
-
254
- if ($controls->is_action('send') && $controls->data['send_on'] < time()) {
255
- $controls->data['send_on'] = time();
256
- }
257
-
258
- $email = Newsletter::instance()->save_email($email, ARRAY_A);
259
-
260
- tnp_prepare_controls($email, $controls);
261
-
262
- if ($email === false) {
263
- $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
264
- }
265
-
266
- $controls->add_message_saved();
267
- }
268
- }
269
-
270
- if (empty($controls->errors) && ($controls->is_action('send') || $controls->is_action('schedule'))) {
271
-
272
- NewsletterStatistics::instance()->reset_stats($email);
273
-
274
- if ($email['subject'] == '') {
275
- $controls->errors = __('A subject is required to send', 'newsletter');
276
- } else {
277
- $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => TNP_Email::STATUS_SENDING), array('id' => $email_id));
278
- $email['status'] = TNP_Email::STATUS_SENDING;
279
- if ($controls->is_action('send')) {
280
- $controls->messages = __('Now sending.', 'newsletter');
281
- } else {
282
- $controls->messages = __('Scheduled.', 'newsletter');
283
- }
284
- }
285
- }
286
-
287
- if (isset($email['options']['status']) && $email['options']['status'] == 'S') {
288
- $controls->warnings[] = __('This newsletter will be sent to not confirmed subscribers.', 'newsletter');
289
- }
290
-
291
- if (strpos($email['message'], '{profile_url}') === false && strpos($email['message'], '{unsubscription_url}') === false && strpos($email['message'], '{unsubscription_confirm_url}') === false) {
292
- $controls->warnings[] = __('The message is missing the subscriber profile or cancellation link.', 'newsletter');
293
- }
294
-
295
- if (TNP_Email::STATUS_ERROR === $email['status'] && isset($email['options']['error_message'])) {
296
- $controls->errors .= sprintf(__('Stopped by fatal error: %s', 'newsletter'), esc_html($email['options']['error_message']));
297
- }
298
-
299
-
300
- if ($email['status'] != 'sent') {
301
- $subscriber_count = $wpdb->get_var(str_replace('*', 'count(*)', $email['query']));
302
- } else {
303
- $subscriber_count = $email['sent'];
304
- }
305
- ?>
306
- <style>
307
- .select2-container {
308
- max-width: 500px;
309
- display: block;
310
- margin: 1px;
311
- margin-top: 5px;
312
- }
313
- </style>
314
-
315
- <div class="wrap tnp-emails tnp-emails-edit" id="tnp-wrap">
316
-
317
- <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
318
-
319
- <div id="tnp-heading">
320
-
321
- <h2><?php _e('Edit Newsletter', 'newsletter') ?></h2>
322
-
323
- </div>
324
-
325
- <div id="tnp-body">
326
- <form method="post" action="" id="newsletter-form">
327
- <?php $controls->init(array('cookie_name' => 'newsletter_emails_edit_tab')); ?>
328
- <?php $controls->hidden('updated') ?>
329
- <div class="tnp-status-header">
330
-
331
- <div class="tnp-two-thirds">
332
-
333
- <div class="tnp-submit">
334
-
335
- <?php if ($email['status'] == 'sending' || $email['status'] == 'sent') { ?>
336
-
337
- <?php $controls->button_back('?page=newsletter_emails_index') ?>
338
-
339
- <?php } else { ?>
340
-
341
- <a class="button-primary" href="<?php echo $module->get_editor_url($email_id, $editor_type) ?>">
342
- <i class="fas fa-edit"></i> <?php _e('Edit', 'newsletter') ?>
343
- </a>
344
-
345
- <?php } ?>
346
-
347
- <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_save(); ?>
348
- <?php if ($email['status'] == 'new') $controls->button_confirm('send', __('Send now', 'newsletter'), __('Start real delivery?', 'newsletter')); ?>
349
- <?php if ($email['status'] == 'sending') $controls->button_confirm('pause', __('Pause', 'newsletter'), __('Pause the delivery?', 'newsletter')); ?>
350
- <?php if ($email['status'] == 'paused' || $email['status'] == 'error') $controls->button_confirm('continue', __('Continue', 'newsletter'), 'Continue the delivery?'); ?>
351
- <?php if ($email['status'] == 'paused') $controls->button_confirm('abort', __('Stop', 'newsletter'), __('This totally stop the delivery, ok?', 'newsletter')); ?>
352
- <?php if ($email['status'] == 'new' || ( $email['status'] == 'paused' && $email['send_on'] > time() )) { ?>
353
- <a id="tnp-schedule-button" class="button-secondary" href="javascript:tnp_toggle_schedule()"><i class="far fa-clock"></i> <?php _e("Schedule") ?></a>
354
- <span id="tnp-schedule" style="display: none;">
355
- <?php $controls->datetime('send_on') ?>
356
- <?php $controls->button_confirm('schedule', __('Schedule', 'newsletter'), __('Schedule delivery?', 'newsletter')); ?>
357
- <a class="button-secondary tnp-button-cancel" href="javascript:tnp_toggle_schedule()"><?php _e("Cancel") ?></a>
358
- </span>
359
- <?php } ?>
360
- </div>
361
-
362
- <?php $controls->text('subject', null, 'Subject'); ?>
363
- &nbsp;&nbsp;&nbsp;
364
- <i class="far fa-lightbulb" data-tnp-modal-target="#subject-ideas-modal" style="color: #fff; font-size: 24px"></i>
365
- </div>
366
-
367
- <div class="tnp-one-third">
368
-
369
- <div id="tnp-nl-status">
370
- <span class="tnp-nl-status-title"><?php _e("Status:") ?></span>
371
- <span class="tnp-nl-status-title-value"><?php _e("") ?> <?php $module->show_email_status_label($email) ?></span>
372
-
373
- <?php $module->show_email_progress_bar($email, array('numbers' => $email['status'] == 'sent' ? false : true)) ?>
374
-
375
- <?php if ($email['status'] == 'sent' || $email['status'] == 'sending') { ?>
376
- <div class="tnp-nl-status-row">
377
- <span class="tnp-nl-status-schedule-value"><?php
378
- if ($email['status'] == 'sent') {
379
- echo __('Sent on'), ' ', $module->format_date($email['send_on']);
380
- } else if ($email['status'] == 'sending' && $email['send_on'] > time()) {
381
- echo __('Scheduled on'), ' ', $module->format_date($email['send_on']);
382
- }
383
- ?></span>
384
- </div>
385
- <?php } ?>
386
- <div class="tnp-nl-status-row">
387
- <span class="tnp-nl-status-schedule-targeting"><?php _e('Targeted subscribers', 'newsletter') ?>:</span>
388
- <span class="tnp-nl-status-schedule-value"><?php echo $subscriber_count ?></span>
389
- </div>
390
-
391
- </div>
392
- </div>
393
-
394
- </div>
395
-
396
- <div id="tabs">
397
-
398
- <ul>
399
- <li><a href="#tabs-options"><?php _e('Sending Options', 'newsletter') ?></a></li>
400
- <li><a href="#tabs-advanced"><?php _e('Advanced', 'newsletter') ?></a></li>
401
- <li><a href="#tabs-preview"><?php _e('Preview', 'newsletter') ?></a></li>
402
- </ul>
403
-
404
-
405
- <div id="tabs-options" class="tnp-list-conditions">
406
- <p>
407
- <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/newsletter-targeting') ?>
408
- </p>
409
-
410
- <p>
411
- <?php _e('Leaving all multichoice options unselected is like to select all them', 'newsletter'); ?>
412
- </p>
413
- <table class="form-table">
414
- <tr>
415
- <th><?php _e('Lists', 'newsletter') ?></th>
416
- <td>
417
- <?php
418
- $lists = $controls->get_list_options();
419
- ?>
420
- <?php $controls->select('options_lists_operator', array('or' => __('Match at least one of', 'newsletter'), 'and' => __('Match all of', 'newsletter'))); ?>
421
-
422
- <?php $controls->select2('options_lists', $lists, null, true, null, __('All', 'newsletter')); ?>
423
-
424
- <br>
425
- <?php _e('must not in one of', 'newsletter') ?>
426
-
427
- <?php $controls->select2('options_lists_exclude', $lists, null, true, null, __('None', 'newsletter')); ?>
428
- </td>
429
- </tr>
430
-
431
- <tr>
432
- <th><?php _e('Language', 'newsletter') ?></th>
433
- <td>
434
- <?php $controls->language('options_language'); ?>
435
- </td>
436
- </tr>
437
-
438
- <tr>
439
- <th><?php _e('Gender', 'newsletter') ?></th>
440
- <td>
441
- <?php $controls->checkboxes_group('options_sex', array('f' => 'Women', 'm' => 'Men', 'n' => 'Not specified')); ?>
442
- </td>
443
- </tr>
444
- <tr>
445
- <th><?php _e('Status', 'newsletter') ?></th>
446
- <td>
447
- <?php $controls->select('options_status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'))); ?>
448
-
449
- </td>
450
- </tr>
451
- <tr>
452
- <th><?php _e('Only to subscribers linked to WP users', 'newsletter') ?></th>
453
- <td>
454
- <?php $controls->yesno('options_wp_users'); ?>
455
- </td>
456
- </tr>
457
- <?php
458
- $fields = TNP_Profile_Service::get_profiles('', TNP_Profile::TYPE_SELECT);
459
- ?>
460
- <?php if (!empty($fields)) { ?>
461
- <tr>
462
- <th><?php _e('Profile fields', 'newsletter') ?></th>
463
- <td>
464
- <?php foreach ($fields as $profile) { ?>
465
- <?php echo esc_html($profile->name), ' ', __('is one of:', 'newsletter') ?>
466
- <?php $controls->select2("options_profile_$profile->id", $profile->options, null, true, null, __('Do not filter by this field', 'newsletter')); ?>
467
- <br>
468
- <?php } ?>
469
- <p class="description">
470
-
471
- </p>
472
- </td>
473
- </tr>
474
- <?php } ?>
475
- </table>
476
-
477
- <?php do_action('newsletter_emails_edit_target', $module->get_email($email_id), $controls) ?>
478
-
479
- </div>
480
-
481
-
482
- <div id="tabs-advanced">
483
-
484
- <table class="form-table">
485
- <tr>
486
- <th><?php _e('Keep private', 'newsletter') ?></th>
487
- <td>
488
- <?php $controls->yesno('private'); ?>
489
- <?php if ($email['status'] == 'sent') { ?>
490
- <?php $controls->button('change-private', __('Save')) ?>
491
- <?php } ?>
492
- <p class="description">
493
- <?php _e('Hide/show from public sent newsletter list.', 'newsletter') ?>
494
- <?php _e('Required', 'newsletter') ?>: <a href="" target="_blank">Newsletter Archive Extension</a>
495
- </p>
496
- </td>
497
- </tr>
498
- <tr>
499
- <th><?php _e('Track clicks and message opening', 'newsletter') ?></th>
500
- <td>
501
- <?php $controls->yesno('track'); ?>
502
- </td>
503
- </tr>
504
- <tr>
505
- <th><?php _e('Sender email address', 'newsletter') ?></th>
506
- <td>
507
- <?php $controls->text_email('options_sender_email', 40); ?>
508
- <div class="tnpc-hint">
509
- Original: <?php echo esc_html(Newsletter::instance()->get_sender_email()) ?>.<br>
510
- If you use a delivery service, be sure to use a validated email address.
511
- </div>
512
- </td>
513
- </tr>
514
- <tr>
515
- <th>
516
- <?php _e('Sender name', 'newsletter') ?>
517
- </th>
518
- <td>
519
- <?php $controls->text('options_sender_name', 40); ?>
520
- <div class="tnpc-hint">
521
- Original: <?php echo esc_html(Newsletter::instance()->get_sender_name()) ?>
522
- </div>
523
- </td>
524
- </tr>
525
- </table>
526
-
527
- <?php do_action('newsletter_emails_edit_other', $module->get_email($email_id), $controls) ?>
528
-
529
- <table class="form-table">
530
- <tr>
531
- <th>Query (tech)</th>
532
- <td><?php echo esc_html($email['query']); ?></td>
533
- </tr>
534
- <tr>
535
- <th>Token (tech)</th>
536
- <td><?php echo esc_html($email['token']); ?></td>
537
- </tr>
538
- <tr>
539
- <th>This is the textual version of your newsletter. If you empty it, only an HTML version will be sent but is an anti-spam best practice to include a text only version.</th>
540
- <td>
541
- <?php if (Newsletter::instance()->options['phpmailer'] == 0) { ?>
542
- <p class="tnp-tab-warning">The text part is sent only when Newsletter manages directly the sending process. <a href="admin.php?page=newsletter_main_main" target="_blank">See the main settings</a>.</p>
543
- <?php } ?>
544
- <?php $controls->textarea_fixed('message_text', '100%', '500'); ?>
545
- </td>
546
- </tr>
547
- </table>
548
- </div>
549
-
550
-
551
- <div id="tabs-preview">
552
-
553
- <div class="tnpc-preview">
554
- <!-- Flat Laptop Browser -->
555
- <div class="fake-browser-ui">
556
- <div class="frame">
557
- <span class="bt-1"></span>
558
- <span class="bt-2"></span>
559
- <span class="bt-3"></span>
560
- </div>
561
- <iframe id="tnpc-preview-desktop" src="" width="700" height="520" alt="" frameborder="0"></iframe>
562
- </div>
563
-
564
- <!-- Flat Mobile Browser -->
565
- <div class="fake-mobile-browser-ui">
566
- <iframe id="tnpc-preview-mobile" src="" width="320" height="445" alt="" frameborder="0"></iframe>
567
- <div class="frame">
568
- <span class="bt-4"></span>
569
- </div>
570
- </div>
571
- </div>
572
-
573
- <script type="text/javascript">
574
- preview_url = ajaxurl + "?action=tnpc_preview&id=<?php echo $email_id ?>";
575
- jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').attr("src", preview_url);
576
- setTimeout(function () {
577
- jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').contents().find("a").click(function (e) {
578
- e.preventDefault();
579
- })
580
- }, 500);
581
- </script>
582
-
583
- <p>
584
- <?php if ($editor_type != NewsletterEmails::EDITOR_HTML && $email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('html', __('Convert to HTML newsletter', 'newsletter'), 'Attention: no way back!'); ?>
585
- </p>
586
- </div>
587
-
588
- </div>
589
-
590
- </form>
591
- </div>
592
-
593
- <?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
594
-
595
- <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
596
-
597
- </div>
 
 
 
 
 
1
+ <?php
2
+ /* @var $this NewsletterEmails */
3
+ defined('ABSPATH') || exit;
4
+
5
+ /* @var $wpdb wpdb */
6
+ require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
7
+ $controls = new NewsletterControls();
8
+ $module = NewsletterEmails::instance();
9
+
10
+ function tnp_prepare_controls($email, $controls) {
11
+ $controls->data = $email;
12
+
13
+ foreach ($email['options'] as $name => $value) {
14
+ $controls->data['options_' . $name] = $value;
15
+ }
16
+ }
17
+
18
+ // Always required
19
+ $email = $this->get_email($_GET['id'], ARRAY_A);
20
+
21
+ if (empty($email)) {
22
+ echo 'Wrong email identifier';
23
+ return;
24
+ }
25
+
26
+ $email_id = $email['id'];
27
+
28
+ /* Satus changes which require a reload */
29
+ if ($controls->is_action('pause')) {
30
+ $this->admin_logger->info('Newsletter ' . $email_id . ' paused');
31
+ $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'paused'), array('id' => $email_id));
32
+ $email = $this->get_email($_GET['id'], ARRAY_A);
33
+ tnp_prepare_controls($email, $controls);
34
+ }
35
+
36
+ if ($controls->is_action('continue')) {
37
+ $this->admin_logger->info('Newsletter ' . $email_id . ' restarted');
38
+ $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => 'sending'), array('id' => $email_id));
39
+ $email = $this->get_email($_GET['id'], ARRAY_A);
40
+ tnp_prepare_controls($email, $controls);
41
+ }
42
+
43
+ if ($controls->is_action('abort')) {
44
+ $this->admin_logger->info('Newsletter ' . $email_id . ' aborted');
45
+ $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set last_id=0, sent=0, status='new' where id=" . $email_id);
46
+ $email = $this->get_email($_GET['id'], ARRAY_A);
47
+ tnp_prepare_controls($email, $controls);
48
+ $controls->messages = __('Delivery definitively cancelled', 'newsletter');
49
+ }
50
+
51
+ if ($controls->is_action('change-private')) {
52
+ $data = [];
53
+ $data['private'] = $controls->data['private'];
54
+ $data['id'] = $email['id'];
55
+ $email = $this->save_email($data, ARRAY_A);
56
+ $controls->add_message_saved();
57
+
58
+ tnp_prepare_controls($email, $controls);
59
+ }
60
+
61
+
62
+ $editor_type = $this->get_editor_type($email);
63
+
64
+ // Backward compatibility: preferences conversion
65
+ if (!$controls->is_action()) {
66
+ if (!isset($email['options']['lists'])) {
67
+
68
+ $options_profile = get_option('newsletter_profile');
69
+
70
+ if (empty($controls->data['preferences_status_operator'])) {
71
+ $email['options']['lists_operator'] = 'or';
72
+ } else {
73
+ $email['options']['lists_operator'] = 'and';
74
+ }
75
+ $controls->data['options_lists'] = array();
76
+ $controls->data['options_lists_exclude'] = array();
77
+
78
+ if (!empty($email['preferences'])) {
79
+ $preferences = explode(',', $email['preferences']);
80
+ $value = empty($email['options']['preferences_status']) ? 'on' : 'off';
81
+
82
+ foreach ($preferences as $x) {
83
+ if ($value == 'on') {
84
+ $controls->data['options_lists'][] = $x;
85
+ } else {
86
+ $controls->data['options_lists_exclude'][] = $x;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ // End backward compatibility
93
+
94
+ if (!$controls->is_action()) {
95
+ tnp_prepare_controls($email, $controls);
96
+ }
97
+
98
+ if ($controls->is_action('html')) {
99
+
100
+ $this->admin_logger->info('Newsletter ' . $email_id . ' converted to HTML');
101
+
102
+ $data = [];
103
+ $data['editor'] = NewsletterEmails::EDITOR_HTML;
104
+ $data['id'] = $email_id;
105
+
106
+ // Backward compatibility: clean up the composer flag
107
+ $data['options'] = $email['options'];
108
+ unset($data['options']['composer']);
109
+ // End backward compatibility
110
+
111
+ $email = $this->save_email($data, ARRAY_A);
112
+ $controls->messages = 'You can now edit the newsletter as pure HTML';
113
+
114
+ tnp_prepare_controls($email, $controls);
115
+
116
+ $editor_type = NewsletterEmails::EDITOR_HTML;
117
+ }
118
+
119
+
120
+
121
+ if ($controls->is_action('test') || $controls->is_action('save') || $controls->is_action('send') || $controls->is_action('schedule')) {
122
+
123
+ if ($email['updated'] != $controls->data['updated']) {
124
+ $controls->errors = 'This newsletter has been modified by someone else. Cannot save.';
125
+ } else {
126
+ $email['updated'] = time();
127
+ if ($controls->is_action('save')) {
128
+ $this->admin_logger->info('Saving newsletter: ' . $email_id);
129
+ } else if ($controls->is_action('send')) {
130
+ $this->admin_logger->info('Sending newsletter: ' . $email_id);
131
+ } else if ($controls->is_action('schedule')) {
132
+ $this->admin_logger->info('Scheduling newsletter: ' . $email_id);
133
+ }
134
+
135
+ $email['subject'] = $controls->data['subject'];
136
+ $email['track'] = $controls->data['track'];
137
+ $email['editor'] = $editor_type;
138
+ $email['private'] = $controls->data['private'];
139
+ $email['message_text'] = $controls->data['message_text'];
140
+ if ($controls->is_action('send')) {
141
+ $email['send_on'] = time();
142
+ } else {
143
+ // Patch, empty on continuation
144
+ if (!empty($controls->data['send_on'])) {
145
+ $email['send_on'] = $controls->data['send_on'];
146
+ }
147
+ }
148
+
149
+ // Reset and refill the options
150
+ // Try without the reset and let's see where the problems are
151
+ //$email['options'] = array();
152
+ // Reset only specific keys
153
+ unset($email['options']['lists']);
154
+ unset($email['options']['lists_operator']);
155
+ unset($email['options']['lists_exclude']);
156
+ unset($email['options']['sex']);
157
+ for ($i = 1; $i <= 20; $i++) {
158
+ unset($email['options']["profile_$i"]);
159
+ }
160
+
161
+ // Patch for Geo addon to be solved with a filter
162
+ unset($email['options']['countries']);
163
+ unset($email['options']['regions']);
164
+ unset($email['options']['cities']);
165
+
166
+ foreach ($controls->data as $name => $value) {
167
+ if (strpos($name, 'options_') === 0) {
168
+ $email['options'][substr($name, 8)] = $value;
169
+ }
170
+ }
171
+
172
+ // Before send, we build the query to extract subscriber, so the delivery engine does not
173
+ // have to worry about the email parameters
174
+ if ($email['options']['status'] == 'S') {
175
+ $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='S'";
176
+ } else {
177
+ $query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
178
+ }
179
+
180
+ if ($email['options']['wp_users'] == '1') {
181
+ $query .= " and wp_user_id<>0";
182
+ }
183
+
184
+ if (!empty($email['options']['language'])) {
185
+ $query .= " and language='" . esc_sql((string) $email['options']['language']) . "'";
186
+ }
187
+
188
+
189
+ $list_where = array();
190
+ if (isset($email['options']['lists']) && count($email['options']['lists'])) {
191
+ foreach ($email['options']['lists'] as $list) {
192
+ $list = (int) $list;
193
+ $list_where[] = 'list_' . $list . '=1';
194
+ }
195
+ }
196
+
197
+ if (!empty($list_where)) {
198
+ if (isset($email['options']['lists_operator']) && $email['options']['lists_operator'] == 'and') {
199
+ $query .= ' and (' . implode(' and ', $list_where) . ')';
200
+ } else {
201
+ $query .= ' and (' . implode(' or ', $list_where) . ')';
202
+ }
203
+ }
204
+
205
+ // Excluded lists
206
+ $list_where = array();
207
+ if (isset($email['options']['lists_exclude']) && count($email['options']['lists_exclude'])) {
208
+ foreach ($email['options']['lists_exclude'] as $list) {
209
+ $list = (int) $list;
210
+ $list_where[] = 'list_' . $list . '=0';
211
+ }
212
+ }
213
+ if (!empty($list_where)) {
214
+ // Must not be in one of the excluded lists
215
+ $query .= ' and (' . implode(' and ', $list_where) . ')';
216
+ }
217
+
218
+ // Gender
219
+ if (isset($email['options']['sex'])) {
220
+ $sex = $email['options']['sex'];
221
+ if (is_array($sex) && count($sex)) {
222
+ $query .= " and sex in (";
223
+ foreach ($sex as $x) {
224
+ $query .= "'" . esc_sql((string) $x) . "', ";
225
+ }
226
+ $query = substr($query, 0, -2);
227
+ $query .= ")";
228
+ }
229
+ }
230
+
231
+ // Profile fields filter
232
+ $profile_clause = array();
233
+ for ($i = 1; $i <= 20; $i++) {
234
+ if (isset($email["options"]["profile_$i"]) && count($email["options"]["profile_$i"])) {
235
+ $profile_clause[] = 'profile_' . $i . " IN ('" . implode("','", esc_sql($email["options"]["profile_$i"])) . "') ";
236
+ }
237
+ }
238
+
239
+ if (!empty($profile_clause)) {
240
+ $query .= ' and (' . implode(' and ', $profile_clause) . ')';
241
+ }
242
+
243
+ // Temporary save to have an object and call the query filter
244
+ $e = Newsletter::instance()->save_email($email);
245
+ $query = apply_filters('newsletter_emails_email_query', $query, $e);
246
+
247
+ $email['query'] = $query;
248
+ if ($email['status'] == 'sent') {
249
+ $email['total'] = $email['sent'];
250
+ } else {
251
+ $email['total'] = $wpdb->get_var(str_replace('*', 'count(*)', $query));
252
+ }
253
+
254
+ if ($controls->is_action('send') && $controls->data['send_on'] < time()) {
255
+ $controls->data['send_on'] = time();
256
+ }
257
+
258
+ $email = Newsletter::instance()->save_email($email, ARRAY_A);
259
+
260
+ tnp_prepare_controls($email, $controls);
261
+
262
+ if ($email === false) {
263
+ $controls->errors = 'Unable to save. Try to deactivate and reactivate the plugin may be the database is out of sync.';
264
+ }
265
+
266
+ $controls->add_message_saved();
267
+ }
268
+ }
269
+
270
+ if (empty($controls->errors) && ($controls->is_action('send') || $controls->is_action('schedule'))) {
271
+
272
+ NewsletterStatistics::instance()->reset_stats($email);
273
+
274
+ if ($email['subject'] == '') {
275
+ $controls->errors = __('A subject is required to send', 'newsletter');
276
+ } else {
277
+ $wpdb->update(NEWSLETTER_EMAILS_TABLE, array('status' => TNP_Email::STATUS_SENDING), array('id' => $email_id));
278
+ $email['status'] = TNP_Email::STATUS_SENDING;
279
+ if ($controls->is_action('send')) {
280
+ $controls->messages = __('Now sending.', 'newsletter');
281
+ } else {
282
+ $controls->messages = __('Scheduled.', 'newsletter');
283
+ }
284
+ }
285
+ }
286
+
287
+ if (isset($email['options']['status']) && $email['options']['status'] == 'S') {
288
+ $controls->warnings[] = __('This newsletter will be sent to not confirmed subscribers.', 'newsletter');
289
+ }
290
+
291
+ if (strpos($email['message'], '{profile_url}') === false && strpos($email['message'], '{unsubscription_url}') === false && strpos($email['message'], '{unsubscription_confirm_url}') === false) {
292
+ $controls->warnings[] = __('The message is missing the subscriber profile or cancellation link.', 'newsletter');
293
+ }
294
+
295
+ if (TNP_Email::STATUS_ERROR === $email['status'] && isset($email['options']['error_message'])) {
296
+ $controls->errors .= sprintf(__('Stopped by fatal error: %s', 'newsletter'), esc_html($email['options']['error_message']));
297
+ }
298
+
299
+
300
+ if ($email['status'] != 'sent') {
301
+ $subscriber_count = $wpdb->get_var(str_replace('*', 'count(*)', $email['query']));
302
+ } else {
303
+ $subscriber_count = $email['sent'];
304
+ }
305
+ ?>
306
+ <style>
307
+ .select2-container {
308
+ max-width: 500px;
309
+ display: block;
310
+ margin: 1px;
311
+ margin-top: 5px;
312
+ }
313
+ </style>
314
+
315
+ <div class="wrap tnp-emails tnp-emails-edit" id="tnp-wrap">
316
+
317
+ <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
318
+
319
+ <div id="tnp-heading">
320
+
321
+ <h2><?php _e('Edit Newsletter', 'newsletter') ?></h2>
322
+
323
+ </div>
324
+
325
+ <div id="tnp-body">
326
+ <form method="post" action="" id="newsletter-form">
327
+ <?php $controls->init(array('cookie_name' => 'newsletter_emails_edit_tab')); ?>
328
+ <?php $controls->hidden('updated') ?>
329
+ <div class="tnp-status-header">
330
+
331
+ <div class="tnp-two-thirds">
332
+
333
+ <div class="tnp-submit">
334
+
335
+ <?php if ($email['status'] == 'sending' || $email['status'] == 'sent') { ?>
336
+
337
+ <?php $controls->button_back('?page=newsletter_emails_index') ?>
338
+
339
+ <?php } else { ?>
340
+
341
+ <a class="button-primary" href="<?php echo $module->get_editor_url($email_id, $editor_type) ?>">
342
+ <i class="fas fa-edit"></i> <?php _e('Edit', 'newsletter') ?>
343
+ </a>
344
+
345
+ <?php } ?>
346
+
347
+ <?php if ($email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_save(); ?>
348
+ <?php if ($email['status'] == 'new') $controls->button_confirm('send', __('Send now', 'newsletter'), __('Start real delivery?', 'newsletter')); ?>
349
+ <?php if ($email['status'] == 'sending') $controls->button_confirm('pause', __('Pause', 'newsletter'), __('Pause the delivery?', 'newsletter')); ?>
350
+ <?php if ($email['status'] == 'paused' || $email['status'] == 'error') $controls->button_confirm('continue', __('Continue', 'newsletter'), 'Continue the delivery?'); ?>
351
+ <?php if ($email['status'] == 'paused') $controls->button_confirm('abort', __('Stop', 'newsletter'), __('This totally stop the delivery, ok?', 'newsletter')); ?>
352
+ <?php if ($email['status'] == 'new' || ( $email['status'] == 'paused' && $email['send_on'] > time() )) { ?>
353
+ <a id="tnp-schedule-button" class="button-secondary" href="javascript:tnp_toggle_schedule()"><i class="far fa-clock"></i> <?php _e("Schedule") ?></a>
354
+ <span id="tnp-schedule" style="display: none;">
355
+ <?php $controls->datetime('send_on') ?>
356
+ <?php $controls->button_confirm('schedule', __('Schedule', 'newsletter'), __('Schedule delivery?', 'newsletter')); ?>
357
+ <a class="button-secondary tnp-button-cancel" href="javascript:tnp_toggle_schedule()"><?php _e("Cancel") ?></a>
358
+ </span>
359
+ <?php } ?>
360
+ </div>
361
+
362
+ <?php $controls->text('subject', null, 'Subject'); ?>
363
+ &nbsp;&nbsp;&nbsp;
364
+ <i class="far fa-lightbulb" data-tnp-modal-target="#subject-ideas-modal" style="color: #fff; font-size: 24px"></i>
365
+ </div>
366
+
367
+ <div class="tnp-one-third">
368
+
369
+ <div id="tnp-nl-status">
370
+ <span class="tnp-nl-status-title"><?php _e("Status:") ?></span>
371
+ <span class="tnp-nl-status-title-value"><?php _e("") ?> <?php $module->show_email_status_label($email) ?></span>
372
+
373
+ <?php $module->show_email_progress_bar($email, array('numbers' => $email['status'] == 'sent' ? false : true)) ?>
374
+
375
+ <?php if ($email['status'] == 'sent' || $email['status'] == 'sending') { ?>
376
+ <div class="tnp-nl-status-row">
377
+ <span class="tnp-nl-status-schedule-value"><?php
378
+ if ($email['status'] == 'sent') {
379
+ echo __('Sent on'), ' ', $module->format_date($email['send_on']);
380
+ } else if ($email['status'] == 'sending' && $email['send_on'] > time()) {
381
+ echo __('Scheduled on'), ' ', $module->format_date($email['send_on']);
382
+ }
383
+ ?></span>
384
+ </div>
385
+ <?php } ?>
386
+ <div class="tnp-nl-status-row">
387
+ <span class="tnp-nl-status-schedule-targeting"><?php _e('Targeted subscribers', 'newsletter') ?>:</span>
388
+ <span class="tnp-nl-status-schedule-value"><?php echo $subscriber_count ?></span>
389
+ </div>
390
+
391
+ </div>
392
+ </div>
393
+
394
+ </div>
395
+
396
+ <div id="tabs">
397
+
398
+ <ul>
399
+ <li><a href="#tabs-options"><?php _e('Sending Options', 'newsletter') ?></a></li>
400
+ <li><a href="#tabs-advanced"><?php _e('Advanced', 'newsletter') ?></a></li>
401
+ <li><a href="#tabs-preview"><?php _e('Preview', 'newsletter') ?></a></li>
402
+ </ul>
403
+
404
+
405
+ <div id="tabs-options" class="tnp-list-conditions">
406
+ <p>
407
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/newsletter-targeting') ?>
408
+ </p>
409
+
410
+ <p>
411
+ <?php _e('Leaving all multichoice options unselected is like to select all them', 'newsletter'); ?>
412
+ </p>
413
+ <table class="form-table">
414
+ <tr>
415
+ <th><?php _e('Lists', 'newsletter') ?></th>
416
+ <td>
417
+ <?php
418
+ $lists = $controls->get_list_options();
419
+ ?>
420
+ <?php $controls->select('options_lists_operator', array('or' => __('Match at least one of', 'newsletter'), 'and' => __('Match all of', 'newsletter'))); ?>
421
+
422
+ <?php $controls->select2('options_lists', $lists, null, true, null, __('All', 'newsletter')); ?>
423
+
424
+ <br>
425
+ <?php _e('must not in one of', 'newsletter') ?>
426
+
427
+ <?php $controls->select2('options_lists_exclude', $lists, null, true, null, __('None', 'newsletter')); ?>
428
+ </td>
429
+ </tr>
430
+
431
+ <tr>
432
+ <th><?php _e('Language', 'newsletter') ?></th>
433
+ <td>
434
+ <?php $controls->language('options_language'); ?>
435
+ </td>
436
+ </tr>
437
+
438
+ <tr>
439
+ <th><?php _e('Gender', 'newsletter') ?></th>
440
+ <td>
441
+ <?php $controls->checkboxes_group('options_sex', array('f' => 'Women', 'm' => 'Men', 'n' => 'Not specified')); ?>
442
+ </td>
443
+ </tr>
444
+ <tr>
445
+ <th><?php _e('Status', 'newsletter') ?></th>
446
+ <td>
447
+ <?php $controls->select('options_status', array('C' => __('Confirmed', 'newsletter'), 'S' => __('Not confirmed', 'newsletter'))); ?>
448
+
449
+ </td>
450
+ </tr>
451
+ <tr>
452
+ <th><?php _e('Only to subscribers linked to WP users', 'newsletter') ?></th>
453
+ <td>
454
+ <?php $controls->yesno('options_wp_users'); ?>
455
+ </td>
456
+ </tr>
457
+ <?php
458
+ $fields = TNP_Profile_Service::get_profiles('', TNP_Profile::TYPE_SELECT);
459
+ ?>
460
+ <?php if (!empty($fields)) { ?>
461
+ <tr>
462
+ <th><?php _e('Profile fields', 'newsletter') ?></th>
463
+ <td>
464
+ <?php foreach ($fields as $profile) { ?>
465
+ <?php echo esc_html($profile->name), ' ', __('is one of:', 'newsletter') ?>
466
+ <?php $controls->select2("options_profile_$profile->id", $profile->options, null, true, null, __('Do not filter by this field', 'newsletter')); ?>
467
+ <br>
468
+ <?php } ?>
469
+ <p class="description">
470
+
471
+ </p>
472
+ </td>
473
+ </tr>
474
+ <?php } ?>
475
+ </table>
476
+
477
+ <?php do_action('newsletter_emails_edit_target', $module->get_email($email_id), $controls) ?>
478
+
479
+ </div>
480
+
481
+
482
+ <div id="tabs-advanced">
483
+
484
+ <table class="form-table">
485
+ <tr>
486
+ <th><?php _e('Keep private', 'newsletter') ?></th>
487
+ <td>
488
+ <?php $controls->yesno('private'); ?>
489
+ <?php if ($email['status'] == 'sent') { ?>
490
+ <?php $controls->button('change-private', __('Save')) ?>
491
+ <?php } ?>
492
+ <p class="description">
493
+ <?php _e('Hide/show from public sent newsletter list.', 'newsletter') ?>
494
+ <?php _e('Required', 'newsletter') ?>: <a href="" target="_blank">Newsletter Archive Extension</a>
495
+ </p>
496
+ </td>
497
+ </tr>
498
+ <tr>
499
+ <th><?php _e('Track clicks and message opening', 'newsletter') ?></th>
500
+ <td>
501
+ <?php $controls->yesno('track'); ?>
502
+ </td>
503
+ </tr>
504
+ <tr>
505
+ <th><?php _e('Sender email address', 'newsletter') ?></th>
506
+ <td>
507
+ <?php $controls->text_email('options_sender_email', 40); ?>
508
+ <div class="tnpc-hint">
509
+ Original: <?php echo esc_html(Newsletter::instance()->get_sender_email()) ?>.<br>
510
+ If you use a delivery service, be sure to use a validated email address.
511
+ </div>
512
+ </td>
513
+ </tr>
514
+ <tr>
515
+ <th>
516
+ <?php _e('Sender name', 'newsletter') ?>
517
+ </th>
518
+ <td>
519
+ <?php $controls->text('options_sender_name', 40); ?>
520
+ <div class="tnpc-hint">
521
+ Original: <?php echo esc_html(Newsletter::instance()->get_sender_name()) ?>
522
+ </div>
523
+ </td>
524
+ </tr>
525
+ </table>
526
+
527
+ <?php do_action('newsletter_emails_edit_other', $module->get_email($email_id), $controls) ?>
528
+
529
+ <table class="form-table">
530
+ <tr>
531
+ <th>Query (tech)</th>
532
+ <td><?php echo esc_html($email['query']); ?></td>
533
+ </tr>
534
+ <tr>
535
+ <th>Token (tech)</th>
536
+ <td><?php echo esc_html($email['token']); ?></td>
537
+ </tr>
538
+ <tr>
539
+ <th>This is the textual version of your newsletter.
540
+ If you empty it, only an HTML version will be sent but is an anti-spam best practice to include a text only version.</th>
541
+ <td>
542
+ <?php if (Newsletter::instance()->options['phpmailer'] == 0) { ?>
543
+ <p class="tnp-tab-warning">
544
+ See <a href="https://wordpress.org/plugins/plaintext-newsletter/" target="_blank">this plugin</a> for automatic plaintext generation.
545
+ The text part is sent only when Newsletter manages
546
+ directly the sending process. <a href="admin.php?page=newsletter_main_main" target="_blank">See the main settings</a>.
547
+ </p>
548
+ <?php } ?>
549
+ <?php $controls->textarea_fixed('message_text', '100%', '500'); ?>
550
+ </td>
551
+ </tr>
552
+ </table>
553
+ </div>
554
+
555
+
556
+ <div id="tabs-preview">
557
+
558
+ <div class="tnpc-preview">
559
+ <!-- Flat Laptop Browser -->
560
+ <div class="fake-browser-ui">
561
+ <div class="frame">
562
+ <span class="bt-1"></span>
563
+ <span class="bt-2"></span>
564
+ <span class="bt-3"></span>
565
+ </div>
566
+ <iframe id="tnpc-preview-desktop" src="" width="700" height="520" alt="" frameborder="0"></iframe>
567
+ </div>
568
+
569
+ <!-- Flat Mobile Browser -->
570
+ <div class="fake-mobile-browser-ui">
571
+ <iframe id="tnpc-preview-mobile" src="" width="320" height="445" alt="" frameborder="0"></iframe>
572
+ <div class="frame">
573
+ <span class="bt-4"></span>
574
+ </div>
575
+ </div>
576
+ </div>
577
+
578
+ <script type="text/javascript">
579
+ preview_url = ajaxurl + "?action=tnpc_preview&id=<?php echo $email_id ?>";
580
+ jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').attr("src", preview_url);
581
+ setTimeout(function () {
582
+ jQuery('#tnpc-preview-desktop, #tnpc-preview-mobile').contents().find("a").click(function (e) {
583
+ e.preventDefault();
584
+ })
585
+ }, 500);
586
+ </script>
587
+
588
+ <p>
589
+ <?php if ($editor_type != NewsletterEmails::EDITOR_HTML && $email['status'] != 'sending' && $email['status'] != 'sent') $controls->button_confirm('html', __('Convert to HTML newsletter', 'newsletter'), 'Attention: no way back!'); ?>
590
+ </p>
591
+ </div>
592
+
593
+ </div>
594
+
595
+ </form>
596
+ </div>
597
+
598
+ <?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
599
+
600
+ <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
601
+
602
+ </div>
emails/emails.php CHANGED
@@ -1146,8 +1146,6 @@ class NewsletterEmails extends NewsletterModule {
1146
 
1147
  function get_composer_css() {
1148
  $css = file_get_contents(__DIR__ . '/tnp-composer/css/newsletter.css');
1149
- $css .= "\n\n";
1150
- $css .= file_get_contents(__DIR__ . '/tnp-composer/css/backend.css');
1151
  $blocks = $this->get_blocks();
1152
  foreach ($blocks as $block) {
1153
  if (!file_exists($block['dir'] . '/style.css')) {
@@ -1159,6 +1157,13 @@ class NewsletterEmails extends NewsletterModule {
1159
  }
1160
  return $css;
1161
  }
 
 
 
 
 
 
 
1162
 
1163
  /**
1164
  * Send an email to the test subscribers.
1146
 
1147
  function get_composer_css() {
1148
  $css = file_get_contents(__DIR__ . '/tnp-composer/css/newsletter.css');
 
 
1149
  $blocks = $this->get_blocks();
1150
  foreach ($blocks as $block) {
1151
  if (!file_exists($block['dir'] . '/style.css')) {
1157
  }
1158
  return $css;
1159
  }
1160
+
1161
+ function get_composer_backend_css() {
1162
+ $css = file_get_contents(__DIR__ . '/tnp-composer/css/backend.css');
1163
+ $css .= "\n\n";
1164
+ $css .= $this->get_composer_css();
1165
+ return $css;
1166
+ }
1167
 
1168
  /**
1169
  * Send an email to the test subscribers.
emails/tnp-composer/index-v2.php CHANGED
@@ -1,206 +1,206 @@
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
- <script type="text/javascript">
33
- if (window.innerWidth < 1550) {
34
- document.body.classList.add('folded');
35
- }
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
- <?php if (!empty($controls->data['sender_email'])) { ?>
58
- <tr>
59
- <th dir="<?php echo $dir ?>"><?php _e('From', 'newsletter') ?></th>
60
- <td dir="<?php echo $dir ?>"><?php echo esc_html($controls->data['sender_email']) ?></td>
61
- </tr>
62
- <?php } ?>
63
- <tr>
64
- <th dir="<?php echo $dir ?>">
65
- <?php _e('Subject', 'newsletter') ?>
66
- <?php if ($context_type === 'automated') { ?>
67
- <?php $this->field_help('https://www.thenewsletterplugin.com/documentation/addons/extended-features/automated-extension/#subject') ?>
68
- <?php } ?>
69
- </th>
70
- <td dir="<?php echo $dir ?>">
71
- <div id="tnpc-subject">
72
- <?php $this->subject('subject'); ?>
73
- </div>
74
- </td>
75
- </tr>
76
- <tr>
77
- <th dir="<?php echo $dir ?>"><span title="<?php esc_attr_e('Shown by some email clients as excerpt', 'newsletter') ?>"><?php _e('Snippet', 'newsletter') ?></span>
78
- <?php $this->field_help('https://www.thenewsletterplugin.com/documentation/newsletters/composer/#subject') ?>
79
- </th>
80
- <td dir="<?php echo $dir ?>"><?php $this->text('preheader') ?></td>
81
- </tr>
82
- </table>
83
-
84
- <div style="text-align: left; margin-left: 1em;">
85
- <a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletter-tags/"
86
- target="_blank">You can use tags to inject subscriber fields</a>. Even on subject.
87
-
88
-
89
- </div>
90
-
91
- <div class="composer-actions">
92
-
93
- <div id="attachment-newsletter-button" class="button-primary" data-tnp-modal-target="#attachment-modal">
94
- <i class="fas fa-paperclip"></i>
95
- </div>
96
- <?php if ($show_test) { ?>
97
- <div id="test-newsletter-button" class="button-primary" data-tnp-modal-target="#test-newsletter-modal">
98
- <i class="fas fa-paper-plane"></i> <?php _e('Test', 'newsletter') ?>
99
- </div>
100
- <?php } ?>
101
-
102
- <div class="composer-view-mode">
103
- <span class="composer-view-mode__item" data-view-mode="desktop">
104
- <i class="fas fa-desktop"></i>
105
- </span>
106
-
107
- <span class="composer-view-mode__item" data-view-mode="mobile">
108
- <i class="fas fa-mobile"></i>
109
- <span>
110
- </div>
111
-
112
- </div>
113
-
114
- <?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/test-newsletter.php' ?>
115
- <?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/attachment.php' ?>
116
-
117
- </div>
118
- <?php } ?>
119
-
120
-
121
- <div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
122
-
123
- <!-- Composer content -->
124
-
125
- </div>
126
- </div>
127
-
128
- <div id="newsletter-builder-sidebar" dir="<?php echo is_rtl() ? 'rtl' : 'ltr' ?>">
129
-
130
- <div class="tnpc-tabs">
131
- <button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" data-tab-id='tnpc-blocks' id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
132
- <button class="tablinks" onclick="openTab(event, 'tnpc-global-styles')" data-tab-id='tnpc-global-styles'><?php _e('Settings', 'newsletter') ?></button>
133
- </div>
134
-
135
- <div id="tnpc-blocks" class="tabcontent">
136
- <?php foreach ($blocks as $k => $section) { ?>
137
- <div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
138
- <!--<h4><span><?php echo ucfirst($k) ?></span></h4>-->
139
- <?php foreach ($section AS $key => $block) { ?>
140
- <div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $key ?>" data-name="<?php echo esc_attr($block['name']) ?>">
141
- <img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
142
- </div>
143
- <?php } ?>
144
- </div>
145
- <?php } ?>
146
- </div>
147
-
148
- <div id="tnpc-global-styles" class="tabcontent">
149
-
150
- <form id="tnpc-global-styles-form">
151
-
152
- <div class="tnp-field-row">
153
- <div class="tnp-field-col-2">
154
- <?php $fields->color('options_composer_background', __('Main background', 'newsletter')) ?>
155
- </div>
156
- <div class="tnp-field-col-2">
157
- <?php $fields->color('options_composer_block_background', 'Blocks background') ?>
158
- </div>
159
- </div>
160
-
161
- <?php $fields->font('options_composer_title_font', __('Titles font', 'newsletter')) ?>
162
- <?php $fields->font('options_composer_text_font', __('Text font', 'newsletter')) ?>
163
- <?php $fields->button_style('options_composer_button', __('Button style', 'newsletter')); ?>
164
-
165
- <button class="button-secondary" name="apply"><?php _e("Apply", 'newsletter') ?></button>
166
-
167
- </form>
168
-
169
- </div>
170
-
171
- <!-- Block options container (dynamically loaded -->
172
- <div id="tnpc-block-options">
173
- <div id="tnpc-block-options-buttons">
174
- <span id="tnpc-block-options-cancel" class="button-secondary"><?php _e("Cancel", "newsletter") ?></span>
175
- <span id="tnpc-block-options-save" class="button-primary"><?php _e("Apply", "newsletter") ?></span>
176
- </div>
177
- <form id="tnpc-block-options-form" onsubmit="return false;"></form>
178
- </div>
179
-
180
- </div>
181
-
182
- <div style="clear: both"></div>
183
-
184
- </div>
185
-
186
- <div style="display: none">
187
- <div id="newsletter-preloaded-export"></div>
188
- <!-- Block placeholder used by jQuery UI -->
189
- <div id="draggable-helper"></div>
190
- <div id="sortable-helper"></div>
191
- </div>
192
-
193
- <script type="text/javascript">
194
- TNP_PLUGIN_URL = "<?php echo esc_js(NEWSLETTER_URL) ?>";
195
- TNP_HOME_URL = "<?php echo esc_js(home_url('/', is_ssl() ? 'https' : 'http')) ?>";
196
- tnp_context_type = "<?php echo esc_js($context_type) ?>";
197
- tnp_nonce = '<?php echo esc_js(wp_create_nonce('save')) ?>';
198
- tnp_preset_nonce = '<?php echo esc_js(wp_create_nonce('preset')) ?>';
199
- </script>
200
- <?php
201
- wp_enqueue_script('tnp-composer', plugins_url('newsletter') . '/emails/tnp-composer/_scripts/newsletter-builder-v2.js', ['tnp-modal', 'tnp-toast'], NEWSLETTER_VERSION);
202
- ?>
203
-
204
- <?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
205
-
206
- <?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
+ <script type="text/javascript">
33
+ if (window.innerWidth < 1550) {
34
+ document.body.classList.add('folded');
35
+ }
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_backend_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
+ <?php if (!empty($controls->data['sender_email'])) { ?>
58
+ <tr>
59
+ <th dir="<?php echo $dir ?>"><?php _e('From', 'newsletter') ?></th>
60
+ <td dir="<?php echo $dir ?>"><?php echo esc_html($controls->data['sender_email']) ?></td>
61
+ </tr>
62
+ <?php } ?>
63
+ <tr>
64
+ <th dir="<?php echo $dir ?>">
65
+ <?php _e('Subject', 'newsletter') ?>
66
+ <?php if ($context_type === 'automated') { ?>
67
+ <?php $this->field_help('https://www.thenewsletterplugin.com/documentation/addons/extended-features/automated-extension/#subject') ?>
68
+ <?php } ?>
69
+ </th>
70
+ <td dir="<?php echo $dir ?>">
71
+ <div id="tnpc-subject">
72
+ <?php $this->subject('subject'); ?>
73
+ </div>
74
+ </td>
75
+ </tr>
76
+ <tr>
77
+ <th dir="<?php echo $dir ?>"><span title="<?php esc_attr_e('Shown by some email clients as excerpt', 'newsletter') ?>"><?php _e('Snippet', 'newsletter') ?></span>
78
+ <?php $this->field_help('https://www.thenewsletterplugin.com/documentation/newsletters/composer/#subject') ?>
79
+ </th>
80
+ <td dir="<?php echo $dir ?>"><?php $this->text('preheader') ?></td>
81
+ </tr>
82
+ </table>
83
+
84
+ <div style="text-align: left; margin-left: 1em;">
85
+ <a href="https://www.thenewsletterplugin.com/documentation/newsletters/newsletter-tags/"
86
+ target="_blank">You can use tags to inject subscriber fields</a>. Even on subject.
87
+
88
+
89
+ </div>
90
+
91
+ <div class="composer-actions">
92
+
93
+ <div id="attachment-newsletter-button" class="button-primary" data-tnp-modal-target="#attachment-modal">
94
+ <i class="fas fa-paperclip"></i>
95
+ </div>
96
+ <?php if ($show_test) { ?>
97
+ <div id="test-newsletter-button" class="button-primary" data-tnp-modal-target="#test-newsletter-modal">
98
+ <i class="fas fa-paper-plane"></i> <?php _e('Test', 'newsletter') ?>
99
+ </div>
100
+ <?php } ?>
101
+
102
+ <div class="composer-view-mode">
103
+ <span class="composer-view-mode__item" data-view-mode="desktop">
104
+ <i class="fas fa-desktop"></i>
105
+ </span>
106
+
107
+ <span class="composer-view-mode__item" data-view-mode="mobile">
108
+ <i class="fas fa-mobile"></i>
109
+ <span>
110
+ </div>
111
+
112
+ </div>
113
+
114
+ <?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/test-newsletter.php' ?>
115
+ <?php include NEWSLETTER_DIR . '/emails/tnp-composer/modal/attachment.php' ?>
116
+
117
+ </div>
118
+ <?php } ?>
119
+
120
+
121
+ <div id="newsletter-builder-area-center-frame-content" dir="<?php echo $dir ?>">
122
+
123
+ <!-- Composer content -->
124
+
125
+ </div>
126
+ </div>
127
+
128
+ <div id="newsletter-builder-sidebar" dir="<?php echo is_rtl() ? 'rtl' : 'ltr' ?>">
129
+
130
+ <div class="tnpc-tabs">
131
+ <button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" data-tab-id='tnpc-blocks' id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
132
+ <button class="tablinks" onclick="openTab(event, 'tnpc-global-styles')" data-tab-id='tnpc-global-styles'><?php _e('Settings', 'newsletter') ?></button>
133
+ </div>
134
+
135
+ <div id="tnpc-blocks" class="tabcontent">
136
+ <?php foreach ($blocks as $k => $section) { ?>
137
+ <div class="newsletter-sidebar-add-buttons" id="sidebar-add-<?php echo $k ?>">
138
+ <!--<h4><span><?php echo ucfirst($k) ?></span></h4>-->
139
+ <?php foreach ($section AS $key => $block) { ?>
140
+ <div class="newsletter-sidebar-buttons-content-tab" data-id="<?php echo $key ?>" data-name="<?php echo esc_attr($block['name']) ?>">
141
+ <img src="<?php echo $block['icon'] ?>" title="<?php echo esc_attr($block['name']) ?>">
142
+ </div>
143
+ <?php } ?>
144
+ </div>
145
+ <?php } ?>
146
+ </div>
147
+
148
+ <div id="tnpc-global-styles" class="tabcontent">
149
+
150
+ <form id="tnpc-global-styles-form">
151
+
152
+ <div class="tnp-field-row">
153
+ <div class="tnp-field-col-2">
154
+ <?php $fields->color('options_composer_background', __('Main background', 'newsletter')) ?>
155
+ </div>
156
+ <div class="tnp-field-col-2">
157
+ <?php $fields->color('options_composer_block_background', 'Blocks background') ?>
158
+ </div>
159
+ </div>
160
+
161
+ <?php $fields->font('options_composer_title_font', __('Titles font', 'newsletter')) ?>
162
+ <?php $fields->font('options_composer_text_font', __('Text font', 'newsletter')) ?>
163
+ <?php $fields->button_style('options_composer_button', __('Button style', 'newsletter')); ?>
164
+
165
+ <button class="button-secondary" name="apply"><?php _e("Apply", 'newsletter') ?></button>
166
+
167
+ </form>
168
+
169
+ </div>
170
+
171
+ <!-- Block options container (dynamically loaded -->
172
+ <div id="tnpc-block-options">
173
+ <div id="tnpc-block-options-buttons">
174
+ <span id="tnpc-block-options-cancel" class="button-secondary"><?php _e("Cancel", "newsletter") ?></span>
175
+ <span id="tnpc-block-options-save" class="button-primary"><?php _e("Apply", "newsletter") ?></span>
176
+ </div>
177
+ <form id="tnpc-block-options-form" onsubmit="return false;"></form>
178
+ </div>
179
+
180
+ </div>
181
+
182
+ <div style="clear: both"></div>
183
+
184
+ </div>
185
+
186
+ <div style="display: none">
187
+ <div id="newsletter-preloaded-export"></div>
188
+ <!-- Block placeholder used by jQuery UI -->
189
+ <div id="draggable-helper"></div>
190
+ <div id="sortable-helper"></div>
191
+ </div>
192
+
193
+ <script type="text/javascript">
194
+ TNP_PLUGIN_URL = "<?php echo esc_js(NEWSLETTER_URL) ?>";
195
+ TNP_HOME_URL = "<?php echo esc_js(home_url('/', is_ssl() ? 'https' : 'http')) ?>";
196
+ tnp_context_type = "<?php echo esc_js($context_type) ?>";
197
+ tnp_nonce = '<?php echo esc_js(wp_create_nonce('save')) ?>';
198
+ tnp_preset_nonce = '<?php echo esc_js(wp_create_nonce('preset')) ?>';
199
+ </script>
200
+ <?php
201
+ wp_enqueue_script('tnp-composer', plugins_url('newsletter') . '/emails/tnp-composer/_scripts/newsletter-builder-v2.js', ['tnp-modal', 'tnp-toast'], NEWSLETTER_VERSION);
202
+ ?>
203
+
204
+ <?php include NEWSLETTER_DIR . '/emails/subjects.php'; ?>
205
+
206
+ <?php if (function_exists('wp_enqueue_editor')) wp_enqueue_editor(); ?>
includes/helper.php CHANGED
@@ -1,417 +1,414 @@
1
- <?php
2
-
3
- defined('ABSPATH') || exit;
4
-
5
- function tnp_post_thumbnail_src($post, $size = 'thumbnail', $alternative = '') {
6
- if (is_object($post)) {
7
- $post = $post->ID;
8
- }
9
-
10
- // Find a media id to be used as featured image
11
- $media_id = get_post_thumbnail_id($post);
12
- if (empty($media_id)) {
13
- $attachments = get_children(array('numberpost' => 1, 'post_parent' => $post, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order'));
14
- if (!empty($attachments)) {
15
- foreach ($attachments as $id => &$attachment) {
16
- $media_id = $id;
17
- break;
18
- }
19
- }
20
- }
21
-
22
- if (!$media_id) {
23
- return $alternative;
24
- }
25
-
26
- if (!defined('NEWSLETTER_MEDIA_RESIZE') || NEWSLETTER_MEDIA_RESIZE) {
27
- if (is_array($size)) {
28
- $src = tnp_media_resize($media_id, $size);
29
- if (is_wp_error($src)) {
30
- Newsletter::instance()->logger->error($src);
31
- return $alternative;
32
- } else {
33
- return $src;
34
- }
35
- }
36
- }
37
-
38
- $media = wp_get_attachment_image_src($media_id, $size);
39
- if (strpos($media[0], 'http') !== 0) {
40
- $media[0] = 'http:' . $media[0];
41
- }
42
- return $media[0];
43
- }
44
-
45
- /**
46
- * @param WP_Post $post
47
- * @param int $length
48
- *
49
- * @return string
50
- */
51
- function tnp_post_excerpt($post, $length = 30, $characters = false) {
52
- if (!$length) return '';
53
-
54
- $excerpt = get_the_excerpt($post->ID);
55
- $excerpt = tnp_delete_all_shordcodes_tags($excerpt);
56
- $excerpt = trim($excerpt);
57
- $excerpt = str_replace('&nbsp;', '', $excerpt);
58
-
59
- if ($characters) {
60
- if (strlen($excerpt) > $length) {
61
- $excerpt = substr($excerpt, 0, $length);
62
- $i = strrpos($excerpt, ' ');
63
- if ($i) {
64
- $excerpt = substr($excerpt, 0, $i);
65
- $excerpt .= '&hellip;';
66
- }
67
- }
68
- } else {
69
- $excerpt = wp_trim_words($excerpt, $length);
70
- }
71
-
72
- return $excerpt;
73
- }
74
-
75
- function tnp_delete_all_shordcodes_tags($post_content = '') {
76
- //Delete open tags
77
- $post_content = preg_replace("/\[[a-zA-Z0-9_-]*?(\s.*?)?\]/", '', $post_content);
78
- //Delete close tags
79
- $post_content = preg_replace("/\[\/[a-zA-Z0-9_-]*?\]/", '', $post_content);
80
-
81
- return $post_content;
82
- }
83
-
84
- function tnp_post_permalink($post) {
85
- return get_permalink($post->ID);
86
- }
87
-
88
- function tnp_post_content($post) {
89
- return $post->post_content;
90
- }
91
-
92
- function tnp_post_title($post) {
93
- return $post->post_title;
94
- }
95
-
96
- function tnp_post_date($post, $format = null) {
97
- if (empty($format)) {
98
- $format = get_option('date_format');
99
- }
100
- return mysql2date($format, $post->post_date);
101
- }
102
-
103
- /**
104
- * Tries to create a resized version of a media uploaded to the media library.
105
- * Returns an empty string if the media does not exists or generally if the attached file
106
- * cannot be found. If the resize fails for whatever reason, fall backs to the
107
- * standard image source returned by WP which is usually not exactly the
108
- * requested size.
109
- *
110
- * @param int $media_id
111
- * @param array $size
112
- * @return string
113
- */
114
- function tnp_media_resize($media_id, $size) {
115
- if (empty($media_id)) {
116
- return '';
117
- }
118
-
119
- $relative_file = get_post_meta($media_id, '_wp_attached_file', true);
120
- if (empty($relative_file)) {
121
- return '';
122
- }
123
-
124
- $width = $size[0];
125
- $height = $size[1];
126
- $crop = false;
127
- if (isset($size[2])) {
128
- $crop = (boolean) $size[2];
129
- }
130
-
131
- $uploads = wp_upload_dir();
132
-
133
- // Based on _wp_relative_upload_path() function for blog which store the
134
- // full patch of media files
135
- if (0 === strpos($relative_file, $uploads['basedir'])) {
136
- $relative_file = str_replace($uploads['basedir'], '', $relative_file);
137
- $relative_file = ltrim($relative_file, '/');
138
- }
139
-
140
- $absolute_file = $uploads['basedir'] . '/' . $relative_file;
141
- // Relative and absolute name of the thumbnail.
142
- $pathinfo = pathinfo($relative_file);
143
-
144
- // We don't know why, but on some systems files with non-ascii characters loose the file name (grrr...)
145
- if (empty($pathinfo['filename'])) {
146
- $src = wp_get_attachment_image_src($media_id, 'full');
147
- return $src[0];
148
- }
149
-
150
- $relative_thumb = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $width . 'x' .
151
- $height . ($crop ? '-c' : '') . '.' . $pathinfo['extension'];
152
- $absolute_thumb = $uploads['basedir'] . '/newsletter/thumbnails/' . $relative_thumb;
153
-
154
- // Thumbnail generation if needed.
155
- if (!file_exists($absolute_thumb) || filemtime($absolute_thumb) < filemtime($absolute_file)) {
156
- $r = wp_mkdir_p($uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
157
-
158
- if (!$r) {
159
- $src = wp_get_attachment_image_src($media_id, 'full');
160
- return $src[0];
161
- }
162
-
163
- $editor = wp_get_image_editor($absolute_file);
164
- if (is_wp_error($editor)) {
165
- $src = wp_get_attachment_image_src($media_id, 'full');
166
- return $src[0];
167
- //return $editor;
168
- //return $uploads['baseurl'] . '/' . $relative_file;
169
- }
170
-
171
- $original_size = $editor->get_size();
172
- if ($width > $original_size['width'] || $height > $original_size['height']) {
173
- $src = wp_get_attachment_image_src($media_id, 'full');
174
- return $src[0];
175
- }
176
-
177
- $editor->set_quality(80);
178
- $resized = $editor->resize($width, $height, $crop);
179
-
180
- if (is_wp_error($resized)) {
181
- $src = wp_get_attachment_image_src($media_id, 'full');
182
- return $src[0];
183
- }
184
-
185
- $saved = $editor->save($absolute_thumb);
186
- if (is_wp_error($saved)) {
187
- $src = wp_get_attachment_image_src($media_id, 'full');
188
- return $src[0];
189
- //return $saved;
190
- //return $uploads['baseurl'] . '/' . $relative_file;
191
- }
192
- }
193
-
194
- return $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
195
- }
196
-
197
- function _tnp_get_default_media($media_id, $size) {
198
-
199
- $src = wp_get_attachment_image_src($media_id, $size);
200
- if (!$src) {
201
- return null;
202
- }
203
- $media = new TNP_Media();
204
- $media->id = $media_id;
205
- $media->url = $src[0];
206
- $media->width = $src[1];
207
- $media->height = $src[2];
208
- return $media;
209
- }
210
-
211
- function tnp_get_media($media_id, $size) {
212
- $src = wp_get_attachment_image_src($media_id, $size);
213
- if (!$src) {
214
- return null;
215
- }
216
- $media = new TNP_Media();
217
- $media->id = $media_id;
218
- $media->url = $src[0];
219
- $media->width = $src[1];
220
- $media->height = $src[2];
221
- return $media;
222
- }
223
-
224
- /**
225
- * Create a resized version of the media stored in the WP media library.
226
- *
227
- * @param int $media_id
228
- * @param array $size
229
- * @return TNP_Media
230
- */
231
- function tnp_resize($media_id, $size) {
232
- if (empty($media_id)) {
233
- return null;
234
- }
235
-
236
- $relative_file = get_post_meta($media_id, '_wp_attached_file', true);
237
-
238
- if (empty($relative_file)) {
239
- return null;
240
- }
241
-
242
- $uploads = wp_upload_dir();
243
-
244
- // Based on _wp_relative_upload_path() function for blog which store the
245
- // full path of media files
246
- if (0 === strpos($relative_file, $uploads['basedir'])) {
247
- $relative_file = str_replace($uploads['basedir'], '', $relative_file);
248
- $relative_file = ltrim($relative_file, '/');
249
- }
250
-
251
- $width = $size[0];
252
- $height = $size[1];
253
- $crop = false;
254
- if (isset($size[2])) {
255
- $crop = (boolean) $size[2];
256
- }
257
-
258
- $absolute_file = $uploads['basedir'] . '/' . $relative_file;
259
-
260
- if (substr($relative_file, -4) === '.gif') {
261
- $editor = wp_get_image_editor($absolute_file);
262
- if (is_wp_error($editor)) {
263
- return _tnp_get_default_media($media_id, $size);
264
- }
265
- $new_size = $editor->get_size();
266
- $media = new TNP_Media();
267
- $media->id = $media_id;
268
- $media->width = $new_size['width'];
269
- $media->height = $new_size['height'];
270
- if ($media->width > $width) {
271
- $media->set_width($width);
272
- }
273
- $media->url = $uploads['baseurl'] . '/' . $relative_file;
274
- return $media;
275
- }
276
-
277
- // Relative and absolute name of the thumbnail.
278
- $pathinfo = pathinfo($relative_file);
279
-
280
- // We don't know why, but on some systems files with non-ascii characters loose the file name (grrr...)
281
- if (empty($pathinfo['filename'])) {
282
- return _tnp_get_default_media($media_id, $size);
283
- }
284
-
285
- $relative_thumb = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $pathinfo['extension'];
286
- $absolute_thumb = $uploads['basedir'] . '/newsletter/thumbnails/' . $relative_thumb;
287
-
288
- // Thumbnail generation if needed.
289
- if (!file_exists($absolute_thumb) || filemtime($absolute_thumb) < filemtime($absolute_file)) {
290
- $r = wp_mkdir_p($uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
291
-
292
- if (!$r) {
293
- Newsletter::instance()->logger->error('Unable to create dir ' . $uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
294
- return _tnp_get_default_media($media_id, $size);
295
- }
296
-
297
- $editor = wp_get_image_editor($absolute_file);
298
- if (is_wp_error($editor)) {
299
- Newsletter::instance()->logger->error($editor);
300
- Newsletter::instance()->logger->error('File: ' . $absolute_file);
301
- return _tnp_get_default_media($media_id, $size);
302
- }
303
-
304
- $original_size = $editor->get_size();
305
- if ($width > $original_size['width'] && ($height > $original_size['height'] || $height == 0)) {
306
- Newsletter::instance()->logger->error('Requested size larger than the original one');
307
- return _tnp_get_default_media($media_id, $size);
308
- }
309
-
310
- if ($height > $original_size['height'] && ($width > $original_size['width'] || $width == 0)) {
311
- Newsletter::instance()->logger->error('Requested size larger than the original one');
312
- return _tnp_get_default_media($media_id, $size);
313
- }
314
-
315
- $editor->set_quality(85);
316
- $resized = $editor->resize($width, $height, $crop);
317
-
318
- if (is_wp_error($resized)) {
319
- Newsletter::instance()->logger->error($resized);
320
- Newsletter::instance()->logger->error('File: ' . $absolute_file);
321
- return _tnp_get_default_media($media_id, $size);
322
- }
323
-
324
- $saved = $editor->save($absolute_thumb);
325
- if (is_wp_error($saved)) {
326
- Newsletter::instance()->logger->error($saved);
327
- return _tnp_get_default_media($media_id, $size);
328
- }
329
- $new_size = $editor->get_size();
330
-
331
- $media = new TNP_Media();
332
- $media->width = $new_size['width'];
333
- $media->height = $new_size['height'];
334
- $media->url = $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
335
- } else {
336
- $media = new TNP_Media();
337
- $new_size = getimagesize($absolute_thumb);
338
- $media->width = $new_size[0];
339
- $media->height = $new_size[1];
340
- $media->url = $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
341
- }
342
-
343
- return $media;
344
- }
345
-
346
- function tnp_resize_2x($media_id, $size) {
347
- $size[0] = $size[0] * 2;
348
- $size[1] = $size[1] * 2;
349
- $media = tnp_resize($media_id, $size);
350
- if (!$media)
351
- return $media;
352
- $media->set_width($size[0] / 2);
353
- return $media;
354
- }
355
-
356
- /**
357
- * @param TNP_Media[] $images
358
- *
359
- * @return int
360
- */
361
- function tnp_get_max_height_of($images) {
362
- $max_height = 0;
363
- foreach ($images as $image) {
364
- $max_height = $image->height > $max_height ? $image->height : $max_height;
365
- }
366
-
367
- return $max_height;
368
- }
369
-
370
- /**
371
- * @param WP_Post[] $product_list
372
- * @param array $size
373
- *
374
- * @return TNP_Media[]
375
- */
376
- function tnp_resize_product_list_featured_image($product_list, $size) {
377
- $images = [];
378
- foreach ($product_list as $p) {
379
- $images[$p->ID] = tnp_resize_2x(TNP_Composer::get_post_thumbnail_id($p->ID), $size);
380
- }
381
-
382
- return $images;
383
- }
384
-
385
- /**
386
- * Get media for "posts" composer block
387
- *
388
- * @param WP_Post post
389
- * @param array $size
390
- * @param string $default_image_url
391
- *
392
- * @return TNP_Media
393
- */
394
- function tnp_composer_block_posts_get_media($post, $size, $default_image_url = null) {
395
- $post_thumbnail_id = TNP_Composer::get_post_thumbnail_id($post);
396
-
397
- $media = null;
398
-
399
- if (!empty($post_thumbnail_id)) {
400
- $media = tnp_resize($post_thumbnail_id, array_values($size));
401
- } else if ($default_image_url) {
402
- Newsletter::instance()->logger->error('Thumbnail id not found');
403
- $media = new TNP_Media();
404
- $media->url = $default_image_url;
405
- $media->width = $size['width'];
406
- $media->height = $size['height'];
407
- }
408
- return $media;
409
- }
410
-
411
- function tnp_outlook_wrapper_open($width = 600) {
412
- return NewsletterEmails::get_outlook_wrapper_open($width);
413
- }
414
-
415
- function tnp_outlook_wrapper_close() {
416
- return NewsletterEmails::get_outlook_wrapper_close();
417
- }
1
+ <?php
2
+
3
+ defined('ABSPATH') || exit;
4
+
5
+ function tnp_post_thumbnail_src($post, $size = 'thumbnail', $alternative = '') {
6
+ if (is_object($post)) {
7
+ $post = $post->ID;
8
+ }
9
+
10
+ // Find a media id to be used as featured image
11
+ $media_id = get_post_thumbnail_id($post);
12
+ if (empty($media_id)) {
13
+ $attachments = get_children(array('numberpost' => 1, 'post_parent' => $post, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order'));
14
+ if (!empty($attachments)) {
15
+ foreach ($attachments as $id => &$attachment) {
16
+ $media_id = $id;
17
+ break;
18
+ }
19
+ }
20
+ }
21
+
22
+ if (!$media_id) {
23
+ return $alternative;
24
+ }
25
+
26
+ if (!defined('NEWSLETTER_MEDIA_RESIZE') || NEWSLETTER_MEDIA_RESIZE) {
27
+ if (is_array($size)) {
28
+ $src = tnp_media_resize($media_id, $size);
29
+ if (is_wp_error($src)) {
30
+ Newsletter::instance()->logger->error($src);
31
+ return $alternative;
32
+ } else {
33
+ return $src;
34
+ }
35
+ }
36
+ }
37
+
38
+ $media = wp_get_attachment_image_src($media_id, $size);
39
+ if (strpos($media[0], 'http') !== 0) {
40
+ $media[0] = 'http:' . $media[0];
41
+ }
42
+ return $media[0];
43
+ }
44
+
45
+ /**
46
+ * @param WP_Post $post
47
+ * @param int $length
48
+ *
49
+ * @return string
50
+ */
51
+ function tnp_post_excerpt($post, $length = 30, $characters = false) {
52
+ if (!$length) return '';
53
+
54
+ $excerpt = get_the_excerpt($post->ID);
55
+ $excerpt = tnp_delete_all_shordcodes_tags($excerpt);
56
+ $excerpt = trim($excerpt);
57
+ $excerpt = str_replace('&nbsp;', '', $excerpt);
58
+
59
+ if ($characters) {
60
+ if (strlen($excerpt) > $length) {
61
+ $excerpt = substr($excerpt, 0, $length);
62
+ $i = strrpos($excerpt, ' ');
63
+ if ($i) {
64
+ $excerpt = substr($excerpt, 0, $i);
65
+ $excerpt .= '&hellip;';
66
+ }
67
+ }
68
+ } else {
69
+ $excerpt = wp_trim_words($excerpt, $length);
70
+ }
71
+
72
+ return $excerpt;
73
+ }
74
+
75
+ function tnp_delete_all_shordcodes_tags($post_content = '') {
76
+ //Delete open tags
77
+ $post_content = preg_replace("/\[[a-zA-Z0-9_-]*?(\s.*?)?\]/", '', $post_content);
78
+ //Delete close tags
79
+ $post_content = preg_replace("/\[\/[a-zA-Z0-9_-]*?\]/", '', $post_content);
80
+
81
+ return $post_content;
82
+ }
83
+
84
+ function tnp_post_permalink($post) {
85
+ return get_permalink($post->ID);
86
+ }
87
+
88
+ function tnp_post_content($post) {
89
+ return $post->post_content;
90
+ }
91
+
92
+ function tnp_post_title($post) {
93
+ return $post->post_title;
94
+ }
95
+
96
+ function tnp_post_date($post, $format = null) {
97
+ return get_the_date( $format, $post );
98
+ }
99
+
100
+ /**
101
+ * Tries to create a resized version of a media uploaded to the media library.
102
+ * Returns an empty string if the media does not exists or generally if the attached file
103
+ * cannot be found. If the resize fails for whatever reason, fall backs to the
104
+ * standard image source returned by WP which is usually not exactly the
105
+ * requested size.
106
+ *
107
+ * @param int $media_id
108
+ * @param array $size
109
+ * @return string
110
+ */
111
+ function tnp_media_resize($media_id, $size) {
112
+ if (empty($media_id)) {
113
+ return '';
114
+ }
115
+
116
+ $relative_file = get_post_meta($media_id, '_wp_attached_file', true);
117
+ if (empty($relative_file)) {
118
+ return '';
119
+ }
120
+
121
+ $width = $size[0];
122
+ $height = $size[1];
123
+ $crop = false;
124
+ if (isset($size[2])) {
125
+ $crop = (boolean) $size[2];
126
+ }
127
+
128
+ $uploads = wp_upload_dir();
129
+
130
+ // Based on _wp_relative_upload_path() function for blog which store the
131
+ // full patch of media files
132
+ if (0 === strpos($relative_file, $uploads['basedir'])) {
133
+ $relative_file = str_replace($uploads['basedir'], '', $relative_file);
134
+ $relative_file = ltrim($relative_file, '/');
135
+ }
136
+
137
+ $absolute_file = $uploads['basedir'] . '/' . $relative_file;
138
+ // Relative and absolute name of the thumbnail.
139
+ $pathinfo = pathinfo($relative_file);
140
+
141
+ // We don't know why, but on some systems files with non-ascii characters loose the file name (grrr...)
142
+ if (empty($pathinfo['filename'])) {
143
+ $src = wp_get_attachment_image_src($media_id, 'full');
144
+ return $src[0];
145
+ }
146
+
147
+ $relative_thumb = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $width . 'x' .
148
+ $height . ($crop ? '-c' : '') . '.' . $pathinfo['extension'];
149
+ $absolute_thumb = $uploads['basedir'] . '/newsletter/thumbnails/' . $relative_thumb;
150
+
151
+ // Thumbnail generation if needed.
152
+ if (!file_exists($absolute_thumb) || filemtime($absolute_thumb) < filemtime($absolute_file)) {
153
+ $r = wp_mkdir_p($uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
154
+
155
+ if (!$r) {
156
+ $src = wp_get_attachment_image_src($media_id, 'full');
157
+ return $src[0];
158
+ }
159
+
160
+ $editor = wp_get_image_editor($absolute_file);
161
+ if (is_wp_error($editor)) {
162
+ $src = wp_get_attachment_image_src($media_id, 'full');
163
+ return $src[0];
164
+ //return $editor;
165
+ //return $uploads['baseurl'] . '/' . $relative_file;
166
+ }
167
+
168
+ $original_size = $editor->get_size();
169
+ if ($width > $original_size['width'] || $height > $original_size['height']) {
170
+ $src = wp_get_attachment_image_src($media_id, 'full');
171
+ return $src[0];
172
+ }
173
+
174
+ $editor->set_quality(80);
175
+ $resized = $editor->resize($width, $height, $crop);
176
+
177
+ if (is_wp_error($resized)) {
178
+ $src = wp_get_attachment_image_src($media_id, 'full');
179
+ return $src[0];
180
+ }
181
+
182
+ $saved = $editor->save($absolute_thumb);
183
+ if (is_wp_error($saved)) {
184
+ $src = wp_get_attachment_image_src($media_id, 'full');
185
+ return $src[0];
186
+ //return $saved;
187
+ //return $uploads['baseurl'] . '/' . $relative_file;
188
+ }
189
+ }
190
+
191
+ return $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
192
+ }
193
+
194
+ function _tnp_get_default_media($media_id, $size) {
195
+
196
+ $src = wp_get_attachment_image_src($media_id, $size);
197
+ if (!$src) {
198
+ return null;
199
+ }
200
+ $media = new TNP_Media();
201
+ $media->id = $media_id;
202
+ $media->url = $src[0];
203
+ $media->width = $src[1];
204
+ $media->height = $src[2];
205
+ return $media;
206
+ }
207
+
208
+ function tnp_get_media($media_id, $size) {
209
+ $src = wp_get_attachment_image_src($media_id, $size);
210
+ if (!$src) {
211
+ return null;
212
+ }
213
+ $media = new TNP_Media();
214
+ $media->id = $media_id;
215
+ $media->url = $src[0];
216
+ $media->width = $src[1];
217
+ $media->height = $src[2];
218
+ return $media;
219
+ }
220
+
221
+ /**
222
+ * Create a resized version of the media stored in the WP media library.
223
+ *
224
+ * @param int $media_id
225
+ * @param array $size
226
+ * @return TNP_Media
227
+ */
228
+ function tnp_resize($media_id, $size) {
229
+ if (empty($media_id)) {
230
+ return null;
231
+ }
232
+
233
+ $relative_file = get_post_meta($media_id, '_wp_attached_file', true);
234
+
235
+ if (empty($relative_file)) {
236
+ return null;
237
+ }
238
+
239
+ $uploads = wp_upload_dir();
240
+
241
+ // Based on _wp_relative_upload_path() function for blog which store the
242
+ // full path of media files
243
+ if (0 === strpos($relative_file, $uploads['basedir'])) {
244
+ $relative_file = str_replace($uploads['basedir'], '', $relative_file);
245
+ $relative_file = ltrim($relative_file, '/');
246
+ }
247
+
248
+ $width = $size[0];
249
+ $height = $size[1];
250
+ $crop = false;
251
+ if (isset($size[2])) {
252
+ $crop = (boolean) $size[2];
253
+ }
254
+
255
+ $absolute_file = $uploads['basedir'] . '/' . $relative_file;
256
+
257
+ if (substr($relative_file, -4) === '.gif') {
258
+ $editor = wp_get_image_editor($absolute_file);
259
+ if (is_wp_error($editor)) {
260
+ return _tnp_get_default_media($media_id, $size);
261
+ }
262
+ $new_size = $editor->get_size();
263
+ $media = new TNP_Media();
264
+ $media->id = $media_id;
265
+ $media->width = $new_size['width'];
266
+ $media->height = $new_size['height'];
267
+ if ($media->width > $width) {
268
+ $media->set_width($width);
269
+ }
270
+ $media->url = $uploads['baseurl'] . '/' . $relative_file;
271
+ return $media;
272
+ }
273
+
274
+ // Relative and absolute name of the thumbnail.
275
+ $pathinfo = pathinfo($relative_file);
276
+
277
+ // We don't know why, but on some systems files with non-ascii characters loose the file name (grrr...)
278
+ if (empty($pathinfo['filename'])) {
279
+ return _tnp_get_default_media($media_id, $size);
280
+ }
281
+
282
+ $relative_thumb = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $pathinfo['extension'];
283
+ $absolute_thumb = $uploads['basedir'] . '/newsletter/thumbnails/' . $relative_thumb;
284
+
285
+ // Thumbnail generation if needed.
286
+ if (!file_exists($absolute_thumb) || filemtime($absolute_thumb) < filemtime($absolute_file)) {
287
+ $r = wp_mkdir_p($uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
288
+
289
+ if (!$r) {
290
+ Newsletter::instance()->logger->error('Unable to create dir ' . $uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
291
+ return _tnp_get_default_media($media_id, $size);
292
+ }
293
+
294
+ $editor = wp_get_image_editor($absolute_file);
295
+ if (is_wp_error($editor)) {
296
+ Newsletter::instance()->logger->error($editor);
297
+ Newsletter::instance()->logger->error('File: ' . $absolute_file);
298
+ return _tnp_get_default_media($media_id, $size);
299
+ }
300
+
301
+ $original_size = $editor->get_size();
302
+ if ($width > $original_size['width'] && ($height > $original_size['height'] || $height == 0)) {
303
+ Newsletter::instance()->logger->error('Requested size larger than the original one');
304
+ return _tnp_get_default_media($media_id, $size);
305
+ }
306
+
307
+ if ($height > $original_size['height'] && ($width > $original_size['width'] || $width == 0)) {
308
+ Newsletter::instance()->logger->error('Requested size larger than the original one');
309
+ return _tnp_get_default_media($media_id, $size);
310
+ }
311
+
312
+ $editor->set_quality(85);
313
+ $resized = $editor->resize($width, $height, $crop);
314
+
315
+ if (is_wp_error($resized)) {
316
+ Newsletter::instance()->logger->error($resized);
317
+ Newsletter::instance()->logger->error('File: ' . $absolute_file);
318
+ return _tnp_get_default_media($media_id, $size);
319
+ }
320
+
321
+ $saved = $editor->save($absolute_thumb);
322
+ if (is_wp_error($saved)) {
323
+ Newsletter::instance()->logger->error($saved);
324
+ return _tnp_get_default_media($media_id, $size);
325
+ }
326
+ $new_size = $editor->get_size();
327
+
328
+ $media = new TNP_Media();
329
+ $media->width = $new_size['width'];
330
+ $media->height = $new_size['height'];
331
+ $media->url = $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
332
+ } else {
333
+ $media = new TNP_Media();
334
+ $new_size = getimagesize($absolute_thumb);
335
+ $media->width = $new_size[0];
336
+ $media->height = $new_size[1];
337
+ $media->url = $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
338
+ }
339
+
340
+ return $media;
341
+ }
342
+
343
+ function tnp_resize_2x($media_id, $size) {
344
+ $size[0] = $size[0] * 2;
345
+ $size[1] = $size[1] * 2;
346
+ $media = tnp_resize($media_id, $size);
347
+ if (!$media)
348
+ return $media;
349
+ $media->set_width($size[0] / 2);
350
+ return $media;
351
+ }
352
+
353
+ /**
354
+ * @param TNP_Media[] $images
355
+ *
356
+ * @return int
357
+ */
358
+ function tnp_get_max_height_of($images) {
359
+ $max_height = 0;
360
+ foreach ($images as $image) {
361
+ $max_height = $image->height > $max_height ? $image->height : $max_height;
362
+ }
363
+
364
+ return $max_height;
365
+ }
366
+
367
+ /**
368
+ * @param WP_Post[] $product_list
369
+ * @param array $size
370
+ *
371
+ * @return TNP_Media[]
372
+ */
373
+ function tnp_resize_product_list_featured_image($product_list, $size) {
374
+ $images = [];
375
+ foreach ($product_list as $p) {
376
+ $images[$p->ID] = tnp_resize_2x(TNP_Composer::get_post_thumbnail_id($p->ID), $size);
377
+ }
378
+
379
+ return $images;
380
+ }
381
+
382
+ /**
383
+ * Get media for "posts" composer block
384
+ *
385
+ * @param WP_Post post
386
+ * @param array $size
387
+ * @param string $default_image_url
388
+ *
389
+ * @return TNP_Media
390
+ */
391
+ function tnp_composer_block_posts_get_media($post, $size, $default_image_url = null) {
392
+ $post_thumbnail_id = TNP_Composer::get_post_thumbnail_id($post);
393
+
394
+ $media = null;
395
+
396
+ if (!empty($post_thumbnail_id)) {
397
+ $media = tnp_resize($post_thumbnail_id, array_values($size));
398
+ } else if ($default_image_url) {
399
+ Newsletter::instance()->logger->error('Thumbnail id not found');
400
+ $media = new TNP_Media();
401
+ $media->url = $default_image_url;
402
+ $media->width = $size['width'];
403
+ $media->height = $size['height'];
404
+ }
405
+ return $media;
406
+ }
407
+
408
+ function tnp_outlook_wrapper_open($width = 600) {
409
+ return NewsletterEmails::get_outlook_wrapper_open($width);
410
+ }
411
+
412
+ function tnp_outlook_wrapper_close() {
413
+ return NewsletterEmails::get_outlook_wrapper_close();
414
+ }
 
 
 
includes/module.php CHANGED
@@ -21,9 +21,11 @@ class TNP_Media {
21
 
22
  /** Sets the width recalculating the height */
23
  public function set_width($width) {
24
- $width = (int)$width;
25
- if (empty($width)) return;
26
- if ($this->width < $width) return;
 
 
27
  $this->height = floor(($width / $this->width) * $this->height);
28
  $this->width = $width;
29
  }
@@ -310,11 +312,11 @@ class TNP_Subscription {
310
  public function __construct() {
311
  $this->data = new TNP_Subscription_Data();
312
  }
313
-
314
  public function is_single_optin() {
315
  return $this->optin == 'single';
316
  }
317
-
318
  public function is_double_optin() {
319
  return $this->optin == 'double';
320
  }
@@ -338,7 +340,7 @@ class TNP_User {
338
  const STATUS_UNSUBSCRIBED = 'U';
339
  const STATUS_BOUNCED = 'B';
340
  const STATUS_COMPLAINED = 'P';
341
-
342
  var $ip = '';
343
 
344
  public static function get_status_label($status) {
@@ -971,42 +973,58 @@ class NewsletterModule {
971
  return false;
972
  }
973
  if (empty($list)) {
974
- return array();
975
  }
976
  return $list;
977
  }
978
 
979
- /**
980
- * @param string $key
981
- * @param mixed $value
982
- * @return TNP_Email[]
983
- */
984
- function get_emails_by_field($key, $value) {
985
  global $wpdb;
 
986
 
987
- $value_placeholder = is_int($value) ? '%d' : '%s';
988
-
989
- $query = $wpdb->prepare("SELECT * FROM " . NEWSLETTER_EMAILS_TABLE . " WHERE %1s=$value_placeholder ORDER BY id DESC", $key, $value);
990
-
991
- $email_list = $wpdb->get_results($query);
992
-
993
- if ($wpdb->last_error) {
994
- $this->logger->error($wpdb->last_error);
995
-
996
- return [];
997
- }
998
-
999
- //Unserialize options
1000
- array_walk($email_list, function ($email) {
1001
  $email->options = maybe_unserialize($email->options);
1002
  if (!is_array($email->options)) {
1003
  $email->options = [];
1004
  }
1005
  });
1006
-
1007
- return $email_list;
1008
  }
1009
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1010
  /**
1011
  * Retrieves an email from DB and unserialize the options.
1012
  *
@@ -1348,8 +1366,9 @@ class NewsletterModule {
1348
  }
1349
 
1350
  function get_user_status_label($user, $html = false) {
1351
- if (!$html) return TNP_User::get_status_label($user->status);
1352
-
 
1353
  $label = TNP_User::get_status_label($user->status);
1354
  $class = 'unknown';
1355
  switch ($user->status) {
@@ -1836,7 +1855,7 @@ class NewsletterModule {
1836
  }
1837
 
1838
  function process_ip($ip) {
1839
-
1840
  $option = Newsletter::instance()->options['ip'];
1841
  if (empty($option)) {
1842
  return $ip;
@@ -2329,13 +2348,14 @@ class NewsletterModule {
2329
  return '';
2330
  }
2331
  $ip = preg_replace('/[^0-9a-fA-F:., ]/', '', trim($ip));
2332
- if (strlen($ip) > 50) $ip = substr($ip, 0, 50);
2333
-
 
2334
  // When more than one IP is present due to firewalls, proxies, and so on. The first one should be the origin.
2335
  if (strpos($ip, ',') !== false) {
2336
  list($ip, $tail) = explode(',', $ip, 2);
2337
  }
2338
- return $ip;
2339
  }
2340
 
2341
  static function get_remote_ip() {
21
 
22
  /** Sets the width recalculating the height */
23
  public function set_width($width) {
24
+ $width = (int) $width;
25
+ if (empty($width))
26
+ return;
27
+ if ($this->width < $width)
28
+ return;
29
  $this->height = floor(($width / $this->width) * $this->height);
30
  $this->width = $width;
31
  }
312
  public function __construct() {
313
  $this->data = new TNP_Subscription_Data();
314
  }
315
+
316
  public function is_single_optin() {
317
  return $this->optin == 'single';
318
  }
319
+
320
  public function is_double_optin() {
321
  return $this->optin == 'double';
322
  }
340
  const STATUS_UNSUBSCRIBED = 'U';
341
  const STATUS_BOUNCED = 'B';
342
  const STATUS_COMPLAINED = 'P';
343
+
344
  var $ip = '';
345
 
346
  public static function get_status_label($status) {
973
  return false;
974
  }
975
  if (empty($list)) {
976
+ return [];
977
  }
978
  return $list;
979
  }
980
 
981
+ function get_emails_by_status($status) {
 
 
 
 
 
982
  global $wpdb;
983
+ $list = $wpdb->get_results($wpdb->prepare("select * from " . NEWSLETTER_EMAILS_TABLE . " where status=%s order by id desc", $status));
984
 
985
+ array_walk($list, function ($email) {
 
 
 
 
 
 
 
 
 
 
 
 
 
986
  $email->options = maybe_unserialize($email->options);
987
  if (!is_array($email->options)) {
988
  $email->options = [];
989
  }
990
  });
991
+ return $list;
 
992
  }
993
 
994
+ /**
995
+ * @param string $key
996
+ * @param mixed $value
997
+ * @return TNP_Email[]
998
+ */
999
+ // function get_emails_by_field($key, $value) {
1000
+ // global $wpdb;
1001
+ //
1002
+ // $value_placeholder = is_int($value) ? '%d' : '%s';
1003
+ //
1004
+ // $key = '`' . str_replace('`', '', $key) . '`';
1005
+ //
1006
+ // $query = $wpdb->prepare("SELECT * FROM " . NEWSLETTER_EMAILS_TABLE . " WHERE $key=$value_placeholder ORDER BY id DESC", $value);
1007
+ // //die($query);
1008
+ //
1009
+ // $email_list = $wpdb->get_results($query);
1010
+ //
1011
+ // if ($wpdb->last_error) {
1012
+ // $this->logger->error($wpdb->last_error);
1013
+ //
1014
+ // return [];
1015
+ // }
1016
+ //
1017
+ // //Unserialize options
1018
+ // array_walk($email_list, function ($email) {
1019
+ // $email->options = maybe_unserialize($email->options);
1020
+ // if (!is_array($email->options)) {
1021
+ // $email->options = [];
1022
+ // }
1023
+ // });
1024
+ //
1025
+ // return $email_list;
1026
+ // }
1027
+
1028
  /**
1029
  * Retrieves an email from DB and unserialize the options.
1030
  *
1366
  }
1367
 
1368
  function get_user_status_label($user, $html = false) {
1369
+ if (!$html)
1370
+ return TNP_User::get_status_label($user->status);
1371
+
1372
  $label = TNP_User::get_status_label($user->status);
1373
  $class = 'unknown';
1374
  switch ($user->status) {
1855
  }
1856
 
1857
  function process_ip($ip) {
1858
+
1859
  $option = Newsletter::instance()->options['ip'];
1860
  if (empty($option)) {
1861
  return $ip;
2348
  return '';
2349
  }
2350
  $ip = preg_replace('/[^0-9a-fA-F:., ]/', '', trim($ip));
2351
+ if (strlen($ip) > 50)
2352
+ $ip = substr($ip, 0, 50);
2353
+
2354
  // When more than one IP is present due to firewalls, proxies, and so on. The first one should be the origin.
2355
  if (strpos($ip, ',') !== false) {
2356
  list($ip, $tail) = explode(',', $ip, 2);
2357
  }
2358
+ return $ip;
2359
  }
2360
 
2361
  static function get_remote_ip() {
includes/tnp-blocks.js CHANGED
@@ -1,5 +1,6 @@
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;
1
  (function (blocks, editor, element, components) {
2
 
3
+
4
  const el = element.createElement;
5
  const {registerBlockType} = blocks;
6
  const { RichText, InspectorControls, withColors, PanelColorSettings, getColorClassName, AlignmentToolbar, BlockControls } = editor;
main/main.php CHANGED
@@ -1,382 +1,388 @@
1
- <?php
2
- /* @var $this Newsletter */
3
- defined('ABSPATH') || exit;
4
-
5
- include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
- $controls = new NewsletterControls();
7
-
8
- if (!$controls->is_action()) {
9
- $controls->data = get_option('newsletter_main');
10
- if (!isset($controls->data['roles'])) {
11
- $controls->data['roles'] = array();
12
- if (!empty($controls->data['editor']))
13
- $controls->data['roles'] = 'editor';
14
- }
15
- } else {
16
-
17
- if ($controls->is_action('save')) {
18
- $errors = null;
19
-
20
- if (!isset($controls->data['roles']))
21
- $controls->data['roles'] = array();
22
-
23
- // Validation
24
- $controls->data['sender_email'] = $this->normalize_email($controls->data['sender_email']);
25
- if (!$this->is_email($controls->data['sender_email'])) {
26
- $controls->errors .= __('The sender email address is not correct.', 'newsletter') . '<br>';
27
- } else {
28
- $controls->data['sender_email'] = $this->normalize_email($controls->data['sender_email']);
29
- }
30
-
31
- if (!$this->is_email($controls->data['return_path'], true)) {
32
- $controls->errors .= __('Return path email is not correct.', 'newsletter') . '<br>';
33
- } else {
34
- $controls->data['return_path'] = $this->normalize_email($controls->data['return_path']);
35
- }
36
-
37
- $controls->data['scheduler_max'] = (int) $controls->data['scheduler_max'];
38
- if ($controls->data['scheduler_max'] < 12)
39
- $controls->data['scheduler_max'] = 12;
40
-
41
-
42
- if (!$this->is_email($controls->data['reply_to'], true)) {
43
- $controls->errors .= __('Reply to email is not correct.', 'newsletter') . '<br>';
44
- } else {
45
- $controls->data['reply_to'] = $this->normalize_email($controls->data['reply_to']);
46
- }
47
-
48
- if (!empty($controls->data['contract_key'])) {
49
- $controls->data['contract_key'] = trim($controls->data['contract_key']);
50
- }
51
-
52
- if (empty($controls->errors)) {
53
- $this->merge_options($controls->data);
54
- $controls->add_message_saved();
55
- $this->logger->debug('Main options saved');
56
- }
57
-
58
- update_option('newsletter_log_level', $controls->data['log_level']);
59
-
60
- //$this->hook_newsletter_extension_versions(true);
61
- delete_transient("tnp_extensions_json");
62
- delete_transient('newsletter_license_data');
63
- }
64
-
65
- if ($controls->is_action('create')) {
66
- $page = array();
67
- $page['post_title'] = 'Newsletter';
68
- $page['post_content'] = '[newsletter]';
69
- $page['post_status'] = 'publish';
70
- $page['post_type'] = 'page';
71
- $page['comment_status'] = 'closed';
72
- $page['ping_status'] = 'closed';
73
- $page['post_category'] = array(1);
74
-
75
- $current_language = $this->get_current_language();
76
- $this->switch_language('');
77
- // Insert the post into the database
78
- $page_id = wp_insert_post($page);
79
- $this->switch_language($current_language);
80
-
81
- $controls->data['page'] = $page_id;
82
- $this->merge_options($controls->data);
83
-
84
- $controls->messages = 'A new page has been created';
85
- }
86
- }
87
-
88
- $license_data = $this->get_license_data(true);
89
-
90
- if (is_wp_error($license_data)) {
91
- $controls->errors .= esc_html('[' . $license_data->get_error_code()) . '] - ' . esc_html($license_data->get_error_message());
92
- } else {
93
- if ($license_data !== false) {
94
- if ($license_data->expire == 0) {
95
- $controls->messages = 'Your FREE license is valid';
96
- } elseif ($license_data->expire >= time()) {
97
- $controls->messages = 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $license_data->expire));
98
- } else {
99
- $controls->errors = 'Your license is expired on ' . esc_html(date('Y-m-d', $license_data->expire));
100
- }
101
- }
102
- }
103
-
104
- $return_path = $this->options['return_path'];
105
-
106
- if (!empty($return_path)) {
107
- list($return_path_local, $return_path_domain) = explode('@', $return_path);
108
-
109
- $sender = $this->options['sender_email'];
110
- list($sender_local, $sender_domain) = explode('@', $sender);
111
-
112
- if ($sender_domain != $return_path_domain) {
113
- $controls->warnings[] = __('Your Return Path domain is different from your Sender domain. Providers may require them to match.', 'newsletter');
114
- }
115
- }
116
- ?>
117
-
118
- <?php include NEWSLETTER_INCLUDES_DIR . '/codemirror.php'; ?>
119
- <style>
120
- .CodeMirror {
121
- border: 1px solid #ddd;
122
- }
123
- </style>
124
-
125
- <script>
126
- jQuery(function () {
127
- var editor = CodeMirror.fromTextArea(document.getElementById("options-css"), {
128
- lineNumbers: true,
129
- mode: 'css',
130
- extraKeys: {"Ctrl-Space": "autocomplete"}
131
- });
132
- });
133
- </script>
134
-
135
- <div class="wrap" id="tnp-wrap">
136
-
137
- <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
138
-
139
- <div id="tnp-heading">
140
-
141
- <h2><?php _e('General Settings', 'newsletter') ?></h2>
142
-
143
- </div>
144
- <div id="tnp-body" class="tnp-main-main">
145
-
146
-
147
- <form method="post" action="">
148
- <?php $controls->init(); ?>
149
-
150
- <div id="tabs">
151
-
152
- <ul>
153
- <li><a href="#tabs-basic"><?php _e('Basic Settings', 'newsletter') ?></a></li>
154
- <li><a href="#tabs-speed"><?php _e('Delivery Speed', 'newsletter') ?></a></li>
155
- <li><a href="#tabs-advanced"><?php _e('Advanced Settings', 'newsletter') ?></a></li>
156
- </ul>
157
-
158
- <div id="tabs-basic">
159
-
160
- <p>
161
- <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration') ?>
162
- </p>
163
-
164
-
165
- <table class="form-table">
166
-
167
- <tr>
168
- <th>
169
- <?php _e('Sender email address', 'newsletter') ?>
170
- <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#sender') ?>
171
- </th>
172
- <td>
173
- <?php $controls->text_email('sender_email', 40); ?>
174
- <div class="description">
175
- <a href="https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#sender" target="_blank">Emails delivered with a different address?</a>
176
- </div>
177
- </td>
178
- </tr>
179
- <tr>
180
- <th>
181
- <?php _e('Sender name', 'newsletter') ?>
182
- </th>
183
- <td>
184
- <?php $controls->text('sender_name', 40); ?>
185
- </td>
186
- </tr>
187
-
188
- <tr>
189
- <th>
190
- <?php _e('Return path', 'newsletter') ?>
191
- <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#return-path') ?>
192
- </th>
193
- <td>
194
- <?php $controls->text_email('return_path', 40); ?>
195
-
196
- </td>
197
- </tr>
198
- <tr>
199
- <th>
200
- <?php _e('Reply to', 'newsletter') ?>
201
- <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#reply-to') ?>
202
- </th>
203
- <td>
204
- <?php $controls->text_email('reply_to', 40); ?>
205
-
206
- </td>
207
- </tr>
208
- <tr>
209
- <th>
210
- <?php _e('Dedicated page', 'newsletter') ?>
211
- <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#dedicated-page') ?>
212
- </th>
213
- <td>
214
- <?php $controls->page('page', __('Unstyled page', 'newsletter'), '', true); ?>
215
- <?php
216
- if (empty($controls->data['page'])) {
217
- $controls->button('create', __('Create the page', 'newsletter'));
218
- }
219
- ?>
220
- </td>
221
- </tr>
222
-
223
- <tr>
224
- <th><?php _e('License key', 'newsletter') ?></th>
225
- <td>
226
- <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
227
- <?php _e('A license key is set', 'newsletter') ?>
228
- <?php } else { ?>
229
- <?php $controls->text('contract_key', 40); ?>
230
- <p class="description">
231
- <?php printf(__('Find it in <a href="%s" target="_blank">your account</a> page', 'newsletter'), "https://www.thenewsletterplugin.com/account") ?>
232
- </p>
233
- <?php } ?>
234
- </td>
235
- </tr>
236
-
237
- </table>
238
- </div>
239
-
240
- <div id="tabs-speed">
241
-
242
- <table class="form-table">
243
- <tr>
244
- <th>
245
- <?php _e('Max emails per hour', 'newsletter') ?>
246
- <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#speed') ?>
247
- </th>
248
- <td>
249
- <?php $controls->text('scheduler_max', 5); ?> (min. 10)
250
- <p class="description">
251
- <a href="?page=newsletter_system_status#tnp-speed">See the collected statistics</a>
252
- </td>
253
- </tr>
254
- </table>
255
-
256
- <?php do_action('newsletter_panel_main_speed', $controls) ?>
257
- </div>
258
-
259
-
260
- <div id="tabs-advanced">
261
-
262
- <p>
263
- <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#advanced') ?>
264
- </p>
265
-
266
- <table class="form-table">
267
- <tr>
268
- <th><?php _e('Allowed roles', 'newsletter') ?></th>
269
- <td>
270
- <?php
271
- $wp_roles = get_editable_roles();
272
- $roles = array();
273
- foreach ($wp_roles as $key => $wp_role) {
274
- if ($key == 'administrator')
275
- continue;
276
- if ($key == 'subscriber')
277
- continue;
278
- $roles[$key] = $wp_role['name'];
279
- }
280
- $controls->checkboxes('roles', $roles);
281
- ?>
282
-
283
- </td>
284
- </tr>
285
-
286
- <tr>
287
- <th>
288
- <?php _e('Tracking default', 'newsletter') ?>
289
- <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#tracking') ?>
290
- </th>
291
- <td>
292
- <?php $controls->yesno('track'); ?>
293
- </td>
294
- </tr>
295
-
296
- <tr>
297
- <th>
298
- <?php _e('Execute shortcodes on newsletters', 'newsletter') ?>
299
- <?php $controls->field_help("https://www.thenewsletterplugin.com/documentation/newsletter-configuration#shortcodes") ?>
300
- </th>
301
- <td>
302
- <?php $controls->yesno('do_shortcodes', 40); ?>
303
- </td>
304
- </tr>
305
-
306
- <tr>
307
- <th>
308
- <?php _e('Log level', 'newsletter') ?>
309
- <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#log') ?>
310
- </th>
311
- <td>
312
- <?php $controls->log_level('log_level'); ?>
313
- </td>
314
- </tr>
315
-
316
- <tr>
317
- <th><?php _e('Standard styles', 'newsletter') ?></th>
318
- <td>
319
- <?php $controls->disabled('css_disabled'); ?>
320
- </td>
321
- </tr>
322
-
323
- <tr>
324
- <th><?php _e('Custom styles', 'newsletter') ?></th>
325
- <td>
326
- <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
327
- <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
328
- <?php } ?>
329
- <?php $controls->textarea('css'); ?>
330
- </td>
331
- </tr>
332
-
333
-
334
- <tr>
335
- <th><?php _e('IP addresses', 'newsletter') ?></th>
336
- <td>
337
- <?php $controls->select('ip', array('' => __('Store', 'newsletter'), 'anonymize' => __('Anonymize', 'newsletter'), 'skip' => __('Do not store', 'newsletter'))); ?>
338
- </td>
339
- </tr>
340
-
341
-
342
-
343
- <tr>
344
- <th>
345
- <?php _e('Debug mode', 'newsletter') ?>
346
- <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#debug') ?>
347
- </th>
348
- <td>
349
- <?php $controls->yesno('debug', 40); ?>
350
- </td>
351
- </tr>
352
-
353
- <tr>
354
- <th>
355
- <?php _e('Email encoding', 'newsletter') ?>
356
- <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#encoding') ?>
357
- </th>
358
- <td>
359
- <?php $controls->select('content_transfer_encoding', array('' => 'Default', '8bit' => '8 bit', 'base64' => 'Base 64', 'binary' => 'Binary', 'quoted-printable' => 'Quoted printable', '7bit' => '7 bit')); ?>
360
- </td>
361
- </tr>
362
-
363
-
364
- </table>
365
-
366
- </div>
367
-
368
-
369
- </div> <!-- tabs -->
370
-
371
- <div class="tnp-buttons">
372
- <?php $controls->button_save(); ?>
373
- </div>
374
-
375
- </form>
376
-
377
- </div>
378
-
379
- <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
380
-
381
- </div>
382
-
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Newsletter */
3
+ defined('ABSPATH') || exit;
4
+
5
+ include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
6
+ $controls = new NewsletterControls();
7
+
8
+ if (!$controls->is_action()) {
9
+ $controls->data = get_option('newsletter_main');
10
+ if (!isset($controls->data['roles'])) {
11
+ $controls->data['roles'] = array();
12
+ if (!empty($controls->data['editor']))
13
+ $controls->data['roles'] = 'editor';
14
+ }
15
+ } else {
16
+
17
+ if ($controls->is_action('save')) {
18
+ $errors = null;
19
+
20
+ if (!isset($controls->data['roles']))
21
+ $controls->data['roles'] = array();
22
+
23
+ // Validation
24
+ $controls->data['sender_email'] = $this->normalize_email($controls->data['sender_email']);
25
+ if (!$this->is_email($controls->data['sender_email'])) {
26
+ $controls->errors .= __('The sender email address is not correct.', 'newsletter') . '<br>';
27
+ } else {
28
+ $controls->data['sender_email'] = $this->normalize_email($controls->data['sender_email']);
29
+ }
30
+
31
+ if (!$this->is_email($controls->data['return_path'], true)) {
32
+ $controls->errors .= __('Return path email is not correct.', 'newsletter') . '<br>';
33
+ } else {
34
+ $controls->data['return_path'] = $this->normalize_email($controls->data['return_path']);
35
+ }
36
+
37
+ $controls->data['scheduler_max'] = (int) $controls->data['scheduler_max'];
38
+ if ($controls->data['scheduler_max'] < 12)
39
+ $controls->data['scheduler_max'] = 12;
40
+
41
+
42
+ if (!$this->is_email($controls->data['reply_to'], true)) {
43
+ $controls->errors .= __('Reply to email is not correct.', 'newsletter') . '<br>';
44
+ } else {
45
+ $controls->data['reply_to'] = $this->normalize_email($controls->data['reply_to']);
46
+ }
47
+
48
+ if (!empty($controls->data['contract_key'])) {
49
+ $controls->data['contract_key'] = trim($controls->data['contract_key']);
50
+ }
51
+
52
+ if (empty($controls->errors)) {
53
+ $this->merge_options($controls->data);
54
+ $controls->add_message_saved();
55
+ $this->logger->debug('Main options saved');
56
+ }
57
+
58
+ update_option('newsletter_log_level', $controls->data['log_level']);
59
+
60
+ //$this->hook_newsletter_extension_versions(true);
61
+ delete_transient("tnp_extensions_json");
62
+ delete_transient('newsletter_license_data');
63
+ }
64
+
65
+ if ($controls->is_action('create')) {
66
+ $page = array();
67
+ $page['post_title'] = 'Newsletter';
68
+ $page['post_content'] = '[newsletter]';
69
+ $page['post_status'] = 'publish';
70
+ $page['post_type'] = 'page';
71
+ $page['comment_status'] = 'closed';
72
+ $page['ping_status'] = 'closed';
73
+ $page['post_category'] = array(1);
74
+
75
+ $current_language = $this->get_current_language();
76
+ $this->switch_language('');
77
+ // Insert the post into the database
78
+ $page_id = wp_insert_post($page);
79
+ $this->switch_language($current_language);
80
+
81
+ $controls->data['page'] = $page_id;
82
+ $this->merge_options($controls->data);
83
+
84
+ $controls->messages = 'A new page has been created';
85
+ }
86
+ }
87
+
88
+ $license_data = $this->get_license_data(true);
89
+
90
+ if (is_wp_error($license_data)) {
91
+ $controls->errors .= esc_html('[' . $license_data->get_error_code()) . '] - ' . esc_html($license_data->get_error_message());
92
+ } else {
93
+ if ($license_data !== false) {
94
+ if ($license_data->expire == 0) {
95
+ $controls->messages = 'Your FREE license is valid';
96
+ } elseif ($license_data->expire >= time()) {
97
+ $controls->messages = 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $license_data->expire));
98
+ } else {
99
+ $controls->errors = 'Your license is expired on ' . esc_html(date('Y-m-d', $license_data->expire));
100
+ }
101
+ }
102
+ }
103
+
104
+ $return_path = $this->options['return_path'];
105
+
106
+ if (!empty($return_path)) {
107
+ list($return_path_local, $return_path_domain) = explode('@', $return_path);
108
+
109
+ $sender = $this->options['sender_email'];
110
+ list($sender_local, $sender_domain) = explode('@', $sender);
111
+
112
+ if ($sender_domain != $return_path_domain) {
113
+ $controls->warnings[] = __('Your Return Path domain is different from your Sender domain. Providers may require them to match.', 'newsletter');
114
+ }
115
+ }
116
+ ?>
117
+
118
+ <?php include NEWSLETTER_INCLUDES_DIR . '/codemirror.php'; ?>
119
+ <style>
120
+ .CodeMirror {
121
+ border: 1px solid #ddd;
122
+ }
123
+ </style>
124
+
125
+ <script>
126
+ jQuery(function () {
127
+ var editor = CodeMirror.fromTextArea(document.getElementById("options-css"), {
128
+ lineNumbers: true,
129
+ mode: 'css',
130
+ extraKeys: {"Ctrl-Space": "autocomplete"}
131
+ });
132
+ });
133
+ </script>
134
+
135
+ <div class="wrap" id="tnp-wrap">
136
+
137
+ <?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
138
+
139
+ <div id="tnp-heading">
140
+
141
+ <h2><?php _e('General Settings', 'newsletter') ?></h2>
142
+
143
+ </div>
144
+ <div id="tnp-body" class="tnp-main-main">
145
+
146
+
147
+ <form method="post" action="">
148
+ <?php $controls->init(); ?>
149
+
150
+ <div id="tabs">
151
+
152
+ <ul>
153
+ <li><a href="#tabs-basic"><?php _e('Basic Settings', 'newsletter') ?></a></li>
154
+ <li><a href="#tabs-speed"><?php _e('Delivery Speed', 'newsletter') ?></a></li>
155
+ <li><a href="#tabs-advanced"><?php _e('Advanced Settings', 'newsletter') ?></a></li>
156
+ </ul>
157
+
158
+ <div id="tabs-basic">
159
+
160
+ <p>
161
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration') ?>
162
+ </p>
163
+
164
+
165
+ <table class="form-table">
166
+
167
+ <tr>
168
+ <th>
169
+ <?php _e('Sender email address', 'newsletter') ?>
170
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#sender') ?>
171
+ </th>
172
+ <td>
173
+ <?php $controls->text_email('sender_email', 40); ?>
174
+ <div class="description">
175
+ <a href="https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#sender" target="_blank">Emails delivered with a different address?</a>
176
+ </div>
177
+ </td>
178
+ </tr>
179
+ <tr>
180
+ <th>
181
+ <?php _e('Sender name', 'newsletter') ?>
182
+ </th>
183
+ <td>
184
+ <?php $controls->text('sender_name', 40); ?>
185
+ </td>
186
+ </tr>
187
+
188
+ <tr>
189
+ <th>
190
+ <?php _e('Return path', 'newsletter') ?>
191
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#return-path') ?>
192
+ </th>
193
+ <td>
194
+ <?php $controls->text_email('return_path', 40); ?>
195
+
196
+ </td>
197
+ </tr>
198
+ <tr>
199
+ <th>
200
+ <?php _e('Reply to', 'newsletter') ?>
201
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#reply-to') ?>
202
+ </th>
203
+ <td>
204
+ <?php $controls->text_email('reply_to', 40); ?>
205
+
206
+ </td>
207
+ </tr>
208
+ <tr>
209
+ <th>
210
+ <?php _e('Dedicated page', 'newsletter') ?>
211
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#dedicated-page') ?>
212
+ </th>
213
+ <td>
214
+ <?php $controls->page('page', __('Unstyled page', 'newsletter'), '', true); ?>
215
+ <?php
216
+ if (empty($controls->data['page'])) {
217
+ $controls->button('create', __('Create the page', 'newsletter'));
218
+ }
219
+ ?>
220
+ <?php if ($this->is_multilanguage()) { ?>
221
+ <p class="description">
222
+ With multilanguage plugins be sure the selected page is translated in every language (usually only the title needs to be translated, the content
223
+ should just be the <code>[newsletter]</code> shortcode).
224
+ </p>
225
+ <?php } ?>
226
+ </td>
227
+ </tr>
228
+
229
+ <tr>
230
+ <th><?php _e('License key', 'newsletter') ?></th>
231
+ <td>
232
+ <?php if (defined('NEWSLETTER_LICENSE_KEY')) { ?>
233
+ <?php _e('A license key is set', 'newsletter') ?>
234
+ <?php } else { ?>
235
+ <?php $controls->text('contract_key', 40); ?>
236
+ <p class="description">
237
+ <?php printf(__('Find it in <a href="%s" target="_blank">your account</a> page', 'newsletter'), "https://www.thenewsletterplugin.com/account") ?>
238
+ </p>
239
+ <?php } ?>
240
+ </td>
241
+ </tr>
242
+
243
+ </table>
244
+ </div>
245
+
246
+ <div id="tabs-speed">
247
+
248
+ <table class="form-table">
249
+ <tr>
250
+ <th>
251
+ <?php _e('Max emails per hour', 'newsletter') ?>
252
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/documentation/installation/newsletter-configuration/#speed') ?>
253
+ </th>
254
+ <td>
255
+ <?php $controls->text('scheduler_max', 5); ?> (min. 10)
256
+ <p class="description">
257
+ <a href="?page=newsletter_system_status#tnp-speed">See the collected statistics</a>
258
+ </td>
259
+ </tr>
260
+ </table>
261
+
262
+ <?php do_action('newsletter_panel_main_speed', $controls) ?>
263
+ </div>
264
+
265
+
266
+ <div id="tabs-advanced">
267
+
268
+ <p>
269
+ <?php $controls->panel_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#advanced') ?>
270
+ </p>
271
+
272
+ <table class="form-table">
273
+ <tr>
274
+ <th><?php _e('Allowed roles', 'newsletter') ?></th>
275
+ <td>
276
+ <?php
277
+ $wp_roles = get_editable_roles();
278
+ $roles = array();
279
+ foreach ($wp_roles as $key => $wp_role) {
280
+ if ($key == 'administrator')
281
+ continue;
282
+ if ($key == 'subscriber')
283
+ continue;
284
+ $roles[$key] = $wp_role['name'];
285
+ }
286
+ $controls->checkboxes('roles', $roles);
287
+ ?>
288
+
289
+ </td>
290
+ </tr>
291
+
292
+ <tr>
293
+ <th>
294
+ <?php _e('Tracking default', 'newsletter') ?>
295
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#tracking') ?>
296
+ </th>
297
+ <td>
298
+ <?php $controls->yesno('track'); ?>
299
+ </td>
300
+ </tr>
301
+
302
+ <tr>
303
+ <th>
304
+ <?php _e('Execute shortcodes on newsletters', 'newsletter') ?>
305
+ <?php $controls->field_help("https://www.thenewsletterplugin.com/documentation/newsletter-configuration#shortcodes") ?>
306
+ </th>
307
+ <td>
308
+ <?php $controls->yesno('do_shortcodes', 40); ?>
309
+ </td>
310
+ </tr>
311
+
312
+ <tr>
313
+ <th>
314
+ <?php _e('Log level', 'newsletter') ?>
315
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#log') ?>
316
+ </th>
317
+ <td>
318
+ <?php $controls->log_level('log_level'); ?>
319
+ </td>
320
+ </tr>
321
+
322
+ <tr>
323
+ <th><?php _e('Standard styles', 'newsletter') ?></th>
324
+ <td>
325
+ <?php $controls->disabled('css_disabled'); ?>
326
+ </td>
327
+ </tr>
328
+
329
+ <tr>
330
+ <th><?php _e('Custom styles', 'newsletter') ?></th>
331
+ <td>
332
+ <?php if (apply_filters('newsletter_enqueue_style', true) === false) { ?>
333
+ <p><strong>Warning: Newsletter styles and custom styles are disable by your theme or a plugin.</strong></p>
334
+ <?php } ?>
335
+ <?php $controls->textarea('css'); ?>
336
+ </td>
337
+ </tr>
338
+
339
+
340
+ <tr>
341
+ <th><?php _e('IP addresses', 'newsletter') ?></th>
342
+ <td>
343
+ <?php $controls->select('ip', array('' => __('Store', 'newsletter'), 'anonymize' => __('Anonymize', 'newsletter'), 'skip' => __('Do not store', 'newsletter'))); ?>
344
+ </td>
345
+ </tr>
346
+
347
+
348
+
349
+ <tr>
350
+ <th>
351
+ <?php _e('Debug mode', 'newsletter') ?>
352
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#debug') ?>
353
+ </th>
354
+ <td>
355
+ <?php $controls->yesno('debug', 40); ?>
356
+ </td>
357
+ </tr>
358
+
359
+ <tr>
360
+ <th>
361
+ <?php _e('Email encoding', 'newsletter') ?>
362
+ <?php $controls->field_help('https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-configuration#encoding') ?>
363
+ </th>
364
+ <td>
365
+ <?php $controls->select('content_transfer_encoding', array('' => 'Default', '8bit' => '8 bit', 'base64' => 'Base 64', 'binary' => 'Binary', 'quoted-printable' => 'Quoted printable', '7bit' => '7 bit')); ?>
366
+ </td>
367
+ </tr>
368
+
369
+
370
+ </table>
371
+
372
+ </div>
373
+
374
+
375
+ </div> <!-- tabs -->
376
+
377
+ <div class="tnp-buttons">
378
+ <?php $controls->button_save(); ?>
379
+ </div>
380
+
381
+ </form>
382
+
383
+ </div>
384
+
385
+ <?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
386
+
387
+ </div>
388
+
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.4.1
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -37,7 +37,7 @@ if (version_compare(phpversion(), '5.6', '<')) {
37
  return;
38
  }
39
 
40
- define('NEWSLETTER_VERSION', '7.4.1');
41
 
42
  global $newsletter, $wpdb;
43
 
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.4.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
  return;
38
  }
39
 
40
+ define('NEWSLETTER_VERSION', '7.4.2');
41
 
42
  global $newsletter, $wpdb;
43
 
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.9.2
4
- Stable tag: 7.4.1
5
  Contributors: satollo,webagile,michael-travan
6
  License: GPLv2 or later
7
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -63,6 +63,7 @@ Improve The Newsletter Plugin with these free addons:
63
  * [Popup Maker Integration](https://wordpress.org/plugins/newsletter-popupmaker/) - (3rd party) integration of Newsletter forms with Popup Maker plugin
64
  * [BuddyPress integration](https://wordpress.org/plugins/newsletter-buddypress/) - subscription opt-in inside BuddyPress signup form
65
  * [WP User Manager addon for Newsletter](https://wordpress.org/plugins/wpum-newsletter/) - adds the subscription option on registration forms
 
66
 
67
  = Professional Addons =
68
 
@@ -125,6 +126,15 @@ Thank you, The Newsletter Team
125
 
126
  == Changelog ==
127
 
 
 
 
 
 
 
 
 
 
128
  = 7.4.1 =
129
 
130
  * Added check on invalid media on two columns post type
1
  === Newsletter ===
2
  Tags: newsletter, email marketing, welcome email, signup forms, contact, lead generation, marketing automation
3
  Tested up to: 5.9.2
4
+ Stable tag: 7.4.2
5
  Contributors: satollo,webagile,michael-travan
6
  License: GPLv2 or later
7
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
63
  * [Popup Maker Integration](https://wordpress.org/plugins/newsletter-popupmaker/) - (3rd party) integration of Newsletter forms with Popup Maker plugin
64
  * [BuddyPress integration](https://wordpress.org/plugins/newsletter-buddypress/) - subscription opt-in inside BuddyPress signup form
65
  * [WP User Manager addon for Newsletter](https://wordpress.org/plugins/wpum-newsletter/) - adds the subscription option on registration forms
66
+ * [Plaintext Generator](https://wordpress.org/plugins/plaintext-newsletter/) - generates the plaintext version from an HTML newsletter
67
 
68
  = Professional Addons =
69
 
126
 
127
  == Changelog ==
128
 
129
+ = 7.4.2 =
130
+
131
+ * Fixed the post date (regression)
132
+ * Added link to the automatic plaintext generator plugin by franciscus
133
+ * Possible fix for our Gutenberg block (sometimes) not working
134
+ * Added uoloads dir and url on System>Status panel
135
+ * Fixed Status panel error when a newsletter is in "error" status
136
+ * Added default width to the logo on header block
137
+
138
  = 7.4.1 =
139
 
140
  * Added check on invalid media on two columns post type
subscription/subscription.php CHANGED
@@ -77,7 +77,7 @@ class NewsletterSubscription extends NewsletterModule {
77
 
78
  if (function_exists('register_block_type')) {
79
  // Add custom blocks to Gutenberg
80
- wp_register_script('tnp-blocks', plugins_url('newsletter') . '/includes/tnp-blocks.js', array('wp-blocks', 'wp-element'), NEWSLETTER_VERSION);
81
  register_block_type('tnp/minimal', array('editor_script' => 'tnp-blocks'));
82
  }
83
  }
77
 
78
  if (function_exists('register_block_type')) {
79
  // Add custom blocks to Gutenberg
80
+ wp_register_script('tnp-blocks', plugins_url('newsletter') . '/includes/tnp-blocks.js', array('wp-block-editor', 'wp-blocks', 'wp-element', 'wp-components'), NEWSLETTER_VERSION);
81
  register_block_type('tnp/minimal', array('editor_script' => 'tnp-blocks'));
82
  }
83
  }
system/status.php CHANGED
@@ -673,6 +673,29 @@ $tnp_wpdb = new TNP_WPDB(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
673
  </td>
674
  </tr>
675
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
676
  <tr>
677
  <?php
678
  set_transient('newsletter_transient_test', 1, 300);
673
  </td>
674
  </tr>
675
 
676
+ <tr>
677
+ <?php
678
+ $uploads = wp_upload_dir();
679
+ ?>
680
+ <td>Uploads dir and url</td>
681
+ <td>
682
+
683
+ </td>
684
+ <td>
685
+ <table class="widefat" style="width: auto">
686
+ <thead>
687
+ <tr><th>Key</th><th>Value</th></tr>
688
+ </thead>
689
+ <tbody>
690
+ <?php foreach ($uploads as $k => $v) { ?>
691
+ <tr><td><?php echo esc_html($k) ?></td><td><?php echo esc_html($v) ?></td></tr>
692
+ <?php } ?>
693
+ </tbody>
694
+ </table>
695
+
696
+ </td>
697
+ </tr>
698
+
699
  <tr>
700
  <?php
701
  set_transient('newsletter_transient_test', 1, 300);
tnp-header.php CHANGED
@@ -205,13 +205,13 @@ if (strpos($current_user_email, 'admin@') === 0) {
205
 
206
  <?php if (empty($license_data)) { ?>
207
  <?php if (time() < 1638226799) { ?>
208
- <li class="tnp-professional-extensions-button" style="background-color: #000; color: #fff; border-color: #FF5F65!important; border-width: 2px !important;"><a href="https://www.thenewsletterplugin.com/premium?utm_source=header&utm_medium=link&utm_campaign=black-friday" target="_blank">
209
- <i class="fas fa-trophy"></i> BLACK FRIDAY IS LIVE</a>
210
- </li>
211
  <?php } else { ?>
212
- <li class="tnp-professional-extensions-button"><a href="<?php echo $premium_url ?>" target="_blank">
213
- <i class="fas fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
214
- </li>
215
  <?php } ?>
216
  <?php } elseif (is_wp_error($license_data)) { ?>
217
  <li class="tnp-professional-extensions-button-red">
@@ -220,13 +220,13 @@ if (strpos($current_user_email, 'admin@') === 0) {
220
 
221
  <?php } elseif ($license_data->expire == 0) { ?>
222
  <?php if (time() < 1638226799) { ?>
223
- <li class="tnp-professional-extensions-button" style="background-color: #000; color: #fff; border-color: #FF5F65!important; border-width: 2px !important;"><a href="https://www.thenewsletterplugin.com/premium?utm_source=header&utm_medium=link&utm_campaign=black-friday" target="_blank">
224
- <i class="fas fa-trophy"></i> BLACK FRIDAY IS LIVE</a>
225
- </li>
226
  <?php } else { ?>
227
- <li class="tnp-professional-extensions-button"><a href="<?php echo $premium_url ?>" target="_blank">
228
- <i class="fas fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
229
- </li>
230
  <?php } ?>
231
 
232
  <?php } elseif ($license_data->expire < time()) { ?>
@@ -310,22 +310,24 @@ if (!defined('NEWSLETTER_CRON_WARNINGS') || NEWSLETTER_CRON_WARNINGS) {
310
  $x = NewsletterSystem::instance()->get_job_status();
311
  if ($x !== NewsletterSystem::JOB_OK) {
312
  echo '<div class="tnpc-warning">The are issues with the delivery engine. Please <a href="?page=newsletter_system_scheduler">check them here</a>.</div>';
313
- }
314
  }
315
  ?>
316
 
317
  <?php
318
  if ($_GET['page'] !== 'newsletter_emails_edit') {
319
 
320
- $last_failed_newsletters = Newsletter::instance()->get_emails_by_field('status', TNP_Email::STATUS_ERROR);
321
-
322
- foreach ($last_failed_newsletters as $newsletter) {
323
- echo '<div class="tnpc-error">';
324
- printf(__('Newsletter "%s" stopped by fatal error.', 'newsletter'), esc_html($newsletter->subject));
325
- echo '&nbsp;';
326
  $c = new NewsletterControls();
327
- $c->btn_link('?page=newsletter_emails_edit&id=' . $newsletter->id, __('Check', 'newsletter'));
328
- echo '</div>';
 
 
 
 
 
 
329
  }
330
  }
331
  ?>
205
 
206
  <?php if (empty($license_data)) { ?>
207
  <?php if (time() < 1638226799) { ?>
208
+ <li class="tnp-professional-extensions-button" style="background-color: #000; color: #fff; border-color: #FF5F65!important; border-width: 2px !important;"><a href="https://www.thenewsletterplugin.com/premium?utm_source=header&utm_medium=link&utm_campaign=black-friday" target="_blank">
209
+ <i class="fas fa-trophy"></i> BLACK FRIDAY IS LIVE</a>
210
+ </li>
211
  <?php } else { ?>
212
+ <li class="tnp-professional-extensions-button"><a href="<?php echo $premium_url ?>" target="_blank">
213
+ <i class="fas fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
214
+ </li>
215
  <?php } ?>
216
  <?php } elseif (is_wp_error($license_data)) { ?>
217
  <li class="tnp-professional-extensions-button-red">
220
 
221
  <?php } elseif ($license_data->expire == 0) { ?>
222
  <?php if (time() < 1638226799) { ?>
223
+ <li class="tnp-professional-extensions-button" style="background-color: #000; color: #fff; border-color: #FF5F65!important; border-width: 2px !important;"><a href="https://www.thenewsletterplugin.com/premium?utm_source=header&utm_medium=link&utm_campaign=black-friday" target="_blank">
224
+ <i class="fas fa-trophy"></i> BLACK FRIDAY IS LIVE</a>
225
+ </li>
226
  <?php } else { ?>
227
+ <li class="tnp-professional-extensions-button"><a href="<?php echo $premium_url ?>" target="_blank">
228
+ <i class="fas fa-trophy"></i> <?php _e('Get Professional Addons', 'newsletter') ?></a>
229
+ </li>
230
  <?php } ?>
231
 
232
  <?php } elseif ($license_data->expire < time()) { ?>
310
  $x = NewsletterSystem::instance()->get_job_status();
311
  if ($x !== NewsletterSystem::JOB_OK) {
312
  echo '<div class="tnpc-warning">The are issues with the delivery engine. Please <a href="?page=newsletter_system_scheduler">check them here</a>.</div>';
313
+ }
314
  }
315
  ?>
316
 
317
  <?php
318
  if ($_GET['page'] !== 'newsletter_emails_edit') {
319
 
320
+ $last_failed_newsletters = Newsletter::instance()->get_emails_by_status(TNP_Email::STATUS_ERROR);
321
+ if ($last_failed_newsletters) {
 
 
 
 
322
  $c = new NewsletterControls();
323
+ foreach ($last_failed_newsletters as $n) {
324
+ echo '<div class="tnpc-error">';
325
+ printf(__('Newsletter "%s" stopped by fatal error.', 'newsletter'), esc_html($n->subject));
326
+ echo '&nbsp;';
327
+
328
+ $c->btn_link('?page=newsletter_emails_edit&id=' . $n->id, __('Check', 'newsletter'));
329
+ echo '</div>';
330
+ }
331
  }
332
  }
333
  ?>