Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms - Version 1.12.11

Version Description

  • Improvement: Deactivation popup allows for keeping or deleting saved data.
  • Improvement: Forms block now supports additional CSS classes.
  • Bugfix: Arrows in dropdowns were ignoring Style settings.
  • Bugfix: Duplicating and drag-dropping fields in the builder was scrolling the field list to the top.
Download this release

Release Info

Developer happyforms
Plugin Icon 128x128 Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms
Version 1.12.11
Comparing to
See all releases

Code changes from version 1.12.10 to 1.12.11

core/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
1
+ .DS_Store
2
+
core/assets/css/admin.css CHANGED
@@ -333,3 +333,25 @@ p.happyforms-message-nav span.divider:last-child {
333
  .happyforms-modal__content form button.button-primary {
334
  margin-top: 30px;
335
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  .happyforms-modal__content form button.button-primary {
334
  margin-top: 30px;
335
  }
336
+
337
+ /**
338
+ *
339
+ * Deactivation modal
340
+ *
341
+ */
342
+ .happyforms-modal__frame--deactivate h1 {
343
+ margin-bottom: 0;
344
+ }
345
+
346
+ .happyforms-modal__frame--deactivate .happyforms-modal__content form label {
347
+ margin: 0 0 10px;
348
+ }
349
+
350
+ /**
351
+ *
352
+ * Gutenberg block
353
+ *
354
+ */
355
+ .edit-post-visual-editor .happyforms-block-form-selector-wrap .components-select-control__input {
356
+ padding: 0 10px;
357
+ }
core/assets/css/color.css CHANGED
@@ -384,6 +384,7 @@
384
 
385
  .happyforms-styles .happyforms-part__select-wrap:after {
386
  border-top: 6px solid #000;
 
387
  }
388
 
389
  .happyforms-styles .happyforms-part--select select:focus,
384
 
385
  .happyforms-styles .happyforms-part__select-wrap:after {
386
  border-top: 6px solid #000;
387
+ border-top-color: var(--happyforms-color-dropdown-item-text);
388
  }
389
 
390
  .happyforms-styles .happyforms-part--select select:focus,
core/assets/css/customize.css CHANGED
@@ -691,10 +691,6 @@ body.adding-happyforms-parts .happyforms-add-new-part:before {
691
  margin-bottom: 0;
692
  }
693
 
694
- .happyforms-form-widgets {
695
- overflow-x: hidden;
696
- }
697
-
698
  .happyforms-style-view .happyforms-form-widgets {
699
  margin-top: 0;
700
  }
691
  margin-bottom: 0;
692
  }
693
 
 
 
 
 
694
  .happyforms-style-view .happyforms-form-widgets {
695
  margin-top: 0;
696
  }
core/assets/js/admin/block.js CHANGED
@@ -19,18 +19,12 @@
19
  } )
20
  options.reverse().unshift( { label: settings.i18n.select_default, value: '' } );
21
 
22
- var getEditLink = function( id ) {
23
- var returnUrl = encodeURIComponent( document.location.href );
24
- var link = settings.editLink.replace( 'ID', id ).replace( 'URL', returnUrl );
25
-
26
- return link;
27
- }
28
-
29
  var ComponentPlaceholder = function( props ) {
30
  var component =
31
  el( Placeholder, {
32
  icon: settings.icon,
33
  label: settings.i18n.placeholder_text,
 
34
  },
35
  el( SelectControl, {
36
  value: '',
@@ -52,48 +46,6 @@
52
  );
53
 
54
  var component = [ shortcode ];
55
- var formID = props.attributes.id;
56
- var noticeID = 'happyforms_gutenberg_' + formID + '_upgrade';
57
- var isDismissed = false;
58
-
59
- for ( var property in settings.dismissed_notices ) {
60
- if ( settings.dismissed_notices.hasOwnProperty( property ) ) {
61
- if ( noticeID === settings.dismissed_notices[property] ) {
62
- isDismissed = true;
63
- }
64
- }
65
- }
66
-
67
- var show = settings.upgrade_notice.show && ! isDismissed;
68
-
69
- if ( show ) {
70
- component = [
71
- el( 'div',
72
- {
73
- id: 'happyforms_notice_' + noticeID
74
- },
75
- el( Notice, {
76
- status: 'warning',
77
- isDismissible: true,
78
- onRemove: function(e, b) {
79
- $.post( settings.ajaxurl, {
80
- action: 'happyforms_hide_notice',
81
- nid: noticeID,
82
- nonce: settings.upgrade_notice.nonces[formID]
83
- }, function( response ) {
84
- $( '#happyforms_notice_' + noticeID ).hide();
85
- } );
86
- }
87
- }, el( 'p',
88
- null,
89
- settings.upgrade_notice.i18n.text,
90
- el( 'a', { href: 'https://happyforms.io/upgrade', target: '_blank' }, ' ' + settings.upgrade_notice.i18n.link_text )
91
- )
92
- ),
93
- ),
94
- shortcode
95
- ];
96
- }
97
 
98
  return component;
99
  };
@@ -110,11 +62,6 @@
110
  },
111
  } ),
112
 
113
- props.attributes.id && el( Button, {
114
- href: getEditLink( props.attributes.id ),
115
- isLink: true,
116
- icon: 'external'
117
- }, settings.i18n.edit_form, el( Icon, { icon: 'external' } ) )
118
  ),
119
  );
120
 
19
  } )
20
  options.reverse().unshift( { label: settings.i18n.select_default, value: '' } );
