Formidable Forms – Form Builder for WordPress - Version 2.0.16

Version Description

  • Escape font family correctly for quotation marks
  • Only check for updates every 24 hours
  • Allow emails to be separated by a space
  • Prevent old versions of Akismet from causing errors
  • Add unit tests for XML import
  • Styling updates for WP 4.4
  • Save form action settings even if they aren't in the default options
  • More contrast on form builder page
  • Use normal font weight for from builder
  • Pro Features:
  • Allow Styles to be duplicated
  • Allow the form key in the CSV download url
  • Make like/not like conditional logic not case-sensitive
  • Fix multiple conditional logics on a Dynamic field
  • Fix XML import with repeating fields
  • Fix notice for old dfe fields
  • Make sure integer is being used for auto_id
  • Fix read-only dependent Dynamic field with a default value
  • Fix conditional radio button default value issue
  • Fixes for conditional logic on sections
  • Fix autoupdating for add-ons
  • Show a message if no license has been entered for an add-on
Download this release

Release Info

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

Code changes from version 2.0.15 to 2.0.16

classes/controllers/FrmStylesController.php CHANGED
@@ -132,6 +132,11 @@ class FrmStylesController {
132
  self::load_styler('default');
133
  }
134
 
 
 
 
 
 
135
  public static function edit( $style_id = false, $message = '' ) {
136
  if ( ! $style_id ) {
137
  $style_id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
@@ -272,7 +277,7 @@ class FrmStylesController {
272
  return;
273
  }
274
 
275
- if ( 'new_style' == $action ) {
276
  return self::$action();
277
  }
278
 
132
  self::load_styler('default');
133
  }
134
 
135
+ public static function duplicate() {
136
+ FrmAppHelper::update_message( __( 'duplicate styling templates', 'formidable' ), 'wrap' );
137
+ self::load_styler('default');
138
+ }
139
+
140
  public static function edit( $style_id = false, $message = '' ) {
141
  if ( ! $style_id ) {
142
  $style_id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
277
  return;
278
  }
279
 
280
+ if ( 'new_style' == $action || 'duplicate' == $action ) {
281
  return self::$action();
282
  }
283
 
classes/helpers/FrmAppHelper.php CHANGED
@@ -10,7 +10,7 @@ class FrmAppHelper {
10
  /**
11
  * @since 2.0
12
  */
13
- public static $plug_version = '2.0.15';
14
 
15
  /**
16
  * @since 1.07.02
10
  /**
11
  * @since 2.0
12
  */
13
+ public static $plug_version = '2.0.16';
14
 
15
  /**
16
  * @since 1.07.02
classes/helpers/FrmFieldsHelper.php CHANGED
@@ -366,6 +366,11 @@ DEFAULT_HTML;
366
  $error_class .= ' frm_field_'. $field['id'] .'_container';
367
  }
368
 
 
 
 
 
 
369
  //Add classes to inline confirmation field (if it doesn't already have classes set)
370
  if ( isset( $field['conf_field'] ) && $field['conf_field'] == 'inline' && ! $field['classes'] ) {
371
  $error_class .= ' frm_first frm_half';
@@ -607,7 +612,7 @@ DEFAULT_HTML;
607
  } else if ( $cond == '<' ) {
608
  $m = $observed_value < $hide_opt;
609
  } else if ( $cond == 'LIKE' || $cond == 'not LIKE' ) {
610
- $m = strpos($observed_value, $hide_opt);
611
  if ( $cond == 'not LIKE' ) {
612
  $m = ( $m === false ) ? true : false;
613
  } else {
366
  $error_class .= ' frm_field_'. $field['id'] .'_container';
367
  }
368
 
369
+ // Add class to embedded form field
370
+ if ( $field['type'] == 'form' ) {
371
+ $error_class .= ' frm_embed_form_container';
372
+ }
373
+
374
  //Add classes to inline confirmation field (if it doesn't already have classes set)
375
  if ( isset( $field['conf_field'] ) && $field['conf_field'] == 'inline' && ! $field['classes'] ) {
376
  $error_class .= ' frm_first frm_half';
612
  } else if ( $cond == '<' ) {
613
  $m = $observed_value < $hide_opt;
614
  } else if ( $cond == 'LIKE' || $cond == 'not LIKE' ) {
615
+ $m = stripos($observed_value, $hide_opt);
616
  if ( $cond == 'not LIKE' ) {
617
  $m = ( $m === false ) ? true : false;
618
  } else {
classes/helpers/FrmStylesHelper.php CHANGED
@@ -56,12 +56,27 @@ class FrmStylesHelper {
56
  }
57
 
58
  public static function enqueue_jquery_css() {
59
- $theme_css = FrmStylesController::get_style_val('theme_css');
 
60
  if ( $theme_css != -1 ) {
61
  wp_enqueue_style('jquery-theme', self::jquery_css_url($theme_css), array(), FrmAppHelper::plugin_version());
62
  }
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  public static function get_upload_base() {
66
  $uploads = wp_upload_dir();
67
  if ( is_ssl() && ! preg_match('/^https:\/\/.*\..*$/', $uploads['baseurl']) ) {
56
  }
57
 
58
  public static function enqueue_jquery_css() {
59
+ $form = self::get_form_for_page();
60
+ $theme_css = FrmStylesController::get_style_val( 'theme_css', $form );
61
  if ( $theme_css != -1 ) {
62
  wp_enqueue_style('jquery-theme', self::jquery_css_url($theme_css), array(), FrmAppHelper::plugin_version());
63
  }
64
  }
65
 
66
+ public static function get_form_for_page() {
67
+ global $frm_vars;
68
+ $form_id = 'default';
69
+ if ( ! empty( $frm_vars['forms_loaded'] ) ) {
70
+ foreach ( $frm_vars['forms_loaded'] as $form ) {
71
+ if ( is_object( $form ) ) {
72
+ $form_id = $form->id;
73
+ break;
74
+ }
75
+ }
76
+ }
77
+ return $form_id;
78
+ }
79
+
80
  public static function get_upload_base() {
81
  $uploads = wp_upload_dir();
82
  if ( is_ssl() && ! preg_match('/^https:\/\/.*\..*$/', $uploads['baseurl']) ) {
classes/helpers/FrmXMLHelper.php CHANGED
@@ -122,8 +122,10 @@ class FrmXMLHelper {
122
  }
123
 
124
  public static function import_xml_forms( $forms, $imported ) {
125
- // Keep track of repeating sections and child forms that are imported
126
- $repeat_fields = $child_forms_missing_parent = array();
 
 
127
 
128
  foreach ( $forms as $item ) {
129
  $form = array(
@@ -149,8 +151,6 @@ class FrmXMLHelper {
149
  $edit_query['created_at'] = $form['created_at'];
150
  }
151
 
152
- $old_parent_form_id = self::maybe_replace_parent_form_id( $imported['forms'], $form['parent_form_id'] );
153
-
154
  $edit_query = apply_filters('frm_match_xml_form', $edit_query, $form);
155
 
156
  $this_form = FrmForm::getAll($edit_query, '', 1);
@@ -163,7 +163,7 @@ class FrmXMLHelper {
163
  // Keep track of whether this specific form was updated or not
164
  $imported['form_status'][ $form_id ] = 'updated';
165
 
166
- $form_fields = FrmField::get_all_for_form( $form_id );
167
  $old_fields = array();
168
  foreach ( $form_fields as $f ) {
169
  $old_fields[ $f->id ] = $f;
@@ -180,12 +180,11 @@ class FrmXMLHelper {
180
  $imported['imported']['forms']++;
181
  // Keep track of whether this specific form was updated or not
182
  $imported['form_status'][ $form_id ] = 'imported';
183
-
184
- self::track_child_forms_missing_parent( (int) $form_id, $old_parent_form_id, $child_forms_missing_parent );
185
  }
186
  }
187
 
188
- self::import_xml_fields( $item->field, $form_id, $this_form, $form_fields, $imported, $repeat_fields );
189
 
190
  // Delete any fields attached to this form that were not included in the template
191
  if ( isset( $form_fields ) && ! empty( $form_fields ) ) {
@@ -208,55 +207,66 @@ class FrmXMLHelper {
208
 
209
  unset($form, $item);
210
  }
211
- self::update_repeat_field_options( $repeat_fields, $imported['forms'] );
212
- self::update_child_form_parents( $child_forms_missing_parent, $imported['forms'] );
213
 
214
  return $imported;
215
  }
216
 
217
  /**
218
- * Replace the parent_form_id on child forms if their parent was already imported
219
- * @since 2.0.13
220
  *
221
- * @param array $imported_forms
222
- * @param int $parent_form_id
223
- * @return int $old_parent_form_id
224
  */
225
- private static function maybe_replace_parent_form_id( $imported_forms, &$parent_form_id ) {
226
- $old_parent_form_id = 0;
 
227
 
228
- if ( ! empty( $parent_form_id ) ) {
229
- if ( isset( $imported_forms[ $parent_form_id ] ) ) {
230
- // The parent has already been imported
231
 
232
- // replace the old parent id with the new one
233
- $parent_form_id = $imported_forms[ $parent_form_id ];
234
  } else {
235
- // The parent will be imported after
236
-
237
- $old_parent_form_id = $parent_form_id;
238
  }
239
- }
240
 
241
- return $old_parent_form_id;
242
  }
243
 
244
  /**
245
- * Track child forms that were imported before their parents
246
- * @since 2.0.13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  *
248
- * @param int $new_form_id
249
- * @param int $old_parent_form_id
250
- * @param array $child_forms_missing_parent
251
  */
252
- private static function track_child_forms_missing_parent( $new_form_id, $old_parent_form_id, &$child_forms_missing_parent ) {
253
- if ( $old_parent_form_id ) {
254
- if ( ! isset( $child_forms_missing_parent[ $old_parent_form_id ] ) ) {
255
- $child_forms_missing_parent[ $old_parent_form_id ] = array();
256
- }
 
257
 
258
- // Multiple child forms may have the same parent
259
- $child_forms_missing_parent[ $old_parent_form_id ][] = $new_form_id;
260
  }
261
  }
262
 
@@ -266,7 +276,7 @@ class FrmXMLHelper {
266
  *
267
  * TODO: Cut down on params
268
  */
269
- private static function import_xml_fields( $xml_fields, $form_id, $this_form, &$form_fields, &$imported, &$repeat_fields ) {
270
  foreach ( $xml_fields as $field ) {
271
  $f = array(
272
  'id' => (int) $field->id,
@@ -296,6 +306,8 @@ class FrmXMLHelper {
296
 
297
  $f = apply_filters('frm_duplicated_field', $f);
298
 
 
 
299
  if ( ! empty($this_form) ) {
300
  // check for field to edit by field id
301
  if ( isset( $form_fields[ $f['id'] ] ) ) {
@@ -322,7 +334,6 @@ class FrmXMLHelper {
322
  if ( $new_id == false ) {
323
  continue;
324
  }
325
- self::track_repeating_fields( $f, $new_id, $repeat_fields );
326
 
327
  // if no matching field id or key in this form, create the field
328
  $imported['imported']['fields']++;
@@ -333,7 +344,6 @@ class FrmXMLHelper {
333
  continue;
334
  }
335
 
336
- self::track_repeating_fields( $f, $new_id, $repeat_fields );
337
  $imported['imported']['fields']++;
338
  }
339
 
@@ -342,70 +352,27 @@ class FrmXMLHelper {
342
  }
343
 
344
  /**
345
- * Update parent_form_id for child forms that were imported before parents
346
- *
347
- * @since 2.0.13
348
  *
349
- * @param array $child_forms_missing_parent
350
- * @param array $imported_forms
 
351
  */
352
- private static function update_child_form_parents( $child_forms_missing_parent, $imported_forms ) {
353
- foreach ( $child_forms_missing_parent as $old_parent_form_id => $child_form_ids ) {
354
- if ( isset( $imported_forms[ $old_parent_form_id ] ) ) {
355
-
356
- // Update all children with this old parent_form_id
357
- $new_parent_form_id = (int) $imported_forms[ $old_parent_form_id ];
358
- foreach ( $child_form_ids as $child_form_id ) {
359
- FrmForm::update( $child_form_id, array( 'parent_form_id' => $new_parent_form_id ) );
360
- }
361
- }
362
  }
363
- }
364
 
365
- /**
366
- * Update form_select for all imported repeating sections and embedded forms
367
- *
368
- * @since 2.0.09
369
- * @param array $repeat_fields - old form ID as keys and section field IDs as items
370
- * @param array $imported_forms
371
- */
372
- private static function update_repeat_field_options( $repeat_fields, $imported_forms ) {
373
- foreach ( $repeat_fields as $old_form_id => $new_repeat_fields ) {
374
- foreach ( $new_repeat_fields as $repeat_field_id ) {
375
- // Get section/embed form field
376
- $repeat_field = FrmField::getOne( $repeat_field_id );
377
- $field_opts = maybe_unserialize( $repeat_field->field_options );
378
-
379
- if ( ! isset( $imported_forms[ $old_form_id ] ) ) {
380
- return;
381
  }
382
- $field_opts['form_select'] = $imported_forms[ $old_form_id ];
383
-
384
- // update form_select now
385
- FrmField::update( $repeat_field_id, array( 'field_options' => maybe_serialize( $field_opts ) ) );
386
  }
387
  }
388
  }
389
 
390
- /**
391
- * Keep track of imported repeating fields and embedded forms
392
- *
393
- * @since 2.0.09
394
- * @param array $f - field array
395
- * @param int $repeat_field_id
396
- * @param array $repeat_fields - pass by reference
397
- */
398
- private static function track_repeating_fields( $f, $repeat_field_id, &$repeat_fields ) {
399
- if ( ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) || $f['type'] == 'form' ) {
400
- $old_form_id = trim( $f['field_options']['form_select'] );
401
- if ( ! isset( $repeat_fields[ $old_form_id ] ) ) {
402
- $repeat_fields[ $old_form_id ] = array();
403
- }
404
-
405
- $repeat_fields[ $old_form_id ][] = $repeat_field_id;
406
- }
407
- }
408
-
409
  public static function import_xml_views( $views, $imported ) {
410
  $imported['posts'] = array();
411
  $form_action_type = FrmFormActionsController::$action_post_type;
122
  }
123
 
124
  public static function import_xml_forms( $forms, $imported ) {
125
+ $child_forms = array();
126
+
127
+ // Import child forms first
128
+ self::put_child_forms_first( $forms );
129
 
130
  foreach ( $forms as $item ) {
131
  $form = array(
151
  $edit_query['created_at'] = $form['created_at'];
152
  }
153
 
 
 
154
  $edit_query = apply_filters('frm_match_xml_form', $edit_query, $form);
155
 
156
  $this_form = FrmForm::getAll($edit_query, '', 1);
163
  // Keep track of whether this specific form was updated or not
164
  $imported['form_status'][ $form_id ] = 'updated';
165
 
166
+ $form_fields = FrmField::get_all_for_form( $form_id, '', 'exclude', 'exclude' );
167
  $old_fields = array();
168
  foreach ( $form_fields as $f ) {
169
  $old_fields[ $f->id ] = $f;
180
  $imported['imported']['forms']++;
181
  // Keep track of whether this specific form was updated or not
182
  $imported['form_status'][ $form_id ] = 'imported';
183
+ self::track_imported_child_forms( (int) $form_id, $form['parent_form_id'], $child_forms );
 
184
  }
185
  }
186
 
187
+ self::import_xml_fields( $item->field, $form_id, $this_form, $form_fields, $imported );
188
 
189
  // Delete any fields attached to this form that were not included in the template
190
  if ( isset( $form_fields ) && ! empty( $form_fields ) ) {
207
 
208
  unset($form, $item);
209
  }
210
+
211
+ self::maybe_update_child_form_parent_id( $imported['forms'], $child_forms );
212
 
213
  return $imported;
214
  }
215
 
216
  /**
217
+ * Put child forms first so they will be imported before parents
 
218
  *
219
+ * @since 2.0.16
220
+ * @param array $forms
 
221
  */
222
+ private static function put_child_forms_first( &$forms ) {
223
+ $child_forms = array();
224
+ $regular_forms = array();
225
 
226
+ foreach ( $forms as $form ) {
227
+ $parent_form_id = isset( $form->parent_form_id) ? (int) $form->parent_form_id : 0;
 
228
 
229
+ if ( $parent_form_id ) {
230
+ $child_forms[] = $form;
231
  } else {
232
+ $regular_forms[] = $form;
 
 
233
  }
234
+ }
235
 
236
+ $forms = array_merge( $child_forms, $regular_forms );
237
  }
238
 
239
  /**
240
+ * Keep track of all imported child forms
241
+ *
242
+ * @since 2.0.16
243
+ * @param int $form_id
244
+ * @param int $parent_form_id
245
+ * @param array $child_forms
246
+ */
247
+ private static function track_imported_child_forms( $form_id, $parent_form_id, &$child_forms ) {
248
+ if ( $parent_form_id ) {
249
+ $child_forms[ $form_id ] = $parent_form_id;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Update the parent_form_id on imported child forms
255
+ * Child forms are imported first so their parent_form_id will need to be updated after the parent is imported
256
  *
257
+ * @since 2.0.6
258
+ * @param array $imported_forms
259
+ * @param array $child_forms
260
  */
261
+ private static function maybe_update_child_form_parent_id( $imported_forms, $child_forms ) {
262
+ foreach ( $child_forms as $child_form_id => $old_parent_form_id ) {
263
+
264
+ if ( isset( $imported_forms[ $old_parent_form_id ] ) && $imported_forms[ $old_parent_form_id ] != $old_parent_form_id ) {
265
+ // Update all children with this old parent_form_id
266
+ $new_parent_form_id = (int) $imported_forms[ $old_parent_form_id ];
267
 
268
+ FrmForm::update( $child_form_id, array( 'parent_form_id' => $new_parent_form_id ) );
269
+ }
270
  }
271
  }
272
 
276
  *
277
  * TODO: Cut down on params
278
  */
279
+ private static function import_xml_fields( $xml_fields, $form_id, $this_form, &$form_fields, &$imported ) {
280
  foreach ( $xml_fields as $field ) {
281
  $f = array(
282
  'id' => (int) $field->id,
306
 
307
  $f = apply_filters('frm_duplicated_field', $f);
308
 
309
+ self::maybe_update_form_select( $f, $imported );
310
+
311
  if ( ! empty($this_form) ) {
312
  // check for field to edit by field id
313
  if ( isset( $form_fields[ $f['id'] ] ) ) {
334
  if ( $new_id == false ) {
335
  continue;
336
  }
 
337
 
338
  // if no matching field id or key in this form, create the field
339
  $imported['imported']['fields']++;
344
  continue;
345
  }
346
 
 
347
  $imported['imported']['fields']++;
348
  }
349
 
352
  }
353
 
354
  /**
355
+ * Switch the form_select on a repeating field or embedded form if it needs to be switched
 
 
356
  *
357
+ * @since 2.0.16
358
+ * @param array $f
359
+ * @param array $imported
360
  */
361
+ private static function maybe_update_form_select( &$f, $imported ) {
362
+ if ( ! isset( $imported['forms'] ) ) {
363
+ return;
 
 
 
 
 
 
 
364
  }
 
365
 
366
+ if ( $f['type'] == 'form' || ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) ) {
367
+ if ( FrmField::is_option_true( $f['field_options'], 'form_select' ) ) {
368
+ $form_select = $f['field_options']['form_select'];
369
+ if ( isset( $imported['forms'][ $form_select ] ) ) {
370
+ $f['field_options']['form_select'] = $imported['forms'][ $form_select ];
 
 
 
 
 
 
 
 
 
 
 
371
  }
 
 
 
 
372
  }
373
  }
374
  }
375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  public static function import_xml_views( $views, $imported ) {
377
  $imported['posts'] = array();
378
  $form_action_type = FrmFormActionsController::$action_post_type;
classes/models/EDD_SL_Plugin_Updater.php CHANGED
@@ -71,7 +71,7 @@ class EDD_SL_Plugin_Updater {
71
  * @param array $_transient_data Update array build by WordPress.
72
  * @return array Modified update array with custom plugin data.
73
  */
74
- function check_update( $_transient_data ) {
75
 
76
  global $pagenow;
77
 
@@ -142,7 +142,7 @@ class EDD_SL_Plugin_Updater {
142
 
143
  $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
144
 
145
- set_transient( $cache_key, $version_info, 3600 );
146
  }
147
 
148
  if ( ! is_object( $version_info ) ) {
@@ -212,7 +212,7 @@ class EDD_SL_Plugin_Updater {
212
  * @param object $_args
213
  * @return object $_data
214
  */
215
- function plugins_api_filter( $_data, $_action = '', $_args = null ) {
216
 
217
  if ( $_action != 'plugin_information' ) {
218
 
@@ -252,7 +252,7 @@ class EDD_SL_Plugin_Updater {
252
  * @param string $url
253
  * @return object $array
254
  */
255
- function http_request_args( $args, $url ) {
256
  // If it is an https request and we are performing a package download, disable ssl verification
257
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
258
  $args['sslverify'] = false;
@@ -299,6 +299,13 @@ class EDD_SL_Plugin_Updater {
299
  'url' => home_url(),
300
  );
301
 
 
 
 
 
 
 
 
302
  $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
303
 
304
  if ( ! is_wp_error( $request ) ) {
@@ -307,8 +314,10 @@ class EDD_SL_Plugin_Updater {
307
 
308
  if ( $request && isset( $request->sections ) ) {
309
  $request->sections = maybe_unserialize( $request->sections );
 
310
  } else {
311
  $request = false;
 
312
  }
313
 
314
  return $request;
71
  * @param array $_transient_data Update array build by WordPress.
72
  * @return array Modified update array with custom plugin data.
73
  */
74
+ public function check_update( $_transient_data ) {
75
 
76
  global $pagenow;
77
 
142
 
143
  $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
144
 
145
+ set_transient( $cache_key, $version_info, HOUR_IN_SECONDS );
146
  }
147
 
148
  if ( ! is_object( $version_info ) ) {
212
  * @param object $_args
213
  * @return object $_data
214
  */
215
+ public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
216
 
217
  if ( $_action != 'plugin_information' ) {
218
 
252
  * @param string $url
253
  * @return object $array
254
  */
255
+ public function http_request_args( $args, $url ) {
256
  // If it is an https request and we are performing a package download, disable ssl verification
257
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
258
  $args['sslverify'] = false;
299
  'url' => home_url(),
300
  );
301
 
302
+ $cache_key = 'edd_plugin_' . md5( sanitize_key( $api_params['license'] . $this->version ) . '_' . $api_params['edd_action'] );
303
+ $cached_response = get_transient( $cache_key );
304
+ if ( $cached_response !== false ) {
305
+ // if this has been checked within 24 hours, don't check again
306
+ return $cached_response;
307
+ }
308
+
309
  $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
310
 
311
  if ( ! is_wp_error( $request ) ) {
314
 
315
  if ( $request && isset( $request->sections ) ) {
316
  $request->sections = maybe_unserialize( $request->sections );
317
+ set_transient( $cache_key, $request, DAY_IN_SECONDS );
318
  } else {
319
  $request = false;
320
+ set_transient( $cache_key, 0, DAY_IN_SECONDS );
321
  }
322
 
323
  return $request;
classes/models/FrmAddon.php CHANGED
@@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
5
  }
6
 
7
  class FrmAddon {
8
- public $store_url = 'http://formidablepro.com';
9
  public $plugin_file;
10
  public $plugin_name;
11
  public $plugin_slug;
@@ -23,6 +23,12 @@ class FrmAddon {
23
  }
24
 
25
  add_filter( 'frm_installed_addons', array( &$this, 'insert_installed_addon' ) );
 
 
 
 
 
 
26
  }
27
 
28
  public function insert_installed_addon( $plugins ) {
@@ -44,7 +50,9 @@ class FrmAddon {
44
  // retrieve our license key from the DB
45
  $license = trim( get_option( $this->option_name . 'key' ) );
46
 
47
- if ( ! empty( $license ) ) {
 
 
48
  if ( ! class_exists('EDD_SL_Plugin_Updater') ) {
49
  include( dirname( __FILE__ ) . '/EDD_SL_Plugin_Updater.php' );
50
  }
@@ -53,12 +61,20 @@ class FrmAddon {
53
  new EDD_SL_Plugin_Updater( $this->store_url, $this->plugin_file, array(
54
  'version' => $this->version,
55
  'license' => $license,
56
- 'item_name' => $this->plugin_name,
57
  'author' => $this->author,
58
  ) );
59
  }
60
  }
61
 
 
 
 
 
 
 
 
 
 
62
  public static function activate() {
63
  check_ajax_referer( 'frm_ajax', 'nonce' );
64
 
5
  }
6
 
7
  class FrmAddon {
8
+ public $store_url = 'https://formidablepro.com';
9
  public $plugin_file;
10
  public $plugin_name;
11
  public $plugin_slug;
23
  }
24
 
25
  add_filter( 'frm_installed_addons', array( &$this, 'insert_installed_addon' ) );
26
+ $this->edd_plugin_updater();
27
+ }
28
+
29
+ public static function load_hooks() {
30
+ add_filter( 'frm_include_addon_page', '__return_true' );
31
+ new static();
32
  }
33
 
34
  public function insert_installed_addon( $plugins ) {
50
  // retrieve our license key from the DB
51
  $license = trim( get_option( $this->option_name . 'key' ) );
52
 
53
+ if ( empty( $license ) ) {
54
+ add_action( 'after_plugin_row_' . plugin_basename( $this->plugin_file ), array( $this, 'show_license_message' ), 10, 2 );
55
+ } else {
56
  if ( ! class_exists('EDD_SL_Plugin_Updater') ) {
57
  include( dirname( __FILE__ ) . '/EDD_SL_Plugin_Updater.php' );
58
  }
61
  new EDD_SL_Plugin_Updater( $this->store_url, $this->plugin_file, array(
62
  'version' => $this->version,
63
  'license' => $license,
 
64
  'author' => $this->author,
65
  ) );
66
  }
67
  }
68
 
69
+ public function show_license_message( $file, $plugin ) {
70
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
71
+ echo '<tr class="plugin-update-tr active"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message">';
72
+ echo sprintf( __( 'Your %1$s license key is missing. Please add it on the %2$slicenses page%3$s.', 'formidable' ), $this->plugin_name, '<a href="' . esc_url( admin_url('admin.php?page=formidable-settings&t=licenses_settings' ) ) . '">', '</a>' );
73
+ $id = sanitize_title( $plugin['Name'] );
74
+ echo '<script type="text/javascript">var d = document.getElementById("' . esc_attr( $id ) . '");if ( d !== null ){ d.className = d.className + " update"; }</script>';
75
+ echo '</div></td></tr>';
76
+ }
77
+
78
  public static function activate() {
79
  check_ajax_referer( 'frm_ajax', 'nonce' );
80
 
classes/models/FrmEntry.php CHANGED
@@ -5,88 +5,37 @@ if ( ! defined('ABSPATH') ) {
5
 
6
  class FrmEntry {
7
 
8
- public static function create( $values ) {
9
- global $wpdb;
10
-
11
- self::sanitize_entry_post( $values );
12
-
13
- $values = apply_filters('frm_pre_create_entry', $values);
 
 
 
 
 
14
 
15
- if ( ! isset( $values['item_key'] ) ) {
16
- $values['item_key'] = '';
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
- $item_name = self::get_new_entry_name( $values, $values['item_key'] );
20
- $new_values = array(
21
- 'item_key' => FrmAppHelper::get_unique_key($values['item_key'], $wpdb->prefix .'frm_items', 'item_key'),
22
- 'name' => FrmAppHelper::truncate( $item_name, 255, 1, '' ),
23
- 'ip' => FrmAppHelper::get_ip_address(),
24
- 'is_draft' => ( ( isset($values['frm_saving_draft']) && $values['frm_saving_draft'] == 1 ) || ( isset($values['is_draft']) && $values['is_draft'] == 1) ) ? 1 : 0,
25
- 'form_id' => isset($values['form_id']) ? (int) $values['form_id']: null,
26
- 'post_id' => isset( $values['post_id'] ) ? (int) $values['post_id']: 0,
27
- 'parent_item_id' => isset( $values['parent_item_id'] ) ? (int) $values['parent_item_id']: 0,
28
- 'created_at' => isset($values['created_at']) ? $values['created_at'] : current_time('mysql', 1),
29
- 'updated_at' => isset($values['updated_at']) ? $values['updated_at'] : ( isset($values['created_at']) ? $values['created_at'] : current_time('mysql', 1) ),
30
- );
31
-
32
- if ( is_array($new_values['name']) ) {
33
- $new_values['name'] = reset($new_values['name']);
34
- }
35
-
36
- if ( isset($values['description']) && ! empty($values['description']) ) {
37
- $new_values['description'] = maybe_serialize($values['description']);
38
- } else {
39
- $new_values['description'] = serialize( array(
40
- 'browser' => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
41
- 'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
42
- ) );
43
- }
44
-
45
- //if(isset($values['id']) and is_numeric($values['id']))
46
- // $new_values['id'] = $values['id'];
47
-
48
- if ( isset($values['frm_user_id']) && ( is_numeric($values['frm_user_id']) || FrmAppHelper::is_admin() ) ) {
49
- $new_values['user_id'] = $values['frm_user_id'];
50
- } else {
51
- $user_ID = get_current_user_id();
52
- $new_values['user_id'] = $user_ID ? $user_ID : 0;
53
- }
54
-
55
- $new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
56
-
57
- // don't create duplicate entry
58
- if ( self::is_duplicate($new_values, $values) ) {
59
- return false;
60
- }
61
-
62
- $query_results = $wpdb->insert( $wpdb->prefix .'frm_items', $new_values );
63
-
64
- if ( ! $query_results ) {
65
- return false;
66
- }
67
-
68
- $entry_id = $wpdb->insert_id;
69
-
70
- global $frm_vars;
71
- if ( ! isset($frm_vars['saved_entries']) ) {
72
- $frm_vars['saved_entries'] = array();
73
- }
74
- $frm_vars['saved_entries'][] = (int) $entry_id;
75
-
76
- if ( isset($values['item_meta']) ) {
77
- FrmEntryMeta::update_entry_metas($entry_id, $values['item_meta']);
78
- }
79
 
80
- self::clear_cache();
81
-
82
- // this is a child entry
83
- $is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
84
-
85
- do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
86
- do_action( 'frm_after_create_entry_'. $new_values['form_id'], $entry_id , compact( 'is_child' ) );
87
-
88
- return $entry_id;
89
- }
90
 
91
  /**
92
  * check for duplicate entries created in the last minute
@@ -185,61 +134,44 @@ class FrmEntry {
185
  return $entry_id;
186
  }
187
 
188
- public static function update( $id, $values ) {
189
- global $wpdb, $frm_vars;
190
- if ( isset($frm_vars['saved_entries']) && is_array($frm_vars['saved_entries']) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
191
- return;
192
- }
193
-
194
- $values = apply_filters('frm_pre_update_entry', $values, $id);
195
-
196
- $user_ID = get_current_user_id();
197
-
198
- $item_name = self::get_new_entry_name( $values );
199
- $new_values = array(
200
- 'name' => $item_name,
201
- 'form_id' => isset($values['form_id']) ? (int) $values['form_id'] : null,
202
- 'is_draft' => ( ( isset($values['frm_saving_draft']) && $values['frm_saving_draft'] == 1 ) || ( isset($values['is_draft']) && $values['is_draft'] == 1) ) ? 1 : 0,
203
- 'updated_at' => current_time('mysql', 1),
204
- 'updated_by' => isset($values['updated_by']) ? $values['updated_by'] : $user_ID,
205
- );
206
-
207
- if ( isset($values['post_id']) ) {
208
- $new_values['post_id'] = (int) $values['post_id'];
209
- }
210
-
211
- if ( isset($values['item_key']) ) {
212
- $new_values['item_key'] = FrmAppHelper::get_unique_key($values['item_key'], $wpdb->prefix .'frm_items', 'item_key', $id);
213
- }
214
-
215
- if ( isset($values['parent_item_id']) ) {
216
- $new_values['parent_item_id'] = (int) $values['parent_item_id'];
217
- }
218
 
219
- if ( isset($values['frm_user_id']) && is_numeric($values['frm_user_id']) ) {
220
- $new_values['user_id'] = $values['frm_user_id'];
221
- }
 
 
 
 
 
 
 
 
222
 
223
- $new_values = apply_filters('frm_update_entry', $new_values, $id);
224
- $query_results = $wpdb->update( $wpdb->prefix .'frm_items', $new_values, compact('id') );
 
 
225
 
226
- if ( $query_results ) {
227
- self::clear_cache();
228
- }
229
 
230
- if ( ! isset( $frm_vars['saved_entries'] ) ) {
231
- $frm_vars['saved_entries'] = array();
232
- }
233
 
234
- $frm_vars['saved_entries'][] = (int) $id;
235
 
236
- if ( isset($values['item_meta']) ) {
237
- FrmEntryMeta::update_entry_metas($id, $values['item_meta']);
238
- }
239
- do_action('frm_after_update_entry', $id, $new_values['form_id']);
240
- do_action('frm_after_update_entry_'. $new_values['form_id'], $id);
241
- return $query_results;
242
- }
243
 
244
  public static function &destroy( $id ) {
245
  global $wpdb;
@@ -501,6 +433,46 @@ class FrmEntry {
501
  }
502
  }
503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  /**
505
  * Sanitize the POST values before we use them
506
  *
@@ -525,6 +497,355 @@ class FrmEntry {
525
  FrmAppHelper::sanitize_request( $sanitize_method, $values );
526
  }
527
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  /**
529
  * @param string $key
530
  * @return int entry_id
5
 
6
  class FrmEntry {
7
 
8
+ /**
9
+ * Create a new entry
10
+ *
11
+ * @param array $values
12
+ * @return int | boolean $entry_id
13
+ */
14
+ public static function create( $values ) {
15
+ $entry_id = self::create_entry( $values, 'standard' );
16
+
17
+ return $entry_id;
18
+ }
19
 
20
+ /**
21
+ * Create a new entry with some differences depending on type
22
+ *
23
+ * @param array $values
24
+ * @param string $type
25
+ * @return int | boolean $entry_id
26
+ */
27
+ private static function create_entry( $values, $type ) {
28
+ $new_values = self::before_insert_entry_in_database( $values, $type );
29
+
30
+ // Don't check XML entries for duplicates
31
+ if ( $type != 'xml' && self::is_duplicate( $new_values, $values ) ) {
32
+ return false;
33
  }
34
 
35
+ $entry_id = self::continue_to_create_entry( $values, $new_values );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ return $entry_id;
38
+ }
 
 
 
 
 
 
 
 
39
 
40
  /**
41
  * check for duplicate entries created in the last minute
134
  return $entry_id;
135
  }
136
 
137
+ /**
138
+ * Update an entry (not via XML)
139
+ *
140
+ * @param int $id
141
+ * @param array $values
142
+ * @return boolean|int $update_results
143
+ */
144
+ public static function update( $id, $values ) {
145
+ $update_results = self::update_entry( $id, $values, 'standard' );
146
+
147
+ return $update_results;
148
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
+ /**
151
+ * Update an entry with some differences depending on the update type
152
+ *
153
+ * @since 2.0.16
154
+ *
155
+ * @param int $id
156
+ * @param array $values
157
+ * @return boolean|int $query_results
158
+ */
159
+ private static function update_entry( $id, $values, $update_type ) {
160
+ global $wpdb;
161
 
162
+ $update = self::before_update_entry( $id, $values, $update_type );
163
+ if ( ! $update ) {
164
+ return false;
165
+ }
166
 
167
+ $new_values = self::package_entry_to_update( $id, $values );
 
 
168
 
169
+ $query_results = $wpdb->update( $wpdb->prefix .'frm_items', $new_values, compact('id') );
 
 
170
 
171
+ self::after_update_entry( $query_results, $id, $values, $new_values );
172
 
173
+ return $query_results;
174
+ }
 
 
 
 
 
175
 
176
  public static function &destroy( $id ) {
177
  global $wpdb;
433
  }
434
  }
435
 
436
+ /**
437
+ * Prepare the data before inserting it into the database
438
+ *
439
+ * @since 2.0.16
440
+ * @param array $values
441
+ * @param string $type
442
+ * @return array $new_values
443
+ */
444
+ private static function before_insert_entry_in_database( &$values, $type ) {
445
+
446
+ self::sanitize_entry_post( $values );
447
+
448
+ if ( $type != 'xml' ) {
449
+ $values = apply_filters('frm_pre_create_entry', $values);
450
+ }
451
+
452
+ $new_values = self::package_entry_data( $values );
453
+
454
+ return $new_values;
455
+ }
456
+
457
+ /**
458
+ * Create an entry and perform after create actions
459
+ *
460
+ * @since 2.0.16
461
+ * @param array $values
462
+ * @param array $new_values
463
+ * @return boolean|int $entry_id
464
+ */
465
+ private static function continue_to_create_entry( $values, $new_values ) {
466
+ $entry_id = self::insert_entry_into_database( $new_values );
467
+ if ( ! $entry_id ) {
468
+ return false;
469
+ }
470
+
471
+ self::after_insert_entry_in_database( $values, $new_values, $entry_id );
472
+
473
+ return $entry_id;
474
+ }
475
+
476
  /**
477
  * Sanitize the POST values before we use them
478
  *
497
  FrmAppHelper::sanitize_request( $sanitize_method, $values );
498
  }
499
 
500
+ /**
501
+ * Prepare the new values for inserting into the database
502
+ *
503
+ * @since 2.0.16
504
+ * @param array $values
505
+ * @return array $new_values
506
+ */
507
+ private static function package_entry_data( &$values ) {
508
+ global $wpdb;
509
+
510
+ if ( ! isset( $values['item_key'] ) ) {
511
+ $values['item_key'] = '';
512
+ }
513
+
514
+ $item_name = self::get_new_entry_name( $values, $values['item_key'] );
515
+ $new_values = array(
516
+ 'item_key' => FrmAppHelper::get_unique_key($values['item_key'], $wpdb->prefix .'frm_items', 'item_key'),
517
+ 'name' => FrmAppHelper::truncate( $item_name, 255, 1, '' ),
518
+ 'ip' => FrmAppHelper::get_ip_address(),
519
+ 'is_draft' => self::get_is_draft_value( $values ),
520
+ 'form_id' => self::get_form_id( $values ),
521
+ 'post_id' => self::get_post_id( $values ),
522
+ 'parent_item_id' => self::get_parent_item_id( $values ),
523
+ 'created_at' => self::get_created_at( $values ),
524
+ 'updated_at' => self::get_updated_at( $values ),
525
+ 'description' => self::get_entry_description( $values ),
526
+ 'user_id' => self::get_entry_user_id( $values ),
527
+ );
528
+
529
+ if ( is_array($new_values['name']) ) {
530
+ $new_values['name'] = reset($new_values['name']);
531
+ }
532
+
533
+ $new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
534
+
535
+ return $new_values;
536
+ }
537
+
538
+ /**
539
+ * Get the is_draft value for a new entry
540
+ *
541
+ * @since 2.0.16
542
+ * @param array $values
543
+ * @return int
544
+ */
545
+ private static function get_is_draft_value( $values ) {
546
+ return ( ( isset( $values['frm_saving_draft'] ) && $values['frm_saving_draft'] == 1 ) || ( isset( $values['is_draft'] ) && $values['is_draft'] == 1 ) ) ? 1 : 0;
547
+ }
548
+
549
+ /**
550
+ * Get the form_id value for a new entry
551
+ *
552
+ * @since 2.0.16
553
+ * @param array $values
554
+ * @return int|null
555
+ */
556
+ private static function get_form_id( $values ) {
557
+ return isset( $values['form_id'] ) ? (int) $values['form_id'] : null;
558
+ }
559
+
560
+ /**
561
+ * Get the post_id value for a new entry
562
+ *
563
+ * @since 2.0.16
564
+ * @param array $values
565
+ * @return int
566
+ */
567
+ private static function get_post_id( $values ) {
568
+ return isset( $values['post_id'] ) ? (int) $values['post_id']: 0;
569
+ }
570
+
571
+ /**
572
+ * Get the parent_item_id value for a new entry
573
+ *
574
+ * @since 2.0.16
575
+ * @param array $values
576
+ * @return int
577
+ */
578
+ private static function get_parent_item_id( $values ) {
579
+ return isset( $values['parent_item_id'] ) ? (int) $values['parent_item_id']: 0;
580
+ }
581
+
582
+ /**
583
+ * Get the created_at value for a new entry
584
+ *
585
+ * @since 2.0.16
586
+ * @param array $values
587
+ * @return string
588
+ */
589
+ private static function get_created_at( $values ) {
590
+ return isset( $values['created_at'] ) ? $values['created_at']: current_time('mysql', 1);
591
+ }
592
+
593
+ /**
594
+ * Get the updated_at value for a new entry
595
+ *
596
+ * @since 2.0.16
597
+ * @param array $values
598
+ * @return string
599
+ */
600
+ private static function get_updated_at( $values ) {
601
+ if ( isset( $values['updated_at'] ) ) {
602
+ $updated_at = $values['updated_at'];
603
+ } else {
604
+ $updated_at = self::get_created_at( $values );
605
+ }
606
+
607
+ return $updated_at;
608
+ }
609
+
610
+ /**
611
+ * Get the description value for a new entry
612
+ *
613
+ * @since 2.0.16
614
+ * @param array $values
615
+ * @return string
616
+ */
617
+ private static function get_entry_description( $values ) {
618
+ if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) {
619
+ $description = maybe_serialize( $values['description'] );
620
+ } else {
621
+ $description = serialize( array(
622
+ 'browser' => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
623
+ 'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
624
+ ) );
625
+ }
626
+
627
+ return $description;
628
+ }
629
+
630
+ /**
631
+ * Get the user_id value for a new entry
632
+ *
633
+ * @since 2.0.16
634
+ * @param array $values
635
+ * @return int
636
+ */
637
+ private static function get_entry_user_id( $values ) {
638
+ if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
639
+ $user_id = $values['frm_user_id'];
640
+ } else {
641
+ $current_user_id = get_current_user_id();
642
+ $user_id = $current_user_id ? $current_user_id : 0;
643
+ }
644
+
645
+ return $user_id;
646
+ }
647
+
648
+ /**
649
+ * Insert new entry into the database
650
+ *
651
+ * @since 2.0.16
652
+ * @param array $new_values
653
+ * @return int | boolean $entry_id
654
+ */
655
+ private static function insert_entry_into_database( $new_values ) {
656
+ global $wpdb;
657
+
658
+ $query_results = $wpdb->insert( $wpdb->prefix .'frm_items', $new_values );
659
+
660
+ if ( ! $query_results ) {
661
+ $entry_id = false;
662
+ } else {
663
+ $entry_id = $wpdb->insert_id;
664
+ }
665
+
666
+ return $entry_id;
667
+ }
668
+
669
+ /**
670
+ * Add the new entry to global $frm_vars
671
+ *
672
+ * @since 2.0.16
673
+ * @param int $entry_id
674
+ */
675
+ private static function add_new_entry_to_frm_vars( $entry_id ) {
676
+ global $frm_vars;
677
+
678
+ if ( ! isset($frm_vars['saved_entries']) ) {
679
+ $frm_vars['saved_entries'] = array();
680
+ }
681
+
682
+ $frm_vars['saved_entries'][] = (int) $entry_id;
683
+ }
684
+
685
+ /**
686
+ * Add entry metas, if there are any
687
+ *
688
+ * @since 2.0.16
689
+ * @param array $values
690
+ * @param int $entry_id
691
+ */
692
+ private static function maybe_add_entry_metas( $values, $entry_id ) {
693
+ if ( isset($values['item_meta']) ) {
694
+ FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] );
695
+ }
696
+ }
697
+
698
+ /**
699
+ * Trigger frm_after_create_entry hooks
700
+ *
701
+ * @since 2.0.16
702
+ * @param int $entry_id
703
+ * @param array $new_values
704
+ */
705
+ private static function after_entry_created_actions( $entry_id, $values, $new_values ) {
706
+ // this is a child entry
707
+ $is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
708
+
709
+ do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
710
+ do_action( 'frm_after_create_entry_'. $new_values['form_id'], $entry_id , compact( 'is_child' ) );
711
+ }
712
+
713
+ /**
714
+ * Actions to perform immediately after an entry is inserted in the frm_items database
715
+ *
716
+ * @since 2.0.16
717
+ * @param array $values
718
+ * @param array $new_values
719
+ * @param int $entry_id
720
+ */
721
+ private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) {
722
+
723
+ self::add_new_entry_to_frm_vars( $entry_id );
724
+
725
+ self::maybe_add_entry_metas( $values, $entry_id );
726
+
727
+ self::clear_cache();
728
+
729
+ self::after_entry_created_actions( $entry_id, $values, $new_values );
730
+ }
731
+
732
+ /**
733
+ * Perform some actions right before updating an entry
734
+ *
735
+ * @since 2.0.16
736
+ * @param int $id
737
+ * @param array $values
738
+ * @param string $update_type
739
+ * @return boolean $update
740
+ */
741
+ private static function before_update_entry( $id, &$values, $update_type ) {
742
+ $update = true;
743
+
744
+ global $frm_vars;
745
+
746
+ if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
747
+ $update = false;
748
+ }
749
+
750
+ if ( $update && $update_type != 'xml' ) {
751
+ $values = apply_filters('frm_pre_update_entry', $values, $id);
752
+ }
753
+
754
+ return $update;
755
+ }
756
+
757
+ /**
758
+ * Package the entry data for updating
759
+ *
760
+ * @since 2.0.16
761
+ * @param int $id
762
+ * @param array $values
763
+ * @return array $new_values
764
+ */
765
+ private static function package_entry_to_update( $id, $values ) {
766
+ global $wpdb;
767
+
768
+ $new_values = array(
769
+ 'name' => self::get_new_entry_name( $values ),
770
+ 'form_id' => self::get_form_id( $values ),
771
+ 'is_draft' => self::get_is_draft_value( $values ),
772
+ 'updated_at' => current_time('mysql', 1),
773
+ 'updated_by' => isset($values['updated_by']) ? $values['updated_by'] : get_current_user_id(),
774
+ 'post_id' => self::get_post_id( $values ),
775
+ 'parent_item_id' => self::get_parent_item_id( $values ),
776
+ );
777
+
778
+ if ( isset($values['item_key']) ) {
779
+ $new_values['item_key'] = FrmAppHelper::get_unique_key($values['item_key'], $wpdb->prefix .'frm_items', 'item_key', $id);
780
+ }
781
+
782
+ if ( isset($values['frm_user_id']) && is_numeric($values['frm_user_id']) ) {
783
+ $new_values['user_id'] = $values['frm_user_id'];
784
+ }
785
+
786
+ $new_values = apply_filters('frm_update_entry', $new_values, $id);
787
+
788
+ return $new_values;
789
+ }
790
+
791
+ /**
792
+ * Perform some actions right after updating an entry
793
+ *
794
+ * @since 2.0.16
795
+ * @param boolean|int $query_results
796
+ * @param int $id
797
+ * @param array $values
798
+ * @param array $new_values
799
+ */
800
+ private static function after_update_entry( $query_results, $id, $values, $new_values ) {
801
+ if ( $query_results ) {
802
+ self::clear_cache();
803
+ }
804
+
805
+ global $frm_vars;
806
+ if ( ! isset( $frm_vars['saved_entries'] ) ) {
807
+ $frm_vars['saved_entries'] = array();
808
+ }
809
+
810
+ $frm_vars['saved_entries'][] = (int) $id;
811
+
812
+ if ( isset( $values['item_meta'] ) ) {
813
+ FrmEntryMeta::update_entry_metas( $id, $values['item_meta'] );
814
+ }
815
+
816
+ do_action('frm_after_update_entry', $id, $new_values['form_id'] );
817
+ do_action('frm_after_update_entry_'. $new_values['form_id'], $id );
818
+ }
819
+
820
+ /**
821
+ * Create entry from an XML import
822
+ * Certain actions aren't necessary when importing (like saving sub entries, checking for duplicates, etc.)
823
+ *
824
+ * @since 2.0.16
825
+ * @param array $values
826
+ * @return int | boolean $entry_id
827
+ */
828
+ public static function create_entry_from_xml( $values ){
829
+ $entry_id = self::create_entry( $values, 'xml' );
830
+
831
+ return $entry_id;
832
+ }
833
+
834
+ /**
835
+ * Update entry from an XML import
836
+ * Certain actions aren't necessary when importing (like saving sub entries and modifying other vals)
837
+ *
838
+ * @since 2.0.16
839
+ * @param int $id
840
+ * @param array $values
841
+ * @return int | boolean $updated
842
+ */
843
+ public static function update_entry_from_xml( $id, $values ) {
844
+ $updated = self::update_entry( $id, $values, 'xml' );
845
+
846
+ return $updated;
847
+ }
848
+
849
  /**
850
  * @param string $key
851
  * @return int entry_id
classes/models/FrmEntryValidate.php CHANGED
@@ -182,7 +182,7 @@ class FrmEntryValidate {
182
 
183
  private static function is_akismet_spam( $values ) {
184
  global $wpcom_api_key;
185
- return ( ( function_exists( 'akismet_http_post' ) || is_callable('Akismet::http_post') ) && ( get_option('wordpress_api_key') || $wpcom_api_key ) && self::akismet( $values ) );
186
  }
187
 
188
  private static function is_akismet_enabled_for_user( $form_id ) {
182
 
183
  private static function is_akismet_spam( $values ) {
184
  global $wpcom_api_key;
185
+ return ( is_callable('Akismet::http_post') && ( get_option('wordpress_api_key') || $wpcom_api_key ) && self::akismet( $values ) );
186
  }
187
 
188
  private static function is_akismet_enabled_for_user( $form_id ) {
classes/models/FrmFormAction.php CHANGED
@@ -457,7 +457,7 @@ class FrmFormAction {
457
  $default_values = $this->get_global_defaults();
458
 
459
  // fill default values
460
- $action->post_content = wp_parse_args( $action->post_content, $default_values);
461
 
462
  foreach ( $default_values as $k => $vals ) {
463
  if ( is_array($vals) && ! empty($vals) ) {
457
  $default_values = $this->get_global_defaults();
458
 
459
  // fill default values
460
+ $action->post_content += $default_values;
461
 
462
  foreach ( $default_values as $k => $vals ) {
463
  if ( is_array($vals) && ! empty($vals) ) {
classes/models/FrmNotification.php CHANGED
@@ -169,7 +169,7 @@ class FrmNotification {
169
  * @since 2.0.1
170
  */
171
  private static function explode_emails( $emails ) {
172
- $emails = ( ! empty( $emails ) ? preg_split( '/(,|;)/', $emails ) : '' );
173
  if ( is_array( $emails ) ) {
174
  $emails = array_map( 'trim', $emails );
175
  } else {
169
  * @since 2.0.1
170
  */
171
  private static function explode_emails( $emails ) {
172
+ $emails = ( ! empty( $emails ) ? preg_split( '/(,|;|\s)/', $emails ) : '' );
173
  if ( is_array( $emails ) ) {
174
  $emails = array_map( 'trim', $emails );
175
  } else {
css/_single_theme.css.php CHANGED
@@ -121,7 +121,7 @@ if ( ! isset( $center_form ) ) {
121
 
122
  .<?php echo esc_html( $style_class ) ?> label.frm_primary_label,
123
  .<?php echo esc_html( $style_class ) ?>.frm_login_form label{
124
- font-family:<?php echo esc_html( stripslashes( $font ) ) ?>;
125
  font-size:<?php echo esc_html( $font_size . $important ) ?>;
126
  color:#<?php echo esc_html( $label_color . $important ) ?>;
127
  font-weight:<?php echo esc_html( $weight . $important ) ?>;
@@ -176,7 +176,7 @@ if ( ! isset( $center_form ) ) {
176
  .<?php echo esc_html( $style_class ) ?> .frm_error{
177
  margin:0;
178
  padding:0;
179
- font-family:<?php echo esc_html( stripslashes($font) . $important ) ?>;
180
  font-size:<?php echo esc_html( $description_font_size . $important ) ?>;
181
  color:#<?php echo esc_html( $description_color . $important ) ?>;
182
  font-weight:<?php echo esc_html( $description_weight . $important ) ?>;
@@ -279,7 +279,7 @@ if ( ! isset( $center_form ) ) {
279
 
280
  .<?php echo esc_html( $style_class ) ?> .frm_scale label{
281
  font-weight:<?php echo esc_html( $check_weight . $important ) ?>;
282
- font-family:<?php echo esc_html( stripslashes($font) . $important ) ?>;
283
  font-size:<?php echo esc_html( $check_font_size . $important ) ?>;
284
  color:#<?php echo esc_html( $check_label_color . $important ) ?>;
285
  }
@@ -299,7 +299,7 @@ if ( ! isset( $center_form ) ) {
299
  .<?php echo esc_html( $style_class ) ?> select,
300
  .<?php echo esc_html( $style_class ) ?> textarea,
301
  .<?php echo esc_html( $style_class ) ?> .chosen-container{
302
- font-family:<?php echo esc_html( stripslashes($font) . $important ) ?>;
303
  font-size:<?php echo esc_html( $field_font_size ) ?>;
304
  margin-bottom:0<?php echo esc_html( $important ) ?>;
305
  }
@@ -374,7 +374,7 @@ if ( ! isset( $center_form ) ) {
374
  .<?php echo esc_html( $style_class ) ?> input[type=file]{
375
  color:#<?php echo esc_html( $text_color . $important ) ?>;
376
  padding:0px;
377
- font-family:<?php echo esc_html( stripslashes( $font ) . $important ) ?>;
378
  font-size:<?php echo esc_html( $field_font_size . $important ) ?>;
379
  }
380
 
@@ -383,7 +383,7 @@ if ( ! isset( $center_form ) ) {
383
  }
384
 
385
  .<?php echo esc_html( $style_class ) ?> .frm_file_names, .<?php echo esc_html( $style_class ) ?> .frm_uploaded_files .frm_remove_link{
386
- font-family:<?php echo esc_html( stripslashes( $font ) . $important ) ?>;
387
  font-size:<?php echo esc_html( $field_font_size . $important ) ?>;
388
  }
389
 
@@ -470,7 +470,7 @@ if ( ! $submit_style ) { ?>
470
  .frm_form_submit_style,
471
  .<?php echo esc_html( $style_class ) ?>.frm_login_form input[type=submit]{
472
  width:<?php echo esc_html( ( $submit_width == '' ? 'auto' : $submit_width ) . $important ) ?>;
473
- font-family:<?php echo esc_html( stripslashes( $font ) ) ?>;
474
  font-size:<?php echo esc_html( $submit_font_size . $important ); ?>;
475
  height:<?php echo esc_html( $submit_height . $important ) ?>;
476
  line-height:normal<?php echo esc_html( $important ) ?>;
@@ -535,13 +535,13 @@ if ( ! $submit_style ) { ?>
535
  ?>
536
 
537
  .<?php echo esc_html( $style_class ) ?> a.frm_save_draft{
538
- font-family:<?php echo esc_html( stripslashes( $font ) ) ?>;
539
  font-size:<?php echo esc_html( $submit_font_size ) ?>;
540
  font-weight:<?php echo esc_html( $submit_weight ) ?>;
541
  }
542
 
543
  .<?php echo esc_html( $style_class ) ?> #frm_field_cptch_number_container{
544
- font-family:<?php echo esc_html( stripslashes( $font ) ) ?>;
545
  font-size:<?php echo esc_html( $font_size . $important ) ?>;
546
  color:#<?php echo esc_html( $label_color . $important ) ?>;
547
  font-weight:<?php echo esc_html( $weight . $important ) ?>;
@@ -574,7 +574,7 @@ if ( ! $submit_style ) { ?>
574
 
575
  .<?php echo esc_html( $style_class ) ?> .frm_radio label,
576
  .<?php echo esc_html( $style_class ) ?> .frm_checkbox label{
577
- font-family:<?php echo esc_html( stripslashes($font) . $important ) ?>;
578
  font-size:<?php echo esc_html( $check_font_size . $important ) ?>;
579
  color:#<?php echo esc_html( $check_label_color . $important ) ?>;
580
  font-weight:<?php echo esc_html( $check_weight . $important ) ?>;
@@ -714,7 +714,7 @@ if ( ! $submit_style ) { ?>
714
  -webkit-border-radius:<?php echo esc_html( $border_radius . $important ) ?>;
715
  border-radius:<?php echo esc_html( $border_radius . $important ) ?>;
716
  font-size:<?php echo esc_html( $submit_font_size . $important ) ?>;
717
- font-family:<?php echo esc_html( stripslashes($font) . $important ) ?>;
718
  font-weight:<?php echo esc_html( $submit_weight . $important ) ?>;
719
  color:#<?php echo esc_html( $submit_text_color . $important ) ?>;
720
  background:#<?php echo esc_html( $submit_bg_color . $important ) ?>;
121
 
122
  .<?php echo esc_html( $style_class ) ?> label.frm_primary_label,
123
  .<?php echo esc_html( $style_class ) ?>.frm_login_form label{
124
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) ) ?>;
125
  font-size:<?php echo esc_html( $font_size . $important ) ?>;
126
  color:#<?php echo esc_html( $label_color . $important ) ?>;
127
  font-weight:<?php echo esc_html( $weight . $important ) ?>;
176
  .<?php echo esc_html( $style_class ) ?> .frm_error{
177
  margin:0;
178
  padding:0;
179
+ font-family:<?php echo FrmAppHelper::kses( stripslashes($font) . $important ) ?>;
180
  font-size:<?php echo esc_html( $description_font_size . $important ) ?>;
181
  color:#<?php echo esc_html( $description_color . $important ) ?>;
182
  font-weight:<?php echo esc_html( $description_weight . $important ) ?>;
279
 
280
  .<?php echo esc_html( $style_class ) ?> .frm_scale label{
281
  font-weight:<?php echo esc_html( $check_weight . $important ) ?>;
282
+ font-family:<?php echo FrmAppHelper::kses( stripslashes($font) . $important ) ?>;
283
  font-size:<?php echo esc_html( $check_font_size . $important ) ?>;
284
  color:#<?php echo esc_html( $check_label_color . $important ) ?>;
285
  }
299
  .<?php echo esc_html( $style_class ) ?> select,
300
  .<?php echo esc_html( $style_class ) ?> textarea,
301
  .<?php echo esc_html( $style_class ) ?> .chosen-container{
302
+ font-family:<?php echo FrmAppHelper::kses( stripslashes($font) . $important ) ?>;
303
  font-size:<?php echo esc_html( $field_font_size ) ?>;
304
  margin-bottom:0<?php echo esc_html( $important ) ?>;
305
  }
374
  .<?php echo esc_html( $style_class ) ?> input[type=file]{
375
  color:#<?php echo esc_html( $text_color . $important ) ?>;
376
  padding:0px;
377
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) . $important ) ?>;
378
  font-size:<?php echo esc_html( $field_font_size . $important ) ?>;
379
  }
380
 
383
  }
384
 
385
  .<?php echo esc_html( $style_class ) ?> .frm_file_names, .<?php echo esc_html( $style_class ) ?> .frm_uploaded_files .frm_remove_link{
386
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) . $important ) ?>;
387
  font-size:<?php echo esc_html( $field_font_size . $important ) ?>;
388
  }
389
 
470
  .frm_form_submit_style,
471
  .<?php echo esc_html( $style_class ) ?>.frm_login_form input[type=submit]{
472
  width:<?php echo esc_html( ( $submit_width == '' ? 'auto' : $submit_width ) . $important ) ?>;
473
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) ) ?>;
474
  font-size:<?php echo esc_html( $submit_font_size . $important ); ?>;
475
  height:<?php echo esc_html( $submit_height . $important ) ?>;
476
  line-height:normal<?php echo esc_html( $important ) ?>;
535
  ?>
536
 
537
  .<?php echo esc_html( $style_class ) ?> a.frm_save_draft{
538
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) ) ?>;
539
  font-size:<?php echo esc_html( $submit_font_size ) ?>;
540
  font-weight:<?php echo esc_html( $submit_weight ) ?>;
541
  }
542
 
543
  .<?php echo esc_html( $style_class ) ?> #frm_field_cptch_number_container{
544
+ font-family:<?php echo FrmAppHelper::kses( stripslashes( $font ) ) ?>;
545
  font-size:<?php echo esc_html( $font_size . $important ) ?>;
546
  color:#<?php echo esc_html( $label_color . $important ) ?>;
547
  font-weight:<?php echo esc_html( $weight . $important ) ?>;
574
 
575
  .<?php echo esc_html( $style_class ) ?> .frm_radio label,
576
  .<?php echo esc_html( $style_class ) ?> .frm_checkbox label{
577
+ font-family:<?php echo FrmAppHelper::kses( stripslashes($font) . $important ) ?>;
578
  font-size:<?php echo esc_html( $check_font_size . $important ) ?>;
579
  color:#<?php echo esc_html( $check_label_color . $important ) ?>;
580
  font-weight:<?php echo esc_html( $check_weight . $important ) ?>;
714
  -webkit-border-radius:<?php echo esc_html( $border_radius . $important ) ?>;
715
  border-radius:<?php echo esc_html( $border_radius . $important ) ?>;
716
  font-size:<?php echo esc_html( $submit_font_size . $important ) ?>;
717
+ font-family:<?php echo FrmAppHelper::kses( stripslashes($font) . $important ) ?>;
718
  font-weight:<?php echo esc_html( $submit_weight . $important ) ?>;
719
  color:#<?php echo esc_html( $submit_text_color . $important ) ?>;
720
  background:#<?php echo esc_html( $submit_bg_color . $important ) ?>;
css/frm_admin.css CHANGED
@@ -203,7 +203,6 @@ div.frm_msg_padding{
203
  .frm_forms.with_frm_style{max-width:100%;}
204
  label.frm_primary_label,
205
  #frm_form_editor_container label.frm_primary_label{
206
- font-size:12px;
207
  font-weight:bold;
208
  }
209
  .form-field label.frm_primary_label{
@@ -412,7 +411,7 @@ form label.frm_primary_label input{font-size:12px;}
412
  vertical-align: middle;
413
  }
414
 
415
- .frm_scale{text-align:center;float:left;}
416
  .frm_scale input{display:block;margin:5px}
417
  .frm_form_fields:not(.frm_sample_form) input, .frm_form_fields:not(.frm_sample_form) select, .frm_form_fields:not(.frm_sample_form) textarea{
418
  margin-bottom:0;
@@ -543,8 +542,8 @@ label input[type="checkbox"], label input[type="radio"]{vertical-align:baseline;
543
  height:34px;
544
  }
545
  .frm_form_builder a:hover{text-decoration:underline;}
546
- .frm_38_trigger .widget-title h4 {padding:10px 15px;}
547
- .frm_38_trigger .widget-top a.widget-action:after {padding: 7px 12px 0;}
548
  #postbox-container-1{width:270px;}
549
  #postbox-container-1 .nodrag a{cursor:pointer;}
550
  #postbox-container-1 .frm_field_list #frm-insert-fields{
@@ -887,7 +886,7 @@ li.ui-state-default.selected .frm-show-click.frm_import_options select {
887
  #form_settings_page #post-body-content{min-width:650px;}
888
  #form_settings_page .frm_posttax_row select{max-width:35%;}
889
  select.frm_cancelnew, input.frm_enternew{width:175px;}
890
- .frm_field_box .widget-inside{background:#FBFBFB;}
891
 
892
  /* Global Settings */
893
  .categorydiv .frm_settings_form div.tabs-panel.general_settings{border-top:none;}
@@ -1008,7 +1007,7 @@ select.frm_cancelnew, input.frm_enternew{width:175px;}
1008
  .frm_email_reply_container select,
1009
  .frm_email_reply_container input,
1010
  .form-table td.frm_150_width{
1011
- width:150px;
1012
  }
1013
 
1014
  #frm_notification_settings .frm_no_top_padding{
@@ -1044,8 +1043,11 @@ select.frm_cancelnew, input.frm_enternew{width:175px;}
1044
  #frm_email_addon_menu h3{
1045
  display: inline-block;
1046
  border-bottom:none;
 
1047
  }
1048
  #frm_email_addon_menu h3{
 
 
1049
  margin: 0;
1050
  padding: 10px 15px;
1051
  overflow: hidden;
@@ -1162,15 +1164,9 @@ label.frm_action_events{
1162
  #form_show_entry_page .inside h3{
1163
  border-top:1px solid #eee;
1164
  border-bottom:none;
1165
- margin:15px -15px;
1166
- padding-left:15px;
1167
- }
1168
-
1169
- #poststuff .frm_form_settings .advanced_settings h3,
1170
- #poststuff .frm_form_settings .frm_email_settings .widget-inside h3,
1171
- #form_show_entry_page .inside h3{
1172
- margin-bottom:0;
1173
- padding-bottom:0;
1174
  }
1175
 
1176
  #poststuff .frm_form_settings h3.frm_first_h3,
@@ -1294,7 +1290,7 @@ span.howto{display:inline;}
1294
  .frm_sorting .form-field .widget select,
1295
  #wpcontent .frm_sorting .form-field .widget select,
1296
  .frm_sorting .form-field .widget textarea{
1297
- width:auto;font-size:11px;
1298
  }
1299
 
1300
  .tagchecklist span.no_taglist {
@@ -1415,7 +1411,7 @@ span.howto{display:inline;}
1415
  .frm_sorting > li.ui-state-default,
1416
  .frm_sorting .no_repeat_section li.ui-state-default.edit_field_type_end_divider:hover{
1417
  border:1px solid transparent;
1418
- font-weight:lighter !important;
1419
  background-color:transparent;
1420
  background-image:none;
1421
  padding:5px;
@@ -1486,8 +1482,8 @@ a.frm_button:hover{
1486
  }
1487
  ul.start_divider{
1488
  padding:6px 12px 0;
1489
- border-left:1px solid #D7D7D7;
1490
- border-bottom:1px solid #D7D7D7;
1491
  min-height:100px;
1492
  }
1493
 
@@ -1524,13 +1520,6 @@ ul.start_divider{
1524
  .frm_validation_msg p label{float:left;width:25%;max-width:100px;}
1525
  .frm_sorting .form-field .widget .frm_validation_msg input{width:71%;}
1526
 
1527
- .frm_38_trigger .frm_sorting .widget-inside .form-table td,
1528
- .frm_38_trigger .frm_sorting .widget-inside .form-table td p,
1529
- .frm_38_trigger .frm_sorting .widget-inside .form-wrap label{
1530
- font-size:12px;
1531
- padding:10px;
1532
- }
1533
-
1534
  .frm_38_trigger .frm_sorting .widget-inside .form-table td p,
1535
  .frm_38_trigger .frm_sorting .widget-inside .form-wrap label{
1536
  padding:10px 0;
@@ -1704,8 +1693,12 @@ table td.frm_left_label{
1704
  .frm_sorting li.ui-state-default.frm_not_divider.selected,
1705
  .frm_38_trigger .frm_sorting li.ui-state-default.frm_not_divider.selected,
1706
  .frm_sorting li.ui-state-default.selected.edit_field_type_divider .divider_section_only{
1707
- border:1px solid #e4f3ff;
1708
  background-color: #fbfdff;
 
 
 
 
 
1709
  }
1710
  .start_divider.frm_sorting li.ui-state-default.frm_not_divider.selected {
1711
  border:1px solid #E7E7E7;
203
  .frm_forms.with_frm_style{max-width:100%;}
204
  label.frm_primary_label,
205
  #frm_form_editor_container label.frm_primary_label{
 
206
  font-weight:bold;
207
  }
208
  .form-field label.frm_primary_label{
411
  vertical-align: middle;
412
  }
413
 
414
+ .frm_scale{text-align:center;float:left;margin-right:10px;}
415
  .frm_scale input{display:block;margin:5px}
416
  .frm_form_fields:not(.frm_sample_form) input, .frm_form_fields:not(.frm_sample_form) select, .frm_form_fields:not(.frm_sample_form) textarea{
417
  margin-bottom:0;
542
  height:34px;
543
  }
544
  .frm_form_builder a:hover{text-decoration:underline;}
545
+ .frm_form_builder .frm_38_trigger .widget-title h4 {padding:10px 15px;}
546
+ .frm_form_builder .frm_38_trigger .widget-top a.widget-action:after {padding: 7px 12px 0;}
547
  #postbox-container-1{width:270px;}
548
  #postbox-container-1 .nodrag a{cursor:pointer;}
549
  #postbox-container-1 .frm_field_list #frm-insert-fields{
886
  #form_settings_page #post-body-content{min-width:650px;}
887
  #form_settings_page .frm_posttax_row select{max-width:35%;}
888
  select.frm_cancelnew, input.frm_enternew{width:175px;}
889
+
890
 
891
  /* Global Settings */
892
  .categorydiv .frm_settings_form div.tabs-panel.general_settings{border-top:none;}
1007
  .frm_email_reply_container select,
1008
  .frm_email_reply_container input,
1009
  .form-table td.frm_150_width{
1010
+ width:170px;
1011
  }
1012
 
1013
  #frm_notification_settings .frm_no_top_padding{
1043
  #frm_email_addon_menu h3{
1044
  display: inline-block;
1045
  border-bottom:none;
1046
+ padding: 10px;
1047
  }
1048
  #frm_email_addon_menu h3{
1049
+ font-size: 14px;
1050
+ line-height: 1.4;
1051
  margin: 0;
1052
  padding: 10px 15px;
1053
  overflow: hidden;
1164
  #form_show_entry_page .inside h3{
1165
  border-top:1px solid #eee;
1166
  border-bottom:none;
1167
+ margin:15px -15px 0;
1168
+ padding: 8px 15px;
1169
+ font-size:14px;
 
 
 
 
 
 
1170
  }
1171
 
1172
  #poststuff .frm_form_settings h3.frm_first_h3,
1290
  .frm_sorting .form-field .widget select,
1291
  #wpcontent .frm_sorting .form-field .widget select,
1292
  .frm_sorting .form-field .widget textarea{
1293
+ width:auto;
1294
  }
1295
 
1296
  .tagchecklist span.no_taglist {
1411
  .frm_sorting > li.ui-state-default,
1412
  .frm_sorting .no_repeat_section li.ui-state-default.edit_field_type_end_divider:hover{
1413
  border:1px solid transparent;
1414
+ font-weight:normal !important;
1415
  background-color:transparent;
1416
  background-image:none;
1417
  padding:5px;
1482
  }
1483
  ul.start_divider{
1484
  padding:6px 12px 0;
1485
+ border-left:1px solid #5B9DD9;
1486
+ border-bottom:1px solid #5B9DD9;
1487
  min-height:100px;
1488
  }
1489
 
1520
  .frm_validation_msg p label{float:left;width:25%;max-width:100px;}
1521
  .frm_sorting .form-field .widget .frm_validation_msg input{width:71%;}
1522
 
 
 
 
 
 
 
 
1523
  .frm_38_trigger .frm_sorting .widget-inside .form-table td p,
1524
  .frm_38_trigger .frm_sorting .widget-inside .form-wrap label{
1525
  padding:10px 0;
1693
  .frm_sorting li.ui-state-default.frm_not_divider.selected,
1694
  .frm_38_trigger .frm_sorting li.ui-state-default.frm_not_divider.selected,
1695
  .frm_sorting li.ui-state-default.selected.edit_field_type_divider .divider_section_only{
 
1696
  background-color: #fbfdff;
1697
+ border: 1px solid #5b9dd9;
1698
+ -webkit-box-shadow: 0 0 1px #96B0C7;;
1699
+ box-shadow: 0 0 1px #96B0C7;
1700
+ -webkit-transition: 0.5s border-color ease-in-out;
1701
+ transition: .5s border-color ease-in-out;
1702
  }
1703
  .start_divider.frm_sorting li.ui-state-default.frm_not_divider.selected {
1704
  border:1px solid #E7E7E7;
formidable.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Formidable
4
  Description: Quickly and easily create drag-and-drop forms
5
- Version: 2.0.15
6
  Plugin URI: http://formidablepro.com/
7
  Author URI: http://strategy11.com
8
  Author: Strategy11
2
  /*
3
  Plugin Name: Formidable
4
  Description: Quickly and easily create drag-and-drop forms
5
+ Version: 2.0.16
6
  Plugin URI: http://formidablepro.com/
7
  Author URI: http://strategy11.com
8
  Author: Strategy11
js/formidable.js CHANGED
@@ -158,7 +158,7 @@ function frmFrontFormJS(){
158
  var field_id = nameParts[0];
159
  var isRepeating = false;
160
 
161
- if ( nameParts.length === 1 || nameParts[1] == '[form' ) {
162
  return field_id;
163
  }
164
 
@@ -663,49 +663,96 @@ function frmFrontFormJS(){
663
 
664
  /* Show Field Functions */
665
  function routeToShowFieldAndSetVal( hideFieldContainer, f ) {
 
 
 
 
666
  if ( hideFieldContainer.length ) {
667
  // Field is not type=hidden
668
- showFieldAndSetValue( hideFieldContainer );
669
  } else {
670
  // Set field value (don't show it)
671
  var fieldName = getFieldName( f.HideField, f.hideContainerID );
672
  var inputs = jQuery( 'input[name^="' + fieldName + '"]' );
673
- setValForInputs( inputs );
674
  }
675
- removeFromHideFields( f.hideContainerID, f.FormId );
676
  }
677
 
678
- function showFieldAndSetValue( container ) {
679
  var inputs = getInputsInContainer( container );
680
 
681
- setValForInputs( inputs );
682
 
683
  container.show();
684
  }
685
 
686
- function setValForInputs( inputs ){
687
  if ( inputs.length ) {
 
 
 
688
  for ( var i = 0; i < inputs.length; i++ ) {
 
 
 
 
 
689
  setDefaultValue( jQuery( inputs[i] ) );
690
  maybeDoCalcForSingleField( inputs[i] );
691
  }
692
  }
693
  }
694
 
695
- function setDefaultValue( input ) {
696
- var inputLenth = input.length;
697
 
698
- // If the field already has a value (i.e. when form is loaded for editing an entry), don't get the default value
699
- if ( input.is(':checkbox, :radio') ) {
700
- if ( input.is(':checked') ) {
701
- return;
 
 
 
 
 
702
  }
703
- } else if ( input.val() ) {
704
- return;
705
  }
706
 
707
- if ( inputLenth ) {
708
- for ( var i = 0, l = inputLenth; i < l; i++ ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  var field = jQuery(input[i]);
710
  var defaultValue = field.data('frmval');
711
  if ( typeof defaultValue !== 'undefined' ) {
@@ -744,9 +791,11 @@ function frmFrontFormJS(){
744
  function maybeGetDynamicFieldData( hvalue, rec ) {
745
  if ( hvalue.DynamicInfoIndices.length > 0 ) {
746
  var dynamicIndex;
 
747
  for ( var t = 0; t < hvalue.DynamicInfoIndices.length; t++ ) {
748
  dynamicIndex = hvalue.DynamicInfoIndices[ t ];
749
- showField( show_fields[ hvalue.hideContainerID ][ dynamicIndex ], hvalue.FieldName, rec );
 
750
  }
751
  }
752
  }
@@ -788,14 +837,14 @@ function frmFrontFormJS(){
788
  /* If no value, then assume no match */
789
  return 0;
790
  }
791
- return d.indexOf(c) != -1;
792
  },
793
  'not LIKE': function(c,d){
794
  if(!d){
795
  /* If no value, then assume no match */
796
  return 1;
797
  }
798
- return d.indexOf(c) == -1;
799
  }
800
  };
801
  return theOperators[op](a, b);
@@ -858,7 +907,7 @@ function frmFrontFormJS(){
858
  var hiddenInput = jQuery( '#' + f.hideContainerID ).find('select[name^="item_meta"], textarea[name^="item_meta"], input[name^="item_meta"]');
859
 
860
  // Get the previously selected field value
861
- var prev = getPrevFieldValue( hiddenInput );
862
 
863
  // Get default value
864
  var defaultValue = hiddenInput.data('frmval');
@@ -899,67 +948,28 @@ function frmFrontFormJS(){
899
  type:'POST',
900
  url:frm_js.ajax_url,
901
  data:{
902
- action:'frm_fields_ajax_data_options', hide_field:field_id,
903
- entry_id:selected, selected_field_id:f.LinkedField, field_id:f.HideField,
904
- default_value:defaultValue, hide_id:f.hideContainerID, nonce:frm_js.nonce
 
905
  },
906
  success:function(html){
907
  $dataField.html(html);
908
- var parentField = $dataField.find('select, input, textarea');
909
- var val = 1;
910
- if ( parentField.attr('type') == 'hidden' ) {
911
- val = parentField.val();
912
- }
913
 
914
- if ( html === '' || val === '' ) {
 
915
  fcont.style.display = 'none';
916
- prev = '';
917
- }else if(f.MatchType != 'all'){
918
  fcont.style.display = '';
919
  }
920
 
921
- if(html !== ''){
922
- if ( prev !== '' ) {
923
- if(!jQuery.isArray(prev)){
924
- var new_prev = [];
925
- new_prev.push(prev);
926
- prev = new_prev;
927
- }
928
-
929
- //select options that were selected previously
930
- jQuery.each(prev, function(ckey,cval){
931
- if ( typeof(cval) === 'undefined' || cval === '' ) {
932
- return;
933
- }
934
- if ( dataType == 'checkbox' || dataType == 'radio' ) {
935
- if ( parentField.length > 1 ) {
936
- parentField.filter('[value="' + cval+ '"]').attr('checked','checked');
937
- } else if ( parentField.val() == cval ){
938
- parentField.attr('checked','checked');
939
- }
940
- } else if ( dataType == 'select' ) {
941
- var selOpt = parentField.children('option[value="'+ cval +'"]');
942
- if(selOpt.length){
943
- selOpt.prop('selected', true);
944
- }else{
945
- //remove options that no longer exist
946
- prev.splice(ckey, 1);
947
- }
948
- }else{
949
- parentField.val(cval);
950
- }
951
- });
952
- } else {
953
- // If no options were selected previously, set to default value
954
- setDefaultValue( getInputsInContainer( $dataField ) );
955
- }
956
- }
957
-
958
- if(parentField.hasClass('frm_chzn') && jQuery().chosen){
959
  jQuery('.frm_chzn').chosen({allow_single_deselect:true});
960
  }
961
 
962
- triggerChange( parentField );
963
  }
964
  });
965
  }
@@ -1148,6 +1158,11 @@ function frmFrontFormJS(){
1148
  return;
1149
  }
1150
 
 
 
 
 
 
1151
  var all_calcs = __FRMCALC;
1152
  var field_key = getFieldKey( field_input.id, field_input.name );
1153
  var triggerField = maybeGetTriggerField( field_input );
@@ -2230,6 +2245,69 @@ function frmFrontFormJS(){
2230
  }
2231
  }
2232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2233
  /* Fallback functions */
2234
  function addIndexOfFallbackForIE8() {
2235
  if ( !Array.prototype.indexOf ) {
158
  var field_id = nameParts[0];
159
  var isRepeating = false;
160
 
161
+ if ( nameParts.length === 1 || nameParts[1] == '[form' || nameParts[1] == '[id' ) {
162
  return field_id;
163
  }
164
 
663
 
664
  /* Show Field Functions */
665
  function routeToShowFieldAndSetVal( hideFieldContainer, f ) {
666
+ var inSection = isAContainerField( hideFieldContainer );
667
+ var inputAtts = {inSection:inSection, formId:f.FormId};
668
+
669
+ removeFromHideFields( f.hideContainerID, f.FormId );
670
  if ( hideFieldContainer.length ) {
671
  // Field is not type=hidden
672
+ showFieldAndSetValue( hideFieldContainer, inputAtts );
673
  } else {
674
  // Set field value (don't show it)
675
  var fieldName = getFieldName( f.HideField, f.hideContainerID );
676
  var inputs = jQuery( 'input[name^="' + fieldName + '"]' );
677
+ setValForInputs( inputs, inputAtts );
678
  }
 
679
  }
680
 
681
+ function showFieldAndSetValue( container, inputAtts ) {
682
  var inputs = getInputsInContainer( container );
683
 
684
+ setValForInputs( inputs, inputAtts );
685
 
686
  container.show();
687
  }
688
 
689
+ function setValForInputs( inputs, fieldAtts ){
690
  if ( inputs.length ) {
691
+ fieldAtts.valSet = false;
692
+ fieldAtts.isHidden = false;
693
+
694
  for ( var i = 0; i < inputs.length; i++ ) {
695
+
696
+ if ( skipThisInput( inputs, i, fieldAtts ) === true ) {
697
+ continue;
698
+ }
699
+
700
  setDefaultValue( jQuery( inputs[i] ) );
701
  maybeDoCalcForSingleField( inputs[i] );
702
  }
703
  }
704
  }
705
 
706
+ function skipThisInput( inputs, i, fieldAtts ) {
707
+ var goToNextIteration = false;
708
 
709
+ if ( i === 0 || inputs[i-1].name != inputs[i].name ) {
710
+ // This field hasn't been checked yet
711
+
712
+ if ( fieldAtts.inSection && isInputConditionallyHidden( inputs[i], fieldAtts ) ) {
713
+ fieldAtts.isHidden = true;
714
+ fieldAtts.valSet = false;
715
+ } else {
716
+ fieldAtts.isHidden = false;
717
+ fieldAtts.valSet = isValueSet( inputs[i] );