PageRenderTime 88ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/newsletter/plugin.php

https://github.com/dedavidd/piratenpartij.nl
PHP | 1240 lines | 837 code | 239 blank | 164 comment | 202 complexity | 7c9bf726a39385cc0ec4c70bef45b570 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. Plugin Name: Newsletter
  4. Plugin URI: http://www.satollo.net/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="http://www.satollo.net/plugins/newsletter#update">this page</a> to know what's changed.</strong>
  6. Version: 3.5.9
  7. Author: Stefano Lissa
  8. Author URI: http://www.satollo.net
  9. Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
  10. Copyright 2009-2014 Stefano Lissa (email: stefano@satollo.net, web: http://www.satollo.net)
  11. */
  12. // Useed as dummy parameter on css and js links
  13. define('NEWSLETTER_VERSION', '3.5.9');
  14. global $wpdb, $newsletter;
  15. //@include_once WP_CONTENT_DIR . '/extensions/newsletter/config.php';
  16. if (!defined('NEWSLETTER_EMAILS_TABLE'))
  17. define('NEWSLETTER_EMAILS_TABLE', $wpdb->prefix . 'newsletter_emails');
  18. if (!defined('NEWSLETTER_USERS_TABLE'))
  19. define('NEWSLETTER_USERS_TABLE', $wpdb->prefix . 'newsletter');
  20. if (!defined('NEWSLETTER_STATS_TABLE'))
  21. define('NEWSLETTER_STATS_TABLE', $wpdb->prefix . 'newsletter_stats');
  22. // Do not use basename(dirname()) since on activation the plugin is sandboxed inside a function
  23. define('NEWSLETTER_SLUG', 'newsletter');
  24. define('NEWSLETTER_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG);
  25. define('NEWSLETTER_INCLUDES_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG . '/includes');
  26. // Almost obsolete but the first two must be kept for compatibility with modules
  27. define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
  28. define('NEWSLETTER_EMAIL_URL', NEWSLETTER_URL . '/do/view.php');
  29. define('NEWSLETTER_SUBSCRIPTION_POPUP_URL', NEWSLETTER_URL . '/do/subscription-popup.php');
  30. define('NEWSLETTER_SUBSCRIBE_URL', NEWSLETTER_URL . '/do/subscribe.php');
  31. define('NEWSLETTER_SUBSCRIBE_POPUP_URL', NEWSLETTER_URL . '/do/subscribe-popup.php');
  32. define('NEWSLETTER_PROFILE_URL', NEWSLETTER_URL . '/do/profile.php');
  33. define('NEWSLETTER_SAVE_URL', NEWSLETTER_URL . '/do/save.php');
  34. define('NEWSLETTER_CONFIRM_URL', NEWSLETTER_URL . '/do/confirm.php');
  35. define('NEWSLETTER_CHANGE_URL', NEWSLETTER_URL . '/do/change.php');
  36. define('NEWSLETTER_UNLOCK_URL', NEWSLETTER_URL . '/do/unlock.php');
  37. define('NEWSLETTER_UNSUBSCRIBE_URL', NEWSLETTER_URL . '/do/unsubscribe.php');
  38. define('NEWSLETTER_UNSUBSCRIPTION_URL', NEWSLETTER_URL . '/do/unsubscription.php');
  39. if (!defined('NEWSLETTER_LIST_MAX'))
  40. define('NEWSLETTER_LIST_MAX', 20);
  41. if (!defined('NEWSLETTER_PROFILE_MAX'))
  42. define('NEWSLETTER_PROFILE_MAX', 20);
  43. if (!defined('NEWSLETTER_FORMS_MAX'))
  44. define('NEWSLETTER_FORMS_MAX', 10);
  45. if (!defined('NEWSLETTER_CRON_INTERVAL'))
  46. define('NEWSLETTER_CRON_INTERVAL', 300);
  47. if (!defined('NEWSLETTER_HEADER'))
  48. define('NEWSLETTER_HEADER', true);
  49. // Force the whole system log level to this value
  50. //define('NEWSLETTER_LOG_LEVEL', 4);
  51. require_once NEWSLETTER_INCLUDES_DIR . '/logger.php';
  52. require_once NEWSLETTER_INCLUDES_DIR . '/store.php';
  53. require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
  54. require_once NEWSLETTER_INCLUDES_DIR . '/themes.php';
  55. class Newsletter extends NewsletterModule {
  56. // Limits to respect to avoid memory, time or provider limits
  57. var $time_start;
  58. var $time_limit;
  59. var $email_limit = 10; // Per run, every 5 minutes
  60. var $limits_set = false;
  61. var $max_emails = 20;
  62. /**
  63. * @var PHPMailer
  64. */
  65. var $mailer;
  66. // Message shown when the interaction is inside a WordPress page
  67. var $message;
  68. var $user;
  69. var $error;
  70. var $theme;
  71. // Theme autocomposer variables
  72. var $theme_max_posts;
  73. var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
  74. var $theme_posts; // WP_Query object
  75. // Secret key to create a unique log file name (and may be other)
  76. var $lock_found = false;
  77. static $instance;
  78. /**
  79. * @return Newsletter
  80. */
  81. static function instance() {
  82. if (self::$instance == null) {
  83. self::$instance = new Newsletter();
  84. }
  85. return self::$instance;
  86. }
  87. function __construct() {
  88. $this->time_start = time();
  89. // Here because the upgrade is called by the parent constructor and uses the scheduler
  90. add_filter('cron_schedules', array($this, 'hook_cron_schedules'), 1000);
  91. parent::__construct('main', '1.2.2');
  92. $max = $this->options['scheduler_max'];
  93. if (!is_numeric($max))
  94. $max = 100;
  95. $this->max_emails = max(floor($max / 12), 1);
  96. add_action('init', array($this, 'hook_init'));
  97. add_action('newsletter', array($this, 'hook_newsletter'), 1);
  98. add_action('newsletter_check_versions', array($this, 'hook_check_versions'), 99);
  99. // This specific event is created by "Feed by mail" panel on configuration
  100. add_action('shutdown', array($this, 'hook_shutdown'));
  101. if (defined('DOING_CRON') && DOING_CRON)
  102. return;
  103. // TODO: Meditation on how to use those ones...
  104. register_activation_hook(__FILE__, array($this, 'hook_activate'));
  105. //register_deactivation_hook(__FILE__, array(&$this, 'hook_deactivate'));
  106. add_action('admin_init', array($this, 'hook_admin_init'));
  107. add_action('wp_head', array($this, 'hook_wp_head'));
  108. add_shortcode('newsletter_lock', array($this, 'shortcode_newsletter_lock'));
  109. add_filter('the_content', array($this, 'hook_the_content'), 99);
  110. add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
  111. if (is_admin()) {
  112. add_action('admin_head', array($this, 'hook_admin_head'));
  113. // Protection against strange schedule removal on some installations
  114. if (!wp_next_scheduled('newsletter') && !defined('WP_INSTALLING')) {
  115. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  116. }
  117. }
  118. }
  119. function hook_activate() {
  120. // Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
  121. // the every-five-minutes schedule named "newsletter" is not present.
  122. // Since the activation does not forces an upgrade, that schedule must be reactivated here. It is activated on
  123. // the upgrade method as well for the user which upgrade the plugin without deactivte it (many).
  124. if (!wp_next_scheduled('newsletter')) {
  125. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  126. }
  127. }
  128. function upgrade() {
  129. global $wpdb, $charset_collate;
  130. parent::upgrade();
  131. $this->upgrade_query("create table if not exists " . NEWSLETTER_EMAILS_TABLE . " (id int auto_increment, primary key (id)) $charset_collate");
  132. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column message longtext");
  133. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column message_text longtext");
  134. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column subject varchar(255) not null default ''");
  135. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column type varchar(50) not null default ''");
  136. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column created timestamp not null default current_timestamp");
  137. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column status enum('new','sending','sent','paused') not null default 'new'");
  138. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column total int not null default 0");
  139. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column last_id int not null default 0");
  140. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column sent int not null default 0");
  141. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column send_on int not null default 0");
  142. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column track tinyint not null default 0");
  143. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column editor tinyint not null default 0");
  144. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column sex char(1) not null default ''");
  145. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " change column sex sex char(1) not null default ''");
  146. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column query text");
  147. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column preferences text");
  148. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column options longtext");
  149. // Cleans up old installations
  150. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " drop column name");
  151. $this->upgrade_query("drop table if exists " . $wpdb->prefix . "newsletter_work");
  152. $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " convert to character set utf8");
  153. // Some setting check to avoid the common support request for mis-configurations
  154. $options = $this->get_options();
  155. if (empty($options['sender_email'])) {
  156. // That code was taken from WordPress
  157. $sitename = strtolower($_SERVER['SERVER_NAME']);
  158. if (substr($sitename, 0, 4) == 'www.')
  159. $sitename = substr($sitename, 4);
  160. // WordPress build an address in the same way using wordpress@...
  161. $options['sender_email'] = 'newsletter@' . $sitename;
  162. $this->save_options($options);
  163. }
  164. if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
  165. $options['scheduler_max'] = 100;
  166. $this->save_options($options);
  167. }
  168. if (empty($options['api_key'])) {
  169. $options['api_key'] = self::get_token();
  170. $this->save_options($options);
  171. }
  172. if (empty($options['scheduler_max'])) {
  173. $options['scheduler_max'] = 100;
  174. $this->save_options($options);
  175. }
  176. wp_clear_scheduled_hook('newsletter');
  177. wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
  178. wp_clear_scheduled_hook('newsletter_update');
  179. wp_clear_scheduled_hook('newsletter_check_versions');
  180. wp_schedule_event(time() + 30, 'newsletter_weekly', 'newsletter_check_versions');
  181. wp_mkdir_p(WP_CONTENT_DIR . '/extensions/newsletter');
  182. wp_mkdir_p(WP_CONTENT_DIR . '/cache/newsletter');
  183. //wp_clear_scheduled_hook('newsletter_updates_run');
  184. wp_clear_scheduled_hook('newsletter_statistics_version_check');
  185. wp_clear_scheduled_hook('newsletter_reports_version_check');
  186. wp_clear_scheduled_hook('newsletter_feed_version_check');
  187. wp_clear_scheduled_hook('newsletter_popup_version_check');
  188. return true;
  189. }
  190. function admin_menu() {
  191. // This adds the main menu page
  192. add_menu_page('Newsletter', 'Newsletter', ($this->options['editor'] == 1) ? 'manage_categories' : 'manage_options', 'newsletter_main_index');
  193. $this->add_menu_page('index', 'Welcome');
  194. $this->add_menu_page('main', 'Configuration');
  195. $this->add_menu_page('diagnostic', 'Diagnostic');
  196. }
  197. /**
  198. * Returns a set of warnings about this installtion the suser should be aware of. Return an empty string
  199. * if there are no warnings.
  200. */
  201. function warnings() {
  202. $warnings = '';
  203. $x = wp_next_scheduled('newsletter');
  204. if ($x === false) {
  205. $warnings .= 'The delivery engine is off (it should never be off). Deactivate and reactivate the plugin. Thank you.<br>';
  206. } else if (time() - $x > 900) {
  207. $warnings .= 'The cron system seems not running correctly. See <a href="http://www.satollo.net/how-to-make-the-wordpress-cron-work" target="_blank">this page</a> for more information.<br>';
  208. }
  209. if (!empty($warnings)) {
  210. echo '<div id="#newsletter-warnings">';
  211. echo $warnings;
  212. echo '</div>';
  213. }
  214. }
  215. function hook_init() {
  216. global $cache_stop, $hyper_cache_stop, $wpdb;
  217. if (is_admin()) {
  218. if ($this->is_admin_page()) {
  219. wp_enqueue_script('jquery-ui-tabs');
  220. wp_enqueue_script('media-upload');
  221. wp_enqueue_script('thickbox');
  222. wp_enqueue_style('thickbox');
  223. }
  224. }
  225. $action = isset($_REQUEST['na']) ? $_REQUEST['na'] : '';
  226. if (empty($action) || is_admin())
  227. return;
  228. // TODO: Remove!
  229. $cache_stop = true;
  230. $hyper_cache_stop = true;
  231. if ($action == 'of') {
  232. echo $this->subscription_form('os');
  233. die();
  234. }
  235. if ($action == 'fu') {
  236. $user = $this->check_user();
  237. if ($user == null)
  238. die('No user');
  239. $wpdb->query("update " . $wpdb->prefix . "newsletter set followup=2 where id=" . $user->id);
  240. $options_followup = get_option('newsletter_followup');
  241. $this->message = $options_followup['unsubscribed_text'];
  242. return;
  243. }
  244. }
  245. function is_admin_page() {
  246. // TODO: Use the module list to detect that...
  247. if (!isset($_GET['page']))
  248. return false;
  249. $page = $_GET['page'];
  250. return strpos($page, 'newsletter_') === 0 || strpos($page, 'newsletter-statistics/') === 0 || strpos($page, 'newsletter/') === 0 ||
  251. strpos($page, 'newsletter-updates/') === 0 || strpos($page, 'newsletter-flows/') === 0;
  252. }
  253. function hook_admin_init() {
  254. }
  255. function hook_admin_head() {
  256. if ($this->is_admin_page()) {
  257. echo '<link type="text/css" rel="stylesheet" href="' . plugins_url('newsletter') . '/admin.css?' . NEWSLETTER_VERSION . '"/>';
  258. echo '<script src="' . plugins_url('newsletter') . '/admin.js?' . NEWSLETTER_VERSION . '"></script>';
  259. }
  260. }
  261. function hook_wp_head() {
  262. if (!empty($this->options['css'])) {
  263. echo "<style type='text/css'>\n";
  264. echo $this->options['css'];
  265. echo "</style>";
  266. }
  267. // TODO: move on subscription module
  268. $profile_options = get_option('newsletter_profile');
  269. if (!empty($profile_options['style'])) {
  270. echo '<link href="' . NewsletterSubscription::instance()->get_style_url($profile_options['style']) . '" type="text/css" rel="stylesheet">';
  271. }
  272. if (!empty($profile_options['widget_style'])) {
  273. echo '<link href="' . NewsletterSubscription::instance()->get_style_url($profile_options['widget_style']) . '" type="text/css" rel="stylesheet">';
  274. }
  275. }
  276. function relink($text, $email_id, $user_id) {
  277. return NewsletterStatistics::instance()->relink($text, $email_id, $user_id);
  278. }
  279. function hook_check_versions() {
  280. //$this->logger->info('Checking for new versions');
  281. $url = 'http://www.satollo.net/wp-content/plugins/file-commerce-pro/version.php?f=';
  282. $modules = array(
  283. 'reports' => 34,
  284. 'feed' => 35,
  285. 'followup' => 37,
  286. 'facebook' => 41,
  287. 'sendgrid' => 40,
  288. 'popup' => 43,
  289. 'mandrill' => 44,
  290. 'mailjet' => 38);
  291. foreach ($modules as $name => $id) {
  292. $version = @file_get_contents($url . $id);
  293. if ($version) {
  294. update_option('newsletter_' . $name . '_available_version', $version);
  295. }
  296. }
  297. }
  298. /**
  299. * Runs every 5 minutes and look for emails that need to be processed.
  300. */
  301. function hook_newsletter() {
  302. global $wpdb;
  303. $this->logger->debug('hook_newsletter> Start');
  304. // Do not accept job activation before at least 4 minutes are elapsed from the last run.
  305. if (!$this->check_transient('engine', NEWSLETTER_CRON_INTERVAL))
  306. return;
  307. // Retrieve all email in "sending" status
  308. $emails = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where status='sending' and send_on<" . time() . " order by id asc");
  309. $this->logger->debug('hook_newsletter> Emails found in sending status: ' . count($emails));
  310. foreach ($emails as &$email) {
  311. $this->logger->debug('hook_newsletter> Sending email ' . $email->id);
  312. if (!$this->send($email))
  313. break;
  314. }
  315. // Remove the semaphore so the delivery engine can be activated again
  316. $this->delete_transient('engine');
  317. $this->logger->debug('hook_newsletter> End');
  318. }
  319. /**
  320. * Sends an email to targeted users ot to users passed on. If a list of users is given (usually a list of test users)
  321. * the query inside the email to retrieve users is not used.
  322. *
  323. * @global type $wpdb
  324. * @global type $newsletter_feed
  325. * @param type $email
  326. * @param array $users
  327. * @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.
  328. */
  329. function send($email, $users = null) {
  330. global $wpdb;
  331. if (is_array($email))
  332. $email = (object) $email;
  333. // This stops the update of last_id and sent fields since it's not a scheduled delivery but a test.
  334. $test = $users != null;
  335. if ($users == null) {
  336. if (empty($email->query)) {
  337. $email->query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
  338. }
  339. $query = $email->query . " and id>" . $email->last_id . " order by id limit " . $this->max_emails;
  340. $users = $wpdb->get_results($query);
  341. // If there was a database error, do nothing
  342. if ($wpdb->last_error) {
  343. $this->logger->fatal($wpdb->last_error);
  344. return;
  345. }
  346. if (empty($users)) {
  347. $this->logger->info('No more users');
  348. $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
  349. return true;
  350. }
  351. }
  352. foreach ($users as &$user) {
  353. // Before try to send, check the limits.
  354. if (!$test && $this->limits_exceeded())
  355. return false;
  356. $headers = array('List-Unsubscribe' => '<' . NEWSLETTER_UNSUBSCRIBE_URL . '?nk=' . $user->id . '-' . $user->token . '>');
  357. $headers['Precedence'] = 'bulk';
  358. $headers['X-Newsletter-Email-Id'] = $email->id;
  359. if (!$test) {
  360. $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
  361. }
  362. $m = $this->replace($email->message, $user, $email->id);
  363. $mt = $this->replace($email->message_text, $user, $email->id);
  364. if ($email->track == 1)
  365. $m = $this->relink($m, $email->id, $user->id);
  366. $s = $this->replace($email->subject, $user);
  367. if (isset($user->wp_user_id) && $user->wp_user_id != 0) {
  368. $this->logger->debug('Have wp_user_id: ' . $user->wp_user_id);
  369. // TODO: possibly name extraction
  370. $wp_user_email = $wpdb->get_var($wpdb->prepare("select user_email from $wpdb->users where id=%d limit 1", $user->wp_user_id));
  371. if (!empty($wp_user_email)) {
  372. $user->email = $wp_user_email;
  373. $this->logger->debug('Email replaced with: ' . $user->email);
  374. } else {
  375. $this->logger->debug('WP user has not an email?!');
  376. }
  377. }
  378. $this->mail($user->email, $s, array('html' => $m, 'text' => $mt), $headers);
  379. $this->email_limit--;
  380. }
  381. return true;
  382. }
  383. /**
  384. * Probably obsolete.
  385. */
  386. function execute($text, $user = null) {
  387. global $wpdb;
  388. ob_start();
  389. $r = eval('?' . '>' . $text);
  390. if ($r === false) {
  391. $this->error = 'Error while executing a PHP expression in a message body. See log file.';
  392. $this->log('Error on execution of ' . $text, 1);
  393. ob_end_clean();
  394. return false;
  395. }
  396. return ob_get_clean();
  397. }
  398. /**
  399. * This function checks is, during processing, we are getting to near to system limits and should stop any further
  400. * work (when returns true).
  401. */
  402. function limits_exceeded() {
  403. global $wpdb;
  404. if (!$this->limits_set) {
  405. $this->logger->debug('limits_exceeded> Setting the limits for the first time');
  406. $max_time = NEWSLETTER_CRON_INTERVAL;
  407. // Actually it should be set on startup, anyway the scripts use as time base the startup time
  408. if (!empty($this->options['php_time_limit'])) {
  409. @set_time_limit((int) $this->options['php_time_limit']);
  410. } else if (defined('NEWSLETTER_MAX_EXECUTION_TIME')) {
  411. @set_time_limit(NEWSLETTER_MAX_EXECUTION_TIME);
  412. }
  413. $max_time = (int) (@ini_get('max_execution_time') * 0.95);
  414. if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL)
  415. $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
  416. $this->time_limit = $this->time_start + $max_time;
  417. $this->logger->info('limits_exceeded> Max time set to ' . $max_time);
  418. $max = $this->options['scheduler_max'];
  419. if (!is_numeric($max))
  420. $max = 100;
  421. $this->email_limit = max(floor($max / 12), 1);
  422. $this->logger->debug('limits_exceeded> Max number of emails can send: ' . $this->email_limit);
  423. $wpdb->query("set session wait_timeout=300");
  424. // From default-constants.php
  425. if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 ))
  426. @ini_set('memory_limit', '256M');
  427. $this->limits_set = true;
  428. }
  429. // The time limit is set on constructor, since it has to be set as early as possible
  430. if (time() > $this->time_limit) {
  431. $this->logger->info('limits_exceeded> Max execution time limit reached');
  432. return true;
  433. }
  434. if ($this->email_limit <= 0) {
  435. $this->logger->info('limits_exceeded> Max emails limit reached');
  436. return true;
  437. }
  438. return false;
  439. }
  440. /**
  441. *
  442. * @param string $to
  443. * @param string $subject
  444. * @param string|array $message
  445. * @param type $headers
  446. * @return boolean
  447. */
  448. var $mail_method = null;
  449. function register_mail_method($callable) {
  450. $this->mail_method = $callable;
  451. }
  452. function mail($to, $subject, $message, $headers = null) {
  453. $this->logger->debug('mail> To: ' . $to);
  454. $this->logger->debug('mail> Subject: ' . $subject);
  455. if (empty($subject)) {
  456. $this->logger->debug('mail> Subject empty, skipped');
  457. return true;
  458. }
  459. // Message carrige returns and line feeds clean up
  460. if (!is_array($message)) {
  461. $message = str_replace("\r\n", "\n", $message);
  462. $message = str_replace("\r", "\n", $message);
  463. $message = str_replace("\n", "\r\n", $message);
  464. } else {
  465. if (!empty($message['text'])) {
  466. $message['text'] = str_replace("\r\n", "\n", $message['text']);
  467. $message['text'] = str_replace("\r", "\n", $message['text']);
  468. $message['text'] = str_replace("\n", "\r\n", $message['text']);
  469. }
  470. if (!empty($message['html'])) {
  471. $message['html'] = str_replace("\r\n", "\n", $message['html']);
  472. $message['html'] = str_replace("\r", "\n", $message['html']);
  473. $message['html'] = str_replace("\n", "\r\n", $message['html']);
  474. }
  475. }
  476. if ($this->mail_method != null) {
  477. return call_user_func($this->mail_method, $to, $subject, $message, $headers);
  478. }
  479. if ($this->mailer == null)
  480. $this->mailer_init();
  481. // Simple message is asumed to be html
  482. if (!is_array($message)) {
  483. $this->mailer->IsHTML(true);
  484. $this->mailer->Body = $message;
  485. } else {
  486. // Only html is present?
  487. if (empty($message['text'])) {
  488. $this->mailer->IsHTML(true);
  489. $this->mailer->Body = $message['html'];
  490. }
  491. // Only text is present?
  492. else if (empty($message['html'])) {
  493. $this->mailer->IsHTML(false);
  494. $this->mailer->Body = $message['text'];
  495. } else {
  496. $this->mailer->IsHTML(true);
  497. $this->mailer->Body = $message['html'];
  498. $this->mailer->AltBody = $message['text'];
  499. }
  500. }
  501. $this->mailer->Subject = $subject;
  502. $this->mailer->ClearCustomHeaders();
  503. if (!empty($headers)) {
  504. foreach ($headers as $key => $value) {
  505. $this->mailer->AddCustomHeader($key . ': ' . $value);
  506. }
  507. }
  508. $this->mailer->ClearAddresses();
  509. $this->mailer->AddAddress($to);
  510. $this->mailer->Send();
  511. if ($this->mailer->IsError()) {
  512. $this->logger->error('mail> ' . $this->mailer->ErrorInfo);
  513. // If the error is due to SMTP connection, the mailer cannot be reused since it does not clean up the connection
  514. // on error.
  515. $this->mailer = null;
  516. return false;
  517. }
  518. return true;
  519. }
  520. function mailer_init() {
  521. require_once ABSPATH . WPINC . '/class-phpmailer.php';
  522. require_once ABSPATH . WPINC . '/class-smtp.php';
  523. $this->mailer = new PHPMailer();
  524. $smtp_options = array();
  525. $smtp_options['enabled'] = $this->options['smtp_enabled'];
  526. $smtp_options['host'] = $this->options['smtp_host'];
  527. $smtp_options['port'] = $this->options['smtp_port'];
  528. $smtp_options['user'] = $this->options['smtp_user'];
  529. $smtp_options['pass'] = $this->options['smtp_pass'];
  530. $smtp_options['secure'] = $this->options['smtp_secure'];
  531. $smtp_options = apply_filters('newsletter_smtp', $smtp_options);
  532. if ($smtp_options['enabled'] == 1) {
  533. $this->mailer->IsSMTP();
  534. $this->mailer->Host = $smtp_options['host'];
  535. if (!empty($smtp_options['port']))
  536. $this->mailer->Port = (int) $smtp_options['port'];
  537. if (!empty($smtp_options['user'])) {
  538. $this->mailer->SMTPAuth = true;
  539. $this->mailer->Username = $smtp_options['user'];
  540. $this->mailer->Password = $smtp_options['pass'];
  541. }
  542. $this->mailer->SMTPKeepAlive = true;
  543. $this->mailer->SMTPSecure = $smtp_options['secure'];
  544. } else {
  545. $this->mailer->IsMail();
  546. }
  547. if (!empty($this->options['content_transfer_encoding'])) {
  548. $this->mailer->Encoding = $this->options['content_transfer_encoding'];
  549. } else {
  550. $this->mailer->Encoding = 'base64';
  551. }
  552. $this->mailer->CharSet = 'UTF-8';
  553. $this->mailer->From = $this->options['sender_email'];
  554. $return_path = $this->options['return_path'];
  555. if (!empty($return_path)) {
  556. $this->mailer->Sender = $return_path;
  557. }
  558. if (!empty($this->options['reply_to'])) {
  559. $this->mailer->AddReplyTo($this->options['reply_to']);
  560. }
  561. $this->mailer->FromName = $this->options['sender_name'];
  562. }
  563. function hook_deactivate() {
  564. wp_clear_scheduled_hook('newsletter');
  565. wp_clear_scheduled_hook('newsletter_feed');
  566. }
  567. function hook_cron_schedules($schedules) {
  568. $schedules['newsletter'] = array(
  569. 'interval' => NEWSLETTER_CRON_INTERVAL, // seconds
  570. 'display' => 'Newsletter'
  571. );
  572. $schedules['newsletter_weekly'] = array(
  573. 'interval' => 86400 * 7, // seconds
  574. 'display' => 'Newsletter Weekly'
  575. );
  576. return $schedules;
  577. }
  578. function shortcode_newsletter_form($attrs, $content) {
  579. return $this->form($attrs['form']);
  580. }
  581. function form($number = null) {
  582. if ($number == null)
  583. return $this->subscription_form();
  584. $options = get_option('newsletter_forms');
  585. $form = $options['form_' . $number];
  586. if (stripos($form, '<form') !== false) {
  587. $form = str_replace('{newsletter_url}', plugins_url('newsletter/do/subscribe.php'), $form);
  588. } else {
  589. $form = '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '" onsubmit="return newsletter_check(this)">' .
  590. $form . '</form>';
  591. }
  592. $form = $this->replace_lists($form);
  593. return $form;
  594. }
  595. function find_file($file1, $file2) {
  596. if (is_file($file1))
  597. return $file1;
  598. return $file2;
  599. }
  600. /**
  601. * Return a user if there are request parameters or cookie with identification data otherwise null.
  602. */
  603. function check_user() {
  604. global $wpdb, $current_user;
  605. if (isset($_REQUEST['nk'])) {
  606. list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
  607. } else if (isset($_REQUEST['ni'])) {
  608. $id = (int) $_REQUEST['ni'];
  609. $token = $_REQUEST['nt'];
  610. } else if (isset($_COOKIE['newsletter'])) {
  611. list ($id, $token) = @explode('-', $_COOKIE['newsletter'], 2);
  612. }
  613. if (is_numeric($id) && !empty($token)) {
  614. return $wpdb->get_row($wpdb->prepare("select * from " . $wpdb->prefix . "newsletter where id=%d and token=%s limit 1", $id, $token));
  615. }
  616. return null;
  617. /*
  618. if ($this->options_main['wp_integration'] != 1) {
  619. return null;
  620. }
  621. get_currentuserinfo();
  622. // Retrieve the related newsletter user
  623. $user = $wpdb->get_row("select * from " . NEWSLETTER_USERS_TABLE . " where wp_user_id=" . $current_user->ID . " limit 1");
  624. // There is an email matching?
  625. if (empty($user)) {
  626. $user = $wpdb->get_row($wpdb->prepare("select * from " . NEWSLETTER_USERS_TABLE . " where email=%s limit 1", strtolower($current_user->user_email)));
  627. // If not found, create a new Newsletter user, else update the wp_user_id since this email must be linked
  628. // to the WP user email.
  629. if (empty($user)) {
  630. return null;
  631. //echo 'WP user not found';
  632. $user = array();
  633. $user['status'] = 'C';
  634. $user['wp_user_id'] = $current_user->ID;
  635. $user['token'] = $this->get_token();
  636. $user['email'] = strtolower($current_user->user_email);
  637. $id = $wpdb->insert(NEWSLETTER_USERS_TABLE, $user);
  638. $user = NewsletterUsers::instance()->get_user($id);
  639. } else {
  640. //echo 'WP user found via email';
  641. $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set wp_user_id=" . $current_user->ID . ", email=%s", $current_user->user_email));
  642. }
  643. } else {
  644. //echo 'WP user found via id';
  645. }
  646. return $user;
  647. */
  648. }
  649. function replace_date($text) {
  650. $text = str_replace('{date}', date_i18n(get_option('date_format')), $text);
  651. // Date processing
  652. $x = 0;
  653. while (($x = strpos($text, '{date_', $x)) !== false) {
  654. $y = strpos($text, '}', $x);
  655. if ($y === false)
  656. continue;
  657. $f = substr($text, $x + 6, $y - $x - 6);
  658. $text = substr($text, 0, $x) . date($f) . substr($text, $y + 1);
  659. }
  660. return $text;
  661. }
  662. /**
  663. * Replace any kind of newsletter placeholder in a text.
  664. */
  665. function replace($text, $user = null, $email_id = null, $referrer = null) {
  666. global $wpdb;
  667. $this->logger->debug('Replace start');
  668. if (is_array($user)) {
  669. $user = $this->get_user($user['id']);
  670. }
  671. $email = null;
  672. if (is_numeric($email_id)) {
  673. $email = $this->get_email($email_id);
  674. }
  675. $text = apply_filters('newsletter_replace', $text, $user, $email);
  676. //$text = str_replace('{home_url}', get_option('home'), $text);
  677. //$text = str_replace('{blog_url}', get_option('home'), $text);
  678. $text = $this->replace_url($text, 'BLOG_URL', get_option('home'));
  679. $text = $this->replace_url($text, 'HOME_URL', get_option('home'));
  680. $text = str_replace('{blog_title}', get_option('blogname'), $text);
  681. $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
  682. $text = $this->replace_date($text);
  683. if ($user != null) {
  684. $options_profile = get_option('newsletter_profile');
  685. $text = str_replace('{email}', $user->email, $text);
  686. if (empty($user->name)) {
  687. $text = str_replace(' {name}', '', $text);
  688. $text = str_replace('{name}', '', $text);
  689. } else {
  690. $text = str_replace('{name}', $user->name, $text);
  691. }
  692. switch ($user->sex) {
  693. case 'm': $text = str_replace('{title}', $options_profile['title_male'], $text);
  694. break;
  695. case 'f': $text = str_replace('{title}', $options_profile['title_female'], $text);
  696. break;
  697. case 'n': $text = str_replace('{title}', $options_profile['title_none'], $text);
  698. break;
  699. default:
  700. $text = str_replace('{title}', '', $text);
  701. }
  702. $text = str_replace('{surname}', $user->surname, $text);
  703. $text = str_replace('{last_name}', $user->surname, $text);
  704. $full_name = trim($user->name . ' ' . $user->surname);
  705. if (empty($full_name)) {
  706. $text = str_replace(' {full_name}', '', $text);
  707. $text = str_replace('{full_name}', '', $text);
  708. } else {
  709. $text = str_replace('{full_name}', $full_name, $text);
  710. }
  711. $text = str_replace('{token}', $user->token, $text);
  712. $text = str_replace('%7Btoken%7D', $user->token, $text);
  713. $text = str_replace('{id}', $user->id, $text);
  714. $text = str_replace('%7Bid%7D', $user->id, $text);
  715. $text = str_replace('{ip}', $user->ip, $text);
  716. $text = str_replace('{key}', $user->id . '-' . $user->token, $text);
  717. $text = str_replace('%7Bkey%7D', $user->id . '-' . $user->token, $text);
  718. if (strpos($text, '{profile_form}') !== false)
  719. $text = str_replace('{profile_form}', NewsletterSubscription::instance()->get_profile_form($user), $text);
  720. for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
  721. $p = 'profile_' . $i;
  722. $text = str_replace('{profile_' . $i . '}', $user->$p, $text);
  723. }
  724. // $profile = $wpdb->get_results("select name,value from " . $wpdb->prefix . "newsletter_profiles where newsletter_id=" . $user->id);
  725. // foreach ($profile as $field) {
  726. // $text = str_ireplace('{np_' . $field->name . '}', htmlspecialchars($field->value), $text);
  727. // }
  728. //
  729. // $text = preg_replace('/\\{np_.+\}/i', '', $text);
  730. $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
  731. $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
  732. $nk = $user->id . '-' . $user->token;
  733. //$text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', self::add_qs(plugins_url('do.php', __FILE__), 'a=c' . $id_token));
  734. $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', plugins_url('newsletter/do/confirm.php') . '?nk=' . $nk);
  735. $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', plugins_url('newsletter/do/unsubscribe.php') . '?nk=' . $nk);
  736. //$text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', NEWSLETTER_URL . '/do/unsubscribe.php?nk=' . $nk);
  737. $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', plugins_url('newsletter/do/unsubscription.php') . '?nk=' . $nk);
  738. $text = $this->replace_url($text, 'CHANGE_URL', plugins_url('newsletter/do/change.php'));
  739. // Obsolete.
  740. $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
  741. $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
  742. $text = $this->replace_url($text, 'FEED_SUBSCRIPTION_URL', self::add_qs($base, 'nm=es' . $id_token));
  743. $text = $this->replace_url($text, 'FEED_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=eu' . $id_token));
  744. if (empty($options_profile['profile_url']))
  745. $text = $this->replace_url($text, 'PROFILE_URL', plugins_url('newsletter/do/profile.php') . '?nk=' . $nk);
  746. else
  747. $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
  748. //$text = $this->replace_url($text, 'UNLOCK_URL', self::add_qs($this->options_main['lock_url'], 'nm=m' . $id_token));
  749. $text = $this->replace_url($text, 'UNLOCK_URL', plugins_url('newsletter/do/unlock.php') . '?nk=' . $nk);
  750. if (!empty($email_id)) {
  751. $text = $this->replace_url($text, 'EMAIL_URL', plugins_url('newsletter/do/view.php') . '?id=' . $email_id . '&amp;nk=' . $nk);
  752. }
  753. for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
  754. $text = $this->replace_url($text, 'LIST_' . $i . '_SUBSCRIPTION_URL', self::add_qs($base, 'nm=ls&amp;nl=' . $i . $id_token));
  755. $text = $this->replace_url($text, 'LIST_' . $i . '_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=lu&amp;nl=' . $i . $id_token));
  756. }
  757. // Profile fields change links
  758. $text = $this->replace_url($text, 'SET_SEX_MALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=m');
  759. $text = $this->replace_url($text, 'SET_SEX_FEMALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=f');
  760. $text = $this->replace_url($text, 'SET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=feed');
  761. $text = $this->replace_url($text, 'UNSET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=feed');
  762. for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
  763. $text = $this->replace_url($text, 'SET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=preference_' . $i);
  764. $text = $this->replace_url($text, 'UNSET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=preference_' . $i);
  765. }
  766. }
  767. if (strpos($text, '{subscription_form}') !== false) {
  768. $text = str_replace('{subscription_form}', NewsletterSubscription::instance()->get_subscription_form($referrer), $text);
  769. } else {
  770. for ($i = 1; $i <= 10; $i++) {
  771. if (strpos($text, "{subscription_form_$i}") !== false) {
  772. $text = str_replace("{subscription_form_$i}", NewsletterSubscription::instance()->get_form($i), $text);
  773. break;
  774. }
  775. }
  776. }
  777. $this->logger->debug('Replace end');
  778. return $text;
  779. }
  780. function replace_url($text, $tag, $url) {
  781. $home = get_option('home') . '/';
  782. $tag_lower = strtolower($tag);
  783. $text = str_replace($home . '{' . $tag_lower . '}', $url, $text);
  784. $text = str_replace($home . '%7B' . $tag_lower . '%7D', $url, $text);
  785. $text = str_replace('{' . $tag_lower . '}', $url, $text);
  786. $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
  787. // for compatibility
  788. $text = str_replace($home . $tag, $url, $text);
  789. return $text;
  790. }
  791. function hook_shutdown() {
  792. if ($this->mailer != null)
  793. $this->mailer->SmtpClose();
  794. }
  795. function hook_the_content($content) {
  796. global $post, $cache_stop;
  797. if ($this->lock_found || !is_singular() || is_user_logged_in()) {
  798. return $content;
  799. }
  800. if (!empty($this->options['lock_ids'])) {
  801. $ids = explode(',', $this->options['lock_ids']);
  802. }
  803. if (!empty($ids) && (has_tag($ids) || in_category($ids) || in_array($post->post_name, $ids))) {
  804. $cache_stop = true;
  805. $user = $this->check_user();
  806. if ($user == null || $user->status != 'C') {
  807. $buffer = $this->replace($this->options['lock_message']);
  808. return '<div class="newsletter-lock">' . do_shortcode($buffer) . '</div>';
  809. }
  810. }
  811. return $content;
  812. }
  813. function shortcode_newsletter_lock($attrs, $content = null) {
  814. global $hyper_cache_stop, $cache_stop;
  815. $this->logger->debug('Lock short code start');
  816. $hyper_cache_stop = true;
  817. $cache_stop = true;
  818. $this->lock_found = true;
  819. $user = $this->check_user();
  820. if (is_user_logged_in() || ($user != null && $user->status == 'C')) {
  821. return do_shortcode($content);
  822. }
  823. $buffer = $this->options['lock_message'];
  824. // ob_start();
  825. // eval('? >' . $buffer . "\n");
  826. // $buffer = ob_get_clean();
  827. // TODO: add the newsletter check on submit
  828. $buffer = str_ireplace('<form', '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '"', $buffer);
  829. $buffer = $this->replace($buffer, null, null, 'lock');
  830. $buffer = do_shortcode($buffer);
  831. $this->logger->debug('Lock short code end');
  832. return '<div class="newsletter-lock">' . $buffer . '</div>';
  833. }
  834. function shortcode_newsletter_profile($attrs, $content) {
  835. global $wpdb, $current_user;
  836. $user = $this->check_user();
  837. if ($user == null) {
  838. return 'No user found.';
  839. }
  840. return $this->profile_form($user);
  841. }
  842. /**
  843. * Exceutes a query and log it.
  844. */
  845. function query($query) {
  846. global $wpdb;
  847. $this->log($query, 3);
  848. return $wpdb->query($query);
  849. }
  850. function notify_admin($user, $subject) {
  851. if ($this->options['notify'] != 1)
  852. return;
  853. $message = "Subscriber details:\n\n" .
  854. "email: " . $user->email . "\n" .
  855. "first name: " . $user->name . "\n" .
  856. "last name: " . $user->surname . "\n" .
  857. "gender: " . $user->sex . "\n";
  858. $options_profile = get_option('newsletter_profile');
  859. for ($i = 0; $i < NEWSLETTER_PROFILE_MAX; $i++) {
  860. if ($options_profile['profile_' . $i] == '')
  861. continue;
  862. $field = 'profile_' . $i;
  863. $message .= $options_profile['profile_' . $i] . ': ' . $user->$field . "\n";
  864. }
  865. for ($i = 0; $i < NEWSLETTER_LIST_MAX; $i++) {
  866. if ($options_profile['list_' . $i] == '')
  867. continue;
  868. $field = 'list_' . $i;
  869. $message .= $options_profile['list_' . $i] . ': ' . $user->$field . "\n";
  870. }
  871. $message .= "token: " . $user->token . "\n" .
  872. "status: " . $user->status . "\n" .
  873. "\nYours, Newsletter.";
  874. wp_mail(get_option('admin_email'), '[' . get_option('blogname') . '] ' . $subject, $message, "Content-type: text/plain; charset=UTF-8\n");
  875. }
  876. function get_user_from_request($required = false) {
  877. if (isset($_REQUEST['nk'])) {
  878. list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
  879. } else if (isset($_REQUEST['ni'])) {
  880. $id = (int) $_REQUEST['ni'];
  881. $token = $_REQUEST['nt'];
  882. }
  883. $user = $this->get_user($id);
  884. if ($user == null || $token != $user->token) {
  885. if ($required)
  886. die('No subscriber found.');
  887. else
  888. return null;
  889. }
  890. return $user;
  891. }
  892. function save_email($email) {
  893. return $this->store->save(NEWSLETTER_EMAILS_TABLE, $email);
  894. }
  895. function delete_email($id) {
  896. return $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
  897. }
  898. function get_email_field($id, $field_name) {
  899. return $this->store->get_field(NEWSLETTER_EMAILS_TABLE, $id, $field_name);
  900. }
  901. /**
  902. * Returns a list of users marked as "test user".
  903. * @return array
  904. */
  905. function get_test_users() {
  906. return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
  907. }
  908. function delete_user($id) {
  909. global $wpdb;
  910. $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
  911. if ($r !== false) {
  912. $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
  913. }
  914. }
  915. function set_user_status($id_or_email, $status) {
  916. global $wpdb;
  917. $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
  918. $id_or_email = strtolower(trim($id_or_email));
  919. if (is_numeric($id_or_email)) {
  920. $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
  921. } else {
  922. $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
  923. }
  924. if ($wpdb->last_error) {
  925. $this->logger->error($wpdb->last_error);
  926. return false;
  927. }
  928. return $r;
  929. }
  930. }
  931. $newsletter = Newsletter::instance();
  932. require_once NEWSLETTER_DIR . '/subscription/subscription.php';
  933. require_once NEWSLETTER_DIR . '/emails/emails.php';
  934. require_once NEWSLETTER_DIR . '/users/users.php';
  935. require_once NEWSLETTER_DIR . '/statistics/statistics.php';
  936. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-feed')) {
  937. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/feed/feed.php')) {
  938. require_once WP_CONTENT_DIR . '/extensions/newsletter/feed/feed.php';
  939. } else {
  940. if (get_option('newsletter_feed_demo_disable') != 1) {
  941. if (is_file(NEWSLETTER_DIR . '/feed/feed.php')) {
  942. require_once NEWSLETTER_DIR . '/feed/feed.php';
  943. }
  944. }
  945. }
  946. }
  947. //if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/updates/updates.php')) {
  948. // require_once WP_CONTENT_DIR . '/extensions/newsletter/updates/updates.php';
  949. //}
  950. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-followup')) {
  951. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/followup/followup.php')) {
  952. require_once WP_CONTENT_DIR . '/extensions/newsletter/followup/followup.php';
  953. }
  954. }
  955. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-reports')) {
  956. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/reports/reports.php')) {
  957. require_once WP_CONTENT_DIR . '/extensions/newsletter/reports/reports.php';
  958. }
  959. }
  960. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-mailjet')) {
  961. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/mailjet/mailjet.php')) {
  962. require_once WP_CONTENT_DIR . '/extensions/newsletter/mailjet/mailjet.php';
  963. }
  964. }
  965. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-sendgrid')) {
  966. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/sendgrid/sendgrid.php')) {
  967. require_once WP_CONTENT_DIR . '/extensions/newsletter/sendgrid/sendgrid.php';
  968. }
  969. }
  970. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-facebook')) {
  971. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/facebook/facebook.php')) {
  972. require_once WP_CONTENT_DIR . '/extensions/newsletter/facebook/facebook.php';
  973. }
  974. }
  975. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-popup')) {
  976. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/popup/popup.php')) {
  977. require_once WP_CONTENT_DIR . '/extensions/newsletter/popup/popup.php';
  978. }
  979. }
  980. if (!is_dir(WP_PLUGIN_DIR . '/newsletter-mandrill')) {
  981. if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/mandrill/mandrill.php')) {
  982. require_once WP_CONTENT_DIR . '/extensions/newsletter/mandrill/mandrill.php';
  983. }
  984. }
  985. require_once(dirname(__FILE__) . '…

Large files files are truncated, but you can click here to view the full file