| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327 |
- <?php
- /*
- Plugin Name: Newsletter
- Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
- 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>
- Version: 6.4.0
- Author: Stefano Lissa & The Newsletter Team
- Author URI: https://www.thenewsletterplugin.com
- Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
- Text Domain: newsletter
- License: GPLv2 or later
- Copyright 2009-2019 The Newsletter Team (email: info@thenewsletterplugin.com, web: https://www.thenewsletterplugin.com)
- Newsletter is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- any later version.
- Newsletter is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Newsletter. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
- */
- define('NEWSLETTER_VERSION', '6.4.0');
- global $newsletter, $wpdb;
- if (!defined('NEWSLETTER_EXTENSION_UPDATE'))
- define('NEWSLETTER_EXTENSION_UPDATE', true);
- if (!defined('NEWSLETTER_EMAILS_TABLE'))
- define('NEWSLETTER_EMAILS_TABLE', $wpdb->prefix . 'newsletter_emails');
- if (!defined('NEWSLETTER_USERS_TABLE'))
- define('NEWSLETTER_USERS_TABLE', $wpdb->prefix . 'newsletter');
- if (!defined('NEWSLETTER_STATS_TABLE'))
- define('NEWSLETTER_STATS_TABLE', $wpdb->prefix . 'newsletter_stats');
- if (!defined('NEWSLETTER_SENT_TABLE'))
- define('NEWSLETTER_SENT_TABLE', $wpdb->prefix . 'newsletter_sent');
- // Do not use basename(dirname()) since on activation the plugin is sandboxed inside a function
- define('NEWSLETTER_SLUG', 'newsletter');
- define('NEWSLETTER_DIR', __DIR__);
- define('NEWSLETTER_INCLUDES_DIR', __DIR__ . '/includes');
- // Almost obsolete but the first two must be kept for compatibility with modules
- define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
- if (!defined('NEWSLETTER_LIST_MAX'))
- define('NEWSLETTER_LIST_MAX', 40);
- if (!defined('NEWSLETTER_PROFILE_MAX'))
- define('NEWSLETTER_PROFILE_MAX', 20);
- if (!defined('NEWSLETTER_FORMS_MAX'))
- define('NEWSLETTER_FORMS_MAX', 10);
- if (!defined('NEWSLETTER_CRON_INTERVAL'))
- define('NEWSLETTER_CRON_INTERVAL', 300);
- if (!defined('NEWSLETTER_HEADER'))
- define('NEWSLETTER_HEADER', true);
- // Force the whole system log level to this value
- //define('NEWSLETTER_LOG_LEVEL', 4);
- require_once NEWSLETTER_INCLUDES_DIR . '/logger.php';
- require_once NEWSLETTER_INCLUDES_DIR . '/store.php';
- require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
- require_once NEWSLETTER_INCLUDES_DIR . '/mailers.php';
- require_once NEWSLETTER_INCLUDES_DIR . '/themes.php';
- require_once NEWSLETTER_INCLUDES_DIR . '/TNP.php';
- class Newsletter extends NewsletterModule {
- // Limits to respect to avoid memory, time or provider limits
- var $time_start;
- var $time_limit;
- var $email_limit = 10; // Per run, every 5 minutes
- var $limits_set = false;
- var $max_emails = 20;
- /**
- * @var PHPMailer
- */
- var $mailer;
- // Message shown when the interaction is inside a WordPress page
- var $message;
- var $user;
- var $error;
- var $theme;
- // Theme autocomposer variables
- var $theme_max_posts;
- var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
- var $theme_posts; // WP_Query object
- // Secret key to create a unique log file name (and may be other)
- var $action = '';
- /** @var Newsletter */
- static $instance;
- const MAX_CRON_SAMPLES = 100;
- const STATUS_NOT_CONFIRMED = 'S';
- const STATUS_CONFIRMED = 'C';
- /**
- * @return Newsletter
- */
- static function instance() {
- if (self::$instance == null) {
- self::$instance = new Newsletter();
- }
- return self::$instance;
- }
- function __construct() {
- // Grab it before a plugin decides to remove it.
- if (isset($_GET['na'])) {
- $this->action = $_GET['na'];
- }
- if (isset($_POST['na'])) {
- $this->action = $_POST['na'];
- }
- $this->time_start = time();
- // Here because the upgrade is called by the parent constructor and uses the scheduler
- add_filter('cron_schedules', function ($schedules) {
- $schedules['newsletter'] = array(
- 'interval' => NEWSLETTER_CRON_INTERVAL, // seconds
- 'display' => 'Every ' . NEWSLETTER_CRON_INTERVAL . ' seconds by Newsletter'
- );
- return $schedules;
- }, 1000);
- parent::__construct('main', '1.5.2', null, array('info', 'smtp'));
- $max = $this->options['scheduler_max'];
- if (!is_numeric($max)) {
- $max = 100;
- }
- $this->max_emails = max(floor($max / (3600 / NEWSLETTER_CRON_INTERVAL)), 1);
- add_action('plugins_loaded', array($this, 'hook_plugins_loaded'));
- add_action('init', array($this, 'hook_init'), 1);
- add_action('wp_loaded', array($this, 'hook_wp_loaded'), 1);
- add_action('newsletter', array($this, 'hook_newsletter'), 1);
- $this->update_cron_stats();
- register_activation_hook(__FILE__, array($this, 'hook_activate'));
- register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
- add_action('admin_init', array($this, 'hook_admin_init'));
- if (is_admin()) {
- add_action('admin_head', array($this, 'hook_admin_head'));
- // Protection against strange schedule removal on some installations
- if (!wp_next_scheduled('newsletter') && (!defined('WP_INSTALLING') || !WP_INSTALLING)) {
- wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
- }
- add_action('admin_menu', array($this, 'add_extensions_menu'), 90);
- }
- }
- function hook_init() {
- global $wpdb;
- if (isset($this->options['debug']) && $this->options['debug'] == 1) {
- ini_set('log_errors', 1);
- ini_set('error_log', WP_CONTENT_DIR . '/logs/newsletter/php-' . date('Y-m') . '-' . get_option('newsletter_logger_secret') . '.txt');
- }
- add_shortcode('newsletter_replace', array($this, 'shortcode_newsletter_replace'));
- add_filter('site_transient_update_plugins', array($this, 'hook_site_transient_update_plugins'));
- if (is_admin()) {
- if (!class_exists('NewsletterExtensions')) {
-
- add_filter('plugin_row_meta', function ($plugin_meta, $plugin_file) {
-
- static $slugs = array();
- if (empty($slugs)) {
- $addons = $this->getTnpExtensions();
- foreach ($addons as $addon) {
- $slugs[] = $addon->wp_slug;
- }
- }
- if (array_search($plugin_file, $slugs) !== false) {
- $plugin_meta[] = '<a href="admin.php?page=newsletter_main_extensions" style="font-weight: bold">Newsletter Addons Manager required</a>';
- }
- return $plugin_meta;
- }, 10, 2);
- }
-
- add_action('in_admin_header', array($this, 'hook_in_admin_header'), 1000);
- if ($this->is_admin_page()) {
- $newsletter_url = plugins_url('newsletter');
- wp_enqueue_script('jquery-ui-tabs');
- wp_enqueue_script('jquery-ui-tooltip');
- wp_enqueue_media();
- wp_enqueue_style('tnp-admin', $newsletter_url . '/admin.css', array(), filemtime(NEWSLETTER_DIR . '/admin.css'));
- wp_enqueue_script('tnp-admin', $newsletter_url . '/admin.js', array('jquery'), time());
- wp_enqueue_style('wp-color-picker');
- wp_enqueue_script('wp-color-picker');
- wp_enqueue_style('tnp-select2', $newsletter_url . '/vendor/select2/select2.css');
- wp_enqueue_script('tnp-select2', $newsletter_url . '/vendor/select2/select2.min.js');
- wp_enqueue_script('tnp-jquery-vmap', $newsletter_url . '/vendor/jqvmap/jquery.vmap.min.js', array('jquery'));
- wp_enqueue_script('tnp-jquery-vmap-world', $newsletter_url . '/vendor/jqvmap/jquery.vmap.world.js', array('tnp-jquery-vmap'));
- wp_enqueue_style('tnp-jquery-vmap', $newsletter_url . '/vendor/jqvmap/jqvmap.min.css');
- wp_register_script('tnp-chart', $newsletter_url . '/vendor/chartjs/Chart.min.js', array('jquery'));
- $dismissed = get_option('newsletter_dismissed', array());
- if (isset($_GET['dismiss'])) {
- $dismissed[$_GET['dismiss']] = 1;
- update_option('newsletter_dismissed', $dismissed);
- wp_redirect($_SERVER['HTTP_REFERER']);
- exit();
- }
- }
- } else {
- add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
- }
- do_action('newsletter_init');
- }
- function hook_wp_loaded() {
- if (empty($this->action)) {
- return;
- }
- if ($this->action == 'test') {
- echo 'ok';
- die();
- }
- do_action('newsletter_action', $this->action);
- }
- function update_cron_stats() {
- if (defined('DOING_CRON') && DOING_CRON) {
- $calls = get_option('newsletter_diagnostic_cron_calls', array());
- $calls[] = time();
- if (count($calls) > self::MAX_CRON_SAMPLES) {
- array_shift($calls);
- }
- update_option('newsletter_diagnostic_cron_calls', $calls, false);
- if (count($calls) > 50) {
- $mean = 0;
- $max = 0;
- $min = 0;
- for ($i = 1; $i < count($calls); $i++) {
- $diff = $calls[$i] - $calls[$i - 1];
- $mean += $diff;
- if ($min == 0 || $min > $diff) {
- $min = $diff;
- }
- if ($max < $diff) {
- $max = $diff;
- }
- }
- $mean = $mean / count($calls) - 1;
- update_option('newsletter_diagnostic_cron_data', array('mean' => $mean, 'max' => $max, 'min' => $min), false);
- } else {
- update_option('newsletter_diagnostic_cron_data', '', false);
- }
- }
- }
- function hook_activate() {
- // Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
- // the every-five-minutes schedule named "newsletter" is not present.
- // Since the activation does not forces an upgrade, that schedule must be reactivated here. It is activated on
- // the upgrade method as well for the user which upgrade the plugin without deactivte it (many).
- if (!wp_next_scheduled('newsletter')) {
- wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
- }
- $install_time = get_option('newsletter_install_time');
- if (!$install_time) {
- update_option('newsletter_install_time', time(), false);
- }
- Newsletter::instance()->upgrade();
- NewsletterUsers::instance()->upgrade();
- NewsletterEmails::instance()->upgrade();
- NewsletterSubscription::instance()->upgrade();
- NewsletterStatistics::instance()->upgrade();
- NewsletterProfile::instance()->upgrade();
- }
- function first_install() {
- parent::first_install();
- update_option('newsletter_show_welcome', '1', false);
- }
- function upgrade() {
- global $wpdb, $charset_collate;
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
- parent::upgrade();
- $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_emails` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `language` varchar(10) NOT NULL DEFAULT '',
- `subject` varchar(255) NOT NULL DEFAULT '',
- `message` longtext,
- `subject2` varchar(255) NOT NULL DEFAULT '',
- `message2` longtext,
- `name2` varchar(255) NOT NULL DEFAULT '',
- `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `status` enum('new','sending','sent','paused') NOT NULL DEFAULT 'new',
- `total` int(11) NOT NULL DEFAULT '0',
- `last_id` int(11) NOT NULL DEFAULT '0',
- `sent` int(11) NOT NULL DEFAULT '0',
- `track` int(11) NOT NULL DEFAULT '0',
- `list` int(11) NOT NULL DEFAULT '0',
- `type` varchar(50) NOT NULL DEFAULT '',
- `query` longtext,
- `editor` tinyint(4) NOT NULL DEFAULT '0',
- `sex` varchar(20) NOT NULL DEFAULT '',
- `theme` varchar(50) NOT NULL DEFAULT '',
- `message_text` longtext,
- `preferences` longtext,
- `send_on` int(11) NOT NULL DEFAULT '0',
- `token` varchar(10) NOT NULL DEFAULT '',
- `options` longtext,
- `private` tinyint(1) NOT NULL DEFAULT '0',
- `click_count` int(10) unsigned NOT NULL DEFAULT '0',
- `version` varchar(10) NOT NULL DEFAULT '',
- `open_count` int(10) unsigned NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`)) $charset_collate;";
- dbDelta($sql);
- // WP does not manage composite primary key when it tries to upgrade a table...
- $suppress_errors = $wpdb->suppress_errors(true);
- dbDelta("CREATE TABLE " . $wpdb->prefix . "newsletter_sent (
- email_id int(10) unsigned NOT NULL DEFAULT '0',
- user_id int(10) unsigned NOT NULL DEFAULT '0',
- status tinyint(1) unsigned NOT NULL DEFAULT '0',
- open tinyint(1) unsigned NOT NULL DEFAULT '0',
- time int(10) unsigned NOT NULL DEFAULT '0',
- error varchar(100) NOT NULL DEFAULT '',
- ip varchar(100) NOT NULL DEFAULT '',
- country varchar(4) NOT NULL DEFAULT '',
- PRIMARY KEY (email_id,user_id),
- KEY user_id (user_id),
- KEY email_id (email_id)
- ) $charset_collate;");
- $wpdb->suppress_errors($suppress_errors);
- // Some setting check to avoid the common support request for mis-configurations
- $options = $this->get_options();
- if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
- $options['scheduler_max'] = 100;
- $this->save_options($options);
- }
- wp_clear_scheduled_hook('newsletter');
- wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
- wp_clear_scheduled_hook('newsletter_extension_versions');
- // No more required
- //wp_schedule_event(time() + 30, 'daily', 'newsletter_extension_versions');
- $subscription_options = get_option('newsletter', array());
- // Settings migration
- if (empty($this->options['page'])) {
- if (isset($subscription_options['page']))
- $this->options['page'] = $subscription_options['page'];
- $this->save_options($this->options);
- }
- if (empty($this->options['css']) && !empty($subscription_options['css'])) {
- $this->options['css'] = $subscription_options['css'];
- $this->save_options($this->options);
- }
- // Migration of "info" options
- $info_options = $this->get_options('info');
- if (!empty($this->options['header_logo']) && empty($info_options['header_logo'])) {
- $info_options = $this->options;
- $this->save_options($info_options, 'info');
- }
- if (!empty($this->options['editor'])) {
- if (empty($this->options['roles'])) {
- $this->options['roles'] = array('editor');
- unset($this->options['editor']);
- }
- $this->save_options($this->options);
- }
- return true;
- }
- function is_allowed() {
- if (current_user_can('administrator')) {
- return true;
- }
- if (!empty($this->options['roles'])) {
- foreach ($this->options['roles'] as $role) {
- if (current_user_can($role)) {
- return true;
- }
- }
- }
- return false;
- }
- function admin_menu() {
- if (!$this->is_allowed())
- return;
- add_menu_page('Newsletter', 'Newsletter', 'exist', 'newsletter_main_index', '', plugins_url('newsletter') . '/images/menu-icon.png', '30.333');
- $this->add_menu_page('index', __('Dashboard', 'newsletter'));
- $this->add_admin_page('info', __('Company info', 'newsletter'));
- if (current_user_can('administrator')) {
- $this->add_menu_page('welcome', __('Welcome', 'newsletter'));
- $this->add_menu_page('main', __('Settings and More', 'newsletter'));
- $this->add_admin_page('smtp', 'SMTP');
- $this->add_admin_page('status', __('Status', 'newsletter'));
- }
- }
- function add_extensions_menu() {
- if (!class_exists('NewsletterExtensions')) {
- $this->add_menu_page('extensions', '<span style="color:#27AE60; font-weight: bold;">' . __('Addons', 'newsletter') . '</span>');
- }
- }
- /**
- * Returns a set of warnings about this installtion the suser should be aware of. Return an empty string
- * if there are no warnings.
- */
- function warnings() {
-
- }
- function hook_in_admin_header() {
- if (!$this->is_admin_page()) {
- add_action('admin_notices', array($this, 'hook_admin_notices'));
- return;
- }
- remove_all_actions('admin_notices');
- remove_all_actions('all_admin_notices');
- add_action('admin_notices', array($this, 'hook_admin_notices'));
- }
- function hook_admin_notices() {
- // Check of Newsletter dedicated page
- if (!empty($this->options['page'])) {
- if (get_post_status($this->options['page']) !== 'publish') {
- echo '<div class="notice notice-error"><p>The Newsletter dedicated page is not published. <a href="', site_url('/wp-admin/post.php') . '?post=', $this->options['page'], '&action=edit"><strong>Edit the page</strong></a> or <a href="admin.php?page=newsletter_main_main"><strong>review the main settings</strong></a>.</p></div>';
- }
- }
- if (isset($this->options['debug']) && $this->options['debug'] == 1) {
- echo '<div class="notice notice-warning"><p>The Newsletter plugin is in <strong>debug mode</strong>. When done change it on Newsletter <a href="admin.php?page=newsletter_main_main"><strong>main settings</strong></a>. Do not keep the debug mode active on production sites.</p></div>';
- }
- if (!defined('NEWSLETTER_CRON_WARNINGS') || NEWSLETTER_CRON_WARNINGS) {
- $x = wp_next_scheduled('newsletter');
- if ($x === false) {
- echo '<div class="notice notice-error"><p>The Newsletter delivery engine is off (it should never be off). Deactivate and reactivate the Newsletter plugin.</p></div>';
- } else if (time() - $x > 900) {
- echo '<div class="notice notice-error"><p>The WP scheduler doesn\'t seem to be running correctly for Newsletter. <a href="https://www.thenewsletterplugin.com/documentation/newsletter-delivery-engine#cron" target="_blank"><strong>Read this page to solve the problem</strong></a>.</p></div>';
- } else {
- // if (empty($this->options['disable_cron_notice'])) {
- // $cron_data = get_option('newsletter_diagnostic_cron_data');
- // if ($cron_data && $cron_data['mean'] > 500) {
- // echo '<div class="notice notice-error"><p>The WP scheduler doesn\'t seem to be triggered enough often for Newsletter. <a href="https://www.thenewsletterplugin.com/documentation/newsletter-delivery-engine#cron" target="_blank"><strong>Read this page to solve the problem</strong></a> or disable this notice on <a href="admin.php?page=newsletter_main_main"><strong>main settings</strong></a>.</p></div>';
- // }
- // }
- }
- }
- }
- function hook_wp_enqueue_scripts() {
- if (empty($this->options['css_disabled']) && apply_filters('newsletter_enqueue_style', true)) {
- wp_enqueue_style('newsletter', plugins_url('newsletter') . '/style.css', array(), NEWSLETTER_VERSION);
- if (!empty($this->options['css'])) {
- wp_add_inline_style('newsletter', $this->options['css']);
- }
- }
- }
- function shortcode_newsletter_replace($attrs, $content) {
- $content = do_shortcode($content);
- $content = $this->replace($content, $this->get_user_from_request(), $this->get_email_from_request());
- return $content;
- }
- function is_admin_page() {
- if (!isset($_GET['page'])) {
- return false;
- }
- $page = $_GET['page'];
- return strpos($page, 'newsletter_') === 0;
- }
- function hook_admin_init() {
- // Verificare il contesto
- if (isset($_GET['page']) && $_GET['page'] === 'newsletter_main_welcome')
- return;
- if (get_option('newsletter_show_welcome')) {
- delete_option('newsletter_show_welcome');
- wp_redirect(admin_url('admin.php?page=newsletter_main_welcome'));
- }
- // https://developer.wordpress.org/plugins/privacy/suggesting-text-for-the-site-privacy-policy/
- // https://make.wordpress.org/core/2018/05/17/4-9-6-update-guide/
- if (function_exists('wp_add_privacy_policy_content')) {
- //wp_add_privacy_policy_content('Newsletter', wp_kses_post( wpautop( $content, false )));
- }
- }
- function hook_admin_head() {
- // Small global rule for sidebar menu entries
- echo '<style>';
- echo '.tnp-side-menu { color: #E67E22!important; }';
- echo '</style>';
- }
- function relink($text, $email_id, $user_id, $email_token = '') {
- return NewsletterStatistics::instance()->relink($text, $email_id, $user_id, $email_token);
- }
- /**
- * Runs every 5 minutes and look for emails that need to be processed.
- */
- function hook_newsletter() {
- global $wpdb;
- $this->logger->debug(__METHOD__ . '> Start');
- // Do not accept job activation before at least 4 minutes are elapsed from the last run.
- if (!$this->check_transient('engine', NEWSLETTER_CRON_INTERVAL)) {
- return;
- }
- // Retrieve all emails in "sending" status
- $emails = $this->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where status='sending' and send_on<" . time() . " order by id asc");
- $this->logger->debug(__METHOD__ . '> Emails found in sending status: ' . count($emails));
- foreach ($emails as $email) {
- $this->logger->info(__METHOD__ . '> Start newsletter ' . $email->id);
- $r = $this->send($email);
- if ($this->limits_exceeded()) {
- break;
- }
- $this->logger->info(__METHOD__ . '> End newsletter ' . $email->id);
- }
- // Remove the semaphore so the delivery engine can be activated again
- $this->delete_transient('engine');
- $this->logger->debug(__METHOD__ . '> End');
- }
- /**
- * Sends an email to targeted users or to given users. If a list of users is given (usually a list of test users)
- * the query inside the email to retrieve users is not used.
- *
- * @global wpdb $wpdb
- * @global type $newsletter_feed
- * @param TNP_Email $email
- * @param array $users
- * @return boolean True if the proccess completed, false if limits was reached. On false the caller should no continue to call it with other emails.
- */
- function send($email, $users = null, $test = false) {
- global $wpdb;
- ignore_user_abort(true);
- if (is_array($email)) {
- $email = (object) $email;
- }
- // Could be a test
- if (empty($email->id)) {
- $email->id = 0;
- }
- $this->logger->info(__METHOD__ . '> Start run for email ' . $email->id);
- // This stops the update of last_id and sent fields since it's not a scheduled delivery but a test or something else (like an autoresponder)
- $supplied_users = $users != null;
- if ($users == null) {
- $skip_this_run = apply_filters('newsletter_send_skip', false, $email);
- if ($skip_this_run) {
- return false;
- }
- if (empty($email->query)) {
- $email->query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
- }
- // TODO: Ask the max emails per hour/run (to be decided) to the mailer
- $email->options = maybe_unserialize($email->options);
- $max_emails = apply_filters('newsletter_send_max_emails', $this->max_emails, $email);
- $this->logger->debug(__METHOD__ . '> Max emails per run: ' . $max_emails);
- if (empty($max_emails)) {
- $this->logger->debug(__METHOD__ . '> Max emails empty after the filter');
- $max_emails = $this->max_emails;
- }
- //$query = apply_filters('newsletter_send_query', $email->query, $email);
- $query = $email->query;
- $query .= " and id>" . $email->last_id . " order by id limit " . $max_emails;
- $this->logger->debug(__METHOD__ . '> Query: ' . $query);
- $users = $this->get_results($query);
- $this->logger->debug(__METHOD__ . '> Loaded users: ' . count($users));
- // If there was a database error, do nothing
- if ($users === false) {
- return new WP_Error('1', 'Unable to query subscribers, check the logs');
- }
- if (empty($users)) {
- $this->logger->info(__METHOD__ . '> No more users, set as sent');
- $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
- return true;
- }
- } else {
- $this->logger->info(__METHOD__ . '> Subscribers supplied');
- }
- $start_time = microtime(true);
- $count = 0;
- $result = true;
- $mailer = $this->get_mailer();
- $batch_size = $mailer->get_batch_size();
- $this->logger->debug(__METHOD__ . '> Batch size: ' . $batch_size);
- // For batch size == 1 (normal condition) we optimize
- if ($batch_size == 1) {
- foreach ($users as $user) {
- if (!$supplied_users && !$test && $this->limits_exceeded()) {
- $result = false;
- break;
- }
- $this->logger->debug(__METHOD__ . '> Processing user ID: ' . $user->id);
- $user = apply_filters('newsletter_send_user', $user);
- $message = $this->build_message($email, $user);
- $this->save_sent_message($message);
- if (!$test) {
- $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
- }
- $r = $mailer->send($message);
- if (!empty($message->error)) {
- $this->save_sent_message($message);
- }
- if (is_wp_error($r)) {
- $this->logger->error($r);
- return $r;
- }
- }
- // TODO: Review if they're useful
- $this->email_limit--;
- $count++;
- } else {
- $chunks = array_chunk($users, $batch_size);
- foreach ($chunks as $chunk) {
- if (!$supplied_users && !$test && $this->limits_exceeded()) {
- $result = false;
- break;
- }
- $messages = array();
- foreach ($chunk as $user) {
- $this->logger->debug(__METHOD__ . '> Processing user ID: ' . $user->id);
- $user = apply_filters('newsletter_send_user', $user);
- $message = $this->build_message($email, $user);
- $this->save_sent_message($message);
- $messages[] = $message;
- if (!$test) {
- $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
- }
- $this->email_limit--;
- $count++;
- }
- $r = $mailer->send_batch($messages);
- foreach ($messages as $message) {
- if (!empty($message->error)) {
- $this->save_sent_message($message);
- }
- }
- if (is_wp_error($r)) {
- $this->logger->error($r);
- return $r;
- }
- }
- }
- $end_time = microtime(true);
- if ($count > 0) {
- $send_calls = get_option('newsletter_diagnostic_send_calls', array());
- $send_calls[] = array($start_time, $end_time, $count, $result);
- if (count($send_calls) > self::MAX_CRON_SAMPLES)
- array_shift($send_calls);
- update_option('newsletter_diagnostic_send_calls', $send_calls, false);
- }
- if ($supplied_users && $this->limits_exceeded()) {
- $result = false;
- }
- $this->logger->info(__METHOD__ . '> End run for email ' . $email->id);
- return $result;
- }
- /**
- *
- * @param TNP_Email $email
- * @param TNP_User $user
- * @return \TNP_Mailer_Message
- */
- function build_message($email, $user) {
- $message = new TNP_Mailer_Message();
- $message->to = $user->email;
- $message->headers = array('List-Unsubscribe' => '<' . $this->build_action_url('u', $user, $email) . '>');
- $message->headers['Precedence'] = 'bulk';
- $message->headers['X-Newsletter-Email-Id'] = $email->id;
- $message->headers['X-Auto-Response-Suppress'] = 'OOF, AutoReply';
- $message->headers = apply_filters('newsletter_message_headers', $message->headers, $email, $user);
- $message->body = preg_replace('/data-json=".*?"/is', '', $email->message);
- $message->body = preg_replace('/ +/s', ' ', $message->body);
- $message->body = $this->replace($message->body, $user, $email);
- if ($this->options['do_shortcodes']) {
- $message->body = do_shortcode($message->body);
- }
- $message->body = apply_filters('newsletter_message_html', $message->body, $email, $user);
- $message->body_text = $this->replace($email->message_text, $user, $email);
- $message->body_text = apply_filters('newsletter_message_text', $message->body_text, $email, $user);
- if ($email->track == 1) {
- $message->body = $this->relink($message->body, $email->id, $user->id, $email->token);
- }
- $message->subject = $this->replace($email->subject, $user);
- $message->subject = apply_filters('newsletter_message_subject', $message->subject, $email, $user);
- // TODO: Use the $email properties when available
- $message->from = $this->options['sender_email'];
- $message->from_name = $this->options['sender_name'];
- $message->email_id = $email->id;
- $message->user_id = $user->id;
- return $message;
- }
- /**
- *
- * @param TNP_Mailer_Message $message
- * @param int $status
- * @param string $error
- */
- function save_sent_message($message) {
- global $wpdb;
- if (!$message->user_id || !$message->email_id) {
- return;
- }
- $status = empty($message->error) ? 0 : 1;
- $this->query($wpdb->prepare("insert into " . $wpdb->prefix . 'newsletter_sent (user_id, email_id, time, status, error) values (%d, %d, %d, %d, %s) on duplicate key update time=%d, status=%d, error=%s', $message->user_id, $message->email_id, time(), $status, $message->error, time(), $status, $message->error));
- }
- /**
- * This function checks is, during processing, we are getting to near to system limits and should stop any further
- * work (when returns true).
- */
- function limits_exceeded() {
- global $wpdb;
- if (!$this->limits_set) {
- $this->logger->debug(__METHOD__ . '> Setting the limits for the first time');
- @set_time_limit(NEWSLETTER_CRON_INTERVAL + 30);
- $max_time = (int) (@ini_get('max_execution_time') * 0.95);
- if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL) {
- $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
- }
- $this->time_limit = $this->time_start + $max_time;
- $this->logger->info(__METHOD__ . '> Max time set to ' . $max_time);
- $max = (int) $this->options['scheduler_max'];
- if (!$max) {
- $max = 100;
- }
- $this->email_limit = max(floor($max / 12), 1);
- $this->logger->debug(__METHOD__ . '> Max number of emails can send: ' . $this->email_limit);
- $wpdb->query("set session wait_timeout=300");
- // From default-constants.php
- if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 )) {
- @ini_set('memory_limit', '256M');
- }
- $this->limits_set = true;
- }
- // The time limit is set on constructor, since it has to be set as early as possible
- if (time() > $this->time_limit) {
- $this->logger->info(__METHOD__ . '> Max execution time limit reached');
- return true;
- }
- if ($this->email_limit <= 0) {
- $this->logger->info(__METHOD__ . '> Max emails limit reached');
- return true;
- }
- return false;
- }
- /**
- * @deprecated since version 6.0.0
- * @param callback $callable
- */
- function register_mail_method($callable) {
- $this->mailer = new NewsletterMailMethodWrapper($callable);
- }
- function register_mailer($mailer) {
- //$this->logger->debug($mailer);
- if (!$mailer)
- return;
- if ($mailer instanceof NewsletterMailer) {
- $this->mailer = $mailer;
- } else {
- $this->logger->debug('Wrapping mailer: ' . get_class($mailer));
- $this->mailer = new NewsletterOldMailerWrapper($mailer);
- }
- }
- /**
- * Returns the current registered mailer which must be used to send emails.
- *
- * @return NewsletterMailer
- */
- function get_mailer() {
- //die('get mailer');
- if ($this->mailer)
- return $this->mailer;
- do_action('newsletter_register_mailer');
- if (!$this->mailer) {
- $smtp = $this->get_options('smtp');
- if (!empty($smtp['enabled'])) {
- $this->mailer = new NewsletterDefaultSMTPMailer($smtp);
- } else {
- $this->mailer = new NewsletterDefaultMailer();
- }
- }
- return $this->mailer;
- }
- function deliver($message) {
- $mailer = $this->get_mailer();
- return $mailer->send($message);
- }
- function mail($to, $subject, $message, $headers = array(), $enqueue = false, $from = false) {
- if (empty($subject)) {
- $this->logger->error('mail> Subject empty, skipped');
- return true;
- }
- $mailer_message = new TNP_Mailer_Message();
- $mailer_message->to = $to;
- $mailer_message->subject = $subject;
- $mailer_message->from = $this->options['sender_email'];
- $mailer_message->from_name = $this->options['sender_name'];
- if (!empty($headers)) {
- $mailer_message->headers = $headers;
- }
- $mailer_message->headers['X-Auto-Response-Suppress'] = 'OOF, AutoReply';
- // Message carrige returns and line feeds clean up
- if (!is_array($message)) {
- $mailer_message->body = $this->clean_eol($message);
- } else {
- if (!empty($message['text'])) {
- $mailer_message->body_text = $this->clean_eol($message['text']);
- }
- if (!empty($message['html'])) {
- $mailer_message->body = $this->clean_eol($message['html']);
- }
- }
- $mailer = $this->get_mailer();
- $r = $mailer->send($mailer_message);
- return !is_wp_error($r);
- }
- /**
- * Returns the SMTP options filtered so extensions can change them.
- */
- function get_smtp_options() {
- $smtp_options = $this->get_options('smtp');
- $smtp_options = apply_filters('newsletter_smtp', $smtp_options);
- return $smtp_options;
- }
- function hook_deactivate() {
- wp_clear_scheduled_hook('newsletter');
- }
- function shortcode_newsletter_form($attrs, $content) {
- return $this->form($attrs['form']);
- }
- function form($number = null) {
- if ($number == null)
- return $this->subscription_form();
- $options = get_option('newsletter_forms');
- $form = $options['form_' . $number];
- if (stripos($form, '<form') !== false) {
- $form = str_replace('{newsletter_url}', plugins_url('newsletter/do/subscribe.php'), $form);
- } else {
- $form = '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '" onsubmit="return newsletter_check(this)">' .
- $form . '</form>';
- }
- $form = $this->replace_lists($form);
- return $form;
- }
- function find_file($file1, $file2) {
- if (is_file($file1))
- return $file1;
- return $file2;
- }
- function hook_site_transient_update_plugins($value) {
- static $extra_response = array();
- //$this->logger->debug('Update plugins transient called');
- if (!$value || !is_object($value)) {
- //$this->logger->info('Empty object');
- return $value;
- }
- if (!isset($value->response) || !is_array($value->response)) {
- $value->response = array();
- }
- if ($extra_response) {
- //$this->logger->debug('Already updated');
- $value->response = array_merge($value->response, $extra_response);
- return $value;
- }
- $extensions = $this->getTnpExtensions();
- if (!$extensions) {
- return $value;
- }
- foreach ($extensions as $extension) {
- unset($value->response[$extension->wp_slug]);
- unset($value->no_update[$extension->wp_slug]);
- }
- if (!NEWSLETTER_EXTENSION_UPDATE) {
- //$this->logger->info('Updates disabled');
- return $value;
- }
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
- if (!function_exists('get_plugin_data')) {
- //$this->logger->error('No get_plugin_data function available!');
- return $value;
- }
- $license_key = $this->get_license_key();
- foreach ($extensions as $extension) {
- // Patch for names convention
- $extension->plugin = $extension->wp_slug;
- //$this->logger->debug('Processing ' . $extension->plugin);
- //$this->logger->debug($extension);
- $plugin_data = false;
- if (file_exists(WP_PLUGIN_DIR . '/' . $extension->plugin)) {
- $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $extension->plugin, false, false);
- } else if (file_exists(WPMU_PLUGIN_DIR . '/' . $extension->plugin)) {
- $plugin_data = get_plugin_data(WPMU_PLUGIN_DIR . '/' . $extension->plugin, false, false);
- }
- if (!$plugin_data) {
- //$this->logger->debug('Seems not installed');
- continue;
- }
- $plugin = new stdClass();
- $plugin->id = $extension->id;
- $plugin->slug = $extension->slug;
- $plugin->plugin = $extension->plugin;
- $plugin->new_version = $extension->version;
- $plugin->url = $extension->url;
- if (class_exists('NewsletterExtensions')) {
- // NO filters here!
- $plugin->package = NewsletterExtensions::$instance->get_package($extension->id, $license_key);
- } else {
- $plugin->package = '';
- }
- // [banners] => Array
- // (
- // [2x] => https://ps.w.org/wp-rss-aggregator/assets/banner-1544x500.png?rev=2040548
- // [1x] => https://ps.w.org/wp-rss-aggregator/assets/banner-772x250.png?rev=2040548
- // )
- // [icons] => Array
- // (
- // [2x] => https://ps.w.org/advanced-custom-fields/assets/icon-256x256.png?rev=1082746
- // [1x] => https://ps.w.org/advanced-custom-fields/assets/icon-128x128.png?rev=1082746
- // )
- if (version_compare($extension->version, $plugin_data['Version']) > 0) {
- //$this->logger->debug('There is a new version');
- $extra_response[$extension->plugin] = $plugin;
- } else {
- //$this->logger->debug('There is NOT a new version');
- $value->no_update[$extension->plugin] = $plugin;
- }
- //$this->logger->debug('Added');
- }
- $value->response = array_merge($value->response, $extra_response);
- return $value;
- }
- /**
- * @deprecated since version 6.1.9
- */
- function get_extension_version($extension_id) {
- $extensions = $this->getTnpExtensions();
- if (!is_array($extensions)) {
- return null;
- }
- foreach ($extensions as $extension) {
- if ($extension->id == $extension_id) {
- return $extension->version;
- }
- }
- return null;
- }
- /**
- * MUST be kept for old addons.
- *
- * @deprecated since version 6.1.9
- */
- function set_extension_update_data($value, $extension) {
- return $value;
- }
- /**
- * Retrieve the extensions form the tnp site
- * @return array
- */
- function getTnpExtensions() {
- $extensions_json = get_transient('tnp_extensions_json');
- if (empty($extensions_json)) {
- $url = "http://www.thenewsletterplugin.com/wp-content/extensions.json?ver=" . NEWSLETTER_VERSION;
- $extensions_response = wp_remote_get($url);
- $extensions_json = wp_remote_retrieve_body($extensions_response);
- if (!empty($extensions_json)) {
- set_transient('tnp_extensions_json', $extensions_json, 72 * 60 * 60);
- }
- }
- $extensions = json_decode($extensions_json);
- return $extensions;
- }
- function clear_extensions_cache() {
- delete_transient('tnp_extensions_json');
- }
- function hook_plugins_loaded() {
- do_action('newsletter_loaded', NEWSLETTER_VERSION);
- if (function_exists('load_plugin_textdomain')) {
- load_plugin_textdomain('newsletter', false, plugin_basename(dirname(__FILE__)) . '/languages');
- }
- }
- var $panels = array();
- function add_panel($key, $panel) {
- if (!isset($this->panels[$key]))
- $this->panels[$key] = array();
- if (!isset($panel['id']))
- $panel['id'] = sanitize_key($panel['label']);
- $this->panels[$key][] = $panel;
- }
- function has_license() {
- return !empty($this->options['contract_key']);
- }
- /**
- * Returns the Newsletter dedicated page URL or an alternative URL if that page if not
- * configured or not available.
- *
- * @staticvar string $url
- * @return string
- */
- var $newsletter_page_url = false;
- function get_newsletter_page_url($language = '') {
- // TODO: Reintroduce the cache
- //if (!$this->newsletter_page_url) {
- if (!empty($this->options['page'])) {
- $this->newsletter_page_url = get_permalink($this->options['page']);
- if ($language && $this->newsletter_page_url) {
- if (class_exists('SitePress')) {
- $this->newsletter_page_url = apply_filters('wpml_permalink', $this->newsletter_page_url, $language);
- }
- if (function_exists('pll_get_post')) {
- $this->newsletter_page_url = get_permalink(pll_get_post($this->options['page']));
- }
- }
- }
- if (!$this->newsletter_page_url) {
- $this->newsletter_page_url = $this->build_action_url('m');
- }
- //}
- return $this->newsletter_page_url;
- }
- function get_license_key() {
- if (defined('NEWSLETTER_LICENSE_KEY')) {
- return NEWSLETTER_LICENSE_KEY;
- } else {
- if (!empty($this->options['contract_key'])) {
- return trim($this->options['contract_key']);
- }
- }
- return false;
- }
- function get_license_data($refresh = false) {
- if (!$refresh) {
- $license_data = get_transient('newsletter_license_data');
- if (!empty($license_data) && is_object($license_data)) {
- return $license_data;
- }
- }
-
- $this->logger->debug('Refreshing the license data');
-
- delete_transient('newsletter_license_data');
- $license_key = $this->get_license_key();
- if (empty($license_key)) {
- $this->logger->debug('License was empty');
- return false;
- }
- $license_data_url = 'https://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/get-license-data.php';
- $response = wp_remote_post($license_data_url, array(
- 'body' => array('k' => $license_key)
- ));
- // Fall back to http...
- if (is_wp_error($response)) {
- $this->logger->error('Falling back to http');
- $this->logger->error($response);
- $response = wp_remote_post($license_data_url, array(
- 'body' => array('k' => $license_key)
- ));
- if (is_wp_error($response)) {
- $this->logger->error($response);
- return $response;
- }
- }
-
- $download_message = 'You can download all addons from www.thenewsletterplugin.com if your license is valid.';
- if (wp_remote_retrieve_response_code($response) != '200') {
- $this->logger->error('license data error: ' . wp_remote_retrieve_response_code($response));
- return new WP_Error(wp_remote_retrieve_response_code($response), 'License validation service error. <br>' . $download_message);
- }
-
- $json = wp_remote_retrieve_body($response);
- $data = json_decode($json);
- if (!is_object($data)) {
- $this->logger->error($json);
- return new WP_Error(1, 'License validation service error. <br>' . $download_message);
- }
- if (isset($data->message)) {
- return new WP_Error(1, $data->message . ' (check the license on Newsletter main settings)');
- }
- $timeout = 24 * 7 * 3600;
- if ($data->expire < time() + $timeout) $timeout = $data->expire;
- set_transient('newsletter_license_data', $data, $timeout);
- return $data;
- }
- /**
- * @deprecated
- * @param type $license_key
- * @return \WP_Error
- */
- public static function check_license($license_key) {
- $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . urlencode($license_key), array('sslverify' => false));
- if (is_wp_error($response)) {
- /* @var $response WP_Error */
- return new WP_Error(-1, 'It seems that your blog cannot contact the license validator. Ask your provider to unlock the HTTP/HTTPS connections to www.thenewsletterplugin.com<br>'
- . esc_html($response->get_error_code()) . ' - ' . esc_html($response->get_error_message()));
- } else if ($response['response']['code'] != 200) {
- return new WP_Error(-1, '[' . $response['response']['code'] . '] The license seems expired or not valid, please check your <a href="https://www.thenewsletterplugin.com/account">license code and status</a>, thank you.'
- . '<br>You can anyway download the professional extension from https://www.thenewsletterplugin.com.');
- } elseif ($expires = json_decode(wp_remote_retrieve_body($response))) {
- return array('expires' => $expires->expire, 'message' => 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $expires->expire)));
- } else {
- return new WP_Error(-1, 'Unable to detect the license expiration. Debug data to report to the support: <code>' . esc_html(wp_remote_retrieve_body($response)) . '</code>');
- }
- }
- }
- $newsletter = Newsletter::instance();
- require_once NEWSLETTER_DIR . '/subscription/subscription.php';
- require_once NEWSLETTER_DIR . '/unsubscription/unsubscription.php';
- require_once NEWSLETTER_DIR . '/profile/profile.php';
- require_once NEWSLETTER_DIR . '/emails/emails.php';
- require_once NEWSLETTER_DIR . '/users/users.php';
- require_once NEWSLETTER_DIR . '/statistics/statistics.php';
- require_once NEWSLETTER_DIR . '/widget/standard.php';
- require_once NEWSLETTER_DIR . '/widget/minimal.php';
|