Newsletter - Version 6.1.2

Version Description

  • Added support for roles
Download this release

Release Info

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

Code changes from version 6.0.8 to 6.1.2

admin.css CHANGED
@@ -1484,6 +1484,13 @@ table.widefat {
1484
  cursor: pointer;
1485
  }
1486
 
 
 
 
 
 
 
 
1487
  .tnp-extension-free {
1488
  color: #D35400;
1489
  padding: 5px 8px;
1484
  cursor: pointer;
1485
  }
1486
 
1487
+ #tnp-body a.tnp-extension-details{
1488
+ color: #999999;
1489
+ padding: 5px 8px;
1490
+ text-decoration: none;
1491
+ cursor: pointer;
1492
+ }
1493
+
1494
  .tnp-extension-free {
1495
  color: #D35400;
1496
  padding: 5px 8px;
emails/blocks/canspam/block.php CHANGED
@@ -10,7 +10,11 @@ $default_options = array(
10
  'font_family' => $font_family,
11
  'font_size' => 13,
12
  'font_color' => '#999999',
13
- 'font_weight' => 'normal'
 
 
 
 
14
  );
15
  $options = array_merge($default_options, $options);
16
  ?>
10
  'font_family' => $font_family,
11
  'font_size' => 13,
12
  'font_color' => '#999999',
13
+ 'font_weight' => 'normal',
14
+ 'block_padding_top' => 15,
15
+ 'block_padding_bottom' => 15,
16
+ 'block_padding_left' => 15,
17
+ 'block_padding_right' => 15
18
  );
19
  $options = array_merge($default_options, $options);
20
  ?>
emails/blocks/posts/block.php CHANGED
@@ -11,7 +11,6 @@
11
 
12
  $defaults = array(
13
  'title' => 'Last news',
14
- 'block_background' => '#E6E9ED',
15
  'color' => '#999999',
16
  'font_family' => 'Helvetica, Arial, sans-serif',
17
  'font_size' => '16',
11
 
12
  $defaults = array(
13
  'title' => 'Last news',
 
14
  'color' => '#999999',
15
  'font_family' => 'Helvetica, Arial, sans-serif',
16
  'font_size' => '16',
emails/blocks/social/block.php CHANGED
@@ -31,7 +31,7 @@ $configured = false;
31
  $configured = true;
32
  ?>
33
  <span class="tnpc-row-edit" data-type="image">
34
- <a href="<?php echo $block_options['facebook_url'] ?>"><img src="<?php echo $social_icon_url ?>/facebook.png" alt=""></a>
35
  </span>
36
  <?php } ?>
37
  <?php
31
  $configured = true;
32
  ?>
33
  <span class="tnpc-row-edit" data-type="image">
34
+ <a href="<?php echo $block_options['facebook_url'] ?>"><img src="<?php echo $social_icon_url ?>/facebook.png" alt="Facebook"></a>
35
  </span>
36
  <?php } ?>
37
  <?php
emails/emails.php CHANGED
@@ -93,15 +93,15 @@ class NewsletterEmails extends NewsletterModule {
93
  }
94
  $options = $this->options_decode(stripslashes_deep($_REQUEST['options']));
95
 
96
- $defaults = array(
97
- 'block_padding_top' => 15,
98
- 'block_padding_bottom' => 15,
99
- 'block_padding_right' => 0,
100
- 'block_padding_left' => 0,
101
- 'block_background' => '#ffffff'
102
- );
103
-
104
- $options = array_merge($defaults, $options);
105
 
106
  $controls = new NewsletterControls($options);
107
  $fields = new NewsletterFields($controls);
