PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://gitlab.com/endomorphosis/reservationtelco
PHP | 1257 lines | 823 code | 253 blank | 181 comment | 219 complexity | 1213523b3e9078495f40ac5739b7dd9c MD5 | raw 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: 1.5.9
  7. Author: Satollo
  8. Author URI: http://www.satollo.net
  9. Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
  10. */
  11. /* Copyright 2008 Satollo (email: info@satollo.net)
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. GNU General Public License for more details.
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. define('NEWSLETTER', '1.5.9');
  25. $newsletter_options_main = get_option('newsletter_main', array());
  26. // Labels loading, after that $newsletter_labels is filled
  27. $newsletter_labels = null;
  28. @include_once(dirname(__FILE__) . '/languages/en_US.php');
  29. if (WPLANG != '') @include_once(dirname(__FILE__) . '/languages/' . WPLANG . '.php');
  30. @include_once(ABSPATH . 'wp-content/plugins/newsletter-custom/languages/en_US.php');
  31. if (WPLANG != '') @include_once(ABSPATH . 'wp-content/plugins/newsletter-custom/languages/' . WPLANG . '.php');
  32. // Don't try to hack that, Newsletter will badly fail
  33. @include(ABSPATH . 'wp-content/plugins/newsletter-extras/newsletter-extras.php');
  34. require_once(dirname(__FILE__) . '/widget.php');
  35. $newsletter_step = 'subscription';
  36. $newsletter_subscriber;
  37. function newsletter_init_labels() {
  38. }
  39. function newsletter_label($name, $default='') {
  40. global $newsletter_labels;
  41. if (isset($newsletter_labels[$name])) return $newsletter_labels[$name];
  42. return $default;
  43. }
  44. function newsletter_echo($name, $default) {
  45. echo newsletter_label($name, $default);
  46. }
  47. function newsletter_request($name, $default=null ) {
  48. if (!isset($_REQUEST[$name])) return $default;
  49. return stripslashes_deep($_REQUEST[$name]);
  50. }
  51. function newsletter_subscribers_count() {
  52. global $wpdb;
  53. return $wpdb->get_var("select count(*) from " . $wpdb->prefix . "newsletter where status='C'");
  54. }
  55. function newsletter_embed_form($form=0) {
  56. $options = get_option('newsletter');
  57. if (newsletter_has_extras('1.0.2') && $form>0) {
  58. echo str_replace('{newsletter_url}', $options['url'], newsletter_extras_get_form($form));
  59. }
  60. else {
  61. echo '<div class="newsletter-embed-form">';
  62. if (isset($options['noname'])) {
  63. echo str_replace('{newsletter_url}', $options['url'], newsletter_label('embedded_form_noname'));
  64. }
  65. else {
  66. echo str_replace('{newsletter_url}', $options['url'], newsletter_label('embedded_form'));
  67. }
  68. echo '</div>';
  69. }
  70. }
  71. if (!is_admin()) {
  72. add_shortcode('newsletter', 'newsletter_call');
  73. add_shortcode('newsletter_form', 'newsletter_form_call');
  74. }
  75. function newsletter_form_call($attrs, $content=null) {
  76. $options = get_option('newsletter');
  77. if (newsletter_has_extras('1.0.2') && isset($attrs['form'])) {
  78. $buffer = str_replace('{newsletter_url}', $options['url'], newsletter_extras_get_form($attrs['form']));
  79. }
  80. else {
  81. $buffer = '<div class="newsletter-embed-form">';
  82. if (!isset($options['noname'])) {
  83. $buffer .= str_replace('{newsletter_url}', $options['url'], newsletter_label('embedded_form'));
  84. }
  85. else {
  86. $buffer .= str_replace('{newsletter_url}', $options['url'], newsletter_label('embedded_form_noname'));
  87. }
  88. $buffer .= '</div>';
  89. }
  90. return $buffer;
  91. }
  92. function newsletter_call($attrs, $content=null) {
  93. global $newsletter_step, $newsletter_subscriber;
  94. $options = get_option('newsletter');
  95. $buffer = '';
  96. // When a user is starting the subscription process
  97. if ($newsletter_step == 'subscription') {
  98. $buffer .= $options['subscription_text'];
  99. if (newsletter_has_extras('1.0.2') && isset($attrs['form'])) {
  100. $buffer .= str_replace('{newsletter_url}', $options['url'], newsletter_extras_get_form($attrs['form']));
  101. }
  102. else {
  103. if (isset($options['noname'])) {
  104. $buffer .= newsletter_label('subscription_form_noname');
  105. }
  106. else {
  107. $buffer .= newsletter_label('subscription_form');
  108. }
  109. //if (!defined('NEWSLETTER_EXTRAS'))
  110. // $buffer .= '<div style="text-align:right;padding:0 10px;margin:0;"><a style="font-size:9px;color:#bbb;text-decoration:none" href="http://www.satollo.net">by satollo.net</a></div>';
  111. }
  112. }
  113. // When a user asked to subscribe and the connfirmation request has been sent
  114. if ($newsletter_step == 'subscribed') {
  115. $text = newsletter_replace($options['subscribed_text'], $newsletter_subscriber);
  116. $buffer .= $text;
  117. }
  118. if ($newsletter_step == 'confirmed') {
  119. $text = newsletter_replace($options['confirmed_text'], $newsletter_subscriber);
  120. $buffer .= $text;
  121. if (isset($options['confirmed_tracking'])) {
  122. ob_start();
  123. eval('?>' . $options['confirmed_tracking']);
  124. $buffer .= ob_get_clean();
  125. }
  126. }
  127. // Here we are when an unsubscription is requested. There are two kind of unsubscription: the
  128. // ones with email and token, so the user has only to confire and the ones without
  129. // data, so the user is requested to insert his email. In the latter case an email
  130. // will be sent to the user with alink to confirm the email removal.
  131. if ($newsletter_step == 'unsubscription' || $newsletter_step == 'unsubscription_error') {
  132. $newsletter_subscriber = newsletter_get_subscriber($_REQUEST['ni']);
  133. $buffer = newsletter_replace($options['unsubscription_text'], $newsletter_subscriber);
  134. $url = newsletter_add_qs($options['url'], 'na=uc&amp;ni=' . $newsletter_subscriber->id .
  135. '&amp;nt=' . $_REQUEST['nt']);
  136. $buffer = newsletter_replace_url($buffer, 'UNSUBSCRIPTION_CONFIRM_URL', $url);
  137. }
  138. // Last message shown to user to say good bye
  139. if ($newsletter_step == 'unsubscribed') {
  140. $text = $options['unsubscribed_text'];
  141. $text = newsletter_replace($text, $newsletter_subscriber);
  142. $buffer .= $text;
  143. }
  144. return '<div class="newsletter">' . $buffer . '</div>';
  145. }
  146. function newsletter_phpmailer_init($phpmailer) {
  147. $options_email = get_option('newsletter_email');
  148. $phpmailer->Sender = $options_email['return_path'];
  149. }
  150. /**
  151. * Sends out newsletters.
  152. *
  153. * I recipients is an array of subscribers, other parameters are ignored and a test
  154. * batch is started. This parameter has priority over all.
  155. *
  156. * If continue is true, the system try to continue a previous batch keeping its
  157. * configuration (eg. if it was a simulation or not).
  158. *
  159. * If continue is false, simulate indicates if the batch is a simulation and forces
  160. * the subscriber's email to a test one, as specified in the configuration.
  161. *
  162. * Return true if the batch is completed.
  163. */
  164. function newsletter_send_batch() {
  165. global $wpdb;
  166. newsletter_info(__FUNCTION__, 'Start');
  167. $options = get_option('newsletter');
  168. $options_email = get_option('newsletter_email');
  169. $batch = get_option('newsletter_batch');
  170. if ($batch == null || !is_array($batch)) {
  171. newsletter_error(__FUNCTION__, 'No batch found');
  172. return;
  173. }
  174. newsletter_debug(__FUNCTION__, "Batch:\n" . print_r($last, true));
  175. // Batch have to contain 'id' which is the starting id, 'simulate' boolean
  176. // to indicate if is a simulation or not, 'scheduled' if it's a scheduled
  177. // sending process. 'list' is the list number, required.
  178. // If 'id' = 0 it's a new seding process.
  179. if (!isset($batch['id'])) {
  180. newsletter_error(__FUNCTION__, 'Batch "id" parameter not present');
  181. return false;
  182. }
  183. if (!isset($batch['list'])) {
  184. newsletter_error(__FUNCTION__, 'Batch "list" parameter not present');
  185. return false;
  186. }
  187. if (!isset($batch['simulate'])) {
  188. newsletter_error(__FUNCTION__, 'Batch "simulate" parameter not present');
  189. return false;
  190. }
  191. if (!isset($batch['scheduled'])) {
  192. newsletter_error(__FUNCTION__, 'Batch "scheduled" parameter not present');
  193. return false;
  194. }
  195. $id = (int)$batch['id'];
  196. $list = (int)$batch['list'];
  197. $simulate = (bool)$batch['simulate'];
  198. $scheduled = (bool)$batch['scheduled']; // Used to avoid echo
  199. if ($scheduled) {
  200. $max = $options_email['scheduler_max'];
  201. if (!is_numeric($max)) $max = 10;
  202. }
  203. else {
  204. $max = $options_email['max'];
  205. if (!is_numeric($max)) $max = 0;
  206. }
  207. $query = "select * from " . $wpdb->prefix . "newsletter where status='C' and list=" . $list .
  208. " and id>" . $id . " order by id";
  209. if ($max > 0) {
  210. $query .= " limit " . $max;
  211. }
  212. $recipients = $wpdb->get_results($query);
  213. // For a new batch save some info
  214. if ($id == 0) {
  215. newsletter_delete_batch_file();
  216. wp_clear_scheduled_hook('newsletter_cron_hook');
  217. $batch['total'] = $wpdb->get_var("select count(*) from " . $wpdb->prefix . "newsletter where status='C' and list=" . $list);
  218. $batch['sent'] = 0;
  219. $batch['completed'] = false;
  220. $batch['message'] = '';
  221. }
  222. // Not all hosting provider allow this...
  223. @set_time_limit(100000);
  224. $start_time = time();
  225. $max_time = (int)(ini_get('max_execution_time') * 0.8);
  226. $db_time = time();
  227. if (!$scheduled) {
  228. echo 'Sending to: <br />';
  229. }
  230. if (isset($options_email['novisual'])) {
  231. $message = $options_email['message'];
  232. }
  233. else {
  234. $message = '<html><head><style type="text/css">' . newsletter_get_theme_css($options_email['theme']) .
  235. '</style></head><body>' . $options_email['message'] . '</body></html>';
  236. }
  237. $idx = 0;
  238. add_action('phpmailer_init','newsletter_phpmailer_init');
  239. if (newsletter_has_extras('1.0.4')) newsletter_init_mail();
  240. foreach ($recipients as $r) {
  241. $url = newsletter_add_qs($options['url'],
  242. 'na=u&amp;ni=' . $r->id . '&amp;nt=' . $r->token);
  243. $m = newsletter_replace_url($message, 'UNSUBSCRIPTION_URL', $url);
  244. $m = newsletter_replace($m, $r);
  245. if (defined('NEWSLETTER_EXTRAS') && isset($options_email['track']))
  246. $m = newsletter_relink($m, $r->id, $options_email['name']);
  247. $s = $options_email['subject'];
  248. $s = newsletter_replace($s, $r);
  249. if ($simulate) {
  250. $x = newsletter_mail($options_email['simulate_email'], $s, $m, true);
  251. }
  252. else {
  253. $x = newsletter_mail($r->email, $s, $m, true);
  254. }
  255. if (!$scheduled) {
  256. echo htmlspecialchars($r->name) . ' (' . $r->email . ') ';
  257. if ($x) {
  258. echo '[OK] - ';
  259. newsletter_debug(__FUNCTION__, 'Sent to ' . $r->id . ' success');
  260. } else {
  261. echo '[KO] - ';
  262. newsletter_debug(__FUNCTION__, 'Sent to ' . $r->id . ' failed');
  263. }
  264. flush();
  265. }
  266. $idx++;
  267. $batch['sent']++;
  268. $batch['id'] = $r->id;
  269. // Try to avoid database timeout
  270. if (time()-$db_time > 15) {
  271. newsletter_debug(__FUNCTION__, 'Batch saving to avoid database timeout');
  272. $db_time = time();
  273. $batch['message'] = 'Temporary saved batch to avoid database timeout';
  274. if (!update_option('newsletter_batch', $batch)) {
  275. newsletter_error(__FUNCTION__, 'Unable to save to database, saving on file system');
  276. newsletter_error(__FUNCTION__, "Batch:\n" . print_r($batch, true));
  277. newsletter_save_batch_file($batch);
  278. remove_action('phpmailer_init','newsletter_phpmailer_init');
  279. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  280. return false;
  281. }
  282. }
  283. // Check for the max emails per batch
  284. if ($max != 0 && $idx >= $max) {
  285. newsletter_info(__FUNCTION__, 'Batch saving due to max emails limit reached');
  286. $batch['message'] = 'Batch max emails limit reached (it is ok)';
  287. if (!update_option('newsletter_batch', $batch)) {
  288. newsletter_error(__FUNCTION__, 'Unable to save to database, saving on file system');
  289. newsletter_error(__FUNCTION__, "Batch:\n" . print_r($batch, true));
  290. newsletter_save_batch_file($batch);
  291. remove_action('phpmailer_init','newsletter_phpmailer_init');
  292. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  293. return false;
  294. }
  295. remove_action('phpmailer_init','newsletter_phpmailer_init');
  296. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  297. return true;
  298. }
  299. // Timeout check, max time is zero if set_time_limit works
  300. if (($max_time != 0 && (time()-$start_time) > $max_time)) {
  301. newsletter_info(__FUNCTION__, 'Batch saving due to max time limit reached');
  302. $batch['message'] = 'Batch max time limit reached (it is ok)';
  303. if (!update_option('newsletter_batch', $batch)) {
  304. newsletter_error(__FUNCTION__, 'Unable to save to database, saving on file system');
  305. newsletter_error(__FUNCTION__, "Batch:\n" . print_r($last, true));
  306. newsletter_save_batch_file($batch);
  307. remove_action('phpmailer_init','newsletter_phpmailer_init');
  308. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  309. return false;
  310. }
  311. remove_action('phpmailer_init','newsletter_phpmailer_init');
  312. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  313. return true;
  314. }
  315. }
  316. // All right (incredible!)
  317. newsletter_info(__FUNCTION__, 'Sending completed!');
  318. $batch['completed'] = true;
  319. $batch['message'] = '';
  320. if (!update_option('newsletter_batch', $batch)) {
  321. newsletter_error(__FUNCTION__, 'Unable to save to database, saving on file system');
  322. newsletter_error(__FUNCTION__, "Batch:\n" . print_r($last, true));
  323. newsletter_save_batch_file($batch);
  324. remove_action('phpmailer_init','newsletter_phpmailer_init');
  325. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  326. return false;
  327. }
  328. remove_action('phpmailer_init','newsletter_phpmailer_init');
  329. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  330. return true;
  331. }
  332. /**
  333. * Send a set of test emails to a list of recipents. The recipients are created
  334. * in the composer page using the test addresses.
  335. */
  336. function newsletter_send_test($recipients) {
  337. global $wpdb;
  338. newsletter_info(__FUNCTION__, 'Start');
  339. $options = get_option('newsletter');
  340. $options_email = get_option('newsletter_email');
  341. @set_time_limit(100000);
  342. echo 'Sending to: <br />';
  343. if (isset($options_email['novisual'])) {
  344. $message = $options_email['message'];
  345. }
  346. else {
  347. $message = '<html><head><style type="text/css">' . newsletter_get_theme_css($options_email['theme']) .
  348. '</style></head><body>' . $options_email['message'] . '</body></html>';
  349. }
  350. if (newsletter_has_extras('1.0.4')) newsletter_init_mail();
  351. foreach ($recipients as $r) {
  352. $url = newsletter_add_qs($options['url'],
  353. 'na=u&amp;ni=' . $r->id . '&amp;nt=' . $r->token);
  354. $m = newsletter_replace_url($message, 'UNSUBSCRIPTION_URL', $url);
  355. $m = newsletter_replace($m, $r);
  356. if (defined('NEWSLETTER_EXTRAS') && isset($options_email['track']))
  357. $m = newsletter_relink($m, $r->id, $options_email['name']);
  358. $s = $options_email['subject'];
  359. $s = newsletter_replace($s, $r);
  360. $x = newsletter_mail($r->email, $s, $m, true);
  361. echo htmlspecialchars($r->name) . ' (' . $r->email . ') ';
  362. flush();
  363. if ($x) {
  364. echo '[OK] -- ';
  365. newsletter_debug(__FUNCTION__, 'Sent to ' . $r->id . ' success');
  366. } else {
  367. echo '[KO] -- ';
  368. newsletter_debug(__FUNCTION__, 'Sent to ' . $r->id . ' failed');
  369. }
  370. }
  371. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  372. }
  373. function newsletter_add_qs($url, $qs, $amp=true) {
  374. if (strpos($url, '?') !== false) {
  375. if ($amp) return $url . '&amp;' . $qs;
  376. else return $url . '&' . $qs;
  377. }
  378. else return $url . '?' . $qs;
  379. }
  380. /**
  381. * Add a request of newsletter subscription into the database with status "S" (waiting
  382. * confirmation) and sends out the confirmation request email to the subscriber.
  383. * The email will contain an URL (or link) the user has to follow to complete the
  384. * subscription (double opt-in).
  385. */
  386. function newsletter_subscribe($email, $name='', $profile=null) {
  387. global $wpdb, $newsletter_subscriber;
  388. $options = get_option('newsletter');
  389. $email = newsletter_normalize_email($email);
  390. $name = newsletter_normalize_name($name);
  391. $list = 0;
  392. if ($profile == null) $profile = array();
  393. // Check if this email is already in our database: if so, just resend the
  394. // confirmation email.
  395. $newsletter_subscriber = newsletter_get_subscriber_by_email($email, $list);
  396. if (!$newsletter_subscriber) {
  397. $token = md5(rand());
  398. if (isset($options['noconfirmation'])) {
  399. $status = 'C';
  400. }
  401. else {
  402. $status = 'S';
  403. }
  404. @$wpdb->insert($wpdb->prefix . 'newsletter', array(
  405. 'email'=>$email,
  406. 'name'=>$name,
  407. 'token'=>$token,
  408. 'list'=>$list,
  409. 'status'=>$status
  410. //'profile'=>serialize($profile)
  411. ));
  412. $id = $wpdb->insert_id;
  413. $newsletter_subscriber = newsletter_get_subscriber($id);
  414. // Profile saving
  415. foreach ($profile as $key=>$value) {
  416. @$wpdb->insert($wpdb->prefix . 'newsletter_profiles', array(
  417. 'newsletter_id'=>$id,
  418. 'name'=>$key,
  419. 'value'=>$value));
  420. }
  421. }
  422. if (isset($options['noconfirmation'])) {
  423. newsletter_send_welcome($newsletter_subscriber);
  424. }
  425. else {
  426. newsletter_send_confirmation($newsletter_subscriber);
  427. }
  428. $message = 'There is a new subscriber to ' . get_option('blogname') . ' newsletter:' . "\n\n" .
  429. $name . ' <' . $email . '>' . "\n\n" .
  430. 'Have a nice day,' . "\n" . 'your Newsletter plugin.';
  431. $subject = '[' . get_option('blogname') . '] New subscription';
  432. newsletter_notify_admin($subject, $message);
  433. }
  434. function newsletter_save($subscriber) {
  435. global $wpdb;
  436. $email = newsletter_normalize_email($email);
  437. $name = newsletter_normalize_name($name);
  438. $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter set email=%s, name=%s where id=%d",
  439. $subscriber['email'], $subscriber['name'], $subscriber['id']));
  440. }
  441. /**
  442. * Resends the confirmation message when asked by user manager panel.
  443. */
  444. function newsletter_send_confirmation($subscriber) {
  445. $options = get_option('newsletter');
  446. newsletter_debug(__FUNCTION__, "Confirmation request to:\n" . print_r($subscriber, true));
  447. $message = $options['confirmation_message'];
  448. $html = newsletter_get_theme_html($options['theme']);
  449. if ($html == null) $html = '{message}';
  450. $message = str_replace('{message}', $message, $html);
  451. // The full URL to the confirmation page
  452. $url = newsletter_add_qs($options['url'], 'na=c&amp;ni=' . $subscriber->id .
  453. '&amp;nt=' . $subscriber->token);
  454. $message = newsletter_replace_url($message, 'SUBSCRIPTION_CONFIRM_URL', $url);
  455. // URL to the unsubscription page (for test purpose)
  456. $url = newsletter_add_qs($options['url'], 'na=u&amp;ni=' . $subscriber->id .
  457. '&amp;nt=' . $subscriber->token);
  458. $message = newsletter_replace_url($message, 'UNSUBSCRIPTION_URL', $url);
  459. $message = newsletter_replace($message, $subscriber);
  460. $subject = newsletter_replace($options['confirmation_subject'], $subscriber);
  461. if (newsletter_has_extras('1.0.4')) newsletter_init_mail();
  462. newsletter_mail($subscriber->email, $subject, $message);
  463. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  464. }
  465. /**
  466. * Return a subscriber by his email. The email will be sanitized and normalized
  467. * before issuing the query to the database.
  468. */
  469. function newsletter_get_subscriber($id) {
  470. global $wpdb;
  471. $recipients = $wpdb->get_results($wpdb->prepare("select * from " . $wpdb->prefix .
  472. "newsletter where id=%d", $id));
  473. if (!$recipients) return null;
  474. return $recipients[0];
  475. }
  476. function newsletter_get_subscriber_by_email($email, $list=0) {
  477. global $wpdb;
  478. $recipients = $wpdb->get_results($wpdb->prepare("select * from " . $wpdb->prefix .
  479. "newsletter where email=%s and list=%d", $email, $list));
  480. if (!$recipients) return null;
  481. return $recipients[0];
  482. }
  483. function newsletter_get_all() {
  484. global $wpdb;
  485. $recipients = $wpdb->get_results("select * from " . $wpdb->prefix . "newsletter order by email");
  486. return $recipients;
  487. }
  488. function newsletter_search($text, $status=null, $order='email') {
  489. global $wpdb;
  490. if ($order == 'id') $order = 'id desc';
  491. $query = "select * from " . $wpdb->prefix . "newsletter where 1=1";
  492. if ($status != null) {
  493. $query .= " and status='" . $wpdb->escape($status) . "'";
  494. }
  495. if ($text == '') {
  496. $recipients = $wpdb->get_results($query . " order by " . $order . ' limit 100');
  497. }
  498. else {
  499. $recipients = $wpdb->get_results($query . " and email like '%" .
  500. $wpdb->escape($text) . "%' or name like '%" . $wpdb->escape($text) . "%' order by " . $order . ' limit 100');
  501. }
  502. if (!$recipients) return null;
  503. return $recipients;
  504. }
  505. function newsletter_get_unconfirmed() {
  506. global $wpdb;
  507. $recipients = $wpdb->get_results("select * from " . $wpdb->prefix . "newsletter where status='S' order by email");
  508. return $recipients;
  509. }
  510. /**
  511. * Normalize an email address,making it lowercase and trimming spaces.
  512. */
  513. function newsletter_normalize_email($email) {
  514. return strtolower(trim($email));
  515. }
  516. function newsletter_normalize_name($name) {
  517. $name = str_replace(';', ' ', $name);
  518. $name = strip_tags($name);
  519. return $name;
  520. }
  521. add_action('init', 'newsletter_init');
  522. /**
  523. * Intercept the request parameters which drive the subscription and unsubscription
  524. * process.
  525. */
  526. function newsletter_init() {
  527. global $newsletter_step, $wpdb, $newsletter_subscriber;
  528. global $hyper_cache_stop;
  529. // "na" always is the action to be performed - stands for "newsletter action"
  530. $action = $_REQUEST['na'];
  531. if (!$action) return;
  532. $hyper_cache_stop = true;
  533. if (defined('NEWSLETTER_EXTRAS')) newsletter_extra_init($action);
  534. $options = get_option('newsletter');
  535. // Subscription request from a subscription form (in page or widget), can be
  536. // a direct subscription with no confirmation
  537. if ($action == 's') {
  538. if (!newsletter_is_email($_REQUEST['ne'])) {
  539. die(newsletter_label('error_email'));
  540. }
  541. // If not set, the subscription form is not requesting the name, so we do not
  542. // raise errors.
  543. if (isset($_REQUEST['nn'])) {
  544. if (trim($_REQUEST['nn']) == '') {
  545. die(newsletter_label('error_name'));
  546. }
  547. }
  548. else {
  549. $_REQUEST['nn'] = '';
  550. }
  551. $profile1 = $_REQUEST['np'];
  552. if (!isset($profile1) || !is_array($profile1)) $profile1 = array();
  553. // keys starting with "_" are removed because used internally
  554. $profile = array();
  555. foreach ($profile1 as $k=>$v) {
  556. if ($k[0] == '_') continue;
  557. $profile[$k] = $v;
  558. }
  559. $profile['_ip'] = $_SERVER['REMOTE_ADDR'];
  560. $profile['_referrer'] = $_SERVER['HTTP_REFERER'];
  561. // Check if the group is good
  562. newsletter_subscribe($_REQUEST['ne'], $_REQUEST['nn'], $profile);
  563. if (isset($options['noconfirmation'])) {
  564. $newsletter_step = 'confirmed';
  565. }
  566. else {
  567. $newsletter_step = 'subscribed';
  568. }
  569. return;
  570. }
  571. // A request to confirm a subscription
  572. if ($action == 'c') {
  573. $id = $_REQUEST['ni'];
  574. newsletter_confirm($id, $_REQUEST['nt']);
  575. header('Location: ' . newsletter_add_qs($options['url'], 'na=cs&ni=' . $id . '&nt=' . $_REQUEST['nt'], false));
  576. die();
  577. }
  578. // Show the confirmed message after a redirection (to avoid mutiple email sending).
  579. // Redirect is sent by action "c".
  580. if ($action == 'cs') {
  581. $newsletter_subscriber = newsletter_get_subscriber($_REQUEST['ni']);
  582. if ($newsletter_subscriber->token != $_REQUEST['nt']) die('Ivalid token');
  583. $newsletter_step = 'confirmed';
  584. }
  585. // Unsubscription process has 2 options: if email and token are specified the user
  586. // will only be asked to confirm. If there is no infos of who remove (when
  587. // mass mail mode is used) the user will be asked to type the emailto be removed.
  588. if ($action == 'u') {
  589. $newsletter_step = 'unsubscription';
  590. }
  591. // User confirmed he want to unsubscribe clicking the link on unsubscription
  592. // page
  593. if ($action == 'uc') {
  594. newsletter_unsubscribe($_REQUEST['ni'], $_REQUEST['nt']);
  595. $newsletter_step = 'unsubscribed';
  596. }
  597. }
  598. /**
  599. * Deletes a subscription (no way back). Fills the global $newsletter_subscriber
  600. * with subscriber data to be used to build up messages.
  601. */
  602. function newsletter_unsubscribe($id, $token) {
  603. global $newsletter_subscriber, $wpdb;
  604. // Save the subscriber for good bye page
  605. $newsletter_subscriber = newsletter_get_subscriber($id);
  606. $wpdb->query($wpdb->prepare("delete from " . $wpdb->prefix . "newsletter where id=%d" .
  607. " and token=%s", $id, $token));
  608. $options = get_option('newsletter');
  609. $html = newsletter_get_theme_html($options['theme']);
  610. if ($html == null) $html = '{message}';
  611. $message = str_replace('{message}', $options['unsubscribed_message'], $html);
  612. $message = newsletter_replace($message, $newsletter_subscriber);
  613. // URL to the unsubscription page (for test purpose)
  614. // $url = newsletter_add_qs($options['url'], 'na=u&amp;ni=' . $newsletter_subscriber->id .
  615. // '&amp;nt=' . $newsletter_subscriber->token);
  616. // $message = newsletter_replace_url($message, 'UNSUBSCRIPTION_URL', $url);
  617. $subject = newsletter_replace($options['unsubscribed_subject'], $newsletter_subscriber);
  618. if (newsletter_has_extras('1.0.4')) newsletter_init_mail();
  619. newsletter_mail($newsletter_subscriber->email, $subject, $message);
  620. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  621. // Admin notification
  622. $message = 'There is an unsubscription to ' . get_option('blogname') . ' newsletter:' . "\n\n" .
  623. $newsletter_subscriber->name . ' <' . $newsletter_subscriber->email . '>' . "\n\n" .
  624. 'Have a nice day,' . "\n" . 'your Newsletter plugin.';
  625. $subject = '[' . get_option('blogname') . '] Unsubscription';
  626. newsletter_notify_admin($subject, $message);
  627. }
  628. /*
  629. * Deletes a specific subscription. Called only from the admin panel.
  630. */
  631. function newsletter_delete($id) {
  632. global $wpdb;
  633. $wpdb->query($wpdb->prepare("delete from " . $wpdb->prefix . "newsletter where id=%d", $id));
  634. }
  635. function newsletter_delete_all($status=null) {
  636. global $wpdb;
  637. if ($status == null) {
  638. $wpdb->query("delete from " . $wpdb->prefix . "newsletter");
  639. }
  640. else {
  641. $wpdb->query("delete from " . $wpdb->prefix . "newsletter where status='" . $wpdb->escape($status) . "'");
  642. }
  643. }
  644. /**
  645. * Confirms a subscription identified by id and token, changing it's status on
  646. * database. Fill the global $newsletter_subscriber with user data.
  647. * If the subscription id already confirmed, the welcome email is still sent to
  648. * the subscriber (the welcome email can contains somthing reserved to the user
  649. * and he may has lost it).
  650. * If id and token do not match, the function does nothing.
  651. */
  652. function newsletter_confirm($id, $token) {
  653. global $wpdb, $newsletter_subscriber;
  654. $options = get_option('newsletter');
  655. $newsletter_subscriber = newsletter_get_subscriber($id);
  656. newsletter_info(__FUNCTION__, "Starting confirmation of subscriber " . $id);
  657. if ($newsletter_subscriber == null) {
  658. newsletter_error(__FUNCTION__, "Subscriber not found");
  659. return;
  660. }
  661. if ($newsletter_subscriber->token != $token) {
  662. newsletter_error(__FUNCTION__, "Token not matching");
  663. return;
  664. }
  665. newsletter_debug(__FUNCTION__, "Confirming subscriber:\n" . print_r($newsletter_subscriber, true));
  666. $count = $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter set status='C' where id=%d", $id));
  667. newsletter_send_welcome($newsletter_subscriber);
  668. }
  669. function newsletter_send_welcome($subscriber) {
  670. $options = get_option('newsletter');
  671. newsletter_debug(__FUNCTION__, "Welcome message to:\n" . print_r($subscriber, true));
  672. $html = newsletter_get_theme_html($options['theme']);
  673. if ($html == null) $html = '{message}';
  674. $message = str_replace('{message}', $options['confirmed_message'], $html);
  675. $message = newsletter_replace($message, $subscriber);
  676. // URL to the unsubscription page (for test purpose)
  677. $url = newsletter_add_qs($options['url'], 'na=u&amp;ni=' . $subscriber->id .
  678. '&amp;nt=' . $subscriber->token);
  679. $message = newsletter_replace_url($message, 'UNSUBSCRIPTION_URL', $url);
  680. $subject = newsletter_replace($options['confirmed_subject'], $subscriber);
  681. if (newsletter_has_extras('1.0.4')) newsletter_init_mail();
  682. newsletter_mail($subscriber->email, $subject, $message);
  683. if (newsletter_has_extras('1.0.4')) newsletter_close_mail();
  684. }
  685. /*
  686. * Changes the status of a subscription identified by its id.
  687. */
  688. function newsletter_set_status($id, $status) {
  689. global $wpdb;
  690. $wpdb->query($wpdb->prepare("update " . $wpdb->prefix . "newsletter set status=%s where id=%d", $status, $id));
  691. }
  692. /*
  693. * Sends a notification message to the blog admin.
  694. */
  695. function newsletter_notify_admin(&$subject, &$message) {
  696. $to = get_option('admin_email');
  697. $headers .= "Content-type: text/plain; charset=UTF-8\n";
  698. wp_mail($to, $subject, $message, $headers);
  699. }
  700. /**
  701. * Sends out an email (html or text). From email and name is retreived from
  702. * Newsletter plugin options. Return false on error. If the subject is empty
  703. * no email is sent out without warning.
  704. * The function uses wp_mail() to really send the message.
  705. */
  706. function newsletter_mail($to, &$subject, &$message, $html=true) {
  707. global $newsletter_mailer, $newsletter_options_main;
  708. if ($subject == '') {
  709. newsletter_debug(__FUNCTION__, 'Subject empty, skipped');
  710. return true;
  711. }
  712. if (newsletter_has_extras('1.0.4')) {
  713. return newsletter_extra_mail($to, &$subject, &$message, $html);
  714. }
  715. $options = get_option('newsletter');
  716. $headers = "MIME-Version: 1.0\n";
  717. if ($html) $headers .= "Content-type: text/html; charset=UTF-8\n";
  718. else $headers .= "Content-type: text/plain; charset=UTF-8\n";
  719. // Special character are manager by wp_mail()
  720. $headers .= 'From: "' . $options['from_name'] . '" <' . $options['from_email'] . ">\n";
  721. $r = wp_mail($to, $subject, $message, $headers);
  722. if (!$r) {
  723. newsletter_error(__FUNCTION__, "wp_mail() failed");
  724. }
  725. return $r;
  726. }
  727. add_action('activate_newsletter/plugin.php', 'newsletter_activate');
  728. function newsletter_activate() {
  729. global $wpdb, $newsletter_options_main;
  730. $options = get_option('newsletter', array());
  731. if (NEWSLETTER >= '1.5.2') {
  732. if (isset($options['logs'])) $newsletter_options_main['logs'] = $options['logs'];
  733. if (isset($options['editor'])) $newsletter_options_main['editor'] = $options['editor'];
  734. if (isset($options['version'])) $newsletter_options_main['version'] = $options['version'];
  735. if (isset($options['no_translation'])) $newsletter_options_main['no_translation'] = $options['no_translation'];
  736. }
  737. // Load the default options
  738. @include_once(dirname(__FILE__) . '/languages/en_US_options.php');
  739. if (WPLANG != '') @include_once(dirname(__FILE__) . '/languages/' . WPLANG . '_options.php');
  740. //@include_once(ABSPATH . 'wp-content/newsletter/languages/custom_options.php');
  741. $options = array_merge($newsletter_default_options, $options);
  742. // SQL to create the table
  743. $sql = 'create table if not exists ' . $wpdb->prefix . 'newsletter (
  744. `id` int not null auto_increment primary key,
  745. `name` varchar (100) not null default \'\',
  746. `email` varchar (100) not null default \'\',
  747. `token` varchar (50) not null default \'\',
  748. `status` varchar (1) not null default \'S\',
  749. `group` int not null default 0,
  750. `profile` text
  751. )';
  752. @$wpdb->query($sql);
  753. if (!isset($newsletter_options_main['version']) || $newsletter_options_main['version'] < '1.4.0') {
  754. $sql = "alter table " . $wpdb->prefix . "newsletter drop primary key";
  755. @$wpdb->query($sql);
  756. $sql = "alter table " . $wpdb->prefix . "newsletter add column id int not null auto_increment primary key";
  757. @$wpdb->query($sql);
  758. $sql = "alter table " . $wpdb->prefix . "newsletter add column list int not null default 0";
  759. @$wpdb->query($sql);
  760. $sql = "alter table " . $wpdb->prefix . "newsletter drop key email_token";
  761. @$wpdb->query($sql);
  762. $sql = "alter table " . $wpdb->prefix . "newsletter add column profile text";
  763. @$wpdb->query($sql);
  764. $sql = "ALTER TABLE " . $wpdb->prefix . "newsletter ADD UNIQUE email_list (email, list)";
  765. @$wpdb->query($sql);
  766. }
  767. if (!isset($newsletter_options_main['version']) || $newsletter_options_main['version'] < '1.4.1') {
  768. $sql = "alter table " . $wpdb->prefix . "newsletter add column created timestamp not null default current_timestamp";
  769. @$wpdb->query($sql);
  770. }
  771. $sql = 'create table if not exists ' . $wpdb->prefix . 'newsletter_profiles (
  772. `newsletter_id` int not null,
  773. `name` varchar (100) not null default \'\',
  774. `value` text,
  775. primary key (newsletter_id, name)
  776. )';
  777. @$wpdb->query($sql);
  778. newsletter_info(__FUNCTION__, 'Activated');
  779. $newsletter_options_main['version'] = NEWSLETTER;
  780. update_option('newsletter_main', $newsletter_options_main);
  781. update_option('newsletter', $options);
  782. if (defined('NEWSLETTER_EXTRAS')) newsletter_extra_activate();
  783. }
  784. if (is_admin()) {
  785. add_action('admin_menu', 'newsletter_admin_menu');
  786. function newsletter_admin_menu() {
  787. global $newsletter_options_main;
  788. $options = get_option('newsletter');
  789. $level = ($newsletter_options_main['editor']==1)?7:10;
  790. if (function_exists('add_menu_page')) {
  791. add_menu_page('Newsletter', 'Newsletter', $level, 'newsletter/main.php', '', '');
  792. }
  793. if (function_exists('add_submenu_page')) {
  794. add_submenu_page('newsletter/main.php', 'Configuration', 'Configuration', $level, 'newsletter/main.php');
  795. add_submenu_page('newsletter/main.php', 'Subscription', 'Subscription', $level, 'newsletter/options.php');
  796. add_submenu_page('newsletter/main.php', 'Composer', 'Composer', $level, 'newsletter/newsletter.php');
  797. add_submenu_page('newsletter/main.php', 'Statistics', 'Statistics', $level, 'newsletter/statistics.php');
  798. add_submenu_page('newsletter/main.php', 'Subscribers', 'Subscribers', $level, 'newsletter/manage.php');
  799. add_submenu_page('newsletter/main.php', 'Import', 'Import', $level, 'newsletter/import.php');
  800. add_submenu_page('newsletter/main.php', 'Export', 'Export', $level, 'newsletter/export.php');
  801. add_submenu_page('newsletter/main.php', 'Forms', 'Forms', $level, 'newsletter/forms.php');
  802. add_submenu_page('newsletter/main.php', 'SMTP', 'SMTP', $level, 'newsletter/smtp.php');
  803. add_submenu_page('newsletter/main.php', 'Update', 'Update', $level, 'newsletter/convert.php');
  804. }
  805. }
  806. add_action('admin_head', 'newsletter_admin_head');
  807. function newsletter_admin_head() {
  808. if (strpos($_GET['page'], 'newsletter/') === 0) {
  809. echo '<link type="text/css" rel="stylesheet" href="' .
  810. get_option('siteurl') . '/wp-content/plugins/newsletter/style.css"/>';
  811. }
  812. }
  813. }
  814. /**
  815. * Fills a text with sunscriber data and blog data replacing some place holders.
  816. */
  817. function newsletter_replace($text, $subscriber) {
  818. $text = str_replace('{home_url}', get_option('home'), $text);
  819. $text = str_replace('{blog_title}', get_option('blogname'), $text);
  820. $text = str_replace('{email}', $subscriber->email, $text);
  821. $text = str_replace('{id}', $subscriber->id, $text);
  822. $text = str_replace('{name}', $subscriber->name, $text);
  823. $text = str_replace('{token}', $subscriber->token, $text);
  824. $text = str_replace('%7Btoken%7D', $subscriber->token, $text);
  825. $text = str_replace('%7Bid%7D', $subscriber->id, $text);
  826. return $text;
  827. }
  828. /**
  829. * Replaces the URL placeholders. There are two kind of URL placeholders: the ones
  830. * lowercase and betweeb curly brakets and the ones all uppercase. The tag to be passed
  831. * is the one all uppercase but the lowercase one will also be replaced.
  832. */
  833. function newsletter_replace_url($text, $tag, $url) {
  834. $home = get_option('home') . '/';
  835. $tag_lower = strtolower($tag);
  836. $text = str_replace($home . '{' . $tag_lower . '}', $url, $text);
  837. $text = str_replace($home . '%7B' . $tag_lower . '%7D', $url, $text);
  838. $text = str_replace('{' . $tag_lower . '}', $url, $text);
  839. // for compatibility
  840. $text = str_replace($home . $tag, $url, $text);
  841. return $text;
  842. }
  843. function newsletter_is_email($email, $empty_ok=false) {
  844. $email = strtolower(trim($email));
  845. if ($empty_ok && $email == '') return true;
  846. if (eregi("^([a-z0-9_\.-])+@(([a-z0-9_-])+\\.)+[a-z]{2,6}$", trim($email))) {
  847. if (strpos($email, 'mailinator.com') !== false) return false;
  848. if (strpos($email, 'guerrillamailblock.com') !== false) return false;
  849. return true;
  850. }
  851. else
  852. return false;
  853. }
  854. function newsletter_delete_batch_file() {
  855. @unlink(dirname(__FILE__) . '/batch.dat');
  856. }
  857. function newsletter_save_batch_file($batch) {
  858. $file = @fopen(dirname(__FILE__) . '/batch.dat', 'w');
  859. if (!$file) return;
  860. @fwrite($file, serialize($batch));
  861. @fclose($file);
  862. }
  863. function newsletter_load_batch_file() {
  864. $content = @file_get_contents(dirname(__FILE__) . '/batch.dat');
  865. return @unserialize($content);
  866. }
  867. /**
  868. * Write a line of log in the log file if the logs are enabled or force is
  869. * set to true.
  870. */
  871. function newsletter_log($text) {
  872. $file = @fopen(dirname(__FILE__) . '/newsletter.log', 'a');
  873. if (!$file) return;
  874. @fwrite($file, date('Y-m-d h:i') . ' ' . $text . "\n");
  875. @fclose($file);
  876. }
  877. function newsletter_debug($fn, $text) {
  878. global $newsletter_options_main;
  879. if ($newsletter_options_main['logs'] < 2) return;
  880. newsletter_log('- DEBUG - ' . $fn . ' - ' . $text);
  881. }
  882. function newsletter_info($fn, $text) {
  883. if ($newsletter_options_main['logs'] < 1) return;
  884. newsletter_log('- INFO - ' . $fn . ' - ' . $text);
  885. }
  886. function newsletter_error($fn, $text) {
  887. if ($newsletter_options_main['logs'] < 1) return;
  888. newsletter_log('- ERROR - ' . $fn . ' - ' . $text);
  889. }
  890. /**
  891. * Retrieves a list of custom themes located under wp-plugins/newsletter-custom/themes.
  892. * Return a list of theme names (which are folder names where the theme files are stored.
  893. */
  894. function newsletter_get_themes() {
  895. $handle = @opendir(ABSPATH . 'wp-content/plugins/newsletter-custom/themes');
  896. $list = array();
  897. if (!$handle) return $list;
  898. while ($file = readdir($handle)) {
  899. if ($file == '.' || $file == '..') continue;
  900. if (!is_dir(ABSPATH . 'wp-content/plugins/newsletter-custom/themes/' . $file)) continue;
  901. if (!is_file(ABSPATH . 'wp-content/plugins/newsletter-custom/themes/' . $file . '/theme.php')) continue;
  902. $list[] = $file;
  903. }
  904. closedir($handle);
  905. return $list;
  906. }
  907. function newsletter_get_extras_themes() {
  908. $handle = @opendir(ABSPATH . 'wp-content/plugins/newsletter-extras/themes');
  909. $list = array();
  910. if (!$handle) return $list;
  911. while ($file = readdir($handle)) {
  912. if ($file == '.' || $file == '..') continue;
  913. if (!is_dir(ABSPATH . 'wp-content/plugins/newsletter-extras/themes/' . $file)) continue;
  914. if (!is_file(ABSPATH . 'wp-content/plugins/newsletter-extras/themes/' . $file . '/theme.php')) continue;
  915. $list[] = $file;
  916. }
  917. closedir($handle);
  918. return $list;
  919. }
  920. /**
  921. * Resets the batch status.
  922. */
  923. function newsletter_reset_batch() {
  924. }
  925. function newsletter_has_extras($version=null) {
  926. if (!defined('NEWSLETTER_EXTRAS')) return false;
  927. if ($version == null) return true;
  928. if ($version <= NEWSLETTER_EXTRAS) return true;
  929. return false;
  930. }
  931. /**
  932. * Find an image for a post checking the media uploaded for the post and
  933. * choosing the first image found.
  934. */
  935. function nt_post_image($post_id, $size='thumbnail', $alternative=null) {
  936. $attachments = get_children(array('post_parent'=>$post_id, 'post_status'=>'inherit', 'post_type'=>'attachment', 'post_mime_type'=>'image', 'order'=>'ASC', 'orderby'=>'menu_order ID' ) );
  937. if (empty($attachments)) {
  938. return $alternative;
  939. }
  940. foreach ($attachments as $id=>$attachment) {
  941. $image = wp_get_attachment_image_src($id, $size);
  942. return $image[0];
  943. }
  944. return null;
  945. }
  946. function nt_option($name, $def = null) {
  947. // if ($newsletter_is_feed && $name == 'posts') {
  948. // $options = get_option('newsletter_feed');
  949. // return $options['posts'];
  950. // }
  951. $options = get_option('newsletter_email');
  952. $option = $options['theme_' . $name];
  953. if (!isset($option)) return $def;
  954. else return $option;
  955. }
  956. /**
  957. * Retrieves the theme dir path.
  958. */
  959. function newsletter_get_theme_dir($theme) {
  960. if ($theme[0] == '*') {
  961. return ABSPATH . '/wp-content/plugins/newsletter-custom/themes/' . substr($theme, 1);
  962. }
  963. elseif ($theme[0] == '$') {
  964. return ABSPATH . '/wp-content/plugins/newsletter-extras/themes/' . substr($theme, 1);
  965. }
  966. else {
  967. return dirname(__FILE__) . '/themes/' . $theme;
  968. }
  969. }
  970. /**
  971. * Retrieves the theme URL (pointing to theme dir).
  972. */
  973. function newsletter_get_theme_url($theme) {
  974. if ($theme[0] == '*') {
  975. return get_option('siteurl') . '/wp-content/plugins/newsletter-custom/themes/' . substr($theme, 1);
  976. }
  977. elseif ($theme[0] == '$') {
  978. return get_option('siteurl') . '/wp-content/plugins/newsletter-extras/themes/' . substr($theme, 1);
  979. }
  980. else {
  981. return get_option('siteurl') . '/wp-content/plugins/newsletter/themes/' . $theme;
  982. }
  983. }
  984. /**
  985. * Loads the theme css content to be embedded in emails body.
  986. */
  987. function newsletter_get_theme_css($theme) {
  988. if ($theme == 'blank') return '';
  989. return @file_get_contents(newsletter_get_theme_dir($theme) . '/style.css');
  990. }
  991. function newsletter_get_theme_html($theme) {
  992. if ($theme == 'blank') return '';
  993. $file = newsletter_get_theme_dir($theme) . '/theme.php';
  994. // Execute the theme file and get the content generated
  995. ob_start();
  996. @include($file);
  997. $html = ob_get_contents();
  998. ob_end_clean();
  999. return $html;
  1000. }
  1001. ?>