Newsletter - Version 6.1.4

Version Description

  • Support for Automated theme regeneration
  • Fixed link tracking
Download this release

Release Info

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

Code changes from version 6.1.3 to 6.1.4

emails/blocks/posts/block.php CHANGED
@@ -3,7 +3,7 @@
3
  * Name: Last posts
4
  * Section: content
5
  * Description: Last posts list with different layouts
6
- * Content: dynamic
7
  */
8
 
9
  /* @var $options array */
@@ -58,20 +58,19 @@ if (!empty($options['tags'])) {
58
 
59
  // Filter by time?
60
  //$options['block_last_run'] = time();
61
- if (!empty($options['block_last_run'])) {
62
  $filters['date_query'] = array(
63
- 'after' => gmdate('c', $options['block_last_run'])
64
  );
65
  }
66
 
67
  $posts = Newsletter::instance()->get_posts($filters, $options['language']);
68
 
69
- // TODO: Check the context or not?
70
- if (empty($posts) && $options['block_context'] == 'automated') {
71
  return;
72
  }
73
 
74
- $options['block_subject'] = $posts[0]->post_title;
75
 
76
  $button_background = $options['button_background'];
77
  $button_label = $options['button_label'];
3
  * Name: Last posts
4
  * Section: content
5
  * Description: Last posts list with different layouts
6
+ * Type: dynamic
7
  */
8
 
9
  /* @var $options array */
58
 
59
  // Filter by time?
60
  //$options['block_last_run'] = time();
61
+ if (!empty($context['last_run'])) {
62
  $filters['date_query'] = array(
63
+ 'after' => gmdate('c', $context['last_run'])
64
  );
65
  }
66
 
67
  $posts = Newsletter::instance()->get_posts($filters, $options['language']);
68
 
69
+ if (empty($posts) && !empty($context['last_run'])) {
 
70
  return;
71
  }
72
 
73
+ $out['subject'] = $posts[0]->post_title;
74
 
75
  $button_background = $options['button_background'];
76
  $button_label = $options['button_label'];
emails/blocks/posts/icon.png CHANGED
Binary file
emails/emails.php CHANGED
@@ -152,10 +152,26 @@ class NewsletterEmails extends NewsletterModule {
152
  $content .= '<div class="clear"></div>';
153
  echo $content;
154
  }
155
-
156
  wp_die();
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  /**
160
  * Regenerates a saved composed email rendering each block. Regeneration is
161
  * conditioned (possibly) by the context. The context is usually passed to blocks
@@ -168,34 +184,47 @@ class NewsletterEmails extends NewsletterModule {
168
  * @param string $theme (Rinominare)
169
  * @return string
170
  */
171
- function regenerate($theme, $context = '', $last_run = 0) {
 
 
 
 
 
 
 
172
  preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
173
  $result = '';
174
  $all_empty = true; // If all dynamic content blocks return an empty html
 
175
  $subject = '';
 
176
  foreach ($matches[1] as $match) {
177
  $a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
178
  $options = $this->options_decode($a);
179
 
180
- if (empty($options['block_id']))
181
- continue;
182
-
183
  $block = $this->get_block($options['block_id']);
184
-
185
- $options['block_last_run'] = $last_run;
186
- $options['block_context'] = $context;
187
 
188
  ob_start();
189
- $s = $this->render_block($options['block_id'], true, $options, true);
190
- if (empty($subject) && !empty($s)) $subject = $s;
 
 
191
  $block_html = ob_get_clean();
192
- $result .= trim($block_html);
193
- // If a dynamic blocks return something, we need to return a regenerated template
194
- if ($last_run && $block['content'] == 'dynamic' && !empty($block_html))
195
- $all_empty = false;
 
 
 
 
196
  }
197
 
198
- if ($last_run && $all_empty) {
 
199
  return '';
200
  }
201
 
@@ -206,7 +235,7 @@ class NewsletterEmails extends NewsletterModule {
206
  } else {
207
 
208
  }
209
- return array('body'=>$result, 'subject'=>$subject);
210
  }
211
 
212
  function remove_block_data($text) {
@@ -221,7 +250,7 @@ class NewsletterEmails extends NewsletterModule {
221
  * @param type $wrapper
222
  * @param type $options
223
  */
224
- function render_block($block_id = null, $wrapper = false, $options = array(), $false_on_empty = false) {
225
  include_once NEWSLETTER_INCLUDES_DIR . '/helper.php';
226
 
227
  $width = 600;
@@ -256,20 +285,16 @@ class NewsletterEmails extends NewsletterModule {
256
  }
257
  return;
258
  }
259
- $is_old_block = isset($block['filename']) && strpos($block['filename'], '.block');
260
 
261
- if ($is_old_block) {
262
- ob_start();
263
- include NEWSLETTER_DIR . '/emails/tnp-composer/blocks/' . $block['filename'] . '.php';
264
- $content = ob_get_clean();
265
- } else {
266
- ob_start();
267
- include $block['dir'] . '/block.php';
268
- $content = ob_get_clean();
269
 
270
- if ($false_on_empty && empty($content)) {
271
- return false;
272
- }
 
 
 
 
273
  }
274
 
275
  $common_defaults = array(
@@ -305,55 +330,37 @@ class NewsletterEmails extends NewsletterModule {
305
  $style .= 'padding-bottom: ' . $options['block_padding_bottom'] . 'px; ';
306
  $style .= 'background-color: ' . $options['block_background'] . ';';
307
 
308
- // Old block type
309
- if ($is_old_block) {
310
-
311
- echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row" data-id="', esc_attr($block_id), "\">\n";
312
- echo "<tr>\n";
313
- echo '<td align="center" style="padding: 0;">', "\n";
314
- echo '<!--[if mso]><table border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '"><![endif]-->', "\n";
315
-
316
- echo '<table border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: ', $width, 'px!important">', "\n";
317
- echo "<tr>\n";
318
- echo '<td class="edit-block" align="center" style="', $style, '" bgcolor="', $options['block_background'], '" width="100%">', "\n";
319
 
320
- echo $content;
321
-
322
- echo "\n</td></tr></table>";
323
- echo '<!--[if mso]></td></tr></table><![endif]-->';
324
- echo "</td></tr></table>\n";
325
- } else {
326
 
327
- $data = $this->options_encode($options);
328
- // First time block creation wrapper
329
- if ($wrapper) {
330
- echo '<table type="block" border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">', "\n";
331
- echo "<tr>";
332
- echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
333
- }
334
-
335
- // Container that fixes the width and makes the block responsive
336
- echo '<!--[if mso]><table border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '"><![endif]-->';
337
- echo "\n";
338
- echo '<table type="options" data-json="', esc_attr($data), '" class="tnpc-block-content" border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: ', $width, 'px!important">', "\n";
339
  echo "<tr>";
340
- echo '<td align="center" style="', $style, '" bgcolor="', $options['block_background'], '" width="100%">', "\n";
 
341
 
342
- //echo "<!-- block generated content -->\n";
343
- echo $content;
344
- //echo "\n<!-- /block generated content -->\n";
 
 
 
345
 
346
- echo "\n</td></tr></table>";
347
- echo '<!--[if mso]></td></tr></table><![endif]-->';
 
348
 
349
- // First time block creation wrapper
350
- if ($wrapper) {
351
- echo "</td></tr></table>";
352
- }
353
- echo "\n";
 
354
  }
355
-
356
- if (isset($options['block_subject'])) return $options['block_subject'];
 
357
  }
358
 
359
  /**
@@ -725,7 +732,7 @@ class NewsletterEmails extends NewsletterModule {
725
  $data['icon'] = content_url($relative_dir . '/icon.png');
726
  }
727
 
728
- $data = get_file_data($full_file, array('name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'content' => 'Content'));
729
  $defaults = array('section' => 'content', 'name' => $file, 'descritpion' => '', 'icon' => NEWSLETTER_URL . '/images/block-icon.png', 'content' => '');
730
  $data = array_merge($defaults, $data);
731
 
@@ -733,7 +740,7 @@ class NewsletterEmails extends NewsletterModule {
733
  $relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
734
  $data['icon'] = content_url($relative_dir . '/icon.png');
735
  }
736
-
737
  $data['id'] = $block_id;
738
 
739
  // Absolute path of the block files
@@ -799,8 +806,8 @@ class NewsletterEmails extends NewsletterModule {
799
 
800
  foreach (TNP_Composer::$block_dirs as $dir) {
801
  $block = $this->build_block($dir);
802
- if (is_wp_error($data)) {
803
- $this->logger->error($data);
804
  continue;
805
  }
806
  if (!isset($blocks[$block['id']])) {
152
  $content .= '<div class="clear"></div>';
153
  echo $content;
154
  }
155
+
156
  wp_die();
157
  }
158
 
159
+ function has_dynamic_blocks($theme) {
160
+ preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
161
+ foreach ($matches[1] as $match) {
162
+ $a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
163
+ $options = $this->options_decode($a);
164
+
165
+ $block = $this->get_block($options['block_id']);
166
+ if (!$block) {
167
+ continue;
168
+ }
169
+ if ($block['type'] == 'dynamic')
170
+ return true;
171
+ }
172
+ return false;
173
+ }
174
+
175
  /**
176
  * Regenerates a saved composed email rendering each block. Regeneration is
177
  * conditioned (possibly) by the context. The context is usually passed to blocks
184
  * @param string $theme (Rinominare)
185
  * @return string
186
  */
187
+ function regenerate($theme, $context = array()) {
188
+
189
+ if (empty($theme)) {
190
+ return array('body' => '', 'subject' => '');
191
+ }
192
+
193
+ $context = array_merge(array('last_run' => 0, 'type' => ''), $context);
194
+
195
  preg_match_all('/data-json="(.*?)"/m', $theme, $matches, PREG_PATTERN_ORDER);
196
  $result = '';
197
  $all_empty = true; // If all dynamic content blocks return an empty html
198
+ $has_dynamic_blocks = false;
199
  $subject = '';
200
+
201
  foreach ($matches[1] as $match) {
202
  $a = html_entity_decode($match, ENT_QUOTES, 'UTF-8');
203
  $options = $this->options_decode($a);
204
 
 
 
 
205
  $block = $this->get_block($options['block_id']);
206
+ if (!$block) {
207
+ continue;
208
+ }
209
 
210
  ob_start();
211
+ $out = $this->render_block($options['block_id'], true, $options, $context);
212
+ if (empty($subject) && !empty($out['subject'])) {
213
+ $subject = $out['subject'];
214
+ }
215
  $block_html = ob_get_clean();
216
+ $result .= $block_html;
217
+ // If a dynamic block return something, we need to return a regenerated template
218
+ if ($block['type'] == 'dynamic') {
219
+ $has_dynamic_blocks = true;
220
+ if (!empty($block_html)) {
221
+ $all_empty = false;
222
+ }
223
+ }
224
  }
225
 
226
+ if ($has_dynamic_blocks && $all_empty) {
227
+ die('all empty');
228
  return '';
229
  }
230
 
235
  } else {
236
 
237
  }
238
+ return array('body' => $result, 'subject' => $subject);
239
  }
240
 
241
  function remove_block_data($text) {
250
  * @param type $wrapper
251
  * @param type $options
252
  */
253
+ function render_block($block_id = null, $wrapper = false, $options = array(), $context = array()) {
254
  include_once NEWSLETTER_INCLUDES_DIR . '/helper.php';
255
 
256
  $width = 600;
285
  }
286
  return;
287
  }
 
288
 
289
+ $out = array('subject' => '');
 
 
 
 
 
 
 
290
 
291
+
292
+ ob_start();
293
+ include $block['dir'] . '/block.php';
294
+ $content = trim(ob_get_clean());
295
+
296
+ if (empty($content)) {
297
+ return $out;
298
  }
299
 
300
  $common_defaults = array(
330
  $style .= 'padding-bottom: ' . $options['block_padding_bottom'] . 'px; ';
331
  $style .= 'background-color: ' . $options['block_background'] . ';';
332
 
 
 
 
 
 
 
 
 
 
 
 
333
 
 
 
 
 
 
 
334
 
335
+ $data = $this->options_encode($options);
336
+ // First time block creation wrapper
337
+ if ($wrapper) {
338
+ echo '<table type="block" border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">', "\n";
 
 
 
 
 
 
 
 
339
  echo "<tr>";
340
+ echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
341
+ }
342
 
343
+ // Container that fixes the width and makes the block responsive
344
+ echo '<!--[if mso]><table border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '"><![endif]-->';
345
+ echo "\n";
346
+ echo '<table type="options" data-json="', esc_attr($data), '" class="tnpc-block-content" border="0" cellpadding="0" align="center" cellspacing="0" width="100%" style="width: 100%!important; max-width: ', $width, 'px!important">', "\n";
347
+ echo "<tr>";
348
+ echo '<td align="center" style="', $style, '" bgcolor="', $options['block_background'], '" width="100%">', "\n";
349
 
350
+ //echo "<!-- block generated content -->\n";
351
+ echo $content;
352
+ //echo "\n<!-- /block generated content -->\n";
353
 
354
+ echo "\n</td></tr></table>";
355
+ echo '<!--[if mso]></td></tr></table><![endif]-->';
356
+
357
+ // First time block creation wrapper
358
+ if ($wrapper) {
359
+ echo "</td></tr></table>";
360
  }
361
+ echo "\n";
362
+
363
+ return $out;
364
  }
365
 
366
  /**
732
  $data['icon'] = content_url($relative_dir . '/icon.png');
733
  }
734
 
735
+ $data = get_file_data($full_file, array('name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'type' => 'Type'));
736
  $defaults = array('section' => 'content', 'name' => $file, 'descritpion' => '', 'icon' => NEWSLETTER_URL . '/images/block-icon.png', 'content' => '');
737
  $data = array_merge($defaults, $data);
738
 
740
  $relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
741
  $data['icon'] = content_url($relative_dir . '/icon.png');
742
  }
743
+
744
  $data['id'] = $block_id;
745
 
746
  // Absolute path of the block files
806
 
807
  foreach (TNP_Composer::$block_dirs as $dir) {
808
  $block = $this->build_block($dir);
809
+ if (is_wp_error($block)) {
810
+ $this->logger->error($block);
811
  continue;
812
  }
813
  if (!isset($blocks[$block['id']])) {
emails/tnp-composer/index.php CHANGED
@@ -63,7 +63,10 @@ $block_options = get_option('newsletter_main');
63
  <button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
64
  <?php /* <button class="tablinks" onclick="openTab(event, 'tnpc-general-options')"><?php _e('General Options', 'newsletter') ?></button> */ ?>
65
  <button class="tablinks" onclick="openTab(event, 'tnpc-mobile-tab')"><i class="fa fa-mobile"></i> <?php _e('Mobile Preview', 'newsletter') ?></button>
 
66
  <button class="tablinks" onclick="openTab(event, 'tnpc-test-tab')"><i class="fa fa-paper-plane"></i> <?php _e('Test', 'newsletter') ?></button>
 
 
67
  </div>
68
 
69
  <div id="tnpc-blocks" class="tabcontent">
63
  <button class="tablinks" onclick="openTab(event, 'tnpc-blocks')" id="defaultOpen"><?php _e('Blocks', 'newsletter') ?></button>
64
  <?php /* <button class="tablinks" onclick="openTab(event, 'tnpc-general-options')"><?php _e('General Options', 'newsletter') ?></button> */ ?>
65
  <button class="tablinks" onclick="openTab(event, 'tnpc-mobile-tab')"><i class="fa fa-mobile"></i> <?php _e('Mobile Preview', 'newsletter') ?></button>
66
+ <?php if ($show_test) { ?>
67
  <button class="tablinks" onclick="openTab(event, 'tnpc-test-tab')"><i class="fa fa-paper-plane"></i> <?php _e('Test', 'newsletter') ?></button>
68
+ <?php } ?>
69
+
70
  </div>
71
 
72
  <div id="tnpc-blocks" class="tabcontent">
includes/controls.php CHANGED
@@ -1665,7 +1665,7 @@ class NewsletterControls {
1665
  echo '<input type="hidden" name="options[subject]" id="options-subject" value="', $value, '">';
1666
  }
1667
 
1668
- function composer_load($name = 'body', $show_subject = false) {
1669
 
1670
  global $controls;
1671
  global $tnpc_show_subject;
1665
  echo '<input type="hidden" name="options[subject]" id="options-subject" value="', $value, '">';
1666
  }
1667
 
1668
+ function composer_load($name = 'body', $show_subject = false, $show_test = true) {
1669
 
1670
  global $controls;
1671
  global $tnpc_show_subject;
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: 6.1.3
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.
@@ -29,7 +29,7 @@
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
- define('NEWSLETTER_VERSION', '6.1.3');
33
 
34
  global $newsletter, $wpdb;
35
 
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: 6.1.4
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.
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
+ define('NEWSLETTER_VERSION', '6.1.4');
33
 
34
  global $newsletter, $wpdb;
35
 
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Tags: email, email marketing, newsletter, newsletter subscribers, welcome email, signup forms, contact, lead generation, popup, marketing automation
3
  Requires at least: 3.4.0
4
  Tested up to: 5.2.2
5
- Stable tag: 6.1.3
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
@@ -108,6 +108,11 @@ Thank you, The Newsletter Team
108
 
109
  == Changelog ==
110
 
 
 
 
 
 
111
  = 6.1.3 =
112
 
113
  * Fix to avoid third party plugin notices to interfere with the composer
2
  Tags: email, email marketing, newsletter, newsletter subscribers, welcome email, signup forms, contact, lead generation, popup, marketing automation
3
  Requires at least: 3.4.0
4
  Tested up to: 5.2.2
5
+ Stable tag: 6.1.4
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
108
 
109
  == Changelog ==
110
 
111
+ = 6.1.4 =
112
+
113
+ * Support for Automated theme regeneration
114
+ * Fixed link tracking
115
+
116
  = 6.1.3 =
117
 
118
  * Fix to avoid third party plugin notices to interfere with the composer
statistics/statistics.php CHANGED
@@ -195,7 +195,7 @@ class NewsletterStatistics extends NewsletterModule {
195
  $this->relink_email_token = $email_token;
196
 
197
  $this->logger->debug('Relink with token: ' . $email_token);
198
- $text = preg_replace_callback('/(<[aA][^>]+href[\s]*=[\s]*["\'])([^>"\']+)(["\'][^>]*>)(.*?)(<\/[Aa]>)/s', array($this, 'relink_callback'), $text);
199
 
200
  $signature = md5($email_id . $user_id . $email_token);
201
  $text = str_replace('</body>', '<img width="1" height="1" alt="" src="' . home_url('/') . '?noti=' . urlencode(base64_encode($email_id . ';' . $user_id . ';' . $signature)) . '"/></body>', $text);
195
  $this->relink_email_token = $email_token;
196
 
197
  $this->logger->debug('Relink with token: ' . $email_token);
198
+ $text = preg_replace_callback('/(<[aA][^>]+href[\s]*=[\s]*["\'])([^>"\']+)(["\'][^>]*>)(.*?)(<\/[Aa]>)/is', array($this, 'relink_callback'), $text);
199
 
200
  $signature = md5($email_id . $user_id . $email_token);
201
  $text = str_replace('</body>', '<img width="1" height="1" alt="" src="' . home_url('/') . '?noti=' . urlencode(base64_encode($email_id . ';' . $user_id . ';' . $signature)) . '"/></body>', $text);