/includes/mail.php

  1. <?php 
  2.  
  3. class WPCF7_Mail { 
  4.  
  5. private static $current = null; 
  6.  
  7. private $name = ''; 
  8. private $template = array(); 
  9. private $use_html = false; 
  10. private $exclude_blank = false; 
  11.  
  12. public static function get_current() { 
  13. return self::$current; 
  14.  
  15. public static function send( $template, $name = '' ) { 
  16. self::$current = new self( $name, $template ); 
  17. return self::$current->compose(); 
  18.  
  19. private function __construct( $name, $template ) { 
  20. $this->name = trim( $name ); 
  21. $this->use_html = ! empty( $template['use_html'] ); 
  22. $this->exclude_blank = ! empty( $template['exclude_blank'] ); 
  23.  
  24. $this->template = wp_parse_args( $template, array( 
  25. 'subject' => '',  
  26. 'sender' => '',  
  27. 'body' => '',  
  28. 'recipient' => '',  
  29. 'additional_headers' => '',  
  30. 'attachments' => '',  
  31. ) ); 
  32.  
  33. public function name() { 
  34. return $this->name; 
  35.  
  36. public function get( $component, $replace_tags = false ) { 
  37. $use_html = ( $this->use_html && 'body' == $component ); 
  38. $exclude_blank = ( $this->exclude_blank && 'body' == $component ); 
  39.  
  40. $template = $this->template; 
  41. $component = isset( $template[$component] ) ? $template[$component] : ''; 
  42.  
  43. if ( $replace_tags ) { 
  44. $component = $this->replace_tags( $component, array( 
  45. 'html' => $use_html,  
  46. 'exclude_blank' => $exclude_blank,  
  47. ) ); 
  48.  
  49. if ( $use_html 
  50. && ! preg_match( '%<html[>\s].*</html>%is', $component ) ) { 
  51. $component = $this->htmlize( $component ); 
  52.  
  53. return $component; 
  54.  
  55. private function htmlize( $body ) { 
  56. $header = apply_filters( 'wpcf7_mail_html_header',  
  57. '<!doctype html> 
  58. <html xmlns="http://www.w3.org/1999/xhtml"> 
  59. <head> 
  60. <title>' . esc_html( $this->get( 'subject', true ) ) . '</title> 
  61. </head> 
  62. <body> 
  63. ', $this ); 
  64.  
  65. $footer = apply_filters( 'wpcf7_mail_html_footer',  
  66. '</body> 
  67. </html>', $this ); 
  68.  
  69. $html = $header . wpautop( $body ) . $footer; 
  70. return $html; 
  71.  
  72. private function compose( $send = true ) { 
  73. $components = array( 
  74. 'subject' => $this->get( 'subject', true ),  
  75. 'sender' => $this->get( 'sender', true ),  
  76. 'body' => $this->get( 'body', true ),  
  77. 'recipient' => $this->get( 'recipient', true ),  
  78. 'additional_headers' => $this->get( 'additional_headers', true ),  
  79. 'attachments' => $this->attachments(),  
  80. ); 
  81.  
  82. $components = apply_filters( 'wpcf7_mail_components',  
  83. $components, wpcf7_get_current_contact_form(), $this ); 
  84.  
  85. if ( ! $send ) { 
  86. return $components; 
  87.  
  88. $subject = wpcf7_strip_newline( $components['subject'] ); 
  89. $sender = wpcf7_strip_newline( $components['sender'] ); 
  90. $recipient = wpcf7_strip_newline( $components['recipient'] ); 
  91. $body = $components['body']; 
  92. $additional_headers = trim( $components['additional_headers'] ); 
  93. $attachments = $components['attachments']; 
  94.  
  95. $headers = "From: $sender\n"; 
  96.  
  97. if ( $this->use_html ) { 
  98. $headers .= "Content-Type: text/html\n"; 
  99. $headers .= "X-WPCF7-Content-Type: text/html\n"; 
  100. } else { 
  101. $headers .= "X-WPCF7-Content-Type: text/plain\n"; 
  102.  
  103. if ( $additional_headers ) { 
  104. $headers .= $additional_headers . "\n"; 
  105.  
  106. return wp_mail( $recipient, $subject, $body, $headers, $attachments ); 
  107.  
  108. public function replace_tags( $content, $args = '' ) { 
  109. if ( true === $args ) { 
  110. $args = array( 'html' => true ); 
  111.  
  112. $args = wp_parse_args( $args, array( 
  113. 'html' => false,  
  114. 'exclude_blank' => false,  
  115. ) ); 
  116.  
  117. return wpcf7_mail_replace_tags( $content, $args ); 
  118.  
  119. private function attachments( $template = null ) { 
  120. if ( ! $template ) { 
  121. $template = $this->get( 'attachments' ); 
  122.  
  123. $attachments = array(); 
  124.  
  125. if ( $submission = WPCF7_Submission::get_instance() ) { 
  126. $uploaded_files = $submission->uploaded_files(); 
  127.  
  128. foreach ( (array) $uploaded_files as $name => $path ) { 
  129. if ( false !== strpos( $template, "[${name}]" ) 
  130. && ! empty( $path ) ) { 
  131. $attachments[] = $path; 
  132.  
  133. foreach ( explode( "\n", $template ) as $line ) { 
  134. $line = trim( $line ); 
  135.  
  136. if ( '[' == substr( $line, 0, 1 ) ) { 
  137. continue; 
  138.  
  139. $path = path_join( WP_CONTENT_DIR, $line ); 
  140.  
  141. if ( @is_readable( $path ) && @is_file( $path ) ) { 
  142. $attachments[] = $path; 
  143.  
  144. return $attachments; 
  145.  
  146. function wpcf7_mail_replace_tags( $content, $args = '' ) { 
  147. $args = wp_parse_args( $args, array( 
  148. 'html' => false,  
  149. 'exclude_blank' => false,  
  150. ) ); 
  151.  
  152. if ( is_array( $content ) ) { 
  153. foreach ( $content as $key => $value ) { 
  154. $content[$key] = wpcf7_mail_replace_tags( $value, $args ); 
  155.  
  156. return $content; 
  157.  
  158. $content = explode( "\n", $content ); 
  159.  
  160. foreach ( $content as $num => $line ) { 
  161. $line = new WPCF7_MailTaggedText( $line, $args ); 
  162. $replaced = $line->replace_tags(); 
  163.  
  164. if ( $args['exclude_blank'] ) { 
  165. $replaced_tags = $line->get_replaced_tags(); 
  166.  
  167. if ( empty( $replaced_tags ) || array_filter( $replaced_tags ) ) { 
  168. $content[$num] = $replaced; 
  169. } else { 
  170. unset( $content[$num] ); // Remove a line. 
  171. } else { 
  172. $content[$num] = $replaced; 
  173.  
  174. $content = implode( "\n", $content ); 
  175.  
  176. return $content; 
  177.  
  178. add_action( 'phpmailer_init', 'wpcf7_phpmailer_init' ); 
  179.  
  180. function wpcf7_phpmailer_init( $phpmailer ) { 
  181. $wpcf7_content_type = false; 
  182.  
  183. foreach ( (array) $phpmailer->getCustomHeaders() as $custom_header ) { 
  184. if ( 'X-WPCF7-Content-Type' == $custom_header[0] ) { 
  185. $wpcf7_content_type = trim( $custom_header[1] ); 
  186. break; 
  187.  
  188. if ( 'text/html' == $wpcf7_content_type ) { 
  189. $phpmailer->msgHTML( $phpmailer->Body ); 
  190.  
  191. class WPCF7_MailTaggedText { 
  192.  
  193. private $html = false; 
  194. private $callback = null; 
  195. private $content = ''; 
  196. private $replaced_tags = array(); 
  197.  
  198. public function __construct( $content, $args = '' ) { 
  199. $args = wp_parse_args( $args, array( 
  200. 'html' => false,  
  201. 'callback' => null,  
  202. ) ); 
  203.  
  204. $this->html = (bool) $args['html']; 
  205.  
  206. if ( null !== $args['callback'] && is_callable( $args['callback'] ) ) { 
  207. $this->callback = $args['callback']; 
  208. } elseif ( $this->html ) { 
  209. $this->callback = array( $this, 'replace_tags_callback_html' ); 
  210. } else { 
  211. $this->callback = array( $this, 'replace_tags_callback' ); 
  212.  
  213. $this->content = $content; 
  214.  
  215. public function get_replaced_tags() { 
  216. return $this->replaced_tags; 
  217.  
  218. public function replace_tags() { 
  219. $regex = '/(\[?)\[[\t ]*' 
  220. . '([a-zA-Z_][0-9a-zA-Z:._-]*)' // [2] = name 
  221. . '((?:[\t ]+"[^"]*"|[\t ]+\'[^\']*\')*)' // [3] = values 
  222. . '[\t ]*\](\]?)/'; 
  223.  
  224. return preg_replace_callback( $regex, $this->callback, $this->content ); 
  225.  
  226. private function replace_tags_callback_html( $matches ) { 
  227. return $this->replace_tags_callback( $matches, true ); 
  228.  
  229. private function replace_tags_callback( $matches, $html = false ) { 
  230. // allow [[foo]] syntax for escaping a tag 
  231. if ( $matches[1] == '[' && $matches[4] == ']' ) { 
  232. return substr( $matches[0], 1, -1 ); 
  233.  
  234. $tag = $matches[0]; 
  235. $tagname = $matches[2]; 
  236. $values = $matches[3]; 
  237.  
  238. if ( ! empty( $values ) ) { 
  239. preg_match_all( '/"[^"]*"|\'[^\']*\'/', $values, $matches ); 
  240. $values = wpcf7_strip_quote_deep( $matches[0] ); 
  241.  
  242. $do_not_heat = false; 
  243.  
  244. if ( preg_match( '/^_raw_(.+)$/', $tagname, $matches ) ) { 
  245. $tagname = trim( $matches[1] ); 
  246. $do_not_heat = true; 
  247.  
  248. $format = ''; 
  249.  
  250. if ( preg_match( '/^_format_(.+)$/', $tagname, $matches ) ) { 
  251. $tagname = trim( $matches[1] ); 
  252. $format = $values[0]; 
  253.  
  254. $submission = WPCF7_Submission::get_instance(); 
  255. $submitted = $submission ? $submission->get_posted_data( $tagname ) : null; 
  256.  
  257. if ( null !== $submitted ) { 
  258.  
  259. if ( $do_not_heat ) { 
  260. $submitted = isset( $_POST[$tagname] ) ? $_POST[$tagname] : ''; 
  261.  
  262. $replaced = $submitted; 
  263.  
  264. if ( ! empty( $format ) ) { 
  265. $replaced = $this->format( $replaced, $format ); 
  266.  
  267. $replaced = wpcf7_flat_join( $replaced ); 
  268.  
  269. if ( $html ) { 
  270. $replaced = esc_html( $replaced ); 
  271. $replaced = wptexturize( $replaced ); 
  272.  
  273. $replaced = apply_filters( 'wpcf7_mail_tag_replaced',  
  274. $replaced, $submitted, $html ); 
  275.  
  276. $replaced = wp_unslash( trim( $replaced ) ); 
  277.  
  278. $this->replaced_tags[$tag] = $replaced; 
  279. return $replaced; 
  280.  
  281. $special = apply_filters( 'wpcf7_special_mail_tags', '', $tagname, $html ); 
  282.  
  283. if ( ! empty( $special ) ) { 
  284. $this->replaced_tags[$tag] = $special; 
  285. return $special; 
  286.  
  287. return $tag; 
  288.  
  289. public function format( $original, $format ) { 
  290. $original = (array) $original; 
  291.  
  292. foreach ( $original as $key => $value ) { 
  293. if ( preg_match( '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $value ) ) { 
  294. $original[$key] = mysql2date( $format, $value ); 
  295.  
  296. return $original; 
  297.  
  298. /** Special Mail Tags */ 
  299.  
  300. add_filter( 'wpcf7_special_mail_tags', 'wpcf7_special_mail_tag', 10, 3 ); 
  301.  
  302. function wpcf7_special_mail_tag( $output, $name, $html ) { 
  303. $name = preg_replace( '/^wpcf7\./', '_', $name ); // for back-compat 
  304.  
  305. $submission = WPCF7_Submission::get_instance(); 
  306.  
  307. if ( ! $submission ) { 
  308. return $output; 
  309.  
  310. if ( '_remote_ip' == $name ) { 
  311. if ( $remote_ip = $submission->get_meta( 'remote_ip' ) ) { 
  312. return $remote_ip; 
  313. } else { 
  314. return ''; 
  315.  
  316. if ( '_user_agent' == $name ) { 
  317. if ( $user_agent = $submission->get_meta( 'user_agent' ) ) { 
  318. return $html ? esc_html( $user_agent ) : $user_agent; 
  319. } else { 
  320. return ''; 
  321.  
  322. if ( '_url' == $name ) { 
  323. if ( $url = $submission->get_meta( 'url' ) ) { 
  324. return esc_url( $url ); 
  325. } else { 
  326. return ''; 
  327.  
  328. if ( '_date' == $name || '_time' == $name ) { 
  329. if ( $timestamp = $submission->get_meta( 'timestamp' ) ) { 
  330. if ( '_date' == $name ) { 
  331. return date_i18n( get_option( 'date_format' ), $timestamp ); 
  332.  
  333. if ( '_time' == $name ) { 
  334. return date_i18n( get_option( 'time_format' ), $timestamp ); 
  335.  
  336. return ''; 
  337.  
  338. if ( '_post_' == substr( $name, 0, 6 ) ) { 
  339. $unit_tag = $submission->get_meta( 'unit_tag' ); 
  340.  
  341. if ( $unit_tag 
  342. && preg_match( '/^wpcf7-f(\d+)-p(\d+)-o(\d+)$/', $unit_tag, $matches ) ) { 
  343. $post_id = absint( $matches[2] ); 
  344.  
  345. if ( $post = get_post( $post_id ) ) { 
  346. if ( '_post_id' == $name ) { 
  347. return (string) $post->ID; 
  348.  
  349. if ( '_post_name' == $name ) { 
  350. return $post->post_name; 
  351.  
  352. if ( '_post_title' == $name ) { 
  353. return $html ? esc_html( $post->post_title ) : $post->post_title; 
  354.  
  355. if ( '_post_url' == $name ) { 
  356. return get_permalink( $post->ID ); 
  357.  
  358. $user = new WP_User( $post->post_author ); 
  359.  
  360. if ( '_post_author' == $name ) { 
  361. return $user->display_name; 
  362.  
  363. if ( '_post_author_email' == $name ) { 
  364. return $user->user_email; 
  365.  
  366. return ''; 
  367.  
  368. return $output; 
.