Formidable Forms – Form Builder for WordPress - Version 2.03.04

Version Description

  • Fix: Allow quotes within shortcodes in email settings
  • Fix: Check if an option is "other" a little more reliably. Instead of checking for 'other' anywhere in the option key, check for other_ at the beginning.
  • Fix: Correctly use default version number for jquery ui URL if query string is not included
  • Fix: Increase room for ids in the database. Increase from 11 to 20 to match the WordPress DB fields
  • Fix: Resolve a conflict with themes adding display:block; as the default for all input elements that is causing checkboxes and radio buttons to look bad
  • Code: Email code refactoring
  • Pro Version *
  • Fix: text calculations using a single dropdown time field
  • Fix: issue with duplicate headings after a repeating section in the default email message and the frm-show-entry shortcode
  • Fix: Prevent blank lines when headings are excluded in the default email message and the frm-show-entry shortcode
  • Fix: Remove the non-functional search box from the Formidable -> Entries page for all forms
  • Fix: invalid HTML when displaying paragraph field text in a Dynamic List field
  • Fix: Prevent a php error message when showing an empty table from the formresults shortcode
  • Fix: & was converting to & in fields watching Lookups
  • Fix: Remove fields within section from section's logic options to help prevent logic loops
  • Fix: Time field conditional statements weren't showing content when they should
  • Fix: Time Field validation was having trouble when the start or end settings didn't include the leading zero (7:30 instead of 07:30)
  • Fix: Unique time fields were causing errors on submit
Download this release

Release Info

Developer sswells
Plugin Icon 128x128 Formidable Forms – Form Builder for WordPress
Version 2.03.04
Comparing to
See all releases

Code changes from version 2.03.03 to 2.03.04

classes/controllers/FrmEntriesController.php CHANGED
@@ -511,13 +511,6 @@ class FrmEntriesController {
511
  return FrmEntryFormat::show_entry( $atts );
512
  }
513
 
514
- public static function filter_shortcode_value( $value, $tag, $atts, $field ) {
515
- $plain_text = add_filter('frm_plain_text_email', true);
516
- FrmEntryFormat::textarea_display_value( $field->type, $plain_text, $value );
517
-
518
- return $value;
519
- }
520
-
521
  public static function get_params( $form = null ) {
522
  _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_params' );
523
  return FrmForm::get_params( $form );
@@ -557,4 +550,14 @@ class FrmEntriesController {
557
  _deprecated_function( __FUNCTION__, '2.02.14', 'FrmProEntriesController::filter_display_value' );
558
  return $value;
559
  }
 
 
 
 
 
 
 
 
 
 
560
  }
511
  return FrmEntryFormat::show_entry( $atts );
512
  }
513
 
 
 
 
 
 
 
 
514
  public static function get_params( $form = null ) {
515
  _deprecated_function( __FUNCTION__, '2.0.9', 'FrmForm::get_params' );
516
  return FrmForm::get_params( $form );
550
  _deprecated_function( __FUNCTION__, '2.02.14', 'FrmProEntriesController::filter_display_value' );
551
  return $value;
552
  }
553
+
554
+ /**
555
+ * @deprecated 2.03.04
556
+ *
557
+ * @return mixed
558
+ */
559
+ public static function filter_shortcode_value( $value ) {
560
+ _deprecated_function( __FUNCTION__, '2.03.04', 'custom code' );
561
+ return $value;
562
+ }
563
  }
