/includes/Actions/Email.php

  1. <?php if ( ! defined( 'ABSPATH' ) ) exit; 
  2.  
  3. /** 
  4. * Class NF_Action_Email 
  5. */ 
  6. final class NF_Actions_Email extends NF_Abstracts_Action 
  7. /** 
  8. * @var string 
  9. */ 
  10. protected $_name = 'email'; 
  11.  
  12. /** 
  13. * @var array 
  14. */ 
  15. protected $_tags = array(); 
  16.  
  17. /** 
  18. * @var string 
  19. */ 
  20. protected $_timing = 'late'; 
  21.  
  22. /** 
  23. * @var int 
  24. */ 
  25. protected $_priority = 10; 
  26.  
  27. /** 
  28. * Constructor 
  29. */ 
  30. public function __construct() 
  31. parent::__construct(); 
  32.  
  33. $this->_nicename = __( 'Email', 'ninja-forms' ); 
  34.  
  35. $settings = Ninja_Forms::config( 'ActionEmailSettings' ); 
  36.  
  37. $this->_settings = array_merge( $this->_settings, $settings ); 
  38.  
  39. $this->_backwards_compatibility(); 
  40.  
  41. /** 
  42. * PUBLIC METHODS 
  43. */ 
  44.  
  45. public function process( $action_settings, $form_id, $data ) 
  46. $errors = $this->check_for_errors( $action_settings ); 
  47.  
  48. $headers = $this->_get_headers( $action_settings ); 
  49.  
  50. if ( has_filter( 'ninja_forms_get_fields_sorted' ) ) { 
  51. $fields_by_key = array(); 
  52. foreach( $data[ 'fields' ] as $field ) { 
  53. if( is_null( $field ) ) continue; 
  54. if( is_array( $field ) ) { 
  55. if( ! isset( $field[ 'key' ] ) ) continue; 
  56. $key = $field[ 'key' ]; 
  57. } else { 
  58. $key = $field->get_setting('key'); 
  59. $fields_by_key[ $key ] = $field; 
  60. $data[ 'fields' ] = apply_filters( 'ninja_forms_get_fields_sorted', array(), $data[ 'fields' ], $fields_by_key, $form_id ); 
  61.  
  62. $attachments = $this->_get_attachments( $action_settings, $data ); 
  63.  
  64. if( 'html' == $action_settings[ 'email_format' ] ) { 
  65. $message = $action_settings['email_message']; 
  66. } else { 
  67. $message = $this->format_plain_text_message( $action_settings[ 'email_message_plain' ] ); 
  68.  
  69. $message = apply_filters( 'ninja_forms_action_email_message', $message, $data, $action_settings ); 
  70.  
  71. try { 
  72. $sent = wp_mail($action_settings['to'], $action_settings['email_subject'], $message, $headers, $attachments); 
  73. } catch ( Exception $e ) { 
  74. $sent = false; 
  75. $errors[ 'email_sent' ] = $e->getMessage(); 
  76.  
  77. $data[ 'actions' ][ 'email' ][ 'to' ] = $action_settings['to']; 
  78. $data[ 'actions' ][ 'email' ][ 'sent' ] = $sent; 
  79. $data[ 'actions' ][ 'email' ][ 'headers' ] = $headers; 
  80. $data[ 'actions' ][ 'email' ][ 'attachments' ] = $attachments; 
  81.  
  82. if( $errors ) { 
  83. $data[ 'errors' ][ 'form' ] = $errors; 
  84.  
  85. if ( ! empty( $attachments ) ) { 
  86. $this->_drop_csv(); 
  87.  
  88. return $data; 
  89.  
  90. protected function check_for_errors( $action_settings ) 
  91. $errors = array(); 
  92.  
  93. $email_address_settings = array( 'to', 'from_address', 'reply_to', 'cc', 'bcc' ); 
  94.  
  95. foreach( $email_address_settings as $setting ) { 
  96. if( ! isset( $action_settings[ $setting ] ) ) continue; 
  97. if( ! $action_settings[ $setting ] ) continue; 
  98.  
  99.  
  100. $email_addresses = is_array( $action_settings[ $setting ] ) ? $action_settings[ $setting ] : explode( ', ', $action_settings[ $setting ] ); 
  101. foreach( (array) $email_addresses as $email ) { 
  102. $email = trim( $email ); 
  103. if ( false !== strpos( $email, '<' ) && false !== strpos( $email, '>' ) ) { 
  104. preg_match('/(?<=<).*?(?=>)/', $email, $email); 
  105. $email = $email[ 0 ]; 
  106. if( ! is_email( $email ) ) { 
  107. $errors[ 'email_' . $email ] = sprintf( __( 'Your email action "%s" has an invalid value for the "%s" setting. Please check this setting and try again.', 'ninja-forms'), $action_settings[ 'label' ], $setting ); 
  108.  
  109. return $errors; 
  110.  
  111. private function _get_headers( $settings ) 
  112. $headers = array(); 
  113.  
  114. $headers[] = 'Content-Type: text/' . $settings[ 'email_format' ]; 
  115. $headers[] = 'charset=UTF-8'; 
  116.  
  117. $headers[] = $this->_format_from( $settings ); 
  118.  
  119. $headers = array_merge( $headers, $this->_format_recipients( $settings ) ); 
  120.  
  121. return $headers; 
  122.  
  123. private function _get_attachments( $settings, $data ) 
  124. $attachments = array(); 
  125.  
  126. if( 1 == $settings[ 'attach_csv' ] ) { 
  127. $attachments[] = $this->_create_csv( $data[ 'fields' ] ); 
  128.  
  129. if( ! isset( $settings[ 'id' ] ) ) $settings[ 'id' ] = ''; 
  130.  
  131. $attachments = apply_filters( 'ninja_forms_action_email_attachments', $attachments, $data, $settings ); 
  132.  
  133. return $attachments; 
  134.  
  135. private function _format_from( $settings ) 
  136. $from_name = get_bloginfo( 'name', 'raw' ); 
  137. $from_name = apply_filters( 'ninja_forms_action_email_from_name', $from_name ); 
  138. $from_name = ( $settings[ 'from_name' ] ) ? $settings[ 'from_name' ] : $from_name; 
  139.  
  140. $from_address = get_bloginfo( 'admin_email' ); 
  141. $from_address = apply_filters( 'ninja_forms_action_email_from_address', $from_address ); 
  142. $from_address = ( $settings[ 'from_address' ] ) ? $settings[ 'from_address' ] : $from_address; 
  143.  
  144. return $this->_format_recipient( 'from', $from_address, $from_name ); 
  145.  
  146. private function _format_recipients( $settings ) 
  147. $headers = array(); 
  148.  
  149. $recipient_settings = array( 
  150. 'Cc' => $settings[ 'cc' ],  
  151. 'Bcc' => $settings[ 'bcc' ],  
  152. 'Reply-to' => $settings[ 'reply_to' ],  
  153. ); 
  154.  
  155. foreach( $recipient_settings as $type => $emails ) { 
  156.  
  157. $emails = explode( ', ', $emails ); 
  158.  
  159. foreach( $emails as $email ) { 
  160.  
  161. if( ! $email ) continue; 
  162.  
  163. $matches = array(); 
  164. if (preg_match('/^"?(?<name>[^<"]+)"? <(?<email>[^>]+)>$/', $email, $matches)) { 
  165. $headers[] = $this->_format_recipient($type, $matches['email'], $matches['name']); 
  166. } else { 
  167. $headers[] = $this->_format_recipient($type, $email); 
  168.  
  169. return $headers; 
  170.  
  171. private function _format_recipient( $type, $email, $name = '' ) 
  172. $type = ucfirst( $type ); 
  173.  
  174. if( ! $name ) $name = $email; 
  175.  
  176. $recipient = "$type: $name <$email>"; 
  177.  
  178. return $recipient; 
  179.  
  180. private function _create_csv( $fields ) 
  181. $csv_array = array(); 
  182.  
  183. // Get our current date. 
  184. $date_format = Ninja_Forms()->get_setting( 'date_format' ); 
  185. $today = date( $date_format, current_time( 'timestamp' ) ); 
  186. $csv_array[ 0 ][] = 'Date Submitted'; 
  187. $csv_array[ 1 ][] = $today; 
  188.  
  189. foreach( $fields as $field ) { 
  190.  
  191. $ignore = array( 
  192. 'hr',  
  193. 'submit',  
  194. 'html' 
  195. ); 
  196.  
  197. $ignore = apply_filters( 'ninja_forms_csv_ignore_fields', $ignore ); 
  198.  
  199. if( ! isset( $field[ 'label' ] ) ) continue; 
  200. if( in_array( $field[ 'type' ], $ignore ) ) continue; 
  201.  
  202. $label = ( '' != $field[ 'admin_label' ] ) ? $field[ 'admin_label' ] : $field[ 'label' ]; 
  203.  
  204. $value = WPN_Helper::stripslashes( $field[ 'value' ] ); 
  205. if ( empty( $value ) ) { 
  206. $value = ''; 
  207. if ( is_array( $value ) ) { 
  208. $value = implode( ', ', $value ); 
  209.  
  210. $csv_array[ 0 ][] = $label; 
  211. $csv_array[ 1 ][] = $value; 
  212.  
  213. $csv_content = WPN_Helper::str_putcsv( $csv_array,  
  214. apply_filters( 'ninja_forms_sub_csv_delimiter', ', ' ),  
  215. apply_filters( 'ninja_forms_sub_csv_enclosure', '"' ),  
  216. apply_filters( 'ninja_forms_sub_csv_terminator', "\n" ) 
  217. ); 
  218.  
  219. $upload_dir = wp_upload_dir(); 
  220. $path = trailingslashit( $upload_dir['path'] ); 
  221.  
  222. // create temporary file 
  223. $path = tempnam( $path, 'Sub' ); 
  224. $temp_file = fopen( $path, 'r+' ); 
  225.  
  226. // write to temp file 
  227. fwrite( $temp_file, $csv_content ); 
  228. fclose( $temp_file ); 
  229.  
  230. // find the directory we will be using for the final file 
  231. $path = pathinfo( $path ); 
  232. $dir = $path['dirname']; 
  233. $basename = $path['basename']; 
  234.  
  235. // create name for file 
  236. $new_name = apply_filters( 'ninja_forms_submission_csv_name', 'ninja-forms-submission' ); 
  237.  
  238. // remove a file if it already exists 
  239. if( file_exists( $dir.'/'.$new_name.'.csv' ) ) { 
  240. unlink( $dir.'/'.$new_name.'.csv' ); 
  241.  
  242. // move file 
  243. rename( $dir.'/'.$basename, $dir.'/'.$new_name.'.csv' ); 
  244. return $dir.'/'.$new_name.'.csv'; 
  245.  
  246. /** 
  247. * Function to delete csv file from temp directory after Email Action has completed. 
  248. */ 
  249. private function _drop_csv() 
  250. $upload_dir = wp_upload_dir(); 
  251. $path = trailingslashit( $upload_dir['path'] ); 
  252.  
  253. // create name for file 
  254. $new_name = apply_filters( 'ninja_forms_submission_csv_name', 'ninja-forms-submission' ); 
  255.  
  256. // remove a file if it already exists 
  257. if( file_exists( $path.'/'.$new_name.'.csv' ) ) { 
  258. unlink( $path.'/'.$new_name.'.csv' ); 
  259.  
  260. /** 
  261. * Backwards Compatibility 
  262. */ 
  263.  
  264. private function _backwards_compatibility() 
  265. add_filter( 'ninja_forms_sub_csv_delimiter', array( $this, 'ninja_forms_sub_csv_delimiter' ), 10, 1 ); 
  266. add_filter( 'ninja_sub_csv_enclosure', array( $this, 'ninja_sub_csv_enclosure' ), 10, 1 ); 
  267. add_filter( 'ninja_sub_csv_terminator', array( $this, 'ninja_sub_csv_terminator' ), 10, 1 ); 
  268. add_filter( 'ninja_forms_action_email_attachments', array( $this, 'ninja_forms_action_email_attachments' ), 10, 3 ); 
  269.  
  270. public function ninja_forms_sub_csv_delimiter( $delimiter ) 
  271. return apply_filters( 'nf_sub_csv_delimiter', $delimiter ); 
  272.  
  273. public function ninja_sub_csv_enclosure( $enclosure ) 
  274. return apply_filters( 'nf_sub_csv_enclosure', $enclosure ); 
  275.  
  276. public function ninja_sub_csv_terminator( $terminator ) 
  277. return apply_filters( 'nf_sub_csv_terminator', $terminator ); 
  278.  
  279. public function ninja_forms_action_email_attachments( $attachments, $form_data, $action_settings ) 
  280. return apply_filters( 'nf_email_notification_attachments', $attachments, $action_settings[ 'id' ] ); 
  281.  
  282. private function format_plain_text_message( $message ) 
  283. $message = str_replace( array( '<table>', '</table>', '<tr><td>', '' ), '', $message ); 
  284. $message = str_replace( '</td><td>', ' ', $message ); 
  285. $message = str_replace( '</td></tr>', "\r\n", $message ); 
  286. return strip_tags( $message ); 
.