21
 
 
 
 
 
 
 
 
22
  var ComponentPlaceholder = function( props ) {
23
  var component =
24
  el( Placeholder, {
25
  icon: settings.icon,
26
  label: settings.i18n.placeholder_text,
27
+ className: settings.i18n.placeholder_class,
28
  },
29
  el( SelectControl, {
30
  value: '',
46
  );
47
 
48
  var component = [ shortcode ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  return component;
51
  };
62
  },
63
  } ),
64
 
 
 
 
 
 
65
  ),
66
  );
67
 
core/assets/js/admin/dashboard.js CHANGED
@@ -4,11 +4,16 @@
4
  window.happyForms = happyForms;
5
 
6
  happyForms.dashboard = {
 
 
7
  init: function() {
8
  $( document ).on( 'click', '.happyforms-editor-button', this.onEditorButton.bind( this ) );
9
  $( '.happyforms-dialog__button' ).on( 'click', this.onDialogButton.bind( this ) );
10
  $( '.happyforms-notice:not(.one-time)' ).on( 'click', '.notice-dismiss', this.onNoticeDismiss.bind( this ) );
11
  $( document ).on( 'click', '.happyforms-modal__frame', this.lockModalEvent );
 
 
 
12
  },
13
 
14
  onEditorButton: function( e ) {
@@ -116,6 +121,39 @@
116
  lockModalEvent: function( e ) {
117
  e.stopPropagation();
118
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  };
120
 
121
  $( function() {
4
  window.happyForms = happyForms;
5
 
6
  happyForms.dashboard = {
7
+ $deactivationLink: null,
8
+
9
  init: function() {
10
  $( document ).on( 'click', '.happyforms-editor-button', this.onEditorButton.bind( this ) );
11
  $( '.happyforms-dialog__button' ).on( 'click', this.onDialogButton.bind( this ) );
12
  $( '.happyforms-notice:not(.one-time)' ).on( 'click', '.notice-dismiss', this.onNoticeDismiss.bind( this ) );
13
  $( document ).on( 'click', '.happyforms-modal__frame', this.lockModalEvent );
14
+ $( document ).on( 'click', 'a[id^="deactivate-happyforms"]', this.openDeactivateModal );
15
+ $( document ).on( 'click', '.happyforms-modal__frame--deactivate input[name="keep-data"]', this.onSelectKeepData );
16
+ $( document ).on( 'submit', '.happyforms-modal__frame--deactivate form', this.onDeactivateModalSubmit );
17
  },
18
 
19
  onEditorButton: function( e ) {
121
  lockModalEvent: function( e ) {
122
  e.stopPropagation();
123
  },
124
+
125
+ openDeactivateModal: function( e ) {
126
+ e.preventDefault();
127
+
128
+ happyForms.dashboard.$deactivationLink = $( e.target );
129
+ happyForms.dashboard.openModal( 'deactivate' );
130
+ },
131
+
132
+ onDeactivateModalSubmit: function( e ) {
133
+ e.preventDefault();
134
+
135
+ var $form = $( e.target );
136
+ var nonce = $( 'input[name="_wpnonce"]', $form ).val();
137
+ var keepData = $( 'input[name="keep-data"]:checked', $form ).val();
138
+ var redirectUrl = happyForms.dashboard.$deactivationLink.attr( 'href' );
139
+
140
+ $.post( ajaxurl, {
141
+ action: settings.actionDeactivateModalSubmit,
142
+ _wpnonce: nonce,
143
+ keep_data: keepData,
144
+ }, function() {
145
+ window.location.href = redirectUrl;
146
+ } );
147
+
148
+ happyForms.dashboard.closeModal();
149
+ },
150
+
151
+ onSelectKeepData: function( e ) {
152
+ var keepData = $( '.happyforms-modal__frame--deactivate input[name="keep-data"]:checked' ).val();
153
+ var buttonText = 'no' == keepData ? settings.textDeactivateAndCleanup : settings.textDeactivateAndKeep;
154
+
155
+ $( '.happyforms-modal__frame--deactivate button[type="submit"]' ).text( buttonText );
156
+ },
157
  };
158
 
159
  $( function() {
core/assets/js/frontend/select.js CHANGED
@@ -7,7 +7,7 @@
7
  this.type = this.$el.data( 'happyforms-type' );
8
 
9
  this.$input = $( '[data-serialize]', this.$el );
10
- var $visualInput = $( 'input[type="text"]', this.$el );
11
  var $select = $( '.happyforms-custom-select-dropdown', this.$el );
12
 
13
  $visualInput.happyFormsSelect( {
@@ -22,4 +22,4 @@
22
  },
23
  };
24
 
25
- } )( jQuery );
7
  this.type = this.$el.data( 'happyforms-type' );
8
 
9
  this.$input = $( '[data-serialize]', this.$el );
10
+ var $visualInput = $( 'input[type="text"]:not(.happyforms-select-dropdown-other)', this.$el );
11
  var $select = $( '.happyforms-custom-select-dropdown', this.$el );
12
 
13
  $visualInput.happyFormsSelect( {
22
  },
23
  };
24
 
25
+ } )( jQuery );
core/classes/class-block.php CHANGED
@@ -67,6 +67,17 @@ class HappyForms_Block {
67
  }
68
 
69
  public function render( $attrs ) {
 
 
 
 
 
 
 
 
 
 
 
70
  return HappyForms()->handle_shortcode( $attrs );
71
  }
72
 
@@ -83,34 +94,18 @@ class HappyForms_Block {
83
  $forms = array_values( wp_list_filter( $forms, array( 'post_status' => 'publish' ) ) );
84
  $forms = wp_list_pluck( $forms, 'post_title', 'ID' );
85
 
86
- $upgrade_notice_nonces = array();
87
 
88
- foreach( $forms as $ID => $form ) {
89
- $upgrade_notice_nonces[$ID] = wp_create_nonce( 'happyforms_dismiss_' . 'happyforms_gutenberg_' . $ID . '_upgrade' );
90
- }
91
-
92
- $edit_link = admin_url( happyforms_get_form_edit_link( 'ID', 'URL' ) );
93
  $block_properties = $this->get_properties();
94
  $data = array(
95
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
96
  'forms' => $forms,
97
- 'editLink' => $edit_link,
98
  'block' => $block_properties,
99
- 'upgrade_notice' => array(
100
- 'show' => ( ! defined( 'HAPPYFORMS_UPGRADE_VERSION' ) ) ? true : false,
101
- 'i18n' => array(
102
- 'text' => __( 'Do you want access to HappyForms’ most powerful features?', 'happyforms' ),
103
- 'link_text' => __( 'Discover HappyForms Upgrade', 'happyforms' ),
104
- ),
105
- 'nonces' => $upgrade_notice_nonces
106
- ),
107
  'i18n' => array(
108
  'select_default' => __( 'Choose', 'happyforms' ),
109
  'placeholder_text' => __( 'Which form would you like to add here?', 'happyforms' ),
110
  'settings_title' => __( 'HappyForms Settings', 'happyforms' ),
111
- 'edit_form' => __( 'Edit Form', 'happyforms' )
112
  ),
113
- 'dismissed_notices' => $admin_notices->get_dismissed_notices( $user_id )
114
  );
115
 
116
  wp_localize_script( 'happyforms-block', '_happyFormsBlockSettings', $data );
67
  }
68
 
69
  public function render( $attrs ) {
70
+ $block_classes = isset( $attrs['className'] ) ? trim( $attrs['className'] ) : '';
71
+
72
+ if ( '' !== $block_classes ) {
73
+ $block_classes = explode( ' ', $block_classes );
74
+
75
+ add_filter( 'happyforms_form_class', function( $class, $form ) use ( $block_classes ) {
76
+ $class = array_merge( $class, $block_classes );
77
+ return $class;
78
+ }, 10, 2 );
79
+ }
80
+
81
  return HappyForms()->handle_shortcode( $attrs );
82
  }
83
 
94
  $forms = array_values( wp_list_filter( $forms, array( 'post_status' => 'publish' ) ) );
95
  $forms = wp_list_pluck( $forms, 'post_title', 'ID' );
96
 
 
97
 
 
 
 
 
 
98
  $block_properties = $this->get_properties();
99
  $data = array(
100
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
101
  'forms' => $forms,
 
102
  'block' => $block_properties,
 
 
 
 
 
 
 
 
103
  'i18n' => array(
104
  'select_default' => __( 'Choose', 'happyforms' ),
105
  'placeholder_text' => __( 'Which form would you like to add here?', 'happyforms' ),
106
  'settings_title' => __( 'HappyForms Settings', 'happyforms' ),
107
+ 'placeholder_class' => 'happyforms-block-form-selector-wrap'
108
  ),
 
109
  );
110
 
111
  wp_localize_script( 'happyforms-block', '_happyFormsBlockSettings', $data );
core/classes/class-deactivation.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class HappyForms_Deactivation {
4
+
5
+ private static $instance;
6
+
7
+ public $modal_action = 'happyforms-deactivate-modal-submit';
8
+ public $option = '_happyforms_cleanup_on_deactivate';
9
+
10
+ public static function instance() {
11
+ if ( is_null( self::$instance ) ) {
12
+ self::$instance = new self();
13
+ }
14
+
15
+ self::$instance->hook();
16
+
17
+ return self::$instance;
18
+ }
19
+
20
+ public function hook() {
21
+ add_action( 'admin_init', [ $this, 'register_modals' ] );
22
+ add_filter( 'happyforms_dashboard_data', [ $this, 'get_dashboard_data' ] );
23
+ add_action( 'wp_ajax_' . $this->modal_action, [ $this, 'deactivate_modal_submit' ] );
24
+ }
25
+
26
+ public function cleanup_on_deactivation() {
27
+ $cleanup = get_option( $this->option, false );
28
+
29
+ return $cleanup;
30
+ }
31
+
32
+ public function register_modals() {
33
+ $modals = happyforms_get_dashboard_modals();
34
+
35
+ $modals->register_modal( 'deactivate', [ $this, 'modal_deactivate_callback' ], [
36
+ 'classes' => 'happyforms-modal__frame--deactivate'
37
+ ] );
38
+ }
39
+
40
+ public function modal_deactivate_callback() {
41
+ require( happyforms_get_core_folder() . '/templates/admin/modal-deactivate.php' );
42
+ }
43
+
44
+ public function get_dashboard_data( $data ) {
45
+ $data['actionDeactivateModalSubmit'] = $this->modal_action;
46
+ $data['textDeactivateAndKeep'] = __( 'Deactivate Plugin', 'happyforms' );
47
+ $data['textDeactivateAndCleanup'] = __( 'Delete Data and Deactivate Plugin', 'happyforms' );
48
+
49
+ return $data;
50
+ }
51
+
52
+ public function deactivate_modal_submit() {
53
+ if ( ! check_ajax_referer( $this->modal_action ) ) {
54
+ return;
55
+ }
56
+
57
+ $keep_data = isset( $_POST['keep_data'] ) ? $_POST['keep_data'] : 'yes';
58
+
59
+ update_option( $this->option, 'no' === $keep_data );
60
+ }
61
+
62
+ }
63
+
64
+ if ( ! function_exists( 'happyforms_get_deactivation' ) ) :
65
+
66
+ function happyforms_get_deactivation() {
67
+ return HappyForms_Deactivation::instance();
68
+ }
69
+
70
+ endif;
71
+
72
+ happyforms_get_deactivation();
core/classes/class-happyforms-core.php CHANGED
@@ -107,8 +107,10 @@ class HappyForms_Core {
107
  // Preview scripts and styles
108
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_preview' ) );
109
  add_action( 'wp_footer', array( $this, 'enqueue_scripts_preview' ) );
110
-
111
  add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) );
 
 
 
112
  }
113
 
114
  public function customize_preview_init() {
107
  // Preview scripts and styles
108
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_preview' ) );
109
  add_action( 'wp_footer', array( $this, 'enqueue_scripts_preview' ) );
 
110
  add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) );
