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

/wp-content/plugins/ninja-forms/includes/Actions/Email.php

https://bitbucket.org/wallindev/wallindev-wp
PHP | 411 lines | 258 code | 91 blank | 62 comment | 41 complexity | ac77c28a87bc8685fcbc564a60a9acb5 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php if ( ! defined( 'ABSPATH' ) ) exit;
  2. /**
  3. * Class NF_Action_Email
  4. */
  5. final class NF_Actions_Email extends NF_Abstracts_Action
  6. {
  7. /**
  8. * @var string
  9. */
  10. protected $_name = 'email';
  11. /**
  12. * @var array
  13. */
  14. protected $_tags = array();
  15. /**
  16. * @var string
  17. */
  18. protected $_timing = 'late';
  19. /**
  20. * @var int
  21. */
  22. protected $_priority = 10;
  23. /**
  24. * Constructor
  25. */
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. $this->_nicename = __( 'Email', 'ninja-forms' );
  30. $settings = Ninja_Forms::config( 'ActionEmailSettings' );
  31. $this->_settings = array_merge( $this->_settings, $settings );
  32. $this->_backwards_compatibility();
  33. }
  34. /*
  35. * PUBLIC METHODS
  36. */
  37. public function process( $action_settings, $form_id, $data )
  38. {
  39. $action_settings = $this->sanitize_address_fields( $action_settings );
  40. $errors = $this->check_for_errors( $action_settings );
  41. $headers = $this->_get_headers( $action_settings );
  42. if ( has_filter( 'ninja_forms_get_fields_sorted' ) ) {
  43. $fields_by_key = array();
  44. foreach( $data[ 'fields' ] as $field ){
  45. if( is_null( $field ) ) continue;
  46. if( is_array( $field ) ){
  47. if( ! isset( $field[ 'key' ] ) ) continue;
  48. $key = $field[ 'key' ];
  49. } else {
  50. $key = $field->get_setting('key');
  51. }
  52. $fields_by_key[ $key ] = $field;
  53. }
  54. $data[ 'fields' ] = apply_filters( 'ninja_forms_get_fields_sorted', array(), $data[ 'fields' ], $fields_by_key, $form_id );
  55. }
  56. $attachments = $this->_get_attachments( $action_settings, $data );
  57. if( 'html' == $action_settings[ 'email_format' ] ) {
  58. $message = wpautop( $action_settings['email_message'] );
  59. } else {
  60. $message = $this->format_plain_text_message( $action_settings[ 'email_message_plain' ] );
  61. }
  62. $message = apply_filters( 'ninja_forms_action_email_message', $message, $data, $action_settings );
  63. try {
  64. /**
  65. * Hook into the email send to override functionality.
  66. * @return bool True if already sent. False to fallback to default behavior. Throw a new Exception if there is an error.
  67. */
  68. if( ! $sent = apply_filters( 'ninja_forms_action_email_send', false, $action_settings, $message, $headers, $attachments ) ){
  69. $sent = wp_mail($action_settings['to'], $action_settings['email_subject'], $message, $headers, $attachments);
  70. }
  71. } catch ( Exception $e ){
  72. $sent = false;
  73. $errors[ 'email_not_sent' ] = $e->getMessage();
  74. }
  75. if( is_user_logged_in() && current_user_can( 'manage_options' ) ) {
  76. $data[ 'actions' ][ 'email' ][ 'to' ] = $action_settings[ 'to' ];
  77. $data[ 'actions' ][ 'email' ][ 'headers' ] = $headers;
  78. $data[ 'actions' ][ 'email' ][ 'attachments' ] = $attachments;
  79. }
  80. $data[ 'actions' ][ 'email' ][ 'sent' ] = $sent;
  81. // Only show errors to Administrators.
  82. if( $errors && current_user_can( 'manage_options' ) ){
  83. $data[ 'errors' ][ 'form' ] = $errors;
  84. }
  85. if ( ! empty( $attachments ) ) {
  86. $this->_drop_csv();
  87. }
  88. return $data;
  89. }
  90. /**
  91. * Sanitizes email address settings
  92. * @since 3.2.2
  93. *
  94. * @param array $action_settings
  95. * @return array
  96. */
  97. protected function sanitize_address_fields( $action_settings )
  98. {
  99. // Build a look array to compare our email address settings to.
  100. $email_address_settings = array( 'to', 'from_address', 'reply_to', 'cc', 'bcc' );
  101. // Loop over the look up values.
  102. foreach( $email_address_settings as $setting ) {
  103. // If the loop up values are not set in the action settings continue.
  104. if ( ! isset( $action_settings[ $setting ] ) ) continue;
  105. // If action settings do not match the look up values continue.
  106. if ( ! $action_settings[ $setting ] ) continue;
  107. // This is the array that will contain the sanitized email address values.
  108. $sanitized_array = array();
  109. /*
  110. * Checks to see action settings is array,
  111. * if not explodes to comma delimited array.
  112. */
  113. if( is_array( $action_settings[ $setting ] ) ) {
  114. $email_addresses = $action_settings[ $setting ];
  115. } else {
  116. $email_addresses = explode( ',', $action_settings[ $setting ] );
  117. }
  118. // Loop over our email addresses.
  119. foreach( $email_addresses as $email ) {
  120. // Updated to trim values in case there is a value with spaces/tabs/etc to remove whitespace
  121. $email = trim( $email );
  122. if ( empty( $email ) ) continue;
  123. // Build our array of the email addresses.
  124. $sanitized_array[] = $email;
  125. }
  126. // Sanitized our array of settings.
  127. $action_settings[ $setting ] = implode( ',' ,$sanitized_array );
  128. }
  129. return $action_settings;
  130. }
  131. protected function check_for_errors( $action_settings )
  132. {
  133. $errors = array();
  134. $email_address_settings = array( 'to', 'from_address', 'reply_to', 'cc', 'bcc' );
  135. foreach( $email_address_settings as $setting ){
  136. if( ! isset( $action_settings[ $setting ] ) ) continue;
  137. if( ! $action_settings[ $setting ] ) continue;
  138. $email_addresses = is_array( $action_settings[ $setting ] ) ? $action_settings[ $setting ] : explode( ',', $action_settings[ $setting ] );
  139. foreach( (array) $email_addresses as $email ){
  140. $email = trim( $email );
  141. if ( false !== strpos( $email, '<' ) && false !== strpos( $email, '>' ) ) {
  142. preg_match('/(?:<)[^>]*(?:>)/', $email, $email);
  143. $email = $email[ 1 ];
  144. }
  145. if( ! is_email( $email ) ) {
  146. $errors[ 'invalid_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 );
  147. }
  148. }
  149. }
  150. return $errors;
  151. }
  152. private function _get_headers( $settings )
  153. {
  154. $headers = array();
  155. $headers[] = 'Content-Type: text/' . $settings[ 'email_format' ];
  156. $headers[] = 'charset=UTF-8';
  157. $headers[] = 'X-Ninja-Forms:ninja-forms'; // Flag for transactional email.
  158. $headers[] = $this->_format_from( $settings );
  159. $headers = array_merge( $headers, $this->_format_recipients( $settings ) );
  160. return $headers;
  161. }
  162. private function _get_attachments( $settings, $data )
  163. {
  164. $attachments = array();
  165. if( isset( $settings[ 'attach_csv' ] ) && 1 == $settings[ 'attach_csv' ] ){
  166. $attachments[] = $this->_create_csv( $data[ 'fields' ] );
  167. }
  168. if( ! isset( $settings[ 'id' ] ) ) $settings[ 'id' ] = '';
  169. $attachments = apply_filters( 'ninja_forms_action_email_attachments', $attachments, $data, $settings );
  170. return $attachments;
  171. }
  172. private function _format_from( $settings )
  173. {
  174. $from_name = get_bloginfo( 'name', 'raw' );
  175. $from_name = apply_filters( 'ninja_forms_action_email_from_name', $from_name );
  176. $from_name = ( $settings[ 'from_name' ] ) ? $settings[ 'from_name' ] : $from_name;
  177. $from_address = get_bloginfo( 'admin_email' );
  178. $from_address = apply_filters( 'ninja_forms_action_email_from_address', $from_address );
  179. $from_address = ( $settings[ 'from_address' ] ) ? $settings[ 'from_address' ] : $from_address;
  180. return $this->_format_recipient( 'from', $from_address, $from_name );
  181. }
  182. private function _format_recipients( $settings )
  183. {
  184. $headers = array();
  185. $recipient_settings = array(
  186. 'Cc' => $settings[ 'cc' ],
  187. 'Bcc' => $settings[ 'bcc' ],
  188. 'Reply-to' => $settings[ 'reply_to' ],
  189. );
  190. foreach( $recipient_settings as $type => $emails ){
  191. $emails = explode( ',', $emails );
  192. foreach( $emails as $email ) {
  193. if( ! $email ) continue;
  194. $matches = array();
  195. if (preg_match('/^"?(?<name>[^<"]+)"? <(?<email>[^>]+)>$/', $email, $matches)) {
  196. $headers[] = $this->_format_recipient($type, $matches['email'], $matches['name']);
  197. } else {
  198. $headers[] = $this->_format_recipient($type, $email);
  199. }
  200. }
  201. }
  202. return $headers;
  203. }
  204. private function _format_recipient( $type, $email, $name = '' )
  205. {
  206. $type = ucfirst( $type );
  207. if( ! $name ) $name = $email;
  208. $recipient = "$type: $name <$email>";
  209. return $recipient;
  210. }
  211. private function _create_csv( $fields )
  212. {
  213. $csv_array = array();
  214. // Get our current date.
  215. $date_format = Ninja_Forms()->get_setting( 'date_format' );
  216. $today = date( $date_format, current_time( 'timestamp' ) );
  217. $csv_array[ 0 ][] = 'Date Submitted';
  218. $csv_array[ 1 ][] = $today;
  219. foreach( $fields as $field ){
  220. $ignore = array(
  221. 'hr',
  222. 'submit',
  223. 'html',
  224. 'creditcardcvc',
  225. 'creditcardexpiration',
  226. 'creditcardfullname',
  227. 'creditcardnumber',
  228. 'creditcardzip',
  229. );
  230. $ignore = apply_filters( 'ninja_forms_csv_ignore_fields', $ignore );
  231. if( ! isset( $field[ 'label' ] ) ) continue;
  232. if( in_array( $field[ 'type' ], $ignore ) ) continue;
  233. $label = ( '' != $field[ 'admin_label' ] ) ? $field[ 'admin_label' ] : $field[ 'label' ];
  234. $value = WPN_Helper::stripslashes( $field[ 'value' ] );
  235. if ( empty( $value ) && ! isset( $value ) ) {
  236. $value = '';
  237. }
  238. if ( is_array( $value ) ) {
  239. $value = implode( ',', $value );
  240. }
  241. // add filter to add single quote if first character in value is '='
  242. $value = apply_filters( 'ninja_forms_subs_export_field_value_' . $field[ 'type' ], $value, $field );
  243. $csv_array[ 0 ][] = $label;
  244. $csv_array[ 1 ][] = $value;
  245. }
  246. $csv_content = WPN_Helper::str_putcsv( $csv_array,
  247. apply_filters( 'ninja_forms_sub_csv_delimiter', ',' ),
  248. apply_filters( 'ninja_forms_sub_csv_enclosure', '"' ),
  249. apply_filters( 'ninja_forms_sub_csv_terminator', "\n" )
  250. );
  251. $upload_dir = wp_upload_dir();
  252. $path = trailingslashit( $upload_dir['path'] );
  253. // create temporary file
  254. $path = tempnam( $path, 'Sub' );
  255. $temp_file = fopen( $path, 'r+' );
  256. // write to temp file
  257. fwrite( $temp_file, $csv_content );
  258. fclose( $temp_file );
  259. // find the directory we will be using for the final file
  260. $path = pathinfo( $path );
  261. $dir = $path['dirname'];
  262. $basename = $path['basename'];
  263. // create name for file
  264. $new_name = apply_filters( 'ninja_forms_submission_csv_name', 'ninja-forms-submission' );
  265. // remove a file if it already exists
  266. if( file_exists( $dir.'/'.$new_name.'.csv' ) ) {
  267. unlink( $dir.'/'.$new_name.'.csv' );
  268. }
  269. // move file
  270. rename( $dir.'/'.$basename, $dir.'/'.$new_name.'.csv' );
  271. return $dir.'/'.$new_name.'.csv';
  272. }
  273. /**
  274. * Function to delete csv file from temp directory after Email Action has completed.
  275. */
  276. private function _drop_csv()
  277. {
  278. $upload_dir = wp_upload_dir();
  279. $path = trailingslashit( $upload_dir['path'] );
  280. // create name for file
  281. $new_name = apply_filters( 'ninja_forms_submission_csv_name', 'ninja-forms-submission' );
  282. // remove a file if it already exists
  283. if( file_exists( $path.'/'.$new_name.'.csv' ) ) {
  284. unlink( $path.'/'.$new_name.'.csv' );
  285. }
  286. }
  287. /*
  288. * Backwards Compatibility
  289. */
  290. private function _backwards_compatibility()
  291. {
  292. add_filter( 'ninja_forms_sub_csv_delimiter', array( $this, 'ninja_forms_sub_csv_delimiter' ), 10, 1 );
  293. add_filter( 'ninja_sub_csv_enclosure', array( $this, 'ninja_sub_csv_enclosure' ), 10, 1 );
  294. add_filter( 'ninja_sub_csv_terminator', array( $this, 'ninja_sub_csv_terminator' ), 10, 1 );
  295. add_filter( 'ninja_forms_action_email_attachments', array( $this, 'ninja_forms_action_email_attachments' ), 10, 3 );
  296. }
  297. public function ninja_forms_sub_csv_delimiter( $delimiter )
  298. {
  299. return apply_filters( 'nf_sub_csv_delimiter', $delimiter );
  300. }
  301. public function ninja_sub_csv_enclosure( $enclosure )
  302. {
  303. return apply_filters( 'nf_sub_csv_enclosure', $enclosure );
  304. }
  305. public function ninja_sub_csv_terminator( $terminator )
  306. {
  307. return apply_filters( 'nf_sub_csv_terminator', $terminator );
  308. }
  309. public function ninja_forms_action_email_attachments( $attachments, $form_data, $action_settings )
  310. {
  311. return apply_filters( 'nf_email_notification_attachments', $attachments, $action_settings[ 'id' ] );
  312. }
  313. private function format_plain_text_message( $message )
  314. {
  315. $message = str_replace( array( '<table>', '</table>', '<tr><td>', '' ), '', $message );
  316. $message = str_replace( '</td><td>', ' ', $message );
  317. $message = str_replace( '</td></tr>', "\r\n", $message );
  318. return strip_tags( $message );
  319. }
  320. }