s2class

The Subscribe2 s2class class.

Defined (1)

The class is defined in the following location(s).

/classes/class-s2-core.php  
  1. class s2class { 
  2. // variables and constructor are declared at the end 
  3. /** 
  4. Load translations 
  5. */ 
  6. function load_translations() { 
  7. load_plugin_textdomain('subscribe2', false, S2DIR); 
  8. load_plugin_textdomain('subscribe2', false, S2DIR . "languages/"); 
  9. $mofile = WP_LANG_DIR . '/subscribe2-' . apply_filters('plugin_locale', get_locale(), 'subscribe2') . '.mo'; 
  10. load_textdomain('subscribe2', $mofile); 
  11. } // end load_translations() 
  12.  
  13. /** 
  14. Load all our strings 
  15. */ 
  16. function load_strings() { 
  17. // adjust the output of Subscribe2 here 
  18.  
  19. $this->please_log_in = "<p class=\"s2_message\">" . sprintf(__('To manage your subscription options please <a href="%1$s">login.</a>', 'subscribe2'), get_option('siteurl') . '/wp-login.php') . "</p>"; 
  20.  
  21. $this->profile = "<p class=\"s2_message\">" . sprintf(__('You may manage your subscription options from your <a href="%1$s">profile</a>', 'subscribe2'), get_option('siteurl') . "/wp-admin/admin.php?page=s2") . "</p>"; 
  22. if ( $this->s2_mu === true ) { 
  23. global $blog_id; 
  24. $user_ID = get_current_user_id(); 
  25. if ( !is_user_member_of_blog($user_ID, $blog_id) ) { 
  26. // if we are on multisite and the user is not a member of this blog change the link 
  27. $this->profile = "<p class=\"s2_message\">" . sprintf(__('<a href="%1$s">Subscribe</a> to email notifications when this blog posts new content.', 'subscribe2'), get_option('siteurl') . "/wp-admin/?s2mu_subscribe=" . $blog_id) . "</p>"; 
  28.  
  29. $this->confirmation_sent = "<p class=\"s2_message\">" . __('A confirmation message is on its way!', 'subscribe2') . "</p>"; 
  30.  
  31. $this->already_subscribed = "<p class=\"s2_error\">" . __('That email address is already subscribed.', 'subscribe2') . "</p>"; 
  32.  
  33. $this->not_subscribed = "<p class=\"s2_error\">" . __('That email address is not subscribed.', 'subscribe2') . "</p>"; 
  34.  
  35. $this->not_an_email = "<p class=\"s2_error\">" . __('Sorry, but that does not look like an email address to me.', 'subscribe2') . "</p>"; 
  36.  
  37. $this->barred_domain = "<p class=\"s2_error\">" . __('Sorry, email addresses at that domain are currently barred due to spam, please use an alternative email address.', 'subscribe2') . "</p>"; 
  38.  
  39. $this->error = "<p class=\"s2_error\">" . __('Sorry, there seems to be an error on the server. Please try again later.', 'subscribe2') . "</p>"; 
  40.  
  41. $this->no_page = __('You must to create a WordPress page for this plugin to work correctly.', 'subscribe2'); 
  42.  
  43. $this->disallowed_keywords = __('Your chosen email type (per-post or digest) does not support the following keywords:', 'subscribe2'); 
  44.  
  45. $this->mail_sent = "<p class=\"s2_message\">" . __('Message sent!', 'subscribe2') . "</p>"; 
  46.  
  47. $this->mail_failed = "<p class=\"s2_error\">" . __('Message failed!', 'subscribe2') . "</p>"; 
  48.  
  49. // confirmation messages 
  50. $this->no_such_email = "<p class=\"s2_error\">" . __('No such email address is registered.', 'subscribe2') . "</p>"; 
  51.  
  52. $this->added = "<p class=\"s2_message\">" . __('You have successfully subscribed!', 'subscribe2') . "</p>"; 
  53.  
  54. $this->deleted = "<p class=\"s2_message\">" . __('You have successfully unsubscribed.', 'subscribe2') . "</p>"; 
  55.  
  56. $this->subscribe = __('subscribe', 'subscribe2'); //ACTION replacement in subscribing confirmation email 
  57.  
  58. $this->unsubscribe = __('unsubscribe', 'subscribe2'); //ACTION replacement in unsubscribing in confirmation email 
  59.  
  60. // menu strings 
  61. $this->options_saved = __('Options saved!', 'subscribe2'); 
  62. $this->options_reset = __('Options reset!', 'subscribe2'); 
  63. } // end load_strings() 
  64.  
  65. /** ===== Install, upgrade, reset ===== */ 
  66. /** 
  67. Install our table 
  68. */ 
  69. function install() { 
  70. // load our translations and strings 
  71. $this->load_translations(); 
  72.  
  73. // include upgrade-functions for maybe_create_table; 
  74. if ( !function_exists('maybe_create_table') ) { 
  75. require_once(ABSPATH . 'wp-admin/install-helper.php'); 
  76. $date = date('Y-m-d'); 
  77. $sql = "CREATE TABLE $this->public ( 
  78. id int(11) NOT NULL auto_increment,  
  79. email varchar(64) NOT NULL default '',  
  80. active tinyint(1) default 0,  
  81. date DATE default '$date' NOT NULL,  
  82. time TIME DEFAULT '00:00:00' NOT NULL,  
  83. ip char(64) NOT NULL default 'admin',  
  84. conf_date DATE,  
  85. conf_time TIME,  
  86. conf_ip char(64),  
  87. PRIMARY KEY (id) )"; 
  88.  
  89. // create the table, as needed 
  90. maybe_create_table($this->public, $sql); 
  91.  
  92. // create table entries for registered users 
  93. $users = $this->get_all_registered('ID'); 
  94. if ( !empty($users) ) { 
  95. foreach ( $users as $user_ID ) { 
  96. $check_format = get_user_meta($user_ID, $this->get_usermeta_keyname('s2_format'), true); 
  97. if ( empty($check_format) ) { 
  98. // no prior settings so create them 
  99. $this->register($user_ID); 
  100.  
  101. // safety check if options exist and if not create them 
  102. if ( !is_array($this->subscribe2_options) ) { 
  103. $this->reset(); 
  104. } // end install() 
  105.  
  106. /** 
  107. Upgrade function for the database and settings 
  108. */ 
  109. function upgrade() { 
  110. // load our translations and strings 
  111. $this->load_translations(); 
  112.  
  113. require(S2PATH . "classes/class-s2-upgrade.php"); 
  114. global $s2_upgrade; 
  115. $s2_upgrade = new s2class_upgrade; 
  116.  
  117. // ensure that the options are in the database 
  118. require(S2PATH . "include/options.php"); 
  119. // catch older versions that didn't use serialised options 
  120. if ( !isset($this->subscribe2_options['version']) ) { 
  121. $this->subscribe2_options['version'] = '2.0'; 
  122.  
  123. // let's take the time to ensure that database entries exist for all registered users 
  124. $s2_upgrade->upgrade_core(); 
  125. if ( version_compare($this->subscribe2_options['version'], '2.3', '<') ) { 
  126. $s2_upgrade->upgrade23(); 
  127. $this->subscribe2_options['version'] = '2.3'; 
  128. update_option('subscribe2_options', $this->subscribe2_options); 
  129. if ( version_compare($this->subscribe2_options['version'], '5.1', '<') ) { 
  130. $s2_upgrade->upgrade51(); 
  131. $this->subscribe2_options['version'] = '5.1'; 
  132. update_option('subscribe2_options', $this->subscribe2_options); 
  133. if ( version_compare($this->subscribe2_options['version'], '5.6', '<') ) { 
  134. $s2_upgrade->upgrade56(); 
  135. $this->subscribe2_options['version'] = '5.6'; 
  136. update_option('subscribe2_options', $this->subscribe2_options); 
  137. if ( version_compare($this->subscribe2_options['version'], '5.9', '<') ) { 
  138. $s2_upgrade->upgrade59(); 
  139. $this->subscribe2_options['version'] = '5.9'; 
  140. update_option('subscribe2_options', $this->subscribe2_options); 
  141. if ( version_compare($this->subscribe2_options['version'], '6.4', '<') ) { 
  142. $s2_upgrade->upgrade64(); 
  143. $this->subscribe2_options['version'] = '6.4'; 
  144. update_option('subscribe2_options', $this->subscribe2_options); 
  145. if ( version_compare($this->subscribe2_options['version'], '7.0', '<') ) { 
  146. $s2_upgrade->upgrade70(); 
  147. $this->subscribe2_options['version'] = '7.0'; 
  148. update_option('subscribe2_options', $this->subscribe2_options); 
  149. if ( version_compare($this->subscribe2_options['version'], '8.5', '<') ) { 
  150. $s2_upgrade->upgrade85(); 
  151. $this->subscribe2_options['version'] = '8.5'; 
  152. update_option('subscribe2_options', $this->subscribe2_options); 
  153. if ( version_compare($this->subscribe2_options['version'], '8.6', '<') ) { 
  154. $s2_upgrade->upgrade86(); 
  155. $this->subscribe2_options['version'] = '8.6'; 
  156. update_option('subscribe2_options', $this->subscribe2_options); 
  157. if ( version_compare($this->subscribe2_options['version'], '8.8', '<') ) { 
  158. $s2_upgrade->upgrade88(); 
  159. $this->subscribe2_options['version'] = '8.8'; 
  160. update_option('subscribe2_options', $this->subscribe2_options); 
  161.  
  162. $this->subscribe2_options['version'] = S2VERSION; 
  163. update_option('subscribe2_options', $this->subscribe2_options); 
  164.  
  165. return; 
  166. } // end upgrade() 
  167.  
  168. /** 
  169. Reset our options 
  170. */ 
  171. function reset() { 
  172. // load our translations and strings 
  173. $this->load_translations(); 
  174.  
  175. delete_option('subscribe2_options'); 
  176. wp_clear_scheduled_hook('s2_digest_cron'); 
  177. unset($this->subscribe2_options); 
  178. require(S2PATH . "include/options.php"); 
  179. $this->subscribe2_options['version'] = S2VERSION; 
  180. update_option('subscribe2_options', $this->subscribe2_options); 
  181. } // end reset() 
  182.  
  183. /** ===== mail handling ===== */ 
  184. /** 
  185. Performs string substitutions for subscribe2 mail tags 
  186. */ 
  187. function substitute($string = '') { 
  188. if ( '' == $string ) { 
  189. return; 
  190. $string = str_replace("{BLOGNAME}", html_entity_decode(get_option('blogname'), ENT_QUOTES), $string); 
  191. $string = str_replace("{BLOGLINK}", get_option('home'), $string); 
  192. $string = str_replace("{TITLE}", stripslashes($this->post_title), $string); 
  193. $link = "<a href=\"" . $this->get_tracking_link($this->permalink) . "\">" . $this->get_tracking_link($this->permalink) . "</a>"; 
  194. $string = str_replace("{PERMALINK}", $link, $string); 
  195. if ( strstr($string, "{TINYLINK}") ) { 
  196. $tinylink = file_get_contents('http://tinyurl.com/api-create.php?url=' . urlencode($this->get_tracking_link($this->permalink))); 
  197. if ( $tinylink !== 'Error' && $tinylink != false ) { 
  198. $tlink = "<a href=\"" . $tinylink . "\">" . $tinylink . "</a>"; 
  199. $string = str_replace("{TINYLINK}", $tlink, $string); 
  200. } else { 
  201. $string = str_replace("{TINYLINK}", $link, $string); 
  202. $string = str_replace("{DATE}", $this->post_date, $string); 
  203. $string = str_replace("{TIME}", $this->post_time, $string); 
  204. $string = str_replace("{MYNAME}", stripslashes($this->myname), $string); 
  205. $string = str_replace("{EMAIL}", $this->myemail, $string); 
  206. $string = str_replace("{AUTHORNAME}", stripslashes($this->authorname), $string); 
  207. $string = str_replace("{CATS}", $this->post_cat_names, $string); 
  208. $string = str_replace("{TAGS}", $this->post_tag_names, $string); 
  209. $string = str_replace("{COUNT}", $this->post_count, $string); 
  210.  
  211. return $string; 
  212. } // end substitute() 
  213.  
  214. /** 
  215. Delivers email to recipients in HTML or plaintext 
  216. */ 
  217. function mail($recipients = array(), $subject = '', $message = '', $type = 'text', $attachments = array()) { 
  218. if ( empty($recipients) || '' == $message ) { return; } 
  219.  
  220. // Replace any escaped html symbols in subject then apply filter 
  221. $subject = strip_tags(html_entity_decode($subject, ENT_QUOTES)); 
  222. $subject = apply_filters('s2_email_subject', $subject); 
  223.  
  224. if ( 'html' == $type ) { 
  225. $headers = $this->headers('html', $attachments); 
  226. if ( 'yes' == $this->subscribe2_options['stylesheet'] ) { 
  227. $mailtext = apply_filters('s2_html_email', "<html><head><title>" . $subject . "</title><link rel=\"stylesheet\" href=\"" . get_stylesheet_uri() . "\" type=\"text/css\" media=\"screen\" /></head><body>" . $message . "</body></html>", $subject, $message); 
  228. } else { 
  229. $mailtext = apply_filters('s2_html_email', "<html><head><title>" . $subject . "</title></head><body>" . $message . "</body></html>", $subject, $message); 
  230. } else { 
  231. $headers = $this->headers('text', $attachments); 
  232. $message = preg_replace('|&[^a][^m][^p].{0, 3};|', '', $message); 
  233. $message = preg_replace('|&|', '&', $message); 
  234. $message = wordwrap(strip_tags($message), $this->word_wrap, "\n"); 
  235. $mailtext = apply_filters('s2_plain_email', $message); 
  236.  
  237. // Construct BCC headers for sending or send individual emails 
  238. $bcc = ''; 
  239. natcasesort($recipients); 
  240. if ( function_exists('wpmq_mail') || $this->subscribe2_options['bcclimit'] == 1 || count($recipients) == 1 ) { 
  241. // BCCLimit is 1 so send individual emails or we only have 1 recipient 
  242. foreach ( $recipients as $recipient ) { 
  243. $recipient = trim($recipient); 
  244. // sanity check -- make sure we have a valid email 
  245. if ( !is_email($recipient) || empty($recipient) ) { continue; } 
  246. // Use the mail queue provided we are not sending a preview 
  247. if ( function_exists('wpmq_mail') && !$this->preview_email ) { 
  248. @wp_mail($recipient, $subject, $mailtext, $headers, $attachments, 0); 
  249. } else { 
  250. @wp_mail($recipient, $subject, $mailtext, $headers, $attachments); 
  251. return true; 
  252. } elseif ( $this->subscribe2_options['bcclimit'] == 0 ) { 
  253. // we're not using BCCLimit 
  254. foreach ( $recipients as $recipient ) { 
  255. $recipient = trim($recipient); 
  256. // sanity check -- make sure we have a valid email 
  257. if ( !is_email($recipient) ) { continue; } 
  258. // and NOT the sender's email, since they'll get a copy anyway 
  259. if ( !empty($recipient) && $this->myemail != $recipient ) { 
  260. ('' == $bcc) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient"; 
  261. // Bcc Headers now constructed by phpmailer class 
  262. $headers .= "$bcc\n"; 
  263. } else { 
  264. // we're using BCCLimit 
  265. $count = 1; 
  266. $batch = array(); 
  267. foreach ( $recipients as $recipient ) { 
  268. $recipient = trim($recipient); 
  269. // sanity check -- make sure we have a valid email 
  270. if ( !is_email($recipient) ) { continue; } 
  271. // and NOT the sender's email, since they'll get a copy anyway 
  272. if ( !empty($recipient) && $this->myemail != $recipient ) { 
  273. ('' == $bcc) ? $bcc = "Bcc: $recipient" : $bcc .= ", $recipient"; 
  274. // Bcc Headers now constructed by phpmailer class 
  275. if ( $this->subscribe2_options['bcclimit'] == $count ) { 
  276. $count = 0; 
  277. $batch[] = $bcc; 
  278. $bcc = ''; 
  279. $count++; 
  280. // add any partially completed batches to our batch array 
  281. if ( '' != $bcc ) { 
  282. $batch[] = $bcc; 
  283. // rewind the array, just to be safe 
  284. reset($recipients); 
  285.  
  286. // actually send mail 
  287. if ( isset($batch) && !empty($batch) ) { 
  288. foreach ( $batch as $bcc ) { 
  289. $newheaders = $headers . "$bcc\n"; 
  290. $status = @wp_mail($this->myemail, $subject, $mailtext, $newheaders, $attachments); 
  291. } else { 
  292. $status = @wp_mail($this->myemail, $subject, $mailtext, $headers, $attachments); 
  293. return $status; 
  294. } // end mail() 
  295.  
  296. /** 
  297. Construct standard set of email headers 
  298. */ 
  299. function headers($type = 'text', $attachments = array()) { 
  300. if ( empty($this->myname) || empty($this->myemail) ) { 
  301. if ( $this->subscribe2_options['sender'] == 'blogname' ) { 
  302. $this->myname = html_entity_decode(get_option('blogname'), ENT_QUOTES); 
  303. $this->myemail = get_option('admin_email'); 
  304. } else { 
  305. $admin = $this->get_userdata($this->subscribe2_options['sender']); 
  306. $this->myname = html_entity_decode($admin->display_name, ENT_QUOTES); 
  307. $this->myemail = $admin->user_email; 
  308. // fail safe to ensure sender details are not empty 
  309. if ( empty($this->myname) ) { 
  310. $this->myname = html_entity_decode(get_option('blogname'), ENT_QUOTES); 
  311. if ( empty($this->myemail) ) { 
  312. // Get the site domain and get rid of www. 
  313. $sitename = strtolower( $_SERVER['SERVER_NAME'] ); 
  314. if ( substr( $sitename, 0, 4 ) == 'www.' ) { 
  315. $sitename = substr( $sitename, 4 ); 
  316. $this->myemail = 'wordpress@' . $sitename; 
  317.  
  318. if ( function_exists('mb_encode_mimeheader') ) { 
  319. $header['From'] = mb_encode_mimeheader($this->myname, 'UTF-8', 'Q') . " <" . $this->myemail . ">"; 
  320. $header['Reply-To'] = mb_encode_mimeheader($this->myname, 'UTF-8', 'Q') . " <" . $this->myemail . ">"; 
  321. } else { 
  322. $header['From'] = $this->myname. " <" . $this->myemail . ">"; 
  323. $header['Reply-To'] = $this->myname . " <" . $this->myemail . ">"; 
  324. $header['Return-path'] = "<" . $this->myemail . ">"; 
  325. $header['Precedence'] = "list\nList-Id: " . html_entity_decode(get_option('blogname'), ENT_QUOTES) . ""; 
  326. if ( empty($attachments) && $type == 'html' ) { 
  327. // To send HTML mail, the Content-Type header must be set 
  328. $header['Content-Type'] = get_option('html_type') . "; charset=\"". get_option('blog_charset') . "\""; 
  329. } elseif ( empty($attachments) && $type == 'text' ) { 
  330. $header['Content-Type'] = "text/plain; charset=\"". get_option('blog_charset') . "\""; 
  331.  
  332. // apply header filter to allow on-the-fly amendments 
  333. $header = apply_filters('s2_email_headers', $header); 
  334. // collapse the headers using $key as the header name 
  335. foreach ( $header as $key => $value ) { 
  336. $headers[$key] = $key . ": " . $value; 
  337. $headers = implode("\n", $headers); 
  338. $headers .= "\n"; 
  339.  
  340. return $headers; 
  341. } // end headers() 
  342.  
  343. /** 
  344. Function to add UTM tracking details to links 
  345. */ 
  346. function get_tracking_link($link) { 
  347. if ( empty($link) ) { return; } 
  348. if ( !empty($this->subscribe2_options['tracking']) ) { 
  349. (strpos($link, '?') > 0) ? $delimiter .= '&' : $delimiter = '?'; 
  350. $tracking = $this->subscribe2_options['tracking']; 
  351. if ( strpos($tracking, "{ID}") ) { 
  352. $id = url_to_postid($link); 
  353. $tracking = str_replace("{ID}", $id, $tracking); 
  354. if ( strpos($tracking, "{TITLE}") ) { 
  355. $id = url_to_postid($link); 
  356. $title = urlencode(htmlentities(get_the_title($id), 1)); 
  357. $tracking = str_replace("{TITLE}", $title, $tracking); 
  358. return $link . $delimiter . $tracking; 
  359. } else { 
  360. return $link; 
  361. } // end get_tracking_link() 
  362.  
  363. /** 
  364. Sends an email notification of a new post 
  365. */ 
  366. function publish($post, $preview = '') { 
  367. if ( !$post ) { return $post; } 
  368.  
  369. if ( $this->s2_mu && !apply_filters('s2_allow_site_switching', $this->site_switching) ) { 
  370. global $switched; 
  371. if ( $switched ) { return; } 
  372.  
  373. if ( $preview == '' ) { 
  374. // we aren't sending a Preview to the current user so carry out checks 
  375. $s2mail = get_post_meta($post->ID, '_s2mail', true); 
  376. if ( (isset($_POST['s2_meta_field']) && $_POST['s2_meta_field'] == 'no') || strtolower(trim($s2mail)) == 'no' ) { return $post; } 
  377.  
  378. // are we doing daily digests? If so, don't send anything now 
  379. if ( $this->subscribe2_options['email_freq'] != 'never' ) { return $post; } 
  380.  
  381. // is the current post of a type that should generate a notification email? 
  382. // uses s2_post_types filter to allow for custom post types in WP 3.0 
  383. if ( $this->subscribe2_options['pages'] == 'yes' ) { 
  384. $s2_post_types = array('page', 'post'); 
  385. } else { 
  386. $s2_post_types = array('post'); 
  387. $s2_post_types = apply_filters('s2_post_types', $s2_post_types); 
  388. if ( !in_array($post->post_type, $s2_post_types) ) { 
  389. return $post; 
  390.  
  391. // Are we sending notifications for password protected posts? 
  392. if ( $this->subscribe2_options['password'] == "no" && $post->post_password != '' ) { 
  393. return $post; 
  394.  
  395. // Is the post assigned to a format for which we should not be sending posts 
  396. $post_format = get_post_format($post->ID); 
  397. $excluded_formats = explode(', ', $this->subscribe2_options['exclude_formats']); 
  398. if ( $post_format !== false && in_array($post_format, $excluded_formats) ) { 
  399. return $post; 
  400.  
  401. $s2_taxonomies = apply_filters('s2_taxonomies', array('category')); 
  402. $post_cats = wp_get_object_terms($post->ID, $s2_taxonomies, array('fields' => 'ids')); 
  403. $check = false; 
  404. // is the current post assigned to any categories 
  405. // which should not generate a notification email? 
  406. foreach ( explode(', ', $this->subscribe2_options['exclude']) as $cat ) { 
  407. if ( in_array($cat, $post_cats) ) { 
  408. $check = true; 
  409.  
  410. if ( $check ) { 
  411. // hang on -- can registered users subscribe to 
  412. // excluded categories? 
  413. if ( '0' == $this->subscribe2_options['reg_override'] ) { 
  414. // nope? okay, let's leave 
  415. return $post; 
  416.  
  417. // Are we sending notifications for Private posts? 
  418. // Action is added if we are, but double check option and post status 
  419. if ( $this->subscribe2_options['private'] == "yes" && $post->post_status == 'private' ) { 
  420. // don't send notification to public users 
  421. $check = true; 
  422.  
  423. // lets collect our subscribers 
  424. $public = array(); 
  425. if ( !$check ) { 
  426. // if this post is assigned to an excluded 
  427. // category, or is a private post then 
  428. // don't send public subscribers a notification 
  429. $public = $this->get_public(); 
  430. if ( $post->post_type == 'page' ) { 
  431. $post_cats_string = implode(', ', get_all_category_ids()); 
  432. } else { 
  433. $post_cats_string = implode(', ', $post_cats); 
  434. $registered = $this->get_registered("cats=$post_cats_string"); 
  435.  
  436. // do we have subscribers? 
  437. if ( empty($public) && empty($registered) ) { 
  438. // if not, no sense doing anything else 
  439. return $post; 
  440. } else { 
  441. // make sure we prime the taxonomy variable for preview posts 
  442. $s2_taxonomies = apply_filters('s2_taxonomies', array('category')); 
  443.  
  444. // we set these class variables so that we can avoid 
  445. // passing them in function calls a little later 
  446. $this->post_title = "<a href=\"" . get_permalink($post->ID) . "\">" . html_entity_decode($post->post_title, ENT_QUOTES) . "</a>"; 
  447. $this->permalink = get_permalink($post->ID); 
  448. $this->post_date = get_the_time(get_option('date_format'), $post); 
  449. $this->post_time = get_the_time('', $post); 
  450.  
  451. $author = get_userdata($post->post_author); 
  452. $this->authorname = html_entity_decode(apply_filters('the_author', $author->display_name), ENT_QUOTES); 
  453.  
  454. // do we send as admin, or post author? 
  455. if ( 'author' == $this->subscribe2_options['sender'] ) { 
  456. // get author details 
  457. $user = &$author; 
  458. $this->myemail = $user->user_email; 
  459. $this->myname = html_entity_decode($user->display_name, ENT_QUOTES); 
  460. } elseif ( 'blogname' == $this->subscribe2_options['sender'] ) { 
  461. $this->myemail = get_option('admin_email'); 
  462. $this->myname = html_entity_decode(get_option('blogname'), ENT_QUOTES); 
  463. } else { 
  464. // get admin details 
  465. $user = $this->get_userdata($this->subscribe2_options['sender']); 
  466. $this->myemail = $user->user_email; 
  467. $this->myname = html_entity_decode($user->display_name, ENT_QUOTES); 
  468.  
  469. $this->post_cat_names = implode(', ', wp_get_object_terms($post->ID, $s2_taxonomies, array('fields' => 'names'))); 
  470. $this->post_tag_names = implode(', ', wp_get_post_tags($post->ID, array('fields' => 'names'))); 
  471.  
  472. // Get email subject 
  473. $subject = html_entity_decode(stripslashes(wp_kses($this->substitute($this->subscribe2_options['notification_subject']), ''))); 
  474. // Get the message template 
  475. $mailtext = apply_filters('s2_email_template', $this->subscribe2_options['mailtext']); 
  476. $mailtext = stripslashes($this->substitute($mailtext)); 
  477.  
  478. $plaintext = $post->post_content; 
  479. if ( function_exists('strip_shortcodes') ) { 
  480. $plaintext = strip_shortcodes($plaintext); 
  481. $plaintext = preg_replace('|<s[^>]*>(.*)<\/s>|Ui', '', $plaintext); 
  482. $plaintext = preg_replace('|<strike[^>]*>(.*)<\/strike>|Ui', '', $plaintext); 
  483. $plaintext = preg_replace('|<del[^>]*>(.*)<\/del>|Ui', '', $plaintext); 
  484. $plaintext = trim(strip_tags($plaintext)); 
  485.  
  486. $gallid = '[gallery id="' . $post->ID . '"'; 
  487. $content = str_replace('[gallery', $gallid, $post->post_content); 
  488.  
  489. // remove the autoembed filter to remove iframes from notification emails 
  490. if ( get_option('embed_autourls') ) { 
  491. global $wp_embed; 
  492. $priority = has_filter('the_content', array(&$wp_embed, 'autoembed')); 
  493. if ( $priority !== false ) { 
  494. remove_filter('the_content', array(&$wp_embed, 'autoembed'), $priority); 
  495.  
  496. $content = apply_filters('the_content', $content); 
  497. $content = str_replace("]]>", "]]>", $content); 
  498.  
  499. $excerpt = $post->post_excerpt; 
  500. if ( '' == $excerpt ) { 
  501. // no excerpt, is there a <!--more--> ? 
  502. if ( false !== strpos($plaintext, '<!--more-->') ) { 
  503. list($excerpt, $more) = explode('<!--more-->', $plaintext, 2); 
  504. // strip leading and trailing whitespace 
  505. $excerpt = strip_tags($excerpt); 
  506. $excerpt = trim($excerpt); 
  507. } else { 
  508. // no <!--more-->, so grab the first 55 words 
  509. $excerpt = strip_tags($plaintext); 
  510. $words = explode(' ', $excerpt, $this->excerpt_length + 1); 
  511. if (count($words) > $this->excerpt_length) { 
  512. array_pop($words); 
  513. array_push($words, '[...]'); 
  514. $excerpt = implode(' ', $words); 
  515. $html_excerpt = $post->post_excerpt; 
  516. if ( '' == $html_excerpt ) { 
  517. // no excerpt, is there a <!--more--> ? 
  518. if ( false !== strpos($content, '<!--more-->') ) { 
  519. list($html_excerpt, $more) = explode('<!--more-->', $content, 2); 
  520. // balance HTML tags and then strip leading and trailing whitespace 
  521. $html_excerpt = trim(balanceTags($html_excerpt, true)); 
  522. } else { 
  523. // no <!--more-->, so grab the first 55 words 
  524. $words = explode(' ', $content, $this->excerpt_length + 1); 
  525. if (count($words) > $this->excerpt_length) { 
  526. array_pop($words); 
  527. array_push($words, '[...]'); 
  528. $html_excerpt = implode(' ', $words); 
  529. // balance HTML tags and then strip leading and trailing whitespace 
  530. $html_excerpt = trim(balanceTags($html_excerpt, true)); 
  531. } else { 
  532. $html_excerpt = $content; 
  533.  
  534. // remove excess white space from with $excerpt and $plaintext 
  535. $excerpt = preg_replace('|[ ]+|', ' ', $excerpt); 
  536. $plaintext = preg_replace('|[ ]+|', ' ', $plaintext); 
  537.  
  538. // prepare mail body texts 
  539. $plain_excerpt_body = str_replace("{POST}", $excerpt, $mailtext); 
  540. $plain_body = str_replace("{POST}", $plaintext, $mailtext); 
  541. $html_body = str_replace("\r\n", "<br />\r\n", $mailtext); 
  542. $html_body = str_replace("{POST}", $content, $html_body); 
  543. $html_excerpt_body = str_replace("\r\n", "<br />\r\n", $mailtext); 
  544. $html_excerpt_body = str_replace("{POST}", $html_excerpt, $html_excerpt_body); 
  545.  
  546. if ( $preview != '' ) { 
  547. $this->myemail = $preview; 
  548. $this->myname = __('Plain Text Excerpt Preview', 'subscribe2'); 
  549. $this->mail(array($preview), $subject, $plain_excerpt_body); 
  550. $this->myname = __('Plain Text Full Preview', 'subscribe2'); 
  551. $this->mail(array($preview), $subject, $plain_body); 
  552. $this->myname = __('HTML Excerpt Preview', 'subscribe2'); 
  553. $this->mail(array($preview), $subject, $html_excerpt_body, 'html'); 
  554. $this->myname = __('HTML Full Preview', 'subscribe2'); 
  555. $this->mail(array($preview), $subject, $html_body, 'html'); 
  556. } else { 
  557. // Registered Subscribers first 
  558. // first we send plaintext summary emails 
  559. $recipients = $this->get_registered("cats=$post_cats_string&format=excerpt&author=$post->post_author"); 
  560. $recipients = apply_filters('s2_send_plain_excerpt_suscribers', $recipients, $post->ID); 
  561. $this->mail($recipients, $subject, $plain_excerpt_body); 
  562.  
  563. // next we send plaintext full content emails 
  564. $recipients = $this->get_registered("cats=$post_cats_string&format=post&author=$post->post_author"); 
  565. $recipients = apply_filters('s2_send_plain_fullcontent_suscribers', $recipients, $post->ID); 
  566. $this->mail($recipients, $subject, $plain_body); 
  567.  
  568. // next we send html excerpt content emails 
  569. $recipients = $this->get_registered("cats=$post_cats_string&format=html_excerpt&author=$post->post_author"); 
  570. $recipients = apply_filters('s2_send_html_excerpt_suscribers', $recipients, $post->ID); 
  571. $this->mail($recipients, $subject, $html_excerpt_body, 'html'); 
  572.  
  573. // next we send html full content emails 
  574. $recipients = $this->get_registered("cats=$post_cats_string&format=html&author=$post->post_author"); 
  575. $recipients = apply_filters('s2_send_html_fullcontent_suscribers', $recipients, $post->ID); 
  576. $this->mail($recipients, $subject, $html_body, 'html'); 
  577.  
  578. // and finally we send to Public Subscribers 
  579. $recipients = apply_filters('s2_send_public_suscribers', $public, $post->ID); 
  580. $this->mail($recipients, $subject, $plain_excerpt_body, 'text'); 
  581. } // end publish() 
  582.  
  583. /** 
  584. Send confirmation email to a public subscriber 
  585. */ 
  586. function send_confirm($what = '', $is_remind = false) { 
  587. if ( $this->filtered == 1 ) { return true; } 
  588. if ( !$this->email || !$what ) { return false; } 
  589. $id = $this->get_id($this->email); 
  590. if ( !$id ) { 
  591. return false; 
  592.  
  593. // generate the URL "?s2=ACTION+HASH+ID" 
  594. // ACTION = 1 to subscribe, 0 to unsubscribe 
  595. // HASH = wp_hash of email address 
  596. // ID = user's ID in the subscribe2 table 
  597. // use home instead of siteurl incase index.php is not in core wordpress directory 
  598. $link = get_option('home') . "/?s2="; 
  599.  
  600. if ( 'add' == $what ) { 
  601. $link .= '1'; 
  602. } elseif ( 'del' == $what ) { 
  603. $link .= '0'; 
  604. $link .= wp_hash($this->email); 
  605. $link .= $id; 
  606.  
  607. // sort the headers now so we have all substitute information 
  608. $mailheaders = $this->headers(); 
  609.  
  610. if ( $is_remind == true ) { 
  611. $body = $this->substitute(stripslashes($this->subscribe2_options['remind_email'])); 
  612. $subject = $this->substitute(stripslashes($this->subscribe2_options['remind_subject'])); 
  613. } else { 
  614. $body = $this->substitute(stripslashes($this->subscribe2_options['confirm_email'])); 
  615. if ( 'add' == $what ) { 
  616. $body = str_replace("{ACTION}", $this->subscribe, $body); 
  617. $subject = str_replace("{ACTION}", $this->subscribe, $this->subscribe2_options['confirm_subject']); 
  618. } elseif ( 'del' == $what ) { 
  619. $body = str_replace("{ACTION}", $this->unsubscribe, $body); 
  620. $subject = str_replace("{ACTION}", $this->unsubscribe, $this->subscribe2_options['confirm_subject']); 
  621. $subject = html_entity_decode($this->substitute(stripslashes($subject)), ENT_QUOTES); 
  622.  
  623. $body = str_replace("{LINK}", $link, $body); 
  624.  
  625. if ( $is_remind == true && function_exists('wpmq_mail') ) { 
  626. // could be sending lots of reminders so queue them if wpmq is enabled 
  627. @wp_mail($this->email, $subject, $body, $mailheaders, '', 0); 
  628. } else { 
  629. return @wp_mail($this->email, $subject, $body, $mailheaders); 
  630. } // end send_confirm() 
  631.  
  632. /** ===== Public Subscriber functions ===== */ 
  633. /** 
  634. Return an array of all the public subscribers 
  635. */ 
  636. function get_public($confirmed = 1) { 
  637. global $wpdb; 
  638. if ( 1 == $confirmed ) { 
  639. if ( '' == $this->all_confirmed ) { 
  640. $this->all_confirmed = $wpdb->get_col("SELECT email FROM $this->public WHERE active='1'"); 
  641. return $this->all_confirmed; 
  642. } else { 
  643. if ( '' == $this->all_unconfirmed ) { 
  644. $this->all_unconfirmed = $wpdb->get_col("SELECT email FROM $this->public WHERE active='0'"); 
  645. return $this->all_unconfirmed; 
  646. } // end get_public() 
  647.  
  648. /** 
  649. Given a public subscriber ID, returns the email address 
  650. */ 
  651. function get_email($id = 0) { 
  652. global $wpdb; 
  653.  
  654. if ( !$id ) { 
  655. return false; 
  656. return $wpdb->get_var($wpdb->prepare("SELECT email FROM $this->public WHERE id=%d", $id)); 
  657. } // end get_email() 
  658.  
  659. /** 
  660. Given a public subscriber email, returns the subscriber ID 
  661. */ 
  662. function get_id($email = '') { 
  663. global $wpdb; 
  664.  
  665. if ( !$email ) { 
  666. return false; 
  667. return $wpdb->get_var($wpdb->prepare("SELECT id FROM $this->public WHERE email=%s", $email)); 
  668. } // end get_id() 
  669.  
  670. /** 
  671. Add an public subscriber to the subscriber table 
  672. If added by admin it is immediately confirmed, otherwise as unconfirmed 
  673. */ 
  674. function add($email = '', $confirm = false) { 
  675. if ( $this->filtered == 1 ) { return; } 
  676. global $wpdb; 
  677.  
  678. if ( !is_email($email) ) { return false; } 
  679.  
  680. if ( false !== $this->is_public($email) ) { 
  681. // is this an email for a registered user 
  682. $check = $wpdb->get_var($wpdb->prepare("SELECT user_email FROM $wpdb->users WHERE user_email=%s", $this->email)); 
  683. if ( $check ) { return; } 
  684. if ( $confirm ) { 
  685. $wpdb->query($wpdb->prepare("UPDATE $this->public SET active='1', ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email)); 
  686. } else { 
  687. $wpdb->query($wpdb->prepare("UPDATE $this->public SET date=CURDATE(), time=CURTIME() WHERE CAST(email as binary)=%s", $email)); 
  688. } else { 
  689. if ( $confirm ) { 
  690. global $current_user; 
  691. $wpdb->query($wpdb->prepare("INSERT INTO $this->public (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 1, $current_user->user_login)); 
  692. } else { 
  693. $wpdb->query($wpdb->prepare("INSERT INTO $this->public (email, active, date, time, ip) VALUES (%s, %d, CURDATE(), CURTIME(), %s)", $email, 0, $this->ip)); 
  694. } // end add() 
  695.  
  696. /** 
  697. Remove a public subscriber user from the subscription table 
  698. */ 
  699. function delete($email = '') { 
  700. global $wpdb; 
  701.  
  702. if ( !is_email($email) ) { return false; } 
  703. $wpdb->query($wpdb->prepare("DELETE FROM $this->public WHERE CAST(email as binary)=%s", $email)); 
  704. } // end delete() 
  705.  
  706. /** 
  707. Toggle a public subscriber's status 
  708. */ 
  709. function toggle($email = '') { 
  710. global $wpdb; 
  711.  
  712. if ( '' == $email || !is_email($email) ) { return false; } 
  713.  
  714. // let's see if this is a public user 
  715. $status = $this->is_public($email); 
  716. if ( false === $status ) { return false; } 
  717.  
  718. if ( '0' == $status ) { 
  719. $wpdb->query($wpdb->prepare("UPDATE $this->public SET active='1', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email)); 
  720. } else { 
  721. $wpdb->query($wpdb->prepare("UPDATE $this->public SET active='0', conf_date=CURDATE(), conf_time=CURTIME(), conf_ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email)); 
  722. } // end toggle() 
  723.  
  724. /** 
  725. Send reminder email to unconfirmed public subscribers 
  726. */ 
  727. function remind($emails = '') { 
  728. if ( '' == $emails ) { return false; } 
  729.  
  730. $recipients = explode(", ", $emails); 
  731. if ( !is_array($recipients) ) { $recipients = (array)$recipients; } 
  732. foreach ( $recipients as $recipient ) { 
  733. $this->email = $recipient; 
  734. $this->send_confirm('add', true); 
  735. } //end remind() 
  736.  
  737. /** 
  738. Is the supplied email address a public subscriber? 
  739. */ 
  740. function is_public($email = '') { 
  741. global $wpdb; 
  742.  
  743. if ( '' == $email ) { return false; } 
  744.  
  745. // run the query and force case sensitivity 
  746. $check = $wpdb->get_var($wpdb->prepare("SELECT active FROM $this->public WHERE CAST(email as binary)=%s", $email)); 
  747. if ( '0' == $check || '1' == $check ) { 
  748. return $check; 
  749. } else { 
  750. return false; 
  751. } // end is_public() 
  752.  
  753. /** ===== Registered User and Subscriber functions ===== */ 
  754. /** 
  755. Is the supplied email address a registered user of the blog? 
  756. */ 
  757. function is_registered($email = '') { 
  758. global $wpdb; 
  759.  
  760. if ( '' == $email ) { return false; } 
  761.  
  762. $check = $wpdb->get_var($wpdb->prepare("SELECT user_email FROM $wpdb->users WHERE user_email=%s", $email)); 
  763. if ( $check ) { 
  764. return true; 
  765. } else { 
  766. return false; 
  767. } // end is_registered() 
  768.  
  769. /** 
  770. Return Registered User ID from email 
  771. */ 
  772. function get_user_id($email = '') { 
  773. global $wpdb; 
  774.  
  775. if ( '' == $email ) { return false; } 
  776.  
  777. $id = $wpdb->get_var($wpdb->prepare("SELECT id FROM $wpdb->users WHERE user_email=%s", $email)); 
  778.  
  779. return $id; 
  780. } // end get_user_id() 
  781.  
  782. /** 
  783. Return an array of all subscribers emails or IDs 
  784. */ 
  785. function get_all_registered($return = 'email') { 
  786. global $wpdb; 
  787.  
  788. if ( $this->s2_mu ) { 
  789. if ( $return === 'ID' ) { 
  790. if ( $this->all_registered_id === '' ) { 
  791. $this->all_registered_id = $wpdb->get_col("SELECT user_id FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities'"); 
  792. return $this->all_registered_id; 
  793. } else { 
  794. if ( $this->all_registered_email === '' ) { 
  795. $this->all_registered_email = $wpdb->get_col("SELECT a.user_email FROM $wpdb->users AS a INNER JOIN $wpdb->usermeta AS b ON a.ID = b.user_id WHERE b.meta_key='" . $wpdb->prefix . "capabilities'"); 
  796. return $this->all_registered_email; 
  797. } else { 
  798. if ( $return === 'ID' ) { 
  799. if ( $this->all_registered_id === '' ) { 
  800. $this->all_registered_id = $wpdb->get_col("SELECT ID FROM $wpdb->users"); 
  801. return $this->all_registered_id; 
  802. } else { 
  803. if ( $this->all_registered_email === '' ) { 
  804. $this->all_registered_email = $wpdb->get_col("SELECT user_email FROM $wpdb->users"); 
  805. return $this->all_registered_email; 
  806. } // end get_all_registered() 
  807.  
  808. /** 
  809. Return an array of registered subscribers 
  810. Collect all the registered users of the blog who are subscribed to the specified categories 
  811. */ 
  812. function get_registered($args = '') { 
  813. global $wpdb; 
  814.  
  815. parse_str($args, $r); 
  816. if ( !isset($r['format']) ) 
  817. $r['format'] = 'all'; 
  818. if ( !isset($r['cats']) ) 
  819. $r['cats'] = ''; 
  820. if ( !isset($r['author']) ) 
  821. $r['author'] = ''; 
  822.  
  823. // collect all subscribers for compulsory categories 
  824. $compulsory = explode(', ', $this->subscribe2_options['compulsory']); 
  825. foreach ( explode(', ', $r['cats']) as $cat ) { 
  826. if ( in_array($cat, $compulsory) ) { 
  827. $r['cats'] = ''; 
  828.  
  829. $JOIN = ''; $AND = ''; 
  830. // text or HTML subscribers 
  831. if ( 'all' != $r['format'] ) { 
  832. $JOIN .= "INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id "; 
  833. $AND .= $wpdb->prepare(" AND b.meta_key=%s AND b.meta_value=", $this->get_usermeta_keyname('s2_format')); 
  834. if ( 'html' == $r['format'] ) { 
  835. $AND .= "'html'"; 
  836. } elseif ( 'html_excerpt' == $r['format'] ) { 
  837. $AND .= "'html_excerpt'"; 
  838. } elseif ( 'post' == $r['format'] ) { 
  839. $AND .= "'post'"; 
  840. } elseif ( 'excerpt' == $r['format'] ) { 
  841. $AND .= "'excerpt'"; 
  842.  
  843. // specific category subscribers 
  844. if ( '' != $r['cats'] ) { 
  845. $JOIN .= "INNER JOIN $wpdb->usermeta AS c ON a.user_id = c.user_id "; 
  846. $and = ''; 
  847. foreach ( explode(', ', $r['cats']) as $cat ) { 
  848. ('' == $and) ? $and = $wpdb->prepare("c.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat) : $and .= $wpdb->prepare(" OR c.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat); 
  849. $AND .= " AND ($and)"; 
  850.  
  851. // specific authors 
  852. if ( '' != $r['author'] ) { 
  853. $JOIN .= "INNER JOIN $wpdb->usermeta AS d ON a.user_id = d.user_id "; 
  854. $AND .= $wpdb->prepare(" AND (d.meta_key=%s AND NOT FIND_IN_SET(%s, d.meta_value))", $this->get_usermeta_keyname('s2_authors'), $r['author']); 
  855.  
  856. if ( $this->s2_mu ) { 
  857. $sql = $wpdb->prepare("SELECT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS e ON a.user_id = e.user_id " . $JOIN . "WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND e.meta_key=%s AND e.meta_value <> ''" . $AND, $this->get_usermeta_keyname('s2_subscribed')); 
  858. } else { 
  859. $sql = $wpdb->prepare("SELECT a.user_id FROM $wpdb->usermeta AS a " . $JOIN . "WHERE a.meta_key=%s AND a.meta_value <> ''" . $AND, $this->get_usermeta_keyname('s2_subscribed')); 
  860. $result = $wpdb->get_col($sql); 
  861. if ( $result ) { 
  862. $ids = implode(', ', array_map(array($this, 'prepare_in_data'), $result)); 
  863. $registered = $wpdb->get_col("SELECT user_email FROM $wpdb->users WHERE ID IN ($ids)"); 
  864.  
  865. if ( empty($registered) ) { return array(); } 
  866.  
  867. // apply filter to registered users to add or remove additional addresses, pass args too for additional control 
  868. $registered = apply_filters('s2_registered_subscribers', $registered, $args); 
  869. return $registered; 
  870. } // end get_registered() 
  871.  
  872. /** 
  873. Function to ensure email is compliant with internet messaging standards 
  874. */ 
  875. function sanitize_email($email) { 
  876. $email = trim($email); 
  877. if ( !is_email($email) ) { return; } 
  878.  
  879. // ensure that domain is in lowercase as per internet email standards http://www.ietf.org/rfc/rfc5321.txt 
  880. list($name, $domain) = explode('@', $email, 2); 
  881. return $name . "@" . strtolower($domain); 
  882. } // end sanitize_email() 
  883.  
  884. /** 
  885. Create the appropriate usermeta values when a user registers 
  886. If the registering user had previously subscribed to notifications, this function will delete them from the public subscriber list first 
  887. */ 
  888. function register($user_ID = 0, $consent = false) { 
  889. global $wpdb; 
  890.  
  891. if ( 0 == $user_ID ) { return $user_ID; } 
  892. $user = get_userdata($user_ID); 
  893.  
  894. // Subscribe registered users to categories obeying excluded categories 
  895. if ( 0 == $this->subscribe2_options['reg_override'] || 'no' == $this->subscribe2_options['newreg_override'] ) { 
  896. $all_cats = $this->all_cats(true, 'ID'); 
  897. } else { 
  898. $all_cats = $this->all_cats(false, 'ID'); 
  899.  
  900. $cats = ''; 
  901. foreach ( $all_cats as $cat ) { 
  902. ('' == $cats) ? $cats = "$cat->term_id" : $cats .= ", $cat->term_id"; 
  903.  
  904. if ( '' == $cats ) { 
  905. // sanity check, might occur if all cats excluded and reg_override = 0 
  906. return $user_ID; 
  907.  
  908. // has this user previously signed up for email notification? 
  909. if ( false !== $this->is_public($this->sanitize_email($user->user_email)) ) { 
  910. // delete this user from the public table, and subscribe them to all the categories 
  911. $this->delete($user->user_email); 
  912. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed'), $cats); 
  913. foreach ( explode(', ', $cats) as $cat ) { 
  914. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_cat') . $cat, $cat); 
  915. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_format'), 'excerpt'); 
  916. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_autosub'), $this->subscribe2_options['autosub_def']); 
  917. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_authors'), ''); 
  918. } else { 
  919. // create post format entries for all users 
  920. if ( in_array($this->subscribe2_options['autoformat'], array('html', 'html_excerpt', 'post', 'excerpt')) ) { 
  921. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_format'), $this->subscribe2_options['autoformat']); 
  922. } else { 
  923. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_format'), 'excerpt'); 
  924. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_autosub'), $this->subscribe2_options['autosub_def']); 
  925. // if the are no existing subscriptions, create them if we have consent 
  926. if ( true === $consent ) { 
  927. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed'), $cats); 
  928. foreach ( explode(', ', $cats) as $cat ) { 
  929. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_cat') . $cat, $cat); 
  930. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_authors'), ''); 
  931. return $user_ID; 
  932. } // end register() 
  933.  
  934. /** 
  935. Get admin data from record 1 or first user with admin rights 
  936. */ 
  937. function get_userdata($admin_id) { 
  938. global $wpdb, $userdata; 
  939.  
  940. if ( is_numeric($admin_id) ) { 
  941. $admin = get_userdata($admin_id); 
  942. } elseif ( $admin_id == 'admin' ) { 
  943. //ensure compatibility with < 4.16 
  944. $admin = get_userdata('1'); 
  945. } else { 
  946. $admin = &$userdata; 
  947.  
  948. if ( empty($admin) || $admin->ID == 0 ) { 
  949. $role = array('role' => 'administrator'); 
  950. $wp_user_query = get_users( $role ); 
  951. $admin = $wp_user_query[0]; 
  952.  
  953. return $admin; 
  954. } //end get_userdata() 
  955.  
  956. /** 
  957. Subscribe/unsubscribe user from one-click submission 
  958. */ 
  959. function one_click_handler($user_ID, $action) { 
  960. if ( !isset($user_ID) || !isset($action) ) { return; } 
  961.  
  962. $all_cats = $this->all_cats(true); 
  963.  
  964. if ( 'subscribe' == $action ) { 
  965. // Subscribe 
  966. $new_cats = array(); 
  967. foreach ( $all_cats as $cat ) { 
  968. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_cat') . $cat->term_id, $cat->term_id); 
  969. $new_cats[] = $cat->term_id; 
  970.  
  971. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed'), implode(', ', $new_cats)); 
  972.  
  973. if ( 'yes' == $this->subscribe2_options['show_autosub'] && 'no' != get_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed'), true) ) { 
  974. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_autosub'), 'yes'); 
  975. } elseif ( 'unsubscribe' == $action ) { 
  976. // Unsubscribe 
  977. foreach ( $all_cats as $cat ) { 
  978. delete_user_meta($user_ID, $this->get_usermeta_keyname('s2_cat') . $cat->term_id); 
  979.  
  980. delete_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed')); 
  981. update_user_meta($user_ID, $this->get_usermeta_keyname('s2_autosub'), 'no'); 
  982. } //end one_click_handler() 
  983.  
  984. /** ===== helper functions: forms and stuff ===== */ 
  985. /** 
  986. Get an object of all categories, include default and custom type 
  987. */ 
  988. function all_cats($exclude = false, $orderby = 'slug') { 
  989. $all_cats = array(); 
  990. $s2_taxonomies = apply_filters('s2_taxonomies', array('category')); 
  991.  
  992. foreach( $s2_taxonomies as $taxonomy ) { 
  993. if ( taxonomy_exists($taxonomy) ) { 
  994. $all_cats = array_merge($all_cats, get_categories(array('hide_empty' => false, 'orderby' => $orderby, 'taxonomy' => $taxonomy))); 
  995.  
  996. if ( $exclude === true ) { 
  997. // remove excluded categories from the returned object 
  998. $excluded = explode(', ', $this->subscribe2_options['exclude']); 
  999.  
  1000. // need to use $id like this as this is a mixed array / object 
  1001. $id = 0; 
  1002. foreach ( $all_cats as $cat) { 
  1003. if ( in_array($cat->term_id, $excluded) ) { 
  1004. unset($all_cats[$id]); 
  1005. $id++; 
  1006.  
  1007. return $all_cats; 
  1008. } // end all_cats() 
  1009.  
  1010. /** 
  1011. Function to sanitise array of data for SQL 
  1012. */ 
  1013. function prepare_in_data($data) { 
  1014. global $wpdb; 
  1015. return $wpdb->prepare('%s', $data); 
  1016. } // end prepare_in_data() 
  1017.  
  1018. /** 
  1019. Export subscriber emails and other details to CSV 
  1020. */ 
  1021. function prepare_export( $subscribers ) { 
  1022. $subscribers = explode(", \r\n", $subscribers); 
  1023. natcasesort($subscribers); 
  1024.  
  1025. $exportcsv = "User Email, User Type, User Name"; 
  1026. $all_cats = $this->all_cats(false, 'ID'); 
  1027.  
  1028. foreach ($all_cats as $cat) { 
  1029. $exportcsv .= ", " . $cat->cat_name; 
  1030. $cat_ids[] = $cat->term_id; 
  1031. $exportcsv .= "\r\n"; 
  1032.  
  1033. if ( !function_exists('get_userdata') ) { 
  1034. require_once(ABSPATH . WPINC . '/pluggable.php'); 
  1035.  
  1036. foreach ( $subscribers as $subscriber ) { 
  1037. if ( $this->is_registered($subscriber) ) { 
  1038. $user_ID = $this->get_user_id( $subscriber ); 
  1039. $user_info = get_userdata( $user_ID ); 
  1040.  
  1041. $cats = explode(', ', get_user_meta($user_ID, $this->get_usermeta_keyname('s2_subscribed'), true)); 
  1042. $subscribed_cats = ''; 
  1043. foreach ( $cat_ids as $cat ) { 
  1044. (in_array($cat, $cats)) ? $subscribed_cats .= ", Yes" : $subscribed_cats .= ", No"; 
  1045.  
  1046. $exportcsv .= $subscriber . ', '; 
  1047. $exportcsv .= __('Registered User', 'subscribe2'); 
  1048. $exportcsv .= ', ' . $user_info->display_name; 
  1049. $exportcsv .= $subscribed_cats . "\r\n"; 
  1050. } else { 
  1051. if ( $this->is_public($subscriber) === '1' ) { 
  1052. $exportcsv .= $subscriber . ', ' . __('Confirmed Public Subscriber', 'subscribe2') . "\r\n"; 
  1053. } elseif ( $this->is_public($subscriber) === '0' ) { 
  1054. $exportcsv .= $subscriber . ', ' . __('Unconfirmed Public Subscriber', 'subscribe2') . "\r\n"; 
  1055.  
  1056. return $exportcsv; 
  1057. } // end prepare_export() 
  1058.  
  1059. /** 
  1060. Filter for usermeta table key names to adjust them if needed for WPMU blogs 
  1061. */ 
  1062. function get_usermeta_keyname($metaname) { 
  1063. global $wpdb; 
  1064.  
  1065. // Is this WordPressMU or not? 
  1066. if ( $this->s2_mu === true ) { 
  1067. switch( $metaname ) { 
  1068. case 's2_subscribed': 
  1069. case 's2_cat': 
  1070. case 's2_format': 
  1071. case 's2_autosub': 
  1072. case 's2_authors': 
  1073. return $wpdb->prefix . $metaname; 
  1074. break; 
  1075. // Not MU or not a prefixed option name 
  1076. return $metaname; 
  1077. } // end get_usermeta_keyname() 
  1078.  
  1079. /** 
  1080. Adds information to the WordPress registration screen for new users 
  1081. */ 
  1082. function register_form() { 
  1083. if ( 'no' == $this->subscribe2_options['autosub'] ) { return; } 
  1084. if ( 'wpreg' == $this->subscribe2_options['autosub'] ) { 
  1085. echo "<p>\r\n<label>"; 
  1086. echo __('Check here to Subscribe to email notifications for new posts', 'subscribe2') . ":<br />\r\n"; 
  1087. echo "<input type=\"checkbox\" name=\"reg_subscribe\"" . checked($this->subscribe2_options['wpregdef'], 'yes', false) . " />"; 
  1088. echo "</label>\r\n"; 
  1089. echo "</p>\r\n"; 
  1090. } elseif ( 'yes' == $this->subscribe2_options['autosub'] ) { 
  1091. echo "<p>\r\n<center>\r\n"; 
  1092. echo __('By registering with this blog you are also agreeing to receive email notifications for new posts but you can unsubscribe at anytime', 'subscribe2') . ".<br />\r\n"; 
  1093. echo "</center></p>\r\n"; 
  1094. } // end register_form() 
  1095.  
  1096. /** 
  1097. Process function to add action if user selects to subscribe to posts during registration 
  1098. */ 
  1099. function register_post($user_ID = 0) { 
  1100. global $_POST; 
  1101. if ( 0 == $user_ID ) { return; } 
  1102. if ( 'yes' == $this->subscribe2_options['autosub'] || ( 'on' == $_POST['reg_subscribe'] && 'wpreg' == $this->subscribe2_options['autosub'] ) ) { 
  1103. $this->register($user_ID, true); 
  1104. } else { 
  1105. $this->register($user_ID, false); 
  1106. } // end register_post() 
  1107.  
  1108. /** ===== comment subscriber functions ===== */ 
  1109. /** 
  1110. Display check box on comment page 
  1111. */ 
  1112. function s2_comment_meta_form() { 
  1113. if ( is_user_logged_in() ) { 
  1114. echo $this->profile; 
  1115. } else { 
  1116. echo "<p style=\"width: auto;\"><label><input type=\"checkbox\" name=\"s2_comment_request\" value=\"1\" " . checked($this->subscribe2_options['comment_def'], 'yes', false) . "/>" . __('Check here to Subscribe to notifications for new posts', 'subscribe2') . "</label></p>"; 
  1117. } // end s2_comment_meta_form() 
  1118.  
  1119. /** 
  1120. Process comment meta data 
  1121. */ 
  1122. function s2_comment_meta($comment_ID, $approved = 0) { 
  1123. if ( $_POST['s2_comment_request'] == '1' ) { 
  1124. switch ($approved) { 
  1125. case '0': 
  1126. // Unapproved so hold in meta data pending moderation 
  1127. add_comment_meta($comment_ID, 's2_comment_request', $_POST['s2_comment_request']); 
  1128. break; 
  1129. case '1': 
  1130. // Approved so add 
  1131. $is_public = $this->is_public($comment->comment_author_email); 
  1132. if ( $is_public == 0 ) { 
  1133. $this->toggle($comment->comment_author_email); 
  1134. $is_registered = $this->is_registered($comment->comment_author_email); 
  1135. if ( !$is_public && !$is_registered ) { 
  1136. $this->add($comment->comment_author_email, true); 
  1137. break; 
  1138. default : 
  1139. break; 
  1140. } // end s2_comment_meta() 
  1141.  
  1142. /** 
  1143. Action subscribe requests made on comment forms when comments are approved 
  1144. */ 
  1145. function comment_status($comment_ID = 0) { 
  1146. global $wpdb; 
  1147.  
  1148. // get meta data 
  1149. $subscribe = get_comment_meta($comment_ID, 's2_comment_request', true); 
  1150. if ( $subscribe != '1' ) { return $comment_ID; } 
  1151.  
  1152. // Retrieve the information about the comment 
  1153. $sql = $wpdb->prepare("SELECT comment_author_email, comment_approved FROM $wpdb->comments WHERE comment_ID=%s LIMIT 1", $comment_ID); 
  1154. $comment = $wpdb->get_row($sql, OBJECT); 
  1155. if ( empty($comment) ) { return $comment_ID; } 
  1156.  
  1157. switch ($comment->comment_approved) { 
  1158. case '0': // Unapproved 
  1159. break; 
  1160. case '1': // Approved 
  1161. $is_public = $this->is_public($comment->comment_author_email); 
  1162. if ( $is_public == 0 ) { 
  1163. $this->toggle($comment->comment_author_email); 
  1164. $is_registered = $this->is_registered($comment->comment_author_email); 
  1165. if ( !$is_public && !$is_registered ) { 
  1166. $this->add($comment->comment_author_email, true); 
  1167. delete_comment_meta($comment_ID, 's2_comment_request'); 
  1168. break; 
  1169. default: // post is trash, spam or deleted 
  1170. delete_comment_meta($comment_ID, 's2_comment_request'); 
  1171. break; 
  1172.  
  1173. return $comment_ID; 
  1174. } // end comment_status() 
  1175.  
  1176. /** ===== widget functions ===== */ 
  1177. /** 
  1178. Register the form widget 
  1179. */ 
  1180. function subscribe2_widget() { 
  1181. require_once( S2PATH . 'include/widget.php'); 
  1182. register_widget('S2_Form_widget'); 
  1183. } // end subscribe2_widget() 
  1184.  
  1185. /** 
  1186. Register the counter widget 
  1187. */ 
  1188. function counter_widget() { 
  1189. require_once( S2PATH . 'include/counterwidget.php'); 
  1190. register_widget('S2_Counter_widget'); 
  1191. } // end counter_widget() 
  1192.  
  1193. /** ===== wp-cron functions ===== */ 
  1194. /** 
  1195. Add a weekly event to cron 
  1196. */ 
  1197. function add_weekly_sched($sched) { 
  1198. $sched['weekly'] = array('interval' => 604800, 'display' => __('Weekly', 'subscribe2')); 
  1199. return $sched; 
  1200. } // end add_weekly_sched() 
  1201.  
  1202. /** 
  1203. Send a digest of recent new posts 
  1204. */ 
  1205. function subscribe2_cron($preview = '', $resend = '') { 
  1206. if ( defined('DOING_S2_CRON') && DOING_S2_CRON ) { return; } 
  1207. define( 'DOING_S2_CRON', true ); 
  1208. global $wpdb, $post; 
  1209.  
  1210. if ( '' == $preview ) { 
  1211. // update last_s2cron execution time before completing or bailing 
  1212. $now = current_time('mysql'); 
  1213. $prev = $this->subscribe2_options['last_s2cron']; 
  1214. $last = $this->subscribe2_options['previous_s2cron']; 
  1215. $this->subscribe2_options['last_s2cron'] = $now; 
  1216. $this->subscribe2_options['previous_s2cron'] = $prev; 
  1217. if ( '' == $resend ) { 
  1218. // update sending times provided this is not a resend 
  1219. update_option('subscribe2_options', $this->subscribe2_options); 
  1220.  
  1221. // set up SQL query based on options 
  1222. if ( $this->subscribe2_options['private'] == 'yes' ) { 
  1223. $status = "'publish', 'private'"; 
  1224. } else { 
  1225. $status = "'publish'"; 
  1226.  
  1227. // send notifications for allowed post type (defaults for posts and pages) 
  1228. // uses s2_post_types filter to allow for custom post types in WP 3.0 
  1229. if ( $this->subscribe2_options['pages'] == 'yes' ) { 
  1230. $s2_post_types = array('page', 'post'); 
  1231. } else { 
  1232. $s2_post_types = array('post'); 
  1233. $s2_post_types = apply_filters('s2_post_types', $s2_post_types); 
  1234. foreach( $s2_post_types as $post_type ) { 
  1235. ('' == $type) ? $type = $wpdb->prepare("%s", $post_type) : $type .= $wpdb->prepare(", %s", $post_type); 
  1236.  
  1237. // collect posts 
  1238. if ( $resend == 'resend' ) { 
  1239. if ( $this->subscribe2_options['cron_order'] == 'desc' ) { 
  1240. $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC", $last, $prev)); 
  1241. } else { 
  1242. $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC", $last, $prev)); 
  1243. } else { 
  1244. if ( $this->subscribe2_options['cron_order'] == 'desc' ) { 
  1245. $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC", $prev, $now)); 
  1246. } else { 
  1247. $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC", $prev, $now)); 
  1248. } else { 
  1249. // we are sending a preview 
  1250. $posts = get_posts('numberposts=1'); 
  1251.  
  1252. // Collect sticky posts if desired 
  1253. if ( $this->subscribe2_options['stickies'] == 'yes' ) { 
  1254. $stickies = get_posts(array('post__in' => get_option('sticky_posts'))); 
  1255. if ( !empty($stickies) ) { 
  1256. $posts = array_merge((array)$stickies, (array)$posts); 
  1257.  
  1258. // do we have any posts? 
  1259. if ( empty($posts) && !has_filter('s2_digest_email') ) { return false; } 
  1260. $this->post_count = count($posts); 
  1261.  
  1262. // if we have posts, let's prepare the digest 
  1263. $datetime = get_option('date_format') . ' @ ' . get_option('time_format'); 
  1264. $all_post_cats = array(); 
  1265. $ids = array(); 
  1266. $mailtext = apply_filters('s2_email_template', $this->subscribe2_options['mailtext']); 
  1267. $table = ''; 
  1268. $tablelinks = ''; 
  1269. $message_post= ''; 
  1270. $message_posttime = ''; 
  1271. foreach ( $posts as $post ) { 
  1272. // keep an array of post ids and skip if we've already done it once 
  1273. if ( in_array($post->ID, $ids) ) { continue; } 
  1274. $ids[] = $post->ID; 
  1275. $s2_taxonomies = apply_filters('s2_taxonomies', array('category')); 
  1276. $post_cats = wp_get_object_terms($post->ID, $s2_taxonomies, array('fields' => 'ids')); 
  1277. $post_cats_string = implode(', ', $post_cats); 
  1278. $all_post_cats = array_unique(array_merge($all_post_cats, $post_cats)); 
  1279. $check = false; 
  1280. // Pages are put into category 1 so make sure we don't exclude 
  1281. // pages if category 1 is excluded 
  1282. if ( $post->post_type != 'page' ) { 
  1283. // is the current post assigned to any categories 
  1284. // which should not generate a notification email? 
  1285. foreach ( explode(', ', $this->subscribe2_options['exclude']) as $cat ) { 
  1286. if ( in_array($cat, $post_cats) ) { 
  1287. $check = true; 
  1288. // is the current post set by the user to 
  1289. // not generate a notification email? 
  1290. $s2mail = get_post_meta($post->ID, '_s2mail', true); 
  1291. if ( strtolower(trim($s2mail)) == 'no' ) { 
  1292. $check = true; 
  1293. // is the current post private 
  1294. // and should this not generate a notification email? 
  1295. if ( $this->subscribe2_options['password'] == 'no' && $post->post_password != '' ) { 
  1296. $check = true; 
  1297. // is the post assigned a format that should 
  1298. // not be included in the notification email? 
  1299. $post_format = get_post_format($post->ID); 
  1300. $excluded_formats = explode(', ', $this->subscribe2_options['exclude_formats']); 
  1301. if ( $post_format !== false && in_array($post_format, $excluded_formats) ) { 
  1302. $check = true; 
  1303. // if this post is excluded 
  1304. // don't include it in the digest 
  1305. if ( $check ) { 
  1306. continue; 
  1307. $post_title = html_entity_decode($post->post_title, ENT_QUOTES); 
  1308. ('' == $table) ? $table .= "* " . $post_title : $table .= "\r\n* " . $post_title; 
  1309. ('' == $tablelinks) ? $tablelinks .= "* " . $post_title : $tablelinks .= "\r\n* " . $post_title; 
  1310. $message_post .= $post_title; 
  1311. $message_posttime .= $post_title; 
  1312. if ( strstr($mailtext, "{AUTHORNAME}") ) { 
  1313. $author = get_userdata($post->post_author); 
  1314. if ( $author->display_name != '' ) { 
  1315. $message_post .= " (" . __('Author', 'subscribe2') . ": " . html_entity_decode(apply_filters('the_author', $author->display_name), ENT_QUOTES) . ")"; 
  1316. $message_posttime .= " (" . __('Author', 'subscribe2') . ": " . html_entity_decode(apply_filters('the_author', $author->display_name), ENT_QUOTES) . ")"; 
  1317. $message_post .= "\r\n"; 
  1318. $message_posttime .= "\r\n"; 
  1319.  
  1320. $message_posttime .= __('Posted on', 'subscribe2') . ": " . mysql2date($datetime, $post->post_date) . "\r\n"; 
  1321. if ( strstr($mailtext, "{TINYLINK}") ) { 
  1322. $tinylink = file_get_contents('http://tinyurl.com/api-create.php?url=' . urlencode($this->get_tracking_link(get_permalink($post->ID)))); 
  1323. } else { 
  1324. $tinylink = false; 
  1325. if ( strstr($mailtext, "{TINYLINK}") && $tinylink !== 'Error' && $tinylink !== false ) { 
  1326. $tablelinks .= "\r\n" . $tinylink . "\r\n"; 
  1327. $message_post .= $tinylink . "\r\n"; 
  1328. $message_posttime .= $tinylink . "\r\n"; 
  1329. } else { 
  1330. $tablelinks .= "\r\n" . $this->get_tracking_link(get_permalink($post->ID)) . "\r\n"; 
  1331. $message_post .= $this->get_tracking_link(get_permalink($post->ID)) . "\r\n"; 
  1332. $message_posttime .= $this->get_tracking_link(get_permalink($post->ID)) . "\r\n"; 
  1333.  
  1334. if ( strstr($mailtext, "{CATS}") ) { 
  1335. $post_cat_names = implode(', ', wp_get_object_terms($post->ID, $s2_taxonomies, array('fields' => 'names'))); 
  1336. $message_post .= __('Posted in', 'subscribe2') . ": " . $post_cat_names . "\r\n"; 
  1337. $message_posttime .= __('Posted in', 'subscribe2') . ": " . $post_cat_names . "\r\n"; 
  1338. if ( strstr($mailtext, "{TAGS}") ) { 
  1339. $post_tag_names = implode(', ', wp_get_post_tags($post->ID, array('fields' => 'names'))); 
  1340. if ( $post_tag_names != '' ) { 
  1341. $message_post .= __('Tagged as', 'subscribe2') . ": " . $post_tag_names . "\r\n"; 
  1342. $message_posttime .= __('Tagged as', 'subscribe2') . ": " . $post_tag_names . "\r\n"; 
  1343. $message_post .= "\r\n"; 
  1344. $message_posttime .= "\r\n"; 
  1345.  
  1346. ( !empty($post->post_excerpt) ) ? $excerpt = $post->post_excerpt : $excerpt = ''; 
  1347. if ( '' == $excerpt ) { 
  1348. // no excerpt, is there a <!--more--> ? 
  1349. if ( false !== strpos($post->post_content, '<!--more-->') ) { 
  1350. list($excerpt, $more) = explode('<!--more-->', $post->post_content, 2); 
  1351. $excerpt = strip_tags($excerpt); 
  1352. if ( function_exists('strip_shortcodes') ) { 
  1353. $excerpt = strip_shortcodes($excerpt); 
  1354. } else { 
  1355. $excerpt = strip_tags($post->post_content); 
  1356. if ( function_exists('strip_shortcodes') ) { 
  1357. $excerpt = strip_shortcodes($excerpt); 
  1358. $words = explode(' ', $excerpt, $this->excerpt_length + 1); 
  1359. if ( count($words) > $this->excerpt_length ) { 
  1360. array_pop($words); 
  1361. array_push($words, '[...]'); 
  1362. $excerpt = implode(' ', $words); 
  1363. // strip leading and trailing whitespace 
  1364. $excerpt = trim($excerpt); 
  1365. $message_post .= $excerpt . "\r\n\r\n"; 
  1366. $message_posttime .= $excerpt . "\r\n\r\n"; 
  1367.  
  1368. // we add a blank line after each post excerpt now trim white space that occurs for the last post 
  1369. $message_post = trim($message_post); 
  1370. $message_posttime = trim($message_posttime); 
  1371. // remove excess white space from within $message_post and $message_posttime 
  1372. $message_post = preg_replace('|[ ]+|', ' ', $message_post); 
  1373. $message_posttime = preg_replace('|[ ]+|', ' ', $message_posttime); 
  1374. $message_post = preg_replace("|[\r\n]{3, }|", "\r\n\r\n", $message_post); 
  1375. $message_posttime = preg_replace("|[\r\n]{3, }|", "\r\n\r\n", $message_posttime); 
  1376.  
  1377. // apply filter to allow external content to be inserted or content manipulated 
  1378. $message_post = apply_filters('s2_digest_email', $message_post, $now, $prev, $last, $this->subscribe2_options['cron_order']); 
  1379. $message_posttime = apply_filters('s2_digest_email', $message_posttime, $now, $prev, $last, $this->subscribe2_options['cron_order']); 
  1380.  
  1381. //sanity check - don't send a mail if the content is empty 
  1382. if ( !$message_post && !$message_posttime && !$table && !$tablelinks ) { 
  1383. return; 
  1384.  
  1385. // get sender details 
  1386. if ( $this->subscribe2_options['sender'] == 'blogname' ) { 
  1387. $this->myname = html_entity_decode(get_option('blogname'), ENT_QUOTES); 
  1388. $this->myemail = get_bloginfo('admin_email'); 
  1389. } else { 
  1390. $user = $this->get_userdata($this->subscribe2_options['sender']); 
  1391. $this->myemail = $user->user_email; 
  1392. $this->myname = html_entity_decode($user->display_name, ENT_QUOTES); 
  1393.  
  1394. $scheds = (array)wp_get_schedules(); 
  1395. $email_freq = $this->subscribe2_options['email_freq']; 
  1396. $display = $scheds[$email_freq]['display']; 
  1397. ( '' == get_option('blogname') ) ? $subject = "" : $subject = "[" . stripslashes(html_entity_decode(get_option('blogname'), ENT_QUOTES)) . "] "; 
  1398. $subject .= $display . " " . __('Digest Email', 'subscribe2'); 
  1399. $mailtext = str_replace("{TABLELINKS}", $tablelinks, $mailtext); 
  1400. $mailtext = str_replace("{TABLE}", $table, $mailtext); 
  1401. $mailtext = str_replace("{POSTTIME}", $message_posttime, $mailtext); 
  1402. $mailtext = str_replace("{POST}", $message_post, $mailtext); 
  1403. $mailtext = stripslashes($this->substitute($mailtext)); 
  1404.  
  1405. // prepare recipients 
  1406. if ( $preview != '' ) { 
  1407. $this->myemail = $preview; 
  1408. $this->myname = __('Digest Preview', 'subscribe2'); 
  1409. $this->mail(array($preview), $subject, $mailtext); 
  1410. } else { 
  1411. $public = $this->get_public(); 
  1412. $all_post_cats_string = implode(', ', $all_post_cats); 
  1413. $registered = $this->get_registered("cats=$all_post_cats_string"); 
  1414. $recipients = array_merge((array)$public, (array)$registered); 
  1415. $this->mail($recipients, $subject, $mailtext); 
  1416. } // end subscribe2_cron() 
  1417.  
  1418. function s2cleaner_task() { 
  1419. $unconfirmed = $this->get_public('0'); 
  1420. if ( empty($unconfirmed) ) { return; } 
  1421. global $wpdb; 
  1422. $sql = "SELECT email FROM $this->public WHERE active='0' AND date < DATE_SUB(CURDATE(), INTERVAL " . $this->clean_interval . " DAY)"; 
  1423. $old_unconfirmed = $wpdb->get_col( $sql ); 
  1424. if ( empty($old_unconfirmed) ) { 
  1425. return; 
  1426. } else { 
  1427. foreach ($old_unconfirmed as $email) { 
  1428. $this->delete($email); 
  1429. return; 
  1430. } // end s2cleaner_task() 
  1431.  
  1432. /** ===== Our constructor ===== */ 
  1433. /** 
  1434. Subscribe2 constructor 
  1435. */ 
  1436. function s2init() { 
  1437. global $wpdb, $wp_version, $wpmu_version; 
  1438. // load the options 
  1439. $this->subscribe2_options = get_option('subscribe2_options'); 
  1440. // if SCRIPT_DEBUG is true, use dev scripts 
  1441. $this->script_debug = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ? '' : '.min'; 
  1442.  
  1443. // get the WordPress release number for in code version comparisons 
  1444. $tmp = explode('-', $wp_version, 2); 
  1445. $this->wp_release = $tmp[0]; 
  1446.  
  1447. // Is this WordPressMU or not? 
  1448. if ( isset($wpmu_version) || strpos($wp_version, 'wordpress-mu') ) { 
  1449. $this->s2_mu = true; 
  1450. if ( function_exists('is_multisite') && is_multisite() ) { 
  1451. $this->s2_mu = true; 
  1452.  
  1453. // add action to handle WPMU subscriptions and unsubscriptions 
  1454. if ( $this->s2_mu === true ) { 
  1455. require_once(S2PATH . "classes/class-s2-multisite.php"); 
  1456. global $s2class_multisite; 
  1457. $s2class_multisite = new s2_multisite; 
  1458. if ( isset($_GET['s2mu_subscribe']) || isset($_GET['s2mu_unsubscribe']) ) { 
  1459. add_action('init', array(&$s2class_multisite, 'wpmu_subscribe')); 
  1460.  
  1461. // load our translations 
  1462. add_action('plugins_loaded', array(&$this, 'load_translations')); 
  1463.  
  1464. // do we need to install anything? 
  1465. $this->public = $wpdb->prefix . "subscribe2"; 
  1466. if ( $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $this->public)) != $this->public ) { $this->install(); } 
  1467. //do we need to upgrade anything? 
  1468. if ( $this->subscribe2_options === false || is_array($this->subscribe2_options) && $this->subscribe2_options['version'] !== S2VERSION ) { 
  1469. add_action('shutdown', array(&$this, 'upgrade')); 
  1470.  
  1471. // add core actions 
  1472. add_filter('cron_schedules', array(&$this, 'add_weekly_sched')); 
  1473. // add actions for automatic subscription based on option settings 
  1474. add_action('register_form', array(&$this, 'register_form')); 
  1475. add_action('user_register', array(&$this, 'register_post')); 
  1476. if ( $this->s2_mu ) { 
  1477. add_action('add_user_to_blog', array(&$s2class_multisite, 'wpmu_add_user'), 10); 
  1478. add_action('remove_user_from_blog', array(&$s2class_multisite, 'wpmu_remove_user'), 10); 
  1479. // add actions for processing posts based on per-post or cron email settings 
  1480. if ( $this->subscribe2_options['email_freq'] != 'never' ) { 
  1481. add_action('s2_digest_cron', array(&$this, 'subscribe2_cron')); 
  1482. } else { 
  1483. add_action('new_to_publish', array(&$this, 'publish')); 
  1484. add_action('draft_to_publish', array(&$this, 'publish')); 
  1485. add_action('auto-draft_to_publish', array(&$this, 'publish')); 
  1486. add_action('pending_to_publish', array(&$this, 'publish')); 
  1487. add_action('private_to_publish', array(&$this, 'publish')); 
  1488. add_action('future_to_publish', array(&$this, 'publish')); 
  1489. if ( $this->subscribe2_options['private'] == 'yes' ) { 
  1490. add_action('new_to_private', array(&$this, 'publish')); 
  1491. add_action('draft_to_private', array(&$this, 'publish')); 
  1492. add_action('auto-draft_to_private', array(&$this, 'publish')); 
  1493. add_action('pending_to_private', array(&$this, 'publish')); 
  1494. // add actions for comment subscribers 
  1495. if ( 'no' != $this->subscribe2_options['comment_subs'] ) { 
  1496. if ( 'before' == $this->subscribe2_options['comment_subs'] ) { 
  1497. add_action('comment_form_after_fields', array(&$this, 's2_comment_meta_form')); 
  1498. } else { 
  1499. add_action('comment_form', array(&$this, 's2_comment_meta_form')); 
  1500. add_action('comment_post', array(&$this, 's2_comment_meta'), 1, 2); 
  1501. add_action('wp_set_comment_status', array(&$this, 'comment_status')); 
  1502. // add action to display widget if option is enabled 
  1503. if ( '1' == $this->subscribe2_options['widget'] ) { 
  1504. add_action('widgets_init', array(&$this, 'subscribe2_widget')); 
  1505. // add action to display counter widget if option is enabled 
  1506. if ( '1' == $this->subscribe2_options['counterwidget'] ) { 
  1507. add_action('widgets_init', array(&$this, 'counter_widget')); 
  1508.  
  1509. // add action to 'clean' unconfirmed Public Subscribers 
  1510. if ( $this->clean_interval > 0 ) { 
  1511. add_action('wp_scheduled_delete', array(&$this, 's2cleaner_task')); 
  1512.  
  1513. // Add actions specific to admin or frontend 
  1514. if ( is_admin() ) { 
  1515. // load strings 
  1516. add_action('init', array(&$this, 'load_strings')); 
  1517.  
  1518. //add menu, authoring and category admin actions 
  1519. add_action('admin_menu', array(&$this, 'admin_menu')); 
  1520. add_action('admin_menu', array(&$this, 's2_meta_init')); 
  1521. add_action('save_post', array(&$this, 's2_meta_handler')); 
  1522. add_action('create_category', array(&$this, 'new_category')); 
  1523. add_action('delete_category', array(&$this, 'delete_category')); 
  1524.  
  1525. // Add filters for Ozh Admin Menu 
  1526. if ( function_exists('wp_ozh_adminmenu') ) { 
  1527. add_filter('ozh_adminmenu_icon_s2_posts', array(&$this, 'ozh_s2_icon')); 
  1528. add_filter('ozh_adminmenu_icon_s2_users', array(&$this, 'ozh_s2_icon')); 
  1529. add_filter('ozh_adminmenu_icon_s2_tools', array(&$this, 'ozh_s2_icon')); 
  1530. add_filter('ozh_adminmenu_icon_s2_settings', array(&$this, 'ozh_s2_icon')); 
  1531.  
  1532. // add write button 
  1533. if ( '1' == $this->subscribe2_options['show_button'] ) { 
  1534. add_action('admin_init', array(&$this, 'button_init')); 
  1535.  
  1536. // add counterwidget css and js 
  1537. if ( '1' == $this->subscribe2_options['counterwidget'] ) { 
  1538. add_action('admin_init', array(&$this, 'widget_s2counter_css_and_js')); 
  1539.  
  1540. // add one-click handlers 
  1541. if ( 'yes' == $this->subscribe2_options['one_click_profile'] ) { 
  1542. add_action( 'show_user_profile', array(&$this, 'one_click_profile_form') ); 
  1543. add_action( 'edit_user_profile', array(&$this, 'one_click_profile_form') ); 
  1544. add_action( 'personal_options_update', array(&$this, 'one_click_profile_form_save') ); 
  1545. add_action( 'edit_user_profile_update', array(&$this, 'one_click_profile_form_save') ); 
  1546.  
  1547. // capture CSV export 
  1548. if ( isset($_POST['s2_admin']) && isset($_POST['csv']) ) { 
  1549. $date = date('Y-m-d'); 
  1550. header("Content-Description: File Transfer"); 
  1551. header("Content-type: application/octet-stream"); 
  1552. header("Content-Disposition: attachment; filename=subscribe2_users_$date.csv"); 
  1553. header("Pragma: no-cache"); 
  1554. header("Expires: 0"); 
  1555. echo $this->prepare_export($_POST['exportcsv']); 
  1556. exit(0); 
  1557. } else { 
  1558. // load strings later on frontend for polylang plugin compatibility 
  1559. add_action('wp', array(&$this, 'load_strings')); 
  1560.  
  1561. if ( isset($_GET['s2']) ) { 
  1562. // someone is confirming a request 
  1563. if ( defined('DOING_S2_CONFIRM') && DOING_S2_CONFIRM ) { return; } 
  1564. define( 'DOING_S2_CONFIRM', true ); 
  1565. add_filter('request', array(&$this, 'query_filter')); 
  1566. add_filter('the_title', array(&$this, 'title_filter')); 
  1567. add_filter('the_content', array(&$this, 'confirm')); 
  1568.  
  1569. // add the frontend filters 
  1570. add_shortcode('subscribe2', array(&$this, 'shortcode')); 
  1571. add_filter('the_content', array(&$this, 'filter'), 10); 
  1572.  
  1573. // add actions for other plugins 
  1574. if ( '1' == $this->subscribe2_options['show_meta'] ) { 
  1575. add_action('wp_meta', array(&$this, 'add_minimeta'), 0); 
  1576.  
  1577. // add actions for ajax form if enabled 
  1578. if ( '1' == $this->subscribe2_options['ajax'] ) { 
  1579. add_action('wp_enqueue_scripts', array(&$this, 'add_ajax')); 
  1580. add_action('wp_footer', array(&$this, 'add_s2_ajax')); 
  1581. } // end s2init() 
  1582.  
  1583. /** 
  1584. PHP5 Constructor 
  1585. Allows dynamic variable setting 
  1586. */ 
  1587. function __construct() { 
  1588. $this->word_wrap = apply_filters('s2_word_wrap', 80); 
  1589. $this->excerpt_length = apply_filters('s2_excerpt_length', 55); 
  1590. $this->site_switching = apply_filters('s2_allow_site_switching', false); 
  1591. $this->clean_interval = apply_filters('s2_clean_interval', 28); 
  1592. } // end __construct() 
  1593.  
  1594. /** ===== our variables ===== */ 
  1595. // cache variables 
  1596. var $subscribe2_options = array(); 
  1597. var $all_confirmed = ''; 
  1598. var $all_unconfirmed = ''; 
  1599. var $all_registered_id = ''; 
  1600. var $all_registered_email = ''; 
  1601. var $all_authors = ''; 
  1602. var $excluded_cats = ''; 
  1603. var $post_title = ''; 
  1604. var $permalink = ''; 
  1605. var $post_date = ''; 
  1606. var $post_time = ''; 
  1607. var $myname = ''; 
  1608. var $myemail = ''; 
  1609. var $authorname = ''; 
  1610. var $post_cat_names = ''; 
  1611. var $post_tag_names = ''; 
  1612. var $post_count = ''; 
  1613. var $signup_dates = array(); 
  1614. var $filtered = 0; 
  1615. var $preview_email = false; 
  1616.  
  1617. // state variables used to affect processing 
  1618. var $s2_mu = false; 
  1619. var $action = ''; 
  1620. var $email = ''; 
  1621. var $message = ''; 
  1622. var $word_wrap; 
  1623. var $excerpt_length; 
  1624. var $site_switching; 
  1625. var $clean_interval; 
  1626.  
  1627. // some messages 
  1628. var $please_log_in = ''; 
  1629. var $profile = ''; 
  1630. var $confirmation_sent = ''; 
  1631. var $already_subscribed = ''; 
  1632. var $not_subscribed =''; 
  1633. var $not_an_email = ''; 
  1634. var $barred_domain = ''; 
  1635. var $error = ''; 
  1636. var $mail_sent = ''; 
  1637. var $mail_failed = ''; 
  1638. var $form = ''; 
  1639. var $no_such_email = ''; 
  1640. var $added = ''; 
  1641. var $deleted = ''; 
  1642. var $subscribe = ''; 
  1643. var $unsubscribe = ''; 
  1644. var $confirm_subject = ''; 
  1645. var $options_saved = ''; 
  1646. var $options_reset = ''; 
  1647. } // end class subscribe2