111
+
112
+ // Deactivation
113
+ require_once( happyforms_get_core_folder() . '/classes/class-deactivation.php' );
114
  }
115
 
116
  public function customize_preview_init() {
core/classes/parts/class-part-select.php CHANGED
@@ -4,6 +4,8 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
4
 
5
  public $type = 'select';
6
 
 
 
7
  public function __construct() {
8
  $this->label = __( 'Dropdown', 'happyforms' );
9
  $this->description = __( 'For selecting one option from a long list. Default value adjustable.', 'happyforms' );
@@ -12,6 +14,8 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
12
  }
13
 
14
  public function hook() {
 
 
15
  add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
16
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
17
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
@@ -118,7 +122,10 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
118
  $part['options'][$o] = wp_parse_args( $option, $this->get_option_defaults() );
119
  }
120
 
121
- include( happyforms_get_core_folder() . '/templates/parts/frontend-select.php' );
 
 
 
122
  }
123
 
124
  /**
4
 
5
  public $type = 'select';
6
 
7
+ public static $parent;
8
+
9
  public function __construct() {
10
  $this->label = __( 'Dropdown', 'happyforms' );
11
  $this->description = __( 'For selecting one option from a long list. Default value adjustable.', 'happyforms' );
14
  }
15
 
16
  public function hook() {
17
+ self::$parent = $this;
18
+
19
  add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
20
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
21
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
122
  $part['options'][$o] = wp_parse_args( $option, $this->get_option_defaults() );
123
  }
124
 
125
+ $template_path = happyforms_get_core_folder() . '/templates/parts/frontend-select.php';
126
+ $template_path = happyforms_get_part_frontend_template_path( $template_path, $this->type );
127
+
128
+ include( $template_path );
129
  }
130
 
131
  /**
core/helpers/helper-activation.php CHANGED
@@ -161,4 +161,59 @@ function happyforms_create_samples() {
161
 
162
  endif;
163
 
164
- add_action( 'happyforms_activate', 'happyforms_create_samples' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  endif;
163
 
164
+ add_action( 'happyforms_activate', 'happyforms_create_samples' );
165
+
166
+ if ( ! function_exists( 'happyforms_cleanup_on_deactivation' ) ) :
167
+
168
+ function happyforms_cleanup_on_deactivation() {
169
+ $cleanup_on_deactivation = happyforms_get_deactivation()->cleanup_on_deactivation();
170
+
171
+ return apply_filters( 'happyforms_cleanup_on_deactivation', $cleanup_on_deactivation );
172
+ }
173
+
174
+ endif;
175
+
176
+ if ( ! function_exists( 'happyforms_cleanup' ) ) :
177
+
178
+ function happyforms_cleanup() {
179
+ if ( ! happyforms_cleanup_on_deactivation() ) {
180
+ return;
181
+ }
182
+
183
+ return;
184
+
185
+ // Forms
186
+ $forms = get_posts( array(
187
+ 'post_type' => 'happyform',
188
+ 'post_status' => array_values( get_post_stati() ),
189
+ 'numberposts' => -1,
190
+ ) );
191
+
192
+ foreach( $forms as $form ) {
193
+ wp_delete_post( $form->ID, true );
194
+ }
195
+
196
+ // General options
197
+ delete_option( 'widget_happyforms_widget' );
198
+ delete_option( 'happyforms-tracking' );
199
+ delete_option( 'ttf_updates_key_happyforms' );
200
+
201
+ // User meta
202
+ $users = get_users();
203
+
204
+ foreach( $users as $user ) {
205
+ delete_user_meta( $user->ID, 'happyforms-dismissed-notices' );
206
+ delete_transient( 'happyforms_admin_notices_' . md5( $user->user_login ) );
207
+ delete_user_meta( $user->ID, 'happyforms-settings-sections-states' );
208
+ }
209
+
210
+ // Migrations
211
+ delete_option( 'happyforms-data-version' );
212
+
213
+ // Deactivation
214
+ delete_option( '_happyforms_cleanup_on_deactivate' );
215
+ }
216
+
217
+ endif;
218
+
219
+ add_action( 'happyforms_deactivate', 'happyforms_cleanup' );
core/helpers/helper-form-templates.php CHANGED
@@ -1312,6 +1312,10 @@ function happyforms_get_phone_countries() {
1312
 
1313
  $countries = apply_filters( 'happyforms_phone_countries', $countries );
1314
 
 
 
 
 
1315
  return $countries;
1316
  }
1317
 
1312
 
1313
  $countries = apply_filters( 'happyforms_phone_countries', $countries );
1314
 
1315
+ uasort( $countries, function ( $country1, $country2 ) {
1316
+ return strcmp( $country1['name'], $country2['name'] );
1317
+ } );
1318
+
1319
  return $countries;
1320
  }
1321
 
core/templates/admin/modal-deactivate.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="happyforms-modal__heading">
2
+ <h1><?php _e( 'What about your data?', 'happyforms' ); ?></h1>
3
+ </div>
4
+ <div class="happyforms-modal__content">
5
+ <form>
6
+ <?php wp_nonce_field( happyforms_get_deactivation()->modal_action ); ?>
7
+ <label for="happyforms-deactivate-keep-data">
8
+ <input type="radio" name="keep-data" value="yes" id="happyforms-deactivate-keep-data" checked />
9
+ <span><?php _e( 'Keep plugin data (recommended)', 'happyforms' ); ?></span>
10
+ </label>
11
+ <label for="happyforms-deactivate-remove-data">
12
+ <input type="radio" name="keep-data" value="no" id="happyforms-deactivate-remove-data" />
13
+ <span><?php _e( 'Permanently delete plugin data', 'happyforms' ); ?></span>
14
+ </label>
15
+ <button type="submit" class="button button-primary button-hero"><?php _e( 'Deactivate Plugin', 'happyforms' ); ?></button>
16
+ </form>
17
+ </div>
core/templates/customize-controls/setup/textarea.php CHANGED
@@ -2,5 +2,8 @@
2
  <label for="<?php echo $control['field']; ?>" class="customize-control-title"><?php echo $control['label']; ?> <?php if ( isset( $control['tooltip'] ) ) : ?><i class="dashicons dashicons-editor-help" aria-hidden="true" data-pointer><span><?php echo $control['tooltip']; ?></span></i><?php endif; ?></label>
3
  <div data-pointer-target>
4
  <textarea name="" id="<?php echo $control['field']; ?>" cols="34" rows="4" data-attribute="<?php echo $control['field']; ?>"><%= <?php echo $control['field']; ?> %></textarea>
 
 
 
5
  </div>
6
  </div>
2
  <label for="<?php echo $control['field']; ?>" class="customize-control-title"><?php echo $control['label']; ?> <?php if ( isset( $control['tooltip'] ) ) : ?><i class="dashicons dashicons-editor-help" aria-hidden="true" data-pointer><span><?php echo $control['tooltip']; ?></span></i><?php endif; ?></label>
3
  <div data-pointer-target>
4
  <textarea name="" id="<?php echo $control['field']; ?>" cols="34" rows="4" data-attribute="<?php echo $control['field']; ?>"><%= <?php echo $control['field']; ?> %></textarea>
5
+ <?php if( ! empty( $control['description'] ) ): ?>
6
+ <p class="description"><?php echo $control['description']; ?></p>
7
+ <?php endif; ?>
8
  </div>
9
  </div>
happyforms.php CHANGED
@@ -5,7 +5,7 @@
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
- * Version: 1.12.10
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
@@ -13,7 +13,7 @@
13
  /**
14
  * The current version of the plugin.
15
  */