@@ -227,21 +227,11 @@ class NewsletterEmails extends NewsletterModule {
227
 
228
  $info = Newsletter::instance()->get_options('info');
229
 
230
- $defaults = array(
231
- 'block_padding_top' => 15,
232
- 'block_padding_bottom' => 15,
233
- 'block_padding_right' => 0,
234
- 'block_padding_left' => 0,
235
- 'block_background' => '#ffffff'
236
- );
237
-
238
  // Just in case...
239
  if (!is_array($options)) {
240
  $options = array();
241
  }
242
 
243
- //$options = array_merge($defaults, $options);
244
-
245
  $block_options = get_option('newsletter_main');
246
 
247
  $block = $this->get_block($block_id);
@@ -251,7 +241,7 @@ class NewsletterEmails extends NewsletterModule {
251
  if ($wrapper) {
252
  echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">';
253
  echo '<tr>';
254
- echo '<td data-options="', esc_attr($data), '" bgcolor="#ffffff" align="center" style="padding: 0; font-family: Helvetica, Arial, sans-serif;" class="edit-block">';
255
  }
256
  echo '<!--[if mso]><table border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '"><![endif]-->';
257
  echo "\n";
@@ -280,6 +270,16 @@ class NewsletterEmails extends NewsletterModule {
280
  }
281
  }
282
 
 
 
 
 
 
 
 
 
 
 
283
  // Obsolete
284
  $content = str_replace('{width}', $width, $content);
285
 
@@ -326,7 +326,7 @@ class NewsletterEmails extends NewsletterModule {
326
  // First time block creation wrapper
327
  if ($wrapper) {
328
  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";
329
- echo "<tr>\n";
330
  echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
331
  }
332
 
@@ -398,7 +398,7 @@ class NewsletterEmails extends NewsletterModule {
398
  }
399
  }
400
 
401
- /**
402
  * Returns the button linked to the correct "edit" page for the passed newsletter. The edit page can be an editor
403
  * or the targeting page (it depends on newsletter status).
404
  *
@@ -439,7 +439,7 @@ class NewsletterEmails extends NewsletterModule {
439
  $editor_type = NewsletterEmails::EDITOR_COMPOSER;
440
  }
441
  // End backward compatibility
442
-
443
  return $editor_type;
444
  }
445
 
@@ -516,13 +516,10 @@ class NewsletterEmails extends NewsletterModule {
516
  break;
517
 
518
  case 'emails-preview':
519
- if (!current_user_can('manage_categories')) {
520
  die('Not enough privileges');
521
  }
522
 
523
- if (Newsletter::instance()->options['editor'] != 1 && !current_user_can('manage_options')) {
524
- die('Not enough privileges');
525
- }
526
  if (!check_admin_referer('view')) {
527
  die();
528
  }
@@ -539,11 +536,7 @@ class NewsletterEmails extends NewsletterModule {
539
 
540
  case 'emails-preview-text':
541
  header('Content-Type: text/plain;charset=UTF-8');
542
- if (!current_user_can('manage_categories')) {
543
- die('Not enough privileges');
544
- }
545
-
546
- if (Newsletter::instance()->options['editor'] != 1 && !current_user_can('manage_options')) {
547
  die('Not enough privileges');
548
  }
549
 
@@ -565,11 +558,7 @@ class NewsletterEmails extends NewsletterModule {
565
 
566
  case 'emails-create':
567
 
568
- if (!current_user_can('manage_categories')) {
569
- die('Not enough privileges');
570
- }
571
-
572
- if ($newsletter->options['editor'] != 1 && !current_user_can('manage_options')) {
573
  die('Not enough privileges');
574
  }
575
 
@@ -719,6 +708,36 @@ class NewsletterEmails extends NewsletterModule {
719
  }
720
  }
721
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
722
  function scan_blocks_dir($dir) {
723
 
724
  if (!is_dir($dir)) {
@@ -733,33 +752,13 @@ class NewsletterEmails extends NewsletterModule {
733
  if ($file == '.' || $file == '..')
734
  continue;
735
 
736
- // The block unique key, we should find out how to biuld it, maybe an hash of the (relative) dir?
737
- $block_id = sanitize_key($file);
738
 
739
- $full_file = $dir . '/' . $file . '/block.php';
740
- if (!is_file($full_file)) {
741
  continue;
742
  }
743
-
744
- $data = get_file_data($full_file, array('name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'content' => 'Content'));
745
-
746
- if (empty($data['name'])) {
747
- $data['name'] = $file;
748
- }
749
- if (empty($data['section'])) {
750
- $data['section'] = 'content';
751
- }
752
- if (empty($data['description'])) {
753
- $data['description'] = '';
754
- }
755
- if (empty($data['content'])) {
756
- $data['content'] = '';
757
- }
758
- // Absolute path of the block files
759
- $data['dir'] = $dir . '/' . $file;
760
-
761
- $data['icon'] = content_url($relative_dir . '/' . $file . '/icon.png');
762
- $list[$block_id] = $data;
763
  }
764
  closedir($handle);
765
  return $list;
@@ -778,34 +777,11 @@ class NewsletterEmails extends NewsletterModule {
778
  if (!is_null($blocks))
779
  return $blocks;
780
 
781
- $blocks = array();
782
-
783
- // Legacy blocks
784
- $handle = opendir(NEWSLETTER_DIR . '/emails/tnp-composer/blocks');
785
- while ($file = readdir($handle)) {
786
- if (strpos($file, '.php') === false) {
787
- continue;
788
- }
789
-
790
- $path_parts = pathinfo($file);
791
- $filename = $path_parts['filename'];
792
- $section = substr($filename, 0, strpos($filename, '-'));
793
- $index = substr($filename, strpos($filename, '-') + 1, 2);
794
- $block = array();
795
- $block['name'] = substr($filename, strrpos($filename, '-') + 1);
796
- $block['filename'] = $filename;
797
- $block['icon'] = plugins_url('newsletter') . '/emails/tnp-composer/blocks/' . $filename . '.png';
798
- $block['section'] = $section;
799
- $block['description'] = '';
800
- // The block ID is the file name for legacy blocks
801
- $blocks[sanitize_key($filename)] = $block;
802
- }
803
- closedir($handle);
804
 
805
- // Packaged standard blocks
806
- $list = $this->scan_blocks_dir(__DIR__ . '/blocks');
807
 
808
- $blocks = array_merge($list, $blocks);
809
 
810
  $dirs = apply_filters('newsletter_blocks_dir', array());
811
 
@@ -814,6 +790,22 @@ class NewsletterEmails extends NewsletterModule {
814
  $list = $this->scan_blocks_dir($dir);
815
  $blocks = array_merge($list, $blocks);
816
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
817
  $blocks = array_reverse($blocks);
818
  return $blocks;
819
  }
93
  }
94
  $options = $this->options_decode(stripslashes_deep($_REQUEST['options']));
95
 
96
+ // $defaults = array(
97
+ // 'block_padding_top' => 15,
98
+ // 'block_padding_bottom' => 15,
99
+ // 'block_padding_right' => 0,
100
+ // 'block_padding_left' => 0,
101
+ // 'block_background' => '#ffffff'
102
+ // );
103
+ //
104
+ // $options = array_merge($defaults, $options);
105
 
106
  $controls = new NewsletterControls($options);
107
  $fields = new NewsletterFields($controls);
227
 
228
  $info = Newsletter::instance()->get_options('info');
229
 
 
 
 
 
 
 
 
 
230
  // Just in case...
231
  if (!is_array($options)) {
232
  $options = array();
233
  }
234
 
 
 
235
  $block_options = get_option('newsletter_main');
236
 
237
  $block = $this->get_block($block_id);
241
  if ($wrapper) {
242
  echo '<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" style="border-collapse: collapse; width: 100%;" class="tnpc-row tnpc-row-block" data-id="', esc_attr($block_id), '">';
243
  echo '<tr>';
244
+ echo '<td data-options="" bgcolor="#ffffff" align="center" style="padding: 0; font-family: Helvetica, Arial, sans-serif;" class="edit-block">';
245
  }
246
  echo '<!--[if mso]><table border="0" cellpadding="0" align="center" cellspacing="0" width="' . $width . '"><tr><td width="' . $width . '"><![endif]-->';
247
  echo "\n";
270
  }
271
  }
272
 
273
+ $common_defaults = array(
274
+ 'block_padding_top' => 0,
275
+ 'block_padding_bottom' => 0,
276
+ 'block_padding_right' => 0,
277
+ 'block_padding_left' => 0,
278
+ 'block_background' => '#ffffff'
279
+ );
280
+
281
+ $options = array_merge($common_defaults, $options);
282
+
283
  // Obsolete
284
  $content = str_replace('{width}', $width, $content);
285
 
326
  // First time block creation wrapper
327
  if ($wrapper) {
328
  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";
329
+ echo "<tr>";
330
  echo '<td align="center" style="padding: 0;" class="edit-block">', "\n";
331
  }
332
 
398
  }
399
  }
400
 
401
+ /**
402
  * Returns the button linked to the correct "edit" page for the passed newsletter. The edit page can be an editor
403
  * or the targeting page (it depends on newsletter status).
404
  *
439
  $editor_type = NewsletterEmails::EDITOR_COMPOSER;
440
  }
441
  // End backward compatibility
442
+
443
  return $editor_type;
444
  }
445
 
516
  break;
517
 
518
  case 'emails-preview':
519
+ if (!Newsletter::instance()->is_allowed()) {
520
  die('Not enough privileges');
521
  }
522
 
 
 
 
523
  if (!check_admin_referer('view')) {
524
  die();
525
  }
536
 
537
  case 'emails-preview-text':
538
  header('Content-Type: text/plain;charset=UTF-8');
539
+ if (!Newsletter::instance()->is_allowed()) {
 
 
 
 
540
  die('Not enough privileges');
541
  }
542
 
558
 
559
  case 'emails-create':
560
 
561
+ if (!Newsletter::instance()->is_allowed()) {
 
 
 
 
562
  die('Not enough privileges');
563
  }
564
 
708
  }
709
  }
710
 
711
+ function build_block($dir) {
712
+ $file = basename($dir);
713
+ $block_id = sanitize_key($file);
714
+ $full_file = $dir . '/block.php';
715
+ if (!is_file($full_file)) {
716
+ return new WP_Error('1', 'Missing block.php file in ' . $dir);
717
+ }
718
+
719
+ if (!is_file($dir . '/icon.png')) {
720
+ $relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
721
+ $data['icon'] = content_url($relative_dir . '/icon.png');
722
+ }
723
+
724
+ $data = get_file_data($full_file, array('name' => 'Name', 'section' => 'Section', 'description' => 'Description', 'content' => 'Content'));
725
+ $defaults = array('section' => 'content', 'name' => $file, 'descritpion' => '', 'icon' => NEWSLETTER_URL . '/images/block-icon.png', 'content' => '');
726
+ $data = array_merge($defaults, $data);
727
+
728
+ if (is_file($dir . '/icon.png')) {
729
+ $relative_dir = substr($dir, strlen(WP_CONTENT_DIR));
730
+ $data['icon'] = content_url($relative_dir . '/icon.png');
731
+ }
732
+
733
+ $data['id'] = $block_id;
734
+
735
+ // Absolute path of the block files
736
+ $data['dir'] = $dir;
737
+
738
+ return $data;
739
+ }
740
+
741
  function scan_blocks_dir($dir) {
742
 
743
  if (!is_dir($dir)) {
752
  if ($file == '.' || $file == '..')
753
  continue;
754
 
755
+ $data = $this->build_block($dir . '/' . $file);
 
756
 
757
+ if (is_wp_error($data)) {
758
+ $this->logger->error($data);
759
  continue;
760
  }
761
+ $list[$data['id']] = $data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
762
  }
763
  closedir($handle);
764
  return $list;
777
  if (!is_null($blocks))
778
  return $blocks;
779
 
780
+ $blocks = $this->scan_blocks_dir(__DIR__ . '/blocks');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
 
782
+ $extended = $this->scan_blocks_dir(WP_CONTENT_DIR . '/extensions/newsletter/blocks');
 
783
 
784
+ $blocks = array_merge($extended, $blocks);
785
 
786
  $dirs = apply_filters('newsletter_blocks_dir', array());
787
 
790
  $list = $this->scan_blocks_dir($dir);
791
  $blocks = array_merge($list, $blocks);
792
  }
793
+
794
+ do_action('newsletter_register_blocks');
795
+
796
+ foreach (TNP_Composer::$block_dirs as $dir) {
797
+ $block = $this->build_block($dir);
798
+ if (is_wp_error($data)) {
799
+ $this->logger->error($data);
800
+ continue;
801
+ }
802
+ if (!isset($blocks[$block['id']])) {
803
+ $blocks[$block['id']] = $block;
804
+ } else {
805
+ $this->logger->error('The block "' . $block['id'] . '" is already registered');
806
+ }
807
+ }
808
+
809
  $blocks = array_reverse($blocks);
810
  return $blocks;
811
  }
images/block-icon.png ADDED
Binary file
includes/TNP.php CHANGED
@@ -22,11 +22,13 @@ class TNP {
22
 
23
  public static function subscribe($params) {
24
 
25
- // error_reporting(E_ALL);
26
-
27
  $newsletter = Newsletter::instance();
28
  $subscription = NewsletterSubscription::instance();
29
 
 
 
 
 
30
  // Messages
31
  $options = get_option('newsletter', array());
32
 
@@ -126,13 +128,14 @@ class TNP {
126
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
127
  }
128
 
129
- if (empty($params['send_emails']) || !$params['send_emails']) {
 
130
  return $user;
131
  }
132
 
133
  $message_type = ($user->status == 'C') ? 'confirmed' : 'confirmation';
134
  $subscription->send_message($message_type, $user);
135
-
136
  return $user;
137
  }
138
 
22
 
23
  public static function subscribe($params) {
24
 
 
 
25
  $newsletter = Newsletter::instance();
26
  $subscription = NewsletterSubscription::instance();
27
 
28
+ // default params
29
+ $defaults = array('send_emails' => true);
30
+ $params = array_merge ($defaults, $params);
31
+
32
  // Messages
33
  $options = get_option('newsletter', array());
34
 
128
  setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');
129
  }
130
 
131
+ // skip messages if send_emails = false
132
+ if (!$params['send_emails']) {
133
  return $user;
134
  }
135
 
136
  $message_type = ($user->status == 'C') ? 'confirmed' : 'confirmation';
137
  $subscription->send_message($message_type, $user);
138
+
139
  return $user;
140
  }
141
 
includes/module.php CHANGED
@@ -2,6 +2,22 @@
2
 
3
  defined('ABSPATH') || exit;
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  /**
6
  * @property int $id The list unique identifier
7
  * @property string $name The list name
@@ -109,8 +125,6 @@ class NewsletterModule {
109
  */
110
  var $version;
111
  var $old_version;
112
- var $module_id;
113
- var $available_version;
114
 
115
  /**
116
  * Prefix for all options stored on WordPress options table.
@@ -127,7 +141,6 @@ class NewsletterModule {
127
  function __construct($module, $version, $module_id = null, $components = array()) {
128
  $this->module = $module;
129
  $this->version = $version;
130
- $this->module_id = $module_id;
131
  $this->prefix = 'newsletter_' . $module;
132
  array_unshift($components, '');
133
  $this->components = $components;
@@ -157,7 +170,6 @@ class NewsletterModule {
157
  }
158
 
159
  add_action('admin_menu', array($this, 'admin_menu'));
160
- $this->available_version = get_option($this->prefix . '_available_version');
161
  }
162
  }
163
 
@@ -228,20 +240,6 @@ class NewsletterModule {
228
  $wpdb->suppress_errors($suppress_errors);
229
  }
230
 
231
- /**
232
- * Kept for compatibility.
233
- */
234
- static function get_available_version($module_id, $force = false) {
235
- return '';
236
- }
237
-
238
- /**
239
- * Kept for compatibility.
240
- */
241
- function new_version_available($force = false) {
242
- return false;
243
- }
244
-
245
  /** Returns a prefix to be used for option names and other things which need to be uniquely named. The parameter
246
  * "sub" should be used when a sub name is needed for another set of options or like.
247
  *
@@ -321,8 +319,9 @@ class NewsletterModule {
321
  }
322
 
323
  function merge_options($options, $sub = '', $language = '') {
324
- if (!is_array($options))
325
  $options = array();
 
326
  $old_options = $this->get_options($sub, $language);
327
  $this->save_options(array_merge($old_options, $options), $sub, null, $language);
328
  }
@@ -372,10 +371,13 @@ class NewsletterModule {
372
  $time = 60;
373
  //usleep(rand(0, 1000000));
374
  if (($value = get_transient($this->get_prefix() . '_' . $name)) !== false) {
375
- $this->logger->error('Blocked by transient ' . $this->get_prefix() . '_' . $name . ' set ' . (time() - $value) . ' seconds ago');
 
376
  return false;
377
  }
378
- set_transient($this->get_prefix() . '_' . $name, time(), $time);
 
 
379
  return true;
380
  }
381
 
@@ -658,23 +660,16 @@ class NewsletterModule {
658
  }
659
 
660
  function add_menu_page($page, $title, $capability = '') {
661
- global $newsletter;
662
  $name = 'newsletter_' . $this->module . '_' . $page;
663
- if (empty($capability)) {
664
- $capability = ($newsletter->options['editor'] == 1) ? 'manage_categories' : 'manage_options';
665
- }
666
- add_submenu_page('newsletter_main_index', $title, $title, $capability, $name, array($this, 'menu_page'));
667
  }
668
-
669
- function add_admin_page($page, $title, $capability = '') {
670
- if (empty($capability)) {
671
- $newsletter = Newsletter::instance();
672
- $capability = ($newsletter->options['editor'] == 1) ? 'manage_categories' : 'manage_options';
673
- }
674
-
675
  $name = 'newsletter_' . $this->module . '_' . $page;
676
  $name = apply_filters('newsletter_admin_page', $name);
677
- add_submenu_page(null, $title, $title, $capability, $name, array($this, 'menu_page'));
678
  }
679
 
680
  function sanitize_file_name($name) {
@@ -689,10 +684,8 @@ class NewsletterModule {
689
  $page = $this->sanitize_file_name($parts[2]);
690
  $page = str_replace('_', '-', $page);
691
 
692
- $file = WP_CONTENT_DIR . '/extensions/newsletter/' . $module . '/' . $page . '.php';
693
- if (!is_file($file)) {
694
- $file = NEWSLETTER_DIR . '/' . $module . '/' . $page . '.php';
695
- }
696
  require $file;
697
  }
698
 
@@ -824,7 +817,7 @@ class NewsletterModule {
824
  }
825
 
826
  function get_email_status_slug($email) {
827
- $email = (object)$email;
828
  if ($email->status == 'sending' && $email->send_on > time()) {
829
  return 'scheduled';
830
  }
@@ -832,7 +825,7 @@ class NewsletterModule {
832
  }
833
 
834
  function get_email_status_label($email) {
835
- $email = (object)$email;
836
  $status = $this->get_email_status_slug($email);
837
  switch ($status) {
838
  case 'sending':
@@ -860,9 +853,9 @@ class NewsletterModule {
860
 
861
  function show_email_progress_bar($email, $attrs = array()) {
862
 
863
- $email = (object)$email;
864
 
865
- $attrs = array_merge(array('format' => 'percent', 'numbers' => false, 'scheduled' => false), $attrs);
866
 
867
  if ($email->status == 'sending' && $email->send_on > time()) {
868
  if ($attrs['scheduled']) {
2
 
3
  defined('ABSPATH') || exit;
4
 
5
+ class TNP_Composer {
6
+ static $block_dirs = array();
7
+
8
+ static function register_block($dir) {
9
+ // Checks
10
+
11
+ if (!file_exists($dir . '/block.php')) {
12
+ $error = new WP_Error('1', 'block.php missing on folder ' . $dir);
13
+ NewsletterEmails::instance()->logger->error($error);
14
+ return $error;
15
+ }
16
+ self::$block_dirs[] = $dir;
17
+ return true;
18
+ }
19
+ }
20
+
21
  /**
22
  * @property int $id The list unique identifier
23
  * @property string $name The list name
125
  */
126
  var $version;
127
  var $old_version;
 
 
128
 
129
  /**
130
  * Prefix for all options stored on WordPress options table.
141
  function __construct($module, $version, $module_id = null, $components = array()) {
142
  $this->module = $module;
143
  $this->version = $version;
 
144
  $this->prefix = 'newsletter_' . $module;
145
  array_unshift($components, '');
146
  $this->components = $components;
170
  }
171
 
172
  add_action('admin_menu', array($this, 'admin_menu'));
 
173
  }
174
  }
175
 
240
  $wpdb->suppress_errors($suppress_errors);
241
  }
242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  /** Returns a prefix to be used for option names and other things which need to be uniquely named. The parameter
244
  * "sub" should be used when a sub name is needed for another set of options or like.
245
  *
319
  }
320
 
321
  function merge_options($options, $sub = '', $language = '') {
322
+ if (!is_array($options)) {
323
  $options = array();
324
+ }
325
  $old_options = $this->get_options($sub, $language);
326
  $this->save_options(array_merge($old_options, $options), $sub, null, $language);
327
  }
371
  $time = 60;
372
  //usleep(rand(0, 1000000));
373
  if (($value = get_transient($this->get_prefix() . '_' . $name)) !== false) {
374
+ list($t, $v) = explode(';', $value, 2);
375
+ $this->logger->error('Blocked by transient ' . $this->get_prefix() . '_' . $name . ' set ' . (time() - $t) . ' seconds ago by ' . $v);
376
  return false;
377
  }
378
+ //$ip = ''; //gethostbyname(gethostname());
379
+ $value = time() . ";" . ABSPATH . ';' . gethostname();
380
+ set_transient($this->get_prefix() . '_' . $name, $value, $time);
381
  return true;
382
  }
383
 
660
  }
661
 
662
  function add_menu_page($page, $title, $capability = '') {
663
+ if (!Newsletter::instance()->is_allowed()) return;
664
  $name = 'newsletter_' . $this->module . '_' . $page;
665
+ add_submenu_page('newsletter_main_index', $title, $title, 'exist', $name, array($this, 'menu_page'));
 
 
 
666
  }
667
+
668
+ function add_admin_page($page, $title) {
669
+ if (!Newsletter::instance()->is_allowed()) return;
 
 
 
 
670
  $name = 'newsletter_' . $this->module . '_' . $page;
671
  $name = apply_filters('newsletter_admin_page', $name);
672
+ add_submenu_page(null, $title, $title, 'exist', $name, array($this, 'menu_page'));
673
  }
674
 
675
  function sanitize_file_name($name) {
684
  $page = $this->sanitize_file_name($parts[2]);
685
  $page = str_replace('_', '-', $page);
686
 
687
+ $file = NEWSLETTER_DIR . '/' . $module . '/' . $page . '.php';
688
+
 
 
689
  require $file;
690
  }
691
 
817
  }
818
 
819
  function get_email_status_slug($email) {
820
+ $email = (object) $email;
821
  if ($email->status == 'sending' && $email->send_on > time()) {
822
  return 'scheduled';
823
  }
825
  }
826
 
827
  function get_email_status_label($email) {
828
+ $email = (object) $email;
829
  $status = $this->get_email_status_slug($email);
830
  switch ($status) {
831
  case 'sending':
853
 
854
  function show_email_progress_bar($email, $attrs = array()) {
855
 
856
+ $email = (object) $email;
857
 
858
+ $attrs = array_merge(array('format' => 'percent', 'numbers' => false, 'scheduled' => false), $attrs);
859
 
860
  if ($email->status == 'sending' && $email->send_on > time()) {
861
  if ($attrs['scheduled']) {
includes/store.php CHANGED
@@ -97,6 +97,7 @@ class NewsletterStore {
97
 
98
  function sanitize($data) {
99
  global $wpdb;
 
100
  if (strpos($wpdb->charset, 'utf8mb4') === 0) return $data;
101
  foreach ($data as $key => $value) {
102
  $data[$key] = preg_replace('%(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})%xs', '', $value);
@@ -133,7 +134,7 @@ class NewsletterStore {
133
  if ($r === false) {
134
  $this->logger->fatal($wpdb->last_error);
135
  $this->logger->fatal($wpdb->last_query);
136
- die('Database error see the log files (log files path can be found on Newsletter diagnostic panel)');
137
  }
138
  }
139
  //$this->logger->debug('save: ' . $wpdb->last_query);
@@ -142,7 +143,7 @@ class NewsletterStore {
142
  if ($r === false) {
143
  $this->logger->fatal($wpdb->last_error);
144
  $this->logger->fatal($wpdb->last_query);
145
- die('Database error see the log files (log files path can be found on Newsletter diagnostic panel)');
146
  }
147
  $id = $wpdb->insert_id;
148
  }
97
 
98
  function sanitize($data) {
99
  global $wpdb;
100
+ //if (strpos($wpdb->charset, 'utf8mb4') === 0) return $data;
101
  if (strpos($wpdb->charset, 'utf8mb4') === 0) return $data;
102
  foreach ($data as $key => $value) {
103
  $data[$key] = preg_replace('%(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})%xs', '', $value);
134
  if ($r === false) {
135
  $this->logger->fatal($wpdb->last_error);
136
  $this->logger->fatal($wpdb->last_query);
137
+ die('Database error. If you were saving a newsletter try a table upgrade from the status panel.');
138
  }
139
  }
140
  //$this->logger->debug('save: ' . $wpdb->last_query);
143
  if ($r === false) {
144
  $this->logger->fatal($wpdb->last_error);
145
  $this->logger->fatal($wpdb->last_query);
146
+ die('Database error. If you were saving a newsletter try a table upgrade from the status panel.');
147
  }
148
  $id = $wpdb->insert_id;
149
  }
main/extensions.php CHANGED
@@ -48,17 +48,27 @@ if ($has_license) {
48
 
49
  <?php if (is_array($extensions)) { ?>
50
 
51
- <!--PREMIUM EXTENSIONS-->
52
  <?php foreach ($extensions AS $e) { ?>
53
 
54
  <?php
55
- $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=activate&id=' . $e->id, 'save');
56
- $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
 
 
 
 
57
  ?>
58
-
59
- <!--PREMIUM EXTENSIONS-->
60
- <?php if ($e->type == "premium") { ?>
 
 
61
  <div class="tnp-extension-premium-box <?php echo $e->slug ?>">
 
 
 
 
62
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>" alt="" /></div>
63
  <h3><?php echo $e->title ?></h3>
64
  <p><?php echo $e->description ?></p>
@@ -69,36 +79,49 @@ if ($has_license) {
69
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
70
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
71
  </a>
 
 
 
 
72
  <?php } else { ?>
73
- <?php if ($has_license) { ?>
74
- <a href="https://www.thenewsletterplugin.com/account" class="tnp-extension-install" target="_blank">
75
- DOWNLOAD NOW
76
- </a>
77
- <?php } else { ?>
78
- <a href="<?php echo $e->url ?>" class="tnp-extension-install" target="_blank">
79
- BUY NOW
80
- </a>
81
- <?php } ?>
 
82
  <?php } ?>
 
83
  </div>
 
84
  </div>
85
  <?php } ?>
86
  <?php } ?>
87
 
88
- <!--FREE EXTENSIONS-->
89
  <?php foreach ($extensions AS $e) { ?>
90
 
91
  <?php
92
- $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=activate&id=' . $e->id, 'save');
93
  if ($subscribed) {
94
  $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
95
  } else {
96
  $e->install_url = 'javascript:newsletter_subscribe(' . $e->id . ')';
97
  }
98
  ?>
99
- <?php if ($e->type == "free") { ?>
 
100
  <div class="tnp-extension-free-box <?php echo $e->slug ?>">
101
- <img class="tnp-extensions-free-badge" src="<?php echo plugins_url('newsletter') ?>/images/extension-free.png">
 
 
 
 
 
102
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>"></div>
103
  <h3><?php echo $e->title ?></h3>
104
  <p><?php echo $e->description ?></p>
@@ -109,26 +132,52 @@ if ($has_license) {
109
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
110
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
111
  </a>
 
 
 
 
112
  <?php } else { ?>
113
- <a href="<?php echo $e->url ?>" class="tnp-extension-install" target="_blank">
114
- <i class="fa fa-download" aria-hidden="true"></i> Download now
115
  </a>
116
  <?php } ?>
 
 
 
 
 
 
 
 
 
 
117
  </div>
118
  </div>
119
  <?php } ?>
120
 
121
  <?php } ?>
122
 
123
- <!-- INTEGRATIONS -->
124
  <?php foreach ($extensions AS $e) { ?>
125
 
126
  <?php
127
- $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=activate&id=' . $e->id, 'save');
128
- $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
 
 
 
 
129
  ?>
130
- <?php if ($e->type == "integration") { ?>
 
 
 
 
131
  <div class="tnp-integration-box <?php echo $e->slug ?>">
 
 
 
 
132
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>" alt="" /></div>
133
  <h3><?php echo $e->title ?></h3>
134
  <p><?php echo $e->description ?></p>
@@ -139,17 +188,25 @@ if ($has_license) {
139
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
140
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
141
  </a>
 
 
 
 
142
  <?php } else { ?>
143
- <?php if ($has_license) { ?>
144
- <a href="https://www.thenewsletterplugin.com/account" class="tnp-extension-install" target="_blank">
145
- DOWNLOAD NOW
146
- </a>
147
- <?php } else { ?>
148
- <a href="<?php echo $e->url ?>" class="tnp-extension-install" target="_blank">
149
- BUY NOW
150
- </a>
151
- <?php } ?>
 
 
 
152
  <?php } ?>
 
153
  </div>
154
  </div>
155
  <?php } ?>
48
 
49
  <?php if (is_array($extensions)) { ?>
50
 
51
+ <!-- Extensions -->
52
  <?php foreach ($extensions AS $e) { ?>
53
 
54
  <?php
55
+ $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_extensions_index&act=activate&id=' . $e->id, 'save');
56
+ if ($subscribed) {
57
+ $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
58
+ } else {
59
+ $e->install_url = 'javascript:newsletter_subscribe(' . $e->id . ')';
60
+ }
61
  ?>
62
+
63
+ <?php if ($e->type == "extension" || $e->type == "premium") { ?>
64
+ <?php if ($e->free) { ?>
65
+ <div class="tnp-extension-free-box <?php echo $e->slug ?>">
66
+ <?php } else { ?>
67
  <div class="tnp-extension-premium-box <?php echo $e->slug ?>">
68
+ <?php } ?>
69
+ <?php if ($e->free) { ?>
70
+ <img class="tnp-extensions-free-badge" src="<?php echo plugins_url('newsletter')?>/images/extension-free.png">
71
+ <?php } ?>
72
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>" alt="" /></div>
73
  <h3><?php echo $e->title ?></h3>
74
  <p><?php echo $e->description ?></p>
79
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
80
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
81
  </a>
82
+ <?php } elseif ($e->downloadable) { ?>
83
+ <a href="<?php echo $e->install_url ?>" class="tnp-extension-install">
84
+ <i class="fa fa-download" aria-hidden="true"></i> Install Now
85
+ </a>
86
  <?php } else { ?>
87
+ <a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=extpanel" class="tnp-extension-buy" target="_blank">
88
+ <i class="fa fa-shopping-cart" aria-hidden="true"></i> Buy Now
89
+ </a>
90
+ <?php } ?>
91
+ <!--
92
+ <?php if ($e->url) { ?>
93
+ <br><br>
94
+ <a href="<?php echo $e->url ?>" class="tnp-extension-details" target="_blank">
95
+ View details
96
+ </a>
97
  <?php } ?>
98
+ -->
99
  </div>
100
+
101
  </div>
102
  <?php } ?>
103
  <?php } ?>
104
 
105
+ <!-- Integrations -->
106
  <?php foreach ($extensions AS $e) { ?>
107
 
108
  <?php
109
+ $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_extensions_index&act=activate&id=' . $e->id, 'save');
110
  if ($subscribed) {
111
  $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
112
  } else {
113
  $e->install_url = 'javascript:newsletter_subscribe(' . $e->id . ')';
114
  }
115
  ?>
116
+ <?php if ($e->type == "integration") { ?>
117
+ <?php if ($e->free) { ?>
118
  <div class="tnp-extension-free-box <?php echo $e->slug ?>">
119
+ <?php } else { ?>
120
+ <div class="tnp-integration-box <?php echo $e->slug ?>">
121
+ <?php } ?>
122
+ <?php if ($e->free) { ?>
123
+ <img class="tnp-extensions-free-badge" src="<?php echo plugins_url('newsletter')?>/images/extension-free.png">
124
+ <?php } ?>
125
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>"></div>
126
  <h3><?php echo $e->title ?></h3>
127
  <p><?php echo $e->description ?></p>
132
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
133
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
134
  </a>
135
+ <?php } elseif ($e->downloadable) { ?>
136
+ <a href="<?php echo $e->install_url ?>" class="tnp-extension-install">
137
+ <i class="fa fa-download" aria-hidden="true"></i> Install Now
138
+ </a>
139
  <?php } else { ?>
140
+ <a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=extpanel" class="tnp-extension-buy" target="_blank">
141
+ <i class="fa fa-shopping-cart" aria-hidden="true"></i> Buy Now
142
  </a>
143
  <?php } ?>
144
+ <!--
145
+ <?php if ($e->url) { ?>
146
+ <br><br>
147
+ <div class="tnp-integration-details">
148
+ <a href="<?php echo $e->url ?>" class="tnp-extension-details" target="_blank">
149
+ View details
150
+ </a>
151
+ </div>
152
+ <?php } ?>
153
+ -->
154
  </div>
155
  </div>
156
  <?php } ?>
157
 
158
  <?php } ?>
159
 
160
+ <!-- Delivery -->
161
  <?php foreach ($extensions AS $e) { ?>
162
 
163
  <?php
164
+ $e->activate_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_extensions_index&act=activate&id=' . $e->id, 'save');
165
+ if ($subscribed) {
166
+ $e->install_url = wp_nonce_url(admin_url('admin.php') . '?page=newsletter_main_extensions&act=install&id=' . $e->id, 'save');
167
+ } else {
168
+ $e->install_url = 'javascript:newsletter_subscribe(' . $e->id . ')';
169
+ }
170
  ?>
171
+
172
+ <?php if ($e->type == "delivery") { ?>
173
+ <?php if ($e->free) { ?>
174
+ <div class="tnp-extension-free-box <?php echo $e->slug ?>">
175
+ <?php } else { ?>
176
  <div class="tnp-integration-box <?php echo $e->slug ?>">
177
+ <?php } ?>
178
+ <?php if ($e->free) { ?>
179
+ <img class="tnp-extensions-free-badge" src="<?php echo plugins_url('newsletter')?>/images/extension-free.png">
180
+ <?php } ?>
181
  <div class="tnp-extensions-image"><img src="<?php echo $e->image ?>" alt="" /></div>
182
  <h3><?php echo $e->title ?></h3>
183
  <p><?php echo $e->description ?></p>
188
  <a href="<?php echo $e->activate_url ?>" class="tnp-extension-activate">
189
  <i class="fa fa-power-off" aria-hidden="true"></i> <?php _e('Activate', 'newsletter') ?>
190
  </a>
191
+ <?php } elseif ($e->downloadable) { ?>
192
+ <a href="<?php echo $e->install_url ?>" class="tnp-extension-install">
193
+ <i class="fa fa-download" aria-hidden="true"></i> Install Now
194
+ </a>
195
  <?php } else { ?>
196
+ <a href="https://www.thenewsletterplugin.com/premium?utm_source=plugin&utm_medium=link&utm_campaign=extpanel" class="tnp-extension-buy" target="_blank">
197
+ <i class="fa fa-shopping-cart" aria-hidden="true"></i> Buy Now
198
+ </a>
199
+ <?php } ?>
200
+ <!--
201
+ <?php if ($e->url) { ?>
202
+ <br><br>
203
+ <div class="tnp-integration-details">
204
+ <a href="<?php echo $e->url ?>" class="tnp-extension-details" target="_blank">
205
+ View details
206
+ </a>
207
+ </div>
208
  <?php } ?>
209
+ -->
210
  </div>
211
  </div>
212
  <?php } ?>
main/main.php CHANGED
@@ -7,10 +7,16 @@ $module = Newsletter::instance();
7
 
8
  if (!$controls->is_action()) {
9
  $controls->data = get_option('newsletter_main');
 
 
 
 
10
  } else {
11
 
12
  if ($controls->is_action('save')) {
13
  $errors = null;
 
 
14
 
15
  // Validation
16
  $controls->data['sender_email'] = $module->normalize_email($controls->data['sender_email']);
@@ -268,9 +274,19 @@ if (!empty($return_path)) {
268
  </td>
269
  </tr>
270
  <tr>
271
- <th><?php _e('Enable access to blog editors?', 'newsletter') ?></th>
272
  <td>
273
- <?php $controls->yesno('editor'); ?>
 
 
 
 
 
 
 
 
 
 
274
  </td>
275
  </tr>
276
 
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'])) $controls->data['roles'] = 'editor';
13
+ }
14
  } else {
15
 
16
  if ($controls->is_action('save')) {
17
  $errors = null;
18
+
19
+ if (!isset($controls->data['roles'])) $controls->data['roles'] = array();
20
 
21
  // Validation
22
  $controls->data['sender_email'] = $module->normalize_email($controls->data['sender_email']);
274
  </td>
275
  </tr>
276
  <tr>
277
+ <th><?php _e('Allowed roles', 'newsletter') ?></th>
278
  <td>
279
+ <?php
280
+ $wp_roles = get_editable_roles();
281
+ $roles = array();
282
+ foreach ($wp_roles as $key=>$wp_role) {
283
+ if ($key == 'administrator') continue;
284
+ if ($key == 'subscriber') continue;
285
+ $roles[$key] = $wp_role['name'];
286
+ }
287
+ $controls->checkboxes('roles', $roles);
288
+ ?>
289
+
290
  </td>
291
  </tr>
292
 
main/status.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
- if (!defined('ABSPATH'))
3
- exit;
4
-
5
 
6
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
7
  $module = Newsletter::instance();
@@ -49,6 +47,20 @@ if ($controls->is_action('trigger')) {
49
  $controls->messages = 'Triggered';
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  if ($controls->is_action('test')) {
53
 
54
  if (!NewsletterModule::is_email($controls->data['test_email'])) {
@@ -423,7 +435,7 @@ $speed = Newsletter::$instance->options['scheduler_max'];
423
  <tr>
424
  <td>Database Charset</td>
425
  <td>
426
- <?php if (DB_CHARSET != 'utf8' && DB_CHARSET != 'utf8mb4') { ?>
427
  <span class="tnp-ko">KO</span>
428
  <?php } else { ?>
429
  <span class="tnp-ok">OK</span>
@@ -431,14 +443,15 @@ $speed = Newsletter::$instance->options['scheduler_max'];
431
 
432
  </td>
433
  <td>
434
- Charset: <?php echo DB_CHARSET; ?>
435
  <br>
436
- <?php if (DB_CHARSET != 'utf8' && DB_CHARSET != 'utf8mb4') { ?>
437
- The recommended charset for your database is <code>utf8</code> or <code>utf8mb4</code>
438
- but the <a href="https://codex.wordpress.org/Converting_Database_Character_Sets" target="_blank">conversion</a>
439
- could be tricky. If you're not experiencing problem, leave things as is.
440
  <?php } else { ?>
441
-
 
442
  <?php } ?>
443
  </td>
444
  </tr>
1
  <?php
2
+ defined('ABSPATH') || exit;
 
 
3
 
4
  @include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
5
  $module = Newsletter::instance();
47
  $controls->messages = 'Triggered';
48
  }
49
 
50
+ if ($controls->is_action('conversion')) {
51
+ $this->logger->info('Maybe convert to utf8mb4');
52
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
53
+ if (function_exists('maybe_convert_table_to_utf8mb4')) {
54
+ maybe_convert_table_to_utf8mb4(NEWSLETTER_EMAILS_TABLE);
55
+ maybe_convert_table_to_utf8mb4(NEWSLETTER_USERS_TABLE);
56
+ $controls->messages = 'Done.';
57
+ } else {
58
+ $controls->errors = 'Table conversion function not available';
59
+ }
60
+ Newsletter::instance()->hook_newsletter();
61
+ $controls->messages = 'Triggered';
62
+ }
63
+
64
  if ($controls->is_action('test')) {
65
 
66
  if (!NewsletterModule::is_email($controls->data['test_email'])) {
435
  <tr>
436
  <td>Database Charset</td>
437
  <td>
438
+ <?php if ($wpdb->charset != 'utf8mb4') { ?>
439
  <span class="tnp-ko">KO</span>
440
  <?php } else { ?>
441
  <span class="tnp-ok">OK</span>
443
 
444
  </td>
445
  <td>
446
+ Charset: <?php echo $wpdb->charset; ?>
447
  <br>
448
+ <?php if ($wpdb->charset != 'utf8mb4') { ?>
449
+ The recommended charset for your database is <code>utf8mb4</code> to avoid possible saving errors when you use emoji.
450
+ Read the WordPress Codex <a href="https://codex.wordpress.org/Converting_Database_Character_Sets" target="_blank">conversion
451
+ instructions</a> (skilled technicia required).
452
  <?php } else { ?>
453
+ If you experience newsletter saving database error
454
+ <?php $controls->button('conversion', 'Try tables upgrade')?>
455
  <?php } ?>
456
  </td>
457
  </tr>
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.0.8
8
  Author: Stefano Lissa & The Newsletter Team
9
  Author URI: https://www.thenewsletterplugin.com
10
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
@@ -29,7 +29,7 @@
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
- define('NEWSLETTER_VERSION', '6.0.8');
33
 
34
  global $newsletter, $wpdb;
35
 
@@ -297,12 +297,6 @@ class Newsletter extends NewsletterModule {
297
  ) $charset_collate;");
298
  $wpdb->suppress_errors($suppress_errors);
299
 
300
- // if ('utf8mb4' === $wpdb->charset) {
301
- // require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
302
- // if (function_exists('maybe_convert_table_to_utf8mb4')) {
303
- // maybe_convert_table_to_utf8mb4(NEWSLETTER_EMAILS_TABLE);
304
- // }
305
- // }
306
  // Some setting check to avoid the common support request for mis-configurations
307
  $options = $this->get_options();
308
 
@@ -341,23 +335,41 @@ class Newsletter extends NewsletterModule {
341
  return true;
342
  }
343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  function admin_menu() {
345
- // This adds the main menu page
346
- add_menu_page('Newsletter', 'Newsletter', ($this->options['editor'] == 1) ? 'manage_categories' : 'manage_options', 'newsletter_main_index', '', plugins_url('newsletter') . '/images/menu-icon.png', '30.333');
347
 
348
- $this->add_menu_page('index', 'Dashboard');
349
- $this->add_menu_page('welcome', 'Welcome');
350
- $this->add_menu_page('main', 'Settings and More', 'manage_options');
351
 
 
 
352
 
353
- $this->add_admin_page('smtp', 'SMTP', 'manage_options');
354
- $this->add_admin_page('status', 'Status', 'manage_options');
355
- $this->add_admin_page('info', 'Company info');
 
 
 
356
  }
357
 
358
  function add_extensions_menu() {
359
  if (!class_exists('NewsletterExtensions')) {
360
- $this->add_menu_page('extensions', '<span style="color:#27AE60; font-weight: bold;">Addons</span>');
361
  }
362
  }
363
 
@@ -422,10 +434,6 @@ class Newsletter extends NewsletterModule {
422
  return;
423
  }
424
 
425
- // TODO: Remove!
426
- $cache_stop = true;
427
- $hyper_cache_stop = true;
428
-
429
  if ($this->action == 'fu') {
430
  $user = $this->check_user();
431
  if ($user == null) {
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.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.
29
  */
30
 
31
  // Used as dummy parameter on css and js links
32
+ define('NEWSLETTER_VERSION', '6.1.2');
33
 
34
  global $newsletter, $wpdb;
35
 
297
  ) $charset_collate;");