classes/controllers/FrmFieldsController.php CHANGED
@@ -338,9 +338,9 @@ class FrmFieldsController {
338
  if ( isset( $field['field_options']['other'] ) && $field['field_options']['other'] == true ) {
339
  $other_array = array();
340
  foreach ( $field['options'] as $opt_key => $opt ) {
341
- if ( $opt_key && strpos( $opt_key, 'other' ) !== false ) {
342
- $other_array[ $opt_key ] = $opt;
343
- }
344
  unset($opt_key, $opt);
345
  }
346
  if ( ! empty($other_array) ) {
338
  if ( isset( $field['field_options']['other'] ) && $field['field_options']['other'] == true ) {
339
  $other_array = array();
340
  foreach ( $field['options'] as $opt_key => $opt ) {
341
+ if ( FrmFieldsHelper::is_other_opt( $opt_key ) ) {
342
+ $other_array[ $opt_key ] = $opt;
343
+ }
344
  unset($opt_key, $opt);
345
  }
346
  if ( ! empty($other_array) ) {
classes/controllers/FrmHooksController.php CHANGED
@@ -55,7 +55,6 @@ class FrmHooksController {
55
  add_action( 'wp_loaded', 'FrmEntriesController::process_entry', 10, 0 );
56
  add_filter( 'frm_redirect_url', 'FrmEntriesController::delete_entry_before_redirect', 50, 3 );
57
  add_action( 'frm_after_entry_processed', 'FrmEntriesController::delete_entry_after_save', 100 );
58
- add_filter( 'frmpro_fields_replace_shortcodes', 'FrmEntriesController::filter_shortcode_value', 10, 4 );
59
 
60
  // Form Actions Controller
61
  add_action( 'init', 'FrmFormActionsController::register_post_types', 1 );
55
  add_action( 'wp_loaded', 'FrmEntriesController::process_entry', 10, 0 );
56
  add_filter( 'frm_redirect_url', 'FrmEntriesController::delete_entry_before_redirect', 50, 3 );
57
  add_action( 'frm_after_entry_processed', 'FrmEntriesController::delete_entry_after_save', 100 );
 
58
 
59
  // Form Actions Controller
60
  add_action( 'init', 'FrmFormActionsController::register_post_types', 1 );
classes/helpers/FrmAppHelper.php CHANGED
@@ -10,7 +10,7 @@ class FrmAppHelper {
10
  /**
11
  * @since 2.0
12
  */
13
- public static $plug_version = '2.03.03';
14
 
15
  /**
16
  * @since 1.07.02
@@ -884,7 +884,7 @@ class FrmAppHelper {
884
  }
885
 
886
  $query = $wp_scripts->registered[ $handle ];
887
- if ( is_object( $query ) ) {
888
  $ver = $query->ver;
889
  }
890
 
10
  /**
11
  * @since 2.0
12
  */
13
+ public static $plug_version = '2.03.04';
14
 
15
  /**
16
  * @since 1.07.02
884
  }
885
 
886
  $query = $wp_scripts->registered[ $handle ];
887
+ if ( is_object( $query ) && ! empty( $query->ver ) ) {
888
  $ver = $query->ver;
889
  }
890
 
classes/helpers/FrmEmailHelper.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 2.03.04
5
+ */
6
+ class FrmEmailHelper {
7
+
8
+ /**
9
+ * Get the userID field from a form
10
+ * This will not get repeating or embedded userID fields
11
+ *
12
+ * @since 2.03.04
13
+ *
14
+ * @param int $form_id
15
+ * @return int
16
+ */
17
+ public static function get_user_id_field_for_form( $form_id ) {
18
+ $where = array(
19
+ 'type' => 'user_id',
20
+ 'form_id' => $form_id,
21
+ );
22
+ $user_id_field = FrmDb::get_var( 'frm_fields', $where, 'id' );
23
+
24
+ return (int) $user_id_field;
25
+ }
26
+
27
+ /**
28
+ * This function should only be fired when Mandrill is sending an HTML email
29
+ * This will make sure Mandrill doesn't mess with our HTML emails
30
+ *
31
+ * @since 2.03.04
32
+ *
33
+ * @return bool
34
+ */
35
+ public static function remove_mandrill_br() {
36
+ return false;
37
+ }
38
+ }
classes/helpers/FrmEntriesHelper.php CHANGED
@@ -497,9 +497,8 @@ class FrmEntriesHelper {
497
  FrmEntryFormat::flatten_multi_file_upload( $field, $val );
498
  }
499
 
500
- public static function textarea_display_value( &$value, $type, $plain_text ) {
501
- _deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryFormat::textarea_display_value' );
502
- FrmEntryFormat::textarea_display_value( $type, $plain_text, $value );
503
  }
504
 
505
  public static function fill_entry_user_info( $atts, array &$values ) {
497
  FrmEntryFormat::flatten_multi_file_upload( $field, $val );
498
  }
499
 
500
+ public static function textarea_display_value() {
501
+ _deprecated_function( __FUNCTION__, '2.0.9', 'custom code' );
 
502
  }
503
 
504
  public static function fill_entry_user_info( $atts, array &$values ) {
classes/helpers/FrmEntriesListHelper.php CHANGED
@@ -78,7 +78,7 @@ class FrmEntriesListHelper extends FrmListHelper {
78
  if ( $which == 'top' && empty( $form_id ) ) {
79
  echo '<div class="alignleft actions">';
80
  echo FrmFormsHelper::forms_dropdown( 'form', $form_id, array( 'blank' => __( 'View all forms', 'formidable' ) ) );
81
- submit_button( __( 'Filter' ), 'filter_action', '', false, array( 'id' => "post-query-submit" ) );
82
  echo '</div>';
83
  }
84
  }
78
  if ( $which == 'top' && empty( $form_id ) ) {
79
  echo '<div class="alignleft actions">';
80
  echo FrmFormsHelper::forms_dropdown( 'form', $form_id, array( 'blank' => __( 'View all forms', 'formidable' ) ) );
81
+ submit_button( __( 'Filter' ), 'filter_action', '', false, array( 'id' => 'post-query-submit' ) );
82
  echo '</div>';
83
  }
84
  }
classes/helpers/FrmFieldsHelper.php CHANGED
@@ -875,17 +875,17 @@ DEFAULT_HTML;
875
  }
876
  }
877
 
878
- /**
879
- * Check if current field option is an "other" option
880
- *
881
- * @since 2.0.6
882
- *
883
- * @param string $opt_key
884
- * @return boolean Returns true if current field option is an "Other" option
885
- */
886
- public static function is_other_opt( $opt_key ) {
887
- return $opt_key && strpos( $opt_key, 'other' ) !== false;
888
- }
889
 
890
  /**
891
  * Get value that belongs in "Other" text box
875
  }
876
  }
877
 
878
+ /**
879
+ * Check if current field option is an "other" option
880
+ *
881
+ * @since 2.0.6
882
+ *
883
+ * @param string $opt_key
884
+ * @return boolean Returns true if current field option is an "Other" option
885
+ */
886
+ public static function is_other_opt( $opt_key ) {
887
+ return $opt_key && strpos( $opt_key, 'other_' ) === 0;
888
+ }
889
 
890
  /**
891
  * Get value that belongs in "Other" text box
classes/models/FrmDb.php CHANGED
@@ -78,7 +78,7 @@ class FrmDb {
78
 
79
  /* Create/Upgrade Fields Table */
80
  $sql[] = 'CREATE TABLE ' . $this->fields . ' (
81
- id int(11) NOT NULL auto_increment,
82
  field_key varchar(100) default NULL,
83
  name text default NULL,
84
  description longtext default NULL,
@@ -115,17 +115,17 @@ class FrmDb {
115
 
116
  /* Create/Upgrade Items Table */
117
  $sql[] = 'CREATE TABLE ' . $this->entries . ' (
118
- id int(11) NOT NULL auto_increment,
119
  item_key varchar(100) default NULL,
120
  name varchar(255) default NULL,
121
  description text default NULL,
122
  ip text default NULL,
123
- form_id int(11) default NULL,
124
- post_id int(11) default NULL,
125
- user_id int(11) default NULL,
126
- parent_item_id int(11) default 0,
127
- is_draft tinyint(1) default 0,
128
- updated_by int(11) default NULL,
129
  created_at datetime NOT NULL,
130
  updated_at datetime NOT NULL,
131
  PRIMARY KEY (id),
@@ -138,10 +138,10 @@ class FrmDb {
138
 
139
  /* Create/Upgrade Meta Table */
140
  $sql[] = 'CREATE TABLE ' . $this->entry_metas . ' (
141
- id int(11) NOT NULL auto_increment,
142
- meta_value longtext default NULL,
143
- field_id int(11) NOT NULL,
144
- item_id int(11) NOT NULL,
145
  created_at datetime NOT NULL,
146
  PRIMARY KEY (id),
147
  KEY field_id (field_id),
78
 
79
  /* Create/Upgrade Fields Table */
80
  $sql[] = 'CREATE TABLE ' . $this->fields . ' (
81
+ id BIGINT(20) NOT NULL auto_increment,
82
  field_key varchar(100) default NULL,
83
  name text default NULL,
84
  description longtext default NULL,
115
 
116
  /* Create/Upgrade Items Table */
117
  $sql[] = 'CREATE TABLE ' . $this->entries . ' (
118
+ id BIGINT(20) NOT NULL auto_increment,
119
  item_key varchar(100) default NULL,
120
  name varchar(255) default NULL,
121
  description text default NULL,
122
  ip text default NULL,
123
+ form_id BIGINT(20) default NULL,
124
+ post_id BIGINT(20) default NULL,
125
+ user_id BIGINT(20) default NULL,
126
+ parent_item_id BIGINT(20) default 0,
127
+ is_draft tinyint(1) default 0,
128
+ updated_by BIGINT(20) default NULL,
129
  created_at datetime NOT NULL,
130
  updated_at datetime NOT NULL,
131
  PRIMARY KEY (id),
138
 
139
  /* Create/Upgrade Meta Table */
140
  $sql[] = 'CREATE TABLE ' . $this->entry_metas . ' (
141
+ id BIGINT(20) NOT NULL auto_increment,
142
+ meta_value longtext default NULL,
143
+ field_id BIGINT(20) NOT NULL,
144
+ item_id BIGINT(20) NOT NULL,
145
  created_at datetime NOT NULL,
146
  PRIMARY KEY (id),
147
  KEY field_id (field_id),
classes/models/FrmEmail.php ADDED
@@ -0,0 +1,743 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @since 2.03.04
5
+ */
6
+ class FrmEmail {
7
+
8
+ private $email_key = '';
9
+ private $to = array();
10
+ private $cc = array();
11
+ private $bcc = array();
12
+ private $from = '';
13
+ private $reply_to = '';
14
+ private $subject = '';
15
+ private $message = '';
16
+ private $attachments = array();
17
+
18
+ private $is_plain_text = false;
19
+ private $is_single_recipient = false;
20
+ private $include_user_info = false;
21
+
22
+ private $charset = '';
23
+ private $content_type = 'text/html';
24
+
25
+ private $settings = array();
26
+ private $entry;
27
+ private $form;
28
+
29
+ /**
30
+ * FrmEmail constructor
31
+ *
32
+ * @param object $action
33
+ * @param object $entry
34
+ * @param object $form
35
+ */
36
+ public function __construct( $action, $entry, $form ) {
37
+ $this->set_email_key( $action );
38
+ $this->entry = $entry;
39
+ $this->form = $form;
40
+ $this->settings = $action->post_content;
41
+
42
+ $user_id_args = self::get_user_id_args( $form->id );
43
+ $this->set_to( $user_id_args );
44
+ $this->set_cc( $user_id_args );
45
+ $this->set_bcc( $user_id_args );
46
+
47
+ if ( ! $this->has_recipients() ) {
48
+ return;
49
+ }
50
+
51
+ $this->set_from( $user_id_args );
52
+ $this->set_reply_to( $user_id_args );
53
+
54
+ $this->set_include_user_info();
55
+ $this->set_is_plain_text();
56
+ $this->set_is_single_recipient( $action );
57
+
58
+ $this->set_charset();
59
+ $this->set_content_type();
60
+
61
+ $this->set_subject();
62
+ $this->set_message();
63
+ $this->set_attachments();
64
+ }
65
+
66
+ /**
67
+ * Set the email key property
68
+ *
69
+ * @since 2.03.04
70
+ *
71
+ * @param object $action
72
+ */
73
+ private function set_email_key( $action ) {
74
+ $this->email_key = $action->ID;
75
+ }
76
+
77
+ /**
78
+ * Set the to addresses
79
+ *
80
+ * @since 2.03.04
81
+ *
82
+ * @param array $user_id_args
83
+ */
84
+ private function set_to( $user_id_args ) {
85
+ $to = $this->prepare_email_setting( $this->settings['email_to'], $user_id_args );
86
+ $to = $this->explode_emails( $to );
87
+
88
+ $where = array(
89
+ 'it.field_id !' => 0,
90
+ 'it.item_id' => $this->entry->id,
91
+ );
92
+ $values = FrmEntryMeta::getAll( $where, ' ORDER BY fi.field_order' );
93
+ $args = array(
94
+ 'email_key' => $this->email_key,
95
+ 'entry' => $this->entry,
96
+ 'form' => $this->form,
97
+ );
98
+ $to = apply_filters( 'frm_to_email', $to, $values, $this->form->id, $args );
99
+
100
+ $this->to = array_unique( (array) $to );
101
+
102
+ if ( empty( $this->to ) ) {
103
+ return;
104
+ }
105
+
106
+ $this->handle_phone_numbers();
107
+
108
+ $this->to = $this->format_recipients( $this->to );
109
+ }
110
+
111
+ /**
112
+ * Set the CC addresses
113
+ *
114
+ * @since 2.03.04
115
+ *
116
+ * @param array $user_id_args
117
+ */
118
+ private function set_cc( $user_id_args ) {
119
+ $this->cc = $this->prepare_additional_recipients( $this->settings['cc'], $user_id_args );
120
+ }
121
+
122
+ /**
123
+ * Set the BCC addresses
124
+ *
125
+ * @since 2.03.04
126
+ *
127
+ * @param array $user_id_args
128
+ */
129
+ private function set_bcc( $user_id_args ) {
130
+ $this->bcc = $this->prepare_additional_recipients( $this->settings['bcc'], $user_id_args );
131
+ }
132
+
133
+ /**
134
+ * Prepare CC and BCC recipients
135
+ *
136
+ * @since 2.03.04
137
+ *
138
+ * @param string $recipients
139
+ * @param array $user_id_args
140
+ *
141
+ * @return array
142
+ */
143
+ private function prepare_additional_recipients( $recipients, $user_id_args ) {
144
+ $recipients = $this->prepare_email_setting( $recipients, $user_id_args );
145
+ $recipients = $this->explode_emails( $recipients );
146
+
147
+ $recipients = array_unique( (array) $recipients );
148
+ $recipients = $this->format_recipients( $recipients );
149
+
150
+ return $recipients;
151
+ }
152
+
153
+ /**
154
+ * Set the From addresses
155
+ *
156
+ * @since 2.03.04
157
+ *
158
+ * @param array $user_id_args
159
+ */
160
+ private function set_from( $user_id_args ) {
161
+ if ( empty( $this->settings['from'] ) ) {
162
+ $from = get_option( 'admin_email' );
163
+ } else {
164
+ $from = $this->prepare_email_setting( $this->settings['from'], $user_id_args );
165
+ }
166
+
167
+ $this->from = $this->format_from( $from );
168
+ }
169
+
170
+ /**
171
+ * Set the Reply To addresses
172
+ *
173
+ * @since 2.03.04
174
+ *
175
+ * @param array $user_id_args
176
+ */
177
+ private function set_reply_to( $user_id_args ) {
178
+ $this->reply_to = trim( $this->settings['reply_to'] );
179
+
180
+ if ( empty( $this->reply_to ) ) {
181
+ $this->reply_to = $this->from;
182
+ } else {
183
+ $this->reply_to = $this->prepare_email_setting( $this->settings['reply_to'], $user_id_args );
184
+ $this->reply_to = $this->format_reply_to( $this->reply_to );
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Set the is_plain_text property
190
+ * This should be set before the message
191
+ *
192
+ * @since 2.03.04
193
+ */
194
+ private function set_is_plain_text() {
195
+ if ( $this->settings['plain_text'] ) {
196
+ $this->is_plain_text = true;
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Set the include_user_info property
202
+ * This should be set before the message
203
+ *
204
+ * @since 2.03.04
205
+ */
206
+ private function set_include_user_info() {
207
+ if ( isset( $this->settings['inc_user_info'] ) ) {
208
+ $this->include_user_info = $this->settings['inc_user_info'];
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Set the is_single_recipient property
214
+ *
215
+ * @since 2.03.04
216
+ *
217
+ * @param $action
218
+ */
219
+ private function set_is_single_recipient( $action ) {
220
+ $args = array(
221
+ 'form' => $this->form,
222
+ 'entry' => $this->entry,
223
+ 'action' => $action,
224
+ );
225
+
226
+ /**
227
+ * Send a separate email for email address in the "to" section
228
+ *
229
+ * @since 2.2.13
230
+ */
231
+ $this->is_single_recipient = apply_filters( 'frm_send_separate_emails', false, $args );
232
+ }
233
+
234
+ /**
235
+ * Set the charset
236
+ *
237
+ * @since 2.03.04
238
+ */
239
+ private function set_charset() {
240
+ $this->charset = get_option( 'blog_charset' );
241
+ }
242
+
243
+ /**
244
+ * Set the content type
245
+ *
246
+ * @since 2.03.04
247
+ */
248
+ private function set_content_type() {
249
+ if ( $this->is_plain_text ) {
250
+ $this->content_type = 'text/plain';
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Set the subject
256
+ *
257
+ * @since 2.03.04
258
+ */
259
+ private function set_subject() {
260
+ if ( empty( $this->settings['email_subject'] ) ) {
261
+ $this->subject = sprintf( __( '%1$s Form submitted on %2$s', 'formidable' ), $this->form->name, '[sitename]' );
262
+ } else {
263
+ $this->subject = $this->settings['email_subject'];
264
+ }
265
+
266
+ $this->subject = FrmFieldsHelper::basic_replace_shortcodes( $this->subject, $this->form, $this->entry );
267
+
268
+ $args = array(
269
+ 'form' => $this->form,
270
+ 'entry' => $this->entry,
271
+ 'email_key' => $this->email_key,
272
+ );
273
+ $this->subject = apply_filters( 'frm_email_subject', $this->subject, $args );
274
+
275
+ $this->subject = wp_specialchars_decode( strip_tags( stripslashes( $this->subject ) ), ENT_QUOTES );
276
+ }
277
+
278
+ /**
279
+ * Set the email message
280
+ *
281
+ * @since 2.03.04
282
+ */
283
+ private function set_message() {
284
+ $this->message = FrmFieldsHelper::basic_replace_shortcodes( $this->settings['email_message'], $this->form, $this->entry );
285
+
286
+ $prev_mail_body = $this->message;
287
+ $pass_entry = clone $this->entry; // make a copy to prevent changes by reference
288
+ $mail_body = FrmEntriesHelper::replace_default_message( $prev_mail_body, array(
289
+ 'id' => $this->entry->id,
290
+ 'entry' => $pass_entry,
291
+ 'plain_text' => $this->is_plain_text,
292
+ 'user_info' => $this->include_user_info,
293
+ ) );
294
+
295
+ // Add the user info if it isn't already included
296
+ if ( $this->include_user_info && $prev_mail_body == $mail_body ) {
297
+ $data = maybe_unserialize( $this->entry->description );
298
+ $mail_body .= "\r\n\r\n" . __( 'User Information', 'formidable' ) . "\r\n";
299
+ $mail_body .= __( 'IP Address', 'formidable' ) . ': ' . $this->entry->ip . "\r\n";
300
+ $mail_body .= __( 'User-Agent (Browser/OS)', 'formidable' ) . ': ' . FrmEntryFormat::get_browser( $data['browser'] ) . "\r\n";
301
+ $mail_body .= __( 'Referrer', 'formidable' ) . ': ' . $data['referrer'] . "\r\n";
302
+ }
303
+
304
+ $this->message = $mail_body;
305
+
306
+ $this->message = do_shortcode( $this->message );
307
+
308
+ if ( $this->is_plain_text ) {
309
+ $this->message = wp_specialchars_decode( strip_tags( $this->message ), ENT_QUOTES );
310
+ }
311
+
312
+ $this->message = apply_filters( 'frm_email_message', $this->message, $this->package_atts() );
313
+ }
314
+
315
+ /**
316
+ * Set the attachments for an email message
317
+ *
318
+ * @since 2.03.04
319
+ */
320
+ private function set_attachments() {
321
+ $args = array(
322
+ 'entry' => $this->entry,
323
+ 'email_key' => $this->email_key,
324
+ );
325
+
326
+ $this->attachments = apply_filters( 'frm_notification_attachment', array(), $this->form, $args );
327
+ }
328
+
329
+ /**
330
+ * Check if an email should send
331
+ *
332
+ * @since 2.03.04
333
+ *
334
+ * @return bool|mixed|void
335
+ */
336
+ public function should_send() {
337
+ if ( ! $this->has_recipients() ) {
338
+ $send = false;
339
+ } else {
340
+
341
+ /**
342
+ * Stop an email based on the message, subject, recipient,
343
+ * or any information included in the email header
344
+ *
345
+ * @since 2.2.8
346
+ */
347
+ $send = apply_filters( 'frm_send_email', true, array(
348
+ 'message' => $this->message,
349
+ 'subject' => $this->subject,
350
+ 'recipient' => $this->to,
351
+ 'header' => $this->package_header(),
352
+ ) );
353
+ }
354
+
355
+ return $send;
356
+ }
357
+
358
+ /**
359
+ * Check if an email has any recipients
360
+ *
361
+ * @since 2.03.04
362
+ *
363
+ * @return bool
364
+ */
365
+ private function has_recipients() {
366
+ if ( empty( $this->to ) && empty( $this->cc ) && empty( $this->bcc ) ) {
367
+ return false;
368
+ } else {
369
+ return true;
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Send an email
375
+ *
376
+ * @since 2.03.04
377
+ *
378
+ * @return bool
379
+ */
380
+ public function send() {
381
+ $this->remove_buddypress_filters();
382
+ $this->add_mandrill_filter();
383
+
384
+ $sent = false;
385
+ if ( count( $this->to ) > 1 && $this->is_single_recipient ) {
386
+ foreach ( $this->to as $recipient ) {
387
+ $sent = $this->send_single( $recipient );
388
+ }
389
+ } else {
390
+ $sent = $this->send_single( $this->to );
391
+ }
392
+
393
+ $this->remove_mandrill_filter();
394
+
395
+ return $sent;
396
+ }
397
+
398
+ /**
399
+ * Send a single email
400
+ *
401
+ * @since 2.03.04
402
+ *
403
+ * @param array|string $recipient
404
+ *
405
+ * @return bool
406
+ */
407
+ private function send_single( $recipient ) {
408
+ $header = apply_filters( 'frm_email_header', $this->package_header(), array(
409
+ 'to_email' => $recipient,
410
+ 'subject' => $this->subject,
411
+ ) );
412
+
413
+ $subject = $this->encode_subject( $this->subject );
414
+
415
+ $sent = wp_mail( $recipient, $subject, $this->message, $header, $this->attachments );
416
+
417
+ if ( ! $sent ) {
418
+ $header = 'From: ' . $this->from . "\r\n";
419
+ $recipient = implode( ',', (array) $recipient );
420
+ $sent = mail( $recipient, $subject, $this->message, $header );
421
+ }
422
+
423
+ do_action( 'frm_notification', $recipient, $subject, $this->message );
424
+
425
+ return $sent;
426
+ }
427
+
428
+ /**
429
+ * Package the email header
430
+ *
431
+ * @since 2.03.04
432
+ *
433
+ * @return array
434
+ */
435
+ private function package_header() {
436
+ $header = array();
437
+
438
+ if ( ! empty( $this->cc ) ) {
439
+ $header[] = 'CC: ' . implode( ',', $this->cc );
440
+ }
441
+
442
+ if ( ! empty( $this->bcc ) ) {
443
+ $header[] = 'BCC: ' . implode( ',', $this->bcc );
444
+ }
445
+
446
+ $header[] = 'From: ' . $this->from;
447
+ $header[] = 'Reply-To: ' . $this->reply_to;
448
+ $header[] = 'Content-Type: ' . $this->content_type . '; charset="' . esc_attr( $this->charset ) . '"';
449
+
450
+ return $header;
451
+ }
452
+
453
+ /**
454
+ * Get the userID field ID and key for email settings
455
+ *
456
+ * @since 2.03.04
457
+ *
458
+ * @param $form_id
459
+ *
460
+ * @return array
461
+ */
462
+ private function get_user_id_args( $form_id ) {
463
+ $user_id_args = array(
464
+ 'field_id' => '',
465
+ 'field_key' => '',
466
+ );
467
+
468
+ $user_id_args['field_id'] = FrmEmailHelper::get_user_id_field_for_form( $form_id );
469
+ if ( $user_id_args['field_id'] ) {
470
+ $user_id_args['field_key'] = FrmField::get_key_by_id( $user_id_args['field_id'] );
471
+ }
472
+
473
+ return $user_id_args;
474
+ }
475
+
476
+ /**
477
+ * Prepare the to, cc, bcc, reply_to, and from setting
478
+ *
479
+ * @since 2.03.04
480
+ *
481
+ * @param string $value
482
+ * @param array $user_id_args
483
+ *
484
+ * @return string
485
+ */
486
+ private function prepare_email_setting( $value, $user_id_args ) {
487
+ if ( strpos( $value, '[' . $user_id_args['field_id'] . ']' ) !== false ) {
488
+ $value = str_replace( '[' . $user_id_args['field_id'] . ']', '[' . $user_id_args['field_id'] . ' show="user_email"]', $value );
489
+ } else if ( strpos( $value, '[' . $user_id_args['field_key'] . ']' ) !== false ) {
490
+ $value = str_replace( '[' . $user_id_args['field_key'] . ']', '[' . $user_id_args['field_key'] . ' show="user_email"]', $value );
491
+ }
492
+
493
+ $value = FrmFieldsHelper::basic_replace_shortcodes( $value, $this->form, $this->entry );
494
+
495
+ // Remove brackets and add a space in case there isn't one
496
+ $value = str_replace( '<', ' ', $value );
497
+ $value = str_replace( array( '"', '>' ), '', $value );
498
+
499
+ return $value;
500
+ }
501
+
502
+ /**
503
+ * Extract the emails from cc and bcc. Allow separation by , or ;.
504
+ * Trim the emails here as well
505
+ *
506
+ * @since 2.03.04
507
+ *
508
+ * @param string $emails
509
+ * @return array|string $emails
510
+ */
511
+ private function explode_emails( $emails ) {
512
+ $emails = ( ! empty( $emails ) ? preg_split( '/(,|;)/', $emails ) : '' );
513
+ if ( is_array( $emails ) ) {
514
+ $emails = array_map( 'trim', $emails );
515
+ } else {
516
+ $emails = trim( $emails );
517
+ }
518
+
519
+ return $emails;
520
+ }
521
+
522
+ /**
523
+ * Format the recipients( to, cc, bcc)
524
+ *
525
+ * @param array $recipients
526
+ *
527
+ * @return array
528
+ */
529
+ private function format_recipients( $recipients ) {
530
+ if ( empty( $recipients ) ) {
531
+ return $recipients;
532
+ }
533
+
534
+ foreach ( $recipients as $key => $val ) {
535
+ $val = trim( $val );
536
+
537
+ if ( is_email( $val ) ) {
538
+ // If a plain email is used, no formatting is needed
539
+ continue;
540
+ } else {
541
+ $parts = explode( ' ', $val );
542
+ $email = end( $parts );
543
+
544
+ if ( is_email( $email ) ) {
545
+ // If user enters a name and email
546
+ $name = trim( str_replace( $email, '', $val ) );
547
+ } else {
548
+ // If user enters a name without an email
549
+ unset( $recipients[ $key ] );
550
+ continue;
551
+ }
552
+ }
553
+
554
+ $recipients[ $key ] = $name . ' <' . $email . '>';
555
+ }
556
+
557
+ return $recipients;
558
+ }
559
+
560
+ /**
561
+ * Format the From header
562
+ *
563
+ * @param string $from
564
+ *
565
+ * @return string
566
+ */
567
+ private function format_from( $from ) {
568
+ $from = trim( $from );
569
+
570
+ if ( is_email( $from ) ) {
571
+ // If a plain email is used, add the site name so "WordPress" doesn't get added
572
+ $from_name = wp_specialchars_decode( FrmAppHelper::site_name(), ENT_QUOTES );
573
+ $from_email = $from;
574
+ } else {
575
+ list( $from_name, $from_email ) = $this->get_name_and_email_for_sender( $from );
576
+ }
577
+
578
+ // if sending the email from a yahoo address, change it to the WordPress default
579
+ if ( strpos( $from_email, '@yahoo.com' ) ) {
580
+
581
+ // Get the site domain and get rid of www.
582
+ $sitename = strtolower( FrmAppHelper::get_server_value( 'SERVER_NAME' ) );
583
+ if ( substr( $sitename, 0, 4 ) == 'www.' ) {
584
+ $sitename = substr( $sitename, 4 );
585
+ }
586
+
587
+ $from_email = 'wordpress@' . $sitename;
588
+ }
589
+
590
+ $from = $from_name . ' <' . $from_email . '>';
591
+
592
+ return $from;
593
+ }
594
+
595
+ /**
596
+ * Format the Reply To property
597
+ *
598
+ * @since 2.03.04
599
+ *
600
+ * @param string $reply_to
601
+ *
602
+ * @return string
603
+ */
604
+ private function format_reply_to( $reply_to ) {
605
+ $reply_to = trim( $reply_to );
606
+
607
+ if ( empty( $reply_to ) ) {
608
+ return $this->from;
609
+ } else if ( is_email( $reply_to ) ) {
610
+ return $reply_to;
611
+ } else {
612
+ list( $name, $email ) = $this->get_name_and_email_for_sender( $reply_to );
613
+ }
614
+
615
+ return $name . ' <' . $email . '>';
616
+ }
617
+
618
+ /**
619
+ * Get the name and email for the From or Reply To header
620
+ *
621
+ * @since 2.03.04
622
+ *
623
+ * @param string $sender
624
+ *
625
+ * @return array
626
+ */
627
+ private function get_name_and_email_for_sender( $sender ) {
628
+ $parts = explode( ' ', $sender );
629
+ $end = end( $parts );
630
+
631
+ if ( is_email( $end ) ) {
632
+ $name = trim( str_replace( $end, '', $sender ) );
633
+ } else {
634
+ // Only a name was entered in the From or Reply To field
635
+ $name = $sender;
636
+ $end = get_option( 'admin_email' );
637
+ }
638
+
639
+ return array( $name, $end );
640
+ }
641
+
642
+ /**
643
+ * Remove phone numbers from To addresses
644
+ * Send the phone numbers to the frm_send_to_not_email hook
645
+ *
646
+ * @since 2.03.04
647
+ */
648
+ private function handle_phone_numbers() {
649
+
650
+ foreach ( $this->to as $key => $recipient ) {
651
+ if ( $recipient != '[admin_email]' && ! is_email( $recipient ) ) {
652
+ $recipient = explode( ' ', $recipient );
653
+
654
+ if ( is_email( end( $recipient ) ) ) {
655
+ continue;
656
+ }
657
+
658
+ do_action( 'frm_send_to_not_email', array(
659
+ 'e' => $recipient,
660
+ 'subject' => $this->subject,
661
+ 'mail_body' => $this->message,
662
+ 'reply_to' => $this->reply_to,
663
+ 'from' => $this->from,
664
+ 'plain_text' => $this->is_plain_text,
665
+ 'attachments' => $this->attachments,
666
+ 'form' => $this->form,
667
+ 'email_key' => $key,
668
+ ) );
669
+
670
+ // Remove phone number from to addresses
671
+ unset( $this->to[ $key ] );
672
+ }
673
+ }
674
+ }
675
+
676
+ /**
677
+ * Package an array of FrmEmail properties
678
+ *
679
+ * @since 2.03.04
680
+ *
681
+ * @return array
682
+ */
683
+ public function package_atts() {
684
+ return array(
685
+ 'to_email' => $this->to,
686
+ 'cc' => $this->cc,
687
+ 'bcc' => $this->bcc,
688
+ 'from' => $this->from,
689
+ 'reply_to' => $this->reply_to,
690
+ 'subject' => $this->subject,
691
+ 'message' => $this->message,
692
+ 'attachments' => $this->attachments,
693
+ 'plain_text' => $this->is_plain_text,
694
+ );
695
+ }
696
+
697
+ /**
698
+ * Remove the Buddypress email filters
699
+ *
700
+ * @since 2.03.04
701
+ */
702
+ private function remove_buddypress_filters() {
703
+ remove_filter( 'wp_mail_from', 'bp_core_email_from_address_filter' );
704
+ remove_filter( 'wp_mail_from_name', 'bp_core_email_from_name_filter' );
705
+ }
706
+
707
+ /**
708
+ * Add Mandrill line break filter
709
+ * Remove line breaks in HTML emails to prevent conflicts with Mandrill
710
+ *
711
+ * @since 2.03.04
712
+ */
713
+ private function add_mandrill_filter() {
714
+ if ( ! $this->is_plain_text ) {
715
+ add_filter( 'mandrill_nl2br', 'FrmEmailHelper::remove_mandrill_br' );
716
+ }
717
+ }
718
+
719
+ /**
720
+ * Remove Mandrill line break filter
721
+ *
722
+ * @since 2.03.04
723
+ */
724
+ private function remove_mandrill_filter() {
725
+ remove_filter( 'mandrill_nl2br', 'FrmEmailHelper::remove_mandrill_br' );
726
+ }
727
+
728
+ /**
729
+ * Encode the email subject
730
+ *
731
+ * @param string $subject
732
+ *
733
+ * @return string
734
+ */
735
+ private function encode_subject( $subject ) {
736
+ if ( apply_filters( 'frm_encode_subject', 1, $subject ) ) {
737
+ $subject = '=?' . $this->charset . '?B?' . base64_encode( $subject ) . '?=';
738
+ }
739
+
740
+ return $subject;
741
+ }
742
+
743
+ }
classes/models/FrmEntryFormat.php CHANGED
@@ -209,7 +209,6 @@ class FrmEntryFormat {
209
  * @since 2.03.02
210
  */
211
  public static function prepare_field_output( $atts, &$val ) {
212
- self::textarea_display_value( $atts['field']->type, $atts['plain_text'], $val );
213
  $val = apply_filters( 'frm_display_' . $atts['field']->type . '_value_custom', $val, array(
214
  'field' => $atts['field'], 'atts' => $atts,
215
  ) );
@@ -218,16 +217,6 @@ class FrmEntryFormat {
218
  self::maybe_strip_html( $atts['plain_text'], $val );
219
  }
220
 
221
- /**
222
- * Replace returns with HTML line breaks for display
223
- * @since 2.0.9
224
- */
225
- public static function textarea_display_value( $type, $plain_text, &$value ) {
226
- if ( $type == 'textarea' && ! $plain_text ) {
227
- $value = str_replace( array( "\r\n", "\r", "\n" ), ' <br/>', $value );
228
- }
229
- }
230
-
231
  /**
232
  * @since 2.03.02
233
  */
@@ -351,7 +340,8 @@ class FrmEntryFormat {
351
 
352
  // see how many we have
353
  $i = count($matches['browser']);
354
- if ( $i != 1 ) {
 
355
  //we will have two since we are not using 'other' argument yet
356
  //see if version is before or after the name
357
  if ( strripos( $u_agent, 'Version' ) < strripos( $u_agent, $ub ) ) {
@@ -359,8 +349,10 @@ class FrmEntryFormat {
359
  } else {
360
  $version = $matches['version'][1];
361
  }
362
- } else {
363
  $version = $matches['version'][0];
 
 
364
  }
365
 
366
  // check if we have a number
@@ -513,4 +505,11 @@ class FrmEntryFormat {
513
  private static function table_row_style( $atts ) {
514
  return ( $atts['odd'] ? $atts['bg_color'] : $atts['bg_color_alt'] );
515
  }
 
 
 
 
 
 
 
516
  }
209
  * @since 2.03.02
210
  */
211
  public static function prepare_field_output( $atts, &$val ) {
 
212
  $val = apply_filters( 'frm_display_' . $atts['field']->type . '_value_custom', $val, array(
213
  'field' => $atts['field'], 'atts' => $atts,
214
  ) );
217
  self::maybe_strip_html( $atts['plain_text'], $val );
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
220
  /**
221
  * @since 2.03.02
222
  */
340
 
341
  // see how many we have
342
  $i = count($matches['browser']);
343
+
344
+ if ( $i > 1 ) {
345
  //we will have two since we are not using 'other' argument yet
346
  //see if version is before or after the name
347
  if ( strripos( $u_agent, 'Version' ) < strripos( $u_agent, $ub ) ) {
349
  } else {
350
  $version = $matches['version'][1];
351
  }
352
+ } else if ( $i === 1 ) {
353
  $version = $matches['version'][0];
354
+ } else {
355
+ $version = '';
356
  }
357
 
358
  // check if we have a number
505
  private static function table_row_style( $atts ) {
506
  return ( $atts['odd'] ? $atts['bg_color'] : $atts['bg_color_alt'] );
507
  }
508
+
509
+ /**
510
+ * @deprecated 2.03.04
511
+ */
512
+ public static function textarea_display_value() {
513
+ _deprecated_function( __FUNCTION__, '2.03.04', 'custom code' );
514
+ }
515
  }
classes/models/FrmNotification.php CHANGED
@@ -1,447 +1,84 @@
1
  <?php
2
 
 
3
  class FrmNotification {
4
  public function __construct() {
5
- if ( ! defined('ABSPATH') ) {
6
- die('You are not allowed to call this page directly.');
7
- }
8
- add_action('frm_trigger_email_action', 'FrmNotification::trigger_email', 10, 3);
9
- }
10
-
11
- public static function trigger_email( $action, $entry, $form ) {
12
- $notification = $action->post_content;
13
- $email_key = $action->ID;
14
-
15
- // Set the subject
16
- if ( empty($notification['email_subject']) ) {
17
- $notification['email_subject'] = sprintf(__( '%1$s Form submitted on %2$s', 'formidable' ), $form->name, '[sitename]');
18
- }
19
-
20
- $plain_text = $notification['plain_text'] ? true : false;
21
-
22
- //Filter these fields
23
- $filter_fields = array(
24
- 'email_to', 'cc', 'bcc',
25
- 'reply_to', 'from',
26
- 'email_subject', 'email_message',
27
- );
28
-
29
- add_filter('frm_plain_text_email', ($plain_text ? '__return_true' : '__return_false'));
30
-
31
- //Get all values in entry in order to get User ID field ID
32
- $values = FrmEntryMeta::getAll( array( 'it.field_id !' => 0, 'it.item_id' => $entry->id ), ' ORDER BY fi.field_order' );
33
- $user_id_field = '';
34
- $user_id_key = '';
35
- foreach ( $values as $value ) {
36
- if ( $value->field_type == 'user_id' ) {
37
- $user_id_field = $value->field_id;
38
- $user_id_key = $value->field_key;
39
- break;
40
- }
41
- unset($value);
42
- }
43
-
44
- //Filter and prepare the email fields
45
- foreach ( $filter_fields as $f ) {
46
- //Don't allow empty From
47
- if ( $f == 'from' && empty( $notification[ $f ] ) ) {
48
- $notification[ $f ] = '[admin_email]';
49
- } else if ( in_array( $f, array( 'email_to', 'cc', 'bcc', 'reply_to', 'from' ) ) ) {
50
- //Remove brackets
51
- //Add a space in case there isn't one
52
- $notification[ $f ] = str_replace( '<', ' ', $notification[ $f ] );
53
- $notification[ $f ] = str_replace( array( '"', '>' ), '', $notification[ $f ] );
54
-
55
- //Switch userID shortcode to email address
56
- if ( strpos( $notification[ $f ], '[' . $user_id_field . ']' ) !== false || strpos( $notification[ $f ], '[' . $user_id_key . ']' ) !== false ) {
57
- $user_data = get_userdata( $entry->metas[ $user_id_field ] );
58
- $user_email = $user_data->user_email;
59
- $notification[ $f ] = str_replace( array( '[' . $user_id_field . ']', '[' . $user_id_key . ']' ), $user_email, $notification[ $f ] );
60
- }
61
- }
62
-
63
- $notification[ $f ] = FrmFieldsHelper::basic_replace_shortcodes( $notification[ $f ], $form, $entry );
64
- }
65
-
66
- //Put recipients, cc, and bcc into an array if they aren't empty
67
- $to_emails = self::explode_emails( $notification['email_to'] );
68
- $cc = self::explode_emails( $notification['cc'] );
69
- $bcc = self::explode_emails( $notification['bcc'] );
70
-
71
- $to_emails = apply_filters('frm_to_email', $to_emails, $values, $form->id, compact('email_key', 'entry', 'form'));
72
-
73
- // Stop now if there aren't any recipients
74
- if ( empty( $to_emails ) && empty( $cc ) && empty( $bcc ) ) {
75
- return;
76
- }
77
-
78
- $to_emails = array_unique( (array) $to_emails );
79
-
80
- $prev_mail_body = $notification['email_message'];
81
- $pass_entry = clone $entry; // make a copy to prevent changes by reference
82
- $mail_body = FrmEntriesHelper::replace_default_message( $prev_mail_body, array(
83
- 'id' => $entry->id, 'entry' => $pass_entry, 'plain_text' => $plain_text,
84
- 'user_info' => ( isset( $notification['inc_user_info'] ) ? $notification['inc_user_info'] : false ),
85
- ) );
86
-
87
- // Add the user info if it isn't already included
88
- if ( $notification['inc_user_info'] && $prev_mail_body == $mail_body ) {
89
- $data = maybe_unserialize($entry->description);
90
- $mail_body .= "\r\n\r\n" . __( 'User Information', 'formidable' ) . "\r\n";
91
- $mail_body .= __( 'IP Address', 'formidable' ) . ': ' . $entry->ip . "\r\n";
92
- $mail_body .= __( 'User-Agent (Browser/OS)', 'formidable' ) . ': ' . FrmEntryFormat::get_browser( $data['browser'] ) . "\r\n";
93
- $mail_body .= __( 'Referrer', 'formidable' ) . ': ' . $data['referrer'] . "\r\n";
94
- }
95
- unset($prev_mail_body);
96
-
97
- // Add attachments
98
- $attachments = apply_filters('frm_notification_attachment', array(), $form, compact('entry', 'email_key') );
99
-
100
- if ( ! empty($notification['email_subject']) ) {
101
- $notification['email_subject'] = apply_filters('frm_email_subject', $notification['email_subject'], compact('form', 'entry', 'email_key'));
102
- }
103
-
104
- // check for a phone number
105
- foreach ( (array) $to_emails as $email_key => $e ) {
106
- if ( $e != '[admin_email]' && ! is_email($e) ) {
107
- $e = explode(' ', $e);
108
-
109
- //If to_email has name <test@mail.com> format
110
- if ( is_email(end($e)) ) {
111
- continue;
112
- }
113
-
114
- do_action('frm_send_to_not_email', array(
115
- 'e' => $e,
116
- 'subject' => $notification['email_subject'],
117
- 'mail_body' => $mail_body,
118
- 'reply_to' => $notification['reply_to'],
119
- 'from' => $notification['from'],
120
- 'plain_text' => $plain_text,
121
- 'attachments' => $attachments,
122
- 'form' => $form,
123
- 'email_key' => $email_key,
124
- ) );
125
-
126
- unset( $to_emails[ $email_key ] );
127
- }
128
- }
129
-
130
- /**
131
- * Send a separate email for email address in the "to" section
132
- * @since 2.2.13
133
- */
134
- $send_single_recipient = apply_filters( 'frm_send_separate_emails', false, compact( 'action', 'entry', 'form' ) );
135
-
136
- // Send the email now
137
- $sent_to = self::send_email( array(
138
- 'to_email' => $to_emails,
139
- 'subject' => $notification['email_subject'],
140
- 'message' => $mail_body,
141
- 'from' => $notification['from'],
142
- 'plain_text' => $plain_text,
143
- 'reply_to' => $notification['reply_to'],
144
- 'attachments' => $attachments,
145
- 'cc' => $cc,
146
- 'bcc' => $bcc,
147
- 'single_recipient' => $send_single_recipient,
148
- ) );
149
-
150
- return $sent_to;
151
- }
152
-
153
- public function entry_created( $entry_id, $form_id ) {
154
- $new_function = 'FrmFormActionsController::trigger_actions("create", ' . $form_id . ', ' . $entry_id . ', "email")';
155
- _deprecated_function( __FUNCTION__, '2.0', $new_function );
156
- FrmFormActionsController::trigger_actions('create', $form_id, $entry_id, 'email');
157
- }
158
-
159
- public function send_notification_email( $to_email, $subject, $message, $from = '', $from_name = '', $plain_text = true, $attachments = array(), $reply_to = '' ) {
160
- _deprecated_function( __FUNCTION__, '2.0', 'FrmNotification::send_email' );
161
 
162
- return self::send_email(compact(
163
- 'to_email', 'subject', 'message',
164
- 'from', 'from_name', 'plain_text',
165
- 'attachments', 'reply_to'
166
- ));
167
- }
168
 
169
  /**
170
- * Extract the emails from cc and bcc. Allow separation by , or ;.
171
- * Trim the emails here as well
172
  *
173
- * @since 2.0.1
 
 
174
  */
175
- private static function explode_emails( $emails ) {
176
- $emails = ( ! empty( $emails ) ? preg_split( '/(,|;)/', $emails ) : '' );
177
- if ( is_array( $emails ) ) {
178
- $emails = array_map( 'trim', $emails );
179
- } else {
180
- $emails = trim( $emails );
181
- }
182
- return $emails;
183
- }
184
-
185
- /**
186
- * Put To, BCC, CC, Reply To, and From fields in Name <test@mail.com> format
187
- * Formats that should work: Name, "Name", test@mail.com, <test@mail.com>, Name <test@mail.com>,
188
- * "Name" <test@mail.com>, Name test@mail.com, "Name" test@mail.com, Name<test@mail.com>, "Name"<test@mail.com>
189
- * "First Last" <test@mail.com>
190
- *
191
- * Things that won't work: First Last (with no email entered)
192
- * @since 2.0
193
- * @param array $atts array of email fields, pass by reference
194
- * @param $admin_email
195
- */
196
- private static function format_email_fields( &$atts, $admin_email ) {
197
-
198
- // If from is empty or is set to admin_email, set it now
199
- $atts['from'] = ( empty($atts['from']) || $atts['from'] == '[admin_email]' ) ? $admin_email : $atts['from'];
200
-
201
- // Filter values in these fields
202
- $filter_fields = array( 'to_email', 'bcc', 'cc', 'from', 'reply_to' );
203
-
204
- foreach ( $filter_fields as $f ) {
205
- // If empty, just skip it
206
- if ( empty( $atts[ $f ] ) ) {
207
- continue;
208
- }
209
-
210
- // to_email, cc, and bcc can be an array
211
- if ( is_array( $atts[ $f ] ) ) {
212
- foreach ( $atts[ $f ] as $key => $val ) {
213
- self::format_single_field( $atts, $f, $val, $key );
214
- unset( $key, $val );
215
- }
216
- unset($f);
217
- continue;
218
- }
219
-
220
- self::format_single_field( $atts, $f, $atts[ $f ] );
221
- }
222
-
223
- // If reply-to isn't set, make it match the from settings
224
- if ( empty( $atts['reply_to'] ) ) {
225
- $atts['reply_to'] = self::get_email_from_formatted_string( $atts['from'] );
226
- }
227
-
228
- if ( ! is_array($atts['to_email']) && '[admin_email]' == $atts['to_email'] ) {
229
- $atts['to_email'] = $admin_email;
230
- }
231
- }
232
-
233
- private static function get_email_from_formatted_string( $value ) {
234
- if ( strpos( $value, '<' ) !== false ) {
235
- preg_match_all( '/\<([^)]+)\>/', $value, $emails );
236
- $value = $emails[1][0];
237
- }
238
- return $value;
239
- }
240
-
241
- /**
242
- * Format individual email fields
243
- *
244
- * @since 2.0
245
- * @param array $atts pass by reference
246
- * @param string $f (to, from, reply_to, etc)
247
- * @param string $val value saved in field
248
- * @param int $key if in array, this will be set
249
- */
250
- private static function format_single_field( &$atts, $f, $val, $key = false ) {
251
- $val = trim($val);
252
-
253
- // If just a plain email is used
254
- if ( is_email($val) ) {
255
- // add sender's name if not included in $from
256
- if ( $f == 'from' ) {
257
- $part_2 = $atts[ $f ];
258
- $part_1 = $atts['from_name'] ? $atts['from_name'] : wp_specialchars_decode( FrmAppHelper::site_name(), ENT_QUOTES );
259
- } else {
260
- return;
261
- }
262
- } else {
263
- $parts = explode(' ', $val);
264
- $part_2 = end($parts);
265
-
266
- // If inputted correcly, $part_2 should be an email
267
- if ( is_email( $part_2 ) ) {
268
- $part_1 = trim( str_replace( $part_2, '', $val ) );
269
- } else if ( in_array( $f, array( 'from', 'reply_to' ) ) ) {
270
- // In case someone just puts a name in the From or Reply To field
271
- $part_1 = $val;
272
- $part_2 = get_option('admin_email');
273
- } else {
274
- // In case someone just puts a name in any other email field
275
- if ( false !== $key ) {
276
- unset( $atts[ $f ][ $key ] );
277
- return;
278
- }
279
- $atts[ $f ] = '';
280
- return;
281
- }
282
- }
283
-
284
- // if sending the email from a yahoo address, change it to the WordPress default
285
- if ( $f == 'from' && strpos( $part_2, '@yahoo.com' ) ) {
286
- // Get the site domain and get rid of www.
287
- $sitename = strtolower( FrmAppHelper::get_server_value( 'SERVER_NAME' ) );
288
- if ( substr( $sitename, 0, 4 ) == 'www.' ) {
289
- $sitename = substr( $sitename, 4 );
290
- }
291
-
292
- $part_2 = 'wordpress@' . $sitename;
293
- }
294
-
295
- // Set up formatted value
296
- $final_val = str_replace( '"', '', $part_1 ) . ' <' . $part_2 . '>';
297
-
298
- // If value is an array
299
- if ( false !== $key ) {
300
- $atts[ $f ][ $key ] = $final_val;
301
- return;
302
- }
303
- $atts[ $f ] = $final_val;
304
- }
305
-
306
- public static function send_email( $atts ) {
307
- $admin_email = get_option('admin_email');
308
- $defaults = array(
309
- 'to_email' => $admin_email,
310
- 'subject' => '',
311
- 'message' => '',
312
- 'from' => $admin_email,
313
- 'from_name' => '',
314
- 'cc' => '',
315
- 'bcc' => '',
316
- 'plain_text' => true,
317
- 'reply_to' => $admin_email,
318
- 'attachments' => array(),
319
- 'single_recipient' => false,
320
- );
321
- $atts = wp_parse_args($atts, $defaults);
322
-
323
- // Put To, BCC, CC, Reply To, and From fields in the correct format
324
- self::format_email_fields( $atts, $admin_email );
325
-
326
- $header = array();
327
- $header[] = 'From: ' . $atts['from'];
328
-
329
- //Allow for cc and bcc arrays
330
- $array_fields = array( 'CC' => $atts['cc'], 'BCC' => $atts['bcc'] );
331
- $cc = array( 'CC' => array(), 'BCC' => array() );
332
- foreach ( $array_fields as $key => $a_field ) {
333
- if ( empty($a_field) ) {
334
- continue;
335
- }
336
-
337
- foreach ( (array) $a_field as $email ) {
338
- $cc[ $key ][] = $email;
339
- }
340
- unset($key, $a_field);
341
- }
342
- $cc = array_filter( $cc ); // remove cc and bcc if they are empty
343
-
344
- foreach ( $cc as $k => $v ) {
345
- $header[] = $k . ': ' . implode( ',', $v );
346
- }
347
-
348
- $content_type = $atts['plain_text'] ? 'text/plain' : 'text/html';
349
- $atts['charset'] = get_option('blog_charset');
350
-
351
- $header[] = 'Reply-To: ' . $atts['reply_to'];
352
- $header[] = 'Content-Type: ' . $content_type . '; charset="' . esc_attr( $atts['charset'] ) . '"';
353
- $atts['subject'] = wp_specialchars_decode( strip_tags( stripslashes( $atts['subject'] ) ), ENT_QUOTES );
354
-
355
- $atts['message'] = do_shortcode( $atts['message'] );
356
-
357
- if ( $atts['plain_text'] ) {
358
- $atts['message'] = wp_specialchars_decode( strip_tags( $atts['message'] ), ENT_QUOTES );
359
- } else {
360
- // remove line breaks in HTML emails to prevent conflicts with Mandrill
361
- add_filter( 'mandrill_nl2br', 'FrmNotification::remove_mandrill_br' );
362
- }
363
- $atts['message'] = apply_filters( 'frm_email_message', $atts['message'], $atts );
364
 
365
- /**
366
- * Stop an email based on the message, subject, recipient,
367
- * or any information included in the email header
368
- * @since 2.2.8
369
- */
370
- $continue_sending = apply_filters( 'frm_send_email', true, array(
371
- 'message' => $atts['message'], 'subject' => $atts['subject'],
372
- 'recipient' => $atts['to_email'], 'header' => $header,
373
- ) );
374
- if ( ! $continue_sending ) {
375
  return;
376
  }
377
 
378
- self::remove_buddypress_filters();
379
-
380
- $sent = '';
381
- if ( is_array( $atts['to_email'] ) && $atts['single_recipient'] ) {
382
- foreach ( $atts['to_email'] as $recipient ) {
383
- $sent = self::send_single_email( $recipient, $atts, $header );
384
- }
385
- } else {
386
- $sent = self::send_single_email( $atts['to_email'], $atts, $header );
387
- }
388
-
389
- // remove the filter now so other emails can still use it
390
- remove_filter( 'mandrill_nl2br', 'FrmNotification::remove_mandrill_br' );
391
-
392
- if ( $sent ) {
393
- return self::return_emails_sent( $atts );
394
- }
395
- }
396
-
397
- private static function send_single_email( $recipient, $atts, $header ) {
398
- $header = apply_filters( 'frm_email_header', $header, array(
399
- 'to_email' => $recipient, 'subject' => $atts['subject'],
400
- ) );
401
 
402
- self::encode_subject( $atts['charset'], $atts['subject'] );
403
-
404
- $sent = wp_mail( $recipient, $atts['subject'], $atts['message'], $header, $atts['attachments'] );
405
- if ( ! $sent ) {
406
- $header = 'From: ' . $atts['from'] . "\r\n";
407
- $recipient = implode( ',', (array) $recipient );
408
- $sent = mail( $recipient, $atts['subject'], $atts['message'], $header );
409
  }
410
-
411
- do_action( 'frm_notification', $recipient, $atts['subject'], $atts['message'] );
412
-
413
- return $sent;
414
  }
415
 
416
- private static function encode_subject( $charset, &$subject ) {
417
- if ( apply_filters('frm_encode_subject', 1, $subject ) ) {
418
- $subject = '=?' . $charset . '?B?' . base64_encode( $subject ) . '?=';
419
- }
 
 
 
420
  }
421
 
422
- private static function remove_buddypress_filters() {
423
- remove_filter( 'wp_mail_from', 'bp_core_email_from_address_filter' );
424
- remove_filter( 'wp_mail_from_name', 'bp_core_email_from_name_filter' );
 
 
 
 
425
  }
426
 
427
- private static function return_emails_sent( $atts ) {
428
- $sent_to = array_merge( (array) $atts['to_email'], (array) $atts['cc'], (array) $atts['bcc'] );
429
- $sent_to = array_filter( $sent_to );
430
-
 
 
 
 
431
  if ( apply_filters( 'frm_echo_emails', false ) ) {
 
 
 
 
432
  $temp = str_replace( '<', '&lt;', $sent_to );
433
- echo ' ' . FrmAppHelper::kses( implode(', ', (array) $temp ) );
434
  }
435
- return $sent_to;
436
  }
437
 
438
  /**
439
- * This function should only be fired when Mandrill is sending an HTML email
440
- * This will make sure Mandrill doesn't mess with our HTML emails
441
- *
442
- * @since 2.0
443
  */
444
  public static function remove_mandrill_br() {
445
- return false;
 
 
 
 
 
 
 
 
446
  }
447
  }
1
  <?php
2
 
3
+ // TODO: change class name to FrmEmailController by 08/2017 or later
4
  class FrmNotification {
5
  public function __construct() {
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ die( 'You are not allowed to call this page directly.' );
8
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ self::hook_emails_to_action();
11
+ }
 
 
 
 
12
 
13
  /**
14
+ * Trigger an email action
 
15
  *
16
+ * @param object $action
17
+ * @param object $entry
18
+ * @param object $form
19
  */
20
+ public static function trigger_email( $action, $entry, $form ) {
21
+ $email = new FrmEmail( $action, $entry, $form );