16
- define( 'HAPPYFORMS_VERSION', '1.12.10' );
17
 
18
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
19
  /**
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
+ * Version: 1.12.11
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
13
  /**
14
  * The current version of the plugin.
15
  */
16
+ define( 'HAPPYFORMS_VERSION', '1.12.11' );
17
 
18
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
19
  /**
inc/assets/js/customize.js CHANGED
@@ -668,6 +668,8 @@
668
  handle: '.happyforms-part-widget-top',
669
  axis: 'y',
670
  tolerance: 'pointer',
 
 
671
 
672
  stop: function ( e, ui ) {
673
  this.trigger( 'sort-stop', e, ui );
668
  handle: '.happyforms-part-widget-top',
669
  axis: 'y',
670
  tolerance: 'pointer',
671
+ scroll: true,
672
+ scrollSpeed: 5,
673
 
674
  stop: function ( e, ui ) {
675
  this.trigger( 'sort-stop', e, ui );
inc/classes/class-happyforms.php CHANGED
@@ -19,7 +19,6 @@ class HappyForms extends HappyForms_Core {
19
  add_action( 'happyforms_do_style_control', array( $this, 'do_control' ), 10, 3 );
20
  add_filter( 'happyforms_setup_controls', array( $this, 'add_dummy_setup_controls' ) );
21
  add_filter( 'happyforms_email_controls', array( $this, 'add_dummy_email_controls' ) );
22
- add_filter( 'happyforms_style_controls', array( $this, 'add_dummy_style_controls' ) );
23
  add_action( 'parse_request', array( $this, 'parse_archive_request' ) );
24
  add_action( 'admin_init', [ $this, 'register_modals' ] );
25
  add_action( 'admin_init', array( $this, 'redirect_to_forms_page' ) );
@@ -162,6 +161,18 @@ class HappyForms extends HappyForms_Core {
162
  'label' => __( 'Schedule visibility', 'happyforms' ),
163
  );
164
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  return $controls;
166
  }
167
 
@@ -205,16 +216,6 @@ class HappyForms extends HappyForms_Core {
205
  return $controls;
206
  }
207
 
208
- public function add_dummy_style_controls( $controls ) {
209
- $controls[110] = array(
210
- 'type' => 'checkbox_dummy',
211
- 'dummy_id' => 'use_theme_styles',
212
- 'label' => __( 'Use theme styles', 'happyforms' ),
213
- );
214
-
215
- return $controls;
216
- }
217
-
218
  public function do_control( $control, $field, $index ) {
219
  $type = $control['type'];
220
 
19
  add_action( 'happyforms_do_style_control', array( $this, 'do_control' ), 10, 3 );
20
  add_filter( 'happyforms_setup_controls', array( $this, 'add_dummy_setup_controls' ) );
21
  add_filter( 'happyforms_email_controls', array( $this, 'add_dummy_email_controls' ) );
 
22
  add_action( 'parse_request', array( $this, 'parse_archive_request' ) );
23
  add_action( 'admin_init', [ $this, 'register_modals' ] );
24
  add_action( 'admin_init', array( $this, 'redirect_to_forms_page' ) );
161
  'label' => __( 'Schedule visibility', 'happyforms' ),
162
  );
163
 
164
+ $controls[3200] = array(
165
+ 'type' => 'checkbox_dummy',
166
+ 'dummy_id' => 'block_emails',
167
+ 'label' => __( 'Scan for the following email addresses, email domains and email partials', 'happyforms' ),
168
+ );
169
+
170
+ $controls[3201] = array(
171
+ 'type' => 'checkbox_dummy',
172
+ 'dummy_id' => 'block_language',
173
+ 'label' => __( 'Scan for the following words, phrases and letters', 'happyforms' ),
174
+ );
175
+
176
  return $controls;
177
  }
178
 
216
  return $controls;
217
  }
218
 
 
 
 
 
 
 
 
 
 
 
219
  public function do_control( $control, $field, $index ) {
220
  $type = $control['type'];
221
 
languages/happyforms.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Happyforms (free) package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Happyforms (free) 1.12.10\n"
6
  "Report-Msgid-Bugs-To: https://thethemefoundry.com/support/\n"
7
- "POT-Creation-Date: 2021-06-15 10:11:01+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -14,8 +14,8 @@ msgstr ""
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
  #: core/classes/class-block.php:49 core/classes/class-form-controller.php:68
17
- #: core/classes/class-happyforms-core.php:164
18
- #: core/classes/class-happyforms-core.php:165
19
  #: core/classes/class-happyforms-widget.php:13 core/helpers/helper-misc.php:997
20
  msgid "Forms"
21
  msgstr ""
@@ -24,28 +24,25 @@ msgstr ""
24
  msgid "Displays a form."
25
  msgstr ""
26
 
27
- #: core/classes/class-block.php:102
28
- msgid "Do you want access to HappyForms’ most powerful features?"
29
- msgstr ""
30
-
31
- #: core/classes/class-block.php:103
32
- msgid "Discover HappyForms Upgrade"
33
- msgstr ""
34
-
35
- #: core/classes/class-block.php:108 core/classes/parts/class-part-select.php:51
36
  msgid "Choose"
37
  msgstr ""
38
 
39
- #: core/classes/class-block.php:109
40
  msgid "Which form would you like to add here?"
41
  msgstr ""
42
 
43
- #: core/classes/class-block.php:110
44
  msgid "HappyForms Settings"
45
  msgstr ""
46
 
47
- #: core/classes/class-block.php:111
48
- msgid "Edit Form"
 
 
 
 
 
49
  msgstr ""
50
 
51
  #: core/classes/class-form-admin.php:159
@@ -182,8 +179,8 @@ msgid "Form"
182
  msgstr ""
183
 
184
  #: core/classes/class-form-controller.php:70
185
- #: core/classes/class-happyforms-core.php:180
186
- #: core/classes/class-happyforms-core.php:181
187
  msgid "Add New"
188
  msgstr ""
189
 
@@ -214,8 +211,8 @@ msgstr ""
214
 
215
  #: core/classes/class-form-controller.php:79
216
  #: core/classes/class-form-controller.php:80
217
- #: core/classes/class-happyforms-core.php:172
218
- #: core/classes/class-happyforms-core.php:173
219
  msgid "All Forms"
220
  msgstr ""
221
 
@@ -926,22 +923,22 @@ msgstr ""
926
  msgid "Additional CSS"
927
  msgstr ""
928
 
929
- #: core/classes/class-happyforms-core.php:188
930
- #: core/classes/class-happyforms-core.php:189
931
  msgid "Activity"
932
  msgstr ""
933
 
934
- #: core/classes/class-happyforms-core.php:197
935
- #: core/classes/class-happyforms-core.php:198
936
  msgid "Integrations"
937
  msgstr ""
938
 
939
- #: core/classes/class-happyforms-core.php:206
940
- #: core/classes/class-happyforms-core.php:207
941
  msgid "Settings"
942
  msgstr ""
943
 
944
- #: core/classes/class-happyforms-core.php:450
945
  msgid "Add Form"
946
  msgstr ""
947
 
@@ -1126,11 +1123,11 @@ msgstr ""
1126
  msgid "For radio buttons allowing one selection."
1127
  msgstr ""
1128
 
1129
- #: core/classes/parts/class-part-select.php:8
1130
  msgid "Dropdown"
1131
  msgstr ""
1132
 
1133
- #: core/classes/parts/class-part-select.php:9
1134
  msgid "For selecting one option from a long list. Default value adjustable."
1135
  msgstr ""
1136
 
@@ -2883,6 +2880,18 @@ msgstr ""
2883
  msgid "Yoruba"
2884
  msgstr ""
2885
 
 
 
 
 
 
 
 
 
 
 
 
 
2886
  #: core/templates/admin-form-modal.php:5
2887
  msgid "Choose a form"
2888
  msgstr ""
@@ -2960,7 +2969,7 @@ msgid "Clear Results"
2960
  msgstr ""
2961
 
2962
  #: core/templates/customize-form-parts-drawer.php:38
2963
- #: inc/classes/class-happyforms.php:112
2964
  #: inc/templates/customize-controls/checkbox_dummy.php:7
2965
  #: inc/templates/customize-controls/email-parts-list-dummy.php:11
2966
  msgid "Upgrade"
@@ -3205,63 +3214,67 @@ msgstr ""
3205
  msgid "Click to edit this part."
3206
  msgstr ""
3207
 
3208
- #: inc/classes/class-happyforms.php:120
3209
  msgid "Randomize fields to prevent bias"
3210
  msgstr ""
3211
 
3212
- #: inc/classes/class-happyforms.php:126
3213
  msgid "Use reCAPTCHA"
3214
  msgstr ""
3215
 
3216
- #: inc/classes/class-happyforms.php:132
3217
  msgid "Save incomplete and abandoned submissions"
3218
  msgstr ""
3219
 
3220
- #: inc/classes/class-happyforms.php:138
3221
  msgid "Let respondents save a draft submission and come back to it later"
3222
  msgstr ""
3223
 
3224
- #: inc/classes/class-happyforms.php:144
3225
  msgid "Require respondents to review a submission before submitting"
3226
  msgstr ""
3227
 
3228
- #: inc/classes/class-happyforms.php:150
3229
  msgid "Disable buttons until required fields are answered"
3230
  msgstr ""
3231
 
3232
- #: inc/classes/class-happyforms.php:156
3233
  msgid "Limit submissions"
3234
  msgstr ""
3235
 
3236
- #: inc/classes/class-happyforms.php:162
3237
  msgid "Schedule visibility"
3238
  msgstr ""
3239
 
3240
- #: inc/classes/class-happyforms.php:172
 
 
 
 
 
 
 
 
3241
  msgid "Include reply link"
3242
  msgstr ""
3243
 
3244
- #: inc/classes/class-happyforms.php:178
3245
  msgid "Include referral web address"
3246
  msgstr ""
3247
 
3248
- #: inc/classes/class-happyforms.php:184 inc/classes/class-happyforms.php:196
3249
  msgid "Attach .pdf"
3250
  msgstr ""
3251
 
3252
- #: inc/classes/class-happyforms.php:190
3253
  msgid "To email address"
3254
  msgstr ""
3255
 
3256
- #: inc/classes/class-happyforms.php:202
3257
  msgid "Send abandonment email"
3258
  msgstr ""
3259
 
3260
- #: inc/classes/class-happyforms.php:212
3261
- msgid "Use theme styles"
3262
- msgstr ""
3263
-
3264
- #: inc/classes/class-happyforms.php:429 inc/classes/class-happyforms.php:447
3265
  msgid "Build your own WordPress form with Happyforms"
3266
  msgstr ""
3267
 
2
  # This file is distributed under the same license as the Happyforms (free) package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Happyforms (free) 1.12.11\n"
6
  "Report-Msgid-Bugs-To: https://thethemefoundry.com/support/\n"
7
+ "POT-Creation-Date: 2021-07-05 08:27:32+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
  #: core/classes/class-block.php:49 core/classes/class-form-controller.php:68
17
+ #: core/classes/class-happyforms-core.php:166
18
+ #: core/classes/class-happyforms-core.php:167
19
  #: core/classes/class-happyforms-widget.php:13 core/helpers/helper-misc.php:997
20
  msgid "Forms"
21
  msgstr ""
24
  msgid "Displays a form."
25
  msgstr ""
26
 
27
+ #: core/classes/class-block.php:104 core/classes/parts/class-part-select.php:55
 
 
 
 
 
 
 
 
28
  msgid "Choose"
29
  msgstr ""
30
 
31
+ #: core/classes/class-block.php:105
32
  msgid "Which form would you like to add here?"
33
  msgstr ""
34
 
35
+ #: core/classes/class-block.php:106
36
  msgid "HappyForms Settings"
37
  msgstr ""
38
 
39
+ #: core/classes/class-deactivation.php:46
40
+ #: core/templates/admin/modal-deactivate.php:15
41
+ msgid "Deactivate Plugin"
42
+ msgstr ""
43
+
44
+ #: core/classes/class-deactivation.php:47
45
+ msgid "Delete Data and Deactivate Plugin"
46
  msgstr ""
47
 
48
  #: core/classes/class-form-admin.php:159
179
  msgstr ""
180
 
181
  #: core/classes/class-form-controller.php:70
182
+ #: core/classes/class-happyforms-core.php:182
183
+ #: core/classes/class-happyforms-core.php:183
184
  msgid "Add New"
185
  msgstr ""
186
 
211
 
212
  #: core/classes/class-form-controller.php:79
213
  #: core/classes/class-form-controller.php:80
214
+ #: core/classes/class-happyforms-core.php:174
215
+ #: core/classes/class-happyforms-core.php:175
216
  msgid "All Forms"
217
  msgstr ""
218
 
923
  msgid "Additional CSS"
924
  msgstr ""
925
 
926
+ #: core/classes/class-happyforms-core.php:190
927
+ #: core/classes/class-happyforms-core.php:191
928
  msgid "Activity"
929
  msgstr ""
930
 
931
+ #: core/classes/class-happyforms-core.php:199
932
+ #: core/classes/class-happyforms-core.php:200
933
  msgid "Integrations"
934
  msgstr ""
935
 
936
+ #: core/classes/class-happyforms-core.php:208
937
+ #: core/classes/class-happyforms-core.php:209
938
  msgid "Settings"
939
  msgstr ""
940
 
941
+ #: core/classes/class-happyforms-core.php:452
942
  msgid "Add Form"
943
  msgstr ""
944
 
1123
  msgid "For radio buttons allowing one selection."
1124
  msgstr ""
1125
 
1126
+ #: core/classes/parts/class-part-select.php:10
1127
  msgid "Dropdown"
1128
  msgstr ""
1129
 
1130
+ #: core/classes/parts/class-part-select.php:11
1131
  msgid "For selecting one option from a long list. Default value adjustable."
1132
  msgstr ""
1133
 
2880
  msgid "Yoruba"
2881
  msgstr ""
2882
 
2883
+ #: core/templates/admin/modal-deactivate.php:2
2884
+ msgid "What about your data?"
2885
+ msgstr ""
2886
+
2887
+ #: core/templates/admin/modal-deactivate.php:9
2888
+ msgid "Keep plugin data (recommended)"
2889
+ msgstr ""
2890
+
2891
+ #: core/templates/admin/modal-deactivate.php:13
2892
+ msgid "Permanently delete plugin data"
2893
+ msgstr ""
2894
+
2895
  #: core/templates/admin-form-modal.php:5
2896
  msgid "Choose a form"
2897
  msgstr ""
2969
  msgstr ""
2970
 
2971
  #: core/templates/customize-form-parts-drawer.php:38
2972
+ #: inc/classes/class-happyforms.php:111
2973
  #: inc/templates/customize-controls/checkbox_dummy.php:7
2974
  #: inc/templates/customize-controls/email-parts-list-dummy.php:11
2975
  msgid "Upgrade"
3214
  msgid "Click to edit this part."
3215
  msgstr ""
3216
 
3217
+ #: inc/classes/class-happyforms.php:119
3218
  msgid "Randomize fields to prevent bias"
3219
  msgstr ""
3220
 
3221
+ #: inc/classes/class-happyforms.php:125
3222
  msgid "Use reCAPTCHA"
3223
  msgstr ""
3224
 
3225
+ #: inc/classes/class-happyforms.php:131
3226
  msgid "Save incomplete and abandoned submissions"
3227
  msgstr ""
3228
 
3229
+ #: inc/classes/class-happyforms.php:137
3230
  msgid "Let respondents save a draft submission and come back to it later"
3231
  msgstr ""
3232
 
3233
+ #: inc/classes/class-happyforms.php:143
3234
  msgid "Require respondents to review a submission before submitting"
3235
  msgstr ""
3236
 
3237
+ #: inc/classes/class-happyforms.php:149
3238
  msgid "Disable buttons until required fields are answered"
3239
  msgstr ""
3240
 
3241
+ #: inc/classes/class-happyforms.php:155
3242
  msgid "Limit submissions"
3243
  msgstr ""
3244
 
3245
+ #: inc/classes/class-happyforms.php:161
3246
  msgid "Schedule visibility"
3247
  msgstr ""
3248
 
3249
+ #: inc/classes/class-happyforms.php:167
3250
+ msgid "Scan for the following email addresses, email domains and email partials"
3251
+ msgstr ""
3252
+
3253
+ #: inc/classes/class-happyforms.php:173
3254
+ msgid "Scan for the following words, phrases and letters"
3255
+ msgstr ""
3256
+
3257
+ #: inc/classes/class-happyforms.php:183
3258
  msgid "Include reply link"
3259
  msgstr ""
3260
 
3261
+ #: inc/classes/class-happyforms.php:189
3262
  msgid "Include referral web address"
3263
  msgstr ""
3264
 
3265
+ #: inc/classes/class-happyforms.php:195 inc/classes/class-happyforms.php:207
3266
  msgid "Attach .pdf"
3267
  msgstr ""
3268
 
3269
+ #: inc/classes/class-happyforms.php:201
3270
  msgid "To email address"
3271
  msgstr ""
3272
 
3273
+ #: inc/classes/class-happyforms.php:213
3274
  msgid "Send abandonment email"
3275
  msgstr ""
3276
 
3277
+ #: inc/classes/class-happyforms.php:430 inc/classes/class-happyforms.php:448
 
 
 
 
3278
  msgid "Build your own WordPress form with Happyforms"
3279
  msgstr ""
3280
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: contact form, contact form plugin, forms, form builder, custom form, intak
5
  Requires at least: 4.8
6
  Tested up to: 5.7.2
7
  Requires PHP: 5.3
8
- Stable tag: 1.12.10
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -151,6 +151,12 @@ Aw, honestly, the thought that you're writing about our contact form builder is
151
 
152
  == Changelog ==
153
 
 
 
 
 
 
 
154
  = 1.12.10 =
155
  * Improvement: More effective honeypot protection.
156
  * Improvement: Javascript dependencies for tooltips are now loaded only when necessary.
@@ -821,6 +827,9 @@ Aw, honestly, the thought that you're writing about our contact form builder is
821
 
822
  == Upgrade Notice ==
823
 
 
 
 
824
  = 1.12.10 =
825
  * Improved honeypot and asset loading, miscellaneous bugfixes.
826
 
5
  Requires at least: 4.8
6
  Tested up to: 5.7.2
7
  Requires PHP: 5.3
8
+ Stable tag: 1.12.11
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
151
 
152
  == Changelog ==
153
 
154
+ = 1.12.11 =
155
+ * Improvement: Deactivation popup allows for keeping or deleting saved data.
156
+ * Improvement: Forms block now supports additional CSS classes.
157
+ * Bugfix: Arrows in dropdowns were ignoring Style settings.
158
+ * Bugfix: Duplicating and drag-dropping fields in the builder was scrolling the field list to the top.
159
+
160
  = 1.12.10 =
161
  * Improvement: More effective honeypot protection.
162
  * Improvement: Javascript dependencies for tooltips are now loaded only when necessary.
827
 
828
  == Upgrade Notice ==
829
 
830
+ = 1.12.11 =
831
+ * Miscellaneous improvements and bugfixes.
832
+
833
  = 1.12.10 =
834
  * Improved honeypot and asset loading, miscellaneous bugfixes.
835