298
  $wpdb->suppress_errors($suppress_errors);
299
 
 
 
 
 
 
 
300
  // Some setting check to avoid the common support request for mis-configurations
301
  $options = $this->get_options();
302
 
335
  return true;
336
  }
337
 
338
+ function is_allowed() {
339
+ if (current_user_can('administrator')) {
340
+ return true;
341
+ }
342
+ if (!empty($this->options['editor']) && current_user_can('editor')) return true;
343
+ if (!empty($this->options['roles'])) {
344
+ foreach ($this->options['roles'] as $role) {
345
+ if (current_user_can($role)) {
346
+ return true;
347
+ }
348
+ }
349
+ }
350
+ return false;
351
+ }
352
+
353
  function admin_menu() {
354
+ if (!$this->is_allowed())
355
+ return;
356
 
357
+ add_menu_page('Newsletter', 'Newsletter', 'exist', 'newsletter_main_index', '', plugins_url('newsletter') . '/images/menu-icon.png', '30.333');
 
 
358
 
359
+ $this->add_menu_page('index', __('Dashboard', 'newsletter'));
360
+ $this->add_admin_page('info', __('Company info', 'newsletter'));
361
 
362
+ if (current_user_can('administrator')) {
363
+ $this->add_menu_page('welcome', __('Welcome', 'newsletter'));
364
+ $this->add_menu_page('main', __('Settings and More', 'newsletter'));
365
+ $this->add_admin_page('smtp', 'SMTP');
366
+ $this->add_admin_page('status', __('Status', 'newsletter'));
367
+ }
368
  }
