iubenda Cookie Solution for GDPR - Version 2.4.1

Version Description

  • Save Cons for non Ajax forms in WPForms
  • Fix saving consent in CF7
Download this release

Release Info

Developer iubenda
Plugin Icon 128x128 iubenda Cookie Solution for GDPR
Version 2.4.1
Comparing to
See all releases

Code changes from version 2.4.0 to 2.4.1

Files changed (4) hide show
  1. includes/forms.php +204 -77
  2. iubenda_cookie_solution.php +4 -3
  3. js/frontend.js +1 -1
  4. readme.txt +8 -5
includes/forms.php CHANGED
@@ -22,6 +22,57 @@ class iubenda_Forms {
22
  add_action( 'init', array( $this, 'register_post_type' ) );
23
  add_action( 'init', array( $this, 'register_post_status' ) );
24
  add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
 
27
  /**
@@ -37,12 +88,12 @@ class iubenda_Forms {
37
  if ( class_exists( 'WPCF7' ) ) {
38
  $this->sources['wpcf7'] = 'Contact Form 7';
39
  }
40
-
41
  // check if WP Forms is active
42
  if ( function_exists( 'wpforms' ) ) {
43
  $this->sources['wpforms'] = 'WP Forms';
44
  }
45
-
46
  // check if EooCommerce is active
47
  if ( function_exists( 'WC' ) ) {
48
  $this->sources['woocommerce'] = 'WooCommerce Checkout';
@@ -72,60 +123,11 @@ class iubenda_Forms {
72
  );
73
 
74
  $forms = $this->get_forms( $form_args );
75
-
76
  // echo '<pre>'; print_r( $forms ); echo '</pre>';
77
 
78
  if ( ! empty( $forms ) ) {
79
- // required form parameters
80
- $form_parameters = array(
81
- 'subject',
82
- 'preferences',
83
- 'exclude',
84
- 'legal_notices'
85
- );
86
- // loop through forms
87
- foreach ( $forms as $form ) {
88
- // bail if user is logged in and source is WP comment form
89
- if ( $form->form_source == 'wp_comment_form' && is_user_logged_in() )
90
- continue;
91
-
92
- // we need unique identifier for the html form
93
- // by default it's object id, used in form html id
94
- $args[$form->form_source][$form->object_id] = array();
95
-
96
- foreach ( $form_parameters as $parameter ) {
97
- $parameter_name = 'form_' . $parameter;
98
- $parameter_value = ! empty( $form->$parameter_name ) ? $form->$parameter_name : '';
99
-
100
- // echo '<pre>'; print_r( $parameter_value ); echo '</pre>';
101
-
102
- switch ( $parameter ) {
103
- case 'legal_notices' :
104
- if ( $parameter_value && is_array( $parameter_value ) ) {
105
- foreach( $parameter_value as $value ) {
106
- $args[$form->form_source][$form->object_id]['consent']['legal_notices'][] = array( 'identifier' => $value );
107
- }
108
- }
109
- break;
110
- default :
111
- if ( $parameter_value ) {
112
- switch ( $form->form_source ) {
113
- case 'wpforms' :
114
- // replace integers with field names
115
- foreach ( $parameter_value as $index => $parameter_item ) {
116
- $parameter_value[$index] = $form->form_fields[$parameter_item]['name'];
117
- }
118
- $args[$form->form_source][$form->object_id]['form']['map'][$parameter] = $parameter_value;
119
- break;
120
- default :
121
- $args[$form->form_source][$form->object_id]['form']['map'][$parameter] = $parameter_value;
122
- break;
123
- }
124
- }
125
- break;
126
- }
127
- }
128
- }
129
  }
130
 
131
  // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
@@ -351,9 +353,9 @@ class iubenda_Forms {
351
  $args['form_preferences'] = ! empty( $args['form_preferences'] ) && is_array( $args['form_preferences'] ) ? array_map( 'esc_attr', $args['form_preferences'] ) : array();
352
  $args['form_exclude'] = ! empty( $args['form_exclude'] ) && is_array( $args['form_exclude'] ) ? array_map( 'esc_attr', $args['form_exclude'] ) : array();
353
  $args['form_legal_notices'] = ! empty( $args['form_legal_notices'] ) && is_array( $args['form_legal_notices'] ) ? array_map( 'esc_attr', $args['form_legal_notices'] ) : array();
354
-
355
  $form_fields = array();
356
-
357
  // sanitize form fields
358
  if ( ! empty( $args['form_fields'] ) && is_array( $args['form_fields'] ) ) {
359
  foreach ( $args['form_fields'] as $form_field ) {
@@ -364,7 +366,7 @@ class iubenda_Forms {
364
  }
365
  }
366
  }
367
-
368
  // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
369
 
370
  // bail if any issues
@@ -473,16 +475,16 @@ class iubenda_Forms {
473
 
474
  if ( $new_fields ) {
475
  $new_forms['updated'] = $exists->ID;
476
-
477
  // update form
478
  $formdata['ID'] = $exists->ID;
479
-
480
  // update to need status if form is already mapped
481
  if ( $exists->post_status == 'mapped' )
482
  $formdata['status'] = 'needs_update';
483
-
484
  // echo '<pre>'; print_r( $formdata ); echo '</pre>'; exit;
485
-
486
  $result = $this->save_form( $formdata );
487
  }
488
  }
@@ -523,7 +525,7 @@ class iubenda_Forms {
523
  'nopaging' => true,
524
  );
525
  $posts = get_posts( $args );
526
-
527
  // echo '<pre>'; print_r( $posts ); echo '</pre>'; exit;
528
 
529
  if ( ! empty( $posts ) ) {
@@ -628,7 +630,7 @@ class iubenda_Forms {
628
  'label' => $field['label']
629
  );
630
  break;
631
- default :
632
  $formdata['form_fields'][] = array(
633
  'id' => $field['id'],
634
  'name' => 'wpforms[fields][' . $index . ']',
@@ -636,7 +638,7 @@ class iubenda_Forms {
636
  'label' => $field['label']
637
  );
638
  }
639
-
640
  }
641
  }
642
  }
@@ -648,7 +650,7 @@ class iubenda_Forms {
648
  }
649
 
650
  break;
651
-
652
  case 'wpcf7' :
653
  $args = array(
654
  'post_type' => 'wpcf7_contact_form',
@@ -692,16 +694,16 @@ class iubenda_Forms {
692
  }
693
 
694
  break;
695
-
696
  case 'woocommerce' :
697
  $checkout_form = '';
698
 
699
  ob_start();
700
-
701
  // Ensure gateways and shipping methods are loaded early.
702
  WC()->payment_gateways();
703
  WC()->shipping();
704
-
705
  /*
706
  * First lets start the session. You cant use here WC_Session directly
707
  * because it's an abstract class. But you can use WC_Session_Handler which
@@ -719,7 +721,7 @@ class iubenda_Forms {
719
 
720
  // Create a cart contents
721
  WC()->cart = new WC_Cart;
722
-
723
  // Create an abstract order
724
  WC()->order = new WC_Order;
725
 
@@ -736,7 +738,7 @@ class iubenda_Forms {
736
  'checkout' => WC()->checkout()
737
  )
738
  );
739
-
740
  wc_get_template(
741
  'checkout/form-pay.php', array(
742
  'order' => WC()->order
@@ -745,7 +747,7 @@ class iubenda_Forms {
745
 
746
  $checkout_form = ob_get_contents();
747
  ob_end_clean();
748
-
749
  if ( ! empty( $checkout_form ) ) {
750
  $formdata = array(
751
  'object_type' => 'custom', // object type where the form data is stored
@@ -761,7 +763,7 @@ class iubenda_Forms {
761
  'textarea',
762
  'select'
763
  );
764
-
765
  // DOMDoc parser
766
  if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
767
  libxml_use_internal_errors( true );
@@ -826,7 +828,7 @@ class iubenda_Forms {
826
 
827
  }
828
  }
829
-
830
  }
831
 
832
  /*
@@ -839,10 +841,10 @@ class iubenda_Forms {
839
 
840
  case 'wp_comment_form' :
841
  $comment_form = '';
842
-
843
  // get comment form for logged out user
844
  $current_user_id = get_current_user_id();
845
-
846
  // get first post
847
  $post_args = array(
848
  'numberposts' => 1,
@@ -850,9 +852,9 @@ class iubenda_Forms {
850
  'order' => 'ASC',
851
  'fields' => 'ids'
852
  );
853
-
854
  $posts = get_posts( $post_args );
855
-
856
  // get comment form
857
  if ( ! empty( $posts ) ) {
858
  wp_set_current_user( 0 );
@@ -988,7 +990,7 @@ class iubenda_Forms {
988
  // check result
989
  if ( ! $posts || is_wp_error( $posts ) )
990
  return false;
991
-
992
  $form = $this->get_form( $posts[0] );
993
 
994
  // kick back results
@@ -1017,4 +1019,129 @@ class iubenda_Forms {
1017
  return $results;
1018
  }
1019
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1020
  }
22
  add_action( 'init', array( $this, 'register_post_type' ) );
23
  add_action( 'init', array( $this, 'register_post_status' ) );
24
  add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
25
+ // Save cons for non ajax forms
26
+ add_action( 'wpforms_process_complete', array( $this, 'process_entry_for_wp_forms' ), 10, 4 );
27
+ }
28
+
29
+ /**
30
+ * Process entry for WP forms
31
+ *
32
+ * @param $fields
33
+ * @param $entry
34
+ * @param $form_data
35
+ * @param $entry_id
36
+ */
37
+ public function process_entry_for_wp_forms($fields, $entry, $form_data, $entry_id ) {
38
+ global $wp_version;
39
+ $public_api_key = iubenda()->options['cons']['public_api_key'];
40
+
41
+ // Escape on ajax request because it will be handle by injected JS "frontend.js"
42
+ // Or escape if the public api key is not defined
43
+ // Check current WP version is newer than 4.7 to use the wp_doing_ajax function
44
+ if ( ( version_compare( $wp_version, '4.7', '>=' ) && wp_doing_ajax() ) || ! $public_api_key ) {
45
+ return;
46
+ }
47
+
48
+ $form_id = $this->array_get( $_POST, 'wpforms.id' );
49
+ $form_args = array(
50
+ 'post_status' => array( 'mapped', 'needs_update' ),
51
+ 'source' => 'wpforms',
52
+ 'id' => $form_id,
53
+ );
54
+
55
+ $form = $this->get_form_by_object_id($form_args);
56
+
57
+ if ( ! $form ) {
58
+ return;
59
+ }
60
+
61
+ $data = array();
62
+ // Prepare form subjects
63
+ foreach ( array( 'subject', 'preferences', 'legal_notices' ) as $key ) {
64
+ $data = $this->prepare_data_for_wp_forms( $form, $key, $entry, $data );
65
+ }
66
+
67
+ $data['proofs'][0]['content'] = json_encode( $_POST );
68
+
69
+ wp_remote_post( iubenda()->options['cons']['cons_endpoint'], array(
70
+ 'body' => json_encode( $data ),
71
+ 'headers' => array(
72
+ 'apikey' => $public_api_key,
73
+ 'Content-Type' => 'application/json',
74
+ ),
75
+ ) );
76
  }
77
 
78
  /**
88
  if ( class_exists( 'WPCF7' ) ) {
89
  $this->sources['wpcf7'] = 'Contact Form 7';
90
  }
91
+
92
  // check if WP Forms is active
93
  if ( function_exists( 'wpforms' ) ) {
94
  $this->sources['wpforms'] = 'WP Forms';
95
  }
96
+
97
  // check if EooCommerce is active
98
  if ( function_exists( 'WC' ) ) {
99
  $this->sources['woocommerce'] = 'WooCommerce Checkout';
123
  );
124
 
125
  $forms = $this->get_forms( $form_args );
126
+
127
  // echo '<pre>'; print_r( $forms ); echo '</pre>';
128
 
129
  if ( ! empty( $forms ) ) {
130
+ $args = $this->prepare_mapped_forms( $forms, $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
132
 
133
  // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
353
  $args['form_preferences'] = ! empty( $args['form_preferences'] ) && is_array( $args['form_preferences'] ) ? array_map( 'esc_attr', $args['form_preferences'] ) : array();
354
  $args['form_exclude'] = ! empty( $args['form_exclude'] ) && is_array( $args['form_exclude'] ) ? array_map( 'esc_attr', $args['form_exclude'] ) : array();
355
  $args['form_legal_notices'] = ! empty( $args['form_legal_notices'] ) && is_array( $args['form_legal_notices'] ) ? array_map( 'esc_attr', $args['form_legal_notices'] ) : array();
356
+
357
  $form_fields = array();
358
+
359
  // sanitize form fields
360
  if ( ! empty( $args['form_fields'] ) && is_array( $args['form_fields'] ) ) {
361
  foreach ( $args['form_fields'] as $form_field ) {
366
  }
367
  }
368
  }
369
+
370
  // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
371
 
372
  // bail if any issues
475
 
476
  if ( $new_fields ) {
477
  $new_forms['updated'] = $exists->ID;
478
+
479
  // update form
480
  $formdata['ID'] = $exists->ID;
481
+
482
  // update to need status if form is already mapped
483
  if ( $exists->post_status == 'mapped' )
484
  $formdata['status'] = 'needs_update';
485
+
486
  // echo '<pre>'; print_r( $formdata ); echo '</pre>'; exit;
487
+
488
  $result = $this->save_form( $formdata );
489
  }
490
  }
525
  'nopaging' => true,
526
  );
527
  $posts = get_posts( $args );
528
+
529
  // echo '<pre>'; print_r( $posts ); echo '</pre>'; exit;
530
 
531
  if ( ! empty( $posts ) ) {
630
  'label' => $field['label']
631
  );
632
  break;
633
+ default :
634
  $formdata['form_fields'][] = array(
635
  'id' => $field['id'],
636
  'name' => 'wpforms[fields][' . $index . ']',
638
  'label' => $field['label']
639
  );
640
  }
641
+
642
  }
643
  }
644
  }
650
  }
651
 
652
  break;
653
+
654
  case 'wpcf7' :
655
  $args = array(
656
  'post_type' => 'wpcf7_contact_form',
694
  }
695
 
696
  break;
697
+
698
  case 'woocommerce' :
699
  $checkout_form = '';
700
 
701
  ob_start();
702
+
703
  // Ensure gateways and shipping methods are loaded early.
704
  WC()->payment_gateways();
705
  WC()->shipping();
706
+
707
  /*
708
  * First lets start the session. You cant use here WC_Session directly
709
  * because it's an abstract class. But you can use WC_Session_Handler which
721
 
722
  // Create a cart contents
723
  WC()->cart = new WC_Cart;
724
+
725
  // Create an abstract order
726
  WC()->order = new WC_Order;
727
 
738
  'checkout' => WC()->checkout()
739
  )
740
  );
741
+
742
  wc_get_template(
743
  'checkout/form-pay.php', array(
744
  'order' => WC()->order
747
 
748
  $checkout_form = ob_get_contents();
749
  ob_end_clean();
750
+
751
  if ( ! empty( $checkout_form ) ) {
752
  $formdata = array(
753
  'object_type' => 'custom', // object type where the form data is stored
763
  'textarea',
764
  'select'
765
  );
766
+
767
  // DOMDoc parser
768
  if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
769
  libxml_use_internal_errors( true );
828
 
829
  }
830
  }
831
+
832
  }
833
 
834
  /*
841
 
842
  case 'wp_comment_form' :
843
  $comment_form = '';
844
+
845
  // get comment form for logged out user
846
  $current_user_id = get_current_user_id();
847
+
848
  // get first post
849
  $post_args = array(
850
  'numberposts' => 1,
852
  'order' => 'ASC',
853
  'fields' => 'ids'
854
  );
855
+
856
  $posts = get_posts( $post_args );
857
+
858
  // get comment form
859
  if ( ! empty( $posts ) ) {
860
  wp_set_current_user( 0 );
990
  // check result
991
  if ( ! $posts || is_wp_error( $posts ) )
992
  return false;
993
+
994
  $form = $this->get_form( $posts[0] );
995
 
996
  // kick back results
1019
  return $results;
1020
  }
1021
 
1022
+ /**
1023
+ * @param array $forms
1024
+ * @param array $args
1025
+ *
1026
+ * @return array
1027
+ */
1028
+ private function prepare_mapped_forms( array $forms, array $args ) {
1029
+ // required form parameters
1030
+ $form_parameters = array(
1031
+ 'subject',
1032
+ 'preferences',
1033
+ 'exclude',
1034
+ 'legal_notices'
1035
+ );
1036
+ // loop through forms
1037
+ foreach ( $forms as $form ) {
1038
+ // bail if user is logged in and source is WP comment form
1039
+ if ( $form->form_source == 'wp_comment_form' && is_user_logged_in() )
1040
+ continue;
1041
+
1042
+ // we need unique identifier for the html form
1043
+ // by default it's object id, used in form html id
1044
+ $args[ $form->form_source ][ $form->object_id ] = array();
1045
+
1046
+ foreach ( $form_parameters as $parameter ) {
1047
+ $parameter_name = 'form_' . $parameter;
1048
+ $parameter_value = ! empty( $form->$parameter_name ) ? $form->$parameter_name : '';
1049
+
1050
+ // echo '<pre>'; print_r( $parameter_value ); echo '</pre>';
1051
+
1052
+ switch ( $parameter ) {
1053
+ case 'legal_notices' :
1054
+ if ( $parameter_value && is_array( $parameter_value ) ) {
1055
+ foreach ( $parameter_value as $value ) {
1056
+ $args[ $form->form_source ][ $form->object_id ]['consent']['legal_notices'][] = array( 'identifier' => $value );
1057
+ }
1058
+ }
1059
+ break;
1060
+ default :
1061
+ if ( $parameter_value ) {
1062
+ switch ( $form->form_source ) {
1063
+ case 'wpforms' :
1064
+ // replace integers with field names
1065
+ foreach ( $parameter_value as $index => $parameter_item ) {
1066
+ $parameter_value[ $index ] = $form->form_fields[ $parameter_item ]['name'];
1067
+ }
1068
+ $args[ $form->form_source ][ $form->object_id ]['form']['map'][ $parameter ] = $parameter_value;
1069
+ break;
1070
+ default :
1071
+ $args[ $form->form_source ][ $form->object_id ]['form']['map'][ $parameter ] = $parameter_value;
1072
+ break;
1073
+ }
1074
+ }
1075
+ break;
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+ return $args;
1081
+ }
1082
+
1083
+ private function array_get( $array, $key, $default = null ) {
1084
+ $value = $default;
1085
+ if ( ! is_array( $array ) ) {
1086
+ return $value( $array );
1087
+ }
1088
+
1089
+ if ( is_null( $key ) ) {
1090
+ return $array;
1091
+ }
1092
+
1093
+ if ( array_key_exists( $key, $array ) ) {
1094
+ return $array[ $key ];
1095
+ }
1096
+
1097
+ if ( strpos( $key, '.' ) === false ) {
1098
+ return $array[ $key ] ?: $default;
1099
+ }
1100
+
1101
+ foreach ( explode( '.', $key ) as $segment ) {
1102
+ if ( ( is_array( $array ) || $array instanceof ArrayAccess ) && array_key_exists( $segment, $array ) ) {
1103
+ $array = $array[ $segment ];
1104
+ } else {
1105
+ return $default;
1106
+ }
1107
+ }
1108
+
1109
+ return $array;
1110
+ }
1111
+
1112
+ /**
1113
+ * Prepare data for subject and preferences
1114
+ *
1115
+ * @param WP_Post $form
1116
+ * @param string $key
1117
+ * @param $entry
1118
+ * @param array $data
1119
+ *
1120
+ * @return array
1121
+ */
1122
+ private function prepare_data_for_wp_forms( $form, $key, $entry, $data ) {
1123
+ // Check is key exist in form before looping
1124
+ if ( ! isset( $form->{"form_{$key}"} ) || ! is_array( $form->{"form_{$key}"} ) ) {
1125
+ return $data;
1126
+ }
1127
+
1128
+ // Prepare form preferences and subject
1129
+ foreach ( $form->{"form_{$key}"} as $map_key => $index ) {
1130
+
1131
+ if ( ! is_numeric( $index ) ) {
1132
+ continue;
1133
+ }
1134
+
1135
+ if ( 'legal_notices' === $key ) {
1136
+ $data['legal_notices'][] = array( 'identifier' => $index );
1137
+ continue;
1138
+ }
1139
+
1140
+ $array_key = trim( $form->form_fields[ $index ]['name'], 'wpforms' );
1141
+ $array_key = substr( str_replace( '][', '.', $array_key ), 1, - 1 );
1142
+ $data[ $key ][ $map_key ] = $this->array_get( $entry, $array_key );
1143
+ }
1144
+
1145
+ return $data;
1146
+ }
1147
  }
iubenda_cookie_solution.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Cookie and Consent Solution for the GDPR & ePrivacy
4
  Plugin URI: https://www.iubenda.com
5
  Description: An All-in-One approach developed by iubenda, which includes functionalities of two powerful solutions that help to make your website GDPR and ePrivacy compliant.
6
- Version: 2.4.0
7
  Author: iubenda
8
  Author URI: https://www.iubenda.com
9
  License: MIT License
@@ -32,7 +32,7 @@ define( 'IUB_DEBUG', false );
32
  * iubenda final class.
33
  *
34
  * @class iubenda
35
- * @version 2.4.0
36
  */
37
  class iubenda {
38
 
@@ -58,10 +58,11 @@ class iubenda {
58
  ),
59
  'cons' => array(
60
  'public_api_key' => '',
 
61
  )
62
  );
63
  public $base_url;
64
- public $version = '2.4.0';
65
  public $activation = array(
66
  'update_version' => 0,
67
  'update_notice' => true,
3
  Plugin Name: Cookie and Consent Solution for the GDPR & ePrivacy
4
  Plugin URI: https://www.iubenda.com
5
  Description: An All-in-One approach developed by iubenda, which includes functionalities of two powerful solutions that help to make your website GDPR and ePrivacy compliant.
6
+ Version: 2.4.1
7
  Author: iubenda
8
  Author URI: https://www.iubenda.com
9
  License: MIT License
32
  * iubenda final class.
33
  *
34
  * @class iubenda
35
+ * @version 2.4.1
36
  */
37
  class iubenda {
38
 
58
  ),
59
  'cons' => array(
60
  'public_api_key' => '',
61
+ 'cons_endpoint' => 'https://consent.iubenda.com/public/consent',
62
  )
63
  );
64
  public $base_url;
65
+ public $version = '2.4.1';
66
  public $activation = array(
67
  'update_version' => 0,
68
  'update_notice' => true,
js/frontend.js CHANGED
@@ -111,7 +111,7 @@
111
  };
112
 
113
  // send only if specific form has been submitted
114
- if ( selector.parentElement.id == e.target.id ) {
115
  _this.submitForm( form, formArgs );
116
 
117
  _iub.cons.sendData();
111
  };
112
 
113
  // send only if specific form has been submitted
114
+ if ( selector.parentElement.id == e.target.parentElement.id ) {
115
  _this.submitForm( form, formArgs );
116
 
117
  _iub.cons.sendData();
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: cookies, cookie law, cookie policy, cookie banner, privacy policy, cookie
5
  Requires at least: 4.0
6
  Requires PHP: 5.2.4
7
  Tested up to: 5.6.0
8
- Stable tag: 2.4.0
9
  License: MIT License
10
  License URI: http://opensource.org/licenses/MIT
11
 
@@ -150,6 +150,10 @@ We will be very happy to receive feedback here: [Uservoice forum](https://suppor
150
 
151
  == Changelog ==
152
 
 
 
 
 
153
  = 2.4.0 =
154
  * New: Use the new check consent endpoint
155
  * Fix: Regenerate AMP files on plugin update
@@ -497,7 +501,6 @@ We will be very happy to receive feedback here: [Uservoice forum](https://suppor
497
 
498
  == Upgrade Notice ==
499
 
500
- = 2.4.0 =
501
- * New: Use the new check consent endpoint
502
- * Fix: Regenerate AMP files on plugin update
503
- * New: Support WPRollback on plugin update
5
  Requires at least: 4.0
6
  Requires PHP: 5.2.4
7
  Tested up to: 5.6.0
8
+ Stable tag: 2.4.1
9
  License: MIT License
10
  License URI: http://opensource.org/licenses/MIT
11
 
150
 
151
  == Changelog ==
152
 
153
+ = 2.4.1 =
154
+ * Save Cons for non Ajax forms in WPForms
155
+ * Fix saving consent in CF7
156
+
157
  = 2.4.0 =
158
  * New: Use the new check consent endpoint
159
  * Fix: Regenerate AMP files on plugin update
501
 
502
  == Upgrade Notice ==
503
 
504
+ = 2.4.1 =
505
+ * Save Cons for non Ajax forms in WPForms
506
+ * Fix saving consent in CF7