plugin.php 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327
  1. <?php
  2. /*
  3. Plugin Name: Newsletter
  4. Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
  5. 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>
  6. Version: 6.4.0
  7. Author: Stefano Lissa & The Newsletter Team
  8. Author URI: https://www.thenewsletterplugin.com
  9. Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
  10. Text Domain: newsletter
  11. License: GPLv2 or later
  12. Copyright 2009-2019 The Newsletter Team (email: info@thenewsletterplugin.com, web: https://www.thenewsletterplugin.com)
  13. Newsletter is free software: you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation, either version 2 of the License, or
  16. any later version.
  17. Newsletter is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. GNU General Public License for more details.
  21. You should have received a copy of the GNU General Public License
  22. along with Newsletter. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
  23. */
  24. define('NEWSLETTER_VERSION', '6.4.0');
  25. global $newsletter, $wpdb;
  26. if (!defined('NEWSLETTER_EXTENSION_UPDATE'))
  27. define('NEWSLETTER_EXTENSION_UPDATE', true);
  28. if (!defined('NEWSLETTER_EMAILS_TABLE'))
  29. define('NEWSLETTER_EMAILS_TABLE', $wpdb->prefix . 'newsletter_emails');
  30. if (!defined('NEWSLETTER_USERS_TABLE'))
  31. define('NEWSLETTER_USERS_TABLE', $wpdb->prefix . 'newsletter');
  32. if (!defined('NEWSLETTER_STATS_TABLE'))
  33. define('NEWSLETTER_STATS_TABLE', $wpdb->prefix . 'newsletter_stats');
  34. if (!defined('NEWSLETTER_SENT_TABLE'))
  35. define('NEWSLETTER_SENT_TABLE', $wpdb->prefix . 'newsletter_sent');
  36. // Do not use basename(dirname()) since on activation the plugin is sandboxed inside a function
  37. define('NEWSLETTER_SLUG', 'newsletter');
  38. define('NEWSLETTER_DIR', __DIR__);
  39. define('NEWSLETTER_INCLUDES_DIR', __DIR__ . '/includes');
  40. // Almost obsolete but the first two must be kept for compatibility with modules
  41. define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
  42. if (!defined('NEWSLETTER_LIST_MAX'))
  43. define('NEWSLETTER_LIST_MAX', 40);
  44. if (!defined('NEWSLETTER_PROFILE_MAX'))
  45. define('NEWSLETTER_PROFILE_MAX', 20);
  46. if (!defined('NEWSLETTER_FORMS_MAX'))
  47. define('NEWSLETTER_FORMS_MAX', 10);
  48. if (!defined('NEWSLETTER_CRON_INTERVAL'))
  49. define('NEWSLETTER_CRON_INTERVAL', 300);
  50. if (!defined('NEWSLETTER_HEADER'))
  51. define('NEWSLETTER_HEADER', true);
  52. // Force the whole system log level to this value
  53. //define('NEWSLETTER_LOG_LEVEL', 4);
  54. require_once NEWSLETTER_INCLUDES_DIR . '/logger.php';
  55. require_once NEWSLETTER_INCLUDES_DIR . '/store.php';
  56. require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
  57. require_once NEWSLETTER_INCLUDES_DIR . '/mailers.php';
  58. require_once NEWSLETTER_INCLUDES_DIR . '/themes.php';
  59. require_once NEWSLETTER_INCLUDES_DIR . '/TNP.php';
  60. class Newsletter extends NewsletterModule {
  61. // Limits to respect to avoid memory, time or provider limits
  62. var $time_start;
  63. var $time_limit;
  64. var $email_limit = 10; // Per run, every 5 minutes
  65. var $limits_set = false;
  66. var $max_emails = 20;
  67. /**
  68. * @var PHPMailer
  69. */
  70. var $mailer;
  71. // Message shown when the interaction is inside a WordPress page
  72. var $message;
  73. var $user;
  74. var $error;
  75. var $theme;
  76. // Theme autocomposer variables
  77. var $theme_max_posts;
  78. var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
  79. var $theme_posts; // WP_Query object
  80. // Secret key to create a unique log file name (and may be other)
  81. var $action = '';
  82. /** @var Newsletter */
  83. static $instance;
  84. const MAX_CRON_SAMPLES = 100;
  85. const STATUS_NOT_CONFIRMED = 'S';
  86. const STATUS_CONFIRMED = 'C';
  87. /**
  88. * @return Newsletter
  89. */
  90. static function instance() {
  91. if (self::$instance == null) {
  92. self::$instance = new Newsletter();
  93. }
  94. return self::$instance;
  95. }
  96. function __construct() {
  97. // Grab it before a plugin decides to remove it.
  98. if (isset($_GET['na'])) {
  99. $this->action = $_GET['na'];
  100. }
  101. if (isset($_POST['na'])) {
  102. $this->action = $_POST['na'];
  103. }
  104. $this->time_start = time();
  105. // Here because the upgrade is called by the parent constructor and uses the scheduler
  106. add_filter('cron_schedules', function ($schedules) {
  107. $schedules['newsletter'] = array(
  108. 'interval' => NEWSLETTER_CRON_INTERVAL, // seconds
  109. 'display' => 'Every ' . NEWSLETTER_CRON_INTERVAL . ' seconds by Newsletter'
  110. );
  111. return $schedules;
  112. }, 1000);
  113. parent::__construct('main', '1.5.2', null, array('info', 'smtp'));
  114. $max = $this->options['scheduler_max'];
  115. if (!is_numeric($max)) {
  116. $max = 100;
  117. }
  118. $this->max_emails = max(floor($max / (3600 / NEWSLETTER_CRON_INTERVAL)), 1);
  119. add_action('plugins_loaded', array($this, 'hook_plugins_loaded'));
  120. add_action('init', array($this, 'hook_init'), 1);
  121. add_action('wp_loaded', array($this, 'hook_wp_loaded'), 1);
  122. add_action('newsletter', array($this, 'hook_newsletter'), 1);
  123. $this->update_cron_stats();
  124. register_activation_hook(__FILE__, array($this, 'hook_activate'));
  125. register_deactivation_hook(__FILE__, array($this, 'hook_deactivate'));
  126. add_action('admin_init', array($this, 'hook_admin_init'));
  127. if (is_admin()) {
  128. add_action('admin_head', array($this, 'hook_admin_head'));
  129. // Protection against strange schedule removal on some installations
  130. if (!wp_next_scheduled('newsletter') && (!defined('WP_INSTALLING') || !WP_INSTALLING)) {
  131. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  132. }
  133. add_action('admin_menu', array($this, 'add_extensions_menu'), 90);
  134. }
  135. }
  136. function hook_init() {
  137. global $wpdb;
  138. if (isset($this->options['debug']) && $this->options['debug'] == 1) {
  139. ini_set('log_errors', 1);
  140. ini_set('error_log', WP_CONTENT_DIR . '/logs/newsletter/php-' . date('Y-m') . '-' . get_option('newsletter_logger_secret') . '.txt');
  141. }
  142. add_shortcode('newsletter_replace', array($this, 'shortcode_newsletter_replace'));
  143. add_filter('site_transient_update_plugins', array($this, 'hook_site_transient_update_plugins'));
  144. if (is_admin()) {
  145. if (!class_exists('NewsletterExtensions')) {
  146. add_filter('plugin_row_meta', function ($plugin_meta, $plugin_file) {
  147. static $slugs = array();
  148. if (empty($slugs)) {
  149. $addons = $this->getTnpExtensions();
  150. foreach ($addons as $addon) {
  151. $slugs[] = $addon->wp_slug;
  152. }
  153. }
  154. if (array_search($plugin_file, $slugs) !== false) {
  155. $plugin_meta[] = '<a href="admin.php?page=newsletter_main_extensions" style="font-weight: bold">Newsletter Addons Manager required</a>';
  156. }
  157. return $plugin_meta;
  158. }, 10, 2);
  159. }
  160. add_action('in_admin_header', array($this, 'hook_in_admin_header'), 1000);
  161. if ($this->is_admin_page()) {
  162. $newsletter_url = plugins_url('newsletter');
  163. wp_enqueue_script('jquery-ui-tabs');
  164. wp_enqueue_script('jquery-ui-tooltip');
  165. wp_enqueue_media();
  166. wp_enqueue_style('tnp-admin', $newsletter_url . '/admin.css', array(), filemtime(NEWSLETTER_DIR . '/admin.css'));
  167. wp_enqueue_script('tnp-admin', $newsletter_url . '/admin.js', array('jquery'), time());
  168. wp_enqueue_style('wp-color-picker');
  169. wp_enqueue_script('wp-color-picker');
  170. wp_enqueue_style('tnp-select2', $newsletter_url . '/vendor/select2/select2.css');
  171. wp_enqueue_script('tnp-select2', $newsletter_url . '/vendor/select2/select2.min.js');
  172. wp_enqueue_script('tnp-jquery-vmap', $newsletter_url . '/vendor/jqvmap/jquery.vmap.min.js', array('jquery'));
  173. wp_enqueue_script('tnp-jquery-vmap-world', $newsletter_url . '/vendor/jqvmap/jquery.vmap.world.js', array('tnp-jquery-vmap'));
  174. wp_enqueue_style('tnp-jquery-vmap', $newsletter_url . '/vendor/jqvmap/jqvmap.min.css');
  175. wp_register_script('tnp-chart', $newsletter_url . '/vendor/chartjs/Chart.min.js', array('jquery'));
  176. $dismissed = get_option('newsletter_dismissed', array());
  177. if (isset($_GET['dismiss'])) {
  178. $dismissed[$_GET['dismiss']] = 1;
  179. update_option('newsletter_dismissed', $dismissed);
  180. wp_redirect($_SERVER['HTTP_REFERER']);
  181. exit();
  182. }
  183. }
  184. } else {
  185. add_action('wp_enqueue_scripts', array($this, 'hook_wp_enqueue_scripts'));
  186. }
  187. do_action('newsletter_init');
  188. }
  189. function hook_wp_loaded() {
  190. if (empty($this->action)) {
  191. return;
  192. }
  193. if ($this->action == 'test') {
  194. echo 'ok';
  195. die();
  196. }
  197. do_action('newsletter_action', $this->action);
  198. }
  199. function update_cron_stats() {
  200. if (defined('DOING_CRON') && DOING_CRON) {
  201. $calls = get_option('newsletter_diagnostic_cron_calls', array());
  202. $calls[] = time();
  203. if (count($calls) > self::MAX_CRON_SAMPLES) {
  204. array_shift($calls);
  205. }
  206. update_option('newsletter_diagnostic_cron_calls', $calls, false);
  207. if (count($calls) > 50) {
  208. $mean = 0;
  209. $max = 0;
  210. $min = 0;
  211. for ($i = 1; $i < count($calls); $i++) {
  212. $diff = $calls[$i] - $calls[$i - 1];
  213. $mean += $diff;
  214. if ($min == 0 || $min > $diff) {
  215. $min = $diff;
  216. }
  217. if ($max < $diff) {
  218. $max = $diff;
  219. }
  220. }
  221. $mean = $mean / count($calls) - 1;
  222. update_option('newsletter_diagnostic_cron_data', array('mean' => $mean, 'max' => $max, 'min' => $min), false);
  223. } else {
  224. update_option('newsletter_diagnostic_cron_data', '', false);
  225. }
  226. }
  227. }
  228. function hook_activate() {
  229. // Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
  230. // the every-five-minutes schedule named "newsletter" is not present.
  231. // Since the activation does not forces an upgrade, that schedule must be reactivated here. It is activated on
  232. // the upgrade method as well for the user which upgrade the plugin without deactivte it (many).
  233. if (!wp_next_scheduled('newsletter')) {
  234. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  235. }
  236. $install_time = get_option('newsletter_install_time');
  237. if (!$install_time) {
  238. update_option('newsletter_install_time', time(), false);
  239. }
  240. Newsletter::instance()->upgrade();
  241. NewsletterUsers::instance()->upgrade();
  242. NewsletterEmails::instance()->upgrade();
  243. NewsletterSubscription::instance()->upgrade();
  244. NewsletterStatistics::instance()->upgrade();
  245. NewsletterProfile::instance()->upgrade();
  246. }
  247. function first_install() {
  248. parent::first_install();
  249. update_option('newsletter_show_welcome', '1', false);
  250. }
  251. function upgrade() {
  252. global $wpdb, $charset_collate;
  253. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  254. parent::upgrade();
  255. $sql = "CREATE TABLE `" . $wpdb->prefix . "newsletter_emails` (
  256. `id` int(11) NOT NULL AUTO_INCREMENT,
  257. `language` varchar(10) NOT NULL DEFAULT '',
  258. `subject` varchar(255) NOT NULL DEFAULT '',
  259. `message` longtext,
  260. `subject2` varchar(255) NOT NULL DEFAULT '',
  261. `message2` longtext,
  262. `name2` varchar(255) NOT NULL DEFAULT '',
  263. `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  264. `status` enum('new','sending','sent','paused') NOT NULL DEFAULT 'new',
  265. `total` int(11) NOT NULL DEFAULT '0',
  266. `last_id` int(11) NOT NULL DEFAULT '0',
  267. `sent` int(11) NOT NULL DEFAULT '0',
  268. `track` int(11) NOT NULL DEFAULT '0',
  269. `list` int(11) NOT NULL DEFAULT '0',
  270. `type` varchar(50) NOT NULL DEFAULT '',
  271. `query` longtext,
  272. `editor` tinyint(4) NOT NULL DEFAULT '0',
  273. `sex` varchar(20) NOT NULL DEFAULT '',
  274. `theme` varchar(50) NOT NULL DEFAULT '',
  275. `message_text` longtext,
  276. `preferences` longtext,
  277. `send_on` int(11) NOT NULL DEFAULT '0',
  278. `token` varchar(10) NOT NULL DEFAULT '',
  279. `options` longtext,
  280. `private` tinyint(1) NOT NULL DEFAULT '0',
  281. `click_count` int(10) unsigned NOT NULL DEFAULT '0',
  282. `version` varchar(10) NOT NULL DEFAULT '',
  283. `open_count` int(10) unsigned NOT NULL DEFAULT '0',
  284. PRIMARY KEY (`id`)) $charset_collate;";
  285. dbDelta($sql);
  286. // WP does not manage composite primary key when it tries to upgrade a table...
  287. $suppress_errors = $wpdb->suppress_errors(true);
  288. dbDelta("CREATE TABLE " . $wpdb->prefix . "newsletter_sent (
  289. email_id int(10) unsigned NOT NULL DEFAULT '0',
  290. user_id int(10) unsigned NOT NULL DEFAULT '0',
  291. status tinyint(1) unsigned NOT NULL DEFAULT '0',
  292. open tinyint(1) unsigned NOT NULL DEFAULT '0',
  293. time int(10) unsigned NOT NULL DEFAULT '0',
  294. error varchar(100) NOT NULL DEFAULT '',
  295. ip varchar(100) NOT NULL DEFAULT '',
  296. country varchar(4) NOT NULL DEFAULT '',
  297. PRIMARY KEY (email_id,user_id),
  298. KEY user_id (user_id),
  299. KEY email_id (email_id)
  300. ) $charset_collate;");
  301. $wpdb->suppress_errors($suppress_errors);
  302. // Some setting check to avoid the common support request for mis-configurations
  303. $options = $this->get_options();
  304. if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
  305. $options['scheduler_max'] = 100;
  306. $this->save_options($options);
  307. }
  308. wp_clear_scheduled_hook('newsletter');
  309. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  310. wp_clear_scheduled_hook('newsletter_extension_versions');
  311. // No more required
  312. //wp_schedule_event(time() + 30, 'daily', 'newsletter_extension_versions');
  313. $subscription_options = get_option('newsletter', array());
  314. // Settings migration
  315. if (empty($this->options['page'])) {
  316. if (isset($subscription_options['page']))
  317. $this->options['page'] = $subscription_options['page'];
  318. $this->save_options($this->options);
  319. }
  320. if (empty($this->options['css']) && !empty($subscription_options['css'])) {
  321. $this->options['css'] = $subscription_options['css'];
  322. $this->save_options($this->options);
  323. }
  324. // Migration of "info" options
  325. $info_options = $this->get_options('info');
  326. if (!empty($this->options['header_logo']) && empty($info_options['header_logo'])) {
  327. $info_options = $this->options;
  328. $this->save_options($info_options, 'info');
  329. }
  330. if (!empty($this->options['editor'])) {
  331. if (empty($this->options['roles'])) {
  332. $this->options['roles'] = array('editor');
  333. unset($this->options['editor']);
  334. }
  335. $this->save_options($this->options);
  336. }
  337. return true;
  338. }
  339. function is_allowed() {
  340. if (current_user_can('administrator')) {
  341. return true;
  342. }
  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. function admin_menu() {
  353. if (!$this->is_allowed())
  354. return;
  355. add_menu_page('Newsletter', 'Newsletter', 'exist', 'newsletter_main_index', '', plugins_url('newsletter') . '/images/menu-icon.png', '30.333');
  356. $this->add_menu_page('index', __('Dashboard', 'newsletter'));
  357. $this->add_admin_page('info', __('Company info', 'newsletter'));
  358. if (current_user_can('administrator')) {
  359. $this->add_menu_page('welcome', __('Welcome', 'newsletter'));
  360. $this->add_menu_page('main', __('Settings and More', 'newsletter'));
  361. $this->add_admin_page('smtp', 'SMTP');
  362. $this->add_admin_page('status', __('Status', 'newsletter'));
  363. }
  364. }
  365. function add_extensions_menu() {
  366. if (!class_exists('NewsletterExtensions')) {
  367. $this->add_menu_page('extensions', '<span style="color:#27AE60; font-weight: bold;">' . __('Addons', 'newsletter') . '</span>');
  368. }
  369. }
  370. /**
  371. * Returns a set of warnings about this installtion the suser should be aware of. Return an empty string
  372. * if there are no warnings.
  373. */
  374. function warnings() {
  375. }
  376. function hook_in_admin_header() {
  377. if (!$this->is_admin_page()) {
  378. add_action('admin_notices', array($this, 'hook_admin_notices'));
  379. return;
  380. }
  381. remove_all_actions('admin_notices');
  382. remove_all_actions('all_admin_notices');
  383. add_action('admin_notices', array($this, 'hook_admin_notices'));
  384. }
  385. function hook_admin_notices() {
  386. // Check of Newsletter dedicated page
  387. if (!empty($this->options['page'])) {
  388. if (get_post_status($this->options['page']) !== 'publish') {
  389. 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>';
  390. }
  391. }
  392. if (isset($this->options['debug']) && $this->options['debug'] == 1) {
  393. 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>';
  394. }
  395. if (!defined('NEWSLETTER_CRON_WARNINGS') || NEWSLETTER_CRON_WARNINGS) {
  396. $x = wp_next_scheduled('newsletter');
  397. if ($x === false) {
  398. 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>';
  399. } else if (time() - $x > 900) {
  400. 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>';
  401. } else {
  402. // if (empty($this->options['disable_cron_notice'])) {
  403. // $cron_data = get_option('newsletter_diagnostic_cron_data');
  404. // if ($cron_data && $cron_data['mean'] > 500) {
  405. // 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>';
  406. // }
  407. // }
  408. }
  409. }
  410. }
  411. function hook_wp_enqueue_scripts() {
  412. if (empty($this->options['css_disabled']) && apply_filters('newsletter_enqueue_style', true)) {
  413. wp_enqueue_style('newsletter', plugins_url('newsletter') . '/style.css', array(), NEWSLETTER_VERSION);
  414. if (!empty($this->options['css'])) {
  415. wp_add_inline_style('newsletter', $this->options['css']);
  416. }
  417. }
  418. }
  419. function shortcode_newsletter_replace($attrs, $content) {
  420. $content = do_shortcode($content);
  421. $content = $this->replace($content, $this->get_user_from_request(), $this->get_email_from_request());
  422. return $content;
  423. }
  424. function is_admin_page() {
  425. if (!isset($_GET['page'])) {
  426. return false;
  427. }
  428. $page = $_GET['page'];
  429. return strpos($page, 'newsletter_') === 0;
  430. }
  431. function hook_admin_init() {
  432. // Verificare il contesto
  433. if (isset($_GET['page']) && $_GET['page'] === 'newsletter_main_welcome')
  434. return;
  435. if (get_option('newsletter_show_welcome')) {
  436. delete_option('newsletter_show_welcome');
  437. wp_redirect(admin_url('admin.php?page=newsletter_main_welcome'));
  438. }
  439. // https://developer.wordpress.org/plugins/privacy/suggesting-text-for-the-site-privacy-policy/
  440. // https://make.wordpress.org/core/2018/05/17/4-9-6-update-guide/
  441. if (function_exists('wp_add_privacy_policy_content')) {
  442. //wp_add_privacy_policy_content('Newsletter', wp_kses_post( wpautop( $content, false )));
  443. }
  444. }
  445. function hook_admin_head() {
  446. // Small global rule for sidebar menu entries
  447. echo '<style>';
  448. echo '.tnp-side-menu { color: #E67E22!important; }';
  449. echo '</style>';
  450. }
  451. function relink($text, $email_id, $user_id, $email_token = '') {
  452. return NewsletterStatistics::instance()->relink($text, $email_id, $user_id, $email_token);
  453. }
  454. /**
  455. * Runs every 5 minutes and look for emails that need to be processed.
  456. */
  457. function hook_newsletter() {
  458. global $wpdb;
  459. $this->logger->debug(__METHOD__ . '> Start');
  460. // Do not accept job activation before at least 4 minutes are elapsed from the last run.
  461. if (!$this->check_transient('engine', NEWSLETTER_CRON_INTERVAL)) {
  462. return;
  463. }
  464. // Retrieve all emails in "sending" status
  465. $emails = $this->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where status='sending' and send_on<" . time() . " order by id asc");
  466. $this->logger->debug(__METHOD__ . '> Emails found in sending status: ' . count($emails));
  467. foreach ($emails as $email) {
  468. $this->logger->info(__METHOD__ . '> Start newsletter ' . $email->id);
  469. $r = $this->send($email);
  470. if ($this->limits_exceeded()) {
  471. break;
  472. }
  473. $this->logger->info(__METHOD__ . '> End newsletter ' . $email->id);
  474. }
  475. // Remove the semaphore so the delivery engine can be activated again
  476. $this->delete_transient('engine');
  477. $this->logger->debug(__METHOD__ . '> End');
  478. }
  479. /**
  480. * Sends an email to targeted users or to given users. If a list of users is given (usually a list of test users)
  481. * the query inside the email to retrieve users is not used.
  482. *
  483. * @global wpdb $wpdb
  484. * @global type $newsletter_feed
  485. * @param TNP_Email $email
  486. * @param array $users
  487. * @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.
  488. */
  489. function send($email, $users = null, $test = false) {
  490. global $wpdb;
  491. ignore_user_abort(true);
  492. if (is_array($email)) {
  493. $email = (object) $email;
  494. }
  495. // Could be a test
  496. if (empty($email->id)) {
  497. $email->id = 0;
  498. }
  499. $this->logger->info(__METHOD__ . '> Start run for email ' . $email->id);
  500. // 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)
  501. $supplied_users = $users != null;
  502. if ($users == null) {
  503. $skip_this_run = apply_filters('newsletter_send_skip', false, $email);
  504. if ($skip_this_run) {
  505. return false;
  506. }
  507. if (empty($email->query)) {
  508. $email->query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
  509. }
  510. // TODO: Ask the max emails per hour/run (to be decided) to the mailer
  511. $email->options = maybe_unserialize($email->options);
  512. $max_emails = apply_filters('newsletter_send_max_emails', $this->max_emails, $email);
  513. $this->logger->debug(__METHOD__ . '> Max emails per run: ' . $max_emails);
  514. if (empty($max_emails)) {
  515. $this->logger->debug(__METHOD__ . '> Max emails empty after the filter');
  516. $max_emails = $this->max_emails;
  517. }
  518. //$query = apply_filters('newsletter_send_query', $email->query, $email);
  519. $query = $email->query;
  520. $query .= " and id>" . $email->last_id . " order by id limit " . $max_emails;
  521. $this->logger->debug(__METHOD__ . '> Query: ' . $query);
  522. $users = $this->get_results($query);
  523. $this->logger->debug(__METHOD__ . '> Loaded users: ' . count($users));
  524. // If there was a database error, do nothing
  525. if ($users === false) {
  526. return new WP_Error('1', 'Unable to query subscribers, check the logs');
  527. }
  528. if (empty($users)) {
  529. $this->logger->info(__METHOD__ . '> No more users, set as sent');
  530. $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
  531. return true;
  532. }
  533. } else {
  534. $this->logger->info(__METHOD__ . '> Subscribers supplied');
  535. }
  536. $start_time = microtime(true);
  537. $count = 0;
  538. $result = true;
  539. $mailer = $this->get_mailer();
  540. $batch_size = $mailer->get_batch_size();
  541. $this->logger->debug(__METHOD__ . '> Batch size: ' . $batch_size);
  542. // For batch size == 1 (normal condition) we optimize
  543. if ($batch_size == 1) {
  544. foreach ($users as $user) {
  545. if (!$supplied_users && !$test && $this->limits_exceeded()) {
  546. $result = false;
  547. break;
  548. }
  549. $this->logger->debug(__METHOD__ . '> Processing user ID: ' . $user->id);
  550. $user = apply_filters('newsletter_send_user', $user);
  551. $message = $this->build_message($email, $user);
  552. $this->save_sent_message($message);
  553. if (!$test) {
  554. $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
  555. }
  556. $r = $mailer->send($message);
  557. if (!empty($message->error)) {
  558. $this->save_sent_message($message);
  559. }
  560. if (is_wp_error($r)) {
  561. $this->logger->error($r);
  562. return $r;
  563. }
  564. }
  565. // TODO: Review if they're useful
  566. $this->email_limit--;
  567. $count++;
  568. } else {
  569. $chunks = array_chunk($users, $batch_size);
  570. foreach ($chunks as $chunk) {
  571. if (!$supplied_users && !$test && $this->limits_exceeded()) {
  572. $result = false;
  573. break;
  574. }
  575. $messages = array();
  576. foreach ($chunk as $user) {
  577. $this->logger->debug(__METHOD__ . '> Processing user ID: ' . $user->id);
  578. $user = apply_filters('newsletter_send_user', $user);
  579. $message = $this->build_message($email, $user);
  580. $this->save_sent_message($message);
  581. $messages[] = $message;
  582. if (!$test) {
  583. $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
  584. }
  585. $this->email_limit--;
  586. $count++;
  587. }
  588. $r = $mailer->send_batch($messages);
  589. foreach ($messages as $message) {
  590. if (!empty($message->error)) {
  591. $this->save_sent_message($message);
  592. }
  593. }
  594. if (is_wp_error($r)) {
  595. $this->logger->error($r);
  596. return $r;
  597. }
  598. }
  599. }
  600. $end_time = microtime(true);
  601. if ($count > 0) {
  602. $send_calls = get_option('newsletter_diagnostic_send_calls', array());
  603. $send_calls[] = array($start_time, $end_time, $count, $result);
  604. if (count($send_calls) > self::MAX_CRON_SAMPLES)
  605. array_shift($send_calls);
  606. update_option('newsletter_diagnostic_send_calls', $send_calls, false);
  607. }
  608. if ($supplied_users && $this->limits_exceeded()) {
  609. $result = false;
  610. }
  611. $this->logger->info(__METHOD__ . '> End run for email ' . $email->id);
  612. return $result;
  613. }
  614. /**
  615. *
  616. * @param TNP_Email $email
  617. * @param TNP_User $user
  618. * @return \TNP_Mailer_Message
  619. */
  620. function build_message($email, $user) {
  621. $message = new TNP_Mailer_Message();
  622. $message->to = $user->email;
  623. $message->headers = array('List-Unsubscribe' => '<' . $this->build_action_url('u', $user, $email) . '>');
  624. $message->headers['Precedence'] = 'bulk';
  625. $message->headers['X-Newsletter-Email-Id'] = $email->id;
  626. $message->headers['X-Auto-Response-Suppress'] = 'OOF, AutoReply';
  627. $message->headers = apply_filters('newsletter_message_headers', $message->headers, $email, $user);
  628. $message->body = preg_replace('/data-json=".*?"/is', '', $email->message);
  629. $message->body = preg_replace('/ +/s', ' ', $message->body);
  630. $message->body = $this->replace($message->body, $user, $email);
  631. if ($this->options['do_shortcodes']) {
  632. $message->body = do_shortcode($message->body);
  633. }
  634. $message->body = apply_filters('newsletter_message_html', $message->body, $email, $user);
  635. $message->body_text = $this->replace($email->message_text, $user, $email);
  636. $message->body_text = apply_filters('newsletter_message_text', $message->body_text, $email, $user);
  637. if ($email->track == 1) {
  638. $message->body = $this->relink($message->body, $email->id, $user->id, $email->token);
  639. }
  640. $message->subject = $this->replace($email->subject, $user);
  641. $message->subject = apply_filters('newsletter_message_subject', $message->subject, $email, $user);
  642. // TODO: Use the $email properties when available
  643. $message->from = $this->options['sender_email'];
  644. $message->from_name = $this->options['sender_name'];
  645. $message->email_id = $email->id;
  646. $message->user_id = $user->id;
  647. return $message;
  648. }
  649. /**
  650. *
  651. * @param TNP_Mailer_Message $message
  652. * @param int $status
  653. * @param string $error
  654. */
  655. function save_sent_message($message) {
  656. global $wpdb;
  657. if (!$message->user_id || !$message->email_id) {
  658. return;
  659. }
  660. $status = empty($message->error) ? 0 : 1;
  661. $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));
  662. }
  663. /**
  664. * This function checks is, during processing, we are getting to near to system limits and should stop any further
  665. * work (when returns true).
  666. */
  667. function limits_exceeded() {
  668. global $wpdb;
  669. if (!$this->limits_set) {
  670. $this->logger->debug(__METHOD__ . '> Setting the limits for the first time');
  671. @set_time_limit(NEWSLETTER_CRON_INTERVAL + 30);
  672. $max_time = (int) (@ini_get('max_execution_time') * 0.95);
  673. if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL) {
  674. $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
  675. }
  676. $this->time_limit = $this->time_start + $max_time;
  677. $this->logger->info(__METHOD__ . '> Max time set to ' . $max_time);
  678. $max = (int) $this->options['scheduler_max'];
  679. if (!$max) {
  680. $max = 100;
  681. }
  682. $this->email_limit = max(floor($max / 12), 1);
  683. $this->logger->debug(__METHOD__ . '> Max number of emails can send: ' . $this->email_limit);
  684. $wpdb->query("set session wait_timeout=300");
  685. // From default-constants.php
  686. if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 )) {
  687. @ini_set('memory_limit', '256M');
  688. }
  689. $this->limits_set = true;
  690. }
  691. // The time limit is set on constructor, since it has to be set as early as possible
  692. if (time() > $this->time_limit) {
  693. $this->logger->info(__METHOD__ . '> Max execution time limit reached');
  694. return true;
  695. }
  696. if ($this->email_limit <= 0) {
  697. $this->logger->info(__METHOD__ . '> Max emails limit reached');
  698. return true;
  699. }
  700. return false;
  701. }
  702. /**
  703. * @deprecated since version 6.0.0
  704. * @param callback $callable
  705. */
  706. function register_mail_method($callable) {
  707. $this->mailer = new NewsletterMailMethodWrapper($callable);
  708. }
  709. function register_mailer($mailer) {
  710. //$this->logger->debug($mailer);
  711. if (!$mailer)
  712. return;
  713. if ($mailer instanceof NewsletterMailer) {
  714. $this->mailer = $mailer;
  715. } else {
  716. $this->logger->debug('Wrapping mailer: ' . get_class($mailer));
  717. $this->mailer = new NewsletterOldMailerWrapper($mailer);
  718. }
  719. }
  720. /**
  721. * Returns the current registered mailer which must be used to send emails.
  722. *
  723. * @return NewsletterMailer
  724. */
  725. function get_mailer() {
  726. //die('get mailer');
  727. if ($this->mailer)
  728. return $this->mailer;
  729. do_action('newsletter_register_mailer');
  730. if (!$this->mailer) {
  731. $smtp = $this->get_options('smtp');
  732. if (!empty($smtp['enabled'])) {
  733. $this->mailer = new NewsletterDefaultSMTPMailer($smtp);
  734. } else {
  735. $this->mailer = new NewsletterDefaultMailer();
  736. }
  737. }
  738. return $this->mailer;
  739. }
  740. function deliver($message) {
  741. $mailer = $this->get_mailer();
  742. return $mailer->send($message);
  743. }
  744. function mail($to, $subject, $message, $headers = array(), $enqueue = false, $from = false) {
  745. if (empty($subject)) {
  746. $this->logger->error('mail> Subject empty, skipped');
  747. return true;
  748. }
  749. $mailer_message = new TNP_Mailer_Message();
  750. $mailer_message->to = $to;
  751. $mailer_message->subject = $subject;
  752. $mailer_message->from = $this->options['sender_email'];
  753. $mailer_message->from_name = $this->options['sender_name'];
  754. if (!empty($headers)) {
  755. $mailer_message->headers = $headers;
  756. }
  757. $mailer_message->headers['X-Auto-Response-Suppress'] = 'OOF, AutoReply';
  758. // Message carrige returns and line feeds clean up
  759. if (!is_array($message)) {
  760. $mailer_message->body = $this->clean_eol($message);
  761. } else {
  762. if (!empty($message['text'])) {
  763. $mailer_message->body_text = $this->clean_eol($message['text']);
  764. }
  765. if (!empty($message['html'])) {
  766. $mailer_message->body = $this->clean_eol($message['html']);
  767. }
  768. }
  769. $mailer = $this->get_mailer();
  770. $r = $mailer->send($mailer_message);
  771. return !is_wp_error($r);
  772. }
  773. /**
  774. * Returns the SMTP options filtered so extensions can change them.
  775. */
  776. function get_smtp_options() {
  777. $smtp_options = $this->get_options('smtp');
  778. $smtp_options = apply_filters('newsletter_smtp', $smtp_options);
  779. return $smtp_options;
  780. }
  781. function hook_deactivate() {
  782. wp_clear_scheduled_hook('newsletter');
  783. }
  784. function shortcode_newsletter_form($attrs, $content) {
  785. return $this->form($attrs['form']);
  786. }
  787. function form($number = null) {
  788. if ($number == null)
  789. return $this->subscription_form();
  790. $options = get_option('newsletter_forms');
  791. $form = $options['form_' . $number];
  792. if (stripos($form, '<form') !== false) {
  793. $form = str_replace('{newsletter_url}', plugins_url('newsletter/do/subscribe.php'), $form);
  794. } else {
  795. $form = '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '" onsubmit="return newsletter_check(this)">' .
  796. $form . '</form>';
  797. }
  798. $form = $this->replace_lists($form);
  799. return $form;
  800. }
  801. function find_file($file1, $file2) {
  802. if (is_file($file1))
  803. return $file1;
  804. return $file2;
  805. }
  806. function hook_site_transient_update_plugins($value) {
  807. static $extra_response = array();
  808. //$this->logger->debug('Update plugins transient called');
  809. if (!$value || !is_object($value)) {
  810. //$this->logger->info('Empty object');
  811. return $value;
  812. }
  813. if (!isset($value->response) || !is_array($value->response)) {
  814. $value->response = array();
  815. }
  816. if ($extra_response) {
  817. //$this->logger->debug('Already updated');
  818. $value->response = array_merge($value->response, $extra_response);
  819. return $value;
  820. }
  821. $extensions = $this->getTnpExtensions();
  822. if (!$extensions) {
  823. return $value;
  824. }
  825. foreach ($extensions as $extension) {
  826. unset($value->response[$extension->wp_slug]);
  827. unset($value->no_update[$extension->wp_slug]);
  828. }
  829. if (!NEWSLETTER_EXTENSION_UPDATE) {
  830. //$this->logger->info('Updates disabled');
  831. return $value;
  832. }
  833. include_once(ABSPATH . 'wp-admin/includes/plugin.php');
  834. if (!function_exists('get_plugin_data')) {
  835. //$this->logger->error('No get_plugin_data function available!');
  836. return $value;
  837. }
  838. $license_key = $this->get_license_key();
  839. foreach ($extensions as $extension) {
  840. // Patch for names convention
  841. $extension->plugin = $extension->wp_slug;
  842. //$this->logger->debug('Processing ' . $extension->plugin);
  843. //$this->logger->debug($extension);
  844. $plugin_data = false;
  845. if (file_exists(WP_PLUGIN_DIR . '/' . $extension->plugin)) {
  846. $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $extension->plugin, false, false);
  847. } else if (file_exists(WPMU_PLUGIN_DIR . '/' . $extension->plugin)) {
  848. $plugin_data = get_plugin_data(WPMU_PLUGIN_DIR . '/' . $extension->plugin, false, false);
  849. }
  850. if (!$plugin_data) {
  851. //$this->logger->debug('Seems not installed');
  852. continue;
  853. }
  854. $plugin = new stdClass();
  855. $plugin->id = $extension->id;
  856. $plugin->slug = $extension->slug;
  857. $plugin->plugin = $extension->plugin;
  858. $plugin->new_version = $extension->version;
  859. $plugin->url = $extension->url;
  860. if (class_exists('NewsletterExtensions')) {
  861. // NO filters here!
  862. $plugin->package = NewsletterExtensions::$instance->get_package($extension->id, $license_key);
  863. } else {
  864. $plugin->package = '';
  865. }
  866. // [banners] => Array
  867. // (
  868. // [2x] => https://ps.w.org/wp-rss-aggregator/assets/banner-1544x500.png?rev=2040548
  869. // [1x] => https://ps.w.org/wp-rss-aggregator/assets/banner-772x250.png?rev=2040548
  870. // )
  871. // [icons] => Array
  872. // (
  873. // [2x] => https://ps.w.org/advanced-custom-fields/assets/icon-256x256.png?rev=1082746
  874. // [1x] => https://ps.w.org/advanced-custom-fields/assets/icon-128x128.png?rev=1082746
  875. // )
  876. if (version_compare($extension->version, $plugin_data['Version']) > 0) {
  877. //$this->logger->debug('There is a new version');
  878. $extra_response[$extension->plugin] = $plugin;
  879. } else {
  880. //$this->logger->debug('There is NOT a new version');
  881. $value->no_update[$extension->plugin] = $plugin;
  882. }
  883. //$this->logger->debug('Added');
  884. }
  885. $value->response = array_merge($value->response, $extra_response);
  886. return $value;
  887. }
  888. /**
  889. * @deprecated since version 6.1.9
  890. */
  891. function get_extension_version($extension_id) {
  892. $extensions = $this->getTnpExtensions();
  893. if (!is_array($extensions)) {
  894. return null;
  895. }
  896. foreach ($extensions as $extension) {
  897. if ($extension->id == $extension_id) {
  898. return $extension->version;
  899. }
  900. }
  901. return null;
  902. }
  903. /**
  904. * MUST be kept for old addons.
  905. *
  906. * @deprecated since version 6.1.9
  907. */
  908. function set_extension_update_data($value, $extension) {
  909. return $value;
  910. }
  911. /**
  912. * Retrieve the extensions form the tnp site
  913. * @return array
  914. */
  915. function getTnpExtensions() {
  916. $extensions_json = get_transient('tnp_extensions_json');
  917. if (empty($extensions_json)) {
  918. $url = "http://www.thenewsletterplugin.com/wp-content/extensions.json?ver=" . NEWSLETTER_VERSION;
  919. $extensions_response = wp_remote_get($url);
  920. $extensions_json = wp_remote_retrieve_body($extensions_response);
  921. if (!empty($extensions_json)) {
  922. set_transient('tnp_extensions_json', $extensions_json, 72 * 60 * 60);
  923. }
  924. }
  925. $extensions = json_decode($extensions_json);
  926. return $extensions;
  927. }
  928. function clear_extensions_cache() {
  929. delete_transient('tnp_extensions_json');
  930. }
  931. function hook_plugins_loaded() {
  932. do_action('newsletter_loaded', NEWSLETTER_VERSION);
  933. if (function_exists('load_plugin_textdomain')) {
  934. load_plugin_textdomain('newsletter', false, plugin_basename(dirname(__FILE__)) . '/languages');
  935. }
  936. }
  937. var $panels = array();
  938. function add_panel($key, $panel) {
  939. if (!isset($this->panels[$key]))
  940. $this->panels[$key] = array();
  941. if (!isset($panel['id']))
  942. $panel['id'] = sanitize_key($panel['label']);
  943. $this->panels[$key][] = $panel;
  944. }
  945. function has_license() {
  946. return !empty($this->options['contract_key']);
  947. }
  948. /**
  949. * Returns the Newsletter dedicated page URL or an alternative URL if that page if not
  950. * configured or not available.
  951. *
  952. * @staticvar string $url
  953. * @return string
  954. */
  955. var $newsletter_page_url = false;
  956. function get_newsletter_page_url($language = '') {
  957. // TODO: Reintroduce the cache
  958. //if (!$this->newsletter_page_url) {
  959. if (!empty($this->options['page'])) {
  960. $this->newsletter_page_url = get_permalink($this->options['page']);
  961. if ($language && $this->newsletter_page_url) {
  962. if (class_exists('SitePress')) {
  963. $this->newsletter_page_url = apply_filters('wpml_permalink', $this->newsletter_page_url, $language);
  964. }
  965. if (function_exists('pll_get_post')) {
  966. $this->newsletter_page_url = get_permalink(pll_get_post($this->options['page']));
  967. }
  968. }
  969. }
  970. if (!$this->newsletter_page_url) {
  971. $this->newsletter_page_url = $this->build_action_url('m');
  972. }
  973. //}
  974. return $this->newsletter_page_url;
  975. }
  976. function get_license_key() {
  977. if (defined('NEWSLETTER_LICENSE_KEY')) {
  978. return NEWSLETTER_LICENSE_KEY;
  979. } else {
  980. if (!empty($this->options['contract_key'])) {
  981. return trim($this->options['contract_key']);
  982. }
  983. }
  984. return false;
  985. }
  986. function get_license_data($refresh = false) {
  987. if (!$refresh) {
  988. $license_data = get_transient('newsletter_license_data');
  989. if (!empty($license_data) && is_object($license_data)) {
  990. return $license_data;
  991. }
  992. }
  993. $this->logger->debug('Refreshing the license data');
  994. delete_transient('newsletter_license_data');
  995. $license_key = $this->get_license_key();
  996. if (empty($license_key)) {
  997. $this->logger->debug('License was empty');
  998. return false;
  999. }
  1000. $license_data_url = 'https://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/get-license-data.php';
  1001. $response = wp_remote_post($license_data_url, array(
  1002. 'body' => array('k' => $license_key)
  1003. ));
  1004. // Fall back to http...
  1005. if (is_wp_error($response)) {
  1006. $this->logger->error('Falling back to http');
  1007. $this->logger->error($response);
  1008. $response = wp_remote_post($license_data_url, array(
  1009. 'body' => array('k' => $license_key)
  1010. ));
  1011. if (is_wp_error($response)) {
  1012. $this->logger->error($response);
  1013. return $response;
  1014. }
  1015. }
  1016. $download_message = 'You can download all addons from www.thenewsletterplugin.com if your license is valid.';
  1017. if (wp_remote_retrieve_response_code($response) != '200') {
  1018. $this->logger->error('license data error: ' . wp_remote_retrieve_response_code($response));
  1019. return new WP_Error(wp_remote_retrieve_response_code($response), 'License validation service error. <br>' . $download_message);
  1020. }
  1021. $json = wp_remote_retrieve_body($response);
  1022. $data = json_decode($json);
  1023. if (!is_object($data)) {
  1024. $this->logger->error($json);
  1025. return new WP_Error(1, 'License validation service error. <br>' . $download_message);
  1026. }
  1027. if (isset($data->message)) {
  1028. return new WP_Error(1, $data->message . ' (check the license on Newsletter main settings)');
  1029. }
  1030. $timeout = 24 * 7 * 3600;
  1031. if ($data->expire < time() + $timeout) $timeout = $data->expire;
  1032. set_transient('newsletter_license_data', $data, $timeout);
  1033. return $data;
  1034. }
  1035. /**
  1036. * @deprecated
  1037. * @param type $license_key
  1038. * @return \WP_Error
  1039. */
  1040. public static function check_license($license_key) {
  1041. $response = wp_remote_get('http://www.thenewsletterplugin.com/wp-content/plugins/file-commerce-pro/check.php?k=' . urlencode($license_key), array('sslverify' => false));
  1042. if (is_wp_error($response)) {
  1043. /* @var $response WP_Error */
  1044. 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>'
  1045. . esc_html($response->get_error_code()) . ' - ' . esc_html($response->get_error_message()));
  1046. } else if ($response['response']['code'] != 200) {
  1047. 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.'
  1048. . '<br>You can anyway download the professional extension from https://www.thenewsletterplugin.com.');
  1049. } elseif ($expires = json_decode(wp_remote_retrieve_body($response))) {
  1050. return array('expires' => $expires->expire, 'message' => 'Your license is valid and expires on ' . esc_html(date('Y-m-d', $expires->expire)));
  1051. } else {
  1052. 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>');
  1053. }
  1054. }
  1055. }
  1056. $newsletter = Newsletter::instance();
  1057. require_once NEWSLETTER_DIR . '/subscription/subscription.php';
  1058. require_once NEWSLETTER_DIR . '/unsubscription/unsubscription.php';
  1059. require_once NEWSLETTER_DIR . '/profile/profile.php';
  1060. require_once NEWSLETTER_DIR . '/emails/emails.php';
  1061. require_once NEWSLETTER_DIR . '/users/users.php';
  1062. require_once NEWSLETTER_DIR . '/statistics/statistics.php';
  1063. require_once NEWSLETTER_DIR . '/widget/standard.php';
  1064. require_once NEWSLETTER_DIR . '/widget/minimal.php';