369
 
370
  function add_extensions_menu() {
371
  if (!class_exists('NewsletterExtensions')) {
372
+ $this->add_menu_page('extensions', '<span style="color:#27AE60; font-weight: bold;">' . __('Addons', 'newsletter') . '</span>');
373
  }
374
  }
375
 
434
  return;
435
  }
436
 
 
 
 
 
437
  if ($this->action == 'fu') {
438
  $user = $this->check_user();
439
  if ($user == null) {
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.0.8
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
@@ -50,25 +50,27 @@ Improve The Newsletter Plugin with these free addons:
50
  * [Archive](https://www.thenewsletterplugin.com/documentation/archive-extension) - creates a simple blog page which lists all your sent newsletters
51
  * [Locked Content](https://www.thenewsletterplugin.com/documentation/locked-content-extension) - open up your premium content only after subscription
52
  * [Newsletter REST API](https://www.thenewsletterplugin.com/developers/dev-newsletter-api) - adds a tier of REST api to integrate with the Newsletter core services
 
53
 
54
- (*easily add them from our Addons panel*)
55
 
56
  = Professional Addons =
57
 
58
  Need *more power*? Feel *something's missing*? The Newsletter Plugin features can be easily extended through our **premium, professional Addons**! Let us introduce just two of them : )
59
 
60
- * [Reports](https://www.thenewsletterplugin.com/reports) - improves the internal statistics collection system and provides better reports of data collected for each sent email. And retargeting. Neat.
61
- * [Automated](https://www.thenewsletterplugin.com/automated) - generates and sends your newsletters using your blog last posts, even custom ones like events or products. Just sit and watch!
62
- * [Autoresponder](https://www.thenewsletterplugin.com/autorespoder) - creates email series to follow up your subscribers
63
  * [WooCommerce Integration](https://www.thenewsletterplugin.com/woocommerce) - subscribe customers to a mailing list and generate product newletters.
 
 
 
 
64
  * [Amazon SES and other mail providers integration](https://www.thenewsletterplugin.com/integrations) - seamlessly integrate Amazon SES and other email service providers with The Newsletter Plugin. Hassle-free.
65
  * [Contact Form 7 Integration](https://www.thenewsletterplugin.com/documentation/contact-form-7-extension) - integrate the subscription on Contact Form 7 forms
66
  * [Ninja Forms Integration](https://www.thenewsletterplugin.com/documentation/ninjaforms-extension) - integrate the subscription on Ninja Forms
67
- * Events Manager and The Events Calendar integrations - add events to your newsletters
68
  * [WP Forms Integration](https://www.thenewsletterplugin.com/documentation/wpforms-extension) - integrate the subscription on WP Forms
 
69
  * [Google Analytics](https://www.thenewsletterplugin.com/google-analytics) - track newsletter links with Google UTM tracking paramaters
70
  * [Subscribe on Comment](https://www.thenewsletterplugin.com/documentation/comments-extension) - adds the subscription option to your blog comment form
71
- * Extended Composer Blocks - adds new blocks to the composer
72
  * [Geolocation](https://www.thenewsletterplugin.com/documentation/geolocation-extension) - adds geolocation capability to target subscribers by location
73
 
74
  = GDPR =
@@ -89,12 +91,6 @@ Premium Users with an active license have access to one-to-one support via our [
89
  * **Our Facebook Page** - [https://www.facebook.com/thenewsletterplugin](https://www.facebook.com/thenewsletterplugin)
90
  * **Our Twitter Account** - [https://twitter.com/newsletterwp](https://twitter.com/newsletterwp)
91
 
92
- == Installation ==
93
-
94
- 1. Put the plug-in folder into [wordpress_dir]/wp-content/plugins/
95
- 2. Go into the WordPress admin interface and activate the plugin
96
- 3. Optional: go to the options page and configure the plugin
97
-
98
  == Frequently Asked Questions ==
99
 
100
  See the [Newsletter FAQ](https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-faq) or the
@@ -112,6 +108,28 @@ Thank you, The Newsletter Team
112
 
113
  == Changelog ==
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  = 6.0.8 =
116
 
117
  * Specific link tracking patch for ElasticEmail
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.2
6
  Contributors: satollo,webagile,michael-travan
7
 
8
  Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
50
  * [Archive](https://www.thenewsletterplugin.com/documentation/archive-extension) - creates a simple blog page which lists all your sent newsletters
51
  * [Locked Content](https://www.thenewsletterplugin.com/documentation/locked-content-extension) - open up your premium content only after subscription
52
  * [Newsletter REST API](https://www.thenewsletterplugin.com/developers/dev-newsletter-api) - adds a tier of REST api to integrate with the Newsletter core services
53
+ * BuddyPress integration - subscription opt-in inside BuddyPress signup form
54
 
55
+ (*easily add them from our [Addons panel](https://www.thenewsletterplugin.com/documentation/install-extensions)*)
56
 
57
  = Professional Addons =
58
 
59
  Need *more power*? Feel *something's missing*? The Newsletter Plugin features can be easily extended through our **premium, professional Addons**! Let us introduce just two of them : )
60
 
61
+ * Extended Composer Blocks - adds new blocks to the drag & drop composer
 
 
62
  * [WooCommerce Integration](https://www.thenewsletterplugin.com/woocommerce) - subscribe customers to a mailing list and generate product newletters.
63
+ * [Reports](https://www.thenewsletterplugin.com/reports) - improves the internal statistics collection system and provides better reports of data collected for each sent email. And retargeting. Neat.
64
+ * [Automated](https://www.thenewsletterplugin.com/automated) - generates and sends your newsletters using your blog last posts, even custom ones like events or products. Just sit and watch!
65
+ * [Autoresponder](https://www.thenewsletterplugin.com/autoresponder) - creates email series to follow up your subscribers
66
+ * [Leads](https://www.thenewsletterplugin.com/leads) adds a fancy subscription popup box or a fixed bar to your website that will boost your conversion rate
67
  * [Amazon SES and other mail providers integration](https://www.thenewsletterplugin.com/integrations) - seamlessly integrate Amazon SES and other email service providers with The Newsletter Plugin. Hassle-free.
68
  * [Contact Form 7 Integration](https://www.thenewsletterplugin.com/documentation/contact-form-7-extension) - integrate the subscription on Contact Form 7 forms
69
  * [Ninja Forms Integration](https://www.thenewsletterplugin.com/documentation/ninjaforms-extension) - integrate the subscription on Ninja Forms
 
70
  * [WP Forms Integration](https://www.thenewsletterplugin.com/documentation/wpforms-extension) - integrate the subscription on WP Forms
71
+ * Events Manager and The Events Calendar (By Modern Tribe) integrations - easily add events to your newsletters
72
  * [Google Analytics](https://www.thenewsletterplugin.com/google-analytics) - track newsletter links with Google UTM tracking paramaters
73
  * [Subscribe on Comment](https://www.thenewsletterplugin.com/documentation/comments-extension) - adds the subscription option to your blog comment form
 
74
  * [Geolocation](https://www.thenewsletterplugin.com/documentation/geolocation-extension) - adds geolocation capability to target subscribers by location
75
 
76
  = GDPR =
91
  * **Our Facebook Page** - [https://www.facebook.com/thenewsletterplugin](https://www.facebook.com/thenewsletterplugin)
92
  * **Our Twitter Account** - [https://twitter.com/newsletterwp](https://twitter.com/newsletterwp)
93
 
 
 
 
 
 
 
94
  == Frequently Asked Questions ==
95
 
96
  See the [Newsletter FAQ](https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-faq) or the
108
 
109
  == Changelog ==
110
 
111
+ = 6.1.2 =
112
+
113
+ * Added support for roles
114
+
115
+ = 6.1.1 =
116
+
117
+ * Added support for custom blocks
118
+
119
+ = 6.1.0 =
120
+
121
+ * Fixed data cleanup for non utf8mb4 database. Emoji not saved solved.
122
+ * Small changes to the addons panel
123
+
124
+ = 6.0.9 =
125
+
126
+ * Changed the access control for editors
127
+ * Added the convert to utf8mb4 on status panel
128
+ * Small loading improvements
129
+ * API Subscribe activation message fix
130
+ * Fixed debug notice on composer
131
+ * Fixed alt attribute on social block
132
+
133
  = 6.0.8 =
134
 
135
  * Specific link tracking patch for ElasticEmail
subscription/subscription.php CHANGED
@@ -483,7 +483,6 @@ class NewsletterSubscription extends NewsletterModule {
483
  $this->add_admin_page('profile', 'Subscription Form');
484
  $this->add_admin_page('forms', 'Forms');
485
  $this->add_admin_page('lists', 'Lists');
486
- $this->add_admin_page('lists-edit', 'List edit');
487
  $this->add_admin_page('template', 'Template');
488
  }
489
 
483
  $this->add_admin_page('profile', 'Subscription Form');
484
  $this->add_admin_page('forms', 'Forms');
485
  $this->add_admin_page('lists', 'Lists');
 
486
  $this->add_admin_page('template', 'Template');
487
  }
488
 
tnp-header.php CHANGED
@@ -7,6 +7,8 @@ $dismissed = get_option('newsletter_dismissed', array());
7
 
8
  $user_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'");
9
 
 
 
10
  function newsletter_print_entries($group) {
11
  $entries = apply_filters('newsletter_menu_' . $group, array());
12
  if ($entries) {
@@ -100,20 +102,11 @@ $warning |= empty($status_options['mail']);
100
  </li>
101
  <li><a href="#"><i class="fa fa-cog"></i> <?php _e('Settings', 'newsletter') ?> <i class="fa fa-chevron-down"></i></a>
102
  <ul>
103
- <?php if (current_user_can('manage_options')) { ?>
104
  <li>
105
  <a href="?page=newsletter_main_main"><i class="fa fa-cogs"></i> <?php _e('General Settings', 'newsletter') ?>
106
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a>
107
  </li>
108
- <?php } ?>
109
-
110
- <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
111
- <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
112
- <li>
113
- <a href="?page=newsletter_subscription_template"><i class="fa fa-file-alt"></i> <?php _e('Messages Template', 'newsletter') ?>
114
- <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a>
115
- </li>
116
- <?php if (current_user_can('manage_options')) { ?>
117
  <?php if (!class_exists('NewsletterSmtp')) { ?>
118
  <li>
119
  <a href="?page=newsletter_main_smtp"><i class="fa fa-server"></i> <?php _e('SMTP', 'newsletter') ?>
@@ -122,6 +115,13 @@ $warning |= empty($status_options['mail']);
122
  </li>
123
  <?php } ?>
124
  <?php } ?>
 
 
 
 
 
 
 
125
 
126
  <?php
127
  newsletter_print_entries('settings');
@@ -129,7 +129,7 @@ $warning |= empty($status_options['mail']);
129
  </ul>
130
  </li>
131
 
132
- <?php if (current_user_can('manage_options')) { ?>
133
  <li>
134
  <a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
135
  <?php if ($warning) { ?>
7
 
8
  $user_count = $wpdb->get_var("select count(*) from " . NEWSLETTER_USERS_TABLE . " where status='C'");
9
 
10
+ $is_administrator = current_user_can('administrator');
11
+
12
  function newsletter_print_entries($group) {
13
  $entries = apply_filters('newsletter_menu_' . $group, array());
14
  if ($entries) {
102
  </li>
103
  <li><a href="#"><i class="fa fa-cog"></i> <?php _e('Settings', 'newsletter') ?> <i class="fa fa-chevron-down"></i></a>
104
  <ul>
105
+ <?php if ($is_administrator) { ?>
106
  <li>
107
  <a href="?page=newsletter_main_main"><i class="fa fa-cogs"></i> <?php _e('General Settings', 'newsletter') ?>
108
  <small><?php _e('Delivery speed, sender details, ...', 'newsletter') ?></small></a>
109
  </li>
 
 
 
 
 
 
 
 
 
110
  <?php if (!class_exists('NewsletterSmtp')) { ?>
111
  <li>
112
  <a href="?page=newsletter_main_smtp"><i class="fa fa-server"></i> <?php _e('SMTP', 'newsletter') ?>
115
  </li>
116
  <?php } ?>
117
  <?php } ?>
118
+
119
+ <li><a href="?page=newsletter_main_info"><i class="fa fa-info"></i> <?php _e('Company Info', 'newsletter') ?>
120
+ <small><?php _e('Social, address, logo and general info', 'newsletter') ?></small></a></li>
121
+ <li>
122
+ <a href="?page=newsletter_subscription_template"><i class="fa fa-file-alt"></i> <?php _e('Messages Template', 'newsletter') ?>
123
+ <small><?php _e('Change the look of your service emails', 'newsletter') ?></small></a>
124
+ </li>
125
 
126
  <?php
127
  newsletter_print_entries('settings');
129
  </ul>
130
  </li>
131
 
132
+ <?php if ($is_administrator) { ?>
133
  <li>
134
  <a href="?page=newsletter_main_status"><i class="fa fa-thermometer"></i> <?php _e('Status', 'newsletter') ?>
135
  <?php if ($warning) { ?>
users/users.php CHANGED
@@ -32,7 +32,7 @@ class NewsletterUsers extends NewsletterModule {
32
  function hook_wp_ajax_newsletter_users_export() {
33
 
34
  $newsletter = Newsletter::instance();
35
- if (current_user_can('manage_options') || ($newsletter->options['editor'] == 1 && current_user_can('manage_categories'))) {
36
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
37
  $controls = new NewsletterControls();
38
 
32
  function hook_wp_ajax_newsletter_users_export() {
33
 
34
  $newsletter = Newsletter::instance();
35
+ if ($newsletter->is_allowed()) {
36
  require_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
37
  $controls = new NewsletterControls();
38