PageRenderTime 52ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/html/AppCode/expressionengine/modules/email/mod.email.php

https://github.com/w3bg/www.hsifin.com
PHP | 1059 lines | 634 code | 225 blank | 200 comment | 179 complexity | 69c4c7ffddffa7a3058a10d73d0734f0 MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010, EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/user_guide/license.html
  13. =====================================================
  14. File: mod.email.php
  15. -----------------------------------------------------
  16. Purpose: Email class
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Email {
  24. var $email_time_interval = '20'; // In seconds
  25. var $email_max_emails = '50'; // Total recipients, not emails
  26. var $use_captchas = 'n';
  27. /** ----------------------------------------
  28. /** Constructor
  29. /** ----------------------------------------*/
  30. function Email()
  31. {
  32. // Make a local reference to the ExpressionEngine super object
  33. $this->EE =& get_instance();
  34. if ($this->EE->config->item('email_module_captchas') === FALSE OR $this->EE->config->item('email_module_captchas') == 'n')
  35. {
  36. $this->use_captchas = 'n';
  37. }
  38. elseif ($this->EE->config->item('email_module_captchas') == 'y')
  39. {
  40. $this->use_captchas = ($this->EE->config->item('captcha_require_members') == 'y' OR
  41. ($this->EE->config->item('captcha_require_members') == 'n' AND $this->EE->session->userdata('member_id') == 0)) ? 'y' : 'n';
  42. }
  43. }
  44. /** ----------------------------------------
  45. /** Contact Form
  46. /** ----------------------------------------*/
  47. function contact_form()
  48. {
  49. $tagdata = $this->EE->TMPL->tagdata;
  50. /** ----------------------------------------
  51. /** Recipient Email Checking
  52. /** ----------------------------------------*/
  53. $recipients = ( ! $this->EE->TMPL->fetch_param('recipients')) ? '' : $this->EE->TMPL->fetch_param('recipients');
  54. $user_recipients = ( ! $this->EE->TMPL->fetch_param('user_recipients')) ? 'false' : $this->EE->TMPL->fetch_param('user_recipients');
  55. $charset = ( ! $this->EE->TMPL->fetch_param('charset')) ? '' : $this->EE->TMPL->fetch_param('charset');
  56. $channel = ( ! $this->EE->TMPL->fetch_param('channel')) ? '' : $this->EE->TMPL->fetch_param('channel');
  57. // No email left behind act
  58. if ($user_recipients == 'false' && $recipients == '')
  59. {
  60. $recipients = $this->EE->config->item('webmaster_email');
  61. }
  62. // Clean and check recipient emails, if any
  63. if ($recipients != '')
  64. {
  65. $array = $this->validate_recipients($recipients);
  66. // Put together into string again
  67. $recipients = implode(',',$array['approved']);
  68. }
  69. /** ----------------------------------------
  70. /** Conditionals
  71. /** ----------------------------------------*/
  72. $cond = array();
  73. $cond['logged_in'] = ($this->EE->session->userdata('member_id') == 0) ? 'FALSE' : 'TRUE';
  74. $cond['logged_out'] = ($this->EE->session->userdata('member_id') != 0) ? 'FALSE' : 'TRUE';
  75. $cond['captcha'] = ($this->use_captchas == 'y') ? 'TRUE' : 'FALSE';
  76. $tagdata = $this->EE->functions->prep_conditionals($tagdata, $cond);
  77. // Load the form helper
  78. $this->EE->load->helper('form');
  79. /** ----------------------------------------
  80. /** Parse "single" variables
  81. /** ----------------------------------------*/
  82. foreach ($this->EE->TMPL->var_single as $key => $val)
  83. {
  84. /** ----------------------------------------
  85. /** parse {member_name}
  86. /** ----------------------------------------*/
  87. if ($key == 'member_name')
  88. {
  89. $name = ($this->EE->session->userdata['screen_name'] != '') ? $this->EE->session->userdata['screen_name'] : $this->EE->session->userdata['username'];
  90. $tagdata = $this->EE->TMPL->swap_var_single($key, form_prep($name), $tagdata);
  91. }
  92. /** ----------------------------------------
  93. /** parse {member_email}
  94. /** ----------------------------------------*/
  95. if ($key == 'member_email')
  96. {
  97. $email = ($this->EE->session->userdata['email'] == '') ? '' : $this->EE->session->userdata['email'];
  98. $tagdata = $this->EE->TMPL->swap_var_single($key, form_prep($email), $tagdata);
  99. }
  100. /** ----------------------------------------
  101. /** parse {current_time}
  102. /** ----------------------------------------*/
  103. if (strncmp($key, 'current_time', 12) == 0)
  104. {
  105. $now = $this->EE->localize->set_localized_time();
  106. $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->localize->decode_date($val,$now), $tagdata);
  107. }
  108. if (($key == 'author_email' OR $key == 'author_name') && ! isset($$key))
  109. {
  110. if ($this->EE->uri->query_string != '')
  111. {
  112. $entry_id = $this->EE->uri->query_string;
  113. $sql = "SELECT exp_members.username, exp_members.email, exp_members.screen_name
  114. FROM exp_channel_titles, exp_members ";
  115. if($channel != '')
  116. {
  117. $sql .= "LEFT JOIN exp_channels ON exp_channels.channel_id = exp_channel_titles.channel_id ";
  118. }
  119. $sql .= "WHERE exp_members.member_id = exp_channel_titles.author_id ";
  120. if ($channel != '')
  121. {
  122. $sql .= $this->EE->functions->sql_andor_string($channel, 'exp_channels.channel_name')." ";
  123. }
  124. if ( ! is_numeric($entry_id))
  125. {
  126. $sql .= "AND exp_channel_titles.url_title = '".$entry_id."' ";
  127. }
  128. else
  129. {
  130. $sql .= "AND exp_channel_titles.entry_id = '$entry_id' ";
  131. }
  132. $query = $this->EE->db->query($sql);
  133. if ($query->num_rows() == 0)
  134. {
  135. $author_name = '';
  136. }
  137. else
  138. {
  139. $author_name = ($query->row('screen_name') != '') ? $query->row('screen_name') : $query->row('username') ;
  140. }
  141. $author_email = ($query->num_rows() == 0) ? '' : $query->row('email') ;
  142. }
  143. else
  144. {
  145. $author_email = '';
  146. $author_name = '';
  147. }
  148. // Do them both now and save ourselves a query
  149. $tagdata = $this->EE->TMPL->swap_var_single('author_email', $author_email, $tagdata);
  150. $tagdata = $this->EE->TMPL->swap_var_single('author_name', $author_name, $tagdata);
  151. }
  152. // Clear out any unused variables.
  153. // This interferes with // $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
  154. }
  155. /** ----------------------------------------
  156. /** Create form
  157. /** ----------------------------------------*/
  158. if ($this->EE->TMPL->fetch_param('name') !== FALSE &&
  159. preg_match("#^[a-zA-Z0-9_\-]+$#i", $this->EE->TMPL->fetch_param('name'), $match))
  160. {
  161. $data['name'] = $this->EE->TMPL->fetch_param('name');
  162. }
  163. if ( function_exists('mcrypt_encrypt') )
  164. {
  165. $init_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  166. $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
  167. $recipients = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->EE->session->sess_crypt_key), $recipients, MCRYPT_MODE_ECB, $init_vect);
  168. }
  169. else
  170. {
  171. $recipients = $recipients.md5($this->EE->session->sess_crypt_key.$recipients);
  172. }
  173. $data['id'] = ($this->EE->TMPL->form_id == '') ? 'contact_form' : $this->EE->TMPL->form_id;
  174. $data['class'] = $this->EE->TMPL->form_class;
  175. $data['hidden_fields'] = array(
  176. 'ACT' => $this->EE->functions->fetch_action_id('Email', 'send_email'),
  177. 'RET' => ( ! $this->EE->TMPL->fetch_param('return')) ? '' : $this->EE->TMPL->fetch_param('return'),
  178. 'URI' => ($this->EE->uri->uri_string == '') ? 'index' : $this->EE->uri->uri_string,
  179. 'recipients' => base64_encode($recipients),
  180. 'user_recipients' => ($user_recipients == 'true') ? md5($this->EE->db->username.$this->EE->db->password.'y') : md5($this->EE->db->username.$this->EE->db->password.'n'),
  181. 'charset' => $charset,
  182. 'redirect' => ( ! $this->EE->TMPL->fetch_param('redirect')) ? '' : $this->EE->TMPL->fetch_param('redirect'),
  183. 'replyto' => ( ! $this->EE->TMPL->fetch_param('replyto')) ? '' : $this->EE->TMPL->fetch_param('replyto')
  184. );
  185. $res = $this->EE->functions->form_declaration($data);
  186. $res .= stripslashes($tagdata);
  187. $res .= "</form>";
  188. return $res;
  189. }
  190. /** ----------------------------------------
  191. /** Tell A Friend Form
  192. /** ----------------------------------------*/
  193. // {exp:email:tell_a_friend charset="utf-8" allow_html='n'}
  194. // {exp:email:tell_a_friend charset="utf-8" allow_html='<p>,<a>' recipients='sales@expressionengine.com'}
  195. // {member_email}, {member_name}, {current_time format="%Y %d %m"}
  196. function tell_a_friend()
  197. {
  198. if ($this->EE->uri->query_string == '')
  199. {
  200. return FALSE;
  201. }
  202. /** ----------------------------------------
  203. /** Recipient Email Checking
  204. /** ----------------------------------------*/
  205. $user_recipients = true; // By default
  206. $recipients = ( ! $this->EE->TMPL->fetch_param('recipients')) ? '' : $this->EE->TMPL->fetch_param('recipients');
  207. $charset = ( ! $this->EE->TMPL->fetch_param('charset')) ? '' : $this->EE->TMPL->fetch_param('charset');
  208. $allow_html = ( ! $this->EE->TMPL->fetch_param('allow_html')) ? 'n' : $this->EE->TMPL->fetch_param('allow_html');
  209. if ( ! $this->EE->TMPL->fetch_param('status'))
  210. {
  211. $this->EE->TMPL->tagparams['status'] = 'open';
  212. }
  213. // Clean and check recipient emails, if any
  214. if ($recipients != '')
  215. {
  216. $array = $this->validate_recipients($recipients);
  217. // Put together into string again
  218. $recipients = implode(',',$array['approved']);
  219. }
  220. /** --------------------------------------
  221. /** Parse page number
  222. /** --------------------------------------*/
  223. // We need to strip the page number from the URL for two reasons:
  224. // 1. So we can create pagination links
  225. // 2. So it won't confuse the query with an improper proper ID
  226. $qstring = $this->EE->uri->query_string;
  227. if (preg_match("#/P(\d+)#", $qstring, $match))
  228. {
  229. $current_page = $match['1'];
  230. $qstring = $this->EE->functions->remove_double_slashes(str_replace($match['0'], '', $qstring));
  231. }
  232. /** --------------------------------------
  233. /** Remove "N"
  234. /** --------------------------------------*/
  235. // The recent comments feature uses "N" as the URL indicator
  236. // It needs to be removed if presenst
  237. if (preg_match("#/N(\d+)#", $qstring, $match))
  238. {
  239. $qstring = $this->EE->functions->remove_double_slashes(str_replace($match['0'], '', $qstring));
  240. }
  241. /* -------------------------------------
  242. /* 'email_module_tellafriend_override' hook.
  243. /* - Allow use of Tell-A-Friend for things besides channel entries
  244. /* - Added EE 1.5.1
  245. */
  246. if ($this->EE->extensions->active_hook('email_module_tellafriend_override') === TRUE)
  247. {
  248. $tagdata = $this->EE->extensions->call('email_module_tellafriend_override', $qstring, $this);
  249. if ($this->EE->extensions->end_script === TRUE) return $tagdata;
  250. }
  251. /** --------------------------------------
  252. /** Else Do the Default Channel Processing
  253. /** -------------------------------------*/
  254. else
  255. {
  256. $entry_id = trim($qstring);
  257. // If there is a slash in the entry ID we'll kill everything after it.
  258. $entry_id = preg_replace("#/.+#", "", $entry_id);
  259. /** ----------------------------------------
  260. /** Do we have a vaild channel and ID number?
  261. /** ----------------------------------------*/
  262. $timestamp = ($this->EE->TMPL->cache_timestamp != '') ? $this->EE->localize->set_gmt($this->EE->TMPL->cache_timestamp) : $this->EE->localize->now;
  263. $channel = ( ! $this->EE->TMPL->fetch_param('channel')) ? '' : $this->EE->TMPL->fetch_param('channel');
  264. $sql = "SELECT entry_id FROM exp_channel_titles, exp_channels
  265. WHERE exp_channel_titles.channel_id = exp_channels.channel_id
  266. AND (expiration_date = 0 OR expiration_date > ".$timestamp.")
  267. AND status != 'closed' AND ";
  268. $sql .= ( ! is_numeric($entry_id)) ? " url_title = '".$entry_id."' " : " entry_id = '$entry_id' ";
  269. if ($channel != '')
  270. {
  271. $sql .= $this->EE->functions->sql_andor_string($channel, 'exp_channels.channel_name')." ";
  272. }
  273. $query = $this->EE->db->query($sql);
  274. // Bad ID? See ya!
  275. if ($query->num_rows() == 0)
  276. {
  277. return FALSE;
  278. }
  279. /** ----------------------------------------
  280. /** Fetch the channel entry
  281. /** ----------------------------------------*/
  282. if ( ! class_exists('Channel'))
  283. {
  284. require PATH_MOD.'channel/mod.channel'.EXT;
  285. }
  286. $channel = new Channel;
  287. $channel->fetch_custom_channel_fields();
  288. $channel->fetch_custom_member_fields();
  289. $channel->build_sql_query();
  290. if ($channel->sql == '')
  291. {
  292. return FALSE;
  293. }
  294. $channel->query = $this->EE->db->query($channel->sql);
  295. if ($channel->query->num_rows() == 0)
  296. {
  297. return FALSE;
  298. }
  299. $this->EE->load->library('typography');
  300. $this->EE->typography->initialize();
  301. $this->EE->typography->encode_email = FALSE;
  302. $this->EE->typography->convert_curly = FALSE;
  303. $channel->fetch_categories();
  304. $channel->parse_channel_entries();
  305. $tagdata = $channel->return_data;
  306. }
  307. /*
  308. /* -------------------------------------*/
  309. /** ----------------------------------------
  310. /** Parse conditionals
  311. /** ----------------------------------------*/
  312. $cond = array();
  313. $cond['captcha'] = ($this->use_captchas == 'y') ? 'TRUE' : 'FALSE';
  314. $tagdata = $this->EE->functions->prep_conditionals($tagdata, $cond);
  315. /** ----------------------------------------
  316. /** Parse tell-a-friend variables
  317. /** ----------------------------------------*/
  318. // {member_name}
  319. $tagdata = $this->EE->TMPL->swap_var_single('member_name', $this->EE->session->userdata['screen_name'], $tagdata);
  320. // {member_email}
  321. $tagdata = $this->EE->TMPL->swap_var_single('member_email', $this->EE->session->userdata['email'], $tagdata);
  322. /** ----------------------------------------
  323. /** A little work on the form field's values
  324. /** ----------------------------------------*/
  325. // Match values in input fields
  326. preg_match_all("/<input(.*?)value=\"(.*?)\"/", $tagdata, $matches);
  327. if(count($matches) > 0 && $allow_html != 'y')
  328. {
  329. foreach($matches['2'] as $value)
  330. {
  331. if ($allow_html == 'n')
  332. {
  333. $new = strip_tags($value);
  334. }
  335. else
  336. {
  337. $new = strip_tags($value,$allow_html);
  338. }
  339. $tagdata = str_replace($value,$new, $tagdata);
  340. }
  341. }
  342. // Remove line breaks
  343. $LB = 'snookums9loves4wookie';
  344. $tagdata = str_replace(array("\r\n", "\r", "\n"), $LB, $tagdata);
  345. // Match textarea content
  346. preg_match_all("/<textarea(.*?)>(.*?)<\/textarea>/", $tagdata, $matches);
  347. if (count($matches) > 0 && $allow_html != 'y')
  348. {
  349. foreach($matches['2'] as $value)
  350. {
  351. if ($allow_html == 'n')
  352. {
  353. $new = strip_tags($value);
  354. }
  355. else
  356. {
  357. $new = strip_tags($value, $allow_html);
  358. }
  359. $tagdata = str_replace($value, $new, $tagdata);
  360. }
  361. }
  362. $tagdata = str_replace($LB, "\n", $tagdata);
  363. /** ----------------------------------------
  364. /** Create form
  365. /** ----------------------------------------*/
  366. if ($this->EE->TMPL->fetch_param('name') !== FALSE &&
  367. preg_match("#^[a-zA-Z0-9_\-]+$#i", $this->EE->TMPL->fetch_param('name'), $match))
  368. {
  369. $data['name'] = $this->EE->TMPL->fetch_param('name');
  370. }
  371. if ( function_exists('mcrypt_encrypt') )
  372. {
  373. $init_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  374. $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
  375. $recipients = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->EE->session->sess_crypt_key), $recipients, MCRYPT_MODE_ECB, $init_vect);
  376. }
  377. else
  378. {
  379. $recipients = $recipients.md5($this->EE->session->sess_crypt_key.$recipients);
  380. }
  381. $data['id'] = ($this->EE->TMPL->form_id == '') ? 'tellafriend_form' : $this->EE->TMPL->form_id;
  382. $data['class'] = $this->EE->TMPL->form_class;
  383. $data['hidden_fields'] = array(
  384. 'ACT' => $this->EE->functions->fetch_action_id('Email', 'send_email'),
  385. 'RET' => ( ! $this->EE->TMPL->fetch_param('return')) ? '' : $this->EE->TMPL->fetch_param('return'),
  386. 'URI' => ($this->EE->uri->uri_string == '') ? 'index' : $this->EE->uri->uri_string,
  387. 'recipients' => base64_encode($recipients),
  388. 'user_recipients' => ($user_recipients == 'true') ? md5($this->EE->db->username.$this->EE->db->password.'y') : md5($this->EE->db->username.$this->EE->db->password.'n'),
  389. 'charset' => $charset,
  390. 'allow_html' => $allow_html,
  391. 'redirect' => ( ! $this->EE->TMPL->fetch_param('redirect')) ? '' : $this->EE->TMPL->fetch_param('redirect'),
  392. 'replyto' => ( ! $this->EE->TMPL->fetch_param('replyto')) ? '' : $this->EE->TMPL->fetch_param('replyto')
  393. );
  394. $res = $this->EE->functions->form_declaration($data);
  395. $res .= stripslashes($tagdata);
  396. $res .= "</form>";
  397. return $res;
  398. }
  399. /** ----------------------------------------
  400. /** Send Email
  401. /** ----------------------------------------*/
  402. function send_email()
  403. {
  404. $error = array();
  405. /** ----------------------------------------
  406. /** Blacklist/Whitelist Check
  407. /** ----------------------------------------*/
  408. if ($this->EE->blacklist->blacklisted == 'y' && $this->EE->blacklist->whitelisted == 'n')
  409. {
  410. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('not_authorized')));
  411. }
  412. /** ----------------------------------------
  413. /** Is the nation of the user banend?
  414. /** ----------------------------------------*/
  415. $this->EE->session->nation_ban_check();
  416. /** ----------------------------------------
  417. /** Check and Set
  418. /** ----------------------------------------*/
  419. $default = array('subject', 'message', 'from', 'user_recipients', 'to', 'recipients', 'name', 'required');
  420. foreach ($default as $val)
  421. {
  422. if ( ! isset($_POST[$val]))
  423. {
  424. $_POST[$val] = '';
  425. }
  426. else
  427. {
  428. if (is_array($_POST[$val]) && ($val == 'message' OR $val == 'required'))
  429. {
  430. $temp = '';
  431. foreach($_POST[$val] as $post_value)
  432. {
  433. $temp .= $this->EE->input->_clean_input_data($post_value)."\n";
  434. }
  435. $_POST[$val] = $temp;
  436. }
  437. if ($val == 'recipients')
  438. {
  439. if ( function_exists('mcrypt_encrypt') )
  440. {
  441. $init_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
  442. $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
  443. $decoded_recipients = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->EE->session->sess_crypt_key), base64_decode($_POST[$val]), MCRYPT_MODE_ECB, $init_vect), "\0");
  444. }
  445. else
  446. {
  447. $raw = base64_decode($_POST[$val]);
  448. $hash = substr($raw, -32);
  449. $decoded_recipients = substr($raw, 0, -32);
  450. if ($hash != md5($this->EE->session->sess_crypt_key.$decoded_recipients))
  451. {
  452. $decoded_recipients = '';
  453. }
  454. }
  455. $_POST[$val] = $decoded_recipients;
  456. }
  457. $_POST[$val] = $this->EE->security->xss_clean(trim(stripslashes($_POST[$val])));
  458. }
  459. }
  460. /** ----------------------------------------
  461. /** Clean incoming
  462. /** ----------------------------------------*/
  463. $clean = array('subject', 'from', 'user_recipients', 'to', 'recipients', 'name');
  464. foreach ($clean as $val)
  465. {
  466. $_POST[$val] = strip_tags($_POST[$val]);
  467. }
  468. /** ----------------------------------------
  469. /** Fetch the email module language pack
  470. /** ----------------------------------------*/
  471. $this->EE->lang->loadfile('email');
  472. /** ----------------------------------------
  473. /** Basic Security Check
  474. /** ----------------------------------------*/
  475. if ($this->EE->session->userdata['ip_address'] == '' OR $this->EE->session->userdata['user_agent'] == '')
  476. {
  477. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('em_unauthorized_request')));
  478. }
  479. /** ----------------------------------------
  480. /** Return Variables
  481. /** ----------------------------------------*/
  482. $x = explode('|',$_POST['RET']);
  483. unset($_POST['RET']);
  484. if (is_numeric($x['0']))
  485. {
  486. $return_link = $this->EE->functions->form_backtrack($x['0']);
  487. }
  488. else
  489. {
  490. $return_link = ($x['0'] == '' OR ! stristr($x['0'],'http://')) ? $this->EE->functions->form_backtrack(2) : $x['0'];
  491. }
  492. $site_name = ($this->EE->config->item('site_name') == '') ? $this->EE->lang->line('back') : stripslashes($this->EE->config->item('site_name'));
  493. $return_name = ( ! isset($x['1']) OR $x['1'] == '') ? $site_name : $x['1'];
  494. /** ----------------------------------------
  495. /** ERROR Checking
  496. /** ----------------------------------------*/
  497. // If the message is empty, bounce them back
  498. if ($_POST['message'] == '')
  499. {
  500. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('message_required')));
  501. }
  502. // If the from field is empty, error
  503. $this->EE->load->helper('email');
  504. if ($_POST['from'] == '' OR ! valid_email($_POST['from']))
  505. {
  506. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('em_sender_required')));
  507. }
  508. // If no recipients, bounce them back
  509. if ($_POST['recipients'] == '' && $_POST['to'] == '')
  510. {
  511. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('em_no_valid_recipients')));
  512. }
  513. /** ----------------------------------------
  514. /** Is the user banned?
  515. /** ----------------------------------------*/
  516. if ($this->EE->session->userdata['is_banned'] == TRUE)
  517. {
  518. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('not_authorized')));
  519. }
  520. /** ----------------------------------------
  521. /** Check Form Hash
  522. /** ----------------------------------------*/
  523. if ($this->EE->config->item('secure_forms') == 'y')
  524. {
  525. $query = $this->EE->db->query("SELECT COUNT(*) AS count FROM exp_security_hashes WHERE hash='".$this->EE->db->escape_str($_POST['XID'])."' AND ip_address = '".$this->EE->input->ip_address()."' AND date > UNIX_TIMESTAMP()-7200");
  526. if ($query->row('count') == 0)
  527. {
  528. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('not_authorized')));
  529. }
  530. }
  531. /** ----------------------------
  532. /** Check Tracking Class
  533. /** ----------------------------*/
  534. $day_ago = $this->EE->localize->now - 60*60*24;
  535. $query = $this->EE->db->query("DELETE FROM exp_email_tracker WHERE email_date < '{$day_ago}'");
  536. if ($this->EE->session->userdata['username'] === false OR $this->EE->session->userdata['username'] == '')
  537. {
  538. $query = $this->EE->db->query("SELECT *
  539. FROM exp_email_tracker
  540. WHERE sender_ip = '".$this->EE->input->ip_address()."'
  541. ORDER BY email_date DESC");
  542. }
  543. else
  544. {
  545. $query = $this->EE->db->query("SELECT *
  546. FROM exp_email_tracker
  547. WHERE sender_username = '".$this->EE->db->escape_str($this->EE->session->userdata['username'])."'
  548. OR sender_ip = '".$this->EE->input->ip_address()."'
  549. ORDER BY email_date DESC");
  550. }
  551. if ($query->num_rows() > 0)
  552. {
  553. // Max Emails - Quick check
  554. if ($query->num_rows() >= $this->email_max_emails)
  555. {
  556. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('em_limit_exceeded')));
  557. }
  558. // Max Emails - Indepth check
  559. $total_sent = 0;
  560. foreach($query->result_array() as $row)
  561. {
  562. $total_sent = $total_sent + $row['number_recipients'];
  563. }
  564. if ($total_sent >= $this->email_max_emails)
  565. {
  566. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('em_limit_exceeded')));
  567. }
  568. // Interval check
  569. if ($query->row('email_date') > ($this->EE->localize->now - $this->email_time_interval))
  570. {
  571. $error[] = str_replace("%s", $this->email_time_interval, $this->EE->lang->line('em_interval_warning'));
  572. return $this->EE->output->show_user_error('general', $error);
  573. }
  574. }
  575. /** ----------------------------------------
  576. /** Review Recipients
  577. /** ----------------------------------------*/
  578. $_POST['user_recipients'] = ($_POST['user_recipients'] == md5($this->EE->db->username.$this->EE->db->password.'y')) ? 'y' : 'n';
  579. if ($_POST['user_recipients'] == 'y' && trim($_POST['to']) != '')
  580. {
  581. $array = $this->validate_recipients($_POST['to']);
  582. $error = array_merge($error, $array['error']);
  583. $approved_tos = $array['approved'];
  584. }
  585. else
  586. {
  587. $approved_tos = array();
  588. }
  589. if (trim($_POST['recipients']) != '')
  590. {
  591. $array = $this->validate_recipients($_POST['recipients']);
  592. $approved_recipients = $array['approved'];
  593. }
  594. else
  595. {
  596. $approved_recipients = array();
  597. }
  598. /** ----------------------------------------------------
  599. /** If we have no valid emails to send, back they go.
  600. /** ----------------------------------------------------*/
  601. if ($_POST['user_recipients'] == 'y' && count($approved_tos) == 0)
  602. {
  603. $error[] = $this->EE->lang->line('em_no_valid_recipients');
  604. }
  605. elseif ( count($approved_recipients) == 0 && count($approved_tos) == 0)
  606. {
  607. $error[] = $this->EE->lang->line('em_no_valid_recipients');
  608. }
  609. /** -------------------------------------
  610. /** Is from email banned?
  611. /** -------------------------------------*/
  612. if ($this->EE->session->ban_check('email', $_POST['from']))
  613. {
  614. $error[] = $this->EE->lang->line('em_banned_from_email');
  615. }
  616. /** ----------------------------------------
  617. /** Do we have errors to display?
  618. /** ----------------------------------------*/
  619. if (count($error) > 0)
  620. {
  621. return $this->EE->output->show_user_error('submission', $error);
  622. }
  623. /** ----------------------------------------
  624. /** Check CAPTCHA
  625. /** ----------------------------------------*/
  626. if ($this->use_captchas == 'y')
  627. {
  628. if ( ! isset($_POST['captcha']) OR $_POST['captcha'] == '')
  629. {
  630. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('captcha_required')));
  631. }
  632. $query = $this->EE->db->query("SELECT COUNT(*) AS count FROM exp_captcha
  633. WHERE word='".$this->EE->db->escape_str($_POST['captcha'])."'
  634. AND ip_address = '".$this->EE->input->ip_address()."'
  635. AND date > UNIX_TIMESTAMP()-7200");
  636. if ($query->row('count') == 0)
  637. {
  638. return $this->EE->output->show_user_error('submission', array($this->EE->lang->line('captcha_incorrect')));
  639. }
  640. $this->EE->db->query("DELETE FROM exp_captcha
  641. WHERE (word='".$this->EE->db->escape_str($_POST['captcha'])."'
  642. AND ip_address = '".$this->EE->input->ip_address()."')
  643. OR date < UNIX_TIMESTAMP()-7200");
  644. }
  645. /** ----------------------------------------
  646. /** Censored Word Checking
  647. /** ----------------------------------------*/
  648. $this->EE->load->library('typography');
  649. $this->EE->typography->initialize();
  650. // Load the text helper
  651. $this->EE->load->helper('text');
  652. $subject = entities_to_ascii($_POST['subject']);
  653. $subject = $this->EE->typography->filter_censored_words($subject);
  654. $message = ($_POST['required'] != '') ? $_POST['required']."\n".$_POST['message'] : $_POST['message'];
  655. $message = $this->EE->security->xss_clean($message);
  656. if (isset($_POST['allow_html']) && $_POST['allow_html'] == 'y' && strlen(strip_tags($message)) != strlen($message))
  657. {
  658. $mail_type = 'html';
  659. }
  660. else
  661. {
  662. $mail_type = 'plain';
  663. }
  664. $message = entities_to_ascii($message);
  665. $message = $this->EE->typography->filter_censored_words($message);
  666. /** ----------------------------
  667. /** Send email
  668. /** ----------------------------*/
  669. $this->EE->load->library('email');
  670. $this->EE->email->wordwrap = true;
  671. $this->EE->email->mailtype = $mail_type;
  672. $this->EE->email->priority = '3';
  673. if (isset($_POST['charset']) && $_POST['charset'] != '')
  674. {
  675. $this->EE->email->charset = $_POST['charset'];
  676. }
  677. if ( count($approved_recipients) == 0 && count($approved_tos) > 0) // No Hidden Recipients
  678. {
  679. foreach ($approved_tos as $val)
  680. {
  681. $this->EE->email->EE_initialize();
  682. $this->EE->email->to($val);
  683. if (isset($_POST['replyto']) && $_POST['replyto'] == 'yes')
  684. {
  685. $this->EE->email->from($this->EE->config->item('webmaster_email'), $this->EE->config->item('webmaster_name'));
  686. $this->EE->email->reply_to($_POST['from'], $_POST['name']);
  687. }
  688. else
  689. {
  690. $this->EE->email->from($_POST['from'],$_POST['name']);
  691. }
  692. $this->EE->email->subject($subject);
  693. $this->EE->email->message($message);
  694. $this->EE->email->send();
  695. }
  696. }
  697. elseif ( count($approved_recipients) > 0 && count($approved_tos) == 0) // Hidden Recipients Only
  698. {
  699. foreach ($approved_recipients as $val)
  700. {
  701. $this->EE->email->EE_initialize();
  702. $this->EE->email->to($val);
  703. if (isset($_POST['replyto']) && $_POST['replyto'] == 'yes')
  704. {
  705. $this->EE->email->from($this->EE->config->item('webmaster_email'), $this->EE->config->item('webmaster_name'));
  706. $this->EE->email->reply_to($_POST['from'], $_POST['name']);
  707. }
  708. else
  709. {
  710. $this->EE->email->from($_POST['from'],$_POST['name']);
  711. }
  712. $this->EE->email->subject($subject);
  713. $this->EE->email->message($message);
  714. $this->EE->email->send();
  715. }
  716. }
  717. else // Combination of Hidden and Regular Recipients, BCC hidden on every regular recipient email
  718. {
  719. foreach ($approved_tos as $val)
  720. {
  721. $this->EE->email->EE_initialize();
  722. $this->EE->email->to($val);
  723. $this->EE->email->bcc(implode(',', $approved_recipients));
  724. if (isset($_POST['replyto']) && $_POST['replyto'] == 'yes')
  725. {
  726. $this->EE->email->from($this->EE->config->item('webmaster_email'), $this->EE->config->item('webmaster_name'));
  727. $this->EE->email->reply_to($_POST['from'], $_POST['name']);
  728. }
  729. else
  730. {
  731. $this->EE->email->from($_POST['from'], $_POST['name']);
  732. }
  733. $this->EE->email->subject($subject);
  734. $this->EE->email->message($message);
  735. $this->EE->email->send();
  736. }
  737. }
  738. /** ----------------------------
  739. /** Store in tracking class
  740. /** ----------------------------*/
  741. $data = array( 'email_date' => $this->EE->localize->now,
  742. 'sender_ip' => $this->EE->input->ip_address(),
  743. 'sender_email' => $_POST['from'],
  744. 'sender_username' => $this->EE->session->userdata['username'],
  745. 'number_recipients' => count($approved_tos) + count($approved_recipients)
  746. );
  747. $this->EE->db->query($this->EE->db->insert_string('exp_email_tracker', $data));
  748. /** -------------------------------------------
  749. /** Delete spam hashes
  750. /** -------------------------------------------*/
  751. if (isset($_POST['XID']))
  752. {
  753. $this->EE->db->query("DELETE FROM exp_security_hashes WHERE (hash='".$this->EE->db->escape_str($_POST['XID'])."' AND ip_address = '".$this->EE->input->ip_address()."') OR date < UNIX_TIMESTAMP()-7200");
  754. }
  755. /* -------------------------------------
  756. /* 'email_module_send_email_end' hook.
  757. /* - After emails are sent, do some additional processing
  758. /* - Added EE 1.5.1
  759. */
  760. if ($this->EE->extensions->active_hook('email_module_send_email_end') === TRUE)
  761. {
  762. $edata = $this->EE->extensions->call('email_module_send_email_end', $subject, $message, $approved_tos, $approved_recipients);
  763. if ($this->EE->extensions->end_script === TRUE) return;
  764. }
  765. /*
  766. /* -------------------------------------*/
  767. /** -------------------------------------------
  768. /** Thank you message
  769. /** -------------------------------------------*/
  770. $data = array( 'title' => $this->EE->lang->line('email_module_name'),
  771. 'heading' => $this->EE->lang->line('thank_you'),
  772. 'content' => $this->EE->lang->line('em_email_sent'),
  773. 'redirect' => $return_link,
  774. 'link' => array($return_link, $return_name)
  775. );
  776. if ($this->EE->input->get_post('redirect') !== FALSE)
  777. {
  778. if(is_numeric($this->EE->input->get_post('redirect')))
  779. {
  780. $data['rate'] = $this->EE->input->get_post('redirect');
  781. }
  782. elseif($this->EE->input->get_post('redirect') == 'none')
  783. {
  784. $data['redirect'] = '';
  785. }
  786. }
  787. $this->EE->output->show_message($data);
  788. }
  789. /** -----------------------------------
  790. /** Validate List of Emails
  791. /** -----------------------------------*/
  792. function validate_recipients($str)
  793. {
  794. // Remove white space and replace with comma
  795. $recipients = preg_replace("/\s*(\S+)\s*/", "\\1,", $str);
  796. // Remove any existing doubles
  797. $recipients = str_replace(",,", ",", $recipients);
  798. // Remove any comma at the end
  799. if (substr($recipients, -1) == ",")
  800. {
  801. $recipients = substr($recipients, 0, -1);
  802. }
  803. // Break into an array via commas and remove duplicates
  804. $emails = preg_split('/[,]/', $recipients);
  805. $emails = array_unique($emails);
  806. // Emails to send email to...
  807. $error = array();
  808. $approved_emails = array();
  809. $this->EE->load->helper('email');
  810. foreach ($emails as $email)
  811. {
  812. if (trim($email) == '') continue;
  813. if (valid_email($email))
  814. {
  815. if ( ! $this->EE->session->ban_check('email', $email))
  816. {
  817. $approved_emails[] = $email;
  818. }
  819. else
  820. {
  821. $error['ban_recp'] = $this->EE->lang->line('em_banned_recipient');
  822. }
  823. }
  824. else
  825. {
  826. $error['bad_recp'] = $this->EE->lang->line('em_invalid_recipient');
  827. }
  828. }
  829. return array('approved' => $approved_emails, 'error' => $error);
  830. }
  831. }
  832. // END CLASS
  833. /* End of file mod.email.php */
  834. /* Location: ./system/expressionengine/modules/email/mod.email.php */